@miller-tech/uap 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +888 -0
  3. package/dist/analyzers/index.d.ts +3 -0
  4. package/dist/analyzers/index.d.ts.map +1 -0
  5. package/dist/analyzers/index.js +684 -0
  6. package/dist/analyzers/index.js.map +1 -0
  7. package/dist/benchmarks/agents/naive-agent.d.ts +60 -0
  8. package/dist/benchmarks/agents/naive-agent.d.ts.map +1 -0
  9. package/dist/benchmarks/agents/naive-agent.js +144 -0
  10. package/dist/benchmarks/agents/naive-agent.js.map +1 -0
  11. package/dist/benchmarks/agents/uap-agent.d.ts +167 -0
  12. package/dist/benchmarks/agents/uap-agent.d.ts.map +1 -0
  13. package/dist/benchmarks/agents/uap-agent.js +437 -0
  14. package/dist/benchmarks/agents/uap-agent.js.map +1 -0
  15. package/dist/benchmarks/benchmark.d.ts +328 -0
  16. package/dist/benchmarks/benchmark.d.ts.map +1 -0
  17. package/dist/benchmarks/benchmark.js +112 -0
  18. package/dist/benchmarks/benchmark.js.map +1 -0
  19. package/dist/benchmarks/execution-verifier.d.ts +41 -0
  20. package/dist/benchmarks/execution-verifier.d.ts.map +1 -0
  21. package/dist/benchmarks/execution-verifier.js +340 -0
  22. package/dist/benchmarks/execution-verifier.js.map +1 -0
  23. package/dist/benchmarks/hierarchical-prompting.d.ts +37 -0
  24. package/dist/benchmarks/hierarchical-prompting.d.ts.map +1 -0
  25. package/dist/benchmarks/hierarchical-prompting.js +246 -0
  26. package/dist/benchmarks/hierarchical-prompting.js.map +1 -0
  27. package/dist/benchmarks/improved-benchmark.d.ts +89 -0
  28. package/dist/benchmarks/improved-benchmark.d.ts.map +1 -0
  29. package/dist/benchmarks/improved-benchmark.js +585 -0
  30. package/dist/benchmarks/improved-benchmark.js.map +1 -0
  31. package/dist/benchmarks/index.d.ts +11 -0
  32. package/dist/benchmarks/index.d.ts.map +1 -0
  33. package/dist/benchmarks/index.js +11 -0
  34. package/dist/benchmarks/index.js.map +1 -0
  35. package/dist/benchmarks/model-integration.d.ts +111 -0
  36. package/dist/benchmarks/model-integration.d.ts.map +1 -0
  37. package/dist/benchmarks/model-integration.js +904 -0
  38. package/dist/benchmarks/model-integration.js.map +1 -0
  39. package/dist/benchmarks/multi-turn-agent.d.ts +44 -0
  40. package/dist/benchmarks/multi-turn-agent.d.ts.map +1 -0
  41. package/dist/benchmarks/multi-turn-agent.js +254 -0
  42. package/dist/benchmarks/multi-turn-agent.js.map +1 -0
  43. package/dist/benchmarks/multi-turn-loop.d.ts +57 -0
  44. package/dist/benchmarks/multi-turn-loop.d.ts.map +1 -0
  45. package/dist/benchmarks/multi-turn-loop.js +167 -0
  46. package/dist/benchmarks/multi-turn-loop.js.map +1 -0
  47. package/dist/benchmarks/tasks.d.ts +19 -0
  48. package/dist/benchmarks/tasks.d.ts.map +1 -0
  49. package/dist/benchmarks/tasks.js +435 -0
  50. package/dist/benchmarks/tasks.js.map +1 -0
  51. package/dist/bin/cli.d.ts +3 -0
  52. package/dist/bin/cli.d.ts.map +1 -0
  53. package/dist/bin/cli.js +546 -0
  54. package/dist/bin/cli.js.map +1 -0
  55. package/dist/bin/llama-server-optimize.d.ts +18 -0
  56. package/dist/bin/llama-server-optimize.d.ts.map +1 -0
  57. package/dist/bin/llama-server-optimize.js +708 -0
  58. package/dist/bin/llama-server-optimize.js.map +1 -0
  59. package/dist/bin/policy.d.ts +3 -0
  60. package/dist/bin/policy.d.ts.map +1 -0
  61. package/dist/bin/policy.js +143 -0
  62. package/dist/bin/policy.js.map +1 -0
  63. package/dist/bin/tool-calls.d.ts +3 -0
  64. package/dist/bin/tool-calls.d.ts.map +1 -0
  65. package/dist/bin/tool-calls.js +4 -0
  66. package/dist/bin/tool-calls.js.map +1 -0
  67. package/dist/browser/index.d.ts +2 -0
  68. package/dist/browser/index.d.ts.map +1 -0
  69. package/dist/browser/index.js +2 -0
  70. package/dist/browser/index.js.map +1 -0
  71. package/dist/browser/web-browser.d.ts +30 -0
  72. package/dist/browser/web-browser.d.ts.map +1 -0
  73. package/dist/browser/web-browser.js +93 -0
  74. package/dist/browser/web-browser.js.map +1 -0
  75. package/dist/cli/agent.d.ts +20 -0
  76. package/dist/cli/agent.d.ts.map +1 -0
  77. package/dist/cli/agent.js +474 -0
  78. package/dist/cli/agent.js.map +1 -0
  79. package/dist/cli/analyze.d.ts +7 -0
  80. package/dist/cli/analyze.d.ts.map +1 -0
  81. package/dist/cli/analyze.js +103 -0
  82. package/dist/cli/analyze.js.map +1 -0
  83. package/dist/cli/completion-gates.d.ts +51 -0
  84. package/dist/cli/completion-gates.d.ts.map +1 -0
  85. package/dist/cli/completion-gates.js +201 -0
  86. package/dist/cli/completion-gates.js.map +1 -0
  87. package/dist/cli/compliance.d.ts +8 -0
  88. package/dist/cli/compliance.d.ts.map +1 -0
  89. package/dist/cli/compliance.js +509 -0
  90. package/dist/cli/compliance.js.map +1 -0
  91. package/dist/cli/coord.d.ts +7 -0
  92. package/dist/cli/coord.d.ts.map +1 -0
  93. package/dist/cli/coord.js +138 -0
  94. package/dist/cli/coord.js.map +1 -0
  95. package/dist/cli/dashboard.d.ts +21 -0
  96. package/dist/cli/dashboard.d.ts.map +1 -0
  97. package/dist/cli/dashboard.js +1508 -0
  98. package/dist/cli/dashboard.js.map +1 -0
  99. package/dist/cli/deploy.d.ts +19 -0
  100. package/dist/cli/deploy.d.ts.map +1 -0
  101. package/dist/cli/deploy.js +387 -0
  102. package/dist/cli/deploy.js.map +1 -0
  103. package/dist/cli/droids.d.ts +9 -0
  104. package/dist/cli/droids.d.ts.map +1 -0
  105. package/dist/cli/droids.js +227 -0
  106. package/dist/cli/droids.js.map +1 -0
  107. package/dist/cli/generate.d.ts +17 -0
  108. package/dist/cli/generate.d.ts.map +1 -0
  109. package/dist/cli/generate.js +432 -0
  110. package/dist/cli/generate.js.map +1 -0
  111. package/dist/cli/hooks.d.ts +9 -0
  112. package/dist/cli/hooks.d.ts.map +1 -0
  113. package/dist/cli/hooks.js +464 -0
  114. package/dist/cli/hooks.js.map +1 -0
  115. package/dist/cli/init.d.ts +12 -0
  116. package/dist/cli/init.d.ts.map +1 -0
  117. package/dist/cli/init.js +364 -0
  118. package/dist/cli/init.js.map +1 -0
  119. package/dist/cli/mcp-router.d.ts +16 -0
  120. package/dist/cli/mcp-router.d.ts.map +1 -0
  121. package/dist/cli/mcp-router.js +143 -0
  122. package/dist/cli/mcp-router.js.map +1 -0
  123. package/dist/cli/memory.d.ts +24 -0
  124. package/dist/cli/memory.d.ts.map +1 -0
  125. package/dist/cli/memory.js +885 -0
  126. package/dist/cli/memory.js.map +1 -0
  127. package/dist/cli/model.d.ts +15 -0
  128. package/dist/cli/model.d.ts.map +1 -0
  129. package/dist/cli/model.js +290 -0
  130. package/dist/cli/model.js.map +1 -0
  131. package/dist/cli/patterns.d.ts +26 -0
  132. package/dist/cli/patterns.d.ts.map +1 -0
  133. package/dist/cli/patterns.js +862 -0
  134. package/dist/cli/patterns.js.map +1 -0
  135. package/dist/cli/rtk-validation.d.ts +9 -0
  136. package/dist/cli/rtk-validation.d.ts.map +1 -0
  137. package/dist/cli/rtk-validation.js +9 -0
  138. package/dist/cli/rtk-validation.js.map +1 -0
  139. package/dist/cli/rtk.d.ts +34 -0
  140. package/dist/cli/rtk.d.ts.map +1 -0
  141. package/dist/cli/rtk.js +401 -0
  142. package/dist/cli/rtk.js.map +1 -0
  143. package/dist/cli/schema-diff.d.ts +7 -0
  144. package/dist/cli/schema-diff.d.ts.map +1 -0
  145. package/dist/cli/schema-diff.js +11 -0
  146. package/dist/cli/schema-diff.js.map +1 -0
  147. package/dist/cli/setup-mcp-router.d.ts +8 -0
  148. package/dist/cli/setup-mcp-router.d.ts.map +1 -0
  149. package/dist/cli/setup-mcp-router.js +163 -0
  150. package/dist/cli/setup-mcp-router.js.map +1 -0
  151. package/dist/cli/setup-wizard.d.ts +2 -0
  152. package/dist/cli/setup-wizard.d.ts.map +1 -0
  153. package/dist/cli/setup-wizard.js +806 -0
  154. package/dist/cli/setup-wizard.js.map +1 -0
  155. package/dist/cli/setup.d.ts +15 -0
  156. package/dist/cli/setup.d.ts.map +1 -0
  157. package/dist/cli/setup.js +154 -0
  158. package/dist/cli/setup.js.map +1 -0
  159. package/dist/cli/sync.d.ts +8 -0
  160. package/dist/cli/sync.d.ts.map +1 -0
  161. package/dist/cli/sync.js +395 -0
  162. package/dist/cli/sync.js.map +1 -0
  163. package/dist/cli/task.d.ts +33 -0
  164. package/dist/cli/task.d.ts.map +1 -0
  165. package/dist/cli/task.js +672 -0
  166. package/dist/cli/task.js.map +1 -0
  167. package/dist/cli/tool-calls.d.ts +20 -0
  168. package/dist/cli/tool-calls.d.ts.map +1 -0
  169. package/dist/cli/tool-calls.js +605 -0
  170. package/dist/cli/tool-calls.js.map +1 -0
  171. package/dist/cli/uap.d.ts +10 -0
  172. package/dist/cli/uap.d.ts.map +1 -0
  173. package/dist/cli/uap.js +398 -0
  174. package/dist/cli/uap.js.map +1 -0
  175. package/dist/cli/update.d.ts +10 -0
  176. package/dist/cli/update.d.ts.map +1 -0
  177. package/dist/cli/update.js +300 -0
  178. package/dist/cli/update.js.map +1 -0
  179. package/dist/cli/visualize.d.ts +77 -0
  180. package/dist/cli/visualize.d.ts.map +1 -0
  181. package/dist/cli/visualize.js +287 -0
  182. package/dist/cli/visualize.js.map +1 -0
  183. package/dist/cli/worktree.d.ts +9 -0
  184. package/dist/cli/worktree.d.ts.map +1 -0
  185. package/dist/cli/worktree.js +213 -0
  186. package/dist/cli/worktree.js.map +1 -0
  187. package/dist/coordination/adaptive-patterns.d.ts +65 -0
  188. package/dist/coordination/adaptive-patterns.d.ts.map +1 -0
  189. package/dist/coordination/adaptive-patterns.js +108 -0
  190. package/dist/coordination/adaptive-patterns.js.map +1 -0
  191. package/dist/coordination/auto-agent.d.ts +82 -0
  192. package/dist/coordination/auto-agent.d.ts.map +1 -0
  193. package/dist/coordination/auto-agent.js +145 -0
  194. package/dist/coordination/auto-agent.js.map +1 -0
  195. package/dist/coordination/capability-router.d.ts +79 -0
  196. package/dist/coordination/capability-router.d.ts.map +1 -0
  197. package/dist/coordination/capability-router.js +334 -0
  198. package/dist/coordination/capability-router.js.map +1 -0
  199. package/dist/coordination/database.d.ts +13 -0
  200. package/dist/coordination/database.d.ts.map +1 -0
  201. package/dist/coordination/database.js +136 -0
  202. package/dist/coordination/database.js.map +1 -0
  203. package/dist/coordination/deploy-batcher.d.ts +122 -0
  204. package/dist/coordination/deploy-batcher.d.ts.map +1 -0
  205. package/dist/coordination/deploy-batcher.js +718 -0
  206. package/dist/coordination/deploy-batcher.js.map +1 -0
  207. package/dist/coordination/droid-validator.d.ts +59 -0
  208. package/dist/coordination/droid-validator.d.ts.map +1 -0
  209. package/dist/coordination/droid-validator.js +142 -0
  210. package/dist/coordination/droid-validator.js.map +1 -0
  211. package/dist/coordination/index.d.ts +10 -0
  212. package/dist/coordination/index.d.ts.map +1 -0
  213. package/dist/coordination/index.js +10 -0
  214. package/dist/coordination/index.js.map +1 -0
  215. package/dist/coordination/pattern-router.d.ts +50 -0
  216. package/dist/coordination/pattern-router.d.ts.map +1 -0
  217. package/dist/coordination/pattern-router.js +118 -0
  218. package/dist/coordination/pattern-router.js.map +1 -0
  219. package/dist/coordination/service.d.ts +81 -0
  220. package/dist/coordination/service.d.ts.map +1 -0
  221. package/dist/coordination/service.js +619 -0
  222. package/dist/coordination/service.js.map +1 -0
  223. package/dist/coordination/worktree-enforcer.d.ts +22 -0
  224. package/dist/coordination/worktree-enforcer.d.ts.map +1 -0
  225. package/dist/coordination/worktree-enforcer.js +71 -0
  226. package/dist/coordination/worktree-enforcer.js.map +1 -0
  227. package/dist/generators/claude-md.d.ts +3 -0
  228. package/dist/generators/claude-md.d.ts.map +1 -0
  229. package/dist/generators/claude-md.js +1020 -0
  230. package/dist/generators/claude-md.js.map +1 -0
  231. package/dist/generators/template-loader.d.ts +105 -0
  232. package/dist/generators/template-loader.d.ts.map +1 -0
  233. package/dist/generators/template-loader.js +291 -0
  234. package/dist/generators/template-loader.js.map +1 -0
  235. package/dist/index.d.ts +49 -0
  236. package/dist/index.d.ts.map +1 -0
  237. package/dist/index.js +63 -0
  238. package/dist/index.js.map +1 -0
  239. package/dist/mcp-router/config/parser.d.ts +9 -0
  240. package/dist/mcp-router/config/parser.d.ts.map +1 -0
  241. package/dist/mcp-router/config/parser.js +174 -0
  242. package/dist/mcp-router/config/parser.js.map +1 -0
  243. package/dist/mcp-router/executor/client.d.ts +31 -0
  244. package/dist/mcp-router/executor/client.d.ts.map +1 -0
  245. package/dist/mcp-router/executor/client.js +189 -0
  246. package/dist/mcp-router/executor/client.js.map +1 -0
  247. package/dist/mcp-router/index.d.ts +22 -0
  248. package/dist/mcp-router/index.d.ts.map +1 -0
  249. package/dist/mcp-router/index.js +18 -0
  250. package/dist/mcp-router/index.js.map +1 -0
  251. package/dist/mcp-router/output-compressor.d.ts +26 -0
  252. package/dist/mcp-router/output-compressor.d.ts.map +1 -0
  253. package/dist/mcp-router/output-compressor.js +236 -0
  254. package/dist/mcp-router/output-compressor.js.map +1 -0
  255. package/dist/mcp-router/search/fuzzy.d.ts +26 -0
  256. package/dist/mcp-router/search/fuzzy.d.ts.map +1 -0
  257. package/dist/mcp-router/search/fuzzy.js +94 -0
  258. package/dist/mcp-router/search/fuzzy.js.map +1 -0
  259. package/dist/mcp-router/server.d.ts +50 -0
  260. package/dist/mcp-router/server.d.ts.map +1 -0
  261. package/dist/mcp-router/server.js +229 -0
  262. package/dist/mcp-router/server.js.map +1 -0
  263. package/dist/mcp-router/session-stats.d.ts +37 -0
  264. package/dist/mcp-router/session-stats.d.ts.map +1 -0
  265. package/dist/mcp-router/session-stats.js +56 -0
  266. package/dist/mcp-router/session-stats.js.map +1 -0
  267. package/dist/mcp-router/tools/discover.d.ts +37 -0
  268. package/dist/mcp-router/tools/discover.d.ts.map +1 -0
  269. package/dist/mcp-router/tools/discover.js +65 -0
  270. package/dist/mcp-router/tools/discover.js.map +1 -0
  271. package/dist/mcp-router/tools/execute.d.ts +43 -0
  272. package/dist/mcp-router/tools/execute.d.ts.map +1 -0
  273. package/dist/mcp-router/tools/execute.js +144 -0
  274. package/dist/mcp-router/tools/execute.js.map +1 -0
  275. package/dist/mcp-router/types.d.ts +62 -0
  276. package/dist/mcp-router/types.d.ts.map +1 -0
  277. package/dist/mcp-router/types.js +6 -0
  278. package/dist/mcp-router/types.js.map +1 -0
  279. package/dist/memory/adaptive-context.d.ts +149 -0
  280. package/dist/memory/adaptive-context.d.ts.map +1 -0
  281. package/dist/memory/adaptive-context.js +1095 -0
  282. package/dist/memory/adaptive-context.js.map +1 -0
  283. package/dist/memory/agent-scoped-memory.d.ts +67 -0
  284. package/dist/memory/agent-scoped-memory.d.ts.map +1 -0
  285. package/dist/memory/agent-scoped-memory.js +126 -0
  286. package/dist/memory/agent-scoped-memory.js.map +1 -0
  287. package/dist/memory/ambiguity-detector.d.ts +54 -0
  288. package/dist/memory/ambiguity-detector.d.ts.map +1 -0
  289. package/dist/memory/ambiguity-detector.js +401 -0
  290. package/dist/memory/ambiguity-detector.js.map +1 -0
  291. package/dist/memory/backends/base.d.ts +18 -0
  292. package/dist/memory/backends/base.d.ts.map +1 -0
  293. package/dist/memory/backends/base.js +2 -0
  294. package/dist/memory/backends/base.js.map +1 -0
  295. package/dist/memory/backends/factory.d.ts +4 -0
  296. package/dist/memory/backends/factory.d.ts.map +1 -0
  297. package/dist/memory/backends/factory.js +53 -0
  298. package/dist/memory/backends/factory.js.map +1 -0
  299. package/dist/memory/backends/github.d.ts +27 -0
  300. package/dist/memory/backends/github.d.ts.map +1 -0
  301. package/dist/memory/backends/github.js +134 -0
  302. package/dist/memory/backends/github.js.map +1 -0
  303. package/dist/memory/backends/qdrant-cloud.d.ts +32 -0
  304. package/dist/memory/backends/qdrant-cloud.d.ts.map +1 -0
  305. package/dist/memory/backends/qdrant-cloud.js +167 -0
  306. package/dist/memory/backends/qdrant-cloud.js.map +1 -0
  307. package/dist/memory/context-compressor.d.ts +116 -0
  308. package/dist/memory/context-compressor.d.ts.map +1 -0
  309. package/dist/memory/context-compressor.js +430 -0
  310. package/dist/memory/context-compressor.js.map +1 -0
  311. package/dist/memory/context-pruner.d.ts +55 -0
  312. package/dist/memory/context-pruner.d.ts.map +1 -0
  313. package/dist/memory/context-pruner.js +85 -0
  314. package/dist/memory/context-pruner.js.map +1 -0
  315. package/dist/memory/correction-propagator.d.ts +44 -0
  316. package/dist/memory/correction-propagator.d.ts.map +1 -0
  317. package/dist/memory/correction-propagator.js +156 -0
  318. package/dist/memory/correction-propagator.js.map +1 -0
  319. package/dist/memory/daily-log.d.ts +67 -0
  320. package/dist/memory/daily-log.d.ts.map +1 -0
  321. package/dist/memory/daily-log.js +143 -0
  322. package/dist/memory/daily-log.js.map +1 -0
  323. package/dist/memory/dynamic-retrieval.d.ts +112 -0
  324. package/dist/memory/dynamic-retrieval.d.ts.map +1 -0
  325. package/dist/memory/dynamic-retrieval.js +908 -0
  326. package/dist/memory/dynamic-retrieval.js.map +1 -0
  327. package/dist/memory/embeddings.d.ts +172 -0
  328. package/dist/memory/embeddings.d.ts.map +1 -0
  329. package/dist/memory/embeddings.js +780 -0
  330. package/dist/memory/embeddings.js.map +1 -0
  331. package/dist/memory/generic-uap-patterns.d.ts +7 -0
  332. package/dist/memory/generic-uap-patterns.d.ts.map +1 -0
  333. package/dist/memory/generic-uap-patterns.js +43 -0
  334. package/dist/memory/generic-uap-patterns.js.map +1 -0
  335. package/dist/memory/hierarchical-memory.d.ts +141 -0
  336. package/dist/memory/hierarchical-memory.d.ts.map +1 -0
  337. package/dist/memory/hierarchical-memory.js +485 -0
  338. package/dist/memory/hierarchical-memory.js.map +1 -0
  339. package/dist/memory/knowledge-graph.d.ts +98 -0
  340. package/dist/memory/knowledge-graph.d.ts.map +1 -0
  341. package/dist/memory/knowledge-graph.js +275 -0
  342. package/dist/memory/knowledge-graph.js.map +1 -0
  343. package/dist/memory/memory-consolidator.d.ts +124 -0
  344. package/dist/memory/memory-consolidator.d.ts.map +1 -0
  345. package/dist/memory/memory-consolidator.js +514 -0
  346. package/dist/memory/memory-consolidator.js.map +1 -0
  347. package/dist/memory/memory-maintenance.d.ts +39 -0
  348. package/dist/memory/memory-maintenance.d.ts.map +1 -0
  349. package/dist/memory/memory-maintenance.js +336 -0
  350. package/dist/memory/memory-maintenance.js.map +1 -0
  351. package/dist/memory/model-router.d.ts +105 -0
  352. package/dist/memory/model-router.d.ts.map +1 -0
  353. package/dist/memory/model-router.js +474 -0
  354. package/dist/memory/model-router.js.map +1 -0
  355. package/dist/memory/multi-view-memory.d.ts +134 -0
  356. package/dist/memory/multi-view-memory.d.ts.map +1 -0
  357. package/dist/memory/multi-view-memory.js +430 -0
  358. package/dist/memory/multi-view-memory.js.map +1 -0
  359. package/dist/memory/predictive-memory.d.ts +79 -0
  360. package/dist/memory/predictive-memory.d.ts.map +1 -0
  361. package/dist/memory/predictive-memory.js +294 -0
  362. package/dist/memory/predictive-memory.js.map +1 -0
  363. package/dist/memory/prepopulate.d.ts +76 -0
  364. package/dist/memory/prepopulate.d.ts.map +1 -0
  365. package/dist/memory/prepopulate.js +832 -0
  366. package/dist/memory/prepopulate.js.map +1 -0
  367. package/dist/memory/semantic-compression.d.ts +77 -0
  368. package/dist/memory/semantic-compression.d.ts.map +1 -0
  369. package/dist/memory/semantic-compression.js +359 -0
  370. package/dist/memory/semantic-compression.js.map +1 -0
  371. package/dist/memory/serverless-qdrant.d.ts +102 -0
  372. package/dist/memory/serverless-qdrant.d.ts.map +1 -0
  373. package/dist/memory/serverless-qdrant.js +369 -0
  374. package/dist/memory/serverless-qdrant.js.map +1 -0
  375. package/dist/memory/short-term/factory.d.ts +26 -0
  376. package/dist/memory/short-term/factory.d.ts.map +1 -0
  377. package/dist/memory/short-term/factory.js +28 -0
  378. package/dist/memory/short-term/factory.js.map +1 -0
  379. package/dist/memory/short-term/indexeddb.d.ts +25 -0
  380. package/dist/memory/short-term/indexeddb.d.ts.map +1 -0
  381. package/dist/memory/short-term/indexeddb.js +64 -0
  382. package/dist/memory/short-term/indexeddb.js.map +1 -0
  383. package/dist/memory/short-term/schema.d.ts +6 -0
  384. package/dist/memory/short-term/schema.d.ts.map +1 -0
  385. package/dist/memory/short-term/schema.js +141 -0
  386. package/dist/memory/short-term/schema.js.map +1 -0
  387. package/dist/memory/short-term/sqlite.d.ts +64 -0
  388. package/dist/memory/short-term/sqlite.d.ts.map +1 -0
  389. package/dist/memory/short-term/sqlite.js +274 -0
  390. package/dist/memory/short-term/sqlite.js.map +1 -0
  391. package/dist/memory/speculative-cache.d.ts +111 -0
  392. package/dist/memory/speculative-cache.d.ts.map +1 -0
  393. package/dist/memory/speculative-cache.js +457 -0
  394. package/dist/memory/speculative-cache.js.map +1 -0
  395. package/dist/memory/task-classifier.d.ts +40 -0
  396. package/dist/memory/task-classifier.d.ts.map +1 -0
  397. package/dist/memory/task-classifier.js +342 -0
  398. package/dist/memory/task-classifier.js.map +1 -0
  399. package/dist/memory/terminal-bench-knowledge.d.ts +48 -0
  400. package/dist/memory/terminal-bench-knowledge.d.ts.map +1 -0
  401. package/dist/memory/terminal-bench-knowledge.js +622 -0
  402. package/dist/memory/terminal-bench-knowledge.js.map +1 -0
  403. package/dist/memory/write-gate.d.ts +39 -0
  404. package/dist/memory/write-gate.d.ts.map +1 -0
  405. package/dist/memory/write-gate.js +190 -0
  406. package/dist/memory/write-gate.js.map +1 -0
  407. package/dist/models/api-client.d.ts +46 -0
  408. package/dist/models/api-client.d.ts.map +1 -0
  409. package/dist/models/api-client.js +182 -0
  410. package/dist/models/api-client.js.map +1 -0
  411. package/dist/models/execution-profiles.d.ts +64 -0
  412. package/dist/models/execution-profiles.d.ts.map +1 -0
  413. package/dist/models/execution-profiles.js +403 -0
  414. package/dist/models/execution-profiles.js.map +1 -0
  415. package/dist/models/executor.d.ts +130 -0
  416. package/dist/models/executor.d.ts.map +1 -0
  417. package/dist/models/executor.js +382 -0
  418. package/dist/models/executor.js.map +1 -0
  419. package/dist/models/index.d.ts +19 -0
  420. package/dist/models/index.d.ts.map +1 -0
  421. package/dist/models/index.js +23 -0
  422. package/dist/models/index.js.map +1 -0
  423. package/dist/models/plan-validator.d.ts +37 -0
  424. package/dist/models/plan-validator.d.ts.map +1 -0
  425. package/dist/models/plan-validator.js +179 -0
  426. package/dist/models/plan-validator.js.map +1 -0
  427. package/dist/models/planner.d.ts +73 -0
  428. package/dist/models/planner.d.ts.map +1 -0
  429. package/dist/models/planner.js +375 -0
  430. package/dist/models/planner.js.map +1 -0
  431. package/dist/models/router.d.ts +96 -0
  432. package/dist/models/router.d.ts.map +1 -0
  433. package/dist/models/router.js +523 -0
  434. package/dist/models/router.js.map +1 -0
  435. package/dist/models/types.d.ts +370 -0
  436. package/dist/models/types.d.ts.map +1 -0
  437. package/dist/models/types.js +232 -0
  438. package/dist/models/types.js.map +1 -0
  439. package/dist/models/unified-router.d.ts +152 -0
  440. package/dist/models/unified-router.d.ts.map +1 -0
  441. package/dist/models/unified-router.js +313 -0
  442. package/dist/models/unified-router.js.map +1 -0
  443. package/dist/policies/convert-policy-to-claude.d.ts +3 -0
  444. package/dist/policies/convert-policy-to-claude.d.ts.map +1 -0
  445. package/dist/policies/convert-policy-to-claude.js +87 -0
  446. package/dist/policies/convert-policy-to-claude.js.map +1 -0
  447. package/dist/policies/database-manager.d.ts +27 -0
  448. package/dist/policies/database-manager.d.ts.map +1 -0
  449. package/dist/policies/database-manager.js +198 -0
  450. package/dist/policies/database-manager.js.map +1 -0
  451. package/dist/policies/enforced-tool-router.d.ts +53 -0
  452. package/dist/policies/enforced-tool-router.d.ts.map +1 -0
  453. package/dist/policies/enforced-tool-router.js +80 -0
  454. package/dist/policies/enforced-tool-router.js.map +1 -0
  455. package/dist/policies/index.d.ts +10 -0
  456. package/dist/policies/index.d.ts.map +1 -0
  457. package/dist/policies/index.js +8 -0
  458. package/dist/policies/index.js.map +1 -0
  459. package/dist/policies/policy-gate.d.ts +59 -0
  460. package/dist/policies/policy-gate.d.ts.map +1 -0
  461. package/dist/policies/policy-gate.js +171 -0
  462. package/dist/policies/policy-gate.js.map +1 -0
  463. package/dist/policies/policy-memory.d.ts +18 -0
  464. package/dist/policies/policy-memory.d.ts.map +1 -0
  465. package/dist/policies/policy-memory.js +126 -0
  466. package/dist/policies/policy-memory.js.map +1 -0
  467. package/dist/policies/policy-tools.d.ts +11 -0
  468. package/dist/policies/policy-tools.d.ts.map +1 -0
  469. package/dist/policies/policy-tools.js +66 -0
  470. package/dist/policies/policy-tools.js.map +1 -0
  471. package/dist/policies/schemas/policy.d.ts +69 -0
  472. package/dist/policies/schemas/policy.d.ts.map +1 -0
  473. package/dist/policies/schemas/policy.js +31 -0
  474. package/dist/policies/schemas/policy.js.map +1 -0
  475. package/dist/tasks/coordination.d.ts +83 -0
  476. package/dist/tasks/coordination.d.ts.map +1 -0
  477. package/dist/tasks/coordination.js +291 -0
  478. package/dist/tasks/coordination.js.map +1 -0
  479. package/dist/tasks/database.d.ts +19 -0
  480. package/dist/tasks/database.d.ts.map +1 -0
  481. package/dist/tasks/database.js +149 -0
  482. package/dist/tasks/database.js.map +1 -0
  483. package/dist/tasks/decoder-gate.d.ts +64 -0
  484. package/dist/tasks/decoder-gate.d.ts.map +1 -0
  485. package/dist/tasks/decoder-gate.js +268 -0
  486. package/dist/tasks/decoder-gate.js.map +1 -0
  487. package/dist/tasks/index.d.ts +6 -0
  488. package/dist/tasks/index.d.ts.map +1 -0
  489. package/dist/tasks/index.js +6 -0
  490. package/dist/tasks/index.js.map +1 -0
  491. package/dist/tasks/service.d.ts +40 -0
  492. package/dist/tasks/service.d.ts.map +1 -0
  493. package/dist/tasks/service.js +671 -0
  494. package/dist/tasks/service.js.map +1 -0
  495. package/dist/tasks/types.d.ts +238 -0
  496. package/dist/tasks/types.d.ts.map +1 -0
  497. package/dist/tasks/types.js +74 -0
  498. package/dist/tasks/types.js.map +1 -0
  499. package/dist/telemetry/index.d.ts +2 -0
  500. package/dist/telemetry/index.d.ts.map +1 -0
  501. package/dist/telemetry/index.js +2 -0
  502. package/dist/telemetry/index.js.map +1 -0
  503. package/dist/telemetry/session-telemetry.d.ts +56 -0
  504. package/dist/telemetry/session-telemetry.d.ts.map +1 -0
  505. package/dist/telemetry/session-telemetry.js +807 -0
  506. package/dist/telemetry/session-telemetry.js.map +1 -0
  507. package/dist/types/analysis.d.ts +82 -0
  508. package/dist/types/analysis.d.ts.map +1 -0
  509. package/dist/types/analysis.js +2 -0
  510. package/dist/types/analysis.js.map +1 -0
  511. package/dist/types/config.d.ts +3324 -0
  512. package/dist/types/config.d.ts.map +1 -0
  513. package/dist/types/config.js +418 -0
  514. package/dist/types/config.js.map +1 -0
  515. package/dist/types/coordination.d.ts +240 -0
  516. package/dist/types/coordination.d.ts.map +1 -0
  517. package/dist/types/coordination.js +43 -0
  518. package/dist/types/coordination.js.map +1 -0
  519. package/dist/types/index.d.ts +4 -0
  520. package/dist/types/index.d.ts.map +1 -0
  521. package/dist/types/index.js +4 -0
  522. package/dist/types/index.js.map +1 -0
  523. package/dist/uap-droids-strict.d.ts +59 -0
  524. package/dist/uap-droids-strict.d.ts.map +1 -0
  525. package/dist/uap-droids-strict.js +200 -0
  526. package/dist/uap-droids-strict.js.map +1 -0
  527. package/dist/utils/config-manager.d.ts +30 -0
  528. package/dist/utils/config-manager.d.ts.map +1 -0
  529. package/dist/utils/config-manager.js +41 -0
  530. package/dist/utils/config-manager.js.map +1 -0
  531. package/dist/utils/fetch-with-retry.d.ts +5 -0
  532. package/dist/utils/fetch-with-retry.d.ts.map +1 -0
  533. package/dist/utils/fetch-with-retry.js +61 -0
  534. package/dist/utils/fetch-with-retry.js.map +1 -0
  535. package/dist/utils/merge-claude-md.d.ts +28 -0
  536. package/dist/utils/merge-claude-md.d.ts.map +1 -0
  537. package/dist/utils/merge-claude-md.js +342 -0
  538. package/dist/utils/merge-claude-md.js.map +1 -0
  539. package/dist/utils/rate-limiter.d.ts +58 -0
  540. package/dist/utils/rate-limiter.d.ts.map +1 -0
  541. package/dist/utils/rate-limiter.js +100 -0
  542. package/dist/utils/rate-limiter.js.map +1 -0
  543. package/dist/utils/string-similarity.d.ts +37 -0
  544. package/dist/utils/string-similarity.d.ts.map +1 -0
  545. package/dist/utils/string-similarity.js +114 -0
  546. package/dist/utils/string-similarity.js.map +1 -0
  547. package/dist/utils/validate-json.d.ts +51 -0
  548. package/dist/utils/validate-json.d.ts.map +1 -0
  549. package/dist/utils/validate-json.js +94 -0
  550. package/dist/utils/validate-json.js.map +1 -0
  551. package/docs/INDEX.md +66 -0
  552. package/docs/architecture/MULTI_MODEL.md +224 -0
  553. package/docs/architecture/SYSTEM_ANALYSIS.md +1117 -0
  554. package/docs/architecture/UAP_COMPLIANCE.md +217 -0
  555. package/docs/architecture/UAP_PROTOCOL.md +339 -0
  556. package/docs/architecture/UAP_STRICT_DROIDS.md +172 -0
  557. package/docs/archive/BALLS_MODE_SELF_ANALYSIS.md +260 -0
  558. package/docs/archive/FAILING_TASKS_SOLUTION_PLAN.md +668 -0
  559. package/docs/archive/JINJA2-SYSTEM-MESSAGE-FIX.md +209 -0
  560. package/docs/archive/NPM-PUBLISH-V0.9.1.md +240 -0
  561. package/docs/archive/OPTIMIZATION_OPTIONS.md +334 -0
  562. package/docs/archive/SETUP_IMPROVEMENTS.md +213 -0
  563. package/docs/archive/UAP_GENERIC_OPTIMIZATION_PLAN.md +270 -0
  564. package/docs/archive/UAP_V103_PATTERN_DESIGN.md +315 -0
  565. package/docs/archive/UAP_V104_COMPLIANCE_DESIGN.md +223 -0
  566. package/docs/archive/changelog/2026-03-10_uap-100-compliance.md +77 -0
  567. package/docs/archive/changelog/2026-03-10_uap-full-system-verification.md +109 -0
  568. package/docs/benchmarks/ACCURACY_ANALYSIS.md +471 -0
  569. package/docs/benchmarks/TOKEN_OPTIMIZATION.md +572 -0
  570. package/docs/benchmarks/VALIDATION_PLAN.md +568 -0
  571. package/docs/benchmarks/VALIDATION_RESULTS.md +161 -0
  572. package/docs/deployment/DEPLOYMENT.md +895 -0
  573. package/docs/deployment/DEPLOYMENT_STRATEGIES.md +518 -0
  574. package/docs/deployment/DEPLOY_BATCHER_ANALYSIS.md +856 -0
  575. package/docs/deployment/DEPLOY_BATCHING.md +273 -0
  576. package/docs/deployment/DEPLOY_BUCKETING_ANALYSIS.md +420 -0
  577. package/docs/deployment/QWEN35_LLAMA_CPP.md +265 -0
  578. package/docs/getting-started/INTEGRATION.md +449 -0
  579. package/docs/getting-started/OVERVIEW.md +344 -0
  580. package/docs/getting-started/SETUP.md +203 -0
  581. package/docs/integrations/MCP_ROUTER_SETUP.md +445 -0
  582. package/docs/integrations/RTK_INTEGRATION.md +468 -0
  583. package/docs/operations/TROUBLESHOOTING.md +660 -0
  584. package/docs/reference/API_REFERENCE.md +903 -0
  585. package/docs/reference/FEATURES.md +472 -0
  586. package/docs/reference/HARNESS-MATRIX.md +318 -0
  587. package/docs/reference/UAP_CLI_REFERENCE.md +600 -0
  588. package/docs/research/BEHAVIORAL_PATTERNS.md +228 -0
  589. package/docs/research/DOMAIN_STRATEGIES.md +316 -0
  590. package/docs/research/MEMORY_SYSTEMS_COMPARISON.md +812 -0
  591. package/docs/research/PATTERN_ANALYSIS_2026-01-18.md +436 -0
  592. package/docs/research/PERFORMANCE_ANALYSIS_2026-01-18.md +209 -0
  593. package/docs/research/PERFORMANCE_TEST_PLAN.md +383 -0
  594. package/docs/research/TERMINAL_BENCH_LEARNINGS.md +217 -0
  595. package/package.json +113 -0
  596. package/scripts/README.md +161 -0
  597. package/templates/CLAUDE.template.md +10 -0
  598. package/templates/CLAUDE_ARCHITECTURE.template.md +103 -0
  599. package/templates/CLAUDE_CODING.template.md +127 -0
  600. package/templates/CLAUDE_DROIDS.template.md +109 -0
  601. package/templates/CLAUDE_MEMORY.template.md +131 -0
  602. package/templates/CLAUDE_WORKFLOWS.template.md +139 -0
  603. package/templates/PROJECT.template.md +209 -0
  604. package/templates/SCHEMA.md +57 -0
  605. package/templates/archive/CLAUDE.template.root-v6.md +534 -0
  606. package/templates/archive/CLAUDE.template.v6.md +534 -0
  607. package/templates/hooks/forgecode/pre-compact.sh +68 -0
  608. package/templates/hooks/forgecode/session-start.sh +169 -0
  609. package/templates/hooks/forgecode.plugin.sh +128 -0
  610. package/templates/hooks/pre-compact.sh +74 -0
  611. package/templates/hooks/session-start.sh +366 -0
  612. package/tools/agents/README.md +224 -0
  613. package/tools/agents/UAP/README.md +386 -0
  614. package/tools/agents/UAP/__init__.py +9 -0
  615. package/tools/agents/UAP/cli.py +901 -0
  616. package/tools/agents/UAP/compliance_verify.sh +108 -0
  617. package/tools/agents/UAP/full_verification.sh +126 -0
  618. package/tools/agents/UAP/version.py +32 -0
  619. package/tools/agents/benchmarks/benchmark_memory_systems.py +730 -0
  620. package/tools/agents/benchmarks/results/benchmark_20260106_064817.json +170 -0
  621. package/tools/agents/benchmarks/results/benchmark_20260106_064817.md +51 -0
  622. package/tools/agents/config/chat_template.jinja +77 -0
  623. package/tools/agents/config/tool-call-schema.json +19 -0
  624. package/tools/agents/config/tool-call.gbnf +58 -0
  625. package/tools/agents/docker/Dockerfile.python +52 -0
  626. package/tools/agents/docker/Dockerfile.ubuntu +55 -0
  627. package/tools/agents/docker-compose.qdrant.yml +24 -0
  628. package/tools/agents/install-opencode-local.sh.j2 +135 -0
  629. package/tools/agents/migrations/apply.py +256 -0
  630. package/tools/agents/opencode_uap_agent.py +1505 -0
  631. package/tools/agents/plugin/README.md +91 -0
  632. package/tools/agents/plugin/index.ts +46 -0
  633. package/tools/agents/plugin/pre-compact.sh +68 -0
  634. package/tools/agents/plugin/session-start.sh +175 -0
  635. package/tools/agents/plugin/uap-commands.ts +45 -0
  636. package/tools/agents/plugin/uap-droids.ts +54 -0
  637. package/tools/agents/plugin/uap-patterns.ts +54 -0
  638. package/tools/agents/plugin/uap-skills.ts +52 -0
  639. package/tools/agents/plugins/uap-enforce.ts +314 -0
  640. package/tools/agents/scripts/__pycache__/tool_call_wrapper.cpython-313.pyc +0 -0
  641. package/tools/agents/scripts/chat_template_verifier.py +343 -0
  642. package/tools/agents/scripts/fix-qwen-template.js +38 -0
  643. package/tools/agents/scripts/fix_qwen_chat_template.py +316 -0
  644. package/tools/agents/scripts/generate_lora_training_data.py +412 -0
  645. package/tools/agents/scripts/init_qdrant.py +151 -0
  646. package/tools/agents/scripts/memory_migration.py +560 -0
  647. package/tools/agents/scripts/migrate_memory_to_qdrant.py +110 -0
  648. package/tools/agents/scripts/prepare_lora.sh +512 -0
  649. package/tools/agents/scripts/query_memory.py +200 -0
  650. package/tools/agents/scripts/qwen-tool-call-test.js +38 -0
  651. package/tools/agents/scripts/qwen-tool-call-wrapper.js +38 -0
  652. package/tools/agents/scripts/qwen_tool_call_test.py +464 -0
  653. package/tools/agents/scripts/qwen_tool_call_wrapper.py +686 -0
  654. package/tools/agents/scripts/start-services.sh +96 -0
  655. package/tools/agents/scripts/tool-choice-proxy.cjs +296 -0
  656. package/tools/agents/scripts/tool_call_test.py +656 -0
  657. package/tools/agents/scripts/tool_call_wrapper.py +799 -0
  658. package/tools/agents/tests/test_uap_compliance.py +257 -0
  659. package/tools/agents/uap_agent.py +122 -0
  660. package/tools/agents/uap_agent_install.sh +12 -0
@@ -0,0 +1,862 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { execSync, execFileSync } from 'child_process';
6
+ import { QdrantClient } from '@qdrant/js-client-rest';
7
+ import { AgentContextConfigSchema } from '../types/index.js';
8
+ /**
9
+ * Load .uap.json config from the current working directory.
10
+ */
11
+ function loadConfig(cwd) {
12
+ const configPath = join(cwd, '.uap.json');
13
+ if (!existsSync(configPath)) {
14
+ console.log(chalk.red(' No .uap.json found. Run `uap init` first.'));
15
+ return null;
16
+ }
17
+ const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
18
+ return AgentContextConfigSchema.parse(raw);
19
+ }
20
+ /**
21
+ * Get pattern RAG settings from config, with defaults.
22
+ */
23
+ function getPatternRagConfig(config) {
24
+ return {
25
+ enabled: config.memory?.patternRag?.enabled ?? false,
26
+ collection: config.memory?.patternRag?.collection ?? 'agent_patterns',
27
+ embeddingModel: config.memory?.patternRag?.embeddingModel ?? 'all-MiniLM-L6-v2',
28
+ vectorSize: config.memory?.patternRag?.vectorSize ?? 384,
29
+ scoreThreshold: config.memory?.patternRag?.scoreThreshold ?? 0.35,
30
+ topK: config.memory?.patternRag?.topK ?? 2,
31
+ indexScript: config.memory?.patternRag?.indexScript ?? './agents/scripts/index_patterns_to_qdrant.py',
32
+ queryScript: config.memory?.patternRag?.queryScript ?? './agents/scripts/query_patterns.py',
33
+ sourceFile: config.memory?.patternRag?.sourceFile ?? 'CLAUDE.md',
34
+ sourceFiles: config.memory?.patternRag?.sourceFiles ?? [],
35
+ skillsDir: config.memory?.patternRag?.skillsDir,
36
+ maxBodyChars: config.memory?.patternRag?.maxBodyChars ?? 400,
37
+ };
38
+ }
39
+ /**
40
+ * Resolve the Qdrant endpoint from config.
41
+ */
42
+ function getQdrantEndpoint(config) {
43
+ const endpoint = config.memory?.longTerm?.endpoint || 'localhost:6333';
44
+ return endpoint.startsWith('http://') || endpoint.startsWith('https://')
45
+ ? endpoint
46
+ : `http://${endpoint}`;
47
+ }
48
+ /**
49
+ * Find a working Python with sentence-transformers available.
50
+ */
51
+ export function findPython(cwd) {
52
+ const candidates = [
53
+ join(cwd, 'agents', '.venv', 'bin', 'python'),
54
+ join(cwd, '.venv', 'bin', 'python'),
55
+ 'python3',
56
+ 'python',
57
+ ];
58
+ for (const py of candidates) {
59
+ try {
60
+ execSync(`${py} -c "import sentence_transformers" 2>/dev/null`, { cwd, stdio: 'pipe' });
61
+ return py;
62
+ }
63
+ catch {
64
+ // Try next candidate
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Bootstrap a Python venv at agents/.venv with sentence-transformers + qdrant-client.
71
+ * Returns the python binary path on success, null on failure.
72
+ * Best-effort: doesn't throw.
73
+ */
74
+ export function ensurePythonVenv(cwd) {
75
+ const venvDir = join(cwd, 'agents', '.venv');
76
+ const venvPython = join(venvDir, 'bin', 'python');
77
+ // If venv already has the deps, return immediately
78
+ try {
79
+ execSync(`${venvPython} -c "import sentence_transformers; import qdrant_client"`, {
80
+ cwd,
81
+ stdio: 'pipe',
82
+ });
83
+ return venvPython;
84
+ }
85
+ catch {
86
+ // Need to create or install deps
87
+ }
88
+ // Find a system python3 to create the venv
89
+ let systemPython = null;
90
+ for (const candidate of ['python3', 'python']) {
91
+ try {
92
+ execSync(`${candidate} --version`, { stdio: 'pipe' });
93
+ systemPython = candidate;
94
+ break;
95
+ }
96
+ catch {
97
+ // try next
98
+ }
99
+ }
100
+ if (!systemPython)
101
+ return null;
102
+ try {
103
+ // Create venv if it doesn't exist
104
+ if (!existsSync(venvPython)) {
105
+ execSync(`${systemPython} -m venv ${venvDir}`, { cwd, stdio: 'pipe', timeout: 30000 });
106
+ }
107
+ // Install deps (uses hardcoded package names, no user input)
108
+ execSync(`${venvPython} -m pip install --quiet sentence-transformers qdrant-client`, {
109
+ cwd,
110
+ stdio: 'pipe',
111
+ timeout: 300000, // 5 min for large deps
112
+ });
113
+ return venvPython;
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ export async function patternsCommand(action, options = {}) {
120
+ const cwd = process.cwd();
121
+ switch (action) {
122
+ case 'status':
123
+ await showPatternStatus(cwd);
124
+ break;
125
+ case 'index':
126
+ await indexPatterns(cwd, options);
127
+ break;
128
+ case 'query':
129
+ await queryPatterns(cwd, options);
130
+ break;
131
+ case 'generate':
132
+ await generateScripts(cwd, options);
133
+ break;
134
+ }
135
+ }
136
+ /**
137
+ * Show pattern RAG status: collection info, pattern count, last indexed.
138
+ */
139
+ async function showPatternStatus(cwd) {
140
+ console.log(chalk.bold('\n=== Pattern RAG Status ===\n'));
141
+ const config = loadConfig(cwd);
142
+ if (!config)
143
+ return;
144
+ const rag = getPatternRagConfig(config);
145
+ console.log(` ${chalk.dim('Enabled:')} ${rag.enabled ? chalk.green('yes') : chalk.yellow('no')}`);
146
+ console.log(` ${chalk.dim('Collection:')} ${rag.collection}`);
147
+ console.log(` ${chalk.dim('Embedding:')} ${rag.embeddingModel}`);
148
+ console.log(` ${chalk.dim('Score Threshold:')} ${rag.scoreThreshold}`);
149
+ console.log(` ${chalk.dim('Top-K:')} ${rag.topK}`);
150
+ console.log(` ${chalk.dim('Source:')} ${rag.sourceFile}`);
151
+ console.log('');
152
+ // Check Qdrant collection
153
+ const url = getQdrantEndpoint(config);
154
+ try {
155
+ const client = new QdrantClient({ url });
156
+ const collections = await client.getCollections();
157
+ const found = collections.collections.find((c) => c.name === rag.collection);
158
+ if (found) {
159
+ const info = await client.getCollection(rag.collection);
160
+ console.log(chalk.green(` Qdrant collection '${rag.collection}':`));
161
+ console.log(` Points: ${info.points_count ?? 'unknown'}`);
162
+ console.log(` Indexed: ${info.indexed_vectors_count ?? 'unknown'}`);
163
+ console.log(` Status: ${info.status}`);
164
+ }
165
+ else {
166
+ console.log(chalk.yellow(` Collection '${rag.collection}' not found.`));
167
+ console.log(chalk.dim(' Run `uap patterns index` to create it.'));
168
+ }
169
+ }
170
+ catch {
171
+ console.log(chalk.dim(' Qdrant not available. Run `uap memory start` first.'));
172
+ }
173
+ // Check Python + scripts
174
+ const python = findPython(cwd);
175
+ console.log('');
176
+ console.log(` ${chalk.dim('Python:')} ${python ? chalk.green(python) : chalk.red('not found')}`);
177
+ console.log(` ${chalk.dim('Index script:')} ${existsSync(join(cwd, rag.indexScript)) ? chalk.green('found') : chalk.yellow('missing')}`);
178
+ console.log(` ${chalk.dim('Query script:')} ${existsSync(join(cwd, rag.queryScript)) ? chalk.green('found') : chalk.yellow('missing')}`);
179
+ console.log('');
180
+ }
181
+ /**
182
+ * Index patterns from CLAUDE.md into the Qdrant collection.
183
+ * Uses the Python index script if available.
184
+ */
185
+ async function indexPatterns(cwd, options) {
186
+ const config = loadConfig(cwd);
187
+ if (!config)
188
+ return;
189
+ const rag = getPatternRagConfig(config);
190
+ const spinner = ora('Indexing patterns...').start();
191
+ // Prefer the Python script if it exists
192
+ const scriptPath = join(cwd, rag.indexScript);
193
+ if (existsSync(scriptPath)) {
194
+ const python = findPython(cwd);
195
+ if (!python) {
196
+ spinner.fail('Python with sentence-transformers not found.');
197
+ console.log(chalk.dim(' Install: pip install sentence-transformers qdrant-client'));
198
+ console.log(chalk.dim(' Or create venv: python3 -m venv agents/.venv && agents/.venv/bin/pip install sentence-transformers qdrant-client'));
199
+ return;
200
+ }
201
+ try {
202
+ const output = execFileSync(python, [scriptPath], {
203
+ cwd,
204
+ encoding: 'utf-8',
205
+ timeout: 120000,
206
+ });
207
+ spinner.succeed('Patterns indexed successfully.');
208
+ if (options.verbose) {
209
+ console.log(chalk.dim(output));
210
+ }
211
+ else {
212
+ // Extract summary line
213
+ const summaryMatch = output.match(/Total: (\d+) documents/);
214
+ if (summaryMatch) {
215
+ console.log(chalk.green(` ${summaryMatch[0]}`));
216
+ }
217
+ }
218
+ }
219
+ catch (err) {
220
+ spinner.fail('Pattern indexing failed.');
221
+ if (err instanceof Error) {
222
+ console.log(chalk.red(` ${err.message.split('\n').slice(0, 3).join('\n ')}`));
223
+ }
224
+ }
225
+ return;
226
+ }
227
+ // No script found - offer to generate
228
+ spinner.warn('Index script not found.');
229
+ console.log(chalk.dim(` Expected: ${rag.indexScript}`));
230
+ console.log(chalk.dim(' Run `uap patterns generate` to create the scripts.'));
231
+ }
232
+ /**
233
+ * Query patterns from the Qdrant collection.
234
+ * Uses the Python query script for real semantic embeddings.
235
+ */
236
+ async function queryPatterns(cwd, options) {
237
+ const search = options.search;
238
+ if (!search) {
239
+ console.log(chalk.red(' Search term required. Usage: uap patterns query <search>'));
240
+ return;
241
+ }
242
+ const config = loadConfig(cwd);
243
+ if (!config)
244
+ return;
245
+ const rag = getPatternRagConfig(config);
246
+ const topK = parseInt(options.top || String(rag.topK));
247
+ const minScore = parseFloat(options.minScore || String(rag.scoreThreshold));
248
+ const format = options.format || 'text';
249
+ // Prefer Python script for real embeddings
250
+ const scriptPath = join(cwd, rag.queryScript);
251
+ if (existsSync(scriptPath)) {
252
+ const python = findPython(cwd);
253
+ if (!python) {
254
+ console.log(chalk.red(' Python with sentence-transformers not found.'));
255
+ return;
256
+ }
257
+ try {
258
+ const output = execFileSync(python, [
259
+ scriptPath,
260
+ search,
261
+ '--top',
262
+ String(topK),
263
+ '--min-score',
264
+ String(minScore),
265
+ '--format',
266
+ format,
267
+ ], { cwd, encoding: 'utf-8', timeout: 30000 });
268
+ if (format === 'json') {
269
+ // Parse and pretty-print
270
+ const patterns = JSON.parse(output);
271
+ if (patterns.length === 0) {
272
+ console.log(chalk.yellow(' No matching patterns found.'));
273
+ return;
274
+ }
275
+ for (const p of patterns) {
276
+ const abbr = p.abbreviation ? ` (${p.abbreviation})` : '';
277
+ console.log(`\n ${chalk.green(`[${p.score.toFixed(3)}]`)} ${chalk.bold(`P${p.id}: ${p.title}${abbr}`)}`);
278
+ console.log(` ${chalk.dim(p.body.slice(0, rag.maxBodyChars))}${p.body.length > rag.maxBodyChars ? '...' : ''}`);
279
+ }
280
+ }
281
+ else {
282
+ console.log(output);
283
+ }
284
+ }
285
+ catch (err) {
286
+ if (err instanceof Error && err.message.includes('Connection refused')) {
287
+ console.log(chalk.dim(' Qdrant not available. Run `uap memory start` first.'));
288
+ }
289
+ else {
290
+ console.log(chalk.red(' Pattern query failed.'));
291
+ if (err instanceof Error) {
292
+ console.log(chalk.dim(` ${err.message.split('\n').slice(0, 2).join('\n ')}`));
293
+ }
294
+ }
295
+ }
296
+ return;
297
+ }
298
+ // Fallback: direct Qdrant query with keyword matching
299
+ console.log(chalk.yellow(' Query script not found. Using fallback keyword search (less accurate).'));
300
+ console.log(chalk.dim(` For semantic search, run \`uap patterns generate\` to create the Python scripts.\n`));
301
+ try {
302
+ const url = getQdrantEndpoint(config);
303
+ const client = new QdrantClient({ url });
304
+ const collections = await client.getCollections();
305
+ const found = collections.collections.some((c) => c.name === rag.collection);
306
+ if (!found) {
307
+ console.log(chalk.yellow(` Collection '${rag.collection}' not found.`));
308
+ console.log(chalk.dim(' Run `uap patterns index` first.'));
309
+ return;
310
+ }
311
+ // Scroll through all points and do keyword matching as fallback
312
+ const result = await client.scroll(rag.collection, { limit: 100, with_payload: true });
313
+ const keywords = search.toLowerCase().split(/\s+/);
314
+ const matches = result.points
315
+ .map((p) => {
316
+ const payload = p.payload;
317
+ const title = String(payload.title || '').toLowerCase();
318
+ const body = String(payload.body || '').toLowerCase();
319
+ const kws = payload.keywords || [];
320
+ let score = 0;
321
+ for (const kw of keywords) {
322
+ if (title.includes(kw))
323
+ score += 2;
324
+ if (body.includes(kw))
325
+ score += 1;
326
+ if (kws.some((k) => k.includes(kw)))
327
+ score += 1.5;
328
+ }
329
+ return {
330
+ id: p.id,
331
+ title: payload.title,
332
+ body: payload.body,
333
+ abbreviation: payload.abbreviation,
334
+ score,
335
+ };
336
+ })
337
+ .filter((m) => m.score > 0)
338
+ .sort((a, b) => b.score - a.score)
339
+ .slice(0, topK);
340
+ if (matches.length === 0) {
341
+ console.log(chalk.yellow(' No matching patterns found.'));
342
+ return;
343
+ }
344
+ for (const m of matches) {
345
+ const abbr = m.abbreviation ? ` (${m.abbreviation})` : '';
346
+ console.log(`\n ${chalk.green(`[${m.score.toFixed(1)}]`)} ${chalk.bold(`P${m.id}: ${m.title}${abbr}`)}`);
347
+ const body = String(m.body || '');
348
+ console.log(` ${chalk.dim(body.slice(0, rag.maxBodyChars))}${body.length > rag.maxBodyChars ? '...' : ''}`);
349
+ }
350
+ console.log('');
351
+ }
352
+ catch {
353
+ console.log(chalk.dim(' Qdrant not available. Run `uap memory start` first.'));
354
+ }
355
+ }
356
+ /**
357
+ * Generate the Python index/query scripts for pattern RAG.
358
+ */
359
+ export async function generateScripts(cwd, options = {}) {
360
+ const config = loadConfig(cwd);
361
+ if (!config)
362
+ return;
363
+ const rag = getPatternRagConfig(config);
364
+ const endpoint = config.memory?.longTerm?.endpoint || 'localhost:6333';
365
+ const endpointUrl = endpoint.startsWith('http')
366
+ ? new URL(endpoint)
367
+ : new URL(`http://${endpoint}`);
368
+ const host = endpointUrl.hostname;
369
+ const port = parseInt(endpointUrl.port) || 6333;
370
+ // Generate index script
371
+ const indexPath = join(cwd, rag.indexScript);
372
+ const indexDir = dirname(indexPath);
373
+ if (!existsSync(indexDir)) {
374
+ mkdirSync(indexDir, { recursive: true });
375
+ }
376
+ if (existsSync(indexPath) && !options.force) {
377
+ console.log(chalk.yellow(` Index script already exists: ${rag.indexScript}`));
378
+ console.log(chalk.dim(' Use --force to overwrite.'));
379
+ }
380
+ else {
381
+ writeFileSync(indexPath, generateIndexScript(rag, host, port));
382
+ execFileSync('chmod', ['+x', indexPath]);
383
+ console.log(chalk.green(` Created: ${rag.indexScript}`));
384
+ }
385
+ // Generate query script
386
+ const queryPath = join(cwd, rag.queryScript);
387
+ const queryDir = dirname(queryPath);
388
+ if (!existsSync(queryDir)) {
389
+ mkdirSync(queryDir, { recursive: true });
390
+ }
391
+ if (existsSync(queryPath) && !options.force) {
392
+ console.log(chalk.yellow(` Query script already exists: ${rag.queryScript}`));
393
+ console.log(chalk.dim(' Use --force to overwrite.'));
394
+ }
395
+ else {
396
+ writeFileSync(queryPath, generateQueryScript(rag, host, port));
397
+ execFileSync('chmod', ['+x', queryPath]);
398
+ console.log(chalk.green(` Created: ${rag.queryScript}`));
399
+ }
400
+ console.log(chalk.dim('\n Install Python deps: pip install sentence-transformers qdrant-client'));
401
+ }
402
+ function generateIndexScript(rag, host, port) {
403
+ // Build the list of additional source files for the Python script
404
+ const sourceFilesJson = JSON.stringify(rag.sourceFiles || []);
405
+ const skillsDirValue = rag.skillsDir ? `"${rag.skillsDir}"` : 'None';
406
+ return `#!/usr/bin/env python3
407
+ """
408
+ Extract knowledge from project documentation and index into Qdrant.
409
+
410
+ Scans multiple sources:
411
+ 1. CLAUDE.md (with @include resolution)
412
+ 2. AGENTS.md and other configured source files
413
+ 3. .claude/skills/*/SKILL.md (skill files)
414
+
415
+ Creates/updates the '${rag.collection}' collection with embeddings from
416
+ ${rag.embeddingModel} for on-demand retrieval by the Pattern RAG system.
417
+
418
+ Generated by: uap patterns generate (v0.8.1+)
419
+ """
420
+
421
+ import re
422
+ import sys
423
+ import hashlib
424
+ from pathlib import Path
425
+ from datetime import datetime, timezone
426
+ from typing import Optional
427
+
428
+ from sentence_transformers import SentenceTransformer
429
+ from qdrant_client import QdrantClient
430
+ from qdrant_client.models import Distance, VectorParams, PointStruct
431
+
432
+ PROJECT_ROOT = Path(__file__).resolve().parents[2]
433
+ PRIMARY_SOURCE = PROJECT_ROOT / "${rag.sourceFile}"
434
+ ADDITIONAL_SOURCES = ${sourceFilesJson}
435
+ SKILLS_DIR: Optional[str] = ${skillsDirValue}
436
+ QDRANT_HOST = "${host}"
437
+ QDRANT_PORT = ${port}
438
+ COLLECTION_NAME = "${rag.collection}"
439
+ EMBEDDING_MODEL = "${rag.embeddingModel}"
440
+ VECTOR_SIZE = ${rag.vectorSize}
441
+ MAX_BODY_CHARS = 2000
442
+
443
+
444
+ def resolve_includes(text: str, base_dir: Path) -> str:
445
+ """Resolve @include directives (e.g. @hooks-session-start.md)."""
446
+ def replace_include(match):
447
+ filename = match.group(1).strip()
448
+ # Search common locations
449
+ candidates = [
450
+ base_dir / filename,
451
+ base_dir / ".claude" / "hooks" / filename,
452
+ base_dir / ".claude" / filename,
453
+ base_dir / "docs" / filename,
454
+ ]
455
+ for candidate in candidates:
456
+ if candidate.exists():
457
+ return candidate.read_text()
458
+ return match.group(0) # Keep original if not found
459
+
460
+ return re.sub(r"^@(\\S+\\.md)$", replace_include, text, flags=re.MULTILINE)
461
+
462
+
463
+ def extract_numbered_patterns(text: str) -> list[dict]:
464
+ """Extract '### Pattern N: Title' blocks (legacy format)."""
465
+ patterns = []
466
+ pattern_regex = re.compile(
467
+ r"### Pattern (\\d+): (.+?)(?:\\s*\\((\\w+)\\))?\\n(.*?)(?=\\n### Pattern \\d+:|\\n## |\\n---|\\Z)",
468
+ re.DOTALL,
469
+ )
470
+ for match in pattern_regex.finditer(text):
471
+ number = int(match.group(1))
472
+ title = match.group(2).strip()
473
+ abbreviation = match.group(3) or ""
474
+ body = match.group(4).strip()
475
+ if len(body) > MAX_BODY_CHARS:
476
+ body = body[:MAX_BODY_CHARS] + "\\n... (truncated)"
477
+ patterns.append({
478
+ "title": title, "abbreviation": abbreviation,
479
+ "category": "pattern", "source": "CLAUDE.md",
480
+ "keywords": list(set(title.lower().split())),
481
+ "body": body,
482
+ "content_hash": hashlib.md5(body.encode()).hexdigest(),
483
+ })
484
+ return patterns
485
+
486
+
487
+ def extract_sections(text: str, source_name: str) -> list[dict]:
488
+ """Extract ## and ### heading sections from any markdown file."""
489
+ sections = []
490
+ # Split on ## headings (level 2 and 3)
491
+ heading_regex = re.compile(r"^(#{2,3})\\s+(.+)$", re.MULTILINE)
492
+ matches = list(heading_regex.finditer(text))
493
+
494
+ for i, match in enumerate(matches):
495
+ level = len(match.group(1))
496
+ title = match.group(2).strip()
497
+
498
+ # Skip HTML comments, empty titles, very short titles
499
+ if title.startswith("<!--") or len(title) < 3:
500
+ continue
501
+
502
+ # Get body until next heading of same or higher level
503
+ start = match.end()
504
+ end = matches[i + 1].start() if i + 1 < len(matches) else len(text)
505
+ body = text[start:end].strip()
506
+
507
+ # Skip empty or trivial sections
508
+ if len(body) < 20:
509
+ continue
510
+
511
+ if len(body) > MAX_BODY_CHARS:
512
+ body = body[:MAX_BODY_CHARS] + "\\n... (truncated)"
513
+
514
+ # Classify category from source name and content
515
+ category = classify_section(title, body, source_name)
516
+
517
+ # Build keywords from title
518
+ keywords = [w.lower() for w in re.findall(r"[a-zA-Z]{3,}", title)]
519
+
520
+ sections.append({
521
+ "title": title,
522
+ "abbreviation": "",
523
+ "category": category,
524
+ "source": source_name,
525
+ "keywords": keywords,
526
+ "body": body,
527
+ "content_hash": hashlib.md5(body.encode()).hexdigest(),
528
+ })
529
+
530
+ return sections
531
+
532
+
533
+ def classify_section(title: str, body: str, source: str) -> str:
534
+ """Classify a section into a category based on content signals."""
535
+ t = title.lower()
536
+ b = body.lower()[:500]
537
+
538
+ if "skill" in source.lower():
539
+ return "skill"
540
+ if any(w in t for w in ["deploy", "kubernetes", "k8s", "cluster", "infra"]):
541
+ return "infrastructure"
542
+ if any(w in t for w in ["security", "auth", "secret", "owasp", "xss"]):
543
+ return "security"
544
+ if any(w in t for w in ["test", "coverage", "vitest", "jest"]):
545
+ return "testing"
546
+ if any(w in t for w in ["performance", "optimize", "cache", "latency"]):
547
+ return "performance"
548
+ if any(w in t for w in ["workflow", "protocol", "checklist", "process"]):
549
+ return "workflow"
550
+ if any(w in t for w in ["database", "postgres", "sql", "pgdog", "cnpg"]):
551
+ return "database"
552
+ if any(w in t for w in ["observ", "monitor", "metric", "log", "trace"]):
553
+ return "observability"
554
+ if any(w in t for w in ["design", "ui", "ux", "css", "style", "theme"]):
555
+ return "design"
556
+ if any(w in t for w in ["review", "quality", "lint", "code"]):
557
+ return "code-quality"
558
+ if "terraform" in b or "iac" in t:
559
+ return "infrastructure"
560
+ return "general"
561
+
562
+
563
+ def extract_skill_frontmatter(text: str) -> tuple[str, str]:
564
+ """Extract name and description from YAML frontmatter."""
565
+ fm_match = re.match(r"^---\\n(.*?)\\n---", text, re.DOTALL)
566
+ if not fm_match:
567
+ return "", ""
568
+ fm = fm_match.group(1)
569
+ name_match = re.search(r"^name:\\s*(.+)$", fm, re.MULTILINE)
570
+ desc_match = re.search(r'^description:\\s*["\\'"]?(.+?)["\\'"]?\\s*$', fm, re.MULTILINE)
571
+ name = name_match.group(1).strip().strip('"').strip("'") if name_match else ""
572
+ desc = desc_match.group(1).strip().strip('"').strip("'") if desc_match else ""
573
+ return name, desc
574
+
575
+
576
+ def scan_skills(project_root: Path, skills_dir: Optional[str]) -> list[dict]:
577
+ """Scan .claude/skills/*/SKILL.md files."""
578
+ docs = []
579
+ # Auto-detect skills directory
580
+ candidates = []
581
+ if skills_dir:
582
+ candidates.append(project_root / skills_dir)
583
+ candidates.extend([
584
+ project_root / ".claude" / "skills",
585
+ project_root / ".factory" / "skills",
586
+ ])
587
+
588
+ for skills_path in candidates:
589
+ if not skills_path.is_dir():
590
+ continue
591
+ skill_files = sorted(skills_path.glob("*/SKILL.md"))
592
+ for sf in skill_files:
593
+ text = sf.read_text()
594
+ skill_name, skill_desc = extract_skill_frontmatter(text)
595
+ if not skill_name:
596
+ skill_name = sf.parent.name
597
+
598
+ # Extract sections from the skill file
599
+ sections = extract_sections(text, f"skill:{skill_name}")
600
+
601
+ # If no sections extracted, index the whole skill as one doc
602
+ if not sections and len(text.strip()) > 50:
603
+ body = text.strip()
604
+ if len(body) > MAX_BODY_CHARS:
605
+ body = body[:MAX_BODY_CHARS] + "\\n... (truncated)"
606
+ sections = [{
607
+ "title": skill_name,
608
+ "abbreviation": "",
609
+ "category": "skill",
610
+ "source": f"skill:{skill_name}",
611
+ "keywords": [w.lower() for w in re.findall(r"[a-zA-Z]{3,}", skill_name + " " + skill_desc)],
612
+ "body": body,
613
+ "content_hash": hashlib.md5(body.encode()).hexdigest(),
614
+ }]
615
+
616
+ # Add skill description as keywords to all sections
617
+ if skill_desc:
618
+ desc_keywords = [w.lower() for w in re.findall(r"[a-zA-Z]{3,}", skill_desc)]
619
+ for s in sections:
620
+ s["keywords"] = list(set(s["keywords"] + desc_keywords))
621
+
622
+ docs.extend(sections)
623
+ if docs:
624
+ break # Use first found skills directory
625
+
626
+ return docs
627
+
628
+
629
+ def deduplicate(docs: list[dict]) -> list[dict]:
630
+ """Remove duplicate documents by content hash."""
631
+ seen = set()
632
+ unique = []
633
+ for d in docs:
634
+ h = d["content_hash"]
635
+ if h not in seen:
636
+ seen.add(h)
637
+ unique.append(d)
638
+ return unique
639
+
640
+
641
+ def index_to_qdrant(docs: list[dict]) -> None:
642
+ """Create collection and upsert document embeddings."""
643
+ if not docs:
644
+ print(" No documents to index — skipping")
645
+ return
646
+
647
+ client = QdrantClient(host=QDRANT_HOST, port=QDRANT_PORT)
648
+ model = SentenceTransformer(EMBEDDING_MODEL, device="cpu")
649
+
650
+ # Recreate collection
651
+ collections = [c.name for c in client.get_collections().collections]
652
+ if COLLECTION_NAME in collections:
653
+ client.delete_collection(COLLECTION_NAME)
654
+ print(f" Deleted existing '{COLLECTION_NAME}' collection")
655
+
656
+ client.create_collection(
657
+ collection_name=COLLECTION_NAME,
658
+ vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE),
659
+ )
660
+ print(f" Created '{COLLECTION_NAME}' collection ({VECTOR_SIZE}-dim cosine)")
661
+
662
+ # Assign sequential IDs and build embeddings
663
+ points = []
664
+ for idx, doc in enumerate(docs, start=1):
665
+ embed_text = f"{doc['title']}. {' '.join(doc['keywords'][:10])}. {doc['body'][:500]}"
666
+ vector = model.encode(embed_text).tolist()
667
+ points.append(PointStruct(
668
+ id=idx, vector=vector,
669
+ payload={
670
+ "title": doc["title"],
671
+ "abbreviation": doc.get("abbreviation", ""),
672
+ "category": doc["category"],
673
+ "source": doc.get("source", ""),
674
+ "detection": doc.get("detection", ""),
675
+ "keywords": doc["keywords"],
676
+ "body": doc["body"],
677
+ "content_hash": doc["content_hash"],
678
+ "indexed_at": datetime.now(tz=timezone.utc).isoformat(),
679
+ },
680
+ ))
681
+
682
+ # Batch upsert (Qdrant handles large batches fine)
683
+ BATCH_SIZE = 100
684
+ for i in range(0, len(points), BATCH_SIZE):
685
+ batch = points[i:i + BATCH_SIZE]
686
+ client.upsert(collection_name=COLLECTION_NAME, points=batch)
687
+ print(f" Indexed {len(points)} documents")
688
+
689
+
690
+ def main():
691
+ print("=== UAP Pattern Indexer (v2 — multi-source) ===")
692
+ all_docs: list[dict] = []
693
+
694
+ # 1. Primary source (CLAUDE.md) with @include resolution
695
+ if PRIMARY_SOURCE.exists():
696
+ text = PRIMARY_SOURCE.read_text()
697
+ text = resolve_includes(text, PROJECT_ROOT)
698
+ print(f" Read {PRIMARY_SOURCE.name} ({len(text)} bytes, includes resolved)")
699
+
700
+ # Try legacy numbered patterns first
701
+ patterns = extract_numbered_patterns(text)
702
+ if patterns:
703
+ print(f" Extracted {len(patterns)} numbered patterns")
704
+ all_docs.extend(patterns)
705
+
706
+ # Also extract heading-based sections
707
+ sections = extract_sections(text, PRIMARY_SOURCE.name)
708
+ if sections:
709
+ print(f" Extracted {len(sections)} sections from {PRIMARY_SOURCE.name}")
710
+ all_docs.extend(sections)
711
+ else:
712
+ print(f" {PRIMARY_SOURCE.name} not found — skipping")
713
+
714
+ # 2. Additional source files (AGENTS.md, etc.)
715
+ for src_name in ADDITIONAL_SOURCES:
716
+ src_path = PROJECT_ROOT / src_name
717
+ if src_path.exists():
718
+ text = src_path.read_text()
719
+ sections = extract_sections(text, src_name)
720
+ print(f" Extracted {len(sections)} sections from {src_name}")
721
+ all_docs.extend(sections)
722
+ else:
723
+ print(f" {src_name} not found — skipping")
724
+
725
+ # 3. Auto-detect common files if no additional sources configured
726
+ if not ADDITIONAL_SOURCES:
727
+ for auto_file in ["AGENTS.md", "CONTRIBUTING.md"]:
728
+ auto_path = PROJECT_ROOT / auto_file
729
+ if auto_path.exists():
730
+ text = auto_path.read_text()
731
+ sections = extract_sections(text, auto_file)
732
+ if sections:
733
+ print(f" Auto-detected {auto_file}: {len(sections)} sections")
734
+ all_docs.extend(sections)
735
+
736
+ # 4. Scan skill files
737
+ skills = scan_skills(PROJECT_ROOT, SKILLS_DIR)
738
+ if skills:
739
+ print(f" Scanned skills: {len(skills)} documents")
740
+ all_docs.extend(skills)
741
+
742
+ # Deduplicate
743
+ all_docs = deduplicate(all_docs)
744
+ print(f" Total unique documents: {len(all_docs)}")
745
+
746
+ # Index
747
+ index_to_qdrant(all_docs)
748
+
749
+ # Summary by category
750
+ categories: dict[str, int] = {}
751
+ for d in all_docs:
752
+ categories[d["category"]] = categories.get(d["category"], 0) + 1
753
+ print("\\n=== Summary by Category ===")
754
+ for cat, count in sorted(categories.items(), key=lambda x: -x[1]):
755
+ print(f" {cat:>20}: {count}")
756
+
757
+ print(f"\\nTotal: {len(all_docs)} documents in '{COLLECTION_NAME}' collection")
758
+
759
+
760
+ if __name__ == "__main__":
761
+ main()
762
+ `;
763
+ }
764
+ function generateQueryScript(rag, host, port) {
765
+ return `#!/usr/bin/env python3
766
+ """
767
+ Query the ${rag.collection} Qdrant collection for task-relevant patterns.
768
+
769
+ Generated by: uap patterns generate
770
+ """
771
+
772
+ import argparse
773
+ import json
774
+ import sys
775
+
776
+ from sentence_transformers import SentenceTransformer
777
+ from qdrant_client import QdrantClient
778
+
779
+ QDRANT_HOST = "${host}"
780
+ QDRANT_PORT = ${port}
781
+ COLLECTION_NAME = "${rag.collection}"
782
+ EMBEDDING_MODEL = "${rag.embeddingModel}"
783
+
784
+ _model = None
785
+
786
+
787
+ def get_model():
788
+ global _model
789
+ if _model is None:
790
+ _model = SentenceTransformer(EMBEDDING_MODEL, device="cpu")
791
+ return _model
792
+
793
+
794
+ def query_patterns(query: str, top_k: int = ${rag.topK}, min_score: float = ${rag.scoreThreshold}) -> list[dict]:
795
+ client = QdrantClient(host=QDRANT_HOST, port=QDRANT_PORT)
796
+ model = get_model()
797
+ vector = model.encode(query).tolist()
798
+ results = client.query_points(
799
+ collection_name=COLLECTION_NAME,
800
+ query=vector,
801
+ limit=top_k,
802
+ score_threshold=min_score,
803
+ )
804
+ patterns = []
805
+ for hit in results.points:
806
+ patterns.append({
807
+ "id": hit.id,
808
+ "score": round(hit.score, 4),
809
+ "title": hit.payload.get("title", ""),
810
+ "abbreviation": hit.payload.get("abbreviation", ""),
811
+ "category": hit.payload.get("category", ""),
812
+ "body": hit.payload.get("body", ""),
813
+ })
814
+ return patterns
815
+
816
+
817
+ def format_for_context(patterns: list[dict]) -> str:
818
+ if not patterns:
819
+ return ""
820
+ lines = ["<uap-patterns>"]
821
+ for p in patterns:
822
+ abbr = f" ({p['abbreviation']})" if p["abbreviation"] else ""
823
+ lines.append(f"### Pattern {p['id']}: {p['title']}{abbr}")
824
+ lines.append(f"Relevance: {p['score']}")
825
+ lines.append(p["body"])
826
+ lines.append("")
827
+ lines.append("</uap-patterns>")
828
+ return "\\n".join(lines)
829
+
830
+
831
+ def main():
832
+ parser = argparse.ArgumentParser(description="Query UAP pattern collection")
833
+ parser.add_argument("query", help="Task description to match patterns against")
834
+ parser.add_argument("--top", type=int, default=${rag.topK})
835
+ parser.add_argument("--min-score", type=float, default=${rag.scoreThreshold})
836
+ parser.add_argument("--format", choices=["text", "json", "context"], default="text")
837
+ args = parser.parse_args()
838
+ try:
839
+ patterns = query_patterns(args.query, top_k=args.top, min_score=args.min_score)
840
+ except Exception as e:
841
+ print(f"ERROR: {e}", file=sys.stderr)
842
+ sys.exit(1)
843
+ if args.format == "json":
844
+ print(json.dumps(patterns, indent=2))
845
+ elif args.format == "context":
846
+ print(format_for_context(patterns))
847
+ else:
848
+ if not patterns:
849
+ print("No matching patterns found.")
850
+ return
851
+ for p in patterns:
852
+ abbr = f" ({p['abbreviation']})" if p["abbreviation"] else ""
853
+ print(f"[{p['score']:.3f}] P{p['id']}: {p['title']}{abbr} [{p['category']}]")
854
+ print(f" {p['body'][:200]}...")
855
+ print()
856
+
857
+
858
+ if __name__ == "__main__":
859
+ main()
860
+ `;
861
+ }
862
+ //# sourceMappingURL=patterns.js.map