@withbuddi/buddi 0.1.0-pre.45 → 0.1.0-pre.47
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/background.js +157 -1
- package/extension/manifest.json +5 -2
- package/extension/popup.html +4 -0
- package/extension/popup.js +18 -0
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.d.ts +3 -8
- package/node_modules/@buddi/cli/dist/mcp/tools.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.js +22 -4
- package/node_modules/@buddi/cli/dist/mcp/tools.js.map +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/artifacts/orphans.d.ts +6 -4
- package/node_modules/@buddi/core/dist/artifacts/orphans.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/artifacts/orphans.js +10 -3
- package/node_modules/@buddi/core/dist/artifacts/orphans.js.map +1 -1
- package/node_modules/@buddi/core/dist/groups.d.ts +0 -9
- package/node_modules/@buddi/core/dist/groups.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/groups.js +13 -1
- package/node_modules/@buddi/core/dist/groups.js.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/onboarding/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/index.js +1 -0
- package/node_modules/@buddi/core/dist/onboarding/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/pages.d.ts +24 -1
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +61 -1
- package/node_modules/@buddi/core/dist/pages.js.map +1 -1
- package/node_modules/@buddi/core/dist/pending-input.d.ts +13 -2
- package/node_modules/@buddi/core/dist/pending-input.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pending-input.js +57 -12
- package/node_modules/@buddi/core/dist/pending-input.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/system-context.d.ts +6 -0
- package/node_modules/@buddi/core/dist/system-context.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/web-settings.d.ts +8 -0
- package/node_modules/@buddi/core/dist/web-settings.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/web-settings.js +14 -0
- package/node_modules/@buddi/core/dist/web-settings.js.map +1 -1
- package/node_modules/@buddi/core/migrations/078_pending_input_files.sql +8 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js +1 -0
- package/node_modules/@buddi/gateway/dist/browser-host.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/agent-run.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/missions/agent-run.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/agent-run.js +2 -1
- package/node_modules/@buddi/gateway/dist/missions/agent-run.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +4 -2
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.js +2 -0
- package/node_modules/@buddi/gateway/dist/missions/reminders.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts +3 -2
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.js +4 -2
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.d.ts +10 -2
- package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.js +24 -10
- package/node_modules/@buddi/gateway/dist/system-context.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 +19 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts +37 -0
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.js +54 -10
- package/node_modules/@buddi/gateway/dist/web/attention.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/canvas-tabs.d.ts +41 -0
- package/node_modules/@buddi/gateway/dist/web/canvas-tabs.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/canvas-tabs.js +68 -0
- package/node_modules/@buddi/gateway/dist/web/canvas-tabs.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +0 -9
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +33 -19
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts +11 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.js +51 -0
- package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/pages.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/pages.js +10 -1
- package/node_modules/@buddi/gateway/dist/web/pages.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts +0 -4
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +72 -2
- package/node_modules/@buddi/gateway/dist/web/server.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/index.d.ts +1 -0
- package/node_modules/@buddi/runtime/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/index.js +1 -0
- package/node_modules/@buddi/runtime/dist/index.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/language.d.ts +65 -0
- package/node_modules/@buddi/runtime/dist/language.d.ts.map +1 -0
- package/node_modules/@buddi/runtime/dist/language.js +191 -0
- package/node_modules/@buddi/runtime/dist/language.js.map +1 -0
- package/node_modules/@buddi/runtime/dist/loop.d.ts +15 -1
- package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.js +103 -14
- package/node_modules/@buddi/runtime/dist/loop.js.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/extract.d.ts +6 -0
- package/node_modules/@buddi/tool-artifacts/dist/extract.d.ts.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/extract.js +6 -0
- package/node_modules/@buddi/tool-artifacts/dist/extract.js.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/tools/artifacts.d.ts +1 -0
- package/node_modules/@buddi/tool-artifacts/dist/tools/artifacts.d.ts.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/tools/artifacts.js +30 -8
- package/node_modules/@buddi/tool-artifacts/dist/tools/artifacts.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts +25 -0
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js +25 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/downloads.d.ts +138 -0
- package/node_modules/@buddi/tool-browser/dist/downloads.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/downloads.js +529 -0
- package/node_modules/@buddi/tool-browser/dist/downloads.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts +17 -1
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/driver.js +48 -0
- package/node_modules/@buddi/tool-browser/dist/driver.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts +23 -0
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.js +20 -0
- package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/host.d.ts +3 -1
- package/node_modules/@buddi/tool-browser/dist/host.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/host.js +9 -2
- package/node_modules/@buddi/tool-browser/dist/host.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.d.ts +7 -3
- package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.js +5 -3
- package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.d.ts +28 -0
- package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.js +58 -1
- package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts +8 -0
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/settings.js +9 -0
- package/node_modules/@buddi/tool-browser/dist/settings.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.d.ts +31 -24
- package/node_modules/@buddi/tool-browser/dist/types.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.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/express-rate-limit/dist/index.cjs +9 -7
- package/node_modules/express-rate-limit/dist/index.mjs +9 -7
- package/node_modules/express-rate-limit/package.json +9 -9
- package/node_modules/nanoid/README.md +3 -3
- package/node_modules/nanoid/index.browser.js +4 -5
- package/node_modules/nanoid/index.d.ts +3 -3
- package/node_modules/nanoid/index.js +2 -3
- package/node_modules/nanoid/nanoid.js +1 -1
- package/node_modules/nanoid/package.json +2 -2
- package/node_modules/nanoid/url-alphabet/index.js +1 -1
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/mcp/tools.d.ts +3 -8
- package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
- package/packages/cli/dist/mcp/tools.js +22 -4
- package/packages/cli/dist/mcp/tools.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/artifacts/orphans.d.ts +6 -4
- package/packages/core/dist/artifacts/orphans.d.ts.map +1 -1
- package/packages/core/dist/artifacts/orphans.js +10 -3
- package/packages/core/dist/artifacts/orphans.js.map +1 -1
- package/packages/core/dist/groups.d.ts +0 -9
- package/packages/core/dist/groups.d.ts.map +1 -1
- package/packages/core/dist/groups.js +13 -1
- package/packages/core/dist/groups.js.map +1 -1
- package/packages/core/dist/onboarding/index.d.ts +1 -0
- package/packages/core/dist/onboarding/index.d.ts.map +1 -1
- package/packages/core/dist/onboarding/index.js +1 -0
- package/packages/core/dist/onboarding/index.js.map +1 -1
- package/packages/core/dist/pages.d.ts +24 -1
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +61 -1
- package/packages/core/dist/pages.js.map +1 -1
- package/packages/core/dist/pending-input.d.ts +13 -2
- package/packages/core/dist/pending-input.d.ts.map +1 -1
- package/packages/core/dist/pending-input.js +57 -12
- package/packages/core/dist/pending-input.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/system-context.d.ts +6 -0
- package/packages/core/dist/system-context.d.ts.map +1 -1
- package/packages/core/dist/web-settings.d.ts +8 -0
- package/packages/core/dist/web-settings.d.ts.map +1 -1
- package/packages/core/dist/web-settings.js +14 -0
- package/packages/core/dist/web-settings.js.map +1 -1
- package/packages/core/migrations/078_pending_input_files.sql +8 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/browser-host.d.ts.map +1 -1
- package/packages/gateway/dist/browser-host.js +1 -0
- package/packages/gateway/dist/browser-host.js.map +1 -1
- package/packages/gateway/dist/missions/agent-run.d.ts +6 -0
- package/packages/gateway/dist/missions/agent-run.d.ts.map +1 -1
- package/packages/gateway/dist/missions/agent-run.js +2 -1
- package/packages/gateway/dist/missions/agent-run.js.map +1 -1
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +4 -2
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/reminders.d.ts +1 -0
- package/packages/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/packages/gateway/dist/missions/reminders.js +2 -0
- package/packages/gateway/dist/missions/reminders.js.map +1 -1
- package/packages/gateway/dist/owner-profile-edit.d.ts +3 -2
- package/packages/gateway/dist/owner-profile-edit.d.ts.map +1 -1
- package/packages/gateway/dist/owner-profile-edit.js +4 -2
- package/packages/gateway/dist/owner-profile-edit.js.map +1 -1
- package/packages/gateway/dist/serve.js +1 -1
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/system-context.d.ts +10 -2
- package/packages/gateway/dist/system-context.d.ts.map +1 -1
- package/packages/gateway/dist/system-context.js +24 -10
- package/packages/gateway/dist/system-context.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +19 -1
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/attention.d.ts +37 -0
- package/packages/gateway/dist/web/attention.d.ts.map +1 -1
- package/packages/gateway/dist/web/attention.js +54 -10
- package/packages/gateway/dist/web/attention.js.map +1 -1
- package/packages/gateway/dist/web/canvas-tabs.d.ts +41 -0
- package/packages/gateway/dist/web/canvas-tabs.d.ts.map +1 -0
- package/packages/gateway/dist/web/canvas-tabs.js +68 -0
- package/packages/gateway/dist/web/canvas-tabs.js.map +1 -0
- package/packages/gateway/dist/web/chat.d.ts +0 -9
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +33 -19
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/extension.d.ts +11 -1
- package/packages/gateway/dist/web/extension.d.ts.map +1 -1
- package/packages/gateway/dist/web/extension.js +51 -0
- package/packages/gateway/dist/web/extension.js.map +1 -1
- package/packages/gateway/dist/web/pages.d.ts.map +1 -1
- package/packages/gateway/dist/web/pages.js +10 -1
- package/packages/gateway/dist/web/pages.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts +0 -4
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +72 -2
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/index.d.ts +1 -0
- package/packages/runtime/dist/index.d.ts.map +1 -1
- package/packages/runtime/dist/index.js +1 -0
- package/packages/runtime/dist/index.js.map +1 -1
- package/packages/runtime/dist/language.d.ts +65 -0
- package/packages/runtime/dist/language.d.ts.map +1 -0
- package/packages/runtime/dist/language.js +191 -0
- package/packages/runtime/dist/language.js.map +1 -0
- package/packages/runtime/dist/loop.d.ts +15 -1
- package/packages/runtime/dist/loop.d.ts.map +1 -1
- package/packages/runtime/dist/loop.js +103 -14
- package/packages/runtime/dist/loop.js.map +1 -1
- package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
- package/packages/tools/artifacts/dist/extract.d.ts +6 -0
- package/packages/tools/artifacts/dist/extract.d.ts.map +1 -1
- package/packages/tools/artifacts/dist/extract.js +6 -0
- package/packages/tools/artifacts/dist/extract.js.map +1 -1
- package/packages/tools/artifacts/dist/tools/artifacts.d.ts +1 -0
- package/packages/tools/artifacts/dist/tools/artifacts.d.ts.map +1 -1
- package/packages/tools/artifacts/dist/tools/artifacts.js +30 -8
- package/packages/tools/artifacts/dist/tools/artifacts.js.map +1 -1
- package/packages/tools/browser/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/controller.d.ts +25 -0
- package/packages/tools/browser/dist/controller.d.ts.map +1 -1
- package/packages/tools/browser/dist/controller.js +25 -1
- package/packages/tools/browser/dist/controller.js.map +1 -1
- package/packages/tools/browser/dist/downloads.d.ts +138 -0
- package/packages/tools/browser/dist/downloads.d.ts.map +1 -0
- package/packages/tools/browser/dist/downloads.js +529 -0
- package/packages/tools/browser/dist/downloads.js.map +1 -0
- package/packages/tools/browser/dist/driver.d.ts +17 -1
- package/packages/tools/browser/dist/driver.d.ts.map +1 -1
- package/packages/tools/browser/dist/driver.js +48 -0
- package/packages/tools/browser/dist/driver.js.map +1 -1
- package/packages/tools/browser/dist/extension.d.ts +23 -0
- package/packages/tools/browser/dist/extension.d.ts.map +1 -1
- package/packages/tools/browser/dist/extension.js +20 -0
- package/packages/tools/browser/dist/extension.js.map +1 -1
- package/packages/tools/browser/dist/host.d.ts +3 -1
- package/packages/tools/browser/dist/host.d.ts.map +1 -1
- package/packages/tools/browser/dist/host.js +9 -2
- package/packages/tools/browser/dist/host.js.map +1 -1
- package/packages/tools/browser/dist/index.d.ts +7 -3
- package/packages/tools/browser/dist/index.d.ts.map +1 -1
- package/packages/tools/browser/dist/index.js +5 -3
- package/packages/tools/browser/dist/index.js.map +1 -1
- package/packages/tools/browser/dist/service.d.ts +28 -0
- package/packages/tools/browser/dist/service.d.ts.map +1 -1
- package/packages/tools/browser/dist/service.js +58 -1
- package/packages/tools/browser/dist/service.js.map +1 -1
- package/packages/tools/browser/dist/settings.d.ts +8 -0
- package/packages/tools/browser/dist/settings.d.ts.map +1 -1
- package/packages/tools/browser/dist/settings.js +9 -0
- package/packages/tools/browser/dist/settings.js.map +1 -1
- package/packages/tools/browser/dist/types.d.ts +31 -24
- package/packages/tools/browser/dist/types.d.ts.map +1 -1
- package/packages/tools/browser/dist/types.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-Bxcetnpt.js +150 -0
- package/packages/web/dist/assets/index-CkzsX0YQ.css +1 -0
- package/packages/web/dist/assets/{lottie_light-DxWeiVDC.js → lottie_light-CM_Bp6rc.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 +4 -4
- package/packages/web/dist/assets/index-CPFSREcP.css +0 -1
- package/packages/web/dist/assets/index-DYUn1V0x.js +0 -150
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agents' downloads area (docs/browser.md, "Downloads").
|
|
3
|
+
*
|
|
4
|
+
* A file a page hands an agent — the bank's transactions CSV, a statement PDF —
|
|
5
|
+
* lands here first, under `<data>/downloads/<agent>/<yyyy-mm-dd>/`, and the
|
|
6
|
+
* browser service then registers it in Files so the agent can pass its id to a
|
|
7
|
+
* plugin's import tool, and removes it from here: Files holds the one kept copy.
|
|
8
|
+
* What stays is only what failed to register; that is swept after thirty days,
|
|
9
|
+
* and the owner can clear it from Settings → Browser.
|
|
10
|
+
*
|
|
11
|
+
* Three rules hold for every file: it is never executable (written 0600, the
|
|
12
|
+
* exec bit never set), no single file is larger than the per-file cap, and no
|
|
13
|
+
* agent keeps more than its cap here. A download that would break one is
|
|
14
|
+
* refused with a sentence the agent can repeat, and nothing partial is left.
|
|
15
|
+
*/
|
|
16
|
+
import { constants } from 'node:fs';
|
|
17
|
+
import { chmod, lstat, mkdir, open, readdir, realpath, rm, stat, unlink } from 'node:fs/promises';
|
|
18
|
+
import os from 'node:os';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
export const DOWNLOAD_FILE_CAP = 50 * 1024 * 1024;
|
|
21
|
+
export const DOWNLOAD_AGENT_CAP = 500 * 1024 * 1024;
|
|
22
|
+
export const DOWNLOAD_RETENTION_DAYS = 30;
|
|
23
|
+
/** A finished file in the owner's own Downloads folder counts only this soon after it was written. */
|
|
24
|
+
export const OWNER_FILE_FRESH_MS = 15 * 60 * 1000;
|
|
25
|
+
/** How long buddi's browser may take over one download before it is stopped. */
|
|
26
|
+
export const DOWNLOAD_TIMEOUT_MS = 5 * 60 * 1000;
|
|
27
|
+
/** How often a transfer's partial file is measured against the cap. */
|
|
28
|
+
export const DOWNLOAD_POLL_MS = 250;
|
|
29
|
+
/** Refused on purpose: a cap, an empty file, a file that is not the one reported. The message is the agent's. */
|
|
30
|
+
export class DownloadRefused extends Error {
|
|
31
|
+
}
|
|
32
|
+
const MIME_BY_EXT = {
|
|
33
|
+
csv: 'text/csv', tsv: 'text/tab-separated-values', txt: 'text/plain', json: 'application/json', xml: 'application/xml',
|
|
34
|
+
pdf: 'application/pdf', ofx: 'application/x-ofx', qfx: 'application/x-ofx', qif: 'application/qif',
|
|
35
|
+
xls: 'application/vnd.ms-excel', xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
36
|
+
doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
37
|
+
zip: 'application/zip', png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp',
|
|
38
|
+
};
|
|
39
|
+
/** The type a download is filed under: what the server said when it said something useful, else the extension's. */
|
|
40
|
+
export function downloadMime(filename, reported) {
|
|
41
|
+
const given = reported?.split(';')[0]?.trim().toLowerCase();
|
|
42
|
+
if (given && given !== 'application/octet-stream' && /^[a-z]+\/[a-z0-9.+-]+$/.test(given))
|
|
43
|
+
return given;
|
|
44
|
+
const ext = path.extname(filename).slice(1).toLowerCase();
|
|
45
|
+
return MIME_BY_EXT[ext] ?? 'application/octet-stream';
|
|
46
|
+
}
|
|
47
|
+
/** A name that is a name: no folders, no control characters, no leading dot, at most 120 characters. */
|
|
48
|
+
export function downloadName(raw) {
|
|
49
|
+
const base = (raw.split(/[\\/]/).pop() ?? '')
|
|
50
|
+
.replace(/[\u0000-\u001f\u007f]/g, '')
|
|
51
|
+
.replace(/[<>:"|?*]/g, '_')
|
|
52
|
+
.replace(/^[.\s]+/, '')
|
|
53
|
+
.trim();
|
|
54
|
+
if (base === '')
|
|
55
|
+
return 'download';
|
|
56
|
+
if (base.length <= 120)
|
|
57
|
+
return base;
|
|
58
|
+
const ext = path.extname(base).slice(0, 12);
|
|
59
|
+
return `${base.slice(0, 120 - ext.length)}${ext}`;
|
|
60
|
+
}
|
|
61
|
+
/** An agent id as a folder name. */
|
|
62
|
+
function agentFolder(agent) {
|
|
63
|
+
return agent.replace(/[^A-Za-z0-9_-]/g, '_').slice(0, 80) || 'agent';
|
|
64
|
+
}
|
|
65
|
+
function kb(bytes) {
|
|
66
|
+
return bytes >= 1024 * 1024 ? `${Math.round(bytes / (1024 * 1024))} MB` : `${Math.max(1, Math.round(bytes / 1024))} KB`;
|
|
67
|
+
}
|
|
68
|
+
/** The address a download came from, for its Files row: origin and path, never the query (signed URLs carry tokens there). */
|
|
69
|
+
export function downloadSource(url) {
|
|
70
|
+
try {
|
|
71
|
+
const parsed = new URL(url);
|
|
72
|
+
return `${parsed.origin}${parsed.pathname}`.slice(0, 2048);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return url.split(/[?#]/)[0].slice(0, 2048);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const DAY = /^\d{4}-\d{2}-\d{2}$/;
|
|
79
|
+
/** `child` is `parent` or inside it (both already resolved). */
|
|
80
|
+
function inside(child, parent) {
|
|
81
|
+
const rel = path.relative(parent, child);
|
|
82
|
+
return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
|
|
83
|
+
}
|
|
84
|
+
/** The resolved path when it exists, else the lexical one. */
|
|
85
|
+
async function resolvedOr(file) {
|
|
86
|
+
try {
|
|
87
|
+
return await realpath(file);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return path.resolve(file);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Watch one transfer in buddi's own browser: stop it the moment its partial
|
|
95
|
+
* file passes the cap, or when it runs past the timeout, so a huge or endless
|
|
96
|
+
* response never fills the disk before the size check. The outcome is what
|
|
97
|
+
* `PendingDownload.failure` hands the store.
|
|
98
|
+
*/
|
|
99
|
+
export function watchTransfer(options) {
|
|
100
|
+
const cap = options.cap ?? DOWNLOAD_FILE_CAP;
|
|
101
|
+
const timeoutMs = options.timeoutMs ?? DOWNLOAD_TIMEOUT_MS;
|
|
102
|
+
const outcome = new Promise((resolve, reject) => {
|
|
103
|
+
let settled = false;
|
|
104
|
+
const finish = (settle) => {
|
|
105
|
+
if (settled)
|
|
106
|
+
return;
|
|
107
|
+
settled = true;
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
clearInterval(poll);
|
|
110
|
+
settle();
|
|
111
|
+
};
|
|
112
|
+
const stop = (message) => finish(() => { void options.cancel().catch(() => undefined); reject(new DownloadRefused(message)); });
|
|
113
|
+
const timer = setTimeout(() => stop(`It was still downloading after ${Math.max(1, Math.round(timeoutMs / 60_000))} minutes, so it was stopped.`), timeoutMs);
|
|
114
|
+
const poll = setInterval(() => {
|
|
115
|
+
void options.size().then((bytes) => {
|
|
116
|
+
if (bytes !== undefined && bytes > cap)
|
|
117
|
+
stop(`That download is larger than ${kb(cap)}, the most agents may download per file.`);
|
|
118
|
+
}, () => undefined);
|
|
119
|
+
}, options.pollMs ?? DOWNLOAD_POLL_MS);
|
|
120
|
+
timer.unref?.();
|
|
121
|
+
poll.unref?.();
|
|
122
|
+
options.done.then((reason) => finish(() => resolve(reason)), (error) => finish(() => resolve(error instanceof Error ? error.message : String(error))));
|
|
123
|
+
});
|
|
124
|
+
// Nobody may ask before it settles (the action ended first): never an unhandled rejection.
|
|
125
|
+
outcome.catch(() => undefined);
|
|
126
|
+
return outcome;
|
|
127
|
+
}
|
|
128
|
+
export class DownloadStore {
|
|
129
|
+
root;
|
|
130
|
+
fileCap;
|
|
131
|
+
agentCap;
|
|
132
|
+
retentionDays;
|
|
133
|
+
#now;
|
|
134
|
+
#home;
|
|
135
|
+
#chromeFolder;
|
|
136
|
+
#dataDir;
|
|
137
|
+
constructor(root, options = {}) {
|
|
138
|
+
this.root = root;
|
|
139
|
+
this.fileCap = options.fileCap ?? DOWNLOAD_FILE_CAP;
|
|
140
|
+
this.agentCap = options.agentCap ?? DOWNLOAD_AGENT_CAP;
|
|
141
|
+
this.retentionDays = options.retentionDays ?? DOWNLOAD_RETENTION_DAYS;
|
|
142
|
+
this.#now = options.now ?? Date.now;
|
|
143
|
+
this.#home = options.homeDir ?? os.homedir();
|
|
144
|
+
this.#chromeFolder = options.chromeFolder ?? (() => undefined);
|
|
145
|
+
this.#dataDir = options.dataDir;
|
|
146
|
+
}
|
|
147
|
+
/** The folder the owner's Chrome saves to: the setting, `~` expanded, else `~/Downloads`. */
|
|
148
|
+
chromeFolder() {
|
|
149
|
+
const set = this.#chromeFolder()?.trim();
|
|
150
|
+
if (!set)
|
|
151
|
+
return path.join(this.#home, 'Downloads');
|
|
152
|
+
if (set === '~' || set.startsWith('~/'))
|
|
153
|
+
return path.join(this.#home, set.slice(1));
|
|
154
|
+
return path.resolve(set);
|
|
155
|
+
}
|
|
156
|
+
async #tally(dir) {
|
|
157
|
+
let bytes = 0;
|
|
158
|
+
let files = 0;
|
|
159
|
+
let entries;
|
|
160
|
+
try {
|
|
161
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { bytes, files };
|
|
165
|
+
}
|
|
166
|
+
for (const entry of entries) {
|
|
167
|
+
const full = path.join(dir, entry.name);
|
|
168
|
+
if (entry.isDirectory()) {
|
|
169
|
+
const inner = await this.#tally(full);
|
|
170
|
+
bytes += inner.bytes;
|
|
171
|
+
files += inner.files;
|
|
172
|
+
}
|
|
173
|
+
else if (entry.isFile()) {
|
|
174
|
+
try {
|
|
175
|
+
bytes += (await stat(full)).size;
|
|
176
|
+
files += 1;
|
|
177
|
+
}
|
|
178
|
+
catch { /* gone meanwhile */ }
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return { bytes, files };
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The finished file a Chrome download left, read only when it plainly is
|
|
185
|
+
* that file: its complete path resolved (no symlinked folder can lead out),
|
|
186
|
+
* inside the folder Chrome saves to, under no dot-directory and not in
|
|
187
|
+
* buddi's data dir, a plain file written in the last minutes with the size
|
|
188
|
+
* Chrome said. It is opened once, then checked and read through that one
|
|
189
|
+
* descriptor, so nothing swapped in after the check is what gets read.
|
|
190
|
+
*/
|
|
191
|
+
async #ownerFile(file, reported) {
|
|
192
|
+
const folderWord = this.#chromeFolder()?.trim() ? 'your Chrome’s download folder' : 'your Downloads folder';
|
|
193
|
+
const refuse = () => new DownloadRefused(`That download could not be read from ${folderWord}.`);
|
|
194
|
+
if (!path.isAbsolute(file))
|
|
195
|
+
throw refuse();
|
|
196
|
+
let real;
|
|
197
|
+
let folder;
|
|
198
|
+
try {
|
|
199
|
+
real = await realpath(file);
|
|
200
|
+
folder = await realpath(this.chromeFolder());
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
throw refuse();
|
|
204
|
+
}
|
|
205
|
+
if (real === folder || !inside(real, folder))
|
|
206
|
+
throw refuse();
|
|
207
|
+
for (const kept of [this.root, this.#dataDir])
|
|
208
|
+
if (kept && inside(real, await resolvedOr(kept)))
|
|
209
|
+
throw refuse();
|
|
210
|
+
if (path.dirname(real).split(path.sep).some((part) => part.startsWith('.')))
|
|
211
|
+
throw refuse();
|
|
212
|
+
let link = true;
|
|
213
|
+
try {
|
|
214
|
+
link = (await lstat(file)).isSymbolicLink();
|
|
215
|
+
}
|
|
216
|
+
catch { /* refused below */ }
|
|
217
|
+
if (link)
|
|
218
|
+
throw refuse();
|
|
219
|
+
let handle;
|
|
220
|
+
try {
|
|
221
|
+
handle = await open(real, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
throw refuse();
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
const info = await handle.stat();
|
|
228
|
+
if (!info.isFile())
|
|
229
|
+
throw refuse();
|
|
230
|
+
// The descriptor is still the file at that resolved path: nothing was swapped between the check and the open.
|
|
231
|
+
const again = await realpath(real).catch(() => '');
|
|
232
|
+
const there = again === real ? await stat(real).catch(() => undefined) : undefined;
|
|
233
|
+
if (!there || there.ino !== info.ino || there.dev !== info.dev)
|
|
234
|
+
throw refuse();
|
|
235
|
+
if (Math.abs(this.#now() - info.mtimeMs) > OWNER_FILE_FRESH_MS)
|
|
236
|
+
throw refuse();
|
|
237
|
+
if (reported !== undefined && reported >= 0 && info.size !== reported)
|
|
238
|
+
throw refuse();
|
|
239
|
+
if (info.size > this.fileCap)
|
|
240
|
+
throw new DownloadRefused(`That download is ${kb(info.size)}; agents may download at most ${kb(this.fileCap)} per file.`);
|
|
241
|
+
return handle.createReadStream({ start: 0, autoClose: true });
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
await handle.close().catch(() => undefined);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** Wait for the transfer to end, stopping it when the run is cancelled. */
|
|
249
|
+
async #settle(pending, signal) {
|
|
250
|
+
if (!pending.failure && !signal)
|
|
251
|
+
return;
|
|
252
|
+
let onAbort = () => { };
|
|
253
|
+
const stopped = new Promise((_, reject) => {
|
|
254
|
+
onAbort = () => reject(new DownloadRefused('The run was stopped, so the download was stopped too.'));
|
|
255
|
+
if (signal?.aborted)
|
|
256
|
+
onAbort();
|
|
257
|
+
else
|
|
258
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
259
|
+
});
|
|
260
|
+
stopped.catch(() => undefined);
|
|
261
|
+
try {
|
|
262
|
+
const failure = await Promise.race([pending.failure?.() ?? Promise.resolve(null), stopped]).catch((error) => {
|
|
263
|
+
if (error instanceof DownloadRefused)
|
|
264
|
+
throw error;
|
|
265
|
+
return null;
|
|
266
|
+
});
|
|
267
|
+
if (failure)
|
|
268
|
+
throw new DownloadRefused(`The download did not finish: ${failure}.`);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
if (signal?.aborted)
|
|
272
|
+
await pending.cancel?.().catch(() => undefined);
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
finally {
|
|
276
|
+
signal?.removeEventListener('abort', onAbort);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/** Copy one download into the agent's area for today. Refuses, and leaves nothing behind, when a cap is hit. */
|
|
280
|
+
async save(agent, pending, options = {}) {
|
|
281
|
+
await this.#settle(pending, options.signal);
|
|
282
|
+
if (pending.size !== undefined && pending.size > this.fileCap) {
|
|
283
|
+
throw new DownloadRefused(`That download is ${kb(pending.size)}; agents may download at most ${kb(this.fileCap)} per file.`);
|
|
284
|
+
}
|
|
285
|
+
const agentDir = path.join(this.root, agentFolder(agent));
|
|
286
|
+
const used = (await this.#tally(agentDir)).bytes;
|
|
287
|
+
const room = this.agentCap - used;
|
|
288
|
+
if (room <= 0 || (pending.size !== undefined && pending.size > room)) {
|
|
289
|
+
throw new DownloadRefused(`This agent's downloads area is full (${kb(used)} of ${kb(this.agentCap)}). The owner can clear it in Settings → Browser.`);
|
|
290
|
+
}
|
|
291
|
+
const limit = Math.min(this.fileCap, room);
|
|
292
|
+
const source = 'path' in pending.read ? await this.#ownerFile(pending.read.path, pending.size) : await pending.read.stream();
|
|
293
|
+
if (!source)
|
|
294
|
+
throw new DownloadRefused('The download did not finish.');
|
|
295
|
+
const day = new Date(this.#now()).toISOString().slice(0, 10);
|
|
296
|
+
const dir = path.join(agentDir, day);
|
|
297
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
298
|
+
const name = downloadName(pending.filename);
|
|
299
|
+
const ext = path.extname(name);
|
|
300
|
+
const stem = name.slice(0, name.length - ext.length);
|
|
301
|
+
let target = '';
|
|
302
|
+
let handle;
|
|
303
|
+
for (let n = 1; n < 1000 && !handle; n++) {
|
|
304
|
+
target = path.join(dir, n === 1 ? name : `${stem} (${n})${ext}`);
|
|
305
|
+
try {
|
|
306
|
+
handle = await open(target, 'wx', 0o600);
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
if (error.code !== 'EEXIST')
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (!handle)
|
|
314
|
+
throw new DownloadRefused('Too many downloads with that name today.');
|
|
315
|
+
let size = 0;
|
|
316
|
+
let over = false;
|
|
317
|
+
try {
|
|
318
|
+
for await (const chunk of source) {
|
|
319
|
+
const buffer = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
|
|
320
|
+
size += buffer.length;
|
|
321
|
+
if (size > limit) {
|
|
322
|
+
over = true;
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
await handle.write(buffer);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
await handle.close().catch(() => undefined);
|
|
330
|
+
await unlink(target).catch(() => undefined);
|
|
331
|
+
throw error;
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
if (over)
|
|
335
|
+
source.destroy?.();
|
|
336
|
+
}
|
|
337
|
+
await handle.close();
|
|
338
|
+
if (over || size === 0) {
|
|
339
|
+
await unlink(target).catch(() => undefined);
|
|
340
|
+
if (size === 0)
|
|
341
|
+
throw new DownloadRefused('The download was empty.');
|
|
342
|
+
throw limit === this.fileCap
|
|
343
|
+
? new DownloadRefused(`That download is larger than ${kb(this.fileCap)}, the most agents may download per file.`)
|
|
344
|
+
: new DownloadRefused(`This agent's downloads area is full (${kb(used)} of ${kb(this.agentCap)}). The owner can clear it in Settings → Browser.`);
|
|
345
|
+
}
|
|
346
|
+
// Never executable, whatever the umask or the server said.
|
|
347
|
+
await chmod(target, 0o600);
|
|
348
|
+
const filename = path.basename(target);
|
|
349
|
+
return { path: target, filename, size, mime: downloadMime(filename, pending.mime), url: pending.url, agent };
|
|
350
|
+
}
|
|
351
|
+
/** The files waiting, newest day first. */
|
|
352
|
+
async waiting() {
|
|
353
|
+
const found = [];
|
|
354
|
+
let agents = [];
|
|
355
|
+
try {
|
|
356
|
+
agents = await readdir(this.root, { withFileTypes: true });
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return found;
|
|
360
|
+
}
|
|
361
|
+
for (const agent of agents) {
|
|
362
|
+
if (!agent.isDirectory())
|
|
363
|
+
continue;
|
|
364
|
+
let days = [];
|
|
365
|
+
try {
|
|
366
|
+
days = await readdir(path.join(this.root, agent.name), { withFileTypes: true });
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
for (const day of days) {
|
|
372
|
+
if (!day.isDirectory() || !DAY.test(day.name))
|
|
373
|
+
continue;
|
|
374
|
+
let names = [];
|
|
375
|
+
try {
|
|
376
|
+
names = await readdir(path.join(this.root, agent.name, day.name), { withFileTypes: true });
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
for (const entry of names) {
|
|
382
|
+
if (!entry.isFile())
|
|
383
|
+
continue;
|
|
384
|
+
let size = 0;
|
|
385
|
+
try {
|
|
386
|
+
size = (await stat(path.join(this.root, agent.name, day.name, entry.name))).size;
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
found.push({ id: `${agent.name}/${day.name}/${entry.name}`, agent: agent.name, day: day.name, name: entry.name, size, mime: downloadMime(entry.name) });
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return found.sort((a, b) => b.day.localeCompare(a.day) || a.agent.localeCompare(b.agent) || a.name.localeCompare(b.name));
|
|
396
|
+
}
|
|
397
|
+
/** The file behind a waiting id, or a refusal when the id is not one of the area's files. */
|
|
398
|
+
async #waitingFile(id) {
|
|
399
|
+
const parts = typeof id === 'string' ? id.split('/') : [];
|
|
400
|
+
const [agent, day, name] = parts;
|
|
401
|
+
if (parts.length !== 3 || !agent || !day || !name || agentFolder(agent) !== agent || !DAY.test(day) || name !== downloadName(name)) {
|
|
402
|
+
throw new DownloadRefused('That file is not in the downloads area.');
|
|
403
|
+
}
|
|
404
|
+
const file = path.join(this.root, agent, day, name);
|
|
405
|
+
let info;
|
|
406
|
+
try {
|
|
407
|
+
info = await lstat(file);
|
|
408
|
+
}
|
|
409
|
+
catch { /* below */ }
|
|
410
|
+
if (!info?.isFile())
|
|
411
|
+
throw new DownloadRefused('That file is no longer in the downloads area.');
|
|
412
|
+
return { path: file, agent, day, name };
|
|
413
|
+
}
|
|
414
|
+
/** Read one waiting file, to file it again. */
|
|
415
|
+
async readWaiting(id) {
|
|
416
|
+
const found = await this.#waitingFile(id);
|
|
417
|
+
const handle = await open(found.path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
418
|
+
try {
|
|
419
|
+
return { bytes: await handle.readFile(), agent: found.agent, name: found.name, mime: downloadMime(found.name) };
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
await handle.close();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/** Remove one waiting file (it was filed), and its day and agent folders once empty. */
|
|
426
|
+
async removeWaiting(id) {
|
|
427
|
+
const found = await this.#waitingFile(id);
|
|
428
|
+
await unlink(found.path);
|
|
429
|
+
const dayDir = path.dirname(found.path);
|
|
430
|
+
try {
|
|
431
|
+
if ((await readdir(dayDir)).length === 0)
|
|
432
|
+
await rm(dayDir, { recursive: true, force: true });
|
|
433
|
+
}
|
|
434
|
+
catch { /* fine */ }
|
|
435
|
+
const agentDir = path.dirname(dayDir);
|
|
436
|
+
try {
|
|
437
|
+
if ((await readdir(agentDir)).length === 0)
|
|
438
|
+
await rm(agentDir, { recursive: true, force: true });
|
|
439
|
+
}
|
|
440
|
+
catch { /* fine */ }
|
|
441
|
+
}
|
|
442
|
+
/** What the area holds, by agent. */
|
|
443
|
+
async usage() {
|
|
444
|
+
const agents = [];
|
|
445
|
+
let entries = [];
|
|
446
|
+
try {
|
|
447
|
+
entries = await readdir(this.root, { withFileTypes: true });
|
|
448
|
+
}
|
|
449
|
+
catch { /* nothing yet */ }
|
|
450
|
+
for (const entry of entries) {
|
|
451
|
+
if (!entry.isDirectory())
|
|
452
|
+
continue;
|
|
453
|
+
const tally = await this.#tally(path.join(this.root, entry.name));
|
|
454
|
+
if (tally.files > 0)
|
|
455
|
+
agents.push({ agent: entry.name, ...tally });
|
|
456
|
+
}
|
|
457
|
+
agents.sort((a, b) => b.bytes - a.bytes);
|
|
458
|
+
return {
|
|
459
|
+
bytes: agents.reduce((sum, a) => sum + a.bytes, 0), files: agents.reduce((sum, a) => sum + a.files, 0), agents,
|
|
460
|
+
fileCap: this.fileCap, agentCap: this.agentCap, retentionDays: this.retentionDays,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/** Empty the area, or one agent's part of it. Files keeps its copies. */
|
|
464
|
+
async clear(agent) {
|
|
465
|
+
if (agent === undefined) {
|
|
466
|
+
let entries = [];
|
|
467
|
+
try {
|
|
468
|
+
entries = await readdir(this.root);
|
|
469
|
+
}
|
|
470
|
+
catch { /* nothing yet */ }
|
|
471
|
+
for (const name of entries)
|
|
472
|
+
await rm(path.join(this.root, name), { recursive: true, force: true });
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
await rm(path.join(this.root, agentFolder(agent)), { recursive: true, force: true });
|
|
476
|
+
}
|
|
477
|
+
return this.usage();
|
|
478
|
+
}
|
|
479
|
+
/** Remove every day older than the retention. Returns how many files went. */
|
|
480
|
+
async sweep() {
|
|
481
|
+
const cutoff = this.#now() - this.retentionDays * 24 * 60 * 60 * 1000;
|
|
482
|
+
let removed = 0;
|
|
483
|
+
let agents = [];
|
|
484
|
+
try {
|
|
485
|
+
agents = await readdir(this.root, { withFileTypes: true });
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
return 0;
|
|
489
|
+
}
|
|
490
|
+
for (const agent of agents) {
|
|
491
|
+
if (!agent.isDirectory())
|
|
492
|
+
continue;
|
|
493
|
+
const agentDir = path.join(this.root, agent.name);
|
|
494
|
+
let days = [];
|
|
495
|
+
try {
|
|
496
|
+
days = await readdir(agentDir, { withFileTypes: true });
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
for (const day of days) {
|
|
502
|
+
const full = path.join(agentDir, day.name);
|
|
503
|
+
// A day folder is dated by its name, the end of that day; anything else by when it was last written.
|
|
504
|
+
let at;
|
|
505
|
+
if (day.isDirectory() && DAY.test(day.name))
|
|
506
|
+
at = Date.parse(`${day.name}T23:59:59.999Z`);
|
|
507
|
+
else {
|
|
508
|
+
try {
|
|
509
|
+
at = (await stat(full)).mtimeMs;
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (!(at < cutoff))
|
|
516
|
+
continue;
|
|
517
|
+
removed += day.isDirectory() ? (await this.#tally(full)).files : 1;
|
|
518
|
+
await rm(full, { recursive: true, force: true });
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
if ((await readdir(agentDir)).length === 0)
|
|
522
|
+
await rm(agentDir, { recursive: true, force: true });
|
|
523
|
+
}
|
|
524
|
+
catch { /* fine */ }
|
|
525
|
+
}
|
|
526
|
+
return removed;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=downloads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"downloads.js","sourceRoot":"","sources":["../src/downloads.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import type { Page } from 'playwright';
|
|
1
|
+
import type { Page, Download } from 'playwright';
|
|
2
|
+
import { type PendingDownload } from './downloads.js';
|
|
2
3
|
import { PlaywrightHost, type DriverOptions, type TabOwner } from './host.js';
|
|
3
4
|
import { type BrowserCommand, type BrowserDriver, type BrowserHand, type Observation, type SeenLoginReport } from './types.js';
|
|
4
5
|
export type { DriverOptions } from './host.js';
|
|
6
|
+
/**
|
|
7
|
+
* Where Chromium writes a Playwright download: `<artifacts>/<guid>`, with
|
|
8
|
+
* `.crdownload` on it while the transfer runs. Playwright keeps the path on
|
|
9
|
+
* the download's artifact and does not publish it, so this reads it
|
|
10
|
+
* defensively: without it only the timeout and the store's own cap hold.
|
|
11
|
+
*/
|
|
12
|
+
export declare function downloadLocalPath(download: Download): string | undefined;
|
|
5
13
|
export declare class PlaywrightDriver implements BrowserDriver, TabOwner {
|
|
6
14
|
#private;
|
|
7
15
|
readonly options: DriverOptions;
|
|
8
16
|
readonly host: PlaywrightHost;
|
|
9
17
|
constructor(options: DriverOptions, host?: PlaywrightHost);
|
|
18
|
+
/**
|
|
19
|
+
* A file one of this conversation's tabs started: read once it finishes,
|
|
20
|
+
* when the service asks. Watched while it runs, and stopped past the
|
|
21
|
+
* per-file cap or the timeout; Chromium's copy is deleted once the service
|
|
22
|
+
* took it or refused it.
|
|
23
|
+
*/
|
|
24
|
+
download(download: Download): void;
|
|
25
|
+
takeDownloads(): PendingDownload[];
|
|
10
26
|
adopt(page: Page): void;
|
|
11
27
|
start(): Promise<void>;
|
|
12
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAsC,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG9E,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAoD,KAAK,WAAW,EAAuB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpN,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAqB/C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAGxE;AAiBD,qBAAa,gBAAiB,YAAW,aAAa,EAAE,QAAQ;;IASlD,QAAQ,CAAC,OAAO,EAAE,aAAa;IAR3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;gBAQT,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,cAAc;IAElE;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAalC,aAAa,IAAI,eAAe,EAAE;IAClC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAQjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuE5B;;;;;;OAMG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAOrH;;;;;;;OAOG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA2C/C,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;IAY/B,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAC/B;;;;;;;;;;OAUG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAWhC,MAAM,IAAI,IAAI;IACd;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,QAAQ;IAC7B,4EAA4E;IAC5E,SAAS,IAAI,OAAO;IAgBpB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAkGxB;IAEF,6FAA6F;IAC7F,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAsDvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|