Skip to content

Editor-first bubble (Cue/Rewrite/Imagine), inline Imagine, pencil Imagine-again - #11

Open
prxshetty wants to merge 27 commits into
mainfrom
feat/margin-image-assets
Open

prxshetty wants to merge 27 commits into
mainfrom
feat/margin-image-assets

Conversation

@prxshetty

Copy link
Copy Markdown
Owner

What

Makes the editor feel editor-first, AI-second:

Bubble menu (ui/src/components/Editor/WritingBubbleMenu.tsx)

  • Two space-separated pills: formatting (Paragraph, B/I/U, link, overflow) + AI (Cue, Rewrite, Imagine)
  • Brand icons (quote / pen / diamond via new brandIcons.tsx), hairline separators, no hover titles, equal-height pills
  • Rewrite/Imagine morph inline at fixed width with expandable vertical view; style pill appears on expand only
  • Imagine generates + inserts directly (no dialog); link morphs to a URL input

Image pill (MarginImage.tsx)

  • Reset button removed; pencil opens a required-input Imagine-again bar (same stacked structure, style on expand)
  • Shimmer loading state, toast errors, old image kept on failure

Slash menu — diamond/upload brand icons, narrower minimal menu, concise hints, word-prefix two-tier filtering

Toasts — new toastStore + Toaster replace all window.alert in editor/file flows

Settings Images tab — provider/ComfyUI-workflows split, Gemini URL hidden, hairline style rows with icon actions, deletable built-ins (except None) with restore, Images above Context, Harness renamed

BackendPOST /api/images/generate now always requires a prompt; removed the empty-prompt fallback + dead dialog regen branch

Docs — writing-guide, debugging, ai-assist updated to the new vocabulary

Verification

  • npx tsc -b: clean
  • backend pytest: 113 passed
  • vitest could not run here (repo toolchain needs Node 22+, env has Node 20) — worth a npm test in CI before merge

Images are first-class workspace resources: paste/drop/slash upload to
workspace/assets/, Markdown holds rel paths, endpoints get [image: alt]
text while harnesses read files via workspace scope. Adds MarginImage
node (source-above, caption=title), slash menu (Floating UI), bubble
link editor, Cmd/Ctrl+click link policy, media API + tests.
Images stay plain Markdown backed by workspace/assets/ (Obsidian-style
|WxH dims, {align=} trailer, Markdown as source of truth). Minimal
selected-state chrome: drag handles, reset, alignment, editable source.
Streamed uploads, vitest round-trip suite, docs/images.md.
Images section now lives in writing-guide.md (syntax table, paste/drag,
no size limit, debugging pointer). Remove /images route; sidebar links
Images to /writing-guide#images first in the Configuration group.
Move debugging.md out of Configuration to top level.
Type /image at a block start to upload from the device (Downloads,
etc.) via the OS file dialog. Files reuse the existing
upload-to-assets pipeline with a file-switch guard; pasted URLs
already import, so no URL mode. ITEMS registry is extensible for
future entries. Minimal title+subtitle menu styling.
- ImageProvider protocol: Margin owns prompt/style/storage, providers own HTTP
- OpenAI-compatible (generations + edits), Stability, FAL, and ComfyUI dual-slot
  (text/edit workflows, upload+inject reference, per-slot seed maps)
- assets/generated/ opaque storage via save_generated_bytes, existing media serving
- POST /api/images/generate (400 config / 502 upstream), /comfy/analyze,
  /logs, /reveal; POST /api/settings/test-image-provider with per-slot status
- 400 = Margin config/request wrong, 502 = provider communication failure
- Full pytest coverage: storage, validation matrix, routing, immutability
…nerate

- Shared ImageGenerateDialog (prompt + style + reference thumbnail, abortable,
  file-switch guard drops cross-document inserts)
- Slash menu gains Generate image; BubbleMenu gains Generate (selection becomes
  the initial prompt, never deleted; insert after selection)
- Image toolbar gains Regenerate: src-only swap preserves size/align/caption,
  native undo restores the previous asset
- Fresh generations use a fixed 'generated image' alt; regen prefills from the
  edit workflow's saved prompt text
- generateImage client in lib/media; slash registry extracted to slashItems
- Settings Images tab: provider config + test, default/custom styles, per-slot
  ComfyUI workflow import with ranked prompt/image/seed pickers
- History dropdown gains Chats/Images toggle (fixed width, minimal rows);
  full run details (input/output, submitted prompt, seed, paths) move to an
  ImageDetailPopup with copy-prompt and open-folder actions
- New GeminiProvider (Nano Banana family): text-to-image plus single
  reference-image edit, x-goog-api-key auth, fixed googleapis endpoint.
  Google's OpenAI-compat layer has no images route (404, probed live),
  so no code is shared with OpenAICompatibleProvider beyond the
  generate() contract and byte validation.
- Defensive response parsing: documented output_image block first,
  magic-byte-validated recursive scan as fallback for envelope drift.
- Safety refusals surfaced explicitly; auth failures map to 400,
  upstream/safety failures to 502 per the status table.
- check_model() powers the Settings Test button (GET /v1beta/models).
- Settings Images tab lists Gemini with key+model fields only.
- 11 new tests: request shapes, nested-block fallback, auth/safety
  mapping, check_model, end-to-end path with null seed
- Log entries get stable ids at save time; DELETE /api/images/logs/{id}
  removes one entry (legacy id-less entries match timestamp+path)
- History Images tab gains hover-reveal delete per row (mirrors chats),
  closing the detail popup if its entry was deleted
- Image log fetches share one in-flight request so rapid open/tab-switch
  sequences never fire redundant requests
- New image_style_overrides setting; resolution precedence is custom
  styles, then built-in overrides, then shipped defaults (None is
  hard-guarded to always mean no style)
- list_styles returns effective prompt plus default_prompt and an
  overridden flag
- Settings Images tab merges default/custom sections into one Styles
  list: every style shows name and prompt with default radio, inline
  edit, per-style reset for overridden built-ins, delete for customs
The bubble never unmounts, so a dismissed rewrite session stayed stuck
and reshown on the next selection. Bind the session to its selection
range and fall back to the default bubble when it clears or moves.
…agine, pencil Imagine-again

Bubble menu is now two space-separated pills: formatting
(Paragraph, B/I/U, link, overflow) and AI (Cue, Rewrite, Imagine)
with brand icons, dividers, and no hover titles. Imagine morphs
inline with an expandable prompt and on-demand style pill instead
of a dialog; the image pill's pencil opens a required-input
Imagine-again bar with the same structure. Centralized toast
notifications replace window.alert across editor flows.

Settings Images tab: provider/ComfyUI-workflows split, Gemini URL
hidden, hairline style rows with icon actions, deletable built-ins
(except None), Images moved above Context, Harness renamed.
Backend requires non-empty prompts; dead regen fallback removed.
Docs updated to match.
…d loading ring

- Second-slot morph: rewrite/imagine/link inputs animate in place of the
  AI pill with per-entry origins; formatting pill hidden while prompting
- Boundary-aware positioning via Floating UI shift/flip
- Minimal borderless style pills with pinned chevron in bubble and
  Imagine-again bar; unified expanded footers; send hints dropped
- Loading shimmer scoped to the active input pill, quieter sweep
…show

- Send buttons use SimpleAssist's filled-pill treatment in the bubble's
  5px radius; pinned chevron on minimal style pills
- Morph animation plays on mode switches only (cleared on animationend)
  so select-to-show stays instant; stable shouldShow stops per-render
  BubbleMenu transactions
- Uniform 4px pill padding; formatting hidden while prompting; loading
  ring scoped to the active input with a quieter sweep
- index.html: Imagine Images, Slash Commands, Inline AI Bubble cards
- writing-guide: link click vs Cmd/Ctrl+Click follow; slash prefix filtering
- Toast previously console-only failures: harness accept/reject,
  file open/save, settings load/save, history fetch/delete, copy,
  folder picker, workspace file listing, harness list
- Toaster restyle: top-right, flat surface with semantic dot,
  no tinted backgrounds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant