docks-kit 0.14.2 → 0.14.3
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 +3 -4
- package/README.md +5 -5
- package/cli/docs/flags.md +1 -2
- package/cli/docs/install.md +2 -2
- package/cli/docs/sync-layers.md +9 -12
- package/cli/docs/toolchain.md +10 -13
- package/cli/src/commands/sync.ts +5 -5
- package/cli/src/commands/toolchain.ts +1 -1
- package/cli/src/commands/update.ts +28 -2
- package/cli/src/engine-native/DESIGN.md +24 -15
- package/cli/src/engine-native/claudeSync.ts +70 -114
- package/cli/src/engine-native/codexSync.ts +7 -3
- package/cli/src/engine-native/deps.ts +21 -45
- package/cli/src/engine-native/index.ts +33 -8
- package/cli/src/engine-native/logger.ts +73 -10
- package/cli/src/engine-native/modes.ts +2 -7
- package/cli/src/engine-native/parseArgs.ts +5 -5
- package/cli/src/engine-native/skillsSync.ts +18 -52
- package/cli/src/engine-native/toolchain.ts +7 -3
- package/cli/src/generated/sotPayload.ts +4 -4
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -7,7 +7,7 @@ Canonical instructions for coding agents working on this project. Compatible wit
|
|
|
7
7
|
Portable configuration kit for AI coding agents. Per-tool Single Source of Truth (SoT) directories get deployed to each tool's user-config location via `./docks-kit sync` — clone once and get a consistent AI-assisted dev environment across supported Linux and macOS hosts. The kit focuses on **token efficiency without sacrificing quality**: every setting and hook is tuned to minimize token consumption while preserving rigorous output. When adding or editing anything, ask: *does this change reduce tokens without weakening correctness?*
|
|
8
8
|
|
|
9
9
|
Tool-specific instructions live alongside this file:
|
|
10
|
-
- **`CLAUDE.md`** — Claude Code SoT (`SoT/.claude/`), env vars, hooks, plugins,
|
|
10
|
+
- **`CLAUDE.md`** — Claude Code SoT (`SoT/.claude/`), env vars, hooks, plugins, status line, session management, permission mode, open concerns.
|
|
11
11
|
- Codex uses this `AGENTS.md` file plus the Codex SoT under `SoT/.codex/`; no separate root `CODEX.md` is needed.
|
|
12
12
|
|
|
13
13
|
|
|
@@ -42,7 +42,6 @@ Codex SoT notes:
|
|
|
42
42
|
- `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.
|
|
43
43
|
- The global prompt SoTs carry the owner's standing authorization for Docks cross-company plan review, which never overrides host or platform denial.
|
|
44
44
|
- 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.
|
|
45
|
-
- Neither global prompt SoT imports `@RTK.md`; Claude uses the hook-backed RTK integration, while Codex has no kit-managed RTK integration.
|
|
46
45
|
- 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.
|
|
47
46
|
- Claude's deployed SoT defaults are `model: opus` 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. `opus` is the alias, not a pinned id: the `minimumVersion` floor of 2.1.219 ensures Claude Code can resolve it to the newest Opus its provider offers — Opus 5 on the Anthropic API or Opus 4.6 on Microsoft Foundry — instead of silently capping Anthropic API users at Opus 4.8 under the former 2.1.170 floor. Keeping the alias provides provider portability and tracks future Opus releases; the literal `claude-opus-5` is unavailable on Foundry. The floor also subsumes Fable 5's older 2.1.170 requirement.
|
|
48
47
|
|
|
@@ -52,7 +51,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT d
|
|
|
52
51
|
|
|
53
52
|
- **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.
|
|
54
53
|
- **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.
|
|
55
|
-
- **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-
|
|
54
|
+
- **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-bubblewrap` (skip optional bubblewrap bootstrap for the Codex Linux sandbox), `--skip-plugin-refresh` (install missing plugins without refreshing existing caches; used by `docks-kit update`), `--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).
|
|
56
55
|
- **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, including the home-relative `~/.local/bin/session-relay` artifact installed outside `~/.claude`; see `CLAUDE.md` § Pruning stale artifacts.
|
|
57
56
|
- **`--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.
|
|
58
57
|
- **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`.
|
|
@@ -69,7 +68,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT d
|
|
|
69
68
|
## Security
|
|
70
69
|
|
|
71
70
|
- No secrets in SoT. The kit's SoT directories are committed; treat them as declarative config only.
|
|
72
|
-
- Treat external
|
|
71
|
+
- Treat external plugin marketplaces and installer downloads as untrusted input. Prefer download-then-run over `curl … | bash` so a truncated stream cannot execute a partial script.
|
|
73
72
|
- **Pin, never float.** Every kit-driven install is pinned to a `SoT/toolchain.json` `verified` version or gated by one — no `@latest` npm/bun installs (Shai-Hulud-class worm surface), no mutable action tags in workflows (commit SHAs only), installer scripts fetched from version tags where upstream supports it. New install surface ⇒ manifest pin first. Details: the `toolchain-context` skill and `cli/docs/toolchain.md`.
|
|
74
73
|
|
|
75
74
|
## Testing
|
package/README.md
CHANGED
|
@@ -34,8 +34,8 @@ The executable carries the generated sync payload; no checkout or adjacent
|
|
|
34
34
|
`SoT/` directory is required.
|
|
35
35
|
|
|
36
36
|
Prerequisites for source/global installs: Bun; Node/npm for npm-global tools.
|
|
37
|
-
`jq` is optional doctor/test tooling. `curl` is used only
|
|
38
|
-
|
|
37
|
+
`jq` is optional doctor/test tooling. `curl` is used only when a requested
|
|
38
|
+
Linux/macOS Bun bootstrap must download an installer.
|
|
39
39
|
|
|
40
40
|
## CLI
|
|
41
41
|
|
|
@@ -68,7 +68,7 @@ golden-regression coverage for dry-run output, mutation snapshots, and argv logs
|
|
|
68
68
|
| `--claude-permissive` | Deploy-time modifier: empty ask/deny (sandboxes only) |
|
|
69
69
|
| `--claude-plugin=<name>` | Sticky opt-in plugin (supabase, n8n) |
|
|
70
70
|
| `--codex-model=<m>` | Deploy-time modifier: deployed Codex model |
|
|
71
|
-
| `--skip-
|
|
71
|
+
| `--skip-bubblewrap` | Skip optional bubblewrap bootstrap (Codex Linux sandbox) |
|
|
72
72
|
| `--skip-plugin-refresh` | Install missing plugins but skip refresh-only updates (used automatically by `docks-kit update`) |
|
|
73
73
|
| `--yes` | Auto-accept toolchain prompts (CI/containers) |
|
|
74
74
|
|
|
@@ -82,7 +82,7 @@ and a later flag-less sync reverts them. Full reference: `docks-kit docs flags`
|
|
|
82
82
|
survive a plain sync. Reconciliation toward the SoT is explicit
|
|
83
83
|
(`--reconcile` / `--prune`).
|
|
84
84
|
- **Idempotent** — every step is safe to re-run; no-change syncs are no-ops.
|
|
85
|
-
- **Toolchain floors** — external tools (
|
|
85
|
+
- **Toolchain floors** — external tools (bun, bwrap,
|
|
86
86
|
effect-solutions, …) install/upgrade against `SoT/toolchain.json`:
|
|
87
87
|
versions above the kit-verified pin prompt before installing
|
|
88
88
|
(`--yes` accepts; non-TTY falls back to the pinned verified version
|
|
@@ -128,7 +128,7 @@ Details: `docks-kit docs platforms`.
|
|
|
128
128
|
Tagging `cli-v*` builds four standalone binaries (Linux x64/arm64 and macOS
|
|
129
129
|
x64/arm64) plus `SHA256SUMS` and attaches them to the GitHub release; npm
|
|
130
130
|
publishes the exact package tarball through trusted publishing with OIDC provenance.
|
|
131
|
-
Package `docks-kit` 0.14.
|
|
131
|
+
Package `docks-kit` 0.14.3 bundles the CLI + generated payload, so npm releases
|
|
132
132
|
are versioned config snapshots without shipping the authoring `SoT/` tree.
|
|
133
133
|
|
|
134
134
|
## Deeper docs
|
package/cli/docs/flags.md
CHANGED
|
@@ -18,7 +18,7 @@ docks-kit sync claude agents # two
|
|
|
18
18
|
| `--dry-run` | Preview without applying |
|
|
19
19
|
| `--reconcile` | Settings layer reconciled toward SoT (SoT keys win; user-only keys preserved; permissions arrays replaced) |
|
|
20
20
|
| `--prune` | Uninstall kit-managed installs not in SoT: plugins, marketplaces, universal skills |
|
|
21
|
-
| `--skip-
|
|
21
|
+
| `--skip-bubblewrap` | Skip optional bubblewrap bootstrap (Codex Linux sandbox) |
|
|
22
22
|
| `--skip-plugin-refresh` | Install missing Claude/Codex plugins but skip refresh-only updates; `docks-kit update` uses this automatically |
|
|
23
23
|
| `--yes` | Auto-accept toolchain above-verified prompts (containers/CI) |
|
|
24
24
|
| `--verbose` / `-v` | Also print no-op confirmations (already in sync, up to date, left as-is); accepted on `sync`, `model`, and `toolchain` |
|
|
@@ -52,4 +52,3 @@ Old flags exit with a rename hint — there is no compat behavior.
|
|
|
52
52
|
| `--680k` | `--claude-compact-window=680k` |
|
|
53
53
|
| `--permissive` | `--claude-permissive` |
|
|
54
54
|
| `--supabase` / `--n8n` | `--claude-plugin=supabase` / `--claude-plugin=n8n` |
|
|
55
|
-
| `--no-rtk` | `--skip-rtk` |
|
package/cli/docs/install.md
CHANGED
|
@@ -94,8 +94,8 @@ sync/config reads.
|
|
|
94
94
|
## Prerequisites
|
|
95
95
|
|
|
96
96
|
- Bun for source/global installs; release binaries embed the runtime
|
|
97
|
-
- Node/npm for npm-global
|
|
97
|
+
- Node/npm for npm-global LSP servers
|
|
98
98
|
- jq is optional doctor/test tooling; sync has no jq runtime dependency
|
|
99
|
-
- curl is required only when a requested Linux/macOS
|
|
99
|
+
- curl is required only when a requested Linux/macOS Bun bootstrap must download
|
|
100
100
|
an installer; an already-present Bun does not require it
|
|
101
101
|
- See `docks-kit toolchain check` for the full picture on this machine
|
package/cli/docs/sync-layers.md
CHANGED
|
@@ -7,31 +7,28 @@ no target means all three.
|
|
|
7
7
|
|
|
8
8
|
Order matters — runtime readiness and settings form one transaction:
|
|
9
9
|
|
|
10
|
-
1.
|
|
11
|
-
first install. Runs FIRST because rtk init rewrites settings.json — the
|
|
12
|
-
later settings merge normalizes whatever it wrote.
|
|
13
|
-
2. Resolve/bootstrap pinned Bun, materialize the sentinel settings template,
|
|
10
|
+
1. Resolve/bootstrap pinned Bun, materialize the sentinel settings template,
|
|
14
11
|
and prepare the merged settings bytes without mutation. If Bun remains
|
|
15
12
|
unavailable, omit only the new runtime pointers and preserve legacy ones.
|
|
16
|
-
|
|
13
|
+
2. When ready, write `bin/statusline.mjs`, `bin/session-start.mjs`,
|
|
17
14
|
`bin/notify.mjs`, and `notification.mp3`; deploy CLAUDE.md; atomically commit
|
|
18
15
|
settings.
|
|
19
|
-
|
|
16
|
+
3. **settings.json merge semantics** — additive: SoT keys win, permissions arrays are
|
|
20
17
|
unioned, user-only keys survive. `--reconcile` replaces permissions arrays
|
|
21
18
|
wholesale instead.
|
|
22
|
-
|
|
19
|
+
4. **Removed-artifact pruning** — prune old shell assets, the Stop hook, stale
|
|
23
20
|
kit-owned settings, retired kit-owned plugin enablement, and the stale
|
|
24
21
|
`~/.local/bin/session-relay` command. A flag-less sync removes
|
|
25
22
|
`advisorModel`; an explicit advisor state excludes only that key so the
|
|
26
23
|
modifier owns it.
|
|
27
|
-
|
|
24
|
+
5. **Deploy-time modifiers** (`--claude-compact-window`, `--claude-permissive`,
|
|
28
25
|
`--claude-model`, `--claude-effort`, `--claude-advisor`) — deployed file only.
|
|
29
|
-
|
|
26
|
+
6. ~/.claude.json (showTurnDuration, user-scoped MCP servers) and connector env
|
|
30
27
|
export.
|
|
31
|
-
|
|
28
|
+
7. **Plugins** — seven idempotent passes via the `claude plugin` CLI
|
|
32
29
|
(marketplaces → install → update → [--prune: uninstall/remove] → re-assert
|
|
33
30
|
SoT enabled-state). Optional opt-ins via `--claude-plugin=<name>`.
|
|
34
|
-
|
|
31
|
+
8. LSP server binaries (npm globals).
|
|
35
32
|
|
|
36
33
|
The statusline reads Claude's native `rate_limits`. There is no OAuth request,
|
|
37
34
|
usage cache, jq/curl runtime dependency, or Stop fetch hook.
|
|
@@ -47,7 +44,7 @@ and `codex plugin add` refresh.
|
|
|
47
44
|
## agents (→ ~/.agents/skills, ~/.claude/skills symlinks)
|
|
48
45
|
|
|
49
46
|
`npx skills add` per missing manifest slug, Claude symlink healing,
|
|
50
|
-
|
|
47
|
+
the effect-solutions CLI (toolchain-gated), and the
|
|
51
48
|
kit-managed snapshot that `--prune` reconciles against.
|
|
52
49
|
|
|
53
50
|
## Reconcile flags
|
package/cli/docs/toolchain.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
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 |
|
|
11
|
-
| `pinnable` | Whether an exact version can be installed
|
|
11
|
+
| `pinnable` | Whether an exact version can be installed |
|
|
12
12
|
|
|
13
13
|
## The gate
|
|
14
14
|
|
|
@@ -26,20 +26,16 @@ now kit-approved" act.
|
|
|
26
26
|
|
|
27
27
|
## Managed tools
|
|
28
28
|
|
|
29
|
-
- **rtk** — PreToolUse hook (supply-chain sensitive: review releases before
|
|
30
|
-
bumping `verified`). Runs FIRST in the claude sync so `rtk init`'s
|
|
31
|
-
settings rewrite is normalized by the merge that follows. Pinned installs
|
|
32
|
-
fetch the installer script from the version tag, not mutable master.
|
|
33
29
|
- **bun** — policy `present`: bootstrap only (pinned to `verified` via the
|
|
34
30
|
installer's version argument), never auto-upgraded. `bun.ts` owns one
|
|
35
31
|
per-engine-run memo shared by Claude runtime, effect-solutions, and direct
|
|
36
32
|
toolchain ensure on supported Linux/macOS hosts.
|
|
37
|
-
- **effect-solutions
|
|
38
|
-
|
|
33
|
+
- **effect-solutions** — policy `track`: self-upgrades toward npm latest,
|
|
34
|
+
gated by its `verified` pin.
|
|
39
35
|
|
|
40
36
|
jq and curl are `check` rows, not global prerequisites. jq is not consumed by
|
|
41
|
-
normal sync. curl is checked only
|
|
42
|
-
download
|
|
37
|
+
normal sync. curl is checked only when a requested Linux/macOS Bun bootstrap
|
|
38
|
+
must download an installer.
|
|
43
39
|
|
|
44
40
|
## Supply-chain stance
|
|
45
41
|
|
|
@@ -52,8 +48,9 @@ probe falls back to the pinned `verified`, never to an ungated latest.
|
|
|
52
48
|
|
|
53
49
|
## Commands
|
|
54
50
|
|
|
55
|
-
```
|
|
56
|
-
docks-kit toolchain check
|
|
57
|
-
docks-kit toolchain ensure
|
|
58
|
-
docks-kit
|
|
51
|
+
```text
|
|
52
|
+
docks-kit toolchain check # doctor table (also inside docks-kit status)
|
|
53
|
+
docks-kit toolchain ensure bun # ensure one supported managed tool
|
|
54
|
+
docks-kit toolchain ensure effect-solutions # ensure the other supported managed tool
|
|
55
|
+
docks-kit sync --yes # unattended: auto-accept gates
|
|
59
56
|
```
|
package/cli/src/commands/sync.ts
CHANGED
|
@@ -49,7 +49,7 @@ const LEGACY_HINTS: Record<string, string> = {
|
|
|
49
49
|
"--permissive": "--permissive was renamed to --claude-permissive",
|
|
50
50
|
"--supabase": "--supabase was renamed to --claude-plugin=supabase",
|
|
51
51
|
"--n8n": "--n8n was renamed to --claude-plugin=n8n",
|
|
52
|
-
"--
|
|
52
|
+
"--skip-rtk": "--skip-rtk was renamed to --skip-bubblewrap",
|
|
53
53
|
"--claude": "--claude was renamed: pass the target as a word, e.g. 'sync claude'",
|
|
54
54
|
"--codex": "--codex was renamed: pass the target as a word, e.g. 'sync codex'",
|
|
55
55
|
"--agents": "--agents was renamed: pass the target as a word, e.g. 'sync agents'"
|
|
@@ -77,8 +77,8 @@ const reconcile = Options.boolean("reconcile").pipe(
|
|
|
77
77
|
const prune = Options.boolean("prune").pipe(
|
|
78
78
|
Options.withDescription("Uninstall kit-managed installs not in SoT (plugins, marketplaces, universal skills)")
|
|
79
79
|
)
|
|
80
|
-
const
|
|
81
|
-
Options.withDescription("Skip optional
|
|
80
|
+
const skipBubblewrap = Options.boolean("skip-bubblewrap").pipe(
|
|
81
|
+
Options.withDescription("Skip optional bubblewrap bootstrap (Codex Linux sandbox)")
|
|
82
82
|
)
|
|
83
83
|
const skipPluginRefresh = Options.boolean("skip-plugin-refresh").pipe(
|
|
84
84
|
Options.withDescription("Install missing plugins but skip refresh-only updates for existing plugins")
|
|
@@ -131,7 +131,7 @@ export const syncCommand = Command.make(
|
|
|
131
131
|
dryRun,
|
|
132
132
|
reconcile,
|
|
133
133
|
prune,
|
|
134
|
-
|
|
134
|
+
skipBubblewrap,
|
|
135
135
|
skipPluginRefresh,
|
|
136
136
|
yes,
|
|
137
137
|
verbose,
|
|
@@ -175,7 +175,7 @@ export const syncCommand = Command.make(
|
|
|
175
175
|
if (config.dryRun) args.push("--dry-run")
|
|
176
176
|
if (config.reconcile) args.push("--reconcile")
|
|
177
177
|
if (config.prune) args.push("--prune")
|
|
178
|
-
if (config.
|
|
178
|
+
if (config.skipBubblewrap) args.push("--skip-bubblewrap")
|
|
179
179
|
if (config.skipPluginRefresh) args.push("--skip-plugin-refresh")
|
|
180
180
|
if (config.yes) args.push("--yes")
|
|
181
181
|
if (config.verbose) args.push("--verbose")
|
|
@@ -2,7 +2,7 @@ import { Args, Command, Options } from "@effect/cli"
|
|
|
2
2
|
import { Effect, Option } from "effect"
|
|
3
3
|
import { bail, engine } from "../engine"
|
|
4
4
|
|
|
5
|
-
const MANAGED = ["
|
|
5
|
+
const MANAGED = ["bun", "effect-solutions"]
|
|
6
6
|
|
|
7
7
|
const op = Args.text({ name: "op" }).pipe(
|
|
8
8
|
Args.withDescription("check (default) | ensure <tool>"),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Options } from "@effect/cli"
|
|
2
2
|
import { Console, Effect } from "effect"
|
|
3
3
|
import { spawnSync } from "node:child_process"
|
|
4
|
-
import { existsSync } from "node:fs"
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs"
|
|
5
5
|
import { join } from "node:path"
|
|
6
6
|
import { bail, compiled } from "../engine"
|
|
7
7
|
import { kitHome } from "../kitHome"
|
|
@@ -32,6 +32,27 @@ export const updateSyncArgs = (home: string): Array<string> => [
|
|
|
32
32
|
"--skip-plugin-refresh"
|
|
33
33
|
]
|
|
34
34
|
|
|
35
|
+
const readPackageVersion = (home: string): string => {
|
|
36
|
+
try {
|
|
37
|
+
const doc: unknown = JSON.parse(readFileSync(join(home, "package.json"), "utf8"))
|
|
38
|
+
if (doc === null || typeof doc !== "object" || !("version" in doc)) return ""
|
|
39
|
+
return typeof doc.version === "string" ? doc.version : ""
|
|
40
|
+
} catch {
|
|
41
|
+
return ""
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const packageUpdateResult = (
|
|
46
|
+
before: string,
|
|
47
|
+
after: string
|
|
48
|
+
): { alreadyCurrent: boolean; message: string } => {
|
|
49
|
+
if (before === "" || after === "") return { alreadyCurrent: false, message: "" }
|
|
50
|
+
if (before === after) {
|
|
51
|
+
return { alreadyCurrent: true, message: `Already at the latest version (${after}).` }
|
|
52
|
+
}
|
|
53
|
+
return { alreadyCurrent: false, message: `Updated ${before} -> ${after}.` }
|
|
54
|
+
}
|
|
55
|
+
|
|
35
56
|
const updateCheckout = (home: string, skipSync: boolean) =>
|
|
36
57
|
Effect.gen(function* () {
|
|
37
58
|
if (spawnSync("git", ["--version"], { stdio: "ignore" }).status !== 0) {
|
|
@@ -52,7 +73,7 @@ const updateCheckout = (home: string, skipSync: boolean) =>
|
|
|
52
73
|
const after = git(home, ["rev-parse", "HEAD"]).out
|
|
53
74
|
|
|
54
75
|
if (before === after) {
|
|
55
|
-
return yield* Console.log(`Already
|
|
76
|
+
return yield* Console.log(`Already at the latest version (${after.slice(0, 7)}, upstream ${upstream.out}).`)
|
|
56
77
|
}
|
|
57
78
|
|
|
58
79
|
const count = git(home, ["rev-list", "--count", `${before}..${after}`]).out
|
|
@@ -89,12 +110,17 @@ const updatePackage = (home: string, skipSync: boolean) =>
|
|
|
89
110
|
home.includes("\\.bun\\") ||
|
|
90
111
|
underEnvDir("BUN_INSTALL_GLOBAL_DIR") ||
|
|
91
112
|
underEnvDir("BUN_INSTALL")
|
|
113
|
+
const beforeVersion = readPackageVersion(home)
|
|
92
114
|
const res = viaBun
|
|
93
115
|
? spawnSync("bun", ["add", "-g", "docks-kit@latest"], { stdio: "inherit" })
|
|
94
116
|
: spawnSync("npm", ["install", "-g", "docks-kit@latest"], { stdio: "inherit" })
|
|
95
117
|
if (res.error !== undefined || res.status !== 0) {
|
|
96
118
|
return yield* bail(`global package update failed (${viaBun ? "bun add -g" : "npm install -g"} docks-kit@latest)`, 1)
|
|
97
119
|
}
|
|
120
|
+
|
|
121
|
+
const result = packageUpdateResult(beforeVersion, readPackageVersion(home))
|
|
122
|
+
if (result.message !== "") yield* Console.log(result.message)
|
|
123
|
+
if (result.alreadyCurrent) return
|
|
98
124
|
if (skipSync) return yield* Console.log("Kit updated. Run: docks-kit sync")
|
|
99
125
|
yield* Console.log("Kit updated - running sync with the new version...")
|
|
100
126
|
// Chain through the package dir just updated (global installs update in
|
|
@@ -27,12 +27,12 @@ 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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **External CLIs stay external.** `claude`, `codex`, `npx`, `npm`, `
|
|
35
|
-
`
|
|
30
|
+
- **Step ordering is load-bearing.** The Claude pipeline resolves Bun, prepares
|
|
31
|
+
materialized settings, writes runtime assets, commits settings, then performs
|
|
32
|
+
readiness-gated legacy cleanup. Modifiers run after the base commit, removals
|
|
33
|
+
before plugins, and LSP checks after plugin state.
|
|
34
|
+
- **External CLIs stay external.** `claude`, `codex`, `npx`, `npm`, `bun`,
|
|
35
|
+
`curl`, and platform package managers are spawned with argv arrays,
|
|
36
36
|
not shell command strings except where the external installer contract is a
|
|
37
37
|
shell script.
|
|
38
38
|
- **Backups precede mutation.** Deployed settings/config files write `.bak`
|
|
@@ -55,6 +55,7 @@ warnings, and the summary. Status-quo confirmations exist but are opt-in.
|
|
|
55
55
|
| `warn(msg)` | stderr | shown | shown | `[warn]` yellow (`\x1b[1;33m`) |
|
|
56
56
|
| `change(msg)` | stderr | shown | shown | `[ok]` green (`\x1b[1;32m`) — ONLY after an operation actually mutated |
|
|
57
57
|
| `verbose(msg)` | stderr | hidden | shown | `[ok]` green — no-op confirmations ("already …", "present", "up to date", "left as-is"), skips |
|
|
58
|
+
| `progress(msg)` | stderr | interactive only | interactive only | dim, transient single-line status with no newline |
|
|
58
59
|
| `data(line)` | stdout | shown | shown | bare — dry-run report lines, `status --json`, summary block, usage text |
|
|
59
60
|
|
|
60
61
|
- stdout is data, stderr is logs — the logger NEVER writes to stdout
|
|
@@ -63,6 +64,15 @@ warnings, and the summary. Status-quo confirmations exist but are opt-in.
|
|
|
63
64
|
printed unfiltered at every verbosity.
|
|
64
65
|
- Prefixes and ANSI codes are stable golden surface; the level controls
|
|
65
66
|
visibility, not the prefix.
|
|
67
|
+
- `logger.ts` `makeLogger`, at progress sink selection, enables transient
|
|
68
|
+
progress when `LoggerSinks.progress` exists. It also enables progress when no
|
|
69
|
+
stderr sink exists and `process.stderr.isTTY` is `true`. It disables progress
|
|
70
|
+
in every other case. Injected golden sinks therefore keep their existing
|
|
71
|
+
bytes unless the harness supplies a progress sink.
|
|
72
|
+
- Each progress write replaces one terminal line. `clearProgress()` erases a
|
|
73
|
+
pending line and does nothing when no line is pending. Every durable
|
|
74
|
+
`change`, `verbose`, `warn`, `err`, or `echo` write erases the pending line
|
|
75
|
+
before it writes durable output.
|
|
66
76
|
|
|
67
77
|
### Change detection
|
|
68
78
|
|
|
@@ -76,9 +86,9 @@ each such skip is an intentional behavior change named in its golden diff.
|
|
|
76
86
|
Exactly one deduplicated warn per requested missing tool per run, uniform shape:
|
|
77
87
|
`[warn] <tool> not installed — <platform-correct install command>`, sourced
|
|
78
88
|
from the dependency registry (`deps.ts`). jq and curl are optional report rows:
|
|
79
|
-
jq has no runtime consumer, while curl warns only
|
|
80
|
-
download
|
|
81
|
-
deleting working legacy hooks or statusline files.
|
|
89
|
+
jq has no runtime consumer, while curl warns only when a requested POSIX Bun
|
|
90
|
+
bootstrap needs an installer download. A missing Bun defers Claude runtime
|
|
91
|
+
migration without deleting working legacy hooks or statusline files.
|
|
82
92
|
|
|
83
93
|
### Summary and next steps
|
|
84
94
|
|
|
@@ -89,10 +99,9 @@ it. The schema below applies to `sync` only.
|
|
|
89
99
|
|
|
90
100
|
The `--- Sync complete ---` block (stdout, `data`) prints on every run,
|
|
91
101
|
including dry-run, with the per-target inventory lines (`Claude:`/`Hooks:`/
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`--verbose`.
|
|
102
|
+
`Plugins:`/`Codex:`/`Skills:`). Next-step advice lines print only when their
|
|
103
|
+
trigger changed this run (plugins changed → `/reload-plugins` line; hooks/env
|
|
104
|
+
changed → restart line; skills changed → discovery line) or under `--verbose`.
|
|
96
105
|
|
|
97
106
|
### Platform seam
|
|
98
107
|
|
|
@@ -118,14 +127,14 @@ active logger binding.
|
|
|
118
127
|
| `parseArgs.ts` | engine usage, target selection, flag parsing, legacy rename hints, model flag validation |
|
|
119
128
|
| `index.ts` | sync orchestration, target dispatch, run summary and next-step blocks |
|
|
120
129
|
| `../payload.ts` | generated text/byte payload reads and presentation-only source labels |
|
|
121
|
-
| `claudeSync.ts` | Claude pipeline:
|
|
130
|
+
| `claudeSync.ts` | Claude pipeline: Bun bootstrap, prepared settings transaction, runtime assets, deploy-time modifiers, `~/.claude.json`, readiness-gated removed artifacts, plugins, optional plugins, LSP binaries |
|
|
122
131
|
| `bun.ts` | per-run memoized Bun resolution/bootstrap shared by Claude runtime, effect-solutions, and direct toolchain ensure |
|
|
123
132
|
| `claudeRuntime.ts` | sentinel validation, absolute runtime paths, no-cutover settings projection, and POSIX statusline commands |
|
|
124
133
|
| `settings.ts` | pure Claude settings merge/reconcile semantics and permission-array union |
|
|
125
134
|
| `claudeModel.ts` | deployed Claude model modifier and direct `model claude` write path |
|
|
126
135
|
| `codexSync.ts` | Codex pipeline: bubblewrap check, config merge, rules, AGENTS.md, personal marketplace, plugin refresh |
|
|
127
136
|
| `codexToml.ts` | line-based top-level TOML replacement and deployed Codex model modifier |
|
|
128
|
-
| `skillsSync.ts` | universal skill install/prune, Claude symlink healing,
|
|
137
|
+
| `skillsSync.ts` | universal skill install/prune, Claude symlink healing, effect-solutions callback, managed-skill snapshot |
|
|
129
138
|
| `toolchain.ts` | tool presence/version probes, verified-version gate, managed install/upgrade orchestration, report table |
|
|
130
139
|
| `modes.ts` | direct `model` and `toolchain` modes |
|
|
131
140
|
| `models.ts` | model catalog listing and validation |
|