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,382 @@
1
+ /**
2
+ * Migration Engine
3
+ *
4
+ * Manages version upgrades by planning and executing migration scripts.
5
+ * Handles incremental upgrades through intermediate versions.
6
+ */
7
+
8
+ const path = require('path');
9
+ const { pathExists, readJSON } = require('../utils/fs-utils');
10
+ const VersionManager = require('../version/version-manager');
11
+ const GitignoreIntegration = require('../gitignore/gitignore-integration');
12
+
13
+ class MigrationEngine {
14
+ constructor() {
15
+ this.versionManager = new VersionManager();
16
+ this.migrationsDir = path.join(__dirname, 'migrations');
17
+ }
18
+
19
+ /**
20
+ * Plans upgrade from current to target version
21
+ *
22
+ * @param {string} fromVersion - Current version
23
+ * @param {string} toVersion - Target version
24
+ * @returns {Promise<UpgradePlan>}
25
+ */
26
+ async planUpgrade(fromVersion, toVersion) {
27
+ try {
28
+ // Calculate upgrade path
29
+ const upgradePath = this.versionManager.calculateUpgradePath(fromVersion, toVersion);
30
+
31
+ // Build list of migrations needed
32
+ const migrations = [];
33
+ for (let i = 0; i < upgradePath.length - 1; i++) {
34
+ const from = upgradePath[i];
35
+ const to = upgradePath[i + 1];
36
+
37
+ // Check if migration script exists
38
+ const migrationScript = await this.findMigrationScript(from, to);
39
+
40
+ // Check compatibility
41
+ const compatibility = this.versionManager.checkCompatibility(from, to);
42
+
43
+ migrations.push({
44
+ from,
45
+ to,
46
+ breaking: compatibility.breaking,
47
+ script: migrationScript,
48
+ required: compatibility.migration === 'required'
49
+ });
50
+ }
51
+
52
+ // Estimate time (rough estimate: 10 seconds per migration)
53
+ const estimatedTime = migrations.length > 0
54
+ ? `${migrations.length * 10} seconds`
55
+ : '< 5 seconds';
56
+
57
+ return {
58
+ fromVersion,
59
+ toVersion,
60
+ path: upgradePath,
61
+ migrations,
62
+ estimatedTime,
63
+ backupRequired: true
64
+ };
65
+ } catch (error) {
66
+ throw new Error(`Failed to plan upgrade: ${error.message}`);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Executes upgrade plan
72
+ *
73
+ * @param {string} projectPath - Absolute path to project root
74
+ * @param {UpgradePlan} plan - Upgrade plan from planUpgrade()
75
+ * @param {Object} options - Upgrade options
76
+ * @param {boolean} options.dryRun - If true, don't make changes
77
+ * @param {Function} options.onProgress - Progress callback (step, total, message)
78
+ * @returns {Promise<UpgradeResult>}
79
+ */
80
+ async executeUpgrade(projectPath, plan, options = {}) {
81
+ const { dryRun = false, onProgress = null } = options;
82
+
83
+ const migrationsExecuted = [];
84
+ const errors = [];
85
+ const warnings = [];
86
+
87
+ try {
88
+ // Read current version info
89
+ const versionInfo = await this.versionManager.readVersion(projectPath);
90
+ if (!versionInfo) {
91
+ throw new Error('version.json not found');
92
+ }
93
+
94
+ // Verify starting version matches plan
95
+ if (versionInfo['kse-version'] !== plan.fromVersion) {
96
+ throw new Error(
97
+ `Version mismatch: expected ${plan.fromVersion}, found ${versionInfo['kse-version']}`
98
+ );
99
+ }
100
+
101
+ if (dryRun) {
102
+ return {
103
+ success: true,
104
+ fromVersion: plan.fromVersion,
105
+ toVersion: plan.toVersion,
106
+ migrationsExecuted: plan.migrations.map(m => ({
107
+ from: m.from,
108
+ to: m.to,
109
+ success: true,
110
+ changes: ['(dry-run) No changes made'],
111
+ error: null
112
+ })),
113
+ backupId: null,
114
+ errors: [],
115
+ warnings: ['Dry run - no changes made']
116
+ };
117
+ }
118
+
119
+ // Execute migrations sequentially
120
+ for (let i = 0; i < plan.migrations.length; i++) {
121
+ const migration = plan.migrations[i];
122
+
123
+ if (onProgress) {
124
+ onProgress(i + 1, plan.migrations.length, `Migrating ${migration.from} → ${migration.to}`);
125
+ }
126
+
127
+ try {
128
+ // Load migration script if it exists
129
+ let migrationResult = {
130
+ from: migration.from,
131
+ to: migration.to,
132
+ success: true,
133
+ changes: [],
134
+ error: null
135
+ };
136
+
137
+ if (migration.script) {
138
+ // Execute migration script
139
+ const script = await this.loadMigration(migration.from, migration.to);
140
+
141
+ if (script) {
142
+ const result = await script.migrate(projectPath, {
143
+ fromVersion: migration.from,
144
+ toVersion: migration.to,
145
+ versionInfo
146
+ });
147
+
148
+ migrationResult.changes = result.changes || [];
149
+ } else {
150
+ migrationResult.changes.push('No migration script needed');
151
+ }
152
+ } else {
153
+ migrationResult.changes.push('No migration script needed');
154
+ }
155
+
156
+ // Update version info
157
+ this.versionManager.addUpgradeHistory(
158
+ versionInfo,
159
+ migration.from,
160
+ migration.to,
161
+ true
162
+ );
163
+
164
+ // Write updated version info
165
+ await this.versionManager.writeVersion(projectPath, versionInfo);
166
+
167
+ migrationsExecuted.push(migrationResult);
168
+ } catch (error) {
169
+ // Migration failed - record error and stop
170
+ const migrationResult = {
171
+ from: migration.from,
172
+ to: migration.to,
173
+ success: false,
174
+ changes: [],
175
+ error: error.message
176
+ };
177
+
178
+ migrationsExecuted.push(migrationResult);
179
+ errors.push(`Migration ${migration.from} → ${migration.to} failed: ${error.message}`);
180
+
181
+ // Add failed upgrade to history
182
+ this.versionManager.addUpgradeHistory(
183
+ versionInfo,
184
+ migration.from,
185
+ migration.to,
186
+ false,
187
+ error.message
188
+ );
189
+ await this.versionManager.writeVersion(projectPath, versionInfo);
190
+
191
+ // Stop execution on first failure
192
+ throw new Error(`Migration failed: ${error.message}`);
193
+ }
194
+ }
195
+
196
+ // Fix .gitignore for team collaboration after successful upgrade
197
+ try {
198
+ const gitignoreIntegration = new GitignoreIntegration();
199
+ const gitignoreResult = await gitignoreIntegration.integrateWithUpgrade(projectPath);
200
+
201
+ if (gitignoreResult.success && gitignoreResult.action !== 'skipped') {
202
+ warnings.push(gitignoreResult.message);
203
+ } else if (!gitignoreResult.success) {
204
+ warnings.push(`⚠️ .gitignore fix failed: ${gitignoreResult.message}`);
205
+ warnings.push('You can fix this manually with: kse doctor --fix-gitignore');
206
+ }
207
+ } catch (gitignoreError) {
208
+ // Don't block upgrade on .gitignore fix failure
209
+ warnings.push(`⚠️ .gitignore check failed: ${gitignoreError.message}`);
210
+ warnings.push('You can fix this manually with: kse doctor --fix-gitignore');
211
+ }
212
+
213
+ return {
214
+ success: true,
215
+ fromVersion: plan.fromVersion,
216
+ toVersion: plan.toVersion,
217
+ migrationsExecuted,
218
+ backupId: null, // Backup ID should be set by caller
219
+ errors,
220
+ warnings
221
+ };
222
+ } catch (error) {
223
+ return {
224
+ success: false,
225
+ fromVersion: plan.fromVersion,
226
+ toVersion: plan.toVersion,
227
+ migrationsExecuted,
228
+ backupId: null,
229
+ errors: [error.message, ...errors],
230
+ warnings
231
+ };
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Loads migration script for version transition
237
+ *
238
+ * @param {string} fromVersion - Source version
239
+ * @param {string} toVersion - Target version
240
+ * @returns {Promise<MigrationScript|null>}
241
+ */
242
+ async loadMigration(fromVersion, toVersion) {
243
+ try {
244
+ const scriptPath = await this.findMigrationScript(fromVersion, toVersion);
245
+
246
+ if (!scriptPath) {
247
+ return null;
248
+ }
249
+
250
+ // Load the migration script
251
+ const script = require(scriptPath);
252
+
253
+ // Validate script interface
254
+ if (!script.migrate || typeof script.migrate !== 'function') {
255
+ throw new Error(`Invalid migration script: missing migrate() function`);
256
+ }
257
+
258
+ return script;
259
+ } catch (error) {
260
+ throw new Error(`Failed to load migration script: ${error.message}`);
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Finds migration script file for version transition
266
+ *
267
+ * @param {string} fromVersion - Source version
268
+ * @param {string} toVersion - Target version
269
+ * @returns {Promise<string|null>} - Absolute path to script or null if not found
270
+ */
271
+ async findMigrationScript(fromVersion, toVersion) {
272
+ // Try different naming conventions
273
+ const possibleNames = [
274
+ `${fromVersion}-to-${toVersion}.js`,
275
+ `${fromVersion}_to_${toVersion}.js`,
276
+ `v${fromVersion}-to-v${toVersion}.js`
277
+ ];
278
+
279
+ for (const name of possibleNames) {
280
+ const scriptPath = path.join(this.migrationsDir, name);
281
+ const exists = await pathExists(scriptPath);
282
+
283
+ if (exists) {
284
+ return scriptPath;
285
+ }
286
+ }
287
+
288
+ return null;
289
+ }
290
+
291
+ /**
292
+ * Validates upgrade result
293
+ *
294
+ * @param {string} projectPath - Absolute path to project root
295
+ * @returns {Promise<ValidationResult>}
296
+ */
297
+ async validate(projectPath) {
298
+ const errors = [];
299
+ const warnings = [];
300
+
301
+ try {
302
+ // Check if .kiro/ directory exists
303
+ const kiroPath = path.join(projectPath, '.kiro');
304
+ const kiroExists = await pathExists(kiroPath);
305
+
306
+ if (!kiroExists) {
307
+ errors.push('.kiro/ directory not found');
308
+ return { success: false, errors, warnings };
309
+ }
310
+
311
+ // Check if version.json exists and is valid
312
+ const versionInfo = await this.versionManager.readVersion(projectPath);
313
+
314
+ if (!versionInfo) {
315
+ errors.push('version.json not found or invalid');
316
+ return { success: false, errors, warnings };
317
+ }
318
+
319
+ // Check required directories
320
+ const requiredDirs = ['specs', 'steering', 'tools', 'backups'];
321
+
322
+ for (const dir of requiredDirs) {
323
+ const dirPath = path.join(kiroPath, dir);
324
+ const exists = await pathExists(dirPath);
325
+
326
+ if (!exists) {
327
+ warnings.push(`${dir}/ directory not found`);
328
+ }
329
+ }
330
+
331
+ // Check required steering files
332
+ const requiredSteeringFiles = [
333
+ 'steering/CORE_PRINCIPLES.md',
334
+ 'steering/ENVIRONMENT.md',
335
+ 'steering/CURRENT_CONTEXT.md',
336
+ 'steering/RULES_GUIDE.md'
337
+ ];
338
+
339
+ for (const file of requiredSteeringFiles) {
340
+ const filePath = path.join(kiroPath, file);
341
+ const exists = await pathExists(filePath);
342
+
343
+ if (!exists) {
344
+ warnings.push(`${file} not found`);
345
+ }
346
+ }
347
+
348
+ return {
349
+ success: errors.length === 0,
350
+ errors,
351
+ warnings
352
+ };
353
+ } catch (error) {
354
+ errors.push(`Validation failed: ${error.message}`);
355
+ return { success: false, errors, warnings };
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Gets available migrations
361
+ *
362
+ * @returns {Promise<string[]>} - Array of migration script names
363
+ */
364
+ async getAvailableMigrations() {
365
+ try {
366
+ const exists = await pathExists(this.migrationsDir);
367
+
368
+ if (!exists) {
369
+ return [];
370
+ }
371
+
372
+ const fs = require('fs-extra');
373
+ const files = await fs.readdir(this.migrationsDir);
374
+
375
+ return files.filter(file => file.endsWith('.js'));
376
+ } catch (error) {
377
+ return [];
378
+ }
379
+ }
380
+ }
381
+
382
+ module.exports = MigrationEngine;
@@ -0,0 +1,52 @@
1
+ # Migration Scripts Directory
2
+
3
+ This directory contains migration scripts for upgrading between versions.
4
+
5
+ ## Migration Script Format
6
+
7
+ Each migration script should follow this format:
8
+
9
+ ```javascript
10
+ module.exports = {
11
+ version: "1.1.0",
12
+ breaking: false,
13
+ description: "Description of what this migration does",
14
+
15
+ /**
16
+ * Executes migration
17
+ * @param {string} projectPath - Absolute path to project root
18
+ * @param {MigrationContext} context - Migration context
19
+ * @returns {Promise<MigrationResult>}
20
+ */
21
+ async migrate(projectPath, context) {
22
+ const changes = [];
23
+
24
+ // Migration logic here
25
+ // Example: Update file structure, modify configs, etc.
26
+
27
+ return {
28
+ success: true,
29
+ changes
30
+ };
31
+ },
32
+
33
+ /**
34
+ * Rolls back migration (optional)
35
+ * @param {string} projectPath - Absolute path to project root
36
+ * @param {MigrationContext} context - Migration context
37
+ * @returns {Promise<void>}
38
+ */
39
+ async rollback(projectPath, context) {
40
+ // Rollback logic here
41
+ }
42
+ };
43
+ ```
44
+
45
+ ## Naming Convention
46
+
47
+ Migration scripts should be named: `{fromVersion}-to-{toVersion}.js`
48
+
49
+ Examples:
50
+ - `1.0.0-to-1.1.0.js`
51
+ - `1.1.0-to-1.2.0.js`
52
+ - `1.2.0-to-2.0.0.js`
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Migration: 1.0.0 → 1.1.0
3
+ *
4
+ * Adds version management foundation:
5
+ * - Ensures version.json exists with correct structure
6
+ * - Adds backups/ directory if missing
7
+ * - No breaking changes
8
+ */
9
+
10
+ const path = require('path');
11
+ const { pathExists, ensureDirectory, writeJSON } = require('../../utils/fs-utils');
12
+
13
+ module.exports = {
14
+ version: "1.1.0",
15
+ breaking: false,
16
+ description: "Add version management foundation (version.json, backups/)",
17
+
18
+ /**
19
+ * Executes migration from 1.0.0 to 1.1.0
20
+ *
21
+ * @param {string} projectPath - Absolute path to project root
22
+ * @param {MigrationContext} context - Migration context
23
+ * @returns {Promise<MigrationResult>}
24
+ */
25
+ async migrate(projectPath, context) {
26
+ const changes = [];
27
+
28
+ try {
29
+ const kiroPath = path.join(projectPath, '.kiro');
30
+
31
+ // 1. Ensure backups/ directory exists
32
+ const backupsPath = path.join(kiroPath, 'backups');
33
+ const backupsExists = await pathExists(backupsPath);
34
+
35
+ if (!backupsExists) {
36
+ await ensureDirectory(backupsPath);
37
+ changes.push('Created backups/ directory');
38
+ }
39
+
40
+ // 2. Ensure version.json has correct structure
41
+ // (This is handled by VersionManager, but we verify it here)
42
+ const versionPath = path.join(kiroPath, 'version.json');
43
+ const versionExists = await pathExists(versionPath);
44
+
45
+ if (versionExists) {
46
+ changes.push('Verified version.json structure');
47
+ } else {
48
+ changes.push('version.json will be created by VersionManager');
49
+ }
50
+
51
+ // 3. Add any other 1.1.0-specific changes here
52
+ // (None for this version - it's just the foundation)
53
+
54
+ return {
55
+ success: true,
56
+ changes
57
+ };
58
+ } catch (error) {
59
+ throw new Error(`Migration 1.0.0 → 1.1.0 failed: ${error.message}`);
60
+ }
61
+ },
62
+
63
+ /**
64
+ * Rolls back migration from 1.1.0 to 1.0.0
65
+ *
66
+ * @param {string} projectPath - Absolute path to project root
67
+ * @param {MigrationContext} context - Migration context
68
+ * @returns {Promise<void>}
69
+ */
70
+ async rollback(projectPath, context) {
71
+ // For 1.0.0 → 1.1.0, rollback is simple:
72
+ // - Remove backups/ directory (but keep backups for safety)
73
+ // - version.json will be handled by VersionManager
74
+
75
+ // Note: We don't actually remove anything to preserve data safety
76
+ // The backup system will handle restoration if needed
77
+ }
78
+ };
@@ -0,0 +1,177 @@
1
+ /**
2
+ * File Diff Utility
3
+ *
4
+ * Provides file comparison and diff detection functionality
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const crypto = require('crypto');
9
+ const path = require('path');
10
+
11
+ class FileDiff {
12
+ /**
13
+ * Calculate file hash
14
+ *
15
+ * @param {string} filePath - Path to file
16
+ * @param {string} algorithm - Hash algorithm (default: 'md5')
17
+ * @returns {Promise<string>} File hash
18
+ */
19
+ async calculateHash(filePath, algorithm = 'md5') {
20
+ if (!await fs.pathExists(filePath)) {
21
+ return null;
22
+ }
23
+
24
+ const content = await fs.readFile(filePath);
25
+ return crypto.createHash(algorithm).update(content).digest('hex');
26
+ }
27
+
28
+ /**
29
+ * Compare two files by content
30
+ *
31
+ * @param {string} file1Path - Path to first file
32
+ * @param {string} file2Path - Path to second file
33
+ * @returns {Promise<boolean>} True if files are identical
34
+ */
35
+ async areFilesIdentical(file1Path, file2Path) {
36
+ // Check if both files exist
37
+ const file1Exists = await fs.pathExists(file1Path);
38
+ const file2Exists = await fs.pathExists(file2Path);
39
+
40
+ if (!file1Exists || !file2Exists) {
41
+ return false;
42
+ }
43
+
44
+ // Compare file sizes first (quick check)
45
+ const stat1 = await fs.stat(file1Path);
46
+ const stat2 = await fs.stat(file2Path);
47
+
48
+ if (stat1.size !== stat2.size) {
49
+ return false;
50
+ }
51
+
52
+ // Compare content hashes
53
+ const hash1 = await this.calculateHash(file1Path);
54
+ const hash2 = await this.calculateHash(file2Path);
55
+
56
+ return hash1 === hash2;
57
+ }
58
+
59
+ /**
60
+ * Compare multiple file pairs
61
+ *
62
+ * @param {Array<{source: string, target: string}>} filePairs - Array of file pairs to compare
63
+ * @param {string} projectRoot - Project root path
64
+ * @returns {Promise<Object>} Comparison results
65
+ */
66
+ async compareFiles(filePairs, projectRoot) {
67
+ const results = {
68
+ identical: [], // Files with same content
69
+ different: [], // Files with different content
70
+ newFiles: [], // Files that don't exist in target
71
+ errors: [] // Files that couldn't be compared
72
+ };
73
+
74
+ for (const pair of filePairs) {
75
+ try {
76
+ const sourcePath = path.isAbsolute(pair.source)
77
+ ? pair.source
78
+ : path.join(projectRoot, pair.source);
79
+ const targetPath = path.isAbsolute(pair.target)
80
+ ? pair.target
81
+ : path.join(projectRoot, pair.target);
82
+
83
+ const targetExists = await fs.pathExists(targetPath);
84
+
85
+ if (!targetExists) {
86
+ results.newFiles.push({
87
+ source: pair.source,
88
+ target: pair.target,
89
+ reason: 'Target file does not exist'
90
+ });
91
+ continue;
92
+ }
93
+
94
+ const identical = await this.areFilesIdentical(sourcePath, targetPath);
95
+
96
+ if (identical) {
97
+ results.identical.push({
98
+ source: pair.source,
99
+ target: pair.target
100
+ });
101
+ } else {
102
+ results.different.push({
103
+ source: pair.source,
104
+ target: pair.target
105
+ });
106
+ }
107
+ } catch (error) {
108
+ results.errors.push({
109
+ source: pair.source,
110
+ target: pair.target,
111
+ error: error.message
112
+ });
113
+ }
114
+ }
115
+
116
+ return results;
117
+ }
118
+
119
+ /**
120
+ * Get file change summary
121
+ *
122
+ * @param {Object} comparisonResults - Results from compareFiles
123
+ * @returns {Object} Summary statistics
124
+ */
125
+ getSummary(comparisonResults) {
126
+ return {
127
+ total: comparisonResults.identical.length +
128
+ comparisonResults.different.length +
129
+ comparisonResults.newFiles.length,
130
+ identical: comparisonResults.identical.length,
131
+ different: comparisonResults.different.length,
132
+ newFiles: comparisonResults.newFiles.length,
133
+ errors: comparisonResults.errors.length,
134
+ needsUpdate: comparisonResults.different.length + comparisonResults.newFiles.length > 0
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Filter files that need update
140
+ *
141
+ * @param {Object} comparisonResults - Results from compareFiles
142
+ * @returns {Array} Files that need to be updated
143
+ */
144
+ getFilesNeedingUpdate(comparisonResults) {
145
+ return [
146
+ ...comparisonResults.different.map(f => ({ ...f, action: 'update' })),
147
+ ...comparisonResults.newFiles.map(f => ({ ...f, action: 'create' }))
148
+ ];
149
+ }
150
+
151
+ /**
152
+ * Check if steering files have changed
153
+ *
154
+ * @param {string} projectRoot - Project root path
155
+ * @param {string} templateRoot - Template root path
156
+ * @returns {Promise<Object>} Steering files comparison
157
+ */
158
+ async compareSteeringFiles(projectRoot, templateRoot) {
159
+ const steeringFiles = [
160
+ '.kiro/steering/CORE_PRINCIPLES.md',
161
+ '.kiro/steering/ENVIRONMENT.md',
162
+ '.kiro/steering/CURRENT_CONTEXT.md',
163
+ '.kiro/steering/RULES_GUIDE.md',
164
+ '.kiro/specs/SPEC_WORKFLOW_GUIDE.md',
165
+ '.kiro/README.md'
166
+ ];
167
+
168
+ const filePairs = steeringFiles.map(file => ({
169
+ source: path.join(templateRoot, file),
170
+ target: path.join(projectRoot, file)
171
+ }));
172
+
173
+ return await this.compareFiles(filePairs, projectRoot);
174
+ }
175
+ }
176
+
177
+ module.exports = FileDiff;