@bhargavvc/sdd-cc 1.30.1 → 1.35.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 (242) hide show
  1. package/README.ja-JP.md +144 -110
  2. package/README.ko-KR.md +143 -107
  3. package/README.md +183 -112
  4. package/README.pt-BR.md +90 -52
  5. package/README.zh-CN.md +141 -101
  6. package/agents/sdd-advisor-researcher.md +23 -0
  7. package/agents/sdd-ai-researcher.md +133 -0
  8. package/agents/sdd-code-fixer.md +516 -0
  9. package/agents/sdd-code-reviewer.md +355 -0
  10. package/agents/sdd-codebase-mapper.md +3 -3
  11. package/agents/sdd-debugger.md +17 -5
  12. package/agents/sdd-doc-verifier.md +201 -0
  13. package/agents/sdd-doc-writer.md +602 -0
  14. package/agents/sdd-domain-researcher.md +153 -0
  15. package/agents/sdd-eval-auditor.md +164 -0
  16. package/agents/sdd-eval-planner.md +154 -0
  17. package/agents/sdd-executor.md +87 -4
  18. package/agents/sdd-framework-selector.md +160 -0
  19. package/agents/sdd-intel-updater.md +314 -0
  20. package/agents/sdd-nyquist-auditor.md +1 -1
  21. package/agents/sdd-phase-researcher.md +71 -4
  22. package/agents/sdd-plan-checker.md +100 -6
  23. package/agents/sdd-planner.md +145 -206
  24. package/agents/sdd-project-researcher.md +25 -2
  25. package/agents/sdd-research-synthesizer.md +3 -3
  26. package/agents/sdd-roadmapper.md +6 -6
  27. package/agents/sdd-security-auditor.md +128 -0
  28. package/agents/sdd-ui-auditor.md +43 -3
  29. package/agents/sdd-ui-checker.md +5 -5
  30. package/agents/sdd-ui-researcher.md +27 -4
  31. package/agents/sdd-user-profiler.md +2 -2
  32. package/agents/sdd-verifier.md +142 -22
  33. package/bin/install.js +2145 -545
  34. package/commands/sdd/add-backlog.md +5 -5
  35. package/commands/sdd/add-tests.md +2 -2
  36. package/commands/sdd/ai-integration-phase.md +36 -0
  37. package/commands/sdd/analyze-dependencies.md +34 -0
  38. package/commands/sdd/audit-fix.md +33 -0
  39. package/commands/sdd/autonomous.md +7 -2
  40. package/commands/sdd/cleanup.md +5 -0
  41. package/commands/sdd/code-review-fix.md +52 -0
  42. package/commands/sdd/code-review.md +55 -0
  43. package/commands/sdd/complete-milestone.md +6 -6
  44. package/commands/sdd/debug.md +22 -9
  45. package/commands/sdd/discuss-phase.md +7 -2
  46. package/commands/sdd/do.md +1 -1
  47. package/commands/sdd/docs-update.md +48 -0
  48. package/commands/sdd/eval-review.md +32 -0
  49. package/commands/sdd/execute-phase.md +4 -0
  50. package/commands/sdd/explore.md +27 -0
  51. package/commands/sdd/fast.md +2 -2
  52. package/commands/sdd/from-sdd2.md +45 -0
  53. package/commands/sdd/help.md +2 -0
  54. package/commands/sdd/import.md +36 -0
  55. package/commands/sdd/intel.md +179 -0
  56. package/commands/sdd/join-discord.md +2 -1
  57. package/commands/sdd/manager.md +1 -0
  58. package/commands/sdd/map-codebase.md +3 -3
  59. package/commands/sdd/new-milestone.md +1 -1
  60. package/commands/sdd/new-project.md +5 -1
  61. package/commands/sdd/new-workspace.md +1 -1
  62. package/commands/sdd/next.md +2 -0
  63. package/commands/sdd/plan-milestone-gaps.md +2 -2
  64. package/commands/sdd/plan-phase.md +6 -1
  65. package/commands/sdd/plant-seed.md +1 -1
  66. package/commands/sdd/profile-user.md +1 -1
  67. package/commands/sdd/quick.md +5 -3
  68. package/commands/sdd/reapply-patches.md +230 -42
  69. package/commands/sdd/research-phase.md +3 -3
  70. package/commands/sdd/review-backlog.md +1 -0
  71. package/commands/sdd/review.md +6 -3
  72. package/commands/sdd/scan.md +26 -0
  73. package/commands/sdd/secure-phase.md +35 -0
  74. package/commands/sdd/ship.md +1 -1
  75. package/commands/sdd/thread.md +5 -5
  76. package/commands/sdd/undo.md +34 -0
  77. package/commands/sdd/verify-work.md +1 -1
  78. package/commands/sdd/workstreams.md +17 -11
  79. package/hooks/dist/sdd-check-update.js +33 -8
  80. package/hooks/dist/sdd-context-monitor.js +17 -8
  81. package/hooks/dist/sdd-phase-boundary.sh +27 -0
  82. package/hooks/dist/sdd-prompt-guard.js +1 -0
  83. package/hooks/dist/sdd-read-guard.js +82 -0
  84. package/hooks/dist/sdd-session-state.sh +33 -0
  85. package/hooks/dist/sdd-statusline.js +137 -15
  86. package/hooks/dist/sdd-validate-commit.sh +47 -0
  87. package/hooks/dist/sdd-workflow-guard.js +4 -4
  88. package/hooks/sdd-check-update.js +139 -0
  89. package/hooks/sdd-context-monitor.js +165 -0
  90. package/hooks/sdd-phase-boundary.sh +27 -0
  91. package/hooks/sdd-prompt-guard.js +97 -0
  92. package/hooks/sdd-read-guard.js +82 -0
  93. package/hooks/sdd-session-state.sh +33 -0
  94. package/hooks/sdd-statusline.js +241 -0
  95. package/hooks/sdd-validate-commit.sh +47 -0
  96. package/hooks/sdd-workflow-guard.js +94 -0
  97. package/package.json +3 -3
  98. package/scripts/build-hooks.js +18 -7
  99. package/scripts/prompt-injection-scan.sh +1 -0
  100. package/scripts/rebrand-gsd-to-sdd.sh +221 -220
  101. package/scripts/run-tests.cjs +5 -1
  102. package/scripts/sync-upstream.sh +1 -1
  103. package/sdd/bin/lib/commands.cjs +79 -17
  104. package/sdd/bin/lib/config.cjs +90 -48
  105. package/sdd/bin/lib/core.cjs +452 -87
  106. package/sdd/bin/lib/docs.cjs +267 -0
  107. package/sdd/bin/lib/frontmatter.cjs +381 -336
  108. package/sdd/bin/lib/init.cjs +110 -16
  109. package/sdd/bin/lib/intel.cjs +660 -0
  110. package/sdd/bin/lib/learnings.cjs +378 -0
  111. package/sdd/bin/lib/milestone.cjs +42 -11
  112. package/sdd/bin/lib/model-profiles.cjs +17 -15
  113. package/sdd/bin/lib/phase.cjs +367 -288
  114. package/sdd/bin/lib/profile-output.cjs +106 -10
  115. package/sdd/bin/lib/roadmap.cjs +146 -115
  116. package/sdd/bin/lib/schema-detect.cjs +238 -0
  117. package/sdd/bin/lib/sdd2-import.cjs +511 -0
  118. package/sdd/bin/lib/security.cjs +124 -3
  119. package/sdd/bin/lib/state.cjs +648 -264
  120. package/sdd/bin/lib/template.cjs +8 -4
  121. package/sdd/bin/lib/verify.cjs +209 -28
  122. package/sdd/bin/lib/workstream.cjs +7 -3
  123. package/sdd/bin/sdd-tools.cjs +184 -12
  124. package/sdd/contexts/dev.md +21 -0
  125. package/sdd/contexts/research.md +22 -0
  126. package/sdd/contexts/review.md +22 -0
  127. package/sdd/references/agent-contracts.md +79 -0
  128. package/sdd/references/ai-evals.md +156 -0
  129. package/sdd/references/ai-frameworks.md +186 -0
  130. package/sdd/references/artifact-types.md +113 -0
  131. package/sdd/references/common-bug-patterns.md +114 -0
  132. package/sdd/references/context-budget.md +49 -0
  133. package/sdd/references/continuation-format.md +25 -25
  134. package/sdd/references/domain-probes.md +125 -0
  135. package/sdd/references/few-shot-examples/plan-checker.md +73 -0
  136. package/sdd/references/few-shot-examples/verifier.md +109 -0
  137. package/sdd/references/gate-prompts.md +100 -0
  138. package/sdd/references/gates.md +70 -0
  139. package/sdd/references/git-integration.md +1 -1
  140. package/sdd/references/ios-scaffold.md +123 -0
  141. package/sdd/references/model-profile-resolution.md +2 -0
  142. package/sdd/references/model-profiles.md +24 -18
  143. package/sdd/references/planner-gap-closure.md +62 -0
  144. package/sdd/references/planner-reviews.md +39 -0
  145. package/sdd/references/planner-revision.md +87 -0
  146. package/sdd/references/planning-config.md +252 -0
  147. package/sdd/references/revision-loop.md +97 -0
  148. package/sdd/references/thinking-models-debug.md +44 -0
  149. package/sdd/references/thinking-models-execution.md +50 -0
  150. package/sdd/references/thinking-models-planning.md +62 -0
  151. package/sdd/references/thinking-models-research.md +50 -0
  152. package/sdd/references/thinking-models-verification.md +55 -0
  153. package/sdd/references/thinking-partner.md +96 -0
  154. package/sdd/references/ui-brand.md +4 -4
  155. package/sdd/references/universal-anti-patterns.md +63 -0
  156. package/sdd/references/verification-overrides.md +227 -0
  157. package/sdd/references/workstream-flag.md +56 -3
  158. package/sdd/templates/AI-SPEC.md +246 -0
  159. package/sdd/templates/DEBUG.md +1 -1
  160. package/sdd/templates/SECURITY.md +61 -0
  161. package/sdd/templates/UAT.md +4 -4
  162. package/sdd/templates/VALIDATION.md +4 -4
  163. package/sdd/templates/claude-md.md +32 -9
  164. package/sdd/templates/config.json +4 -0
  165. package/sdd/templates/debug-subagent-prompt.md +1 -1
  166. package/sdd/templates/dev-preferences.md +1 -1
  167. package/sdd/templates/discovery.md +2 -2
  168. package/sdd/templates/phase-prompt.md +1 -1
  169. package/sdd/templates/planner-subagent-prompt.md +3 -3
  170. package/sdd/templates/project.md +1 -1
  171. package/sdd/templates/research.md +1 -1
  172. package/sdd/templates/state.md +2 -2
  173. package/sdd/workflows/add-phase.md +8 -8
  174. package/sdd/workflows/add-tests.md +12 -9
  175. package/sdd/workflows/add-todo.md +5 -3
  176. package/sdd/workflows/ai-integration-phase.md +284 -0
  177. package/sdd/workflows/analyze-dependencies.md +96 -0
  178. package/sdd/workflows/audit-fix.md +157 -0
  179. package/sdd/workflows/audit-milestone.md +11 -11
  180. package/sdd/workflows/audit-uat.md +2 -2
  181. package/sdd/workflows/autonomous.md +195 -27
  182. package/sdd/workflows/check-todos.md +12 -10
  183. package/sdd/workflows/cleanup.md +2 -0
  184. package/sdd/workflows/code-review-fix.md +497 -0
  185. package/sdd/workflows/code-review.md +515 -0
  186. package/sdd/workflows/complete-milestone.md +56 -22
  187. package/sdd/workflows/diagnose-issues.md +10 -3
  188. package/sdd/workflows/discovery-phase.md +5 -3
  189. package/sdd/workflows/discuss-phase-assumptions.md +24 -6
  190. package/sdd/workflows/discuss-phase-power.md +291 -0
  191. package/sdd/workflows/discuss-phase.md +173 -21
  192. package/sdd/workflows/do.md +23 -21
  193. package/sdd/workflows/docs-update.md +1155 -0
  194. package/sdd/workflows/eval-review.md +155 -0
  195. package/sdd/workflows/execute-phase.md +594 -38
  196. package/sdd/workflows/execute-plan.md +67 -96
  197. package/sdd/workflows/explore.md +139 -0
  198. package/sdd/workflows/fast.md +5 -5
  199. package/sdd/workflows/forensics.md +2 -2
  200. package/sdd/workflows/health.md +4 -4
  201. package/sdd/workflows/help.md +122 -119
  202. package/sdd/workflows/import.md +276 -0
  203. package/sdd/workflows/inbox.md +387 -0
  204. package/sdd/workflows/insert-phase.md +7 -7
  205. package/sdd/workflows/list-phase-assumptions.md +4 -4
  206. package/sdd/workflows/list-workspaces.md +2 -2
  207. package/sdd/workflows/manager.md +35 -32
  208. package/sdd/workflows/map-codebase.md +7 -5
  209. package/sdd/workflows/milestone-summary.md +2 -2
  210. package/sdd/workflows/new-milestone.md +17 -9
  211. package/sdd/workflows/new-project.md +50 -25
  212. package/sdd/workflows/new-workspace.md +7 -5
  213. package/sdd/workflows/next.md +67 -11
  214. package/sdd/workflows/note.md +9 -7
  215. package/sdd/workflows/pause-work.md +75 -12
  216. package/sdd/workflows/plan-milestone-gaps.md +8 -8
  217. package/sdd/workflows/plan-phase.md +294 -42
  218. package/sdd/workflows/plant-seed.md +6 -3
  219. package/sdd/workflows/pr-branch.md +42 -14
  220. package/sdd/workflows/profile-user.md +9 -7
  221. package/sdd/workflows/progress.md +45 -45
  222. package/sdd/workflows/quick.md +195 -47
  223. package/sdd/workflows/remove-phase.md +6 -6
  224. package/sdd/workflows/remove-workspace.md +3 -1
  225. package/sdd/workflows/research-phase.md +2 -2
  226. package/sdd/workflows/resume-project.md +12 -12
  227. package/sdd/workflows/review.md +109 -9
  228. package/sdd/workflows/scan.md +102 -0
  229. package/sdd/workflows/secure-phase.md +166 -0
  230. package/sdd/workflows/session-report.md +2 -2
  231. package/sdd/workflows/settings.md +38 -12
  232. package/sdd/workflows/ship.md +21 -9
  233. package/sdd/workflows/stats.md +1 -1
  234. package/sdd/workflows/transition.md +23 -23
  235. package/sdd/workflows/ui-phase.md +15 -7
  236. package/sdd/workflows/ui-review.md +29 -4
  237. package/sdd/workflows/undo.md +314 -0
  238. package/sdd/workflows/update.md +171 -20
  239. package/sdd/workflows/validate-phase.md +6 -4
  240. package/sdd/workflows/verify-phase.md +210 -6
  241. package/sdd/workflows/verify-work.md +83 -9
  242. package/sdd/commands/sdd/workstreams.md +0 -63
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Docs — Commands for the docs-update workflow
3
+ *
4
+ * Provides `cmdDocsInit` which returns project signals, existing doc inventory
5
+ * with SDD marker detection, doc tooling detection, monorepo awareness, and
6
+ * model resolution. Used by Phase 2 to route doc generation appropriately.
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { output, loadConfig, resolveModelInternal, pathExistsInternal, toPosixPath, checkAgentsInstalled } = require('./core.cjs');
12
+
13
+ // ─── Constants ────────────────────────────────────────────────────────────────
14
+
15
+ const SDD_MARKER = '<!-- generated-by: sdd-doc-writer -->';
16
+
17
+ const SKIP_DIRS = new Set([
18
+ 'node_modules', '.git', '.planning', '.claude', '__pycache__',
19
+ 'target', 'dist', 'build', '.next', '.nuxt', 'coverage',
20
+ '.vscode', '.idea',
21
+ ]);
22
+
23
+ // ─── Private helpers ──────────────────────────────────────────────────────────
24
+
25
+ /**
26
+ * Check whether a file begins with the SDD doc writer marker.
27
+ * Reads the first 500 bytes only — avoids loading large files.
28
+ *
29
+ * @param {string} filePath - Absolute path to the file
30
+ * @returns {boolean}
31
+ */
32
+ function hasSddMarker(filePath) {
33
+ try {
34
+ const buf = Buffer.alloc(500);
35
+ const fd = fs.openSync(filePath, 'r');
36
+ const bytesRead = fs.readSync(fd, buf, 0, 500, 0);
37
+ fs.closeSync(fd);
38
+ return buf.slice(0, bytesRead).toString('utf-8').includes(SDD_MARKER);
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Recursively scan the project root (immediate .md files) and docs/ directory
46
+ * (up to 4 levels deep) for Markdown files, excluding dirs in SKIP_DIRS.
47
+ *
48
+ * @param {string} cwd - Project root
49
+ * @returns {Array<{path: string, has_sdd_marker: boolean}>}
50
+ */
51
+ function scanExistingDocs(cwd) {
52
+ const MAX_DEPTH = 4;
53
+ const results = [];
54
+
55
+ /**
56
+ * Recursively walk a directory for .md files up to MAX_DEPTH levels.
57
+ * @param {string} dir - Directory to scan
58
+ * @param {number} depth - Current depth (1-based)
59
+ */
60
+ function walkDir(dir, depth) {
61
+ if (depth > MAX_DEPTH) return;
62
+ try {
63
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
64
+ for (const entry of entries) {
65
+ if (SKIP_DIRS.has(entry.name)) continue;
66
+ const abs = path.join(dir, entry.name);
67
+ if (entry.isDirectory()) {
68
+ walkDir(abs, depth + 1);
69
+ } else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
70
+ const rel = toPosixPath(path.relative(cwd, abs));
71
+ results.push({ path: rel, has_sdd_marker: hasSddMarker(abs) });
72
+ }
73
+ }
74
+ } catch { /* directory may not exist — best-effort */ }
75
+ }
76
+
77
+ // Scan root-level .md files (non-recursive)
78
+ try {
79
+ const entries = fs.readdirSync(cwd, { withFileTypes: true });
80
+ for (const entry of entries) {
81
+ if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
82
+ const abs = path.join(cwd, entry.name);
83
+ const rel = toPosixPath(path.relative(cwd, abs));
84
+ results.push({ path: rel, has_sdd_marker: hasSddMarker(abs) });
85
+ }
86
+ }
87
+ } catch { /* best-effort */ }
88
+
89
+ // Recursively scan docs/ directory
90
+ const docsDir = path.join(cwd, 'docs');
91
+ walkDir(docsDir, 1);
92
+
93
+ // Fallback: if docs/ does not exist, try documentation/ or doc/
94
+ try {
95
+ fs.statSync(docsDir);
96
+ } catch {
97
+ const alternatives = ['documentation', 'doc'];
98
+ for (const alt of alternatives) {
99
+ const altDir = path.join(cwd, alt);
100
+ try {
101
+ const stat = fs.statSync(altDir);
102
+ if (stat.isDirectory()) {
103
+ walkDir(altDir, 1);
104
+ break;
105
+ }
106
+ } catch { /* not present */ }
107
+ }
108
+ }
109
+
110
+ return results.sort((a, b) => a.path.localeCompare(b.path));
111
+ }
112
+
113
+ /**
114
+ * Detect project type signals from the filesystem and package.json.
115
+ * All checks are best-effort and never throw.
116
+ *
117
+ * @param {string} cwd - Project root
118
+ * @returns {Object} Boolean signal fields
119
+ */
120
+ function detectProjectType(cwd) {
121
+ const exists = (rel) => {
122
+ try { return pathExistsInternal(cwd, rel); } catch { return false; }
123
+ };
124
+
125
+ // has_cli_bin: package.json has a `bin` field
126
+ let has_cli_bin = false;
127
+ try {
128
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
129
+ has_cli_bin = !!(pkg.bin && (typeof pkg.bin === 'string' || Object.keys(pkg.bin).length > 0));
130
+ } catch { /* no package.json or invalid JSON */ }
131
+
132
+ // is_monorepo: pnpm-workspace.yaml, lerna.json, or package.json workspaces
133
+ let is_monorepo = exists('pnpm-workspace.yaml') || exists('lerna.json');
134
+ if (!is_monorepo) {
135
+ try {
136
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
137
+ is_monorepo = Array.isArray(pkg.workspaces) && pkg.workspaces.length > 0;
138
+ } catch { /* ignore */ }
139
+ }
140
+
141
+ // has_tests: common test directories or test frameworks in devDependencies
142
+ let has_tests = exists('test') || exists('tests') || exists('__tests__') || exists('spec');
143
+ if (!has_tests) {
144
+ try {
145
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
146
+ const devDeps = Object.keys(pkg.devDependencies || {});
147
+ has_tests = devDeps.some(d => ['vitest', 'jest', 'mocha', 'jasmine', 'ava'].includes(d));
148
+ } catch { /* ignore */ }
149
+ }
150
+
151
+ // has_deploy_config: various deployment config files
152
+ const deployFiles = [
153
+ 'Dockerfile', 'docker-compose.yml', 'docker-compose.yaml',
154
+ 'fly.toml', 'render.yaml', 'vercel.json', 'netlify.toml', 'railway.json',
155
+ '.github/workflows/deploy.yml', '.github/workflows/deploy.yaml',
156
+ ];
157
+ const has_deploy_config = deployFiles.some(f => exists(f));
158
+
159
+ return {
160
+ has_package_json: exists('package.json'),
161
+ has_api_routes: (
162
+ exists('src/app/api') || exists('routes') || exists('src/routes') ||
163
+ exists('api') || exists('server')
164
+ ),
165
+ has_cli_bin,
166
+ is_open_source: exists('LICENSE') || exists('LICENSE.md'),
167
+ has_deploy_config,
168
+ is_monorepo,
169
+ has_tests,
170
+ };
171
+ }
172
+
173
+ /**
174
+ * Detect known documentation tooling in the project.
175
+ *
176
+ * @param {string} cwd - Project root
177
+ * @returns {Object} Boolean detection fields
178
+ */
179
+ function detectDocTooling(cwd) {
180
+ const exists = (rel) => {
181
+ try { return pathExistsInternal(cwd, rel); } catch { return false; }
182
+ };
183
+
184
+ return {
185
+ docusaurus: exists('docusaurus.config.js') || exists('docusaurus.config.ts'),
186
+ vitepress: (
187
+ exists('.vitepress/config.js') ||
188
+ exists('.vitepress/config.ts') ||
189
+ exists('.vitepress/config.mts')
190
+ ),
191
+ mkdocs: exists('mkdocs.yml'),
192
+ storybook: exists('.storybook'),
193
+ };
194
+ }
195
+
196
+ /**
197
+ * Extract monorepo workspace globs from pnpm-workspace.yaml, package.json
198
+ * workspaces, or lerna.json.
199
+ *
200
+ * @param {string} cwd - Project root
201
+ * @returns {string[]} Array of workspace glob patterns, or [] if not a monorepo
202
+ */
203
+ function detectMonorepoWorkspaces(cwd) {
204
+ // pnpm-workspace.yaml
205
+ try {
206
+ const content = fs.readFileSync(path.join(cwd, 'pnpm-workspace.yaml'), 'utf-8');
207
+ const lines = content.split('\n');
208
+ const workspaces = [];
209
+ for (const line of lines) {
210
+ const m = line.match(/^\s*-\s+['"]?(.+?)['"]?\s*$/);
211
+ if (m) workspaces.push(m[1].trim());
212
+ }
213
+ if (workspaces.length > 0) return workspaces;
214
+ } catch { /* not present */ }
215
+
216
+ // package.json workspaces
217
+ try {
218
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
219
+ if (Array.isArray(pkg.workspaces) && pkg.workspaces.length > 0) {
220
+ return pkg.workspaces;
221
+ }
222
+ } catch { /* not present or invalid */ }
223
+
224
+ // lerna.json
225
+ try {
226
+ const lerna = JSON.parse(fs.readFileSync(path.join(cwd, 'lerna.json'), 'utf-8'));
227
+ if (Array.isArray(lerna.packages) && lerna.packages.length > 0) {
228
+ return lerna.packages;
229
+ }
230
+ } catch { /* not present or invalid */ }
231
+
232
+ return [];
233
+ }
234
+
235
+ // ─── Public commands ──────────────────────────────────────────────────────────
236
+
237
+ /**
238
+ * Return JSON context for the docs-update workflow: project signals, existing
239
+ * doc inventory, doc tooling detection, monorepo workspaces, and model
240
+ * resolution. Follows the cmdInitMapCodebase pattern.
241
+ *
242
+ * @example
243
+ * node sdd-tools.cjs docs-init --raw
244
+ *
245
+ * @param {string} cwd - Project root directory
246
+ * @param {boolean} raw - Pass raw JSON flag through to output()
247
+ */
248
+ function cmdDocsInit(cwd, raw) {
249
+ const config = loadConfig(cwd);
250
+ const result = {
251
+ doc_writer_model: resolveModelInternal(cwd, 'sdd-doc-writer'),
252
+ commit_docs: config.commit_docs,
253
+ existing_docs: scanExistingDocs(cwd),
254
+ project_type: detectProjectType(cwd),
255
+ doc_tooling: detectDocTooling(cwd),
256
+ monorepo_workspaces: detectMonorepoWorkspaces(cwd),
257
+ planning_exists: pathExistsInternal(cwd, '.planning'),
258
+ };
259
+ // Inject project_root and agent installation status (mirrors withProjectRoot in init.cjs)
260
+ result.project_root = cwd;
261
+ const agentStatus = checkAgentsInstalled();
262
+ result.agents_installed = agentStatus.agents_installed;
263
+ result.missing_agents = agentStatus.missing_agents;
264
+ output(result, raw);
265
+ }
266
+
267
+ module.exports = { cmdDocsInit };