sidecar-cli 0.1.5-beta.1 → 0.1.5-rc.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/README.md CHANGED
@@ -23,12 +23,6 @@ Install globally (stable):
23
23
  npm install -g sidecar-cli
24
24
  ```
25
25
 
26
- Note on npm deprecation warnings:
27
-
28
- - You may see a transitive warning for `prebuild-install@7.1.3` during install.
29
- - This currently comes from `better-sqlite3` (Sidecar's SQLite dependency), not from Sidecar code directly.
30
- - Sidecar still installs/works normally; we will update when upstream dependency chain moves off it.
31
-
32
26
  Install beta:
33
27
 
34
28
  ```bash
@@ -64,7 +58,7 @@ brew upgrade sidecar
64
58
 
65
59
  Requirements:
66
60
 
67
- - Node.js 20+
61
+ - Node.js 22+ (Sidecar uses the built-in `node:sqlite` module)
68
62
  - npm
69
63
 
70
64
  Install dependencies:
@@ -85,6 +79,18 @@ Run locally in dev mode:
85
79
  npm run dev -- --help
86
80
  ```
87
81
 
82
+ ## Release channels
83
+
84
+ Sidecar ships features through `beta` → `rc` → `stable` as version bumps — there are no per-feature channel flags. Install `@beta` to try new features early; install default (stable) for the latest promoted release.
85
+
86
+ | Channel | Current version | Notes |
87
+ | --- | --- | --- |
88
+ | stable (`latest`) | `0.1.4` | Promoted releases. Homebrew tracks this channel. |
89
+ | rc | _none newer than stable_ | Release candidates published only when preparing a stable cut. |
90
+ | beta | `0.1.5-beta.2` | Dual-runner pipelines, run replay, ambient capture via Claude Code hooks, typed validation + auto-approve, freestanding prompt specs, `sidecar demo`. |
91
+
92
+ Per-version release notes live at [github.com/karlhills/sidecar-cli/releases](https://github.com/karlhills/sidecar-cli/releases).
93
+
88
94
  ## Quick start
89
95
 
90
96
  1. Initialize in a project directory:
@@ -135,11 +141,34 @@ This creates:
135
141
 
136
142
  Use `--force` to overwrite Sidecar-managed files.
137
143
 
144
+ ## Two namespaces: `log` and `work`
145
+
146
+ Sidecar is one CLI that does two jobs: capture local project memory, and run AI coding agents against that memory. Each job has a namespace:
147
+
148
+ - **`sidecar log <cmd>`** — memory: `worklog`, `decision`, `note`, `recent`, `context`, `summary`, `session`, `event`, `artifact`
149
+ - **`sidecar work <cmd>`** — runner: `task`, `run`, `prompt`, `hooks`
150
+
151
+ The underlying verbs still work directly, so `sidecar worklog record ...` and `sidecar log worklog record ...` are equivalent. Pick the form that reads best in your workflow.
152
+
153
+ ```bash
154
+ sidecar log worklog record --done "..." --files src/a.ts
155
+ sidecar log decision record --title "..." --summary "..."
156
+ sidecar log context --format markdown
157
+ sidecar log summary refresh
158
+
159
+ sidecar work task create --title "..."
160
+ sidecar work run T-001
161
+ sidecar work prompt compile ./prompt.yaml
162
+ ```
163
+
164
+ Run `sidecar log --help` or `sidecar work --help` for the full listing.
165
+
138
166
  ## Core commands
139
167
 
140
168
  Global:
141
169
 
142
170
  - `sidecar init [--force] [--name <project-name>] [--instructions-template <name>] [--instructions-file <path>] [--json]`
171
+ - `sidecar demo [--cleanup] [--json]`
143
172
  - `sidecar status [--json]`
144
173
  - `sidecar preferences show [--json]`
145
174
  - `sidecar ui [--no-open] [--port <port>] [--install-only] [--project <path>] [--reinstall]`
@@ -148,6 +177,15 @@ Global:
148
177
  - `sidecar export [--format json|jsonl] [--output <path>]`
149
178
  - `sidecar help`
150
179
 
180
+ Runner and prompts:
181
+
182
+ - `sidecar run <task-id> [--runner codex|claude|codex,claude] [--agent-role <role>] [--dry-run] [--json]`
183
+ - `sidecar run replay <run-id> [--runner <r>] [--agent-role <role>] [--reason <text>] [--edit-prompt] [--dry-run] [--json]`
184
+ - `sidecar run list [--task <task-id>] [--json]` · `sidecar run show <run-id> [--json]`
185
+ - `sidecar run queue [--json]` · `sidecar run start-ready [--dry-run] [--json]`
186
+ - `sidecar prompt compile <task-or-file> [--runner <r>] [--agent-role <role>] [--budget <n>] [--section-policy ...] [--explain] [--format json] [-o <path>]`
187
+ - `sidecar hooks print` · `sidecar hook <session-start|session-end|file-edit|user-prompt> [--actor-name <name>] [--json]`
188
+
151
189
  Context and summary:
152
190
 
153
191
  - `sidecar context [--limit <n>] [--format text|markdown|json] [--json]`
@@ -179,6 +217,138 @@ Artifacts:
179
217
  - `sidecar artifact add <path> [--kind file|doc|screenshot|other] [--note <text>] [--json]`
180
218
  - `sidecar artifact list [--json]`
181
219
 
220
+ ## Validation kinds and auto-approve
221
+
222
+ Task packets describe post-run validation commands under `execution.commands.validation`. Each entry is tagged with a **kind** so Sidecar can route the result intelligently, apply a sensible default timeout, and surface the outcome in the UI and CLI.
223
+
224
+ ### Kinds
225
+
226
+ | Kind | Default timeout | Intended for |
227
+ | --- | --- | --- |
228
+ | `typecheck` | 3 min | `tsc --noEmit`, `mypy`, `pyright` |
229
+ | `lint` | 3 min | `eslint`, `ruff`, `golangci-lint` |
230
+ | `test` | 10 min | unit/integration suites |
231
+ | `build` | 10 min | bundlers, compilers, image builds |
232
+ | `custom` | 5 min | anything else (the legacy default) |
233
+
234
+ ### Authoring
235
+
236
+ On the CLI, prefix a command with `kind:`. Entries without a prefix default to `custom`.
237
+
238
+ ```bash
239
+ sidecar task create \
240
+ --title "Add import flow" \
241
+ --summary "..." --goal "..." \
242
+ --validate-cmds "typecheck:tsc --noEmit,lint:eslint .,test:npm test"
243
+ ```
244
+
245
+ In a task packet JSON file, use the object form:
246
+
247
+ ```json
248
+ "execution": {
249
+ "commands": {
250
+ "validation": [
251
+ { "kind": "typecheck", "command": "tsc --noEmit" },
252
+ { "kind": "test", "command": "npm test", "timeout_ms": 900000 },
253
+ "bash scripts/smoke.sh"
254
+ ]
255
+ }
256
+ }
257
+ ```
258
+
259
+ String entries are accepted for back-compat (promoted to `{ kind: "custom", command }` on load).
260
+
261
+ ### Auto-approve on all-green
262
+
263
+ When every validation step passes for a run, Sidecar can auto-approve the run so you don't have to click through the review queue for a strictly-green outcome. It's opt-in:
264
+
265
+ ```json
266
+ // .sidecar/preferences.json
267
+ { "review": { "autoApproveOnAllGreen": true } }
268
+ ```
269
+
270
+ Behavior when enabled:
271
+
272
+ - The run's `review_state` flips to `approved`, `reviewed_by` is set to `sidecar:auto`, and the review note records how many steps passed.
273
+ - Runs with zero configured validation steps are **not** auto-approved — a runner-only success still requires a human click.
274
+ - Any failing step blocks the run as today (task moves to `blocked`, blocker message includes the kind).
275
+
276
+ ## Dual-runner pipelines
277
+
278
+ Pass a comma-separated list to `--runner` and Sidecar runs each runner sequentially on the same task, feeding the previous run's summary into the next runner's compiled prompt as linked context.
279
+
280
+ ```bash
281
+ sidecar run T-001 --runner codex,claude
282
+ sidecar run T-001 --runner codex,claude --agent-role builder-app --dry-run
283
+ ```
284
+
285
+ Each step produces its own run record linked back to the first run in the pipeline via `parent_run_id`. The CLI prints a one-line summary per step (runner, agent role, run id, status, duration, changed file count), and the full pipeline envelope is available with `--json`. Use this to pair a planner/builder runner with a reviewer runner, or to compare runners head-to-head on the same task.
286
+
287
+ ## Replay a run
288
+
289
+ When a run finishes (whether ok, blocked, or failed) you can kick off a fresh run with the **same task** and a link back to the original via `sidecar run replay`. It's the fastest way to try a different runner, re-run after fixing a blocker, or fork a green run into an experiment without losing the audit trail.
290
+
291
+ ```bash
292
+ sidecar run replay R-001 --reason "retry with claude after codex blocker"
293
+ sidecar run replay R-001 --runner claude --agent-role builder-app --edit-prompt
294
+ sidecar run replay R-001 --reason "dry-run with new validation" --dry-run
295
+ ```
296
+
297
+ Flags:
298
+
299
+ - `--runner codex|claude` — override the parent's runner (defaults to parent's runner).
300
+ - `--agent-role <role>` — override the parent's agent role.
301
+ - `--reason "<text>"` — stored on the new run as `replay_reason`; surfaced in CLI and UI.
302
+ - `--edit-prompt` — opens the compiled prompt in `$VISUAL`/`$EDITOR` before the runner starts so you can tweak it.
303
+ - `--dry-run` — compile the prompt and create the run record without executing the runner.
304
+ - `--json` — machine-readable envelope output.
305
+
306
+ The new run record carries `parent_run_id: "R-001"` plus your `replay_reason`. `sidecar run show <id>` renders the lineage both ways:
307
+
308
+ - The parent shows **Replayed as:** with each child run id.
309
+ - Each child shows **Replay of:** with the parent id and reason.
310
+
311
+ The UI's Run Detail panel mirrors this: `Replay of:` links back to the parent; `Replays:` lists every child with its status. Both are clickable for one-hop navigation through a lineage.
312
+
313
+ ## Ambient capture via Claude Code hooks
314
+
315
+ Sidecar can capture an ongoing Claude Code session into worklog/session records **without any explicit `sidecar worklog record` calls**. Once you wire Claude Code's hook system to `sidecar hook <event>`, every session start, file edit, and session end flows into your project memory automatically.
316
+
317
+ Print the ready-to-paste settings block:
318
+
319
+ ```bash
320
+ sidecar hooks print
321
+ ```
322
+
323
+ Paste the `hooks` object into `.claude/settings.json` (project) or `~/.claude/settings.json` (user). Claude Code merges hook arrays across scopes, so user-level and project-level hooks compose.
324
+
325
+ The template wires four events:
326
+
327
+ | Claude Code event | Sidecar hook | Effect |
328
+ | ------------------ | ---------------------- | ------------------------------------------------------------------ |
329
+ | `SessionStart` | `sidecar hook session-start` | Opens a Sidecar session (`actor=agent`, name `claude-code:<sid>`). Idempotent. |
330
+ | `SessionEnd` | `sidecar hook session-end` | Closes the active session. Safe to call when none is open. |
331
+ | `PostToolUse` (Edit\|Write\|MultiEdit\|NotebookEdit) | `sidecar hook file-edit` | Records a worklog `"Edited <path> via <tool>"` and links the file as an artifact. Lazy-opens a session if none is active. |
332
+ | `UserPromptSubmit` | `sidecar hook user-prompt` | Records the first 200 chars of the prompt as a note. |
333
+
334
+ Each hook:
335
+
336
+ - Reads its payload JSON from stdin (Claude Code supplies it automatically).
337
+ - **Always exits 0** — hooks never block the caller, even on internal errors.
338
+ - Accepts `--actor-name <name>` to override the default actor name.
339
+ - Accepts `--json` to emit a structured envelope (useful when testing).
340
+
341
+ Quick manual smoke test:
342
+
343
+ ```bash
344
+ echo '{"session_id":"abc"}' | sidecar hook session-start
345
+ echo '{"tool_name":"Edit","tool_input":{"file_path":"'"$PWD"'/README.md"}}' | sidecar hook file-edit
346
+ sidecar hook session-end
347
+ sidecar recent --type worklog --limit 3
348
+ ```
349
+
350
+ Codex users can invoke the same CLI from any shell hook or wrapper script — the payload schema is permissive, so a minimal `{"tool_input":{"file_path":"..."}}` works.
351
+
182
352
  ## Automatic prompt token budgeting
183
353
 
184
354
  When Sidecar compiles task prompts (`sidecar prompt compile` and run execution flows), it automatically applies a token budget to reduce context size without degrading execution quality.
@@ -202,6 +372,61 @@ Prompt optimization data is included in compile output and stored on run records
202
372
  - `prompt_budget_target`
203
373
  - `prompt_trimmed_sections`
204
374
 
375
+ ## Freestanding prompt specs
376
+
377
+ `sidecar prompt compile` also accepts a `.yaml`/`.yml`/`.json` spec file — no TaskPacket required. This lets you iterate on prompts directly, or compose them programmatically from another tool.
378
+
379
+ ```bash
380
+ sidecar prompt compile ./my-prompt.yaml
381
+ sidecar prompt compile ./my-prompt.yaml --explain
382
+ sidecar prompt compile ./my-prompt.yaml --budget 1500 --budget-max 2000
383
+ sidecar prompt compile ./my-prompt.yaml --section-policy notes=drop,examples=trim-last
384
+ sidecar prompt compile ./my-prompt.yaml -o out.md
385
+ sidecar prompt compile ./my-prompt.yaml --format json
386
+ ```
387
+
388
+ Spec schema:
389
+
390
+ ```yaml
391
+ header:
392
+ - "# My Prompt"
393
+ - "Optional preamble rendered verbatim."
394
+
395
+ sections:
396
+ - id: objective # optional — auto-slugified from title if omitted
397
+ title: Objective
398
+ required: true # forces policy=keep (never trimmed or dropped)
399
+ content: | # text section: string or string[]
400
+ Describe the goal in one or two sentences.
401
+
402
+ - title: Notes
403
+ list: # list section
404
+ - First note
405
+ - Second note
406
+ - Third note
407
+ empty_placeholder: "- no notes yet"
408
+ trim:
409
+ policy: trim-last # keep | trim-last | drop
410
+ limit: 2 # target-pass cap
411
+ limit_strict: 1 # safety-valve cap
412
+ overflow_label: notes # renders "+ N more notes (see task packet for full list)"
413
+
414
+ budget:
415
+ target: 1200 # soft target
416
+ max: 1500 # hard ceiling before strict pass
417
+
418
+ policy_overrides:
419
+ notes: keep # override per-section trim policies by id
420
+ ```
421
+
422
+ Trim policies:
423
+
424
+ - `keep` — never trim or drop (default for text sections and `required: true`)
425
+ - `trim-last` — apply `limit` on the target pass, `limit_strict` on the strict pass (lists only)
426
+ - `drop` — remove the whole section on the strict pass when still over budget
427
+
428
+ `--explain` prints a per-section trace (policy applied, tokens, items kept/total) to stderr. `--format json` emits the standard envelope with `markdown` + full `metadata.sections` trace for programmatic use.
429
+
205
430
  ## Example workflow
206
431
 
207
432
  ```bash
@@ -312,22 +537,26 @@ sidecar ui --project ../other-repo
312
537
  sidecar ui --reinstall
313
538
  ```
314
539
 
315
- Initial UI screens:
540
+ UI screens:
316
541
 
317
- - Overview: project info, active session, recent decisions/worklogs, open tasks, recent notes
318
- - Timeline: recent events in chronological order
319
- - Tasks: open and completed tasks
320
- - Decisions: decision records with summary and timestamps
321
- - Preferences: `.sidecar/preferences.json` and `.sidecar/summary.md`
542
+ - **Mission Control**: open tasks, ready queue, runs in flight, pipelines, and run review queue — the main operational surface.
543
+ - **Run Detail**: compiled prompt and runner log viewers, typed validation results (kind badges, exit code, duration, snippet), replay lineage (`Replay of:` / `Replays:`), and auto-approval markers.
544
+ - **Overview**: project info, active session, recent decisions/worklogs, open tasks, recent notes, and counts.
545
+ - **Timeline**: paginated event stream (load-more).
546
+ - **Tasks** and **Decisions**: list views with summary and timestamps.
547
+ - **Preferences**: edit `.sidecar/preferences.json` and view `.sidecar/summary.md`.
322
548
 
323
- UI write support (v1):
549
+ UI write support:
324
550
 
325
- - Add notes from Overview
326
- - Add open tasks from Overview
327
- - Edit `.sidecar/preferences.json` from Preferences
551
+ - Add notes and open tasks from Overview.
552
+ - Trigger `run replay` with optional reason, runner override, and agent-role override from Run Detail.
553
+ - Edit `.sidecar/preferences.json` from Preferences.
328
554
  - `output.humanTime` controls timestamp style in human-readable CLI output:
329
555
  - `true`: friendly local times (for example `3/18/2026, 11:51 AM`)
330
556
  - `false`: raw ISO-style timestamps
557
+ - `review.autoApproveOnAllGreen` — auto-approve runs when every validation step passes (see "Validation kinds and auto-approve").
558
+
559
+ See [packages/ui/UI.md](packages/ui/UI.md) for the full UI reference (state model, views, modals, HTTP API, accessibility).
331
560
 
332
561
  ## JSON output
333
562