Phase 3 of the CJS↔SDK hard-seam migration (parent #3524). Introduces the Builder/Reader pattern for paired Modules with mixed pure-and-I/O concerns — the template for Phase 4 and follow-up enhancements that migrate other paired Modules. Phase 1 and Phase 2 migrated Modules where both sides used character-equivalent logic. Phase 3 introduces the case where the pure logic is shareable but the I/O is legitimately per-side. The Builder/Reader split resolves this: - The Builder is pure — accepts pre-collected data (BuilderInputs struct), returns the typed projection. One source of truth; one generator-emitted CJS mirror. Drift is structurally impossible. - The Readers are per-side hand-authored Adapters that do the fs reads in their native idiom (currently both sync; either side can go async later without touching the Builder), then delegate to the Builder. - sdk/src/workstream-inventory/builder.ts — Builder source. 170 lines. Pure. Exports buildWorkstreamInventory(inputs), isCompletedInventory(status), plus the three typed inventory interfaces (WorkstreamPhaseInventory, WorkstreamInventory, WorkstreamInventoryList). - sdk/src/workstream-inventory/builder.test.ts — 18 vitest pinning fixtures across all status branches, progress-percent clamping, active-marker projection, and isCompletedInventory classifier. - sdk/scripts/gen-workstream-inventory-builder.mjs — generator. Captures function bodies via Function.prototype.toString(); emits with the standard GENERATED FILE banner. Includes a small `const relative = path.relative;` preamble in the output to handle ESM destructured imports in the compiled source. - sdk/scripts/check-workstream-inventory-builder-fresh.mjs — freshness check. Imports the generator function directly (rather than duplicating logic) — a cleaner pattern than Phase 1/2's approach. - get-shit-done/bin/lib/workstream-inventory-builder.generated.cjs — generator-emitted CJS mirror. - tests/workstream-inventory-builder-generator.test.cjs — 16 parity assertions confirming CJS-generated output == SDK source output for every fixture. - bin/lib/workstream-inventory.cjs: 159 → 132 lines. Projection logic gone. `inspectWorkstream` and `listWorkstreamInventories` collect BuilderInputs via the existing sync fs functions and delegate to the Builder. `isCompletedInventory` re-exported from the Builder (its signature changed from object→string, but no external callers exist so the change is safe). - sdk/src/query/workstream-inventory.ts: 196 → 143 lines. Same shape, sync fs (the SDK was already sync — surprise from recon). Types re-exported from the Builder. - sdk/package.json: gen:workstream-inventory-builder and check:workstream-inventory-builder-fresh scripts. - package.json: proxy for the freshness check. - .githooks/pre-commit: drift block. - .github/workflows/test.yml: drift check step. - CONTEXT.md: amended "Workstream Inventory Module" entry to document the Builder/Reader split. - docs/INVENTORY.md, docs/INVENTORY-MANIFEST.json: +1 module count, +1 row for the generated builder. - Full suite: 9229/9229 pass (baseline 9215 + 14 net new from the parity assertions). - Vitest: 18 Builder fixtures pass. - Reader shrink: -27 lines on CJS, -53 lines on SDK. - Net diff (modified files only): +68 / -133 = 65-line reduction. New files (Builder, generator, freshness check, parity test) add ~600 lines of new structured code. 1. `isCompletedInventory` signature changed from isCompletedInventory(inventory: object) to isCompletedInventory(status: string). Original CJS exported the object form but no external caller passed an object — they all passed inventory.status. Verified by grep before committing. 2. Generator preamble. The compiled ESM uses `import { relative } from 'node:path'`, making `relative` a free variable in `buildWorkstreamInventory`. The generator emits `const relative = path.relative;` so the captured function body works in CJS. 3. Freshness check imports the generator. The freshness check imports the generator's buildWorkstreamInventoryBuilderCjs() function directly rather than duplicating generation logic. Cleaner than Phase 1/2; future generators should follow this. Shareable via the Builder/Reader pattern in future enhancements: - frontmatter (pure YAML/markdown parsing) - plan-scan (pure PLAN.md structure parsing) - decisions (pure decision-record parsing) - secrets (regex-based detection in text) - uat (UAT-criteria parsing) Structural divergence — different approach needed: - state — sync vs async file ops; mutation paths differ. - workstream — lifecycle ops; per-side API surface differs. - phase, roadmap, init, profile-output, template — large surfaces; each its own potential enhancement. None of these is in scope for Phase 3. Closes #3544.
80 lines
2.5 KiB
JSON
80 lines
2.5 KiB
JSON
{
|
|
"name": "get-shit-done-cc",
|
|
"version": "1.50.0-canary.0",
|
|
"description": "A meta-prompting, context engineering and spec-driven development system for Claude Code, OpenCode, Gemini and Codex by TÂCHES.",
|
|
"bin": {
|
|
"get-shit-done-cc": "bin/install.js",
|
|
"gsd-sdk": "bin/gsd-sdk.js",
|
|
"gsd-tools": "bin/gsd-sdk.js"
|
|
},
|
|
"files": [
|
|
"bin",
|
|
"commands",
|
|
"get-shit-done",
|
|
"agents",
|
|
"hooks",
|
|
"scripts",
|
|
"sdk/src",
|
|
"sdk/shared",
|
|
"sdk/prompts",
|
|
"sdk/dist",
|
|
"sdk/package.json",
|
|
"sdk/package-lock.json",
|
|
"sdk/tsconfig.json"
|
|
],
|
|
"keywords": [
|
|
"claude",
|
|
"claude-code",
|
|
"ai",
|
|
"meta-prompting",
|
|
"context-engineering",
|
|
"spec-driven-development",
|
|
"gemini",
|
|
"gemini-cli",
|
|
"codex",
|
|
"codex-cli"
|
|
],
|
|
"author": "TÂCHES",
|
|
"license": "MIT",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+https://github.com/gsd-build/get-shit-done.git"
|
|
},
|
|
"homepage": "https://github.com/gsd-build/get-shit-done",
|
|
"bugs": {
|
|
"url": "https://github.com/gsd-build/get-shit-done/issues"
|
|
},
|
|
"engines": {
|
|
"node": ">=22.0.0"
|
|
},
|
|
"dependencies": {
|
|
"@anthropic-ai/claude-agent-sdk": "^0.2.84",
|
|
"ws": "^8.20.0"
|
|
},
|
|
"devDependencies": {
|
|
"c8": "^11.0.0"
|
|
},
|
|
"optionalDependencies": {
|
|
"fallow": "^2.70.0"
|
|
},
|
|
"scripts": {
|
|
"build:hooks": "node scripts/build-hooks.js",
|
|
"build:sdk": "cd sdk && npm ci && npm run build",
|
|
"check:alias-drift": "cd sdk && npm run check:alias-drift",
|
|
"check:state-document-fresh": "cd sdk && npm run check:state-document-fresh",
|
|
"check:configuration-fresh": "cd sdk && npm run check:configuration-fresh",
|
|
"check:workstream-inventory-builder-fresh": "cd sdk && npm run check:workstream-inventory-builder-fresh",
|
|
"prepublishOnly": "npm run build:hooks && npm run build:sdk",
|
|
"pretest": "npm run build:sdk && npm run lint:skill-deps",
|
|
"pretest:coverage": "npm run build:sdk",
|
|
"lint:descriptions": "node scripts/lint-descriptions.cjs",
|
|
"lint:skill-deps": "node scripts/lint-skill-deps.cjs",
|
|
"lint:tests": "node scripts/lint-no-source-grep.cjs",
|
|
"lint:changeset": "node scripts/changeset/lint.cjs",
|
|
"changeset": "node scripts/changeset/new.cjs",
|
|
"changelog:render": "node scripts/changeset/cli.cjs render",
|
|
"test": "node scripts/run-tests.cjs",
|
|
"test:coverage": "c8 --check-coverage --lines 70 --reporter text --include 'get-shit-done/bin/lib/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs"
|
|
}
|
|
}
|