@agenthippo-ai/agenthippo 1.110.9 → 1.110.19

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 (533) hide show
  1. package/out/agentpack/types.js +2 -5
  2. package/out/analytics/dashboard/artifactManager.js +2 -439
  3. package/out/analytics/dashboard/fleetDisplayUtils.js +2 -162
  4. package/out/analytics/dashboard/fleetOrchestrator.js +3 -142
  5. package/out/analytics/dashboard/fleetRegistry.js +2 -79
  6. package/out/analytics/dashboard/fleetRowDefaults.js +2 -87
  7. package/out/analytics/dashboard/fleetScriptAdapter.js +2 -146
  8. package/out/analytics/dashboard/fleetTypes.js +2 -29
  9. package/out/analytics/dashboard/index.js +2 -17
  10. package/out/analytics/dashboard/indexingService.js +2 -422
  11. package/out/analytics/dashboard/localFleetAdapter.js +2 -222
  12. package/out/analytics/dashboard/performanceMonitor.js +5 -76
  13. package/out/analytics/dashboard/processManager.js +2 -209
  14. package/out/analytics/dashboard/provider.js +38 -3817
  15. package/out/analytics/dashboard/queryRunner.js +62 -750
  16. package/out/analytics/dashboard/scheduledFleetStorage.js +2 -241
  17. package/out/analytics/dashboard/sessionJsonlFleet.js +3 -204
  18. package/out/analytics/dashboard/teamViewDiscovery.js +2 -106
  19. package/out/analytics/dashboard/webview/panel.js +34 -2318
  20. package/out/analytics/dashboard/webview/runtime-bridge.js +2 -82
  21. package/out/analytics/lifecycle.js +2 -43
  22. package/out/analytics/service.js +8 -1277
  23. package/out/auth/authBaseUrl.js +2 -59
  24. package/out/auth/bootstrapApply.js +2 -71
  25. package/out/auth/brokerClient.js +2 -160
  26. package/out/auth/callbackUri.js +2 -59
  27. package/out/auth/githubStoreGate.js +2 -70
  28. package/out/auth/loopbackAuthServer.js +4 -159
  29. package/out/auth/onboardingPrompt.js +2 -112
  30. package/out/auth/pkce.js +2 -9
  31. package/out/auth/provider.js +2 -226
  32. package/out/auth/sessionStore.js +2 -156
  33. package/out/auth/signInFlow.js +2 -183
  34. package/out/cli/index.js +619 -551
  35. package/out/cli/run-custom-engine-runner.js +3 -318
  36. package/out/cli/vscode-shim.js +2 -86
  37. package/out/engines/factory.js +2 -45
  38. package/out/engines/types.js +2 -17
  39. package/out/examples/run-headless-repl.js +6 -286
  40. package/out/examples/run-headless.js +2 -187
  41. package/out/extension.js +32 -4473
  42. package/out/gateway/gatewayRouteIndex.js +6 -371
  43. package/out/gateway/gatewaySessionStore.js +3 -243
  44. package/out/gateway/index.js +2 -31
  45. package/out/gateway/resetMappings.js +2 -52
  46. package/out/gateway/service.js +5 -1249
  47. package/out/mcp/publish.js +2 -143
  48. package/out/remote/handleRemoteChat.js +2 -169
  49. package/out/remote/remotePackStatusBar.js +3 -103
  50. package/out/remote/remoteTrust.js +6 -277
  51. package/out/remote/serveClient.js +4 -277
  52. package/out/remoteSkills.js +3 -191
  53. package/out/runtime/index.js +2 -32
  54. package/out/runtime/vscode/index.js +2 -20
  55. package/out/runtime/vscode/vscode-config-provider.js +2 -77
  56. package/out/runtime/vscode/vscode-edit-tracker.js +2 -122
  57. package/out/runtime/vscode/vscode-logger.js +2 -30
  58. package/out/runtime/vscode/vscode-permission-handler.js +2 -72
  59. package/out/scripts/agentide-litellm.sh +0 -1
  60. package/out/scripts/agentide_litellm_hooks_v1.py +170 -418
  61. package/out/scripts/analytics/agent-fleet-widget.js +18 -257
  62. package/out/scripts/analytics/agentide-litellm-otel.config.yaml +4 -4
  63. package/out/scripts/analytics/duckdbLocator.js +2 -28
  64. package/out/scripts/analytics/generate-default-charts.py +43 -323
  65. package/out/scripts/analytics/hotspot-analysis-widget.js +4 -430
  66. package/out/scripts/analytics/index-traces.py +78 -1036
  67. package/out/scripts/analytics/session-comparison-widget.js +26 -472
  68. package/out/scripts/analytics/session-timeline-widget.js +25 -846
  69. package/out/scripts/analytics/setup-analytics.ps1 +8 -1
  70. package/out/scripts/analytics/setup-analytics.sh +13 -2
  71. package/out/scripts/analytics/token-cost-flamegraph-widget.js +4 -461
  72. package/out/scripts/analytics/token-cost-trend-widget.js +4 -534
  73. package/out/scripts/analytics/workflows-collector.cjs +4 -314
  74. package/out/scripts/analytics/workflows-daemon.mjs +9 -185
  75. package/out/scripts/analytics/workflows-widget.cjs +15 -159
  76. package/out/scripts/analytics/wow-model-widget.js +10 -120
  77. package/out/scripts/vendor-tools.mjs +2 -233
  78. package/out/skills/publish.js +3 -178
  79. package/out/store/github/setup.js +7 -212
  80. package/out/store/oramaIndex.js +2 -884
  81. package/out/sync.js +26 -1829
  82. package/out/terminalLogger.js +5 -358
  83. package/out/utils/pathSafety.js +2 -60
  84. package/out/utils/pythonRunner.js +4 -258
  85. package/out/utils/toolPath.js +2 -83
  86. package/out/workspaceFolders.js +2 -59
  87. package/package.json +1 -1
  88. package/out/agentpack/github.js +0 -547
  89. package/out/agentpack/index.js +0 -67
  90. package/out/agentpack/install.js +0 -297
  91. package/out/agentpack/manager.js +0 -441
  92. package/out/agentpack/manifest.js +0 -135
  93. package/out/agentpack/paths.js +0 -498
  94. package/out/agentpack/publish.js +0 -248
  95. package/out/agentpack/stores.js +0 -554
  96. package/out/analytics/dashboard/fleetStatusUtils.js +0 -30
  97. package/out/analytics/dashboard/fleetTitleUtils.js +0 -68
  98. package/out/analytics/dashboard/refreshPolicy.js +0 -16
  99. package/out/analytics/dashboard/scheduledFleetFingerprint.js +0 -22
  100. package/out/analytics/dashboard/scheduledFleetUtils.js +0 -22
  101. package/out/analytics/dashboard/sessionEventFleetStats.js +0 -118
  102. package/out/analytics/dashboard/viewsConfigMerge.js +0 -221
  103. package/out/analytics/dashboard/webview/codicon.ttf +0 -0
  104. package/out/analytics/identity.js +0 -0
  105. package/out/analytics/sessionEvents.js +0 -323
  106. package/out/auth/callbackUriParse.js +0 -59
  107. package/out/auth/types.js +0 -12
  108. package/out/auth-broker/config.js +0 -112
  109. package/out/auth-broker/jwt.js +0 -105
  110. package/out/auth-broker/pkce.js +0 -59
  111. package/out/auth-broker/server.js +0 -677
  112. package/out/auth-broker/store.js +0 -275
  113. package/out/authority/warrant.js +0 -206
  114. package/out/base-prompts/mcp-servers/.mcp.json +0 -13
  115. package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +0 -142
  116. package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +0 -13
  117. package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +0 -1192
  118. package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +0 -23
  119. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +0 -12
  120. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +0 -102
  121. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +0 -137
  122. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +0 -118
  123. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +0 -209
  124. package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +0 -431
  125. package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +0 -270
  126. package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +0 -18
  127. package/out/base-prompts/rules/AGENTS.md +0 -204
  128. package/out/base-prompts/skills/agent-browser/SKILL.md +0 -102
  129. package/out/base-prompts/skills/agent-builder/SKILL.md +0 -73
  130. package/out/base-prompts/skills/agent-builder/references/agent-pack.md +0 -63
  131. package/out/base-prompts/skills/agent-builder/references/crewai.md +0 -66
  132. package/out/base-prompts/skills/agent-builder/references/langchain.md +0 -60
  133. package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +0 -73
  134. package/out/base-prompts/skills/agent-engine-creator/SKILL.md +0 -586
  135. package/out/base-prompts/skills/agent-engine-installer/SKILL.md +0 -106
  136. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +0 -259
  137. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +0 -189
  138. package/out/base-prompts/skills/agenthippo-cli/SKILL.md +0 -69
  139. package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +0 -63
  140. package/out/base-prompts/skills/agentpack-creator/SKILL.md +0 -375
  141. package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +0 -261
  142. package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +0 -195
  143. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +0 -391
  144. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +0 -294
  145. package/out/base-prompts/skills/agentpack-testbench/SKILL.md +0 -135
  146. package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +0 -202
  147. package/out/base-prompts/skills/algorithmic-art/SKILL.md +0 -405
  148. package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +0 -223
  149. package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +0 -599
  150. package/out/base-prompts/skills/debug-agent/SKILL.md +0 -83
  151. package/out/base-prompts/skills/desktop-automation/SKILL.md +0 -166
  152. package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +0 -441
  153. package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +0 -280
  154. package/out/base-prompts/skills/docx/LICENSE.txt +0 -30
  155. package/out/base-prompts/skills/docx/SKILL.md +0 -197
  156. package/out/base-prompts/skills/docx/docx-js.md +0 -350
  157. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  158. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  159. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  160. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  161. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  162. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  163. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  164. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  165. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  166. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  167. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  168. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  169. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  170. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  171. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  172. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  173. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  174. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  175. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  176. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  177. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  178. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  179. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  180. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  181. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  182. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  183. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  184. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  185. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  186. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  187. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  188. package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
  189. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  190. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  191. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  192. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  193. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  194. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  195. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  196. package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +0 -159
  197. package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +0 -29
  198. package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +0 -69
  199. package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
  200. package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +0 -951
  201. package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +0 -274
  202. package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
  203. package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
  204. package/out/base-prompts/skills/docx/ooxml.md +0 -610
  205. package/out/base-prompts/skills/docx/scripts/__init__.py +0 -1
  206. package/out/base-prompts/skills/docx/scripts/document.py +0 -1276
  207. package/out/base-prompts/skills/docx/scripts/templates/comments.xml +0 -3
  208. package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +0 -3
  209. package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
  210. package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +0 -3
  211. package/out/base-prompts/skills/docx/scripts/templates/people.xml +0 -3
  212. package/out/base-prompts/skills/docx/scripts/utilities.py +0 -374
  213. package/out/base-prompts/skills/gateway-outbound/SKILL.md +0 -136
  214. package/out/base-prompts/skills/mcp-builder/LICENSE.txt +0 -202
  215. package/out/base-prompts/skills/mcp-builder/SKILL.md +0 -328
  216. package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +0 -602
  217. package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  218. package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  219. package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  220. package/out/base-prompts/skills/mcp-builder/scripts/connections.py +0 -151
  221. package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +0 -373
  222. package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  223. package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +0 -2
  224. package/out/base-prompts/skills/openclaw/SKILL.md +0 -406
  225. package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +0 -61
  226. package/out/base-prompts/skills/pdf/LICENSE.txt +0 -30
  227. package/out/base-prompts/skills/pdf/SKILL.md +0 -294
  228. package/out/base-prompts/skills/pdf/forms.md +0 -205
  229. package/out/base-prompts/skills/pdf/reference.md +0 -612
  230. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +0 -70
  231. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
  232. package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +0 -12
  233. package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
  234. package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +0 -41
  235. package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +0 -152
  236. package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +0 -114
  237. package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
  238. package/out/base-prompts/skills/pptx/LICENSE.txt +0 -30
  239. package/out/base-prompts/skills/pptx/SKILL.md +0 -484
  240. package/out/base-prompts/skills/pptx/html2pptx.md +0 -625
  241. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  242. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  243. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  244. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  245. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  246. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  247. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  248. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  249. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  250. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  251. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  252. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  253. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  254. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  255. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  256. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  257. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  258. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  259. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  260. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  261. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  262. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  263. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  264. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  265. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  266. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  267. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  268. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  269. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  270. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  271. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  272. package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
  273. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  274. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  275. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  276. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  277. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  278. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  279. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  280. package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +0 -159
  281. package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +0 -29
  282. package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +0 -69
  283. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
  284. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +0 -951
  285. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
  286. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
  287. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
  288. package/out/base-prompts/skills/pptx/ooxml.md +0 -427
  289. package/out/base-prompts/skills/pptx/scripts/html2pptx.js +0 -984
  290. package/out/base-prompts/skills/pptx/scripts/inventory.py +0 -1020
  291. package/out/base-prompts/skills/pptx/scripts/rearrange.py +0 -231
  292. package/out/base-prompts/skills/pptx/scripts/replace.py +0 -385
  293. package/out/base-prompts/skills/pptx/scripts/thumbnail.py +0 -450
  294. package/out/base-prompts/skills/prompt-lab/SKILL.md +0 -149
  295. package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +0 -2551
  296. package/out/base-prompts/skills/skill-creator/LICENSE.txt +0 -202
  297. package/out/base-prompts/skills/skill-creator/SKILL.md +0 -371
  298. package/out/base-prompts/skills/skill-creator/references/output-patterns.md +0 -82
  299. package/out/base-prompts/skills/skill-creator/references/workflows.md +0 -28
  300. package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +0 -303
  301. package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +0 -110
  302. package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +0 -95
  303. package/out/base-prompts/skills/skill-installer/SKILL.md +0 -251
  304. package/out/base-prompts/skills/skill-installer/references/store-api.md +0 -219
  305. package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +0 -83
  306. package/out/base-prompts/skills/spotlight-insights/SKILL.md +0 -101
  307. package/out/base-prompts/skills/spotlight-optimize/SKILL.md +0 -93
  308. package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +0 -2551
  309. package/out/base-prompts/skills/spotlight-query/SKILL.md +0 -314
  310. package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +0 -163
  311. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +0 -2551
  312. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +0 -744
  313. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +0 -14
  314. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +0 -7
  315. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +0 -5
  316. package/out/base-prompts/skills/spotlight-report/SKILL.md +0 -86
  317. package/out/base-prompts/skills/spotlight-visualize/SKILL.md +0 -92
  318. package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +0 -2551
  319. package/out/base-prompts/skills/xlsx/LICENSE.txt +0 -30
  320. package/out/base-prompts/skills/xlsx/SKILL.md +0 -289
  321. package/out/base-prompts/skills/xlsx/recalc.py +0 -178
  322. package/out/branding.js +0 -49
  323. package/out/cli/commands/anywhere.js +0 -66
  324. package/out/cli/commands/ask.js +0 -246
  325. package/out/cli/commands/auth-broker.js +0 -24
  326. package/out/cli/commands/auth.js +0 -219
  327. package/out/cli/commands/chat.js +0 -357
  328. package/out/cli/commands/conformance.js +0 -249
  329. package/out/cli/commands/data-plane.js +0 -67
  330. package/out/cli/commands/deploy.js +0 -263
  331. package/out/cli/commands/gateway.js +0 -218
  332. package/out/cli/commands/idp.js +0 -85
  333. package/out/cli/commands/pack.js +0 -399
  334. package/out/cli/commands/probe-custom-engine.js +0 -82
  335. package/out/cli/commands/sandbox.js +0 -332
  336. package/out/cli/commands/serve.js +0 -1758
  337. package/out/cli/commands/store.js +0 -927
  338. package/out/cli/credential-context.js +0 -91
  339. package/out/cli/data-plane/broker.js +0 -78
  340. package/out/cli/data-plane/connector-host.js +0 -121
  341. package/out/cli/data-plane/egress.js +0 -189
  342. package/out/cli/data-plane/gateway.js +0 -218
  343. package/out/cli/data-plane/index.js +0 -152
  344. package/out/cli/data-plane/registry.js +0 -89
  345. package/out/cli/data-plane/remote.js +0 -106
  346. package/out/cli/data-plane/sidecar.js +0 -161
  347. package/out/cli/deploy/blueprints/registry.js +0 -84
  348. package/out/cli/deploy/layers/identity.js +0 -172
  349. package/out/cli/deploy-init.js +0 -3023
  350. package/out/cli/deps.js +0 -342
  351. package/out/cli/idp-init.js +0 -338
  352. package/out/cli/pack-install-ref.js +0 -15
  353. package/out/cli/pack-loader.js +0 -418
  354. package/out/cli/pack-runtime.js +0 -61
  355. package/out/cli/runtime.js +0 -450
  356. package/out/cli/serve-hardening.js +0 -607
  357. package/out/cli/state-sync.js +0 -424
  358. package/out/cli/utils.js +0 -231
  359. package/out/engines/base.js +0 -188
  360. package/out/engines/claude.js +0 -1254
  361. package/out/engines/codex.js +0 -862
  362. package/out/engines/custom.js +0 -674
  363. package/out/engines/customEngineIpc.js +0 -95
  364. package/out/engines/customEngineRunnerEmbed.js +0 -107
  365. package/out/engines/customRegistry.js +0 -274
  366. package/out/engines/embeddedCustomEngineRunner.generated.js +0 -9
  367. package/out/engines/engineApiKey.js +0 -138
  368. package/out/engines/install.js +0 -372
  369. package/out/engines/persistentEngineWorker.js +0 -320
  370. package/out/engines/publish.js +0 -341
  371. package/out/evidence/sessionShip.js +0 -610
  372. package/out/gateway/bridge.js +0 -843
  373. package/out/gateway/cli-agent-id.js +0 -36
  374. package/out/gateway/client.js +0 -336
  375. package/out/gateway/client.test.js +0 -395
  376. package/out/gateway/gateway-scope-errors.js +0 -14
  377. package/out/gateway/gatewayBackup.js +0 -76
  378. package/out/gateway/installSource.js +0 -68
  379. package/out/gateway/lifecycle.js +0 -3190
  380. package/out/gateway/openclaw-channel-routing.js +0 -317
  381. package/out/gateway/outboundHandles.js +0 -373
  382. package/out/gateway/outboundPaths.js +0 -75
  383. package/out/gateway/outboundSend.js +0 -254
  384. package/out/gateway/protocol.js +0 -48
  385. package/out/gateway/secretsPreflight.js +0 -90
  386. package/out/gateway/sessionRouting.js +0 -77
  387. package/out/headless/index.js +0 -539
  388. package/out/headless/sync.js +0 -473
  389. package/out/live-e2e/mcp-demo/server.mjs +0 -32
  390. package/out/live-probe/connector.mjs +0 -8
  391. package/out/live-probe/env-report.mjs +0 -8
  392. package/out/mcp.js +0 -654
  393. package/out/pack/caps.js +0 -271
  394. package/out/pack/governor.js +0 -309
  395. package/out/pack/lease-schema.js +0 -270
  396. package/out/pack/lease.js +0 -640
  397. package/out/pack/reconcile.js +0 -217
  398. package/out/pack/signature.js +0 -839
  399. package/out/permissions.js +0 -108
  400. package/out/permissions.mapping.yaml +0 -68
  401. package/out/registry/index.js +0 -332
  402. package/out/runner/host.js +0 -131
  403. package/out/runner/protocol.js +0 -108
  404. package/out/runner/remoteEngine.js +0 -130
  405. package/out/runtime/interfaces/config-provider.js +0 -32
  406. package/out/runtime/interfaces/edit-tracker.js +0 -24
  407. package/out/runtime/interfaces/index.js +0 -29
  408. package/out/runtime/interfaces/logger.js +0 -40
  409. package/out/runtime/interfaces/permission-handler.js +0 -66
  410. package/out/runtime/interfaces/session-store.js +0 -342
  411. package/out/runtime/vscode/vscode-session-store.js +0 -22
  412. package/out/sandbox/containerDriver.js +0 -570
  413. package/out/sandbox/processDriver.js +0 -315
  414. package/out/sandbox/sandboxRunner.js +0 -191
  415. package/out/sandbox/support.js +0 -301
  416. package/out/sandbox/types.js +0 -55
  417. package/out/scripts/analytics/fleet-local-adapter.js +0 -246
  418. package/out/scripts/analytics/live-fleet-4-collector.cjs +0 -315
  419. package/out/scripts/analytics/live-fleet-4-daemon.mjs +0 -134
  420. package/out/scripts/analytics/live-fleet-4-widget.cjs +0 -433
  421. package/out/scripts/gateway/Dockerfile.serve +0 -45
  422. package/out/scripts/gateway/docker-serve.sh +0 -248
  423. package/out/scripts/gateway/setup-gateway-server.ps1 +0 -953
  424. package/out/scripts/gateway/setup-gateway-server.sh +0 -935
  425. package/out/session.js +0 -272
  426. package/out/shared/agentEngines.js +0 -170
  427. package/out/shared/index.js +0 -109
  428. package/out/shared/models.js +0 -136
  429. package/out/shared/providers.js +0 -205
  430. package/out/spotlight/install.js +0 -345
  431. package/out/spotlight/publish.js +0 -544
  432. package/out/spotlight/yaml.js +0 -31
  433. package/out/store/index.js +0 -786
  434. package/out/store/shared.js +0 -241
  435. package/out/test/agentEnvFile.test.js +0 -97
  436. package/out/test/agentYaml.test.js +0 -373
  437. package/out/test/agentpack.test.js +0 -639
  438. package/out/test/analytics-lifecycle.test.js +0 -174
  439. package/out/test/analytics.test.js +0 -756
  440. package/out/test/auth-baseurl.test.js +0 -132
  441. package/out/test/auth-bootstrapApply.test.js +0 -123
  442. package/out/test/auth-broker-hardening.test.js +0 -227
  443. package/out/test/auth-broker.test.js +0 -541
  444. package/out/test/auth-callback.test.js +0 -62
  445. package/out/test/blueprint-registry.test.js +0 -105
  446. package/out/test/branding.test.js +0 -242
  447. package/out/test/caps-governor.test.js +0 -455
  448. package/out/test/cli-agent-id.test.js +0 -55
  449. package/out/test/codex-new-file-survival.test.js +0 -119
  450. package/out/test/configuration-scopes.test.js +0 -131
  451. package/out/test/credential-context.test.js +0 -160
  452. package/out/test/custom-env-layering.test.js +0 -151
  453. package/out/test/customEngineInstall.test.js +0 -100
  454. package/out/test/customRegistry.test.js +0 -122
  455. package/out/test/data-plane-engine-wiring.test.js +0 -250
  456. package/out/test/data-plane.test.js +0 -311
  457. package/out/test/deploy-init.test.js +0 -854
  458. package/out/test/deps-auto-install.test.js +0 -81
  459. package/out/test/egress-broker.test.js +0 -172
  460. package/out/test/engine-integration.test.js +0 -297
  461. package/out/test/enginePaths.test.js +0 -195
  462. package/out/test/enginePublish.test.js +0 -82
  463. package/out/test/fleetDisplayUtils.test.js +0 -100
  464. package/out/test/gateway-client.test.js +0 -409
  465. package/out/test/gateway-install-source.test.js +0 -111
  466. package/out/test/gateway-lifecycle.test.js +0 -608
  467. package/out/test/gateway-outbound.test.js +0 -538
  468. package/out/test/gateway-reset-mappings.test.js +0 -221
  469. package/out/test/gateway-route-index.test.js +0 -235
  470. package/out/test/gateway-secrets-preflight.test.js +0 -127
  471. package/out/test/gateway-session-routing.test.js +0 -65
  472. package/out/test/gateway-session-store.test.js +0 -216
  473. package/out/test/github.test.js +0 -232
  474. package/out/test/governor-hardening.test.js +0 -217
  475. package/out/test/headless-sync.test.js +0 -301
  476. package/out/test/helpers/manifest-fixtures.js +0 -27
  477. package/out/test/idp-init.test.js +0 -151
  478. package/out/test/lease-signature.test.js +0 -357
  479. package/out/test/lease-trust-root.test.js +0 -273
  480. package/out/test/lease-validation.test.js +0 -169
  481. package/out/test/lease.test.js +0 -114
  482. package/out/test/mcp-obo.test.js +0 -107
  483. package/out/test/mcp.test.js +0 -389
  484. package/out/test/model-routing.test.js +0 -133
  485. package/out/test/openclaw-channel-routing.test.js +0 -191
  486. package/out/test/pack-admission.test.js +0 -216
  487. package/out/test/pack-digest-parity.test.js +0 -140
  488. package/out/test/pack-reconcile.test.js +0 -183
  489. package/out/test/pack-signature-artifact.test.js +0 -103
  490. package/out/test/pack-signature.test.js +0 -176
  491. package/out/test/pack-trust-root.test.js +0 -202
  492. package/out/test/pathSafety.test.js +0 -63
  493. package/out/test/permissions.test.js +0 -175
  494. package/out/test/persistent-engine-worker.test.js +0 -220
  495. package/out/test/refreshPolicy.test.js +0 -60
  496. package/out/test/registry.test.js +0 -351
  497. package/out/test/remote-trust.test.js +0 -242
  498. package/out/test/runner-protocol.test.js +0 -249
  499. package/out/test/runtime.test.js +0 -349
  500. package/out/test/sandbox-driver.test.js +0 -553
  501. package/out/test/sandbox-hardening.test.js +0 -395
  502. package/out/test/sandbox-runner.test.js +0 -343
  503. package/out/test/scheduledFleetStorage.test.js +0 -72
  504. package/out/test/serve-gateway-turn.test.js +0 -267
  505. package/out/test/serve-hardening.test.js +0 -418
  506. package/out/test/serveClient.test.js +0 -209
  507. package/out/test/sessionJsonlFleet.test.js +0 -78
  508. package/out/test/sessionShip.test.js +0 -560
  509. package/out/test/shared.test.js +0 -173
  510. package/out/test/skills-mcp.test.js +0 -299
  511. package/out/test/spotlightPublish.test.js +0 -327
  512. package/out/test/spotlightYaml.test.js +0 -58
  513. package/out/test/state-sync-peer.test.js +0 -156
  514. package/out/test/store-install-safe.test.js +0 -69
  515. package/out/test/store.test.js +0 -331
  516. package/out/test/stores.test.js +0 -504
  517. package/out/test/sync-switch.test.js +0 -251
  518. package/out/test/teamViewDiscovery.test.js +0 -90
  519. package/out/test/tls-bypass.test.js +0 -90
  520. package/out/test/toolPath.test.js +0 -120
  521. package/out/test/utils.test.js +0 -308
  522. package/out/test/viewsConfigMerge.test.js +0 -180
  523. package/out/test/warrant.test.js +0 -138
  524. package/out/test/windows-command-line.test.js +0 -75
  525. package/out/utils/agentEnvFile.js +0 -131
  526. package/out/utils/binary.js +0 -175
  527. package/out/utils/index.js +0 -37
  528. package/out/utils/network.js +0 -74
  529. package/out/utils/paths.js +0 -116
  530. package/out/utils/pid.js +0 -180
  531. package/out/utils/resolveNodeBinary.js +0 -168
  532. package/out/utils/windowsCommandLine.js +0 -29
  533. package/out/utils.js +0 -968
package/out/pack/lease.js DELETED
@@ -1,640 +0,0 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) AgentHippo.ai. All rights reserved.
4
- *--------------------------------------------------------------------------------------------*/
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MAX_LEASE_ENVELOPE_TTL_SECONDS = exports.LEASE_JWS_TYP = exports.LeaseDeniedError = exports.LEASE_MAX_STALENESS_ENV = exports.DEFAULT_LEASE_MAX_STALENESS_SECONDS = exports.MIN_LEASE_POLL_SECONDS = exports.DEFAULT_LEASE_POLL_SECONDS = void 0;
7
- exports.resolveLeasePollSeconds = resolveLeasePollSeconds;
8
- exports.leaseCacheSecondsFor = leaseCacheSecondsFor;
9
- exports.effectiveKillLatencySeconds = effectiveKillLatencySeconds;
10
- exports.leaseMaxStalenessFromEnv = leaseMaxStalenessFromEnv;
11
- exports.denyVerdict = denyVerdict;
12
- exports.resolveFollowedUsers = resolveFollowedUsers;
13
- exports.leaseIsDead = leaseIsDead;
14
- exports.policyVersion = policyVersion;
15
- exports.assertAdmitted = assertAdmitted;
16
- exports.signLease = signLease;
17
- exports.verifySignedLease = verifySignedLease;
18
- exports.requireSignedLease = requireSignedLease;
19
- exports.createLeaseSource = createLeaseSource;
20
- /**
21
- * Lease + pinned version — the kill switch and rollback (PLAN/serve-v4-clean.md §5).
22
- *
23
- * Deliberately ONE mechanism for two jobs: "may this artifact run here, now?" is the same
24
- * question whether it is asked commercially (entitlement) or operationally (emergency stop).
25
- * It is checked at **sandbox creation**, which is why kill and rollback need no new subsystem:
26
- *
27
- * kill — revoke the lease ⇒ every instance refuses NEW sandboxes immediately;
28
- * sandboxes already running are bounded by their TTL (eventual kill, no fleet loop),
29
- * and can be ended now with `SandboxDriver.destroy` on the instance that owns them.
30
- * rollback — pin `version` ⇒ new sandboxes run the pinned pack; running sandboxes drain by TTL.
31
- * No hot-swap machinery: version convergence IS sandbox lifecycle.
32
- *
33
- * The lease is *fail-closed on expiry* but *fail-open on transport*: an unreachable control
34
- * plane must not take a customer's fleet down, while an expired lease must not keep running.
35
- * That asymmetry is deliberate and is the kind of thing that silently flips if unstated.
36
- */
37
- const crypto_1 = require("crypto");
38
- const warrant_1 = require("../authority/warrant");
39
- const lease_schema_1 = require("./lease-schema");
40
- const signature_1 = require("./signature");
41
- /**
42
- * The single source of truth for the lease poll interval.
43
- *
44
- * Kill latency is `poll + cache`, and those two numbers used to be written down in five places
45
- * with two different defaults: the cache defaulted to 60s while every poll defaulted to 30s, so a
46
- * fleet whose banner printed "lease poll 30s" actually took up to 90s to honour a kill switch —
47
- * and the comment sitting next to the cache line warned about exactly that drift. Everything now
48
- * derives from here.
49
- */
50
- exports.DEFAULT_LEASE_POLL_SECONDS = 30;
51
- /** Below this, polling costs more than it buys. */
52
- exports.MIN_LEASE_POLL_SECONDS = 5;
53
- function resolveLeasePollSeconds(requested) {
54
- const n = typeof requested === 'number' && Number.isFinite(requested) ? requested : exports.DEFAULT_LEASE_POLL_SECONDS;
55
- return Math.max(exports.MIN_LEASE_POLL_SECONDS, Math.floor(n));
56
- }
57
- /**
58
- * How long a fetched lease may be reused, derived from the poll interval.
59
- *
60
- * Equal to the poll: serve runs three independent timers on the poll cadence (policy provenance,
61
- * pack convergence, the governor) and they must share one fetch rather than tripling load on the
62
- * control plane. Because a cached copy can be up to `cache` seconds old when a poll reads it, the
63
- * WORST-CASE latency from an operator hitting stop to this instance refusing a turn is
64
- * `poll + cache`. That number is printed at boot rather than the poll interval alone —
65
- * `effectiveKillLatencySeconds` exists so the banner cannot drift from the behaviour again.
66
- *
67
- * An operator who needs it faster does not lower the poll: `governor.refresh()` (wired to the
68
- * admin endpoint / control-plane webhook) re-reads immediately.
69
- */
70
- function leaseCacheSecondsFor(pollSeconds) {
71
- return resolveLeasePollSeconds(pollSeconds);
72
- }
73
- /** Worst-case seconds between a control-plane change and this instance enforcing it. */
74
- function effectiveKillLatencySeconds(pollSeconds) {
75
- const poll = resolveLeasePollSeconds(pollSeconds);
76
- return poll + leaseCacheSecondsFor(poll);
77
- }
78
- /**
79
- * Ceiling on how long a lease may go unrefreshed before this instance refuses turns.
80
- *
81
- * The kill switch failed OPEN under network denial with no ceiling at all: `createLeaseSource`
82
- * keeps the last lease on any transport error, bounded only by that lease's own `expiresAt` —
83
- * which a control plane typically sets days or weeks out. An attacker who can drop packets to the
84
- * control plane (or a customer who firewalls it) therefore keeps a revoked fleet running until the
85
- * entitlement expires, and "revoke the lease" stops meaning "stop the fleet".
86
- *
87
- * The default is deliberately generous. Too low and a real control-plane outage becomes a
88
- * customer-visible outage — the fail-open-on-transport property exists for good reasons and this
89
- * must not quietly delete it. 24 hours is far longer than any plausible planned outage and far
90
- * shorter than a typical lease lifetime, so it converts "indefinite" into "bounded" without
91
- * bricking a deployment that has ever successfully polled. Set 0 to disable the ceiling entirely
92
- * (explicitly accepting the unbounded behaviour); set it lower for a tighter guarantee.
93
- */
94
- exports.DEFAULT_LEASE_MAX_STALENESS_SECONDS = 24 * 60 * 60;
95
- exports.LEASE_MAX_STALENESS_ENV = 'AGENTHIPPO_LEASE_MAX_STALENESS_SECONDS';
96
- function leaseMaxStalenessFromEnv(env = process.env) {
97
- const raw = env[exports.LEASE_MAX_STALENESS_ENV]?.trim();
98
- if (raw === undefined || raw === '') {
99
- return exports.DEFAULT_LEASE_MAX_STALENESS_SECONDS;
100
- }
101
- const n = Number(raw);
102
- if (!Number.isFinite(n) || n < 0) {
103
- return exports.DEFAULT_LEASE_MAX_STALENESS_SECONDS;
104
- }
105
- return Math.floor(n);
106
- }
107
- /**
108
- * Does any live rule name this session?
109
- *
110
- * Session matching accepts BOTH the full session key and the bare `session_id` the caller sent,
111
- * because serve namespaces keys by verified user (`u<hash>--<id>`) and an operator reading a
112
- * support ticket has the bare id, not the hash. Accepting only the full key would make the
113
- * console's most obvious input silently match nothing.
114
- *
115
- * User matching prefers the RESOLVED user id when the caller knows it, and falls back to the
116
- * `u<hash>--` key prefix otherwise. The prefix alone was not enough: a gateway sender with no
117
- * explicit session id gets the key `gateway-<userId>`, which has no `u<hash>--` prefix, so
118
- * "stop this user" matched nothing for every Telegram/Slack conversation while the console
119
- * reported the rule applied — a stop order that silently covers only some of a user's sessions is
120
- * worse than one that fails loudly.
121
- */
122
- function denyVerdict(lease, req, nowSeconds) {
123
- if (!lease?.deny?.length) {
124
- return { denied: false };
125
- }
126
- const now = nowSeconds ?? Math.floor(Date.now() / 1000);
127
- const sep = req.sessionKey.indexOf('--');
128
- const bareSession = sep >= 0 ? req.sessionKey.slice(sep + 2) : req.sessionKey;
129
- // `kill` outranks `drain` when both match, so a narrower emergency order is never softened
130
- // by a broader routine one.
131
- let verdict = { denied: false };
132
- for (const rule of lease.deny) {
133
- if (rule.until !== undefined && rule.until <= now) {
134
- continue;
135
- }
136
- let hit = false;
137
- if (rule.scope === 'pack') {
138
- hit = rule.match === req.pack;
139
- }
140
- else if (rule.scope === 'session') {
141
- hit = rule.match === req.sessionKey || rule.match === bareSession;
142
- // Identity binding (mitigation 2 above): a rule naming a user matches only when the
143
- // verified identity agrees, so the same session id presented by another account misses.
144
- // When the caller resolved NO identity we cannot contradict the rule, so the id-only
145
- // match stands — refusing there would let an unauthenticated shape silently ignore a
146
- // stop order.
147
- if (hit && rule.user !== undefined && req.userId !== undefined && rule.user !== req.userId) {
148
- hit = false;
149
- }
150
- // Rotation escape (mitigation 3): the same user under a different session id.
151
- if (!hit && rule.followUser !== false && req.userId !== undefined && deniedByFollowedUser(rule, req.userId, req.followedUsers)) {
152
- hit = true;
153
- }
154
- }
155
- else if (rule.scope === 'user') {
156
- // Exact identity when we have it; the namespaced-key prefix as the fallback for call
157
- // sites that only hold a session key (the lease watcher sweeping live sandboxes).
158
- hit = (req.userId !== undefined && rule.match === req.userId)
159
- || (req.userHash !== undefined && req.sessionKey.startsWith(`u${req.userHash(rule.match)}--`));
160
- }
161
- if (!hit) {
162
- continue;
163
- }
164
- const reason = `${rule.mode === 'kill' ? 'stopped' : 'draining'} by the control plane${rule.reason ? `: ${rule.reason}` : ''}`;
165
- if (rule.mode === 'kill') {
166
- return { denied: true, mode: 'kill', reason };
167
- }
168
- if (!verdict.denied) {
169
- verdict = { denied: true, mode: 'drain', reason };
170
- }
171
- }
172
- return verdict;
173
- }
174
- const followKey = (rule) => `${rule.scope}:${rule.match}`;
175
- function deniedByFollowedUser(rule, userId, followed) {
176
- return followed?.get(followKey(rule))?.has(userId) ?? false;
177
- }
178
- /**
179
- * Which verified users a session-scoped rule reaches, given what we have learned about sessions.
180
- *
181
- * `sessionUsers` is the governor's sessionKey → verified user map, populated on the turn path.
182
- * A session rule naming `s` therefore also covers every OTHER session belonging to whoever was
183
- * last seen using `s` — which is what makes "stop this session" survive the caller simply sending
184
- * a new `session_id`. Rules that set `followUser: false`, and rules for deployments where no
185
- * identity was ever resolved, produce no entries and behave exactly as before.
186
- */
187
- function resolveFollowedUsers(lease, sessionUsers, nowSeconds) {
188
- const out = new Map();
189
- if (!lease?.deny?.length) {
190
- return out;
191
- }
192
- const now = nowSeconds ?? Math.floor(Date.now() / 1000);
193
- for (const rule of lease.deny) {
194
- if (rule.scope !== 'session' || rule.followUser === false) {
195
- continue;
196
- }
197
- if (rule.until !== undefined && rule.until <= now) {
198
- continue;
199
- }
200
- const users = new Set();
201
- for (const [sessionKey, userId] of sessionUsers) {
202
- const sep = sessionKey.indexOf('--');
203
- const bare = sep >= 0 ? sessionKey.slice(sep + 2) : sessionKey;
204
- if (rule.match !== sessionKey && rule.match !== bare) {
205
- continue;
206
- }
207
- // An explicitly identity-bound rule must not widen itself to a different account.
208
- if (rule.user !== undefined && rule.user !== userId) {
209
- continue;
210
- }
211
- users.add(userId);
212
- }
213
- if (users.size > 0) {
214
- out.set(followKey(rule), users);
215
- }
216
- }
217
- return out;
218
- }
219
- /**
220
- * True when the lease says "stop now" — revoked, disabled, or expired.
221
- *
222
- * `assertAdmitted` refuses NEW sandboxes; this is what a watcher uses to also end the ones already
223
- * running. Without it an emergency stop takes up to a full sandbox TTL to take effect, which is not
224
- * what an operator hitting a kill switch means by "stop".
225
- */
226
- function leaseIsDead(lease, nowSeconds) {
227
- // No lease ⇒ unmanaged deployment; nothing to kill. Same rule as admission.
228
- if (!lease) {
229
- return { dead: false };
230
- }
231
- const now = nowSeconds ?? Math.floor(Date.now() / 1000);
232
- if (!lease.enabled) {
233
- return { dead: true, reason: `kill switch active${lease.reason ? `: ${lease.reason}` : ''}` };
234
- }
235
- if (lease.expiresAt <= now) {
236
- return { dead: true, reason: `lease expired at ${new Date(lease.expiresAt * 1000).toISOString()}` };
237
- }
238
- return { dead: false };
239
- }
240
- /**
241
- * Version of the policy in force — sha256 over the canonicalised lease (sorted keys,
242
- * `expiresAt` excluded: it changes every poll and is not policy).
243
- *
244
- * This is what makes "was the cap enforced?" answerable after anyone edits a cap
245
- * (PLAN/compliance.md §3.1, R-3 policy provenance): a turn stamped with this value can be tied
246
- * to the exact rules that governed it, not to whatever the lease says at audit time.
247
- */
248
- function policyVersion(lease) {
249
- if (!lease) {
250
- return undefined;
251
- }
252
- const { expiresAt: _ignored, ...policy } = lease;
253
- const canonical = (v) => {
254
- if (Array.isArray(v)) {
255
- return v.map(canonical);
256
- }
257
- if (v && typeof v === 'object') {
258
- return Object.fromEntries(Object.keys(v).sort()
259
- .map((k) => [k, canonical(v[k])]));
260
- }
261
- return v;
262
- };
263
- return (0, crypto_1.createHash)('sha256').update(JSON.stringify(canonical(policy))).digest('hex');
264
- }
265
- class LeaseDeniedError extends Error {
266
- constructor(message) {
267
- super(message);
268
- this.name = 'LeaseDeniedError';
269
- }
270
- }
271
- exports.LeaseDeniedError = LeaseDeniedError;
272
- /**
273
- * The admission decision. Throws `LeaseDeniedError` — the caller (`createSandboxRunner.admit`)
274
- * lets it propagate so no sandbox is ever created for refused work.
275
- */
276
- function assertAdmitted(lease, req) {
277
- // No lease configured at all ⇒ unlicensed/unmanaged deployment: allow. Self-hosted dev and
278
- // the free tier must keep working without a control plane. Enforcement begins once an
279
- // operator configures one.
280
- if (!lease) {
281
- return;
282
- }
283
- const now = req.nowSeconds ?? Math.floor(Date.now() / 1000);
284
- if (!lease.enabled) {
285
- throw new LeaseDeniedError(`kill switch active for pack ${req.pack}${lease.reason ? `: ${lease.reason}` : ''}`);
286
- }
287
- if (lease.pack !== req.pack) {
288
- throw new LeaseDeniedError(`lease is for pack ${lease.pack}, not ${req.pack}`);
289
- }
290
- if (lease.expiresAt <= now) {
291
- throw new LeaseDeniedError(`lease for ${req.pack} expired at ${new Date(lease.expiresAt * 1000).toISOString()}`);
292
- }
293
- // Rollback: the pinned version is the only one admitted. Running sandboxes drain on TTL.
294
- if (lease.version && lease.version !== req.version) {
295
- throw new LeaseDeniedError(`pack ${req.pack} is pinned to ${lease.version}; refusing to start ${req.version} (rollback in force)`);
296
- }
297
- // Supply-chain pin: the signed digest, not a mutable tag.
298
- if (lease.imageDigest && req.image && !req.image.includes(lease.imageDigest)) {
299
- throw new LeaseDeniedError(`image for ${req.pack} does not match the leased digest ${lease.imageDigest}`);
300
- }
301
- // Scoped stop orders. Both modes refuse a NEW sandbox — they differ only in what happens to one
302
- // already running, which is the lease watcher's job, not admission's.
303
- if (req.sessionKey) {
304
- const verdict = denyVerdict(lease, {
305
- sessionKey: req.sessionKey,
306
- pack: req.pack,
307
- userHash: req.userHash,
308
- userId: req.userId,
309
- followedUsers: req.followedUsers,
310
- }, now);
311
- if (verdict.denied) {
312
- throw new LeaseDeniedError(verdict.reason ?? 'stopped by the control plane');
313
- }
314
- }
315
- }
316
- // ---------------------------------------------------------------------------------------------
317
- // Signed leases
318
- // ---------------------------------------------------------------------------------------------
319
- /**
320
- * WIRE FORMAT — signed lease.
321
- *
322
- * A **compact JWS (ES256)** whose payload is the `LeaseEnvelopeClaims` object above; identical
323
- * machinery to `pack.sig` and to inference warrants, verified through the same
324
- * `verifyCompactJws` (alg pinned to ES256, `kid` must already be known, raw R||S encoding) — but
325
- * against its OWN JWKS trust root (`loadLeaseTrustRoot`, purpose `lease-signing`), not the pack
326
- * one. A key that can vouch for a lease should not thereby be able to vouch for code, and the
327
- * control plane will not register one kid under both purposes anyway.
328
- *
329
- * header { "alg": "ES256", "typ": "agenthippo-lease+jws", "kid": "<key id>" }
330
- * payload { "lease": { …Lease… }, "aud": "<instance-id>" | "*", "sub": "<pack>",
331
- * "iat": <epoch s>, "exp": <epoch s>, "iss"?: "…", "jti"?: "…" }
332
- *
333
- * The endpoint may answer with any of:
334
- * 1. the compact JWS as the response body (`text/plain` or a JSON string),
335
- * 2. `{"lease": "<compact JWS>"}` — an envelope, so an endpoint can add unsigned metadata,
336
- * 3. a bare `Lease` JSON object — LEGACY, unsigned, accepted only while signing is not required.
337
- *
338
- * `typ` prevents a pack signature (`typ: JWT`) from being replayed as a lease under the same key.
339
- *
340
- * Why each binding is present:
341
- *
342
- * aud the instance this lease was minted for. A lease captured from one instance cannot be
343
- * replayed at another. `*` is a legitimate fleet-wide lease and is accepted as such.
344
- * sub the pack, cross-checked against `lease.pack`, so a lease for one product cannot be
345
- * re-labelled as another after signing.
346
- * iat monotonic per instance: an envelope older than the newest one already accepted is
347
- * refused. This is the anti-ROLLBACK binding, and it is the one that matters most —
348
- * without it an on-path attacker replays yesterday's `enabled: true` lease forever and the
349
- * kill switch never lands. `governor.checkLease` treats a restored lease as "lease
350
- * restored — accepting turns again", so a replay does not merely delay a kill, it lifts
351
- * one that has already latched.
352
- * exp the ENVELOPE's own expiry, separate from `lease.expiresAt` (an entitlement boundary that
353
- * is legitimately weeks out). Capped at `MAX_LEASE_ENVELOPE_TTL_SECONDS`, for the same
354
- * reason warrants are capped: there is no revocation list, so lifetime IS the revocation.
355
- */
356
- exports.LEASE_JWS_TYP = 'agenthippo-lease+jws';
357
- /** Longer than this and the envelope is a credential, not a lease refresh. */
358
- exports.MAX_LEASE_ENVELOPE_TTL_SECONDS = 3600;
359
- /** Mint a signed lease. Used by the control plane and by tests; serve only ever verifies. */
360
- function signLease(lease, key, input) {
361
- const now = input.nowSeconds ?? Math.floor(Date.now() / 1000);
362
- const ttl = Math.min(input.ttlSeconds ?? 300, exports.MAX_LEASE_ENVELOPE_TTL_SECONDS);
363
- const claims = {
364
- lease,
365
- aud: input.instanceId ?? '*',
366
- sub: lease.pack,
367
- iat: now,
368
- exp: now + ttl,
369
- ...(input.iss ? { iss: input.iss } : {}),
370
- };
371
- return (0, warrant_1.signCompactJws)({ typ: exports.LEASE_JWS_TYP, kid: key.kid }, claims, key.privateKeyPem);
372
- }
373
- function verifySignedLease(token, publicKeysByKid, input = {}) {
374
- if (Object.keys(publicKeysByKid).length === 0) {
375
- return { ok: false, reason: 'no trusted lease-signing keys are configured on this instance' };
376
- }
377
- const jws = (0, warrant_1.verifyCompactJws)(token, publicKeysByKid, { typ: exports.LEASE_JWS_TYP });
378
- if (!jws.ok) {
379
- return { ok: false, reason: `lease signature: ${jws.reason}` };
380
- }
381
- const claims = jws.payload;
382
- const now = input.nowSeconds ?? Math.floor(Date.now() / 1000);
383
- const skew = input.clockSkewSeconds ?? 60;
384
- if (typeof claims.iat !== 'number' || !Number.isFinite(claims.iat)) {
385
- return { ok: false, reason: 'lease envelope has no issued-at' };
386
- }
387
- if (typeof claims.exp !== 'number' || !Number.isFinite(claims.exp)) {
388
- return { ok: false, reason: 'lease envelope has no expiry' };
389
- }
390
- if (claims.exp - claims.iat > exports.MAX_LEASE_ENVELOPE_TTL_SECONDS) {
391
- return { ok: false, reason: `lease envelope lifetime ${claims.exp - claims.iat}s exceeds the ${exports.MAX_LEASE_ENVELOPE_TTL_SECONDS}s cap` };
392
- }
393
- if (claims.exp + skew <= now) {
394
- return { ok: false, reason: `lease envelope expired at ${new Date(claims.exp * 1000).toISOString()}` };
395
- }
396
- if (claims.iat - skew > now) {
397
- return { ok: false, reason: 'lease envelope is issued in the future' };
398
- }
399
- if (input.minIat !== undefined && claims.iat < input.minIat) {
400
- return { ok: false, reason: `lease envelope is older than one already accepted (replay/rollback: iat ${claims.iat} < ${input.minIat})` };
401
- }
402
- if (input.instanceId !== undefined && claims.aud !== '*' && claims.aud !== input.instanceId) {
403
- return { ok: false, reason: `lease envelope is for instance ${claims.aud}, not ${input.instanceId}` };
404
- }
405
- const parsed = (0, lease_schema_1.parseLease)(claims.lease);
406
- if (!parsed.ok) {
407
- return { ok: false, reason: `signed lease is malformed: ${parsed.reason}` };
408
- }
409
- if (claims.sub !== parsed.lease.pack) {
410
- return { ok: false, reason: `lease envelope subject ${claims.sub} does not match lease.pack ${parsed.lease.pack}` };
411
- }
412
- return { ok: true, lease: parsed.lease, claims };
413
- }
414
- /** Tighten-only, exactly like `requireSignedPack`. Neither side may waive the other's demand. */
415
- function requireSignedLease(leaseValue, localValue) {
416
- return Boolean(leaseValue) || Boolean(localValue);
417
- }
418
- const looksLikeCompactJws = (s) => /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(s);
419
- /**
420
- * Caching lease source.
421
- *
422
- * Fail-OPEN on transport (network down ⇒ keep serving on the last known lease), fail-CLOSED on
423
- * content (an expired or disabled lease refuses, cached or not). Three things changed:
424
- *
425
- * 1. The body is VALIDATED (`parseLease`), not cast. A document that does not parse is treated
426
- * exactly like a transport failure — the last good lease is kept and the failure is loud —
427
- * rather than being installed as policy with `NaN` caps and unreadable deny rules.
428
- * 2. A SIGNED lease is verified against the LEASE trust root. Unsigned leases still work, and say
429
- * so loudly, unless signing is required — in which case they are refused.
430
- * 3. Staleness is BOUNDED. Past `maxStalenessSeconds` without a successful refresh, `get`
431
- * returns a synthetic disabled lease so admission and the governor both fail closed. Network
432
- * denial can no longer hold a revoked fleet open indefinitely.
433
- */
434
- function createLeaseSource(opts) {
435
- let cached = opts.staticLease;
436
- let fetchedAt = 0;
437
- /** Wall-clock of the last SUCCESSFUL fetch. Distinct from `fetchedAt`, which drives the cache. */
438
- let lastGoodAt;
439
- let lastError;
440
- let sawSignedLease = false;
441
- /** Sticky: once the plane has demanded signed leases, an unsigned response cannot undo it. */
442
- let leaseDemandsSignature = false;
443
- let newestIat;
444
- let staleWarned = false;
445
- let unsignedWarned = false;
446
- let urlChecked = false;
447
- const ttl = opts.cacheSeconds ?? leaseCacheSecondsFor(exports.DEFAULT_LEASE_POLL_SECONDS);
448
- const maxStaleness = opts.maxStalenessSeconds ?? leaseMaxStalenessFromEnv(opts.env);
449
- const doFetch = opts.fetchImpl ?? fetch;
450
- const signingRequired = () => requireSignedLease(leaseDemandsSignature, opts.requireSignedLease);
451
- /**
452
- * What `get` hands back once the ceiling is passed. A synthetic lease rather than `undefined`
453
- * because `undefined` means "unmanaged, admit everything" everywhere in this file — returning it
454
- * here would fail OPEN, which is the bug.
455
- */
456
- const staleLease = (staleFor) => ({
457
- ...(cached ?? { pack: '', expiresAt: 0 }),
458
- enabled: false,
459
- reason: `the control plane has not been reachable for ${staleFor}s, past the ${maxStaleness}s staleness ceiling ` +
460
- `(${exports.LEASE_MAX_STALENESS_ENV}). Refusing work rather than running on a lease that can no longer be revoked. ` +
461
- `Set ${exports.LEASE_MAX_STALENESS_ENV}=0 to accept unbounded staleness.`,
462
- });
463
- const parseBody = (text, now) => {
464
- const trimmed = text.trim();
465
- let jws;
466
- let jsonBody;
467
- if (looksLikeCompactJws(trimmed)) {
468
- jws = trimmed;
469
- }
470
- else {
471
- try {
472
- jsonBody = JSON.parse(trimmed);
473
- }
474
- catch (err) {
475
- return { ok: false, reason: `lease body is not JSON: ${err instanceof Error ? err.message : String(err)}` };
476
- }
477
- if (typeof jsonBody === 'string' && looksLikeCompactJws(jsonBody.trim())) {
478
- jws = jsonBody.trim();
479
- }
480
- else if (jsonBody && typeof jsonBody === 'object' && typeof jsonBody.lease === 'string') {
481
- jws = (jsonBody.lease).trim();
482
- }
483
- }
484
- if (jws) {
485
- const verified = verifySignedLease(jws, opts.signingKeys?.() ?? {}, {
486
- instanceId: opts.instanceId,
487
- minIat: newestIat,
488
- nowSeconds: now,
489
- });
490
- if (!verified.ok) {
491
- return { ok: false, reason: verified.reason };
492
- }
493
- newestIat = verified.claims.iat;
494
- return { ok: true, lease: verified.lease, signed: true };
495
- }
496
- if (signingRequired()) {
497
- return {
498
- ok: false,
499
- reason: 'a signed lease is required but the control plane returned an unsigned one ' +
500
- '(expected a compact JWS body or {"lease":"<jws>"})',
501
- };
502
- }
503
- const parsed = (0, lease_schema_1.parseLease)(jsonBody);
504
- if (!parsed.ok) {
505
- return { ok: false, reason: parsed.reason };
506
- }
507
- for (const w of parsed.warnings) {
508
- opts.logger?.warn(`[Lease] ${w}`);
509
- }
510
- return { ok: true, lease: parsed.lease, signed: false };
511
- };
512
- return {
513
- status(nowSeconds) {
514
- const now = nowSeconds ?? Math.floor(Date.now() / 1000);
515
- const staleFor = lastGoodAt === undefined ? undefined : now - lastGoodAt;
516
- return {
517
- signed: sawSignedLease,
518
- requireSignedLease: signingRequired(),
519
- lastGoodAt,
520
- stalenessSeconds: staleFor,
521
- maxStalenessSeconds: maxStaleness,
522
- failClosed: maxStaleness > 0 && staleFor !== undefined && staleFor > maxStaleness,
523
- lastError,
524
- };
525
- },
526
- async get(nowSeconds) {
527
- const now = nowSeconds ?? Math.floor(Date.now() / 1000);
528
- if (!opts.url) {
529
- return cached;
530
- }
531
- // The lease decides whether this instance may run at all, so the channel it arrives on is
532
- // checked too — but WARNED about rather than refused, and the asymmetry with the trust
533
- // root is deliberate. Refusing to poll a plaintext lease URL would stop the kill switch
534
- // from arriving at all: it fails OPEN, which is strictly worse than polling an
535
- // interceptable channel. The trust root refuses because refusing there fails CLOSED
536
- // (packs stop verifying). The real fix for a plaintext lease is `requireSignedLease` —
537
- // most of what an on-path device could do is undone once the signature, not the
538
- // transport, is what is being trusted.
539
- //
540
- // There used to be a `leaseUrlRefused` flag here, declared and read but never assigned:
541
- // its comment promised "we never poll it at all", which is precisely the refusal the
542
- // paragraph above rules out. It has been deleted rather than wired up — a live flag that
543
- // bricks a fleet's kill switch is worse than a dead one.
544
- //
545
- // The warning fires in EVERY insecure case. It used to be guarded by
546
- // `else if (!signingRequired())`, so the case an operator most needs to hear about — one
547
- // who has demanded signed leases and therefore believes the channel is accounted for —
548
- // was the only silent one.
549
- if (!urlChecked) {
550
- urlChecked = true;
551
- const secure = (0, signature_1.assertSecureTrustUrl)(opts.url, 'AGENTHIPPO_LEASE_URL', opts.env ?? process.env);
552
- if (secure.ok) {
553
- for (const w of secure.warnings) {
554
- opts.logger?.warn(`[Lease] ${w}`);
555
- }
556
- }
557
- else if (signingRequired()) {
558
- // Signing covers the CONTENT, not the channel. What is left is still governance:
559
- // the poll carries this instance's id, pack and version in the clear, and an
560
- // on-path device can withhold a kill switch by replaying the last envelope until
561
- // its own `exp` runs out.
562
- opts.logger?.warn(`[Lease] INSECURE LEASE CHANNEL — ${secure.reason} Signed leases are required here, so the ` +
563
- 'policy itself is still verified — but the channel is not: anyone on the path can read this ' +
564
- `instance's identity, pack and version, and can delay a kill switch by up to ` +
565
- `${exports.MAX_LEASE_ENVELOPE_TTL_SECONDS}s by replaying the last envelope. requireSignedLease is not a ` +
566
- 'substitute for https; serve the lease over https.');
567
- }
568
- else {
569
- opts.logger?.warn(`[Lease] INSECURE LEASE CHANNEL — ${secure.reason} Anyone on the path can lift this instance's ` +
570
- 'kill switch, widen its caps or change its version pin. Continuing to poll (refusing would ' +
571
- 'disable the kill switch entirely), but this deployment is not governable until the lease is ' +
572
- 'signed: set requireSignedLease and have the control plane sign leases.');
573
- }
574
- }
575
- if (cached && now - fetchedAt < ttl) {
576
- return cached;
577
- }
578
- try {
579
- const headers = { accept: 'application/json, text/plain' };
580
- for (const [key, value] of Object.entries(opts.identity?.() ?? {})) {
581
- if (value !== undefined && value !== '') {
582
- headers[`x-agenthippo-${key}`] = String(value);
583
- }
584
- }
585
- const res = await doFetch(opts.url, { headers });
586
- if (!res.ok) {
587
- throw new Error(`lease fetch ${res.status}`);
588
- }
589
- const text = typeof res.text === 'function'
590
- ? await res.text()
591
- // Test doubles and older shims implement only `json()`.
592
- : JSON.stringify(await res.json());
593
- const parsed = parseBody(text, now);
594
- if (!parsed.ok) {
595
- // A garbled or unverifiable document is NOT installed as policy. It behaves like a
596
- // transport failure, which is the only reading that cannot be used to weaken
597
- // enforcement by publishing junk.
598
- throw new Error(parsed.reason);
599
- }
600
- if (parsed.signed) {
601
- sawSignedLease = true;
602
- if (parsed.lease.requireSignedLease) {
603
- leaseDemandsSignature = true;
604
- }
605
- }
606
- else if (!unsignedWarned) {
607
- unsignedWarned = true;
608
- opts.logger?.warn('[Lease] running on an UNSIGNED lease. Anyone who can answer or intercept ' +
609
- `${opts.url} can lift this instance's kill switch, widen its caps and change its version pin. ` +
610
- 'Have the control plane sign leases (ES256 compact JWS) and set requireSignedLease.');
611
- }
612
- cached = parsed.lease;
613
- fetchedAt = now;
614
- lastGoodAt = now;
615
- lastError = undefined;
616
- staleWarned = false;
617
- return cached;
618
- }
619
- catch (err) {
620
- lastError = err instanceof Error ? err.message : String(err);
621
- // Transport failure keeps the LAST lease, which still expires on its own clock —
622
- // an outage cannot extend an entitlement, only preserve one already granted.
623
- opts.logger?.warn(`[Lease] fetch failed, using cached lease: ${lastError}`);
624
- if (lastGoodAt === undefined) {
625
- lastGoodAt = now;
626
- }
627
- const staleFor = now - lastGoodAt;
628
- if (maxStaleness > 0 && staleFor > maxStaleness) {
629
- if (!staleWarned) {
630
- staleWarned = true;
631
- opts.logger?.warn(`[Lease] STALENESS CEILING PASSED — no successful lease refresh for ${staleFor}s ` +
632
- `(ceiling ${maxStaleness}s). Failing closed: turns are refused until the control plane is reachable.`);
633
- }
634
- return staleLease(staleFor);
635
- }
636
- return cached;
637
- }
638
- },
639
- };
640
- }