Files
msd-core/sdk/package.json
Tom Boucher 8090456b66 feat(3555): QueryRuntimeBridge.executeForCjs synchronous primitive (Phase 5.0 of #3524)
Phase 5.0 of the CJS↔SDK hard-seam migration (parent #3524).
Foundational PR. Ships ONLY the synchronous primitive on the SDK
runtime bridge plus pinning tests. Per-family CJS router migrations
(state.*, verify.*, init.*, phase.*, phases.*, validate.*,
roadmap.*, frontmatter.*, config.*) become follow-up enhancements
that each reuse this primitive.

## What landed

- sdk/src/runtime-bridge-sync/index.ts (155 lines) — public API.
  Exports executeForCjs(input: RuntimeBridgeExecuteInput):
  RuntimeBridgeSyncResult. Synchronous; lazily creates the
  synckit sync function on first call.
- sdk/src/runtime-bridge-sync/worker.ts (167 lines) — synckit
  worker. Constructs a native-only QueryRuntimeBridge (with
  allowFallbackToSubprocess: false), awaits its async execute,
  catches GSDToolsError / GSDError, maps classification to the
  six ADR-0001 canonical error kinds plus exit code.
- sdk/src/runtime-bridge-sync/index.test.ts (197 lines, 8 vitest
  pinning fixtures) — success path; unknown_command;
  native_failure (shape); validation_error (shape); shape
  invariants; idempotency.
- tests/runtime-bridge-sync-smoke.test.cjs (99 lines, 4
  node:test cases) — proves the primitive works from CJS
  callers via require().

## Decisions

1. Synchronous-bridging mechanism: synckit. Disqualified:
   - deasync: stagnant (68 open issues, single maintainer,
     last release Nov 2025), private Node API (process.binding('uv')),
     untested on Node 22, documented deadlocks with modern
     Promise chains.
   - Sync-native SDK refactor: technically infeasible —
     acquireStateLock in state-mutation.ts uses await setTimeout
     for retry backoff; making that fully sync requires either
     Atomics.wait (which IS synckit), busy-loop (degrades
     responsiveness), or breaking 100+ SDK consumers.
   Synckit (v0.11.12) is pure JS, actively maintained (last
   push today), stable public APIs (Atomics.wait +
   SharedArrayBuffer), Node 22 compatible, no native compile.

2. Native-only transport inside the worker. The sync bridge
   uses allowFallbackToSubprocess: false. Unknown commands
   surface as unknown_command instead of spawning gsd-sdk.
   Keeps the worker self-contained and predictable.

3. Worker path resolution. resolveWorkerPath() navigates ../..
   from the loaded module URL to land at
   dist/runtime-bridge-sync/worker.js — works under both
   vitest (loads src) and CJS consumers (load dist).

4. GSDError.Blocked → validation_error. ADR-0001's 6-kind
   taxonomy has no `blocked` kind; Blocked classification is
   mapped onto validation_error since the operational shape
   matches (prerequisite missing).

## Numbers

- 8 SDK vitest pinning tests pass.
- 4 CJS smoke tests pass.
- Full suite: 9286/9286 pass (baseline 9282; +4 from the
  new smoke test cases).
- SDK vitest unit: 1860/1860 pass.
- Performance: 80ms first-call cold latency (Worker startup +
  bridge construction); 0.1ms steady-state per-call latency
  (10-call average after warmup). Well within budget for CJS
  dispatcher overhead.

## Canonical error kind coverage

- unknown_command: covered with pinning fixture
- native_failure: shape coverage (handler that throws)
- validation_error: shape coverage (GSDError.Validation +
  GSDError.Blocked)
- internal_error: shape coverage only (eliciting TypeError
  reliably from a registered handler requires elaborate fixture)
- native_timeout: NOT pinned (no registered handler genuinely
  times out; classification logic present in worker)
- fallback_failure: NOT pinned (subprocess fallback disabled
  by design in sync bridge)

The classification logic is in the worker regardless; per-family
migration PRs will exercise the unpinned kinds incidentally.

## Wiring

- sdk/package.json: synckit ^0.11.12 added as runtime
  dependency (not devDependency — it's required at runtime
  whenever a CJS caller invokes executeForCjs).
- sdk/package-lock.json: regenerated.
- CONTEXT.md: new "Sync Runtime Bridge Module" entry added
  after Dispatch Policy Module. Existing "CJS Command Router
  Adapter Module" entry amended with one sentence pointing at
  the primitive and the per-family migration roadmap.

No generator/freshness check needed for this phase — the
primitive IS the SDK (not a generated CJS mirror).

Closes #3555.
2026-05-15 11:10:03 -04:00

65 lines
2.1 KiB
JSON

{
"name": "@gsd-build/sdk",
"version": "1.50.0-canary.0",
"description": "GSD SDK — programmatic interface for running GSD plans via the Agent SDK",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"bin": {
"gsd-sdk": "./dist/cli.js"
},
"files": [
"dist",
"shared",
"prompts"
],
"repository": {
"type": "git",
"url": "git+https://github.com/gsd-build/get-shit-done.git",
"directory": "sdk"
},
"homepage": "https://github.com/gsd-build/get-shit-done/tree/main/sdk",
"bugs": {
"url": "https://github.com/gsd-build/get-shit-done/issues"
},
"author": "TÂCHES",
"license": "MIT",
"engines": {
"node": ">=22.0.0"
},
"scripts": {
"build": "tsc",
"check:alias-drift": "npm run build && node scripts/check-command-aliases-fresh.mjs",
"gen:state-document": "npm run build && npx tsx scripts/gen-state-document.ts",
"check:state-document-fresh": "npm run build && node scripts/check-state-document-fresh.mjs",
"gen:configuration": "npm run build && node scripts/gen-configuration.mjs",
"check:configuration-fresh": "npm run build && node scripts/check-configuration-fresh.mjs",
"gen:workstream-inventory-builder": "npm run build && node scripts/gen-workstream-inventory-builder.mjs",
"check:workstream-inventory-builder-fresh": "npm run build && node scripts/check-workstream-inventory-builder-fresh.mjs",
"gen:project-root": "npm run build && node scripts/gen-project-root.mjs",
"check:project-root-fresh": "npm run build && node scripts/check-project-root-fresh.mjs",
"prepublishOnly": "rm -rf dist && tsc && chmod +x dist/cli.js",
"test": "vitest run",
"test:unit": "vitest run --project unit",
"test:integration": "vitest run --project integration"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.84",
"synckit": "^0.11.12",
"ws": "^8.20.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/ws": "^8.18.1",
"tsx": "^4.22.0",
"typescript": "^5.7.0",
"vitest": "^3.1.1"
}
}