get-shit-done-cc 1.37.1 → 1.38.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.
Files changed (146) hide show
  1. package/README.md +5 -8
  2. package/agents/gsd-doc-classifier.md +168 -0
  3. package/agents/gsd-doc-synthesizer.md +204 -0
  4. package/bin/install.js +105 -1
  5. package/commands/gsd/import.md +1 -0
  6. package/commands/gsd/ingest-docs.md +42 -0
  7. package/commands/gsd/ultraplan-phase.md +33 -0
  8. package/get-shit-done/references/doc-conflict-engine.md +91 -0
  9. package/get-shit-done/workflows/import.md +6 -36
  10. package/get-shit-done/workflows/ingest-docs.md +326 -0
  11. package/get-shit-done/workflows/sketch.md +3 -1
  12. package/get-shit-done/workflows/ultraplan-phase.md +189 -0
  13. package/package.json +7 -2
  14. package/sdk/package-lock.json +1998 -0
  15. package/sdk/package.json +52 -0
  16. package/sdk/prompts/agents/gsd-executor.md +110 -0
  17. package/sdk/prompts/agents/gsd-phase-researcher.md +158 -0
  18. package/sdk/prompts/agents/gsd-plan-checker.md +145 -0
  19. package/sdk/prompts/agents/gsd-planner.md +214 -0
  20. package/sdk/prompts/agents/gsd-project-researcher.md +323 -0
  21. package/sdk/prompts/agents/gsd-research-synthesizer.md +237 -0
  22. package/sdk/prompts/agents/gsd-roadmapper.md +670 -0
  23. package/sdk/prompts/agents/gsd-verifier.md +144 -0
  24. package/sdk/prompts/templates/project.md +186 -0
  25. package/sdk/prompts/templates/requirements.md +231 -0
  26. package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
  27. package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
  28. package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
  29. package/sdk/prompts/templates/research-project/STACK.md +120 -0
  30. package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
  31. package/sdk/prompts/templates/roadmap.md +202 -0
  32. package/sdk/prompts/templates/state.md +175 -0
  33. package/sdk/prompts/workflows/discuss-phase.md +123 -0
  34. package/sdk/prompts/workflows/execute-plan.md +106 -0
  35. package/sdk/prompts/workflows/plan-phase.md +84 -0
  36. package/sdk/prompts/workflows/research-phase.md +44 -0
  37. package/sdk/prompts/workflows/verify-phase.md +142 -0
  38. package/sdk/src/assembled-prompts.test.ts +349 -0
  39. package/sdk/src/cli-transport.test.ts +388 -0
  40. package/sdk/src/cli-transport.ts +130 -0
  41. package/sdk/src/cli.test.ts +383 -0
  42. package/sdk/src/cli.ts +590 -0
  43. package/sdk/src/config.test.ts +168 -0
  44. package/sdk/src/config.ts +162 -0
  45. package/sdk/src/context-engine.test.ts +295 -0
  46. package/sdk/src/context-engine.ts +170 -0
  47. package/sdk/src/context-truncation.test.ts +163 -0
  48. package/sdk/src/context-truncation.ts +233 -0
  49. package/sdk/src/e2e.integration.test.ts +178 -0
  50. package/sdk/src/errors.ts +72 -0
  51. package/sdk/src/event-stream.test.ts +661 -0
  52. package/sdk/src/event-stream.ts +441 -0
  53. package/sdk/src/gsd-tools.test.ts +407 -0
  54. package/sdk/src/gsd-tools.ts +314 -0
  55. package/sdk/src/headless-prompts.test.ts +159 -0
  56. package/sdk/src/index.ts +326 -0
  57. package/sdk/src/init-e2e.integration.test.ts +136 -0
  58. package/sdk/src/init-runner.test.ts +783 -0
  59. package/sdk/src/init-runner.ts +734 -0
  60. package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
  61. package/sdk/src/logger.test.ts +149 -0
  62. package/sdk/src/logger.ts +113 -0
  63. package/sdk/src/milestone-runner.test.ts +421 -0
  64. package/sdk/src/phase-prompt.test.ts +538 -0
  65. package/sdk/src/phase-prompt.ts +264 -0
  66. package/sdk/src/phase-runner-types.test.ts +421 -0
  67. package/sdk/src/phase-runner.integration.test.ts +377 -0
  68. package/sdk/src/phase-runner.test.ts +2286 -0
  69. package/sdk/src/phase-runner.ts +1164 -0
  70. package/sdk/src/plan-parser.test.ts +528 -0
  71. package/sdk/src/plan-parser.ts +427 -0
  72. package/sdk/src/prompt-builder.test.ts +306 -0
  73. package/sdk/src/prompt-builder.ts +193 -0
  74. package/sdk/src/prompt-sanitizer.test.ts +260 -0
  75. package/sdk/src/prompt-sanitizer.ts +71 -0
  76. package/sdk/src/query/QUERY-HANDLERS.md +33 -0
  77. package/sdk/src/query/commit.test.ts +202 -0
  78. package/sdk/src/query/commit.ts +267 -0
  79. package/sdk/src/query/config-mutation.test.ts +356 -0
  80. package/sdk/src/query/config-mutation.ts +462 -0
  81. package/sdk/src/query/config-query.test.ts +161 -0
  82. package/sdk/src/query/config-query.ts +159 -0
  83. package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
  84. package/sdk/src/query/frontmatter-mutation.ts +325 -0
  85. package/sdk/src/query/frontmatter.test.ts +266 -0
  86. package/sdk/src/query/frontmatter.ts +360 -0
  87. package/sdk/src/query/helpers.test.ts +254 -0
  88. package/sdk/src/query/helpers.ts +353 -0
  89. package/sdk/src/query/index.ts +458 -0
  90. package/sdk/src/query/init-complex.test.ts +232 -0
  91. package/sdk/src/query/init-complex.ts +578 -0
  92. package/sdk/src/query/init.test.ts +308 -0
  93. package/sdk/src/query/init.ts +959 -0
  94. package/sdk/src/query/intel.test.ts +90 -0
  95. package/sdk/src/query/intel.ts +316 -0
  96. package/sdk/src/query/phase-lifecycle.test.ts +1079 -0
  97. package/sdk/src/query/phase-lifecycle.ts +1453 -0
  98. package/sdk/src/query/phase.test.ts +307 -0
  99. package/sdk/src/query/phase.ts +340 -0
  100. package/sdk/src/query/pipeline.test.ts +169 -0
  101. package/sdk/src/query/pipeline.ts +243 -0
  102. package/sdk/src/query/profile.test.ts +54 -0
  103. package/sdk/src/query/profile.ts +367 -0
  104. package/sdk/src/query/progress.test.ts +156 -0
  105. package/sdk/src/query/progress.ts +267 -0
  106. package/sdk/src/query/registry.test.ts +181 -0
  107. package/sdk/src/query/registry.ts +174 -0
  108. package/sdk/src/query/roadmap.test.ts +275 -0
  109. package/sdk/src/query/roadmap.ts +470 -0
  110. package/sdk/src/query/skills.test.ts +73 -0
  111. package/sdk/src/query/skills.ts +56 -0
  112. package/sdk/src/query/state-mutation.test.ts +390 -0
  113. package/sdk/src/query/state-mutation.ts +761 -0
  114. package/sdk/src/query/state.test.ts +347 -0
  115. package/sdk/src/query/state.ts +395 -0
  116. package/sdk/src/query/stubs.test.ts +351 -0
  117. package/sdk/src/query/summary.test.ts +55 -0
  118. package/sdk/src/query/summary.ts +178 -0
  119. package/sdk/src/query/template.test.ts +179 -0
  120. package/sdk/src/query/template.ts +242 -0
  121. package/sdk/src/query/uat.test.ts +73 -0
  122. package/sdk/src/query/uat.ts +175 -0
  123. package/sdk/src/query/utils.test.ts +82 -0
  124. package/sdk/src/query/utils.ts +92 -0
  125. package/sdk/src/query/validate.test.ts +656 -0
  126. package/sdk/src/query/validate.ts +738 -0
  127. package/sdk/src/query/verify.test.ts +414 -0
  128. package/sdk/src/query/verify.ts +588 -0
  129. package/sdk/src/query/websearch.test.ts +31 -0
  130. package/sdk/src/query/websearch.ts +82 -0
  131. package/sdk/src/query/workspace.test.ts +119 -0
  132. package/sdk/src/query/workspace.ts +131 -0
  133. package/sdk/src/query/workstream.test.ts +51 -0
  134. package/sdk/src/query/workstream.ts +252 -0
  135. package/sdk/src/research-gate.test.ts +190 -0
  136. package/sdk/src/research-gate.ts +94 -0
  137. package/sdk/src/session-runner.test.ts +98 -0
  138. package/sdk/src/session-runner.ts +299 -0
  139. package/sdk/src/tool-scoping.test.ts +160 -0
  140. package/sdk/src/tool-scoping.ts +61 -0
  141. package/sdk/src/types.ts +913 -0
  142. package/sdk/src/workstream-utils.ts +33 -0
  143. package/sdk/src/ws-flag.test.ts +285 -0
  144. package/sdk/src/ws-transport.test.ts +161 -0
  145. package/sdk/src/ws-transport.ts +93 -0
  146. package/sdk/tsconfig.json +20 -0
package/README.md CHANGED
@@ -89,14 +89,11 @@ People who want to describe what they want and have it built correctly — witho
89
89
 
90
90
  Built-in quality gates catch real problems: schema drift detection flags ORM changes missing migrations, security enforcement anchors verification to threat models, and scope reduction detection prevents the planner from silently dropping your requirements.
91
91
 
92
- ### v1.36.0 Highlights
92
+ ### v1.37.0 Highlights
93
93
 
94
- - **Knowledge graph integration** — `/gsd-graphify` brings knowledge graphs to planning agents for richer context connections
95
- - **SDK typed query foundation** — Registry-based `gsd-sdk query` command with classified errors and handlers for state, roadmap, phase lifecycle, and config
96
- - **TDD pipeline mode** — Opt-in test-driven development workflow with `--tdd` flag
97
- - **Context-window-aware prompt thinning** — Automatic prompt size reduction for sub-200K models
98
- - **Project skills awareness** — 9 GSD agents now discover and use project-scoped skills
99
- - **30+ bug fixes** — Worktree safety, state management, installer paths, and health check optimizations
94
+ - **Spiking & sketching** — `/gsd-spike` runs 2–5 focused experiments with Given/When/Then verdicts; `/gsd-sketch` produces 2–3 interactive HTML mockup variants per design question — both store artifacts in `.planning/` and pair with wrap-up commands to package findings into project-local skills
95
+ - **Agent size-budget enforcement** — Tiered line-count limits (XL: 1 600, Large: 1 000, Default: 500) keep agent prompts lean; violations surface in CI
96
+ - **Shared boilerplate extraction** — Mandatory-initial-read and project-skills-discovery logic extracted to reference files, reducing duplication across a dozen agents
100
97
 
101
98
  ---
102
99
 
@@ -196,7 +193,7 @@ npx get-shit-done-cc --all --global # Install to all directories
196
193
 
197
194
  Use `--global` (`-g`) or `--local` (`-l`) to skip the location prompt.
198
195
  Use `--claude`, `--opencode`, `--gemini`, `--kilo`, `--codex`, `--copilot`, `--cursor`, `--windsurf`, `--antigravity`, `--augment`, `--trae`, `--qwen`, `--codebuddy`, `--cline`, or `--all` to skip the runtime prompt.
199
- Use `--sdk` to also install the GSD SDK CLI (`gsd-sdk`) for headless autonomous execution.
196
+ The GSD SDK CLI (`gsd-sdk`) is installed automatically (required by `/gsd-*` commands). Pass `--no-sdk` to skip the SDK install, or `--sdk` to force a reinstall.
200
197
 
201
198
  </details>
202
199
 
@@ -0,0 +1,168 @@
1
+ ---
2
+ name: gsd-doc-classifier
3
+ description: Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Spawned in parallel by /gsd-ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
4
+ tools: Read, Write, Grep, Glob
5
+ color: yellow
6
+ # hooks:
7
+ # PostToolUse:
8
+ # - matcher: "Write|Edit"
9
+ # hooks:
10
+ # - type: command
11
+ # command: "true"
12
+ ---
13
+
14
+ <role>
15
+ You are a GSD doc classifier. You read ONE document and write a structured classification to `.planning/intel/classifications/`. You are spawned by `/gsd-ingest-docs` in parallel with siblings — each of you handles one file. Your output is consumed by `gsd-doc-synthesizer`.
16
+
17
+ **CRITICAL: Mandatory Initial Read**
18
+ If the prompt contains a `<required_reading>` block, use the `Read` tool to load every file listed there before doing anything else. That is your primary context.
19
+ </role>
20
+
21
+ <why_this_matters>
22
+ Your classification drives extraction. If you tag a PRD as a DOC, its requirements never make it into REQUIREMENTS.md. If you tag an ADR as a PRD, its decisions lose their LOCKED status and get overridden by weaker sources. Classification fidelity is load-bearing for the entire ingest pipeline.
23
+ </why_this_matters>
24
+
25
+ <taxonomy>
26
+
27
+ **ADR** (Architecture Decision Record)
28
+ - One architectural or technical decision, locked once made
29
+ - Hallmarks: `Status: Accepted|Proposed|Superseded`, numbered filename (`0001-`, `ADR-001-`), sections like `Context / Decision / Consequences`
30
+ - Content: trade-off analysis ending in one chosen path
31
+ - Produces: **locked decisions** (highest precedence by default)
32
+
33
+ **PRD** (Product Requirements Document)
34
+ - What the product/feature should do, from a user/business perspective
35
+ - Hallmarks: user stories, acceptance criteria, success metrics, goals/non-goals, "as a user..." language
36
+ - Content: requirements + scope, not implementation
37
+ - Produces: **requirements** (mid precedence)
38
+
39
+ **SPEC** (Technical Specification)
40
+ - How something is built — APIs, schemas, contracts, non-functional requirements
41
+ - Hallmarks: endpoint tables, request/response schemas, SLOs, protocol definitions, data models
42
+ - Content: implementation contracts the system must honor
43
+ - Produces: **technical constraints** (above PRD, below ADR)
44
+
45
+ **DOC** (General Documentation)
46
+ - Supporting context: guides, tutorials, design rationales, onboarding, runbooks
47
+ - Hallmarks: prose-heavy, tutorial structure, explanations without a decision or requirement
48
+ - Produces: **context only** (lowest precedence)
49
+
50
+ **UNKNOWN**
51
+ - Cannot be confidently placed in any of the above
52
+ - Record observed signals and let the synthesizer or user decide
53
+
54
+ </taxonomy>
55
+
56
+ <process>
57
+
58
+ <step name="parse_input">
59
+ The prompt gives you:
60
+ - `FILEPATH` — the document to classify (absolute path)
61
+ - `OUTPUT_DIR` — where to write your JSON output (e.g., `.planning/intel/classifications/`)
62
+ - `MANIFEST_TYPE` (optional) — if present, the manifest declared this file's type; treat as authoritative, skip heuristic+LLM classification
63
+ - `MANIFEST_PRECEDENCE` (optional) — override precedence if declared
64
+ </step>
65
+
66
+ <step name="heuristic_classification">
67
+ Before reading the file, apply fast filename/path heuristics:
68
+
69
+ - Path matches `**/adr/**` or filename `ADR-*.md` or `0001-*.md`…`9999-*.md` → strong ADR signal
70
+ - Path matches `**/prd/**` or filename `PRD-*.md` → strong PRD signal
71
+ - Path matches `**/spec/**`, `**/specs/**`, `**/rfc/**` or filename `SPEC-*.md`/`RFC-*.md` → strong SPEC signal
72
+ - Everything else → unclear, proceed to content analysis
73
+
74
+ If `MANIFEST_TYPE` is provided, skip to `extract_metadata` with that type.
75
+ </step>
76
+
77
+ <step name="read_and_analyze">
78
+ Read the file. Parse its frontmatter (if YAML) and scan the first 50 lines + any table-of-contents.
79
+
80
+ **Frontmatter signals (authoritative if present):**
81
+ - `type: adr|prd|spec|doc` → use directly
82
+ - `status: Accepted|Proposed|Superseded|Draft` → ADR signal
83
+ - `decision:` field → ADR
84
+ - `requirements:` or `user_stories:` → PRD
85
+
86
+ **Content signals:**
87
+ - Contains `## Decision` + `## Consequences` sections → ADR
88
+ - Contains `## User Stories` or `As a [user], I want` paragraphs → PRD
89
+ - Contains endpoint/schema tables, OpenAPI snippets, protocol fields → SPEC
90
+ - None of the above, prose only → DOC
91
+
92
+ **Ambiguity rule:** If two types compete at roughly equal strength, pick the one with the highest-precedence signal (ADR > SPEC > PRD > DOC). Record the ambiguity in `notes`.
93
+
94
+ **Confidence:**
95
+ - `high` — frontmatter or filename convention + matching content signals
96
+ - `medium` — content signals only, one dominant
97
+ - `low` — signals conflict or are thin → classify as best guess but flag the low confidence
98
+
99
+ If signals are too thin to choose, output `UNKNOWN` with `low` confidence and list observed signals in `notes`.
100
+ </step>
101
+
102
+ <step name="extract_metadata">
103
+ Regardless of type, extract:
104
+
105
+ - **title** — the document's H1, or the filename if no H1
106
+ - **summary** — one sentence (≤ 30 words) describing the doc's subject
107
+ - **scope** — list of concrete nouns the doc is about (systems, components, features)
108
+ - **cross_refs** — list of other doc paths referenced by this doc (markdown links, filename mentions). Include both relative and absolute paths as-written.
109
+ - **locked_markers** — for ADRs only: does status read `Accepted` (locked) vs `Proposed`/`Draft` (not locked)? Set `locked: true|false`.
110
+ </step>
111
+
112
+ <step name="write_output">
113
+ Write to `{OUTPUT_DIR}/{slug}.json` where `slug` is the filename without extension (replace non-alphanumerics with `-`).
114
+
115
+ JSON schema:
116
+
117
+ ```json
118
+ {
119
+ "source_path": "{FILEPATH}",
120
+ "type": "ADR|PRD|SPEC|DOC|UNKNOWN",
121
+ "confidence": "high|medium|low",
122
+ "manifest_override": false,
123
+ "title": "...",
124
+ "summary": "...",
125
+ "scope": ["...", "..."],
126
+ "cross_refs": ["path/to/other.md", "..."],
127
+ "locked": true,
128
+ "precedence": null,
129
+ "notes": "Only populated when confidence is low or ambiguity was resolved"
130
+ }
131
+ ```
132
+
133
+ Field rules:
134
+ - `manifest_override: true` only when `MANIFEST_TYPE` was provided
135
+ - `locked`: always `false` unless type is `ADR` with `Accepted` status
136
+ - `precedence`: `null` unless `MANIFEST_PRECEDENCE` was provided (then store the integer)
137
+ - `notes`: omit or empty string when confidence is `high`
138
+
139
+ **ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
140
+ </step>
141
+
142
+ <step name="return_confirmation">
143
+ Return one line to the orchestrator. No JSON, no document contents.
144
+
145
+ ```
146
+ Classified: {filename} → {TYPE} ({confidence}){, LOCKED if true}
147
+ ```
148
+ </step>
149
+
150
+ </process>
151
+
152
+ <anti_patterns>
153
+ Do NOT:
154
+ - Read the doc's transitive references — only classify what you were assigned
155
+ - Invent classification types beyond the five defined
156
+ - Output anything other than the one-line confirmation to the orchestrator
157
+ - Downgrade confidence silently — when unsure, output `UNKNOWN` with signals in `notes`
158
+ - Classify a `Proposed` or `Draft` ADR as `locked: true` — only `Accepted` counts as locked
159
+ - Use markdown tables or prose in your JSON output — stick to the schema
160
+ </anti_patterns>
161
+
162
+ <success_criteria>
163
+ - [ ] Exactly one JSON file written to OUTPUT_DIR
164
+ - [ ] Schema matches the template above, all required fields present
165
+ - [ ] Confidence level reflects the actual signal strength
166
+ - [ ] `locked` is true only for Accepted ADRs
167
+ - [ ] Confirmation line returned to orchestrator (≤ 1 line)
168
+ </success_criteria>
@@ -0,0 +1,204 @@
1
+ ---
2
+ name: gsd-doc-synthesizer
3
+ description: Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-ref cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes INGEST-CONFLICTS.md with three buckets (auto-resolved, competing-variants, unresolved-blockers). Spawned by /gsd-ingest-docs.
4
+ tools: Read, Write, Grep, Glob, Bash
5
+ color: orange
6
+ # hooks:
7
+ # PostToolUse:
8
+ # - matcher: "Write|Edit"
9
+ # hooks:
10
+ # - type: command
11
+ # command: "true"
12
+ ---
13
+
14
+ <role>
15
+ You are a GSD doc synthesizer. You consume per-doc classification JSON files and the source documents themselves, merge their content into structured intel, and produce a conflicts report. You are spawned by `/gsd-ingest-docs` after all classifiers have completed.
16
+
17
+ You do NOT prompt the user. You do NOT write PROJECT.md, REQUIREMENTS.md, or ROADMAP.md — those are produced downstream by `gsd-roadmapper` using your output. Your job is synthesis + conflict surfacing.
18
+
19
+ **CRITICAL: Mandatory Initial Read**
20
+ If the prompt contains a `<required_reading>` block, load every file listed there first — especially `references/doc-conflict-engine.md` which defines your conflict report format.
21
+ </role>
22
+
23
+ <why_this_matters>
24
+ You are the precedence-enforcing layer. Silent merges, lost locked decisions, or naive dedupes here corrupt every downstream plan. When in doubt, surface the conflict rather than pick.
25
+ </why_this_matters>
26
+
27
+ <inputs>
28
+ The prompt provides:
29
+ - `CLASSIFICATIONS_DIR` — directory containing per-doc `*.json` files produced by `gsd-doc-classifier`
30
+ - `INTEL_DIR` — where to write synthesized intel (typically `.planning/intel/`)
31
+ - `CONFLICTS_PATH` — where to write `INGEST-CONFLICTS.md` (typically `.planning/INGEST-CONFLICTS.md`)
32
+ - `MODE` — `new` or `merge`
33
+ - `EXISTING_CONTEXT` (merge mode only) — list of paths to existing `.planning/` files to check against (ROADMAP.md, PROJECT.md, REQUIREMENTS.md, CONTEXT.md files)
34
+ - `PRECEDENCE` — ordered list, default `["ADR", "SPEC", "PRD", "DOC"]`; may be overridden per-doc via the classification's `precedence` field
35
+ </inputs>
36
+
37
+ <precedence_rules>
38
+
39
+ **Default ordering:** `ADR > SPEC > PRD > DOC`. Higher-precedence sources win when content contradicts.
40
+
41
+ **Per-doc override:** If a classification has a non-null `precedence` integer, it overrides the default for that doc only. Lower integer = higher precedence.
42
+
43
+ **LOCKED decisions:**
44
+ - An ADR with `locked: true` produces decisions that cannot be auto-overridden by any source, including another LOCKED ADR.
45
+ - **LOCKED vs LOCKED:** two locked ADRs in the ingest set that contradict → hard BLOCKER, both in `new` and `merge` modes. Never auto-resolve.
46
+ - **LOCKED vs non-LOCKED:** LOCKED wins, logged in auto-resolved bucket with rationale.
47
+ - **Merge mode, LOCKED in ingest vs existing locked decision in CONTEXT.md:** hard BLOCKER.
48
+
49
+ **Same requirement, divergent acceptance criteria across PRDs:**
50
+ Do NOT pick one. Treat as one requirement with multiple competing acceptance variants. Write all variants to the `competing-variants` bucket for user resolution.
51
+
52
+ </precedence_rules>
53
+
54
+ <process>
55
+
56
+ <step name="load_classifications">
57
+ Read every `*.json` in `CLASSIFICATIONS_DIR`. Build an in-memory index keyed by `source_path`. Count by type.
58
+
59
+ If any classification is `UNKNOWN` with `low` confidence, note it — these will surface as unresolved-blockers (user must type-tag via manifest and re-run).
60
+ </step>
61
+
62
+ <step name="cycle_detection">
63
+ Build a directed graph from `cross_refs`. Run cycle detection (DFS with three-color marking).
64
+
65
+ If cycles exist:
66
+ - Record each cycle as an unresolved-blocker entry
67
+ - Do NOT proceed with synthesis on the cyclic set — synthesis loops produce garbage
68
+ - Docs outside the cycle may still be synthesized
69
+
70
+ **Cap:** Max traversal depth 50. If the ref graph exceeds this, abort with a BLOCKER entry directing user to shrink input via `--manifest`.
71
+ </step>
72
+
73
+ <step name="extract_per_type">
74
+ For each classified doc, read the source and extract per-type content. Write per-type intel files to `INTEL_DIR`:
75
+
76
+ - **ADRs** → `INTEL_DIR/decisions.md`
77
+ - One entry per ADR: title, source path, status (locked/proposed), decision statement, scope
78
+ - Preserve every decision separately; synthesis happens in the next step
79
+
80
+ - **PRDs** → `INTEL_DIR/requirements.md`
81
+ - One entry per requirement: ID (derive `REQ-{slug}`), source PRD path, description, acceptance criteria, scope
82
+ - One PRD usually yields multiple requirements
83
+
84
+ - **SPECs** → `INTEL_DIR/constraints.md`
85
+ - One entry per constraint: title, source path, type (api-contract | schema | nfr | protocol), content block
86
+
87
+ - **DOCs** → `INTEL_DIR/context.md`
88
+ - Running notes keyed by topic; appended verbatim with source attribution
89
+
90
+ Every entry must have `source: {path}` so downstream consumers can trace provenance.
91
+ </step>
92
+
93
+ <step name="detect_conflicts">
94
+ Walk the extracted intel to find conflicts. Apply precedence rules to classify each into a bucket.
95
+
96
+ **Conflict detection passes:**
97
+
98
+ 1. **LOCKED-vs-LOCKED ADR contradiction** — two ADRs with `locked: true` whose decision statements contradict on the same scope → `unresolved-blockers`
99
+ 2. **ADR-vs-existing locked CONTEXT.md (merge mode only)** — any ingest decision contradicts a decision in an existing `<decisions>` block marked locked → `unresolved-blockers`
100
+ 3. **PRD requirement overlap with different acceptance** — two PRDs define requirements on the same scope with non-identical acceptance criteria → `competing-variants`; preserve all variants
101
+ 4. **SPEC contradicts higher-precedence ADR** — SPEC asserts a technical decision contradicting a higher-precedence ADR decision → `auto-resolved` with ADR as winner, rationale logged
102
+ 5. **Lower-precedence contradicts higher** (non-locked) — `auto-resolved` with higher-precedence source winning
103
+ 6. **UNKNOWN-confidence-low docs** — `unresolved-blockers` (user must re-tag)
104
+ 7. **Cycle-detection blockers** (from previous step) — `unresolved-blockers`
105
+
106
+ Apply the `doc-conflict-engine` severity semantics:
107
+ - `unresolved-blockers` maps to [BLOCKER] — gate the workflow
108
+ - `competing-variants` maps to [WARNING] — user must pick before routing
109
+ - `auto-resolved` maps to [INFO] — recorded for transparency
110
+ </step>
111
+
112
+ <step name="write_conflicts_report">
113
+ Write `CONFLICTS_PATH` using the format from `references/doc-conflict-engine.md`. Three buckets, plain text, no tables.
114
+
115
+ Structure:
116
+
117
+ ```
118
+ ## Conflict Detection Report
119
+
120
+ ### BLOCKERS ({N})
121
+
122
+ [BLOCKER] LOCKED ADR contradiction
123
+ Found: docs/adr/0004-db.md declares "Postgres" (Accepted)
124
+ Expected: docs/adr/0011-db.md declares "DynamoDB" (Accepted) — same scope "primary datastore"
125
+ → Resolve by marking one ADR Superseded, or set precedence in --manifest
126
+
127
+ ### WARNINGS ({N})
128
+
129
+ [WARNING] Competing acceptance variants for REQ-user-auth
130
+ Found: docs/prd/auth-v1.md requires "email+password", docs/prd/auth-v2.md requires "SSO only"
131
+ Impact: Synthesis cannot pick without losing intent
132
+ → Choose one variant or split into two requirements before routing
133
+
134
+ ### INFO ({N})
135
+
136
+ [INFO] Auto-resolved: ADR > SPEC on cache layer
137
+ Note: docs/adr/0007-cache.md (Accepted) chose Redis; docs/specs/cache-api.md assumed Memcached — ADR wins, SPEC updated to Redis in synthesized intel
138
+ ```
139
+
140
+ Every entry requires `source:` references for every claim.
141
+ </step>
142
+
143
+ <step name="write_synthesis_summary">
144
+ Write `INTEL_DIR/SYNTHESIS.md` — a human-readable summary of what was synthesized:
145
+
146
+ - Doc counts by type
147
+ - Decisions locked (count + source paths)
148
+ - Requirements extracted (count, with IDs)
149
+ - Constraints (count + type breakdown)
150
+ - Context topics (count)
151
+ - Conflicts: N blockers, N competing-variants, N auto-resolved
152
+ - Pointer to `CONFLICTS_PATH` for detail
153
+ - Pointer to per-type intel files
154
+
155
+ This is the single entry point `gsd-roadmapper` reads.
156
+
157
+ **ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
158
+ </step>
159
+
160
+ <step name="return_confirmation">
161
+ Return ≤ 10 lines to the orchestrator:
162
+
163
+ ```
164
+ ## Synthesis Complete
165
+
166
+ Docs synthesized: {N} ({breakdown})
167
+ Decisions locked: {N}
168
+ Requirements: {N}
169
+ Conflicts: {N} blockers, {N} variants, {N} auto-resolved
170
+
171
+ Intel: {INTEL_DIR}/
172
+ Report: {CONFLICTS_PATH}
173
+
174
+ {If blockers > 0: "STATUS: BLOCKED — review report before routing"}
175
+ {If variants > 0: "STATUS: AWAITING USER — competing variants need resolution"}
176
+ {Else: "STATUS: READY — safe to route"}
177
+ ```
178
+
179
+ Do NOT dump intel contents. The orchestrator reads the files directly.
180
+ </step>
181
+
182
+ </process>
183
+
184
+ <anti_patterns>
185
+ Do NOT:
186
+ - Pick a winner between two LOCKED ADRs — always BLOCK
187
+ - Merge competing PRD acceptance criteria into a single "combined" criterion — preserve all variants
188
+ - Write PROJECT.md, REQUIREMENTS.md, ROADMAP.md, or STATE.md — those are the roadmapper's job
189
+ - Skip cycle detection — synthesis loops produce garbage output
190
+ - Use markdown tables in the conflicts report — violates the doc-conflict-engine contract
191
+ - Auto-resolve by filename order, timestamp, or arbitrary tiebreaker — precedence rules only
192
+ - Silently drop `UNKNOWN`-confidence-low docs — they must surface as blockers
193
+ </anti_patterns>
194
+
195
+ <success_criteria>
196
+ - [ ] All classifications in CLASSIFICATIONS_DIR consumed
197
+ - [ ] Cycle detection run on cross-ref graph
198
+ - [ ] Per-type intel files written to INTEL_DIR
199
+ - [ ] INGEST-CONFLICTS.md written with three buckets, format per `doc-conflict-engine.md`
200
+ - [ ] SYNTHESIS.md written as entry point for downstream consumers
201
+ - [ ] LOCKED-vs-LOCKED contradictions surface as BLOCKERs, never auto-resolved
202
+ - [ ] Competing acceptance variants preserved, never merged
203
+ - [ ] Confirmation returned (≤ 10 lines)
204
+ </success_criteria>
package/bin/install.js CHANGED
@@ -77,6 +77,13 @@ const hasBoth = args.includes('--both'); // Legacy flag, keeps working
77
77
  const hasAll = args.includes('--all');
78
78
  const hasUninstall = args.includes('--uninstall') || args.includes('-u');
79
79
  const hasPortableHooks = args.includes('--portable-hooks') || process.env.GSD_PORTABLE_HOOKS === '1';
80
+ const hasSdk = args.includes('--sdk');
81
+ const hasNoSdk = args.includes('--no-sdk');
82
+
83
+ if (hasSdk && hasNoSdk) {
84
+ console.error(` ${yellow}Cannot specify both --sdk and --no-sdk${reset}`);
85
+ process.exit(1);
86
+ }
80
87
 
81
88
  // Runtime selection - can be set by flags or interactive prompt
82
89
  let selectedRuntimes = [];
@@ -6626,6 +6633,95 @@ function promptLocation(runtimes) {
6626
6633
  });
6627
6634
  }
6628
6635
 
6636
+ /**
6637
+ * Build `@gsd-build/sdk` from the in-repo `sdk/` source tree and install the
6638
+ * resulting `gsd-sdk` binary globally so workflow commands that shell out to
6639
+ * `gsd-sdk query …` succeed.
6640
+ *
6641
+ * We build from source rather than `npm install -g @gsd-build/sdk` because the
6642
+ * npm-published package lags the source tree and shipping a stale SDK breaks
6643
+ * every /gsd-* command that depends on newer query handlers.
6644
+ *
6645
+ * Skip if --no-sdk. Skip if already on PATH (unless --sdk was explicit).
6646
+ * Failures are warnings, not fatal.
6647
+ */
6648
+ function installSdkIfNeeded() {
6649
+ if (hasNoSdk) {
6650
+ console.log(`\n ${dim}Skipping GSD SDK install (--no-sdk)${reset}`);
6651
+ return;
6652
+ }
6653
+
6654
+ const { spawnSync } = require('child_process');
6655
+ const path = require('path');
6656
+ const fs = require('fs');
6657
+
6658
+ if (!hasSdk) {
6659
+ const probe = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['gsd-sdk'], { stdio: 'ignore' });
6660
+ if (probe.status === 0) {
6661
+ console.log(` ${green}✓${reset} GSD SDK already installed (gsd-sdk on PATH)`);
6662
+ return;
6663
+ }
6664
+ }
6665
+
6666
+ // Locate the in-repo sdk/ directory relative to this installer file.
6667
+ // For global npm installs this resolves inside the published package dir;
6668
+ // for git-based installs (npx github:..., local clone) it resolves to the
6669
+ // repo's sdk/ tree. Both contain the source tree because root package.json
6670
+ // includes "sdk" in its `files` array.
6671
+ const sdkDir = path.resolve(__dirname, '..', 'sdk');
6672
+ const sdkPackageJson = path.join(sdkDir, 'package.json');
6673
+
6674
+ const warnManual = (reason) => {
6675
+ console.warn(` ${yellow}⚠${reset} ${reason}`);
6676
+ console.warn(` Build manually from the repo sdk/ directory:`);
6677
+ console.warn(` ${cyan}cd ${sdkDir} && npm install && npm run build && npm install -g .${reset}`);
6678
+ console.warn(` Then restart your shell so the updated PATH is picked up.`);
6679
+ console.warn(` Without it, /gsd-* commands will fail with "command not found: gsd-sdk".`);
6680
+ };
6681
+
6682
+ if (!fs.existsSync(sdkPackageJson)) {
6683
+ warnManual(`SDK source tree not found at ${sdkDir}.`);
6684
+ return;
6685
+ }
6686
+
6687
+ console.log(`\n ${cyan}Building GSD SDK from source (${sdkDir})…${reset}`);
6688
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
6689
+
6690
+ // 1. Install sdk build-time dependencies (tsc, etc.)
6691
+ const installResult = spawnSync(npmCmd, ['install'], { cwd: sdkDir, stdio: 'inherit' });
6692
+ if (installResult.status !== 0) {
6693
+ warnManual('Failed to `npm install` in sdk/.');
6694
+ return;
6695
+ }
6696
+
6697
+ // 2. Compile TypeScript → sdk/dist/
6698
+ const buildResult = spawnSync(npmCmd, ['run', 'build'], { cwd: sdkDir, stdio: 'inherit' });
6699
+ if (buildResult.status !== 0) {
6700
+ warnManual('Failed to `npm run build` in sdk/.');
6701
+ return;
6702
+ }
6703
+
6704
+ // 3. Install the built package globally so `gsd-sdk` lands on PATH.
6705
+ const globalResult = spawnSync(npmCmd, ['install', '-g', '.'], { cwd: sdkDir, stdio: 'inherit' });
6706
+ if (globalResult.status !== 0) {
6707
+ warnManual('Failed to `npm install -g .` from sdk/.');
6708
+ return;
6709
+ }
6710
+
6711
+ // Verify gsd-sdk is actually resolvable on PATH. npm's global bin dir is
6712
+ // not always on the current shell's PATH (Homebrew prefixes, nvm setups,
6713
+ // unconfigured npm prefix), so a zero exit status from `npm install -g`
6714
+ // alone is not proof of a working binary.
6715
+ const resolverCmd = process.platform === 'win32' ? 'where' : 'which';
6716
+ const verify = spawnSync(resolverCmd, ['gsd-sdk'], { encoding: 'utf-8' });
6717
+ if (verify.status === 0 && verify.stdout && verify.stdout.trim()) {
6718
+ console.log(` ${green}✓${reset} Built and installed GSD SDK from source (gsd-sdk resolved at ${verify.stdout.trim().split('\n')[0]})`);
6719
+ } else {
6720
+ warnManual('Built and installed GSD SDK from source but gsd-sdk is not on PATH — npm global bin may not be in your PATH.');
6721
+ if (verify.stderr) console.warn(` resolver stderr: ${verify.stderr.trim()}`);
6722
+ }
6723
+ }
6724
+
6629
6725
  /**
6630
6726
  * Install GSD for all selected runtimes
6631
6727
  */
@@ -6641,7 +6737,15 @@ function installAllRuntimes(runtimes, isGlobal, isInteractive) {
6641
6737
  const primaryStatuslineResult = results.find(r => statuslineRuntimes.includes(r.runtime));
6642
6738
 
6643
6739
  const finalize = (shouldInstallStatusline) => {
6644
- // Handle SDK installation before printing final summaries
6740
+ // Build @gsd-build/sdk from the in-repo sdk/ source and install it globally
6741
+ // so `gsd-sdk` lands on PATH. Every /gsd-* command shells out to
6742
+ // `gsd-sdk query …`; without this, commands fail with "command not found:
6743
+ // gsd-sdk". The npm-published @gsd-build/sdk is kept intentionally frozen
6744
+ // at an older version; we always build from source so users get the SDK
6745
+ // that matches the installed GSD version.
6746
+ // Runs by default; skip with --no-sdk. Idempotent when already present.
6747
+ installSdkIfNeeded();
6748
+
6645
6749
  const printSummaries = () => {
6646
6750
  for (const result of results) {
6647
6751
  const useStatusline = statuslineRuntimes.includes(result.runtime) && shouldInstallStatusline;
@@ -25,6 +25,7 @@ Future: `--prd` mode for PRD extraction is planned for a follow-up PR.
25
25
  @~/.claude/get-shit-done/workflows/import.md
26
26
  @~/.claude/get-shit-done/references/ui-brand.md
27
27
  @~/.claude/get-shit-done/references/gate-prompts.md
28
+ @~/.claude/get-shit-done/references/doc-conflict-engine.md
28
29
  </execution_context>
29
30
 
30
31
  <context>
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: gsd:ingest-docs
3
+ description: Scan a repo for mixed ADRs, PRDs, SPECs, and DOCs and bootstrap or merge the full .planning/ setup from them. Classifies each doc in parallel, synthesizes a consolidated context with a conflicts report, and routes to new-project or merge-milestone depending on whether .planning/ already exists.
4
+ argument-hint: "[path] [--mode new|merge] [--manifest <file>] [--resolve auto|interactive]"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Bash
10
+ - Glob
11
+ - Grep
12
+ - AskUserQuestion
13
+ - Task
14
+ ---
15
+
16
+ <objective>
17
+ Build the full `.planning/` setup (or merge into an existing one) from multiple pre-existing planning documents — ADRs, PRDs, SPECs, DOCs — in one pass.
18
+
19
+ - **Net-new bootstrap** (`--mode new`, default when `.planning/` is absent): produces PROJECT.md + REQUIREMENTS.md + ROADMAP.md + STATE.md from synthesized doc content, delegating final generation to `gsd-roadmapper`.
20
+ - **Merge into existing** (`--mode merge`, default when `.planning/` is present): appends phases and requirements derived from the ingested docs; hard-blocks any contradiction with existing locked decisions.
21
+
22
+ Auto-synthesizes most conflicts using the precedence rule `ADR > SPEC > PRD > DOC` (overridable via manifest). Surfaces unresolved cases in `.planning/INGEST-CONFLICTS.md` with three buckets: auto-resolved, competing-variants, unresolved-blockers. The BLOCKER gate from the shared conflict engine prevents any destination file from being written when unresolved contradictions exist.
23
+
24
+ **Inputs:** directory-convention discovery (`docs/adr/`, `docs/prd/`, `docs/specs/`, `docs/rfc/`, root-level `{ADR,PRD,SPEC,RFC}-*.md`), or an explicit `--manifest <file>` YAML listing `{path, type, precedence?}` per doc.
25
+
26
+ **v1 constraints:** hard cap of 50 docs per invocation; `--resolve interactive` is reserved for a future release.
27
+ </objective>
28
+
29
+ <execution_context>
30
+ @~/.claude/get-shit-done/workflows/ingest-docs.md
31
+ @~/.claude/get-shit-done/references/ui-brand.md
32
+ @~/.claude/get-shit-done/references/gate-prompts.md
33
+ @~/.claude/get-shit-done/references/doc-conflict-engine.md
34
+ </execution_context>
35
+
36
+ <context>
37
+ $ARGUMENTS
38
+ </context>
39
+
40
+ <process>
41
+ Execute the ingest-docs workflow end-to-end. Preserve all approval gates (discovery, conflict report, routing) and the BLOCKER safety rule.
42
+ </process>
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: gsd:ultraplan-phase
3
+ description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd-import. Claude Code only."
4
+ argument-hint: "[phase-number]"
5
+ allowed-tools:
6
+ - Read
7
+ - Bash
8
+ - Glob
9
+ - Grep
10
+ ---
11
+
12
+ <objective>
13
+ Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
14
+
15
+ Ultraplan drafts the plan in a remote cloud session while your terminal stays free.
16
+ Review and comment on the plan in your browser, then import it back via /gsd-import --from.
17
+
18
+ ⚠ BETA: ultraplan is in research preview. Use /gsd-plan-phase for stable local planning.
19
+ Requirements: Claude Code v2.1.91+, claude.ai account, GitHub repository.
20
+ </objective>
21
+
22
+ <execution_context>
23
+ @~/.claude/get-shit-done/workflows/ultraplan-phase.md
24
+ @~/.claude/get-shit-done/references/ui-brand.md
25
+ </execution_context>
26
+
27
+ <context>
28
+ $ARGUMENTS
29
+ </context>
30
+
31
+ <process>
32
+ Execute the ultraplan-phase workflow end-to-end.
33
+ </process>