docks-kit 0.3.0 → 0.5.0

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/AGENTS.md CHANGED
@@ -19,6 +19,7 @@ Tool-specific instructions live alongside this file:
19
19
  | `cli/` | Effect-TS CLI + bundled docs topics |
20
20
  | `SoT/models.json` | Kit-verified model catalog |
21
21
  | `SoT/toolchain.json` | Toolchain floors manifest (verified pins consumed by EngineNative) |
22
+ | `SoT/.claude/bin/` | Dependency-free Bun runtime programs for Claude's statusline, SessionStart, and Notification |
22
23
  | `install.sh` | Global installer |
23
24
  | `.github/workflows/release-cli.yml` | `cli-v*` release binaries + npm publish |
24
25
  | `README.md` | Front door |
@@ -31,11 +32,13 @@ Tool-specific instructions live alongside this file:
31
32
 
32
33
  Codex SoT notes:
33
34
  - `SoT/.codex/AGENTS.md` deploys to `~/.codex/AGENTS.md` as global Codex instructions.
34
- - `SoT/.codex/config.toml` pins Codex to `model = "gpt-5.5"`, sets reasoning effort/summaries (`xhigh` + `detailed`), `model_verbosity = "medium"` (Codex ships gpt-5.5 at `low`; medium restores the API default), `personality`, live top-level `web_search`, workspace-write sandboxing with sandboxed command network access, cross-session `memories` (+ dedicated note tools), `[agents]` subagent limits (`max_threads = 12`, `max_depth = 2` — intentionally above Codex defaults for broad parallel kit work; deeper recursion increases cost and predictability risk), a 128 KiB `project_doc_max_bytes` budget for the repo-side AGENTS.md chain (the global `~/.codex/AGENTS.md` is uncapped and not counted), and enables the Docks plugins as `docks@docks` + `session-relay@docks`.
35
+ - `SoT/.codex/config.toml` pins Codex to `model = "gpt-5.6-sol"`, sets reasoning effort/summaries (`xhigh` + `detailed`), `model_verbosity = "medium"`, `personality`, live top-level `web_search`, workspace-write sandboxing with sandboxed command network access, cross-session `memories` (+ dedicated note tools), `[agents]` subagent limits (`max_threads = 12`, `max_depth = 2` — intentionally above Codex defaults for broad parallel kit work; deeper recursion increases cost and predictability risk), a 128 KiB `project_doc_max_bytes` budget for the repo-side AGENTS.md chain (the global `~/.codex/AGENTS.md` is uncapped and not counted), and enables the Docks plugins as `docks@docks` + `session-relay@docks`.
35
36
  - `SoT/.codex/rules/*.rules` deploys to `~/.codex/rules/` as kit-managed Codex command policy. This is Codex's equivalent of permission allow/prompt/block rules; user-learned approvals in `~/.codex/rules/default.rules` are preserved.
36
37
  - `SoT/.codex/plugins/marketplace.json` deploys to Codex's personal marketplace path at `~/.agents/plugins/marketplace.json`; when the `codex` CLI is available, sync reruns `codex plugin add <plugin@marketplace>` for enabled SoT plugins so stale cached installs are refreshed.
37
38
  - The `codex` CLI binary is upstream-owned, not kit-owned. The official standalone installer keeps package metadata under `$CODEX_HOME/packages/standalone` and places the `codex` symlink in `~/.local/bin` by default; sync only warns with a download-then-run installer command when the CLI is missing. Existing installs can self-update with `codex update`; npm and Homebrew remain upstream alternatives.
38
39
  - `SoT/.codex/AGENTS.md` deliberately does not import `@RTK.md`: RTK's published Codex integration is prompt-file based rather than hook based, so importing it leaks implementation detail into agent-visible context. Use Codex hooks for RTK only after the kit installs a hook-backed Codex integration.
40
+ - Claude runtime settings are an authoring template with sentinels. `claudeRuntime.ts` materializes absolute Bun/script paths only after the shared `bun.ts` bootstrap is ready; `claudeSync.ts` writes all runtime assets before atomically committing settings, then prunes the legacy shell scripts and Stop hook. Native `rate_limits` is the sole quota source, so jq/curl/OAuth caches are not runtime dependencies. A missing Bun defers only this cutover and preserves legacy pointers/files.
41
+ - Claude's deployed SoT defaults are `model: fable` and `effortLevel: high`; `advisorModel` is deliberately absent/off. `--claude-advisor=on` is the per-machine opt-in and writes `advisorModel: fable` after the settings merge.
39
42
 
40
43
  For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT directory.
41
44
 
@@ -43,10 +46,10 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT d
43
46
 
44
47
  - **Idempotent operations.** Every EngineNative sync step must be safe to re-run. Settings merges, plugin installs, and marketplace adds are all idempotent — re-running with no SoT changes is a no-op.
45
48
  - **Removed bash engine.** The bash engine was removed after the `bash-engine-final` tag. `DOCKS_KIT_ENGINE=bash` must fail with the removed-engine message; engine bugs are fixed forward in EngineNative.
46
- - **Targeted syncs.** `./docks-kit sync` accepts positional targets: `claude`, `codex`, and `agents`. Use the narrowest target that matches the SoT change (for example, `./docks-kit sync codex` for Codex-only config edits); targets can be combined with `--dry-run`, `--skip-rtk`, `--reconcile`, `--prune`, `--yes` (auto-accept toolchain prompts), and the deploy-time modifiers `--claude-compact-window=<tokens>` / `--claude-permissive` / `--claude-model=<m>` / `--codex-model=<m>` (see `CLAUDE.md` § Deploy-time modifiers).
49
+ - **Targeted syncs.** `./docks-kit sync` accepts positional targets: `claude`, `codex`, and `agents`. Use the narrowest target that matches the SoT change (for example, `./docks-kit sync codex` for Codex-only config edits); targets can be combined with `--dry-run`, `--skip-rtk`, `--reconcile`, `--prune`, `--yes` (auto-accept toolchain prompts), and the deploy-time modifiers `--claude-compact-window=<tokens>` / `--claude-permissive` / `--claude-model=<m>` / `--claude-effort=<level>` / `--claude-advisor=<on|off|default>` / `--codex-model=<m>` / `--codex-effort=<level>` (see `CLAUDE.md` § Deploy-time modifiers).
47
50
  - **Additive by default.** Keys present in deployed config but absent from SoT are preserved on default sync. This protects user-only additions, but means drift accumulates — neither flag-less reset can clean it up. The one exception is the Claude `removed` manifest (`claude::_removed_manifest`), a curated list of unambiguous kit-owned artifacts that `claude::sync_removals` force-prunes on every sync; see `CLAUDE.md` § Pruning stale artifacts.
48
51
  - **`--reconcile` / `--prune` are the kit-owned reconcile flags.** Orthogonal — `--reconcile` reconciles the settings layer (SoT-declared keys/tables/arrays win; user-only keys and nested objects are preserved; permissions arrays are replaced wholesale by SoT). `--prune` uninstalls kit-managed installations not in the SoT (plugins, marketplaces, and `~/.agents/skills/*` entries tracked in `~/.agents/.kit-managed-skills`). Combine for a full reset to SoT's kit-managed scope. User-only additions outside the kit's scope (custom env vars, mcpServers, manually-installed skills, third-party plugins not declared in SoT) are always preserved. Each tool's per-tool file documents the specific paths and diff recipes.
49
- - **SOLID-aligned modules.** `cli/src/engine-native/parseArgs.ts` owns flag parsing/validation. `toolchain.ts` owns the verified-version gate over `SoT/toolchain.json`. `claudeSync.ts`, `codexSync.ts`, and `skillsSync.ts` own tool-specific sync logic. `index.ts` is the thin orchestrator. The public CLI seam is `cli/src/engine.ts`.
52
+ - **SOLID-aligned modules.** `cli/src/engine-native/parseArgs.ts` owns flag parsing/validation. `toolchain.ts` owns the verified-version gate over `SoT/toolchain.json`; `bun.ts` owns the shared, memoized Bun bootstrap; `claudeRuntime.ts` owns Claude settings materialization. `claudeSync.ts`, `codexSync.ts`, and `skillsSync.ts` own tool-specific sync logic. `index.ts` is the thin orchestrator. The public CLI seam is `cli/src/engine.ts`.
50
53
  - **Small, reviewable changes.** Bundled multi-concern PRs are harder to review and revert. Split an engine/CLI change and a per-tool config change unless the change requires atomicity.
51
54
  - **Dry-run before destructive flags.** Always preview with `./docks-kit sync --dry-run` (or the relevant `diff <(jq -S …)` recipe in the per-tool file) before invoking `--reconcile` or `--prune`. User-added permissions / env vars / plugins absent from SoT will be discarded.
52
55
  - **SoT prompt files are rules, not explanation.** `SoT/.claude/CLAUDE.md` and `SoT/.codex/AGENTS.md` are loaded into every agent session's prompt context — every line costs prompt tokens on every turn for every user. Restrict their content to rules, heuristics, and `<constraint>` blocks the agent must *act on* during a turn. Do NOT add inline source citations (`Source: …`, attributed quotes), "why this rule exists" preface text, version-watermarking trivia (e.g. "Distilled from X v2.0, captured 2025-11-07"), per-bug workarounds, or installation instructions. Provenance, motivation, and historical context belong in `CLAUDE.md` / `AGENTS.md` at the repo root (humans read once) or in commit messages — never in the SoT. For every line, apply the official test: would removing it cause the agent to make mistakes? If not, cut it — over-instruction degrades adherence on current frontier models.
@@ -75,7 +78,7 @@ This project ships **kit-mechanic skills** under `.claude/skills/` — narrowly-
75
78
  When a kit-mechanic skill, its `references/`, or a wrapper agent (`.claude/agents/*.md` + its `.codex/agents/*.toml` twin) cites EngineNative internals, name the **module + exported/local function + semantic anchor** (e.g. `claudeSync.ts syncPlugins, pass 5 uninstall guard`) — never a raw `file:NNN` line number, which goes stale on every refactor. Keep exactly one coarse `metadata.source_files[].lines` range per skill file as the sole intentional line-number touchpoint.
76
79
  </constraint>
77
80
 
78
- **Universal-skill bootstrap.** `SoT/.agents/skills.txt` declares [agentskills.io](https://agentskills.io/specification) slugs the kit installs to `~/.agents/skills/` on every machine via `skillsSync.ts`. The bootstrap invokes `npx skills add <slug> -g -y -a claude-code codex` per missing skill — `<slug>` comes first because the CLI's `-a/--agent` flag is variadic and would otherwise swallow it. Naming **both** agents (`claude-code` + `codex`, the kit's support matrix) keeps the CLI in multi-agent mode: it writes the canonical `SKILL.md` to the universal `~/.agents/skills/<name>/` path — which Codex reads natively (per [OpenAI's Codex docs](https://developers.openai.com/codex/skills/), `$HOME/.agents/skills` is a user-level skill source) — and symlinks `~/.claude/skills/<name>` → it for Claude Code, which wants its own per-tool directory. A *single* `-a claude-code` would instead trigger a copy-direct shortcut (a real copy into `~/.claude/skills/`, no canonical path, Codex uncovered); `-a '*'` would over-reach into every AI tool the CLI can detect (~50). Add a new universal skill by appending one `<owner>/<repo>` line to `skills.txt` and re-running `./docks-kit sync` — idempotent: existing skills are skipped after checking `~/.agents/skills/<name>`. Skills that depend on a separate CLI binary get an explicit auto-install helper in `skillsSync.ts` (e.g. `syncAgentBrowserCli` runs `npm install -g agent-browser` + `agent-browser install --with-deps` on Linux; the `--with-deps` flag may prompt for sudo to install system libs). That helper also **self-upgrades** a present-but-stale binary: when `agent-browser`'s installed version is older than npm's `latest` it re-runs `npm install -g agent-browser` (the numeric-sort compare never downgrades a locally-newer pre-release, and skips silently when npm is absent/offline); the Chrome download is not repeated on upgrade. A second helper, `syncEffectSolutionsCli`, installs the optional `effect-solutions` Effect-docs CLI used by the `effect-kit` plugin: gated on `effect-kit` being enabled in SoT, it auto-installs Bun when absent (download-then-run, never `curl | bash`) and symlinks **both** `bun` and the CLI into `~/.local/bin`. Linking bun too is mandatory — the CLI's `#!/usr/bin/env bun` shebang needs `bun` on PATH at run time — and `~/.local/bin` is the only dir reliably on the *non-interactive* agent PATH, since `~/.bashrc`'s "if not interactive, return" guard means rc PATH edits never reach agent shells (the same PATH reason the official Codex standalone installer targets `~/.local/bin`).
81
+ **Universal-skill bootstrap.** `SoT/.agents/skills.txt` declares [agentskills.io](https://agentskills.io/specification) slugs the kit installs to `~/.agents/skills/` on every machine via `skillsSync.ts`. The bootstrap invokes `npx skills add <slug> -g -y -a claude-code codex` per missing skill — `<slug>` comes first because the CLI's `-a/--agent` flag is variadic and would otherwise swallow it. Naming **both** agents (`claude-code` + `codex`, the kit's support matrix) keeps the CLI in multi-agent mode: it writes the canonical `SKILL.md` to the universal `~/.agents/skills/<name>/` path — which Codex reads natively (per [OpenAI's Codex docs](https://developers.openai.com/codex/skills/), `$HOME/.agents/skills` is a user-level skill source) — and symlinks `~/.claude/skills/<name>` → it for Claude Code, which wants its own per-tool directory. A *single* `-a claude-code` would instead trigger a copy-direct shortcut (a real copy into `~/.claude/skills/`, no canonical path, Codex uncovered); `-a '*'` would over-reach into every AI tool the CLI can detect (~50). Add a new universal skill by appending one `<owner>/<repo>` line to `skills.txt` and re-running `./docks-kit sync` — idempotent: existing skills are skipped after checking `~/.agents/skills/<name>`. Skills that depend on a separate CLI binary get an explicit auto-install helper in `skillsSync.ts` (e.g. `syncAgentBrowserCli` runs `npm install -g agent-browser` + `agent-browser install --with-deps` on Linux; the `--with-deps` flag may prompt for sudo to install system libs). That helper also **self-upgrades** a present-but-stale binary: when `agent-browser`'s installed version is older than npm's `latest` it re-runs `npm install -g agent-browser` (the numeric-sort compare never downgrades a locally-newer pre-release, and skips silently when npm is absent/offline); the Chrome download is not repeated on upgrade. A second helper, `syncEffectSolutionsCli`, installs the optional `effect-solutions` Effect-docs CLI used by the `effect-kit` plugin. It calls the shared `bun.ts` `bunBootstrap` when needed, then symlinks **both** `bun` and the CLI into `~/.local/bin`. Linking Bun too is mandatory — the CLI's `#!/usr/bin/env bun` shebang needs it on PATH at run time — and `~/.local/bin` is the only dir reliably on the *non-interactive* agent PATH, since `~/.bashrc`'s "if not interactive, return" guard means rc PATH edits never reach agent shells (the same PATH reason the official Codex standalone installer targets `~/.local/bin`).
79
82
 
80
83
  ## Plans
81
84
 
package/README.md CHANGED
@@ -29,8 +29,9 @@ Download the platform release binary from GitHub Releases and run it directly.
29
29
  The executable carries the generated sync payload; no checkout or adjacent
30
30
  `SoT/` directory is required.
31
31
 
32
- Prerequisites for source/global installs: Bun plus `jq` and `curl` for sync
33
- preflight; Node/npm for npm-global tools.
32
+ Prerequisites for source/global installs: Bun; Node/npm for npm-global tools.
33
+ `jq` is optional doctor/test tooling. `curl` is used only at requested POSIX
34
+ RTK/Bun download boundaries, not as a global sync prerequisite.
34
35
 
35
36
  ## CLI
36
37
 
@@ -83,12 +84,17 @@ and a later flag-less sync reverts them. Full reference: `docks-kit docs flags`
83
84
  when possible). `docks-kit toolchain check` shows the full table.
84
85
  - **Model catalog** — `SoT/models.json` is the research-verified source for
85
86
  model validation, listings, and pickers.
87
+ - **Claude runtime** — sync materializes three dependency-free Bun `.mjs`
88
+ programs for statusline, SessionStart, and Notification. Quota display uses
89
+ Claude's native `rate_limits`; there is no OAuth fetch, shared usage cache,
90
+ or Stop hook. If Bun cannot be resolved or bootstrapped, sync preserves a
91
+ working legacy hook/statusline setup and reports that migration is deferred.
86
92
 
87
93
  ## Repository map
88
94
 
89
95
  | Path | Purpose |
90
96
  |------|---------|
91
- | `SoT/.claude/` | Claude Code SoT (settings, hooks, status line, CLAUDE.md) |
97
+ | `SoT/.claude/` | Claude Code SoT (settings template, Bun runtime programs, CLAUDE.md) |
92
98
  | `SoT/.codex/` | Codex SoT (config.toml, rules, AGENTS.md, marketplace) |
93
99
  | `SoT/.agents/` | Universal-skill manifest |
94
100
  | `SoT/models.json` | Kit-verified model catalog |
package/cli/docs/flags.md CHANGED
@@ -27,12 +27,17 @@ docks-kit sync claude agents # two
27
27
  | Flag | Effect |
28
28
  |------|--------|
29
29
  | `--claude-model=<m>` | Deploy-time modifier: deployed model (aliases or full claude-* IDs; `default` unsets) |
30
+ | `--claude-effort=<level>` | Deploy-time modifier: `effortLevel`; valid `low`, `medium`, `high`, `xhigh`, or `default` (Claude SoT: `high`) |
31
+ | `--claude-advisor=<state>` | Deploy-time modifier: advisor `on`, `off`, or `default` (SoT off/unset) |
30
32
  | `--claude-compact-window=<n>` | Deploy-time modifier: autocompact window in tokens (`680000` or `680k`) |
31
33
  | `--claude-permissive` | Deploy-time modifier: empty permissions.ask/deny (sandboxes) |
32
34
  | `--claude-plugin=<name>` | Sticky opt-in plugin (known: supabase, n8n); comma-separate for several |
33
35
  | `--codex-model=<m>` | Deploy-time modifier: deployed Codex model |
36
+ | `--codex-effort=<level>` | Deploy-time modifier: `model_reasoning_effort`; valid `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, `ultra`, or `default` (Codex SoT: `xhigh`; model-dependent) |
34
37
 
35
- Bare `--claude-model` / `--codex-model` (no value) prints the model catalog.
38
+ Bare model, effort, or advisor modifiers print the relevant valid-value catalog
39
+ and exit 2. A modifier for a target not selected by the positional arguments is
40
+ ignored with a warning; Claude modifiers never touch Codex config and vice versa.
36
41
 
37
42
  ## Renamed legacy flags (pre-CLI sync.sh)
38
43
 
@@ -26,6 +26,30 @@ are versioned config snapshots without publishing the authoring `SoT/` tree.
26
26
  Kit-home resolution remains available for checkout/package update behavior and
27
27
  display paths, but sync reads do not depend on it.
28
28
 
29
+ ### Bun 1.3.14 blocked-postinstall notice
30
+
31
+ A supported global install may finish successfully with this exact notice:
32
+
33
+ ```
34
+ Blocked 1 postinstall. Run `bun pm -g untrusted` for details.
35
+ ```
36
+
37
+ For the pinned production dependency graph, the diagnostic names only:
38
+
39
+ ```
40
+ ./node_modules/@parcel/watcher @2.5.6
41
+ » [install]: node scripts/build-from-source.js
42
+ ```
43
+
44
+ `@parcel/watcher` is a transitive of the Effect Bun runtime. Supported default
45
+ installs already carry its platform prebuilt package, and that install script
46
+ only attempts a source build when `npm_config_build_from_source=true` was
47
+ explicitly requested. `esbuild` is not in the consumer production graph. The
48
+ blocked notice therefore needs no trust action for the supported default
49
+ install; `docks-kit --version`, model catalogs, toolchain checks, and real sync
50
+ remain functional with the script blocked. CI pins the one-package/one-command
51
+ identity above and will fail if the script-bearing set changes.
52
+
29
53
  ## 3. curl installer (Unix-only)
30
54
 
31
55
  ```
@@ -75,7 +99,9 @@ sync/config reads.
75
99
 
76
100
  ## Prerequisites
77
101
 
78
- - jq and curl (sync preflight checks them for the deployed assets and installers)
79
102
  - Bun for source/global installs; release binaries embed the runtime
80
103
  - Node/npm for npm-global tools (agent-browser, LSP servers)
104
+ - jq is optional doctor/test tooling; sync has no jq runtime dependency
105
+ - curl is required only when a requested POSIX RTK/Bun bootstrap must download
106
+ an installer; an already-present Bun does not require it
81
107
  - See `docks-kit toolchain check` for the full picture on this machine
@@ -18,8 +18,8 @@ the entry and date when a model ships or retires.
18
18
  ## The `best` alias and `default` pseudo-value
19
19
 
20
20
  - `best` resolves to Fable 5 where the org has access, latest Opus otherwise.
21
- Needs Claude Code >= 2.1.170. (The kit SoT default is `opus`, paired with
22
- the `fable` advisor see the advisor note below.)
21
+ Needs Claude Code >= 2.1.170. The kit SoT pins `fable` directly, so lack of
22
+ Fable access is surfaced instead of silently changing the configured model.
23
23
  - `default` is an engine pseudo-value: it DELETES the deployed `model` key so
24
24
  the account default applies. It never reaches the settings file as a value.
25
25
 
@@ -29,14 +29,14 @@ the entry and date when a model ships or retires.
29
29
  docks-kit models # both catalogs
30
30
  docks-kit models claude --json # machine-readable
31
31
  docks-kit model claude # current deployed + SoT + picker (TTY)
32
- docks-kit model claude fable # set deployed model
32
+ docks-kit model claude opus # per-machine override from the Fable SoT
33
33
  docks-kit sync claude --claude-model=opus # same, as part of a sync
34
34
  ```
35
35
 
36
36
  ## Advisor pairing note (Claude)
37
37
 
38
- The advisor model must be at least as capable as the main model; Fable
39
- outranks Opus, so an Opus main + Fable advisor works while Fable main +
40
- Opus advisor is rejected. The SoT ships `model: opus` + `advisorModel:
41
- fable` as the deployed-everywhere default; use settings.local.json only
42
- for a deliberate per-machine deviation.
38
+ The SoT ships `model: fable` with advisor off (`advisorModel` unset).
39
+ Advisor is a per-machine opt-in: `docks-kit sync claude --claude-advisor=on`
40
+ writes `advisorModel: fable`; `off` and `default` delete the key. Fable-main +
41
+ Fable-advisor is an accepted pairing. The advisor needs Fable org access and
42
+ Claude Code >= 2.1.170.
@@ -5,15 +5,32 @@ the SoT is never touched. They all share one contract:
5
5
 
6
6
  > A later flag-less sync reverts the modifier: the settings merge (Claude)
7
7
  > and the config.toml merge (Codex) re-assert SoT values for kit-owned keys.
8
- > Re-pass the flag on machines that should keep the override, or make it
9
- > persistent in `~/.claude/settings.local.json` (which sync never touches).
8
+ > Re-pass the flag on machines that should keep the override. Claude-only
9
+ > profiles can instead use `~/.claude/settings.local.json`, which sync never
10
+ > touches.
11
+
12
+ Claude's embedded SoT is `model: fable`, `effortLevel: high`, with advisor
13
+ off (`advisorModel` unset). Codex's embedded reasoning effort is `xhigh`.
10
14
 
11
15
  | Modifier | Deployed change | Typical use |
12
16
  |----------|-----------------|-------------|
13
- | `--claude-model=<m>` | `.model` in ~/.claude/settings.json (`default` deletes the key) | Drop one machine to opus while the SoT stays on `best` |
17
+ | `--claude-model=<m>` | `.model` in ~/.claude/settings.json (`default` deletes the key) | Override one machine while the SoT retains `fable` |
18
+ | `--claude-effort=<level>` | `.effortLevel` in ~/.claude/settings.json (`default` writes `high`) | Tune persisted Claude effort per machine; valid `low`, `medium`, `high`, `xhigh` |
19
+ | `--claude-advisor=<state>` | `on` sets `.advisorModel = "fable"`; `off`/`default` remove it | Enable Claude advisor only on machines that need it |
14
20
  | `--claude-compact-window=<n>` | `env.CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Disposable containers running long autonomous work (e.g. `680k`) — not host machines |
15
21
  | `--claude-permissive` | `permissions.ask = []`, `permissions.deny = []` | Sandboxes/containers where prompts stall unattended work. Never on a host — the deny list is the safety floor |
16
22
  | `--codex-model=<m>` | top-level `model = "…"` in ~/.codex/config.toml | Same as claude-model, for Codex |
23
+ | `--codex-effort=<level>` | top-level `model_reasoning_effort = "…"` (`default` writes `xhigh`) | Tune Codex effort per machine; valid `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, `ultra` (model-dependent) |
24
+
25
+ Bare effort/advisor flags print their verified catalog and exit 2. Invalid
26
+ values do the same with a clear error. Passing a tool-specific modifier without
27
+ selecting that positional target warns and ignores it.
28
+
29
+ A flag-less Claude sync also removes the formerly kit-owned `advisorModel`
30
+ from machines synced before advisor became opt-in. Any explicit advisor state
31
+ owns that key for the run: `on` writes `fable`; `off` and `default` delete it.
32
+ Codex has no advisor modifier because its documented config has no advisor
33
+ setting; `review_model` applies only to `/review`.
17
34
 
18
35
  ## Standalone get/set (no full sync)
19
36
 
@@ -9,7 +9,7 @@ AI-assisted dev environment on every machine.
9
9
 
10
10
  | Piece | Role |
11
11
  |-------|------|
12
- | `SoT/.claude/` | Claude Code config (settings, hooks, status line, CLAUDE.md) |
12
+ | `SoT/.claude/` | Claude Code config (settings template, Bun runtime programs, CLAUDE.md) |
13
13
  | `SoT/.codex/` | Codex config (config.toml, rules, AGENTS.md, marketplace) |
14
14
  | `SoT/.agents/` | Universal agent skills manifest (agentskills.io standard) |
15
15
  | `SoT/models.json` | Kit-verified model catalog (see `docks-kit docs models`) |
@@ -34,6 +34,9 @@ AI-assisted dev environment on every machine.
34
34
  EngineNative owns mutation. No-Bun recovery is a platform release binary.
35
35
  - **Authoring/runtime split**: changes begin in `SoT/`; build/prepack freshness
36
36
  checks keep the generated in-memory payload byte-identical for every runtime.
37
+ - **Native Claude runtime**: three dependency-free Bun `.mjs` programs own the
38
+ statusline, SessionStart, and Notification. Quotas come only from native
39
+ `rate_limits`; missing Bun defers cutover without deleting legacy fallbacks.
37
40
 
38
41
  ## Where to go next
39
42
 
@@ -33,8 +33,11 @@ CI coverage (all on the pinned windows-2025 label): EngineNative PowerShell
33
33
  smoke with `HOME` unset — `%USERPROFILE%` path resolution, `.cmd` tool
34
34
  spawning (npm), toolchain gate branches (`.github/workflows/parity.yml`,
35
35
  `native-windows` job); the two entrypoints above (`windows-entrypoints.yml`).
36
- Deployed hook/statusline assets stay shell scripts by design — Claude Code on
37
- Windows executes them through its own Git Bash.
36
+ Deployed SessionStart/Notification hooks directly exec an absolute real
37
+ `bun.exe`. Claude still shell-evaluates the statusline, so its stored command is
38
+ an encoded PowerShell missing-file guard that behaves identically when the outer
39
+ shell is native PowerShell or Git Bash. CI executes both outer-shell paths and
40
+ pins output bytes/channels plus latency ceilings.
38
41
 
39
42
  **Status: supported** — real-machine verified 2026-07-09 (Claude Code loads
40
43
  the synced `%USERPROFILE%\.claude`; full sync, self-update, plugin passes,
@@ -5,30 +5,41 @@ no target means all three.
5
5
 
6
6
  ## claude (→ ~/.claude, ~/.claude.json, shell rc)
7
7
 
8
- Order matters — toolchain first, config after:
8
+ Order matters — runtime readiness and settings form one transaction:
9
9
 
10
10
  1. **RTK** (toolchain-gated): install/upgrade, then `rtk init --global` on
11
11
  first install. Runs FIRST because rtk init rewrites settings.json — the
12
12
  later settings merge normalizes whatever it wrote.
13
- 2. Scripts (statusline, fetch-usage, notification.mp3), hooks, CLAUDE.md.
14
- 3. **settings.json merge** additive: SoT keys win, permissions arrays are
13
+ 2. Resolve/bootstrap pinned Bun, materialize the sentinel settings template,
14
+ and prepare the merged settings bytes without mutation. If Bun remains
15
+ unavailable, omit only the new runtime pointers and preserve legacy ones.
16
+ 3. When ready, write `bin/statusline.mjs`, `bin/session-start.mjs`,
17
+ `bin/notify.mjs`, and `notification.mp3`; deploy CLAUDE.md; atomically commit
18
+ settings.
19
+ 4. **settings.json merge semantics** — additive: SoT keys win, permissions arrays are
15
20
  unioned, user-only keys survive. `--reconcile` replaces permissions arrays
16
21
  wholesale instead.
17
- 4. **Deploy-time modifiers** (`--claude-compact-window`, `--claude-permissive`,
18
- `--claude-model`) deployed file only.
19
- 5. ~/.claude.json (showTurnDuration, user-scoped MCP servers), connector env
20
- export, removed-artifact pruning.
21
- 6. **Plugins**seven idempotent passes via the `claude plugin` CLI
22
+ 5. **Removed-artifact pruning** prune old shell assets, the Stop hook, and
23
+ stale kit-owned settings. A flag-less sync removes `advisorModel`; an
24
+ explicit advisor state excludes only that key so the modifier owns it.
25
+ 6. **Deploy-time modifiers** (`--claude-compact-window`, `--claude-permissive`,
26
+ `--claude-model`, `--claude-effort`, `--claude-advisor`) deployed file only.
27
+ 7. ~/.claude.json (showTurnDuration, user-scoped MCP servers) and connector env
28
+ export.
29
+ 8. **Plugins** — seven idempotent passes via the `claude plugin` CLI
22
30
  (marketplaces → install → update → [--prune: uninstall/remove] → re-assert
23
31
  SoT enabled-state). Optional opt-ins via `--claude-plugin=<name>`.
24
- 7. LSP server binaries (npm globals).
32
+ 9. LSP server binaries (npm globals).
33
+
34
+ The statusline reads Claude's native `rate_limits`. There is no OAuth request,
35
+ usage cache, jq/curl runtime dependency, or Stop fetch hook.
25
36
 
26
37
  ## codex (→ ~/.codex, ~/.agents/plugins)
27
38
 
28
39
  bubblewrap check (Linux), config.toml merge (top-level keys replaced
29
40
  per-key, [table] blocks replaced wholesale, user-only keys/tables preserved),
30
- `--codex-model` modifier, rules, AGENTS.md, personal marketplace file,
31
- `codex plugin add` refresh.
41
+ `--codex-model` then `--codex-effort` modifiers, rules, AGENTS.md, personal
42
+ marketplace file, `codex plugin add` refresh.
32
43
 
33
44
  ## agents (→ ~/.agents/skills, ~/.claude/skills symlinks)
34
45
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Field | Meaning |
6
6
  |-------|---------|
7
- | `kind` | `required` (preflight hard dep) / `check` (doctor visibility) / `managed` (kit installs + upgrades) / `pin` (no binary — a version pin for npx-invoked tools, e.g. `skills-cli`) |
7
+ | `kind` | `check` (doctor visibility) / `managed` (kit installs + upgrades) / `pin` (no binary — a version pin for npx-invoked tools, e.g. `skills-cli`) |
8
8
  | `policy` | `track` (upgrade toward latest, gated by `verified`) / `present` (install when missing, never upgrade) |
9
9
  | `floor` | Minimum acceptable version (below → upgrade automatically) |
10
10
  | `verified` | Last kit-tested version — the gate line |
@@ -31,10 +31,16 @@ now kit-approved" act.
31
31
  settings rewrite is normalized by the merge that follows. Pinned installs
32
32
  fetch the installer script from the version tag, not mutable master.
33
33
  - **bun** — policy `present`: bootstrap only (pinned to `verified` via the
34
- installer's `bun-vX.Y.Z` release-tag argument), never auto-upgraded.
34
+ installer's version argument), never auto-upgraded. `bun.ts` owns one
35
+ per-engine-run memo shared by Claude runtime, effect-solutions, and direct
36
+ toolchain ensure. Windows resolves only a real absolute `bun.exe` for hooks.
35
37
  - **effect-solutions**, **agent-browser** — policy `track`: self-upgrade
36
38
  toward npm latest, gated by their `verified` pins.
37
39
 
40
+ jq and curl are `check` rows, not global prerequisites. jq is not consumed by
41
+ normal sync. curl is checked only at a requested POSIX RTK/Bun installer
42
+ download boundary; Windows Bun bootstrap uses PowerShell's native download.
43
+
38
44
  ## Supply-chain stance
39
45
 
40
46
  Every kit-driven install is pinned to a `verified` version or gated by one —
@@ -5,6 +5,12 @@ import { existsSync } from "node:fs"
5
5
  import { join } from "node:path"
6
6
  import { bail, engine } from "../engine"
7
7
  import type { Logger } from "../engine-native/logger"
8
+ import {
9
+ advisorCatalog,
10
+ advisorFlagGrammar,
11
+ effortCatalog,
12
+ effortFlagGrammar
13
+ } from "../efforts"
8
14
  import { kitHome } from "../kitHome"
9
15
  import { modelCatalog, type Tool } from "../manifests"
10
16
  import { LoggerService } from "../services"
@@ -49,7 +55,7 @@ const LEGACY_HINTS: Record<string, string> = {
49
55
  "--agents": "--agents was renamed: pass the target as a word, e.g. 'sync agents'"
50
56
  }
51
57
 
52
- const catalogHint = (t: Tool): string => {
58
+ const modelCatalogHint = (t: Tool): string => {
53
59
  const c = modelCatalog(t)
54
60
  const list = c.models
55
61
  .map((m) => ` ${m.id}${m.note !== undefined ? ` — ${m.note}` : ""}`)
@@ -85,6 +91,14 @@ const claudeModel = Options.text("claude-model").pipe(
85
91
  Options.withDescription("Deploy-time modifier: set deployed Claude model (see `docks-kit models claude`)"),
86
92
  Options.optional
87
93
  )
94
+ const claudeEffort = Options.text("claude-effort").pipe(
95
+ Options.withDescription("Deploy-time modifier: set Claude effortLevel (bare flag shows valid levels)"),
96
+ Options.optional
97
+ )
98
+ const claudeAdvisor = Options.text("claude-advisor").pipe(
99
+ Options.withDescription("Deploy-time modifier: set Claude advisor on/off/default"),
100
+ Options.optional
101
+ )
88
102
  const claudeCompactWindow = Options.text("claude-compact-window").pipe(
89
103
  Options.withDescription("Deploy-time modifier: set deployed autocompact window in tokens (e.g. 680000 or 680k)"),
90
104
  Options.optional
@@ -102,6 +116,10 @@ const codexModel = Options.text("codex-model").pipe(
102
116
  Options.withDescription("Deploy-time modifier: set deployed Codex model (see `docks-kit models codex`)"),
103
117
  Options.optional
104
118
  )
119
+ const codexEffort = Options.text("codex-effort").pipe(
120
+ Options.withDescription("Deploy-time modifier: set Codex model_reasoning_effort (bare flag shows valid levels)"),
121
+ Options.optional
122
+ )
105
123
 
106
124
  export const syncCommand = Command.make(
107
125
  "sync",
@@ -114,10 +132,13 @@ export const syncCommand = Command.make(
114
132
  yes,
115
133
  verbose,
116
134
  claudeModel,
135
+ claudeEffort,
136
+ claudeAdvisor,
117
137
  claudeCompactWindow,
118
138
  claudePermissive,
119
139
  claudePlugin,
120
- codexModel
140
+ codexModel,
141
+ codexEffort
121
142
  },
122
143
  (config) =>
123
144
  Effect.gen(function* () {
@@ -125,7 +146,14 @@ export const syncCommand = Command.make(
125
146
  if (VALID_TARGETS.includes(t)) continue
126
147
  if (t === "--claude-model" || t === "--codex-model") {
127
148
  const tool: Tool = t === "--claude-model" ? "claude" : "codex"
128
- return yield* bail(`${catalogHint(tool)}\n${t} requires a value: ${t}=<model>`)
149
+ return yield* bail(`${modelCatalogHint(tool)}\n${t} requires a value: ${t}=<model>`)
150
+ }
151
+ if (t === "--claude-effort" || t === "--codex-effort") {
152
+ const tool: Tool = t === "--claude-effort" ? "claude" : "codex"
153
+ return yield* bail(`${effortCatalog(tool)}\n${t} requires a value: ${effortFlagGrammar(tool)}`)
154
+ }
155
+ if (t === "--claude-advisor") {
156
+ return yield* bail(`${advisorCatalog()}\n${t} requires a value: ${advisorFlagGrammar()}`)
129
157
  }
130
158
  const hint = LEGACY_HINTS[t]
131
159
  if (hint !== undefined) {
@@ -148,8 +176,11 @@ export const syncCommand = Command.make(
148
176
  if (config.verbose) args.push("--verbose")
149
177
  if (config.claudePermissive) args.push("--claude-permissive")
150
178
  Option.map(config.claudeModel, (m) => args.push(`--claude-model=${m}`))
179
+ Option.map(config.claudeEffort, (level) => args.push(`--claude-effort=${level}`))
180
+ Option.map(config.claudeAdvisor, (state) => args.push(`--claude-advisor=${state}`))
151
181
  Option.map(config.claudeCompactWindow, (w) => args.push(`--claude-compact-window=${w}`))
152
182
  Option.map(config.codexModel, (m) => args.push(`--codex-model=${m}`))
183
+ Option.map(config.codexEffort, (level) => args.push(`--codex-effort=${level}`))
153
184
  for (const occurrence of config.claudePlugin) {
154
185
  occurrence
155
186
  .split(",")
@@ -0,0 +1,91 @@
1
+ import { sotClaudeSettings, type Tool } from "./manifests"
2
+ import { payloadText } from "./payload"
3
+
4
+ export const CLAUDE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh"] as const
5
+ export const CODEX_REASONING_EFFORTS = [
6
+ "none",
7
+ "minimal",
8
+ "low",
9
+ "medium",
10
+ "high",
11
+ "xhigh",
12
+ "max",
13
+ "ultra"
14
+ ] as const
15
+ export const CLAUDE_ADVISOR_STATES = ["on", "off", "default"] as const
16
+
17
+ const VERIFIED = "2026-07-10"
18
+ const DEFAULT = "default"
19
+
20
+ export type ClaudeEffortLevel = typeof CLAUDE_EFFORT_LEVELS[number]
21
+ export type CodexReasoningEffort = typeof CODEX_REASONING_EFFORTS[number]
22
+ export type ClaudeAdvisorState = typeof CLAUDE_ADVISOR_STATES[number]
23
+
24
+ const upstreamEfforts = (tool: Tool): ReadonlyArray<string> =>
25
+ tool === "claude" ? CLAUDE_EFFORT_LEVELS : CODEX_REASONING_EFFORTS
26
+
27
+ export const effortModifierValues = (tool: Tool): ReadonlyArray<string> => [
28
+ ...upstreamEfforts(tool),
29
+ DEFAULT
30
+ ]
31
+
32
+ export const effortValueGrammar = (tool: Tool): string => effortModifierValues(tool).join("|")
33
+
34
+ export const effortFlagGrammar = (tool: Tool): string =>
35
+ `--${tool}-effort=<${effortValueGrammar(tool)}>`
36
+
37
+ export const advisorValueGrammar = (): string => CLAUDE_ADVISOR_STATES.join("|")
38
+
39
+ export const advisorFlagGrammar = (): string => `--claude-advisor=<${advisorValueGrammar()}>`
40
+
41
+ export const isEffortModifierValue = (tool: Tool, value: string): boolean =>
42
+ effortModifierValues(tool).includes(value)
43
+
44
+ export function validateEffortDefault(tool: Tool, value: unknown): string {
45
+ const toolName = tool === "claude" ? "Claude" : "Codex"
46
+ const setting = tool === "claude" ? "effortLevel" : "model_reasoning_effort"
47
+ if (typeof value !== "string" || value === "") {
48
+ throw new Error(`Embedded SoT ${toolName} ${setting} is missing`)
49
+ }
50
+ if (!upstreamEfforts(tool).includes(value)) {
51
+ throw new Error(`Embedded SoT ${toolName} ${setting} '${value}' is outside the verified catalog`)
52
+ }
53
+ return value
54
+ }
55
+
56
+ function codexSotEffort(): string | undefined {
57
+ return payloadText("SoT/.codex/config.toml").match(/^model_reasoning_effort\s*=\s*"([^"]+)"/m)?.[1]
58
+ }
59
+
60
+ export function sotEffort(tool: Tool): string {
61
+ const value = tool === "claude" ? sotClaudeSettings().effortLevel : codexSotEffort()
62
+ return validateEffortDefault(tool, value)
63
+ }
64
+
65
+ export function resolveEffort(tool: Tool, value: string): string {
66
+ if (value === DEFAULT) return sotEffort(tool)
67
+ if (!upstreamEfforts(tool).includes(value)) {
68
+ throw new Error(`Invalid ${tool} effort '${value}'`)
69
+ }
70
+ return value
71
+ }
72
+
73
+ export function effortCatalog(tool: Tool): string {
74
+ const setting = tool === "claude" ? "effortLevel" : "model_reasoning_effort"
75
+ const lines = [
76
+ `Available ${tool} effort levels (${setting}; verified ${VERIFIED}):`,
77
+ ...upstreamEfforts(tool).map((value) => ` ${value}`),
78
+ ` default — SoT: ${sotEffort(tool)}`
79
+ ]
80
+ if (tool === "codex") lines.push(" (support is model-dependent)")
81
+ return lines.join("\n")
82
+ }
83
+
84
+ export function advisorCatalog(): string {
85
+ return [
86
+ `Available claude advisor states (advisorModel; verified ${VERIFIED}):`,
87
+ " on — set advisorModel: fable",
88
+ " off — unset advisorModel",
89
+ " default — SoT: off (unset)"
90
+ ].join("\n")
91
+ }
@@ -27,9 +27,10 @@ explicit removed-engine diagnostic and exits 2 with the recovery tag message.
27
27
  - **Prove-red stays red.** The golden suites compare live native output to a
28
28
  mismatched golden under `--prove-red` and must exit non-zero after printing
29
29
  `prove-red OK`.
30
- - **Step ordering is load-bearing.** The Claude pipeline runs RTK before the
31
- settings merge, modifiers after it, removals before plugins, and LSP checks
32
- after plugin state.
30
+ - **Step ordering is load-bearing.** The Claude pipeline runs RTK, resolves Bun,
31
+ prepares materialized settings, writes runtime assets, commits settings, then
32
+ performs readiness-gated legacy cleanup. Modifiers run after the base commit,
33
+ removals before plugins, and LSP checks after plugin state.
33
34
  - **External CLIs stay external.** `claude`, `codex`, `npx`, `npm`, `rtk`,
34
35
  `bun`, `curl`, and platform package managers are spawned with argv arrays,
35
36
  not shell command strings except where the external installer contract is a
@@ -72,10 +73,12 @@ each such skip is an intentional behavior change named in its golden diff.
72
73
 
73
74
  ### Missing dependencies
74
75
 
75
- Exactly one deduplicated warn per missing tool per run, uniform shape:
76
+ Exactly one deduplicated warn per requested missing tool per run, uniform shape:
76
77
  `[warn] <tool> not installed — <platform-correct install command>`, sourced
77
- from the dependency registry (`deps.ts`). Required tools keep their current
78
- exit behavior the error carries the same install hint.
78
+ from the dependency registry (`deps.ts`). jq and curl are optional report rows:
79
+ jq has no runtime consumer, while curl warns only at a requested POSIX RTK/Bun
80
+ download boundary. A missing Bun defers Claude runtime migration without
81
+ deleting working legacy hooks or statusline files.
79
82
 
80
83
  ### Summary and next steps
81
84
 
@@ -114,15 +117,17 @@ active logger binding.
114
117
 
115
118
  | Module | Owns |
116
119
  |---|---|
117
- | `parseArgs.ts` | engine usage, target selection, flag parsing, legacy rename hints, preflight, model flag validation |
120
+ | `parseArgs.ts` | engine usage, target selection, flag parsing, legacy rename hints, model flag validation |
118
121
  | `index.ts` | sync orchestration, target dispatch, run summary and next-step blocks |
119
122
  | `../payload.ts` | generated text/byte payload reads and presentation-only source labels |
120
- | `claudeSync.ts` | Claude pipeline: RTK, assets, settings merge, deploy-time modifiers, `~/.claude.json`, connector env, removed artifacts, plugins, optional plugins, LSP binaries |
123
+ | `claudeSync.ts` | Claude pipeline: RTK, prepared settings transaction, runtime assets, deploy-time modifiers, `~/.claude.json`, readiness-gated removed artifacts, plugins, optional plugins, LSP binaries |
124
+ | `bun.ts` | per-run memoized Bun resolution/bootstrap shared by Claude runtime, effect-solutions, and direct toolchain ensure |
125
+ | `claudeRuntime.ts` | sentinel validation, absolute runtime paths, no-cutover settings projection, and POSIX/encoded-PowerShell statusline commands |
121
126
  | `settings.ts` | pure Claude settings merge/reconcile semantics and permission-array union |
122
127
  | `claudeModel.ts` | deployed Claude model modifier and direct `model claude` write path |
123
128
  | `codexSync.ts` | Codex pipeline: bubblewrap check, config merge, rules, AGENTS.md, personal marketplace, plugin refresh |
124
129
  | `codexToml.ts` | line-based top-level TOML replacement and deployed Codex model modifier |
125
- | `skillsSync.ts` | universal skill install/prune, Claude symlink healing, agent-browser/effect-solutions/Bun helpers, managed-skill snapshot |
130
+ | `skillsSync.ts` | universal skill install/prune, Claude symlink healing, agent-browser/effect-solutions callbacks, managed-skill snapshot |
126
131
  | `toolchain.ts` | tool presence/version probes, verified-version gate, managed install/upgrade orchestration, report table |
127
132
  | `modes.ts` | direct `model` and `toolchain` modes |
128
133
  | `models.ts` | model catalog listing and validation |
@@ -142,8 +147,9 @@ active logger binding.
142
147
  - Symlink creation falls back to copy where the platform or permissions require
143
148
  it.
144
149
  - Bubblewrap and shell-rc work are Linux/macOS only.
145
- - Claude hook/statusline assets remain shell scripts because Claude Code owns
146
- that runtime.
150
+ - Claude command hooks directly exec the resolved absolute `bun.exe`; the
151
+ statusline stores an encoded PowerShell missing-file guard because Claude
152
+ shell-evaluates `statusLine.command` through PowerShell or Git Bash.
147
153
 
148
154
  ## Tests
149
155
 
@@ -153,8 +159,9 @@ active logger binding.
153
159
  - `bun run golden:mutation` compares live native mutation snapshots, argv logs,
154
160
  output, and TOML invariants to `cli/test/goldens/mutation.json`.
155
161
  - `.github/workflows/parity.yml` is now the golden-regression workflow: Linux
156
- runs unit + golden + prove-red; the `native-windows` job runs PowerShell
157
- smoke checks for native Windows behavior.
162
+ runs unit + golden + prove-red plus the exact materialized POSIX runtime
163
+ commands; the `native-windows` job executes the same stored statusline command
164
+ through PowerShell and Git Bash plus direct Bun hooks.
158
165
  - `.github/workflows/windows-entrypoints.yml` verifies the release binary and
159
166
  `bun add -g` entrypoints on Windows.
160
167
 
@@ -162,5 +169,5 @@ active logger binding.
162
169
 
163
170
  - Reintroducing the removed shell engine as a supported fallback. Fix forward in
164
171
  EngineNative; recover historical source only from `bash-engine-final`.
165
- - Porting Claude Code's hook/statusline shell assets.
172
+ - Adding a compiled runner or CLI hook subcommand for Claude's Bun runtime.
166
173
  - Adding new sync features while changing the engine contract.