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,73 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * SteeringComplianceChecker - Validates steering directory compliance
6
+ *
7
+ * Ensures the .kiro/steering/ directory contains only allowed files
8
+ * and no subdirectories to prevent context pollution and excessive
9
+ * token consumption in AI sessions.
10
+ */
11
+ class SteeringComplianceChecker {
12
+ /**
13
+ * Get list of allowed files in steering directory
14
+ *
15
+ * @returns {string[]} Array of allowed file names
16
+ */
17
+ getAllowedFiles() {
18
+ return [
19
+ 'CORE_PRINCIPLES.md',
20
+ 'ENVIRONMENT.md',
21
+ 'CURRENT_CONTEXT.md',
22
+ 'RULES_GUIDE.md'
23
+ ];
24
+ }
25
+
26
+ /**
27
+ * Check if steering directory is compliant
28
+ *
29
+ * @param {string} steeringPath - Path to steering directory
30
+ * @returns {ComplianceResult} Result with status and violations
31
+ */
32
+ check(steeringPath) {
33
+ // Non-existent directory is compliant
34
+ if (!fs.existsSync(steeringPath)) {
35
+ return { compliant: true };
36
+ }
37
+
38
+ const violations = [];
39
+ const allowedFiles = this.getAllowedFiles();
40
+
41
+ try {
42
+ const entries = fs.readdirSync(steeringPath, { withFileTypes: true });
43
+
44
+ for (const entry of entries) {
45
+ if (entry.isDirectory()) {
46
+ // Subdirectories are not allowed
47
+ violations.push({
48
+ type: 'subdirectory',
49
+ name: entry.name,
50
+ path: path.join(steeringPath, entry.name)
51
+ });
52
+ } else if (!allowedFiles.includes(entry.name)) {
53
+ // File not in allowlist
54
+ violations.push({
55
+ type: 'disallowed_file',
56
+ name: entry.name,
57
+ path: path.join(steeringPath, entry.name)
58
+ });
59
+ }
60
+ }
61
+
62
+ return {
63
+ compliant: violations.length === 0,
64
+ violations
65
+ };
66
+ } catch (error) {
67
+ // Re-throw unexpected errors
68
+ throw error;
69
+ }
70
+ }
71
+ }
72
+
73
+ module.exports = SteeringComplianceChecker;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * SteeringLoader - 统一加载并合并 L1-L4 四层 Steering 约束
3
+ *
4
+ * L1: CORE_PRINCIPLES.md (通用约束)
5
+ * L2: ENVIRONMENT.md (环境约束)
6
+ * L3: CURRENT_CONTEXT.md (全局上下文)
7
+ * L4: .kiro/specs/{spec-name}/steering.md (Spec 级约束, via SpecSteering)
8
+ *
9
+ * 单 Agent 模式下跳过 L4。
10
+ *
11
+ * Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 6.4
12
+ */
13
+
14
+ const path = require('path');
15
+ const fs = require('fs-extra');
16
+ const { SpecSteering } = require('./spec-steering');
17
+ const { MultiAgentConfig } = require('../collab/multi-agent-config');
18
+
19
+ const STEERING_DIR = '.kiro/steering';
20
+
21
+ const LAYER_FILES = {
22
+ l1: 'CORE_PRINCIPLES.md',
23
+ l2: 'ENVIRONMENT.md',
24
+ l3: 'CURRENT_CONTEXT.md',
25
+ };
26
+
27
+ class SteeringLoader {
28
+ /**
29
+ * @param {string} workspaceRoot - Absolute path to the project root
30
+ */
31
+ constructor(workspaceRoot) {
32
+ this._workspaceRoot = workspaceRoot;
33
+ this._specSteering = new SpecSteering(workspaceRoot);
34
+ this._multiAgentConfig = new MultiAgentConfig(workspaceRoot);
35
+ }
36
+
37
+ /**
38
+ * 加载所有层级的 Steering 内容。
39
+ * 单 Agent 模式下跳过 L4。
40
+ *
41
+ * @param {string|null} specName - 当前 Spec 名称,null 时跳过 L4
42
+ * @returns {Promise<{
43
+ * l1: string|null,
44
+ * l2: string|null,
45
+ * l3: string|null,
46
+ * l4: {constraints: string[], notes: string[], decisions: string[]}|null
47
+ * }>}
48
+ */
49
+ async load(specName = null) {
50
+ const [l1, l2, l3] = await Promise.all([
51
+ this._loadLayerFile('l1'),
52
+ this._loadLayerFile('l2'),
53
+ this._loadLayerFile('l3'),
54
+ ]);
55
+
56
+ let l4 = null;
57
+ if (specName) {
58
+ const enabled = await this._multiAgentConfig.isEnabled();
59
+ if (enabled) {
60
+ l4 = await this._loadL4(specName);
61
+ }
62
+ }
63
+
64
+ return { l1, l2, l3, l4 };
65
+ }
66
+
67
+ /**
68
+ * 加载并合并所有层级,L4 覆盖 L1-L3 的冲突项。
69
+ * L4 内容追加在最后,使其优先级最高。
70
+ *
71
+ * @param {string|null} specName
72
+ * @returns {Promise<{layers: object, merged: string}>}
73
+ */
74
+ async loadMerged(specName = null) {
75
+ const layers = await this.load(specName);
76
+ const parts = [];
77
+
78
+ if (layers.l1) {
79
+ parts.push(layers.l1);
80
+ }
81
+ if (layers.l2) {
82
+ parts.push(layers.l2);
83
+ }
84
+ if (layers.l3) {
85
+ parts.push(layers.l3);
86
+ }
87
+ if (layers.l4) {
88
+ parts.push(this._formatL4(layers.l4));
89
+ }
90
+
91
+ return {
92
+ layers,
93
+ merged: parts.join('\n\n---\n\n'),
94
+ };
95
+ }
96
+
97
+ // ── Private helpers ──────────────────────────────────────────────
98
+
99
+ /**
100
+ * Load a L1/L2/L3 layer file. Returns null if the file doesn't exist.
101
+ * @param {'l1'|'l2'|'l3'} layerKey
102
+ * @returns {Promise<string|null>}
103
+ */
104
+ async _loadLayerFile(layerKey) {
105
+ const filename = LAYER_FILES[layerKey];
106
+ const filePath = path.join(this._workspaceRoot, STEERING_DIR, filename);
107
+
108
+ try {
109
+ const exists = await fs.pathExists(filePath);
110
+ if (!exists) {
111
+ return null;
112
+ }
113
+ return await fs.readFile(filePath, 'utf8');
114
+ } catch (err) {
115
+ console.warn(`[SteeringLoader] Failed to read ${layerKey} (${filename}): ${err.message}`);
116
+ return null;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Load L4 via SpecSteering. Returns null if the file doesn't exist or is corrupted.
122
+ * @param {string} specName
123
+ * @returns {Promise<{constraints: string[], notes: string[], decisions: string[]}|null>}
124
+ */
125
+ async _loadL4(specName) {
126
+ try {
127
+ return await this._specSteering.read(specName);
128
+ } catch (err) {
129
+ console.warn(`[SteeringLoader] Failed to read L4 for ${specName}: ${err.message}`);
130
+ return null;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Format L4 structured object back to a Markdown string for merging.
136
+ * @param {{constraints: string[], notes: string[], decisions: string[]}} l4
137
+ * @returns {string}
138
+ */
139
+ _formatL4(l4) {
140
+ return this._specSteering.format(l4);
141
+ }
142
+ }
143
+
144
+ module.exports = { SteeringLoader };
@@ -0,0 +1,289 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const inquirer = require('inquirer');
4
+
5
+ /**
6
+ * SteeringManager - 管理 Steering 文件的独占使用
7
+ *
8
+ * 负责检测、备份、安装和恢复 steering 文件
9
+ */
10
+ class SteeringManager {
11
+ constructor() {
12
+ this.steeringDir = '.kiro/steering';
13
+ this.backupBaseDir = '.kiro/backups';
14
+ }
15
+
16
+ /**
17
+ * 检测项目中的 steering 文件
18
+ *
19
+ * @param {string} projectPath - 项目根目录路径
20
+ * @returns {Promise<Object>} 检测结果
21
+ */
22
+ async detectSteering(projectPath) {
23
+ const steeringPath = path.join(projectPath, this.steeringDir);
24
+
25
+ // 检查 steering 目录是否存在
26
+ const exists = await fs.pathExists(steeringPath);
27
+
28
+ if (!exists) {
29
+ return {
30
+ hasExistingSteering: false,
31
+ files: [],
32
+ path: steeringPath
33
+ };
34
+ }
35
+
36
+ // 读取 steering 目录中的文件
37
+ const files = await fs.readdir(steeringPath);
38
+
39
+ // 过滤出 .md 文件
40
+ const mdFiles = files.filter(f => f.endsWith('.md'));
41
+
42
+ // 获取文件详细信息
43
+ const fileDetails = await Promise.all(
44
+ mdFiles.map(async (file) => {
45
+ const filePath = path.join(steeringPath, file);
46
+ const stats = await fs.stat(filePath);
47
+ return {
48
+ name: file,
49
+ path: filePath,
50
+ size: stats.size,
51
+ modified: stats.mtime
52
+ };
53
+ })
54
+ );
55
+
56
+ return {
57
+ hasExistingSteering: mdFiles.length > 0,
58
+ files: fileDetails,
59
+ path: steeringPath,
60
+ count: mdFiles.length
61
+ };
62
+ }
63
+
64
+ /**
65
+ * 提示用户选择 steering 策略
66
+ *
67
+ * @param {Object} detection - detectSteering 的返回结果
68
+ * @returns {Promise<string>} 选择的策略 ('use-kse' | 'use-project')
69
+ */
70
+ async promptStrategy(detection) {
71
+ if (!detection.hasExistingSteering) {
72
+ // 没有现有 steering 文件,默认使用 kse
73
+ return 'use-kse';
74
+ }
75
+
76
+ console.log('\n⚠️ Steering Conflict Detected');
77
+ console.log('━'.repeat(60));
78
+ console.log(`Found ${detection.count} existing steering file(s) in ${this.steeringDir}:`);
79
+ console.log('');
80
+
81
+ detection.files.forEach(file => {
82
+ console.log(` • ${file.name} (${(file.size / 1024).toFixed(1)} KB)`);
83
+ });
84
+
85
+ console.log('');
86
+ console.log('Kiro IDE loads all files in .kiro/steering/, which means you must');
87
+ console.log('choose between kse steering rules OR your project\'s existing rules.');
88
+ console.log('');
89
+
90
+ const response = await inquirer.prompt([{
91
+ type: 'list',
92
+ name: 'strategy',
93
+ message: 'How would you like to proceed?',
94
+ choices: [
95
+ {
96
+ name: 'Use kse steering (backup existing files) - Recommended for new kse users',
97
+ value: 'use-kse'
98
+ },
99
+ {
100
+ name: 'Keep existing steering (skip kse steering) - For projects with custom steering rules',
101
+ value: 'use-project'
102
+ }
103
+ ]
104
+ }]);
105
+
106
+ return response.strategy;
107
+ }
108
+
109
+ /**
110
+ * 备份现有的 steering 文件
111
+ *
112
+ * @param {string} projectPath - 项目根目录路径
113
+ * @returns {Promise<Object>} 备份结果
114
+ */
115
+ async backupSteering(projectPath) {
116
+ const steeringPath = path.join(projectPath, this.steeringDir);
117
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
118
+ const backupId = `steering-${timestamp}`;
119
+ const backupPath = path.join(projectPath, this.backupBaseDir, backupId);
120
+
121
+ // 检查 steering 目录是否存在
122
+ const exists = await fs.pathExists(steeringPath);
123
+ if (!exists) {
124
+ return {
125
+ success: false,
126
+ error: 'Steering directory does not exist',
127
+ backupId: null,
128
+ backupPath: null
129
+ };
130
+ }
131
+
132
+ try {
133
+ // 创建备份目录
134
+ await fs.ensureDir(backupPath);
135
+
136
+ // 复制所有文件
137
+ await fs.copy(steeringPath, backupPath, {
138
+ overwrite: false,
139
+ errorOnExist: false
140
+ });
141
+
142
+ // 验证备份
143
+ const backupFiles = await fs.readdir(backupPath);
144
+ const originalFiles = await fs.readdir(steeringPath);
145
+
146
+ return {
147
+ success: true,
148
+ backupId,
149
+ backupPath,
150
+ filesBackedUp: backupFiles.length,
151
+ timestamp,
152
+ verified: backupFiles.length === originalFiles.length
153
+ };
154
+ } catch (error) {
155
+ return {
156
+ success: false,
157
+ error: error.message,
158
+ backupId,
159
+ backupPath
160
+ };
161
+ }
162
+ }
163
+
164
+ /**
165
+ * 安装 kse steering 文件
166
+ *
167
+ * @param {string} projectPath - 项目根目录路径
168
+ * @returns {Promise<Object>} 安装结果
169
+ */
170
+ async installKseSteering(projectPath) {
171
+ const steeringPath = path.join(projectPath, this.steeringDir);
172
+ const templatePath = path.join(__dirname, '../../template/.kiro/steering');
173
+
174
+ try {
175
+ // 确保 steering 目录存在
176
+ await fs.ensureDir(steeringPath);
177
+
178
+ // 检查模板目录是否存在
179
+ const templateExists = await fs.pathExists(templatePath);
180
+ if (!templateExists) {
181
+ return {
182
+ success: false,
183
+ error: 'kse steering template directory not found',
184
+ filesInstalled: 0
185
+ };
186
+ }
187
+
188
+ // 复制模板文件
189
+ const templateFiles = await fs.readdir(templatePath);
190
+ const mdFiles = templateFiles.filter(f => f.endsWith('.md'));
191
+
192
+ let installedCount = 0;
193
+ for (const file of mdFiles) {
194
+ const srcPath = path.join(templatePath, file);
195
+ const destPath = path.join(steeringPath, file);
196
+
197
+ await fs.copy(srcPath, destPath, {
198
+ overwrite: true
199
+ });
200
+ installedCount++;
201
+ }
202
+
203
+ return {
204
+ success: true,
205
+ filesInstalled: installedCount,
206
+ files: mdFiles
207
+ };
208
+ } catch (error) {
209
+ return {
210
+ success: false,
211
+ error: error.message,
212
+ filesInstalled: 0
213
+ };
214
+ }
215
+ }
216
+
217
+ /**
218
+ * 从备份恢复 steering 文件
219
+ *
220
+ * @param {string} projectPath - 项目根目录路径
221
+ * @param {string} backupId - 备份 ID
222
+ * @returns {Promise<Object>} 恢复结果
223
+ */
224
+ async restoreSteering(projectPath, backupId) {
225
+ const steeringPath = path.join(projectPath, this.steeringDir);
226
+ const backupPath = path.join(projectPath, this.backupBaseDir, backupId);
227
+
228
+ // 检查备份是否存在
229
+ const backupExists = await fs.pathExists(backupPath);
230
+ if (!backupExists) {
231
+ return {
232
+ success: false,
233
+ error: `Backup not found: ${backupId}`,
234
+ filesRestored: 0
235
+ };
236
+ }
237
+
238
+ try {
239
+ // 清空现有 steering 目录
240
+ await fs.emptyDir(steeringPath);
241
+
242
+ // 从备份恢复
243
+ await fs.copy(backupPath, steeringPath, {
244
+ overwrite: true
245
+ });
246
+
247
+ // 验证恢复
248
+ const restoredFiles = await fs.readdir(steeringPath);
249
+
250
+ return {
251
+ success: true,
252
+ filesRestored: restoredFiles.length,
253
+ backupId,
254
+ files: restoredFiles
255
+ };
256
+ } catch (error) {
257
+ return {
258
+ success: false,
259
+ error: error.message,
260
+ filesRestored: 0,
261
+ backupId
262
+ };
263
+ }
264
+ }
265
+
266
+ /**
267
+ * 列出所有可用的 steering 备份
268
+ *
269
+ * @param {string} projectPath - 项目根目录路径
270
+ * @returns {Promise<Array>} 备份列表
271
+ */
272
+ async listBackups(projectPath) {
273
+ const backupBasePath = path.join(projectPath, this.backupBaseDir);
274
+
275
+ const exists = await fs.pathExists(backupBasePath);
276
+ if (!exists) {
277
+ return [];
278
+ }
279
+
280
+ const entries = await fs.readdir(backupBasePath, { withFileTypes: true });
281
+ const steeringBackups = entries
282
+ .filter(entry => entry.isDirectory() && entry.name.startsWith('steering-'))
283
+ .map(entry => entry.name);
284
+
285
+ return steeringBackups;
286
+ }
287
+ }
288
+
289
+ module.exports = SteeringManager;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Task module exports
3
+ * @module lib/task
4
+ */
5
+
6
+ const TaskClaimer = require('./task-claimer');
7
+ const { TaskStatusStore } = require('./task-status-store');
8
+
9
+ module.exports = {
10
+ TaskClaimer,
11
+ TaskStatusStore
12
+ };