@withbuddi/buddi 0.1.0-pre.47 → 0.1.0-pre.49
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.
- package/extension/manifest.json +2 -2
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +4 -4
- package/node_modules/@buddi/core/dist/host/build.d.ts +8 -1
- package/node_modules/@buddi/core/dist/host/build.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/host/build.js +45 -0
- package/node_modules/@buddi/core/dist/host/build.js.map +1 -1
- package/node_modules/@buddi/core/dist/host/types.d.ts +53 -1
- package/node_modules/@buddi/core/dist/host/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.js +1 -0
- package/node_modules/@buddi/core/dist/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/pages.d.ts +60 -1
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +71 -5
- package/node_modules/@buddi/core/dist/pages.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/assets.d.ts +4 -4
- package/node_modules/@buddi/core/dist/plugin/assets.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/assets.js +2 -2
- package/node_modules/@buddi/core/dist/plugin/assets.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +8 -4
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/requires.d.ts +20 -0
- package/node_modules/@buddi/core/dist/plugin/requires.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/requires.js +11 -0
- package/node_modules/@buddi/core/dist/plugin/requires.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/uses.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/uses.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/uses.js +2 -0
- package/node_modules/@buddi/core/dist/plugin/uses.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.js +1 -1
- package/node_modules/@buddi/core/dist/plugin-assets.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin-assets.js +3 -1
- package/node_modules/@buddi/core/dist/plugin-assets.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +8 -1
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/runtimes/__fixtures__/server.d.ts +26 -0
- package/node_modules/@buddi/core/dist/runtimes/__fixtures__/server.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/__fixtures__/server.js +93 -0
- package/node_modules/@buddi/core/dist/runtimes/__fixtures__/server.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/area.d.ts +22 -0
- package/node_modules/@buddi/core/dist/runtimes/area.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/area.js +127 -0
- package/node_modules/@buddi/core/dist/runtimes/area.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/config.d.ts +54 -0
- package/node_modules/@buddi/core/dist/runtimes/config.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/config.js +57 -0
- package/node_modules/@buddi/core/dist/runtimes/config.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/consent.d.ts +170 -0
- package/node_modules/@buddi/core/dist/runtimes/consent.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/consent.js +205 -0
- package/node_modules/@buddi/core/dist/runtimes/consent.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/download.d.ts +95 -0
- package/node_modules/@buddi/core/dist/runtimes/download.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/download.js +333 -0
- package/node_modules/@buddi/core/dist/runtimes/download.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/index.d.ts +10 -0
- package/node_modules/@buddi/core/dist/runtimes/index.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/index.js +10 -0
- package/node_modules/@buddi/core/dist/runtimes/index.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/models.d.ts +78 -0
- package/node_modules/@buddi/core/dist/runtimes/models.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/models.js +240 -0
- package/node_modules/@buddi/core/dist/runtimes/models.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/native.d.ts +49 -0
- package/node_modules/@buddi/core/dist/runtimes/native.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/native.js +27 -0
- package/node_modules/@buddi/core/dist/runtimes/native.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/onnx.d.ts +87 -0
- package/node_modules/@buddi/core/dist/runtimes/onnx.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/onnx.js +582 -0
- package/node_modules/@buddi/core/dist/runtimes/onnx.js.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/pins.d.ts +53 -0
- package/node_modules/@buddi/core/dist/runtimes/pins.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/runtimes/pins.js +75 -0
- package/node_modules/@buddi/core/dist/runtimes/pins.js.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts +9 -3
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/missions.js +12 -3
- package/node_modules/@buddi/core/dist/scheduler/missions.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts +8 -3
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.js +5 -1
- package/node_modules/@buddi/core/dist/scheduler/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/approval.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/approval.js +3 -1
- package/node_modules/@buddi/core/dist/secrets/approval.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/use.d.ts +3 -1
- package/node_modules/@buddi/core/dist/secrets/use.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/use.js +2 -0
- package/node_modules/@buddi/core/dist/secrets/use.js.map +1 -1
- package/node_modules/@buddi/core/dist/surfaces.d.ts +1 -1
- package/node_modules/@buddi/core/dist/surfaces.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/surfaces.js +2 -2
- package/node_modules/@buddi/core/dist/surfaces.js.map +1 -1
- package/node_modules/@buddi/core/dist/tools.d.ts +26 -0
- package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/tools.js.map +1 -1
- package/node_modules/@buddi/core/dist/views.d.ts +751 -10
- package/node_modules/@buddi/core/dist/views.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/views.js +105 -0
- package/node_modules/@buddi/core/dist/views.js.map +1 -1
- package/node_modules/@buddi/core/migrations/079_mission_browser_owner.sql +7 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/agents/catalog.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/catalog.js +6 -3
- package/node_modules/@buddi/gateway/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts +24 -10
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js +6 -2
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts +17 -4
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js +25 -5
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js +22 -0
- package/node_modules/@buddi/gateway/dist/browser-host.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/chrome-scope.d.ts +91 -0
- package/node_modules/@buddi/gateway/dist/missions/chrome-scope.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/chrome-scope.js +194 -0
- package/node_modules/@buddi/gateway/dist/missions/chrome-scope.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts +20 -0
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +76 -3
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts +10 -2
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.js +53 -5
- package/node_modules/@buddi/gateway/dist/missions/reminders.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/run-consent.d.ts +12 -0
- package/node_modules/@buddi/gateway/dist/missions/run-consent.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/run-consent.js +26 -0
- package/node_modules/@buddi/gateway/dist/missions/run-consent.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/owner-notify.d.ts +0 -11
- package/node_modules/@buddi/gateway/dist/owner-notify.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/owner-notify.js +3 -1
- package/node_modules/@buddi/gateway/dist/owner-notify.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/asset-image.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/asset-image.js +11 -2
- package/node_modules/@buddi/gateway/dist/plugins/asset-image.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/update.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/update.js +3 -0
- package/node_modules/@buddi/gateway/dist/plugins/update.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/report-audio.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/report-audio.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/report-audio.js +13 -0
- package/node_modules/@buddi/gateway/dist/report-audio.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +2 -1
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/api.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/api.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/api.js +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/api.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/approvals.d.ts +2 -1
- package/node_modules/@buddi/gateway/dist/telegram/approvals.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/approvals.js +16 -4
- package/node_modules/@buddi/gateway/dist/telegram/approvals.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/html.js +2 -2
- package/node_modules/@buddi/gateway/dist/telegram/leading-media.d.ts +43 -0
- package/node_modules/@buddi/gateway/dist/telegram/leading-media.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/leading-media.js +68 -0
- package/node_modules/@buddi/gateway/dist/telegram/leading-media.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.js +25 -3
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts +4 -2
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js +33 -7
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +4 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +10 -7
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +13 -3
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/approval-ask.d.ts +8 -0
- package/node_modules/@buddi/gateway/dist/web/approval-ask.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/approval-ask.js +25 -0
- package/node_modules/@buddi/gateway/dist/web/approval-ask.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.js +13 -2
- package/node_modules/@buddi/gateway/dist/web/plugins.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/web/read.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.js +1 -0
- package/node_modules/@buddi/gateway/dist/web/read.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/runtimes.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/web/runtimes.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/runtimes.js +25 -0
- package/node_modules/@buddi/gateway/dist/web/runtimes.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/server.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +46 -12
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/service.d.ts +9 -0
- package/node_modules/@buddi/gateway/dist/web/service.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/service.js +27 -0
- package/node_modules/@buddi/gateway/dist/web/service.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/write.d.ts +11 -1
- package/node_modules/@buddi/gateway/dist/web/write.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/write.js +18 -1
- package/node_modules/@buddi/gateway/dist/web/write.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/delegate.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/delegate.js +1 -0
- package/node_modules/@buddi/runtime/dist/delegate.js.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts +5 -0
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js +41 -5
- package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts +6 -0
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.js +2 -2
- package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
- package/node_modules/docx/dist/charts.cjs +18 -10
- package/node_modules/docx/dist/charts.iife.js +18 -10
- package/node_modules/docx/dist/charts.mjs +18 -10
- package/node_modules/docx/dist/charts.umd.cjs +18 -10
- package/node_modules/docx/dist/index.cjs +2300 -283
- package/node_modules/docx/dist/index.d.cts +605 -32
- package/node_modules/docx/dist/index.d.ts +605 -32
- package/node_modules/docx/dist/index.iife.js +2300 -283
- package/node_modules/docx/dist/index.mjs +2293 -284
- package/node_modules/docx/dist/index.umd.cjs +2300 -283
- package/node_modules/docx/dist/layout.cjs +50860 -0
- package/node_modules/docx/dist/layout.d.cts +385 -0
- package/node_modules/docx/dist/layout.d.ts +385 -0
- package/node_modules/docx/dist/layout.iife.js +50863 -0
- package/node_modules/docx/dist/layout.mjs +50856 -0
- package/node_modules/docx/dist/layout.umd.cjs +50864 -0
- package/node_modules/docx/dist/math.cjs +7 -7
- package/node_modules/docx/dist/math.iife.js +7 -7
- package/node_modules/docx/dist/math.mjs +7 -7
- package/node_modules/docx/dist/math.umd.cjs +7 -7
- package/node_modules/docx/dist/shapes.cjs +2051 -2470
- package/node_modules/docx/dist/shapes.iife.js +2051 -2470
- package/node_modules/docx/dist/shapes.mjs +2051 -2470
- package/node_modules/docx/dist/shapes.umd.cjs +2051 -2470
- package/node_modules/docx/dist/watermarks.cjs +4 -4
- package/node_modules/docx/dist/watermarks.iife.js +4 -4
- package/node_modules/docx/dist/watermarks.mjs +4 -4
- package/node_modules/docx/dist/watermarks.umd.cjs +4 -4
- package/node_modules/docx/package.json +18 -5
- package/node_modules/imapflow/CHANGELOG.md +17 -0
- package/node_modules/imapflow/dist/cjs/commands/append.js +10 -3
- package/node_modules/imapflow/dist/cjs/commands/authenticate.js +27 -18
- package/node_modules/imapflow/dist/cjs/commands/close.d.ts +12 -1
- package/node_modules/imapflow/dist/cjs/commands/close.js +4 -2
- package/node_modules/imapflow/dist/cjs/commands/copyuid-parser.js +16 -2
- package/node_modules/imapflow/dist/cjs/commands/delete.js +2 -1
- package/node_modules/imapflow/dist/cjs/commands/esearch-parser.js +8 -2
- package/node_modules/imapflow/dist/cjs/commands/fetch.js +35 -9
- package/node_modules/imapflow/dist/cjs/commands/id.js +8 -1
- package/node_modules/imapflow/dist/cjs/commands/idle.js +15 -5
- package/node_modules/imapflow/dist/cjs/commands/list.js +10 -1
- package/node_modules/imapflow/dist/cjs/commands/login.js +5 -1
- package/node_modules/imapflow/dist/cjs/commands/logout.js +7 -0
- package/node_modules/imapflow/dist/cjs/commands/namespace.js +7 -3
- package/node_modules/imapflow/dist/cjs/commands/quota.js +3 -1
- package/node_modules/imapflow/dist/cjs/commands/rename.js +2 -1
- package/node_modules/imapflow/dist/cjs/commands/select.js +5 -0
- package/node_modules/imapflow/dist/cjs/commands/status.js +6 -1
- package/node_modules/imapflow/dist/cjs/commands/store.d.ts +1 -1
- package/node_modules/imapflow/dist/cjs/commands/store.js +1 -2
- package/node_modules/imapflow/dist/cjs/download.js +82 -91
- package/node_modules/imapflow/dist/cjs/handler/imap-compiler.js +45 -29
- package/node_modules/imapflow/dist/cjs/handler/limits.d.ts +11 -0
- package/node_modules/imapflow/dist/cjs/handler/limits.js +16 -1
- package/node_modules/imapflow/dist/cjs/handler/parser-instance.d.ts +10 -0
- package/node_modules/imapflow/dist/cjs/handler/parser-instance.js +25 -10
- package/node_modules/imapflow/dist/cjs/handler/token-parser.js +162 -78
- package/node_modules/imapflow/dist/cjs/imap-flow.js +235 -89
- package/node_modules/imapflow/dist/cjs/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/cjs/package-info.js +1 -1
- package/node_modules/imapflow/dist/cjs/proxy-connection.js +7 -7
- package/node_modules/imapflow/dist/cjs/search-compiler.js +37 -16
- package/node_modules/imapflow/dist/cjs/special-use.js +10 -5
- package/node_modules/imapflow/dist/cjs/tools.d.ts +10 -1
- package/node_modules/imapflow/dist/cjs/tools.js +30 -3
- package/node_modules/imapflow/dist/cjs/types.d.ts +19 -4
- package/node_modules/imapflow/dist/esm/commands/append.js +11 -4
- package/node_modules/imapflow/dist/esm/commands/authenticate.js +28 -19
- package/node_modules/imapflow/dist/esm/commands/close.d.ts +12 -1
- package/node_modules/imapflow/dist/esm/commands/close.js +5 -3
- package/node_modules/imapflow/dist/esm/commands/copyuid-parser.js +16 -2
- package/node_modules/imapflow/dist/esm/commands/delete.js +2 -1
- package/node_modules/imapflow/dist/esm/commands/esearch-parser.js +8 -2
- package/node_modules/imapflow/dist/esm/commands/fetch.js +35 -9
- package/node_modules/imapflow/dist/esm/commands/id.js +9 -2
- package/node_modules/imapflow/dist/esm/commands/idle.js +16 -6
- package/node_modules/imapflow/dist/esm/commands/list.js +10 -1
- package/node_modules/imapflow/dist/esm/commands/login.js +6 -2
- package/node_modules/imapflow/dist/esm/commands/logout.js +7 -0
- package/node_modules/imapflow/dist/esm/commands/namespace.js +7 -3
- package/node_modules/imapflow/dist/esm/commands/quota.js +3 -1
- package/node_modules/imapflow/dist/esm/commands/rename.js +2 -1
- package/node_modules/imapflow/dist/esm/commands/select.js +5 -0
- package/node_modules/imapflow/dist/esm/commands/status.js +7 -2
- package/node_modules/imapflow/dist/esm/commands/store.d.ts +1 -1
- package/node_modules/imapflow/dist/esm/commands/store.js +1 -2
- package/node_modules/imapflow/dist/esm/download.js +82 -91
- package/node_modules/imapflow/dist/esm/handler/imap-compiler.js +45 -29
- package/node_modules/imapflow/dist/esm/handler/limits.d.ts +11 -0
- package/node_modules/imapflow/dist/esm/handler/limits.js +14 -0
- package/node_modules/imapflow/dist/esm/handler/parser-instance.d.ts +10 -0
- package/node_modules/imapflow/dist/esm/handler/parser-instance.js +25 -10
- package/node_modules/imapflow/dist/esm/handler/token-parser.js +163 -79
- package/node_modules/imapflow/dist/esm/imap-flow.js +235 -89
- package/node_modules/imapflow/dist/esm/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/esm/package-info.js +1 -1
- package/node_modules/imapflow/dist/esm/proxy-connection.js +7 -7
- package/node_modules/imapflow/dist/esm/search-compiler.js +37 -16
- package/node_modules/imapflow/dist/esm/special-use.js +10 -5
- package/node_modules/imapflow/dist/esm/tools.d.ts +10 -1
- package/node_modules/imapflow/dist/esm/tools.js +29 -3
- package/node_modules/imapflow/dist/esm/types.d.ts +19 -4
- package/node_modules/imapflow/package.json +3 -2
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/agents/frontmatter.d.ts +4 -4
- package/packages/core/dist/host/build.d.ts +8 -1
- package/packages/core/dist/host/build.d.ts.map +1 -1
- package/packages/core/dist/host/build.js +45 -0
- package/packages/core/dist/host/build.js.map +1 -1
- package/packages/core/dist/host/types.d.ts +53 -1
- package/packages/core/dist/host/types.d.ts.map +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/pages.d.ts +60 -1
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +71 -5
- package/packages/core/dist/pages.js.map +1 -1
- package/packages/core/dist/plugin/assets.d.ts +4 -4
- package/packages/core/dist/plugin/assets.d.ts.map +1 -1
- package/packages/core/dist/plugin/assets.js +2 -2
- package/packages/core/dist/plugin/assets.js.map +1 -1
- package/packages/core/dist/plugin/index.d.ts +8 -4
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js +1 -1
- package/packages/core/dist/plugin/index.js.map +1 -1
- package/packages/core/dist/plugin/requires.d.ts +20 -0
- package/packages/core/dist/plugin/requires.d.ts.map +1 -1
- package/packages/core/dist/plugin/requires.js +11 -0
- package/packages/core/dist/plugin/requires.js.map +1 -1
- package/packages/core/dist/plugin/uses.d.ts +1 -1
- package/packages/core/dist/plugin/uses.d.ts.map +1 -1
- package/packages/core/dist/plugin/uses.js +2 -0
- package/packages/core/dist/plugin/uses.js.map +1 -1
- package/packages/core/dist/plugin/version.d.ts +1 -1
- package/packages/core/dist/plugin/version.js +1 -1
- package/packages/core/dist/plugin-assets.d.ts.map +1 -1
- package/packages/core/dist/plugin-assets.js +3 -1
- package/packages/core/dist/plugin-assets.js.map +1 -1
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +8 -1
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/runtimes/__fixtures__/server.d.ts +26 -0
- package/packages/core/dist/runtimes/__fixtures__/server.d.ts.map +1 -0
- package/packages/core/dist/runtimes/__fixtures__/server.js +93 -0
- package/packages/core/dist/runtimes/__fixtures__/server.js.map +1 -0
- package/packages/core/dist/runtimes/area.d.ts +22 -0
- package/packages/core/dist/runtimes/area.d.ts.map +1 -0
- package/packages/core/dist/runtimes/area.js +127 -0
- package/packages/core/dist/runtimes/area.js.map +1 -0
- package/packages/core/dist/runtimes/config.d.ts +54 -0
- package/packages/core/dist/runtimes/config.d.ts.map +1 -0
- package/packages/core/dist/runtimes/config.js +57 -0
- package/packages/core/dist/runtimes/config.js.map +1 -0
- package/packages/core/dist/runtimes/consent.d.ts +170 -0
- package/packages/core/dist/runtimes/consent.d.ts.map +1 -0
- package/packages/core/dist/runtimes/consent.js +205 -0
- package/packages/core/dist/runtimes/consent.js.map +1 -0
- package/packages/core/dist/runtimes/download.d.ts +95 -0
- package/packages/core/dist/runtimes/download.d.ts.map +1 -0
- package/packages/core/dist/runtimes/download.js +333 -0
- package/packages/core/dist/runtimes/download.js.map +1 -0
- package/packages/core/dist/runtimes/index.d.ts +10 -0
- package/packages/core/dist/runtimes/index.d.ts.map +1 -0
- package/packages/core/dist/runtimes/index.js +10 -0
- package/packages/core/dist/runtimes/index.js.map +1 -0
- package/packages/core/dist/runtimes/models.d.ts +78 -0
- package/packages/core/dist/runtimes/models.d.ts.map +1 -0
- package/packages/core/dist/runtimes/models.js +240 -0
- package/packages/core/dist/runtimes/models.js.map +1 -0
- package/packages/core/dist/runtimes/native.d.ts +49 -0
- package/packages/core/dist/runtimes/native.d.ts.map +1 -0
- package/packages/core/dist/runtimes/native.js +27 -0
- package/packages/core/dist/runtimes/native.js.map +1 -0
- package/packages/core/dist/runtimes/onnx.d.ts +87 -0
- package/packages/core/dist/runtimes/onnx.d.ts.map +1 -0
- package/packages/core/dist/runtimes/onnx.js +582 -0
- package/packages/core/dist/runtimes/onnx.js.map +1 -0
- package/packages/core/dist/runtimes/pins.d.ts +53 -0
- package/packages/core/dist/runtimes/pins.d.ts.map +1 -0
- package/packages/core/dist/runtimes/pins.js +75 -0
- package/packages/core/dist/runtimes/pins.js.map +1 -0
- package/packages/core/dist/scheduler/missions.d.ts +9 -3
- package/packages/core/dist/scheduler/missions.d.ts.map +1 -1
- package/packages/core/dist/scheduler/missions.js +12 -3
- package/packages/core/dist/scheduler/missions.js.map +1 -1
- package/packages/core/dist/scheduler/types.d.ts +8 -3
- package/packages/core/dist/scheduler/types.d.ts.map +1 -1
- package/packages/core/dist/scheduler/types.js +5 -1
- package/packages/core/dist/scheduler/types.js.map +1 -1
- package/packages/core/dist/secrets/approval.d.ts.map +1 -1
- package/packages/core/dist/secrets/approval.js +3 -1
- package/packages/core/dist/secrets/approval.js.map +1 -1
- package/packages/core/dist/secrets/use.d.ts +3 -1
- package/packages/core/dist/secrets/use.d.ts.map +1 -1
- package/packages/core/dist/secrets/use.js +2 -0
- package/packages/core/dist/secrets/use.js.map +1 -1
- package/packages/core/dist/surfaces.d.ts +1 -1
- package/packages/core/dist/surfaces.d.ts.map +1 -1
- package/packages/core/dist/surfaces.js +2 -2
- package/packages/core/dist/surfaces.js.map +1 -1
- package/packages/core/dist/tools.d.ts +26 -0
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/dist/views.d.ts +751 -10
- package/packages/core/dist/views.d.ts.map +1 -1
- package/packages/core/dist/views.js +105 -0
- package/packages/core/dist/views.js.map +1 -1
- package/packages/core/migrations/079_mission_browser_owner.sql +7 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/agents/catalog.d.ts.map +1 -1
- package/packages/gateway/dist/agents/catalog.js +6 -3
- package/packages/gateway/dist/agents/catalog.js.map +1 -1
- package/packages/gateway/dist/agents/catalogue-package.d.ts +24 -10
- package/packages/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
- package/packages/gateway/dist/agents/catalogue-package.js +6 -2
- package/packages/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.d.ts +17 -4
- package/packages/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.js +25 -5
- package/packages/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/packages/gateway/dist/browser-host.d.ts +7 -0
- package/packages/gateway/dist/browser-host.d.ts.map +1 -1
- package/packages/gateway/dist/browser-host.js +22 -0
- package/packages/gateway/dist/browser-host.js.map +1 -1
- package/packages/gateway/dist/missions/chrome-scope.d.ts +91 -0
- package/packages/gateway/dist/missions/chrome-scope.d.ts.map +1 -0
- package/packages/gateway/dist/missions/chrome-scope.js +194 -0
- package/packages/gateway/dist/missions/chrome-scope.js.map +1 -0
- package/packages/gateway/dist/missions/execute.d.ts +20 -0
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +76 -3
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/reminders.d.ts +10 -2
- package/packages/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/packages/gateway/dist/missions/reminders.js +53 -5
- package/packages/gateway/dist/missions/reminders.js.map +1 -1
- package/packages/gateway/dist/missions/run-consent.d.ts +12 -0
- package/packages/gateway/dist/missions/run-consent.d.ts.map +1 -0
- package/packages/gateway/dist/missions/run-consent.js +26 -0
- package/packages/gateway/dist/missions/run-consent.js.map +1 -0
- package/packages/gateway/dist/owner-notify.d.ts +0 -11
- package/packages/gateway/dist/owner-notify.d.ts.map +1 -1
- package/packages/gateway/dist/owner-notify.js +3 -1
- package/packages/gateway/dist/owner-notify.js.map +1 -1
- package/packages/gateway/dist/plugins/asset-image.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/asset-image.js +11 -2
- package/packages/gateway/dist/plugins/asset-image.js.map +1 -1
- package/packages/gateway/dist/plugins/update.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/update.js +3 -0
- package/packages/gateway/dist/plugins/update.js.map +1 -1
- package/packages/gateway/dist/report-audio.d.ts +10 -0
- package/packages/gateway/dist/report-audio.d.ts.map +1 -0
- package/packages/gateway/dist/report-audio.js +13 -0
- package/packages/gateway/dist/report-audio.js.map +1 -0
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +2 -1
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/telegram/api.d.ts +1 -0
- package/packages/gateway/dist/telegram/api.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/api.js +1 -0
- package/packages/gateway/dist/telegram/api.js.map +1 -1
- package/packages/gateway/dist/telegram/approvals.d.ts +2 -1
- package/packages/gateway/dist/telegram/approvals.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/approvals.js +16 -4
- package/packages/gateway/dist/telegram/approvals.js.map +1 -1
- package/packages/gateway/dist/telegram/html.js +2 -2
- package/packages/gateway/dist/telegram/leading-media.d.ts +43 -0
- package/packages/gateway/dist/telegram/leading-media.d.ts.map +1 -0
- package/packages/gateway/dist/telegram/leading-media.js +68 -0
- package/packages/gateway/dist/telegram/leading-media.js.map +1 -0
- package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/main.js +25 -3
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/outbound.d.ts +4 -2
- package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/outbound.js +33 -7
- package/packages/gateway/dist/telegram/outbound.js.map +1 -1
- package/packages/gateway/dist/telegram/surface.d.ts +4 -0
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +10 -7
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +13 -3
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/approval-ask.d.ts +8 -0
- package/packages/gateway/dist/web/approval-ask.d.ts.map +1 -1
- package/packages/gateway/dist/web/approval-ask.js +25 -0
- package/packages/gateway/dist/web/approval-ask.js.map +1 -1
- package/packages/gateway/dist/web/plugins.d.ts +1 -0
- package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
- package/packages/gateway/dist/web/plugins.js +13 -2
- package/packages/gateway/dist/web/plugins.js.map +1 -1
- package/packages/gateway/dist/web/read.d.ts +2 -0
- package/packages/gateway/dist/web/read.d.ts.map +1 -1
- package/packages/gateway/dist/web/read.js +1 -0
- package/packages/gateway/dist/web/read.js.map +1 -1
- package/packages/gateway/dist/web/runtimes.d.ts +10 -0
- package/packages/gateway/dist/web/runtimes.d.ts.map +1 -0
- package/packages/gateway/dist/web/runtimes.js +25 -0
- package/packages/gateway/dist/web/runtimes.js.map +1 -0
- package/packages/gateway/dist/web/server.d.ts +1 -1
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +46 -12
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/service.d.ts +9 -0
- package/packages/gateway/dist/web/service.d.ts.map +1 -1
- package/packages/gateway/dist/web/service.js +27 -0
- package/packages/gateway/dist/web/service.js.map +1 -1
- package/packages/gateway/dist/web/write.d.ts +11 -1
- package/packages/gateway/dist/web/write.d.ts.map +1 -1
- package/packages/gateway/dist/web/write.js +18 -1
- package/packages/gateway/dist/web/write.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/delegate.d.ts.map +1 -1
- package/packages/runtime/dist/delegate.js +1 -0
- package/packages/runtime/dist/delegate.js.map +1 -1
- package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/controller.d.ts +5 -0
- package/packages/tools/browser/dist/controller.d.ts.map +1 -1
- package/packages/tools/browser/dist/controller.js +41 -5
- package/packages/tools/browser/dist/controller.js.map +1 -1
- package/packages/tools/browser/dist/routes.d.ts +6 -0
- package/packages/tools/browser/dist/routes.d.ts.map +1 -1
- package/packages/tools/browser/dist/routes.js +2 -2
- package/packages/tools/browser/dist/routes.js.map +1 -1
- package/packages/tools/email/dist/.tsbuildinfo +1 -1
- package/packages/tools/host/dist/.tsbuildinfo +1 -1
- package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
- package/packages/tools/memory/dist/.tsbuildinfo +1 -1
- package/packages/tools/web/dist/.tsbuildinfo +1 -1
- package/packages/web/dist/assets/index-DBVZzTau.css +1 -0
- package/packages/web/dist/assets/index-Dz7zNZd9.js +155 -0
- package/packages/web/dist/assets/lamejs-fr7QR4q8.js +14 -0
- package/packages/web/dist/assets/{lottie_light-CM_Bp6rc.js → lottie_light-CDos62XP.js} +1 -1
- package/packages/web/dist/build.json +1 -1
- package/packages/web/dist/index.html +2 -2
- package/packages/web/dist/precache.json +5 -4
- package/packages/web/dist/assets/index-Bxcetnpt.js +0 -150
- package/packages/web/dist/assets/index-CkzsX0YQ.css +0 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createAction } from '../actions/store.js';
|
|
3
|
+
import { formatDownloadSize } from './download.js';
|
|
4
|
+
import { checkModelRequest, markModelApproved, startModelDownload } from './models.js';
|
|
5
|
+
import { markOnnxApproved, onnxState, startOnnxDownload } from './onnx.js';
|
|
6
|
+
export const RUNTIMES_PLUGIN = 'runtimes';
|
|
7
|
+
export const RUNTIMES_TOOL = 'runtimes.download';
|
|
8
|
+
export const RUNTIMES_TOOL_VERSION = '1.0.0';
|
|
9
|
+
const fileSchema = z
|
|
10
|
+
.object({ url: z.string(), sha256: z.string(), bytes: z.number().int().positive(), name: z.string() })
|
|
11
|
+
.strict();
|
|
12
|
+
const input = z
|
|
13
|
+
.object({
|
|
14
|
+
/** What the card is about, so a second ask for the same thing finds it. */
|
|
15
|
+
key: z.string(),
|
|
16
|
+
plugin: z.string(),
|
|
17
|
+
reason: z.string(),
|
|
18
|
+
engine: z
|
|
19
|
+
.object({ version: z.string(), platform: z.string(), downloadBytes: z.number().int(), sizeBytes: z.number().int() })
|
|
20
|
+
.strict()
|
|
21
|
+
.optional(),
|
|
22
|
+
model: z
|
|
23
|
+
.object({
|
|
24
|
+
name: z.string(),
|
|
25
|
+
bytes: z.number().int().nonnegative(),
|
|
26
|
+
/** A shared model core downloads into `models/<id>/`. */
|
|
27
|
+
id: z.string().optional(),
|
|
28
|
+
files: z.array(fileSchema).optional(),
|
|
29
|
+
})
|
|
30
|
+
.strict()
|
|
31
|
+
.optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
/** The card's question, and what it will do. Deterministic in its arguments. */
|
|
35
|
+
export function describeRuntimesDownload(args) {
|
|
36
|
+
const model = args.model;
|
|
37
|
+
const engine = args.engine;
|
|
38
|
+
const modelText = model ? `the ${model.name}${model.bytes > 0 ? ` (${formatDownloadSize(model.bytes)})` : ''}` : '';
|
|
39
|
+
const question = model && engine
|
|
40
|
+
? `Download ${modelText} and the engine that runs it (${formatDownloadSize(engine.downloadBytes)})?`
|
|
41
|
+
: engine
|
|
42
|
+
? `Download the engine that runs local models (${formatDownloadSize(engine.downloadBytes)})?`
|
|
43
|
+
: `Download ${modelText}?`;
|
|
44
|
+
const reason = args.reason.trim();
|
|
45
|
+
const lines = [`${args.plugin} asks: ${/[.!?…]$/.test(reason) ? reason : `${reason}.`}`];
|
|
46
|
+
if (engine) {
|
|
47
|
+
lines.push(`The engine is ONNX Runtime ${engine.version} for this computer (${engine.platform}), from npm, checked against its pinned checksum; ` +
|
|
48
|
+
`${formatDownloadSize(engine.sizeBytes)} stays on disk, shared by every plugin that runs local models.`);
|
|
49
|
+
}
|
|
50
|
+
if (model?.files)
|
|
51
|
+
lines.push(`The model's ${model.files.length === 1 ? 'file is' : `${model.files.length} files are`} checked against their pinned checksums too.`);
|
|
52
|
+
return {
|
|
53
|
+
envelope: {
|
|
54
|
+
plugin: args.plugin,
|
|
55
|
+
reason: args.reason,
|
|
56
|
+
...(engine ? { engine } : {}),
|
|
57
|
+
...(model ? { model: { name: model.name, bytes: model.bytes, ...(model.id ? { id: model.id } : {}), ...(model.files ? { files: model.files.map((f) => ({ url: f.url, sha256: f.sha256, bytes: f.bytes })) } : {}) } } : {}),
|
|
58
|
+
},
|
|
59
|
+
// The question on a line of its own: it is the card's heading on Telegram and in notifications.
|
|
60
|
+
preview: `${question}\n${lines.join(' ')}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const downloadTool = {
|
|
64
|
+
name: RUNTIMES_TOOL,
|
|
65
|
+
description: "Start a local-model download the owner approved. Runs only from an approved action.",
|
|
66
|
+
tier: 'gated',
|
|
67
|
+
ownerOnly: true,
|
|
68
|
+
input,
|
|
69
|
+
describe: (args) => describeRuntimesDownload(args),
|
|
70
|
+
async execute(args, _ctx) {
|
|
71
|
+
const started = [];
|
|
72
|
+
if (args.engine) {
|
|
73
|
+
// The yes is kept until the download ends: a restart mid-way resumes it on the next ensure.
|
|
74
|
+
await markOnnxApproved().catch(() => { });
|
|
75
|
+
void startOnnxDownload();
|
|
76
|
+
started.push('engine');
|
|
77
|
+
}
|
|
78
|
+
if (args.model?.id && args.model.files) {
|
|
79
|
+
try {
|
|
80
|
+
const checked = checkModelRequest({ id: args.model.id, files: args.model.files });
|
|
81
|
+
await markModelApproved(checked.id, checked.files).catch(() => { });
|
|
82
|
+
void startModelDownload({ id: args.model.id, files: args.model.files }).catch(() => { });
|
|
83
|
+
started.push(`model ${args.model.id}`);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return { started, refused: err instanceof Error ? err.message : String(err) };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
started,
|
|
91
|
+
note: started.length === 0 ? 'Nothing to download.' : `Downloading ${started.join(' and ')}; ${args.plugin} can use it once it is ready.`,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
/** Core's manifest for the approval tool. Registered by the gateway beside the other core families. */
|
|
96
|
+
export function createRuntimesManifest() {
|
|
97
|
+
return {
|
|
98
|
+
name: RUNTIMES_PLUGIN,
|
|
99
|
+
version: RUNTIMES_TOOL_VERSION,
|
|
100
|
+
schema: 'core',
|
|
101
|
+
migrationsDir: '',
|
|
102
|
+
tools: [downloadTool],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
106
|
+
/**
|
|
107
|
+
* The arguments of the card for what is missing, or undefined when nothing is.
|
|
108
|
+
* `engine` is whether the engine must come too. Throws a `ModelRefusal` for a
|
|
109
|
+
* model that is not one.
|
|
110
|
+
*/
|
|
111
|
+
export function downloadArgs(plugin, reason, engine, model) {
|
|
112
|
+
if (typeof reason !== 'string' || reason.trim() === '')
|
|
113
|
+
throw new TypeError('ensure needs a reason the owner reads on the card');
|
|
114
|
+
let modelArgs;
|
|
115
|
+
if (model !== undefined) {
|
|
116
|
+
if (model.files !== undefined || model.id !== undefined) {
|
|
117
|
+
const checked = checkModelRequest({ id: model.id ?? '', files: model.files ?? [] });
|
|
118
|
+
modelArgs = { name: clip(model.name ?? checked.id), bytes: checked.bytes, id: checked.id, files: checked.files };
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const bytes = model.bytes ?? 0;
|
|
122
|
+
if (!Number.isSafeInteger(bytes) || bytes < 0)
|
|
123
|
+
throw new TypeError('a model\'s bytes are a whole number');
|
|
124
|
+
modelArgs = { name: clip(model.name ?? 'model'), bytes };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const state = onnxState();
|
|
128
|
+
const engineArgs = engine ? { version: state.version, platform: state.platform, downloadBytes: state.downloadBytes, sizeBytes: state.sizeBytes } : undefined;
|
|
129
|
+
if (engineArgs === undefined && modelArgs === undefined)
|
|
130
|
+
return undefined;
|
|
131
|
+
const key = `${engineArgs ? `onnx@${engineArgs.version}/${engineArgs.platform}` : ''}|${modelArgs ? (modelArgs.id ?? `named:${modelArgs.name}`) : ''}`;
|
|
132
|
+
return { key, plugin, reason: clip(reason.trim(), 280), ...(engineArgs ? { engine: engineArgs } : {}), ...(modelArgs ? { model: modelArgs } : {}) };
|
|
133
|
+
}
|
|
134
|
+
function clip(text, max = 80) {
|
|
135
|
+
const flat = String(text).replace(/\s+/g, ' ').trim();
|
|
136
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
137
|
+
}
|
|
138
|
+
/** One raise at a time in this process; the database lock covers every process. */
|
|
139
|
+
let raising = Promise.resolve();
|
|
140
|
+
/**
|
|
141
|
+
* Raise the card, or answer the one already pending for the same thing.
|
|
142
|
+
* Answers the action id. The lookup and the insert run under one advisory
|
|
143
|
+
* lock in one transaction, so two plugins asking in the same tick (speech and
|
|
144
|
+
* news at boot) get one card between them, not two.
|
|
145
|
+
*/
|
|
146
|
+
export function raiseDownloadCard(facts, args) {
|
|
147
|
+
const next = raising.then(() => raiseLocked(facts, args));
|
|
148
|
+
raising = next.catch(() => { });
|
|
149
|
+
return next;
|
|
150
|
+
}
|
|
151
|
+
async function raiseLocked(facts, args) {
|
|
152
|
+
const client = await facts.pool.connect();
|
|
153
|
+
let created;
|
|
154
|
+
let id;
|
|
155
|
+
try {
|
|
156
|
+
await client.query('begin');
|
|
157
|
+
await client.query('select pg_advisory_xact_lock(hashtext($1))', [RUNTIMES_TOOL]);
|
|
158
|
+
// The engine alone is answered by any pending card that brings it: the
|
|
159
|
+
// owner is asked about the engine once, whichever plugin asked first.
|
|
160
|
+
const engineOnly = args.engine !== undefined && args.model === undefined;
|
|
161
|
+
const { rows } = await client.query(`select a.id from core.actions a join core.approvals p on p.action_id = a.id
|
|
162
|
+
where a.tool = $1 and p.state = 'pending' and a.expires_at > $3
|
|
163
|
+
and (a.canonical_args->>'key' = $2 or ($4 and starts_with(a.canonical_args->>'key', $2)))
|
|
164
|
+
order by a.created_at desc limit 1`, [RUNTIMES_TOOL, args.key, facts.now(), engineOnly]);
|
|
165
|
+
const open = rows[0];
|
|
166
|
+
if (open !== undefined) {
|
|
167
|
+
id = String(open.id);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const card = describeRuntimesDownload(args);
|
|
171
|
+
let conversationId = null;
|
|
172
|
+
if (facts.conversationId !== undefined && UUID.test(facts.conversationId)) {
|
|
173
|
+
const found = await client.query(`select 1 from core.conversations where id = $1`, [facts.conversationId]);
|
|
174
|
+
if (found.rows.length > 0)
|
|
175
|
+
conversationId = facts.conversationId;
|
|
176
|
+
}
|
|
177
|
+
created = await createAction(client, {
|
|
178
|
+
tool: RUNTIMES_TOOL,
|
|
179
|
+
toolVersion: RUNTIMES_TOOL_VERSION,
|
|
180
|
+
agentId: facts.agentId ?? facts.plugin,
|
|
181
|
+
conversationId,
|
|
182
|
+
canonicalArgs: args,
|
|
183
|
+
envelope: card.envelope,
|
|
184
|
+
preview: card.preview,
|
|
185
|
+
tier: 'gated',
|
|
186
|
+
now: facts.now(),
|
|
187
|
+
});
|
|
188
|
+
id = created.id;
|
|
189
|
+
}
|
|
190
|
+
await client.query('commit');
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
await client.query('rollback').catch(() => { });
|
|
194
|
+
throw err;
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
client.release();
|
|
198
|
+
}
|
|
199
|
+
// Telegram and push are told about a new card; telling them never fails the ask.
|
|
200
|
+
if (created !== undefined && facts.askApproval !== undefined) {
|
|
201
|
+
await facts.askApproval(created).catch(() => { });
|
|
202
|
+
}
|
|
203
|
+
return id;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=consent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consent.js","sourceRoot":"","sources":["../../src/runtimes/consent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { request as httpsRequest } from 'node:https';
|
|
2
|
+
import { type LookupAll } from '../host/http.js';
|
|
3
|
+
import { type AddressPolicy } from '../plugin/url.js';
|
|
4
|
+
/** An answer whose body is read as it arrives, never buffered whole. */
|
|
5
|
+
export interface DownloadResponse {
|
|
6
|
+
status: number;
|
|
7
|
+
body: AsyncIterable<Uint8Array>;
|
|
8
|
+
}
|
|
9
|
+
/** How a download asks for a URL: tests hand in one over a local server. */
|
|
10
|
+
export type DownloadGet = (url: string, opts?: {
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}) => Promise<DownloadResponse>;
|
|
13
|
+
/** How `nodeGet` dials: tests point it at a local server and a resolver of their own. */
|
|
14
|
+
export interface NodeGetOptions {
|
|
15
|
+
request?: typeof httpsRequest;
|
|
16
|
+
/** Where a checked URL is actually sent. Tests only: the checks run on the URL before it. */
|
|
17
|
+
rewrite?: (url: string) => string;
|
|
18
|
+
/** The address rules; `DEFAULT_POLICY` in shipped code. */
|
|
19
|
+
policy?: AddressPolicy;
|
|
20
|
+
/** How a name is resolved before the guard judges it. */
|
|
21
|
+
resolve?: LookupAll;
|
|
22
|
+
}
|
|
23
|
+
/** The most redirects one download follows. */
|
|
24
|
+
export declare const DOWNLOAD_MAX_REDIRECTS = 5;
|
|
25
|
+
/**
|
|
26
|
+
* GET over `node:https`, one connection per request and no pool (the reason
|
|
27
|
+
* the shared transport exists; it buffers whole answers, and an engine is a
|
|
28
|
+
* hundred megabytes). The same guards as the shared transport: every URL —
|
|
29
|
+
* the first and every redirect — goes through `checkUrl` (no credentials, the
|
|
30
|
+
* web's own ports, no private or local host), https only, and the socket
|
|
31
|
+
* resolves through `guardedLookup`, so a name that answers a private address
|
|
32
|
+
* is refused before anything is sent. Five redirects at most.
|
|
33
|
+
*/
|
|
34
|
+
export declare function nodeGet(options?: NodeGetOptions): DownloadGet;
|
|
35
|
+
/** A file pinned by its hash and length. */
|
|
36
|
+
export interface PinnedDownload {
|
|
37
|
+
url: string;
|
|
38
|
+
sha256: string;
|
|
39
|
+
bytes: number;
|
|
40
|
+
}
|
|
41
|
+
/** Why a download was refused or failed, in a sentence for the owner. */
|
|
42
|
+
export declare class DownloadError extends Error {
|
|
43
|
+
constructor(message: string);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A fresh temporary name in `dir`: `.tmp-<random><suffix>`, or
|
|
47
|
+
* `.tmp-<owner>+<random><suffix>` when an owner (a model id) is named, so a
|
|
48
|
+
* sweep for one owner never touches another's download in the same folder.
|
|
49
|
+
* `+` is not a character an id may hold, so `.tmp-a+` never matches `a-b`'s.
|
|
50
|
+
*/
|
|
51
|
+
export declare function tempName(dir: string, suffix?: string, owner?: string): string;
|
|
52
|
+
/** The prefix of an owner's temporaries (`tempName`'s third argument). */
|
|
53
|
+
export declare function tempPrefix(owner?: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Delete every `.tmp-*` entry in `dir` (or only an owner's, `.tmp-<owner>+*`):
|
|
56
|
+
* what a download that died left. `keep` spares the entries a running download
|
|
57
|
+
* owns. Never throws.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sweepTemp(dir: string, owner?: string, keep?: (name: string) => boolean): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Fetch `file.url` into `dest`, checking the length and sha256 as the bytes
|
|
62
|
+
* arrive. On any failure `dest` is deleted and a `DownloadError` thrown; on
|
|
63
|
+
* success `dest` holds exactly the pinned bytes.
|
|
64
|
+
*/
|
|
65
|
+
export declare function downloadVerified(get: DownloadGet, file: PinnedDownload, dest: string, opts?: {
|
|
66
|
+
signal?: AbortSignal;
|
|
67
|
+
onProgress?: (received: number) => void;
|
|
68
|
+
}): Promise<void>;
|
|
69
|
+
/** One entry to keep from a tarball. */
|
|
70
|
+
export interface TarWanted {
|
|
71
|
+
entry: string;
|
|
72
|
+
dest: string;
|
|
73
|
+
sha256: string;
|
|
74
|
+
bytes: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Stream a `.tgz` and write only the wanted entries, each to its `dest`,
|
|
78
|
+
* checking each one's length and sha256. Throws a `DownloadError` naming the
|
|
79
|
+
* first entry that is missing, the wrong size or the wrong hash; the caller
|
|
80
|
+
* deletes the folder the entries went into.
|
|
81
|
+
*/
|
|
82
|
+
export declare function extractVerified(tgz: string, wanted: readonly TarWanted[]): Promise<void>;
|
|
83
|
+
/** The sha256 of a file on disk, streamed. */
|
|
84
|
+
export declare function sha256OfFile(file: string): Promise<string>;
|
|
85
|
+
/** The longest failure reason kept, logged or shown. */
|
|
86
|
+
export declare const REASON_MAX = 300;
|
|
87
|
+
/**
|
|
88
|
+
* A failure reason safe to log, keep on disk and show in Settings: every
|
|
89
|
+
* stored secret scrubbed, every URL cut to its host (no credentials, path or
|
|
90
|
+
* query, where a signed link keeps its key), one line, at most 300 characters.
|
|
91
|
+
*/
|
|
92
|
+
export declare function safeReason(text: string): string;
|
|
93
|
+
/** Bytes as the owner reads them: `114 MB`, `850 KB`, `1.2 GB`. */
|
|
94
|
+
export declare function formatDownloadSize(bytes: number): string;
|
|
95
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/runtimes/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downloading what buddi runs locally — the ONNX engine and shared models —
|
|
3
|
+
* with one set of safety rules (docs/plugin-host-api.md §4.2 `onnx`, 1.32):
|
|
4
|
+
*
|
|
5
|
+
* - Everything is written under a `.tmp-*` name in the folder it will end up
|
|
6
|
+
* in, so the final move is a same-filesystem `rename`, atomic.
|
|
7
|
+
* - The sha256 and the length are checked against the pin while the bytes
|
|
8
|
+
* arrive; a mismatch deletes the temporary file and nothing is moved.
|
|
9
|
+
* - A download that dies half-way deletes what it wrote; one from a process
|
|
10
|
+
* that died is swept by the next download into that folder.
|
|
11
|
+
* - Nothing downloaded is opened, executed or loaded before its hash matched.
|
|
12
|
+
*
|
|
13
|
+
* The tarball reader is the smallest that reads an npm tarball (ustar, with
|
|
14
|
+
* pax and GNU long names): it streams through gunzip and writes only the
|
|
15
|
+
* entries asked for, hashing each as it goes.
|
|
16
|
+
*/
|
|
17
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
18
|
+
import { createReadStream } from 'node:fs';
|
|
19
|
+
import { open, readdir, rm } from 'node:fs/promises';
|
|
20
|
+
import { request as httpsRequest } from 'node:https';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { createGunzip } from 'node:zlib';
|
|
23
|
+
import { guardedLookup } from '../host/http.js';
|
|
24
|
+
import { DEFAULT_POLICY, checkUrl } from '../plugin/url.js';
|
|
25
|
+
import { scrubText } from '../secrets/scrub.js';
|
|
26
|
+
/** The most redirects one download follows. */
|
|
27
|
+
export const DOWNLOAD_MAX_REDIRECTS = 5;
|
|
28
|
+
/**
|
|
29
|
+
* GET over `node:https`, one connection per request and no pool (the reason
|
|
30
|
+
* the shared transport exists; it buffers whole answers, and an engine is a
|
|
31
|
+
* hundred megabytes). The same guards as the shared transport: every URL —
|
|
32
|
+
* the first and every redirect — goes through `checkUrl` (no credentials, the
|
|
33
|
+
* web's own ports, no private or local host), https only, and the socket
|
|
34
|
+
* resolves through `guardedLookup`, so a name that answers a private address
|
|
35
|
+
* is refused before anything is sent. Five redirects at most.
|
|
36
|
+
*/
|
|
37
|
+
export function nodeGet(options = {}) {
|
|
38
|
+
const request = options.request ?? httpsRequest;
|
|
39
|
+
const rewrite = options.rewrite ?? ((url) => url);
|
|
40
|
+
const policy = options.policy ?? DEFAULT_POLICY;
|
|
41
|
+
const lookup = guardedLookup(options.resolve, policy);
|
|
42
|
+
const once = (url, signal) => new Promise((resolve, reject) => {
|
|
43
|
+
const req = request(rewrite(url), { method: 'GET', agent: false, lookup, headers: { 'user-agent': 'buddi', accept: '*/*' }, ...(signal ? { signal } : {}) }, resolve);
|
|
44
|
+
req.setTimeout(60_000, () => req.destroy(new Error('the server went quiet for a minute')));
|
|
45
|
+
req.on('error', reject);
|
|
46
|
+
req.end();
|
|
47
|
+
});
|
|
48
|
+
return async (url, opts = {}) => {
|
|
49
|
+
let current = url;
|
|
50
|
+
for (let hop = 0; hop <= DOWNLOAD_MAX_REDIRECTS; hop += 1) {
|
|
51
|
+
const checked = checkUrl(current, policy);
|
|
52
|
+
if (checked.url.protocol !== 'https:')
|
|
53
|
+
throw new Error(`refusing ${checked.url.host}: downloads are https only`);
|
|
54
|
+
const res = await once(current, opts.signal);
|
|
55
|
+
const status = res.statusCode ?? 0;
|
|
56
|
+
const location = res.headers.location;
|
|
57
|
+
if (status >= 300 && status < 400 && typeof location === 'string') {
|
|
58
|
+
res.resume();
|
|
59
|
+
current = new URL(location, current).toString();
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (status < 200 || status >= 300)
|
|
63
|
+
res.resume();
|
|
64
|
+
return { status, body: res };
|
|
65
|
+
}
|
|
66
|
+
throw new Error('too many redirects');
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Why a download was refused or failed, in a sentence for the owner. */
|
|
70
|
+
export class DownloadError extends Error {
|
|
71
|
+
constructor(message) {
|
|
72
|
+
super(message);
|
|
73
|
+
this.name = 'DownloadError';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A fresh temporary name in `dir`: `.tmp-<random><suffix>`, or
|
|
78
|
+
* `.tmp-<owner>+<random><suffix>` when an owner (a model id) is named, so a
|
|
79
|
+
* sweep for one owner never touches another's download in the same folder.
|
|
80
|
+
* `+` is not a character an id may hold, so `.tmp-a+` never matches `a-b`'s.
|
|
81
|
+
*/
|
|
82
|
+
export function tempName(dir, suffix = '', owner) {
|
|
83
|
+
return path.join(dir, `.tmp-${owner === undefined ? '' : `${owner}+`}${randomBytes(6).toString('hex')}${suffix}`);
|
|
84
|
+
}
|
|
85
|
+
/** The prefix of an owner's temporaries (`tempName`'s third argument). */
|
|
86
|
+
export function tempPrefix(owner) {
|
|
87
|
+
return owner === undefined ? '.tmp-' : `.tmp-${owner}+`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Delete every `.tmp-*` entry in `dir` (or only an owner's, `.tmp-<owner>+*`):
|
|
91
|
+
* what a download that died left. `keep` spares the entries a running download
|
|
92
|
+
* owns. Never throws.
|
|
93
|
+
*/
|
|
94
|
+
export async function sweepTemp(dir, owner, keep = () => false) {
|
|
95
|
+
let names;
|
|
96
|
+
try {
|
|
97
|
+
names = await readdir(dir);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
let swept = 0;
|
|
103
|
+
const prefix = tempPrefix(owner);
|
|
104
|
+
for (const name of names) {
|
|
105
|
+
if (!name.startsWith(prefix) || keep(name))
|
|
106
|
+
continue;
|
|
107
|
+
await rm(path.join(dir, name), { recursive: true, force: true }).catch(() => { });
|
|
108
|
+
swept += 1;
|
|
109
|
+
}
|
|
110
|
+
return swept;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Fetch `file.url` into `dest`, checking the length and sha256 as the bytes
|
|
114
|
+
* arrive. On any failure `dest` is deleted and a `DownloadError` thrown; on
|
|
115
|
+
* success `dest` holds exactly the pinned bytes.
|
|
116
|
+
*/
|
|
117
|
+
export async function downloadVerified(get, file, dest, opts = {}) {
|
|
118
|
+
let handle;
|
|
119
|
+
try {
|
|
120
|
+
let response;
|
|
121
|
+
try {
|
|
122
|
+
response = await get(file.url, opts.signal ? { signal: opts.signal } : {});
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
throw new DownloadError(`Could not reach ${hostOf(file.url)}: ${safeReason(err instanceof Error ? err.message : String(err))}${errorCode(err)}`);
|
|
126
|
+
}
|
|
127
|
+
if (response.status < 200 || response.status >= 300) {
|
|
128
|
+
throw new DownloadError(`${hostOf(file.url)} answered ${response.status} for ${path.posix.basename(new URL(file.url).pathname)}.`);
|
|
129
|
+
}
|
|
130
|
+
handle = await open(dest, 'wx');
|
|
131
|
+
const hash = createHash('sha256');
|
|
132
|
+
let received = 0;
|
|
133
|
+
try {
|
|
134
|
+
for await (const chunk of response.body) {
|
|
135
|
+
received += chunk.byteLength;
|
|
136
|
+
if (received > file.bytes) {
|
|
137
|
+
throw new DownloadError(`${path.posix.basename(new URL(file.url).pathname)} is larger than the ${file.bytes} bytes pinned for it.`);
|
|
138
|
+
}
|
|
139
|
+
hash.update(chunk);
|
|
140
|
+
await handle.write(chunk);
|
|
141
|
+
opts.onProgress?.(received);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
if (err instanceof DownloadError)
|
|
146
|
+
throw err;
|
|
147
|
+
throw new DownloadError(`The download from ${hostOf(file.url)} broke off after ${received} bytes: ${safeReason(err instanceof Error ? err.message : String(err))}${errorCode(err)}`);
|
|
148
|
+
}
|
|
149
|
+
if (received !== file.bytes) {
|
|
150
|
+
throw new DownloadError(`The download from ${hostOf(file.url)} ended after ${received} of ${file.bytes} bytes.`);
|
|
151
|
+
}
|
|
152
|
+
const digest = hash.digest('hex');
|
|
153
|
+
if (digest !== file.sha256.toLowerCase()) {
|
|
154
|
+
throw new DownloadError(`The file from ${hostOf(file.url)} does not match its pinned checksum (sha256 ${digest.slice(0, 12)}…, expected ${file.sha256.slice(0, 12)}…).`);
|
|
155
|
+
}
|
|
156
|
+
await handle.close();
|
|
157
|
+
handle = undefined;
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
await handle?.close().catch(() => { });
|
|
161
|
+
await rm(dest, { force: true }).catch(() => { });
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Stream a `.tgz` and write only the wanted entries, each to its `dest`,
|
|
167
|
+
* checking each one's length and sha256. Throws a `DownloadError` naming the
|
|
168
|
+
* first entry that is missing, the wrong size or the wrong hash; the caller
|
|
169
|
+
* deletes the folder the entries went into.
|
|
170
|
+
*/
|
|
171
|
+
export async function extractVerified(tgz, wanted) {
|
|
172
|
+
const byEntry = new Map(wanted.map((w) => [w.entry, w]));
|
|
173
|
+
const done = new Set();
|
|
174
|
+
let pending = Buffer.alloc(0);
|
|
175
|
+
// The entry being read: how much of its body is left, the padding after it,
|
|
176
|
+
// and where its bytes go (a file, a pax/long-name buffer, or nowhere).
|
|
177
|
+
let body = null;
|
|
178
|
+
let nextName;
|
|
179
|
+
let zeros = 0;
|
|
180
|
+
let ended = false;
|
|
181
|
+
const finishEntry = async () => {
|
|
182
|
+
if (body === null)
|
|
183
|
+
return;
|
|
184
|
+
if (body.file) {
|
|
185
|
+
const { handle, hash, want } = body.file;
|
|
186
|
+
await handle.close();
|
|
187
|
+
const digest = hash.digest('hex');
|
|
188
|
+
if (digest !== want.sha256.toLowerCase()) {
|
|
189
|
+
throw new DownloadError(`${want.entry} does not match its pinned checksum.`);
|
|
190
|
+
}
|
|
191
|
+
done.add(want.entry);
|
|
192
|
+
}
|
|
193
|
+
if (body.meta) {
|
|
194
|
+
const text = Buffer.concat(body.meta.parts);
|
|
195
|
+
if (body.meta.kind === 'longname')
|
|
196
|
+
nextName = text.toString('utf8').replace(/\0.*$/s, '');
|
|
197
|
+
else {
|
|
198
|
+
const found = /(?:^|\n)\d+ path=([^\n]*)\n/.exec(text.toString('utf8'));
|
|
199
|
+
if (found)
|
|
200
|
+
nextName = found[1];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const gunzip = createReadStream(tgz).pipe(createGunzip());
|
|
205
|
+
try {
|
|
206
|
+
for await (const chunk of gunzip) {
|
|
207
|
+
if (ended)
|
|
208
|
+
break;
|
|
209
|
+
pending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);
|
|
210
|
+
while (!ended) {
|
|
211
|
+
if (body !== null) {
|
|
212
|
+
if (body.remaining > 0) {
|
|
213
|
+
if (pending.length === 0)
|
|
214
|
+
break;
|
|
215
|
+
const take = Math.min(body.remaining, pending.length);
|
|
216
|
+
const slice = pending.subarray(0, take);
|
|
217
|
+
if (body.file) {
|
|
218
|
+
body.file.hash.update(slice);
|
|
219
|
+
await body.file.handle.write(slice);
|
|
220
|
+
}
|
|
221
|
+
else if (body.meta) {
|
|
222
|
+
body.meta.parts.push(Buffer.from(slice));
|
|
223
|
+
}
|
|
224
|
+
body.remaining -= take;
|
|
225
|
+
pending = pending.subarray(take);
|
|
226
|
+
if (body.remaining > 0)
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
if (pending.length < body.pad)
|
|
230
|
+
break;
|
|
231
|
+
pending = pending.subarray(body.pad);
|
|
232
|
+
await finishEntry();
|
|
233
|
+
body = null;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (pending.length < 512)
|
|
237
|
+
break;
|
|
238
|
+
const header = pending.subarray(0, 512);
|
|
239
|
+
pending = pending.subarray(512);
|
|
240
|
+
if (header.every((byte) => byte === 0)) {
|
|
241
|
+
zeros += 1;
|
|
242
|
+
if (zeros >= 2)
|
|
243
|
+
ended = true;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
zeros = 0;
|
|
247
|
+
const field = (start, length) => header.subarray(start, start + length).toString('utf8').replace(/\0.*$/s, '');
|
|
248
|
+
const size = parseInt(field(124, 12).trim() || '0', 8);
|
|
249
|
+
if (!Number.isFinite(size) || size < 0)
|
|
250
|
+
throw new DownloadError('The tarball has an entry whose size cannot be read.');
|
|
251
|
+
const type = String.fromCharCode(header[156] ?? 0);
|
|
252
|
+
const prefix = field(345, 155);
|
|
253
|
+
const name = nextName ?? (prefix ? `${prefix}/${field(0, 100)}` : field(0, 100));
|
|
254
|
+
const pad = (512 - (size % 512)) % 512;
|
|
255
|
+
if (type === 'x' || type === 'L') {
|
|
256
|
+
body = { remaining: size, pad, meta: { kind: type === 'x' ? 'pax' : 'longname', parts: [] } };
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
nextName = undefined;
|
|
260
|
+
const want = (type === '0' || type === '\0') ? byEntry.get(name) : undefined;
|
|
261
|
+
if (want !== undefined && !done.has(name)) {
|
|
262
|
+
if (size !== want.bytes) {
|
|
263
|
+
throw new DownloadError(`${want.entry} is ${size} bytes, not the ${want.bytes} pinned for it.`);
|
|
264
|
+
}
|
|
265
|
+
const handle = await open(want.dest, 'wx');
|
|
266
|
+
body = { remaining: size, pad, file: { handle, hash: createHash('sha256'), want } };
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
body = { remaining: size, pad };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
if (body?.file)
|
|
276
|
+
await body.file.handle.close().catch(() => { });
|
|
277
|
+
gunzip.destroy();
|
|
278
|
+
if (err instanceof DownloadError)
|
|
279
|
+
throw err;
|
|
280
|
+
throw new DownloadError(`The tarball could not be read: ${err instanceof Error ? err.message : String(err)}`);
|
|
281
|
+
}
|
|
282
|
+
if (body?.file) {
|
|
283
|
+
await body.file.handle.close().catch(() => { });
|
|
284
|
+
throw new DownloadError(`The tarball ended inside ${body.file.want.entry}.`);
|
|
285
|
+
}
|
|
286
|
+
const missing = wanted.find((w) => !done.has(w.entry));
|
|
287
|
+
if (missing)
|
|
288
|
+
throw new DownloadError(`The tarball has no ${missing.entry}.`);
|
|
289
|
+
}
|
|
290
|
+
/** The sha256 of a file on disk, streamed. */
|
|
291
|
+
export async function sha256OfFile(file) {
|
|
292
|
+
const hash = createHash('sha256');
|
|
293
|
+
for await (const chunk of createReadStream(file))
|
|
294
|
+
hash.update(chunk);
|
|
295
|
+
return hash.digest('hex');
|
|
296
|
+
}
|
|
297
|
+
function hostOf(url) {
|
|
298
|
+
try {
|
|
299
|
+
return new URL(url).host || 'the server';
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return 'the server';
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/** ` (ECONNRESET)`: a system error's short code, when it has one. */
|
|
306
|
+
function errorCode(err) {
|
|
307
|
+
const code = err?.code;
|
|
308
|
+
return typeof code === 'string' && /^[A-Z0-9_]{2,32}$/.test(code) && !(err instanceof Error && err.message.includes(code)) ? ` (${code})` : '';
|
|
309
|
+
}
|
|
310
|
+
/** The longest failure reason kept, logged or shown. */
|
|
311
|
+
export const REASON_MAX = 300;
|
|
312
|
+
const URL_IN_TEXT = /\b[a-z][a-z0-9+.-]*:\/\/[^\s"'<>()`]+/gi;
|
|
313
|
+
/**
|
|
314
|
+
* A failure reason safe to log, keep on disk and show in Settings: every
|
|
315
|
+
* stored secret scrubbed, every URL cut to its host (no credentials, path or
|
|
316
|
+
* query, where a signed link keeps its key), one line, at most 300 characters.
|
|
317
|
+
*/
|
|
318
|
+
export function safeReason(text) {
|
|
319
|
+
const scrubbed = scrubText(String(text)).replace(URL_IN_TEXT, (found) => hostOf(found));
|
|
320
|
+
const line = scrubbed.replace(/[\u0000-\u001f\u007f]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
321
|
+
return line.length > REASON_MAX ? `${line.slice(0, REASON_MAX - 1)}…` : line;
|
|
322
|
+
}
|
|
323
|
+
/** Bytes as the owner reads them: `114 MB`, `850 KB`, `1.2 GB`. */
|
|
324
|
+
export function formatDownloadSize(bytes) {
|
|
325
|
+
if (bytes >= 1e9)
|
|
326
|
+
return `${(bytes / 1e9).toFixed(1)} GB`;
|
|
327
|
+
if (bytes >= 1e6)
|
|
328
|
+
return `${Math.round(bytes / 1e6)} MB`;
|
|
329
|
+
if (bytes >= 1e3)
|
|
330
|
+
return `${Math.round(bytes / 1e3)} KB`;
|
|
331
|
+
return `${bytes} bytes`;
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=download.js.map
|