refactor(app): extract prompt-input derived state into derived-state.ts - #1083
Conversation
Move the 12 read-only derived memos (info/status/working/imageAttachments/ actionReady/abortReady/commentCount/blank/stopping/contextItems/placeholder/ accepting) out of the PromptInput component into createPromptDerivedState. Pure extraction, no behavior change.
|
Warning Review limit reached
More reviews will be available in 43 minutes and 14 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR refactors the prompt input component by extracting 12+ inline ChangesPrompt input derived state refactoring
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request refactors the PromptInput component by extracting its derived state memos into a new helper function, createPromptDerivedState, in a separate file. The review feedback suggests a minor cleanup: since the status memo is only used internally within the new helper function to compute working, it does not need to be returned or destructured in the main component.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Suggested priority: P2 (includes user-path files (packages/app/src/components/prompt-input.tsx, packages/app/src/components/prompt-input/derived-state.ts)).
P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.
The status memo is only consumed internally by working() inside the factory, so it no longer needs to be returned or destructured in prompt-input.tsx. Behavior unchanged; status is still computed lazily. Addresses gemini-code-assist review on #1083.
…ts (#1091) Slice 2 of the serial prompt-input.tsx slimming line (slice 1 = #1083). Pure extraction, no behavior/DOM/aria/copy/storage-key change. Change boundary: - New prompt-input/commands-mode.ts exposing createPromptCommandsAndMode(deps): owns the pick() file-picker action, setMode() + the shellModeKey/normalModeKey constants, and the command.register("prompt-input", ...) registration (file.attach / prompt.mode.shell / prompt.mode.normal). Returns only { pick } (setMode and the mode keybinds have no external consumers). - prompt-input.tsx now calls the factory synchronously at the cluster's original position, so command.register's owner-scoped onCleanup and the registration order (vs createPromptAttachments and the props.edit effect) are unchanged. Removed the now-unused canUseNativeFilePicker and pickAttachments imports. Late-binding handled by injection seams (the only textual changes): - addPickedPaths is produced by createPromptAttachments later in the file, so it is injected as the accessor thunk () => addPickedPaths and resolved as addPickedPaths() inside pick — preserving the pre-existing forward-reference closure timing (pick runs only post-mount). - editorRef?.focus() -> editorRef()?.focus() (editorRef injected as a getter). - () => fileInputRef?.click() -> injected fallbackInputClick. Command ids, mod+u / mod+shift+x / mod+shift+e keybinds, language.t keys, and the three disabled expressions are verbatim. prompt-input.tsx 637 -> 601; commands-mode.ts +84. Verification: typecheck 8/8, eslint clean on both files, targeted tests 394 pass / 2 pre-existing dev-base failures (command-prepend, path-b-integration: isPromptEqual-not-found bun ESM load-order flake; neither imports the changed files, zero regression). Independent review (codex, xhigh) GATE PASS, no P1/P2: confirmed byte-faithful logic, no construction-time TDZ on the thunk, owner-scoped registration preserved, reactivity preserved, imports correct, order unchanged. No review threads raised. Residual risk: none — pure extraction. The file-picker fallback hits native platform.openFilePickerDialog, but that code is unchanged.
…ffect.ts (#1093) Slice 3 of the serial prompt-input.tsx slimming line (slice 1 = #1083, slice 2 = #1091). Pure extraction, no behavior/DOM/aria/copy/storage-key change. Change boundary: - New prompt-input/edit-load-effect.ts exposing createEditLoadEffect(deps): sets up the deferred createEffect that loads an edit/followup draft into the editor (keyed on props.edit?.id). Returns void. - prompt-input.tsx calls the factory synchronously at the effect's original position, so it registers in the component owner with { defer: true } intact and no ordering change. All deps (prompt, setStore, editorRef getter, queueScroll, editDraft, onEditLoaded) are available there — no late-binding. Injection seams (the only textual changes): - props.edit -> editDraft (accessor () => props.edit); the on() source () => editDraft()?.id still tracks props.edit?.id, so reactivity is unchanged. - editorRef.focus() -> editorRef().focus(); setCursorPosition(editorRef, ...) -> setCursorPosition(editorRef(), ...) (editorRef injected as a getter). - props.onEditLoaded?.() -> onEditLoaded() (injected thunk wrapping the optional call; fire timing preserved — synchronously after scheduling the rAF). The 7 copied context fields, the four setStore calls, prompt.set, and the rAF block are verbatim. props.edit / props.onEditLoaded are used only by this effect. prompt-input.tsx 601 -> 572; edit-load-effect.ts +63. Verification: typecheck 8/8, eslint clean on both files, targeted tests 404 pass / 2 pre-existing dev-base failures (command-prepend, path-b-integration: these deterministically fail locally because they value-import prompt.tsx which loads @solidjs/router, a client-only module that throws in bun's server test env without a router mock — neither imports the changed files, zero regression; a standalone fix PR is queued next). Independent review (codex, xhigh) GATE PASS, no P1/P2: byte-faithful effect body, equivalent reactivity, preserved defer, owner-scoped registration, correct imports. Residual risk: none — pure extraction.
Summary
Slice 1 of the prompt-input.tsx component-slimming line (continuation of the #1066 submit.ts/question-dock line, same
prompt-input/family). Pure extraction, no behavior change.Moves the 12 read-only derived memos out of the
PromptInputcomponent into a newprompt-input/derived-state.tsfactorycreatePromptDerivedState(deps):info,status,working,imageAttachments,actionReady,abortReadycommentCount,blank,stopping,contextItems,placeholder,acceptingThe factory takes injected deps (
store,prompt,sync,sdk,permission,language,activeSessionIDaccessor, andactionReadyProp/abortReadyPropthunks wrappingprops.actionReady?.()/props.abortReady?.()). Logic moved byte-faithfully;actionReady = actionReadyProp() ?? trueandabortReady = abortReadyProp() ?? actionReady()preserved. Removed now-unused imports (isWorkInFlightStatus,promptPlaceholder,ImageAttachmentPart).prompt-input.tsx: 659 -> 638 lines.Test plan
bun run typecheck— 8/8 successfulbun test src/components/prompt-input— 382 pass, 2 fail identical to clean dev base (pre-existingcommand-prepend/path-b-integrationenv failures, unrelated)eslintclean on both changed production files/codex review— no P1/P2Summary by CodeRabbit