Add provider-backed Side Quest conversations#8282
Conversation
f37a030 to
64adb45
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis change introduces “Side Quest,” enabling provider-owned Codex conversations alongside terminal sessions. It adds app-server communication, session orchestration, IPC and preload APIs, renderer chat views and composers, terminal selection and launch flows, quoted context handling, session persistence, transcript retry behavior, localization, and supporting tests. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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.
Actionable comments posted: 5
🧹 Nitpick comments (5)
docs/reference/plans/2026-07-11-side-quests.md (1)
88-92: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider varying sentence beginnings in Phase 3 bullets.
Three consecutive bullets begin with "Add". Consider rewording for readability, e.g., "Include keyboard access…" or "Introduce telemetry…".
Source: Linters/SAST tools
src/main/side-quest/codex-app-server-jsonl-client.test.ts (1)
59-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSecond rejection assertion is a substring match.
toThrow('exited with code 7')at line 72 would also match'exited with code 7: startup failed', so it doesn't strictly verify that subsequent requests exclude the stderr payload. Consider using a stricter matcher if distinguishing that behavior matters.Otherwise, the test suite is solid — init ordering, routing, exit rejection, invalid JSONL, and timeout termination are all well-covered.
src/main/side-quest/codex-side-quest-manager.ts (1)
85-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument why Side Quests force read-only, non-interactive execution.
These policy values are a security and product boundary; add a brief rationale so future changes do not silently enable writes or approval prompts.
Proposed comment
const result = await connection.request('thread/start', { cwd, + // Why: Side Quests answer questions about workspace state but must + // never mutate it or block the conversation on approval prompts. approvalPolicy: 'never', sandbox: 'read-only',As per coding guidelines, “When code is driven by a design document or non-obvious constraint, add a brief one- or two-line comment explaining why it behaves that way.”
Source: Coding guidelines
src/renderer/src/components/native-chat/SideQuestQuoteCard.tsx (1)
77-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse approved typography tokens for the quote-card header.
text-[11px]andtracking-[0.05em]introduce arbitrary typography values in renderer UI. Replace them with the documentedmain.css/styleguide tokens, or add a named token if this size is intentional.As per coding guidelines, renderer UI must use documented tokens instead of invented font sizes and styling values.
Source: Coding guidelines
src/renderer/src/lib/start-terminal-side-quest.test.ts (1)
31-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a test case for the provider transport path.
All three tests invoke
beforeOpenChat?.('side-tab')with a single argument, sotransportis alwaysundefinedand only the non-provider branch is exercised. The provider path (transport === 'provider') whereseedNativeChatSideQuestReadinessis intentionally skipped is never verified — and this is the primary path for Codex Side Quests per the PR objectives.🧪 Suggested test for provider transport
it('surfaces a specific runtime-host limitation', () => { mocks.launchSideQuest.mockReturnValue({ status: 'runtime-unsupported' }) startTerminalSideQuest({ worktreeId: 'worktree', sourceGroupId: 'source-group', agent: 'codex', capturedText: 'context', sourceLabel: 'Terminal' }) expect(mocks.toastError).toHaveBeenCalledWith( 'Side Quests are not available in runtime-hosted workspaces yet.' ) }) + + it('skips readiness seeding for provider transport but still seeds context', () => { + mocks.launchSideQuest.mockReturnValue({ + status: 'started', + groupId: 'side-group', + terminalTabId: 'side-tab' + }) + + startTerminalSideQuest({ + worktreeId: 'worktree', + sourceGroupId: 'source-group', + agent: 'codex', + capturedText: 'context', + sourceLabel: 'Terminal' + }) + + mocks.launchSideQuest.mock.calls[0][0].beforeOpenChat?.('side-tab', 'provider') + expect(mocks.seedNativeChatSideQuestReadiness).not.toHaveBeenCalled() + expect(mocks.seedNativeChatSideQuestContext).toHaveBeenCalledWith('side-tab', expect.anything()) + }) })
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7b3d2efd-c50a-4e45-9b36-63330cdae801
📒 Files selected for processing (74)
docs/reference/plans/2026-07-11-side-quests.mdsrc/main/ipc/register-core-handlers.test.tssrc/main/ipc/register-core-handlers.tssrc/main/ipc/side-quest.tssrc/main/native-chat/transcript-read-cache.tssrc/main/native-chat/transcript-reader.tssrc/main/side-quest/codex-app-server-jsonl-client.test.tssrc/main/side-quest/codex-app-server-jsonl-client.tssrc/main/side-quest/codex-app-server-process.tssrc/main/side-quest/codex-app-server-protocol.tssrc/main/side-quest/codex-app-server-test-process.tssrc/main/side-quest/codex-side-quest-manager.test.tssrc/main/side-quest/codex-side-quest-manager.tssrc/main/side-quest/codex-side-quest-native-chat.test.tssrc/main/side-quest/codex-side-quest-native-chat.tssrc/main/side-quest/codex-side-quest-thread-config.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/Terminal.tsxsrc/renderer/src/components/native-chat/NativeChatComposer.tsxsrc/renderer/src/components/native-chat/NativeChatComposerField.tsxsrc/renderer/src/components/native-chat/NativeChatView.tsxsrc/renderer/src/components/native-chat/ProviderSideQuestComposer.tsxsrc/renderer/src/components/native-chat/ProviderSideQuestView.tsxsrc/renderer/src/components/native-chat/SideQuestQuoteCard.test.tsxsrc/renderer/src/components/native-chat/SideQuestQuoteCard.tsxsrc/renderer/src/components/native-chat/native-chat-composer-target.tssrc/renderer/src/components/native-chat/native-chat-side-quest-context-cache.test.tssrc/renderer/src/components/native-chat/native-chat-side-quest-context-cache.tssrc/renderer/src/components/native-chat/native-chat-side-quest-readiness-cache.test.tssrc/renderer/src/components/native-chat/native-chat-side-quest-readiness-cache.tssrc/renderer/src/components/native-chat/native-chat-working-suppression.test.tssrc/renderer/src/components/native-chat/native-chat-working-suppression.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.test.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.tssrc/renderer/src/components/native-chat/use-native-chat-side-quest-context.test.tsxsrc/renderer/src/components/native-chat/use-native-chat-side-quest-context.tssrc/renderer/src/components/native-chat/use-native-chat-toggle-shortcut.tssrc/renderer/src/components/native-chat/use-provider-side-quest-session.tssrc/renderer/src/components/tab-bar/TabBar.tsxsrc/renderer/src/components/terminal-pane/TerminalContextMenu.test.tsxsrc/renderer/src/components/terminal-pane/TerminalContextMenu.tsxsrc/renderer/src/components/terminal-pane/TerminalPane.tsxsrc/renderer/src/components/terminal-pane/TerminalPaneOverlayLayer.tsxsrc/renderer/src/components/terminal-pane/TerminalSideQuestMenuItem.tsxsrc/renderer/src/components/terminal-pane/TerminalSideQuestSelectionAction.test.tsxsrc/renderer/src/components/terminal-pane/TerminalSideQuestSelectionAction.tsxsrc/renderer/src/components/terminal-pane/terminal-side-quest-selection.test.tssrc/renderer/src/components/terminal-pane/terminal-side-quest-selection.tssrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/lib/agent-paste-draft.tssrc/renderer/src/lib/launch-agent-in-new-tab.test.tssrc/renderer/src/lib/launch-agent-in-new-tab.tssrc/renderer/src/lib/launch-side-quest.test.tssrc/renderer/src/lib/launch-side-quest.tssrc/renderer/src/lib/side-quest-agent.test.tssrc/renderer/src/lib/side-quest-agent.tssrc/renderer/src/lib/side-quest-context.test.tssrc/renderer/src/lib/side-quest-context.tssrc/renderer/src/lib/start-terminal-side-quest.test.tssrc/renderer/src/lib/start-terminal-side-quest.tssrc/renderer/src/lib/workspace-session.test.tssrc/renderer/src/store/slices/terminal-side-quest-session.test.tssrc/renderer/src/store/slices/terminals-hydration.test.tssrc/renderer/src/store/slices/terminals.tssrc/shared/side-quest-runtime-types.tssrc/shared/side-quest-types.tssrc/shared/types.tssrc/shared/workspace-session-schema.test.tssrc/shared/workspace-session-schema.ts
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e12a273a-1072-4694-b77c-bbbadee705f3
📒 Files selected for processing (15)
docs/reference/plans/2026-07-11-side-quests.mdsrc/main/ipc/side-quest.test.tssrc/main/ipc/side-quest.tssrc/main/side-quest/codex-app-server-jsonl-client.test.tssrc/main/side-quest/codex-side-quest-manager.tssrc/renderer/src/components/Terminal.tsxsrc/renderer/src/components/terminal-pane/TerminalPane.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/lib/agent-paste-draft.test.tssrc/renderer/src/lib/agent-paste-draft.tssrc/renderer/src/lib/start-terminal-side-quest.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/reference/plans/2026-07-11-side-quests.md
🚧 Files skipped from review as they are similar to previous changes (11)
- src/renderer/src/components/Terminal.tsx
- src/renderer/src/lib/agent-paste-draft.ts
- src/main/side-quest/codex-app-server-jsonl-client.test.ts
- src/renderer/src/i18n/locales/es.json
- src/renderer/src/i18n/locales/ko.json
- src/renderer/src/i18n/locales/ja.json
- src/renderer/src/components/terminal-pane/TerminalPane.tsx
- src/main/ipc/side-quest.ts
- src/renderer/src/i18n/locales/en.json
- src/main/side-quest/codex-side-quest-manager.ts
- src/renderer/src/i18n/locales/zh.json
Summary
Add Side Quests, a way to ask questions about terminal output in a separate native-chat pane without interrupting the terminal or its active agent.
codex app-serverprocess for local Codex Side Quests instead of launching a hidden TUI for every question.The product inspiration is Cursor's Side Chat feature: Cursor announcement on X. Orca's implementation uses its existing worktree split model and a provider-backed native conversation, under the name Side Quests.
The performance motivation was the previous 22–25 second hidden-TUI/MCP startup path. A real local provider smoke test for this implementation produced a thread in 241 ms, the first response delta at 3.0 seconds, and turn completion at 3.9 seconds.
Contributor X: @gatsby74
Screenshots
Side.Quest.mp4
Testing
pnpm lintpnpm typecheckpnpm test— Node 24: 2,690 files / 28,185 tests passed; 5 files / 39 tests skippedpnpm buildAI Review Report
The AI review traced terminal selection through split creation, provider-thread persistence, IPC/preload transport, live message reconciliation, interruption, cleanup, and restored-session reads.
metaKey, separator, or platform-specific shortcut label was introduced.No blocking review issue remains. Interactive validation was performed on macOS; Linux/Windows behavior is covered by shared code paths, typecheck, unit tests, and production builds rather than manual UI runs.
Security Audit
sandbox: read-onlyandapprovalPolicy: never; inherited MCP servers and built-in apps are disabled.Follow-up security work is only needed when enabling direct provider transport on SSH/runtime hosts; that should preserve the same sandbox, capability-disable, and ownership boundaries.
Notes
@-mentioning a Side Quest back into the main conversation, persisted unsent quote context, history/rename/archive UI, and direct-provider parity beyond local Codex.