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,249 @@
1
+ /**
2
+ * TemplateApplicator - Applies templates to create new Specs
3
+ *
4
+ * Handles file copying, variable substitution, and frontmatter removal.
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const { FileSystemError } = require('./template-error');
10
+
11
+ class TemplateApplicator {
12
+ constructor() {
13
+ this.requiredFiles = ['requirements.md', 'design.md', 'tasks.md'];
14
+ }
15
+
16
+ /**
17
+ * Applies a template to create a new Spec
18
+ *
19
+ * @param {string} specName - Spec name (e.g., 'user-authentication')
20
+ * @param {string} templatePath - Path to template directory
21
+ * @param {string} targetDir - Target Spec directory
22
+ * @param {Object} options - Application options
23
+ * @param {boolean} options.force - Overwrite existing files
24
+ * @param {Object} options.variables - Custom variables
25
+ * @returns {Promise<Object>} Application result
26
+ */
27
+ async applyTemplate(specName, templatePath, targetDir, options = {}) {
28
+ const { force = false, variables = {} } = options;
29
+
30
+ const result = {
31
+ success: true,
32
+ filesCreated: [],
33
+ filesSkipped: [],
34
+ errors: []
35
+ };
36
+
37
+ // Check if template exists
38
+ if (!await fs.pathExists(templatePath)) {
39
+ throw new FileSystemError(
40
+ 'Template directory does not exist',
41
+ { templatePath }
42
+ );
43
+ }
44
+
45
+ // Check if target directory exists
46
+ if (await fs.pathExists(targetDir) && !force) {
47
+ throw new FileSystemError(
48
+ 'Target directory already exists',
49
+ {
50
+ targetDir,
51
+ suggestion: 'Use --force to overwrite or choose a different name'
52
+ }
53
+ );
54
+ }
55
+
56
+ // Create target directory
57
+ await fs.ensureDir(targetDir);
58
+
59
+ // Prepare variables
60
+ const allVariables = this._prepareVariables(specName, variables);
61
+
62
+ // Copy and transform files
63
+ for (const file of this.requiredFiles) {
64
+ const sourcePath = path.join(templatePath, file);
65
+ const targetPath = path.join(targetDir, file);
66
+
67
+ if (!await fs.pathExists(sourcePath)) {
68
+ result.errors.push(`Template missing file: ${file}`);
69
+ continue;
70
+ }
71
+
72
+ try {
73
+ // Read source file
74
+ let content = await fs.readFile(sourcePath, 'utf8');
75
+
76
+ // Remove frontmatter
77
+ content = this.removeFrontmatter(content);
78
+
79
+ // Transform variables
80
+ content = this.transformVariables(content, allVariables);
81
+
82
+ // Normalize line endings
83
+ content = this.normalizeLineEndings(content);
84
+
85
+ // Write target file
86
+ await fs.writeFile(targetPath, content, 'utf8');
87
+
88
+ result.filesCreated.push(file);
89
+ } catch (error) {
90
+ result.errors.push(`Failed to process ${file}: ${error.message}`);
91
+ result.success = false;
92
+ }
93
+ }
94
+
95
+ return result;
96
+ }
97
+
98
+ /**
99
+ * Prepares variables for substitution
100
+ *
101
+ * @param {string} specName - Spec name
102
+ * @param {Object} customVariables - Custom variables
103
+ * @returns {Object} All variables
104
+ * @private
105
+ */
106
+ _prepareVariables(specName, customVariables = {}) {
107
+ const now = new Date();
108
+
109
+ // Convert kebab-case to Title Case (preserve hyphens for numbers)
110
+ const specNameTitle = specName
111
+ .split('-')
112
+ .map(word => {
113
+ // If word is all digits, keep it as is
114
+ if (/^\d+$/.test(word)) {
115
+ return word;
116
+ }
117
+ // Otherwise capitalize first letter
118
+ return word.charAt(0).toUpperCase() + word.slice(1);
119
+ })
120
+ .join(' ');
121
+
122
+ const defaultVariables = {
123
+ SPEC_NAME: specName,
124
+ SPEC_NAME_TITLE: specNameTitle,
125
+ DATE: now.toISOString().split('T')[0],
126
+ YEAR: now.getFullYear().toString(),
127
+ AUTHOR: this._getAuthorName(),
128
+ PROJECT_NAME: this._getProjectName()
129
+ };
130
+
131
+ return { ...defaultVariables, ...customVariables };
132
+ }
133
+
134
+ /**
135
+ * Gets author name from Git config
136
+ *
137
+ * @returns {string} Author name
138
+ * @private
139
+ */
140
+ _getAuthorName() {
141
+ try {
142
+ const { execSync } = require('child_process');
143
+ const name = execSync('git config user.name', { encoding: 'utf8' }).trim();
144
+ return name || 'Unknown';
145
+ } catch (error) {
146
+ return 'Unknown';
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Gets project name from package.json or directory
152
+ *
153
+ * @returns {string} Project name
154
+ * @private
155
+ */
156
+ _getProjectName() {
157
+ try {
158
+ const packagePath = path.join(process.cwd(), 'package.json');
159
+ if (fs.existsSync(packagePath)) {
160
+ const pkg = require(packagePath);
161
+ return pkg.name || path.basename(process.cwd());
162
+ }
163
+ } catch (error) {
164
+ // Ignore
165
+ }
166
+
167
+ return path.basename(process.cwd());
168
+ }
169
+
170
+ /**
171
+ * Removes YAML frontmatter from content
172
+ *
173
+ * @param {string} content - File content
174
+ * @returns {string} Content without frontmatter
175
+ */
176
+ removeFrontmatter(content) {
177
+ // Normalize line endings first
178
+ const normalized = content.replace(/\r\n/g, '\n');
179
+ // Remove frontmatter
180
+ return normalized.replace(/^---\n[\s\S]*?\n---\n/, '');
181
+ }
182
+
183
+ /**
184
+ * Transforms variables in content
185
+ *
186
+ * @param {string} content - File content
187
+ * @param {Object} variables - Variables to substitute
188
+ * @returns {string} Transformed content
189
+ */
190
+ transformVariables(content, variables) {
191
+ let result = content;
192
+
193
+ for (const [key, value] of Object.entries(variables)) {
194
+ const placeholder = `{{${key}}}`;
195
+ result = result.split(placeholder).join(value);
196
+ }
197
+
198
+ return result;
199
+ }
200
+
201
+ /**
202
+ * Normalizes line endings to LF
203
+ *
204
+ * @param {string} content - File content
205
+ * @returns {string} Content with LF line endings
206
+ */
207
+ normalizeLineEndings(content) {
208
+ return content.replace(/\r\n/g, '\n');
209
+ }
210
+
211
+ /**
212
+ * Handles file conflict
213
+ *
214
+ * @param {string} targetPath - Target file path
215
+ * @param {string} strategy - Conflict strategy ('overwrite', 'skip', 'rename')
216
+ * @returns {Promise<string>} Resolved target path
217
+ */
218
+ async handleConflict(targetPath, strategy = 'skip') {
219
+ if (!await fs.pathExists(targetPath)) {
220
+ return targetPath;
221
+ }
222
+
223
+ switch (strategy) {
224
+ case 'overwrite':
225
+ return targetPath;
226
+
227
+ case 'skip':
228
+ return null;
229
+
230
+ case 'rename':
231
+ let counter = 1;
232
+ let newPath = targetPath;
233
+ const ext = path.extname(targetPath);
234
+ const base = targetPath.slice(0, -ext.length);
235
+
236
+ while (await fs.pathExists(newPath)) {
237
+ newPath = `${base}-${counter}${ext}`;
238
+ counter++;
239
+ }
240
+
241
+ return newPath;
242
+
243
+ default:
244
+ return targetPath;
245
+ }
246
+ }
247
+ }
248
+
249
+ module.exports = TemplateApplicator;
@@ -0,0 +1,256 @@
1
+ /**
2
+ * TemplateCreator - Main orchestrator for template creation workflow
3
+ */
4
+
5
+ const SpecReader = require('./spec-reader');
6
+ const ContentGeneralizer = require('./content-generalizer');
7
+ const MetadataCollector = require('./metadata-collector');
8
+ const FrontmatterGenerator = require('./frontmatter-generator');
9
+ const TemplateValidator = require('./template-validator');
10
+ const TemplateExporter = require('./template-exporter');
11
+
12
+ class TemplateCreator {
13
+ constructor(options = {}) {
14
+ this.options = options;
15
+ this.specReader = new SpecReader();
16
+ this.contentGeneralizer = new ContentGeneralizer();
17
+ this.metadataCollector = new MetadataCollector(options);
18
+ this.frontmatterGenerator = new FrontmatterGenerator();
19
+ this.templateValidator = new TemplateValidator();
20
+ this.templateExporter = new TemplateExporter();
21
+ }
22
+
23
+ /**
24
+ * Creates a template from an existing Spec
25
+ * @param {Object} options - Creation options
26
+ * @returns {Promise<Object>} Creation result
27
+ */
28
+ async createTemplate(options) {
29
+ const {
30
+ spec,
31
+ output,
32
+ preview = false,
33
+ dryRun = false,
34
+ interactive = true
35
+ } = options;
36
+
37
+ try {
38
+ console.log('🚀 Starting template creation...\n');
39
+
40
+ // Step 1: Read and validate Spec
41
+ console.log('📖 Step 1: Reading Spec...');
42
+ const specInfo = await this.specReader.findSpec(spec);
43
+ console.log(` Found: ${specInfo.name}`);
44
+
45
+ const validation = await this.specReader.validateSpecStructure(specInfo.path);
46
+ if (!validation.valid) {
47
+ throw new Error(`Missing required files: ${validation.missingFiles.join(', ')}`);
48
+ }
49
+ console.log(` ✓ All required files present\n`);
50
+
51
+ const fileContents = await this.specReader.readSpecFiles(specInfo.path);
52
+ const specMetadata = this.specReader.extractSpecMetadata(specInfo.path, fileContents);
53
+
54
+ // Step 2: Generalize content
55
+ console.log('🔄 Step 2: Generalizing content...');
56
+ const generalizationResult = this.contentGeneralizer.generalize(fileContents, specMetadata);
57
+ console.log(` Replacements: ${generalizationResult.summary.totalReplacements}`);
58
+ console.log(` Flags: ${generalizationResult.summary.totalFlags}\n`);
59
+
60
+ // Step 3: Collect metadata
61
+ console.log('📝 Step 3: Collecting metadata...');
62
+ const metadata = await this.metadataCollector.collectMetadata(specMetadata, interactive);
63
+ console.log(` ✓ Metadata collected\n`);
64
+
65
+ // Step 4: Generate frontmatter
66
+ console.log('📄 Step 4: Generating frontmatter...');
67
+ const frontmatter = this.frontmatterGenerator.generateFrontmatter(metadata);
68
+ const filesWithFrontmatter = {};
69
+
70
+ for (const [filename, fileData] of Object.entries(generalizationResult.files)) {
71
+ if (fileData.generalized) {
72
+ filesWithFrontmatter[filename] = this.frontmatterGenerator.addFrontmatter(
73
+ fileData.generalized,
74
+ frontmatter
75
+ );
76
+ }
77
+ }
78
+ console.log(` ✓ Frontmatter added to all files\n`);
79
+
80
+ // Step 5: Validate template
81
+ console.log('✅ Step 5: Validating template...');
82
+ const validationResult = await this.validateTemplate(filesWithFrontmatter, metadata);
83
+ console.log(` Quality Score: ${validationResult.score}/100`);
84
+ console.log(` Errors: ${validationResult.errors.length}`);
85
+ console.log(` Warnings: ${validationResult.warnings.length}\n`);
86
+
87
+ if (validationResult.errors.length > 0) {
88
+ console.log('❌ Validation Errors:');
89
+ validationResult.errors.forEach(error => console.log(` - ${error}`));
90
+ console.log('');
91
+ }
92
+
93
+ if (validationResult.warnings.length > 0) {
94
+ console.log('⚠️ Validation Warnings:');
95
+ validationResult.warnings.forEach(warning => console.log(` - ${warning}`));
96
+ console.log('');
97
+ }
98
+
99
+ // Step 6: Preview (if requested)
100
+ if (preview) {
101
+ console.log('👀 Preview:');
102
+ this.showPreview(fileContents, generalizationResult);
103
+ console.log('');
104
+ }
105
+
106
+ // Step 7: Export template
107
+ if (dryRun) {
108
+ console.log('🏃 Dry run mode - skipping export\n');
109
+ return {
110
+ success: true,
111
+ dryRun: true,
112
+ metadata,
113
+ validationResult
114
+ };
115
+ }
116
+
117
+ console.log('📦 Step 6: Exporting template...');
118
+ const exportResult = await this.templateExporter.exportTemplate(
119
+ {
120
+ metadata,
121
+ files: filesWithFrontmatter,
122
+ validationResult,
123
+ generalizationResult
124
+ },
125
+ output
126
+ );
127
+
128
+ console.log(` ✓ Template exported to: ${exportResult.outputDir}\n`);
129
+
130
+ // Final summary
131
+ console.log('✨ Template creation complete!\n');
132
+ console.log('📁 Files created:');
133
+ exportResult.filesCreated.forEach(file => console.log(` - ${file}`));
134
+ console.log('');
135
+ console.log('📖 Next steps:');
136
+ console.log(` 1. Review the template in: ${exportResult.outputDir}`);
137
+ console.log(` 2. Check REVIEW_CHECKLIST.md for items to verify`);
138
+ console.log(` 3. Test the template: kse spec create test --template ${metadata.name}`);
139
+ console.log(` 4. Follow SUBMISSION_GUIDE.md to submit to repository`);
140
+ console.log('');
141
+
142
+ return exportResult;
143
+
144
+ } catch (error) {
145
+ console.error(`\n❌ Error: ${error.message}\n`);
146
+ throw error;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Validates template
152
+ * @param {Object} files - Template files
153
+ * @param {Object} metadata - Template metadata
154
+ * @returns {Promise<Object>} Validation result
155
+ */
156
+ async validateTemplate(files, metadata) {
157
+ const errors = [];
158
+ const warnings = [];
159
+ let score = 100;
160
+
161
+ // Validate frontmatter in each file
162
+ for (const [filename, content] of Object.entries(files)) {
163
+ if (!content) continue;
164
+
165
+ // Check for frontmatter
166
+ if (!content.trim().startsWith('---')) {
167
+ errors.push(`${filename}: Missing YAML frontmatter`);
168
+ score -= 10;
169
+ continue;
170
+ }
171
+
172
+ // Validate YAML syntax
173
+ const yamlValidation = this.frontmatterGenerator.validateYaml(
174
+ content.split('---')[1]
175
+ );
176
+ if (!yamlValidation.valid) {
177
+ errors.push(`${filename}: Invalid YAML frontmatter - ${yamlValidation.errors.join(', ')}`);
178
+ score -= 10;
179
+ }
180
+
181
+ // Check for remaining project-specific content (high confidence patterns)
182
+ const projectSpecificPatterns = [
183
+ /\.kiro\/specs\/\d+-\d+-[a-z-]+/g, // Specific spec paths
184
+ /kiro-spec-engine/g, // Project name (unless it's the template itself)
185
+ ];
186
+
187
+ projectSpecificPatterns.forEach(pattern => {
188
+ const matches = content.match(pattern);
189
+ if (matches && matches.length > 3) { // Allow a few occurrences
190
+ warnings.push(`${filename}: Possible project-specific content: ${matches[0]}`);
191
+ score -= 2;
192
+ }
193
+ });
194
+
195
+ // Check for template variable syntax
196
+ const malformedVariables = content.match(/\{\{[^}]*\}\}(?!\})/g);
197
+ if (malformedVariables) {
198
+ malformedVariables.forEach(v => {
199
+ if (!/^\{\{[A-Z_]+\}\}$/.test(v)) {
200
+ warnings.push(`${filename}: Malformed template variable: ${v}`);
201
+ score -= 1;
202
+ }
203
+ });
204
+ }
205
+ }
206
+
207
+ // Validate metadata
208
+ const metadataValidation = this.metadataCollector.validateMetadata(metadata);
209
+ if (!metadataValidation.valid) {
210
+ errors.push(...metadataValidation.errors);
211
+ score -= 15;
212
+ }
213
+
214
+ // Ensure score doesn't go below 0
215
+ score = Math.max(0, score);
216
+
217
+ return {
218
+ valid: errors.length === 0,
219
+ score,
220
+ errors,
221
+ warnings,
222
+ breakdown: {
223
+ structure: errors.length === 0 ? 30 : 15,
224
+ frontmatter: errors.filter(e => e.includes('frontmatter')).length === 0 ? 20 : 10,
225
+ variables: warnings.filter(w => w.includes('variable')).length === 0 ? 20 : 15,
226
+ content: warnings.filter(w => w.includes('project-specific')).length === 0 ? 20 : 15,
227
+ references: 10
228
+ }
229
+ };
230
+ }
231
+
232
+ /**
233
+ * Shows preview of changes
234
+ * @param {Object} originalContent - Original Spec content
235
+ * @param {Object} generalizationResult - Generalization result
236
+ */
237
+ showPreview(originalContent, generalizationResult) {
238
+ for (const [filename, fileData] of Object.entries(generalizationResult.files)) {
239
+ console.log(`\n📄 ${filename}:`);
240
+ console.log(` Replacements: ${fileData.replacements.length}`);
241
+
242
+ fileData.replacements.forEach(r => {
243
+ console.log(` - ${r.pattern} → ${r.variable} (${r.count} times)`);
244
+ });
245
+
246
+ if (fileData.flags.length > 0) {
247
+ console.log(` Flags: ${fileData.flags.length}`);
248
+ fileData.flags.forEach(f => {
249
+ console.log(` - Line ${f.line}: ${f.message} - "${f.content}"`);
250
+ });
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ module.exports = TemplateCreator;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Template Error Classes
3
+ *
4
+ * Provides specialized error types for template operations with
5
+ * context-specific error messages and troubleshooting suggestions.
6
+ */
7
+
8
+ /**
9
+ * Base error class for all template-related errors
10
+ */
11
+ class TemplateError extends Error {
12
+ constructor(type, message, details = {}) {
13
+ super(message);
14
+ this.name = 'TemplateError';
15
+ this.type = type;
16
+ this.details = details;
17
+ this.suggestions = this.generateSuggestions();
18
+
19
+ // Maintain proper stack trace
20
+ if (Error.captureStackTrace) {
21
+ Error.captureStackTrace(this, this.constructor);
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Generate context-specific troubleshooting suggestions
27
+ * @returns {string[]} Array of suggestion strings
28
+ */
29
+ generateSuggestions() {
30
+ switch (this.type) {
31
+ case 'network':
32
+ return [
33
+ 'Check your internet connection',
34
+ 'Verify the repository URL is correct',
35
+ 'Try again later if the service is temporarily unavailable',
36
+ 'Check if you need to configure proxy settings'
37
+ ];
38
+
39
+ case 'validation':
40
+ return [
41
+ 'Review the template structure requirements',
42
+ 'Check the YAML frontmatter syntax',
43
+ 'Ensure all required fields are present',
44
+ 'Refer to CONTRIBUTING.md for template format'
45
+ ];
46
+
47
+ case 'filesystem':
48
+ return [
49
+ 'Check file permissions',
50
+ 'Ensure sufficient disk space',
51
+ 'Verify the path is correct',
52
+ 'Try running with elevated permissions if needed'
53
+ ];
54
+
55
+ case 'git':
56
+ return [
57
+ 'Ensure Git is installed and in PATH',
58
+ 'Check repository URL is accessible',
59
+ 'Verify Git credentials if repository is private',
60
+ 'Try clearing the cache and re-downloading'
61
+ ];
62
+
63
+ default:
64
+ return [
65
+ 'Check the error details above',
66
+ 'Refer to documentation for troubleshooting',
67
+ 'Report this issue if the problem persists'
68
+ ];
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Format error for display to user
74
+ * @returns {string} Formatted error message
75
+ */
76
+ format() {
77
+ let output = `\n❌ ${this.message}\n`;
78
+
79
+ if (Object.keys(this.details).length > 0) {
80
+ output += '\nDetails:\n';
81
+ for (const [key, value] of Object.entries(this.details)) {
82
+ output += ` ${key}: ${value}\n`;
83
+ }
84
+ }
85
+
86
+ if (this.suggestions.length > 0) {
87
+ output += '\nSuggestions:\n';
88
+ this.suggestions.forEach((suggestion, index) => {
89
+ output += ` ${index + 1}. ${suggestion}\n`;
90
+ });
91
+ }
92
+
93
+ return output;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Network-related errors (download, clone, pull)
99
+ */
100
+ class NetworkError extends TemplateError {
101
+ constructor(message, details = {}) {
102
+ super('network', message, details);
103
+ this.name = 'NetworkError';
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Template validation errors
109
+ */
110
+ class ValidationError extends TemplateError {
111
+ constructor(message, details = {}) {
112
+ super('validation', message, details);
113
+ this.name = 'ValidationError';
114
+ }
115
+ }
116
+
117
+ /**
118
+ * File system operation errors
119
+ */
120
+ class FileSystemError extends TemplateError {
121
+ constructor(message, details = {}) {
122
+ super('filesystem', message, details);
123
+ this.name = 'FileSystemError';
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Git operation errors
129
+ */
130
+ class GitError extends TemplateError {
131
+ constructor(message, details = {}) {
132
+ super('git', message, details);
133
+ this.name = 'GitError';
134
+ }
135
+ }
136
+
137
+ module.exports = {
138
+ TemplateError,
139
+ NetworkError,
140
+ ValidationError,
141
+ FileSystemError,
142
+ GitError
143
+ };