@devtrack-solution/codesdd 1.2.2

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 (433) hide show
  1. package/.sdd/skills/curated/api-clean-flask-langgraph/SKILL.md +2751 -0
  2. package/.sdd/skills/curated/devtrack-api/SKILL.md +137 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -0
  4. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +381 -0
  5. package/.sdd/skills/curated/devtrack-api/references/architecture-governance.md +219 -0
  6. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +359 -0
  7. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +127 -0
  8. package/.sdd/skills/curated/devtrack-api/references/imports-lint.md +207 -0
  9. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +167 -0
  10. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +334 -0
  11. package/LICENSE +21 -0
  12. package/README.md +842 -0
  13. package/bin/codesdd.js +10 -0
  14. package/dist/cli/index.d.ts +3 -0
  15. package/dist/cli/index.js +560 -0
  16. package/dist/commands/change.d.ts +35 -0
  17. package/dist/commands/change.js +296 -0
  18. package/dist/commands/completion.d.ts +72 -0
  19. package/dist/commands/completion.js +258 -0
  20. package/dist/commands/config.d.ts +36 -0
  21. package/dist/commands/config.js +552 -0
  22. package/dist/commands/feedback.d.ts +9 -0
  23. package/dist/commands/feedback.js +184 -0
  24. package/dist/commands/schema.d.ts +6 -0
  25. package/dist/commands/schema.js +870 -0
  26. package/dist/commands/sdd/execution.d.ts +3 -0
  27. package/dist/commands/sdd/execution.js +409 -0
  28. package/dist/commands/sdd/shared.d.ts +9 -0
  29. package/dist/commands/sdd/shared.js +84 -0
  30. package/dist/commands/sdd/skills.d.ts +3 -0
  31. package/dist/commands/sdd/skills.js +154 -0
  32. package/dist/commands/sdd.d.ts +3 -0
  33. package/dist/commands/sdd.js +769 -0
  34. package/dist/commands/show.d.ts +14 -0
  35. package/dist/commands/show.js +133 -0
  36. package/dist/commands/spec.d.ts +15 -0
  37. package/dist/commands/spec.js +228 -0
  38. package/dist/commands/validate.d.ts +24 -0
  39. package/dist/commands/validate.js +295 -0
  40. package/dist/commands/workflow/index.d.ts +17 -0
  41. package/dist/commands/workflow/index.js +12 -0
  42. package/dist/commands/workflow/instructions.d.ts +29 -0
  43. package/dist/commands/workflow/instructions.js +383 -0
  44. package/dist/commands/workflow/new-change.d.ts +11 -0
  45. package/dist/commands/workflow/new-change.js +45 -0
  46. package/dist/commands/workflow/schemas.d.ts +10 -0
  47. package/dist/commands/workflow/schemas.js +34 -0
  48. package/dist/commands/workflow/shared.d.ts +57 -0
  49. package/dist/commands/workflow/shared.js +117 -0
  50. package/dist/commands/workflow/status.d.ts +14 -0
  51. package/dist/commands/workflow/status.js +76 -0
  52. package/dist/commands/workflow/templates.d.ts +16 -0
  53. package/dist/commands/workflow/templates.js +68 -0
  54. package/dist/core/archive.d.ts +16 -0
  55. package/dist/core/archive.js +487 -0
  56. package/dist/core/artifact-graph/graph.d.ts +56 -0
  57. package/dist/core/artifact-graph/graph.js +141 -0
  58. package/dist/core/artifact-graph/index.d.ts +7 -0
  59. package/dist/core/artifact-graph/index.js +13 -0
  60. package/dist/core/artifact-graph/instruction-loader.d.ts +143 -0
  61. package/dist/core/artifact-graph/instruction-loader.js +215 -0
  62. package/dist/core/artifact-graph/resolver.d.ts +81 -0
  63. package/dist/core/artifact-graph/resolver.js +258 -0
  64. package/dist/core/artifact-graph/schema.d.ts +13 -0
  65. package/dist/core/artifact-graph/schema.js +108 -0
  66. package/dist/core/artifact-graph/state.d.ts +12 -0
  67. package/dist/core/artifact-graph/state.js +54 -0
  68. package/dist/core/artifact-graph/types.d.ts +45 -0
  69. package/dist/core/artifact-graph/types.js +43 -0
  70. package/dist/core/available-tools.d.ts +16 -0
  71. package/dist/core/available-tools.js +30 -0
  72. package/dist/core/branding.d.ts +8 -0
  73. package/dist/core/branding.js +12 -0
  74. package/dist/core/cli/command-matrix.d.ts +23 -0
  75. package/dist/core/cli/command-matrix.js +123 -0
  76. package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
  77. package/dist/core/command-generation/adapters/amazon-q.js +26 -0
  78. package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
  79. package/dist/core/command-generation/adapters/antigravity.js +26 -0
  80. package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
  81. package/dist/core/command-generation/adapters/auggie.js +27 -0
  82. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  83. package/dist/core/command-generation/adapters/claude.js +50 -0
  84. package/dist/core/command-generation/adapters/cline.d.ts +14 -0
  85. package/dist/core/command-generation/adapters/cline.js +27 -0
  86. package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
  87. package/dist/core/command-generation/adapters/codebuddy.js +28 -0
  88. package/dist/core/command-generation/adapters/codex.d.ts +16 -0
  89. package/dist/core/command-generation/adapters/codex.js +39 -0
  90. package/dist/core/command-generation/adapters/continue.d.ts +13 -0
  91. package/dist/core/command-generation/adapters/continue.js +28 -0
  92. package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
  93. package/dist/core/command-generation/adapters/costrict.js +27 -0
  94. package/dist/core/command-generation/adapters/crush.d.ts +13 -0
  95. package/dist/core/command-generation/adapters/crush.js +30 -0
  96. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  97. package/dist/core/command-generation/adapters/cursor.js +44 -0
  98. package/dist/core/command-generation/adapters/factory.d.ts +13 -0
  99. package/dist/core/command-generation/adapters/factory.js +27 -0
  100. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  101. package/dist/core/command-generation/adapters/gemini.js +26 -0
  102. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  103. package/dist/core/command-generation/adapters/github-copilot.js +26 -0
  104. package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
  105. package/dist/core/command-generation/adapters/iflow.js +29 -0
  106. package/dist/core/command-generation/adapters/index.d.ts +29 -0
  107. package/dist/core/command-generation/adapters/index.js +29 -0
  108. package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
  109. package/dist/core/command-generation/adapters/kilocode.js +23 -0
  110. package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
  111. package/dist/core/command-generation/adapters/kiro.js +26 -0
  112. package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
  113. package/dist/core/command-generation/adapters/opencode.js +29 -0
  114. package/dist/core/command-generation/adapters/pi.d.ts +14 -0
  115. package/dist/core/command-generation/adapters/pi.js +41 -0
  116. package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
  117. package/dist/core/command-generation/adapters/qoder.js +30 -0
  118. package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
  119. package/dist/core/command-generation/adapters/qwen.js +26 -0
  120. package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
  121. package/dist/core/command-generation/adapters/roocode.js +27 -0
  122. package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
  123. package/dist/core/command-generation/adapters/windsurf.js +51 -0
  124. package/dist/core/command-generation/generator.d.ts +21 -0
  125. package/dist/core/command-generation/generator.js +27 -0
  126. package/dist/core/command-generation/index.d.ts +22 -0
  127. package/dist/core/command-generation/index.js +24 -0
  128. package/dist/core/command-generation/registry.d.ts +36 -0
  129. package/dist/core/command-generation/registry.js +92 -0
  130. package/dist/core/command-generation/types.d.ts +56 -0
  131. package/dist/core/command-generation/types.js +8 -0
  132. package/dist/core/completions/command-registry.d.ts +7 -0
  133. package/dist/core/completions/command-registry.js +461 -0
  134. package/dist/core/completions/completion-provider.d.ts +60 -0
  135. package/dist/core/completions/completion-provider.js +102 -0
  136. package/dist/core/completions/factory.d.ts +64 -0
  137. package/dist/core/completions/factory.js +75 -0
  138. package/dist/core/completions/generators/bash-generator.d.ts +32 -0
  139. package/dist/core/completions/generators/bash-generator.js +174 -0
  140. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  141. package/dist/core/completions/generators/fish-generator.js +157 -0
  142. package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
  143. package/dist/core/completions/generators/powershell-generator.js +207 -0
  144. package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
  145. package/dist/core/completions/generators/zsh-generator.js +250 -0
  146. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  147. package/dist/core/completions/installers/bash-installer.js +318 -0
  148. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  149. package/dist/core/completions/installers/fish-installer.js +143 -0
  150. package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
  151. package/dist/core/completions/installers/powershell-installer.js +327 -0
  152. package/dist/core/completions/installers/zsh-installer.d.ts +125 -0
  153. package/dist/core/completions/installers/zsh-installer.js +452 -0
  154. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  155. package/dist/core/completions/templates/bash-templates.js +24 -0
  156. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  157. package/dist/core/completions/templates/fish-templates.js +39 -0
  158. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  159. package/dist/core/completions/templates/powershell-templates.js +25 -0
  160. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  161. package/dist/core/completions/templates/zsh-templates.js +36 -0
  162. package/dist/core/completions/types.d.ts +79 -0
  163. package/dist/core/completions/types.js +2 -0
  164. package/dist/core/config-prompts.d.ts +9 -0
  165. package/dist/core/config-prompts.js +34 -0
  166. package/dist/core/config-schema.d.ts +86 -0
  167. package/dist/core/config-schema.js +213 -0
  168. package/dist/core/config.d.ts +17 -0
  169. package/dist/core/config.js +33 -0
  170. package/dist/core/converters/json-converter.d.ts +6 -0
  171. package/dist/core/converters/json-converter.js +51 -0
  172. package/dist/core/global-config.d.ts +44 -0
  173. package/dist/core/global-config.js +125 -0
  174. package/dist/core/index.d.ts +2 -0
  175. package/dist/core/index.js +3 -0
  176. package/dist/core/init.d.ts +36 -0
  177. package/dist/core/init.js +576 -0
  178. package/dist/core/legacy-cleanup.d.ts +162 -0
  179. package/dist/core/legacy-cleanup.js +512 -0
  180. package/dist/core/list.d.ts +9 -0
  181. package/dist/core/list.js +173 -0
  182. package/dist/core/migration.d.ts +23 -0
  183. package/dist/core/migration.js +108 -0
  184. package/dist/core/parsers/change-parser.d.ts +13 -0
  185. package/dist/core/parsers/change-parser.js +193 -0
  186. package/dist/core/parsers/markdown-parser.d.ts +22 -0
  187. package/dist/core/parsers/markdown-parser.js +187 -0
  188. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  189. package/dist/core/parsers/requirement-blocks.js +201 -0
  190. package/dist/core/profile-sync-drift.d.ts +38 -0
  191. package/dist/core/profile-sync-drift.js +201 -0
  192. package/dist/core/profiles.d.ts +26 -0
  193. package/dist/core/profiles.js +41 -0
  194. package/dist/core/project-config.d.ts +64 -0
  195. package/dist/core/project-config.js +223 -0
  196. package/dist/core/schemas/base.schema.d.ts +13 -0
  197. package/dist/core/schemas/base.schema.js +13 -0
  198. package/dist/core/schemas/change.schema.d.ts +73 -0
  199. package/dist/core/schemas/change.schema.js +31 -0
  200. package/dist/core/schemas/index.d.ts +4 -0
  201. package/dist/core/schemas/index.js +4 -0
  202. package/dist/core/schemas/spec.schema.d.ts +18 -0
  203. package/dist/core/schemas/spec.schema.js +15 -0
  204. package/dist/core/sdd/adr-policy.d.ts +7 -0
  205. package/dist/core/sdd/adr-policy.js +47 -0
  206. package/dist/core/sdd/adr.d.ts +4 -0
  207. package/dist/core/sdd/adr.js +27 -0
  208. package/dist/core/sdd/bootstrap.d.ts +28 -0
  209. package/dist/core/sdd/bootstrap.js +353 -0
  210. package/dist/core/sdd/check.d.ts +51 -0
  211. package/dist/core/sdd/check.js +831 -0
  212. package/dist/core/sdd/coordination/coordination-adapters.d.ts +73 -0
  213. package/dist/core/sdd/coordination/coordination-adapters.js +87 -0
  214. package/dist/core/sdd/coordination/index.d.ts +2 -0
  215. package/dist/core/sdd/coordination/index.js +2 -0
  216. package/dist/core/sdd/dedup.d.ts +23 -0
  217. package/dist/core/sdd/dedup.js +62 -0
  218. package/dist/core/sdd/default-bootstrap-files.d.ts +23 -0
  219. package/dist/core/sdd/default-bootstrap-files.js +385 -0
  220. package/dist/core/sdd/default-skills.d.ts +16 -0
  221. package/dist/core/sdd/default-skills.js +427 -0
  222. package/dist/core/sdd/diagnose.d.ts +25 -0
  223. package/dist/core/sdd/diagnose.js +1312 -0
  224. package/dist/core/sdd/docs-sync.d.ts +21 -0
  225. package/dist/core/sdd/docs-sync.js +231 -0
  226. package/dist/core/sdd/domain/helpers.d.ts +6 -0
  227. package/dist/core/sdd/domain/helpers.js +37 -0
  228. package/dist/core/sdd/domain/lifecycle-guardrails.d.ts +22 -0
  229. package/dist/core/sdd/domain/lifecycle-guardrails.js +31 -0
  230. package/dist/core/sdd/domain/lifecycle-hooks.d.ts +16 -0
  231. package/dist/core/sdd/domain/lifecycle-hooks.js +27 -0
  232. package/dist/core/sdd/domain/post-active-validation.d.ts +15 -0
  233. package/dist/core/sdd/domain/post-active-validation.js +71 -0
  234. package/dist/core/sdd/domain/traceability.d.ts +8 -0
  235. package/dist/core/sdd/domain/traceability.js +83 -0
  236. package/dist/core/sdd/domain/transition-engine.d.ts +49 -0
  237. package/dist/core/sdd/domain/transition-engine.js +120 -0
  238. package/dist/core/sdd/fingerprint.d.ts +23 -0
  239. package/dist/core/sdd/fingerprint.js +146 -0
  240. package/dist/core/sdd/import-openspec.d.ts +31 -0
  241. package/dist/core/sdd/import-openspec.js +232 -0
  242. package/dist/core/sdd/init.d.ts +36 -0
  243. package/dist/core/sdd/init.js +65 -0
  244. package/dist/core/sdd/json-schema.d.ts +6 -0
  245. package/dist/core/sdd/json-schema.js +59 -0
  246. package/dist/core/sdd/legacy-operations.d.ts +286 -0
  247. package/dist/core/sdd/legacy-operations.js +2175 -0
  248. package/dist/core/sdd/lenses.d.ts +14 -0
  249. package/dist/core/sdd/lenses.js +97 -0
  250. package/dist/core/sdd/merge-catalog.d.ts +9 -0
  251. package/dist/core/sdd/merge-catalog.js +70 -0
  252. package/dist/core/sdd/migrate-workspace.d.ts +36 -0
  253. package/dist/core/sdd/migrate-workspace.js +344 -0
  254. package/dist/core/sdd/migrate.d.ts +24 -0
  255. package/dist/core/sdd/migrate.js +385 -0
  256. package/dist/core/sdd/resolve-project-root.d.ts +15 -0
  257. package/dist/core/sdd/resolve-project-root.js +46 -0
  258. package/dist/core/sdd/root-resolver.d.ts +16 -0
  259. package/dist/core/sdd/root-resolver.js +62 -0
  260. package/dist/core/sdd/sanitize.d.ts +35 -0
  261. package/dist/core/sdd/sanitize.js +750 -0
  262. package/dist/core/sdd/services/approve.service.d.ts +20 -0
  263. package/dist/core/sdd/services/approve.service.js +82 -0
  264. package/dist/core/sdd/services/audit.service.d.ts +53 -0
  265. package/dist/core/sdd/services/audit.service.js +136 -0
  266. package/dist/core/sdd/services/breakdown.service.d.ts +35 -0
  267. package/dist/core/sdd/services/breakdown.service.js +185 -0
  268. package/dist/core/sdd/services/context.service.d.ts +346 -0
  269. package/dist/core/sdd/services/context.service.js +278 -0
  270. package/dist/core/sdd/services/debate.service.d.ts +16 -0
  271. package/dist/core/sdd/services/debate.service.js +73 -0
  272. package/dist/core/sdd/services/decide.service.d.ts +23 -0
  273. package/dist/core/sdd/services/decide.service.js +81 -0
  274. package/dist/core/sdd/services/dedup-apply.service.d.ts +39 -0
  275. package/dist/core/sdd/services/dedup-apply.service.js +259 -0
  276. package/dist/core/sdd/services/feature-lint.service.d.ts +29 -0
  277. package/dist/core/sdd/services/feature-lint.service.js +146 -0
  278. package/dist/core/sdd/services/finalize.service.d.ts +33 -0
  279. package/dist/core/sdd/services/finalize.service.js +707 -0
  280. package/dist/core/sdd/services/frontend-gap.service.d.ts +23 -0
  281. package/dist/core/sdd/services/frontend-gap.service.js +117 -0
  282. package/dist/core/sdd/services/frontend-impact.service.d.ts +19 -0
  283. package/dist/core/sdd/services/frontend-impact.service.js +46 -0
  284. package/dist/core/sdd/services/ingest-deposito.service.d.ts +32 -0
  285. package/dist/core/sdd/services/ingest-deposito.service.js +231 -0
  286. package/dist/core/sdd/services/insight.service.d.ts +21 -0
  287. package/dist/core/sdd/services/insight.service.js +81 -0
  288. package/dist/core/sdd/services/legacy-capability.service.d.ts +24 -0
  289. package/dist/core/sdd/services/legacy-capability.service.js +59 -0
  290. package/dist/core/sdd/services/mcp-runtime.service.d.ts +42 -0
  291. package/dist/core/sdd/services/mcp-runtime.service.js +144 -0
  292. package/dist/core/sdd/services/metrics.service.d.ts +49 -0
  293. package/dist/core/sdd/services/metrics.service.js +181 -0
  294. package/dist/core/sdd/services/next.service.d.ts +35 -0
  295. package/dist/core/sdd/services/next.service.js +54 -0
  296. package/dist/core/sdd/services/onboard.service.d.ts +9 -0
  297. package/dist/core/sdd/services/onboard.service.js +165 -0
  298. package/dist/core/sdd/services/rebuild.service.d.ts +31 -0
  299. package/dist/core/sdd/services/rebuild.service.js +482 -0
  300. package/dist/core/sdd/services/scan-naming.service.d.ts +43 -0
  301. package/dist/core/sdd/services/scan-naming.service.js +246 -0
  302. package/dist/core/sdd/services/skills-invoke.service.d.ts +24 -0
  303. package/dist/core/sdd/services/skills-invoke.service.js +63 -0
  304. package/dist/core/sdd/services/skills-sync.service.d.ts +15 -0
  305. package/dist/core/sdd/services/skills-sync.service.js +117 -0
  306. package/dist/core/sdd/services/start.service.d.ts +26 -0
  307. package/dist/core/sdd/services/start.service.js +237 -0
  308. package/dist/core/sdd/skills.d.ts +15 -0
  309. package/dist/core/sdd/skills.js +46 -0
  310. package/dist/core/sdd/state-lock.d.ts +19 -0
  311. package/dist/core/sdd/state-lock.js +144 -0
  312. package/dist/core/sdd/state.d.ts +155 -0
  313. package/dist/core/sdd/state.js +1000 -0
  314. package/dist/core/sdd/store/in-memory-adapter.d.ts +12 -0
  315. package/dist/core/sdd/store/in-memory-adapter.js +27 -0
  316. package/dist/core/sdd/store/index.d.ts +5 -0
  317. package/dist/core/sdd/store/index.js +5 -0
  318. package/dist/core/sdd/store/sdd-stores.d.ts +25 -0
  319. package/dist/core/sdd/store/sdd-stores.js +59 -0
  320. package/dist/core/sdd/store/state-store.d.ts +32 -0
  321. package/dist/core/sdd/store/state-store.js +2 -0
  322. package/dist/core/sdd/store/yaml-file-adapter.d.ts +12 -0
  323. package/dist/core/sdd/store/yaml-file-adapter.js +43 -0
  324. package/dist/core/sdd/structural-health.d.ts +557 -0
  325. package/dist/core/sdd/structural-health.js +187 -0
  326. package/dist/core/sdd/transaction.d.ts +14 -0
  327. package/dist/core/sdd/transaction.js +100 -0
  328. package/dist/core/sdd/types.d.ts +1570 -0
  329. package/dist/core/sdd/types.js +617 -0
  330. package/dist/core/sdd/views.d.ts +3 -0
  331. package/dist/core/sdd/views.js +560 -0
  332. package/dist/core/sdd/workspace-schemas.d.ts +620 -0
  333. package/dist/core/sdd/workspace-schemas.js +254 -0
  334. package/dist/core/sdd/write-manifest.d.ts +25 -0
  335. package/dist/core/sdd/write-manifest.js +353 -0
  336. package/dist/core/shared/index.d.ts +8 -0
  337. package/dist/core/shared/index.js +8 -0
  338. package/dist/core/shared/skill-generation.d.ts +49 -0
  339. package/dist/core/shared/skill-generation.js +106 -0
  340. package/dist/core/shared/tool-detection.d.ts +71 -0
  341. package/dist/core/shared/tool-detection.js +158 -0
  342. package/dist/core/specs-apply.d.ts +73 -0
  343. package/dist/core/specs-apply.js +385 -0
  344. package/dist/core/styles/palette.d.ts +7 -0
  345. package/dist/core/styles/palette.js +8 -0
  346. package/dist/core/templates/index.d.ts +8 -0
  347. package/dist/core/templates/index.js +9 -0
  348. package/dist/core/templates/skill-templates.d.ts +20 -0
  349. package/dist/core/templates/skill-templates.js +19 -0
  350. package/dist/core/templates/types.d.ts +19 -0
  351. package/dist/core/templates/types.js +5 -0
  352. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  353. package/dist/core/templates/workflows/apply-change.js +308 -0
  354. package/dist/core/templates/workflows/archive-change.d.ts +10 -0
  355. package/dist/core/templates/workflows/archive-change.js +277 -0
  356. package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
  357. package/dist/core/templates/workflows/bulk-archive-change.js +502 -0
  358. package/dist/core/templates/workflows/continue-change.d.ts +10 -0
  359. package/dist/core/templates/workflows/continue-change.js +232 -0
  360. package/dist/core/templates/workflows/explore.d.ts +10 -0
  361. package/dist/core/templates/workflows/explore.js +475 -0
  362. package/dist/core/templates/workflows/feedback.d.ts +9 -0
  363. package/dist/core/templates/workflows/feedback.js +108 -0
  364. package/dist/core/templates/workflows/ff-change.d.ts +10 -0
  365. package/dist/core/templates/workflows/ff-change.js +206 -0
  366. package/dist/core/templates/workflows/new-change.d.ts +10 -0
  367. package/dist/core/templates/workflows/new-change.js +151 -0
  368. package/dist/core/templates/workflows/onboard.d.ts +10 -0
  369. package/dist/core/templates/workflows/onboard.js +573 -0
  370. package/dist/core/templates/workflows/propose.d.ts +10 -0
  371. package/dist/core/templates/workflows/propose.js +224 -0
  372. package/dist/core/templates/workflows/sdd.d.ts +10 -0
  373. package/dist/core/templates/workflows/sdd.js +107 -0
  374. package/dist/core/templates/workflows/sync-specs.d.ts +10 -0
  375. package/dist/core/templates/workflows/sync-specs.js +286 -0
  376. package/dist/core/templates/workflows/verify-change.d.ts +10 -0
  377. package/dist/core/templates/workflows/verify-change.js +346 -0
  378. package/dist/core/update.d.ts +77 -0
  379. package/dist/core/update.js +538 -0
  380. package/dist/core/validation/constants.d.ts +34 -0
  381. package/dist/core/validation/constants.js +40 -0
  382. package/dist/core/validation/types.d.ts +18 -0
  383. package/dist/core/validation/types.js +2 -0
  384. package/dist/core/validation/validator.d.ts +33 -0
  385. package/dist/core/validation/validator.js +409 -0
  386. package/dist/core/view.d.ts +8 -0
  387. package/dist/core/view.js +170 -0
  388. package/dist/index.d.ts +3 -0
  389. package/dist/index.js +3 -0
  390. package/dist/prompts/searchable-multi-select.d.ts +28 -0
  391. package/dist/prompts/searchable-multi-select.js +159 -0
  392. package/dist/telemetry/config.d.ts +32 -0
  393. package/dist/telemetry/config.js +68 -0
  394. package/dist/telemetry/index.d.ts +44 -0
  395. package/dist/telemetry/index.js +207 -0
  396. package/dist/ui/ascii-patterns.d.ts +16 -0
  397. package/dist/ui/ascii-patterns.js +133 -0
  398. package/dist/ui/welcome-screen.d.ts +10 -0
  399. package/dist/ui/welcome-screen.js +146 -0
  400. package/dist/utils/change-metadata.d.ts +51 -0
  401. package/dist/utils/change-metadata.js +147 -0
  402. package/dist/utils/change-utils.d.ts +62 -0
  403. package/dist/utils/change-utils.js +121 -0
  404. package/dist/utils/command-references.d.ts +18 -0
  405. package/dist/utils/command-references.js +20 -0
  406. package/dist/utils/file-system.d.ts +36 -0
  407. package/dist/utils/file-system.js +281 -0
  408. package/dist/utils/index.d.ts +6 -0
  409. package/dist/utils/index.js +9 -0
  410. package/dist/utils/interactive.d.ts +18 -0
  411. package/dist/utils/interactive.js +21 -0
  412. package/dist/utils/item-discovery.d.ts +4 -0
  413. package/dist/utils/item-discovery.js +73 -0
  414. package/dist/utils/match.d.ts +3 -0
  415. package/dist/utils/match.js +22 -0
  416. package/dist/utils/openspec-compat.d.ts +2 -0
  417. package/dist/utils/openspec-compat.js +2 -0
  418. package/dist/utils/shell-detection.d.ts +20 -0
  419. package/dist/utils/shell-detection.js +41 -0
  420. package/dist/utils/task-progress.d.ts +8 -0
  421. package/dist/utils/task-progress.js +36 -0
  422. package/package.json +111 -0
  423. package/schemas/sdd/1-spec.schema.json +221 -0
  424. package/schemas/sdd/2-plan.schema.json +199 -0
  425. package/schemas/sdd/3-tasks.schema.json +102 -0
  426. package/schemas/sdd/4-changelog.schema.json +55 -0
  427. package/schemas/sdd/5-quality.schema.json +427 -0
  428. package/schemas/sdd/workspace-catalog.schema.json +1012 -0
  429. package/schemas/spec-driven/schema.yaml +153 -0
  430. package/schemas/spec-driven/templates/design.md +19 -0
  431. package/schemas/spec-driven/templates/proposal.md +23 -0
  432. package/schemas/spec-driven/templates/spec.md +8 -0
  433. package/schemas/spec-driven/templates/tasks.md +9 -0
@@ -0,0 +1,831 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { promises as fs } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { parse as parseYaml } from 'yaml';
5
+ import { CLI_NAME } from '../branding.js';
6
+ import { ID_PATTERNS, } from './types.js';
7
+ import { loadProjectSddConfig, loadStateSnapshot, resolveSddPaths, } from './state.js';
8
+ import { DEFAULT_CURATED_SKILL_CATALOG } from './default-skills.js';
9
+ import { renderViews } from './views.js';
10
+ import { syncSddGuideDocs, validateSddGuideDocs } from './docs-sync.js';
11
+ import { evaluateWorkspaceTraceability } from './domain/traceability.js';
12
+ import { detectArchiveArchivedLifecycleCollisions } from './domain/post-active-validation.js';
13
+ import { parseWorkspaceYamlDocument, workspaceTasksSchema, } from './workspace-schemas.js';
14
+ function checkUniqueIds(items, scope, errors) {
15
+ const seen = new Set();
16
+ for (const item of items) {
17
+ if (seen.has(item.id)) {
18
+ errors.push(`ID duplicado "${item.id}" em ${scope}`);
19
+ }
20
+ seen.add(item.id);
21
+ }
22
+ }
23
+ const FORBIDDEN_TITLE_PATTERNS = ['debate:', 'insight:', '(preencher', '(placeholder'];
24
+ function hasForbiddenTitleToken(title) {
25
+ const lowered = title.toLowerCase();
26
+ for (const token of FORBIDDEN_TITLE_PATTERNS) {
27
+ if (lowered.includes(token))
28
+ return token;
29
+ }
30
+ return null;
31
+ }
32
+ function validateDiscoveryRecords(records, errors) {
33
+ for (const record of records) {
34
+ if (record.type === 'INS' && !ID_PATTERNS.insight.test(record.id)) {
35
+ errors.push(`Discovery record ${record.id} is INS but does not follow INS-####`);
36
+ }
37
+ if (record.type === 'DEB' && !ID_PATTERNS.debate.test(record.id)) {
38
+ errors.push(`Discovery record ${record.id} is DEB but does not follow DEB-####`);
39
+ }
40
+ if (record.type === 'RAD' && !ID_PATTERNS.epicOrRadar.test(record.id)) {
41
+ errors.push(`Discovery record ${record.id} is RAD but does not follow RAD-### or EPIC-####`);
42
+ }
43
+ if (record.type === 'EPIC' && !ID_PATTERNS.epicOrRadar.test(record.id)) {
44
+ errors.push(`Discovery record ${record.id} is EPIC but does not follow EPIC-#### (or legacy RAD-###)`);
45
+ }
46
+ if (record.type === 'EPIC') {
47
+ const forbidden = hasForbiddenTitleToken(record.title);
48
+ if (forbidden) {
49
+ errors.push(`EPIC ${record.id} possui titulo invalido com token proibido "${forbidden}": "${record.title}"`);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ function validateBacklog(items, errors, warnings) {
55
+ const ids = new Set(items.map((item) => item.id));
56
+ const lockOwners = new Map();
57
+ for (const item of items) {
58
+ const forbidden = hasForbiddenTitleToken(item.title);
59
+ if (forbidden) {
60
+ errors.push(`FEAT ${item.id} possui titulo invalido com token proibido "${forbidden}": "${item.title}"`);
61
+ }
62
+ if (item.origin_type !== 'direct' && !item.origin_ref) {
63
+ warnings.push(`Item de backlog ${item.id} tem origin_type="${item.origin_type}" mas origin_ref vazio`);
64
+ }
65
+ for (const dep of item.blocked_by) {
66
+ if (!ids.has(dep)) {
67
+ warnings.push(`Item de backlog ${item.id} bloqueado por referencia inexistente: ${dep}`);
68
+ }
69
+ }
70
+ for (const lock of item.lock_domains) {
71
+ const owners = lockOwners.get(lock) || [];
72
+ owners.push(item.id);
73
+ lockOwners.set(lock, owners);
74
+ }
75
+ }
76
+ for (const [lock, owners] of lockOwners.entries()) {
77
+ if (owners.length > 1) {
78
+ warnings.push(`Lock domain "${lock}" compartilhado por: ${owners.join(', ')}`);
79
+ }
80
+ }
81
+ }
82
+ function validateReferentialIntegrity(snapshot, errors, warnings, isStrict) {
83
+ const discoveryIds = new Set(snapshot.discoveryIndex.records.map((record) => record.id));
84
+ const backlogIds = new Set(snapshot.backlog.items.map((item) => item.id));
85
+ const frontendGapIds = new Set(snapshot.frontendGaps?.items.map((gap) => gap.id) ?? []);
86
+ const techDebtIds = new Set(snapshot.techDebt.items.map((item) => item.id));
87
+ const record = (message) => {
88
+ if (isStrict)
89
+ errors.push(message);
90
+ else
91
+ warnings.push(`[LEGACY] ${message}`);
92
+ };
93
+ for (const item of snapshot.backlog.items || []) {
94
+ if ((item.origin_type === 'epic' || item.origin_type === 'radar') && item.origin_ref) {
95
+ if (!discoveryIds.has(item.origin_ref)) {
96
+ record(`FEAT ${item.id} points to origin_ref="${item.origin_ref}", which does not exist in the discovery index.`);
97
+ }
98
+ }
99
+ if (item.origin_type === 'frontend_gap' && item.origin_ref && !frontendGapIds.has(item.origin_ref)) {
100
+ record(`FEAT ${item.id} aponta para frontend gap origin_ref="${item.origin_ref}" inexistente.`);
101
+ }
102
+ if (item.origin_type === 'tech_debt' && item.origin_ref && !techDebtIds.has(item.origin_ref)) {
103
+ record(`FEAT ${item.id} aponta para tech debt origin_ref="${item.origin_ref}" inexistente.`);
104
+ }
105
+ for (const dep of item.blocked_by || []) {
106
+ if (!backlogIds.has(dep)) {
107
+ record(`FEAT ${item.id} bloqueada por referencia inexistente: ${dep}`);
108
+ }
109
+ }
110
+ }
111
+ for (const rec of snapshot.discoveryIndex.records || []) {
112
+ for (const rel of rec.related_ids || []) {
113
+ if (!discoveryIds.has(rel) && !backlogIds.has(rel)) {
114
+ record(`Discovery ${rec.id} has related_id="${rel}" referencing an unknown ID in the ecosystem (neither Discovery nor Backlog).`);
115
+ }
116
+ }
117
+ }
118
+ if (snapshot.finalizeQueue?.items) {
119
+ for (const fq of snapshot.finalizeQueue.items) {
120
+ if (!backlogIds.has(fq.feature_id)) {
121
+ record(`Finalize queue has entry for feature_id="${fq.feature_id}" blocked by an unknown feature.`);
122
+ }
123
+ }
124
+ }
125
+ if (snapshot.unblockEvents?.events) {
126
+ for (const ev of snapshot.unblockEvents.events) {
127
+ if (!backlogIds.has(ev.feature_id)) {
128
+ record(`Unblock event points to feature_id="${ev.feature_id}", which is no longer listed in the backlog.`);
129
+ }
130
+ if (ev.unblocked_by && !backlogIds.has(ev.unblocked_by)) {
131
+ record(`Unblock event was triggered by unblocked_by="${ev.unblocked_by}" pointing to an unknown FEAT.`);
132
+ }
133
+ }
134
+ }
135
+ }
136
+ function validateSkillOperationalIntegrity(snapshot, errors) {
137
+ const knownSkills = new Set((snapshot.skillCatalog?.skills || []).map((skill) => skill.id));
138
+ const currentBundles = new Map((snapshot.skillCatalog?.bundles || []).map((bundle) => [bundle.id, bundle]));
139
+ for (const defaultSkill of DEFAULT_CURATED_SKILL_CATALOG.skills) {
140
+ if (!knownSkills.has(defaultSkill.id)) {
141
+ errors.push(`Default curated skill "${defaultSkill.id}" is missing from skill-catalog.yaml`);
142
+ }
143
+ }
144
+ for (const bundle of snapshot.skillCatalog?.bundles || []) {
145
+ for (const skillId of bundle.skill_ids || []) {
146
+ if (!knownSkills.has(skillId)) {
147
+ errors.push(`Skill bundle "${bundle.id}" references unknown skill "${skillId}"`);
148
+ }
149
+ }
150
+ }
151
+ for (const defaultBundle of DEFAULT_CURATED_SKILL_CATALOG.bundles) {
152
+ const currentBundle = currentBundles.get(defaultBundle.id);
153
+ if (!currentBundle) {
154
+ errors.push(`Default skill bundle "${defaultBundle.id}" is missing from skill-catalog.yaml`);
155
+ continue;
156
+ }
157
+ for (const skillId of defaultBundle.skill_ids) {
158
+ if (!currentBundle.skill_ids.includes(skillId)) {
159
+ errors.push(`Default skill bundle "${defaultBundle.id}" is missing skill "${skillId}"`);
160
+ }
161
+ }
162
+ }
163
+ for (const skillId of snapshot.skillRouting?.default_skills || []) {
164
+ if (!knownSkills.has(skillId)) {
165
+ errors.push(`Skill routing default_skills references unknown skill "${skillId}"`);
166
+ }
167
+ }
168
+ for (const route of snapshot.skillRouting?.routes || []) {
169
+ for (const skillId of route.skills || []) {
170
+ if (!knownSkills.has(skillId)) {
171
+ errors.push(`Skill routing route "${route.domain}" references unknown skill "${skillId}"`);
172
+ }
173
+ }
174
+ }
175
+ }
176
+ function computeGraphSummary(items) {
177
+ const byId = new Map(items.map((item) => [item.id, item]));
178
+ const runnable = items.filter((item) => {
179
+ if (item.status === 'DONE' || item.status === 'ARCHIVED')
180
+ return false;
181
+ if (item.status === 'BLOCKED')
182
+ return false;
183
+ const unresolvedDeps = item.blocked_by.filter((depId) => {
184
+ const dep = byId.get(depId);
185
+ return !dep || dep.status !== 'DONE';
186
+ });
187
+ return unresolvedDeps.length === 0;
188
+ });
189
+ const lockOwners = new Map();
190
+ let blocked = 0;
191
+ let readyForParallel = 0;
192
+ for (const item of items) {
193
+ if (item.status === 'DONE' || item.status === 'ARCHIVED')
194
+ continue;
195
+ const unresolvedDeps = item.blocked_by.filter((depId) => {
196
+ const dep = byId.get(depId);
197
+ return !dep || dep.status !== 'DONE';
198
+ });
199
+ const isBlocked = item.status === 'BLOCKED' || unresolvedDeps.length > 0;
200
+ if (isBlocked)
201
+ blocked++;
202
+ }
203
+ for (const item of runnable) {
204
+ for (const lock of item.lock_domains) {
205
+ const owners = lockOwners.get(lock) || [];
206
+ owners.push(item.id);
207
+ lockOwners.set(lock, owners);
208
+ }
209
+ }
210
+ const conflictingIds = new Set();
211
+ for (const owners of lockOwners.values()) {
212
+ if (owners.length > 1) {
213
+ for (const id of owners)
214
+ conflictingIds.add(id);
215
+ }
216
+ }
217
+ for (const item of runnable) {
218
+ const hasConflict = conflictingIds.has(item.id);
219
+ if (item.status === 'READY' && !hasConflict) {
220
+ readyForParallel++;
221
+ }
222
+ }
223
+ return {
224
+ readyForParallel,
225
+ blocked,
226
+ lockConflicts: conflictingIds.size,
227
+ };
228
+ }
229
+ function roundPercent(done, total) {
230
+ if (total <= 0)
231
+ return 0;
232
+ return Math.round((done / total) * 100);
233
+ }
234
+ function computeProgress(items) {
235
+ const activeItems = items.filter((item) => item.status !== 'ARCHIVED');
236
+ const total = activeItems.length;
237
+ const done = activeItems.filter((item) => item.status === 'DONE').length;
238
+ const byRadar = new Map();
239
+ for (const item of activeItems) {
240
+ if ((item.origin_type !== 'radar' && item.origin_type !== 'epic') || !item.origin_ref)
241
+ continue;
242
+ const current = byRadar.get(item.origin_ref) || { done: 0, total: 0 };
243
+ current.total += 1;
244
+ if (item.status === 'DONE')
245
+ current.done += 1;
246
+ byRadar.set(item.origin_ref, current);
247
+ }
248
+ const progressByRadar = Array.from(byRadar.entries())
249
+ .sort((a, b) => a[0].localeCompare(b[0]))
250
+ .map(([radar_id, values]) => ({
251
+ radar_id,
252
+ done: values.done,
253
+ total: values.total,
254
+ percent: roundPercent(values.done, values.total),
255
+ }));
256
+ return {
257
+ progressGlobal: {
258
+ done,
259
+ total,
260
+ percent: roundPercent(done, total),
261
+ },
262
+ progressByRadar,
263
+ };
264
+ }
265
+ function validateTechDebt(items, errors) {
266
+ for (const item of items) {
267
+ if (!ID_PATTERNS.techDebt.test(item.id)) {
268
+ errors.push(`Technical debt item ${item.id} does not follow TD-###`);
269
+ }
270
+ }
271
+ }
272
+ function validateFrontendReferences(gaps, backlog, errors, warnings) {
273
+ const gapIds = new Set(gaps.map((g) => g.id));
274
+ for (const item of backlog) {
275
+ for (const gapRef of item.frontend_gap_refs) {
276
+ if (!gapIds.has(gapRef)) {
277
+ warnings.push(`Item de backlog ${item.id} referencia gap de frontend inexistente: ${gapRef}`);
278
+ }
279
+ }
280
+ }
281
+ const featureIds = new Set(backlog.map((b) => b.id));
282
+ for (const gap of gaps) {
283
+ if (gap.resolved_by_feature && !featureIds.has(gap.resolved_by_feature)) {
284
+ errors.push(`Frontend gap ${gap.id} has resolved_by_feature=${gap.resolved_by_feature}, which was not found in the backlog`);
285
+ }
286
+ }
287
+ }
288
+ async function validateActiveTaskChecklist(activeDir, items, warnings) {
289
+ for (const item of items) {
290
+ if (item.status !== 'IN_PROGRESS')
291
+ continue;
292
+ const taskDocPath = path.join(activeDir, item.id, '3-tasks.yaml');
293
+ if (!existsSync(taskDocPath)) {
294
+ warnings.push(`Task checklist missing for ${item.id} in .sdd/active.`);
295
+ continue;
296
+ }
297
+ const content = await fs.readFile(taskDocPath, 'utf-8').catch(() => '');
298
+ if (!content.trim()) {
299
+ warnings.push(`Task roadmap missing for ${item.id} in .sdd/active.`);
300
+ continue;
301
+ }
302
+ const parseResult = workspaceTasksSchema.safeParse(parseYaml(content));
303
+ if (!parseResult.success) {
304
+ warnings.push(`Task roadmap YAML invalid for ${item.id}: ${parseResult.error.message}`);
305
+ continue;
306
+ }
307
+ let taskRoadmap;
308
+ try {
309
+ taskRoadmap = parseWorkspaceYamlDocument('3-tasks.yaml', content);
310
+ }
311
+ catch (error) {
312
+ const message = error instanceof Error ? error.message : String(error);
313
+ warnings.push(`Task roadmap YAML invalid for ${item.id}: ${message}`);
314
+ continue;
315
+ }
316
+ const phases = new Set(taskRoadmap.tasks.map((task) => task.phase));
317
+ const missingPhases = ['preparation', 'implementation', 'testing', 'documentation', 'finalization'].filter((phase) => !phases.has(phase));
318
+ const testingTasksMissingScripts = taskRoadmap.tasks.some((task) => task.phase === 'testing' && task.test_scripts.length === 0);
319
+ if (missingPhases.length > 0 || testingTasksMissingScripts) {
320
+ const problems = [
321
+ missingPhases.length > 0 ? `missing phases ${missingPhases.join(', ')}` : '',
322
+ testingTasksMissingScripts ? 'testing tasks require test_scripts[]' : '',
323
+ ].filter(Boolean);
324
+ warnings.push(`Task roadmap incomplete for ${item.id}: ${problems.join('; ')}`);
325
+ }
326
+ }
327
+ }
328
+ async function validateWorkspaceCoherence(activeDir, archivedDir, items, warnings) {
329
+ for (const item of items) {
330
+ const activePath = path.join(activeDir, item.id);
331
+ const archivedPath = path.join(archivedDir, item.id);
332
+ const activeExists = existsSync(activePath);
333
+ const archivedExists = existsSync(archivedPath);
334
+ if (item.status === 'IN_PROGRESS' && !activeExists) {
335
+ warnings.push(`Feature ${item.id} em IN_PROGRESS sem workspace ativo em .sdd/active.`);
336
+ }
337
+ if ((item.status === 'DONE' || item.status === 'ARCHIVED') && activeExists) {
338
+ warnings.push(`Feature ${item.id} concluida ainda presente em .sdd/active.`);
339
+ }
340
+ if (item.status === 'IN_PROGRESS' && archivedExists) {
341
+ warnings.push(`Feature ${item.id} em IN_PROGRESS ja possui workspace em .sdd/archived.`);
342
+ }
343
+ }
344
+ }
345
+ function isPrivacyComplianceBacklogItem(item) {
346
+ if (item.origin_ref === 'EPIC-0020' || item.origin_ref === 'EPIC-0021')
347
+ return true;
348
+ const refs = new Set(item.acceptance_refs || []);
349
+ return refs.has('EPIC-0020') || refs.has('EPIC-0021') || refs.has('DEB-0021') || refs.has('INS-0021');
350
+ }
351
+ function validatePrivacySourceRegistry(snapshot, warnings) {
352
+ const privacyItems = snapshot.backlog.items.filter((item) => item.status !== 'DONE' && item.status !== 'ARCHIVED' && isPrivacyComplianceBacklogItem(item));
353
+ if (privacyItems.length === 0)
354
+ return;
355
+ if (snapshot.sourceIndex.jurisdiction_profiles.length === 0) {
356
+ warnings.push('Privacy compliance baseline incomplete: source-index.jurisdiction_profiles is empty while EPIC-0020/EPIC-0021 features are active.');
357
+ }
358
+ if (snapshot.sourceIndex.control_catalog.length === 0) {
359
+ warnings.push('Privacy compliance baseline incomplete: source-index.control_catalog is empty while EPIC-0020/EPIC-0021 features are active.');
360
+ }
361
+ if (snapshot.sourceIndex.version_events.length === 0) {
362
+ warnings.push('Privacy compliance baseline incomplete: source-index.version_events is empty while EPIC-0020/EPIC-0021 features are active.');
363
+ }
364
+ const activeRefs = new Set();
365
+ for (const item of privacyItems) {
366
+ activeRefs.add(item.id);
367
+ if (item.origin_ref)
368
+ activeRefs.add(item.origin_ref);
369
+ }
370
+ const missingMetadata = [];
371
+ for (const source of snapshot.sourceIndex.sources) {
372
+ const relevant = source.used_by.some((ref) => activeRefs.has(ref));
373
+ if (!relevant)
374
+ continue;
375
+ const hasAuthority = source.authority !== 'unknown';
376
+ const hasClassification = source.source_classification !== 'other';
377
+ const hasVerificationDate = Boolean((source.last_verified_at || '').trim());
378
+ const hasVersion = typeof source.source_version === 'number' && source.source_version > 0;
379
+ const hasFingerprint = Boolean((source.source_fingerprint || '').trim());
380
+ if (hasAuthority && hasClassification && hasVerificationDate && hasVersion && hasFingerprint)
381
+ continue;
382
+ missingMetadata.push(source.id);
383
+ }
384
+ if (missingMetadata.length > 0) {
385
+ warnings.push(`Privacy source registry metadata incomplete for: ${missingMetadata.slice(0, 12).join(', ')}${missingMetadata.length > 12 ? ' ...' : ''}`);
386
+ }
387
+ }
388
+ async function validatePrivacyWorkspaceChecklist(activeDir, items, warnings) {
389
+ const privacyItems = items.filter((item) => item.status === 'IN_PROGRESS' && isPrivacyComplianceBacklogItem(item));
390
+ for (const item of privacyItems) {
391
+ const specPath = path.join(activeDir, item.id, '1-spec.yaml');
392
+ const planPath = path.join(activeDir, item.id, '2-plan.yaml');
393
+ const qualityPath = path.join(activeDir, item.id, '5-quality.yaml');
394
+ if (!existsSync(specPath) || !existsSync(planPath) || !existsSync(qualityPath)) {
395
+ warnings.push(`Privacy checklist incomplete for ${item.id}: missing one of 1-spec/2-plan/5-quality YAML files.`);
396
+ continue;
397
+ }
398
+ try {
399
+ const spec = parseWorkspaceYamlDocument('1-spec.yaml', await fs.readFile(specPath, 'utf-8'));
400
+ const plan = parseWorkspaceYamlDocument('2-plan.yaml', await fs.readFile(planPath, 'utf-8'));
401
+ const quality = parseWorkspaceYamlDocument('5-quality.yaml', await fs.readFile(qualityPath, 'utf-8'));
402
+ const specRefs = spec.compliance_context?.source_refs || [];
403
+ const specJurisdictions = spec.compliance_context?.jurisdictions || [];
404
+ const planSources = plan.privacy_controls?.source_registry_refs || [];
405
+ const planProfiles = plan.privacy_controls?.jurisdiction_profiles || [];
406
+ const planControls = plan.privacy_controls?.control_ids || [];
407
+ const selectedSkills = plan.skill_conformance?.selected_skills || [];
408
+ const detectedConflicts = plan.skill_conformance?.detected_conflicts || [];
409
+ const architectureTree = (plan.skill_conformance?.architecture_tree_ascii || '').trim();
410
+ const hasSecurityIntegrity = Boolean(quality.security_integrity);
411
+ if (specRefs.length === 0 || specJurisdictions.length === 0) {
412
+ warnings.push(`Privacy checklist incomplete for ${item.id}: 1-spec.yaml missing compliance_context.source_refs/jurisdictions.`);
413
+ }
414
+ if (planSources.length === 0 || planProfiles.length === 0 || planControls.length === 0) {
415
+ warnings.push(`Privacy checklist incomplete for ${item.id}: 2-plan.yaml missing privacy_controls source/profile/control links.`);
416
+ }
417
+ if (selectedSkills.length === 0) {
418
+ warnings.push(`Privacy checklist incomplete for ${item.id}: 2-plan.yaml missing skill_conformance.selected_skills.`);
419
+ }
420
+ if (!architectureTree && item.execution_kind !== 'documentation') {
421
+ warnings.push(`Privacy checklist incomplete for ${item.id}: 2-plan.yaml missing skill_conformance.architecture_tree_ascii for code-impacting execution.`);
422
+ }
423
+ if (detectedConflicts.length > 0 && !(plan.skill_conformance?.resolution_adr_ref || '').trim()) {
424
+ warnings.push(`Privacy checklist incomplete for ${item.id}: detected skill conflicts require skill_conformance.resolution_adr_ref.`);
425
+ }
426
+ if (!hasSecurityIntegrity) {
427
+ warnings.push(`Privacy checklist incomplete for ${item.id}: 5-quality.yaml missing security_integrity validation block.`);
428
+ }
429
+ }
430
+ catch (error) {
431
+ const message = error instanceof Error ? error.message : String(error);
432
+ warnings.push(`Privacy checklist parse error for ${item.id}: ${message}`);
433
+ }
434
+ }
435
+ }
436
+ async function validateTraceabilityWorkspaceChecklist(projectRoot, activeDir, items, warnings) {
437
+ const traceabilityItems = items.filter((item) => item.status === 'IN_PROGRESS');
438
+ for (const item of traceabilityItems) {
439
+ const specPath = path.join(activeDir, item.id, '1-spec.yaml');
440
+ const changelogPath = path.join(activeDir, item.id, '4-changelog.yaml');
441
+ const qualityPath = path.join(activeDir, item.id, '5-quality.yaml');
442
+ if (!existsSync(specPath) || !existsSync(changelogPath) || !existsSync(qualityPath)) {
443
+ warnings.push(`Traceability checklist incomplete for ${item.id}: missing one of 1-spec/4-changelog/5-quality YAML files.`);
444
+ continue;
445
+ }
446
+ try {
447
+ const spec = parseWorkspaceYamlDocument('1-spec.yaml', await fs.readFile(specPath, 'utf-8'));
448
+ const changelog = parseWorkspaceYamlDocument('4-changelog.yaml', await fs.readFile(changelogPath, 'utf-8'));
449
+ const quality = parseWorkspaceYamlDocument('5-quality.yaml', await fs.readFile(qualityPath, 'utf-8'));
450
+ const result = evaluateWorkspaceTraceability(projectRoot, spec, changelog, quality);
451
+ if (!result.ok) {
452
+ warnings.push(`Traceability checklist incomplete for ${item.id}: ${result.reasons.join(' | ')}`);
453
+ }
454
+ }
455
+ catch (error) {
456
+ const message = error instanceof Error ? error.message : String(error);
457
+ warnings.push(`Traceability checklist parse error for ${item.id}: ${message}`);
458
+ }
459
+ }
460
+ }
461
+ function featureRequiresQualityContract(item) {
462
+ if (item.status === 'ARCHIVED' || item.status === 'DONE')
463
+ return false;
464
+ return Boolean(item.quality_contract) || item.status === 'IN_PROGRESS' || item.origin_ref === 'EPIC-0013';
465
+ }
466
+ async function detectMissingQualityArtifacts(activeDir, items) {
467
+ const missing = [];
468
+ for (const item of items) {
469
+ if (item.status !== 'IN_PROGRESS')
470
+ continue;
471
+ if (!item.quality_contract || item.quality_contract.enabled === false)
472
+ continue;
473
+ const qualityPath = path.join(activeDir, item.id, '5-quality.yaml');
474
+ if (!existsSync(qualityPath)) {
475
+ missing.push(item.id);
476
+ }
477
+ }
478
+ return missing;
479
+ }
480
+ function parseRouteToken(value) {
481
+ const token = value.trim();
482
+ if (!token)
483
+ return null;
484
+ if (token.startsWith('route:')) {
485
+ const raw = token.slice('route:'.length).trim();
486
+ if (!raw)
487
+ return null;
488
+ return raw.startsWith('/') ? raw : `/${raw}`;
489
+ }
490
+ if (token.startsWith('/'))
491
+ return token;
492
+ const inlineRoute = token.match(/\/[a-z0-9_\-/:]*/i);
493
+ if (inlineRoute && inlineRoute[0])
494
+ return inlineRoute[0];
495
+ return null;
496
+ }
497
+ function featureHasMetadataFrontendEvidence(item) {
498
+ const routes = [
499
+ ...item.produces.map(parseRouteToken),
500
+ ...item.consumes.map(parseRouteToken),
501
+ ...(item.frontend_surface_tokens || []).map(parseRouteToken),
502
+ ].filter((value) => Boolean(value));
503
+ const surfaces = (item.frontend_surface_tokens || []).map((value) => value.trim()).filter(Boolean);
504
+ return (routes.length > 0 ||
505
+ surfaces.length > 0 ||
506
+ item.touches.includes('frontend') ||
507
+ item.execution_kind === 'frontend_coverage');
508
+ }
509
+ async function validateCanonicalSddStructure(memoryRoot, errors) {
510
+ const forbiddenTopLevelDirs = ['backlog', 'features', 'finalize', 'queue'];
511
+ for (const dirName of forbiddenTopLevelDirs) {
512
+ const candidate = path.join(memoryRoot, dirName);
513
+ if (existsSync(candidate)) {
514
+ errors.push(`Non-canonical SDD structure detected: ${path.relative(process.cwd(), candidate)}. Use only state/, planning/, active/, and archived/.`);
515
+ }
516
+ }
517
+ const forbiddenNestedPaths = [path.join(memoryRoot, 'backlog', 'features')];
518
+ for (const candidate of forbiddenNestedPaths) {
519
+ if (existsSync(candidate)) {
520
+ errors.push(`Non-canonical SDD structure detected: ${path.relative(process.cwd(), candidate)}. Feature backlog must exist only in .sdd/state/backlog.yaml and rendered planning views.`);
521
+ }
522
+ }
523
+ }
524
+ export class SddCheckCommand {
525
+ async execute(projectRoot, options = {}) {
526
+ let config;
527
+ let paths;
528
+ const errors = [];
529
+ const warnings = [];
530
+ try {
531
+ config = await loadProjectSddConfig(projectRoot);
532
+ paths = resolveSddPaths(projectRoot, config);
533
+ }
534
+ catch (error) {
535
+ return {
536
+ valid: false,
537
+ errors: [error.message],
538
+ warnings,
539
+ summary: {
540
+ discovery: 0,
541
+ backlog: 0,
542
+ techDebt: 0,
543
+ finalizeQueue: 0,
544
+ frontendEnabled: false,
545
+ frontendGaps: 0,
546
+ frontendRoutes: 0,
547
+ progress_global: { done: 0, total: 0, percent: 0 },
548
+ progress_by_radar: [],
549
+ ready_for_parallel: 0,
550
+ blocked: 0,
551
+ lock_conflicts: 0,
552
+ documentation_sync: false,
553
+ core_views_stale: true,
554
+ missing_architecture_fields: [],
555
+ frontend_coverage_sync: true,
556
+ quality_contract_sync: true,
557
+ features_missing_frontend_declaration: [],
558
+ features_with_frontend_conflict: [],
559
+ features_missing_fgap_link: [],
560
+ features_missing_quality_contract: [],
561
+ features_missing_quality_artifact: [],
562
+ graph: {
563
+ readyForParallel: 0,
564
+ blocked: 0,
565
+ lockConflicts: 0,
566
+ },
567
+ },
568
+ };
569
+ }
570
+ if (!existsSync(paths.memoryRoot)) {
571
+ throw new Error(`SDD memory directory not found at ${paths.memoryRoot}. Run "${CLI_NAME} sdd init".`);
572
+ }
573
+ await validateCanonicalSddStructure(paths.memoryRoot, errors);
574
+ const requiredFiles = [
575
+ paths.stateFiles.discoveryIndex,
576
+ paths.stateFiles.backlog,
577
+ paths.stateFiles.techDebt,
578
+ paths.stateFiles.finalizeQueue,
579
+ paths.stateFiles.skillCatalog,
580
+ paths.stateFiles.unblockEvents,
581
+ paths.stateFiles.sourceIndex,
582
+ ];
583
+ for (const filePath of requiredFiles) {
584
+ if (!existsSync(filePath)) {
585
+ errors.push(`Arquivo de estado obrigatorio ausente: ${path.relative(projectRoot, filePath)}`);
586
+ }
587
+ }
588
+ if (config.frontend.enabled) {
589
+ if (!existsSync(paths.stateFiles.frontendGaps)) {
590
+ errors.push(`Arquivo de estado de frontend ausente: ${path.relative(projectRoot, paths.stateFiles.frontendGaps)}`);
591
+ }
592
+ if (!existsSync(paths.stateFiles.frontendMap)) {
593
+ errors.push(`Arquivo de estado de frontend ausente: ${path.relative(projectRoot, paths.stateFiles.frontendMap)}`);
594
+ }
595
+ }
596
+ const canonicalFiles = [
597
+ paths.stateFiles.architecture,
598
+ paths.stateFiles.serviceCatalog,
599
+ paths.stateFiles.techStack,
600
+ paths.stateFiles.integrationContracts,
601
+ paths.stateFiles.repoMap,
602
+ ];
603
+ for (const filePath of canonicalFiles) {
604
+ if (!existsSync(filePath)) {
605
+ errors.push(`Missing canonical file: ${path.relative(projectRoot, filePath)}`);
606
+ }
607
+ }
608
+ if (config.frontend.enabled && !existsSync(paths.stateFiles.frontendDecisions)) {
609
+ errors.push(`Missing canonical frontend file: ${path.relative(projectRoot, paths.stateFiles.frontendDecisions)}`);
610
+ }
611
+ if (errors.length > 0) {
612
+ return {
613
+ valid: false,
614
+ errors,
615
+ warnings,
616
+ summary: {
617
+ discovery: 0,
618
+ backlog: 0,
619
+ techDebt: 0,
620
+ finalizeQueue: 0,
621
+ frontendEnabled: config.frontend.enabled,
622
+ frontendGaps: 0,
623
+ frontendRoutes: 0,
624
+ progress_global: { done: 0, total: 0, percent: 0 },
625
+ progress_by_radar: [],
626
+ ready_for_parallel: 0,
627
+ blocked: 0,
628
+ lock_conflicts: 0,
629
+ documentation_sync: false,
630
+ core_views_stale: true,
631
+ missing_architecture_fields: [],
632
+ frontend_coverage_sync: true,
633
+ quality_contract_sync: true,
634
+ features_missing_frontend_declaration: [],
635
+ features_with_frontend_conflict: [],
636
+ features_missing_fgap_link: [],
637
+ features_missing_quality_contract: [],
638
+ features_missing_quality_artifact: [],
639
+ graph: {
640
+ readyForParallel: 0,
641
+ blocked: 0,
642
+ lockConflicts: 0,
643
+ },
644
+ },
645
+ };
646
+ }
647
+ let snapshot;
648
+ try {
649
+ snapshot = await loadStateSnapshot(paths, config);
650
+ }
651
+ catch (error) {
652
+ return {
653
+ valid: false,
654
+ errors: [`Schema de estado invalido: ${error.message}`],
655
+ warnings,
656
+ summary: {
657
+ discovery: 0,
658
+ backlog: 0,
659
+ techDebt: 0,
660
+ finalizeQueue: 0,
661
+ frontendEnabled: config.frontend.enabled,
662
+ frontendGaps: 0,
663
+ frontendRoutes: 0,
664
+ progress_global: { done: 0, total: 0, percent: 0 },
665
+ progress_by_radar: [],
666
+ ready_for_parallel: 0,
667
+ blocked: 0,
668
+ lock_conflicts: 0,
669
+ documentation_sync: false,
670
+ core_views_stale: true,
671
+ missing_architecture_fields: [],
672
+ frontend_coverage_sync: true,
673
+ quality_contract_sync: true,
674
+ features_missing_frontend_declaration: [],
675
+ features_with_frontend_conflict: [],
676
+ features_missing_fgap_link: [],
677
+ features_missing_quality_contract: [],
678
+ features_missing_quality_artifact: [],
679
+ graph: {
680
+ readyForParallel: 0,
681
+ blocked: 0,
682
+ lockConflicts: 0,
683
+ },
684
+ },
685
+ };
686
+ }
687
+ checkUniqueIds(snapshot.discoveryIndex.records, 'discovery-index.records', errors);
688
+ checkUniqueIds(snapshot.backlog.items, 'backlog.items', errors);
689
+ checkUniqueIds(snapshot.techDebt.items, 'tech-debt.items', errors);
690
+ validateDiscoveryRecords(snapshot.discoveryIndex.records, errors);
691
+ validateBacklog(snapshot.backlog.items, errors, warnings);
692
+ validateTechDebt(snapshot.techDebt.items, errors);
693
+ const isStrict = options.strict ?? false;
694
+ validateReferentialIntegrity(snapshot, errors, warnings, isStrict);
695
+ validateSkillOperationalIntegrity(snapshot, errors);
696
+ const archiveCollisions = await detectArchiveArchivedLifecycleCollisions(paths);
697
+ for (const collision of archiveCollisions) {
698
+ errors.push(collision.message);
699
+ }
700
+ if (config.frontend.enabled && snapshot.frontendGaps) {
701
+ checkUniqueIds(snapshot.frontendGaps.items, 'frontend-gaps.items', errors);
702
+ validateFrontendReferences(snapshot.frontendGaps.items, snapshot.backlog.items, errors, warnings);
703
+ }
704
+ await validateActiveTaskChecklist(paths.activeDir, snapshot.backlog.items, warnings);
705
+ await validateWorkspaceCoherence(paths.activeDir, paths.archivedDir, snapshot.backlog.items, warnings);
706
+ validatePrivacySourceRegistry(snapshot, warnings);
707
+ await validatePrivacyWorkspaceChecklist(paths.activeDir, snapshot.backlog.items, warnings);
708
+ await validateTraceabilityWorkspaceChecklist(paths.projectRoot, paths.activeDir, snapshot.backlog.items, warnings);
709
+ const featuresMissingFrontendDeclaration = config.frontend.enabled
710
+ ? snapshot.backlog.items
711
+ .filter((item) => item.status !== 'ARCHIVED' && item.status !== 'DONE')
712
+ .filter((item) => (item.frontend_impact_status || 'unknown') === 'unknown')
713
+ .map((item) => item.id)
714
+ : [];
715
+ const featuresWithFrontendConflict = config.frontend.enabled
716
+ ? snapshot.backlog.items
717
+ .filter((item) => item.status !== 'ARCHIVED' && item.status !== 'DONE')
718
+ .filter((item) => (item.frontend_impact_status || 'unknown') === 'none')
719
+ .filter((item) => featureHasMetadataFrontendEvidence(item))
720
+ .map((item) => item.id)
721
+ : [];
722
+ const featuresMissingFgapLink = config.frontend.enabled
723
+ ? snapshot.backlog.items
724
+ .filter((item) => item.status !== 'ARCHIVED' && item.status !== 'DONE')
725
+ .filter((item) => (item.frontend_impact_status || 'unknown') === 'required')
726
+ .filter((item) => item.frontend_gap_refs.length === 0)
727
+ .map((item) => item.id)
728
+ : [];
729
+ const featuresMissingQualityContract = snapshot.backlog.items
730
+ .filter(featureRequiresQualityContract)
731
+ .filter((item) => !item.quality_contract || item.quality_contract.enabled === false)
732
+ .map((item) => item.id);
733
+ const featuresMissingQualityArtifact = await detectMissingQualityArtifacts(paths.activeDir, snapshot.backlog.items);
734
+ const missingArchitectureFields = [];
735
+ if (snapshot.architecture.nodes.length === 0) {
736
+ missingArchitectureFields.push('architecture.nodes vazio');
737
+ }
738
+ if (snapshot.serviceCatalog.services.length === 0) {
739
+ missingArchitectureFields.push('service-catalog.services vazio');
740
+ }
741
+ if (snapshot.techStack.items.length === 0) {
742
+ missingArchitectureFields.push('tech-stack.items vazio');
743
+ }
744
+ if (snapshot.integrationContracts.contracts.length === 0) {
745
+ missingArchitectureFields.push('integration-contracts.contracts vazio');
746
+ }
747
+ if (snapshot.repoMap.items.length === 0) {
748
+ missingArchitectureFields.push('repo-map.items vazio');
749
+ }
750
+ const hasFrontendDecisionDemand = config.frontend.enabled &&
751
+ ((snapshot.frontendGaps?.items.length ?? 0) > 0 ||
752
+ snapshot.backlog.items.some((item) => featureHasMetadataFrontendEvidence(item)));
753
+ if (hasFrontendDecisionDemand && (snapshot.frontendDecisions?.items.length ?? 0) === 0) {
754
+ missingArchitectureFields.push('frontend-decisions.items vazio');
755
+ }
756
+ const shouldRender = options.render ?? config.views.autoRender;
757
+ if (shouldRender && errors.length === 0) {
758
+ await renderViews(paths, config, snapshot);
759
+ await syncSddGuideDocs(projectRoot, paths, config);
760
+ }
761
+ const coreFiles = [
762
+ path.join(paths.coreDir, 'index.md'),
763
+ path.join(paths.coreDir, 'servicos.md'),
764
+ path.join(paths.coreDir, 'spec-tecnologica.md'),
765
+ path.join(paths.coreDir, 'repo-map.md'),
766
+ ];
767
+ if (config.frontend.enabled) {
768
+ coreFiles.push(path.join(paths.coreDir, 'frontend-map.md'));
769
+ coreFiles.push(path.join(paths.coreDir, 'frontend-sitemap.md'));
770
+ coreFiles.push(path.join(paths.coreDir, 'frontend-decisions.md'));
771
+ }
772
+ const coreViewsStale = coreFiles.some((file) => !existsSync(file));
773
+ const docsValidation = await validateSddGuideDocs(projectRoot, paths, config);
774
+ if (!docsValidation.documentationSync) {
775
+ warnings.push(`Onboarding blocks are not synchronized: ${docsValidation.missingBlocks.join(', ')}`);
776
+ }
777
+ if (featuresMissingFrontendDeclaration.length > 0) {
778
+ warnings.push(`Features sem declaracao de impacto frontend: ${featuresMissingFrontendDeclaration.join(', ')}`);
779
+ }
780
+ if (featuresWithFrontendConflict.length > 0) {
781
+ warnings.push(`Features com conflito de cobertura frontend: ${featuresWithFrontendConflict.join(', ')}`);
782
+ }
783
+ if (featuresMissingFgapLink.length > 0) {
784
+ warnings.push(`Features com frontend_impact=required sem FGAP vinculado: ${featuresMissingFgapLink.join(', ')}`);
785
+ }
786
+ if (featuresMissingQualityContract.length > 0) {
787
+ warnings.push(`Features missing quality_contract: ${featuresMissingQualityContract.join(', ')}`);
788
+ }
789
+ if (featuresMissingQualityArtifact.length > 0) {
790
+ warnings.push(`Features missing active 5-quality.yaml artifact: ${featuresMissingQualityArtifact.join(', ')}`);
791
+ }
792
+ const graph = computeGraphSummary(snapshot.backlog.items);
793
+ const progress = computeProgress(snapshot.backlog.items);
794
+ const frontendCoverageSync = featuresMissingFrontendDeclaration.length === 0 &&
795
+ featuresWithFrontendConflict.length === 0 &&
796
+ featuresMissingFgapLink.length === 0;
797
+ const qualityContractSync = featuresMissingQualityContract.length === 0 &&
798
+ featuresMissingQualityArtifact.length === 0;
799
+ return {
800
+ valid: errors.length === 0,
801
+ errors,
802
+ warnings,
803
+ summary: {
804
+ discovery: snapshot.discoveryIndex.records.length,
805
+ backlog: snapshot.backlog.items.length,
806
+ techDebt: snapshot.techDebt.items.length,
807
+ finalizeQueue: snapshot.finalizeQueue.items.length,
808
+ frontendEnabled: config.frontend.enabled,
809
+ frontendGaps: snapshot.frontendGaps?.items.length ?? 0,
810
+ frontendRoutes: snapshot.frontendMap?.routes.length ?? 0,
811
+ progress_global: progress.progressGlobal,
812
+ progress_by_radar: progress.progressByRadar,
813
+ ready_for_parallel: graph.readyForParallel,
814
+ blocked: graph.blocked,
815
+ lock_conflicts: graph.lockConflicts,
816
+ documentation_sync: docsValidation.documentationSync,
817
+ core_views_stale: coreViewsStale,
818
+ missing_architecture_fields: missingArchitectureFields,
819
+ frontend_coverage_sync: frontendCoverageSync,
820
+ quality_contract_sync: qualityContractSync,
821
+ features_missing_frontend_declaration: featuresMissingFrontendDeclaration,
822
+ features_with_frontend_conflict: featuresWithFrontendConflict,
823
+ features_missing_fgap_link: featuresMissingFgapLink,
824
+ features_missing_quality_contract: featuresMissingQualityContract,
825
+ features_missing_quality_artifact: featuresMissingQualityArtifact,
826
+ graph,
827
+ },
828
+ };
829
+ }
830
+ }
831
+ //# sourceMappingURL=check.js.map