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 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ // index.ts — B19
3
+ // Entry point for the dk-forge-server MCP server.
4
+ // Starts the server on stdio transport for use with Claude and other MCP clients.
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { createForgeServer } from './server.js';
7
+ async function main() {
8
+ const server = await createForgeServer();
9
+ const transport = new StdioServerTransport();
10
+ // Connect the server to the stdio transport
11
+ await server.connect(transport);
12
+ // Handle graceful shutdown on SIGINT (Ctrl-C) and SIGTERM
13
+ const shutdown = async (signal) => {
14
+ process.stderr.write(`\ndk-forge-server: received ${signal}, shutting down...\n`);
15
+ try {
16
+ // Close storage connections if the server exposes a close method
17
+ const serverWithClose = server;
18
+ if (typeof serverWithClose._closeConnections === 'function') {
19
+ await serverWithClose._closeConnections();
20
+ }
21
+ await server.close();
22
+ }
23
+ catch (err) {
24
+ process.stderr.write(`dk-forge-server: shutdown error: ${String(err)}\n`);
25
+ }
26
+ process.exit(0);
27
+ };
28
+ process.on('SIGINT', () => { void shutdown('SIGINT'); });
29
+ process.on('SIGTERM', () => { void shutdown('SIGTERM'); });
30
+ // Keep the process alive — stdio transport reads from stdin
31
+ // Node.js will keep running while stdin is open
32
+ }
33
+ main().catch((err) => {
34
+ process.stderr.write(`dk-forge-server: fatal error: ${String(err)}\n`);
35
+ process.exit(1);
36
+ });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,iBAAiB;AACjB,kDAAkD;AAClD,kFAAkF;AAElF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,4CAA4C;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,MAAM,sBAAsB,CAAC,CAAC;QAElF,IAAI,CAAC;YACH,iEAAiE;YACjE,MAAM,eAAe,GAAG,MAEvB,CAAC;YACF,IAAI,OAAO,eAAe,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;gBAC5D,MAAM,eAAe,CAAC,iBAAiB,EAAE,CAAC;YAC5C,CAAC;YAED,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3D,4DAA4D;IAC5D,gDAAgD;AAClD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * AST-aware code chunker (ADR-5).
3
+ * Primary strategy: each top-level entity becomes one chunk (function, class, interface, etc.)
4
+ * Fallback: fixed-size 512-token chunks with 64-token overlap for non-parseable files.
5
+ * Large entities (>1024 tokens) are split at method boundaries.
6
+ */
7
+ import type { ParsedEntity, ParsedImport, CodeChunk, ChunkType } from '../util/types.js';
8
+ /**
9
+ * Generate chunks from parsed AST entities.
10
+ * Called when we have a successful AST parse result.
11
+ */
12
+ export declare function chunkFromEntities(entities: ParsedEntity[], imports: ParsedImport[], fileContent: string, filePath: string, repoId: string, language: string, indexedAt: number): CodeChunk[];
13
+ /**
14
+ * Generate fixed-size chunks for non-parseable files (markdown, JSON, YAML, config).
15
+ */
16
+ export declare function chunkFixed(content: string, filePath: string, repoId: string, language: string, indexedAt: number): CodeChunk[];
17
+ export declare function makeChunk(content: string, filePath: string, repoId: string, entityType: ChunkType, startLine: number, endLine: number, language: string, indexedAt: number, entityName?: string): CodeChunk;
18
+ export declare function buildChunkHeader(filePath: string, entityName: string | null, entityType: ChunkType, startLine: number, endLine: number): string;
19
+ //# sourceMappingURL=chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../../src/ingestion/chunker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOzF;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,SAAS,EAAE,CAcb;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,SAAS,EAAE,CAyCb;AAsGD,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,SAAS,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,SAAS,CAkBX;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,UAAU,EAAE,SAAS,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CAGR"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * AST-aware code chunker (ADR-5).
3
+ * Primary strategy: each top-level entity becomes one chunk (function, class, interface, etc.)
4
+ * Fallback: fixed-size 512-token chunks with 64-token overlap for non-parseable files.
5
+ * Large entities (>1024 tokens) are split at method boundaries.
6
+ */
7
+ import { createHash } from 'crypto';
8
+ import { randomUUID } from 'crypto';
9
+ import { extname } from 'path';
10
+ import { estimateTokens } from '../util/token-counter.js';
11
+ const CHUNK_MAX_TOKENS = 1024;
12
+ const FIXED_CHUNK_SIZE_TOKENS = 512;
13
+ const FIXED_CHUNK_OVERLAP_TOKENS = 64;
14
+ /**
15
+ * Generate chunks from parsed AST entities.
16
+ * Called when we have a successful AST parse result.
17
+ */
18
+ export function chunkFromEntities(entities, imports, fileContent, filePath, repoId, language, indexedAt) {
19
+ const chunks = [];
20
+ // Generate the file-level chunk (imports + any top-level statements not in entities)
21
+ const fileLevelChunk = buildFileLevelChunk(imports, fileContent, filePath, repoId, language, indexedAt, entities);
22
+ if (fileLevelChunk)
23
+ chunks.push(fileLevelChunk);
24
+ // Generate one chunk per entity
25
+ for (const entity of entities) {
26
+ const entityChunks = buildEntityChunks(entity, filePath, repoId, language, indexedAt);
27
+ chunks.push(...entityChunks);
28
+ }
29
+ return chunks;
30
+ }
31
+ /**
32
+ * Generate fixed-size chunks for non-parseable files (markdown, JSON, YAML, config).
33
+ */
34
+ export function chunkFixed(content, filePath, repoId, language, indexedAt) {
35
+ const ext = extname(filePath).toLowerCase();
36
+ const chunkType = detectNonCodeType(ext);
37
+ // Split content into lines for better boundary detection
38
+ const lines = content.split('\n');
39
+ const chunks = [];
40
+ let currentLines = [];
41
+ let currentTokens = 0;
42
+ let startLine = 1;
43
+ const flushChunk = (endLine) => {
44
+ if (currentLines.length === 0)
45
+ return;
46
+ const chunkContent = buildChunkHeader(filePath, null, chunkType, startLine, endLine) +
47
+ currentLines.join('\n');
48
+ chunks.push(makeChunk(chunkContent, filePath, repoId, chunkType, startLine, endLine, language, indexedAt));
49
+ };
50
+ for (const line of lines) {
51
+ const lineTokens = estimateTokens(line);
52
+ if (currentTokens + lineTokens > FIXED_CHUNK_SIZE_TOKENS && currentLines.length > 0) {
53
+ flushChunk(startLine + currentLines.length - 1);
54
+ // Overlap: keep last N token-equivalent lines
55
+ const overlapLines = getOverlapLines(currentLines, FIXED_CHUNK_OVERLAP_TOKENS);
56
+ startLine = startLine + currentLines.length - overlapLines.length;
57
+ currentLines = overlapLines;
58
+ currentTokens = estimateTokensForLines(overlapLines);
59
+ }
60
+ currentLines.push(line);
61
+ currentTokens += lineTokens;
62
+ }
63
+ if (currentLines.length > 0) {
64
+ flushChunk(startLine + currentLines.length - 1);
65
+ }
66
+ return chunks;
67
+ }
68
+ function buildFileLevelChunk(imports, fileContent, filePath, repoId, language, indexedAt, entities) {
69
+ if (imports.length === 0 && entities.length > 0)
70
+ return null;
71
+ // Build import block
72
+ const importLines = imports.map(imp => {
73
+ if (imp.isDefault) {
74
+ return `import ${imp.specifiers} from '${imp.fromPath}';`;
75
+ }
76
+ return `import ${imp.specifiers} from '${imp.fromPath}';`;
77
+ });
78
+ // Find the last line of the last import to get file-level lines
79
+ const importBlock = importLines.join('\n');
80
+ if (!importBlock.trim())
81
+ return null;
82
+ const header = buildChunkHeader(filePath, null, 'file_level', 1, importLines.length);
83
+ const content = header + importBlock;
84
+ if (estimateTokens(content) < 10)
85
+ return null;
86
+ return makeChunk(content, filePath, repoId, 'file_level', 1, importLines.length, language, indexedAt);
87
+ }
88
+ function buildEntityChunks(entity, filePath, repoId, language, indexedAt) {
89
+ const chunkType = entityTypeToChunkType(entity.type);
90
+ const header = buildChunkHeader(filePath, entity.name, chunkType, entity.startLine, entity.endLine);
91
+ const content = header + entity.sourceText;
92
+ const tokens = estimateTokens(content);
93
+ if (tokens <= CHUNK_MAX_TOKENS) {
94
+ // Single chunk for this entity
95
+ return [makeChunk(content, filePath, repoId, chunkType, entity.startLine, entity.endLine, language, indexedAt)];
96
+ }
97
+ // Entity is too large - split at method/property boundaries (heuristic line split)
98
+ return splitLargeEntity(content, entity, filePath, repoId, chunkType, language, indexedAt);
99
+ }
100
+ function splitLargeEntity(content, entity, filePath, repoId, chunkType, language, indexedAt) {
101
+ const chunks = [];
102
+ const lines = content.split('\n');
103
+ let currentLines = [];
104
+ let currentTokens = 0;
105
+ let chunkIndex = 0;
106
+ let chunkStartLine = entity.startLine;
107
+ const flush = () => {
108
+ if (currentLines.length === 0)
109
+ return;
110
+ const chunkContent = currentLines.join('\n');
111
+ const chunkEndLine = chunkStartLine + currentLines.length - 1;
112
+ chunks.push(makeChunk(chunkContent, filePath, repoId, chunkType, chunkStartLine, chunkEndLine, language, indexedAt, `${entity.name}_part${chunkIndex++}`));
113
+ chunkStartLine = chunkEndLine + 1;
114
+ currentLines = [];
115
+ currentTokens = 0;
116
+ };
117
+ for (const line of lines) {
118
+ const lineTokens = estimateTokens(line);
119
+ if (currentTokens + lineTokens > CHUNK_MAX_TOKENS && currentLines.length > 0) {
120
+ flush();
121
+ }
122
+ currentLines.push(line);
123
+ currentTokens += lineTokens;
124
+ }
125
+ flush();
126
+ return chunks;
127
+ }
128
+ export function makeChunk(content, filePath, repoId, entityType, startLine, endLine, language, indexedAt, entityName) {
129
+ const id = randomUUID();
130
+ const contentHash = createHash('sha256').update(content, 'utf8').digest('hex');
131
+ return {
132
+ id,
133
+ repoId,
134
+ filePath,
135
+ entityName: entityName ?? null,
136
+ entityType,
137
+ startLine,
138
+ endLine,
139
+ language,
140
+ contentHash,
141
+ content,
142
+ contentPreview: content.slice(0, 200),
143
+ indexedAt,
144
+ };
145
+ }
146
+ export function buildChunkHeader(filePath, entityName, entityType, startLine, endLine) {
147
+ const nameStr = entityName ? ` ${entityName}` : '';
148
+ return `// [dk-forge] file: ${filePath} | entity:${nameStr} (${entityType}) | lines: ${startLine}-${endLine}\n`;
149
+ }
150
+ function entityTypeToChunkType(type) {
151
+ const map = {
152
+ function: 'function',
153
+ class: 'class',
154
+ interface: 'interface',
155
+ type_alias: 'type_alias',
156
+ variable: 'variable',
157
+ module: 'file_level',
158
+ file: 'file_level',
159
+ };
160
+ return map[type] ?? 'file_level';
161
+ }
162
+ function detectNonCodeType(ext) {
163
+ if (ext === '.md' || ext === '.mdx')
164
+ return 'markdown';
165
+ if (ext === '.json' || ext === '.yaml' || ext === '.yml' || ext === '.toml')
166
+ return 'config';
167
+ if (ext === '.graphql' || ext === '.gql')
168
+ return 'config';
169
+ if (ext === '.sql')
170
+ return 'config';
171
+ return 'config';
172
+ }
173
+ function getOverlapLines(lines, targetTokens) {
174
+ let tokens = 0;
175
+ const result = [];
176
+ for (let i = lines.length - 1; i >= 0; i--) {
177
+ const line = lines[i] ?? '';
178
+ const t = estimateTokens(line);
179
+ if (tokens + t > targetTokens)
180
+ break;
181
+ result.unshift(line);
182
+ tokens += t;
183
+ }
184
+ return result;
185
+ }
186
+ function estimateTokensForLines(lines) {
187
+ return lines.reduce((sum, line) => sum + estimateTokens(line), 0);
188
+ }
189
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../../src/ingestion/chunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Embedding pipeline using Transformers.js with ONNX backend (ADR-2).
3
+ * Model: all-MiniLM-L6-v2 (384-dim, ~23 MB quantized, ~5ms/embed).
4
+ * Singleton pattern - expensive to initialize, reuse across all calls.
5
+ * Batch embedding: adaptive batch size (32 for long, 64 for short texts).
6
+ *
7
+ * Phase 5 changes:
8
+ * - Lazy initialization: model loads on first real query, not at startup.
9
+ * - isReady() lets callers surface "model loading..." status.
10
+ * - Adaptive batching: short texts (<100 chars) use batch size 64.
11
+ * - Throughput logging at info level during indexing.
12
+ */
13
+ /**
14
+ * Returns true when the embedding pipeline has been initialized and is ready.
15
+ * False means the first embed call will trigger model load (adds ~3-5 seconds).
16
+ */
17
+ export declare function isReady(): boolean;
18
+ /**
19
+ * Embed a single text string.
20
+ * Returns a 384-dimensional float array.
21
+ */
22
+ export declare function embedText(text: string): Promise<number[]>;
23
+ /**
24
+ * Embed multiple texts in adaptive batches.
25
+ * Short texts (< SHORT_TEXT_THRESHOLD chars average) use batch size 64.
26
+ * Long texts use batch size 32.
27
+ * Returns arrays in the same order as input.
28
+ * Logs embedding throughput (texts/sec) at info level.
29
+ */
30
+ export declare function embedBatch(texts: string[]): Promise<number[][]>;
31
+ /**
32
+ * Get the embedding dimension.
33
+ */
34
+ export declare function getEmbeddingDimension(): number;
35
+ /**
36
+ * Optionally pre-warm the embedding pipeline in the background.
37
+ *
38
+ * Phase 5: This is now a no-op at the call site — initialization is lazy.
39
+ * The model will load on the first real embed call instead.
40
+ * This function is kept for backward compatibility; callers that previously
41
+ * awaited it will continue to work. The model loads asynchronously without
42
+ * blocking the MCP server startup.
43
+ */
44
+ export declare function warmupEmbedder(): Promise<void>;
45
+ //# sourceMappingURL=embedder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedder.d.ts","sourceRoot":"","sources":["../../src/ingestion/embedder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH;;;GAGG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAkDD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAI/D;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CA6CrE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAIpD"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Embedding pipeline using Transformers.js with ONNX backend (ADR-2).
3
+ * Model: all-MiniLM-L6-v2 (384-dim, ~23 MB quantized, ~5ms/embed).
4
+ * Singleton pattern - expensive to initialize, reuse across all calls.
5
+ * Batch embedding: adaptive batch size (32 for long, 64 for short texts).
6
+ *
7
+ * Phase 5 changes:
8
+ * - Lazy initialization: model loads on first real query, not at startup.
9
+ * - isReady() lets callers surface "model loading..." status.
10
+ * - Adaptive batching: short texts (<100 chars) use batch size 64.
11
+ * - Throughput logging at info level during indexing.
12
+ */
13
+ import { logger } from '../util/logger.js';
14
+ const BASE_BATCH_SIZE = 32;
15
+ const SHORT_TEXT_BATCH_SIZE = 64;
16
+ const SHORT_TEXT_THRESHOLD = 100; // chars
17
+ const MODEL_NAME = 'Xenova/all-MiniLM-L6-v2';
18
+ const EMBEDDING_DIMENSION = 384;
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ let pipelineInstance = null;
21
+ let initPromise = null;
22
+ let modelReady = false;
23
+ /**
24
+ * Returns true when the embedding pipeline has been initialized and is ready.
25
+ * False means the first embed call will trigger model load (adds ~3-5 seconds).
26
+ */
27
+ export function isReady() {
28
+ return modelReady;
29
+ }
30
+ /**
31
+ * Initialize the embedding pipeline (singleton).
32
+ * Lazy: only called on first embed request, not at server startup.
33
+ * Downloads model on first use, uses cached copy thereafter.
34
+ */
35
+ async function ensurePipeline() {
36
+ if (pipelineInstance)
37
+ return;
38
+ if (initPromise)
39
+ return initPromise;
40
+ initPromise = (async () => {
41
+ try {
42
+ logger.info('Initializing embedding model (lazy load)', { model: MODEL_NAME });
43
+ const { pipeline, env } = await import('@huggingface/transformers');
44
+ // Configure cache location
45
+ const cacheDir = process.env.TRANSFORMERS_CACHE ?? undefined;
46
+ if (cacheDir) {
47
+ env.cacheDir = cacheDir;
48
+ }
49
+ // Use ONNX backend (default in Transformers.js)
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ pipelineInstance = await pipeline('feature-extraction', MODEL_NAME, {
52
+ dtype: 'q8', // Quantized INT8 for smaller memory footprint
53
+ });
54
+ modelReady = true;
55
+ logger.info('Embedding model initialized', { model: MODEL_NAME, dimension: EMBEDDING_DIMENSION });
56
+ }
57
+ catch (err) {
58
+ logger.error('Failed to initialize embedding model', { error: String(err) });
59
+ initPromise = null;
60
+ throw err;
61
+ }
62
+ })();
63
+ return initPromise;
64
+ }
65
+ /**
66
+ * Choose optimal batch size based on average text length.
67
+ * Short texts (<100 chars on average) pack more efficiently at batch 64.
68
+ */
69
+ function chooseBatchSize(texts) {
70
+ if (texts.length === 0)
71
+ return BASE_BATCH_SIZE;
72
+ const avgLen = texts.reduce((s, t) => s + t.length, 0) / texts.length;
73
+ return avgLen < SHORT_TEXT_THRESHOLD ? SHORT_TEXT_BATCH_SIZE : BASE_BATCH_SIZE;
74
+ }
75
+ /**
76
+ * Embed a single text string.
77
+ * Returns a 384-dimensional float array.
78
+ */
79
+ export async function embedText(text) {
80
+ await ensurePipeline();
81
+ const result = await pipelineInstance(text, { pooling: 'mean', normalize: true });
82
+ return Array.from(result.data);
83
+ }
84
+ /**
85
+ * Embed multiple texts in adaptive batches.
86
+ * Short texts (< SHORT_TEXT_THRESHOLD chars average) use batch size 64.
87
+ * Long texts use batch size 32.
88
+ * Returns arrays in the same order as input.
89
+ * Logs embedding throughput (texts/sec) at info level.
90
+ */
91
+ export async function embedBatch(texts) {
92
+ if (texts.length === 0)
93
+ return [];
94
+ await ensurePipeline();
95
+ const batchSize = chooseBatchSize(texts);
96
+ const results = [];
97
+ const startTime = Date.now();
98
+ for (let i = 0; i < texts.length; i += batchSize) {
99
+ const batch = texts.slice(i, i + batchSize);
100
+ try {
101
+ const output = await pipelineInstance(batch, { pooling: 'mean', normalize: true });
102
+ // output.data is a flat Float32Array: [batch_size * dim]
103
+ const data = output.data;
104
+ const dim = data.length / batch.length;
105
+ for (let j = 0; j < batch.length; j++) {
106
+ const vector = Array.from(data.slice(j * dim, (j + 1) * dim));
107
+ results.push(vector);
108
+ }
109
+ }
110
+ catch (err) {
111
+ logger.warn('Embedding batch failed, using zero vectors', {
112
+ batchStart: i,
113
+ batchSize: batch.length,
114
+ error: String(err),
115
+ });
116
+ // Fallback: push zero vectors for failed batch
117
+ for (let j = 0; j < batch.length; j++) {
118
+ results.push(new Array(EMBEDDING_DIMENSION).fill(0));
119
+ }
120
+ }
121
+ }
122
+ const elapsedMs = Date.now() - startTime;
123
+ const throughput = elapsedMs > 0 ? Math.round((texts.length / elapsedMs) * 1000) : texts.length;
124
+ logger.info('Embedding batch complete', {
125
+ totalTexts: texts.length,
126
+ batchSize,
127
+ elapsedMs,
128
+ throughputTextsPerSec: throughput,
129
+ });
130
+ return results;
131
+ }
132
+ /**
133
+ * Get the embedding dimension.
134
+ */
135
+ export function getEmbeddingDimension() {
136
+ return EMBEDDING_DIMENSION;
137
+ }
138
+ /**
139
+ * Optionally pre-warm the embedding pipeline in the background.
140
+ *
141
+ * Phase 5: This is now a no-op at the call site — initialization is lazy.
142
+ * The model will load on the first real embed call instead.
143
+ * This function is kept for backward compatibility; callers that previously
144
+ * awaited it will continue to work. The model loads asynchronously without
145
+ * blocking the MCP server startup.
146
+ */
147
+ export async function warmupEmbedder() {
148
+ // Do not eagerly load — lazy initialization is handled by ensurePipeline().
149
+ // Log a message so callers know the model will warm on first use.
150
+ logger.info('Embedding pipeline will warm on first use (lazy mode)', { model: MODEL_NAME });
151
+ }
152
+ //# sourceMappingURL=embedder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../src/ingestion/embedder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Git history analyzer for co-modification edges (Phase 2 full implementation).
3
+ * Runs `git log --name-only` to find files changed together frequently,
4
+ * creates CO_MODIFIED edges, and detects test file relationships.
5
+ *
6
+ * Phase 3 additions:
7
+ * - analyzeFileStats(): per-file commit count, stability, velocity
8
+ * - extractCommitRecords(): parse git log into CommitRecord[]
9
+ */
10
+ import type { GraphStore } from '../storage/interfaces.js';
11
+ import type { FileChangeStats, CommitRecord } from '../util/types.js';
12
+ export interface CoModificationPair {
13
+ fileA: string;
14
+ fileB: string;
15
+ count: number;
16
+ lastCommit: string;
17
+ }
18
+ export interface GitAnalysisResult {
19
+ coModifications: CoModificationPair[];
20
+ testPairs: Array<{
21
+ testFile: string;
22
+ sourceFile: string;
23
+ }>;
24
+ totalCommitsAnalyzed: number;
25
+ errors: string[];
26
+ }
27
+ /**
28
+ * Analyze git history to find files frequently changed together.
29
+ * Parses `git log --name-only` output for the last `historyDepth` commits,
30
+ * counts co-occurrence pairs, and returns pairs with count >= minComodCount.
31
+ */
32
+ export declare function analyzeCoModifications(repoPath: string, historyDepth?: number, minComodCount?: number): Promise<CoModificationPair[]>;
33
+ /**
34
+ * Parse `git log --name-only --format="%H"` output into commit groups.
35
+ * Each group contains a commit hash and the list of files changed.
36
+ */
37
+ export declare function parseGitLog(stdout: string): Array<{
38
+ hash: string;
39
+ files: string[];
40
+ }>;
41
+ /**
42
+ * Detect test files and their corresponding source files.
43
+ * Returns pairs: { testFile, sourceFile }
44
+ *
45
+ * Handles patterns:
46
+ * foo.spec.ts -> foo.ts
47
+ * foo.test.ts -> foo.ts
48
+ * __tests__/foo.ts -> ../foo.ts (sibling detection)
49
+ */
50
+ export declare function detectTestFiles(files: string[]): Promise<Array<{
51
+ testFile: string;
52
+ sourceFile: string;
53
+ }>>;
54
+ /**
55
+ * Run full git analysis for a repo: co-modifications + test file detection.
56
+ * Then write the edges to FalkorDB.
57
+ */
58
+ export declare function runGitAnalysis(repoPath: string, repoId: string, allFiles: string[], graphStore: GraphStore, historyDepth?: number, minComodCount?: number): Promise<GitAnalysisResult>;
59
+ /**
60
+ * Analyze per-file change statistics from git history.
61
+ * Runs a second git log with `%H|%s|%an|%aI` format (hash, subject, author, ISO date)
62
+ * plus `--name-only` to map commits to files.
63
+ *
64
+ * Computes per-file:
65
+ * - commitCount: total commits touching this file
66
+ * - stabilityScore: 0-1, higher = fewer recent changes relative to history
67
+ * - changeVelocity: -1 to +1, positive = accelerating changes
68
+ * - lastCommitHash, lastCommitTs, recentMessages (last 5)
69
+ */
70
+ export declare function analyzeFileStats(repoPath: string, historyDepth?: number): Promise<Map<string, FileChangeStats>>;
71
+ /**
72
+ * Extract commit records from git history.
73
+ * Parses git log into CommitRecord[], filtering merge commits and
74
+ * bulk reformats (commits touching >50 files).
75
+ */
76
+ export declare function extractCommitRecords(repoPath: string, historyDepth?: number): Promise<CommitRecord[]>;
77
+ //# sourceMappingURL=git-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-analyzer.d.ts","sourceRoot":"","sources":["../../src/ingestion/git-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKtE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,kBAAkB,EAAE,CAAC;IACtC,SAAS,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAY,EAC1B,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA2D/B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,GACb,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwC1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAuC1D;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,UAAU,EACtB,YAAY,GAAE,MAAY,EAC1B,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAoE5B;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAY,GACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAiFvC;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAY,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CAwCzB"}