Skip to content

feat(code): dedicated Codex-style Code surface behind NEXT_PUBLIC_CAVE_CODE_SURFACE#3716

Merged
BunsDev merged 1 commit into
mainfrom
feat/code-surface-mode
Jul 23, 2026
Merged

feat(code): dedicated Codex-style Code surface behind NEXT_PUBLIC_CAVE_CODE_SURFACE#3716
BunsDev merged 1 commit into
mainfrom
feat/code-surface-mode

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 23, 2026

Copy link
Copy Markdown
Member

What

Phase 1 of the dedicated Code surface (bead cave-k0ua): a Codex-style multi-session coding tab, flag-gated by NEXT_PUBLIC_CAVE_CODE_SURFACE. Default-off builds behave byte-identically (GitHub row, legacy code→chat redirect, chat rail untouched).

This consciously reverses the earlier Code-mode retirement on the owner's request; the code-view.test.ts retirement guard is replaced by code-surface-mode.test.ts, whose header documents the sanctioned shape.

Flag on

  • Sidebar's quiet GitHub row becomes a Code row (same slot, same assigned-work badge); GitHub mounts whole as a tab inside the surface.
  • CodeView: Sessions | GitHub top tabs → project-grouped session rail (branch chip, PR badge, +N −N diffstat, worktree mark, activity dot; cave-9q24 attribution rules — never a shared checkout's git.branch) → per-session overview pane with Open in Chat.
  • Deep links: ?mode=code&session=<id>&ctab=<sessions|github> (read-once-then-strip, the ?mode= idiom).

Flag off

  • code deep links keep the retirement-era fallback: cave:navigate-mode → newest repo chat; every other entry (?mode=, persisted last-surface) funnels through a new setMode gate → Chat.

Wiring

  • workspace-mode.ts: code rejoins CanonicalWorkspaceMode (github stays canonical this phase; alias conversion happens at flag-default-on).
  • FOLDER_MODES: conditional spread inside the single literal, so palette / mobile tabs / canonical-name extraction keep deriving from one source. Row type extracted as FolderModeRow for the spread's contextual typing.
  • lazy-surfaces.tsx: CodeView code-split; GitHubView chunk stays separate inside CodeView (local dynamic(), avoids a lazy-surfaces cycle).
  • code-surface.ts: pure model — rail grouping/sorting, badge derivation, tab vocabulary (CODE_WORKBENCH_TABS fixes deep-link names for the upcoming tabs), deep-link parsing — with behavioral tests.

Follow-ups (planned PR series)

Workbench tabs (Diff via SessionChangesInner, Files via ProjectTree+CodeMirror with save, Terminal, PR stage pipeline), inspector (branch/worktrees), composer, new-session flow, mobile drill-in, e2e smoke — then the flagged chat-rail slimming.

Verification

  • pnpm test:app → 891 files ✓; pnpm test:api → 239 ✓; pnpm typecheck ✓; check-tests-wired
  • Targeted pinned suites (canonical-nav-names, sidebar-minimal, palette-canonical-names, workspace-alias-modes, chat-rail-modern-redesign, mobile-shell-smoke, roles-tools-navigation, command-palette, workspace-mode, grimoire-view, session-changes-inner, code-editor) all green under the css-source-contract hook.

…CE (cave-k0ua)

Reintroduces a canonical "code" WorkspaceMode as a Codex-style multi-session
coding surface, consciously reversing the earlier Code-mode retirement on the
owner's request. Flag-gated: default-off builds are byte-identical in behavior
(GitHub row, legacy code->chat redirect, chat rail untouched).

- workspace-mode: "code" rejoins CanonicalWorkspaceMode (github stays canonical)
- feature-flags: caveCodeSurface() reads NEXT_PUBLIC_CAVE_CODE_SURFACE
- sidebar: flag swaps the quiet GitHub row for a Code row (conditional spread
  keeps FOLDER_MODES one literal for palette/mobile/canonical-name derivation)
- workspace: WORKSPACE_MODE_TITLES.code, lazy CodeView render branch, flag-off
  gates in both the cave:navigate-mode redirect and the setMode funnel
- CodeView shell: Sessions|GitHub top tabs, project-grouped session rail with
  per-session branch/PR/diffstat/worktree badges (cave-9q24 attribution rules),
  session overview pane, GitHubView mounted whole under the GitHub tab
- code-surface.ts: pure model (grouping, badges, deep-link parse) w/ behavioral
  tests; code-view.test.ts retirement guard replaced by code-surface-mode.test.ts
  pin suite documenting the sanctioned reversal

Workbench tabs (Diff/Files/Terminal/PR), inspector, composer, and new-session
flow land in follow-up PRs; CODE_WORKBENCH_TABS already fixes their deep-link
vocabulary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 18:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Codex-style Code workspace surface, flag-gated behind NEXT_PUBLIC_CAVE_CODE_SURFACE, reintroducing "code" as a canonical workspace mode while preserving the legacy “code → chat” fallback when the flag is off.

Changes:

  • Re-add "code" to workspace mode vocabulary and route "code" requests through a new setMode gate when the flag is off.
  • Introduce the Code surface shell (CodeView, CodeSessionRail) plus a pure, testable model in src/lib/code-surface.ts (grouping, badges, deep-link parsing).
  • Swap the quiet sidebar row between GitHub and Code based on the flag; move GitHub into CodeView as a top tab; update pin suites and test wiring.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/lib/workspace-mode.ts Reintroduces "code" in canonical workspace modes.
src/lib/workspace-mode.test.ts Updates mode-vocabulary guard test to stop treating "code" as retired.
src/lib/feature-flags.ts Adds caveCodeSurface() feature flag helper.
src/lib/code-surface.ts New pure model for Code surface (tabs, grouping, deep-link parsing, badges).
src/lib/code-surface.test.ts Behavioral tests for code-surface model helpers.
src/components/workspace.tsx Adds Code mode title/render branch; gates "code" mode to Chat when flag is off; keeps legacy navigate-mode redirect when flag is off.
src/components/sidebar-minimal.tsx Implements Code⇄GitHub quiet-row swap via conditional spread under caveCodeSurface().
src/components/lazy-surfaces.tsx Adds lazy-loaded CodeView surface chunk.
src/components/code-view.tsx New Code surface shell with Sessions/GitHub tabs and per-session overview.
src/components/code-view.test.ts Removes the prior retirement-guard pin suite.
src/components/code-surface-mode.test.ts New pin suite documenting the sanctioned flag-gated Code surface shape.
src/components/code-session-rail.tsx New Code surface session rail UI (project-grouped, badges, selection).
src/components/chat-rail-modern-redesign.test.ts Updates pin to reflect flag-off-only code deep-link redirect.
scripts/run-tests.mjs Rewires app test suite list to the new pin suite + new model tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/code-surface.ts
* behavioral tests for pure logic, source pins for wiring).
*/

import type { SessionRow } from "@/lib/types";
Comment thread src/lib/code-surface.ts
Comment on lines +42 to +46
export function isCodeRailSession(row: SessionRow): boolean {
if (row.archived_at) return false;
if (row.generated) return false;
return true;
}
Comment on lines +56 to +58
export function CodeSessionRail({ sessions, selectedId, onSelect }: CodeSessionRailProps) {
const groups = groupCodeRailSessions(sessions);
if (groups.length === 0) {
@BunsDev
BunsDev merged commit 31b3579 into main Jul 23, 2026
16 checks passed
BunsDev added a commit that referenced this pull request Jul 23, 2026
Phase 2 of the Code surface (cave-k0ua, follows #3716). Replaces the
read-only session overview pane with a real per-session workbench:

- code-workbench.tsx — header (familiar, branch/PR/diffstat chips, Open
  in Chat) + Diff | Files | Terminal tab strip. All tabs scope to
  codeSessionWorkRoot (worktree over shared checkout, cave-9q24).
- Diff tab: SessionChangesInner keyed by work root — diffs, commit,
  create-PR, checkpoints, revert (proven panel, reused whole).
- Files tab: new code-workbench-files.tsx composition — ProjectTree +
  RailFilePreview (CodeMirror editing + Cmd/Ctrl+S save included);
  dynamic() so CodeMirror stays out of the surface chunk.
- Terminal tab: RailTerminalPanel, lazy + keepalive once opened; same
  pty thread as chat's rail terminal by design (cave.rail.<sessionId>).
- code-surface.ts: codeSessionWorkRoot moved into the pure model with
  behavioral tests; workbench wiring pinned in code-surface-mode.test.ts.

Deep link ?wtab= now lands on real tabs ('pr' still coerces to diff
until the PR panel tab ships). Chat rail untouched.

Verified: pnpm test:app (891), test:api (239), typecheck all green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BunsDev added a commit that referenced this pull request Jul 23, 2026
…3722)

Phase 3 of the Code surface (cave-k0ua, follows #3716/#3719). The
workbench's reserved 'pr' tab becomes real:

- code-session-pr-panel.tsx — stage strip (bead → PR → checks → review
  → merged) via the SAME resolveStageForBranch the work queue and chat
  stage header use, anchored to codeSessionBranch (attributed branch,
  cave-9q24 — never the checkout's current branch).
- Live check runs (/api/github/checks, 30s re-poll while pending) with
  pass/fail counts and details links.
- Review threads (/api/github/comments?isPull=1) with resolve/unresolve
  (POST /api/github/resolve-thread), authed-gated.
- Actions: comment / approve (POST /api/github/review) and squash-only
  merge (POST /api/github/merge) behind a two-click confirm.
- No-PR state points at the Diff tab's Create PR flow.
- Workbench: 'pr' deep-link coercion removed — ?wtab=pr now lands here;
  tab strip gains PR; panel dynamic() + keyed by session id.

Pins: PR-panel wiring added to code-surface-mode.test.ts (stage-model
reuse, attributed branch, API surface, squash-only, confirm-gated merge).

Verified: pnpm test:app (892), test:api (239), typecheck, eslint green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BunsDev added a commit that referenced this pull request Jul 23, 2026
Phase 4 of the Code surface (cave-k0ua, follows #3716/#3719/#3722):
the surface goes from read-only to generative.

- code-composer.tsx — Codex-style 'Ask for follow-up changes' box under
  every workbench tab except Terminal. Sends through the sanctioned
  client LLM path (streamFamiliarText → /api/chat/send) RESUMING the
  selected session (sessionId rides), rooted at codeSessionWorkRoot
  (cave-9q24). Streams a compact reply tail with 'Full thread in Chat';
  Stop cancels via /api/chat/stop with the send's runId.
- code-new-session.tsx — '+ New session' modal: project + familiar
  pickers (/api/projects, /api/familiars), optional FRESH worktree
  (existing /api/changes action=create-worktree → .worktrees/<branch>),
  kickoff prompt. The send carries no sessionId (fresh thread, saved
  like any chat); onSession hands the id to the rail immediately while
  the stream keeps flowing server-side.
- code-session-rail.tsx — + New session entry (also in empty state).
- code-view.tsx — pendingNewIdRef guard: a just-created session's
  selection survives until /api/sessions/list catches up (the newest-
  session auto-pick must not clobber it).

Pins added for all of the above in code-surface-mode.test.ts.

Verified: pnpm test:app (892), test:api (239), typecheck, eslint green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@BunsDev
BunsDev deleted the feat/code-surface-mode branch July 23, 2026 22:52
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.

2 participants