specweave 0.32.0 → 0.32.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 (191) hide show
  1. package/CLAUDE.md +176 -2
  2. package/README.md +22 -0
  3. package/bin/specweave.js +18 -1
  4. package/dist/src/cli/commands/cache.d.ts +17 -0
  5. package/dist/src/cli/commands/cache.d.ts.map +1 -0
  6. package/dist/src/cli/commands/cache.js +126 -0
  7. package/dist/src/cli/commands/cache.js.map +1 -0
  8. package/dist/src/cli/commands/init.js +1 -1
  9. package/dist/src/cli/commands/init.js.map +1 -1
  10. package/dist/src/cli/commands/plan/increment-detector.js +2 -2
  11. package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
  12. package/dist/src/cli/commands/sync-spec-commits.js +1 -1
  13. package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
  14. package/dist/src/cli/commands/sync-specs.js +2 -2
  15. package/dist/src/cli/commands/sync-specs.js.map +1 -1
  16. package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
  17. package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
  18. package/dist/src/cli/workers/living-docs-worker.js +66 -1
  19. package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
  20. package/dist/src/config/types.d.ts +203 -1208
  21. package/dist/src/config/types.d.ts.map +1 -1
  22. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
  23. package/dist/src/core/discrepancy/increment-generator.js +5 -2
  24. package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
  25. package/dist/src/core/increment/duplicate-detector.js +2 -2
  26. package/dist/src/core/increment/duplicate-detector.js.map +1 -1
  27. package/dist/src/core/increment/increment-archiver.d.ts +24 -0
  28. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  29. package/dist/src/core/increment/increment-archiver.js +59 -2
  30. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  31. package/dist/src/core/increment/increment-status.js +2 -2
  32. package/dist/src/core/increment/increment-status.js.map +1 -1
  33. package/dist/src/core/increment/increment-utils.d.ts +85 -0
  34. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  35. package/dist/src/core/increment/increment-utils.js +102 -4
  36. package/dist/src/core/increment/increment-utils.js.map +1 -1
  37. package/dist/src/core/increment/metadata-validator.js +1 -1
  38. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  39. package/dist/src/core/living-docs/feature-id-manager.js +1 -1
  40. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  41. package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
  42. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  43. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
  44. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
  45. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +247 -0
  46. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
  47. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
  48. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
  49. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
  50. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
  51. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
  52. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
  53. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
  54. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
  55. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
  56. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
  57. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
  58. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
  59. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
  60. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
  61. package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
  62. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
  63. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +18 -0
  64. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
  65. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +154 -0
  66. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
  67. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
  68. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
  69. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
  70. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
  71. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +146 -0
  72. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
  73. package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
  74. package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
  75. package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -0
  76. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  77. package/dist/src/core/living-docs/living-docs-sync.js +36 -2
  78. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  79. package/dist/src/core/sync/spec-increment-mapper.js +3 -3
  80. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
  81. package/dist/src/importers/item-converter.d.ts +25 -0
  82. package/dist/src/importers/item-converter.d.ts.map +1 -1
  83. package/dist/src/importers/item-converter.js +135 -5
  84. package/dist/src/importers/item-converter.js.map +1 -1
  85. package/dist/src/init/architecture/types.d.ts +33 -140
  86. package/dist/src/init/architecture/types.d.ts.map +1 -1
  87. package/dist/src/init/compliance/types.d.ts +30 -27
  88. package/dist/src/init/compliance/types.d.ts.map +1 -1
  89. package/dist/src/init/repo/types.d.ts +11 -34
  90. package/dist/src/init/repo/types.d.ts.map +1 -1
  91. package/dist/src/init/research/src/config/types.d.ts +15 -82
  92. package/dist/src/init/research/src/config/types.d.ts.map +1 -1
  93. package/dist/src/init/research/types.d.ts +38 -93
  94. package/dist/src/init/research/types.d.ts.map +1 -1
  95. package/dist/src/init/team/types.d.ts +4 -42
  96. package/dist/src/init/team/types.d.ts.map +1 -1
  97. package/dist/src/types/dashboard-cache.d.ts +181 -0
  98. package/dist/src/types/dashboard-cache.d.ts.map +1 -0
  99. package/dist/src/types/dashboard-cache.js +65 -0
  100. package/dist/src/types/dashboard-cache.js.map +1 -0
  101. package/dist/src/utils/docs-validator.d.ts +131 -0
  102. package/dist/src/utils/docs-validator.d.ts.map +1 -0
  103. package/dist/src/utils/docs-validator.js +529 -0
  104. package/dist/src/utils/docs-validator.js.map +1 -0
  105. package/dist/src/utils/feature-id-collision.js +1 -1
  106. package/dist/src/utils/feature-id-collision.js.map +1 -1
  107. package/dist/src/utils/html-to-mdx.d.ts +1 -0
  108. package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
  109. package/dist/src/utils/html-to-mdx.js +43 -5
  110. package/dist/src/utils/html-to-mdx.js.map +1 -1
  111. package/package.json +1 -1
  112. package/plugins/specweave/agents/pm/AGENT.md +10 -7
  113. package/plugins/specweave/commands/specweave-archive-features.md +5 -7
  114. package/plugins/specweave/commands/specweave-archive.md +2 -1
  115. package/plugins/specweave/commands/specweave-do.md +35 -1
  116. package/plugins/specweave/commands/specweave-done.md +96 -0
  117. package/plugins/specweave/commands/specweave-import-external.md +45 -18
  118. package/plugins/specweave/commands/specweave-increment.md +331 -33
  119. package/plugins/specweave/commands/specweave-jobs.md +2 -2
  120. package/plugins/specweave/commands/specweave-progress.md +4 -4
  121. package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
  122. package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
  123. package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
  124. package/plugins/specweave/commands/specweave-validate-features.md +13 -8
  125. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  126. package/plugins/specweave/hooks/hooks.json +33 -4
  127. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  128. package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
  129. package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
  130. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  131. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  132. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  133. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  134. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  135. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  136. package/plugins/specweave/hooks/post-task-completion.sh +4 -23
  137. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  138. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
  139. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  140. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  141. package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
  142. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  143. package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
  144. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  145. package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
  146. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
  147. package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
  148. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  149. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
  150. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
  151. package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
  152. package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
  153. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
  154. package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
  155. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
  156. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
  157. package/plugins/specweave/scripts/README.md +166 -0
  158. package/plugins/specweave/scripts/cleanup-state.sh +142 -0
  159. package/plugins/specweave/scripts/force-kill.sh +142 -0
  160. package/plugins/specweave/scripts/jobs.js +171 -0
  161. package/plugins/specweave/scripts/progress.js +170 -0
  162. package/plugins/specweave/scripts/read-costs.sh +132 -0
  163. package/plugins/specweave/scripts/read-jobs.sh +324 -0
  164. package/plugins/specweave/scripts/read-progress.sh +185 -0
  165. package/plugins/specweave/scripts/read-status.sh +146 -0
  166. package/plugins/specweave/scripts/read-workflow.sh +173 -0
  167. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
  168. package/plugins/specweave/scripts/session-watchdog.sh +192 -0
  169. package/plugins/specweave/scripts/status.js +154 -0
  170. package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
  171. package/plugins/specweave/skills/increment-planner/SKILL.md +333 -24
  172. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -9
  173. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -2
  174. package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
  175. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  176. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  177. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  178. package/plugins/specweave-docs/commands/build.md +32 -4
  179. package/plugins/specweave-docs/commands/preview.md +43 -1
  180. package/plugins/specweave-docs/commands/validate.md +250 -0
  181. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
  182. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  183. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  184. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  185. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  186. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
  187. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
  188. package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
  189. package/plugins/specweave/hooks/post-write-spec.sh +0 -267
  190. package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
  191. package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
@@ -0,0 +1,170 @@
1
+ import { AdoClientV2 } from "./ado-client-v2.js";
2
+ import { EnhancedContentBuilder } from "../../../src/core/sync/enhanced-content-builder.js";
3
+ import { SpecIncrementMapper } from "../../../src/core/sync/spec-increment-mapper.js";
4
+ import { parseSpecContent } from "../../../src/core/spec-content-sync.js";
5
+ import path from "path";
6
+ import fs from "fs/promises";
7
+ async function syncSpecToAdoWithEnhancedContent(options) {
8
+ const { specPath, organization, project, dryRun = false, verbose = false } = options;
9
+ try {
10
+ const baseSpec = await parseSpecContent(specPath);
11
+ if (!baseSpec) {
12
+ return {
13
+ success: false,
14
+ action: "error",
15
+ error: "Failed to parse spec content"
16
+ };
17
+ }
18
+ if (verbose) {
19
+ console.log(`\u{1F4C4} Parsed spec: ${baseSpec.identifier.compact}`);
20
+ }
21
+ const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
22
+ const rootDir = await findSpecWeaveRoot(specPath);
23
+ const mapper = new SpecIncrementMapper(rootDir);
24
+ const mapping = await mapper.mapSpecToIncrements(specId);
25
+ if (verbose) {
26
+ console.log(`\u{1F517} Found ${mapping.increments.length} related increments`);
27
+ }
28
+ const taskMapping = buildTaskMapping(mapping.increments, organization, project);
29
+ const architectureDocs = await findArchitectureDocs(rootDir, specId);
30
+ const enhancedSpec = {
31
+ ...baseSpec,
32
+ summary: baseSpec.description,
33
+ taskMapping,
34
+ architectureDocs
35
+ };
36
+ const builder = new EnhancedContentBuilder();
37
+ const description = builder.buildExternalDescription(enhancedSpec);
38
+ if (verbose) {
39
+ console.log(`\u{1F4DD} Generated description: ${description.length} characters`);
40
+ }
41
+ if (dryRun) {
42
+ console.log("\u{1F50D} DRY RUN - Would create/update feature with:");
43
+ console.log(` Title: ${baseSpec.title}`);
44
+ console.log(` Description length: ${description.length}`);
45
+ return {
46
+ success: true,
47
+ action: "no-change",
48
+ tasksLinked: taskMapping?.tasks.length || 0
49
+ };
50
+ }
51
+ if (!organization || !project) {
52
+ return {
53
+ success: false,
54
+ action: "error",
55
+ error: "Azure DevOps organization/project not specified"
56
+ };
57
+ }
58
+ const profile = {
59
+ provider: "ado",
60
+ displayName: `${organization}/${project}`,
61
+ config: {
62
+ organization,
63
+ project
64
+ },
65
+ timeRange: { default: "1M", max: "6M" }
66
+ };
67
+ const pat = process.env.AZURE_DEVOPS_PAT || "";
68
+ const client = new AdoClientV2(profile, pat);
69
+ const existingFeature = await findExistingFeature(client, baseSpec.identifier.compact);
70
+ let result;
71
+ if (existingFeature) {
72
+ await client.updateWorkItem(existingFeature.id, {
73
+ title: `[${baseSpec.identifier.compact}] ${baseSpec.title}`,
74
+ description
75
+ });
76
+ result = {
77
+ success: true,
78
+ action: "updated",
79
+ featureId: existingFeature.id,
80
+ featureUrl: `https://dev.azure.com/${organization}/${project}/_workitems/edit/${existingFeature.id}`,
81
+ tasksLinked: taskMapping?.tasks.length || 0
82
+ };
83
+ } else {
84
+ const feature = await client.createEpic({
85
+ title: `[${baseSpec.identifier.compact}] ${baseSpec.title}`,
86
+ description,
87
+ tags: ["spec", "external-tool-sync"]
88
+ });
89
+ result = {
90
+ success: true,
91
+ action: "created",
92
+ featureId: feature.id,
93
+ featureUrl: `https://dev.azure.com/${organization}/${project}/_workitems/edit/${feature.id}`,
94
+ tasksLinked: taskMapping?.tasks.length || 0
95
+ };
96
+ }
97
+ if (verbose) {
98
+ console.log(`\u2705 ${result.action === "created" ? "Created" : "Updated"} feature #${result.featureId}`);
99
+ }
100
+ return result;
101
+ } catch (error) {
102
+ return {
103
+ success: false,
104
+ action: "error",
105
+ error: error.message
106
+ };
107
+ }
108
+ }
109
+ async function findSpecWeaveRoot(specPath) {
110
+ let currentDir = path.dirname(specPath);
111
+ while (true) {
112
+ const specweaveDir = path.join(currentDir, ".specweave");
113
+ try {
114
+ await fs.access(specweaveDir);
115
+ return currentDir;
116
+ } catch {
117
+ const parentDir = path.dirname(currentDir);
118
+ if (parentDir === currentDir) {
119
+ throw new Error(".specweave directory not found");
120
+ }
121
+ currentDir = parentDir;
122
+ }
123
+ }
124
+ }
125
+ function buildTaskMapping(increments, organization, project) {
126
+ if (increments.length === 0) return void 0;
127
+ const firstIncrement = increments[0];
128
+ const tasks = firstIncrement.tasks.map((task) => ({
129
+ id: task.id,
130
+ title: task.title,
131
+ userStories: task.userStories
132
+ }));
133
+ return {
134
+ incrementId: firstIncrement.id,
135
+ tasks,
136
+ tasksUrl: `https://dev.azure.com/${organization}/${project}/_git/repo?path=/.specweave/increments/${firstIncrement.id}/tasks.md`
137
+ };
138
+ }
139
+ async function findArchitectureDocs(rootDir, specId) {
140
+ const docs = [];
141
+ const archDir = path.join(rootDir, ".specweave/docs/internal/architecture");
142
+ try {
143
+ const adrDir = path.join(archDir, "adr");
144
+ try {
145
+ const adrs = await fs.readdir(adrDir);
146
+ const relatedAdrs = adrs.filter((file) => file.includes(specId.replace("spec-", "")));
147
+ for (const adr of relatedAdrs) {
148
+ docs.push({
149
+ type: "adr",
150
+ path: path.join(adrDir, adr),
151
+ title: adr.replace(".md", "").replace(/-/g, " ")
152
+ });
153
+ }
154
+ } catch {
155
+ }
156
+ } catch {
157
+ }
158
+ return docs;
159
+ }
160
+ async function findExistingFeature(client, specId) {
161
+ try {
162
+ const features = await client.queryWorkItems(`[System.Title] Contains '[${specId}]' AND [System.WorkItemType] = 'Feature'`);
163
+ return features[0] || null;
164
+ } catch {
165
+ return null;
166
+ }
167
+ }
168
+ export {
169
+ syncSpecToAdoWithEnhancedContent
170
+ };
@@ -1,19 +1,47 @@
1
1
  ---
2
2
  name: specweave-docs:build
3
- description: Build static documentation site for deployment. Auto-setup on first run. Outputs production-ready HTML/CSS/JS.
3
+ description: Build static documentation site for deployment. Validates docs first, auto-fixes issues, auto-setup on first run. Outputs production-ready HTML/CSS/JS.
4
4
  ---
5
5
 
6
6
  # Documentation Build Command
7
7
 
8
8
  Build production-ready static documentation site for deployment to any static host.
9
9
 
10
+ **CRITICAL**: Runs pre-flight validation to catch issues BEFORE building.
11
+
10
12
  ## Your Task
11
13
 
12
14
  **IMPORTANT**: This command must work in ANY SpecWeave user project, not just the SpecWeave repo itself.
13
15
 
14
- ### Step 1: Ensure Docusaurus is Set Up
16
+ ### Step 1: CRITICAL - Run Pre-Flight Validation
17
+
18
+ **ALWAYS validate BEFORE building to prevent cryptic webpack errors!**
19
+
20
+ ```typescript
21
+ import { DocsValidator } from '../../../src/utils/docs-validator.js';
22
+
23
+ const validator = new DocsValidator({
24
+ docsPath: '.specweave/docs/internal',
25
+ autoFix: true, // Auto-fix common issues
26
+ });
27
+
28
+ console.log('\n🔍 Running pre-build validation...\n');
29
+ const result = await validator.validate();
30
+
31
+ // Show summary
32
+ console.log(DocsValidator.formatResult(result));
33
+
34
+ // If errors remain after auto-fix, STOP and report
35
+ if (!result.valid) {
36
+ console.log('\n❌ Documentation has errors that must be fixed before build.');
37
+ console.log(' Fix the issues above, then try again.\n');
38
+ process.exit(1);
39
+ }
40
+
41
+ console.log('\n✅ Validation passed! Proceeding with build...\n');
42
+ ```
15
43
 
16
- First, ensure the cached Docusaurus installation exists:
44
+ ### Step 2: Ensure Docusaurus is Set Up
17
45
 
18
46
  ```bash
19
47
  # Check if Docusaurus is set up
@@ -26,7 +54,7 @@ fi
26
54
 
27
55
  If not set up, follow the same setup steps as `/specweave-docs:preview` (Step 3 in preview.md).
28
56
 
29
- ### Step 2: Run Build
57
+ ### Step 3: Run Build
30
58
 
31
59
  ```bash
32
60
  cd .specweave/cache/docs-site && npm run build
@@ -1,12 +1,14 @@
1
1
  ---
2
2
  name: specweave-docs:preview
3
- description: Launch Docusaurus documentation server for internal living docs. Auto-setup on first run. Port 3015.
3
+ description: Launch Docusaurus documentation server for internal living docs. Validates docs first, auto-fixes issues, auto-setup on first run. Port 3015.
4
4
  ---
5
5
 
6
6
  # Documentation Preview Command
7
7
 
8
8
  Launch Docusaurus development server with hot reload, Mermaid diagrams, and auto-generated sidebar.
9
9
 
10
+ **CRITICAL**: Runs pre-flight validation to catch issues BEFORE starting the server.
11
+
10
12
  ## Your Task
11
13
 
12
14
  **IMPORTANT**: This command must work in ANY SpecWeave user project, not just the SpecWeave repo itself.
@@ -22,6 +24,46 @@ ls -la .specweave/docs/internal/
22
24
  # Run 'specweave init' first or create the folder structure."
23
25
  ```
24
26
 
27
+ ### Step 1.5: CRITICAL - Run Pre-Flight Validation
28
+
29
+ **ALWAYS run validation BEFORE starting the server!**
30
+
31
+ ```typescript
32
+ import { DocsValidator } from '../../../src/utils/docs-validator.js';
33
+
34
+ const validator = new DocsValidator({
35
+ docsPath: '.specweave/docs/internal',
36
+ autoFix: true, // Auto-fix common issues
37
+ });
38
+
39
+ console.log('\n🔍 Running pre-flight validation...\n');
40
+ const result = await validator.validate();
41
+
42
+ // Show summary
43
+ console.log(DocsValidator.formatResult(result));
44
+
45
+ // If errors remain after auto-fix, STOP and report
46
+ if (!result.valid) {
47
+ console.log('\n❌ Documentation has errors that must be fixed before preview.');
48
+ console.log(' Fix the issues above, then try again.\n');
49
+ process.exit(1);
50
+ }
51
+
52
+ console.log('\n✅ Validation passed! Starting server...\n');
53
+ ```
54
+
55
+ **What this catches:**
56
+ - YAML frontmatter errors (unquoted colons, tabs)
57
+ - MDX compatibility issues (unquoted attributes, unclosed tags)
58
+ - Duplicate routes
59
+ - Broken internal links
60
+
61
+ **Auto-fixes applied:**
62
+ - Wraps YAML values with colons in quotes
63
+ - Quotes HTML attributes
64
+ - Adds closing slashes to void elements (`<br>` → `<br />`)
65
+ - Converts tabs to spaces in YAML
66
+
25
67
  ### Step 2: Check for Cached Installation
26
68
 
27
69
  ```bash
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: specweave-docs:validate
3
+ description: Validate documentation before preview/build. Catches YAML, MDX, broken links, and naming issues. Auto-fix available. Run this BEFORE preview or build to prevent cryptic webpack errors.
4
+ ---
5
+
6
+ # Documentation Validation Command
7
+
8
+ Validate your documentation for Docusaurus compatibility BEFORE starting the preview server or building.
9
+
10
+ ## Why This Matters
11
+
12
+ Docusaurus compilation errors are often cryptic:
13
+ - `Unexpected character` → unquoted HTML attribute
14
+ - `Unterminated JSX contents` → unclosed tag
15
+ - `Could not parse expression` → bad YAML frontmatter
16
+
17
+ This validator catches these issues **before** you see webpack errors.
18
+
19
+ ## Usage
20
+
21
+ ```bash
22
+ # Validate internal docs (default)
23
+ /specweave-docs:validate
24
+
25
+ # Validate with auto-fix
26
+ /specweave-docs:validate --fix
27
+
28
+ # Validate public docs
29
+ /specweave-docs:validate public
30
+
31
+ # Validate specific path
32
+ /specweave-docs:validate --path .specweave/docs/internal/specs
33
+ ```
34
+
35
+ ## Your Task
36
+
37
+ **CRITICAL**: Run validation BEFORE starting preview or build!
38
+
39
+ ### Step 1: Determine Docs Path
40
+
41
+ ```bash
42
+ # Check which docs to validate
43
+ DOCS_TYPE="${1:-internal}" # internal or public
44
+
45
+ if [ "$DOCS_TYPE" = "public" ]; then
46
+ DOCS_PATH=".specweave/docs/public"
47
+ else
48
+ DOCS_PATH=".specweave/docs/internal"
49
+ fi
50
+
51
+ # Verify path exists
52
+ if [ ! -d "$DOCS_PATH" ]; then
53
+ echo "❌ Documentation path not found: $DOCS_PATH"
54
+ exit 1
55
+ fi
56
+ ```
57
+
58
+ ### Step 2: Run Validation
59
+
60
+ Execute the validation using the DocsValidator:
61
+
62
+ ```typescript
63
+ import { DocsValidator } from '../../../src/utils/docs-validator.js';
64
+ import * as path from 'path';
65
+
66
+ // Get options from command args
67
+ const autoFix = process.argv.includes('--fix');
68
+ const docsType = process.argv.find(a => a === 'public') ? 'public' : 'internal';
69
+ const docsPath = path.resolve(`.specweave/docs/${docsType}`);
70
+
71
+ // Create validator
72
+ const validator = new DocsValidator({
73
+ docsPath,
74
+ autoFix,
75
+ });
76
+
77
+ // Run validation
78
+ console.log(`\n📋 Validating ${docsType} documentation...`);
79
+ console.log(` Path: ${docsPath}\n`);
80
+
81
+ const result = await validator.validate();
82
+
83
+ // Display formatted result
84
+ console.log(DocsValidator.formatResult(result));
85
+
86
+ // Exit with error code if invalid (for CI integration)
87
+ if (!result.valid && !autoFix) {
88
+ console.log('💡 Tip: Run with --fix to auto-repair fixable issues\n');
89
+ process.exit(1);
90
+ }
91
+ ```
92
+
93
+ ### Step 3: Report Results
94
+
95
+ Display a clear summary:
96
+
97
+ ```
98
+ ═══════════════════════════════════════════════════════════════
99
+ DOCUMENTATION VALIDATION REPORT
100
+ ═══════════════════════════════════════════════════════════════
101
+
102
+ ✅ Documentation is valid and ready for preview/build
103
+
104
+ Errors: 0
105
+ Warnings: 3
106
+ Info: 0
107
+
108
+ ═══════════════════════════════════════════════════════════════
109
+ ```
110
+
111
+ Or if issues found:
112
+
113
+ ```
114
+ ═══════════════════════════════════════════════════════════════
115
+ DOCUMENTATION VALIDATION REPORT
116
+ ═══════════════════════════════════════════════════════════════
117
+
118
+ ❌ Documentation has issues that need to be fixed
119
+
120
+ Errors: 2
121
+ Warnings: 5
122
+ Info: 0
123
+
124
+ ERRORS (must fix):
125
+ ───────────────────────────────────────────────────────────────
126
+ 📄 specs/FS-118E/FEATURE.md
127
+ ❌ yaml_unquoted_colon:3: Unquoted colon in YAML value: title: Feature: External Sync [auto-fixable]
128
+
129
+ 📄 architecture/diagrams/overview.md
130
+ ❌ mdx_compatibility: Unquoted attribute: target=_blank [auto-fixable]
131
+
132
+ QUICK FIXES:
133
+ ───────────────────────────────────────────────────────────────
134
+ 1. Run validation with auto-fix:
135
+ /specweave-docs:validate --fix
136
+
137
+ 2. Or fix manually:
138
+ • YAML: Wrap values with colons in quotes
139
+ title: "Feature: Auth" (not title: Feature: Auth)
140
+ • MDX: Quote HTML attributes, close self-closing tags
141
+ target="_blank" (not target=_blank)
142
+ <br /> (not <br>)
143
+
144
+ ═══════════════════════════════════════════════════════════════
145
+ ```
146
+
147
+ ## What Gets Validated
148
+
149
+ ### 1. YAML Frontmatter
150
+ - Unclosed frontmatter (`---` without closing `---`)
151
+ - Unquoted colons in values (`title: Feature: Auth` → error)
152
+ - Tab characters (YAML requires spaces)
153
+ - Invalid syntax
154
+
155
+ ### 2. MDX/JSX Compatibility
156
+ - Unquoted HTML attributes (`target=_blank` → needs quotes)
157
+ - Non-self-closing void tags (`<br>` → needs `<br />`)
158
+ - Script/style tags (not allowed in MDX)
159
+ - Unclosed HTML comments
160
+
161
+ ### 3. File Issues
162
+ - Duplicate routes (same path, different extensions)
163
+ - Invalid filename characters
164
+ - Spaces in filenames (URL issues)
165
+ - Very long filenames
166
+
167
+ ### 4. Internal Links
168
+ - Broken links to non-existent files
169
+ - Links to files outside docs folder (warning)
170
+ - Malformed link syntax
171
+
172
+ ## Auto-Fix Behavior
173
+
174
+ With `--fix`, the validator automatically repairs:
175
+
176
+ | Issue Type | Auto-Fix Action |
177
+ |------------|-----------------|
178
+ | `yaml_unquoted_colon` | Wraps value in quotes |
179
+ | `yaml_tabs` | Converts tabs to spaces |
180
+ | `mdx_compatibility` | Quotes attributes, closes tags |
181
+
182
+ Issues that **cannot** be auto-fixed:
183
+ - Broken links (need manual review)
184
+ - Duplicate routes (need to rename/delete)
185
+ - Invalid filenames (need manual rename)
186
+
187
+ ## CI/CD Integration
188
+
189
+ Use in GitHub Actions to gate deployments:
190
+
191
+ ```yaml
192
+ name: Validate Docs
193
+
194
+ on:
195
+ push:
196
+ paths:
197
+ - '.specweave/docs/**'
198
+
199
+ jobs:
200
+ validate:
201
+ runs-on: ubuntu-latest
202
+ steps:
203
+ - uses: actions/checkout@v4
204
+ - uses: actions/setup-node@v4
205
+ with:
206
+ node-version: '20'
207
+ - run: npm install
208
+ - run: npx specweave docs:validate
209
+ ```
210
+
211
+ ## Troubleshooting
212
+
213
+ ### "yaml_unquoted_colon" errors
214
+ ```yaml
215
+ # Wrong:
216
+ title: Feature: External Sync
217
+
218
+ # Correct:
219
+ title: "Feature: External Sync"
220
+ ```
221
+
222
+ ### "mdx_compatibility" errors
223
+ ```html
224
+ <!-- Wrong -->
225
+ <a href="..." target=_blank>Link</a>
226
+ <br>
227
+
228
+ <!-- Correct -->
229
+ <a href="..." target="_blank">Link</a>
230
+ <br />
231
+ ```
232
+
233
+ ### Many broken link warnings
234
+ If you see many warnings about links to `CLAUDE.md`, `README.md`, or `_archive/`:
235
+ - These are references to files outside the docs folder
236
+ - They're warnings, not errors
237
+ - The docs will still render, links just won't work in preview
238
+
239
+ ### To suppress warnings for intentional external refs
240
+ Add to docusaurus.config.ts:
241
+ ```typescript
242
+ onBrokenLinks: 'warn', // Not 'throw'
243
+ onBrokenMarkdownLinks: 'warn',
244
+ ```
245
+
246
+ ## See Also
247
+
248
+ - `/specweave-docs:preview` - Preview docs (runs validation first)
249
+ - `/specweave-docs:build` - Build docs (runs validation first)
250
+ - `/specweave-docs:health` - Full documentation health report