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,361 @@
1
+ // RepoRegistry — manages repo registration, manifest reading, and git detection.
2
+ //
3
+ // Registration flow:
4
+ // 1. Resolve the repo path (absolute)
5
+ // 2. Read .forge/manifest.yaml — required; if absent, returns an error result
6
+ // 3. Resolve git remote origin URL (best-effort; local-only repos work too)
7
+ // 4. Compute a stable repo ID: SHA-256(remote URL) first 12 hex chars, or
8
+ // SHA-256(absolute path) if no remote
9
+ // 5. Upsert the repo row in SQLite
10
+ // 6. Check if knowledge YAML content hash changed (compare manifest_hash)
11
+ // 7. If changed (or newly registered), trigger KnowledgeHydrator to re-sync
12
+ // all knowledge items into Qdrant's knowledge collection
13
+ // 8. Return registration result
14
+ //
15
+ // The registry operates standalone (no pipeline project required). Used by
16
+ // both the MCP registration tools and the CLI `forge register` command.
17
+ import { createHash } from 'node:crypto';
18
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
19
+ import { join, resolve, basename } from 'node:path';
20
+ import { execFileSync } from 'node:child_process';
21
+ import { parse, stringify } from 'yaml';
22
+ import { KnowledgeYamlStore } from './store.js';
23
+ import { logger } from '../util/logger.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Constants
26
+ // ---------------------------------------------------------------------------
27
+ const FORGE_DIR_NAME = '.forge';
28
+ const MANIFEST_FILE = 'manifest.yaml';
29
+ const KNOWLEDGE_CATEGORY_FILES = [
30
+ 'gotchas.yaml',
31
+ 'patterns.yaml',
32
+ 'decisions.yaml',
33
+ 'conventions.yaml',
34
+ ];
35
+ // ---------------------------------------------------------------------------
36
+ // RepoRegistry
37
+ // ---------------------------------------------------------------------------
38
+ export class RepoRegistry {
39
+ db;
40
+ hydrator;
41
+ constructor(db, hydrator) {
42
+ this.db = db;
43
+ this.hydrator = hydrator;
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // register — primary entry point (spec B5 signature)
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Register (or update) a repo at `path`.
50
+ *
51
+ * Requires a .forge/manifest.yaml to exist at <path>/.forge/manifest.yaml.
52
+ * If the manifest is absent, throws an error describing the fix.
53
+ *
54
+ * Steps:
55
+ * 1. Read manifest from .forge/manifest.yaml
56
+ * 2. Resolve git origin URL
57
+ * 3. Generate repo_id from origin URL (or path hash if no remote)
58
+ * 4. Upsert into SQLite repos table
59
+ * 5. Compute knowledge content hash and compare with stored hash
60
+ * 6. If hash changed (or newly registered), hydrate Qdrant knowledge collection
61
+ * 7. Return RegisterResult
62
+ */
63
+ async register(path, options) {
64
+ const repoPath = resolve(path);
65
+ const forgePath = join(repoPath, FORGE_DIR_NAME);
66
+ const manifestPath = join(forgePath, MANIFEST_FILE);
67
+ // Manifest is required. Return a clear error if absent.
68
+ if (!existsSync(manifestPath)) {
69
+ throw new Error(`No .forge/manifest.yaml found at ${forgePath}. ` +
70
+ `Run \`forge init\` in the repo first, or call initForge() to create the directory structure.`);
71
+ }
72
+ const manifest = this.readManifest(forgePath);
73
+ if (!manifest) {
74
+ throw new Error(`Failed to parse .forge/manifest.yaml at ${forgePath}. ` +
75
+ `Check the file for syntax errors.`);
76
+ }
77
+ // Resolve git remote and generate repo ID.
78
+ const remote = this.resolveGitOrigin(repoPath);
79
+ const repoId = manifest.repo_id_override
80
+ ? manifest.repo_id_override
81
+ : this.generateRepoId(remote ?? repoPath);
82
+ const name = manifest.name;
83
+ const stack = manifest.stack;
84
+ const sharing = manifest.sharing;
85
+ const org = manifest.org ?? null;
86
+ const now = Date.now();
87
+ // Compute knowledge content hash for change detection.
88
+ const yamlStore = new KnowledgeYamlStore(forgePath);
89
+ const knowledgeHash = yamlStore.getContentHash();
90
+ // Check existing row.
91
+ const existing = this.db.get(`SELECT * FROM repos WHERE id = ?`, [repoId]);
92
+ const newlyRegistered = !existing;
93
+ const knowledgeChanged = !existing || existing.manifest_hash !== knowledgeHash;
94
+ if (existing) {
95
+ this.db.run(`UPDATE repos
96
+ SET name = ?, path = ?, remote = ?, stack = ?, sharing = ?,
97
+ org = ?, last_seen_at = ?, manifest_hash = ?
98
+ WHERE id = ?`, [
99
+ name, repoPath, remote ?? null, JSON.stringify(stack),
100
+ sharing, org, now, knowledgeHash, repoId,
101
+ ]);
102
+ logger.info('RepoRegistry.register: repo updated', { repoId, name });
103
+ }
104
+ else {
105
+ this.db.run(`INSERT INTO repos
106
+ (id, name, path, remote, stack, sharing, org, registered_at, last_seen_at, manifest_hash)
107
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
108
+ repoId, name, repoPath, remote ?? null, JSON.stringify(stack),
109
+ sharing, org, now, now, knowledgeHash,
110
+ ]);
111
+ logger.info('RepoRegistry.register: repo registered', { repoId, name });
112
+ }
113
+ // Hydrate Qdrant knowledge collection if content changed.
114
+ let knowledgeItemsLoaded = 0;
115
+ if (knowledgeChanged && this.hydrator) {
116
+ try {
117
+ knowledgeItemsLoaded = await this.hydrator.hydrate(repoId, sharing);
118
+ logger.info('RepoRegistry.register: knowledge hydrated', {
119
+ repoId,
120
+ itemCount: knowledgeItemsLoaded,
121
+ });
122
+ }
123
+ catch (err) {
124
+ // Hydration failure is non-fatal — registration proceeds.
125
+ logger.warn('RepoRegistry.register: knowledge hydration failed (non-fatal)', {
126
+ repoId,
127
+ error: String(err),
128
+ });
129
+ }
130
+ }
131
+ else if (!this.hydrator) {
132
+ logger.debug('RepoRegistry.register: no hydrator configured, skipping knowledge sync', {
133
+ repoId,
134
+ });
135
+ }
136
+ return {
137
+ repo_id: repoId,
138
+ name,
139
+ path: repoPath,
140
+ remote: remote ?? undefined,
141
+ stack,
142
+ sharing,
143
+ newly_registered: newlyRegistered,
144
+ knowledge_items_loaded: knowledgeItemsLoaded,
145
+ };
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // initForge — create .forge/ directory structure (spec B5 method)
149
+ // ---------------------------------------------------------------------------
150
+ /**
151
+ * Initialize the .forge/ directory in a repo at `repoPath`.
152
+ * Creates:
153
+ * .forge/manifest.yaml — from provided manifest
154
+ * .forge/knowledge/gotchas.yaml
155
+ * .forge/knowledge/patterns.yaml
156
+ * .forge/knowledge/decisions.yaml
157
+ * .forge/knowledge/conventions.yaml
158
+ * .forge/.gitignore — excludes .forge.db
159
+ *
160
+ * All files are created only if they do not already exist.
161
+ * Returns { forgePath, filesCreated } listing the paths that were created.
162
+ */
163
+ initForge(repoPath, manifest) {
164
+ const absRepoPath = resolve(repoPath);
165
+ const forgePath = join(absRepoPath, FORGE_DIR_NAME);
166
+ const knowledgeDir = join(forgePath, 'knowledge');
167
+ const filesCreated = [];
168
+ // Create .forge/ directory
169
+ if (!existsSync(forgePath)) {
170
+ mkdirSync(forgePath, { recursive: true });
171
+ filesCreated.push(forgePath);
172
+ }
173
+ // Create .forge/knowledge/ subdirectory
174
+ if (!existsSync(knowledgeDir)) {
175
+ mkdirSync(knowledgeDir, { recursive: true });
176
+ filesCreated.push(knowledgeDir);
177
+ }
178
+ // Write manifest.yaml
179
+ const manifestPath = join(forgePath, MANIFEST_FILE);
180
+ if (!existsSync(manifestPath)) {
181
+ const yamlContent = stringify(manifest, { indent: 2 });
182
+ writeFileSync(manifestPath, yamlContent, 'utf8');
183
+ filesCreated.push(manifestPath);
184
+ }
185
+ // Create empty YAML category files
186
+ for (const file of KNOWLEDGE_CATEGORY_FILES) {
187
+ const filePath = join(knowledgeDir, file);
188
+ if (!existsSync(filePath)) {
189
+ writeFileSync(filePath, '[]\n', 'utf8');
190
+ filesCreated.push(filePath);
191
+ }
192
+ }
193
+ // Create .gitignore to exclude local SQLite database
194
+ const gitignorePath = join(forgePath, '.gitignore');
195
+ if (!existsSync(gitignorePath)) {
196
+ writeFileSync(gitignorePath, '.forge.db\n', 'utf8');
197
+ filesCreated.push(gitignorePath);
198
+ }
199
+ logger.info('RepoRegistry.initForge: .forge/ directory initialized', {
200
+ forgePath,
201
+ filesCreated: filesCreated.length,
202
+ });
203
+ return { forgePath, filesCreated };
204
+ }
205
+ // ---------------------------------------------------------------------------
206
+ // Manifest reading (spec B5 signature: takes forgePath, not repoPath)
207
+ // ---------------------------------------------------------------------------
208
+ /**
209
+ * Read and parse .forge/manifest.yaml from `forgePath` (the .forge/ directory).
210
+ * Returns null if the file is absent or unparseable.
211
+ *
212
+ * NOTE: This method takes the .forge/ directory path, NOT the repo root.
213
+ * Callers that have the repo root should pass join(repoPath, '.forge').
214
+ */
215
+ readManifest(forgePath) {
216
+ const manifestPath = join(forgePath, MANIFEST_FILE);
217
+ if (!existsSync(manifestPath))
218
+ return null;
219
+ return this._parseManifestFile(manifestPath);
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Git origin resolution (public — spec B5)
223
+ // ---------------------------------------------------------------------------
224
+ /**
225
+ * Resolve the git remote origin URL for the repo at `repoPath`.
226
+ * Uses `git -C <repoPath> config --get remote.origin.url`.
227
+ * Returns null if the path is not a git repo or has no origin.
228
+ */
229
+ resolveGitOrigin(repoPath) {
230
+ try {
231
+ const output = execFileSync('git', ['-C', repoPath, 'config', '--get', 'remote.origin.url'], {
232
+ encoding: 'utf-8',
233
+ stdio: ['ignore', 'pipe', 'ignore'],
234
+ timeout: 3000,
235
+ }).trim();
236
+ return output || null;
237
+ }
238
+ catch {
239
+ return null;
240
+ }
241
+ }
242
+ // ---------------------------------------------------------------------------
243
+ // Repo ID generation (public — spec B5)
244
+ // ---------------------------------------------------------------------------
245
+ /**
246
+ * Generate a stable repo ID from a remote URL or local path.
247
+ * Uses SHA-256, returns first 12 hex characters.
248
+ *
249
+ * For remote URLs: normalises to strip .git suffix and trailing slashes
250
+ * before hashing so that git@github.com:org/repo and
251
+ * https://github.com/org/repo.git produce the same ID.
252
+ */
253
+ generateRepoId(remoteOrPath) {
254
+ const normalised = remoteOrPath
255
+ .trim()
256
+ .replace(/\.git$/, '')
257
+ .replace(/\/$/, '')
258
+ .toLowerCase();
259
+ return createHash('sha256').update(normalised).digest('hex').slice(0, 12);
260
+ }
261
+ // ---------------------------------------------------------------------------
262
+ // Query helpers
263
+ // ---------------------------------------------------------------------------
264
+ /**
265
+ * Get a registered repo by ID.
266
+ * Returns null if not found.
267
+ */
268
+ getRepo(repoId) {
269
+ const row = this.db.get(`SELECT * FROM repos WHERE id = ?`, [repoId]);
270
+ return row ? this._rowToRepo(row) : null;
271
+ }
272
+ /**
273
+ * List all registered repos sorted by last_seen_at descending.
274
+ * Returns repos augmented with knowledge_count (total items in Qdrant).
275
+ * knowledge_count is always 0 when Qdrant is not available — it is a
276
+ * best-effort annotation, not a blocking query.
277
+ */
278
+ listRepos() {
279
+ const rows = this.db.all(`SELECT * FROM repos ORDER BY last_seen_at DESC`);
280
+ return rows.map((row) => ({
281
+ ...this._rowToRepo(row),
282
+ // knowledge_count: Qdrant query is async; this is a synchronous method.
283
+ // Return 0 — callers that need counts should call vectorStore.getKnowledgeCount()
284
+ // separately or use async listReposWithCounts() if added later.
285
+ knowledge_count: 0,
286
+ }));
287
+ }
288
+ /**
289
+ * Update the last_seen_at timestamp for a repo.
290
+ * Called on session-start to record that the repo is actively being used.
291
+ */
292
+ touch(repoId) {
293
+ this.db.run(`UPDATE repos SET last_seen_at = ? WHERE id = ?`, [Date.now(), repoId]);
294
+ }
295
+ /**
296
+ * Remove a repo from the registry.
297
+ * Does NOT remove Qdrant knowledge items — call hydrator.removeRepo() separately
298
+ * if you want to clean up vector data.
299
+ */
300
+ removeRepo(repoId) {
301
+ this.db.run(`DELETE FROM repos WHERE id = ?`, [repoId]);
302
+ logger.info('RepoRegistry.removeRepo: repo removed from SQLite', { repoId });
303
+ }
304
+ // ---------------------------------------------------------------------------
305
+ // Backward-compat helpers (camelCase API — kept for existing callers)
306
+ // ---------------------------------------------------------------------------
307
+ /** Whether a .forge/ directory exists in the given repo path. */
308
+ forgeDirectoryExists(repoPath) {
309
+ const targetPath = resolve(repoPath ?? process.cwd());
310
+ return existsSync(join(targetPath, FORGE_DIR_NAME));
311
+ }
312
+ /** Find a registered repo by its filesystem path. */
313
+ findRepoByPath(repoPath) {
314
+ const absPath = resolve(repoPath);
315
+ const row = this.db.get(`SELECT * FROM repos WHERE path = ?`, [absPath]);
316
+ return row ? this._rowToRepo(row) : null;
317
+ }
318
+ // ---------------------------------------------------------------------------
319
+ // Private helpers
320
+ // ---------------------------------------------------------------------------
321
+ _parseManifestFile(manifestPath) {
322
+ try {
323
+ const content = readFileSync(manifestPath, 'utf8');
324
+ const parsed = parse(content);
325
+ return parsed ?? null;
326
+ }
327
+ catch (err) {
328
+ logger.warn('RepoRegistry._parseManifestFile: failed to read manifest', {
329
+ path: manifestPath,
330
+ error: String(err),
331
+ });
332
+ return null;
333
+ }
334
+ }
335
+ _repoNameFromPath(repoPath) {
336
+ // basename handles both forward and backslash separators via path.basename
337
+ return basename(repoPath) || 'unknown';
338
+ }
339
+ _rowToRepo(row) {
340
+ let stack;
341
+ try {
342
+ stack = JSON.parse(row.stack);
343
+ }
344
+ catch {
345
+ stack = [];
346
+ }
347
+ return {
348
+ id: row.id,
349
+ name: row.name,
350
+ path: row.path,
351
+ remote: row.remote,
352
+ stack,
353
+ sharing: row.sharing,
354
+ org: row.org,
355
+ registeredAt: row.registered_at,
356
+ lastSeenAt: row.last_seen_at,
357
+ manifestHash: row.manifest_hash,
358
+ };
359
+ }
360
+ }
361
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/knowledge/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import type { QdrantVectorStore } from '../storage/qdrant-store.js';
2
+ import type { KnowledgeCategory, KnowledgeItem } from '../util/types.js';
3
+ /**
4
+ * Result shape returned from KnowledgeSearch.search().
5
+ * Uses snake_case field names to match the MCP tool response contract.
6
+ */
7
+ export interface KnowledgeSearchResult {
8
+ id: string;
9
+ category: string;
10
+ title: string;
11
+ content: string;
12
+ confidence: number;
13
+ stack_tags: string[];
14
+ source_repo: string;
15
+ relevance_score: number;
16
+ }
17
+ export interface KnowledgeSearchOptions {
18
+ repoId?: string;
19
+ category?: KnowledgeCategory;
20
+ stackTags?: string[];
21
+ minConfidence?: number;
22
+ limit?: number;
23
+ scoreThreshold?: number;
24
+ }
25
+ export declare class KnowledgeSearch {
26
+ private readonly vectorStore;
27
+ constructor(vectorStore: QdrantVectorStore);
28
+ /**
29
+ * Semantic search across knowledge items stored in the Qdrant knowledge
30
+ * collection.
31
+ *
32
+ * Options:
33
+ * category — filter to a single KnowledgeCategory
34
+ * stack_tags — filter to items that share at least one tag (OR match)
35
+ * repo_id — used for same-repo scoring boost; also hard-filters
36
+ * when include_cross_repo is false
37
+ * limit — max results to return (default 10)
38
+ * include_cross_repo— include items from other repos (default true)
39
+ * min_confidence — minimum confidence score (default 0.3)
40
+ *
41
+ * Returns results sorted descending by relevance_score.
42
+ * Returns [] when Qdrant is unavailable — never throws.
43
+ */
44
+ search(query: string, options?: {
45
+ category?: KnowledgeCategory;
46
+ stack_tags?: string[];
47
+ repo_id?: string;
48
+ limit?: number;
49
+ include_cross_repo?: boolean;
50
+ min_confidence?: number;
51
+ }): Promise<KnowledgeSearchResult[]>;
52
+ /**
53
+ * Increment access_count and update accessed_at for a knowledge item.
54
+ * Optionally bumps the confidence score by boostAmount.
55
+ *
56
+ * Called when an agent actively consumes a knowledge item — access signals
57
+ * genuine utility and nudges confidence upward.
58
+ * Silent on Qdrant failure (non-fatal side effect).
59
+ */
60
+ boostConfidence(knowledgeId: string, boostAmount?: number): Promise<void>;
61
+ /**
62
+ * Return gotcha items optionally filtered by stack tags.
63
+ * Uses Qdrant filter (category=gotcha) plus optional stack_tags OR match.
64
+ * Results sorted by confidence descending.
65
+ * Gracefully returns [] on Qdrant unavailability.
66
+ */
67
+ getGotchas(stack?: string[], limit?: number, minConfidence?: number): Promise<KnowledgeItem[]>;
68
+ /**
69
+ * Return pattern items optionally filtered by domain.
70
+ * `domain` is treated as a stack tag (single-element array) for consistency.
71
+ * Results sorted by confidence descending.
72
+ * Gracefully returns [] on Qdrant unavailability.
73
+ */
74
+ getPatterns(domain?: string, limit?: number, minConfidence?: number): Promise<KnowledgeItem[]>;
75
+ /** Convenience: search with category=gotcha. Backward-compat camelCase API. */
76
+ searchGotchas(query: string, opts?: Omit<KnowledgeSearchOptions, 'category'>): Promise<KnowledgeSearchResult[]>;
77
+ /** Convenience: search with category=decision. Backward-compat camelCase API. */
78
+ searchDecisions(query: string, opts?: Omit<KnowledgeSearchOptions, 'category'>): Promise<KnowledgeSearchResult[]>;
79
+ /** Convenience: search with category=pattern. Backward-compat camelCase API. */
80
+ searchPatterns(query: string, opts?: Omit<KnowledgeSearchOptions, 'category'>): Promise<KnowledgeSearchResult[]>;
81
+ /** Convenience: search with category=convention. Backward-compat camelCase API. */
82
+ searchConventions(query: string, opts?: Omit<KnowledgeSearchOptions, 'category'>): Promise<KnowledgeSearchResult[]>;
83
+ /** True when the vector store is configured and healthy. */
84
+ isAvailable(): Promise<boolean>;
85
+ /**
86
+ * Retrieve knowledge items by category using Qdrant filter scroll (no
87
+ * semantic query). Falls back to semantic search when filterKnowledge is
88
+ * not yet available on the store.
89
+ */
90
+ private _getByCategory;
91
+ /**
92
+ * Build the Qdrant filter object from search option components.
93
+ *
94
+ * We construct the full Qdrant filter shape directly here (not relying on
95
+ * QdrantVectorStore.buildFilter) because we need both "must" (AND) and
96
+ * "should" (OR) conditions which the simple flat-map builder cannot express.
97
+ *
98
+ * Qdrant filter reference:
99
+ * { must: [...], should: [...], must_not: [...] }
100
+ * Each condition: { key: string, match: { value } } or { key, range: { gte } }
101
+ */
102
+ private _buildQdrantFilter;
103
+ /**
104
+ * Convert a KnowledgePayload from Qdrant into a KnowledgeItem.
105
+ * Returns null if required fields are missing.
106
+ */
107
+ private _payloadToKnowledgeItem;
108
+ /**
109
+ * Convert a KnowledgeSearchResult back to a KnowledgeItem shape.
110
+ * Used as a fallback when filterKnowledge is not available on the store.
111
+ */
112
+ private _resultToKnowledgeItem;
113
+ }
114
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/knowledge/search.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AAM3F;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAaD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,iBAAiB;IAM3D;;;;;;;;;;;;;;;OAeG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,iBAAiB,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAgHnC;;;;;;;OAOG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyD7E;;;;;OAKG;IACG,UAAU,CACd,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,KAAK,SAAK,EACV,aAAa,SAAM,GAClB,OAAO,CAAC,aAAa,EAAE,CAAC;IAI3B;;;;;OAKG;IACG,WAAW,CACf,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,SAAK,EACV,aAAa,SAAM,GAClB,OAAO,CAAC,aAAa,EAAE,CAAC;IAS3B,+EAA+E;IACzE,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAAC,GAC9C,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAUnC,iFAAiF;IAC3E,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAAC,GAC9C,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAUnC,gFAAgF;IAC1E,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAAC,GAC9C,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAUnC,mFAAmF;IAC7E,iBAAiB,CACrB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAAC,GAC9C,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAUnC,4DAA4D;IACtD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAQrC;;;;OAIG;YACW,cAAc;IA6D5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;IAsE1B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAc/B"}