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,446 @@
1
+ /**
2
+ * CLI commands for Agent Orchestration
3
+ *
4
+ * Provides `kse orchestrate run|status|stop` subcommands for managing
5
+ * parallel Spec execution via Codex CLI sub-agents.
6
+ *
7
+ * Requirements: 6.1 (run), 6.2 (status), 6.3 (stop), 6.4 (spec validation), 6.5 (maxParallel validation)
8
+ */
9
+
10
+ const chalk = require('chalk');
11
+ const path = require('path');
12
+ const fs = require('fs-extra');
13
+
14
+ const SPECS_DIR = '.kiro/specs';
15
+ const STATUS_FILE = '.kiro/config/orchestration-status.json';
16
+
17
+ /**
18
+ * Run orchestration programmatically.
19
+ *
20
+ * @param {object} options
21
+ * @param {string} [options.specs] - Comma separated spec names
22
+ * @param {string[]} [options.specNames] - Explicit spec names array
23
+ * @param {number} [options.maxParallel]
24
+ * @param {boolean} [options.json]
25
+ * @param {boolean} [options.silent]
26
+ * @param {object} dependencies
27
+ * @param {string} [dependencies.workspaceRoot]
28
+ * @returns {Promise<object>}
29
+ */
30
+ async function runOrchestration(options = {}, dependencies = {}) {
31
+ const workspaceRoot = dependencies.workspaceRoot || process.cwd();
32
+ const specNames = Array.isArray(options.specNames)
33
+ ? options.specNames.map(name => `${name}`.trim()).filter(Boolean)
34
+ : _parseSpecNamesOption(options.specs);
35
+
36
+ if (specNames.length === 0) {
37
+ throw new Error('No specs specified');
38
+ }
39
+
40
+ const maxParallel = options.maxParallel;
41
+ if (maxParallel !== undefined && (isNaN(maxParallel) || maxParallel < 1)) {
42
+ throw new Error('--max-parallel must be >= 1');
43
+ }
44
+
45
+ const missing = await _validateSpecs(workspaceRoot, specNames);
46
+ if (missing.length > 0) {
47
+ throw new Error(`Specs not found: ${missing.join(', ')}`);
48
+ }
49
+
50
+ const { OrchestratorConfig } = require('../orchestrator/orchestrator-config');
51
+ const { BootstrapPromptBuilder } = require('../orchestrator/bootstrap-prompt-builder');
52
+ const { AgentSpawner } = require('../orchestrator/agent-spawner');
53
+ const { StatusMonitor } = require('../orchestrator/status-monitor');
54
+ const { OrchestrationEngine } = require('../orchestrator/orchestration-engine');
55
+
56
+ const DependencyManager = require('../collab/dependency-manager');
57
+ const MetadataManager = require('../collab/metadata-manager');
58
+ const { AgentRegistry } = require('../collab/agent-registry');
59
+ const { SpecLifecycleManager } = require('../collab/spec-lifecycle-manager');
60
+ const { MachineIdentifier } = require('../lock/machine-identifier');
61
+
62
+ let contextSyncManager = null;
63
+ try {
64
+ const { ContextSyncManager } = require('../steering/context-sync-manager');
65
+ contextSyncManager = new ContextSyncManager(workspaceRoot);
66
+ } catch (_err) {
67
+ // Non-fatal — status sync will be skipped
68
+ }
69
+
70
+ const orchestratorConfig = new OrchestratorConfig(workspaceRoot);
71
+ const config = await orchestratorConfig.getConfig();
72
+ const effectiveMaxParallel = maxParallel || config.maxParallel;
73
+
74
+ const bootstrapPromptBuilder = new BootstrapPromptBuilder(workspaceRoot, orchestratorConfig);
75
+ const machineIdentifier = new MachineIdentifier(
76
+ path.join(workspaceRoot, '.kiro', 'config')
77
+ );
78
+ const agentRegistry = new AgentRegistry(workspaceRoot, machineIdentifier);
79
+ const agentSpawner = new AgentSpawner(
80
+ workspaceRoot, orchestratorConfig, agentRegistry, bootstrapPromptBuilder
81
+ );
82
+ const metadataManager = new MetadataManager(workspaceRoot);
83
+ const dependencyManager = new DependencyManager(metadataManager);
84
+ const specLifecycleManager = new SpecLifecycleManager(
85
+ workspaceRoot, contextSyncManager, agentRegistry
86
+ );
87
+ const statusMonitor = new StatusMonitor(specLifecycleManager, contextSyncManager);
88
+
89
+ const engine = new OrchestrationEngine(workspaceRoot, {
90
+ agentSpawner,
91
+ dependencyManager,
92
+ specLifecycleManager,
93
+ statusMonitor,
94
+ orchestratorConfig,
95
+ agentRegistry,
96
+ });
97
+
98
+ if (!options.silent && !options.json) {
99
+ console.log(
100
+ chalk.blue('🚀'),
101
+ `Starting orchestration for ${specNames.length} spec(s) (max-parallel: ${effectiveMaxParallel})...`
102
+ );
103
+ }
104
+
105
+ const statusIntervalMs = Number.isInteger(options.statusIntervalMs) && options.statusIntervalMs > 0
106
+ ? options.statusIntervalMs
107
+ : 1000;
108
+
109
+ let statusWriteChain = Promise.resolve();
110
+ const persistStatus = () => {
111
+ const statusSnapshot = engine.getStatus();
112
+ statusWriteChain = statusWriteChain.then(async () => {
113
+ await _writeStatus(workspaceRoot, statusSnapshot);
114
+ if (typeof options.onStatus === 'function') {
115
+ await Promise.resolve(options.onStatus(statusSnapshot));
116
+ }
117
+ }).catch(() => {});
118
+ return statusWriteChain;
119
+ };
120
+
121
+ const statusEvents = [
122
+ 'batch:start',
123
+ 'batch:complete',
124
+ 'spec:start',
125
+ 'spec:complete',
126
+ 'spec:failed',
127
+ 'spec:rate-limited',
128
+ 'launch:budget-hold',
129
+ 'parallel:throttled',
130
+ 'parallel:recovered',
131
+ 'orchestration:complete'
132
+ ];
133
+
134
+ for (const eventName of statusEvents) {
135
+ engine.on(eventName, () => {
136
+ void persistStatus();
137
+ });
138
+ }
139
+
140
+ const statusTimer = setInterval(() => {
141
+ void persistStatus();
142
+ }, statusIntervalMs);
143
+ if (typeof statusTimer.unref === 'function') {
144
+ statusTimer.unref();
145
+ }
146
+
147
+ let result;
148
+ try {
149
+ result = await engine.start(specNames, { maxParallel: effectiveMaxParallel });
150
+ } finally {
151
+ clearInterval(statusTimer);
152
+ await persistStatus();
153
+ await statusWriteChain;
154
+ }
155
+
156
+ const finalStatus = engine.getStatus();
157
+ if (result && typeof result === 'object' && finalStatus && typeof finalStatus === 'object') {
158
+ if (finalStatus.rateLimit && typeof finalStatus.rateLimit === 'object') {
159
+ result.rateLimit = { ...finalStatus.rateLimit };
160
+ }
161
+ if (finalStatus.parallel && typeof finalStatus.parallel === 'object') {
162
+ result.parallel = { ...finalStatus.parallel };
163
+ }
164
+ }
165
+
166
+ if (!options.silent) {
167
+ if (options.json) {
168
+ console.log(JSON.stringify(result, null, 2));
169
+ } else {
170
+ _printResult(result);
171
+ }
172
+ }
173
+
174
+ return result;
175
+ }
176
+
177
+ /**
178
+ * Register orchestrate commands on the given Commander program.
179
+ * @param {import('commander').Command} program
180
+ */
181
+ function registerOrchestrateCommands(program) {
182
+ const orchestrate = program
183
+ .command('orchestrate')
184
+ .description('Manage agent orchestration for parallel Spec execution');
185
+
186
+ // ── kse orchestrate run ──────────────────────────────────────────
187
+ orchestrate
188
+ .command('run')
189
+ .description('Start orchestration for specified Specs')
190
+ .requiredOption('--specs <specs>', 'Comma-separated list of Spec names')
191
+ .option('--max-parallel <n>', 'Maximum parallel agents', parseInt)
192
+ .option('--json', 'Output in JSON format')
193
+ .action(async (options) => {
194
+ try {
195
+ const result = await runOrchestration(options);
196
+
197
+ if (result.status === 'failed') {
198
+ process.exit(1);
199
+ }
200
+ } catch (err) {
201
+ _errorAndExit(err.message, options.json);
202
+ }
203
+ });
204
+
205
+ // ── kse orchestrate status ───────────────────────────────────────
206
+ orchestrate
207
+ .command('status')
208
+ .description('Show current orchestration status')
209
+ .option('--json', 'Output in JSON format')
210
+ .action(async (options) => {
211
+ try {
212
+ const workspaceRoot = process.cwd();
213
+ const status = await _readStatus(workspaceRoot);
214
+
215
+ if (!status) {
216
+ if (options.json) {
217
+ console.log(JSON.stringify({ status: 'idle', message: 'No orchestration data found' }));
218
+ } else {
219
+ console.log(chalk.gray('No orchestration data found. Run `kse orchestrate run` first.'));
220
+ }
221
+ return;
222
+ }
223
+
224
+ if (options.json) {
225
+ console.log(JSON.stringify(status, null, 2));
226
+ } else {
227
+ _printStatus(status);
228
+ }
229
+ } catch (err) {
230
+ _errorAndExit(err.message, options.json);
231
+ }
232
+ });
233
+
234
+ // ── kse orchestrate stop ─────────────────────────────────────────
235
+ orchestrate
236
+ .command('stop')
237
+ .description('Stop all running agents')
238
+ .action(async () => {
239
+ try {
240
+ const workspaceRoot = process.cwd();
241
+ const status = await _readStatus(workspaceRoot);
242
+
243
+ if (!status || status.status !== 'running') {
244
+ console.log(chalk.gray('No running orchestration to stop.'));
245
+ return;
246
+ }
247
+
248
+ // Write a stop signal into the status file
249
+ status.status = 'stopped';
250
+ status.completedAt = new Date().toISOString();
251
+ await _writeStatus(workspaceRoot, status);
252
+
253
+ console.log(chalk.yellow('⏹'), 'Stop signal sent. Running agents will be terminated.');
254
+ } catch (err) {
255
+ console.error(chalk.red('Error:'), err.message);
256
+ process.exit(1);
257
+ }
258
+ });
259
+ }
260
+
261
+ // ── Helpers ──────────────────────────────────────────────────────────
262
+
263
+ /**
264
+ * Validate that all spec directories exist.
265
+ * @param {string} workspaceRoot
266
+ * @param {string[]} specNames
267
+ * @returns {Promise<string[]>} Missing spec names
268
+ */
269
+ async function _validateSpecs(workspaceRoot, specNames) {
270
+ const missing = [];
271
+ for (const name of specNames) {
272
+ const specDir = path.join(workspaceRoot, SPECS_DIR, name);
273
+ const exists = await fs.pathExists(specDir);
274
+ if (!exists) {
275
+ missing.push(name);
276
+ }
277
+ }
278
+ return missing;
279
+ }
280
+
281
+ /**
282
+ * Read persisted orchestration status.
283
+ * @param {string} workspaceRoot
284
+ * @returns {Promise<object|null>}
285
+ */
286
+ async function _readStatus(workspaceRoot) {
287
+ const statusPath = path.join(workspaceRoot, STATUS_FILE);
288
+ try {
289
+ return await fs.readJson(statusPath);
290
+ } catch (_err) {
291
+ return null;
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Persist orchestration status to disk.
297
+ * @param {string} workspaceRoot
298
+ * @param {object} status
299
+ */
300
+ async function _writeStatus(workspaceRoot, status) {
301
+ const statusPath = path.join(workspaceRoot, STATUS_FILE);
302
+ await fs.ensureDir(path.dirname(statusPath));
303
+ await fs.writeJson(statusPath, status, { spaces: 2 });
304
+ }
305
+
306
+ /**
307
+ * Print a human-readable orchestration result.
308
+ * @param {object} result
309
+ */
310
+ function _printResult(result) {
311
+ const icon = result.status === 'completed' ? chalk.green('✓') : chalk.red('✗');
312
+ console.log(`${icon} Orchestration ${result.status}`);
313
+ if (result.totalSpecs !== undefined) {
314
+ console.log(chalk.gray(` Total: ${result.totalSpecs} Completed: ${result.completedSpecs} Failed: ${result.failedSpecs}`));
315
+ }
316
+ if (result.specs) {
317
+ for (const [name, info] of Object.entries(result.specs)) {
318
+ const sym = _statusSymbol(info.status);
319
+ const extra = info.error ? chalk.gray(` — ${info.error}`) : '';
320
+ console.log(` ${sym} ${name}${extra}`);
321
+ }
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Print a human-readable orchestration status.
327
+ * @param {object} status
328
+ */
329
+ function _printStatus(status) {
330
+ console.log(chalk.bold('Orchestration Status'));
331
+ console.log(chalk.gray('===================='));
332
+ console.log(`Status: ${_statusSymbol(status.status)} ${status.status}`);
333
+ if (status.totalSpecs !== undefined) {
334
+ console.log(`Total: ${status.totalSpecs} Completed: ${status.completedSpecs || 0} Failed: ${status.failedSpecs || 0} Running: ${status.runningSpecs || 0}`);
335
+ }
336
+ if (status.currentBatch !== undefined && status.totalBatches !== undefined) {
337
+ console.log(`Batch: ${status.currentBatch} / ${status.totalBatches}`);
338
+ }
339
+ if (status.parallel) {
340
+ const effective = status.parallel.effectiveMaxParallel ?? '-';
341
+ const max = status.parallel.maxParallel ?? '-';
342
+ const adaptive = status.parallel.adaptive === false ? 'off' : 'on';
343
+ console.log(`Parallel: ${effective} / ${max} (adaptive: ${adaptive})`);
344
+ }
345
+ if (status.rateLimit) {
346
+ const signals = status.rateLimit.signalCount || 0;
347
+ const backoff = status.rateLimit.totalBackoffMs || 0;
348
+ console.log(`Rate-limit: ${signals} signal(s), total backoff ${backoff}ms`);
349
+
350
+ const holdWindowMs = Number(status.rateLimit.lastLaunchHoldMs) || 0;
351
+ const lastSignalAtMs = Date.parse(status.rateLimit.lastSignalAt || '');
352
+ const elapsedSinceSignalMs = Number.isFinite(lastSignalAtMs)
353
+ ? Math.max(0, Date.now() - lastSignalAtMs)
354
+ : Infinity;
355
+ const holdRemainingMs = holdWindowMs > 0
356
+ ? Math.max(0, holdWindowMs - elapsedSinceSignalMs)
357
+ : 0;
358
+ if (holdRemainingMs > 0) {
359
+ console.log(`Rate-limit launch hold: ${holdRemainingMs}ms remaining`);
360
+ }
361
+
362
+ const launchBudgetPerMinute = Number(status.rateLimit.launchBudgetPerMinute);
363
+ if (Number.isFinite(launchBudgetPerMinute) && launchBudgetPerMinute > 0) {
364
+ const launchBudgetWindowMs = Number(status.rateLimit.launchBudgetWindowMs) || 60000;
365
+ const launchBudgetUsed = Number(status.rateLimit.launchBudgetUsed) || 0;
366
+ const launchBudgetHoldCount = Number(status.rateLimit.launchBudgetHoldCount) || 0;
367
+ console.log(
368
+ `Launch budget: ${launchBudgetUsed}/${launchBudgetPerMinute} in ${launchBudgetWindowMs}ms (holds: ${launchBudgetHoldCount})`
369
+ );
370
+
371
+ const launchBudgetHoldWindowMs = Number(status.rateLimit.lastLaunchBudgetHoldMs) || 0;
372
+ const lastLaunchBudgetHoldAtMs = Date.parse(status.rateLimit.lastLaunchBudgetHoldAt || '');
373
+ const elapsedSinceBudgetHoldMs = Number.isFinite(lastLaunchBudgetHoldAtMs)
374
+ ? Math.max(0, Date.now() - lastLaunchBudgetHoldAtMs)
375
+ : Infinity;
376
+ const budgetHoldRemainingMs = launchBudgetHoldWindowMs > 0
377
+ ? Math.max(0, launchBudgetHoldWindowMs - elapsedSinceBudgetHoldMs)
378
+ : 0;
379
+ if (budgetHoldRemainingMs > 0) {
380
+ console.log(`Launch budget hold: ${budgetHoldRemainingMs}ms remaining`);
381
+ }
382
+ }
383
+ }
384
+ if (status.specs) {
385
+ console.log('');
386
+ for (const [name, info] of Object.entries(status.specs)) {
387
+ const sym = _statusSymbol(info.status);
388
+ const extra = info.error ? chalk.gray(` — ${info.error}`) : '';
389
+ console.log(` ${sym} ${name}${extra}`);
390
+ }
391
+ }
392
+ }
393
+
394
+ /**
395
+ * Map status string to a coloured symbol.
396
+ * @param {string} status
397
+ * @returns {string}
398
+ */
399
+ function _statusSymbol(status) {
400
+ const map = {
401
+ completed: chalk.green('✓'),
402
+ running: chalk.yellow('⧗'),
403
+ pending: chalk.gray('○'),
404
+ failed: chalk.red('✗'),
405
+ timeout: chalk.red('⏱'),
406
+ skipped: chalk.gray('⊘'),
407
+ idle: chalk.gray('○'),
408
+ stopped: chalk.yellow('⏹'),
409
+ };
410
+ return map[status] || '?';
411
+ }
412
+
413
+ /**
414
+ * Print an error and exit. Respects --json mode.
415
+ * @param {string} message
416
+ * @param {boolean} [json]
417
+ */
418
+ function _errorAndExit(message, json) {
419
+ if (json) {
420
+ console.log(JSON.stringify({ error: message }));
421
+ } else {
422
+ console.error(chalk.red('Error:'), message);
423
+ }
424
+ process.exit(1);
425
+ }
426
+
427
+ /**
428
+ * Parse a comma-separated specs option.
429
+ * @param {string} specsOption
430
+ * @returns {string[]}
431
+ */
432
+ function _parseSpecNamesOption(specsOption) {
433
+ if (!specsOption || typeof specsOption !== 'string') {
434
+ return [];
435
+ }
436
+
437
+ return specsOption
438
+ .split(',')
439
+ .map(item => item.trim())
440
+ .filter(Boolean);
441
+ }
442
+
443
+ module.exports = {
444
+ registerOrchestrateCommands,
445
+ runOrchestration,
446
+ };
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Prompt Command
3
+ *
4
+ * Generates task-specific prompts for AI coding assistants
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const PromptGenerator = require('../context/prompt-generator');
9
+
10
+ /**
11
+ * Generate task prompt
12
+ *
13
+ * @param {string} specName - Spec name
14
+ * @param {string} taskId - Task ID
15
+ * @param {Object} options - Command options
16
+ * @param {string} options.tool - Target tool (generic, claude-code, cursor, codex, kiro)
17
+ * @param {number} options.maxLength - Maximum context length
18
+ * @returns {Promise<void>}
19
+ */
20
+ async function generatePrompt(specName, taskId, options = {}) {
21
+ const projectPath = process.cwd();
22
+ const generator = new PromptGenerator();
23
+
24
+ console.log(chalk.red('🔥') + ' Generating Task Prompt');
25
+ console.log();
26
+
27
+ try {
28
+ console.log(`Spec: ${chalk.cyan(specName)}`);
29
+ console.log(`Task: ${chalk.cyan(taskId)}`);
30
+
31
+ const targetTool = options.tool || 'generic';
32
+ console.log(`Target Tool: ${chalk.cyan(targetTool)}`);
33
+ console.log();
34
+
35
+ const generateOptions = {
36
+ targetTool,
37
+ maxContextLength: options.maxLength || 10000
38
+ };
39
+
40
+ console.log('Generating prompt...');
41
+ console.log();
42
+
43
+ const result = await generator.generatePrompt(
44
+ projectPath,
45
+ specName,
46
+ taskId,
47
+ generateOptions
48
+ );
49
+
50
+ if (result.success) {
51
+ console.log(chalk.green('✅ Prompt generated successfully'));
52
+ console.log();
53
+ console.log(`Prompt file: ${chalk.cyan(result.promptPath)}`);
54
+ console.log(`Size: ${chalk.gray(formatBytes(result.size))}`);
55
+ console.log();
56
+ console.log('Usage:');
57
+ console.log(' 1. Copy the prompt file content');
58
+ console.log(' 2. Paste it into your AI coding assistant');
59
+ console.log(' 3. Follow the implementation guidelines');
60
+ console.log(' 4. Update task status after completion');
61
+ console.log();
62
+
63
+ // Tool-specific tips
64
+ if (targetTool === 'claude-code') {
65
+ console.log(chalk.blue('💡 Claude Code Tips:'));
66
+ console.log(' • Copy the entire prompt into the chat');
67
+ console.log(' • Reference specific sections as needed');
68
+ } else if (targetTool === 'cursor') {
69
+ console.log(chalk.blue('💡 Cursor Tips:'));
70
+ console.log(' • Paste the prompt into the composer');
71
+ console.log(' • Use Cmd+K to apply changes');
72
+ } else if (targetTool === 'codex') {
73
+ console.log(chalk.blue('💡 GitHub Copilot Tips:'));
74
+ console.log(' • Include the prompt in code comments');
75
+ console.log(' • Let Copilot suggest implementations');
76
+ } else if (targetTool === 'kiro') {
77
+ console.log(chalk.blue('💡 Kiro IDE Tips:'));
78
+ console.log(' • Steering rules are loaded automatically');
79
+ console.log(' • Use #File to reference specific files');
80
+ }
81
+ } else {
82
+ console.log(chalk.red('❌ Prompt generation failed'));
83
+ console.log();
84
+ console.log(`Error: ${result.error}`);
85
+ }
86
+ } catch (error) {
87
+ console.log(chalk.red('❌ Error:'), error.message);
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Format bytes to human-readable string
93
+ *
94
+ * @param {number} bytes - Bytes
95
+ * @returns {string} Formatted string
96
+ */
97
+ function formatBytes(bytes) {
98
+ if (bytes < 1024) return `${bytes} B`;
99
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
100
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
101
+ }
102
+
103
+ module.exports = {
104
+ generatePrompt
105
+ };
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Repository Management Command Group
3
+ *
4
+ * Manages multiple Git subrepositories within a single project
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const InitHandler = require('../repo/handlers/init-handler');
9
+ const StatusHandler = require('../repo/handlers/status-handler');
10
+ const ExecHandler = require('../repo/handlers/exec-handler');
11
+ const HealthHandler = require('../repo/handlers/health-handler');
12
+
13
+ /**
14
+ * Initialize repository configuration
15
+ *
16
+ * @param {Object} options - Command options
17
+ * @param {boolean} options.yes - Skip confirmation prompts
18
+ * @param {number} options.maxDepth - Maximum scan depth
19
+ * @param {string} options.exclude - Comma-separated paths to exclude
20
+ * @param {boolean} options.nested - Enable nested repository scanning (default: true)
21
+ * @returns {Promise<void>}
22
+ */
23
+ async function initRepo(options = {}) {
24
+ const projectPath = process.cwd();
25
+ const handler = new InitHandler(projectPath);
26
+
27
+ console.log(chalk.red('🔥') + ' Initializing Repository Configuration');
28
+ console.log();
29
+
30
+ try {
31
+ await handler.execute({
32
+ skipConfirmation: options.yes,
33
+ maxDepth: options.maxDepth,
34
+ exclude: options.exclude ? options.exclude.split(',').map(p => p.trim()) : [],
35
+ nested: options.nested !== false // Default to true, false only if --no-nested is used
36
+ });
37
+ } catch (error) {
38
+ console.log(chalk.red('❌ Error:'), error.message);
39
+ process.exit(1);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Display repository status
45
+ *
46
+ * @param {Object} options - Command options
47
+ * @param {boolean} options.verbose - Show detailed status
48
+ * @returns {Promise<void>}
49
+ */
50
+ async function statusRepo(options = {}) {
51
+ const projectPath = process.cwd();
52
+ const handler = new StatusHandler(projectPath);
53
+
54
+ console.log(chalk.red('🔥') + ' Repository Status');
55
+ console.log();
56
+
57
+ try {
58
+ await handler.execute({
59
+ verbose: options.verbose
60
+ });
61
+ } catch (error) {
62
+ console.log(chalk.red('❌ Error:'), error.message);
63
+ process.exit(1);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Execute command across repositories
69
+ *
70
+ * @param {string} command - Git command to execute
71
+ * @param {Object} options - Command options
72
+ * @param {boolean} options.dryRun - Show commands without executing
73
+ * @returns {Promise<void>}
74
+ */
75
+ async function execRepo(command, options = {}) {
76
+ const projectPath = process.cwd();
77
+ const handler = new ExecHandler(projectPath);
78
+
79
+ console.log(chalk.red('🔥') + ' Executing Command Across Repositories');
80
+ console.log();
81
+
82
+ try {
83
+ await handler.execute(command, {
84
+ dryRun: options.dryRun
85
+ });
86
+ } catch (error) {
87
+ console.log(chalk.red('❌ Error:'), error.message);
88
+ process.exit(1);
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Check repository health
94
+ *
95
+ * @param {Object} options - Command options
96
+ * @returns {Promise<void>}
97
+ */
98
+ async function healthRepo(options = {}) {
99
+ const projectPath = process.cwd();
100
+ const handler = new HealthHandler(projectPath);
101
+
102
+ console.log(chalk.red('🔥') + ' Repository Health Check');
103
+ console.log();
104
+
105
+ try {
106
+ await handler.execute(options);
107
+ } catch (error) {
108
+ console.log(chalk.red('❌ Error:'), error.message);
109
+ process.exit(1);
110
+ }
111
+ }
112
+
113
+ module.exports = {
114
+ initRepo,
115
+ statusRepo,
116
+ execRepo,
117
+ healthRepo
118
+ };