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,328 @@
1
+ /**
2
+ * MetadataCollector - Collects template metadata through interactive prompts
3
+ */
4
+
5
+ const inquirer = require('inquirer');
6
+ const { execSync } = require('child_process');
7
+
8
+ class MetadataCollector {
9
+ constructor(options = {}) {
10
+ this.interactive = options.interactive !== false;
11
+ this.categories = [
12
+ 'web-features',
13
+ 'backend-features',
14
+ 'infrastructure',
15
+ 'testing',
16
+ 'documentation',
17
+ 'other'
18
+ ];
19
+ }
20
+
21
+ /**
22
+ * Collects all template metadata
23
+ * @param {Object} specMetadata - Extracted Spec metadata
24
+ * @param {boolean} interactive - Use interactive prompts
25
+ * @returns {Promise<Object>} Template metadata
26
+ */
27
+ async collectMetadata(specMetadata, interactive = this.interactive) {
28
+ if (!interactive) {
29
+ return this.getDefaultMetadata(specMetadata);
30
+ }
31
+
32
+ const metadata = {};
33
+
34
+ // Template name
35
+ metadata.name = await this.promptTemplateName(specMetadata.specName);
36
+
37
+ // Description
38
+ metadata.description = await this.promptDescription();
39
+
40
+ // Category
41
+ metadata.category = await this.promptCategory();
42
+
43
+ // Tags
44
+ const suggestedTags = this.suggestTags({ 'requirements.md': '' });
45
+ metadata.tags = await this.promptTags(suggestedTags);
46
+
47
+ // Author
48
+ metadata.author = await this.promptAuthor(specMetadata.author);
49
+
50
+ // Version
51
+ metadata.version = await this.promptVersion();
52
+
53
+ // KSE version
54
+ metadata.kse_version = await this.promptKseVersion();
55
+
56
+ // Timestamps
57
+ const now = new Date().toISOString().split('T')[0];
58
+ metadata.created_at = now;
59
+ metadata.updated_at = now;
60
+
61
+ // Validate and confirm
62
+ const validation = this.validateMetadata(metadata);
63
+ if (!validation.valid) {
64
+ throw new Error(`Metadata validation failed: ${validation.errors.join(', ')}`);
65
+ }
66
+
67
+ console.log('\n📋 Metadata Summary:');
68
+ console.log(JSON.stringify(metadata, null, 2));
69
+
70
+ const { confirmed } = await inquirer.prompt([
71
+ {
72
+ type: 'confirm',
73
+ name: 'confirmed',
74
+ message: 'Confirm metadata?',
75
+ default: true
76
+ }
77
+ ]);
78
+
79
+ if (!confirmed) {
80
+ throw new Error('Metadata collection cancelled by user');
81
+ }
82
+
83
+ return metadata;
84
+ }
85
+
86
+ /**
87
+ * Prompts for template name
88
+ * @param {string} defaultName - Default name
89
+ * @returns {Promise<string>} Template name
90
+ */
91
+ async promptTemplateName(defaultName) {
92
+ const { name } = await inquirer.prompt([
93
+ {
94
+ type: 'input',
95
+ name: 'name',
96
+ message: 'Template name (kebab-case):',
97
+ default: defaultName,
98
+ validate: (input) => {
99
+ if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(input)) {
100
+ return 'Name must be in kebab-case format (lowercase, hyphens only)';
101
+ }
102
+ return true;
103
+ }
104
+ }
105
+ ]);
106
+ return name;
107
+ }
108
+
109
+ /**
110
+ * Prompts for description
111
+ * @returns {Promise<string>} Description
112
+ */
113
+ async promptDescription() {
114
+ const { description } = await inquirer.prompt([
115
+ {
116
+ type: 'input',
117
+ name: 'description',
118
+ message: 'Brief description (1-2 sentences):',
119
+ validate: (input) => {
120
+ if (input.length < 10) {
121
+ return 'Description must be at least 10 characters';
122
+ }
123
+ if (input.length > 200) {
124
+ return 'Description must be less than 200 characters';
125
+ }
126
+ return true;
127
+ }
128
+ }
129
+ ]);
130
+ return description;
131
+ }
132
+
133
+ /**
134
+ * Prompts for category
135
+ * @returns {Promise<string>} Selected category
136
+ */
137
+ async promptCategory() {
138
+ const { category } = await inquirer.prompt([
139
+ {
140
+ type: 'list',
141
+ name: 'category',
142
+ message: 'Select category:',
143
+ choices: this.categories
144
+ }
145
+ ]);
146
+ return category;
147
+ }
148
+
149
+ /**
150
+ * Prompts for tags
151
+ * @param {Array} suggestedTags - Suggested tags
152
+ * @returns {Promise<Array>} Tags
153
+ */
154
+ async promptTags(suggestedTags = []) {
155
+ const suggestionText = suggestedTags.length > 0
156
+ ? ` (suggested: ${suggestedTags.join(', ')})`
157
+ : '';
158
+
159
+ const { tagsInput } = await inquirer.prompt([
160
+ {
161
+ type: 'input',
162
+ name: 'tagsInput',
163
+ message: `Tags (comma-separated)${suggestionText}:`,
164
+ default: suggestedTags.join(', ')
165
+ }
166
+ ]);
167
+
168
+ return tagsInput
169
+ .split(',')
170
+ .map(tag => tag.trim().toLowerCase())
171
+ .filter(tag => tag.length > 0);
172
+ }
173
+
174
+ /**
175
+ * Prompts for author
176
+ * @param {string} defaultAuthor - Default author
177
+ * @returns {Promise<string>} Author name
178
+ */
179
+ async promptAuthor(defaultAuthor) {
180
+ const { author } = await inquirer.prompt([
181
+ {
182
+ type: 'input',
183
+ name: 'author',
184
+ message: 'Author name:',
185
+ default: defaultAuthor || this.getGitUser()
186
+ }
187
+ ]);
188
+ return author;
189
+ }
190
+
191
+ /**
192
+ * Prompts for version
193
+ * @returns {Promise<string>} Version
194
+ */
195
+ async promptVersion() {
196
+ const { version } = await inquirer.prompt([
197
+ {
198
+ type: 'input',
199
+ name: 'version',
200
+ message: 'Template version:',
201
+ default: '1.0.0',
202
+ validate: (input) => {
203
+ if (!/^\d+\.\d+\.\d+$/.test(input)) {
204
+ return 'Version must follow semver format (e.g., 1.0.0)';
205
+ }
206
+ return true;
207
+ }
208
+ }
209
+ ]);
210
+ return version;
211
+ }
212
+
213
+ /**
214
+ * Prompts for KSE version
215
+ * @returns {Promise<string>} KSE version
216
+ */
217
+ async promptKseVersion() {
218
+ const currentVersion = this.getCurrentKseVersion();
219
+ const { kseVersion } = await inquirer.prompt([
220
+ {
221
+ type: 'input',
222
+ name: 'kseVersion',
223
+ message: 'Minimum KSE version required:',
224
+ default: currentVersion
225
+ }
226
+ ]);
227
+ return kseVersion;
228
+ }
229
+
230
+ /**
231
+ * Validates metadata completeness
232
+ * @param {Object} metadata - Collected metadata
233
+ * @returns {Object} Validation result
234
+ */
235
+ validateMetadata(metadata) {
236
+ const errors = [];
237
+ const requiredFields = ['name', 'description', 'category', 'tags', 'author', 'version', 'kse_version'];
238
+
239
+ for (const field of requiredFields) {
240
+ if (!metadata[field]) {
241
+ errors.push(`Missing required field: ${field}`);
242
+ }
243
+ }
244
+
245
+ // Validate kebab-case name
246
+ if (metadata.name && !/^[a-z0-9]+(-[a-z0-9]+)*$/.test(metadata.name)) {
247
+ errors.push('Name must be in kebab-case format');
248
+ }
249
+
250
+ // Validate semver version
251
+ if (metadata.version && !/^\d+\.\d+\.\d+$/.test(metadata.version)) {
252
+ errors.push('Version must follow semver format');
253
+ }
254
+
255
+ // Validate category
256
+ if (metadata.category && !this.categories.includes(metadata.category)) {
257
+ errors.push(`Category must be one of: ${this.categories.join(', ')}`);
258
+ }
259
+
260
+ return {
261
+ valid: errors.length === 0,
262
+ errors
263
+ };
264
+ }
265
+
266
+ /**
267
+ * Suggests tags based on content analysis
268
+ * @param {Object} fileContents - Spec file contents
269
+ * @returns {Array} Suggested tags
270
+ */
271
+ suggestTags(fileContents) {
272
+ const allContent = Object.values(fileContents).join(' ').toLowerCase();
273
+ const keywords = [
274
+ 'api', 'rest', 'graphql', 'database', 'authentication', 'authorization',
275
+ 'testing', 'deployment', 'ci/cd', 'monitoring', 'logging', 'caching',
276
+ 'frontend', 'backend', 'cli', 'template', 'automation', 'integration'
277
+ ];
278
+
279
+ return keywords.filter(keyword => allContent.includes(keyword)).slice(0, 5);
280
+ }
281
+
282
+ /**
283
+ * Gets default metadata (non-interactive mode)
284
+ * @param {Object} specMetadata - Spec metadata
285
+ * @returns {Object} Default metadata
286
+ */
287
+ getDefaultMetadata(specMetadata) {
288
+ const now = new Date().toISOString().split('T')[0];
289
+ return {
290
+ name: specMetadata.specName,
291
+ description: `Template for ${specMetadata.specNameTitle}`,
292
+ category: 'other',
293
+ tags: [],
294
+ author: specMetadata.author || this.getGitUser(),
295
+ version: '1.0.0',
296
+ kse_version: this.getCurrentKseVersion(),
297
+ created_at: now,
298
+ updated_at: now
299
+ };
300
+ }
301
+
302
+ /**
303
+ * Gets git user name
304
+ * @returns {string} Git user name
305
+ */
306
+ getGitUser() {
307
+ try {
308
+ return execSync('git config user.name', { encoding: 'utf-8' }).trim();
309
+ } catch {
310
+ return 'Unknown';
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Gets current KSE version
316
+ * @returns {string} KSE version
317
+ */
318
+ getCurrentKseVersion() {
319
+ try {
320
+ const packageJson = require('../../package.json');
321
+ return packageJson.version;
322
+ } catch {
323
+ return '1.0.0';
324
+ }
325
+ }
326
+ }
327
+
328
+ module.exports = MetadataCollector;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Path Utilities
3
+ *
4
+ * Platform-independent path handling utilities for template operations.
5
+ */
6
+
7
+ const path = require('path');
8
+ const os = require('os');
9
+
10
+ /**
11
+ * Normalize path to use forward slashes and resolve home directory
12
+ * @param {string} filePath - Path to normalize
13
+ * @returns {string} Normalized path
14
+ */
15
+ function normalize(filePath) {
16
+ if (!filePath) {
17
+ throw new Error('Path cannot be empty');
18
+ }
19
+
20
+ // Expand home directory
21
+ let normalized = expandHome(filePath);
22
+
23
+ // Convert to absolute path if relative
24
+ if (!path.isAbsolute(normalized)) {
25
+ normalized = path.resolve(normalized);
26
+ }
27
+
28
+ // Convert backslashes to forward slashes
29
+ normalized = normalized.replace(/\\/g, '/');
30
+
31
+ return normalized;
32
+ }
33
+
34
+ /**
35
+ * Expand ~ to home directory
36
+ * @param {string} filePath - Path that may contain ~
37
+ * @returns {string} Path with ~ expanded
38
+ */
39
+ function expandHome(filePath) {
40
+ if (!filePath) return filePath;
41
+
42
+ if (filePath === '~' || filePath.startsWith('~/') || filePath.startsWith('~\\')) {
43
+ return path.join(os.homedir(), filePath.slice(1));
44
+ }
45
+
46
+ return filePath;
47
+ }
48
+
49
+ /**
50
+ * Get the default template cache directory
51
+ * @returns {string} Path to cache directory
52
+ */
53
+ function getDefaultCacheDir() {
54
+ return normalize(path.join(os.homedir(), '.kse', 'templates'));
55
+ }
56
+
57
+ /**
58
+ * Get the cache directory for a specific source
59
+ * @param {string} sourceName - Name of the template source
60
+ * @returns {string} Path to source cache directory
61
+ */
62
+ function getSourceCacheDir(sourceName) {
63
+ return normalize(path.join(getDefaultCacheDir(), sourceName));
64
+ }
65
+
66
+ /**
67
+ * Get the path to cache metadata file
68
+ * @returns {string} Path to metadata file
69
+ */
70
+ function getCacheMetadataPath() {
71
+ return normalize(path.join(getDefaultCacheDir(), '.cache-metadata.json'));
72
+ }
73
+
74
+ /**
75
+ * Get the path to sources configuration file
76
+ * @returns {string} Path to sources file
77
+ */
78
+ function getSourcesConfigPath() {
79
+ return normalize(path.join(getDefaultCacheDir(), '.sources.json'));
80
+ }
81
+
82
+ /**
83
+ * Join path segments using forward slashes
84
+ * @param {...string} segments - Path segments to join
85
+ * @returns {string} Joined path
86
+ */
87
+ function join(...segments) {
88
+ return path.join(...segments).replace(/\\/g, '/');
89
+ }
90
+
91
+ /**
92
+ * Get the directory name of a path
93
+ * @param {string} filePath - File path
94
+ * @returns {string} Directory name
95
+ */
96
+ function dirname(filePath) {
97
+ return path.dirname(filePath).replace(/\\/g, '/');
98
+ }
99
+
100
+ /**
101
+ * Get the base name of a path
102
+ * @param {string} filePath - File path
103
+ * @param {string} ext - Optional extension to remove
104
+ * @returns {string} Base name
105
+ */
106
+ function basename(filePath, ext) {
107
+ return path.basename(filePath, ext);
108
+ }
109
+
110
+ /**
111
+ * Get the extension of a path
112
+ * @param {string} filePath - File path
113
+ * @returns {string} Extension (including dot)
114
+ */
115
+ function extname(filePath) {
116
+ return path.extname(filePath);
117
+ }
118
+
119
+ /**
120
+ * Check if a path is within another path
121
+ * @param {string} child - Child path
122
+ * @param {string} parent - Parent path
123
+ * @returns {boolean} True if child is within parent
124
+ */
125
+ function isWithin(child, parent) {
126
+ const childNorm = normalize(child);
127
+ const parentNorm = normalize(parent);
128
+
129
+ return childNorm.startsWith(parentNorm + '/') || childNorm === parentNorm;
130
+ }
131
+
132
+ module.exports = {
133
+ normalize,
134
+ expandHome,
135
+ getDefaultCacheDir,
136
+ getSourceCacheDir,
137
+ getCacheMetadataPath,
138
+ getSourcesConfigPath,
139
+ join,
140
+ dirname,
141
+ basename,
142
+ extname,
143
+ isWithin
144
+ };