Decompose prompt-input and unify optimistic message mutations.
packages/app/src/components/prompt-input.tsx has already been partially decomposed and is now ~1,391 LOC. Editor DOM helpers, attachments, history, and submit flow were extracted into packages/app/src/components/prompt-input/*.ts, but optimistic mutation ownership and some UI/controller responsibilities are still split across call sites. This spec continues from that refactored baseline.
prompt-input.tsx into modular UI + controller pieces.as unknown as Part[]).pages/session.tsx, pages/layout.tsx).This workstream owns:
packages/app/src/components/prompt-input.tsxpackages/app/src/components/prompt-input/**packages/app/src/context/sync.tsx (optimistic API surface only)This workstream must not edit:
packages/app/src/pages/session.tsx (spec 09)packages/app/src/pages/layout.tsx (spec 10)packages/app/src/context/global-sync.tsx (spec 12)packages/app/src/context/file.tsx (spec 13)prompt-input.tsx.prompt-input/editor-dom.tsprompt-input/attachments.tsprompt-input/history.tsprompt-input/submit.tsas unknown as Part[] in submit path).prompt-input.tsx:
Build on the existing packages/app/src/components/prompt-input/ modules by adding/further splitting modules such as:
use-prompt-composer.ts - state machine for submit/abort/history.build-request-parts.ts - typed request-part construction.slash-popover.tsx - slash command list rendering.context-items.tsx - context pills and interactions.Keep existing lower-level modules (attachments.ts, editor-dom.ts, history.ts, submit.ts) and narrow their responsibilities where needed.
Add sync-level optimistic APIs (in context/sync.tsx or context/sync-optimistic.ts):
session.optimistic.add(...)session.optimistic.remove(...)Prompt input should call these APIs instead of directly mutating message/part stores.
prompt-input/submit.ts) to remove ad hoc casting.produce(...) optimistic mutations with optimistic APIs.prompt-input.tsx is significantly smaller (target: under 1,200 LOC).as unknown as Part[] in optimistic request construction path.bun run typecheck (from packages/app).e2e/prompt/prompt.spec.tse2e/prompt/context.spec.tse2e/prompt/prompt-slash-open.spec.tse2e/prompt/prompt-mention.spec.ts