docks-kit 0.8.2 → 0.10.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
@@ -4,24 +4,29 @@ Canonical instructions for coding agents working on this project. Compatible wit
4
4
 
5
5
  ## Repository purpose
6
6
 
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, sync to your home directory, get a consistent AI-assisted dev environment everywhere. 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?*
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
10
  - **`CLAUDE.md`** — Claude Code SoT (`SoT/.claude/`), env vars, hooks, plugins, RTK, 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
+
14
+ docks-kit runtime, standalone binary, and Session Relay prebuilt support is
15
+ exactly Linux x64/arm64 and macOS x64/arm64. Unsupported hosts fail before the
16
+ launcher can fall back to Bun source.
17
+
13
18
  ## Repository layout (cross-cutting)
14
19
 
15
20
  | Path | Purpose |
16
21
  |------|---------|
17
- | `docks-kit` | CLI launcher: runs the platform binary in `cli/dist/` only when its `--version` matches `package.json`, otherwise Bun-from-source (auto-installs Bun + `node_modules`). No-Bun recovery is the standalone platform release binary |
22
+ | `docks-kit` | CLI launcher: on supported hosts, runs the platform binary in `cli/dist/` only when its `--version` matches `package.json`, otherwise Bun-from-source (auto-installs Bun + `node_modules`). Unsupported hosts fail before source fallback. No-Bun recovery is the standalone platform release binary |
18
23
  | `cli/src/engine-native/` | EngineNative implementation for `sync`, `model`, `workflow`, and `toolchain`; idempotent, flag-gated for destructive reconciliation |
19
24
  | `cli/` | Effect-TS CLI + bundled docs topics |
20
25
  | `SoT/models.json` | Kit-verified model catalog plus the strict Docks workflow-role registry |
21
26
  | `SoT/toolchain.json` | Toolchain floors manifest (verified pins consumed by EngineNative) |
22
27
  | `SoT/.claude/bin/` | Dependency-free Bun runtime programs for Claude's statusline, SessionStart, and Notification |
23
28
  | `install.sh` | Global installer |
24
- | `.github/workflows/release-cli.yml` | `cli-v*` release binaries + npm publish |
29
+ | `.github/workflows/release-cli.yml` | `cli-v*` release: four Linux/macOS x64/arm64 binaries, `SHA256SUMS`, and npm publish |
25
30
  | `README.md` | Front door |
26
31
  | `package.json` / `bun.lock` | npm package: `bin` = `cli/src/main.ts`; bundles `cli/` with the generated in-memory SoT payload |
27
32
  | `SoT/.agents/skills.txt` | Universal-skill manifest, intentionally empty by default. Adding an [agentskills.io](https://agentskills.io/specification) slug opts it into EngineNative's shared `~/.agents/skills/` bootstrap and Claude symlink. |
@@ -36,6 +41,7 @@ Codex SoT notes:
36
41
  - `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.
37
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.
38
43
  - `docks-kit status` verifies Session Relay only through the supported `codex plugin list --json` inventory. `ready` means installed and enabled for a newly started Codex session; it is not evidence about an old process, lifecycle state, receive-path health, or worker quiescence. The global prompt SoTs carry the owner's standing authorization for Docks cross-company plan review, which never overrides host or platform denial.
44
+ - Claude and Codex sync call `sessionRelayCli.ts ensureSessionRelayCli` immediately before their plugin passes. It installs the exact source-pinned precompiled command at `~/.local/bin/session-relay` for Linux/macOS x64/arm64 only, requires committed digest = same-release `SHA256SUMS` row = downloaded bytes, smoke-tests the staged version, and atomically replaces the stable path. `agents`-only sync never enters this boundary. The four pinned production digests correspond to the stable `session-relay--v0.12.0` assets and its `SHA256SUMS`.
39
45
  - Both global prompt SoTs carry one byte-identical compact `Docks-workflow-models:` record. Root `--model-orchestrator` / `--model-reviewer` / `--model-implementer` / review-bound flags update only that deployed record; `docks-kit models workflow` lists the closed selectors, and a flag-less sync restores defaults.
40
46
  - Codex workflow selectors use the closed `<tool>:<model>@<effort>[+fast]` routing grammar. Fast is intentionally absent from the global SoT: no suffix means Standard and keeps the backward-compatible schema-1 record; `+fast` emits a schema-2 candidate with `service_tier: "fast"`. Docks and Session Relay consumers must explicitly launch unsuffixed Codex roles with the default service tier so a user's global Fast preference cannot leak into workflows.
41
47
  - 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.
@@ -52,7 +58,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT d
52
58
  - **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`, `--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).
53
59
  - **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.
54
60
  - **`--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.
55
- - **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`.
61
+ - **SOLID-aligned modules.** `cli/src/engine-native/parseArgs.ts` owns flag parsing/validation. `toolchain.ts` owns the verified-version gate over `SoT/toolchain.json`; `sessionRelayCli.ts` owns the closed release manifest, platform mapping, checksum/smoke transaction, and atomic Session Relay replacement; `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`.
56
62
  - **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.
57
63
  - **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.
58
64
  - **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.
@@ -91,7 +97,7 @@ When a kit-mechanic skill, its `references/`, or a wrapper agent (`.claude/agent
91
97
  Multi-commit work plans live in `docs/plans/active/` (status is a frontmatter field) and `docs/plans/finished/` (archive). Every plan file is a complete cold-handoff document — goal, context & rationale, environment & how-to-run, steps with exact paths, executable acceptance criteria, and a binary cold-handoff checklist — so any agent (or a weaker model) can pick one up cold without guessing. Skills handle every operation: `plan-init` (bootstrap/migrate), `plan-manager` (list/show/start/block/ship/new, auto-commit on transition, self-review on draft), `plan-review` (verification). Trigger by natural language or the matching `plan-*` skill. `active/` is multi-occupancy.
92
98
  </constraint>
93
99
 
94
- The full convention (frontmatter schema, body sections, one-pass local self-review, bounded strong-default X/S review receipts, workflow roles, open-questions, age tokens) lives in `docs/plans/AGENTS.md`. `docs/plans/CLAUDE.md` is a one-line `@AGENTS.md` import for Claude Code's nested discovery. If `.codex/agents/plan-manager.toml` and `.codex/agents/plan-review.toml` exist, Codex may use them for explicit subagent delegation; otherwise run the matching `plan-*` skill inline.
100
+ The full convention (frontmatter schema, body sections, one-pass local checklist self-review, schema-5 role `primary`, GPT-5.6-sol/high/`service_tier:"default"` (Standard) → Fable/high Opus/xhigh availability-only fallback, exact eight-criterion evidence checklist, primary-role waivers, one full round plus at most one accepted-blocker repair, open questions, and age tokens) lives in `docs/plans/AGENTS.md`. `docs/plans/CLAUDE.md` is a one-line `@AGENTS.md` import for Claude Code's nested discovery. If `.codex/agents/plan-manager.toml` and `.codex/agents/plan-review.toml` exist, Codex may use them for explicit subagent delegation; otherwise run the matching `plan-*` skill inline.
95
101
 
96
102
  Distinct from per-tool **Open Concerns** sections (wait-on-upstream
97
103
  blockers tied to a vendor shipping a fix — these live inside the per-tool
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Portable configuration kit for AI coding agents. Per-tool **Single Source of
4
4
  Truth (SoT)** directories are deployed to each tool's user-config location —
5
- clone once, sync everywhere, get a consistent AI-assisted dev environment on
6
- every machine. Tuned for **token efficiency without sacrificing quality**.
5
+ clone once and get a consistent AI-assisted dev environment across supported
6
+ Linux and macOS machines. Tuned for **token efficiency without sacrificing quality**.
7
7
 
8
8
  Supported tools: **Claude Code**, **Codex**, and any agent consuming
9
9
  [agentskills.io](https://agentskills.io) universal skills.
@@ -17,10 +17,12 @@ cd ~/projects/public
17
17
  ./docks-kit status # doctor view: drift, toolchain, plugins, skills
18
18
  ```
19
19
 
20
- The `./docks-kit` launcher prefers a compiled binary (`cli/dist/`) only when
21
- its version matches the checkout, then runs from source via Bun auto-installing
22
- Bun and dependencies when missing. Stale ignored build artifacts cannot mask
23
- newer checkout code.
20
+ The `./docks-kit` launcher supports Linux x64/arm64 and macOS x64/arm64.
21
+ On those hosts it prefers a compiled binary (`cli/dist/`) only when its version
22
+ matches the checkout, then runs from source via Bun—auto-installing Bun and
23
+ dependencies when missing. Unsupported hosts fail immediately and never fall
24
+ back to Bun source. Stale ignored build artifacts cannot mask newer checkout
25
+ code.
24
26
 
25
27
  Other install paths (global `bun add -g docks-kit`, curl installer) —
26
28
  see `./docks-kit docs install`.
@@ -32,7 +34,7 @@ The executable carries the generated sync payload; no checkout or adjacent
32
34
  `SoT/` directory is required.
33
35
 
34
36
  Prerequisites for source/global installs: Bun; Node/npm for npm-global tools.
35
- `jq` is optional doctor/test tooling. `curl` is used only at requested POSIX
37
+ `jq` is optional doctor/test tooling. `curl` is used only at requested Linux/macOS
36
38
  RTK/Bun download boundaries, not as a global sync prerequisite.
37
39
 
38
40
  ## CLI
@@ -102,6 +104,13 @@ current valid values, while a later flag-less sync restores all defaults.
102
104
  versions above the kit-verified pin prompt before installing
103
105
  (`--yes` accepts; non-TTY falls back to the pinned verified version
104
106
  when possible). `docks-kit toolchain check` shows the full table.
107
+ - **Session Relay CLI** — Claude/Codex syncs ensure the source-pinned
108
+ precompiled `session-relay` command in `~/.local/bin` immediately before
109
+ Session Relay plugin reconciliation. Linux/macOS x64/arm64 assets must match
110
+ both the committed digest and their release `SHA256SUMS`, then pass an exact
111
+ staged version smoke before atomic replacement; failures preserve any prior
112
+ command. The four production digests are pinned for the stable
113
+ `session-relay--v0.12.0` assets and match the same-release `SHA256SUMS`.
105
114
  - **Model catalog** — `SoT/models.json` is the research-verified source for
106
115
  model validation, listings, pickers, and the Docks workflow-role registry.
107
116
  - **Claude runtime** — sync materializes three dependency-free Bun `.mjs`
@@ -129,19 +138,21 @@ current valid values, while a later flag-less sync restores all defaults.
129
138
 
130
139
  ## Platform support
131
140
 
132
- | Platform | CLI | Sync engine |
133
- |----------|-----|-------------|
134
- | Linux | ✅ native | ✅ native |
135
- | macOS (x64/arm64) | ✅ native | ✅ native |
136
- | Windows | native binary (`.exe` and `bun add -g` CI-verified) | ✅ EngineNative (TS, default engine — no Git Bash); real-machine verified 2026-07-09 — RTK hooks are native too (rtk ≥0.37.2) |
141
+ | Platform | Architecture | docks-kit binary | Session Relay prebuilt | Sync engine |
142
+ |----------|--------------|------------------|------------------------|-------------|
143
+ | Linux | x64 | | | ✅ native |
144
+ | Linux | arm64 | ✅ | | ✅ native |
145
+ | macOS | x64 | | | ✅ native |
146
+ | macOS | arm64 | ✅ | ✅ | ✅ native |
137
147
 
138
148
  Details: `docks-kit docs platforms`.
139
149
 
140
150
  ## Releases
141
151
 
142
- Tagging `cli-v*` builds five standalone binaries (+ SHA256SUMS) and attaches
143
- them to the GitHub release; npm publish runs when the `NPM_TOKEN` secret is
144
- configured. Package bundles the CLI + generated payload, so npm releases are
152
+ Tagging `cli-v*` builds four standalone binaries (Linux x64/arm64 and macOS
153
+ x64/arm64) plus `SHA256SUMS` and attaches them to the GitHub release; npm
154
+ publish runs when the `NPM_TOKEN` secret is configured.
155
+ Package bundles the CLI + generated payload, so npm releases are
145
156
  versioned config snapshots without shipping the authoring `SoT/` tree.
146
157
 
147
158
  ## Deeper docs
@@ -1,5 +1,8 @@
1
1
  # Installing docks-kit
2
2
 
3
+ Supported hosts are Linux x64/arm64 and macOS x64/arm64. Unsupported hosts
4
+ fail before the launcher can fall back to Bun source.
5
+
3
6
  ## 1. Repo checkout (development / current users)
4
7
 
5
8
  ```
@@ -8,10 +11,11 @@ cd ~/projects/public
8
11
  ./docks-kit sync
9
12
  ```
10
13
 
11
- The `./docks-kit` launcher prefers a compiled binary in `cli/dist/` only when
12
- its reported version matches `package.json`, then falls back to Bun-from-source
13
- (auto-installing Bun via download-then-run and `bun install --frozen-lockfile`
14
- when needed). An ignored stale build is reported and bypassed.
14
+ On a supported host, the `./docks-kit` launcher prefers a compiled binary in
15
+ `cli/dist/` only when its reported version matches `package.json`, then falls
16
+ back to Bun-from-source (auto-installing Bun via download-then-run and
17
+ `bun install --frozen-lockfile` when needed). An ignored stale build is reported
18
+ and bypassed.
15
19
 
16
20
  ## 2. Global via Bun (effect-solutions-style)
17
21
 
@@ -51,7 +55,7 @@ install; `docks-kit --version`, model catalogs, toolchain checks, and real sync
51
55
  remain functional with the script blocked. CI pins the one-package/one-command
52
56
  identity above and will fail if the script-bearing set changes.
53
57
 
54
- ## 3. curl installer (Unix-only)
58
+ ## 3. curl installer (Linux/macOS)
55
59
 
56
60
  ```
57
61
  curl -fsSL https://raw.githubusercontent.com/DocksDocks/public/main/install.sh -o /tmp/docks-kit-install.sh
@@ -61,20 +65,7 @@ bash /tmp/docks-kit-install.sh && rm /tmp/docks-kit-install.sh
61
65
  Download-then-run, never `curl | bash` — stream truncation has bitten this
62
66
  kit before. The installer bootstraps Bun when absent, runs
63
67
  `bun add -g docks-kit`, and links the binary into `~/.local/bin`.
64
- **Linux/macOS only** on Windows use the compiled `.exe` or `bun add -g`
65
- (both CI-verified; see below).
66
-
67
- ## Windows entrypoints
68
-
69
- Two supported paths (CI-verified on windows-2025, native PowerShell):
70
-
71
- - **Compiled binary** — `docks-kit-windows-x64.exe` release asset. No Bun,
72
- no Git Bash: the exe embeds the runtime and generated payload, and
73
- EngineNative runs in-process from any working directory.
74
- - **`bun add -g docks-kit`** — bun creates a working shim for the
75
- `#!/usr/bin/env bun` bin; the package carries the same generated payload.
76
-
77
- `install.sh` is not a Windows path.
68
+ This installer supports Linux and macOS only.
78
69
 
79
70
  ## Keeping the kit up to date
80
71
 
@@ -105,6 +96,6 @@ sync/config reads.
105
96
  - Bun for source/global installs; release binaries embed the runtime
106
97
  - Node/npm for npm-global tools (agent-browser, LSP servers)
107
98
  - jq is optional doctor/test tooling; sync has no jq runtime dependency
108
- - curl is required only when a requested POSIX RTK/Bun bootstrap must download
99
+ - curl is required only when a requested Linux/macOS RTK/Bun bootstrap must download
109
100
  an installer; an already-present Bun does not require it
110
101
  - See `docks-kit toolchain check` for the full picture on this machine
@@ -1,46 +1,18 @@
1
1
  # Platform support
2
2
 
3
- | Platform | CLI (docks-kit) | Sync engine | Notes |
4
- |----------|-----------------|-------------|-------|
5
- | Linux | native | EngineNative (TS) | Primary target |
6
- | macOS | native (x64 + arm64) | EngineNative (TS) | Release binary or Bun source path |
7
- | Windows | native (`.exe` / `bun add -g`, CI-verified) | EngineNative (TS) — no Git Bash | Real-machine verified 2026-07-09 |
8
-
9
- EngineNative is the only supported engine on all platforms. `DOCKS_KIT_ENGINE=bash`
10
- now exits with the removed-engine message and points at the `bash-engine-final`
11
- tag for historical recovery.
12
-
13
- ## Windows detail
14
-
15
- Supported entrypoints (both verified in CI on windows-2025 under native
16
- PowerShell see `.github/workflows/windows-entrypoints.yml`):
17
-
18
- - **`docks-kit-windows-x64.exe`** (release asset) the no-toolchain path.
19
- No Bun, no Git Bash; the exe embeds the runtime and generated payload, and
20
- EngineNative runs in-process from any working directory.
21
- - **`bun add -g docks-kit`** — bun creates a working Windows shim for the
22
- `#!/usr/bin/env bun` bin; the package carries the same generated payload.
23
- - `install.sh` is **Unix-only** and not a Windows path.
24
-
25
- The managed tools all run natively on Windows: Claude Code (requires Git
26
- Bash for its own Bash tool — that requirement is Claude Code's, not this
27
- kit's), Codex CLI (native PowerShell + Windows sandbox), RTK (native
28
- binaries; since rtk 0.37.2 the PreToolUse hook is a native binary command —
29
- `rtk hook claude`, no shell or jq. Only the kit's *auto-installer* is
30
- Unix-only: install rtk natively, then sync).
31
-
32
- CI coverage (all on the pinned windows-2025 label): EngineNative PowerShell
33
- smoke with `HOME` unset — `%USERPROFILE%` path resolution, `.cmd` tool
34
- spawning (npm), toolchain gate branches (`.github/workflows/parity.yml`,
35
- `native-windows` job); the two entrypoints above (`windows-entrypoints.yml`).
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.
41
-
42
- **Status: supported** — real-machine verified 2026-07-09 (Claude Code loads
43
- the synced `%USERPROFILE%\.claude`; full sync, self-update, plugin passes,
44
- universal skills, and agent-browser all green on native PowerShell). Needs
45
- git on PATH for plugin marketplaces; rtk installs natively via its Windows
46
- release (the kit's auto-install is Unix-only).
3
+ The supported host matrix is exact:
4
+
5
+ | Platform | Architecture | docks-kit binary | Session Relay prebuilt | Sync engine |
6
+ |----------|--------------|------------------|------------------------|-------------|
7
+ | Linux | x64 | `docks-kit-linux-x64` | `x86_64-unknown-linux-musl` | EngineNative (TS) |
8
+ | Linux | arm64 | `docks-kit-linux-arm64` | `aarch64-unknown-linux-musl` | EngineNative (TS) |
9
+ | macOS | x64 | `docks-kit-darwin-x64` | `x86_64-apple-darwin` | EngineNative (TS) |
10
+ | macOS | arm64 | `docks-kit-darwin-arm64` | `aarch64-apple-darwin` | EngineNative (TS) |
11
+
12
+ Windows and every other host are unsupported. The launcher fails before any
13
+ Bun-from-source fallback, and Session Relay installation reports the unsupported
14
+ host without downloading an asset.
15
+
16
+ EngineNative is the only supported engine on supported hosts.
17
+ `DOCKS_KIT_ENGINE=bash` exits with the removed-engine message and points at the
18
+ `bash-engine-final` tag for historical recovery.
@@ -26,10 +26,15 @@ Order matters — runtime readiness and settings form one transaction:
26
26
  `--claude-model`, `--claude-effort`, `--claude-advisor`) — deployed file only.
27
27
  7. ~/.claude.json (showTurnDuration, user-scoped MCP servers) and connector env
28
28
  export.
29
- 8. **Plugins** — seven idempotent passes via the `claude plugin` CLI
29
+ 8. **Session Relay CLI** — ensure the exact source-pinned precompiled command
30
+ in `~/.local/bin` for the supported host. A staged asset must match both the
31
+ source digest and same-release `SHA256SUMS`, then report exact version before
32
+ atomic replacement. Failure stops before Session Relay plugin work and
33
+ preserves any prior command.
34
+ 9. **Plugins** — seven idempotent passes via the `claude plugin` CLI
30
35
  (marketplaces → install → update → [--prune: uninstall/remove] → re-assert
31
36
  SoT enabled-state). Optional opt-ins via `--claude-plugin=<name>`.
32
- 9. LSP server binaries (npm globals).
37
+ 10. LSP server binaries (npm globals).
33
38
 
34
39
  The statusline reads Claude's native `rate_limits`. There is no OAuth request,
35
40
  usage cache, jq/curl runtime dependency, or Stop fetch hook.
@@ -40,12 +45,15 @@ bubblewrap check (Linux), config.toml merge (top-level keys replaced
40
45
  per-key, [table] blocks replaced wholesale, user-only keys/tables preserved),
41
46
  `--codex-model` then `--codex-effort` modifiers, rules, AGENTS.md, personal
42
47
  marketplace file, `codex plugin add` refresh.
48
+ Immediately before `codex plugin add`, the same Session Relay CLI ensure runs;
49
+ an ensure failure prevents the plugin pass.
43
50
 
44
51
  ## agents (→ ~/.agents/skills, ~/.claude/skills symlinks)
45
52
 
46
53
  `npx skills add` per missing manifest slug, Claude symlink healing,
47
54
  CLI binaries (agent-browser, effect-solutions — toolchain-gated), and the
48
55
  kit-managed snapshot that `--prune` reconciles against.
56
+ This target never ensures or downloads Session Relay.
49
57
 
50
58
  ## Reconcile flags
51
59
 
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Field | Meaning |
6
6
  |-------|---------|
7
- | `kind` | `check` (doctor visibility) / `managed` (kit installs + upgrades) / `pin` (no binary — a version pin for npx-invoked tools, e.g. `skills-cli`) |
8
- | `policy` | `track` (upgrade toward latest, gated by `verified`) / `present` (install when missing, never upgrade) |
7
+ | `kind` | `check` (doctor visibility) / `managed` (kit installs + upgrades) / `managed-release` (dedicated source-pinned release transaction) / `pin` (no binary — a version pin for npx-invoked tools, e.g. `skills-cli`) |
8
+ | `policy` | `track` (upgrade toward latest, gated by `verified`) / `present` (install when missing, never upgrade) / `exact` (install the declared release only) |
9
9
  | `floor` | Minimum acceptable version (below → upgrade automatically) |
10
10
  | `verified` | Last kit-tested version — the gate line |
11
11
  | `pinnable` | Whether an exact version can be installed (rtk: `RTK_VERSION=vX.Y.Z`) |
@@ -33,13 +33,24 @@ now kit-approved" act.
33
33
  - **bun** — policy `present`: bootstrap only (pinned to `verified` via the
34
34
  installer's version argument), never auto-upgraded. `bun.ts` owns one
35
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.
36
+ toolchain ensure on supported Linux/macOS hosts.
37
37
  - **effect-solutions**, **agent-browser** — policy `track`: self-upgrade
38
38
  toward npm latest, gated by their `verified` pins.
39
+ - **session-relay** — policy `exact`: Claude/Codex sync and
40
+ `docks-kit toolchain ensure session-relay` select exactly one of four targets
41
+ (`x86_64-unknown-linux-musl`, `aarch64-unknown-linux-musl`,
42
+ `x86_64-apple-darwin`, `aarch64-apple-darwin`). The installer downloads the
43
+ pinned `session-relay--v0.12.0` asset and same-release `SHA256SUMS`, requires
44
+ source pin = selected row = downloaded bytes, chmods/smoke-tests only the
45
+ sibling stage, then renames it over `~/.local/bin/session-relay`. Offline,
46
+ unsupported-host, checksum, chmod, version, download, or rename failures
47
+ preserve an existing command byte-for-byte. The four pinned production
48
+ digests correspond to the stable `session-relay--v0.12.0` assets and match
49
+ its `SHA256SUMS`.
39
50
 
40
51
  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.
52
+ normal sync. curl is checked only at a requested Linux/macOS RTK/Bun installer
53
+ download boundary.
43
54
 
44
55
  ## Supply-chain stance
45
56
 
@@ -55,5 +66,6 @@ probe falls back to the pinned `verified`, never to an ungated latest.
55
66
  ```
56
67
  docks-kit toolchain check # doctor table (also inside docks-kit status)
57
68
  docks-kit toolchain ensure rtk # install/upgrade one tool per policy
69
+ docks-kit toolchain ensure session-relay # install exact verified release
58
70
  docks-kit sync --yes # unattended: auto-accept gates
59
71
  ```
@@ -20,7 +20,7 @@ const TOPICS: Record<string, { summary: string; body: string }> = {
20
20
  "toolchain": { summary: "Verified-version floors, gate policy, --yes semantics", body: toolchain },
21
21
  "plugins": { summary: "enabledPlugins tri-state + optional plugin opt-ins", body: plugins },
22
22
  "install": { summary: "Install paths: repo checkout, bun add -g, curl installer", body: install },
23
- "platforms": { summary: "Platform support: Linux/macOS native, Windows via Git Bash/WSL", body: platforms }
23
+ "platforms": { summary: "Platform support: Linux/macOS x64 and arm64", body: platforms }
24
24
  }
25
25
 
26
26
  const topic = Args.text({ name: "topic" }).pipe(
@@ -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 = ["rtk", "bun", "effect-solutions", "agent-browser"]
5
+ const MANAGED = ["rtk", "bun", "effect-solutions", "agent-browser", "session-relay"]
6
6
 
7
7
  const op = Args.text({ name: "op" }).pipe(
8
8
  Args.withDescription("check (default) | ensure <tool>"),
@@ -96,12 +96,10 @@ hooks/env changed → restart line; skills changed → discovery line) or under
96
96
 
97
97
  ### Platform seam
98
98
 
99
- All platform branching routes through `os.ts` the only engine module that
100
- reads `process.platform`, with one named exemption: `exec.ts`'s path/exec
101
- primitives (`commandExists` PATHEXT resolution and `X_OK` probing) stay
102
- self-contained because they sit below the seam. `deps.ts` install hints
103
- default their platform from `os.ts` and keep the parameter injectable for
104
- tests.
99
+ All host detection routes through `os.ts`, the engine module that reads
100
+ `process.platform`. `exec.ts` contains only POSIX executable and PATH probes.
101
+ `deps.ts` install hints default their platform from `os.ts` and keep the
102
+ parameter injectable for tests.
105
103
 
106
104
  ### Verbosity plumbing
107
105
 
@@ -122,7 +120,7 @@ active logger binding.
122
120
  | `../payload.ts` | generated text/byte payload reads and presentation-only source labels |
123
121
  | `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
122
  | `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 |
123
+ | `claudeRuntime.ts` | sentinel validation, absolute runtime paths, no-cutover settings projection, and POSIX statusline commands |
126
124
  | `settings.ts` | pure Claude settings merge/reconcile semantics and permission-array union |
127
125
  | `claudeModel.ts` | deployed Claude model modifier and direct `model claude` write path |
128
126
  | `codexSync.ts` | Codex pipeline: bubblewrap check, config merge, rules, AGENTS.md, personal marketplace, plugin refresh |
@@ -132,24 +130,20 @@ active logger binding.
132
130
  | `modes.ts` | direct `model` and `toolchain` modes |
133
131
  | `models.ts` | model catalog listing and validation |
134
132
  | `jq.ts` | JSON helpers that preserve jq-style merge/order/stringify behavior where the deployed file contract needs it |
135
- | `exec.ts` | path helpers, command probes, capture/spawn wrappers, Windows command resolution, change-detecting write/copy helpers |
133
+ | `exec.ts` | slash-stable path helpers, POSIX command probes, capture/spawn wrappers, and change-detecting write/copy helpers |
136
134
  | `logger.ts` | Logger shape + stable raw stdout/stderr sink factory; the run-scoped verbosity gate lives in `index.ts` |
137
- | `deps.ts` | external-tool registry: identity, requirement class, presence probe, platform-correct install hints, per-manager missing-tool dedup; callers supply the current run Logger to `warnMissing` |
138
- | `os.ts` | platform capability seam — the single `process.platform` reader (`platformName`, `isWindows`, `isLinux`, shell-rc applicability) |
135
+ | `deps.ts` | external-tool registry: identity, requirement class, presence probe, supported-host install hints, per-manager missing-tool dedup; callers supply the current run Logger to `warnMissing` |
136
+ | `os.ts` | platform capability seam — the single `process.platform` reader (`platformName`, `isLinux`, shell-rc applicability) |
139
137
  | `services.ts` | shared raw-Logger + DependencyManager + Platform factory; wrapped in Effect Layers at `cli/src/services.ts`, with the run-scoped Logger gate applied only by `runEngineNative` |
140
138
 
141
- ## Windows Specifics
139
+ ## Platform Support
142
140
 
143
- - Home resolves through Node's platform APIs; CI deliberately unsets `HOME` so
144
- `%USERPROFILE%` is exercised.
145
- - Paths are built through `node:path`.
146
- - Connector env uses `setx` on win32; Unix shell rc files are not touched.
147
- - Symlink creation falls back to copy where the platform or permissions require
148
- it.
149
- - Bubblewrap and shell-rc work are Linux/macOS only.
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.
141
+ - EngineNative supports Linux and macOS on x64 and arm64.
142
+ - Unsupported hosts fail before launcher fallback, dependency probes, downloads,
143
+ settings writes, or sync work.
144
+ - Runtime hooks use POSIX commands and absolute Bun paths.
145
+ - Symlink creation remains capability-driven: permission or filesystem failures
146
+ fall back to copy without predicting the host.
153
147
 
154
148
  ## Tests
155
149
 
@@ -158,12 +152,10 @@ active logger binding.
158
152
  `cli/test/goldens/dryrun.json`.
159
153
  - `bun run golden:mutation` compares live native mutation snapshots, argv logs,
160
154
  output, and TOML invariants to `cli/test/goldens/mutation.json`.
161
- - `.github/workflows/parity.yml` is now the golden-regression workflow: Linux
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.
165
- - `.github/workflows/windows-entrypoints.yml` verifies the release binary and
166
- `bun add -g` entrypoints on Windows.
155
+ - `.github/workflows/parity.yml` is the golden-regression workflow: Linux runs
156
+ unit + golden + prove-red plus the exact materialized POSIX runtime commands.
157
+ - `.github/workflows/release-cli.yml` publishes the four Linux/macOS x64/arm64
158
+ binaries, `SHA256SUMS`, and the npm package.
167
159
 
168
160
  ## Non-Goals
169
161
 
@@ -4,7 +4,6 @@ import { tmpdir } from "node:os"
4
4
 
5
5
  import { p } from "./exec"
6
6
  import type { Ctx } from "./index"
7
- import { encodePowerShellCommand, powerShellLiteral } from "./powershell"
8
7
  import type { EngineServices } from "./services"
9
8
  import { field } from "./toolchain"
10
9
 
@@ -17,31 +16,14 @@ function remember(ctx: Ctx, state: BunRuntimeState): BunRuntimeState {
17
16
  return state
18
17
  }
19
18
 
20
- function predictedExecutable(ctx: Ctx, services: EngineServices): string {
19
+ function predictedExecutable(ctx: Ctx): string {
21
20
  const root = process.env["BUN_INSTALL"] !== undefined && process.env["BUN_INSTALL"] !== ""
22
21
  ? process.env["BUN_INSTALL"]!
23
22
  : p(ctx.home, ".bun")
24
- return p(root, "bin", services.platform.isWindows() ? "bun.exe" : "bun")
23
+ return p(root, "bin", "bun")
25
24
  }
26
25
 
27
- function windowsDownloadScript(installer: string): string {
28
- return `$ErrorActionPreference = 'Stop'; Invoke-WebRequest -Uri ${powerShellLiteral("https://bun.sh/install.ps1")} -OutFile ${powerShellLiteral(installer)}`
29
- }
30
-
31
- function installBun(ctx: Ctx, services: EngineServices, pin: string, installer: string): void {
32
- if (services.platform.isWindows()) {
33
- const encoded = encodePowerShellCommand(windowsDownloadScript(installer))
34
- const download = spawnSync("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", encoded], { stdio: "ignore" })
35
- if (download.error === undefined && download.status === 0) {
36
- spawnSync(
37
- "powershell.exe",
38
- ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", installer, "-Version", pin, "-DownloadWithoutCurl"],
39
- { stdio: "ignore" }
40
- )
41
- }
42
- return
43
- }
44
-
26
+ function installBun(pin: string, installer: string): void {
45
27
  const download = spawnSync("curl", ["-fsSL", "https://bun.sh/install", "-o", installer], { stdio: "ignore" })
46
28
  if (download.error === undefined && download.status === 0) {
47
29
  spawnSync("bash", [installer, `bun-v${pin}`], { stdio: "ignore" })
@@ -59,19 +41,19 @@ export function bunBootstrap(ctx: Ctx, services: EngineServices): BunRuntimeStat
59
41
  services.logger.warn("Bun bootstrap aborted — SoT/toolchain.json has no verified Bun pin")
60
42
  return remember(ctx, { kind: "deferred", reason: "install-failed" })
61
43
  }
62
- if (!services.platform.isWindows() && services.deps.probe("curl").state === "missing") {
44
+ if (services.deps.probe("curl").state === "missing") {
63
45
  services.deps.warnMissing("curl", services.logger, "cannot bootstrap Bun; install Bun manually, then re-run sync")
64
46
  return remember(ctx, { kind: "deferred", reason: "missing-curl" })
65
47
  }
66
48
  if (ctx.dryRun) {
67
- const executable = predictedExecutable(ctx, services)
49
+ const executable = predictedExecutable(ctx)
68
50
  services.logger.echo(`[dry-run] install Bun ${pin} (kit-verified) -> ${executable}`)
69
51
  return remember(ctx, { kind: "ready", executable })
70
52
  }
71
53
  services.logger.warn(`Bun not found — installing Bun ${pin} (kit-verified)...`)
72
- const installer = p(tmpdir(), `bun-install-${process.pid}.${services.platform.isWindows() ? "ps1" : "sh"}`)
54
+ const installer = p(tmpdir(), `bun-install-${process.pid}.sh`)
73
55
  try {
74
- installBun(ctx, services, pin, installer)
56
+ installBun(pin, installer)
75
57
  } finally {
76
58
  rmSync(installer, { force: true })
77
59
  }
@@ -1,7 +1,5 @@
1
1
  import { p } from "./exec"
2
2
  import { isObject, parseJson, type Json } from "./jq"
3
- import { encodePowerShellCommand, powerShellLiteral } from "./powershell"
4
- import type { Platform } from "./services"
5
3
 
6
4
  const BUN_SENTINEL = "__DOCKS_KIT_BUN__"
7
5
  const SESSION_START_SENTINEL = "__DOCKS_KIT_SESSION_START__"
@@ -89,22 +87,15 @@ function posixLiteral(value: string): string {
89
87
  return `'${value.replaceAll("'", `'"'"'`)}'`
90
88
  }
91
89
 
92
- export function statusLineCommand(runtime: ClaudeRuntimePaths, platform: Platform): string {
93
- if (!platform.isWindows()) {
94
- const bun = posixLiteral(runtime.bun)
95
- const script = posixLiteral(runtime.statusline)
96
- return `test -x ${bun} && test -f ${script} && exec ${bun} ${script} || true`
97
- }
98
- const bun = powerShellLiteral(runtime.bun.replaceAll("\\", "/"))
99
- const script = powerShellLiteral(runtime.statusline.replaceAll("\\", "/"))
100
- const guard = `$ProgressPreference = 'SilentlyContinue'; if ((Test-Path -LiteralPath ${bun} -PathType Leaf) -and (Test-Path -LiteralPath ${script} -PathType Leaf)) { & ${bun} ${script} }`
101
- return `powershell.exe -NoProfile -NonInteractive -EncodedCommand ${encodePowerShellCommand(guard)}`
90
+ export function statusLineCommand(runtime: ClaudeRuntimePaths): string {
91
+ const bun = posixLiteral(runtime.bun)
92
+ const script = posixLiteral(runtime.statusline)
93
+ return `test -x ${bun} && test -f ${script} && exec ${bun} ${script} || true`
102
94
  }
103
95
 
104
96
  export function materializeClaudeSettings(
105
97
  template: Json,
106
- runtime: ClaudeRuntimePaths | undefined,
107
- platform: Platform
98
+ runtime: ClaudeRuntimePaths | undefined
108
99
  ): Json {
109
100
  validateTemplate(template)
110
101
  const result = cloneJson(template)
@@ -122,7 +113,7 @@ export function materializeClaudeSettings(
122
113
  notification["command"] = runtime.bun
123
114
  notification["args"] = [runtime.notify]
124
115
  if (!isObject(result) || !isObject(result["statusLine"])) throw new Error("Claude statusLine object is missing")
125
- result["statusLine"]["command"] = statusLineCommand(runtime, platform)
116
+ result["statusLine"]["command"] = statusLineCommand(runtime)
126
117
  }
127
118
 
128
119
  for (const sentinel of [BUN_SENTINEL, SESSION_START_SENTINEL, NOTIFY_SENTINEL, STATUSLINE_SENTINEL]) {