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,230 @@
1
+ // KnowledgeYamlStore — reads and writes .forge/knowledge/*.yaml files.
2
+ //
3
+ // Each file is a YAML array of KnowledgeItem objects. The store maps
4
+ // KnowledgeCategory values to dedicated files so items can be retrieved
5
+ // by category without loading the full corpus.
6
+ //
7
+ // Design notes:
8
+ // - File I/O is synchronous. The MCP server is single-threaded; sync I/O
9
+ // keeps the surface area small and the error handling straightforward.
10
+ // - The store never caches in memory — every read hits the filesystem.
11
+ // This ensures multi-process safety (e.g. CLI + server running together)
12
+ // and keeps memory pressure low for a local dev tool.
13
+ // - getContentHash() enables cheap change detection by the knowledge-keeper
14
+ // agent without re-parsing every item.
15
+ import { parse, stringify } from 'yaml';
16
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { createHash } from 'node:crypto';
19
+ // ---------------------------------------------------------------------------
20
+ // Constants
21
+ // ---------------------------------------------------------------------------
22
+ const CATEGORY_FILES = {
23
+ gotcha: 'gotchas.yaml',
24
+ pattern: 'patterns.yaml',
25
+ decision: 'decisions.yaml',
26
+ convention: 'conventions.yaml',
27
+ };
28
+ const ALL_CATEGORIES = ['gotcha', 'pattern', 'decision', 'convention'];
29
+ // ---------------------------------------------------------------------------
30
+ // KnowledgeYamlStore
31
+ // ---------------------------------------------------------------------------
32
+ export class KnowledgeYamlStore {
33
+ forgeDir;
34
+ knowledgeDir;
35
+ constructor(forgeDir) {
36
+ this.forgeDir = forgeDir;
37
+ this.knowledgeDir = join(forgeDir, 'knowledge');
38
+ }
39
+ // ---------------------------------------------------------------------------
40
+ // Public API
41
+ // ---------------------------------------------------------------------------
42
+ /**
43
+ * Read all items from a single category file.
44
+ * Returns an empty array if the file does not exist or is empty.
45
+ */
46
+ readCategory(category) {
47
+ const filePath = this._filePath(category);
48
+ return this._readFile(filePath);
49
+ }
50
+ /**
51
+ * Read all items across every category file, concatenated into one array.
52
+ * Items from each category are returned in file order, categories in the
53
+ * order defined by ALL_CATEGORIES.
54
+ */
55
+ readAll() {
56
+ const result = [];
57
+ for (const category of ALL_CATEGORIES) {
58
+ result.push(...this.readCategory(category));
59
+ }
60
+ return result;
61
+ }
62
+ /**
63
+ * Overwrite a category file with the supplied items array.
64
+ * Creates the knowledge directory if it does not exist.
65
+ * Passing an empty array produces a file containing `[]`.
66
+ */
67
+ writeCategory(category, items) {
68
+ this._ensureDir();
69
+ const filePath = this._filePath(category);
70
+ const yaml = stringify(items, {
71
+ indent: 2,
72
+ // Use block scalars for long content strings so diffs are readable.
73
+ defaultStringType: 'PLAIN',
74
+ });
75
+ writeFileSync(filePath, yaml, 'utf8');
76
+ }
77
+ /**
78
+ * Append a single item to the appropriate category file.
79
+ * The category is derived from the item's id prefix:
80
+ * gotcha-* → gotcha
81
+ * pattern-* → pattern
82
+ * decision-* → decision
83
+ * convention-* → convention
84
+ *
85
+ * If the item does not match any prefix, it falls through to the pattern
86
+ * file as a safe default.
87
+ */
88
+ addItem(item) {
89
+ const category = this._categoryFromItem(item);
90
+ const existing = this.readCategory(category);
91
+ // Deduplicate by id — if an item with this id already exists, replace it.
92
+ const idx = existing.findIndex((i) => i.id === item.id);
93
+ if (idx >= 0) {
94
+ existing[idx] = item;
95
+ }
96
+ else {
97
+ existing.push(item);
98
+ }
99
+ this.writeCategory(category, existing);
100
+ }
101
+ /**
102
+ * Update an existing item by id across all category files.
103
+ * Applies the supplied partial updates to the first matching item.
104
+ * Returns true if an item was found and updated, false otherwise.
105
+ */
106
+ updateItem(id, updates) {
107
+ for (const category of ALL_CATEGORIES) {
108
+ const items = this.readCategory(category);
109
+ const idx = items.findIndex((i) => i.id === id);
110
+ if (idx >= 0) {
111
+ items[idx] = {
112
+ ...items[idx],
113
+ ...updates,
114
+ // Always bump updated_at when the caller hasn't supplied it.
115
+ updated_at: updates.updated_at ?? Date.now(),
116
+ };
117
+ this.writeCategory(category, items);
118
+ return true;
119
+ }
120
+ }
121
+ return false;
122
+ }
123
+ /**
124
+ * Remove an item by id across all category files.
125
+ * Returns true if an item was found and removed, false otherwise.
126
+ */
127
+ removeItem(id) {
128
+ for (const category of ALL_CATEGORIES) {
129
+ const items = this.readCategory(category);
130
+ const filtered = items.filter((i) => i.id !== id);
131
+ if (filtered.length < items.length) {
132
+ this.writeCategory(category, filtered);
133
+ return true;
134
+ }
135
+ }
136
+ return false;
137
+ }
138
+ /**
139
+ * Create the .forge/knowledge/ directory and initialise empty YAML files
140
+ * for every category. Existing files are left untouched — initialize() is
141
+ * safe to call multiple times.
142
+ */
143
+ initialize() {
144
+ this._ensureDir();
145
+ for (const category of ALL_CATEGORIES) {
146
+ const filePath = this._filePath(category);
147
+ if (!existsSync(filePath)) {
148
+ // Write an empty YAML array so the file is valid YAML from the start.
149
+ writeFileSync(filePath, '[]\n', 'utf8');
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * Compute a SHA-256 hash over the concatenated contents of all category
155
+ * files. Files that do not exist contribute an empty string to the hash.
156
+ * The hash changes whenever any item is added, updated, or removed, making
157
+ * it useful for cheap change detection without re-parsing every item.
158
+ */
159
+ getContentHash() {
160
+ const hash = createHash('sha256');
161
+ for (const category of ALL_CATEGORIES) {
162
+ const filePath = this._filePath(category);
163
+ if (existsSync(filePath)) {
164
+ const content = readFileSync(filePath, 'utf8');
165
+ hash.update(content);
166
+ }
167
+ else {
168
+ hash.update('');
169
+ }
170
+ }
171
+ return hash.digest('hex');
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Private helpers
175
+ // ---------------------------------------------------------------------------
176
+ /** Absolute path to the YAML file for a given category. */
177
+ _filePath(category) {
178
+ return join(this.knowledgeDir, CATEGORY_FILES[category]);
179
+ }
180
+ /** Ensure the knowledge directory exists. */
181
+ _ensureDir() {
182
+ if (!existsSync(this.knowledgeDir)) {
183
+ mkdirSync(this.knowledgeDir, { recursive: true });
184
+ }
185
+ }
186
+ /**
187
+ * Parse a YAML file and return its items.
188
+ * Returns [] when the file is missing, empty, or contains a YAML null
189
+ * (which is what an empty file or `---` alone produces).
190
+ */
191
+ _readFile(filePath) {
192
+ if (!existsSync(filePath)) {
193
+ return [];
194
+ }
195
+ // Guard against zero-byte files — parse('') returns null in the yaml
196
+ // package, not an empty array.
197
+ const stat = statSync(filePath);
198
+ if (stat.size === 0) {
199
+ return [];
200
+ }
201
+ const content = readFileSync(filePath, 'utf8');
202
+ const parsed = parse(content);
203
+ if (parsed === null || parsed === undefined) {
204
+ return [];
205
+ }
206
+ if (!Array.isArray(parsed)) {
207
+ throw new Error(`KnowledgeYamlStore: expected array at ${filePath}, got ${typeof parsed}`);
208
+ }
209
+ // Cast: the YAML is authoritative. Callers writing items go through our
210
+ // typed addItem/writeCategory methods so the shape is always correct.
211
+ return parsed;
212
+ }
213
+ /**
214
+ * Derive the KnowledgeCategory for a given item based on its id prefix.
215
+ * Falls back to 'pattern' when the id does not match a known prefix.
216
+ */
217
+ _categoryFromItem(item) {
218
+ const id = item.id.toLowerCase();
219
+ if (id.startsWith('gotcha'))
220
+ return 'gotcha';
221
+ if (id.startsWith('pattern'))
222
+ return 'pattern';
223
+ if (id.startsWith('decision'))
224
+ return 'decision';
225
+ if (id.startsWith('convention'))
226
+ return 'convention';
227
+ return 'pattern';
228
+ }
229
+ }
230
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/knowledge/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { QdrantVectorStore } from '../storage/qdrant-store.js';
2
+ export declare class ConfidenceManager {
3
+ /**
4
+ * Apply time-based confidence decay to all knowledge items in Qdrant.
5
+ *
6
+ * Algorithm:
7
+ * 1. Scroll through all knowledge items in pages of SCROLL_PAGE_SIZE.
8
+ * 2. For each item whose accessed_at is older than DECAY_GRACE_PERIOD_MS:
9
+ * a. Compute new_confidence = max(MIN_CONFIDENCE, confidence - decayRate).
10
+ * b. If new_confidence != confidence, call setPayload to update.
11
+ * 3. Return the total count of items whose confidence was updated.
12
+ *
13
+ * This method is intentionally slow (one HTTP call per decayed item) because
14
+ * it is designed to run as a background task, not in the hot path. A batch
15
+ * update path can be optimised once the volume of knowledge items justifies it.
16
+ */
17
+ decayAll(vectorStore: QdrantVectorStore, decayRate?: number): Promise<number>;
18
+ /**
19
+ * Boost the confidence of a specific knowledge item.
20
+ *
21
+ * Updates:
22
+ * confidence += amount (capped at MAX_CONFIDENCE)
23
+ * accessed_at = now
24
+ * access_count += 1
25
+ *
26
+ * Fails silently on Qdrant errors — boosting is a best-effort operation.
27
+ */
28
+ boost(vectorStore: QdrantVectorStore, knowledgeId: string, amount?: number): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=confidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../src/learning/confidence.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAwBpE,qBAAa,iBAAiB;IAC5B;;;;;;;;;;;;;OAaG;IACG,QAAQ,CACZ,WAAW,EAAE,iBAAiB,EAC9B,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,MAAM,CAAC;IAoElB;;;;;;;;;OASG;IACG,KAAK,CACT,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,MAAa,GACpB,OAAO,CAAC,IAAI,CAAC;CA0CjB"}
@@ -0,0 +1,165 @@
1
+ // ConfidenceManager — B12
2
+ //
3
+ // Manages confidence score lifecycle for knowledge items stored in Qdrant.
4
+ //
5
+ // Confidence represents how well-validated a knowledge item is:
6
+ // 0.0 – pure speculation, has never proven useful
7
+ // 0.5 – moderate confidence, has been seen in a couple of contexts
8
+ // 1.0 – very high confidence, validated across many projects
9
+ //
10
+ // Two operations:
11
+ //
12
+ // decayAll(vectorStore, decayRate)
13
+ // Applies time-based confidence decay to all items that have not been
14
+ // accessed recently. Items accessed within the last 30 days are not
15
+ // decayed. The default decay rate is 0.01 per run (about 1 percentage
16
+ // point). Items whose confidence would fall below MIN_CONFIDENCE (0.1)
17
+ // are floored there rather than deleted — deletion is a policy decision
18
+ // for operators, not an automatic side effect of decay.
19
+ //
20
+ // boost(vectorStore, knowledgeId, amount)
21
+ // Increases the confidence of a specific item by `amount` (default 0.05).
22
+ // Also bumps accessed_at and access_count. Capped at 1.0.
23
+ //
24
+ // Both methods are async and fail silently on Qdrant errors — confidence
25
+ // management is best-effort. It must never block the pipeline.
26
+ import { logger } from '../util/logger.js';
27
+ // ---------------------------------------------------------------------------
28
+ // Constants
29
+ // ---------------------------------------------------------------------------
30
+ /** Items accessed within this window (ms) are not decayed. */
31
+ const DECAY_GRACE_PERIOD_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
32
+ /** Items whose confidence falls at or below this value are not decayed further. */
33
+ const MIN_CONFIDENCE = 0.1;
34
+ /** Maximum confidence a single boost can reach. */
35
+ const MAX_CONFIDENCE = 1.0;
36
+ /** How many knowledge items to scroll per Qdrant page during decay. */
37
+ const SCROLL_PAGE_SIZE = 100;
38
+ // ---------------------------------------------------------------------------
39
+ // ConfidenceManager
40
+ // ---------------------------------------------------------------------------
41
+ export class ConfidenceManager {
42
+ /**
43
+ * Apply time-based confidence decay to all knowledge items in Qdrant.
44
+ *
45
+ * Algorithm:
46
+ * 1. Scroll through all knowledge items in pages of SCROLL_PAGE_SIZE.
47
+ * 2. For each item whose accessed_at is older than DECAY_GRACE_PERIOD_MS:
48
+ * a. Compute new_confidence = max(MIN_CONFIDENCE, confidence - decayRate).
49
+ * b. If new_confidence != confidence, call setPayload to update.
50
+ * 3. Return the total count of items whose confidence was updated.
51
+ *
52
+ * This method is intentionally slow (one HTTP call per decayed item) because
53
+ * it is designed to run as a background task, not in the hot path. A batch
54
+ * update path can be optimised once the volume of knowledge items justifies it.
55
+ */
56
+ async decayAll(vectorStore, decayRate = 0.01) {
57
+ const healthy = await vectorStore.isHealthy();
58
+ if (!healthy) {
59
+ logger.warn('ConfidenceManager.decayAll: Qdrant unavailable, skipping decay');
60
+ return 0;
61
+ }
62
+ const now = Date.now();
63
+ const graceCutoff = now - DECAY_GRACE_PERIOD_MS;
64
+ let decayedCount = 0;
65
+ // Use filterKnowledge (scroll with empty filter) to paginate through all
66
+ // knowledge items. setKnowledgePayload is used to patch confidence values.
67
+ // Both methods are real exports on QdrantVectorStore.
68
+ let page;
69
+ try {
70
+ page = await vectorStore.filterKnowledge({}, SCROLL_PAGE_SIZE);
71
+ }
72
+ catch (err) {
73
+ logger.warn('ConfidenceManager.decayAll: initial scroll failed, stopping', {
74
+ error: String(err),
75
+ });
76
+ return 0;
77
+ }
78
+ for (const point of page) {
79
+ const p = point.payload;
80
+ const accessedAt = p.accessed_at ?? 0;
81
+ const confidence = p.confidence ?? 0;
82
+ // Skip recently accessed items
83
+ if (accessedAt >= graceCutoff)
84
+ continue;
85
+ // Skip items already at floor
86
+ if (confidence <= MIN_CONFIDENCE)
87
+ continue;
88
+ const newConfidence = Math.max(MIN_CONFIDENCE, confidence - decayRate);
89
+ // Round to 4 decimal places to avoid floating-point drift
90
+ const rounded = Math.round(newConfidence * 10000) / 10000;
91
+ if (rounded === confidence)
92
+ continue; // No change needed
93
+ try {
94
+ await vectorStore.setKnowledgePayload(point.id, { confidence: rounded });
95
+ decayedCount++;
96
+ logger.debug('ConfidenceManager.decayAll: item decayed', {
97
+ id: point.id,
98
+ oldConfidence: confidence,
99
+ newConfidence: rounded,
100
+ });
101
+ }
102
+ catch (err) {
103
+ // Non-fatal — log and continue to next item
104
+ logger.debug('ConfidenceManager.decayAll: failed to update item', {
105
+ id: point.id,
106
+ error: String(err),
107
+ });
108
+ }
109
+ }
110
+ logger.info('ConfidenceManager.decayAll: complete', {
111
+ decayedCount,
112
+ decayRate,
113
+ });
114
+ return decayedCount;
115
+ }
116
+ /**
117
+ * Boost the confidence of a specific knowledge item.
118
+ *
119
+ * Updates:
120
+ * confidence += amount (capped at MAX_CONFIDENCE)
121
+ * accessed_at = now
122
+ * access_count += 1
123
+ *
124
+ * Fails silently on Qdrant errors — boosting is a best-effort operation.
125
+ */
126
+ async boost(vectorStore, knowledgeId, amount = 0.05) {
127
+ const healthy = await vectorStore.isHealthy();
128
+ if (!healthy) {
129
+ logger.debug('ConfidenceManager.boost: Qdrant unavailable, skip', { knowledgeId });
130
+ return;
131
+ }
132
+ try {
133
+ let currentConfidence = 0.5;
134
+ let currentAccessCount = 0;
135
+ const existing = await vectorStore.getKnowledge(knowledgeId);
136
+ if (!existing) {
137
+ logger.debug('ConfidenceManager.boost: item not found', { knowledgeId });
138
+ return;
139
+ }
140
+ const payload = existing;
141
+ currentConfidence = (typeof payload.confidence === 'number' ? payload.confidence : null) ?? 0.5;
142
+ currentAccessCount = (typeof payload.access_count === 'number' ? payload.access_count : null) ?? 0;
143
+ const newConfidence = Math.min(MAX_CONFIDENCE, currentConfidence + amount);
144
+ const rounded = Math.round(newConfidence * 10000) / 10000;
145
+ await vectorStore.setKnowledgePayload(knowledgeId, {
146
+ confidence: rounded,
147
+ accessed_at: Date.now(),
148
+ access_count: currentAccessCount + 1,
149
+ });
150
+ logger.debug('ConfidenceManager.boost: boosted', {
151
+ knowledgeId,
152
+ oldConfidence: currentConfidence,
153
+ newConfidence: rounded,
154
+ newAccessCount: currentAccessCount + 1,
155
+ });
156
+ }
157
+ catch (err) {
158
+ logger.warn('ConfidenceManager.boost: failed (non-fatal)', {
159
+ knowledgeId,
160
+ error: String(err),
161
+ });
162
+ }
163
+ }
164
+ }
165
+ //# sourceMappingURL=confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/learning/confidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { PipelineDB } from '../storage/sqlite.js';
2
+ import type { KnowledgeYamlStore } from '../knowledge/store.js';
3
+ import type { KnowledgeSearch } from '../knowledge/search.js';
4
+ import type { KnowledgeItem, KnowledgeCategory, Phase, PipelinePhase } from '../util/types.js';
5
+ import { embedText } from '../ingestion/embedder.js';
6
+ /** Minimum quality score for a step to be considered a candidate. */
7
+ declare const QUALITY_THRESHOLD = 0.7;
8
+ /** Words that strongly suggest a step contains a gotcha / pain point. */
9
+ declare const GOTCHA_KEYWORDS: string[];
10
+ /** Words that suggest a step contains a positive pattern. */
11
+ declare const PATTERN_KEYWORDS: string[];
12
+ export declare class PatternExtractor {
13
+ private readonly db;
14
+ private readonly knowledgeStore;
15
+ private readonly knowledgeSearch;
16
+ private readonly embedder;
17
+ constructor(db: PipelineDB, knowledgeStore: KnowledgeYamlStore, knowledgeSearch: KnowledgeSearch, embedder: typeof embedText);
18
+ /**
19
+ * Extract knowledge from all trajectory steps of a completed project.
20
+ *
21
+ * Algorithm:
22
+ * 1. Load all trajectories + their steps for the project.
23
+ * 2. Collect steps that are either:
24
+ * a. High quality (qualityScore >= QUALITY_THRESHOLD), or
25
+ * b. Contain gotcha-like language in action/result text.
26
+ * 3. For each candidate step, determine whether it looks like a gotcha
27
+ * or a pattern (keyword matching).
28
+ * 4. Deduplicate against existing knowledge (semantic similarity check).
29
+ * 5. Promote unique candidates to KnowledgeItem records.
30
+ * 6. Return the list of newly created items.
31
+ */
32
+ extractFromProject(projectId: string): Promise<KnowledgeItem[]>;
33
+ /**
34
+ * Promote a raw observation string to a full KnowledgeItem.
35
+ *
36
+ * Steps:
37
+ * 1. Synthesise a title from the first sentence of the observation.
38
+ * 2. Build a KnowledgeItem with appropriate defaults.
39
+ * 3. Add to the YAML store (the git-tracked source of truth).
40
+ * 4. Embed and upsert to Qdrant via hydrateItem() (if available).
41
+ * 5. Return the new item.
42
+ */
43
+ promoteToKnowledge(observation: string, category: KnowledgeCategory, repoId: string, phase?: Phase | PipelinePhase, agent?: string): Promise<KnowledgeItem>;
44
+ /**
45
+ * Check whether the observation text is semantically too close to an
46
+ * existing knowledge item (similarity > 0.92). If so, we skip promotion
47
+ * to avoid building up near-duplicate entries over many projects.
48
+ */
49
+ private isDuplicateKnowledge;
50
+ }
51
+ export { GOTCHA_KEYWORDS, PATTERN_KEYWORDS, QUALITY_THRESHOLD };
52
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/learning/patterns.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,KAAK,EACL,aAAa,EAGd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAOrD,qEAAqE;AACrE,QAAA,MAAM,iBAAiB,MAAM,CAAC;AAE9B,yEAAyE;AACzE,QAAA,MAAM,eAAe,UAgBpB,CAAC;AAEF,6DAA6D;AAC7D,QAAA,MAAM,gBAAgB,UAWrB,CAAC;AAMF,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAHR,EAAE,EAAE,UAAU,EACd,cAAc,EAAE,kBAAkB,EAClC,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,OAAO,SAAS;IAG7C;;;;;;;;;;;;;OAaG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA2FrE;;;;;;;;;OASG;IACG,kBAAkB,CACtB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GAAG,aAAa,EAC7B,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC;IAgFzB;;;;OAIG;YACW,oBAAoB;CAiBnC;AAkDD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC"}