Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ Update corresponding Docs in [CrewCode Docs](/docs/), and [AGENTS.md](/AGENTS.md

## Agent Notes

Mobile window tabs use the bottom workspace dock's Tabs button and an on-demand
sheet; never reserve a top tab-strip row on phones. Preserve exact tab selection,
observed activity, pinned-tab close protection, built-in/plugin new-tab actions,
and dismiss-on-selection. Desktop retains its tab strip. Mobile overlay offsets
must not reserve the former 40px strip. See `docs/mobile-responsive-pages.md`.


Claude effort menus include Off, Adaptive, Low, Medium, High, XHigh, and Max.
Adaptive is a Claude-only UI selection: omit SDK `effort` and `thinking` so
Claude Code retains its environment/settings/model resolution. Off explicitly
disables thinking; named levels pass through as SDK effort values. Keep the
session, crew, desktop/web, and SSH contracts aligned. See `docs/reasoning-effort.md`.

The context usage meter must prefer the active provider's reported full context
window over model-catalog metadata and static limits. Codex app-server usage
reports `modelContextWindow` as an effective prompt budget; when a known full
Expand Down Expand Up @@ -374,8 +387,20 @@ Brain catalogue without replacing genuine identities the Brain already owns, onc
desktop catalogue authority exists. An explicit Background Brain enable is a new
owner-observed handoff: before the enable-triggered reload, seed the exact foreground
desktop chat/session catalogue even when an older authority marker exists. Reconcile
the current desktop workspace registry first for matching ids/paths and preserve
genuine Brain-only/browser-created workspaces. Until that marker is present, or while
the current desktop workspace registry first for matching ids/paths. Preserve only
Brain-only/browser-created workspaces whose observed creation time is newer than the
desktop registry; never resurrect older entries missing from the current desktop list.
Treat explicit Background Brain enable as an audited owner-local grant of each exact
existing registered local project path, preserving scopes and never granting a broader
parent; standalone Brain remains explicit-root-only and SSH stays desktop-only. Attached
Electron must read the exact native registry. Brain/browser catalogue reads may expose
registered metadata outside current roots as locked rows, but every content or execution
operation still requires the existing scope, registered-workspace, and live-root gates.
Never relay device-local project icon data in the workspace catalogue. Keep individual
encrypted Hub frames within the existing 8 MiB connection-burst ceiling and preflight
Brain output so an oversized RPC result closes only its logical browser tunnel, not the
machine relay.
Until that marker is present, or while
the Brain still contains transcript-derived recovered rows, Electron reseeds the exact desktop
names, active selection, tab-key order, and per-tab session order; drop unmatched
recovered navigation rows while preserving transcript shards, and retain genuine
Expand Down Expand Up @@ -452,6 +477,12 @@ The composer PromptPicker has separate Prompts and Skills tabs backed by the sha

On phones, Code Editor keeps the code canvas primary and opens its file tree as a dismissible right overlay. Git Sidebar must remain the same stateful surface on desktop and mobile, becoming an off-canvas panel with backdrop/close controls instead of being hidden or squeezing chat/editor content. Changes by turn is a full-screen mobile review: its catalogue stacks above the diff when open, while a targeted changed-file route keeps the catalogue closed. Keep all JS/CSS decisions aligned at `≤768px`; see `docs/mobile-responsive-pages.md`.

Mobile/Hub typography must honor the live chat `--mono-size` and CodeMirror
`--editor-size` settings. Keep the composer at `max(16px, --mono-size)` to prevent
iOS focus zoom without blocking larger user-selected text, and keep the editor size
authoritative over CodeMirror's runtime-injected theme. See
`docs/mobile-responsive-pages.md`.

The Code Editor file tree is lazy and must expose dependency, build-output, cache,
and workspace-local Python environment folders on demand for local and SSH roots.
Keep `.git` and `.DS_Store` hidden from direct browsing. Do not widen bounded
Expand Down Expand Up @@ -502,7 +533,7 @@ CrewCoder `crew-tasks` activity remains provider-owned and optional. Preserve th

YuHeard PTY integration must remain bundle-safe. `PtyService` receives the active YuHeard server through an injected accessor and statically imports its shell-wrapper helpers; do not use runtime relative `require('./yuheard-*')` calls from PTY code because electron-vite can move that code into a chunk without emitting the required sibling modules. CLI launch, initial TUI paint, and prompt submission are not completed turns. Codex must use only its exact `approval-requested` and `agent-turn-complete` hook events—never generic PTY idle/BEL heuristics—while output fallback detection remains available for agents without an exact hook. Suppress every YuHeard surface only when the exact completing terminal owns keyboard focus in the focused CrewCode window; a different pane must still alert. See `docs/yuheard.md`.

CrewCoder agent profiles are separate from CrewCode execution modes. Show the desktop model-row profile picker only when the installed CrewCoder provider is active; disable it during a running turn, persist the optional session-scoped `crewcoderMode`, omit `--mode` for Configured default, and pass only `general | crewcoder | plugin | extension` to `crewcoder acp --mode`. A concrete profile locks the underlying CrewCode permission policy to Build and disables Ask/Plan/Build/Full on desktop and phone; Configured default re-enables those controls. Never retain a hidden prior Ask, Plan, or Full Access policy under a concrete profile. When the concrete `crewcoder` profile is active, show the separate desktop approval picker and persist `crewcoderApprovalMode`; expose only CrewCoder's `review`, `always`, `never`, `full-access`, and `sandboxed` values, with `review` as the fail-closed default. Treat approval changes as immutable launch authority: disable them during a running turn, drop only the idle bridge, include the value in custody, and native-resume on the next prompt. Never suppresses prompts but continues to block dangerous calls; Sandboxed applies the native sandbox policy where supported; Full access bypasses CrewCoder approval requests and dangerous-command blocking, so label that risk truthfully and never imply CrewCode Build still interposes. Never route Ask/Plan/Build/Full into CrewCoder's `--mode`. The `crewcoder` profile's plan gate is CrewCoder-owned: project `crewcoder_clarify` / `crewcoder_propose_plan` into the activity overlay and send `/approve-plan` as a prompt, never as a tool-permission Allow/Deny. See `docs/crewcoder-provider.md`.
CrewCoder agent profiles are separate from CrewCode execution modes. Show the desktop model-row profile picker only when the installed CrewCoder provider is active; disable it during a running turn, persist the optional session-scoped `crewcoderMode`, omit `--mode` for Configured default, and pass only `general | crewcoder | plugin | extension` to `crewcoder acp --mode`. A concrete profile locks the underlying CrewCode permission policy to Build and disables Ask/Plan/Build/Full on desktop and phone; Configured default re-enables those controls. Never retain a hidden prior Ask, Plan, or Full Access policy under a concrete profile. When the installed CrewCoder provider is active, show the separate desktop approval picker across general, crewcoder, plugin, extension, and Configured default; persist `crewcoderApprovalMode` independently of profile changes and honor it at launch in every profile; expose only CrewCoder's `review`, `always`, `never`, `full-access`, and `sandboxed` values, with `review` as the fail-closed default. Treat approval changes as immutable launch authority: disable them during a running turn, drop only the idle bridge, include the value in custody, and native-resume on the next prompt. Never suppresses prompts but continues to block dangerous calls; Sandboxed applies the native sandbox policy where supported; Full access bypasses CrewCoder approval requests and dangerous-command blocking, so label that risk truthfully and never imply CrewCode Build still interposes. Never route Ask/Plan/Build/Full into CrewCoder's `--mode`. The `crewcoder` profile's plan gate is CrewCoder-owned: project `crewcoder_clarify` / `crewcoder_propose_plan` into the activity overlay and send `/approve-plan` as a prompt, never as a tool-permission Allow/Deny. See `docs/crewcoder-provider.md`.

CrewCoder manual compaction is capability-gated. Expose the bridge `compact()` path only after observing exact `initialize._meta["crewcoder/sessionCompact"].method === "session/compact"`; older CrewCoder versions retain summary-reset. Call the advertised method only while idle and keep CrewCoder's durable session id and ACP child after success. Use the returned summary to replace CrewCode's replay shard and add the visible compact-summary card while retaining the full rich display transcript. Treat `_crewcoder/compaction_update` as authoritative, never infer a duplicate from usage, never fabricate a turn for idle progress, and do not clear usage/replay when the provider reports a skipped compact. See `docs/crewcoder-provider.md` and `docs/conversation-storage.md`.

Expand Down
14 changes: 9 additions & 5 deletions docs/crewcoder-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

CrewCoder is a first-class CrewCode chat and Crew provider implemented by
`src/main/agents/crewcoder-bridge.ts`. CrewCode is the ACP **client**: it spawns
`crewcoder acp --approval review`, optionally adding a selected CrewCoder
`crewcoder acp --approval <policy>` (defaulting to `review`), optionally adding a selected CrewCoder
`--mode`, and translates newline-delimited JSON-RPC 2.0 onto the shared
`AgentBridge` event stream. CrewCoder remains the ACP agent.

Expand Down Expand Up @@ -36,15 +36,17 @@ a turn is running so authority cannot change underneath live execution. It
stays absent for unavailable or inactive providers and from the phone layout,
where the desktop model-row reveal itself is intentionally hidden.

When the concrete **CrewCoder** profile is selected, the row also shows a
session-scoped approval picker with all native policies:
When CrewCoder is the active installed provider, the row also shows a
session-scoped approval picker for **General**, **CrewCoder**, **Plugin**,
**Extension**, and **Configured default**, with all native policies:

- **Review** (`review`) lets safe calls proceed and asks for mutations and dangerous calls.
- **Always** (`always`) asks for every non-safe call.
- **Never** (`never`) shows no prompts while continuing to block dangerous calls.
- **Full access** (`full-access`) accepts calls without prompts.
- **Sandboxed** (`sandboxed`) shows no prompts and runs non-dangerous calls through the sandbox policy where supported.

The selected policy survives profile changes, including Configured default.
Older or invalid persisted values fail closed to Review. Changing the policy
drops only the idle CrewCoder bridge and native-resumes it on the next prompt;
both controls are disabled during a running turn. Full access is an explicit
Expand Down Expand Up @@ -219,8 +221,10 @@ CrewCoder TUI, including active → pending → completed ordering.

## Mode and permission enforcement

CrewCoder always starts with `--approval review`; CrewCode applies the current
composer mode when each `session/request_permission` arrives:
CrewCoder starts with the session's selected `--approval` policy in every agent
profile, defaulting to `review`. CrewCode applies the current composer mode
when a `session/request_permission` arrives; policies that emit no request
bypass this permission overlay:

| CrewCode mode | Decision |
| --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion docs/current-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Queued follow-up messages are also session-scoped. There is exactly ONE follow-u

Composer execution modes are `ask | plan | build | full`, where `full` is displayed as **Full Access**. A mode has an optional prompt preamble (`buildModePreamble`) **plus** a real per-provider permission policy; the preamble is advisory, not enforcement. Settings customizes the shared prompt text, while `Session.modePromptsEnabled` controls injection per Solo Chat from `ChatHeader`; it defaults true, copies on duplicate, and locks after startup context is sent because provider context cannot be revoked. Disabling it must never weaken provider-native permission policy, and skills/delegation context must still be delivered. Build approvals may grant **allow all (this turn ONLY)** only through main-issued `{bridgeId, turnId}` capability state: approve the current and later permission requests in that turn, clear on every turn/bridge termination boundary, and never use provider-native remembered choices that could outlive the turn. The wire value is `'full'` (renamed from `'yolo'`), the display token is `Mode` = `'Full'`, and the label is `MODE_LABEL` = `'Full Access'`. Because the wire value changed, persisted sessions and `defaultMode` can still hold `'yolo'`, so every read of a persisted mode goes through `normalizeModeLevel()` (`yolo` -> `full`, unknown -> `build`) — an unrecognized level returns `undefined` from `MODE_FROM_SETTINGS`, which crashes the composer mode picker and prepends a literal "undefined" to the prompt. Full Access means every tool is pre-approved: Claude uses `bypassPermissions`, Codex uses `workspace-write` + `never` approvals (deliberately NOT `danger-full-access` — worktree isolation stays), pi/hermes/CrewCoder auto-accept permission requests, and agents must never ask for tool permission. `toolPolicy: 'read-only'` always overrides the mode, so supervisor and completion bridges stay read-only even in Full Access, and real `AskUserQuestion` prompts still surface. See `docs/execution-modes.md`.

Reasoning effort choices are provider-native: Claude exposes `off/low/medium/high/xhigh/max`; Codex exposes `off/low/medium/high/xhigh/max/ultra`; other providers expose `off/low/medium/high/xhigh`. Claude `off` must explicitly disable SDK thinking, and its named levels map to SDK `effort`. Codex `xhigh/max/ultra` must pass through app-server unchanged rather than silently downgrade. Codex Ultra's automatic delegation is upstream provider behavior—CrewCode does not emulate it. See `docs/reasoning-effort.md`.
Reasoning effort choices are provider-native: Claude exposes `off/adaptive/low/medium/high/xhigh/max`; Codex exposes `off/low/medium/high/xhigh/max/ultra`; other providers expose `off/low/medium/high/xhigh`. Claude `off` must explicitly disable SDK thinking; `adaptive` omits both SDK `effort` and `thinking` to retain Claude Code's settings/model resolution, and its named levels map to SDK `effort`. Codex `xhigh/max/ultra` must pass through app-server unchanged rather than silently downgrade. Codex Ultra's automatic delegation is upstream provider behavior—CrewCode does not emulate it. See `docs/reasoning-effort.md`.

## Claude SDK Global skills isolation

Expand Down
20 changes: 18 additions & 2 deletions docs/desktop-web-continuity.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ session and provider.

Every explicit enable also reconciles the current desktop workspace registry into the
Brain before attachment: current desktop entries and ordering win for matching ids or
paths, while genuine browser-created workspaces are retained. Immediately after the
paths. A Brain-only workspace is retained only when its observed creation time is newer
than the current desktop registry; older missing entries are treated as intentionally
removed and are not resurrected. The same explicit local enable auditably adds each
existing registered local project as an exact Brain authorization root while preserving
the current scopes; it never grants a broader parent or adds a scope. SSH workspaces
remain desktop-only. Immediately after the
Brain attaches, but before Electron reloads, the foreground renderer sends its exact
current chat/session and workspace-tab catalogue through the owner-loopback desktop
control. This enable-time handoff supersedes an older persisted authority marker, so a
Expand All @@ -97,12 +102,23 @@ After attachment, the Brain store is authoritative for:
- the workspace-tab and chat-session catalogue needed to find the same threads on
another client.

Attached Electron continues to read the exact native desktop workspace catalogue so
Brain attachment cannot hide local or SSH projects. Brain/browser `workspaces.list`
returns that same registered catalogue after `workspace:read` is granted. Rows outside
the currently authorized roots remain visible as **Authorize** and SSH rows as
**Desktop**; they cannot be opened and no filesystem, Git, terminal, or agent operation
may cross the existing root gate.
Project icon data remains device-local and is omitted from relayed workspace catalogues
so several large icons cannot disconnect the Brain during browser startup. Relay frames
are bounded to the Hub's existing 8 MiB connection-burst budget; Brain rejects an
oversized result on only the affected logical tunnel before it reaches the Hub.

Each renderer still uses localStorage as a bounded paint/navigation cache. At startup,
it hydrates the catalogue plus bounded recent tails for active and locally cached
conversation scopes from the Brain. A cold conversation hydrates its own bounded tail
when opened. Each remote scope tail is capped at 96 KiB; the 32-scope startup window
therefore stays below 3 MiB of transcript plaintext and leaves encryption and other
startup RPCs headroom inside the Hub's shared 8 MiB relay burst. Full shards remain
startup RPCs headroom inside the Hub's shared 8 MiB relay burst and frame ceiling. Full shards remain
authoritative on the Brain. The renderer never requests `transcripts.loadAll` over the
Brain/Hub relay: combining a large transcript store into one encrypted frame can exceed both
the relay frame limit and the JavaScript string limit. Full per-scope shards remain
Expand Down
22 changes: 21 additions & 1 deletion docs/mobile-responsive-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ treat `≤768px` as mobile. The renderer is shared by direct `crewcode serve` an
Hub-relayed browser sessions; responsive work must not fork the underlying data
or privileged client paths.

## Window tabs

On phones, the top window-tab strip is replaced by a **Tabs** button and open-tab
count in the existing bottom workspace dock. It opens a scrollable bottom sheet
with the active tab highlighted, observed agent/crew activity, and separate close
buttons. Pinned tabs stay protected from closing. Selecting a tab dismisses the
sheet; **New tab** exposes the same built-in and plugin destinations as desktop.
Escape, the backdrop, the close button, and dragging the handle dismiss the sheet.
Keyboard focus stays within the sheet and returns to its trigger on dismissal.
Desktop retains its existing tab strip. Mobile workspace, Git, and file-tree
overlays start at the top of the viewport without reserving the former 40px strip.

## Typography

Hub/mobile renderers apply the same live chat and Code Editor typography settings
as desktop. Agent replies and user bubbles consume `--mono-size`; the phone composer
uses the selected size with a 16px minimum to prevent iOS focus zoom. CodeMirror's
runtime theme must not override `--editor-size`, including after the editor is already
mounted. These preferences remain browser-device-local and update without a reload.

## Code and Git review

- **Code Editor** keeps the code canvas full width. Tabs and status metadata
Expand All @@ -21,7 +41,7 @@ or privileged client paths.
stack above the diff, menus and branch selection use mobile overlay layers,
and interactive controls/inputs remain touch-sized and iOS-safe.
- **Changes by turn** becomes a full-screen review surface between the mobile
tab bar and workspace dock. With its catalogue visible, turn/file selection
viewport top and workspace dock. With its catalogue visible, turn/file selection
stacks above the diff. Direct changed-file targets keep the catalogue closed
so the selected Pierre diff receives the full viewport.

Expand Down
Loading
Loading