forge-server 0.1.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 (412) hide show
  1. package/.claude/hooks/worktree-create.sh +64 -0
  2. package/.claude/hooks/worktree-remove.sh +57 -0
  3. package/.claude/settings.local.json +29 -0
  4. package/.forge/knowledge/conventions.yaml +1 -0
  5. package/.forge/knowledge/decisions.yaml +1 -0
  6. package/.forge/knowledge/gotchas.yaml +1 -0
  7. package/.forge/knowledge/patterns.yaml +1 -0
  8. package/.forge/manifest.yaml +6 -0
  9. package/CLAUDE.md +144 -0
  10. package/bin/setup-forge.sh +132 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +553 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/context/codebase.d.ts +57 -0
  16. package/dist/context/codebase.d.ts.map +1 -0
  17. package/dist/context/codebase.js +301 -0
  18. package/dist/context/codebase.js.map +1 -0
  19. package/dist/context/injector.d.ts +147 -0
  20. package/dist/context/injector.d.ts.map +1 -0
  21. package/dist/context/injector.js +533 -0
  22. package/dist/context/injector.js.map +1 -0
  23. package/dist/context/memory.d.ts +32 -0
  24. package/dist/context/memory.d.ts.map +1 -0
  25. package/dist/context/memory.js +140 -0
  26. package/dist/context/memory.js.map +1 -0
  27. package/dist/context/session-index.d.ts +54 -0
  28. package/dist/context/session-index.d.ts.map +1 -0
  29. package/dist/context/session-index.js +265 -0
  30. package/dist/context/session-index.js.map +1 -0
  31. package/dist/context/session.d.ts +42 -0
  32. package/dist/context/session.d.ts.map +1 -0
  33. package/dist/context/session.js +121 -0
  34. package/dist/context/session.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +37 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/ingestion/chunker.d.ts +19 -0
  40. package/dist/ingestion/chunker.d.ts.map +1 -0
  41. package/dist/ingestion/chunker.js +189 -0
  42. package/dist/ingestion/chunker.js.map +1 -0
  43. package/dist/ingestion/embedder.d.ts +45 -0
  44. package/dist/ingestion/embedder.d.ts.map +1 -0
  45. package/dist/ingestion/embedder.js +152 -0
  46. package/dist/ingestion/embedder.js.map +1 -0
  47. package/dist/ingestion/git-analyzer.d.ts +77 -0
  48. package/dist/ingestion/git-analyzer.d.ts.map +1 -0
  49. package/dist/ingestion/git-analyzer.js +437 -0
  50. package/dist/ingestion/git-analyzer.js.map +1 -0
  51. package/dist/ingestion/indexer.d.ts +79 -0
  52. package/dist/ingestion/indexer.d.ts.map +1 -0
  53. package/dist/ingestion/indexer.js +766 -0
  54. package/dist/ingestion/indexer.js.map +1 -0
  55. package/dist/ingestion/markdown-chunker.d.ts +19 -0
  56. package/dist/ingestion/markdown-chunker.d.ts.map +1 -0
  57. package/dist/ingestion/markdown-chunker.js +243 -0
  58. package/dist/ingestion/markdown-chunker.js.map +1 -0
  59. package/dist/ingestion/markdown-knowledge.d.ts +21 -0
  60. package/dist/ingestion/markdown-knowledge.d.ts.map +1 -0
  61. package/dist/ingestion/markdown-knowledge.js +129 -0
  62. package/dist/ingestion/markdown-knowledge.js.map +1 -0
  63. package/dist/ingestion/parser.d.ts +20 -0
  64. package/dist/ingestion/parser.d.ts.map +1 -0
  65. package/dist/ingestion/parser.js +429 -0
  66. package/dist/ingestion/parser.js.map +1 -0
  67. package/dist/ingestion/watcher.d.ts +28 -0
  68. package/dist/ingestion/watcher.d.ts.map +1 -0
  69. package/dist/ingestion/watcher.js +147 -0
  70. package/dist/ingestion/watcher.js.map +1 -0
  71. package/dist/knowledge/hydrator.d.ts +37 -0
  72. package/dist/knowledge/hydrator.d.ts.map +1 -0
  73. package/dist/knowledge/hydrator.js +220 -0
  74. package/dist/knowledge/hydrator.js.map +1 -0
  75. package/dist/knowledge/registry.d.ts +129 -0
  76. package/dist/knowledge/registry.d.ts.map +1 -0
  77. package/dist/knowledge/registry.js +361 -0
  78. package/dist/knowledge/registry.js.map +1 -0
  79. package/dist/knowledge/search.d.ts +114 -0
  80. package/dist/knowledge/search.d.ts.map +1 -0
  81. package/dist/knowledge/search.js +428 -0
  82. package/dist/knowledge/search.js.map +1 -0
  83. package/dist/knowledge/store.d.ts +76 -0
  84. package/dist/knowledge/store.d.ts.map +1 -0
  85. package/dist/knowledge/store.js +230 -0
  86. package/dist/knowledge/store.js.map +1 -0
  87. package/dist/learning/confidence.d.ts +30 -0
  88. package/dist/learning/confidence.d.ts.map +1 -0
  89. package/dist/learning/confidence.js +165 -0
  90. package/dist/learning/confidence.js.map +1 -0
  91. package/dist/learning/patterns.d.ts +52 -0
  92. package/dist/learning/patterns.d.ts.map +1 -0
  93. package/dist/learning/patterns.js +290 -0
  94. package/dist/learning/patterns.js.map +1 -0
  95. package/dist/learning/trajectory.d.ts +55 -0
  96. package/dist/learning/trajectory.d.ts.map +1 -0
  97. package/dist/learning/trajectory.js +200 -0
  98. package/dist/learning/trajectory.js.map +1 -0
  99. package/dist/memory/memory-compat.d.ts +100 -0
  100. package/dist/memory/memory-compat.d.ts.map +1 -0
  101. package/dist/memory/memory-compat.js +146 -0
  102. package/dist/memory/memory-compat.js.map +1 -0
  103. package/dist/memory/observation-store.d.ts +57 -0
  104. package/dist/memory/observation-store.d.ts.map +1 -0
  105. package/dist/memory/observation-store.js +154 -0
  106. package/dist/memory/observation-store.js.map +1 -0
  107. package/dist/memory/session-tracker.d.ts +81 -0
  108. package/dist/memory/session-tracker.d.ts.map +1 -0
  109. package/dist/memory/session-tracker.js +262 -0
  110. package/dist/memory/session-tracker.js.map +1 -0
  111. package/dist/pipeline/engine.d.ts +179 -0
  112. package/dist/pipeline/engine.d.ts.map +1 -0
  113. package/dist/pipeline/engine.js +691 -0
  114. package/dist/pipeline/engine.js.map +1 -0
  115. package/dist/pipeline/events.d.ts +54 -0
  116. package/dist/pipeline/events.d.ts.map +1 -0
  117. package/dist/pipeline/events.js +157 -0
  118. package/dist/pipeline/events.js.map +1 -0
  119. package/dist/pipeline/parallel.d.ts +83 -0
  120. package/dist/pipeline/parallel.d.ts.map +1 -0
  121. package/dist/pipeline/parallel.js +277 -0
  122. package/dist/pipeline/parallel.js.map +1 -0
  123. package/dist/pipeline/state-machine.d.ts +65 -0
  124. package/dist/pipeline/state-machine.d.ts.map +1 -0
  125. package/dist/pipeline/state-machine.js +176 -0
  126. package/dist/pipeline/state-machine.js.map +1 -0
  127. package/dist/query/graph-queries.d.ts +84 -0
  128. package/dist/query/graph-queries.d.ts.map +1 -0
  129. package/dist/query/graph-queries.js +216 -0
  130. package/dist/query/graph-queries.js.map +1 -0
  131. package/dist/query/hybrid-search.d.ts +34 -0
  132. package/dist/query/hybrid-search.d.ts.map +1 -0
  133. package/dist/query/hybrid-search.js +263 -0
  134. package/dist/query/hybrid-search.js.map +1 -0
  135. package/dist/query/intent-detector.d.ts +35 -0
  136. package/dist/query/intent-detector.d.ts.map +1 -0
  137. package/dist/query/intent-detector.js +115 -0
  138. package/dist/query/intent-detector.js.map +1 -0
  139. package/dist/query/ranking.d.ts +57 -0
  140. package/dist/query/ranking.d.ts.map +1 -0
  141. package/dist/query/ranking.js +109 -0
  142. package/dist/query/ranking.js.map +1 -0
  143. package/dist/server.d.ts +3 -0
  144. package/dist/server.d.ts.map +1 -0
  145. package/dist/server.js +291 -0
  146. package/dist/server.js.map +1 -0
  147. package/dist/storage/falkordb-store.d.ts +73 -0
  148. package/dist/storage/falkordb-store.d.ts.map +1 -0
  149. package/dist/storage/falkordb-store.js +346 -0
  150. package/dist/storage/falkordb-store.js.map +1 -0
  151. package/dist/storage/file-cache.d.ts +32 -0
  152. package/dist/storage/file-cache.d.ts.map +1 -0
  153. package/dist/storage/file-cache.js +115 -0
  154. package/dist/storage/file-cache.js.map +1 -0
  155. package/dist/storage/interfaces.d.ts +151 -0
  156. package/dist/storage/interfaces.d.ts.map +1 -0
  157. package/dist/storage/interfaces.js +7 -0
  158. package/dist/storage/interfaces.js.map +1 -0
  159. package/dist/storage/qdrant-store.d.ts +110 -0
  160. package/dist/storage/qdrant-store.d.ts.map +1 -0
  161. package/dist/storage/qdrant-store.js +467 -0
  162. package/dist/storage/qdrant-store.js.map +1 -0
  163. package/dist/storage/schema.d.ts +4 -0
  164. package/dist/storage/schema.d.ts.map +1 -0
  165. package/dist/storage/schema.js +136 -0
  166. package/dist/storage/schema.js.map +1 -0
  167. package/dist/storage/sqlite.d.ts +35 -0
  168. package/dist/storage/sqlite.d.ts.map +1 -0
  169. package/dist/storage/sqlite.js +132 -0
  170. package/dist/storage/sqlite.js.map +1 -0
  171. package/dist/tools/collaboration-tools.d.ts +111 -0
  172. package/dist/tools/collaboration-tools.d.ts.map +1 -0
  173. package/dist/tools/collaboration-tools.js +174 -0
  174. package/dist/tools/collaboration-tools.js.map +1 -0
  175. package/dist/tools/context-tools.d.ts +293 -0
  176. package/dist/tools/context-tools.d.ts.map +1 -0
  177. package/dist/tools/context-tools.js +437 -0
  178. package/dist/tools/context-tools.js.map +1 -0
  179. package/dist/tools/graph-tools.d.ts +129 -0
  180. package/dist/tools/graph-tools.d.ts.map +1 -0
  181. package/dist/tools/graph-tools.js +237 -0
  182. package/dist/tools/graph-tools.js.map +1 -0
  183. package/dist/tools/ingestion-tools.d.ts +96 -0
  184. package/dist/tools/ingestion-tools.d.ts.map +1 -0
  185. package/dist/tools/ingestion-tools.js +90 -0
  186. package/dist/tools/ingestion-tools.js.map +1 -0
  187. package/dist/tools/learning-tools.d.ts +168 -0
  188. package/dist/tools/learning-tools.d.ts.map +1 -0
  189. package/dist/tools/learning-tools.js +158 -0
  190. package/dist/tools/learning-tools.js.map +1 -0
  191. package/dist/tools/memory-tools.d.ts +183 -0
  192. package/dist/tools/memory-tools.d.ts.map +1 -0
  193. package/dist/tools/memory-tools.js +197 -0
  194. package/dist/tools/memory-tools.js.map +1 -0
  195. package/dist/tools/phase-tools.d.ts +954 -0
  196. package/dist/tools/phase-tools.d.ts.map +1 -0
  197. package/dist/tools/phase-tools.js +1215 -0
  198. package/dist/tools/phase-tools.js.map +1 -0
  199. package/dist/tools/pipeline-tools.d.ts +140 -0
  200. package/dist/tools/pipeline-tools.d.ts.map +1 -0
  201. package/dist/tools/pipeline-tools.js +162 -0
  202. package/dist/tools/pipeline-tools.js.map +1 -0
  203. package/dist/tools/registration-tools.d.ts +220 -0
  204. package/dist/tools/registration-tools.d.ts.map +1 -0
  205. package/dist/tools/registration-tools.js +391 -0
  206. package/dist/tools/registration-tools.js.map +1 -0
  207. package/dist/util/circuit-breaker.d.ts +75 -0
  208. package/dist/util/circuit-breaker.d.ts.map +1 -0
  209. package/dist/util/circuit-breaker.js +159 -0
  210. package/dist/util/circuit-breaker.js.map +1 -0
  211. package/dist/util/config.d.ts +23 -0
  212. package/dist/util/config.d.ts.map +1 -0
  213. package/dist/util/config.js +164 -0
  214. package/dist/util/config.js.map +1 -0
  215. package/dist/util/logger.d.ts +13 -0
  216. package/dist/util/logger.d.ts.map +1 -0
  217. package/dist/util/logger.js +45 -0
  218. package/dist/util/logger.js.map +1 -0
  219. package/dist/util/token-counter.d.ts +24 -0
  220. package/dist/util/token-counter.d.ts.map +1 -0
  221. package/dist/util/token-counter.js +48 -0
  222. package/dist/util/token-counter.js.map +1 -0
  223. package/dist/util/types.d.ts +525 -0
  224. package/dist/util/types.d.ts.map +1 -0
  225. package/dist/util/types.js +5 -0
  226. package/dist/util/types.js.map +1 -0
  227. package/docker-compose.yml +20 -0
  228. package/docs/plans/2026-02-27-swarm-coordination/architecture.md +203 -0
  229. package/docs/plans/2026-02-27-swarm-coordination/vision.md +57 -0
  230. package/docs/plans/completed/2026-02-26-forge-plugin-bundling/architecture.md +1 -0
  231. package/docs/plans/completed/2026-02-26-forge-plugin-bundling/vision.md +300 -0
  232. package/docs/plans/completed/2026-02-27-forge-swarm-learning/architecture.md +480 -0
  233. package/docs/plans/completed/2026-02-27-forge-swarm-learning/verification-checklist.md +462 -0
  234. package/docs/plans/completed/2026-02-27-git-history-atlassian/git-jira-plan.md +181 -0
  235. package/package.json +39 -0
  236. package/plugin/.claude-plugin/plugin.json +8 -0
  237. package/plugin/.mcp.json +15 -0
  238. package/plugin/README.md +134 -0
  239. package/plugin/agents/architect.md +367 -0
  240. package/plugin/agents/backend-specialist.md +263 -0
  241. package/plugin/agents/brainstormer.md +122 -0
  242. package/plugin/agents/data-specialist.md +266 -0
  243. package/plugin/agents/designer.md +408 -0
  244. package/plugin/agents/frontend-specialist.md +241 -0
  245. package/plugin/agents/inspector.md +406 -0
  246. package/plugin/agents/knowledge-keeper.md +443 -0
  247. package/plugin/agents/platform-engineer.md +326 -0
  248. package/plugin/agents/product-manager.md +268 -0
  249. package/plugin/agents/product-owner.md +438 -0
  250. package/plugin/agents/pulse-checker.md +73 -0
  251. package/plugin/agents/qa-strategist.md +500 -0
  252. package/plugin/agents/self-improver.md +310 -0
  253. package/plugin/agents/strategist.md +360 -0
  254. package/plugin/agents/supervisor.md +380 -0
  255. package/plugin/commands/brainstorm.md +25 -0
  256. package/plugin/commands/forge.md +88 -0
  257. package/plugin/docs/atlassian-integration.md +110 -0
  258. package/plugin/docs/workflow.md +126 -0
  259. package/plugin/skills/agent-development/.skillfish.json +10 -0
  260. package/plugin/skills/agent-development/SKILL.md +415 -0
  261. package/plugin/skills/agent-development/examples/agent-creation-prompt.md +238 -0
  262. package/plugin/skills/agent-development/examples/complete-agent-examples.md +427 -0
  263. package/plugin/skills/agent-development/references/agent-creation-system-prompt.md +207 -0
  264. package/plugin/skills/agent-development/references/system-prompt-design.md +411 -0
  265. package/plugin/skills/agent-development/references/triggering-examples.md +491 -0
  266. package/plugin/skills/agent-development/scripts/validate-agent.sh +217 -0
  267. package/plugin/skills/agent-handoff/SKILL.md +335 -0
  268. package/plugin/skills/anti-stub/SKILL.md +317 -0
  269. package/plugin/skills/brainstorm/SKILL.md +31 -0
  270. package/plugin/skills/debugging/SKILL.md +276 -0
  271. package/plugin/skills/fix/SKILL.md +62 -0
  272. package/plugin/skills/frontend-design/.skillfish.json +10 -0
  273. package/plugin/skills/frontend-design/SKILL.md +42 -0
  274. package/plugin/skills/gotchas/SKILL.md +61 -0
  275. package/plugin/skills/graph-orchestrator/SKILL.md +38 -0
  276. package/plugin/skills/history/SKILL.md +58 -0
  277. package/plugin/skills/impact/SKILL.md +59 -0
  278. package/plugin/skills/implementation-execution/SKILL.md +291 -0
  279. package/plugin/skills/index-repo/SKILL.md +55 -0
  280. package/plugin/skills/interviewing/SKILL.md +225 -0
  281. package/plugin/skills/knowledge-curation/SKILL.md +393 -0
  282. package/plugin/skills/learn/SKILL.md +69 -0
  283. package/plugin/skills/mcp-integration/.skillfish.json +10 -0
  284. package/plugin/skills/mcp-integration/SKILL.md +554 -0
  285. package/plugin/skills/mcp-integration/examples/http-server.json +20 -0
  286. package/plugin/skills/mcp-integration/examples/sse-server.json +19 -0
  287. package/plugin/skills/mcp-integration/examples/stdio-server.json +26 -0
  288. package/plugin/skills/mcp-integration/references/authentication.md +549 -0
  289. package/plugin/skills/mcp-integration/references/server-types.md +536 -0
  290. package/plugin/skills/mcp-integration/references/tool-usage.md +538 -0
  291. package/plugin/skills/nestjs/.skillfish.json +10 -0
  292. package/plugin/skills/nestjs/SKILL.md +669 -0
  293. package/plugin/skills/nestjs/drizzle-reference.md +1894 -0
  294. package/plugin/skills/nestjs/reference.md +1447 -0
  295. package/plugin/skills/nestjs/workflow-optimization.md +229 -0
  296. package/plugin/skills/parallel-dispatch/SKILL.md +308 -0
  297. package/plugin/skills/project-discovery/SKILL.md +304 -0
  298. package/plugin/skills/search/SKILL.md +56 -0
  299. package/plugin/skills/security-audit/SKILL.md +362 -0
  300. package/plugin/skills/skill-development/.skillfish.json +10 -0
  301. package/plugin/skills/skill-development/SKILL.md +637 -0
  302. package/plugin/skills/skill-development/references/skill-creator-original.md +209 -0
  303. package/plugin/skills/tdd/SKILL.md +273 -0
  304. package/plugin/skills/terminal-presentation/SKILL.md +395 -0
  305. package/plugin/skills/test-strategy/SKILL.md +365 -0
  306. package/plugin/skills/verification-protocol/SKILL.md +256 -0
  307. package/plugin/skills/visual-explainer/CHANGELOG.md +97 -0
  308. package/plugin/skills/visual-explainer/LICENSE +21 -0
  309. package/plugin/skills/visual-explainer/README.md +137 -0
  310. package/plugin/skills/visual-explainer/SKILL.md +352 -0
  311. package/plugin/skills/visual-explainer/banner.png +0 -0
  312. package/plugin/skills/visual-explainer/package.json +11 -0
  313. package/plugin/skills/visual-explainer/prompts/diff-review.md +68 -0
  314. package/plugin/skills/visual-explainer/prompts/fact-check.md +63 -0
  315. package/plugin/skills/visual-explainer/prompts/generate-slides.md +18 -0
  316. package/plugin/skills/visual-explainer/prompts/generate-web-diagram.md +10 -0
  317. package/plugin/skills/visual-explainer/prompts/plan-review.md +86 -0
  318. package/plugin/skills/visual-explainer/prompts/project-recap.md +61 -0
  319. package/plugin/skills/visual-explainer/references/css-patterns.md +1188 -0
  320. package/plugin/skills/visual-explainer/references/libraries.md +470 -0
  321. package/plugin/skills/visual-explainer/references/responsive-nav.md +212 -0
  322. package/plugin/skills/visual-explainer/references/slide-patterns.md +1403 -0
  323. package/plugin/skills/visual-explainer/templates/architecture.html +596 -0
  324. package/plugin/skills/visual-explainer/templates/data-table.html +540 -0
  325. package/plugin/skills/visual-explainer/templates/mermaid-flowchart.html +435 -0
  326. package/plugin/skills/visual-explainer/templates/slide-deck.html +913 -0
  327. package/src/cli.ts +655 -0
  328. package/src/context/.gitkeep +0 -0
  329. package/src/context/codebase.ts +393 -0
  330. package/src/context/injector.ts +797 -0
  331. package/src/context/memory.ts +187 -0
  332. package/src/context/session-index.ts +327 -0
  333. package/src/context/session.ts +152 -0
  334. package/src/index.ts +47 -0
  335. package/src/ingestion/.gitkeep +0 -0
  336. package/src/ingestion/chunker.ts +277 -0
  337. package/src/ingestion/embedder.ts +167 -0
  338. package/src/ingestion/git-analyzer.ts +545 -0
  339. package/src/ingestion/indexer.ts +984 -0
  340. package/src/ingestion/markdown-chunker.ts +337 -0
  341. package/src/ingestion/markdown-knowledge.ts +175 -0
  342. package/src/ingestion/parser.ts +475 -0
  343. package/src/ingestion/watcher.ts +182 -0
  344. package/src/knowledge/.gitkeep +0 -0
  345. package/src/knowledge/hydrator.ts +246 -0
  346. package/src/knowledge/registry.ts +463 -0
  347. package/src/knowledge/search.ts +565 -0
  348. package/src/knowledge/store.ts +262 -0
  349. package/src/learning/.gitkeep +0 -0
  350. package/src/learning/confidence.ts +193 -0
  351. package/src/learning/patterns.ts +360 -0
  352. package/src/learning/trajectory.ts +268 -0
  353. package/src/memory/.gitkeep +0 -0
  354. package/src/memory/memory-compat.ts +233 -0
  355. package/src/memory/observation-store.ts +224 -0
  356. package/src/memory/session-tracker.ts +332 -0
  357. package/src/pipeline/.gitkeep +0 -0
  358. package/src/pipeline/engine.ts +1139 -0
  359. package/src/pipeline/events.ts +253 -0
  360. package/src/pipeline/parallel.ts +394 -0
  361. package/src/pipeline/state-machine.ts +199 -0
  362. package/src/query/.gitkeep +0 -0
  363. package/src/query/graph-queries.ts +262 -0
  364. package/src/query/hybrid-search.ts +337 -0
  365. package/src/query/intent-detector.ts +131 -0
  366. package/src/query/ranking.ts +161 -0
  367. package/src/server.ts +352 -0
  368. package/src/storage/.gitkeep +0 -0
  369. package/src/storage/falkordb-store.ts +388 -0
  370. package/src/storage/file-cache.ts +141 -0
  371. package/src/storage/interfaces.ts +201 -0
  372. package/src/storage/qdrant-store.ts +557 -0
  373. package/src/storage/schema.ts +139 -0
  374. package/src/storage/sqlite.ts +168 -0
  375. package/src/tools/.gitkeep +0 -0
  376. package/src/tools/collaboration-tools.ts +208 -0
  377. package/src/tools/context-tools.ts +493 -0
  378. package/src/tools/graph-tools.ts +295 -0
  379. package/src/tools/ingestion-tools.ts +122 -0
  380. package/src/tools/learning-tools.ts +181 -0
  381. package/src/tools/memory-tools.ts +234 -0
  382. package/src/tools/phase-tools.ts +1452 -0
  383. package/src/tools/pipeline-tools.ts +188 -0
  384. package/src/tools/registration-tools.ts +450 -0
  385. package/src/util/.gitkeep +0 -0
  386. package/src/util/circuit-breaker.ts +193 -0
  387. package/src/util/config.ts +177 -0
  388. package/src/util/logger.ts +53 -0
  389. package/src/util/token-counter.ts +52 -0
  390. package/src/util/types.ts +710 -0
  391. package/tests/context/.gitkeep +0 -0
  392. package/tests/integration/.gitkeep +0 -0
  393. package/tests/knowledge/.gitkeep +0 -0
  394. package/tests/learning/.gitkeep +0 -0
  395. package/tests/pipeline/.gitkeep +0 -0
  396. package/tests/tools/.gitkeep +0 -0
  397. package/tsconfig.json +21 -0
  398. package/vitest.config.ts +10 -0
  399. package/vscode-extension/.vscodeignore +7 -0
  400. package/vscode-extension/README.md +43 -0
  401. package/vscode-extension/out/edge-collector.js +274 -0
  402. package/vscode-extension/out/edge-collector.js.map +1 -0
  403. package/vscode-extension/out/extension.js +264 -0
  404. package/vscode-extension/out/extension.js.map +1 -0
  405. package/vscode-extension/out/forge-client.js +318 -0
  406. package/vscode-extension/out/forge-client.js.map +1 -0
  407. package/vscode-extension/package-lock.json +59 -0
  408. package/vscode-extension/package.json +71 -0
  409. package/vscode-extension/src/edge-collector.ts +320 -0
  410. package/vscode-extension/src/extension.ts +269 -0
  411. package/vscode-extension/src/forge-client.ts +364 -0
  412. package/vscode-extension/tsconfig.json +19 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Claude-flow / Ruflo memory compatibility layer.
3
+ * Translates between the two memory schemas and the unified ObservationPayload format.
4
+ * Ensures memory_store, memory_retrieve, memory_search work with both parameter shapes.
5
+ *
6
+ * Claude-flow schema: { content, type, category, tags, metadata, importance, ttl }
7
+ * Ruflo schema: { key, value, namespace, tags, ttl }
8
+ */
9
+
10
+ import type { ObservationPayload } from '../util/types.js';
11
+
12
+ // ============================================================
13
+ // Parameter Shape Detection
14
+ // ============================================================
15
+
16
+ export type MemorySource = 'forge' | 'claude-flow' | 'ruflo';
17
+
18
+ export interface NormalizedMemoryInput {
19
+ content: string;
20
+ key: string | null;
21
+ namespace: string;
22
+ type: ObservationPayload['type'];
23
+ tags: string[];
24
+ importance: number;
25
+ ttl?: number;
26
+ metadata: Record<string, unknown>;
27
+ source: MemorySource;
28
+ // Ruflo-style original value (preserved for retrieval)
29
+ originalValue?: unknown;
30
+ }
31
+
32
+ /**
33
+ * Detect whether input follows ruflo-style (key+value) or claude-flow-style (content).
34
+ */
35
+ export function detectMemorySource(input: {
36
+ key?: string;
37
+ value?: unknown;
38
+ content?: string;
39
+ type?: string;
40
+ category?: string;
41
+ namespace?: string;
42
+ }): MemorySource {
43
+ if (input.key !== undefined && input.value !== undefined) {
44
+ return 'ruflo';
45
+ }
46
+ if (input.content !== undefined || input.type !== undefined || input.category !== undefined) {
47
+ return 'claude-flow';
48
+ }
49
+ // Ambiguous - use key presence as tiebreaker
50
+ if (input.key !== undefined) {
51
+ return 'ruflo';
52
+ }
53
+ return 'claude-flow';
54
+ }
55
+
56
+ /**
57
+ * Normalize a memory_store input into unified format regardless of schema origin.
58
+ */
59
+ export function normalizeMemoryInput(input: {
60
+ // Ruflo-style
61
+ key?: string;
62
+ value?: unknown;
63
+ // Claude-flow-style
64
+ content?: string;
65
+ type?: 'episodic' | 'semantic' | 'procedural' | 'working';
66
+ category?: string;
67
+ // Shared
68
+ namespace?: string;
69
+ tags?: string[];
70
+ metadata?: Record<string, unknown>;
71
+ importance?: number;
72
+ ttl?: number;
73
+ }): NormalizedMemoryInput {
74
+ const source = detectMemorySource(input);
75
+
76
+ let content: string;
77
+ let key: string | null;
78
+ let originalValue: unknown;
79
+
80
+ if (source === 'ruflo') {
81
+ key = input.key ?? `mem-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
82
+ originalValue = input.value;
83
+ content = typeof input.value === 'string'
84
+ ? input.value
85
+ : JSON.stringify(input.value ?? '');
86
+ } else {
87
+ // claude-flow style
88
+ key = input.key ?? null;
89
+ content = input.content ?? '';
90
+ originalValue = undefined;
91
+ }
92
+
93
+ // category is an alias for namespace in claude-flow
94
+ const namespace = input.namespace ?? input.category ?? 'default';
95
+
96
+ return {
97
+ content,
98
+ key,
99
+ namespace,
100
+ type: input.type ?? 'episodic',
101
+ tags: input.tags ?? [],
102
+ importance: input.importance ?? 0.5,
103
+ ttl: input.ttl,
104
+ metadata: input.metadata ?? {},
105
+ source,
106
+ originalValue,
107
+ };
108
+ }
109
+
110
+ /**
111
+ * Format an ObservationPayload for ruflo-style retrieve response.
112
+ * Parses content back to original value if it was JSON.
113
+ */
114
+ export function formatRufloRetrieve(payload: ObservationPayload): {
115
+ key: string;
116
+ value: unknown;
117
+ content: string;
118
+ namespace: string;
119
+ type: string;
120
+ tags: string[];
121
+ importance: number;
122
+ created_at: string;
123
+ accessed_at: string;
124
+ found: boolean;
125
+ } {
126
+ let value: unknown = payload.content;
127
+ // Try to parse back to original type
128
+ try {
129
+ value = JSON.parse(payload.content);
130
+ } catch {
131
+ value = payload.content;
132
+ }
133
+
134
+ return {
135
+ key: payload.key ?? '',
136
+ value,
137
+ content: payload.content,
138
+ namespace: payload.namespace,
139
+ type: payload.type,
140
+ tags: payload.tags,
141
+ importance: payload.importance,
142
+ created_at: new Date(payload.created_at).toISOString(),
143
+ accessed_at: new Date(payload.accessed_at).toISOString(),
144
+ found: true,
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Format an ObservationPayload for memory_search response (compatible with both schemas).
150
+ */
151
+ export function formatMemorySearchResult(payload: ObservationPayload, relevanceScore: number): {
152
+ id: string;
153
+ key: string | null;
154
+ content: string;
155
+ value: unknown;
156
+ type: string;
157
+ namespace: string;
158
+ tags: string[];
159
+ importance: number;
160
+ relevance: number;
161
+ created_at: string;
162
+ accessed_at: string;
163
+ metadata: Record<string, unknown> | undefined;
164
+ source: MemorySource;
165
+ } {
166
+ let value: unknown = payload.content;
167
+ // Try to parse back to original type for ruflo compat
168
+ try {
169
+ value = JSON.parse(payload.content);
170
+ } catch {
171
+ value = payload.content;
172
+ }
173
+
174
+ return {
175
+ id: payload.id,
176
+ key: payload.key,
177
+ content: payload.content,
178
+ value,
179
+ type: payload.type,
180
+ namespace: payload.namespace,
181
+ tags: payload.tags,
182
+ importance: payload.importance,
183
+ relevance: relevanceScore,
184
+ created_at: new Date(payload.created_at).toISOString(),
185
+ accessed_at: new Date(payload.accessed_at).toISOString(),
186
+ metadata: Object.keys(payload.metadata).length > 0 ? payload.metadata : undefined,
187
+ source: payload.source,
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Build a Qdrant filter for memory_search based on the input parameters.
193
+ */
194
+ export function buildMemorySearchFilter(params: {
195
+ namespace?: string;
196
+ category?: string;
197
+ type?: string;
198
+ tags?: string[];
199
+ source?: MemorySource;
200
+ includeStale?: boolean;
201
+ }): Record<string, unknown> | undefined {
202
+ const must: Array<{ key: string; match: { value: unknown } }> = [];
203
+
204
+ // Namespace / category filter
205
+ const ns = params.namespace ?? params.category;
206
+ if (ns && ns !== 'default') {
207
+ must.push({ key: 'namespace', match: { value: ns } });
208
+ }
209
+
210
+ // Type filter
211
+ if (params.type && params.type !== 'all') {
212
+ must.push({ key: 'type', match: { value: params.type } });
213
+ }
214
+
215
+ // Source filter
216
+ if (params.source) {
217
+ must.push({ key: 'source', match: { value: params.source } });
218
+ }
219
+
220
+ // Tags filter - must match ALL tags (AND logic per architecture spec)
221
+ // Qdrant doesn't support AND on array elements natively, so we filter post-search
222
+ // The tags param is handled in post-processing.
223
+
224
+ return must.length > 0 ? { must } : undefined;
225
+ }
226
+
227
+ /**
228
+ * Post-filter results by tags (AND logic: result must have ALL requested tags).
229
+ */
230
+ export function filterByTags<T extends { tags: string[] }>(results: T[], tags: string[]): T[] {
231
+ if (!tags || tags.length === 0) return results;
232
+ return results.filter(r => tags.every(tag => r.tags.includes(tag)));
233
+ }
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Observation store - CRUD for observations with symbol linking.
3
+ * Observations are stored in Qdrant (vector search) and FalkorDB (graph links).
4
+ * Implements the save_observation and related memory tool semantics from architecture.md.
5
+ *
6
+ * Note: ObservationRoute is defined inline here rather than imported from
7
+ * knowledge/routing-engine.ts (that module is not merged from forge-graph-rag;
8
+ * the pipeline server has its own knowledge/ modules).
9
+ */
10
+
11
+ import { randomUUID } from 'crypto';
12
+ import type { VectorStore, GraphStore } from '../storage/interfaces.js';
13
+ import type { ObservationPayload } from '../util/types.js';
14
+ import { embedText } from '../ingestion/embedder.js';
15
+ import { LINK_OBSERVATION_TO_SYMBOL, UPSERT_OBSERVATION } from '../query/graph-queries.js';
16
+ import { incrementObservationCount } from './session-tracker.js';
17
+ import { logger } from '../util/logger.js';
18
+
19
+ // Inline type — matches the shape from forge-graph-rag's routing-engine.ts
20
+ export interface ObservationRoute {
21
+ writeVector: boolean;
22
+ writeGraphNode: boolean;
23
+ defaultNamespace: string;
24
+ }
25
+
26
+ export interface SaveObservationOptions {
27
+ content: string;
28
+ symbols?: string[];
29
+ repoId?: string;
30
+ importance?: number;
31
+ tags?: string[];
32
+ category?: string;
33
+ sessionId: string;
34
+ type?: ObservationPayload['type'];
35
+ source?: ObservationPayload['source'];
36
+ // Ruflo-style key-value support
37
+ key?: string;
38
+ namespace?: string;
39
+ value?: unknown;
40
+ metadata?: Record<string, unknown>;
41
+ ttl?: number;
42
+ }
43
+
44
+ export interface SaveObservationResult {
45
+ id: string;
46
+ stored: boolean;
47
+ linkedSymbols: string[];
48
+ unresolvedSymbols: string[];
49
+ }
50
+
51
+ /**
52
+ * Save an observation to Qdrant (vector) and optionally FalkorDB (graph node + symbol links).
53
+ * The optional `route` parameter controls whether graph operations are executed.
54
+ * When `route.writeGraphNode` is false (external repo), only Qdrant is written.
55
+ */
56
+ export async function saveObservation(
57
+ opts: SaveObservationOptions,
58
+ vectorStore: VectorStore,
59
+ graphStore: GraphStore,
60
+ route?: ObservationRoute
61
+ ): Promise<SaveObservationResult> {
62
+ // Default route: write everywhere (backward-compatible when caller doesn't supply route)
63
+ const effectiveRoute: ObservationRoute = route ?? {
64
+ writeVector: true,
65
+ writeGraphNode: true,
66
+ defaultNamespace: 'default',
67
+ };
68
+ const {
69
+ content,
70
+ symbols = [],
71
+ repoId = null,
72
+ importance = 0.5,
73
+ tags = [],
74
+ category = null,
75
+ sessionId,
76
+ type = 'episodic',
77
+ source = 'forge',
78
+ key = null,
79
+ namespace = 'default',
80
+ value,
81
+ metadata = {},
82
+ ttl,
83
+ } = opts;
84
+
85
+ const id = randomUUID();
86
+ const now = Date.now();
87
+
88
+ // Build the content string - for ruflo-style key/value, serialize value
89
+ let finalContent = content;
90
+ if (!finalContent && value !== undefined) {
91
+ finalContent = typeof value === 'string' ? value : JSON.stringify(value);
92
+ }
93
+ if (!finalContent) {
94
+ finalContent = key ? `[key: ${key}]` : '[empty observation]';
95
+ }
96
+
97
+ // Build the observation payload (stored in Qdrant)
98
+ const payload: ObservationPayload = {
99
+ id,
100
+ repo_id: repoId ?? null,
101
+ session_id: sessionId,
102
+ content: finalContent,
103
+ type,
104
+ category,
105
+ tags,
106
+ importance,
107
+ created_at: now,
108
+ accessed_at: now,
109
+ access_count: 0,
110
+ is_stale: false,
111
+ linked_symbols: [],
112
+ source,
113
+ metadata: ttl ? { ...metadata, ttl, expires_at: now + ttl * 1000 } : metadata,
114
+ key,
115
+ namespace,
116
+ };
117
+
118
+ // Embed the content
119
+ let vector: number[];
120
+ try {
121
+ vector = await embedText(finalContent);
122
+ } catch (err) {
123
+ logger.warn('Failed to embed observation content', { error: String(err) });
124
+ // Fallback: zero vector (won't match anything but stores the payload)
125
+ vector = new Array(384).fill(0);
126
+ }
127
+
128
+ // Store in Qdrant
129
+ try {
130
+ await vectorStore.upsertObservation(id, vector, payload);
131
+ } catch (err) {
132
+ logger.error('Failed to store observation in Qdrant', { id, error: String(err) });
133
+ return { id, stored: false, linkedSymbols: [], unresolvedSymbols: symbols };
134
+ }
135
+
136
+ // Store Observation node in FalkorDB and link to symbols (owned repos only)
137
+ const linkedSymbols: string[] = [];
138
+ const unresolvedSymbols: string[] = [];
139
+
140
+ if (effectiveRoute.writeGraphNode) {
141
+ try {
142
+ await graphStore.query(UPSERT_OBSERVATION(id, finalContent, sessionId, importance));
143
+
144
+ // Attempt to link each symbol
145
+ for (const symbolName of symbols) {
146
+ try {
147
+ const effectiveRepoId = repoId ?? '';
148
+ await graphStore.query(LINK_OBSERVATION_TO_SYMBOL(id, symbolName, effectiveRepoId));
149
+ linkedSymbols.push(symbolName);
150
+ logger.debug('Linked observation to symbol', { observationId: id, symbol: symbolName });
151
+ } catch {
152
+ unresolvedSymbols.push(symbolName);
153
+ logger.debug('Symbol not found in graph for observation link', { symbol: symbolName });
154
+ }
155
+ }
156
+
157
+ // Update payload with resolved symbols
158
+ if (linkedSymbols.length > 0) {
159
+ await vectorStore.updateObservation(id, { linked_symbols: linkedSymbols });
160
+ }
161
+ } catch (err) {
162
+ // Graph operations failing is non-fatal - Qdrant is the source of truth
163
+ logger.warn('FalkorDB observation node creation failed (non-fatal)', { id, error: String(err) });
164
+ unresolvedSymbols.push(...symbols);
165
+ }
166
+ } else {
167
+ // External repo: all symbols are unresolved (no graph to link against)
168
+ unresolvedSymbols.push(...symbols);
169
+ logger.debug('External repo observation — skipping graph node creation', { id, repoId });
170
+ }
171
+
172
+ // Increment the in-memory session observation count
173
+ incrementObservationCount();
174
+
175
+ logger.info('Observation saved', {
176
+ id,
177
+ contentLength: finalContent.length,
178
+ linkedSymbols: linkedSymbols.length,
179
+ unresolvedSymbols: unresolvedSymbols.length,
180
+ });
181
+
182
+ return { id, stored: true, linkedSymbols, unresolvedSymbols };
183
+ }
184
+
185
+ /**
186
+ * Retrieve an observation by ID.
187
+ */
188
+ export async function getObservation(
189
+ id: string,
190
+ vectorStore: VectorStore
191
+ ): Promise<ObservationPayload | null> {
192
+ return vectorStore.getObservation(id);
193
+ }
194
+
195
+ /**
196
+ * Update access tracking for an observation (access_count, accessed_at).
197
+ */
198
+ export async function touchObservation(
199
+ id: string,
200
+ vectorStore: VectorStore
201
+ ): Promise<void> {
202
+ try {
203
+ const obs = await vectorStore.getObservation(id);
204
+ if (obs) {
205
+ await vectorStore.updateObservation(id, {
206
+ accessed_at: Date.now(),
207
+ access_count: (obs.access_count ?? 0) + 1,
208
+ });
209
+ }
210
+ } catch (err) {
211
+ logger.debug('Failed to update observation access tracking', { id, error: String(err) });
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Check if an observation has expired (TTL expired).
217
+ */
218
+ export function isExpired(payload: ObservationPayload): boolean {
219
+ const expiresAt = payload.metadata?.expires_at;
220
+ if (typeof expiresAt === 'number') {
221
+ return Date.now() > expiresAt;
222
+ }
223
+ return false;
224
+ }