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,156 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const docsCommand = require('../../commands/docs');
4
+
5
+ function createDefaultRules(projectPath = process.cwd()) {
6
+ return [
7
+ {
8
+ id: 'mandatory',
9
+ description: 'Verify mandatory Spec files exist',
10
+ async execute(context) {
11
+ const specPath = path.join(projectPath, '.kiro', 'specs', context.specId);
12
+ const requiredFiles = ['requirements.md', 'design.md', 'tasks.md'];
13
+ const checks = await Promise.all(requiredFiles.map(async fileName => {
14
+ const filePath = path.join(specPath, fileName);
15
+ const exists = await fs.pathExists(filePath);
16
+ return { fileName, exists };
17
+ }));
18
+
19
+ const missing = checks.filter(item => !item.exists).map(item => item.fileName);
20
+ const passRatio = checks.filter(item => item.exists).length / requiredFiles.length;
21
+
22
+ return {
23
+ passed: missing.length === 0,
24
+ ratio: passRatio,
25
+ details: {
26
+ requiredFiles,
27
+ missing
28
+ },
29
+ warnings: missing.length > 0 ? [`Missing files: ${missing.join(', ')}`] : []
30
+ };
31
+ }
32
+ },
33
+ {
34
+ id: 'tests',
35
+ description: 'Verify tasks include explicit validation intent',
36
+ async execute(context) {
37
+ const tasksPath = path.join(projectPath, '.kiro', 'specs', context.specId, 'tasks.md');
38
+ if (!await fs.pathExists(tasksPath)) {
39
+ return {
40
+ passed: false,
41
+ ratio: 0,
42
+ details: { reason: 'tasks.md missing' },
43
+ warnings: ['tasks.md missing']
44
+ };
45
+ }
46
+
47
+ const content = await fs.readFile(tasksPath, 'utf8');
48
+ const hasValidationHints = /验证|Validation|Acceptance/i.test(content);
49
+
50
+ return {
51
+ passed: hasValidationHints,
52
+ ratio: hasValidationHints ? 1 : 0,
53
+ details: {
54
+ hasValidationHints
55
+ },
56
+ warnings: hasValidationHints ? [] : ['No validation markers found in tasks.md']
57
+ };
58
+ }
59
+ },
60
+ {
61
+ id: 'docs',
62
+ description: 'Validate document structure compatibility',
63
+ async execute(context) {
64
+ const exitCode = await docsCommand('validate', {
65
+ spec: context.specId
66
+ });
67
+
68
+ return {
69
+ passed: exitCode === 0,
70
+ ratio: exitCode === 0 ? 1 : 0,
71
+ details: {
72
+ exitCode
73
+ },
74
+ warnings: exitCode === 0 ? [] : [`docs validate returned exit code ${exitCode}`]
75
+ };
76
+ }
77
+ },
78
+ {
79
+ id: 'config_consistency',
80
+ description: 'Verify project-level KSE config baseline exists',
81
+ async execute() {
82
+ const kiroDir = path.join(projectPath, '.kiro');
83
+ const configDir = path.join(kiroDir, 'config');
84
+ const hasKiro = await fs.pathExists(kiroDir);
85
+ const hasConfig = await fs.pathExists(configDir);
86
+
87
+ const ratio = hasKiro && hasConfig ? 1 : hasKiro ? 0.5 : 0;
88
+ const warnings = [];
89
+ if (!hasKiro) {
90
+ warnings.push('.kiro directory missing');
91
+ }
92
+ if (hasKiro && !hasConfig) {
93
+ warnings.push('.kiro/config directory missing');
94
+ }
95
+
96
+ return {
97
+ passed: hasKiro,
98
+ ratio,
99
+ details: {
100
+ hasKiro,
101
+ hasConfig
102
+ },
103
+ warnings
104
+ };
105
+ }
106
+ },
107
+ {
108
+ id: 'traceability',
109
+ description: 'Verify requirement-design-task traceability hints',
110
+ async execute(context) {
111
+ const specPath = path.join(projectPath, '.kiro', 'specs', context.specId);
112
+ const designPath = path.join(specPath, 'design.md');
113
+ const tasksPath = path.join(specPath, 'tasks.md');
114
+
115
+ const hasDesign = await fs.pathExists(designPath);
116
+ const hasTasks = await fs.pathExists(tasksPath);
117
+
118
+ if (!hasDesign || !hasTasks) {
119
+ return {
120
+ passed: false,
121
+ ratio: 0,
122
+ details: {
123
+ hasDesign,
124
+ hasTasks
125
+ },
126
+ warnings: ['design.md or tasks.md missing']
127
+ };
128
+ }
129
+
130
+ const [designContent, tasksContent] = await Promise.all([
131
+ fs.readFile(designPath, 'utf8'),
132
+ fs.readFile(tasksPath, 'utf8')
133
+ ]);
134
+
135
+ const hasMapping = /Mapping|ę˜ å°„|Requirement/i.test(designContent);
136
+ const hasTaskReferences = /Requirement|Design|éœ€ę±‚|设讔/i.test(tasksContent);
137
+ const scoreParts = [hasMapping, hasTaskReferences].filter(Boolean).length;
138
+
139
+ return {
140
+ passed: hasMapping && hasTaskReferences,
141
+ ratio: scoreParts / 2,
142
+ details: {
143
+ hasMapping,
144
+ hasTaskReferences
145
+ },
146
+ warnings: hasMapping && hasTaskReferences ? [] : ['Traceability links are incomplete']
147
+ };
148
+ }
149
+ }
150
+ ];
151
+ }
152
+
153
+ module.exports = {
154
+ createDefaultRules
155
+ };
156
+
@@ -0,0 +1,51 @@
1
+ class RuleRegistry {
2
+ constructor(initialRules = []) {
3
+ this.rules = new Map();
4
+ initialRules.forEach(rule => this.register(rule));
5
+ }
6
+
7
+ register(rule) {
8
+ if (!rule || !rule.id || typeof rule.execute !== 'function') {
9
+ throw new Error('Invalid gate rule: expected id and execute()');
10
+ }
11
+
12
+ this.rules.set(rule.id, rule);
13
+ }
14
+
15
+ setEnabled(ruleId, enabled) {
16
+ const rule = this.rules.get(ruleId);
17
+ if (!rule) {
18
+ throw new Error(`Rule not found: ${ruleId}`);
19
+ }
20
+
21
+ rule.enabled = !!enabled;
22
+ }
23
+
24
+ get(ruleId) {
25
+ return this.rules.get(ruleId);
26
+ }
27
+
28
+ list() {
29
+ return Array.from(this.rules.values());
30
+ }
31
+
32
+ listEnabled(policyRules = {}) {
33
+ return this.list().filter(rule => {
34
+ const policy = policyRules[rule.id];
35
+ if (!policy) {
36
+ return false;
37
+ }
38
+
39
+ if (typeof rule.enabled === 'boolean') {
40
+ return rule.enabled;
41
+ }
42
+
43
+ return policy.enabled !== false;
44
+ });
45
+ }
46
+ }
47
+
48
+ module.exports = {
49
+ RuleRegistry
50
+ };
51
+
@@ -0,0 +1,164 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * AdoptionConfig - 箔理 adoption-config.json é…ē½®ę–‡ä»¶
6
+ *
7
+ * 记录锹目采用 kse ę—¶ēš„é…ē½®é€‰ę‹©
8
+ */
9
+ class AdoptionConfig {
10
+ constructor(projectPath) {
11
+ this.projectPath = projectPath;
12
+ this.configPath = path.join(projectPath, '.kiro', 'adoption-config.json');
13
+ }
14
+
15
+ /**
16
+ * čÆ»å–é…ē½®ę–‡ä»¶
17
+ *
18
+ * @returns {Promise<Object|null>} é…ē½®åÆ¹č±”ļ¼Œå¦‚ęžœäøå­˜åœØåˆ™čæ”å›ž null
19
+ */
20
+ async read() {
21
+ try {
22
+ const exists = await fs.pathExists(this.configPath);
23
+ if (!exists) {
24
+ return null;
25
+ }
26
+
27
+ const content = await fs.readFile(this.configPath, 'utf8');
28
+ return JSON.parse(content);
29
+ } catch (error) {
30
+ console.error(`Error reading adoption config: ${error.message}`);
31
+ return null;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * å†™å…„é…ē½®ę–‡ä»¶
37
+ *
38
+ * @param {Object} config - é…ē½®åÆ¹č±”
39
+ * @returns {Promise<boolean>} 是否成功
40
+ */
41
+ async write(config) {
42
+ try {
43
+ // ē”®äæē›®å½•å­˜åœØ
44
+ await fs.ensureDir(path.dirname(this.configPath));
45
+
46
+ // å†™å…„é…ē½®
47
+ await fs.writeFile(
48
+ this.configPath,
49
+ JSON.stringify(config, null, 2),
50
+ 'utf8'
51
+ );
52
+
53
+ return true;
54
+ } catch (error) {
55
+ console.error(`Error writing adoption config: ${error.message}`);
56
+ return false;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * ꛓꖰ steering ē­–ē•„é…ē½®
62
+ *
63
+ * @param {string} strategy - ē­–ē•„ ('use-kse' | 'use-project')
64
+ * @param {string|null} backupId - 备份 IDļ¼ˆå¦‚ęžœęœ‰ļ¼‰
65
+ * @returns {Promise<boolean>} 是否成功
66
+ */
67
+ async updateSteeringStrategy(strategy, backupId = null) {
68
+ // čÆ»å–ēŽ°ęœ‰é…ē½®
69
+ let config = await this.read();
70
+
71
+ if (!config) {
72
+ // åˆ›å»ŗę–°é…ē½®
73
+ config = {
74
+ version: '1.0.0',
75
+ adoptedAt: new Date().toISOString(),
76
+ multiUserMode: false
77
+ };
78
+ }
79
+
80
+ // ꛓꖰ steering ē­–ē•„
81
+ config.steeringStrategy = strategy;
82
+
83
+ if (backupId) {
84
+ config.steeringBackupId = backupId;
85
+ }
86
+
87
+ config.lastUpdated = new Date().toISOString();
88
+
89
+ // å†™å…„é…ē½®
90
+ return await this.write(config);
91
+ }
92
+
93
+ /**
94
+ * ę›“ę–°å¤šē”Øęˆ·ęØ”å¼é…ē½®
95
+ *
96
+ * @param {boolean} enabled - ę˜Æå¦åÆē”Øå¤šē”Øęˆ·ęØ”å¼
97
+ * @returns {Promise<boolean>} 是否成功
98
+ */
99
+ async updateMultiUserMode(enabled) {
100
+ let config = await this.read();
101
+
102
+ if (!config) {
103
+ config = {
104
+ version: '1.0.0',
105
+ adoptedAt: new Date().toISOString()
106
+ };
107
+ }
108
+
109
+ config.multiUserMode = enabled;
110
+ config.lastUpdated = new Date().toISOString();
111
+
112
+ return await this.write(config);
113
+ }
114
+
115
+ /**
116
+ * čŽ·å– steering ē­–ē•„
117
+ *
118
+ * @returns {Promise<string|null>} ē­–ē•„ęˆ– null
119
+ */
120
+ async getSteeringStrategy() {
121
+ const config = await this.read();
122
+ return config ? config.steeringStrategy : null;
123
+ }
124
+
125
+ /**
126
+ * čŽ·å– steering 备份 ID
127
+ *
128
+ * @returns {Promise<string|null>} 备份 ID ꈖ null
129
+ */
130
+ async getSteeringBackupId() {
131
+ const config = await this.read();
132
+ return config ? config.steeringBackupId : null;
133
+ }
134
+
135
+ /**
136
+ * ę£€ęŸ„ę˜Æå¦åÆē”Øå¤šē”Øęˆ·ęØ”å¼
137
+ *
138
+ * @returns {Promise<boolean>} ę˜Æå¦åÆē”Ø
139
+ */
140
+ async isMultiUserMode() {
141
+ const config = await this.read();
142
+ return config ? (config.multiUserMode || false) : false;
143
+ }
144
+
145
+ /**
146
+ * åˆ›å»ŗåˆå§‹é…ē½®
147
+ *
148
+ * @param {Object} options - é…ē½®é€‰é”¹
149
+ * @returns {Promise<boolean>} 是否成功
150
+ */
151
+ async initialize(options = {}) {
152
+ const config = {
153
+ version: '1.0.0',
154
+ adoptedAt: new Date().toISOString(),
155
+ steeringStrategy: options.steeringStrategy || 'use-kse',
156
+ multiUserMode: options.multiUserMode || false,
157
+ ...options
158
+ };
159
+
160
+ return await this.write(config);
161
+ }
162
+ }
163
+
164
+ module.exports = AdoptionConfig;
@@ -0,0 +1,204 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const chalk = require('chalk');
4
+
5
+ /**
6
+ * Automatically fix steering directory compliance violations
7
+ * by backing up and removing disallowed files and subdirectories
8
+ */
9
+ class ComplianceAutoFixer {
10
+ /**
11
+ * Fix compliance violations automatically (no user confirmation)
12
+ * @param {string} steeringPath - Path to steering directory
13
+ * @param {Array} violations - List of violations from compliance check
14
+ * @returns {Object} Fix result with backup info and cleaned files
15
+ */
16
+ async fix(steeringPath, violations) {
17
+ if (!violations || violations.length === 0) {
18
+ return {
19
+ success: true,
20
+ message: 'No violations to fix',
21
+ backupPath: null,
22
+ cleanedFiles: [],
23
+ cleanedDirs: []
24
+ };
25
+ }
26
+
27
+ // Separate violations by type
28
+ const disallowedFiles = violations
29
+ .filter(v => v.type === 'disallowed_file')
30
+ .map(v => v.name);
31
+ const subdirectories = violations
32
+ .filter(v => v.type === 'subdirectory')
33
+ .map(v => v.name);
34
+
35
+ // Check if this is a multi-user project (contexts/ directory exists)
36
+ const contextsPath = path.join(path.dirname(path.dirname(steeringPath)), 'contexts');
37
+ const isMultiUser = await fs.pathExists(contextsPath);
38
+
39
+ // Show what will be fixed
40
+ console.log(chalk.yellow('\nšŸ”§ Auto-fixing steering directory compliance violations...\n'));
41
+
42
+ if (disallowedFiles.length > 0) {
43
+ console.log(chalk.yellow('Disallowed files to be removed:'));
44
+ disallowedFiles.forEach(file => console.log(` - ${file}`));
45
+ console.log();
46
+ }
47
+
48
+ if (subdirectories.length > 0) {
49
+ console.log(chalk.yellow('Subdirectories to be removed:'));
50
+ subdirectories.forEach(dir => console.log(` - ${dir}/`));
51
+ console.log();
52
+ }
53
+
54
+ // Show multi-user warning if applicable
55
+ if (isMultiUser) {
56
+ console.log(chalk.blue('ā„¹ļø Multi-user project detected'));
57
+ console.log(chalk.blue(' Your personal CURRENT_CONTEXT.md is preserved in contexts/'));
58
+ console.log();
59
+ }
60
+
61
+ // Create backup
62
+ const backupPath = await this._createBackup(steeringPath, disallowedFiles, subdirectories);
63
+ console.log(chalk.green(`āœ“ Backup created: ${backupPath}\n`));
64
+
65
+ // Clean up violations
66
+ const cleanedFiles = [];
67
+ const cleanedDirs = [];
68
+
69
+ // Remove disallowed files
70
+ for (const file of disallowedFiles) {
71
+ const filePath = path.join(steeringPath, file);
72
+ try {
73
+ await fs.remove(filePath);
74
+ cleanedFiles.push(file);
75
+ console.log(chalk.green(`āœ“ Removed file: ${file}`));
76
+ } catch (error) {
77
+ console.error(chalk.red(`āœ— Failed to remove ${file}: ${error.message}`));
78
+ }
79
+ }
80
+
81
+ // Remove subdirectories
82
+ for (const dir of subdirectories) {
83
+ const dirPath = path.join(steeringPath, dir);
84
+ try {
85
+ await fs.remove(dirPath);
86
+ cleanedDirs.push(dir);
87
+ console.log(chalk.green(`āœ“ Removed directory: ${dir}/`));
88
+ } catch (error) {
89
+ console.error(chalk.red(`āœ— Failed to remove ${dir}/: ${error.message}`));
90
+ }
91
+ }
92
+
93
+ console.log(chalk.green('\nāœ“ Steering directory cleaned successfully!\n'));
94
+ console.log(chalk.blue('Backup location:'));
95
+ console.log(` ${backupPath}\n`);
96
+ console.log(chalk.blue('To restore from backup:'));
97
+ console.log(` kse rollback --backup ${path.basename(backupPath)}\n`);
98
+
99
+ return {
100
+ success: true,
101
+ message: 'Steering directory fixed successfully',
102
+ backupPath,
103
+ cleanedFiles,
104
+ cleanedDirs
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Create differential backup of violations only
110
+ * @private
111
+ */
112
+ async _createBackup(steeringPath, files, dirs) {
113
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
114
+ const backupId = `steering-cleanup-${timestamp}`;
115
+ const backupPath = path.join(path.dirname(path.dirname(steeringPath)), 'backups', backupId);
116
+
117
+ // Create backup directory
118
+ await fs.ensureDir(backupPath);
119
+
120
+ // Backup disallowed files
121
+ for (const file of files) {
122
+ const sourcePath = path.join(steeringPath, file);
123
+ const destPath = path.join(backupPath, file);
124
+
125
+ if (await fs.pathExists(sourcePath)) {
126
+ await fs.copy(sourcePath, destPath);
127
+ }
128
+ }
129
+
130
+ // Backup subdirectories
131
+ for (const dir of dirs) {
132
+ const sourcePath = path.join(steeringPath, dir);
133
+ const destPath = path.join(backupPath, dir);
134
+
135
+ if (await fs.pathExists(sourcePath)) {
136
+ await fs.copy(sourcePath, destPath);
137
+ }
138
+ }
139
+
140
+ // Create backup manifest
141
+ const manifest = {
142
+ backupId,
143
+ timestamp: new Date().toISOString(),
144
+ type: 'steering-cleanup',
145
+ steeringPath,
146
+ files,
147
+ directories: dirs,
148
+ totalItems: files.length + dirs.length
149
+ };
150
+
151
+ await fs.writeJson(path.join(backupPath, 'manifest.json'), manifest, { spaces: 2 });
152
+
153
+ return backupPath;
154
+ }
155
+
156
+ /**
157
+ * Restore from backup
158
+ * @param {string} backupPath - Path to backup directory
159
+ * @param {string} steeringPath - Path to steering directory
160
+ */
161
+ async restore(backupPath, steeringPath) {
162
+ // Read manifest
163
+ const manifestPath = path.join(backupPath, 'manifest.json');
164
+ if (!await fs.pathExists(manifestPath)) {
165
+ throw new Error('Invalid backup: manifest.json not found');
166
+ }
167
+
168
+ const manifest = await fs.readJson(manifestPath);
169
+
170
+ console.log(chalk.yellow('\nšŸ”„ Restoring from backup...\n'));
171
+
172
+ // Restore files
173
+ for (const file of manifest.files) {
174
+ const sourcePath = path.join(backupPath, file);
175
+ const destPath = path.join(steeringPath, file);
176
+
177
+ if (await fs.pathExists(sourcePath)) {
178
+ await fs.copy(sourcePath, destPath);
179
+ console.log(chalk.green(`āœ“ Restored file: ${file}`));
180
+ }
181
+ }
182
+
183
+ // Restore directories
184
+ for (const dir of manifest.directories) {
185
+ const sourcePath = path.join(backupPath, dir);
186
+ const destPath = path.join(steeringPath, dir);
187
+
188
+ if (await fs.pathExists(sourcePath)) {
189
+ await fs.copy(sourcePath, destPath);
190
+ console.log(chalk.green(`āœ“ Restored directory: ${dir}/`));
191
+ }
192
+ }
193
+
194
+ console.log(chalk.green('\nāœ“ Restore completed!\n'));
195
+
196
+ return {
197
+ success: true,
198
+ restoredFiles: manifest.files,
199
+ restoredDirs: manifest.directories
200
+ };
201
+ }
202
+ }
203
+
204
+ module.exports = ComplianceAutoFixer;
@@ -0,0 +1,99 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ /**
6
+ * ComplianceCache - Manages version-based check caching
7
+ *
8
+ * Stores the last successful compliance check version to avoid
9
+ * repeated checks for the same kse version.
10
+ */
11
+ class ComplianceCache {
12
+ /**
13
+ * Create a new ComplianceCache instance
14
+ *
15
+ * @param {string} cachePath - Optional custom cache file path
16
+ */
17
+ constructor(cachePath = null) {
18
+ this.cachePath = cachePath || this.getDefaultCachePath();
19
+ }
20
+
21
+ /**
22
+ * Get the default cache file path
23
+ *
24
+ * @returns {string} Path to ~/.kse/steering-check-cache.json
25
+ */
26
+ getDefaultCachePath() {
27
+ const homeDir = os.homedir();
28
+ return path.join(homeDir, '.kse', 'steering-check-cache.json');
29
+ }
30
+
31
+ /**
32
+ * Check if cache is valid for current version
33
+ *
34
+ * @param {string} currentVersion - Current kse version
35
+ * @returns {boolean} True if cache is valid
36
+ */
37
+ isValid(currentVersion) {
38
+ try {
39
+ if (!fs.existsSync(this.cachePath)) {
40
+ return false;
41
+ }
42
+
43
+ const cache = JSON.parse(fs.readFileSync(this.cachePath, 'utf8'));
44
+ return cache.version === currentVersion && cache.lastCheck === 'success';
45
+ } catch (error) {
46
+ // Treat any cache read error as cache miss
47
+ return false;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Update cache with successful check
53
+ *
54
+ * @param {string} version - kse version
55
+ * @returns {boolean} True if update succeeded
56
+ */
57
+ update(version) {
58
+ try {
59
+ const cacheDir = path.dirname(this.cachePath);
60
+
61
+ // Ensure cache directory exists
62
+ if (!fs.existsSync(cacheDir)) {
63
+ fs.mkdirSync(cacheDir, { recursive: true });
64
+ }
65
+
66
+ const cacheData = {
67
+ version,
68
+ timestamp: new Date().toISOString(),
69
+ lastCheck: 'success'
70
+ };
71
+
72
+ fs.writeFileSync(this.cachePath, JSON.stringify(cacheData, null, 2), 'utf8');
73
+ return true;
74
+ } catch (error) {
75
+ // Log error but don't throw - cache write failure is not critical
76
+ console.warn(`Warning: Failed to update compliance cache: ${error.message}`);
77
+ return false;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Clear the cache
83
+ *
84
+ * @returns {boolean} True if clear succeeded
85
+ */
86
+ clear() {
87
+ try {
88
+ if (fs.existsSync(this.cachePath)) {
89
+ fs.unlinkSync(this.cachePath);
90
+ }
91
+ return true;
92
+ } catch (error) {
93
+ console.warn(`Warning: Failed to clear compliance cache: ${error.message}`);
94
+ return false;
95
+ }
96
+ }
97
+ }
98
+
99
+ module.exports = ComplianceCache;