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,208 @@
1
+ /**
2
+ * Entry Manager
3
+ * Handles knowledge entry file operations
4
+ */
5
+
6
+ const fs = require('fs-extra');
7
+ const path = require('path');
8
+ const yaml = require('js-yaml');
9
+
10
+ class EntryManager {
11
+ constructor(knowledgePath) {
12
+ this.knowledgePath = knowledgePath;
13
+ }
14
+
15
+ /**
16
+ * Create new entry
17
+ * @param {string} type - Entry type
18
+ * @param {string} title - Entry title
19
+ * @param {string} content - Entry content
20
+ * @param {Object} metadata - Entry metadata
21
+ * @returns {Object} - Created entry info
22
+ */
23
+ async create(type, title, content, metadata) {
24
+ const id = this.generateId();
25
+ const filename = this.generateFilename(type, title);
26
+ const filePath = path.join(this.knowledgePath, `${type}s`, filename);
27
+
28
+ const fullMetadata = {
29
+ id,
30
+ type,
31
+ title,
32
+ created: new Date().toISOString(),
33
+ updated: new Date().toISOString(),
34
+ tags: metadata.tags || [],
35
+ category: metadata.category || null,
36
+ status: 'active',
37
+ integration: null,
38
+ ...metadata
39
+ };
40
+
41
+ const fileContent = this.serializeFrontmatter(fullMetadata, content);
42
+
43
+ await fs.ensureDir(path.dirname(filePath));
44
+ await fs.writeFile(filePath, fileContent, 'utf-8');
45
+
46
+ return {
47
+ id,
48
+ file: path.relative(this.knowledgePath, filePath),
49
+ path: filePath
50
+ };
51
+ }
52
+
53
+ /**
54
+ * Read entry
55
+ * @param {string} filePath - Entry file path
56
+ * @returns {Object} - Entry data
57
+ */
58
+ async read(filePath) {
59
+ const content = await fs.readFile(filePath, 'utf-8');
60
+ return this.parseFrontmatter(content);
61
+ }
62
+
63
+ /**
64
+ * Update entry
65
+ * @param {string} filePath - Entry file path
66
+ * @param {string} content - New content
67
+ * @param {Object} metadata - Updated metadata
68
+ */
69
+ async update(filePath, content, metadata) {
70
+ const existing = await this.read(filePath);
71
+
72
+ const updatedMetadata = {
73
+ ...existing.metadata,
74
+ ...metadata,
75
+ updated: new Date().toISOString()
76
+ };
77
+
78
+ const fileContent = this.serializeFrontmatter(updatedMetadata, content || existing.content);
79
+ await fs.writeFile(filePath, fileContent, 'utf-8');
80
+ }
81
+
82
+ /**
83
+ * Delete entry
84
+ * @param {string} filePath - Entry file path
85
+ * @param {boolean} backup - Create backup before deletion
86
+ */
87
+ async delete(filePath, backup = true) {
88
+ if (backup) {
89
+ const backupDir = path.join(this.knowledgePath, '.backups');
90
+ await fs.ensureDir(backupDir);
91
+
92
+ const timestamp = Date.now();
93
+ const basename = path.basename(filePath);
94
+ const backupPath = path.join(backupDir, `${timestamp}-${basename}`);
95
+
96
+ await fs.copy(filePath, backupPath);
97
+ }
98
+
99
+ await fs.remove(filePath);
100
+ }
101
+
102
+ /**
103
+ * Check if entry exists
104
+ * @param {string} filePath - Entry file path
105
+ * @returns {boolean}
106
+ */
107
+ async exists(filePath) {
108
+ return fs.pathExists(filePath);
109
+ }
110
+
111
+ /**
112
+ * Parse frontmatter from content
113
+ * @param {string} content - File content
114
+ * @returns {Object} - Parsed data
115
+ */
116
+ parseFrontmatter(content) {
117
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
118
+
119
+ if (!match) {
120
+ throw new Error('Invalid entry format: missing frontmatter');
121
+ }
122
+
123
+ const [, frontmatter, body] = match;
124
+
125
+ try {
126
+ const metadata = yaml.load(frontmatter);
127
+ return {
128
+ metadata,
129
+ content: body.trim()
130
+ };
131
+ } catch (error) {
132
+ throw new Error(`Invalid YAML frontmatter: ${error.message}`);
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Serialize frontmatter and content
138
+ * @param {Object} metadata - Entry metadata
139
+ * @param {string} content - Entry content
140
+ * @returns {string} - Serialized content
141
+ */
142
+ serializeFrontmatter(metadata, content) {
143
+ const frontmatter = yaml.dump(metadata, {
144
+ indent: 2,
145
+ lineWidth: -1
146
+ });
147
+
148
+ return `---\n${frontmatter}---\n\n${content}`;
149
+ }
150
+
151
+ /**
152
+ * Validate entry structure
153
+ * @param {string} filePath - Entry file path
154
+ * @returns {Object} - Validation result
155
+ */
156
+ async validate(filePath) {
157
+ try {
158
+ const data = await this.read(filePath);
159
+ const { metadata } = data;
160
+
161
+ const errors = [];
162
+
163
+ if (!metadata.id) errors.push('Missing id');
164
+ if (!metadata.type) errors.push('Missing type');
165
+ if (!metadata.title) errors.push('Missing title');
166
+ if (!metadata.created) errors.push('Missing created date');
167
+ if (!metadata.updated) errors.push('Missing updated date');
168
+ if (!metadata.status) errors.push('Missing status');
169
+
170
+ return {
171
+ valid: errors.length === 0,
172
+ errors
173
+ };
174
+ } catch (error) {
175
+ return {
176
+ valid: false,
177
+ errors: [error.message]
178
+ };
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Generate unique ID
184
+ * @returns {string} - Unique ID
185
+ */
186
+ generateId() {
187
+ const timestamp = Date.now();
188
+ const random = Math.random().toString(36).substring(2, 8);
189
+ return `kb-${timestamp}-${random}`;
190
+ }
191
+
192
+ /**
193
+ * Generate filename from title
194
+ * @param {string} type - Entry type
195
+ * @param {string} title - Entry title
196
+ * @returns {string} - Kebab-case filename
197
+ */
198
+ generateFilename(type, title) {
199
+ const kebab = title
200
+ .toLowerCase()
201
+ .replace(/[^a-z0-9]+/g, '-')
202
+ .replace(/^-+|-+$/g, '');
203
+
204
+ return `${kebab}.md`;
205
+ }
206
+ }
207
+
208
+ module.exports = EntryManager;
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Index Manager
3
+ * Manages knowledge base index for fast lookups
4
+ */
5
+
6
+ const fs = require('fs-extra');
7
+ const path = require('path');
8
+
9
+ class IndexManager {
10
+ constructor(knowledgePath) {
11
+ this.knowledgePath = knowledgePath;
12
+ this.indexPath = path.join(knowledgePath, 'index.json');
13
+ this.index = null;
14
+ }
15
+
16
+ /**
17
+ * Load index from file
18
+ * @returns {Object} - Index data
19
+ */
20
+ async load() {
21
+ if (this.index) {
22
+ return this.index;
23
+ }
24
+
25
+ if (await fs.pathExists(this.indexPath)) {
26
+ try {
27
+ this.index = await fs.readJson(this.indexPath);
28
+ return this.index;
29
+ } catch (error) {
30
+ throw new Error(`Failed to load index: ${error.message}`);
31
+ }
32
+ }
33
+
34
+ // Initialize empty index
35
+ this.index = {
36
+ version: '1.0.0',
37
+ entries: [],
38
+ stats: {
39
+ totalEntries: 0,
40
+ byType: {},
41
+ byStatus: {},
42
+ byTag: {}
43
+ },
44
+ lastUpdated: new Date().toISOString()
45
+ };
46
+
47
+ return this.index;
48
+ }
49
+
50
+ /**
51
+ * Save index to file
52
+ */
53
+ async save() {
54
+ if (!this.index) {
55
+ throw new Error('Index not loaded');
56
+ }
57
+
58
+ this.index.lastUpdated = new Date().toISOString();
59
+ await fs.writeJson(this.indexPath, this.index, { spaces: 2 });
60
+ }
61
+
62
+ /**
63
+ * Add entry to index
64
+ * @param {Object} metadata - Entry metadata
65
+ */
66
+ async addEntry(metadata) {
67
+ await this.load();
68
+
69
+ const entry = {
70
+ id: metadata.id,
71
+ type: metadata.type,
72
+ title: metadata.title,
73
+ file: metadata.file,
74
+ created: metadata.created,
75
+ updated: metadata.updated,
76
+ tags: metadata.tags || [],
77
+ category: metadata.category || null,
78
+ status: metadata.status || 'active',
79
+ integration: metadata.integration || null
80
+ };
81
+
82
+ this.index.entries.push(entry);
83
+ this._updateStats();
84
+ await this.save();
85
+ }
86
+
87
+ /**
88
+ * Update entry in index
89
+ * @param {string} id - Entry ID
90
+ * @param {Object} updates - Updates to apply
91
+ */
92
+ async updateEntry(id, updates) {
93
+ await this.load();
94
+
95
+ const entry = this.index.entries.find(e => e.id === id);
96
+ if (!entry) {
97
+ throw new Error(`Entry not found: ${id}`);
98
+ }
99
+
100
+ Object.assign(entry, updates);
101
+ entry.updated = new Date().toISOString();
102
+
103
+ this._updateStats();
104
+ await this.save();
105
+ }
106
+
107
+ /**
108
+ * Remove entry from index
109
+ * @param {string} id - Entry ID
110
+ */
111
+ async removeEntry(id) {
112
+ await this.load();
113
+
114
+ const index = this.index.entries.findIndex(e => e.id === id);
115
+ if (index === -1) {
116
+ throw new Error(`Entry not found: ${id}`);
117
+ }
118
+
119
+ this.index.entries.splice(index, 1);
120
+ this._updateStats();
121
+ await this.save();
122
+ }
123
+
124
+ /**
125
+ * Find entry by ID
126
+ * @param {string} id - Entry ID
127
+ * @returns {Object|null} - Entry or null
128
+ */
129
+ async findById(id) {
130
+ await this.load();
131
+ return this.index.entries.find(e => e.id === id) || null;
132
+ }
133
+
134
+ /**
135
+ * Find entries by type
136
+ * @param {string} type - Entry type
137
+ * @returns {Array} - Matching entries
138
+ */
139
+ async findByType(type) {
140
+ await this.load();
141
+ return this.index.entries.filter(e => e.type === type);
142
+ }
143
+
144
+ /**
145
+ * Find entries by tag
146
+ * @param {string} tag - Tag name
147
+ * @returns {Array} - Matching entries
148
+ */
149
+ async findByTag(tag) {
150
+ await this.load();
151
+ return this.index.entries.filter(e => e.tags.includes(tag));
152
+ }
153
+
154
+ /**
155
+ * Search entries by keyword
156
+ * @param {string} keyword - Search keyword
157
+ * @returns {Array} - Matching entries
158
+ */
159
+ async search(keyword) {
160
+ await this.load();
161
+
162
+ const lowerKeyword = keyword.toLowerCase();
163
+
164
+ return this.index.entries.filter(entry => {
165
+ return (
166
+ entry.title.toLowerCase().includes(lowerKeyword) ||
167
+ entry.tags.some(tag => tag.toLowerCase().includes(lowerKeyword)) ||
168
+ (entry.category && entry.category.toLowerCase().includes(lowerKeyword))
169
+ );
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Get statistics
175
+ * @returns {Object} - Statistics
176
+ */
177
+ async getStats() {
178
+ await this.load();
179
+ return this.index.stats;
180
+ }
181
+
182
+ /**
183
+ * Rebuild index from files
184
+ */
185
+ async rebuild() {
186
+ const EntryManager = require('./entry-manager');
187
+ const entryManager = new EntryManager(this.knowledgePath);
188
+
189
+ this.index = {
190
+ version: '1.0.0',
191
+ entries: [],
192
+ stats: {
193
+ totalEntries: 0,
194
+ byType: {},
195
+ byStatus: {},
196
+ byTag: {}
197
+ },
198
+ lastUpdated: new Date().toISOString()
199
+ };
200
+
201
+ const types = ['pattern', 'lesson', 'workflow', 'checklist', 'reference'];
202
+
203
+ for (const type of types) {
204
+ const typeDir = path.join(this.knowledgePath, `${type}s`);
205
+
206
+ if (await fs.pathExists(typeDir)) {
207
+ const files = await fs.readdir(typeDir);
208
+
209
+ for (const file of files) {
210
+ if (file.endsWith('.md')) {
211
+ const filePath = path.join(typeDir, file);
212
+
213
+ try {
214
+ const data = await entryManager.read(filePath);
215
+ const { metadata } = data;
216
+
217
+ await this.addEntry({
218
+ ...metadata,
219
+ file: path.relative(this.knowledgePath, filePath)
220
+ });
221
+ } catch (error) {
222
+ console.warn(`Failed to read ${file}: ${error.message}`);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ await this.save();
230
+ }
231
+
232
+ /**
233
+ * Update statistics
234
+ * @private
235
+ */
236
+ _updateStats() {
237
+ const stats = {
238
+ totalEntries: this.index.entries.length,
239
+ byType: {},
240
+ byStatus: {},
241
+ byTag: {}
242
+ };
243
+
244
+ for (const entry of this.index.entries) {
245
+ // Count by type
246
+ stats.byType[entry.type] = (stats.byType[entry.type] || 0) + 1;
247
+
248
+ // Count by status
249
+ stats.byStatus[entry.status] = (stats.byStatus[entry.status] || 0) + 1;
250
+
251
+ // Count by tag
252
+ for (const tag of entry.tags) {
253
+ stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;
254
+ }
255
+ }
256
+
257
+ this.index.stats = stats;
258
+ }
259
+ }
260
+
261
+ module.exports = IndexManager;