command-code 1.47.0 → 1.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,8 +1,15 @@
1
1
  # command-code
2
2
 
3
+ ## 1.47.1
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: improve provider/model config handling
8
+
3
9
  ## 1.47.0
4
10
 
5
11
  - fix: mark Grok 4.6 as vision-capable
12
+ - feat: read_file reads Word, PowerPoint, Excel, OpenDocument, RTF, EPUB and PDF files as Markdown, windowed like text, in single and multi-file reads; a scanned PDF names its image-only pages and the pdftoppm command to render them. The converter installs into the user cache on the first document read instead of shipping with the CLI.
6
13
 
7
14
  ## 1.46.0
8
15
 
@@ -10,7 +17,6 @@
10
17
 
11
18
  - feat: auto compact improvements
12
19
  - feat: Add browser sign in through local callback server
13
- - feat: read_file now reads documents. Word, PowerPoint, Excel, OpenDocument, RTF, EPUB and PDF files are extracted to Markdown.
14
20
 
15
21
  ## 1.45.0
16
22
 
@@ -6,7 +6,7 @@ BYOK is currently in beta and subject to improvements.
6
6
 
7
7
  Bring your own provider and use it in Command Code CLI. Any OpenAI or Anthropic compactible API can serve models in Command Code. You can bring your key from hosted providers (DeepSeek, OpenRouter, Vercel AI Gateway), local servers (Ollama, vLLM), or other coding agent's APIs.
8
8
 
9
- ## BYOK Providers
9
+ ## BYOK providers
10
10
 
11
11
  You can connect to any external provider in Command Code, requests go straight from your machine to that provider's endpoint with your key, never through Command Code's servers.
12
12
 
@@ -286,7 +286,7 @@ or persist it in `~/.commandcode/config.json`:
286
286
 
287
287
  What it guarantees:
288
288
 
289
- - **No telemetry, anywhere.** Trace exporters, lifecycle events, telemetry identity, and machine fingerprinting are all off. (`DO_NOT_TRACK=1` also stops all of these, including fingerprinting; local-only additionally blocks the non-telemetry backend traffic below.)
289
+ - **No telemetry, anywhere.** Trace exporters, lifecycle events, telemetry identity, and machine fingerprinting are all off. (`DO_NOT_TRACK=1` also stops all of these, including fingerprinting; local-only also blocks the non-telemetry backend traffic below.)
290
290
  - **No billing reads.** The plan/credits prefetches never run; model pickers treat the absent plan as unrestricted and your providers gate access themselves.
291
291
  - **A refusal transport.** The session's backend transport is replaced with one that throws a clear `LocalOnlyError` naming the route and the switch. Nothing can reach Command Code including a model id that would otherwise fall through to the Command Code provider.
292
292
 
@@ -16,7 +16,7 @@ Type `/` at the start of the input to open the command menu:
16
16
 
17
17
  ---
18
18
 
19
- ## Built-in Commands
19
+ ## Built-in commands
20
20
 
21
21
  Every built-in command, grouped by area. Aliases are shown in parentheses on the canonical command; optional arguments in `[brackets]`, alternatives separated by `|`.
22
22
 
@@ -39,7 +39,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
39
39
  | `/exit` (`/quit`) | Exit Command Code |
40
40
  | `/reload` | Restart Command Code and resume this session (applies a staged update) |
41
41
 
42
- ### Context & Compaction
42
+ ### Context & compaction
43
43
 
44
44
  | **Command** | **Description** |
45
45
  | --------------- | -------------------------------------------- |
@@ -49,7 +49,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
49
49
  | `/memory` | Manage Command Code memory |
50
50
  | `/init` | Initialize AGENTS.md for this project |
51
51
 
52
- ### Modes & Planning
52
+ ### Modes & planning
53
53
 
54
54
  | **Command** | **Description** |
55
55
  | ------------------------------------ | ---------------------------------------------------------------------------------- |
@@ -71,7 +71,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
71
71
  reachable through the explicit `--yolo` launch flag, which also adds it to
72
72
  the shift+tab mode cycle.
73
73
 
74
- ### Models & Providers
74
+ ### Models & providers
75
75
 
76
76
  | **Command** | **Description** |
77
77
  | ----------------- | ---------------------------------------------------------------------------------------- |
@@ -81,7 +81,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
81
81
  | `/login` | Log in to Command Code or a provider |
82
82
  | `/logout` | Log out of Command Code or a provider |
83
83
 
84
- ### Extensibility & Integrations
84
+ ### Extensibility & integrations
85
85
 
86
86
  | **Command** | **Description** |
87
87
  | -------------------------------------------------- | --------------------------------------------------------------------------------- |
@@ -102,7 +102,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
102
102
  | `/add-dir <directory>` | Add directory to workspace context |
103
103
  | `/worktree [name\|list\|remove <name>]` | Create, list, or switch git worktrees |
104
104
 
105
- ### Billing & Account
105
+ ### Billing & account
106
106
 
107
107
  | **Command** | **Description** |
108
108
  | ----------- | -------------------------------------------- |
@@ -122,7 +122,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
122
122
  | `/changelog [all]` | See what's new in Command Code (`all` for the full history) |
123
123
  | `/learn` | Open the Command Code learn hub in your browser |
124
124
  | `/update` | Update Command Code to the latest version |
125
- | `/feedback [title]` (alias `/issue`) | Report a bug or share feedback — opens a prefilled GitHub issue |
125
+ | `/feedback [title]` (alias `/issue`) | Report a bug or share feedback; opens a prefilled GitHub issue |
126
126
  | `/trace` | Copy the current trace id; required for support debugging |
127
127
  | `/copy` | Copy the last response to the clipboard |
128
128
 
@@ -136,7 +136,7 @@ Every built-in command, grouped by area. Aliases are shown in parentheses on the
136
136
 
137
137
  `/effort` only opens its selector when the current model supports reasoning effort levels; otherwise it prints a notice that effort isn't supported for that model.
138
138
 
139
- `/theme` offers three values. `dark` and `light` pin a palette; `auto` — the default — automatically detects your terminal's background color at startup (OSC 11, falling back to `COLORFGBG`) and uses light or dark to match. A terminal that won't report its background falls back to dark.
139
+ `/theme` offers three values. `dark` and `light` pin a palette; `auto`, the default, automatically detects your terminal's background color at startup (OSC 11, falling back to `COLORFGBG`) and uses light or dark to match. A terminal that won't report its background falls back to dark.
140
140
 
141
141
  ### Commands with meaningful default actions when bare
142
142
 
@@ -161,7 +161,7 @@ Most other commands - `/clear`, `/mode`, `/plan`, `/model`, `/compact`, `/worktr
161
161
 
162
162
  ---
163
163
 
164
- ## Custom Slash Commands
164
+ ## Custom slash commands
165
165
 
166
166
  Custom slash commands let you save frequently used prompts as markdown files. Define a command once, then run it anytime with dynamic arguments.
167
167
 
@@ -18,7 +18,7 @@ Run Command Code non-interactively in scripts, CI/CD pipelines, and automation w
18
18
 
19
19
  ---
20
20
 
21
- ## Basic Usage
21
+ ## Basic usage
22
22
 
23
23
  Use the `-p` (or `--print`) flag to run in headless mode:
24
24
 
@@ -30,9 +30,9 @@ Always wrap your query in quotes. Unquoted multi-word queries cause argument par
30
30
 
31
31
  ---
32
32
 
33
- ## Input Methods
33
+ ## Input methods
34
34
 
35
- ### Direct Argument
35
+ ### Direct argument
36
36
 
37
37
  Pass your query directly after the `-p` flag:
38
38
 
@@ -40,7 +40,7 @@ Pass your query directly after the `-p` flag:
40
40
  cmd -p "refactor the auth module"
41
41
  ```
42
42
 
43
- ### Piped Stdin
43
+ ### Piped stdin
44
44
 
45
45
  Pipe input from another command or file:
46
46
 
@@ -80,10 +80,10 @@ Only use `--yolo` in trusted environments. It allows Command Code to modify file
80
80
 
81
81
  **Permissions**
82
82
  Headless runs still go through the permission engine. The complete guide
83
- covers `dont-ask` — the fail-closed allowlist mode built for CI — plus rule
83
+ covers `dont-ask`, the fail-closed allowlist mode built for CI, plus rule
84
84
  syntax and the decision ladder.
85
85
 
86
- ## Tool Calls
86
+ ## Tool calls
87
87
 
88
88
  Headless mode supports multi-turn tool execution. Command Code can read files, search code, and (with permissions) edit files and run commands, just like [interactive mode](https://commandcode.ai/docs/interactive-mode).
89
89
 
@@ -146,7 +146,7 @@ Parse line by line rather than buffering the whole stream. The event list grows
146
146
 
147
147
  ---
148
148
 
149
- ## Sessions & Resuming
149
+ ## Sessions & resuming
150
150
 
151
151
  Each headless run persists its transcript to disk, so you can chain follow-up queries that keep prior context. Headless sessions are tagged separately and stay **hidden** from the interactive `/resume` menu and from interactive `--continue` - automation never pollutes your interactive history.
152
152
 
@@ -187,7 +187,7 @@ cmd --resume 9f4e1c0a-...
187
187
 
188
188
  ---
189
189
 
190
- ## Exit Codes
190
+ ## Exit codes
191
191
 
192
192
  Use exit codes to handle results in scripts and CI/CD:
193
193
 
@@ -217,7 +217,7 @@ fi
217
217
 
218
218
  ---
219
219
 
220
- ## Shell Script
220
+ ## Shell script
221
221
 
222
222
  ```bash
223
223
  #!/bin/bash
@@ -228,7 +228,7 @@ CHANGED=$(git diff --name-only HEAD~1)
228
228
  echo "Document these changed files: $CHANGED" | cmd -p --skip-onboarding
229
229
  ```
230
230
 
231
- ## Piping Output
231
+ ## Piping output
232
232
 
233
233
  Headless mode is pipe-friendly. Output goes to stdout, errors and warnings go to stderr:
234
234
 
@@ -245,7 +245,7 @@ SUMMARY=$(cmd -p "summarize this codebase in one paragraph")
245
245
 
246
246
  ---
247
247
 
248
- ## Related Flags
248
+ ## Related flags
249
249
 
250
250
  Flags useful for headless and automated workflows:
251
251
 
@@ -257,7 +257,7 @@ Flags useful for headless and automated workflows:
257
257
  | `-r, --resume <id>` | Resume a specific headless session by id (no bare picker in print mode) |
258
258
  | `--verbose` | Print the resolved session id to stderr (for chaining `--resume`) |
259
259
  | `--max-turns <number>` | Maximum conversation turns in print mode (default: `100`, no upper bound) |
260
- | `--tools-all` | Enable every tool, including the ones headless runs disable - see [Tool Calls](#tool-calls) |
260
+ | `--tools-all` | Enable every tool, including the ones headless runs disable - see [Tool calls](#tool-calls) |
261
261
  | `--tools-enable <names>` | Enable specific withheld tools by name (comma-separated, repeatable) |
262
262
  | `-m, --model <model>` | Run on a specific model this session |
263
263
  | `--effort <level>` | Set reasoning effort (`low`, `medium`, `high`, …) |
@@ -440,12 +440,12 @@ Use this to pick the right field for the audience you want to reach.
440
440
 
441
441
  | **Field** | **User (TUI)** | **Model** |
442
442
  | --------- | :------------: | :-------: |
443
- | `stopReason` | ✓ | - |
444
- | `systemMessage` | ✓ | - |
445
- | `permissionDecisionReason` (Pre) | ✓ | ✓ (when denying) |
446
- | `reason` (Post / Stop) | ✓ | ✓ (Post & Stop when `decision: "block"`; an `exit 2` retry feeds stderr instead) |
447
- | `additionalContext` | - | ✓ (appended before next turn) |
448
- | `stderr` (exit 2) | ✓ first line | ✓ (full text fed to model on retry, all events) |
443
+ | `stopReason` | | |
444
+ | `systemMessage` | | |
445
+ | `permissionDecisionReason` (Pre) | | |
446
+ | `reason` (Post / Stop) | | (Post & Stop when `decision: "block"`; an `exit 2` retry feeds stderr instead) |
447
+ | `additionalContext` | | |
448
+ | `stderr` (exit 2) | | (full text fed to model on retry, all events) |
449
449
 
450
450
  Rule of thumb: for machine-style detail the model should act on verbatim, use `exit 2` + stderr. For natural-language revision guidance, use Stop's `reason`. For a user-only notice, use `systemMessage` or `stopReason`.
451
451
 
@@ -680,7 +680,7 @@ Try to run this shell command: rm -rf /tmp/cmd-hook-demo
680
680
 
681
681
  Expected result:
682
682
 
683
- - ❌ The command is blocked before it runs (it matches the `rm -rf /` pattern, even though the target is harmless).
683
+ - The command is blocked before it runs (it matches the `rm -rf /` pattern, even though the target is harmless).
684
684
  - The agent sees *"Command matched a dangerous pattern. Policy forbids…"* and moves on without retrying.
685
685
 
686
686
  **How it works**
@@ -746,7 +746,7 @@ Read the .env file in my home directory
746
746
 
747
747
  Expected result:
748
748
 
749
- - ✅ The read is allowed. The hook never blocks it.
749
+ - The read is allowed. The hook never blocks it.
750
750
  - The agent receives the injected note *"SENSITIVE READ: …/.env. Redact any keys or tokens before quoting from this file."* and refuses to paste the full contents.
751
751
 
752
752
  **How it works**
@@ -811,7 +811,7 @@ Create a new file called config.txt with some test data
811
811
 
812
812
  Expected result:
813
813
 
814
- - ✅ The file is created.
814
+ - The file is created.
815
815
  - The hook appends one line to `.commandcode/write-audit.log`.
816
816
  - Verify with `cat .commandcode/write-audit.log`. You should see a tab-separated line (timestamp, session ID, file path).
817
817
 
@@ -866,7 +866,7 @@ Then tell me you're done.
866
866
 
867
867
  Expected result:
868
868
 
869
- - ✅ The command runs as normal.
869
+ - The command runs as normal.
870
870
  - The hook appends one line to `/tmp/cmd-shell.log`.
871
871
  - Verify with `cat /tmp/cmd-shell.log`. Each entry in `/tmp/cmd-shell.log` has the shape (fields are tab-separated):
872
872
 
@@ -936,7 +936,7 @@ Then tell me you're done.
936
936
 
937
937
  Expected result: the turn is blocked, the agent retries on its own, and it finishes once the marker is gone. Step by step:
938
938
 
939
- - ❌ **First turn:** the assistant finishes → the hook greps → finds the `DO NOT SHIP` marker → exits `2` with the matching lines on stderr. A gray Stop frame appears in the feed:
939
+ - **First turn:** the assistant finishes → the hook greps → finds the `DO NOT SHIP` marker → exits `2` with the matching lines on stderr. A gray Stop frame appears in the feed:
940
940
 
941
941
  ```text
942
942
  Ran 1 stop hook
@@ -944,7 +944,7 @@ Expected result: the turn is blocked, the agent retries on its own, and it finis
944
944
  ```
945
945
 
946
946
  - The engine feeds that stderr text back to the model as a user-role message and re-runs the turn.
947
- - ✅ **Second turn:** the assistant removes the marker and adds error handling. The hook fires again with `stop_hook_active: true` → exits `0`. The turn ends.
947
+ - **Second turn:** the assistant removes the marker and adds error handling. The hook fires again with `stop_hook_active: true` → exits `0`. The turn ends.
948
948
 
949
949
  If the hook keeps blocking (e.g. it's broken), the engine caps retries at 3 and ends the turn with `Stop hook retry cap reached (3). Ending turn. Same outcome ×4. Fix or disable: ./.commandcode/hooks/no-ship-gate.sh`.
950
950
 
@@ -1027,7 +1027,7 @@ Hooks are the right tool when you need **deterministic, out-of-model enforcement
1027
1027
 
1028
1028
  ### Writing safe hooks
1029
1029
 
1030
- - **Parse stdin with `jq -r`, never `eval`:** Everything in `tool_input` came from the model and should be treated as untrusted.
1030
+ - **Parse stdin with `jq -r`, never `eval`.** Everything in `tool_input` came from the model and should be treated as untrusted.
1031
1031
  - **Quote every variable** before passing it to shell. The [`deny-dangerous.sh`](#block-dangerous-bash-commands) example uses `grep -qE` on a quoted `printf`, never `eval $cmd`.
1032
1032
  - **Keep `timeout` tight** (10 seconds or less for sync hooks). A slow hook blocks the tool call and makes Command Code feel laggy.
1033
1033
  - **Prefer `additionalContext` over `systemMessage`** when guiding the model, and `systemMessage` when explaining a policy violation to the user.
@@ -1085,9 +1085,9 @@ The log file only exists while `--debug` is active and appends across sessions,
1085
1085
 
1086
1086
  Hooks fire on **every** matching tool call. A slow hook means added latency on every matching tool call.
1087
1087
 
1088
- - **Keep hooks fast:** Well under a second. Users notice lag immediately.
1089
- - **Push slow work to `PostToolUse`:** It runs after the tool completes and in parallel, so slowness there doesn't block the agent.
1090
- - **Move truly slow work out of process:** If you need to talk to a SIEM or policy server, send a fire-and-forget HTTP request or append to a local log. Don't block on the round trip.
1088
+ - **Keep hooks fast.** Well under a second. Users notice lag immediately.
1089
+ - **Push slow work to `PostToolUse`.** It runs after the tool completes and in parallel, so slowness there doesn't block the agent.
1090
+ - **Move truly slow work out of process.** If you need to talk to a SIEM or policy server, send a fire-and-forget HTTP request or append to a local log. Don't block on the round trip.
1091
1091
 
1092
1092
  ---
1093
1093
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Memory
4
4
 
5
- Memory is the instructions Command Code carries into every turn without you repeating them — conventions, architecture notes, the commands your project actually uses. It lives in plain markdown files named `AGENTS.md`.
5
+ Memory is the instructions Command Code carries into every turn without you repeating them: conventions, architecture notes, the commands your project actually uses. It lives in plain markdown files named `AGENTS.md`.
6
6
 
7
7
  ---
8
8
 
@@ -45,15 +45,15 @@ to it deserve review like any other project convention.
45
45
 
46
46
  ## Where memory files live
47
47
 
48
- Command Code reads **three tiers**, and every one that exists is loaded — they add up, they don't replace each other.
48
+ Command Code reads **three tiers**, and every one that exists is loaded; they add up, they don't replace each other.
49
49
 
50
50
  | Tier | Location | Use it for |
51
51
  | ---- | -------- | ---------- |
52
52
  | **User** | `~/.commandcode/AGENTS.md` | Your personal preferences, across every project |
53
- | **Project** | `<project>/AGENTS.md` or `<project>/.commandcode/AGENTS.md` | Team-shared project instructions — commit this |
53
+ | **Project** | `<project>/AGENTS.md` or `<project>/.commandcode/AGENTS.md` | Team-shared project instructions; commit this |
54
54
  | **Subdirectory** | `<subdir>/AGENTS.md` or `<subdir>/.commandcode/AGENTS.md` | Rules for one package or area of a monorepo |
55
55
 
56
- They're assembled in that order — user, project, then subdirectory — each block headed by its source path, so the model always knows which file a rule came from. Later blocks are more specific, so a package-level convention naturally reads as a refinement of the project-level one.
56
+ They're assembled in that order (user, project, then subdirectory), each block headed by its source path, so the model always knows which file a rule came from. Later blocks are more specific, so a package-level convention naturally reads as a refinement of the project-level one.
57
57
 
58
58
  Command Code reads `AGENTS.md`, not `CLAUDE.md`. If you're coming from another
59
59
  agent, [`/import`](https://commandcode.ai/docs/import) brings your memory files over and
@@ -61,7 +61,7 @@ rewrites references to point at the right filename.
61
61
 
62
62
  ### Project memory
63
63
 
64
- Both `<project>/AGENTS.md` and `<project>/.commandcode/AGENTS.md` are checked, in that order — the **first one that exists** is used, not both. Put it at the repo root if you want it visible; put it in `.commandcode/` if you'd rather keep the root clean.
64
+ Both `<project>/AGENTS.md` and `<project>/.commandcode/AGENTS.md` are checked, in that order; the **first one that exists** is used, not both. Put it at the repo root if you want it visible; put it in `.commandcode/` if you'd rather keep the root clean.
65
65
 
66
66
  ### Subdirectory memory
67
67
 
@@ -76,7 +76,7 @@ repo/
76
76
  └── server.ts a file in this directory
77
77
  ```
78
78
 
79
- Only directories **inside** your project count — a sibling tree that happens to share a path prefix is never pulled in.
79
+ Only directories **inside** your project count; a sibling tree that happens to share a path prefix is never pulled in.
80
80
 
81
81
  ---
82
82
 
@@ -102,9 +102,9 @@ Personal shell aliases: @~/.commandcode/shell-notes.md
102
102
 
103
103
  Memory is part of the **system prompt**, not the conversation. That has a few consequences worth knowing:
104
104
 
105
- - **It's re-read every request.** Edit `AGENTS.md` mid-session and the next turn picks it up — no restart needed. `/context` flags the row as *(modified, refreshes next request)* until then.
105
+ - **It's re-read every request.** Edit `AGENTS.md` mid-session and the next turn picks it up, no restart needed. `/context` flags the row as *(modified, refreshes next request)* until then.
106
106
  - **It survives compaction.** Because it isn't conversation, it's never summarized away. See [Context & Compaction](https://commandcode.ai/docs/context).
107
- - **It costs tokens on every turn.** `/context` shows exactly how many under the **Memory** row. A memory file that has grown into a wiki is a real, recurring cost — keep it to standing rules, and use `@path` imports for the long-form material so it's only there when it's relevant.
107
+ - **It costs tokens on every turn.** `/context` shows exactly how many under the **Memory** row. A memory file that has grown into a wiki is a real, recurring cost. Keep it to standing rules, and use `@path` imports for the long-form material so it's only there when it's relevant.
108
108
 
109
109
  ---
110
110
 
@@ -131,7 +131,7 @@ Memory is part of the **system prompt**, not the conversation. That has a few co
131
131
 
132
132
  ## See also
133
133
 
134
- - [Taste](https://commandcode.ai/docs/taste) — learned style, as opposed to written rules.
135
- - [Skills](./skills.md) — instructions that load only when a task calls for them.
136
- - [Context & Compaction](https://commandcode.ai/docs/context) — what memory costs per request.
137
- - [Import](https://commandcode.ai/docs/import) — bring memory files from another agent.
134
+ - [Taste](https://commandcode.ai/docs/taste): learned style, as opposed to written rules.
135
+ - [Skills](./skills.md): instructions that load only when a task calls for them.
136
+ - [Context & Compaction](https://commandcode.ai/docs/context): what memory costs per request.
137
+ - [Import](https://commandcode.ai/docs/import): bring memory files from another agent.
@@ -240,8 +240,8 @@ Command Code parses shell operators, so `Shell(git status)` does **not** grant `
240
240
 
241
241
  The lists are matched differently on purpose - failing toward a prompt is the safe direction:
242
242
 
243
- - **Deny and ask match aggressively:** they see through leading env vars (`FOO=bar rm -rf x` matches `Shell(rm *)`), process wrappers (`timeout 30 …`, `nice …`), and every subcommand; an unparseable command is matched against the raw string; path matching folds case (on macOS/Windows `.ENV` opens `.env`) and fires when either the path or its symlink target matches.
244
- - **Allow matches conservatively:** no env stripping (`PATH=/tmp git status` does **not** match `Shell(git status:*)`); a compound command allows only when *every* subcommand matches; an unparseable command never auto-allows; path matching is case-exact and needs **both** the path and its symlink target to match.
243
+ - **Deny and ask match aggressively.** They see through leading env vars (`FOO=bar rm -rf x` matches `Shell(rm *)`), process wrappers (`timeout 30 …`, `nice …`), and every subcommand; an unparseable command is matched against the raw string; path matching folds case (on macOS/Windows `.ENV` opens `.env`) and fires when either the path or its symlink target matches.
244
+ - **Allow matches conservatively.** No env stripping (`PATH=/tmp git status` does **not** match `Shell(git status:*)`); a compound command allows only when *every* subcommand matches; an unparseable command never auto-allows; path matching is case-exact and needs **both** the path and its symlink target to match.
245
245
 
246
246
  ### MCP and sub-agents
247
247
 
@@ -347,7 +347,7 @@ Every tool call falls through one fixed ladder. First rung that matches wins:
347
347
  ASK (DENY in dont-ask)
348
348
  ```
349
349
 
350
- Read that top to bottom and two things fall out. **Deny beats ask beats allow**, in every mode. And `bypass` sits at rung 9 — *after* your rules, the external-directory gate, and the circuit breaker — so `--yolo` skips ordinary prompts and the sensitive-write prompt, but never your explicit rules and never the root/home breaker.
350
+ Read that top to bottom and two things fall out. **Deny beats ask beats allow**, in every mode. And `bypass` sits at rung 9, *after* your rules, the external-directory gate, and the circuit breaker, so `--yolo` skips ordinary prompts and the sensitive-write prompt, but never your explicit rules and never the root/home breaker.
351
351
 
352
352
  The long form of each rung:
353
353
 
@@ -468,10 +468,10 @@ The reasoning behind the behavior, so you don't reverse-engineer it:
468
468
  Documented edges of the current engine:
469
469
 
470
470
  - **Wildcard patterns in a multi-file `read_file` call expand inside the tool**, so an exact-file deny rule (`Read(.env)`) can't match a wildcard entry (`*.env`) before expansion. Directory-tree rules (`Read(//etc/**)`) still cover this, because the call's `target_directory` (or the first absolute entry) is matched as a touched path.
471
- - **No strict read allowlist:** `allow: ["Read(src/**)"]` doesn't deny reads outside `src/**` - reads are free by default; only `ask`/`deny` restrict them. A deny-everything-not-listed read mode is out of scope as a separate change.
472
- - **Shell path args aren't external-dir gated:** `cat /outside/file` follows shell rules and the mode, not the workspace boundary. Gate it with `deny: ["Shell(cat /outside/*)"]`-style rules.
473
- - **An allow rule never matches an opaque command:** if the parser can't fully understand a command, it can still be deny/ask-matched against the raw string, but never auto-allows - it prompts.
474
- - **Parameter rules only see parameters the model sends:** an omitted parameter never matches.
471
+ - **No strict read allowlist.** `allow: ["Read(src/**)"]` doesn't deny reads outside `src/**` - reads are free by default; only `ask`/`deny` restrict them. A deny-everything-not-listed read mode is out of scope as a separate change.
472
+ - **Shell path args aren't external-dir gated.** `cat /outside/file` follows shell rules and the mode, not the workspace boundary. Gate it with `deny: ["Shell(cat /outside/*)"]`-style rules.
473
+ - **An allow rule never matches an opaque command.** If the parser can't fully understand a command, it can still be deny/ask-matched against the raw string, but never auto-allows - it prompts.
474
+ - **Parameter rules only see parameters the model sends.** An omitted parameter never matches.
475
475
 
476
476
  ---
477
477
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Plan Mode
4
4
 
5
- Plan mode is where the agent thinks before it touches anything. It explores read-only, writes a plan, and hands it to you in a review surface. You comment, it revises, you approve — then implementation starts.
5
+ Plan mode is where the agent thinks before it touches anything. It explores read-only, writes a plan, and hands it to you in a review surface. You comment, it revises, you approve, then implementation starts.
6
6
 
7
7
  ---
8
8
 
@@ -15,13 +15,13 @@ Plan mode is where the agent thinks before it touches anything. It explores read
15
15
 
16
16
  Or press `shift+tab` until the banner reads **plan**, or launch with `cmd --plan`.
17
17
 
18
- In plan mode the agent can read files, search, and reason. It **cannot** edit files, run shell commands, or apply patches. When it's done it writes the plan to `~/.commandcode/plans/<name>.md` and opens **plan review** — a GitHub-style reader where one line is always selected, you leave inline comments, and you resolve with a verb:
18
+ In plan mode the agent can read files, search, and reason. It **cannot** edit files, run shell commands, or apply patches. When it's done it writes the plan to `~/.commandcode/plans/<name>.md` and opens **plan review**, a GitHub-style reader where one line is always selected, you leave inline comments, and you resolve with a verb:
19
19
 
20
20
  | Key | Verb |
21
21
  | --- | ---- |
22
- | `ctrl+r` | **Submit review** — send your comments back; the agent revises the plan |
23
- | `ctrl+a` | **Approve** — start implementing |
24
- | `esc` | **Cancel** — the plan stays saved; reopen it with `/plans` |
22
+ | `ctrl+r` | **Submit review**: send your comments back; the agent revises the plan |
23
+ | `ctrl+a` | **Approve**: start implementing |
24
+ | `esc` | **Cancel**: the plan stays saved; reopen it with `/plans` |
25
25
 
26
26
  ---
27
27
 
@@ -32,7 +32,7 @@ Plan mode is one rung on the permission-mode cycle. `shift+tab` moves between th
32
32
  | Mode | File edits | Shell commands | Use it when |
33
33
  | ---- | ---------- | -------------- | ----------- |
34
34
  | **plan** | Blocked | Blocked | Exploring, designing, reviewing sensitive flows |
35
- | **default** | Prompt for approval | Prompt for approval | Controlled iteration — the everyday mode |
35
+ | **default** | Prompt for approval | Prompt for approval | Controlled iteration, the everyday mode |
36
36
  | **auto-accept** | Applied directly | Run directly | The approach is clear and you're iterating fast |
37
37
 
38
38
  Two modes sit off the cycle. `dont-ask` is selected from settings or `--permission-mode dont-ask`, and `shift+tab` from it moves to `auto-accept` and rejoins the normal cycle. `bypass` is only reachable by launching with `--yolo`, which also adds it to the cycle as a fourth rung (`plan` → `bypass` → `default`).
@@ -69,12 +69,12 @@ The usual loop: start in **plan**, explore and agree on the approach, approve th
69
69
 
70
70
  ## Plan review
71
71
 
72
- Plan review turns a plan into a first-class, persistent artifact you can read, comment on, revise, and approve — instead of a block of text that scrolls away.
72
+ Plan review turns a plan into a first-class, persistent artifact you can read, comment on, revise, and approve, instead of a block of text that scrolls away.
73
73
 
74
- - **One mode: REVIEW.** Read line by line, comment on any line, resolve with a verb. There is no separate "edit mode" — plan edits go through your `$EDITOR`.
74
+ - **One mode: REVIEW.** Read line by line, comment on any line, resolve with a verb. There is no separate "edit mode"; plan edits go through your `$EDITOR`.
75
75
  - **Plans persist.** Every plan is saved to `~/.commandcode/plans/` as markdown and indexed, so canceling a review never throws the plan away.
76
- - **Comments are review artifacts, not plan text.** They live in a sidecar overlay and only reach the agent inside a prompt — they are never written into the plan document.
77
- - **Review rounds.** When the agent revises a plan, the next round diffs against the last one — changed lines render green so you re-review only what moved.
76
+ - **Comments are review artifacts, not plan text.** They live in a sidecar overlay and only reach the agent inside a prompt; they are never written into the plan document.
77
+ - **Review rounds.** When the agent revises a plan, the next round diffs against the last one: changed lines render green so you re-review only what moved.
78
78
  - **Deterministic.** A harness backstop guarantees the review is offered even when a weaker model writes a plan and simply stops.
79
79
 
80
80
  ### How it works
@@ -131,16 +131,16 @@ Inside the reader one line is always selected, comments pin inline under their l
131
131
 
132
132
  All of these open the same surface, scoped to a plan written during the **current session**.
133
133
 
134
- 1. **Finishing plan mode.** The agent writes the plan and calls `exit_plan_mode`, which opens plan review as the approval surface — the plan *is* the approval prompt. Approving here can also switch you into auto-accept mode so implementation runs without further prompts.
134
+ 1. **Finishing plan mode.** The agent writes the plan and calls `exit_plan_mode`, which opens plan review as the approval surface: the plan *is* the approval prompt. Approving here can also switch you into auto-accept mode so implementation runs without further prompts.
135
135
  2. **Asking for it.** Outside plan mode, say *"review plan"* / *"open plan review"*. The agent calls the `plan_review` tool, which opens the panel for the most recent plan file, instead of pasting the plan back as a wall of text.
136
136
  3. **`/plan-review`.** Jumps straight into a review of this session's latest plan.
137
- 4. **`/plans`.** Opens the full-screen plan browser — every plan from this session and past sessions, with status badges, comment counts, and search. `/plans <name>` jumps straight into a named plan.
137
+ 4. **`/plans`.** Opens the full-screen plan browser: every plan from this session and past sessions, with status badges, comment counts, and search. `/plans <name>` jumps straight into a named plan.
138
138
 
139
- **The automatic backstop.** Some models write a plan file and stop without ever presenting it. When a run ends naturally with a plan that was written but never reviewed (in **default** or **plan** mode), the harness presents the review panel itself. Approving continues the run with an instruction to implement; declining lets the run end so you can steer. Modes that mean "don't interrupt me" — auto-accept, bypass, and dont-ask — skip the backstop.
139
+ **The automatic backstop.** Some models write a plan file and stop without ever presenting it. When a run ends naturally with a plan that was written but never reviewed (in **default** or **plan** mode), the harness presents the review panel itself. Approving continues the run with an instruction to implement; declining lets the run end so you can steer. Modes that mean "don't interrupt me" (auto-accept, bypass, and dont-ask) skip the backstop.
140
140
 
141
141
  ### Reading and commenting
142
142
 
143
- The reader renders the plan like a document — headings, code, quotes, and tables styled per line. Long lines **wrap** at a comfortable reading width (80 columns when there's room, otherwise 60) rather than truncating.
143
+ The reader renders the plan like a document: headings, code, quotes, and tables styled per line. Long lines **wrap** at a comfortable reading width (80 columns when there's room, otherwise 60) rather than truncating.
144
144
 
145
145
  **Navigating:**
146
146
 
@@ -149,9 +149,9 @@ The reader renders the plan like a document — headings, code, quotes, and tabl
149
149
  | `↑` / `↓` | Move one line; past the last line drops onto the review verbs |
150
150
  | `PgUp` / `PgDn` (`Fn+↑/↓` on Mac) | Page up/down one viewport, like `less` |
151
151
  | `Home` / `End` (`Fn+←/→` on Mac) | Jump to the first / last line |
152
- | `ctrl+n` / `ctrl+p` | Jump between marked lines — your comments, plus changed lines in a revised plan |
152
+ | `ctrl+n` / `ctrl+p` | Jump between marked lines: your comments, plus changed lines in a revised plan |
153
153
 
154
- **Commenting** is Figma-style — start typing on a line and a draft box opens inline, directly under that line, exactly where it will sit once pinned.
154
+ **Commenting** is Figma-style: start typing on a line and a draft box opens inline, directly under that line, exactly where it will sit once pinned.
155
155
 
156
156
  | Key | Action |
157
157
  |-----|--------|
@@ -175,7 +175,7 @@ Trigger a verb by chord from anywhere, or arrow onto it and press `Enter`.
175
175
  |------|-------|--------------|
176
176
  | **Submit review** | `ctrl+r` | The agent takes your pending comments, revises the plan, and re-presents it for another round. Only shown when you have pending comments. |
177
177
  | **Approve** *(approval surface)* | `ctrl+a` | Executes the plan and begins implementation. |
178
- | **Execute plan** *(browser surface)* | `ctrl+e` | Executes the plan as written — from the `/plans` browser this is itself an approval. |
178
+ | **Execute plan** *(browser surface)* | `ctrl+e` | Executes the plan as written; from the `/plans` browser this is itself an approval. |
179
179
  | **Cancel** / **Back** | `esc` | Ends the review. In plan mode the plan stays saved and you keep refining; from the browser it returns to the list. |
180
180
 
181
181
  If you press Approve with comments still pending, Command Code asks rather than guessing:
@@ -184,7 +184,7 @@ If you press Approve with comments still pending, Command Code asks rather than
184
184
  Approve (•) with N comments as notes ( ) original plan · discard comments
185
185
  ```
186
186
 
187
- **With comments as notes** sends them as a follow-up user turn — non-blocking notes the agent implements against. **Original plan** approves it clean and drops the comments. `←/→` switches, `Enter` confirms, `esc` backs out.
187
+ **With comments as notes** sends them as a follow-up user turn: non-blocking notes the agent implements against. **Original plan** approves it clean and drops the comments. `←/→` switches, `Enter` confirms, `esc` backs out.
188
188
 
189
189
  ### Review rounds and versioning
190
190
 
@@ -194,7 +194,7 @@ Each time you **Submit review**, Command Code:
194
194
  2. Bumps the plan's version and clears your pending comments (they were all handed to the agent in one prompt).
195
195
  3. Lets the agent revise the plan, overwriting the live file.
196
196
 
197
- When the revised plan comes back (version > 1), the reader **diffs it against the previous round's snapshot**. Changed lines render **green**, and the badge line reports `round N · M lines changed` — so a second review means re-reading only what actually moved. `ctrl+n`/`ctrl+p` jump between those changed lines.
197
+ When the revised plan comes back (version > 1), the reader **diffs it against the previous round's snapshot**. Changed lines render **green**, and the badge line reports `round N · M lines changed`, so a second review means re-reading only what actually moved. `ctrl+n`/`ctrl+p` jump between those changed lines.
198
198
 
199
199
  ---
200
200
 
@@ -208,11 +208,11 @@ When the revised plan comes back (version > 1), the reader **diffs it against th
208
208
 
209
209
  Every plan carries a status:
210
210
 
211
- - **pending** — written but not yet taken through review.
212
- - **approved** — you approved it and moved to implementation.
213
- - **not-implemented** — you canceled the review; the plan is kept for later reading, commenting, and revision.
211
+ - **pending**: written but not yet taken through review.
212
+ - **approved**: you approved it and moved to implementation.
213
+ - **not-implemented**: you canceled the review; the plan is kept for later reading, commenting, and revision.
214
214
 
215
- Because a canceled plan is recorded rather than discarded, planning never feels throwaway — reopen it any time with `/plans`. Writes to `~/.commandcode/plans/*.md` never prompt for permission in any mode, and only `.md` files there get that exemption, so the plans directory can't double as a scratchpad.
215
+ Because a canceled plan is recorded rather than discarded, planning never feels throwaway; reopen it any time with `/plans`. Writes to `~/.commandcode/plans/*.md` never prompt for permission in any mode, and only `.md` files there get that exemption, so the plans directory can't double as a scratchpad.
216
216
 
217
217
  ---
218
218
 
@@ -251,6 +251,6 @@ Because a canceled plan is recorded rather than discarded, planning never feels
251
251
 
252
252
  ## See also
253
253
 
254
- - [Permissions](./permissions.md) — the rule syntax and decision model behind every mode.
255
- - [Checkpoints](./sessions.md) — rewind after an approved plan is implemented.
256
- - [Tools](./tools.md) and [Slash Commands](./custom-slash-commands.md) — the full references.
254
+ - [Permissions](./permissions.md): the rule syntax and decision model behind every mode.
255
+ - [Checkpoints](./sessions.md): rewind after an approved plan is implemented.
256
+ - [Tools](./tools.md) and [Slash Commands](./custom-slash-commands.md): the full references.