@agenthippo-ai/agenthippo 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 (480) hide show
  1. package/LICENSE +21 -0
  2. package/bin/agenthippo.js +2 -0
  3. package/out/agentpack/github.js +547 -0
  4. package/out/agentpack/index.js +66 -0
  5. package/out/agentpack/install.js +297 -0
  6. package/out/agentpack/manager.js +441 -0
  7. package/out/agentpack/manifest.js +135 -0
  8. package/out/agentpack/paths.js +475 -0
  9. package/out/agentpack/publish.js +248 -0
  10. package/out/agentpack/stores.js +554 -0
  11. package/out/agentpack/types.js +5 -0
  12. package/out/analytics/dashboard/artifactManager.js +439 -0
  13. package/out/analytics/dashboard/fleetDisplayUtils.js +159 -0
  14. package/out/analytics/dashboard/fleetOrchestrator.js +142 -0
  15. package/out/analytics/dashboard/fleetRegistry.js +79 -0
  16. package/out/analytics/dashboard/fleetRowDefaults.js +87 -0
  17. package/out/analytics/dashboard/fleetScriptAdapter.js +146 -0
  18. package/out/analytics/dashboard/fleetStatusUtils.js +30 -0
  19. package/out/analytics/dashboard/fleetTitleUtils.js +68 -0
  20. package/out/analytics/dashboard/fleetTypes.js +29 -0
  21. package/out/analytics/dashboard/index.js +17 -0
  22. package/out/analytics/dashboard/indexingService.js +422 -0
  23. package/out/analytics/dashboard/localFleetAdapter.js +222 -0
  24. package/out/analytics/dashboard/performanceMonitor.js +76 -0
  25. package/out/analytics/dashboard/processManager.js +209 -0
  26. package/out/analytics/dashboard/provider.js +3885 -0
  27. package/out/analytics/dashboard/queryRunner.js +994 -0
  28. package/out/analytics/dashboard/refreshPolicy.js +16 -0
  29. package/out/analytics/dashboard/scheduledFleetFingerprint.js +22 -0
  30. package/out/analytics/dashboard/scheduledFleetStorage.js +241 -0
  31. package/out/analytics/dashboard/scheduledFleetUtils.js +22 -0
  32. package/out/analytics/dashboard/sessionEventFleetStats.js +118 -0
  33. package/out/analytics/dashboard/sessionJsonlFleet.js +204 -0
  34. package/out/analytics/dashboard/teamViewDiscovery.js +106 -0
  35. package/out/analytics/dashboard/viewsConfigMerge.js +221 -0
  36. package/out/analytics/dashboard/webview/analytics-panel.html +155 -0
  37. package/out/analytics/dashboard/webview/codicon.ttf +0 -0
  38. package/out/analytics/dashboard/webview/index.html +78 -0
  39. package/out/analytics/dashboard/webview/panel.js +2295 -0
  40. package/out/analytics/dashboard/webview/runtime-bridge.js +82 -0
  41. package/out/analytics/dashboard/webview/styles.css +1009 -0
  42. package/out/analytics/lifecycle.js +43 -0
  43. package/out/analytics/service.js +1279 -0
  44. package/out/analytics/sessionEvents.js +231 -0
  45. package/out/auth/bootstrapApply.js +72 -0
  46. package/out/auth/brokerClient.js +126 -0
  47. package/out/auth/callbackUri.js +59 -0
  48. package/out/auth/callbackUriParse.js +59 -0
  49. package/out/auth/githubStoreGate.js +70 -0
  50. package/out/auth/loopbackAuthServer.js +165 -0
  51. package/out/auth/pkce.js +9 -0
  52. package/out/auth/provider.js +239 -0
  53. package/out/auth/sessionStore.js +193 -0
  54. package/out/auth/signInFlow.js +182 -0
  55. package/out/auth/types.js +12 -0
  56. package/out/auth-broker/config.js +62 -0
  57. package/out/auth-broker/jwt.js +105 -0
  58. package/out/auth-broker/pkce.js +57 -0
  59. package/out/auth-broker/server.js +539 -0
  60. package/out/auth-broker/store.js +273 -0
  61. package/out/base-prompts/gateway/openclaw-starter.json5 +144 -0
  62. package/out/base-prompts/gateway/slack-socket-mode-minimal.manifest.json +44 -0
  63. package/out/base-prompts/mcp-servers/.mcp.json +13 -0
  64. package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +142 -0
  65. package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +13 -0
  66. package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +1192 -0
  67. package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +23 -0
  68. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +12 -0
  69. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +102 -0
  70. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +137 -0
  71. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +118 -0
  72. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +209 -0
  73. package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +431 -0
  74. package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +270 -0
  75. package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +18 -0
  76. package/out/base-prompts/rules/AGENTS.md +204 -0
  77. package/out/base-prompts/skills/agent-browser/SKILL.md +102 -0
  78. package/out/base-prompts/skills/agent-builder/SKILL.md +73 -0
  79. package/out/base-prompts/skills/agent-builder/references/agent-pack.md +63 -0
  80. package/out/base-prompts/skills/agent-builder/references/crewai.md +66 -0
  81. package/out/base-prompts/skills/agent-builder/references/langchain.md +60 -0
  82. package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +73 -0
  83. package/out/base-prompts/skills/agent-engine-creator/SKILL.md +586 -0
  84. package/out/base-prompts/skills/agent-engine-installer/SKILL.md +106 -0
  85. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +259 -0
  86. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +189 -0
  87. package/out/base-prompts/skills/agenthippo-cli/SKILL.md +69 -0
  88. package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +63 -0
  89. package/out/base-prompts/skills/agentpack-creator/SKILL.md +375 -0
  90. package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +261 -0
  91. package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +195 -0
  92. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +391 -0
  93. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +294 -0
  94. package/out/base-prompts/skills/agentpack-testbench/SKILL.md +135 -0
  95. package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +202 -0
  96. package/out/base-prompts/skills/algorithmic-art/SKILL.md +405 -0
  97. package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +223 -0
  98. package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +599 -0
  99. package/out/base-prompts/skills/debug-agent/SKILL.md +83 -0
  100. package/out/base-prompts/skills/desktop-automation/SKILL.md +166 -0
  101. package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +441 -0
  102. package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +280 -0
  103. package/out/base-prompts/skills/docx/LICENSE.txt +30 -0
  104. package/out/base-prompts/skills/docx/SKILL.md +197 -0
  105. package/out/base-prompts/skills/docx/docx-js.md +350 -0
  106. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  107. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  108. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  109. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  110. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  111. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  112. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  113. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  114. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  115. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  116. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  117. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  118. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  119. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  120. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  121. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  122. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  123. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  124. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  125. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  126. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  127. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  128. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  129. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  130. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  131. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  132. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  133. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  134. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  135. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  136. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  137. package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  138. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  139. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  140. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  141. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  142. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  143. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  144. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  145. package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +159 -0
  146. package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +29 -0
  147. package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +69 -0
  148. package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  149. package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +951 -0
  150. package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  151. package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  152. package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  153. package/out/base-prompts/skills/docx/ooxml.md +610 -0
  154. package/out/base-prompts/skills/docx/scripts/__init__.py +1 -0
  155. package/out/base-prompts/skills/docx/scripts/document.py +1276 -0
  156. package/out/base-prompts/skills/docx/scripts/templates/comments.xml +3 -0
  157. package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  158. package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  159. package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +3 -0
  160. package/out/base-prompts/skills/docx/scripts/templates/people.xml +3 -0
  161. package/out/base-prompts/skills/docx/scripts/utilities.py +374 -0
  162. package/out/base-prompts/skills/gateway-outbound/SKILL.md +136 -0
  163. package/out/base-prompts/skills/mcp-builder/LICENSE.txt +202 -0
  164. package/out/base-prompts/skills/mcp-builder/SKILL.md +328 -0
  165. package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +602 -0
  166. package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  167. package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  168. package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  169. package/out/base-prompts/skills/mcp-builder/scripts/connections.py +151 -0
  170. package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +373 -0
  171. package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  172. package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +2 -0
  173. package/out/base-prompts/skills/openclaw/SKILL.md +406 -0
  174. package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +61 -0
  175. package/out/base-prompts/skills/pdf/LICENSE.txt +30 -0
  176. package/out/base-prompts/skills/pdf/SKILL.md +294 -0
  177. package/out/base-prompts/skills/pdf/forms.md +205 -0
  178. package/out/base-prompts/skills/pdf/reference.md +612 -0
  179. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  180. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  181. package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +12 -0
  182. package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  183. package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +41 -0
  184. package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +152 -0
  185. package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  186. package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  187. package/out/base-prompts/skills/pptx/LICENSE.txt +30 -0
  188. package/out/base-prompts/skills/pptx/SKILL.md +484 -0
  189. package/out/base-prompts/skills/pptx/html2pptx.md +625 -0
  190. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  191. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  192. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  193. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  194. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  195. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  196. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  197. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  198. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  199. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  200. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  201. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  202. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  203. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  204. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  205. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  206. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  207. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  208. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  209. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  210. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  211. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  212. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  213. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  214. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  215. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  216. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  217. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  218. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  219. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  220. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  221. package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  222. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  223. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  224. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  225. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  226. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  227. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  228. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  229. package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +159 -0
  230. package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +29 -0
  231. package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +69 -0
  232. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  233. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  234. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  235. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  236. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  237. package/out/base-prompts/skills/pptx/ooxml.md +427 -0
  238. package/out/base-prompts/skills/pptx/scripts/html2pptx.js +984 -0
  239. package/out/base-prompts/skills/pptx/scripts/inventory.py +1020 -0
  240. package/out/base-prompts/skills/pptx/scripts/rearrange.py +231 -0
  241. package/out/base-prompts/skills/pptx/scripts/replace.py +385 -0
  242. package/out/base-prompts/skills/pptx/scripts/thumbnail.py +450 -0
  243. package/out/base-prompts/skills/prompt-lab/SKILL.md +149 -0
  244. package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +2551 -0
  245. package/out/base-prompts/skills/skill-creator/LICENSE.txt +202 -0
  246. package/out/base-prompts/skills/skill-creator/SKILL.md +371 -0
  247. package/out/base-prompts/skills/skill-creator/references/output-patterns.md +82 -0
  248. package/out/base-prompts/skills/skill-creator/references/workflows.md +28 -0
  249. package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +303 -0
  250. package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +110 -0
  251. package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +95 -0
  252. package/out/base-prompts/skills/skill-installer/SKILL.md +251 -0
  253. package/out/base-prompts/skills/skill-installer/references/store-api.md +219 -0
  254. package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +83 -0
  255. package/out/base-prompts/skills/spotlight-insights/SKILL.md +101 -0
  256. package/out/base-prompts/skills/spotlight-optimize/SKILL.md +93 -0
  257. package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +2551 -0
  258. package/out/base-prompts/skills/spotlight-query/SKILL.md +314 -0
  259. package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +163 -0
  260. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +2551 -0
  261. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +744 -0
  262. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +14 -0
  263. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +7 -0
  264. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +5 -0
  265. package/out/base-prompts/skills/spotlight-report/SKILL.md +86 -0
  266. package/out/base-prompts/skills/spotlight-visualize/SKILL.md +92 -0
  267. package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +2551 -0
  268. package/out/base-prompts/skills/xlsx/LICENSE.txt +30 -0
  269. package/out/base-prompts/skills/xlsx/SKILL.md +289 -0
  270. package/out/base-prompts/skills/xlsx/recalc.py +178 -0
  271. package/out/branding.js +23 -0
  272. package/out/cli/commands/anywhere.js +66 -0
  273. package/out/cli/commands/ask.js +243 -0
  274. package/out/cli/commands/auth-broker.js +24 -0
  275. package/out/cli/commands/auth.js +219 -0
  276. package/out/cli/commands/chat.js +354 -0
  277. package/out/cli/commands/deploy.js +223 -0
  278. package/out/cli/commands/gateway.js +160 -0
  279. package/out/cli/commands/pack.js +220 -0
  280. package/out/cli/commands/probe-custom-engine.js +82 -0
  281. package/out/cli/commands/serve.js +583 -0
  282. package/out/cli/commands/store.js +919 -0
  283. package/out/cli/credential-context.js +113 -0
  284. package/out/cli/deploy-init.js +2087 -0
  285. package/out/cli/deps.js +238 -0
  286. package/out/cli/index.js +390 -0
  287. package/out/cli/pack-loader.js +376 -0
  288. package/out/cli/run-custom-engine-runner.js +318 -0
  289. package/out/cli/runtime.js +409 -0
  290. package/out/cli/serve-hardening.js +325 -0
  291. package/out/cli/state-sync.js +135 -0
  292. package/out/cli/utils.js +220 -0
  293. package/out/cli/vscode-shim.js +86 -0
  294. package/out/engines/base.js +159 -0
  295. package/out/engines/claude.js +1215 -0
  296. package/out/engines/codex.js +759 -0
  297. package/out/engines/custom.js +632 -0
  298. package/out/engines/customEngineIpc.js +95 -0
  299. package/out/engines/customEngineRunnerEmbed.js +107 -0
  300. package/out/engines/customRegistry.js +274 -0
  301. package/out/engines/embeddedCustomEngineRunner.generated.js +9 -0
  302. package/out/engines/engineApiKey.js +138 -0
  303. package/out/engines/factory.js +45 -0
  304. package/out/engines/install.js +372 -0
  305. package/out/engines/persistentEngineWorker.js +320 -0
  306. package/out/engines/publish.js +341 -0
  307. package/out/engines/types.js +17 -0
  308. package/out/examples/run-headless-repl.js +291 -0
  309. package/out/examples/run-headless.js +187 -0
  310. package/out/extension.js +4472 -0
  311. package/out/gateway/bridge.js +805 -0
  312. package/out/gateway/cli-agent-id.js +36 -0
  313. package/out/gateway/client.js +303 -0
  314. package/out/gateway/client.test.js +395 -0
  315. package/out/gateway/gateway-scope-errors.js +14 -0
  316. package/out/gateway/gatewayBackup.js +76 -0
  317. package/out/gateway/gatewayRouteIndex.js +371 -0
  318. package/out/gateway/gatewaySessionStore.js +243 -0
  319. package/out/gateway/index.js +31 -0
  320. package/out/gateway/lifecycle.js +3056 -0
  321. package/out/gateway/openclaw-channel-routing.js +317 -0
  322. package/out/gateway/outboundHandles.js +373 -0
  323. package/out/gateway/outboundPaths.js +72 -0
  324. package/out/gateway/outboundSend.js +254 -0
  325. package/out/gateway/protocol.js +48 -0
  326. package/out/gateway/resetMappings.js +52 -0
  327. package/out/gateway/service.js +1244 -0
  328. package/out/gateway/sessionRouting.js +77 -0
  329. package/out/headless/index.js +505 -0
  330. package/out/headless/sync.js +473 -0
  331. package/out/mcp/publish.js +143 -0
  332. package/out/mcp.js +597 -0
  333. package/out/permissions.js +108 -0
  334. package/out/permissions.mapping.yaml +68 -0
  335. package/out/registry/index.js +332 -0
  336. package/out/remote/handleRemoteChat.js +122 -0
  337. package/out/remote/remotePackStatusBar.js +103 -0
  338. package/out/remote/serveClient.js +216 -0
  339. package/out/remoteSkills.js +191 -0
  340. package/out/runtime/index.js +32 -0
  341. package/out/runtime/interfaces/config-provider.js +32 -0
  342. package/out/runtime/interfaces/edit-tracker.js +22 -0
  343. package/out/runtime/interfaces/index.js +29 -0
  344. package/out/runtime/interfaces/logger.js +40 -0
  345. package/out/runtime/interfaces/permission-handler.js +66 -0
  346. package/out/runtime/interfaces/session-store.js +342 -0
  347. package/out/runtime/vscode/index.js +20 -0
  348. package/out/runtime/vscode/vscode-config-provider.js +77 -0
  349. package/out/runtime/vscode/vscode-edit-tracker.js +120 -0
  350. package/out/runtime/vscode/vscode-logger.js +30 -0
  351. package/out/runtime/vscode/vscode-permission-handler.js +72 -0
  352. package/out/runtime/vscode/vscode-session-store.js +22 -0
  353. package/out/scripts/agentide-litellm.ps1 +501 -0
  354. package/out/scripts/agentide-litellm.sh +700 -0
  355. package/out/scripts/agentide_litellm_hooks_v1.py +604 -0
  356. package/out/scripts/analytics/agent-fleet-widget.js +954 -0
  357. package/out/scripts/analytics/agentide-litellm-otel.config.yaml +160 -0
  358. package/out/scripts/analytics/default-seed-scripts.json +12 -0
  359. package/out/scripts/analytics/duckdbLocator.js +29 -0
  360. package/out/scripts/analytics/fleet-local-adapter.js +246 -0
  361. package/out/scripts/analytics/fleet-workflow.sh +263 -0
  362. package/out/scripts/analytics/generate-default-charts.py +685 -0
  363. package/out/scripts/analytics/hotspot-analysis-widget.js +909 -0
  364. package/out/scripts/analytics/index-traces.py +1394 -0
  365. package/out/scripts/analytics/install-analytics.sh +286 -0
  366. package/out/scripts/analytics/live-fleet-4-collector.cjs +315 -0
  367. package/out/scripts/analytics/live-fleet-4-daemon.mjs +134 -0
  368. package/out/scripts/analytics/live-fleet-4-widget.cjs +433 -0
  369. package/out/scripts/analytics/otel-collector.yaml +55 -0
  370. package/out/scripts/analytics/query-analytics.ps1 +396 -0
  371. package/out/scripts/analytics/query-analytics.sh +2551 -0
  372. package/out/scripts/analytics/session-comparison-widget.js +1468 -0
  373. package/out/scripts/analytics/session-timeline-widget.js +2137 -0
  374. package/out/scripts/analytics/setup-analytics.ps1 +432 -0
  375. package/out/scripts/analytics/setup-analytics.sh +854 -0
  376. package/out/scripts/analytics/start-analytics.ps1 +169 -0
  377. package/out/scripts/analytics/start-analytics.sh +323 -0
  378. package/out/scripts/analytics/token-cost-flamegraph-widget.js +954 -0
  379. package/out/scripts/analytics/token-cost-trend-widget.js +1062 -0
  380. package/out/scripts/analytics/workflows-collector.cjs +315 -0
  381. package/out/scripts/analytics/workflows-daemon.mjs +186 -0
  382. package/out/scripts/analytics/workflows-widget.cjs +433 -0
  383. package/out/scripts/analytics/wow-model-widget.js +191 -0
  384. package/out/scripts/gateway/Dockerfile.serve +45 -0
  385. package/out/scripts/gateway/docker-serve.sh +248 -0
  386. package/out/scripts/gateway/setup-gateway-server.ps1 +953 -0
  387. package/out/scripts/gateway/setup-gateway-server.sh +935 -0
  388. package/out/scripts/gateway/setup-gateway.ps1 +1813 -0
  389. package/out/scripts/gateway/setup-gateway.sh +1541 -0
  390. package/out/scripts/setup-cli.ps1 +86 -0
  391. package/out/scripts/setup-cli.sh +117 -0
  392. package/out/scripts/tools-manifest.json +83 -0
  393. package/out/scripts/vendor-tools.mjs +234 -0
  394. package/out/session.js +272 -0
  395. package/out/shared/agentEngines.js +170 -0
  396. package/out/shared/index.js +109 -0
  397. package/out/shared/models.js +235 -0
  398. package/out/shared/providers.js +202 -0
  399. package/out/skills/publish.js +178 -0
  400. package/out/spotlight/install.js +339 -0
  401. package/out/spotlight/publish.js +544 -0
  402. package/out/spotlight/yaml.js +31 -0
  403. package/out/store/github/setup.js +235 -0
  404. package/out/store/github/templates/build-index.ts +339 -0
  405. package/out/store/github/templates/build-index.yml +97 -0
  406. package/out/store/github/templates/package.json +11 -0
  407. package/out/store/index.js +755 -0
  408. package/out/store/oramaIndex.js +884 -0
  409. package/out/store/shared.js +241 -0
  410. package/out/sync.js +1827 -0
  411. package/out/terminalLogger.js +358 -0
  412. package/out/test/agentEnvFile.test.js +97 -0
  413. package/out/test/agentYaml.test.js +373 -0
  414. package/out/test/agentpack.test.js +639 -0
  415. package/out/test/analytics-lifecycle.test.js +174 -0
  416. package/out/test/analytics.test.js +524 -0
  417. package/out/test/auth-bootstrapApply.test.js +102 -0
  418. package/out/test/auth-broker.test.js +434 -0
  419. package/out/test/auth-callback.test.js +62 -0
  420. package/out/test/branding.test.js +229 -0
  421. package/out/test/cli-agent-id.test.js +55 -0
  422. package/out/test/credential-context.test.js +105 -0
  423. package/out/test/customEngineInstall.test.js +100 -0
  424. package/out/test/customRegistry.test.js +122 -0
  425. package/out/test/deploy-init.test.js +532 -0
  426. package/out/test/deps-auto-install.test.js +81 -0
  427. package/out/test/engine-integration.test.js +297 -0
  428. package/out/test/enginePaths.test.js +195 -0
  429. package/out/test/enginePublish.test.js +82 -0
  430. package/out/test/fleetDisplayUtils.test.js +96 -0
  431. package/out/test/gateway-client.test.js +381 -0
  432. package/out/test/gateway-lifecycle.test.js +608 -0
  433. package/out/test/gateway-outbound.test.js +531 -0
  434. package/out/test/gateway-reset-mappings.test.js +221 -0
  435. package/out/test/gateway-route-index.test.js +235 -0
  436. package/out/test/gateway-session-routing.test.js +47 -0
  437. package/out/test/gateway-session-store.test.js +216 -0
  438. package/out/test/github.test.js +232 -0
  439. package/out/test/headless-sync.test.js +279 -0
  440. package/out/test/helpers/manifest-fixtures.js +27 -0
  441. package/out/test/mcp-obo.test.js +82 -0
  442. package/out/test/mcp.test.js +307 -0
  443. package/out/test/openclaw-channel-routing.test.js +191 -0
  444. package/out/test/pathSafety.test.js +63 -0
  445. package/out/test/permissions.test.js +175 -0
  446. package/out/test/persistent-engine-worker.test.js +220 -0
  447. package/out/test/refreshPolicy.test.js +60 -0
  448. package/out/test/registry.test.js +351 -0
  449. package/out/test/runtime.test.js +349 -0
  450. package/out/test/scheduledFleetStorage.test.js +72 -0
  451. package/out/test/serve-hardening.test.js +192 -0
  452. package/out/test/serveClient.test.js +173 -0
  453. package/out/test/sessionJsonlFleet.test.js +78 -0
  454. package/out/test/shared.test.js +173 -0
  455. package/out/test/skills-mcp.test.js +299 -0
  456. package/out/test/spotlightPublish.test.js +299 -0
  457. package/out/test/spotlightYaml.test.js +58 -0
  458. package/out/test/state-sync-peer.test.js +74 -0
  459. package/out/test/store.test.js +331 -0
  460. package/out/test/stores.test.js +504 -0
  461. package/out/test/sync-switch.test.js +251 -0
  462. package/out/test/teamViewDiscovery.test.js +90 -0
  463. package/out/test/toolPath.test.js +120 -0
  464. package/out/test/utils.test.js +308 -0
  465. package/out/test/viewsConfigMerge.test.js +180 -0
  466. package/out/test/windows-command-line.test.js +75 -0
  467. package/out/utils/agentEnvFile.js +131 -0
  468. package/out/utils/binary.js +175 -0
  469. package/out/utils/index.js +37 -0
  470. package/out/utils/network.js +74 -0
  471. package/out/utils/pathSafety.js +60 -0
  472. package/out/utils/paths.js +116 -0
  473. package/out/utils/pid.js +180 -0
  474. package/out/utils/pythonRunner.js +258 -0
  475. package/out/utils/resolveNodeBinary.js +168 -0
  476. package/out/utils/toolPath.js +83 -0
  477. package/out/utils/windowsCommandLine.js +29 -0
  478. package/out/utils.js +915 -0
  479. package/out/workspaceFolders.js +59 -0
  480. package/package.json +41 -0
@@ -0,0 +1,994 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) AgentHippo.ai. All rights reserved.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.QueryRunnerImpl = exports.QueryRunnerError = void 0;
40
+ const vscode = __importStar(require("vscode"));
41
+ const path = __importStar(require("path"));
42
+ const fs_1 = require("fs");
43
+ const child_process_1 = require("child_process");
44
+ const util_1 = require("util");
45
+ const index_1 = require("../../utils/index");
46
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
47
+ class QueryRunnerError extends Error {
48
+ code;
49
+ constructor(message, code) {
50
+ super(message);
51
+ this.code = code;
52
+ this.name = 'QueryRunnerError';
53
+ }
54
+ }
55
+ exports.QueryRunnerError = QueryRunnerError;
56
+ // -----------------------------------------------------------------------------
57
+ // Implementation
58
+ // -----------------------------------------------------------------------------
59
+ const CACHE_TTL = 30_000;
60
+ const INDEXED_DB_FILENAME = 'analytics.duckdb';
61
+ const INDEXED_DB_REQUIRED_TABLE = 'spans';
62
+ const INDEXED_DB_REQUIRED_COLUMNS = ['trace_id', 'start_ms', 'duration_ms', 'cost', 'model', 'session_id', 'project_id', 'agent_id'];
63
+ const DEFAULT_DUCKDB_MEMORY_LIMIT_MB = 1024;
64
+ const DEFAULT_DUCKDB_THREADS = 2;
65
+ const DEFAULT_DUCKDB_QUERY_TIMEOUT_SECONDS = 30;
66
+ const DEFAULT_DUCKDB_MAX_RESULT_ROWS = 5000;
67
+ const MIN_DUCKDB_MEMORY_MB = 64;
68
+ const MIN_DUCKDB_THREADS = 1;
69
+ const MIN_DUCKDB_TIMEOUT_SECONDS = 5;
70
+ const MIN_DUCKDB_MAX_RESULT_ROWS = 100;
71
+ const MAX_DUCKDB_MAX_RESULT_ROWS = 100_000;
72
+ const DEFAULT_DUCKDB_TEMP_DIRECTORY = path.join((0, index_1.getAgentideHome)(), 'analytics', 'tmp', 'duckdb');
73
+ const FLEET_SESSIONS_TABLE = 'fleet_sessions';
74
+ class QueryRunnerImpl {
75
+ outputChannel;
76
+ cache = new Map();
77
+ duckdbPath;
78
+ indexedDbPath;
79
+ schemaValidated = false;
80
+ fleetSchemaReady = false;
81
+ fleetSchemaEnsurePromise;
82
+ activeDuckDbQueries = 0;
83
+ duckDbQueryWaiters = [];
84
+ maxDuckDbConcurrentQueries = 1;
85
+ lastLoggedRuntimeProfile;
86
+ analyticsConfig;
87
+ tracesDir = path.join((0, index_1.getAgentideHome)(), 'analytics', 'traces');
88
+ constructor(outputChannel) {
89
+ this.outputChannel = outputChannel;
90
+ }
91
+ async ensureDuckDB() {
92
+ if (this.duckdbPath) {
93
+ return this.duckdbPath;
94
+ }
95
+ const candidates = process.platform === 'win32'
96
+ ? ['duckdb', 'duckdb.exe', path.join((0, index_1.getAgentideHome)(), 'bin', 'duckdb.exe'), path.join((0, index_1.getAgentideHome)(), 'bin', 'duckdb')]
97
+ : ['duckdb', path.join((0, index_1.getAgentideHome)(), 'bin', 'duckdb'), '/opt/homebrew/bin/duckdb', '/usr/local/bin/duckdb', '/usr/bin/duckdb'];
98
+ for (const candidate of candidates) {
99
+ try {
100
+ await execFileAsync(candidate, ['--version'], { timeout: 5000 });
101
+ this.duckdbPath = candidate;
102
+ this.outputChannel.appendLine(`[QueryRunner] Using DuckDB at: ${candidate}`);
103
+ return candidate;
104
+ }
105
+ catch {
106
+ // continue
107
+ }
108
+ }
109
+ const installHint = process.platform === 'win32'
110
+ ? 'Run Setup Spotlight first (it installs ~/.agent-hippo/bin/duckdb.exe)'
111
+ : 'Run Setup Spotlight first or install with: brew install duckdb';
112
+ throw new QueryRunnerError(`DuckDB not found. ${installHint}`, 'DUCKDB_NOT_FOUND');
113
+ }
114
+ getIndexedDbPath() {
115
+ return path.join(this.tracesDir, INDEXED_DB_FILENAME);
116
+ }
117
+ getAnalyticsConfig() {
118
+ if (this.analyticsConfig) {
119
+ return this.analyticsConfig;
120
+ }
121
+ const config = vscode.workspace.getConfiguration('agentide.analytics');
122
+ const memoryLimitMb = Math.max(MIN_DUCKDB_MEMORY_MB, Number(config.get('duckdb.memoryLimitMb', DEFAULT_DUCKDB_MEMORY_LIMIT_MB)) || DEFAULT_DUCKDB_MEMORY_LIMIT_MB);
123
+ const threads = Math.max(MIN_DUCKDB_THREADS, Number(config.get('duckdb.threads', DEFAULT_DUCKDB_THREADS)) || DEFAULT_DUCKDB_THREADS);
124
+ const timeoutSeconds = Math.max(MIN_DUCKDB_TIMEOUT_SECONDS, Number(config.get('duckdb.queryTimeoutSeconds', DEFAULT_DUCKDB_QUERY_TIMEOUT_SECONDS)) || DEFAULT_DUCKDB_QUERY_TIMEOUT_SECONDS);
125
+ const maxResultRows = Math.max(MIN_DUCKDB_MAX_RESULT_ROWS, Math.min(MAX_DUCKDB_MAX_RESULT_ROWS, Number(config.get('duckdb.maxResultRows', DEFAULT_DUCKDB_MAX_RESULT_ROWS)) || DEFAULT_DUCKDB_MAX_RESULT_ROWS));
126
+ const tempDirectory = (config.get('duckdb.tempDirectory', '') || '').trim() || DEFAULT_DUCKDB_TEMP_DIRECTORY;
127
+ this.analyticsConfig = { memoryLimitMb, threads, queryTimeoutMs: timeoutSeconds * 1000, maxResultRows, tempDirectory };
128
+ return this.analyticsConfig;
129
+ }
130
+ sqlLiteral(value) {
131
+ return '\'' + value.replace(/'/g, '\'\'') + '\'';
132
+ }
133
+ normalizeFilters(filters) {
134
+ const scope = filters?.scope === 'workspace' ? 'workspace' : 'global';
135
+ const projectId = filters?.projectId?.trim() || undefined;
136
+ const agentId = filters?.agentId?.trim() || undefined;
137
+ return { scope, projectId, agentId };
138
+ }
139
+ buildTraceFilterConditions(filters, alias) {
140
+ const normalized = this.normalizeFilters(filters);
141
+ const prefix = alias ? `${alias}.` : '';
142
+ const conditions = [];
143
+ if (normalized.scope === 'workspace') {
144
+ if (!normalized.projectId) {
145
+ conditions.push('1 = 0');
146
+ }
147
+ else {
148
+ conditions.push(`(${prefix}project_id = ${this.sqlLiteral(normalized.projectId)} OR ${prefix}project_id IS NULL)`);
149
+ }
150
+ }
151
+ if (normalized.agentId) {
152
+ conditions.push(`${prefix}agent_id = ${this.sqlLiteral(normalized.agentId)}`);
153
+ }
154
+ return conditions;
155
+ }
156
+ buildFilterCacheKey(filters) {
157
+ const normalized = this.normalizeFilters(filters);
158
+ return `${normalized.scope}|${normalized.projectId ?? ''}|${normalized.agentId ?? ''}`;
159
+ }
160
+ buildRuntimeSettingsSql() {
161
+ const cfg = this.getAnalyticsConfig();
162
+ const lines = [`SET memory_limit='${cfg.memoryLimitMb}MB';`, `SET threads=${cfg.threads};`, 'SET preserve_insertion_order=false;'];
163
+ if (cfg.tempDirectory) {
164
+ lines.push(`SET temp_directory=${this.sqlLiteral(cfg.tempDirectory)};`);
165
+ }
166
+ return lines.join('\n');
167
+ }
168
+ logRuntimeProfileOnce() {
169
+ const cfg = this.getAnalyticsConfig();
170
+ const profile = `${cfg.memoryLimitMb}|${cfg.threads}|${cfg.queryTimeoutMs}|${cfg.maxResultRows}|${cfg.tempDirectory}`;
171
+ if (this.lastLoggedRuntimeProfile === profile) {
172
+ return;
173
+ }
174
+ this.lastLoggedRuntimeProfile = profile;
175
+ this.outputChannel.appendLine(`[QueryRunner] DuckDB runtime profile: memory=${cfg.memoryLimitMb}MB threads=${cfg.threads} timeoutMs=${cfg.queryTimeoutMs} maxRows=${cfg.maxResultRows} tempDir=${cfg.tempDirectory}`);
176
+ }
177
+ async ensureIndexedDbReady(duckdb) {
178
+ if (this.indexedDbPath && this.schemaValidated) {
179
+ return this.indexedDbPath;
180
+ }
181
+ const dbPath = this.getIndexedDbPath();
182
+ try {
183
+ await fs_1.promises.access(dbPath, fs_1.constants.R_OK);
184
+ }
185
+ catch {
186
+ throw new QueryRunnerError(`Indexed analytics DB not found at ${dbPath}. Run Setup Spotlight or re-index traces.`, 'INDEX_UNAVAILABLE');
187
+ }
188
+ const cfg = this.getAnalyticsConfig();
189
+ await fs_1.promises.mkdir(cfg.tempDirectory, { recursive: true }).catch(() => undefined);
190
+ const requiredColumns = INDEXED_DB_REQUIRED_COLUMNS.map(col => this.sqlLiteral(col)).join(', ');
191
+ const validationSql = `${this.buildRuntimeSettingsSql()}\nSELECT (SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '${INDEXED_DB_REQUIRED_TABLE}') AS table_count, (SELECT COUNT(*) FROM information_schema.columns WHERE table_name = '${INDEXED_DB_REQUIRED_TABLE}' AND column_name IN (${requiredColumns})) AS column_count;`;
192
+ try {
193
+ const { stdout } = await execFileAsync(duckdb, ['-readonly', dbPath, '-json', '-c', validationSql], { timeout: cfg.queryTimeoutMs, maxBuffer: 1024 * 1024 });
194
+ const rows = stdout.trim() ? JSON.parse(stdout) : [];
195
+ const row = rows[0];
196
+ if (!row || Number(row.table_count) < 1 || Number(row.column_count) < INDEXED_DB_REQUIRED_COLUMNS.length) {
197
+ throw new QueryRunnerError('Indexed analytics DB schema is stale or incomplete. Re-index traces and refresh.', 'INDEX_UNAVAILABLE');
198
+ }
199
+ }
200
+ catch (error) {
201
+ if (error instanceof QueryRunnerError) {
202
+ throw error;
203
+ }
204
+ throw new QueryRunnerError(`Indexed analytics DB is unreadable at ${dbPath}. Run Setup Spotlight or re-index traces.`, 'INDEX_UNAVAILABLE');
205
+ }
206
+ this.schemaValidated = true;
207
+ this.indexedDbPath = dbPath;
208
+ return dbPath;
209
+ }
210
+ clampLimit(limit) {
211
+ return Math.max(1, Math.min(this.getAnalyticsConfig().maxResultRows, Math.floor(limit || 1)));
212
+ }
213
+ async acquireDuckDbQuerySlot() {
214
+ while (this.activeDuckDbQueries >= this.maxDuckDbConcurrentQueries) {
215
+ await new Promise(resolve => this.duckDbQueryWaiters.push(resolve));
216
+ }
217
+ this.activeDuckDbQueries += 1;
218
+ }
219
+ releaseDuckDbQuerySlot() {
220
+ this.activeDuckDbQueries = Math.max(0, this.activeDuckDbQueries - 1);
221
+ const next = this.duckDbQueryWaiters.shift();
222
+ next?.();
223
+ }
224
+ async runDuckDB(sqlBody) {
225
+ const duckdb = await this.ensureDuckDB();
226
+ await this.acquireDuckDbQuerySlot();
227
+ try {
228
+ const dbPath = await this.ensureIndexedDbReady(duckdb);
229
+ this.logRuntimeProfileOnce();
230
+ const sql = `${this.buildRuntimeSettingsSql()}\n${sqlBody}`;
231
+ const cfg = this.getAnalyticsConfig();
232
+ const { stdout, stderr } = await execFileAsync(duckdb, ['-readonly', dbPath, '-json', '-c', sql], { timeout: cfg.queryTimeoutMs, maxBuffer: 10 * 1024 * 1024 });
233
+ if (stderr && !stderr.includes('Warning')) {
234
+ this.outputChannel.appendLine(`[QueryRunner] DuckDB stderr: ${stderr}`);
235
+ }
236
+ if (!stdout.trim()) {
237
+ return [];
238
+ }
239
+ return JSON.parse(stdout);
240
+ }
241
+ catch (error) {
242
+ if (error instanceof QueryRunnerError) {
243
+ throw error;
244
+ }
245
+ if (error instanceof Error && error.message.includes('timeout')) {
246
+ throw new QueryRunnerError(`Query timed out (>${Math.floor(this.getAnalyticsConfig().queryTimeoutMs / 1000)}s)`, 'TIMEOUT');
247
+ }
248
+ throw new QueryRunnerError(`Query failed: ${error}`, 'QUERY_ERROR');
249
+ }
250
+ finally {
251
+ this.releaseDuckDbQuerySlot();
252
+ }
253
+ }
254
+ sqlNullableLiteral(value) {
255
+ if (value === undefined || value === null) {
256
+ return 'NULL';
257
+ }
258
+ return this.sqlLiteral(String(value));
259
+ }
260
+ sqlBool(value) {
261
+ return value ? 'TRUE' : 'FALSE';
262
+ }
263
+ isDuckDbLockError(error) {
264
+ const message = error instanceof Error ? error.message : String(error);
265
+ return message.includes('Could not set lock on file')
266
+ || message.includes('Conflicting lock is held');
267
+ }
268
+ isFleetSchemaMismatchError(error) {
269
+ if (this.isDuckDbLockError(error)) {
270
+ return false;
271
+ }
272
+ const message = error instanceof Error ? error.message : String(error);
273
+ return message.includes('ON CONFLICT')
274
+ || message.includes('Constraint')
275
+ || message.includes('conflict target')
276
+ || message.includes('unique constraint')
277
+ || message.includes('PRIMARY KEY')
278
+ || message.includes('primary key');
279
+ }
280
+ async sleep(ms) {
281
+ await new Promise(resolve => setTimeout(resolve, ms));
282
+ }
283
+ async runDuckDBExecForFleet(sqlBody) {
284
+ const duckdb = await this.ensureDuckDB();
285
+ await this.acquireDuckDbQuerySlot();
286
+ try {
287
+ const dbPath = await this.ensureIndexedDbReady(duckdb);
288
+ const cfg = this.getAnalyticsConfig();
289
+ const sql = `${this.buildRuntimeSettingsSql()}\n${sqlBody}`;
290
+ await execFileAsync(duckdb, [dbPath, '-json', '-c', sql], {
291
+ timeout: cfg.queryTimeoutMs,
292
+ maxBuffer: 10 * 1024 * 1024,
293
+ });
294
+ }
295
+ finally {
296
+ this.releaseDuckDbQuerySlot();
297
+ }
298
+ }
299
+ async runDuckDBExecForFleetWithLockRetry(sqlBody, options) {
300
+ const maxWaitMs = Math.max(0, Math.floor(options?.maxWaitMs ?? 2000));
301
+ const startedAt = Date.now();
302
+ let attempt = 0;
303
+ while (true) {
304
+ try {
305
+ await this.runDuckDBExecForFleet(sqlBody);
306
+ return;
307
+ }
308
+ catch (error) {
309
+ if (!this.isDuckDbLockError(error)) {
310
+ throw error;
311
+ }
312
+ const elapsed = Date.now() - startedAt;
313
+ if (elapsed >= maxWaitMs) {
314
+ throw error;
315
+ }
316
+ const delay = Math.min(250, 30 * Math.pow(2, attempt));
317
+ attempt += 1;
318
+ await this.sleep(delay);
319
+ }
320
+ }
321
+ }
322
+ getFromCache(key) {
323
+ const entry = this.cache.get(key);
324
+ if (entry && entry.expiresAt > Date.now()) {
325
+ return entry.data;
326
+ }
327
+ this.cache.delete(key);
328
+ return null;
329
+ }
330
+ setCache(key, data) {
331
+ this.cache.set(key, { data, expiresAt: Date.now() + CACHE_TTL });
332
+ }
333
+ invalidateCache() {
334
+ this.cache.clear();
335
+ this.analyticsConfig = undefined;
336
+ }
337
+ async getCostSummary(filters) {
338
+ const cacheKey = `costSummary:${this.buildFilterCacheKey(filters)}`;
339
+ const cached = this.getFromCache(cacheKey);
340
+ if (cached) {
341
+ return cached;
342
+ }
343
+ try {
344
+ const conditions = ['cost IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
345
+ const whereClause = conditions.join(' AND ');
346
+ const rows = await this.runDuckDB(`
347
+ SELECT
348
+ COALESCE(SUM(cost), 0) as totalCost,
349
+ COUNT(*) as totalRequests,
350
+ COALESCE(AVG(duration_ms), 0) as avgDurationMs,
351
+ COALESCE(SUM(input_tokens), 0) as totalInputTokens,
352
+ COALESCE(SUM(output_tokens), 0) as totalOutputTokens,
353
+ COALESCE((SELECT model FROM spans WHERE ${whereClause} GROUP BY model ORDER BY SUM(cost) DESC LIMIT 1), 'unknown') as topModel
354
+ FROM spans
355
+ WHERE ${whereClause}`);
356
+ const row = rows[0] ?? { totalCost: 0, totalRequests: 0, avgDurationMs: 0, totalInputTokens: 0, totalOutputTokens: 0, topModel: 'unknown' };
357
+ this.setCache(cacheKey, row);
358
+ return row;
359
+ }
360
+ catch (error) {
361
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
362
+ return { totalCost: 0, totalRequests: 0, avgDurationMs: 0, totalInputTokens: 0, totalOutputTokens: 0, topModel: 'unknown' };
363
+ }
364
+ throw error;
365
+ }
366
+ }
367
+ async getRecentSessions(limit = 10, filters) {
368
+ const safeLimit = this.clampLimit(limit);
369
+ const cacheKey = `recentSessions:${safeLimit}:${this.buildFilterCacheKey(filters)}`;
370
+ const cached = this.getFromCache(cacheKey);
371
+ if (cached) {
372
+ return cached;
373
+ }
374
+ try {
375
+ const conditions = ['session_id IS NOT NULL', 'cost IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
376
+ const rows = await this.runDuckDB(`
377
+ SELECT
378
+ session_id as sessionId,
379
+ agent_id as agentId,
380
+ SUM(cost) as totalCost,
381
+ COUNT(*) as requestCount,
382
+ AVG(duration_ms) as avgDurationMs,
383
+ MIN(to_timestamp(start_ms / 1000)) as startedAt
384
+ FROM spans
385
+ WHERE ${conditions.join(' AND ')}
386
+ GROUP BY session_id, agent_id
387
+ ORDER BY MAX(start_ms) DESC
388
+ LIMIT ${safeLimit}`);
389
+ this.setCache(cacheKey, rows);
390
+ return rows;
391
+ }
392
+ catch (error) {
393
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
394
+ return [];
395
+ }
396
+ throw error;
397
+ }
398
+ }
399
+ async getFleetSessions(limit = 200, filters) {
400
+ const safeLimit = this.clampLimit(limit);
401
+ const cacheKey = `fleetSessions:${safeLimit}:${this.buildFilterCacheKey(filters)}`;
402
+ const cached = this.getFromCache(cacheKey);
403
+ if (cached) {
404
+ return cached;
405
+ }
406
+ try {
407
+ const conditions = ['session_id IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
408
+ const sqlWithEngine = `
409
+ SELECT
410
+ session_id as sessionId,
411
+ agent_id as agentId,
412
+ to_timestamp(start_ms / 1000) as startedAt,
413
+ to_timestamp((start_ms + COALESCE(duration_ms, 0)) / 1000) as endedAt,
414
+ 0 as turns,
415
+ 0 as totalTokens,
416
+ COALESCE(model, 'unknown') as model,
417
+ COALESCE(engine, '') as engine
418
+ FROM spans
419
+ WHERE ${conditions.join(' AND ')}
420
+ QUALIFY row_number() OVER (
421
+ PARTITION BY session_id
422
+ ORDER BY start_ms DESC
423
+ ) = 1
424
+ ORDER BY start_ms DESC
425
+ LIMIT ${safeLimit}`;
426
+ const sqlWithoutEngine = `
427
+ SELECT
428
+ session_id as sessionId,
429
+ agent_id as agentId,
430
+ to_timestamp(start_ms / 1000) as startedAt,
431
+ to_timestamp((start_ms + COALESCE(duration_ms, 0)) / 1000) as endedAt,
432
+ 0 as turns,
433
+ 0 as totalTokens,
434
+ COALESCE(model, 'unknown') as model
435
+ FROM spans
436
+ WHERE ${conditions.join(' AND ')}
437
+ QUALIFY row_number() OVER (
438
+ PARTITION BY session_id
439
+ ORDER BY start_ms DESC
440
+ ) = 1
441
+ ORDER BY start_ms DESC
442
+ LIMIT ${safeLimit}`;
443
+ let rows;
444
+ try {
445
+ rows = await this.runDuckDB(sqlWithEngine);
446
+ }
447
+ catch (engineErr) {
448
+ const msg = engineErr instanceof Error ? engineErr.message : String(engineErr);
449
+ if (msg.includes('engine') || msg.includes('column') || msg.includes('referenced')) {
450
+ rows = await this.runDuckDB(sqlWithoutEngine);
451
+ rows = rows.map((r) => ({ ...r, engine: '' }));
452
+ }
453
+ else {
454
+ throw engineErr;
455
+ }
456
+ }
457
+ this.setCache(cacheKey, rows);
458
+ return rows;
459
+ }
460
+ catch (error) {
461
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
462
+ return [];
463
+ }
464
+ throw error;
465
+ }
466
+ }
467
+ async getModelBreakdown(filters) {
468
+ const cacheKey = `modelBreakdown:${this.buildFilterCacheKey(filters)}`;
469
+ const cached = this.getFromCache(cacheKey);
470
+ if (cached) {
471
+ return cached;
472
+ }
473
+ try {
474
+ const conditions = ['cost IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
475
+ const rows = await this.runDuckDB(`
476
+ SELECT COALESCE(model, 'unknown') as model, SUM(cost) as cost, COUNT(*) as requestCount
477
+ FROM spans
478
+ WHERE ${conditions.join(' AND ')}
479
+ GROUP BY model
480
+ ORDER BY cost DESC`);
481
+ const totalCost = rows.reduce((sum, row) => sum + Number(row.cost || 0), 0);
482
+ const result = rows.map(row => ({ ...row, percentage: totalCost > 0 ? (row.cost / totalCost) * 100 : 0 }));
483
+ this.setCache(cacheKey, result);
484
+ return result;
485
+ }
486
+ catch (error) {
487
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
488
+ return [];
489
+ }
490
+ throw error;
491
+ }
492
+ }
493
+ async getCostTrend(days = 7, filters) {
494
+ const cacheKey = `costTrend:${days}:${this.buildFilterCacheKey(filters)}`;
495
+ const cached = this.getFromCache(cacheKey);
496
+ if (cached) {
497
+ return cached;
498
+ }
499
+ try {
500
+ const conditions = ['cost IS NOT NULL', `start_ms > (EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - INTERVAL '${Math.max(1, Math.floor(days || 1))} days')) * 1000)`, ...this.buildTraceFilterConditions(filters)];
501
+ const rows = await this.runDuckDB(`
502
+ SELECT strftime(to_timestamp(start_ms / 1000), '%Y-%m-%d') as date, SUM(cost) as cost, COUNT(*) as requestCount
503
+ FROM spans
504
+ WHERE ${conditions.join(' AND ')}
505
+ GROUP BY date
506
+ ORDER BY date ASC`);
507
+ this.setCache(cacheKey, rows);
508
+ return rows;
509
+ }
510
+ catch (error) {
511
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
512
+ return [];
513
+ }
514
+ throw error;
515
+ }
516
+ }
517
+ async getAgentIds(filters) {
518
+ const normalized = this.normalizeFilters(filters);
519
+ const scopeOnlyFilters = { scope: normalized.scope, projectId: normalized.projectId };
520
+ const cacheKey = `agentIds:${this.buildFilterCacheKey(scopeOnlyFilters)}`;
521
+ const cached = this.getFromCache(cacheKey);
522
+ if (cached) {
523
+ return cached;
524
+ }
525
+ try {
526
+ const conditions = ['agent_id IS NOT NULL', ...this.buildTraceFilterConditions(scopeOnlyFilters)];
527
+ const rows = await this.runDuckDB(`
528
+ SELECT DISTINCT agent_id as agentId
529
+ FROM spans
530
+ WHERE ${conditions.join(' AND ')}
531
+ ORDER BY agent_id ASC`);
532
+ const ids = rows.map(row => row.agentId).filter((value) => Boolean(value));
533
+ this.setCache(cacheKey, ids);
534
+ return ids;
535
+ }
536
+ catch (error) {
537
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
538
+ return [];
539
+ }
540
+ throw error;
541
+ }
542
+ }
543
+ async hasData(filters) {
544
+ const cacheKey = `hasData:${this.buildFilterCacheKey(filters)}`;
545
+ const cached = this.getFromCache(cacheKey);
546
+ if (cached !== null) {
547
+ return cached;
548
+ }
549
+ try {
550
+ const conditions = ['cost IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
551
+ const rows = await this.runDuckDB(`SELECT COUNT(*) as count FROM spans WHERE ${conditions.join(' AND ')}`);
552
+ const hasData = Number(rows[0]?.count ?? 0) > 0;
553
+ this.setCache(cacheKey, hasData);
554
+ return hasData;
555
+ }
556
+ catch (error) {
557
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
558
+ this.setCache(cacheKey, false);
559
+ return false;
560
+ }
561
+ return false;
562
+ }
563
+ }
564
+ async getDataHash(filters) {
565
+ const cacheKey = `dataHash:${this.buildFilterCacheKey(filters)}`;
566
+ const cached = this.getFromCache(cacheKey);
567
+ if (cached !== null) {
568
+ return cached;
569
+ }
570
+ try {
571
+ const conditions = ['cost IS NOT NULL', ...this.buildTraceFilterConditions(filters)];
572
+ const rows = await this.runDuckDB(`
573
+ SELECT
574
+ COUNT(*) as spanCount,
575
+ COALESCE(CAST(SUM(start_ms) AS BIGINT), 0) as startSum,
576
+ COALESCE(CAST(SUM(CAST(cost * 1000000 AS BIGINT)) AS BIGINT), 0) as costMicros,
577
+ COALESCE(MAX(start_ms), 0) as latestStartMs
578
+ FROM spans
579
+ WHERE ${conditions.join(' AND ')}`);
580
+ const row = rows[0];
581
+ if (!row || Number(row.spanCount) === 0) {
582
+ this.setCache(cacheKey, '');
583
+ return '';
584
+ }
585
+ const hash = [Number(row.spanCount), Number(row.startSum), Number(row.costMicros), Number(row.latestStartMs)].join('-');
586
+ this.setCache(cacheKey, hash);
587
+ return hash;
588
+ }
589
+ catch (error) {
590
+ if (error instanceof QueryRunnerError && error.code === 'INDEX_UNAVAILABLE') {
591
+ this.setCache(cacheKey, '');
592
+ return '';
593
+ }
594
+ return '';
595
+ }
596
+ }
597
+ async getDashboardBootstrap(filters) {
598
+ const normalized = this.normalizeFilters(filters);
599
+ const scopeFilters = { scope: normalized.scope, projectId: normalized.projectId };
600
+ const [hasData, dataHash, agentIds, summary] = await Promise.all([
601
+ this.hasData(filters),
602
+ this.getDataHash(filters),
603
+ this.getAgentIds(scopeFilters),
604
+ this.getCostSummary(filters),
605
+ ]);
606
+ return { summary, agentIds, hasData, dataHash };
607
+ }
608
+ async getDuckDbBinaryPath() {
609
+ return await this.ensureDuckDB();
610
+ }
611
+ async getAnalyticsDbPath() {
612
+ const duckdb = await this.ensureDuckDB();
613
+ return await this.ensureIndexedDbReady(duckdb);
614
+ }
615
+ async ensureFleetSchema() {
616
+ if (this.fleetSchemaReady) {
617
+ return;
618
+ }
619
+ if (!this.fleetSchemaEnsurePromise) {
620
+ this.fleetSchemaEnsurePromise = this.ensureFleetSchemaInternal()
621
+ .then(() => {
622
+ this.fleetSchemaReady = true;
623
+ })
624
+ .finally(() => {
625
+ this.fleetSchemaEnsurePromise = undefined;
626
+ });
627
+ }
628
+ await this.fleetSchemaEnsurePromise;
629
+ }
630
+ async ensureFleetSchemaInternal() {
631
+ const createTableSql = `
632
+ CREATE TABLE IF NOT EXISTS ${FLEET_SESSIONS_TABLE} (
633
+ source VARCHAR NOT NULL,
634
+ session_id VARCHAR NOT NULL,
635
+ agent_id VARCHAR,
636
+ status VARCHAR NOT NULL,
637
+ started_at VARCHAR,
638
+ ended_at VARCHAR,
639
+ card_title VARCHAR,
640
+ task_title VARCHAR,
641
+ model VARCHAR,
642
+ engine VARCHAR,
643
+ channel_type VARCHAR,
644
+ channel_target VARCHAR,
645
+ turns BIGINT,
646
+ total_tokens BIGINT,
647
+ disconnect_capable BOOLEAN,
648
+ updated_at TIMESTAMP,
649
+ PRIMARY KEY (source, session_id)
650
+ );
651
+ `;
652
+ // 1) Create table if missing.
653
+ await this.runDuckDBExecForFleetWithLockRetry(createTableSql, { maxWaitMs: 2000 });
654
+ // 2) Validate uniqueness/constraint shape supports ON CONFLICT (source, session_id).
655
+ // Older dev DBs may exist with a different PK shape, which would break Fleet upserts.
656
+ const schemaCheckSql = `
657
+ BEGIN;
658
+ INSERT INTO ${FLEET_SESSIONS_TABLE} (
659
+ source,
660
+ session_id,
661
+ status,
662
+ started_at,
663
+ ended_at,
664
+ card_title,
665
+ task_title,
666
+ model,
667
+ engine,
668
+ channel_type,
669
+ channel_target,
670
+ turns,
671
+ total_tokens,
672
+ disconnect_capable,
673
+ updated_at
674
+ ) VALUES (
675
+ '__schema_check__',
676
+ '__schema_check__',
677
+ 'in_progress',
678
+ '',
679
+ '',
680
+ NULL,
681
+ '',
682
+ 'unknown',
683
+ '',
684
+ 'none',
685
+ '',
686
+ 0,
687
+ 0,
688
+ FALSE,
689
+ current_timestamp
690
+ )
691
+ ON CONFLICT (source, session_id) DO UPDATE SET
692
+ updated_at = current_timestamp;
693
+ DELETE FROM ${FLEET_SESSIONS_TABLE}
694
+ WHERE source = '__schema_check__' AND session_id = '__schema_check__';
695
+ COMMIT;
696
+ `;
697
+ try {
698
+ await this.runDuckDBExecForFleetWithLockRetry(schemaCheckSql, { maxWaitMs: 2000 });
699
+ }
700
+ catch (error) {
701
+ if (!this.isFleetSchemaMismatchError(error)) {
702
+ throw error;
703
+ }
704
+ // 3) Migration fallback: re-create fleet_sessions with the correct PK,
705
+ // preserving card_title when possible.
706
+ const migrationSql = `
707
+ BEGIN;
708
+ CREATE TABLE IF NOT EXISTS ${FLEET_SESSIONS_TABLE}__new (
709
+ source VARCHAR NOT NULL,
710
+ session_id VARCHAR NOT NULL,
711
+ agent_id VARCHAR,
712
+ status VARCHAR NOT NULL,
713
+ started_at VARCHAR,
714
+ ended_at VARCHAR,
715
+ card_title VARCHAR,
716
+ task_title VARCHAR,
717
+ model VARCHAR,
718
+ engine VARCHAR,
719
+ channel_type VARCHAR,
720
+ channel_target VARCHAR,
721
+ turns BIGINT,
722
+ total_tokens BIGINT,
723
+ disconnect_capable BOOLEAN,
724
+ updated_at TIMESTAMP,
725
+ PRIMARY KEY (source, session_id)
726
+ );
727
+
728
+ INSERT INTO ${FLEET_SESSIONS_TABLE}__new (
729
+ source, session_id, agent_id, status, started_at, ended_at, card_title, task_title,
730
+ model, engine, channel_type, channel_target, turns, total_tokens, disconnect_capable, updated_at
731
+ )
732
+ SELECT
733
+ source,
734
+ session_id,
735
+ agent_id,
736
+ CASE WHEN status IS NULL OR TRIM(CAST(status AS VARCHAR)) = '' THEN 'in_progress' ELSE CAST(status AS VARCHAR) END AS status,
737
+ started_at,
738
+ ended_at,
739
+ card_title,
740
+ task_title,
741
+ model,
742
+ engine,
743
+ channel_type,
744
+ channel_target,
745
+ turns,
746
+ total_tokens,
747
+ disconnect_capable,
748
+ COALESCE(updated_at, current_timestamp)
749
+ FROM ${FLEET_SESSIONS_TABLE};
750
+
751
+ DROP TABLE ${FLEET_SESSIONS_TABLE};
752
+ ALTER TABLE ${FLEET_SESSIONS_TABLE}__new RENAME TO ${FLEET_SESSIONS_TABLE};
753
+ COMMIT;
754
+ `;
755
+ this.outputChannel.appendLine(`[QueryRunner] Migrating fleet_sessions schema to (source, session_id) PK (legacy DB detected).`);
756
+ await this.runDuckDBExecForFleetWithLockRetry(migrationSql, { maxWaitMs: 5000 });
757
+ }
758
+ }
759
+ async readFleetSessions(options) {
760
+ await this.ensureFleetSchema();
761
+ const sources = options?.sources?.filter(s => typeof s === 'string' && s.trim() !== '') ?? [];
762
+ const sourceCondition = sources.length > 0
763
+ ? `WHERE source IN (${sources.map(s => this.sqlLiteral(String(s))).join(', ')})`
764
+ : '';
765
+ const sql = `
766
+ SELECT
767
+ source as source,
768
+ session_id as sessionId,
769
+ agent_id as agentId,
770
+ status as status,
771
+ started_at as startedAt,
772
+ ended_at as endedAt,
773
+ card_title as cardTitle,
774
+ task_title as taskTitle,
775
+ model as model,
776
+ engine as engine,
777
+ channel_type as channelType,
778
+ channel_target as channelTarget,
779
+ turns as turns,
780
+ total_tokens as totalTokens,
781
+ disconnect_capable as disconnectCapable,
782
+ updated_at as updatedAt
783
+ FROM ${FLEET_SESSIONS_TABLE}
784
+ ${sourceCondition}
785
+ ORDER BY updated_at DESC`;
786
+ const rows = await this.runDuckDB(sql);
787
+ return rows.map((r) => {
788
+ const status = String(r.status ?? '').trim();
789
+ const disconnect = r.disconnectCapable;
790
+ const startedAt = typeof r.startedAt === 'string' ? r.startedAt : String(r.startedAt ?? '');
791
+ const endedAt = typeof r.endedAt === 'string' ? r.endedAt : String(r.endedAt ?? '');
792
+ return {
793
+ source: typeof r.source === 'string' ? r.source : String(r.source ?? ''),
794
+ sessionId: typeof r.sessionId === 'string' ? r.sessionId : String(r.sessionId ?? ''),
795
+ agentId: typeof r.agentId === 'string' && r.agentId.trim() ? r.agentId : undefined,
796
+ status: status === 'scheduled' ? 'scheduled' : status === 'done' ? 'done' : 'in_progress',
797
+ startedAt,
798
+ endedAt,
799
+ cardTitle: typeof r.cardTitle === 'string' ? r.cardTitle : undefined,
800
+ taskTitle: typeof r.taskTitle === 'string' ? r.taskTitle : String(r.taskTitle ?? ''),
801
+ model: typeof r.model === 'string' ? r.model : String(r.model ?? ''),
802
+ engine: typeof r.engine === 'string' ? r.engine : String(r.engine ?? ''),
803
+ channelType: typeof r.channelType === 'string' ? r.channelType : String(r.channelType ?? 'none'),
804
+ channelTarget: typeof r.channelTarget === 'string' ? r.channelTarget : String(r.channelTarget ?? ''),
805
+ turns: Number(r.turns ?? 0),
806
+ totalTokens: Number(r.totalTokens ?? 0),
807
+ disconnectCapable: disconnect === true || disconnect === 1 || disconnect === 'true',
808
+ updatedAt: typeof r.updatedAt === 'string' ? r.updatedAt : String(r.updatedAt ?? new Date().toISOString()),
809
+ };
810
+ });
811
+ }
812
+ async writeFleetSessions(sourceId, rows) {
813
+ if (!Array.isArray(rows)) {
814
+ return;
815
+ }
816
+ await this.ensureFleetSchema();
817
+ const safeSourceId = String(sourceId ?? '').trim() || 'local';
818
+ const sessionIds = Array.from(new Set(rows
819
+ .map(r => String(r.sessionId ?? '').trim())
820
+ .filter(Boolean)));
821
+ const existingTitles = new Map();
822
+ if (sessionIds.length > 0) {
823
+ const titleSql = `
824
+ SELECT
825
+ session_id as sessionId,
826
+ card_title as cardTitle
827
+ FROM ${FLEET_SESSIONS_TABLE}
828
+ WHERE source = ${this.sqlLiteral(safeSourceId)}
829
+ AND session_id IN (${sessionIds.map(id => this.sqlLiteral(id)).join(', ')})
830
+ `;
831
+ const titleRows = await this.runDuckDB(titleSql);
832
+ for (const row of titleRows) {
833
+ const key = String(row.sessionId ?? '').trim();
834
+ const value = row.cardTitle == null ? '' : String(row.cardTitle);
835
+ if (key && value.trim()) {
836
+ existingTitles.set(key, value);
837
+ }
838
+ }
839
+ }
840
+ if (rows.length === 0) {
841
+ return;
842
+ }
843
+ const clearSql = `
844
+ DELETE FROM ${FLEET_SESSIONS_TABLE}
845
+ WHERE source = ${this.sqlLiteral(safeSourceId)};
846
+ `;
847
+ await this.runDuckDBExecForFleetWithLockRetry(clearSql, { maxWaitMs: 2000 });
848
+ const chunkSize = 200;
849
+ for (let i = 0; i < rows.length; i += chunkSize) {
850
+ const chunk = rows.slice(i, i + chunkSize);
851
+ const values = chunk.map(r => {
852
+ const u = r.updatedAt != null && r.updatedAt !== '' ? this.sqlLiteral(r.updatedAt) : 'current_timestamp';
853
+ const preservedCardTitle = existingTitles.get(String(r.sessionId ?? '').trim());
854
+ const resolvedCardTitle = preservedCardTitle ?? r.cardTitle;
855
+ const incomingCardTitle = resolvedCardTitle !== undefined ? this.sqlNullableLiteral(resolvedCardTitle) : 'NULL';
856
+ return `(
857
+ ${this.sqlLiteral(safeSourceId)},
858
+ ${this.sqlLiteral(r.sessionId)},
859
+ ${r.agentId ? this.sqlLiteral(r.agentId) : 'NULL'},
860
+ ${this.sqlLiteral(r.status)},
861
+ ${this.sqlLiteral(r.startedAt ?? '')},
862
+ ${this.sqlLiteral(r.endedAt ?? '')},
863
+ ${incomingCardTitle},
864
+ ${this.sqlLiteral(r.taskTitle ?? '')},
865
+ ${this.sqlLiteral(r.model ?? '')},
866
+ ${this.sqlLiteral(r.engine ?? '')},
867
+ ${this.sqlLiteral(r.channelType ?? '')},
868
+ ${this.sqlLiteral(r.channelTarget ?? '')},
869
+ ${Number.isFinite(r.turns) ? String(Math.floor(r.turns)) : '0'},
870
+ ${Number.isFinite(r.totalTokens) ? String(Math.floor(r.totalTokens)) : '0'},
871
+ ${this.sqlBool(Boolean(r.disconnectCapable))},
872
+ ${u}
873
+ )`;
874
+ }).join(',\n');
875
+ // Upsert semantics:
876
+ // - refresh updates runtime fields (status/times/tokens/etc)
877
+ // - preserves user-edited card_title if it exists (non-empty)
878
+ // - initializes card_title from incoming card_title, else task_title.
879
+ const sql = `
880
+ INSERT INTO ${FLEET_SESSIONS_TABLE} (
881
+ source,
882
+ session_id,
883
+ agent_id,
884
+ status,
885
+ started_at,
886
+ ended_at,
887
+ card_title,
888
+ task_title,
889
+ model,
890
+ engine,
891
+ channel_type,
892
+ channel_target,
893
+ turns,
894
+ total_tokens,
895
+ disconnect_capable,
896
+ updated_at
897
+ ) VALUES
898
+ ${values}
899
+ ON CONFLICT (source, session_id) DO UPDATE SET
900
+ agent_id = excluded.agent_id,
901
+ status = excluded.status,
902
+ started_at = excluded.started_at,
903
+ ended_at = excluded.ended_at,
904
+ card_title = COALESCE(
905
+ NULLIF(${FLEET_SESSIONS_TABLE}.card_title, ''),
906
+ NULLIF(excluded.card_title, ''),
907
+ NULLIF(excluded.task_title, '')
908
+ ),
909
+ task_title = excluded.task_title,
910
+ model = excluded.model,
911
+ engine = excluded.engine,
912
+ channel_type = excluded.channel_type,
913
+ channel_target = excluded.channel_target,
914
+ turns = excluded.turns,
915
+ total_tokens = excluded.total_tokens,
916
+ disconnect_capable = excluded.disconnect_capable,
917
+ updated_at = excluded.updated_at;
918
+ `;
919
+ await this.runDuckDBExecForFleetWithLockRetry(sql, { maxWaitMs: 2000 });
920
+ }
921
+ }
922
+ async updateFleetCardTitle(sourceId, sessionId, cardTitle) {
923
+ await this.ensureFleetSchema();
924
+ const safeSessionId = String(sessionId ?? '').trim();
925
+ if (!safeSessionId) {
926
+ return;
927
+ }
928
+ const title = cardTitle ?? '';
929
+ const safeSourceId = String(sourceId ?? '').trim() || 'local';
930
+ // Lock contention happens during background indexing; retry writes briefly.
931
+ const sql = `
932
+ BEGIN;
933
+ UPDATE ${FLEET_SESSIONS_TABLE}
934
+ SET card_title = ${this.sqlLiteral(title)},
935
+ updated_at = current_timestamp
936
+ WHERE source = ${this.sqlLiteral(safeSourceId)}
937
+ AND session_id = ${this.sqlLiteral(safeSessionId)};
938
+
939
+ INSERT INTO ${FLEET_SESSIONS_TABLE} (
940
+ source,
941
+ session_id,
942
+ card_title,
943
+ updated_at
944
+ ) SELECT
945
+ ${this.sqlLiteral(safeSourceId)},
946
+ ${this.sqlLiteral(safeSessionId)},
947
+ ${this.sqlLiteral(title)},
948
+ current_timestamp
949
+ WHERE NOT EXISTS (
950
+ SELECT 1 FROM ${FLEET_SESSIONS_TABLE}
951
+ WHERE source = ${this.sqlLiteral(safeSourceId)}
952
+ AND session_id = ${this.sqlLiteral(safeSessionId)}
953
+ );
954
+ COMMIT;
955
+ `;
956
+ await this.runDuckDBExecForFleetWithLockRetry(sql, { maxWaitMs: 2000 });
957
+ }
958
+ async readFleetCardTitles(sessionIds) {
959
+ const ids = Array.from(new Set(sessionIds.filter(s => typeof s === 'string' && s.trim() !== '')));
960
+ if (ids.length === 0) {
961
+ return {};
962
+ }
963
+ await this.ensureFleetSchema();
964
+ const out = {};
965
+ const chunkSize = 200;
966
+ for (let i = 0; i < ids.length; i += chunkSize) {
967
+ const chunk = ids.slice(i, i + chunkSize);
968
+ const sql = `
969
+ SELECT
970
+ session_id as sessionId,
971
+ arg_max(card_title, updated_at) as cardTitle
972
+ FROM ${FLEET_SESSIONS_TABLE}
973
+ WHERE session_id IN (${chunk.map(s => this.sqlLiteral(String(s))).join(', ')})
974
+ GROUP BY session_id`;
975
+ const rows = await this.runDuckDB(sql);
976
+ for (const row of rows) {
977
+ if (!row.sessionId) {
978
+ continue;
979
+ }
980
+ out[row.sessionId] = row.cardTitle === null ? '' : String(row.cardTitle);
981
+ }
982
+ }
983
+ return out;
984
+ }
985
+ dispose() {
986
+ this.cache.clear();
987
+ this.activeDuckDbQueries = 0;
988
+ while (this.duckDbQueryWaiters.length > 0) {
989
+ const waiter = this.duckDbQueryWaiters.shift();
990
+ waiter?.();
991
+ }
992
+ }
993
+ }
994
+ exports.QueryRunnerImpl = QueryRunnerImpl;