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,410 @@
1
+ /**
2
+ * Conflict Resolver
3
+ *
4
+ * Manages both automatic and interactive conflict resolution.
5
+ * - Automatic mode: Uses FileClassifier for smart resolution
6
+ * - Interactive mode: Prompts user for decisions
7
+ * Provides three-tier resolution: skip-all, overwrite-all, or review-each.
8
+ */
9
+
10
+ const chalk = require('chalk');
11
+ const inquirer = require('inquirer');
12
+ const path = require('path');
13
+ const DiffViewer = require('./diff-viewer');
14
+ const { FileClassifier, FileCategory, ResolutionAction } = require('./file-classifier');
15
+
16
+ /**
17
+ * ConflictResolver class for automatic and interactive conflict resolution
18
+ */
19
+ class ConflictResolver {
20
+ constructor() {
21
+ this.diffViewer = new DiffViewer();
22
+ this.fileClassifier = new FileClassifier();
23
+ }
24
+
25
+ /**
26
+ * Resolves conflicts automatically using FileClassifier
27
+ *
28
+ * @param {FileConflict[]} conflicts - Array of conflicts
29
+ * @returns {Object} Resolution result with map and summary
30
+ */
31
+ resolveConflictAutomatic(conflicts) {
32
+ const resolutionMap = {};
33
+ const summary = {
34
+ total: conflicts.length,
35
+ update: 0,
36
+ preserve: 0,
37
+ merge: 0,
38
+ skip: 0,
39
+ byCategory: {
40
+ [FileCategory.TEMPLATE]: [],
41
+ [FileCategory.USER_CONTENT]: [],
42
+ [FileCategory.CONFIG]: [],
43
+ [FileCategory.GENERATED]: []
44
+ }
45
+ };
46
+
47
+ // Process each conflict
48
+ for (const conflict of conflicts) {
49
+ // Get resolution rule from FileClassifier
50
+ const rule = this.fileClassifier.getResolutionRule(conflict.path);
51
+
52
+ // Map ResolutionAction to file resolution
53
+ let resolution;
54
+ switch (rule.action) {
55
+ case ResolutionAction.UPDATE:
56
+ resolution = 'overwrite';
57
+ summary.update++;
58
+ break;
59
+
60
+ case ResolutionAction.PRESERVE:
61
+ resolution = 'keep';
62
+ summary.preserve++;
63
+ break;
64
+
65
+ case ResolutionAction.MERGE:
66
+ resolution = 'merge';
67
+ summary.merge++;
68
+ break;
69
+
70
+ case ResolutionAction.SKIP:
71
+ resolution = 'skip';
72
+ summary.skip++;
73
+ break;
74
+
75
+ default:
76
+ // Fallback: preserve for safety
77
+ resolution = 'keep';
78
+ summary.preserve++;
79
+ }
80
+
81
+ // Store resolution
82
+ resolutionMap[conflict.path] = resolution;
83
+
84
+ // Track by category
85
+ summary.byCategory[rule.category].push({
86
+ path: conflict.path,
87
+ action: rule.action,
88
+ resolution: resolution,
89
+ reason: rule.reason
90
+ });
91
+ }
92
+
93
+ return {
94
+ resolutionMap,
95
+ summary
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Displays automatic resolution summary
101
+ *
102
+ * @param {Object} summary - Resolution summary from resolveConflictAutomatic
103
+ * @returns {void}
104
+ */
105
+ displayAutomaticResolutionSummary(summary) {
106
+ console.log();
107
+ console.log(chalk.blue('🤖 Automatic Conflict Resolution'));
108
+ console.log(chalk.blue('═══════════════════════════════════════════════════════'));
109
+ console.log();
110
+
111
+ console.log(chalk.cyan(`Total conflicts: ${summary.total}`));
112
+ console.log();
113
+
114
+ // Display by action
115
+ if (summary.update > 0) {
116
+ console.log(chalk.green(`✅ Update (backup + use template): ${summary.update} file(s)`));
117
+ }
118
+
119
+ if (summary.preserve > 0) {
120
+ console.log(chalk.yellow(`⏭️ Preserve (keep existing): ${summary.preserve} file(s)`));
121
+ }
122
+
123
+ if (summary.merge > 0) {
124
+ console.log(chalk.blue(`🔀 Merge (backup + merge): ${summary.merge} file(s)`));
125
+ }
126
+
127
+ if (summary.skip > 0) {
128
+ console.log(chalk.gray(`⏩ Skip (regenerate): ${summary.skip} file(s)`));
129
+ }
130
+
131
+ console.log();
132
+
133
+ // Display by category
134
+ console.log(chalk.blue('By Category:'));
135
+ console.log();
136
+
137
+ // Template files
138
+ const templates = summary.byCategory[FileCategory.TEMPLATE];
139
+ if (templates.length > 0) {
140
+ console.log(chalk.green(`📝 Template Files (${templates.length}):`));
141
+ templates.forEach(item => {
142
+ console.log(chalk.gray(` → ${item.path} (${item.action})`));
143
+ });
144
+ console.log();
145
+ }
146
+
147
+ // User content
148
+ const userContent = summary.byCategory[FileCategory.USER_CONTENT];
149
+ if (userContent.length > 0) {
150
+ console.log(chalk.yellow(`📦 User Content (${userContent.length}):`));
151
+ userContent.forEach(item => {
152
+ console.log(chalk.gray(` → ${item.path} (${item.action})`));
153
+ });
154
+ console.log();
155
+ }
156
+
157
+ // Config files
158
+ const configs = summary.byCategory[FileCategory.CONFIG];
159
+ if (configs.length > 0) {
160
+ console.log(chalk.blue(`⚙️ Config Files (${configs.length}):`));
161
+ configs.forEach(item => {
162
+ console.log(chalk.gray(` → ${item.path} (${item.action})`));
163
+ });
164
+ console.log();
165
+ }
166
+
167
+ // Generated files
168
+ const generated = summary.byCategory[FileCategory.GENERATED];
169
+ if (generated.length > 0) {
170
+ console.log(chalk.gray(`🔄 Generated Files (${generated.length}):`));
171
+ generated.forEach(item => {
172
+ console.log(chalk.gray(` → ${item.path} (${item.action})`));
173
+ });
174
+ console.log();
175
+ }
176
+
177
+ console.log(chalk.blue('═══════════════════════════════════════════════════════'));
178
+ console.log();
179
+ }
180
+
181
+ /**
182
+ * Displays conflict summary grouped by category
183
+ *
184
+ * @param {FileConflict[]} conflicts - Array of conflicts
185
+ * @returns {void}
186
+ */
187
+ displayConflictSummary(conflicts) {
188
+ console.log();
189
+ console.log(chalk.yellow('⚠️ Conflicts Detected'));
190
+ console.log(chalk.yellow('═══════════════════════════════════════════════════════'));
191
+ console.log();
192
+
193
+ // Categorize conflicts
194
+ const categorized = this.categorizeConflicts(conflicts);
195
+
196
+ // Display by category
197
+ if (categorized.steering.length > 0) {
198
+ console.log(chalk.blue('Steering Files:'));
199
+ categorized.steering.forEach(c => console.log(` - ${c.path}`));
200
+ console.log();
201
+ }
202
+
203
+ if (categorized.documentation.length > 0) {
204
+ console.log(chalk.blue('Documentation:'));
205
+ categorized.documentation.forEach(c => console.log(` - ${c.path}`));
206
+ console.log();
207
+ }
208
+
209
+ if (categorized.tools.length > 0) {
210
+ console.log(chalk.blue('Tools:'));
211
+ categorized.tools.forEach(c => console.log(` - ${c.path}`));
212
+ console.log();
213
+ }
214
+
215
+ if (categorized.other.length > 0) {
216
+ console.log(chalk.blue('Other:'));
217
+ categorized.other.forEach(c => console.log(` - ${c.path}`));
218
+ console.log();
219
+ }
220
+
221
+ console.log(chalk.yellow(`Total: ${conflicts.length} conflict(s)`));
222
+ console.log(chalk.yellow('═══════════════════════════════════════════════════════'));
223
+ console.log();
224
+ }
225
+
226
+ /**
227
+ * Categorizes conflicts by type
228
+ *
229
+ * @param {FileConflict[]} conflicts - Array of conflicts
230
+ * @returns {CategorizedConflicts}
231
+ */
232
+ categorizeConflicts(conflicts) {
233
+ return {
234
+ steering: conflicts.filter(c => c.path.startsWith('steering/')),
235
+ documentation: conflicts.filter(c =>
236
+ c.path.endsWith('.md') && !c.path.startsWith('steering/')
237
+ ),
238
+ tools: conflicts.filter(c => c.path.startsWith('tools/')),
239
+ other: conflicts.filter(c =>
240
+ !c.path.startsWith('steering/') &&
241
+ !c.path.startsWith('tools/') &&
242
+ !c.path.endsWith('.md')
243
+ )
244
+ };
245
+ }
246
+
247
+ /**
248
+ * Prompts user for overall conflict resolution strategy
249
+ *
250
+ * @param {FileConflict[]} conflicts - Array of detected conflicts
251
+ * @returns {Promise<ConflictStrategy>} - 'skip-all' | 'overwrite-all' | 'review-each'
252
+ */
253
+ async promptStrategy(conflicts) {
254
+ const { strategy } = await inquirer.prompt([
255
+ {
256
+ type: 'list',
257
+ name: 'strategy',
258
+ message: 'How would you like to handle these conflicts?',
259
+ choices: [
260
+ {
261
+ name: 'Skip conflicting files (keep existing files)',
262
+ value: 'skip-all'
263
+ },
264
+ {
265
+ name: 'Overwrite conflicting files (backup will be created)',
266
+ value: 'overwrite-all'
267
+ },
268
+ {
269
+ name: 'Review conflicts one by one',
270
+ value: 'review-each'
271
+ }
272
+ ],
273
+ default: 'skip-all'
274
+ }
275
+ ]);
276
+
277
+ return strategy;
278
+ }
279
+
280
+ /**
281
+ * Prompts user for resolution of a single file conflict
282
+ *
283
+ * @param {FileConflict} conflict - The conflict to resolve
284
+ * @param {number} currentIndex - Current conflict number (for display)
285
+ * @param {number} totalConflicts - Total number of conflicts
286
+ * @param {string} projectPath - Project root path
287
+ * @returns {Promise<FileResolution>} - 'keep' | 'overwrite'
288
+ */
289
+ async promptFileResolution(conflict, currentIndex, totalConflicts, projectPath) {
290
+ console.log();
291
+ console.log(chalk.blue('─────────────────────────────────────────────────────'));
292
+ console.log(chalk.blue(`Conflict ${currentIndex} of ${totalConflicts}`));
293
+ console.log(chalk.blue('─────────────────────────────────────────────────────'));
294
+ console.log();
295
+ console.log(chalk.cyan('File:'), conflict.path);
296
+ console.log();
297
+
298
+ let resolution = null;
299
+
300
+ while (resolution === null) {
301
+ const { action } = await inquirer.prompt([
302
+ {
303
+ type: 'list',
304
+ name: 'action',
305
+ message: 'What would you like to do?',
306
+ choices: [
307
+ {
308
+ name: 'Keep existing file',
309
+ value: 'keep'
310
+ },
311
+ {
312
+ name: 'Use template file (backup will be created)',
313
+ value: 'overwrite'
314
+ },
315
+ {
316
+ name: 'View diff',
317
+ value: 'view-diff'
318
+ }
319
+ ],
320
+ default: 'keep'
321
+ }
322
+ ]);
323
+
324
+ if (action === 'view-diff') {
325
+ // Show diff
326
+ const existingPath = path.join(projectPath, '.kiro', conflict.path);
327
+ const templatePath = conflict.templatePath || path.join(projectPath, 'template', '.kiro', conflict.path);
328
+
329
+ try {
330
+ await this.diffViewer.showDiff(existingPath, templatePath);
331
+ } catch (diffError) {
332
+ console.log();
333
+ console.log(chalk.yellow('⚠️ Unable to generate diff for this file'));
334
+ console.log(chalk.gray(` Reason: ${diffError.message}`));
335
+ console.log();
336
+ console.log(chalk.gray(' You can open the files in your editor to compare:'));
337
+ console.log(chalk.gray(` Existing: ${existingPath}`));
338
+ console.log(chalk.gray(` Template: ${templatePath}`));
339
+ console.log();
340
+ }
341
+
342
+ // Re-prompt with only keep/overwrite options
343
+ const { finalAction } = await inquirer.prompt([
344
+ {
345
+ type: 'list',
346
+ name: 'finalAction',
347
+ message: 'After viewing the diff, what would you like to do?',
348
+ choices: [
349
+ {
350
+ name: 'Keep existing file',
351
+ value: 'keep'
352
+ },
353
+ {
354
+ name: 'Use template file (backup will be created)',
355
+ value: 'overwrite'
356
+ }
357
+ ],
358
+ default: 'keep'
359
+ }
360
+ ]);
361
+
362
+ resolution = finalAction;
363
+ } else {
364
+ resolution = action;
365
+ }
366
+ }
367
+
368
+ return resolution;
369
+ }
370
+
371
+ /**
372
+ * Processes all conflicts based on strategy and returns resolution map
373
+ *
374
+ * @param {FileConflict[]} conflicts - Array of conflicts
375
+ * @param {ConflictStrategy} strategy - Overall strategy
376
+ * @param {string} projectPath - Project root path
377
+ * @returns {Promise<ResolutionMap>} - Map of file paths to resolutions
378
+ */
379
+ async resolveConflicts(conflicts, strategy, projectPath) {
380
+ const resolutionMap = {};
381
+
382
+ if (strategy === 'skip-all') {
383
+ // Mark all as 'keep'
384
+ conflicts.forEach(conflict => {
385
+ resolutionMap[conflict.path] = 'keep';
386
+ });
387
+ } else if (strategy === 'overwrite-all') {
388
+ // Mark all as 'overwrite'
389
+ conflicts.forEach(conflict => {
390
+ resolutionMap[conflict.path] = 'overwrite';
391
+ });
392
+ } else if (strategy === 'review-each') {
393
+ // Prompt for each conflict
394
+ for (let i = 0; i < conflicts.length; i++) {
395
+ const conflict = conflicts[i];
396
+ const resolution = await this.promptFileResolution(
397
+ conflict,
398
+ i + 1,
399
+ conflicts.length,
400
+ projectPath
401
+ );
402
+ resolutionMap[conflict.path] = resolution;
403
+ }
404
+ }
405
+
406
+ return resolutionMap;
407
+ }
408
+ }
409
+
410
+ module.exports = ConflictResolver;
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Detection Engine
3
+ *
4
+ * Analyzes project structure and determines the appropriate adoption strategy.
5
+ * Detects project type, existing .kiro/ components, and potential conflicts.
6
+ */
7
+
8
+ const path = require('path');
9
+ const {
10
+ pathExists,
11
+ listFiles,
12
+ readJSON
13
+ } = require('../utils/fs-utils');
14
+ const SteeringManager = require('../steering/steering-manager');
15
+
16
+ class DetectionEngine {
17
+ constructor() {
18
+ this.kiroDir = '.kiro';
19
+ this.versionFile = 'version.json';
20
+ this.specsDir = 'specs';
21
+ this.steeringDir = 'steering';
22
+ this.toolsDir = 'tools';
23
+ this.steeringManager = new SteeringManager();
24
+ }
25
+
26
+ /**
27
+ * Analyzes project directory and returns detection result
28
+ *
29
+ * @param {string} projectPath - Absolute path to project root
30
+ * @returns {Promise<DetectionResult>}
31
+ */
32
+ async analyze(projectPath) {
33
+ try {
34
+ const kiroPath = path.join(projectPath, this.kiroDir);
35
+ const hasKiroDir = await pathExists(kiroPath);
36
+
37
+ let hasVersionFile = false;
38
+ let hasSpecs = false;
39
+ let hasSteering = false;
40
+ let hasTools = false;
41
+ let existingVersion = null;
42
+ let steeringDetection = null;
43
+
44
+ if (hasKiroDir) {
45
+ // Check for version.json
46
+ const versionPath = path.join(kiroPath, this.versionFile);
47
+ hasVersionFile = await pathExists(versionPath);
48
+
49
+ if (hasVersionFile) {
50
+ try {
51
+ const versionInfo = await readJSON(versionPath);
52
+ existingVersion = versionInfo['kse-version'] || null;
53
+ } catch (error) {
54
+ // Invalid version file
55
+ hasVersionFile = false;
56
+ }
57
+ }
58
+
59
+ // Check for specs/
60
+ const specsPath = path.join(kiroPath, this.specsDir);
61
+ hasSpecs = await pathExists(specsPath);
62
+
63
+ // Check for steering/ using SteeringManager
64
+ steeringDetection = await this.steeringManager.detectSteering(projectPath);
65
+ hasSteering = steeringDetection.hasExistingSteering;
66
+
67
+ // Check for tools/
68
+ const toolsPath = path.join(kiroPath, this.toolsDir);
69
+ hasTools = await pathExists(toolsPath);
70
+ }
71
+
72
+ // Detect project type
73
+ const projectType = await this.detectProjectType(projectPath);
74
+
75
+ // Detect conflicts (only if we're going to add template files)
76
+ const conflicts = hasKiroDir ? await this.detectConflicts(projectPath) : [];
77
+
78
+ return {
79
+ hasKiroDir,
80
+ hasVersionFile,
81
+ hasSpecs,
82
+ hasSteering,
83
+ hasTools,
84
+ projectType,
85
+ existingVersion,
86
+ conflicts,
87
+ steeringDetection // Add steering detection details
88
+ };
89
+ } catch (error) {
90
+ throw new Error(`Failed to analyze project: ${error.message}`);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Determines which adoption strategy to use
96
+ *
97
+ * @param {DetectionResult} result - Detection result from analyze()
98
+ * @returns {AdoptionMode} - 'fresh', 'partial', or 'full'
99
+ */
100
+ determineStrategy(result) {
101
+ // Fresh adoption: no .kiro/ directory
102
+ if (!result.hasKiroDir) {
103
+ return 'fresh';
104
+ }
105
+
106
+ // Partial adoption: .kiro/ exists but no version.json
107
+ if (!result.hasVersionFile) {
108
+ return 'partial';
109
+ }
110
+
111
+ // Full adoption: complete .kiro/ with version.json
112
+ return 'full';
113
+ }
114
+
115
+ /**
116
+ * Detects project type (Node.js, Python, mixed, unknown)
117
+ *
118
+ * @param {string} projectPath - Absolute path to project root
119
+ * @returns {Promise<ProjectType>}
120
+ */
121
+ async detectProjectType(projectPath) {
122
+ try {
123
+ const hasPackageJson = await pathExists(path.join(projectPath, 'package.json'));
124
+ const hasRequirementsTxt = await pathExists(path.join(projectPath, 'requirements.txt'));
125
+ const hasPyprojectToml = await pathExists(path.join(projectPath, 'pyproject.toml'));
126
+ const hasSetupPy = await pathExists(path.join(projectPath, 'setup.py'));
127
+
128
+ const isNodeJs = hasPackageJson;
129
+ const isPython = hasRequirementsTxt || hasPyprojectToml || hasSetupPy;
130
+
131
+ if (isNodeJs && isPython) {
132
+ return 'mixed';
133
+ } else if (isNodeJs) {
134
+ return 'nodejs';
135
+ } else if (isPython) {
136
+ return 'python';
137
+ } else {
138
+ return 'unknown';
139
+ }
140
+ } catch (error) {
141
+ throw new Error(`Failed to detect project type: ${error.message}`);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Detects conflicts between existing files and template files
147
+ *
148
+ * @param {string} projectPath - Absolute path to project root
149
+ * @returns {Promise<FileConflict[]>}
150
+ */
151
+ async detectConflicts(projectPath) {
152
+ const conflicts = [];
153
+
154
+ try {
155
+ const kiroPath = path.join(projectPath, this.kiroDir);
156
+
157
+ // Define template files that might conflict
158
+ const templateFiles = [
159
+ 'steering/CORE_PRINCIPLES.md',
160
+ 'steering/ENVIRONMENT.md',
161
+ 'steering/CURRENT_CONTEXT.md',
162
+ 'steering/RULES_GUIDE.md',
163
+ 'tools/ultrawork_enhancer.py',
164
+ 'README.md',
165
+ 'ultrawork-application-guide.md',
166
+ 'ultrawork-integration-summary.md',
167
+ 'sisyphus-deep-dive.md'
168
+ ];
169
+
170
+ for (const templateFile of templateFiles) {
171
+ const filePath = path.join(kiroPath, templateFile);
172
+ const exists = await pathExists(filePath);
173
+
174
+ if (exists) {
175
+ conflicts.push({
176
+ path: templateFile,
177
+ type: 'file',
178
+ existingContent: filePath,
179
+ templateContent: `template:${templateFile}`
180
+ });
181
+ }
182
+ }
183
+
184
+ return conflicts;
185
+ } catch (error) {
186
+ throw new Error(`Failed to detect conflicts: ${error.message}`);
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Categorizes conflicts by type for better display
192
+ *
193
+ * @param {FileConflict[]} conflicts - Array of conflicts
194
+ * @returns {CategorizedConflicts}
195
+ */
196
+ categorizeConflicts(conflicts) {
197
+ return {
198
+ steering: conflicts.filter(c => c.path.startsWith('steering/')),
199
+ documentation: conflicts.filter(c =>
200
+ c.path.endsWith('.md') &&
201
+ !c.path.startsWith('steering/') &&
202
+ !c.path.startsWith('tools/')
203
+ ),
204
+ tools: conflicts.filter(c => c.path.startsWith('tools/')),
205
+ other: conflicts.filter(c =>
206
+ !c.path.startsWith('steering/') &&
207
+ !c.path.startsWith('tools/') &&
208
+ !c.path.endsWith('.md')
209
+ )
210
+ };
211
+ }
212
+
213
+ /**
214
+ * Validates that a project path is valid
215
+ *
216
+ * @param {string} projectPath - Path to validate
217
+ * @returns {Promise<boolean>}
218
+ */
219
+ async validateProjectPath(projectPath) {
220
+ try {
221
+ const exists = await pathExists(projectPath);
222
+ if (!exists) {
223
+ return false;
224
+ }
225
+
226
+ // Check if it's a directory
227
+ const fs = require('fs-extra');
228
+ const stats = await fs.stat(projectPath);
229
+ return stats.isDirectory();
230
+ } catch (error) {
231
+ return false;
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Gets a summary of the detection result for display
237
+ *
238
+ * @param {DetectionResult} result - Detection result
239
+ * @returns {string} - Human-readable summary
240
+ */
241
+ getSummary(result) {
242
+ const lines = [];
243
+
244
+ lines.push('Project Analysis:');
245
+ lines.push(` Project Type: ${result.projectType}`);
246
+ lines.push(` .kiro/ Directory: ${result.hasKiroDir ? 'Yes' : 'No'}`);
247
+
248
+ if (result.hasKiroDir) {
249
+ lines.push(` version.json: ${result.hasVersionFile ? 'Yes' : 'No'}`);
250
+ if (result.existingVersion) {
251
+ lines.push(` Current Version: ${result.existingVersion}`);
252
+ }
253
+ lines.push(` specs/: ${result.hasSpecs ? 'Yes' : 'No'}`);
254
+ lines.push(` steering/: ${result.hasSteering ? 'Yes' : 'No'}`);
255
+
256
+ // Show steering details if available
257
+ if (result.steeringDetection && result.steeringDetection.hasExistingSteering) {
258
+ lines.push(` Files: ${result.steeringDetection.count} file(s)`);
259
+ }
260
+
261
+ lines.push(` tools/: ${result.hasTools ? 'Yes' : 'No'}`);
262
+
263
+ if (result.conflicts.length > 0) {
264
+ lines.push(` Conflicts: ${result.conflicts.length} file(s)`);
265
+ }
266
+ }
267
+
268
+ const strategy = this.determineStrategy(result);
269
+ lines.push(` Recommended Strategy: ${strategy}`);
270
+
271
+ return lines.join('\n');
272
+ }
273
+ }
274
+
275
+ module.exports = DetectionEngine;