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,684 @@
1
+ /**
2
+ * Watch Command Group
3
+ *
4
+ * Manages watch mode for automated file monitoring and command execution
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const path = require('path');
9
+ const fs = require('fs-extra');
10
+ const inquirer = require('inquirer');
11
+ const WatchManager = require('../watch/watch-manager');
12
+ const { listPresets, getPreset, mergePreset, validatePreset } = require('../watch/presets');
13
+
14
+ /**
15
+ * Start watch mode
16
+ *
17
+ * @param {Object} options - Command options
18
+ * @param {string} options.config - Custom config file path
19
+ * @param {string} options.patterns - Override patterns (comma-separated)
20
+ * @returns {Promise<void>}
21
+ */
22
+ async function startWatch(options = {}) {
23
+ const projectPath = process.cwd();
24
+ const configPath = options.config || path.join(projectPath, '.kiro/watch-config.json');
25
+
26
+ console.log(chalk.red('🔥') + ' Starting Watch Mode');
27
+ console.log();
28
+
29
+ try {
30
+ const watchManager = new WatchManager({ configPath });
31
+
32
+ // Load configuration
33
+ await watchManager.loadConfig();
34
+
35
+ // Override patterns if specified
36
+ if (options.patterns) {
37
+ const patterns = options.patterns.split(',').map(p => p.trim());
38
+ watchManager.config.patterns = patterns;
39
+ console.log('Using custom patterns:', chalk.cyan(patterns.join(', ')));
40
+ console.log();
41
+ }
42
+
43
+ // Start watch mode
44
+ await watchManager.start();
45
+
46
+ console.log(chalk.green('✅ Watch mode started'));
47
+ console.log();
48
+ console.log('Watching patterns:');
49
+ for (const pattern of watchManager.config.patterns) {
50
+ console.log(` ${chalk.gray('•')} ${pattern}`);
51
+ }
52
+ console.log();
53
+ console.log('Actions configured:');
54
+ const actionCount = Object.keys(watchManager.config.actions || {}).length;
55
+ console.log(` ${chalk.cyan(actionCount)} action(s)`);
56
+ console.log();
57
+ console.log('Commands:');
58
+ console.log(` ${chalk.cyan('kse watch status')} - Check status`);
59
+ console.log(` ${chalk.cyan('kse watch logs')} - View logs`);
60
+ console.log(` ${chalk.cyan('kse watch stop')} - Stop watch mode`);
61
+ console.log();
62
+ console.log(chalk.gray('Press Ctrl+C to stop'));
63
+
64
+ // Keep process running
65
+ process.on('SIGINT', async () => {
66
+ console.log();
67
+ console.log('Stopping watch mode...');
68
+ await watchManager.stop();
69
+ console.log(chalk.green('✅ Watch mode stopped'));
70
+ process.exit(0);
71
+ });
72
+
73
+ } catch (error) {
74
+ console.log(chalk.red('❌ Error:'), error.message);
75
+ if (process.env.NODE_ENV !== 'test') {
76
+ process.exit(1);
77
+ }
78
+ throw error;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Stop watch mode
84
+ *
85
+ * @param {Object} options - Command options
86
+ * @returns {Promise<void>}
87
+ */
88
+ async function stopWatch(options = {}) {
89
+ const projectPath = process.cwd();
90
+ const configPath = path.join(projectPath, '.kiro/watch-config.json');
91
+
92
+ console.log(chalk.red('🔥') + ' Stopping Watch Mode');
93
+ console.log();
94
+
95
+ try {
96
+ const watchManager = new WatchManager({ configPath });
97
+ await watchManager.stop();
98
+
99
+ console.log(chalk.green('✅ Watch mode stopped'));
100
+ } catch (error) {
101
+ console.log(chalk.red('❌ Error:'), error.message);
102
+ if (process.env.NODE_ENV !== 'test') {
103
+ process.exit(1);
104
+ }
105
+ throw error;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Show watch mode status
111
+ *
112
+ * @param {Object} options - Command options
113
+ * @returns {Promise<void>}
114
+ */
115
+ async function statusWatch(options = {}) {
116
+ const projectPath = process.cwd();
117
+ const configPath = path.join(projectPath, '.kiro/watch-config.json');
118
+
119
+ console.log(chalk.red('🔥') + ' Watch Mode Status');
120
+ console.log();
121
+
122
+ try {
123
+ const watchManager = new WatchManager({ configPath });
124
+ const status = watchManager.getStatus();
125
+
126
+ // Running status
127
+ const runningStatus = status.running ? chalk.green('Running') : chalk.gray('Stopped');
128
+ console.log(`Status: ${runningStatus}`);
129
+ console.log();
130
+
131
+ if (status.running) {
132
+ // Patterns
133
+ console.log('Watching patterns:');
134
+ for (const pattern of status.patterns || []) {
135
+ console.log(` ${chalk.gray('•')} ${pattern}`);
136
+ }
137
+ console.log();
138
+
139
+ // Actions
140
+ console.log('Actions:');
141
+ const actionCount = Object.keys(status.actions || {}).length;
142
+ console.log(` ${chalk.cyan(actionCount)} action(s) configured`);
143
+ console.log();
144
+
145
+ // Recent activity
146
+ if (status.recentActivity && status.recentActivity.length > 0) {
147
+ console.log('Recent activity:');
148
+ for (const activity of status.recentActivity.slice(0, 5)) {
149
+ const time = new Date(activity.timestamp).toLocaleTimeString();
150
+ const result = activity.result === 'success' ? chalk.green('✓') : chalk.red('✗');
151
+ console.log(` ${result} ${chalk.gray(time)} ${activity.file}`);
152
+ }
153
+ console.log();
154
+ }
155
+
156
+ // Error count
157
+ if (status.errorCount > 0) {
158
+ console.log(chalk.yellow(`⚠️ ${status.errorCount} error(s) occurred`));
159
+ console.log(`Run ${chalk.cyan('kse watch logs')} to view details`);
160
+ console.log();
161
+ }
162
+ } else {
163
+ console.log(chalk.gray('Watch mode is not running'));
164
+ console.log();
165
+ console.log(`Run ${chalk.cyan('kse watch start')} to start`);
166
+ }
167
+ } catch (error) {
168
+ console.log(chalk.red('❌ Error:'), error.message);
169
+ if (process.env.NODE_ENV !== 'test') {
170
+ process.exit(1);
171
+ }
172
+ throw error;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Display execution logs
178
+ *
179
+ * @param {Object} options - Command options
180
+ * @param {number} options.tail - Number of lines to show
181
+ * @param {boolean} options.follow - Follow mode (tail -f)
182
+ * @returns {Promise<void>}
183
+ */
184
+ async function logsWatch(options = {}) {
185
+ const projectPath = process.cwd();
186
+
187
+ console.log(chalk.red('🔥') + ' Watch Mode Logs');
188
+ console.log();
189
+
190
+ try {
191
+ const lines = parseTailOption(options.tail, 50);
192
+ const logPath = resolveWatchLogPath(projectPath, options);
193
+ const rawLines = await readRawLogLines(logPath);
194
+ const logs = rawLines.slice(-lines).map(parseLogEntry);
195
+
196
+ if (logs.length === 0 && !options.follow) {
197
+ console.log(chalk.gray('No logs found'));
198
+ return;
199
+ }
200
+
201
+ if (logs.length > 0) {
202
+ console.log(`Showing last ${chalk.cyan(logs.length)} log entries:`);
203
+ console.log();
204
+ for (const log of logs) {
205
+ printLogEntry(log);
206
+ }
207
+ }
208
+
209
+ if (options.follow) {
210
+ console.log();
211
+ if (logs.length === 0) {
212
+ console.log(chalk.gray('No logs found yet. Waiting for new entries...'));
213
+ }
214
+ console.log(chalk.gray('Following logs... (Press Ctrl+C to stop)'));
215
+ await followLogStream(logPath, {
216
+ startLineCount: rawLines.length,
217
+ pollIntervalMs: parseTailOption(options.pollIntervalMs, 500),
218
+ followDurationMs: parseTailOption(options.followDurationMs, 0)
219
+ });
220
+ }
221
+ } catch (error) {
222
+ console.log(chalk.red('❌ Error:'), error.message);
223
+ if (process.env.NODE_ENV !== 'test') {
224
+ process.exit(1);
225
+ }
226
+ throw error;
227
+ }
228
+ }
229
+
230
+ function parseTailOption(input, fallbackValue) {
231
+ const parsed = Number.parseInt(input, 10);
232
+ if (Number.isFinite(parsed) && parsed > 0) {
233
+ return parsed;
234
+ }
235
+
236
+ return fallbackValue;
237
+ }
238
+
239
+ function resolveWatchLogPath(projectPath, options = {}) {
240
+ if (options.logPath) {
241
+ return path.isAbsolute(options.logPath)
242
+ ? options.logPath
243
+ : path.join(projectPath, options.logPath);
244
+ }
245
+
246
+ const logFile = options.logFile || 'execution.log';
247
+ return path.join(projectPath, '.kiro', 'watch', 'logs', logFile);
248
+ }
249
+
250
+ async function readRawLogLines(logPath) {
251
+ if (!await fs.pathExists(logPath)) {
252
+ return [];
253
+ }
254
+
255
+ const content = await fs.readFile(logPath, 'utf8');
256
+ if (!content.trim()) {
257
+ return [];
258
+ }
259
+
260
+ return content
261
+ .split(/\r?\n/)
262
+ .map(line => line.trim())
263
+ .filter(line => line.length > 0);
264
+ }
265
+
266
+ function parseLogEntry(line) {
267
+ try {
268
+ return JSON.parse(line);
269
+ } catch (error) {
270
+ return {
271
+ timestamp: new Date().toISOString(),
272
+ level: 'info',
273
+ message: line
274
+ };
275
+ }
276
+ }
277
+
278
+ function printLogEntry(log) {
279
+ const timestamp = log.timestamp ? new Date(log.timestamp) : new Date();
280
+ const time = Number.isNaN(timestamp.getTime())
281
+ ? String(log.timestamp || '')
282
+ : timestamp.toLocaleTimeString();
283
+ const level = formatLogLevel(log.level || 'info');
284
+ const message = log.message || log.event || JSON.stringify(log);
285
+
286
+ console.log(`${chalk.gray(time)} ${level} ${message}`);
287
+
288
+ if (log.error) {
289
+ const errorText = typeof log.error === 'string'
290
+ ? log.error
291
+ : JSON.stringify(log.error);
292
+ console.log(` ${chalk.red('Error:')} ${errorText}`);
293
+ }
294
+ }
295
+
296
+ async function followLogStream(logPath, options = {}) {
297
+ const pollIntervalMs = parseTailOption(options.pollIntervalMs, 500);
298
+ const followDurationMs = parseTailOption(options.followDurationMs, 0);
299
+ const deadline = followDurationMs > 0 ? Date.now() + followDurationMs : null;
300
+ let cursor = Number.isFinite(options.startLineCount) ? options.startLineCount : 0;
301
+ let stopped = false;
302
+
303
+ const onSigInt = () => {
304
+ stopped = true;
305
+ console.log();
306
+ console.log(chalk.gray('Stopped following logs.'));
307
+ };
308
+
309
+ process.once('SIGINT', onSigInt);
310
+
311
+ try {
312
+ while (!stopped) {
313
+ const rawLines = await readRawLogLines(logPath);
314
+
315
+ if (rawLines.length < cursor) {
316
+ // File rotation/truncation: reset cursor and continue from new content.
317
+ cursor = 0;
318
+ }
319
+
320
+ if (rawLines.length > cursor) {
321
+ const appended = rawLines.slice(cursor).map(parseLogEntry);
322
+ for (const entry of appended) {
323
+ printLogEntry(entry);
324
+ }
325
+ cursor = rawLines.length;
326
+ }
327
+
328
+ if (deadline && Date.now() >= deadline) {
329
+ break;
330
+ }
331
+
332
+ await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
333
+ }
334
+ } finally {
335
+ process.removeListener('SIGINT', onSigInt);
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Display automation metrics
341
+ *
342
+ * @param {Object} options - Command options
343
+ * @param {string} options.format - Output format (text/json)
344
+ * @returns {Promise<void>}
345
+ */
346
+ async function metricsWatch(options = {}) {
347
+ const projectPath = process.cwd();
348
+ const configPath = path.join(projectPath, '.kiro/watch-config.json');
349
+
350
+ console.log(chalk.red('🔥') + ' Watch Mode Metrics');
351
+ console.log();
352
+
353
+ try {
354
+ const watchManager = new WatchManager({ configPath });
355
+ const metrics = watchManager.getMetrics();
356
+
357
+ if (options.format === 'json') {
358
+ console.log(JSON.stringify(metrics, null, 2));
359
+ return;
360
+ }
361
+
362
+ // Text format
363
+ console.log('Execution Statistics:');
364
+ console.log(` Total executions: ${chalk.cyan(metrics.totalExecutions || 0)}`);
365
+ console.log(` Successful: ${chalk.green(metrics.successfulExecutions || 0)}`);
366
+ console.log(` Failed: ${chalk.red(metrics.failedExecutions || 0)}`);
367
+ console.log(` Success rate: ${chalk.cyan(((metrics.successRate || 0) * 100).toFixed(1))}%`);
368
+ console.log();
369
+
370
+ console.log('Performance:');
371
+ console.log(` Average duration: ${chalk.cyan((metrics.averageDuration || 0).toFixed(0))}ms`);
372
+ console.log(` Time saved: ${chalk.cyan(formatTimeSaved(metrics.timeSaved || 0))}`);
373
+ console.log();
374
+
375
+ if (metrics.byAction && Object.keys(metrics.byAction).length > 0) {
376
+ console.log('By Action:');
377
+ for (const [action, count] of Object.entries(metrics.byAction)) {
378
+ console.log(` ${action}: ${chalk.cyan(count)}`);
379
+ }
380
+ console.log();
381
+ }
382
+
383
+ if (metrics.errors && metrics.errors.length > 0) {
384
+ console.log(chalk.yellow(`Recent Errors (${metrics.errors.length}):`));
385
+ for (const error of metrics.errors.slice(0, 5)) {
386
+ const time = new Date(error.timestamp).toLocaleTimeString();
387
+ console.log(` ${chalk.gray(time)} ${error.message}`);
388
+ }
389
+ }
390
+ } catch (error) {
391
+ console.log(chalk.red('❌ Error:'), error.message);
392
+ if (process.env.NODE_ENV !== 'test') {
393
+ process.exit(1);
394
+ }
395
+ throw error;
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Initialize watch configuration
401
+ *
402
+ * @param {Object} options - Command options
403
+ * @param {boolean} options.force - Overwrite existing config
404
+ * @returns {Promise<void>}
405
+ */
406
+ async function initWatch(options = {}) {
407
+ const projectPath = process.cwd();
408
+ const configPath = path.join(projectPath, '.kiro/watch-config.json');
409
+
410
+ console.log(chalk.red('🔥') + ' Initialize Watch Configuration');
411
+ console.log();
412
+
413
+ try {
414
+ // Check if config already exists
415
+ if (await fs.pathExists(configPath) && !options.force) {
416
+ console.log(chalk.yellow('⚠️ Configuration already exists'));
417
+ console.log();
418
+ console.log(`Path: ${chalk.gray(configPath)}`);
419
+ console.log();
420
+ console.log(`Use ${chalk.cyan('--force')} to overwrite`);
421
+ return;
422
+ }
423
+
424
+ // Create default configuration
425
+ const defaultConfig = {
426
+ enabled: true,
427
+ patterns: [
428
+ '**/tasks.md',
429
+ '**/.kiro/specs/*/requirements.md',
430
+ '**/.kiro/specs/*/design.md'
431
+ ],
432
+ ignored: [
433
+ '**/node_modules/**',
434
+ '**/.git/**',
435
+ '**/coverage/**'
436
+ ],
437
+ actions: {
438
+ '**/tasks.md': {
439
+ command: 'kse workspace sync',
440
+ debounce: 2000,
441
+ description: 'Sync workspace when tasks are updated'
442
+ }
443
+ },
444
+ debounce: {
445
+ default: 2000
446
+ },
447
+ logging: {
448
+ enabled: true,
449
+ level: 'info',
450
+ maxSize: '10MB',
451
+ rotation: true
452
+ },
453
+ retry: {
454
+ enabled: true,
455
+ maxAttempts: 3,
456
+ backoff: 'exponential'
457
+ }
458
+ };
459
+
460
+ // Ensure directory exists
461
+ await fs.ensureDir(path.dirname(configPath));
462
+
463
+ // Write configuration
464
+ await fs.writeJson(configPath, defaultConfig, { spaces: 2 });
465
+
466
+ console.log(chalk.green('✅ Configuration created'));
467
+ console.log();
468
+ console.log(`Path: ${chalk.gray(configPath)}`);
469
+ console.log();
470
+ console.log('Default patterns:');
471
+ for (const pattern of defaultConfig.patterns) {
472
+ console.log(` ${chalk.gray('•')} ${pattern}`);
473
+ }
474
+ console.log();
475
+ console.log('Next steps:');
476
+ console.log(` 1. Edit config: ${chalk.cyan(configPath)}`);
477
+ console.log(` 2. Start watch: ${chalk.cyan('kse watch start')}`);
478
+ } catch (error) {
479
+ console.log(chalk.red('❌ Error:'), error.message);
480
+ if (process.env.NODE_ENV !== 'test') {
481
+ process.exit(1);
482
+ }
483
+ throw error;
484
+ }
485
+ }
486
+
487
+ /**
488
+ * Format log level with color
489
+ *
490
+ * @param {string} level - Log level
491
+ * @returns {string} Formatted level
492
+ */
493
+ function formatLogLevel(level) {
494
+ const levels = {
495
+ debug: chalk.gray('[DEBUG]'),
496
+ info: chalk.blue('[INFO]'),
497
+ warn: chalk.yellow('[WARN]'),
498
+ error: chalk.red('[ERROR]')
499
+ };
500
+ return levels[level] || chalk.gray(`[${level.toUpperCase()}]`);
501
+ }
502
+
503
+ /**
504
+ * Format time saved in human-readable format
505
+ *
506
+ * @param {number} ms - Milliseconds
507
+ * @returns {string} Formatted time
508
+ */
509
+ function formatTimeSaved(ms) {
510
+ if (ms < 1000) {
511
+ return `${ms}ms`;
512
+ } else if (ms < 60000) {
513
+ return `${(ms / 1000).toFixed(1)}s`;
514
+ } else if (ms < 3600000) {
515
+ return `${(ms / 60000).toFixed(1)}m`;
516
+ } else {
517
+ return `${(ms / 3600000).toFixed(1)}h`;
518
+ }
519
+ }
520
+
521
+ /**
522
+ * List available presets
523
+ *
524
+ * @param {Object} options - Command options
525
+ * @returns {Promise<void>}
526
+ */
527
+ async function listPresetsWatch(options = {}) {
528
+ console.log(chalk.red('🔥') + ' Available Watch Presets');
529
+ console.log();
530
+
531
+ const presets = listPresets();
532
+
533
+ for (const preset of presets) {
534
+ console.log(`${chalk.cyan(preset.name)}`);
535
+ console.log(` ${chalk.gray(preset.description)}`);
536
+ console.log();
537
+ }
538
+
539
+ console.log('Install a preset:');
540
+ console.log(` ${chalk.cyan('kse watch install <preset-name>')}`);
541
+ }
542
+
543
+ /**
544
+ * Install a preset
545
+ *
546
+ * @param {string} presetName - Preset name
547
+ * @param {Object} options - Command options
548
+ * @param {boolean} options.force - Overwrite existing actions
549
+ * @returns {Promise<void>}
550
+ */
551
+ async function installPresetWatch(presetName, options = {}) {
552
+ const projectPath = process.cwd();
553
+ const configPath = path.join(projectPath, '.kiro/watch-config.json');
554
+
555
+ console.log(chalk.red('🔥') + ` Installing Preset: ${chalk.cyan(presetName)}`);
556
+ console.log();
557
+
558
+ try {
559
+ // Validate preset exists
560
+ const validation = validatePreset(presetName);
561
+ if (!validation.valid) {
562
+ console.log(chalk.red('❌ Invalid preset'));
563
+ console.log();
564
+ for (const error of validation.errors) {
565
+ console.log(` ${chalk.red('•')} ${error}`);
566
+ }
567
+ console.log();
568
+ console.log('Available presets:');
569
+ const presets = listPresets();
570
+ for (const preset of presets) {
571
+ console.log(` ${chalk.cyan('•')} ${preset.name}`);
572
+ }
573
+ if (process.env.NODE_ENV !== 'test') {
574
+ process.exit(1);
575
+ }
576
+ throw new Error('Invalid preset');
577
+ }
578
+
579
+ // Get preset
580
+ const preset = getPreset(presetName);
581
+
582
+ // Check if config exists
583
+ let existingConfig = {};
584
+ if (await fs.pathExists(configPath)) {
585
+ existingConfig = await fs.readJson(configPath);
586
+ } else {
587
+ // Create default config
588
+ existingConfig = {
589
+ enabled: true,
590
+ patterns: [],
591
+ ignored: ['**/node_modules/**', '**/.git/**', '**/coverage/**'],
592
+ actions: {},
593
+ debounce: { default: 2000 },
594
+ logging: {
595
+ enabled: true,
596
+ level: 'info',
597
+ maxSize: '10MB',
598
+ rotation: true
599
+ },
600
+ retry: {
601
+ enabled: true,
602
+ maxAttempts: 3,
603
+ backoff: 'exponential'
604
+ }
605
+ };
606
+ }
607
+
608
+ // Check for conflicts
609
+ const conflicts = [];
610
+ for (const pattern of Object.keys(preset.actions)) {
611
+ if (existingConfig.actions && existingConfig.actions[pattern]) {
612
+ conflicts.push(pattern);
613
+ }
614
+ }
615
+
616
+ if (conflicts.length > 0 && !options.force) {
617
+ console.log(chalk.yellow('⚠️ Conflicts detected'));
618
+ console.log();
619
+ console.log('The following patterns already have actions:');
620
+ for (const pattern of conflicts) {
621
+ console.log(` ${chalk.yellow('•')} ${pattern}`);
622
+ }
623
+ console.log();
624
+
625
+ const { proceed } = await inquirer.prompt([{
626
+ type: 'confirm',
627
+ name: 'proceed',
628
+ message: 'Overwrite existing actions?',
629
+ default: false
630
+ }]);
631
+
632
+ if (!proceed) {
633
+ console.log('Installation cancelled');
634
+ return;
635
+ }
636
+ }
637
+
638
+ // Merge preset
639
+ const mergedConfig = mergePreset(existingConfig, presetName);
640
+
641
+ // Ensure directory exists
642
+ await fs.ensureDir(path.dirname(configPath));
643
+
644
+ // Save configuration
645
+ await fs.writeJson(configPath, mergedConfig, { spaces: 2 });
646
+
647
+ console.log(chalk.green('✅ Preset installed successfully'));
648
+ console.log();
649
+ console.log('Added patterns:');
650
+ for (const pattern of preset.patterns) {
651
+ console.log(` ${chalk.gray('•')} ${pattern}`);
652
+ }
653
+ console.log();
654
+ console.log('Added actions:');
655
+ for (const [pattern, action] of Object.entries(preset.actions)) {
656
+ console.log(` ${chalk.gray('•')} ${pattern}`);
657
+ console.log(` ${chalk.gray(action.description)}`);
658
+ }
659
+ console.log();
660
+ console.log('Next steps:');
661
+ console.log(` ${chalk.cyan('kse watch start')} - Start watch mode`);
662
+ } catch (error) {
663
+ console.log(chalk.red('❌ Error:'), error.message);
664
+ if (process.env.NODE_ENV !== 'test') {
665
+ process.exit(1);
666
+ }
667
+ throw error;
668
+ }
669
+ }
670
+
671
+ module.exports = {
672
+ startWatch,
673
+ stopWatch,
674
+ statusWatch,
675
+ logsWatch,
676
+ metricsWatch,
677
+ initWatch,
678
+ listPresetsWatch,
679
+ installPresetWatch,
680
+ _resolveWatchLogPath: resolveWatchLogPath,
681
+ _readRawLogLines: readRawLogLines,
682
+ _parseLogEntry: parseLogEntry,
683
+ _followLogStream: followLogStream
684
+ };