docks-kit 0.16.15 → 0.16.16

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
@@ -80,7 +80,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`, `SoT/.omp/`), see the m
80
80
  - **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.
81
81
  - **Failed harness-CLI operations fail the sync.** A kit-managed marketplace or plugin command that exits non-zero is recorded through `failures.ts recordFailure` — it still warns in place, and `index.ts engineSync, failure ledger` lists every entry under `--- Failures ---` after the summary, then returns exit 1. A skip is not a failure: a missing harness CLI, missing git, a missing `SoT/toolchain.json` pin, and an unavailable plugin inventory stay warn-only with exit 0, and `ompSync.ts syncMarketplace, probe guard` returns before spawning so a host without omp never records one. Aggregate roll-up warnings (`N plugin operation(s) failed`) stay warns, because each counted site already records itself.
82
82
  - **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.
83
- - **Effect 4 CLI stack.** The CLI pins `effect@4.0.0-rc.109` (including `effect/unstable/cli`), `@effect/platform-bun@4.0.0-rc.109` (`BunServices.layer`, `BunRuntime.runMain`), `@effect/vitest@4.0.0-rc.109`, and `vitest@4.1.11` (inside the `@effect/vitest` peer range `>=4.1.0 <5.0.0`; 4.1.11 fixes GHSA-82fw-gwwq-j7x9). `@effect/cli` and `@effect/platform` are removed and must not be reintroduced.
83
+ - **Effect 4 CLI stack.** The CLI pins `effect@4.0.0-rc.115` (including `effect/unstable/cli`), `@effect/platform-bun@4.0.0-rc.115` (`BunServices.layer`, `BunRuntime.runMain`), `@effect/vitest@4.0.0-rc.115`, and `vitest@5.0.0` (inside the `@effect/vitest` peer range `>=5.0.0 <6.0.0`; 5.0.0 is past the 5.x patch point for GHSA-82fw-gwwq-j7x9, fixed in 5.0.0-rc.2). `@effect/cli` and `@effect/platform` are removed and must not be reintroduced.
84
84
  - **Effect skill routing.** Effect work in this checkout must verify migration and API call shapes against the installed declarations under `node_modules/effect/dist/unstable/cli/`, never from memory or a mutable dist-tag. The `effect-ts-setup`, `effect-ts-port`, and `effect-ts-specialist` skills target Effect 3.x and do not apply.
85
85
  - **Targeted syncs.** `./docks-kit sync` accepts positional targets: `claude`, `codex`, `agents`, and `omp`. Use the narrowest target that matches the SoT change (for example, `./docks-kit sync omp` for omp-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), `--reconcile`, `--prune`, 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).
86
86
  - **Per-machine harness selection.** `~/.docks-kit/state.json` drives a flag-less sync. A missing file selects `claude`, `codex`, and `agents`; it never selects `omp` implicitly. `sync` never prompts and never writes the selection file. `docks-kit harnesses` is the only command that writes the selection.
package/README.md CHANGED
@@ -59,10 +59,10 @@ docks-kit docs [topic] self-documentation (10 topics)
59
59
  The CLI is a typed Effect 4 RC front-end on Bun; all mutation runs through
60
60
  EngineNative in `cli/src/engine-native/`, with golden-regression coverage for
61
61
  dry-run output, mutation snapshots, and argv logs. Its dependency graph is
62
- `effect@4.0.0-rc.109` (including `effect/unstable/cli`),
63
- `@effect/platform-bun@4.0.0-rc.109` (`BunServices.layer` and
64
- `BunRuntime.runMain`), `@effect/vitest@4.0.0-rc.109`, and `vitest@4.1.11`
65
- (inside the `@effect/vitest` peer range `>=4.1.0 <5.0.0`). `@effect/cli` and
62
+ `effect@4.0.0-rc.115` (including `effect/unstable/cli`),
63
+ `@effect/platform-bun@4.0.0-rc.115` (`BunServices.layer` and
64
+ `BunRuntime.runMain`), `@effect/vitest@4.0.0-rc.115`, and `vitest@5.0.0`
65
+ (inside the `@effect/vitest` peer range `>=5.0.0 <6.0.0`). `@effect/cli` and
66
66
  `@effect/platform` are removed: neither has a 4.x release, the CLI API moved
67
67
  into core, and the standalone platform package was unused here.
68
68
 
@@ -40,9 +40,9 @@ one package with an `install` script, `msgpackr-extract` by way of
40
40
  `effect > msgpackr`, and Bun raises no trust prompt for it.
41
41
 
42
42
  The install prints no peer dependency warning. The root pins
43
- `@effect/platform-node-shared` at `4.0.0-rc.109`, the same release as the
43
+ `@effect/platform-node-shared` at `4.0.0-rc.115`, the same release as the
44
44
  pinned `effect`, so a fresh registry resolution installs exactly one copy of
45
- each and the transitive peer range `effect@^4.0.0-rc.109` is satisfied. Without
45
+ each and the transitive peer range `effect@^4.0.0-rc.115` is satisfied. Without
46
46
  that root pin, `@effect/platform-bun` requests the shared package through a
47
47
  caret range over a prerelease and a fresh install can pair a newer shared
48
48
  package with the pinned `effect`.
@@ -34,9 +34,10 @@ an installer. An already-present Bun skips that download on every host.
34
34
  from `typescript-language-server` 6's `engines` field. The kit installs that
35
35
  server as an npm global for the `typescript-lsp` plugin, so an older Node runs
36
36
  a server its own manifest rejects. `docks-kit toolchain check` prints
37
- `below-floor` for a Node older than 22.22.2 and changes nothing else. No sync
38
- pass, install, or launcher consults the Node floor. A host below the floor
39
- still runs every kit operation.
37
+ `below-floor` for a Node older than 22.22.2. The sync pass reads the same
38
+ floor: it skips the `typescript-language-server` install on such a host, warns
39
+ with the host Node version, and installs the other language servers. Nothing
40
+ else consults the floor, so a host below it still runs every kit operation.
40
41
 
41
42
  ## Language-server upgrades
42
43
 
@@ -46,7 +47,7 @@ that is already present. A `verified` bump therefore reaches a fresh host
46
47
  immediately and leaves an existing install alone.
47
48
 
48
49
  A lagging server shows as `below-floor` in `docks-kit toolchain check`. To move
49
- it, install the pinned version by hand:
50
+ it, upgrade Node to 22.22.2 or newer, then install the pinned version by hand:
50
51
 
51
52
  ```bash
52
53
  npm install -g typescript-language-server@6.0.0
@@ -8,7 +8,7 @@ import { p, spawnProcess } from "./exec"
8
8
  import { recordFailure } from "./failures"
9
9
  import type { Ctx } from "./index"
10
10
  import { compareCodepoints, deepMerge, isObject, jqStringify, parseJson, readJsonFile, type Json } from "./jq"
11
- import { field } from "./toolchain"
11
+ import { belowFloor, field, installedVersion } from "./toolchain"
12
12
  import { payloadText } from "../payload"
13
13
 
14
14
  async function cli(args: Array<string>): Promise<{ ok: boolean; out: string; detail: string }> {
@@ -389,6 +389,19 @@ function lspPkg(ctx: Ctx, tool: string, pkg: string): string | undefined {
389
389
  return undefined
390
390
  }
391
391
 
392
+ /**
393
+ * npm treats a package's `engines` field as advisory unless the host opted
394
+ * into engine-strict, so installing typescript-language-server 6 on an older
395
+ * Node succeeds and then fails at every startup. Report the host Node version
396
+ * when it is too old, and the empty string when the install is safe.
397
+ */
398
+ async function nodeBelowServerFloor(ctx: Ctx): Promise<string> {
399
+ const floor = field("node", "floor")
400
+ if (floor === "") return ""
401
+ const installed = await installedVersion(ctx, "node")
402
+ return belowFloor(installed, floor) ? installed : ""
403
+ }
404
+
392
405
  export async function syncLspServers(ctx: Ctx): Promise<void> {
393
406
  const { change, clearProgress, echo, progress, verbose, warn } = ctx.services.logger
394
407
  const sot = parseJson(payloadText("SoT/.claude/settings.json"))
@@ -402,9 +415,17 @@ export async function syncLspServers(ctx: Ctx): Promise<void> {
402
415
  const tsServerMissing = hasTs && ctx.services.deps.probe("typescript-language-server").state === "missing"
403
416
  const tscMissing = hasTs && ctx.services.deps.probe("tsc").state === "missing"
404
417
  const missingToolCount = Number(phpMissing) + Number(tsServerMissing) + Number(tscMissing)
418
+ const blockingNode = tsServerMissing ? await nodeBelowServerFloor(ctx) : ""
419
+ if (blockingNode !== "") {
420
+ warn(
421
+ `Skipping typescript-language-server install: Node ${blockingNode} is older than the ${field("node", "floor")} that version requires. Upgrade Node, then re-run sync.`
422
+ )
423
+ }
405
424
  const missing = [
406
425
  phpMissing ? lspPkg(ctx, "intelephense", "intelephense") : undefined,
407
- tsServerMissing ? lspPkg(ctx, "typescript-language-server", "typescript-language-server") : undefined,
426
+ tsServerMissing && blockingNode === ""
427
+ ? lspPkg(ctx, "typescript-language-server", "typescript-language-server")
428
+ : undefined,
408
429
  tscMissing ? lspPkg(ctx, "tsc", "typescript") : undefined
409
430
  ].filter((spec): spec is string => spec !== undefined)
410
431
 
@@ -34,6 +34,15 @@ function isNewer(a: string, b: string): boolean {
34
34
  return compareCodepoints(a, b) > 0
35
35
  }
36
36
 
37
+ /**
38
+ * A readable installed version strictly older than the manifest floor. The
39
+ * doctor row and the LSP install gate must agree on that judgement, so both
40
+ * ask here rather than re-deriving it.
41
+ */
42
+ export function belowFloor(installed: string, floor: string): boolean {
43
+ return installed !== "" && floor !== "" && isNewer(floor, installed)
44
+ }
45
+
37
46
  export function present(ctx: Ctx, tool: ToolId): boolean {
38
47
  return ctx.services.deps.probe(tool).state === "present"
39
48
  }
@@ -103,7 +112,7 @@ export async function report(ctx: Ctx): Promise<void> {
103
112
  if (present(ctx, toolId)) {
104
113
  installed = await installedVersion(ctx, toolId)
105
114
  status = installed === "" ? "unknown" : "ok"
106
- if (floor !== "" && installed !== "" && isNewer(floor, installed)) {
115
+ if (belowFloor(installed, floor)) {
107
116
  status = "below-floor"
108
117
  } else if (verified !== "" && installed !== "" && isNewer(installed, verified)) {
109
118
  status = "above-verified"
@@ -1,7 +1,7 @@
1
1
  // Generated by cli/scripts/generate-sot-payload.ts. DO NOT EDIT.
2
2
  // Edit SoT/, notification.mp3, or package.json, then run: bun cli/scripts/generate-sot-payload.ts
3
3
 
4
- export const GENERATED_PACKAGE_VERSION = "0.16.15"
4
+ export const GENERATED_PACKAGE_VERSION = "0.16.16"
5
5
 
6
6
  export const GENERATED_PAYLOAD_TEXT = {
7
7
  "SoT/.agents/skills.txt": "# Universal AI-agent skill manifest intentionally empty.\n# Global skill discovery is opt-in: add one <owner>/<repo> slug per line.\n# EngineNative ignores comments and blank lines.\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docks-kit",
3
- "version": "0.16.15",
3
+ "version": "0.16.16",
4
4
  "description": "Portable AI coding agent config kit — SoT sync engine + typed CLI for Claude Code, Codex, and universal agent skills",
5
5
  "type": "module",
6
6
  "license": "MIT",