specweave 0.17.16 → 0.17.19

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 (232) hide show
  1. package/CLAUDE.md +405 -2495
  2. package/README.md +92 -2
  3. package/dist/locales/de/.gitkeep +0 -0
  4. package/dist/locales/de/cli.json +108 -0
  5. package/dist/locales/en/cli.json +287 -0
  6. package/dist/locales/en/errors.json +7 -0
  7. package/dist/locales/en/templates.json +6 -0
  8. package/dist/locales/es/.gitkeep +0 -0
  9. package/dist/locales/es/cli.json +41 -0
  10. package/dist/locales/fr/.gitkeep +0 -0
  11. package/dist/locales/fr/cli.json +108 -0
  12. package/dist/locales/ja/.gitkeep +0 -0
  13. package/dist/locales/ja/cli.json +108 -0
  14. package/dist/locales/ko/.gitkeep +0 -0
  15. package/dist/locales/ko/cli.json +108 -0
  16. package/dist/locales/pt/.gitkeep +0 -0
  17. package/dist/locales/pt/cli.json +108 -0
  18. package/dist/locales/ru/.gitkeep +0 -0
  19. package/dist/locales/ru/cli.json +269 -0
  20. package/dist/locales/zh/.gitkeep +0 -0
  21. package/dist/locales/zh/cli.json +108 -0
  22. package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
  23. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +188 -36
  24. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
  25. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
  26. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +65 -6
  27. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
  28. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts +54 -0
  29. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts.map +1 -0
  30. package/dist/plugins/specweave-ado/lib/ado-status-sync.js +86 -0
  31. package/dist/plugins/specweave-ado/lib/ado-status-sync.js.map +1 -0
  32. package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.d.ts +25 -0
  33. package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.d.ts.map +1 -0
  34. package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js +191 -0
  35. package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js.map +1 -0
  36. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +139 -0
  37. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts.map +1 -0
  38. package/dist/plugins/specweave-github/lib/duplicate-detector.js +389 -0
  39. package/dist/plugins/specweave-github/lib/duplicate-detector.js.map +1 -0
  40. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +26 -0
  41. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +1 -0
  42. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +249 -0
  43. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -0
  44. package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +63 -0
  45. package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -0
  46. package/dist/plugins/specweave-github/lib/epic-content-builder.js +216 -0
  47. package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -0
  48. package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
  49. package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
  50. package/dist/plugins/specweave-github/lib/github-client.js +25 -13
  51. package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
  52. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts +83 -0
  53. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +1 -0
  54. package/dist/plugins/specweave-github/lib/github-epic-sync.js +466 -0
  55. package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -0
  56. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts +43 -0
  57. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts.map +1 -0
  58. package/dist/plugins/specweave-github/lib/github-status-sync.js +82 -0
  59. package/dist/plugins/specweave-github/lib/github-status-sync.js.map +1 -0
  60. package/dist/plugins/specweave-github/lib/task-sync.d.ts +5 -0
  61. package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +1 -1
  62. package/dist/plugins/specweave-github/lib/task-sync.js +38 -2
  63. package/dist/plugins/specweave-github/lib/task-sync.js.map +1 -1
  64. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +28 -0
  65. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -0
  66. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +156 -0
  67. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -0
  68. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +66 -0
  69. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -0
  70. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +274 -0
  71. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -0
  72. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +56 -0
  73. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -0
  74. package/dist/plugins/specweave-jira/lib/jira-status-sync.js +93 -0
  75. package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -0
  76. package/dist/spec-parser.js +629 -0
  77. package/dist/src/cli/commands/init.d.ts.map +1 -1
  78. package/dist/src/cli/commands/init.js +107 -3
  79. package/dist/src/cli/commands/init.js.map +1 -1
  80. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  81. package/dist/src/cli/helpers/issue-tracker/index.js +48 -3
  82. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  83. package/dist/src/core/deduplication/command-deduplicator.d.ts +166 -0
  84. package/dist/src/core/deduplication/command-deduplicator.d.ts.map +1 -0
  85. package/dist/src/core/deduplication/command-deduplicator.js +254 -0
  86. package/dist/src/core/deduplication/command-deduplicator.js.map +1 -0
  87. package/dist/src/core/living-docs/hierarchy-mapper.d.ts +142 -0
  88. package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -0
  89. package/dist/src/core/living-docs/hierarchy-mapper.js +453 -0
  90. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -0
  91. package/dist/src/core/living-docs/index.d.ts +10 -84
  92. package/dist/src/core/living-docs/index.d.ts.map +1 -1
  93. package/dist/src/core/living-docs/index.js +10 -164
  94. package/dist/src/core/living-docs/index.js.map +1 -1
  95. package/dist/src/core/living-docs/spec-distributor.d.ts +106 -0
  96. package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -0
  97. package/dist/src/core/living-docs/spec-distributor.js +823 -0
  98. package/dist/src/core/living-docs/spec-distributor.js.map +1 -0
  99. package/dist/src/core/living-docs/types.d.ts +201 -0
  100. package/dist/src/core/living-docs/types.d.ts.map +1 -0
  101. package/dist/src/core/living-docs/types.js +15 -0
  102. package/dist/src/core/living-docs/types.js.map +1 -0
  103. package/dist/src/core/logging/prompt-logger.d.ts +70 -0
  104. package/dist/src/core/logging/prompt-logger.d.ts.map +1 -0
  105. package/dist/src/core/logging/prompt-logger.js +247 -0
  106. package/dist/src/core/logging/prompt-logger.js.map +1 -0
  107. package/dist/src/core/status-line/status-line-manager.d.ts +15 -24
  108. package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
  109. package/dist/src/core/status-line/status-line-manager.js +33 -70
  110. package/dist/src/core/status-line/status-line-manager.js.map +1 -1
  111. package/dist/src/core/status-line/types.d.ts +19 -31
  112. package/dist/src/core/status-line/types.d.ts.map +1 -1
  113. package/dist/src/core/status-line/types.js +5 -9
  114. package/dist/src/core/status-line/types.js.map +1 -1
  115. package/dist/src/core/sync/conflict-resolver.d.ts +66 -0
  116. package/dist/src/core/sync/conflict-resolver.d.ts.map +1 -0
  117. package/dist/src/core/sync/conflict-resolver.js +108 -0
  118. package/dist/src/core/sync/conflict-resolver.js.map +1 -0
  119. package/dist/src/core/sync/enhanced-content-builder.d.ts +55 -0
  120. package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -0
  121. package/dist/src/core/sync/enhanced-content-builder.js +202 -0
  122. package/dist/src/core/sync/enhanced-content-builder.js.map +1 -0
  123. package/dist/src/core/sync/label-detector.d.ts +66 -0
  124. package/dist/src/core/sync/label-detector.d.ts.map +1 -0
  125. package/dist/src/core/sync/label-detector.js +211 -0
  126. package/dist/src/core/sync/label-detector.js.map +1 -0
  127. package/dist/src/core/sync/retry-logic.d.ts +64 -0
  128. package/dist/src/core/sync/retry-logic.d.ts.map +1 -0
  129. package/dist/src/core/sync/retry-logic.js +165 -0
  130. package/dist/src/core/sync/retry-logic.js.map +1 -0
  131. package/dist/src/core/sync/spec-content-sync.d.ts +88 -0
  132. package/dist/src/core/sync/spec-content-sync.d.ts.map +1 -0
  133. package/dist/src/core/sync/spec-content-sync.js +5 -0
  134. package/dist/src/core/sync/spec-content-sync.js.map +1 -0
  135. package/dist/src/core/sync/spec-increment-mapper.d.ts +100 -0
  136. package/dist/src/core/sync/spec-increment-mapper.d.ts.map +1 -0
  137. package/dist/src/core/sync/spec-increment-mapper.js +424 -0
  138. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -0
  139. package/dist/src/core/sync/status-cache.d.ts +91 -0
  140. package/dist/src/core/sync/status-cache.d.ts.map +1 -0
  141. package/dist/src/core/sync/status-cache.js +140 -0
  142. package/dist/src/core/sync/status-cache.js.map +1 -0
  143. package/dist/src/core/sync/status-mapper.d.ts +69 -0
  144. package/dist/src/core/sync/status-mapper.d.ts.map +1 -0
  145. package/dist/src/core/sync/status-mapper.js +90 -0
  146. package/dist/src/core/sync/status-mapper.js.map +1 -0
  147. package/dist/src/core/sync/status-sync-engine.d.ts +162 -0
  148. package/dist/src/core/sync/status-sync-engine.d.ts.map +1 -0
  149. package/dist/src/core/sync/status-sync-engine.js +347 -0
  150. package/dist/src/core/sync/status-sync-engine.js.map +1 -0
  151. package/dist/src/core/sync/sync-event-logger.d.ts +99 -0
  152. package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -0
  153. package/dist/src/core/sync/sync-event-logger.js +103 -0
  154. package/dist/src/core/sync/sync-event-logger.js.map +1 -0
  155. package/dist/src/core/sync/types.d.ts +52 -0
  156. package/dist/src/core/sync/types.d.ts.map +1 -0
  157. package/dist/src/core/sync/types.js +5 -0
  158. package/dist/src/core/sync/types.js.map +1 -0
  159. package/dist/src/core/sync/workflow-detector.d.ts +95 -0
  160. package/dist/src/core/sync/workflow-detector.d.ts.map +1 -0
  161. package/dist/src/core/sync/workflow-detector.js +175 -0
  162. package/dist/src/core/sync/workflow-detector.js.map +1 -0
  163. package/dist/src/core/types/config.d.ts +51 -0
  164. package/dist/src/core/types/config.d.ts.map +1 -1
  165. package/dist/src/core/types/config.js +47 -0
  166. package/dist/src/core/types/config.js.map +1 -1
  167. package/dist/src/core/types/increment-metadata.d.ts +4 -0
  168. package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
  169. package/dist/src/core/types/increment-metadata.js.map +1 -1
  170. package/dist/src/utils/github-url.d.ts +53 -0
  171. package/dist/src/utils/github-url.d.ts.map +1 -0
  172. package/dist/src/utils/github-url.js +90 -0
  173. package/dist/src/utils/github-url.js.map +1 -0
  174. package/dist/src/utils/spec-parser.d.ts +145 -0
  175. package/dist/src/utils/spec-parser.d.ts.map +1 -0
  176. package/dist/src/utils/spec-parser.js +640 -0
  177. package/dist/src/utils/spec-parser.js.map +1 -0
  178. package/dist/tsconfig.tsbuildinfo +1 -0
  179. package/package.json +1 -1
  180. package/plugins/specweave/agents/pm/AGENT.md +160 -13
  181. package/plugins/specweave/agents/pm/templates/increment-spec.md +158 -0
  182. package/plugins/specweave/agents/pm/templates/living-docs-spec.md +113 -0
  183. package/plugins/specweave/commands/specweave-done.md +163 -0
  184. package/plugins/specweave/commands/specweave.md +70 -405
  185. package/plugins/specweave/hooks/hooks.json +4 -0
  186. package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
  187. package/plugins/specweave/hooks/lib/update-status-line.sh +79 -111
  188. package/plugins/specweave/hooks/post-increment-planning.sh +133 -37
  189. package/plugins/specweave/hooks/pre-command-deduplication.sh +86 -0
  190. package/plugins/specweave/lib/hooks/sync-living-docs.js +139 -34
  191. package/plugins/specweave/lib/hooks/sync-living-docs.ts +234 -38
  192. package/plugins/specweave/skills/SKILLS-INDEX.md +4 -24
  193. package/plugins/specweave/skills/increment-planner/SKILL.md +94 -0
  194. package/plugins/specweave/skills/increment-work-router/SKILL.md +466 -0
  195. package/plugins/specweave-ado/commands/specweave-ado-sync-spec.md +1 -1
  196. package/plugins/specweave-ado/lib/ado-spec-content-sync.js +49 -5
  197. package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +72 -6
  198. package/plugins/specweave-ado/lib/ado-status-sync.js +80 -0
  199. package/plugins/specweave-ado/lib/ado-status-sync.ts +121 -0
  200. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  201. package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +205 -0
  202. package/plugins/specweave-github/commands/specweave-github-sync-epic.md +248 -0
  203. package/plugins/specweave-github/commands/specweave-github-sync-spec.md +1 -1
  204. package/plugins/specweave-github/hooks/post-task-completion.sh +32 -0
  205. package/plugins/specweave-github/lib/duplicate-detector.js +370 -0
  206. package/plugins/specweave-github/lib/duplicate-detector.ts +525 -0
  207. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  208. package/plugins/specweave-github/lib/enhanced-github-sync.ts +322 -0
  209. package/plugins/specweave-github/lib/epic-content-builder.js +227 -0
  210. package/plugins/specweave-github/lib/epic-content-builder.ts +317 -0
  211. package/plugins/specweave-github/lib/github-client.js +21 -10
  212. package/plugins/specweave-github/lib/github-client.ts +27 -16
  213. package/plugins/specweave-github/lib/github-epic-sync.js +488 -0
  214. package/plugins/specweave-github/lib/github-epic-sync.ts +715 -0
  215. package/plugins/specweave-github/lib/github-status-sync.js +71 -0
  216. package/plugins/specweave-github/lib/github-status-sync.ts +107 -0
  217. package/plugins/specweave-github/lib/task-sync.js +33 -2
  218. package/plugins/specweave-github/lib/task-sync.ts +44 -2
  219. package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +267 -0
  220. package/plugins/specweave-jira/commands/specweave-jira-sync-spec.md +1 -1
  221. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  222. package/plugins/specweave-jira/lib/enhanced-jira-sync.ts +196 -0
  223. package/plugins/specweave-jira/lib/jira-epic-sync.js +304 -0
  224. package/plugins/specweave-jira/lib/jira-epic-sync.ts +459 -0
  225. package/plugins/specweave-jira/lib/jira-status-sync.js +79 -0
  226. package/plugins/specweave-jira/lib/jira-status-sync.ts +139 -0
  227. package/plugins/specweave-release/commands/specweave-release-platform.md +1 -1
  228. package/plugins/specweave-release/hooks/post-task-completion.sh +2 -2
  229. package/src/templates/AGENTS.md.template +88 -1
  230. package/src/templates/CLAUDE.md.template +49 -0
  231. package/plugins/specweave/skills/increment-quality-judge/SKILL.md +0 -524
  232. package/plugins/specweave/skills/plugin-installer/SKILL.md +0 -353
@@ -27,9 +27,10 @@ async function syncLivingDocs(incrementId) {
27
27
  specCopied = result.success;
28
28
  changedDocs = result.changedFiles;
29
29
  } else {
30
- console.log("\u{1F4CB} Using simple sync mode (legacy)");
31
- specCopied = await copyIncrementSpecToLivingDocs(incrementId);
32
- changedDocs = detectChangedDocs();
30
+ console.log("\u{1F4CA} Using hierarchical distribution mode (v2.1 - Epic + User Stories)");
31
+ const result = await hierarchicalDistribution(incrementId);
32
+ specCopied = result.success;
33
+ changedDocs = result.changedFiles;
33
34
  }
34
35
  if (changedDocs.length === 0 && !specCopied) {
35
36
  console.log("\u2139\uFE0F No living docs changed");
@@ -43,43 +44,47 @@ async function syncLivingDocs(incrementId) {
43
44
  }
44
45
  }
45
46
  async function intelligentSyncLivingDocs(incrementId, config) {
47
+ console.log(" \u26A0\uFE0F Intelligent sync not yet fully implemented");
48
+ console.log(" Falling back to hierarchical distribution mode...");
49
+ return await hierarchicalDistribution(incrementId);
50
+ }
51
+ async function hierarchicalDistribution(incrementId) {
46
52
  try {
47
- const { syncIncrement } = await import("../../../../src/core/living-docs/index.js");
48
- console.log(" \u{1F4D6} Parsing and classifying spec sections...");
49
- const result = await syncIncrement(incrementId, {
50
- verbose: false,
51
- // We'll log our own summary
52
- dryRun: false,
53
- parser: {
54
- preserveCodeBlocks: true,
55
- preserveLinks: true,
56
- preserveImages: true
57
- },
58
- distributor: {
59
- generateFrontmatter: true,
60
- preserveOriginal: config.livingDocs?.intelligent?.preserveOriginal ?? true
61
- },
62
- linker: {
63
- generateBacklinks: config.livingDocs?.intelligent?.generateCrossLinks ?? true,
64
- updateExisting: true
65
- }
53
+ const { SpecDistributor } = await import("../../../../src/core/living-docs/index.js");
54
+ console.log(" \u{1F4CA} Parsing and distributing spec into hierarchical structure...");
55
+ const projectRoot = process.cwd();
56
+ const distributor = new SpecDistributor(projectRoot, {
57
+ overwriteExisting: false,
58
+ createBackups: true
66
59
  });
67
- console.log(` \u2705 Intelligent sync complete:`);
68
- console.log(` Project: ${result.project.name} (${(result.project.confidence * 100).toFixed(0)}% confidence)`);
69
- console.log(` Files created: ${result.distribution.summary.filesCreated}`);
70
- console.log(` Files updated: ${result.distribution.summary.filesUpdated}`);
71
- console.log(` Cross-links: ${result.links.length}`);
72
- console.log(` Duration: ${result.duration}ms`);
73
- const changedFiles = [
74
- ...result.distribution.created.map((f) => f.path),
75
- ...result.distribution.updated.map((f) => f.path)
76
- ];
60
+ const result = await distributor.distribute(incrementId);
61
+ if (!result.success) {
62
+ console.error(` \u274C Distribution failed with errors:`);
63
+ for (const error of result.errors) {
64
+ console.error(` - ${error}`);
65
+ }
66
+ return { success: false, changedFiles: [] };
67
+ }
68
+ console.log(` \u2705 Hierarchical distribution complete:`);
69
+ console.log(` Epic ID: ${result.specId}`);
70
+ console.log(` User Stories: ${result.totalStories}`);
71
+ console.log(` Files created: ${result.totalFiles}`);
72
+ console.log(` Epic: ${path.basename(result.epicPath)}`);
73
+ console.log(` User story files: ${result.userStoryPaths.length}`);
74
+ if (result.warnings.length > 0) {
75
+ console.log(` \u26A0\uFE0F Warnings:`);
76
+ for (const warning of result.warnings) {
77
+ console.log(` - ${warning}`);
78
+ }
79
+ }
80
+ const changedFiles = [result.epicPath, ...result.userStoryPaths];
77
81
  return {
78
- success: result.success,
82
+ success: true,
79
83
  changedFiles
80
84
  };
81
85
  } catch (error) {
82
- console.error(` \u274C Intelligent sync failed: ${error}`);
86
+ console.error(` \u274C Hierarchical distribution failed: ${error}`);
87
+ console.error(error.stack);
83
88
  console.error(" Falling back to simple sync mode...");
84
89
  const copied = await copyIncrementSpecToLivingDocs(incrementId);
85
90
  return {
@@ -88,7 +93,107 @@ async function intelligentSyncLivingDocs(incrementId, config) {
88
93
  };
89
94
  }
90
95
  }
96
+ async function extractAndMergeLivingDocs(incrementId) {
97
+ try {
98
+ const {
99
+ parseIncrementSpec,
100
+ parseLivingDocsSpec,
101
+ extractSpecId,
102
+ mergeUserStories,
103
+ generateRelatedDocsLinks,
104
+ writeLivingDocsSpec
105
+ } = await import("../../../../src/utils/spec-parser.js");
106
+ const projectRoot = process.cwd();
107
+ const incrementSpecPath = path.join(projectRoot, ".specweave", "increments", incrementId, "spec.md");
108
+ if (!fs.existsSync(incrementSpecPath)) {
109
+ console.log(`\u26A0\uFE0F Increment spec not found: ${incrementSpecPath}`);
110
+ return false;
111
+ }
112
+ console.log(` \u{1F4D6} Parsing increment spec: ${incrementId}`);
113
+ const incrementSpec = await parseIncrementSpec(incrementSpecPath);
114
+ if (incrementSpec.userStories.length === 0) {
115
+ console.log(`\u2139\uFE0F No user stories found in increment spec, skipping sync`);
116
+ return false;
117
+ }
118
+ console.log(` \u2705 Found ${incrementSpec.userStories.length} user stories in increment`);
119
+ const specId = incrementSpec.implementsSpec || extractSpecId(incrementId);
120
+ const livingDocsDir = path.join(projectRoot, ".specweave", "docs", "internal", "specs", "default");
121
+ const livingDocsPath = path.join(livingDocsDir, `${specId}-${incrementId.replace(/^\d+-/, "")}.md`);
122
+ const livingDocsExists = fs.existsSync(livingDocsPath);
123
+ if (livingDocsExists) {
124
+ console.log(` \u{1F4DA} Living docs spec exists, merging user stories...`);
125
+ const livingSpec = await parseLivingDocsSpec(livingDocsPath);
126
+ const mergedStories = mergeUserStories(
127
+ livingSpec.userStories,
128
+ incrementSpec.userStories,
129
+ incrementId
130
+ );
131
+ const newStoriesCount = mergedStories.length - livingSpec.userStories.length;
132
+ const existingEntry = livingSpec.implementationHistory.find((e) => e.increment === incrementId);
133
+ if (!existingEntry) {
134
+ livingSpec.implementationHistory.push({
135
+ increment: incrementId,
136
+ stories: incrementSpec.userStories.map((s) => s.id),
137
+ status: "complete",
138
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
139
+ });
140
+ } else {
141
+ existingEntry.status = "complete";
142
+ existingEntry.date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
143
+ }
144
+ livingSpec.userStories = mergedStories;
145
+ livingSpec.lastUpdated = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
146
+ await writeLivingDocsSpec(livingDocsPath, livingSpec);
147
+ console.log(` \u2705 Merged ${newStoriesCount} new user stories into living docs`);
148
+ console.log(` \u2705 Updated implementation history for ${incrementId}`);
149
+ } else {
150
+ console.log(` \u{1F4DD} Creating new living docs spec: ${specId}`);
151
+ const relatedDocs = generateRelatedDocsLinks(incrementSpec, projectRoot);
152
+ const livingSpec = {
153
+ id: specId,
154
+ title: incrementSpec.title,
155
+ featureArea: extractFeatureArea(incrementSpec.title),
156
+ overview: incrementSpec.overview,
157
+ userStories: incrementSpec.userStories.map((story) => ({
158
+ ...story,
159
+ implementedIn: incrementId,
160
+ status: "complete"
161
+ })),
162
+ implementationHistory: [
163
+ {
164
+ increment: incrementId,
165
+ stories: incrementSpec.userStories.map((s) => s.id),
166
+ status: "complete",
167
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
168
+ }
169
+ ],
170
+ relatedDocs,
171
+ externalLinks: {},
172
+ priority: incrementSpec.priority,
173
+ status: "active",
174
+ created: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
175
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
176
+ };
177
+ await fs.ensureDir(livingDocsDir);
178
+ await writeLivingDocsSpec(livingDocsPath, livingSpec);
179
+ console.log(` \u2705 Created new living docs spec: ${specId}`);
180
+ console.log(` \u2705 Added ${incrementSpec.userStories.length} user stories`);
181
+ console.log(` \u2705 Generated links to ${relatedDocs.architecture.length} architecture docs`);
182
+ console.log(` \u2705 Generated links to ${relatedDocs.adrs.length} ADRs`);
183
+ }
184
+ return true;
185
+ } catch (error) {
186
+ console.error(`\u274C Error extracting/merging living docs: ${error}`);
187
+ console.error(error.stack);
188
+ return false;
189
+ }
190
+ }
191
+ function extractFeatureArea(title) {
192
+ return title.replace(/^(Increment \d+:\s*)?/, "").trim();
193
+ }
91
194
  async function copyIncrementSpecToLivingDocs(incrementId) {
195
+ console.warn("\u26A0\uFE0F Using deprecated copyIncrementSpecToLivingDocs (simple mode)");
196
+ console.warn(" Consider enabling intelligent mode to avoid duplication");
92
197
  try {
93
198
  const incrementSpecPath = path.join(process.cwd(), ".specweave", "increments", incrementId, "spec.md");
94
199
  const livingDocsPath = path.join(process.cwd(), ".specweave", "docs", "internal", "specs", `spec-${incrementId}.md`);
@@ -87,10 +87,11 @@ async function syncLivingDocs(incrementId: string): Promise<void> {
87
87
  specCopied = result.success;
88
88
  changedDocs = result.changedFiles;
89
89
  } else {
90
- // Simple mode: Copy spec to living docs (legacy)
91
- console.log('📋 Using simple sync mode (legacy)');
92
- specCopied = await copyIncrementSpecToLivingDocs(incrementId);
93
- changedDocs = detectChangedDocs();
90
+ // Hierarchical distribution mode: Epic + User Stories (v2.1)
91
+ console.log('📊 Using hierarchical distribution mode (v2.1 - Epic + User Stories)');
92
+ const result = await hierarchicalDistribution(incrementId);
93
+ specCopied = result.success;
94
+ changedDocs = result.changedFiles;
94
95
  }
95
96
 
96
97
  if (changedDocs.length === 0 && !specCopied) {
@@ -113,58 +114,81 @@ async function syncLivingDocs(incrementId: string): Promise<void> {
113
114
 
114
115
  /**
115
116
  * Intelligent sync using the new architecture (v0.18.0+)
117
+ *
118
+ * NOTE: syncIncrement not yet implemented, fallback to hierarchical distribution
116
119
  */
117
120
  async function intelligentSyncLivingDocs(
118
121
  incrementId: string,
119
122
  config: Config
123
+ ): Promise<{ success: boolean; changedFiles: string[] }> {
124
+ console.log(' ⚠️ Intelligent sync not yet fully implemented');
125
+ console.log(' Falling back to hierarchical distribution mode...');
126
+
127
+ // Fallback to hierarchical distribution
128
+ return await hierarchicalDistribution(incrementId);
129
+ }
130
+
131
+ /**
132
+ * Hierarchical distribution using new architecture (v2.1 - Epic + User Stories)
133
+ *
134
+ * Distributes increment spec into hierarchical structure:
135
+ * - Epic file (SPEC-###.md) - High-level summary (50-80 lines)
136
+ * - User story files (us-###.md) - Detailed requirements (80-120 lines each)
137
+ * - Links to tasks.md for implementation details
138
+ */
139
+ async function hierarchicalDistribution(
140
+ incrementId: string
120
141
  ): Promise<{ success: boolean; changedFiles: string[] }> {
121
142
  try {
122
143
  // Dynamic import to avoid circular dependencies
123
- const { syncIncrement } = await import('../../../../src/core/living-docs/index.js');
124
-
125
- console.log(' 📖 Parsing and classifying spec sections...');
126
-
127
- const result = await syncIncrement(incrementId, {
128
- verbose: false, // We'll log our own summary
129
- dryRun: false,
130
- parser: {
131
- preserveCodeBlocks: true,
132
- preserveLinks: true,
133
- preserveImages: true,
134
- },
135
- distributor: {
136
- generateFrontmatter: true,
137
- preserveOriginal: config.livingDocs?.intelligent?.preserveOriginal ?? true,
138
- },
139
- linker: {
140
- generateBacklinks: config.livingDocs?.intelligent?.generateCrossLinks ?? true,
141
- updateExisting: true,
142
- },
144
+ const { SpecDistributor } = await import('../../../../src/core/living-docs/index.js');
145
+
146
+ console.log(' 📊 Parsing and distributing spec into hierarchical structure...');
147
+
148
+ const projectRoot = process.cwd();
149
+ const distributor = new SpecDistributor(projectRoot, {
150
+ overwriteExisting: false,
151
+ createBackups: true,
143
152
  });
144
153
 
154
+ const result = await distributor.distribute(incrementId);
155
+
156
+ if (!result.success) {
157
+ console.error(` ❌ Distribution failed with errors:`);
158
+ for (const error of result.errors) {
159
+ console.error(` - ${error}`);
160
+ }
161
+ return { success: false, changedFiles: [] };
162
+ }
163
+
145
164
  // Log summary
146
- console.log(` ✅ Intelligent sync complete:`);
147
- console.log(` Project: ${result.project.name} (${(result.project.confidence * 100).toFixed(0)}% confidence)`);
148
- console.log(` Files created: ${result.distribution.summary.filesCreated}`);
149
- console.log(` Files updated: ${result.distribution.summary.filesUpdated}`);
150
- console.log(` Cross-links: ${result.links.length}`);
151
- console.log(` Duration: ${result.duration}ms`);
165
+ console.log(` ✅ Hierarchical distribution complete:`);
166
+ console.log(` Epic ID: ${result.specId}`);
167
+ console.log(` User Stories: ${result.totalStories}`);
168
+ console.log(` Files created: ${result.totalFiles}`);
169
+ console.log(` Epic: ${path.basename(result.epicPath)}`);
170
+ console.log(` User story files: ${result.userStoryPaths.length}`);
171
+
172
+ if (result.warnings.length > 0) {
173
+ console.log(` ⚠️ Warnings:`);
174
+ for (const warning of result.warnings) {
175
+ console.log(` - ${warning}`);
176
+ }
177
+ }
152
178
 
153
179
  // Collect changed file paths
154
- const changedFiles = [
155
- ...result.distribution.created.map((f) => f.path),
156
- ...result.distribution.updated.map((f) => f.path),
157
- ];
180
+ const changedFiles = [result.epicPath, ...result.userStoryPaths];
158
181
 
159
182
  return {
160
- success: result.success,
183
+ success: true,
161
184
  changedFiles,
162
185
  };
163
186
  } catch (error) {
164
- console.error(` ❌ Intelligent sync failed: ${error}`);
165
- console.error(' Falling back to simple sync mode...');
187
+ console.error(` ❌ Hierarchical distribution failed: ${error}`);
188
+ console.error((error as Error).stack);
166
189
 
167
190
  // Fallback to simple mode
191
+ console.error(' Falling back to simple sync mode...');
168
192
  const copied = await copyIncrementSpecToLivingDocs(incrementId);
169
193
  return {
170
194
  success: copied,
@@ -174,10 +198,182 @@ async function intelligentSyncLivingDocs(
174
198
  }
175
199
 
176
200
  /**
177
- * Copy increment spec to living docs (legacy/simple mode)
201
+ * Extract and merge living docs (v2.0 - NO DUPLICATION!)
202
+ *
203
+ * NEW ARCHITECTURE:
204
+ * - Living docs = Permanent EPIC (GitHub Project, Jira Epic, ADO Feature)
205
+ * - Increment spec = Temporary ITERATION (GitHub Issue, Jira Story, ADO User Story)
206
+ *
207
+ * What this does:
208
+ * 1. Parse increment spec (extract user stories ONLY)
209
+ * 2. Check if living docs spec exists
210
+ * 3. If exists: Merge new user stories (avoid duplicates)
211
+ * 4. If not: Create new living docs spec
212
+ * 5. Generate links to architecture/ADRs (NO duplication!)
213
+ * 6. Update implementation history
214
+ *
215
+ * What this DOESN'T do:
216
+ * - ❌ Copy architecture details (those live in architecture/)
217
+ * - ❌ Copy ADR content (those live in architecture/adr/)
218
+ * - ❌ Copy success metrics (those live in increment reports)
219
+ * - ❌ Copy future enhancements (those live in roadmap)
220
+ *
221
+ * Returns true if living docs updated, false if skipped
222
+ */
223
+ async function extractAndMergeLivingDocs(incrementId: string): Promise<boolean> {
224
+ try {
225
+ // Import parser utilities
226
+ const {
227
+ parseIncrementSpec,
228
+ parseLivingDocsSpec,
229
+ extractSpecId,
230
+ mergeUserStories,
231
+ generateRelatedDocsLinks,
232
+ writeLivingDocsSpec,
233
+ } = await import('../../../../src/utils/spec-parser.js');
234
+
235
+ const projectRoot = process.cwd();
236
+ const incrementSpecPath = path.join(projectRoot, '.specweave', 'increments', incrementId, 'spec.md');
237
+
238
+ // Check if increment spec exists
239
+ if (!fs.existsSync(incrementSpecPath)) {
240
+ console.log(`⚠️ Increment spec not found: ${incrementSpecPath}`);
241
+ return false;
242
+ }
243
+
244
+ console.log(` 📖 Parsing increment spec: ${incrementId}`);
245
+
246
+ // 1. Parse increment spec (extract user stories)
247
+ const incrementSpec = await parseIncrementSpec(incrementSpecPath);
248
+
249
+ if (incrementSpec.userStories.length === 0) {
250
+ console.log(`ℹ️ No user stories found in increment spec, skipping sync`);
251
+ return false;
252
+ }
253
+
254
+ console.log(` ✅ Found ${incrementSpec.userStories.length} user stories in increment`);
255
+
256
+ // 2. Determine living docs spec ID
257
+ const specId = incrementSpec.implementsSpec || extractSpecId(incrementId);
258
+ const livingDocsDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'specs', 'default');
259
+ const livingDocsPath = path.join(livingDocsDir, `${specId}-${incrementId.replace(/^\d+-/, '')}.md`);
260
+
261
+ // 3. Check if living docs spec exists
262
+ const livingDocsExists = fs.existsSync(livingDocsPath);
263
+
264
+ if (livingDocsExists) {
265
+ console.log(` 📚 Living docs spec exists, merging user stories...`);
266
+
267
+ // MERGE MODE: Add new user stories to existing spec
268
+ const livingSpec = await parseLivingDocsSpec(livingDocsPath);
269
+
270
+ // Merge user stories (adds new, updates existing)
271
+ const mergedStories = mergeUserStories(
272
+ livingSpec.userStories,
273
+ incrementSpec.userStories,
274
+ incrementId
275
+ );
276
+
277
+ const newStoriesCount = mergedStories.length - livingSpec.userStories.length;
278
+
279
+ // Update implementation history
280
+ const existingEntry = livingSpec.implementationHistory.find(e => e.increment === incrementId);
281
+
282
+ if (!existingEntry) {
283
+ livingSpec.implementationHistory.push({
284
+ increment: incrementId,
285
+ stories: incrementSpec.userStories.map(s => s.id),
286
+ status: 'complete',
287
+ date: new Date().toISOString().split('T')[0],
288
+ });
289
+ } else {
290
+ // Update existing entry
291
+ existingEntry.status = 'complete';
292
+ existingEntry.date = new Date().toISOString().split('T')[0];
293
+ }
294
+
295
+ // Update user stories
296
+ livingSpec.userStories = mergedStories;
297
+
298
+ // Update last_updated
299
+ livingSpec.lastUpdated = new Date().toISOString().split('T')[0];
300
+
301
+ // Write updated spec
302
+ await writeLivingDocsSpec(livingDocsPath, livingSpec);
303
+
304
+ console.log(` ✅ Merged ${newStoriesCount} new user stories into living docs`);
305
+ console.log(` ✅ Updated implementation history for ${incrementId}`);
306
+
307
+ } else {
308
+ console.log(` 📝 Creating new living docs spec: ${specId}`);
309
+
310
+ // CREATE MODE: First increment for this spec
311
+ const relatedDocs = generateRelatedDocsLinks(incrementSpec, projectRoot);
312
+
313
+ const livingSpec = {
314
+ id: specId,
315
+ title: incrementSpec.title,
316
+ featureArea: extractFeatureArea(incrementSpec.title),
317
+ overview: incrementSpec.overview,
318
+ userStories: incrementSpec.userStories.map(story => ({
319
+ ...story,
320
+ implementedIn: incrementId,
321
+ status: 'complete' as const,
322
+ })),
323
+ implementationHistory: [
324
+ {
325
+ increment: incrementId,
326
+ stories: incrementSpec.userStories.map(s => s.id),
327
+ status: 'complete' as const,
328
+ date: new Date().toISOString().split('T')[0],
329
+ },
330
+ ],
331
+ relatedDocs,
332
+ externalLinks: {} as { github?: string; jira?: string; ado?: string },
333
+ priority: incrementSpec.priority,
334
+ status: 'active',
335
+ created: new Date().toISOString().split('T')[0],
336
+ lastUpdated: new Date().toISOString().split('T')[0],
337
+ };
338
+
339
+ // Ensure directory exists
340
+ await fs.ensureDir(livingDocsDir);
341
+
342
+ // Write new spec
343
+ await writeLivingDocsSpec(livingDocsPath, livingSpec);
344
+
345
+ console.log(` ✅ Created new living docs spec: ${specId}`);
346
+ console.log(` ✅ Added ${incrementSpec.userStories.length} user stories`);
347
+ console.log(` ✅ Generated links to ${relatedDocs.architecture.length} architecture docs`);
348
+ console.log(` ✅ Generated links to ${relatedDocs.adrs.length} ADRs`);
349
+ }
350
+
351
+ return true;
352
+
353
+ } catch (error) {
354
+ console.error(`❌ Error extracting/merging living docs: ${error}`);
355
+ console.error((error as Error).stack);
356
+ return false;
357
+ }
358
+ }
359
+
360
+ /**
361
+ * Extract feature area from title
362
+ */
363
+ function extractFeatureArea(title: string): string {
364
+ // Simple heuristic: Use title as feature area
365
+ // Can be customized later based on keywords
366
+ return title.replace(/^(Increment \d+:\s*)?/, '').trim();
367
+ }
368
+
369
+ /**
370
+ * Copy increment spec to living docs (DEPRECATED - use extractAndMergeLivingDocs instead)
178
371
  * Returns true if spec was copied, false if skipped
179
372
  */
180
373
  async function copyIncrementSpecToLivingDocs(incrementId: string): Promise<boolean> {
374
+ console.warn('⚠️ Using deprecated copyIncrementSpecToLivingDocs (simple mode)');
375
+ console.warn(' Consider enabling intelligent mode to avoid duplication');
376
+
181
377
  try {
182
378
  const incrementSpecPath = path.join(process.cwd(), '.specweave', 'increments', incrementId, 'spec.md');
183
379
  const livingDocsPath = path.join(process.cwd(), '.specweave', 'docs', 'internal', 'specs', `spec-${incrementId}.md`);
@@ -2,9 +2,9 @@
2
2
 
3
3
  **Purpose**: Quick reference for all available skills. Read this file BEFORE starting any task.
4
4
 
5
- **Last Updated**: 2025-11-10 (manually updated to include plugin-installer and plugin-expert)
5
+ **Last Updated**: 2025-11-13 (removed deprecated skills: plugin-installer, increment-quality-judge v1)
6
6
 
7
- **Total Skills**: 14
7
+ **Total Skills**: 18
8
8
 
9
9
  ---
10
10
 
@@ -37,16 +37,6 @@ Step 4: Execute → Follow the increment planning workflow
37
37
 
38
38
  ### Framework Core
39
39
 
40
- #### plugin-installer
41
-
42
- **Description**: Proactive just-in-time plugin installation. Auto-detects when specialized plugins are needed (frontend, kubernetes, ML, payments, testing, etc.) and installs them automatically before use. Activates for React, Next.js, K8s, Kubernetes, Helm, TensorFlow, PyTorch, ML model, Stripe, billing, payment, Playwright, E2E testing, Figma, design system, ADO, Azure DevOps, infrastructure, Prometheus, Grafana, monitoring, Node.js, Python backend, REST API, cloud deployment, diagram, Mermaid, C4, architecture diagram.
43
-
44
- **Activates for**: React, Next.js, frontend, UI component, K8s, Kubernetes, deploy, TensorFlow, ML model, Stripe, billing, E2E testing, Figma, diagram, architecture diagram
45
-
46
- **Location**: `.claude/skills/plugin-installer/SKILL.md`
47
-
48
- ---
49
-
50
40
  #### plugin-expert
51
41
 
52
42
  **Description**: Expert knowledge of Claude Code's plugin system, marketplace management, and installation commands. Activates for plugin installation, marketplace setup, plugin troubleshooting, plugin commands. Keywords plugin install, plugin marketplace, claude code plugins, plugin management, plugin errors, marketplace add, plugin list.
@@ -85,16 +75,6 @@ Step 4: Execute → Follow the increment planning workflow
85
75
 
86
76
  ---
87
77
 
88
- #### increment-quality-judge
89
-
90
- **Description**: Optional AI-powered quality assessment for specifications, plans, and tests. Goes beyond rule-based validation to evaluate clarity, testability, edge cases, and architecture soundness. Activates for validate quality, quality check, assess spec, evaluate increment, spec review, quality score.
91
-
92
- **Location**: `.claude/skills/increment-quality-judge/SKILL.md`
93
-
94
- **Allowed tools**: Read, Grep, Glob
95
-
96
- ---
97
-
98
78
  #### specweave-detector
99
79
 
100
80
  **Description**: Detects SpecWeave context (.specweave/ directory exists) and provides workflow documentation. Explains available slash commands and workflow. Keywords slash commands, /specweave:increment, /increment, /specweave:do, /specweave:progress, /specweave:validate, /specweave:done, specweave commands, workflow help, specweave folder.
@@ -202,13 +182,13 @@ Step 4: Execute → Follow the increment planning workflow
202
182
 
203
183
  | Your Task | Relevant Skill | Keywords |
204
184
  |-----------|---------------|----------|
205
- | "Preview internal docs" | `plugin-installer` | "preview docs", "Docusaurus", "documentation UI" |
206
185
  | "Plan a new feature" | `increment-planner` | "feature planning", "create increment" |
186
+ | "Implement feature" | `increment-work-router` | "implement", "complete", "build", "work on" |
207
187
  | "Sync to JIRA" | `jira-sync` | "JIRA sync", "create JIRA issue" |
208
188
  | "Create diagram" | `diagrams-architect` | "architecture diagram", "C4 diagram" |
209
189
  | "Build React UI" | `frontend` | "React", "components", "UI" |
210
190
  | "Deploy to cloud" | `hetzner-provisioner` | "deploy", "infrastructure" |
211
- | "Quality check" | `increment-quality-judge` | "quality check", "assess spec" |
191
+ | "Quality check" | `increment-quality-judge-v2` | "quality check", "assess spec", "risk assessment" |
212
192
  | "E2E testing" | `e2e-playwright` | "E2E test", "browser test" |
213
193
  | "Generate docs site" | `docusaurus` | "documentation site", "docs" |
214
194