122 lines
4.1 KiB
Markdown
122 lines
4.1 KiB
Markdown
## Prompt input and optimistic-state consolidation
|
|
|
|
Decompose prompt-input and unify optimistic message mutations.
|
|
|
|
---
|
|
|
|
### Summary
|
|
|
|
`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.
|
|
|
|
---
|
|
|
|
### Goals
|
|
|
|
- Split `prompt-input.tsx` into modular UI + controller pieces.
|
|
- Centralize optimistic message add/remove behavior behind sync-context APIs.
|
|
- Remove unsafe cast path around optimistic parts (`as unknown as Part[]`).
|
|
- Keep existing prompt UX and submission semantics unchanged.
|
|
|
|
---
|
|
|
|
### Non-goals
|
|
|
|
- No redesign of prompt input visuals.
|
|
- No changes to session protocol or backend APIs.
|
|
- No changes to unrelated page modules (`pages/session.tsx`, `pages/layout.tsx`).
|
|
|
|
---
|
|
|
|
### Parallel ownership (important)
|
|
|
|
This workstream owns:
|
|
|
|
- `packages/app/src/components/prompt-input.tsx`
|
|
- New files under `packages/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)
|
|
|
|
---
|
|
|
|
### Current state
|
|
|
|
- File size: ~1,391 LOC for `prompt-input.tsx`.
|
|
- Existing extracted modules:
|
|
- `prompt-input/editor-dom.ts`
|
|
- `prompt-input/attachments.ts`
|
|
- `prompt-input/history.ts`
|
|
- `prompt-input/submit.ts`
|
|
- Optimistic mutation and request-part casting still need consolidation (including remaining `as unknown as Part[]` in submit path).
|
|
- Remaining concerns still tightly coupled in `prompt-input.tsx`:
|
|
- slash/mention UI rendering and keyboard orchestration
|
|
- context pill interactions and focus behavior
|
|
- composition glue across history/attachments/submit
|
|
|
|
---
|
|
|
|
### Proposed structure
|
|
|
|
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.
|
|
|
|
---
|
|
|
|
### Phased steps
|
|
|
|
1. Extract typed request-part builder (likely from `prompt-input/submit.ts`) to remove ad hoc casting.
|
|
2. Introduce sync optimistic APIs with current behavior.
|
|
3. Replace remaining direct `produce(...)` optimistic mutations with optimistic APIs.
|
|
4. Extract remaining UI subtrees (slash popover, context items, toolbar controls).
|
|
5. Extract controller hook and keep route component as composition shell.
|
|
|
|
---
|
|
|
|
### Acceptance criteria
|
|
|
|
- Optimistic update logic exists in one place only.
|
|
- `prompt-input.tsx` is significantly smaller (target: under 1,200 LOC).
|
|
- Prompt submit/abort/history behavior remains unchanged.
|
|
- No `as unknown as Part[]` in optimistic request construction path.
|
|
|
|
---
|
|
|
|
### Validation plan
|
|
|
|
- Typecheck: `bun run typecheck` (from `packages/app`).
|
|
- Targeted e2e checks:
|
|
- `e2e/prompt/prompt.spec.ts`
|
|
- `e2e/prompt/context.spec.ts`
|
|
- `e2e/prompt/prompt-slash-open.spec.ts`
|
|
- `e2e/prompt/prompt-mention.spec.ts`
|
|
- Manual check:
|
|
- submit with file/image/context attachments
|
|
- abort in-flight turn
|
|
- history up/down restore behavior
|
|
|
|
---
|
|
|
|
### Handoff notes
|
|
|
|
- Preserve sequence semantics around optimistic insert, worktree wait, send, and rollback.
|
|
- Keep sync optimistic API data-oriented and reusable by future callers.
|
|
- Do not mix this with broader sync/global-sync refactors in the same diff.
|