scene-capability-engine 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +2513 -0
  2. package/LICENSE +21 -0
  3. package/README.md +765 -0
  4. package/README.zh.md +630 -0
  5. package/bin/kiro-spec-engine.js +796 -0
  6. package/bin/kse.js +3 -0
  7. package/bin/sce.js +3 -0
  8. package/bin/sco.js +3 -0
  9. package/docs/331-poc-adaptation-roadmap.md +156 -0
  10. package/docs/331-poc-dual-track-integration-guide.md +120 -0
  11. package/docs/331-poc-weekly-delivery-checklist.md +52 -0
  12. package/docs/OFFLINE_INSTALL.md +96 -0
  13. package/docs/README.md +279 -0
  14. package/docs/adopt-migration-guide.md +599 -0
  15. package/docs/adoption-guide.md +616 -0
  16. package/docs/agent-hooks-analysis.md +815 -0
  17. package/docs/architecture.md +733 -0
  18. package/docs/articles/ai-driven-development-philosophy-and-practice-review.md +208 -0
  19. package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +459 -0
  20. package/docs/articles/ai-driven-development-philosophy-and-practice.md +492 -0
  21. package/docs/autonomous-control-guide.md +851 -0
  22. package/docs/command-reference.md +1368 -0
  23. package/docs/community.md +115 -0
  24. package/docs/cross-tool-guide.md +555 -0
  25. package/docs/developer-guide.md +619 -0
  26. package/docs/document-governance.md +865 -0
  27. package/docs/environment-management-guide.md +526 -0
  28. package/docs/examples/add-export-command/design.md +194 -0
  29. package/docs/examples/add-export-command/requirements.md +110 -0
  30. package/docs/examples/add-export-command/tasks.md +88 -0
  31. package/docs/examples/add-rest-api/design.md +855 -0
  32. package/docs/examples/add-rest-api/requirements.md +323 -0
  33. package/docs/examples/add-rest-api/tasks.md +355 -0
  34. package/docs/examples/add-user-dashboard/design.md +192 -0
  35. package/docs/examples/add-user-dashboard/requirements.md +143 -0
  36. package/docs/examples/add-user-dashboard/tasks.md +91 -0
  37. package/docs/faq.md +697 -0
  38. package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +156 -0
  39. package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +24 -0
  40. package/docs/images/wechat-qr.png +0 -0
  41. package/docs/integration-modes.md +529 -0
  42. package/docs/integration-philosophy.md +313 -0
  43. package/docs/knowledge-management-guide.md +263 -0
  44. package/docs/manual-workflows-guide.md +418 -0
  45. package/docs/moqui-capability-matrix.md +73 -0
  46. package/docs/moqui-template-core-library-playbook.md +109 -0
  47. package/docs/multi-agent-coordination-guide.md +553 -0
  48. package/docs/multi-repo-management-guide.md +1344 -0
  49. package/docs/quick-start-with-ai-tools.md +375 -0
  50. package/docs/quick-start.md +146 -0
  51. package/docs/release-checklist.md +121 -0
  52. package/docs/releases/README.md +13 -0
  53. package/docs/releases/v1.46.2-validation.md +45 -0
  54. package/docs/releases/v1.46.2.md +50 -0
  55. package/docs/scene-runtime-guide.md +347 -0
  56. package/docs/spec-collaboration-guide.md +369 -0
  57. package/docs/spec-locking-guide.md +225 -0
  58. package/docs/spec-numbering-guide.md +348 -0
  59. package/docs/spec-workflow.md +519 -0
  60. package/docs/steering-strategy-guide.md +196 -0
  61. package/docs/team-collaboration-guide.md +465 -0
  62. package/docs/testing-strategy.md +272 -0
  63. package/docs/tools/claude-guide.md +654 -0
  64. package/docs/tools/cursor-guide.md +706 -0
  65. package/docs/tools/generic-guide.md +446 -0
  66. package/docs/tools/kiro-guide.md +308 -0
  67. package/docs/tools/vscode-guide.md +445 -0
  68. package/docs/tools/windsurf-guide.md +391 -0
  69. package/docs/troubleshooting.md +1135 -0
  70. package/docs/upgrade-guide.md +639 -0
  71. package/docs/value-observability-guide.md +127 -0
  72. package/docs/zh/README.md +341 -0
  73. package/docs/zh/quick-start.md +764 -0
  74. package/docs/zh/release-checklist.md +121 -0
  75. package/docs/zh/releases/README.md +13 -0
  76. package/docs/zh/releases/v1.46.2-validation.md +45 -0
  77. package/docs/zh/releases/v1.46.2.md +50 -0
  78. package/docs/zh/spec-numbering-guide.md +348 -0
  79. package/docs/zh/tools/claude-guide.md +349 -0
  80. package/docs/zh/tools/cursor-guide.md +281 -0
  81. package/docs/zh/tools/generic-guide.md +499 -0
  82. package/docs/zh/tools/kiro-guide.md +342 -0
  83. package/docs/zh/tools/vscode-guide.md +449 -0
  84. package/docs/zh/tools/windsurf-guide.md +378 -0
  85. package/docs/zh/value-observability-guide.md +127 -0
  86. package/docs//344/272/244/344/273/230/346/270/205/345/215/225.md +75 -0
  87. package/lib/adoption/adoption-logger.js +487 -0
  88. package/lib/adoption/adoption-strategy.js +538 -0
  89. package/lib/adoption/backup-manager.js +420 -0
  90. package/lib/adoption/conflict-resolver.js +410 -0
  91. package/lib/adoption/detection-engine.js +275 -0
  92. package/lib/adoption/diff-viewer.js +226 -0
  93. package/lib/adoption/error-formatter.js +509 -0
  94. package/lib/adoption/file-classifier.js +385 -0
  95. package/lib/adoption/progress-reporter.js +534 -0
  96. package/lib/adoption/smart-orchestrator.js +470 -0
  97. package/lib/adoption/strategy-selector.js +218 -0
  98. package/lib/adoption/summary-generator.js +493 -0
  99. package/lib/adoption/template-sync.js +605 -0
  100. package/lib/auto/autonomous-engine.js +485 -0
  101. package/lib/auto/checkpoint-manager.js +300 -0
  102. package/lib/auto/close-loop-runner.js +2476 -0
  103. package/lib/auto/config-schema.js +176 -0
  104. package/lib/auto/decision-engine.js +344 -0
  105. package/lib/auto/error-recovery-manager.js +580 -0
  106. package/lib/auto/goal-decomposer.js +278 -0
  107. package/lib/auto/progress-tracker.js +502 -0
  108. package/lib/auto/safety-manager.js +186 -0
  109. package/lib/auto/semantic-decomposer.js +137 -0
  110. package/lib/auto/state-manager.js +126 -0
  111. package/lib/auto/task-queue-manager.js +340 -0
  112. package/lib/backup/backup-system.js +372 -0
  113. package/lib/backup/selective-backup.js +207 -0
  114. package/lib/collab/agent-registry.js +240 -0
  115. package/lib/collab/collab-manager.js +285 -0
  116. package/lib/collab/contract-manager.js +320 -0
  117. package/lib/collab/coordinator.js +370 -0
  118. package/lib/collab/dependency-manager.js +280 -0
  119. package/lib/collab/index.js +20 -0
  120. package/lib/collab/integration-manager.js +202 -0
  121. package/lib/collab/merge-coordinator.js +252 -0
  122. package/lib/collab/metadata-manager.js +233 -0
  123. package/lib/collab/multi-agent-config.js +120 -0
  124. package/lib/collab/spec-lifecycle-manager.js +304 -0
  125. package/lib/collab/sync-barrier.js +88 -0
  126. package/lib/collab/visualizer.js +208 -0
  127. package/lib/commands/adopt.js +749 -0
  128. package/lib/commands/auto.js +19559 -0
  129. package/lib/commands/collab.js +275 -0
  130. package/lib/commands/context.js +99 -0
  131. package/lib/commands/docs.js +808 -0
  132. package/lib/commands/doctor.js +273 -0
  133. package/lib/commands/env.js +420 -0
  134. package/lib/commands/knowledge.js +309 -0
  135. package/lib/commands/lock.js +235 -0
  136. package/lib/commands/ops.js +409 -0
  137. package/lib/commands/orchestrate.js +446 -0
  138. package/lib/commands/prompt.js +105 -0
  139. package/lib/commands/repo.js +118 -0
  140. package/lib/commands/rollback.js +219 -0
  141. package/lib/commands/scene.js +15549 -0
  142. package/lib/commands/spec-bootstrap.js +147 -0
  143. package/lib/commands/spec-gate.js +157 -0
  144. package/lib/commands/spec-pipeline.js +205 -0
  145. package/lib/commands/status.js +321 -0
  146. package/lib/commands/task.js +199 -0
  147. package/lib/commands/templates.js +654 -0
  148. package/lib/commands/upgrade.js +231 -0
  149. package/lib/commands/value.js +569 -0
  150. package/lib/commands/watch.js +684 -0
  151. package/lib/commands/workflows.js +240 -0
  152. package/lib/commands/workspace-multi.js +325 -0
  153. package/lib/commands/workspace.js +189 -0
  154. package/lib/context/context-exporter.js +378 -0
  155. package/lib/context/prompt-generator.js +482 -0
  156. package/lib/data/moqui-capability-lexicon.json +45 -0
  157. package/lib/environment/backup-system.js +189 -0
  158. package/lib/environment/environment-manager.js +379 -0
  159. package/lib/environment/environment-registry.js +168 -0
  160. package/lib/gitignore/gitignore-backup.js +229 -0
  161. package/lib/gitignore/gitignore-detector.js +239 -0
  162. package/lib/gitignore/gitignore-integration.js +267 -0
  163. package/lib/gitignore/gitignore-transformer.js +193 -0
  164. package/lib/gitignore/layered-rules-template.js +42 -0
  165. package/lib/governance/archive-tool.js +284 -0
  166. package/lib/governance/cleanup-tool.js +237 -0
  167. package/lib/governance/config-manager.js +186 -0
  168. package/lib/governance/diagnostic-engine.js +271 -0
  169. package/lib/governance/doc-reference-checker.js +200 -0
  170. package/lib/governance/execution-logger.js +243 -0
  171. package/lib/governance/file-scanner.js +285 -0
  172. package/lib/governance/hooks-manager.js +333 -0
  173. package/lib/governance/reporter.js +337 -0
  174. package/lib/governance/validation-engine.js +181 -0
  175. package/lib/i18n.js +79 -0
  176. package/lib/knowledge/entry-manager.js +208 -0
  177. package/lib/knowledge/index-manager.js +261 -0
  178. package/lib/knowledge/knowledge-manager.js +273 -0
  179. package/lib/knowledge/template-manager.js +191 -0
  180. package/lib/lock/index.js +21 -0
  181. package/lib/lock/lock-file.js +192 -0
  182. package/lib/lock/lock-manager.js +321 -0
  183. package/lib/lock/machine-identifier.js +135 -0
  184. package/lib/lock/steering-file-lock.js +207 -0
  185. package/lib/lock/task-lock-manager.js +345 -0
  186. package/lib/operations/audit-logger.js +293 -0
  187. package/lib/operations/feedback-manager.js +1147 -0
  188. package/lib/operations/index.js +23 -0
  189. package/lib/operations/models/index.js +170 -0
  190. package/lib/operations/operations-manager.js +151 -0
  191. package/lib/operations/operations-validator.js +280 -0
  192. package/lib/operations/permission-manager.js +354 -0
  193. package/lib/operations/template-loader.js +143 -0
  194. package/lib/orchestrator/agent-spawner.js +629 -0
  195. package/lib/orchestrator/bootstrap-prompt-builder.js +236 -0
  196. package/lib/orchestrator/index.js +19 -0
  197. package/lib/orchestrator/orchestration-engine.js +1270 -0
  198. package/lib/orchestrator/orchestrator-config.js +173 -0
  199. package/lib/orchestrator/status-monitor.js +591 -0
  200. package/lib/python-checker.js +209 -0
  201. package/lib/repo/config-manager.js +580 -0
  202. package/lib/repo/errors/config-error.js +13 -0
  203. package/lib/repo/errors/git-error.js +15 -0
  204. package/lib/repo/errors/repo-error.js +14 -0
  205. package/lib/repo/git-operations.js +181 -0
  206. package/lib/repo/handlers/.gitkeep +1 -0
  207. package/lib/repo/handlers/exec-handler.js +155 -0
  208. package/lib/repo/handlers/health-handler.js +169 -0
  209. package/lib/repo/handlers/init-handler.js +197 -0
  210. package/lib/repo/handlers/status-handler.js +176 -0
  211. package/lib/repo/output-formatter.js +184 -0
  212. package/lib/repo/path-resolver.js +178 -0
  213. package/lib/repo/repo-manager.js +514 -0
  214. package/lib/scene-runtime/audit-emitter.js +59 -0
  215. package/lib/scene-runtime/binding-plugin-loader.js +351 -0
  216. package/lib/scene-runtime/binding-registry.js +349 -0
  217. package/lib/scene-runtime/eval-bridge.js +44 -0
  218. package/lib/scene-runtime/index.js +19 -0
  219. package/lib/scene-runtime/moqui-adapter.js +620 -0
  220. package/lib/scene-runtime/moqui-client.js +606 -0
  221. package/lib/scene-runtime/moqui-extractor.js +2029 -0
  222. package/lib/scene-runtime/plan-compiler.js +208 -0
  223. package/lib/scene-runtime/policy-gate.js +58 -0
  224. package/lib/scene-runtime/runtime-executor.js +358 -0
  225. package/lib/scene-runtime/scene-loader.js +96 -0
  226. package/lib/scene-runtime/scene-ontology.js +959 -0
  227. package/lib/scene-runtime/scene-template-linter.js +852 -0
  228. package/lib/scene-runtime/templates/scene-template-erp-query-v0.1.yaml +28 -0
  229. package/lib/scene-runtime/templates/scene-template-hybrid-shadow-v0.1.yaml +34 -0
  230. package/lib/spec/bootstrap/context-collector.js +48 -0
  231. package/lib/spec/bootstrap/draft-generator.js +158 -0
  232. package/lib/spec/bootstrap/questionnaire-engine.js +70 -0
  233. package/lib/spec/bootstrap/trace-emitter.js +59 -0
  234. package/lib/spec/multi-spec-orchestrate.js +93 -0
  235. package/lib/spec/pipeline/constants.js +6 -0
  236. package/lib/spec/pipeline/stage-adapters.js +118 -0
  237. package/lib/spec/pipeline/stage-runner.js +146 -0
  238. package/lib/spec/pipeline/state-store.js +119 -0
  239. package/lib/spec-gate/engine/gate-engine.js +165 -0
  240. package/lib/spec-gate/policy/default-policy.js +22 -0
  241. package/lib/spec-gate/policy/policy-loader.js +103 -0
  242. package/lib/spec-gate/result-emitter.js +81 -0
  243. package/lib/spec-gate/rules/default-rules.js +156 -0
  244. package/lib/spec-gate/rules/rule-registry.js +51 -0
  245. package/lib/steering/adoption-config.js +164 -0
  246. package/lib/steering/compliance-auto-fixer.js +204 -0
  247. package/lib/steering/compliance-cache.js +99 -0
  248. package/lib/steering/compliance-error-reporter.js +70 -0
  249. package/lib/steering/context-sync-manager.js +273 -0
  250. package/lib/steering/index.js +92 -0
  251. package/lib/steering/spec-steering.js +230 -0
  252. package/lib/steering/steering-compliance-checker.js +73 -0
  253. package/lib/steering/steering-loader.js +144 -0
  254. package/lib/steering/steering-manager.js +289 -0
  255. package/lib/task/index.js +12 -0
  256. package/lib/task/task-claimer.js +489 -0
  257. package/lib/task/task-status-store.js +418 -0
  258. package/lib/templates/cache-manager.js +440 -0
  259. package/lib/templates/content-generalizer.js +247 -0
  260. package/lib/templates/frontmatter-generator.js +128 -0
  261. package/lib/templates/git-handler.js +471 -0
  262. package/lib/templates/metadata-collector.js +328 -0
  263. package/lib/templates/path-utils.js +144 -0
  264. package/lib/templates/registry-parser.js +505 -0
  265. package/lib/templates/spec-reader.js +216 -0
  266. package/lib/templates/template-applicator.js +249 -0
  267. package/lib/templates/template-creator.js +256 -0
  268. package/lib/templates/template-error.js +143 -0
  269. package/lib/templates/template-exporter.js +502 -0
  270. package/lib/templates/template-manager.js +782 -0
  271. package/lib/templates/template-validator.js +361 -0
  272. package/lib/upgrade/migration-engine.js +382 -0
  273. package/lib/upgrade/migrations/.gitkeep +52 -0
  274. package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +78 -0
  275. package/lib/utils/file-diff.js +177 -0
  276. package/lib/utils/fs-utils.js +274 -0
  277. package/lib/utils/tool-detector.js +383 -0
  278. package/lib/utils/validation.js +324 -0
  279. package/lib/value/gate-summary-emitter.js +99 -0
  280. package/lib/value/metric-contract-loader.js +210 -0
  281. package/lib/value/risk-evaluator.js +117 -0
  282. package/lib/value/weekly-snapshot-builder.js +61 -0
  283. package/lib/version/version-checker.js +156 -0
  284. package/lib/version/version-manager.js +327 -0
  285. package/lib/watch/action-executor.js +458 -0
  286. package/lib/watch/event-debouncer.js +323 -0
  287. package/lib/watch/execution-logger.js +550 -0
  288. package/lib/watch/file-watcher.js +499 -0
  289. package/lib/watch/presets.js +266 -0
  290. package/lib/watch/watch-manager.js +533 -0
  291. package/lib/workspace/multi/global-config.js +150 -0
  292. package/lib/workspace/multi/index.js +22 -0
  293. package/lib/workspace/multi/path-utils.js +173 -0
  294. package/lib/workspace/multi/workspace-context-resolver.js +244 -0
  295. package/lib/workspace/multi/workspace-registry.js +196 -0
  296. package/lib/workspace/multi/workspace-state-manager.js +537 -0
  297. package/lib/workspace/multi/workspace.js +90 -0
  298. package/lib/workspace/workspace-manager.js +370 -0
  299. package/lib/workspace/workspace-sync.js +356 -0
  300. package/locales/en.json +114 -0
  301. package/locales/zh.json +114 -0
  302. package/package.json +102 -0
  303. package/template/.kiro/README.md +247 -0
  304. package/template/.kiro/hooks/check-spec-on-create.kiro.hook +17 -0
  305. package/template/.kiro/hooks/run-tests-on-save.kiro.hook +13 -0
  306. package/template/.kiro/hooks/sync-tasks-on-edit.kiro.hook +16 -0
  307. package/template/.kiro/specs/SPEC_WORKFLOW_GUIDE.md +134 -0
  308. package/template/.kiro/steering/CORE_PRINCIPLES.md +133 -0
  309. package/template/.kiro/steering/CURRENT_CONTEXT.md +30 -0
  310. package/template/.kiro/steering/ENVIRONMENT.md +35 -0
  311. package/template/.kiro/steering/RULES_GUIDE.md +46 -0
  312. package/template/.kiro/templates/operations/default/change-impact.md +112 -0
  313. package/template/.kiro/templates/operations/default/deployment.md +91 -0
  314. package/template/.kiro/templates/operations/default/feedback-response.md +269 -0
  315. package/template/.kiro/templates/operations/default/migration-plan.md +172 -0
  316. package/template/.kiro/templates/operations/default/monitoring.md +135 -0
  317. package/template/.kiro/templates/operations/default/operations.md +135 -0
  318. package/template/.kiro/templates/operations/default/rollback.md +143 -0
  319. package/template/.kiro/templates/operations/default/tools.yaml +364 -0
  320. package/template/.kiro/templates/operations/default/troubleshooting.md +123 -0
  321. package/template/.kiro/tools/backup_manager.py +295 -0
  322. package/template/.kiro/tools/configuration_manager.py +218 -0
  323. package/template/.kiro/tools/document_evaluator.py +550 -0
  324. package/template/.kiro/tools/enhancement_logger.py +168 -0
  325. package/template/.kiro/tools/error_handler.py +335 -0
  326. package/template/.kiro/tools/improvement_identifier.py +444 -0
  327. package/template/.kiro/tools/modification_applicator.py +737 -0
  328. package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
  329. package/template/.kiro/tools/quality_scorer.py +305 -0
  330. package/template/.kiro/tools/report_generator.py +154 -0
  331. package/template/.kiro/tools/ultrawork_enhancer.py +676 -0
  332. package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
  333. package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
  334. package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
  335. package/template/.kiro/tools/workflow_quality_gate.py +100 -0
  336. package/template/README.md +111 -0
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Diagnostic Engine
3
+ *
4
+ * Scans and analyzes project documentation structure
5
+ */
6
+
7
+ const path = require('path');
8
+ const FileScanner = require('./file-scanner');
9
+ const ConfigManager = require('./config-manager');
10
+
11
+ class DiagnosticEngine {
12
+ constructor(projectPath, config) {
13
+ this.projectPath = projectPath;
14
+ this.config = config;
15
+ this.scanner = new FileScanner(projectPath);
16
+ this.violations = [];
17
+ }
18
+
19
+ /**
20
+ * Run full diagnostic scan
21
+ *
22
+ * @returns {Promise<DiagnosticReport>}
23
+ */
24
+ async scan() {
25
+ this.violations = []; // Reset violations
26
+
27
+ await this.scanRootDirectory();
28
+ await this.scanSpecDirectories();
29
+
30
+ return this.generateReport();
31
+ }
32
+
33
+ /**
34
+ * Scan root directory for violations
35
+ *
36
+ * @returns {Promise<void>}
37
+ */
38
+ async scanRootDirectory() {
39
+ const mdFiles = await this.scanner.findMarkdownFiles(this.projectPath);
40
+ const allowedFiles = this.config.rootAllowedFiles || [];
41
+
42
+ for (const filePath of mdFiles) {
43
+ const basename = path.basename(filePath);
44
+
45
+ if (!allowedFiles.includes(basename)) {
46
+ // Check if it's a temporary document
47
+ const isTemporary = this.scanner.matchesPattern(filePath, this.config.temporaryPatterns || []);
48
+
49
+ this.violations.push({
50
+ type: 'root_violation',
51
+ path: filePath,
52
+ description: `Unexpected markdown file in root directory: ${basename}`,
53
+ severity: isTemporary ? 'warning' : 'error',
54
+ recommendation: isTemporary
55
+ ? `Delete temporary file: ${basename}`
56
+ : `Move ${basename} to appropriate location or delete if temporary`
57
+ });
58
+ }
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Scan all Spec directories
64
+ *
65
+ * @returns {Promise<void>}
66
+ */
67
+ async scanSpecDirectories() {
68
+ const specDirs = await this.scanner.findSpecDirectories();
69
+
70
+ for (const specDir of specDirs) {
71
+ await this.scanSpecDirectory(specDir);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Scan a single Spec directory
77
+ *
78
+ * @param {string} specPath - Path to Spec directory
79
+ * @returns {Promise<void>}
80
+ */
81
+ async scanSpecDirectory(specPath) {
82
+ const specName = path.basename(specPath);
83
+ const requiredFiles = ['requirements.md', 'design.md', 'tasks.md'];
84
+
85
+ // Check for missing required files
86
+ for (const requiredFile of requiredFiles) {
87
+ const filePath = path.join(specPath, requiredFile);
88
+ const exists = await this.scanner.exists(filePath);
89
+
90
+ if (!exists) {
91
+ this.violations.push({
92
+ type: 'missing_required_file',
93
+ path: filePath,
94
+ description: `Missing required file in Spec ${specName}: ${requiredFile}`,
95
+ severity: 'error',
96
+ recommendation: `Create ${requiredFile} in ${specName}`
97
+ });
98
+ }
99
+ }
100
+
101
+ // Check for temporary documents in Spec directory
102
+ const mdFiles = await this.scanner.findMarkdownFiles(specPath);
103
+ const temporaryFiles = this.scanner.matchPatterns(mdFiles, this.config.temporaryPatterns || []);
104
+
105
+ for (const tempFile of temporaryFiles) {
106
+ const basename = path.basename(tempFile);
107
+
108
+ // Don't flag required files as temporary even if they match patterns
109
+ if (!requiredFiles.includes(basename)) {
110
+ this.violations.push({
111
+ type: 'temporary_document',
112
+ path: tempFile,
113
+ description: `Temporary document should be deleted: ${basename}`,
114
+ severity: 'warning',
115
+ recommendation: `Delete temporary file: ${basename} from ${specName}`
116
+ });
117
+ }
118
+ }
119
+
120
+ // Check for misplaced artifacts (files not in subdirectories)
121
+ const allFiles = await this.scanner.getFiles(specPath);
122
+
123
+ for (const filePath of allFiles) {
124
+ const basename = path.basename(filePath);
125
+
126
+ // Skip required files
127
+ if (requiredFiles.includes(basename)) {
128
+ continue;
129
+ }
130
+
131
+ // Skip temporary files (already flagged as temporary_document)
132
+ if (this.scanner.matchesPattern(filePath, this.config.temporaryPatterns || [])) {
133
+ continue;
134
+ }
135
+
136
+ // This is a misplaced artifact
137
+ this.violations.push({
138
+ type: 'misplaced_artifact',
139
+ path: filePath,
140
+ description: `Artifact not in subdirectory: ${basename}`,
141
+ severity: 'warning',
142
+ recommendation: `Move ${basename} to appropriate subdirectory (${this.config.specSubdirs.join(', ')})`
143
+ });
144
+ }
145
+
146
+ // Check subdirectory naming
147
+ const subdirs = await this.scanner.getSubdirectories(specPath);
148
+ const allowedSubdirs = this.config.specSubdirs || [];
149
+
150
+ for (const subdirPath of subdirs) {
151
+ const subdirName = path.basename(subdirPath);
152
+
153
+ // Skip hidden directories
154
+ if (subdirName.startsWith('.')) {
155
+ continue;
156
+ }
157
+
158
+ if (!allowedSubdirs.includes(subdirName)) {
159
+ this.violations.push({
160
+ type: 'invalid_subdirectory',
161
+ path: subdirPath,
162
+ description: `Non-standard subdirectory in Spec ${specName}: ${subdirName}`,
163
+ severity: 'info',
164
+ recommendation: `Rename to one of: ${allowedSubdirs.join(', ')}, or remove if not needed`
165
+ });
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Generate diagnostic report
172
+ *
173
+ * @returns {DiagnosticReport}
174
+ */
175
+ generateReport() {
176
+ const compliant = this.violations.length === 0;
177
+
178
+ return {
179
+ compliant,
180
+ violations: this.violations,
181
+ summary: this.generateSummary(),
182
+ recommendations: this.generateRecommendations()
183
+ };
184
+ }
185
+
186
+ /**
187
+ * Generate summary statistics
188
+ *
189
+ * @returns {Object}
190
+ */
191
+ generateSummary() {
192
+ const summary = {
193
+ totalViolations: this.violations.length,
194
+ byType: {},
195
+ bySeverity: {
196
+ error: 0,
197
+ warning: 0,
198
+ info: 0
199
+ }
200
+ };
201
+
202
+ // Count by type
203
+ for (const violation of this.violations) {
204
+ summary.byType[violation.type] = (summary.byType[violation.type] || 0) + 1;
205
+ summary.bySeverity[violation.severity] = (summary.bySeverity[violation.severity] || 0) + 1;
206
+ }
207
+
208
+ return summary;
209
+ }
210
+
211
+ /**
212
+ * Generate actionable recommendations
213
+ *
214
+ * @returns {string[]}
215
+ */
216
+ generateRecommendations() {
217
+ const recommendations = [];
218
+ const summary = this.generateSummary();
219
+
220
+ // Root violations
221
+ if (summary.byType.root_violation > 0) {
222
+ recommendations.push('Run `kse cleanup` to remove temporary files from root directory');
223
+ }
224
+
225
+ // Temporary documents
226
+ if (summary.byType.temporary_document > 0) {
227
+ recommendations.push('Run `kse cleanup` to remove temporary documents from Spec directories');
228
+ }
229
+
230
+ // Misplaced artifacts
231
+ if (summary.byType.misplaced_artifact > 0) {
232
+ recommendations.push('Run `kse docs archive --spec <spec-name>` to organize artifacts into subdirectories');
233
+ }
234
+
235
+ // Missing required files
236
+ if (summary.byType.missing_required_file > 0) {
237
+ recommendations.push('Create missing required files (requirements.md, design.md, tasks.md) in affected Specs');
238
+ }
239
+
240
+ // Invalid subdirectories
241
+ if (summary.byType.invalid_subdirectory > 0) {
242
+ recommendations.push('Rename non-standard subdirectories to match allowed names');
243
+ }
244
+
245
+ // General recommendation
246
+ if (recommendations.length > 0) {
247
+ recommendations.push('Run `kse validate --all` after fixes to confirm compliance');
248
+ }
249
+
250
+ return recommendations;
251
+ }
252
+ }
253
+
254
+ /**
255
+ * @typedef {Object} DiagnosticReport
256
+ * @property {boolean} compliant - Whether project is compliant
257
+ * @property {Violation[]} violations - List of violations found
258
+ * @property {Object} summary - Summary statistics
259
+ * @property {string[]} recommendations - Actionable recommendations
260
+ */
261
+
262
+ /**
263
+ * @typedef {Object} Violation
264
+ * @property {string} type - Violation type (root_violation, spec_violation, etc.)
265
+ * @property {string} path - File or directory path
266
+ * @property {string} description - Human-readable description
267
+ * @property {string} severity - Severity level (error, warning, info)
268
+ * @property {string} recommendation - How to fix
269
+ */
270
+
271
+ module.exports = DiagnosticEngine;
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Document Reference Checker
3
+ *
4
+ * Checks for incorrect project references and unresolved placeholders in documentation
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+
10
+ class DocReferenceChecker {
11
+ constructor(projectRoot = process.cwd()) {
12
+ this.projectRoot = projectRoot;
13
+
14
+ // Common incorrect references to check
15
+ this.incorrectReferences = [
16
+ '上海图书馆',
17
+ 'MinIO',
18
+ '测试项目',
19
+ '简化测试项目',
20
+ 'Kiro AI-OS'
21
+ ];
22
+
23
+ // Placeholder patterns to check
24
+ this.placeholderPatterns = [
25
+ /\[TODO:.*?\]/g,
26
+ /\[项目名称.*?\]/g,
27
+ /\[请修改.*?\]/g,
28
+ /\[根据项目.*?\]/g
29
+ ];
30
+
31
+ // Files to check
32
+ this.filesToCheck = [
33
+ '.kiro/specs/SPEC_WORKFLOW_GUIDE.md',
34
+ '.kiro/steering/ENVIRONMENT.md',
35
+ '.kiro/steering/CURRENT_CONTEXT.md',
36
+ '.kiro/README.md',
37
+ 'README.md',
38
+ 'package.json'
39
+ ];
40
+ }
41
+
42
+ /**
43
+ * Check all documentation files
44
+ *
45
+ * @returns {Promise<Object>} Check results
46
+ */
47
+ async checkAll() {
48
+ const results = {
49
+ incorrectReferences: [],
50
+ unresolvedPlaceholders: [],
51
+ filesChecked: 0,
52
+ issuesFound: 0
53
+ };
54
+
55
+ for (const file of this.filesToCheck) {
56
+ const filePath = path.join(this.projectRoot, file);
57
+
58
+ if (await fs.pathExists(filePath)) {
59
+ results.filesChecked++;
60
+ const fileResults = await this.checkFile(filePath);
61
+
62
+ if (fileResults.incorrectReferences.length > 0) {
63
+ results.incorrectReferences.push({
64
+ file,
65
+ references: fileResults.incorrectReferences
66
+ });
67
+ results.issuesFound += fileResults.incorrectReferences.length;
68
+ }
69
+
70
+ if (fileResults.unresolvedPlaceholders.length > 0) {
71
+ results.unresolvedPlaceholders.push({
72
+ file,
73
+ placeholders: fileResults.unresolvedPlaceholders
74
+ });
75
+ results.issuesFound += fileResults.unresolvedPlaceholders.length;
76
+ }
77
+ }
78
+ }
79
+
80
+ return results;
81
+ }
82
+
83
+ /**
84
+ * Check a single file
85
+ *
86
+ * @param {string} filePath - Path to file
87
+ * @returns {Promise<Object>} File check results
88
+ */
89
+ async checkFile(filePath) {
90
+ const content = await fs.readFile(filePath, 'utf-8');
91
+ const lines = content.split('\n');
92
+
93
+ const results = {
94
+ incorrectReferences: [],
95
+ unresolvedPlaceholders: []
96
+ };
97
+
98
+ // Check for incorrect references
99
+ lines.forEach((line, index) => {
100
+ this.incorrectReferences.forEach(ref => {
101
+ if (line.includes(ref)) {
102
+ results.incorrectReferences.push({
103
+ line: index + 1,
104
+ content: line.trim(),
105
+ reference: ref
106
+ });
107
+ }
108
+ });
109
+ });
110
+
111
+ // Check for unresolved placeholders (only in non-template files)
112
+ if (!filePath.includes('template/')) {
113
+ lines.forEach((line, index) => {
114
+ this.placeholderPatterns.forEach(pattern => {
115
+ const matches = line.match(pattern);
116
+ if (matches) {
117
+ matches.forEach(match => {
118
+ results.unresolvedPlaceholders.push({
119
+ line: index + 1,
120
+ content: line.trim(),
121
+ placeholder: match
122
+ });
123
+ });
124
+ }
125
+ });
126
+ });
127
+ }
128
+
129
+ return results;
130
+ }
131
+
132
+ /**
133
+ * Generate report
134
+ *
135
+ * @param {Object} results - Check results
136
+ * @returns {string} Formatted report
137
+ */
138
+ generateReport(results) {
139
+ let report = '# Document Reference Check Report\n\n';
140
+ report += `**Date**: ${new Date().toISOString().split('T')[0]}\n`;
141
+ report += `**Files Checked**: ${results.filesChecked}\n`;
142
+ report += `**Issues Found**: ${results.issuesFound}\n\n`;
143
+
144
+ if (results.issuesFound === 0) {
145
+ report += '✅ **No issues found!** All documentation is clean.\n';
146
+ return report;
147
+ }
148
+
149
+ // Incorrect references
150
+ if (results.incorrectReferences.length > 0) {
151
+ report += '## 🔴 Incorrect Project References\n\n';
152
+ results.incorrectReferences.forEach(item => {
153
+ report += `### ${item.file}\n\n`;
154
+ item.references.forEach(ref => {
155
+ report += `- **Line ${ref.line}**: Found "${ref.reference}"\n`;
156
+ report += ` \`\`\`\n ${ref.content}\n \`\`\`\n\n`;
157
+ });
158
+ });
159
+ }
160
+
161
+ // Unresolved placeholders
162
+ if (results.unresolvedPlaceholders.length > 0) {
163
+ report += '## 🟡 Unresolved Placeholders\n\n';
164
+ results.unresolvedPlaceholders.forEach(item => {
165
+ report += `### ${item.file}\n\n`;
166
+ item.placeholders.forEach(ph => {
167
+ report += `- **Line ${ph.line}**: ${ph.placeholder}\n`;
168
+ report += ` \`\`\`\n ${ph.content}\n \`\`\`\n\n`;
169
+ });
170
+ });
171
+ }
172
+
173
+ // Recommendations
174
+ report += '## 💡 Recommendations\n\n';
175
+ if (results.incorrectReferences.length > 0) {
176
+ report += '1. Remove or replace incorrect project references\n';
177
+ report += '2. Ensure all documentation reflects the correct project identity\n';
178
+ }
179
+ if (results.unresolvedPlaceholders.length > 0) {
180
+ report += '3. Replace all [TODO: ...] placeholders with actual project information\n';
181
+ report += '4. Update ENVIRONMENT.md with correct project details\n';
182
+ }
183
+
184
+ return report;
185
+ }
186
+
187
+ /**
188
+ * Save report to file
189
+ *
190
+ * @param {string} report - Report content
191
+ * @param {string} outputPath - Output file path
192
+ * @returns {Promise<void>}
193
+ */
194
+ async saveReport(report, outputPath) {
195
+ await fs.ensureDir(path.dirname(outputPath));
196
+ await fs.writeFile(outputPath, report, 'utf-8');
197
+ }
198
+ }
199
+
200
+ module.exports = DocReferenceChecker;
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Execution Logger
3
+ *
4
+ * Tracks governance tool executions for metrics and reporting
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+
10
+ class ExecutionLogger {
11
+ constructor(projectPath) {
12
+ this.projectPath = projectPath;
13
+ this.logDir = path.join(projectPath, '.kiro', 'logs');
14
+ this.logFile = path.join(this.logDir, 'governance-history.json');
15
+ this.maxLogSize = 10 * 1024 * 1024; // 10MB
16
+ this.maxRotatedLogs = 5;
17
+ }
18
+
19
+ /**
20
+ * Log a governance tool execution
21
+ *
22
+ * @param {string} tool - Tool name (diagnostic, cleanup, validation, archive)
23
+ * @param {string} operation - Operation performed
24
+ * @param {Object} results - Operation results
25
+ * @returns {Promise<void>}
26
+ */
27
+ async logExecution(tool, operation, results) {
28
+ try {
29
+ // Ensure log directory exists
30
+ await fs.ensureDir(this.logDir);
31
+
32
+ // Check if log rotation is needed
33
+ await this.rotateLogIfNeeded();
34
+
35
+ // Create log entry
36
+ const entry = {
37
+ timestamp: new Date().toISOString(),
38
+ tool,
39
+ operation,
40
+ results: this.sanitizeResults(results)
41
+ };
42
+
43
+ // Read existing log or create new array
44
+ let logEntries = [];
45
+ if (await fs.pathExists(this.logFile)) {
46
+ try {
47
+ const content = await fs.readFile(this.logFile, 'utf8');
48
+ logEntries = JSON.parse(content);
49
+
50
+ // Ensure it's an array
51
+ if (!Array.isArray(logEntries)) {
52
+ logEntries = [];
53
+ }
54
+ } catch (error) {
55
+ // If log file is corrupted, start fresh
56
+ console.warn('Log file corrupted, starting fresh');
57
+ logEntries = [];
58
+ }
59
+ }
60
+
61
+ // Append new entry
62
+ logEntries.push(entry);
63
+
64
+ // Write back to file
65
+ await fs.writeFile(this.logFile, JSON.stringify(logEntries, null, 2), 'utf8');
66
+ } catch (error) {
67
+ // Log errors should not break the main operation
68
+ console.error('Failed to log execution:', error.message);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Get execution history
74
+ *
75
+ * @param {Object} options - Filter options
76
+ * @param {string} options.tool - Filter by tool name
77
+ * @param {Date} options.since - Filter by date
78
+ * @param {number} options.limit - Limit number of entries
79
+ * @returns {Promise<Array>}
80
+ */
81
+ async getHistory(options = {}) {
82
+ try {
83
+ // Check if log file exists
84
+ if (!await fs.pathExists(this.logFile)) {
85
+ return [];
86
+ }
87
+
88
+ // Read log file
89
+ const content = await fs.readFile(this.logFile, 'utf8');
90
+ let entries = JSON.parse(content);
91
+
92
+ // Ensure it's an array
93
+ if (!Array.isArray(entries)) {
94
+ return [];
95
+ }
96
+
97
+ // Apply filters
98
+ if (options.tool) {
99
+ entries = entries.filter(entry => entry.tool === options.tool);
100
+ }
101
+
102
+ if (options.since) {
103
+ const sinceTime = options.since.getTime();
104
+ entries = entries.filter(entry => {
105
+ const entryTime = new Date(entry.timestamp).getTime();
106
+ return entryTime >= sinceTime;
107
+ });
108
+ }
109
+
110
+ // Apply limit
111
+ if (options.limit && options.limit > 0) {
112
+ entries = entries.slice(-options.limit);
113
+ }
114
+
115
+ return entries;
116
+ } catch (error) {
117
+ console.error('Failed to read execution history:', error.message);
118
+ return [];
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Rotate log file if it exceeds max size
124
+ *
125
+ * @returns {Promise<void>}
126
+ */
127
+ async rotateLogIfNeeded() {
128
+ try {
129
+ // Check if log file exists
130
+ if (!await fs.pathExists(this.logFile)) {
131
+ return;
132
+ }
133
+
134
+ // Check file size
135
+ const stats = await fs.stat(this.logFile);
136
+
137
+ if (stats.size < this.maxLogSize) {
138
+ return;
139
+ }
140
+
141
+ // Rotate logs
142
+ await this.rotateLog();
143
+ } catch (error) {
144
+ console.error('Failed to check log size:', error.message);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Rotate log file
150
+ *
151
+ * @returns {Promise<void>}
152
+ */
153
+ async rotateLog() {
154
+ try {
155
+ // Remove oldest rotated log if we have max number
156
+ const oldestLog = path.join(this.logDir, `governance-history.${this.maxRotatedLogs}.json`);
157
+ if (await fs.pathExists(oldestLog)) {
158
+ await fs.remove(oldestLog);
159
+ }
160
+
161
+ // Shift existing rotated logs
162
+ for (let i = this.maxRotatedLogs - 1; i >= 1; i--) {
163
+ const currentLog = path.join(this.logDir, `governance-history.${i}.json`);
164
+ const nextLog = path.join(this.logDir, `governance-history.${i + 1}.json`);
165
+
166
+ if (await fs.pathExists(currentLog)) {
167
+ await fs.move(currentLog, nextLog, { overwrite: true });
168
+ }
169
+ }
170
+
171
+ // Rotate current log to .1
172
+ const rotatedLog = path.join(this.logDir, 'governance-history.1.json');
173
+ await fs.move(this.logFile, rotatedLog, { overwrite: true });
174
+
175
+ // Create new empty log
176
+ await fs.writeFile(this.logFile, '[]', 'utf8');
177
+ } catch (error) {
178
+ console.error('Failed to rotate log:', error.message);
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Sanitize results for logging (remove sensitive data, limit size)
184
+ *
185
+ * @param {Object} results - Operation results
186
+ * @returns {Object}
187
+ */
188
+ sanitizeResults(results) {
189
+ // Create a shallow copy
190
+ const sanitized = { ...results };
191
+
192
+ // Limit array sizes to prevent huge logs
193
+ const maxArraySize = 100;
194
+
195
+ if (Array.isArray(sanitized.violations) && sanitized.violations.length > maxArraySize) {
196
+ sanitized.violations = sanitized.violations.slice(0, maxArraySize);
197
+ sanitized.violationsTruncated = true;
198
+ }
199
+
200
+ if (Array.isArray(sanitized.deletedFiles) && sanitized.deletedFiles.length > maxArraySize) {
201
+ sanitized.deletedFiles = sanitized.deletedFiles.slice(0, maxArraySize);
202
+ sanitized.deletedFilesTruncated = true;
203
+ }
204
+
205
+ if (Array.isArray(sanitized.movedFiles) && sanitized.movedFiles.length > maxArraySize) {
206
+ sanitized.movedFiles = sanitized.movedFiles.slice(0, maxArraySize);
207
+ sanitized.movedFilesTruncated = true;
208
+ }
209
+
210
+ if (Array.isArray(sanitized.errors) && sanitized.errors.length > maxArraySize) {
211
+ sanitized.errors = sanitized.errors.slice(0, maxArraySize);
212
+ sanitized.errorsTruncated = true;
213
+ }
214
+
215
+ return sanitized;
216
+ }
217
+
218
+ /**
219
+ * Clear all logs (for testing or reset)
220
+ *
221
+ * @returns {Promise<void>}
222
+ */
223
+ async clearLogs() {
224
+ try {
225
+ // Remove main log file
226
+ if (await fs.pathExists(this.logFile)) {
227
+ await fs.remove(this.logFile);
228
+ }
229
+
230
+ // Remove rotated logs
231
+ for (let i = 1; i <= this.maxRotatedLogs; i++) {
232
+ const rotatedLog = path.join(this.logDir, `governance-history.${i}.json`);
233
+ if (await fs.pathExists(rotatedLog)) {
234
+ await fs.remove(rotatedLog);
235
+ }
236
+ }
237
+ } catch (error) {
238
+ console.error('Failed to clear logs:', error.message);
239
+ }
240
+ }
241
+ }
242
+
243
+ module.exports = ExecutionLogger;