@withbuddi/buddi 0.1.0-pre.37 → 0.1.0-pre.38
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 +130 -12
- package/extension/manifest.json +2 -2
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts +10 -0
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts.map +1 -0
- package/node_modules/@buddi/cli/dist/access-cmd.js +160 -0
- package/node_modules/@buddi/cli/dist/access-cmd.js.map +1 -0
- package/node_modules/@buddi/cli/dist/args.d.ts +10 -0
- package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/args.js +29 -1
- package/node_modules/@buddi/cli/dist/args.js.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +28 -2
- package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.js +54 -29
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +36 -12
- package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.js +32 -9
- package/node_modules/@buddi/cli/dist/doctor.js.map +1 -1
- package/node_modules/@buddi/cli/dist/main.d.ts +2 -0
- package/node_modules/@buddi/cli/dist/main.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/main.js +18 -1
- package/node_modules/@buddi/cli/dist/main.js.map +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.d.ts +2 -0
- package/node_modules/@buddi/core/dist/agents/catalog.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js +1 -0
- package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.d.ts +2 -0
- package/node_modules/@buddi/core/dist/agents/edit.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.js +3 -1
- package/node_modules/@buddi/core/dist/agents/edit.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +11 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.js +7 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.js.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/plugin/index.d.ts +3 -0
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js +3 -0
- package/node_modules/@buddi/core/dist/plugin/index.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/questions/store.d.ts +12 -0
- package/node_modules/@buddi/core/dist/questions/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/store.js +11 -1
- package/node_modules/@buddi/core/dist/questions/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.d.ts +8 -0
- package/node_modules/@buddi/core/dist/questions/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.js +15 -0
- package/node_modules/@buddi/core/dist/questions/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts +8 -0
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.js +9 -3
- package/node_modules/@buddi/core/dist/queue/jobs.js.map +1 -1
- package/node_modules/@buddi/core/dist/queue/worker.d.ts +2 -0
- package/node_modules/@buddi/core/dist/queue/worker.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/worker.js +2 -1
- package/node_modules/@buddi/core/dist/queue/worker.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts +7 -1
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +73 -11
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/routes.d.ts +153 -0
- package/node_modules/@buddi/core/dist/routes.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/routes.js +47 -0
- package/node_modules/@buddi/core/dist/routes.js.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts +5 -3
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/missions.js +9 -7
- package/node_modules/@buddi/core/dist/scheduler/missions.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts +7 -0
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.js +1 -0
- package/node_modules/@buddi/core/dist/scheduler/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/tools.d.ts +59 -2
- 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/migrations/075_access_providers.sql +43 -0
- package/node_modules/@buddi/core/migrations/076_mission_browser.sql +7 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/agents/canvas.d.ts +12 -12
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts +38 -20
- 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 -0
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/delegation.js +1 -0
- package/node_modules/@buddi/gateway/dist/agents/delegation.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts +7 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js +15 -6
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/bootstrap.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/bootstrap.js +8 -0
- package/node_modules/@buddi/gateway/dist/bootstrap.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts +30 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js +56 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js +9 -5
- package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.d.ts +2 -1
- package/node_modules/@buddi/gateway/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.js +2 -1
- package/node_modules/@buddi/gateway/dist/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts +34 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +92 -8
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/parked.d.ts +133 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.js +249 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +49 -9
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts +18 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js +42 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.js +7 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.js +6 -7
- package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.d.ts +17 -17
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.js +33 -37
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.js +17 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.js +11 -3
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +10 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts +8 -0
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.js +8 -2
- package/node_modules/@buddi/gateway/dist/tips/facts.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.js +15 -0
- package/node_modules/@buddi/gateway/dist/tips/rules.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/arrival.d.ts +24 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.js +18 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.d.ts +124 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.js +206 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts +163 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js +438 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.d.ts +31 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js +74 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.d.ts +145 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.js +474 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts +9 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.js +9 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.d.ts +30 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.js +76 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.d.ts +173 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.js +11 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.d.ts +33 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.js +32 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/{tailscale.d.ts → access/tailscale.d.ts} +27 -0
- package/node_modules/@buddi/gateway/dist/web/access/tailscale.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/{tailscale.js → access/tailscale.js} +118 -3
- package/node_modules/@buddi/gateway/dist/web/access/tailscale.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agents.js +19 -1
- package/node_modules/@buddi/gateway/dist/web/agents.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts +4 -3
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +96 -17
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.js +11 -3
- package/node_modules/@buddi/gateway/dist/web/attention.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +23 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +62 -2
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.d.ts +3 -0
- package/node_modules/@buddi/gateway/dist/web/client-key.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.js +8 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts +9 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.js +61 -1
- package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/http.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/web/http.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/http.js +15 -1
- package/node_modules/@buddi/gateway/dist/web/http.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts +38 -2
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +576 -145
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +24 -14
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.js +42 -14
- package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.js +47 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.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 +8 -0
- package/node_modules/@buddi/runtime/dist/delegate.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/delegate.js +19 -1
- package/node_modules/@buddi/runtime/dist/delegate.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.d.ts +2 -0
- package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.js +18 -4
- 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-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/availability.d.ts +2 -2
- package/node_modules/@buddi/tool-browser/dist/availability.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/availability.js +2 -2
- package/node_modules/@buddi/tool-browser/dist/availability.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts +76 -58
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js +751 -219
- package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts +12 -0
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.js +8 -0
- package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.d.ts +13 -5
- package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.js +29 -12
- package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/manager.d.ts +39 -21
- package/node_modules/@buddi/tool-browser/dist/manager.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/manager.js +229 -136
- package/node_modules/@buddi/tool-browser/dist/manager.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts +130 -0
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/routes.js +283 -0
- package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/service.d.ts +157 -114
- package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.js +379 -390
- package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts +88 -0
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/settings.js +86 -0
- package/node_modules/@buddi/tool-browser/dist/settings.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.d.ts +203 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.js +142 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/types.d.ts +14 -3
- package/node_modules/@buddi/tool-browser/dist/types.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.js +9 -9
- 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/imapflow/CHANGELOG.md +15 -0
- 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/search-compiler.js +21 -31
- 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/search-compiler.js +21 -31
- package/node_modules/imapflow/package.json +2 -2
- package/node_modules/pino/CONTRIBUTING.md +1 -5
- package/node_modules/pino/LICENSE +1 -1
- package/node_modules/pino/README.md +1 -1
- package/node_modules/pino/SECURITY.md +2 -18
- package/node_modules/pino/browser.js +8 -68
- package/node_modules/pino/docs/api.md +4 -75
- package/node_modules/pino/docs/asynchronous.md +3 -18
- package/node_modules/pino/docs/browser.md +0 -63
- package/node_modules/pino/docs/child-loggers.md +1 -22
- package/node_modules/pino/docs/ecosystem.md +0 -1
- package/node_modules/pino/docs/help.md +3 -11
- package/node_modules/pino/docs/lts.md +0 -29
- package/node_modules/pino/docs/pretty.md +0 -3
- package/node_modules/pino/docs/redaction.md +8 -3
- package/node_modules/pino/docs/transports.md +0 -71
- package/node_modules/pino/docs/web.md +14 -11
- package/node_modules/pino/eslint.config.js +7 -15
- package/node_modules/pino/lib/caller.js +0 -10
- package/node_modules/pino/lib/meta.js +1 -1
- package/node_modules/pino/lib/multistream.js +7 -15
- package/node_modules/pino/lib/redaction.js +3 -8
- package/node_modules/pino/lib/symbols.js +1 -3
- package/node_modules/pino/lib/tools.js +2 -2
- package/node_modules/pino/lib/transport.js +1 -14
- package/node_modules/pino/lib/worker.js +1 -4
- package/node_modules/pino/package.json +22 -14
- package/node_modules/pino/pino.d.ts +736 -709
- package/node_modules/pino/pino.js +2 -27
- package/node_modules/pino/test/basic.test.js +0 -66
- package/node_modules/pino/test/escaping.test.js +0 -17
- package/node_modules/pino/test/fixtures/ts/transpile.cjs +3 -3
- package/node_modules/pino/test/helper.js +2 -6
- package/node_modules/pino/test/multistream.test.js +0 -64
- package/node_modules/pino/test/redact.test.js +0 -30
- package/node_modules/pino/test/transport/core.test.js +0 -85
- package/node_modules/pino/test/transport/sync-false.test.js +0 -12
- package/node_modules/pino/test/transport/uses-pino-config.test.js +4 -4
- package/node_modules/pino/test/types/pino-import.test-d.cts +30 -0
- package/node_modules/pino/test/types/pino-multistream.test-d.ts +28 -0
- package/node_modules/pino/test/types/pino-top-export.test-d.ts +34 -0
- package/node_modules/pino/test/types/{pino-transport.tst.ts → pino-transport.test-d.ts} +70 -85
- package/node_modules/pino/test/types/pino-type-only.test-d.ts +75 -0
- package/node_modules/pino/test/types/{pino.tst.ts → pino.test-d.ts} +137 -135
- package/node_modules/pino/test/types/pino.ts +7 -14
- package/node_modules/pino/tsconfig.json +6 -6
- package/node_modules/real-require/README.md +6 -6
- package/node_modules/real-require/package.json +21 -10
- package/node_modules/real-require/src/index.js +2 -2
- package/node_modules/thread-stream/node_modules/real-require/LICENSE.md +21 -0
- package/node_modules/thread-stream/node_modules/real-require/README.md +51 -0
- package/node_modules/thread-stream/node_modules/real-require/package.json +38 -0
- package/node_modules/thread-stream/node_modules/real-require/src/index.js +14 -0
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/access-cmd.d.ts +10 -0
- package/packages/cli/dist/access-cmd.d.ts.map +1 -0
- package/packages/cli/dist/access-cmd.js +160 -0
- package/packages/cli/dist/access-cmd.js.map +1 -0
- package/packages/cli/dist/args.d.ts +10 -0
- package/packages/cli/dist/args.d.ts.map +1 -1
- package/packages/cli/dist/args.js +29 -1
- package/packages/cli/dist/args.js.map +1 -1
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +28 -2
- package/packages/cli/dist/commands.js.map +1 -1
- package/packages/cli/dist/doctor-probes.d.ts.map +1 -1
- package/packages/cli/dist/doctor-probes.js +54 -29
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +36 -12
- package/packages/cli/dist/doctor.d.ts.map +1 -1
- package/packages/cli/dist/doctor.js +32 -9
- package/packages/cli/dist/doctor.js.map +1 -1
- package/packages/cli/dist/main.d.ts +2 -0
- package/packages/cli/dist/main.d.ts.map +1 -1
- package/packages/cli/dist/main.js +18 -1
- package/packages/cli/dist/main.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/agents/catalog.d.ts +2 -0
- package/packages/core/dist/agents/catalog.d.ts.map +1 -1
- package/packages/core/dist/agents/catalog.js +1 -0
- package/packages/core/dist/agents/catalog.js.map +1 -1
- package/packages/core/dist/agents/edit.d.ts +2 -0
- package/packages/core/dist/agents/edit.d.ts.map +1 -1
- package/packages/core/dist/agents/edit.js +3 -1
- package/packages/core/dist/agents/edit.js.map +1 -1
- package/packages/core/dist/agents/frontmatter.d.ts +11 -0
- package/packages/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/packages/core/dist/agents/frontmatter.js +7 -0
- package/packages/core/dist/agents/frontmatter.js.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/plugin/index.d.ts +3 -0
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js +3 -0
- package/packages/core/dist/plugin/index.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/questions/store.d.ts +12 -0
- package/packages/core/dist/questions/store.d.ts.map +1 -1
- package/packages/core/dist/questions/store.js +11 -1
- package/packages/core/dist/questions/store.js.map +1 -1
- package/packages/core/dist/questions/types.d.ts +8 -0
- package/packages/core/dist/questions/types.d.ts.map +1 -1
- package/packages/core/dist/questions/types.js +15 -0
- package/packages/core/dist/questions/types.js.map +1 -1
- package/packages/core/dist/queue/jobs.d.ts +8 -0
- package/packages/core/dist/queue/jobs.d.ts.map +1 -1
- package/packages/core/dist/queue/jobs.js +9 -3
- package/packages/core/dist/queue/jobs.js.map +1 -1
- package/packages/core/dist/queue/worker.d.ts +2 -0
- package/packages/core/dist/queue/worker.d.ts.map +1 -1
- package/packages/core/dist/queue/worker.js +2 -1
- package/packages/core/dist/queue/worker.js.map +1 -1
- package/packages/core/dist/registry.d.ts +7 -1
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +73 -11
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/routes.d.ts +153 -0
- package/packages/core/dist/routes.d.ts.map +1 -0
- package/packages/core/dist/routes.js +47 -0
- package/packages/core/dist/routes.js.map +1 -0
- package/packages/core/dist/scheduler/missions.d.ts +5 -3
- package/packages/core/dist/scheduler/missions.d.ts.map +1 -1
- package/packages/core/dist/scheduler/missions.js +9 -7
- package/packages/core/dist/scheduler/missions.js.map +1 -1
- package/packages/core/dist/scheduler/types.d.ts +7 -0
- package/packages/core/dist/scheduler/types.d.ts.map +1 -1
- package/packages/core/dist/scheduler/types.js +1 -0
- package/packages/core/dist/scheduler/types.js.map +1 -1
- package/packages/core/dist/tools.d.ts +59 -2
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/migrations/075_access_providers.sql +43 -0
- package/packages/core/migrations/076_mission_browser.sql +7 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/agents/canvas.d.ts +12 -12
- package/packages/gateway/dist/agents/catalogue-package.d.ts +38 -20
- package/packages/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
- package/packages/gateway/dist/agents/catalogue-package.js +6 -0
- package/packages/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/packages/gateway/dist/agents/delegation.d.ts +10 -0
- package/packages/gateway/dist/agents/delegation.d.ts.map +1 -1
- package/packages/gateway/dist/agents/delegation.js +1 -0
- package/packages/gateway/dist/agents/delegation.js.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.d.ts +7 -1
- package/packages/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.js +15 -6
- package/packages/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/packages/gateway/dist/bootstrap.d.ts.map +1 -1
- package/packages/gateway/dist/bootstrap.js +8 -0
- package/packages/gateway/dist/bootstrap.js.map +1 -1
- package/packages/gateway/dist/browser-host.d.ts +30 -1
- package/packages/gateway/dist/browser-host.d.ts.map +1 -1
- package/packages/gateway/dist/browser-host.js +56 -1
- package/packages/gateway/dist/browser-host.js.map +1 -1
- package/packages/gateway/dist/chat/session.d.ts.map +1 -1
- package/packages/gateway/dist/chat/session.js +9 -5
- package/packages/gateway/dist/chat/session.js.map +1 -1
- package/packages/gateway/dist/index.d.ts +2 -1
- package/packages/gateway/dist/index.d.ts.map +1 -1
- package/packages/gateway/dist/index.js +2 -1
- package/packages/gateway/dist/index.js.map +1 -1
- package/packages/gateway/dist/missions/execute.d.ts +34 -1
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +92 -8
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/parked.d.ts +133 -0
- package/packages/gateway/dist/missions/parked.d.ts.map +1 -0
- package/packages/gateway/dist/missions/parked.js +249 -0
- package/packages/gateway/dist/missions/parked.js.map +1 -0
- package/packages/gateway/dist/serve.d.ts +7 -0
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +49 -9
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/surfaces/browser-cards.d.ts +18 -0
- package/packages/gateway/dist/surfaces/browser-cards.d.ts.map +1 -0
- package/packages/gateway/dist/surfaces/browser-cards.js +42 -0
- package/packages/gateway/dist/surfaces/browser-cards.js.map +1 -0
- package/packages/gateway/dist/surfaces/browser-continuation.js +1 -1
- package/packages/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/packages/gateway/dist/surfaces/owner-request.d.ts +6 -0
- package/packages/gateway/dist/surfaces/owner-request.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/owner-request.js +7 -1
- package/packages/gateway/dist/surfaces/owner-request.js.map +1 -1
- package/packages/gateway/dist/system-context.d.ts.map +1 -1
- package/packages/gateway/dist/system-context.js +6 -7
- package/packages/gateway/dist/system-context.js.map +1 -1
- package/packages/gateway/dist/telegram/browser-view.d.ts +17 -17
- package/packages/gateway/dist/telegram/browser-view.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/browser-view.js +33 -37
- package/packages/gateway/dist/telegram/browser-view.js.map +1 -1
- package/packages/gateway/dist/telegram/channel.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/channel.js +17 -1
- package/packages/gateway/dist/telegram/channel.js.map +1 -1
- package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/main.js +11 -3
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +10 -0
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/tips/facts.d.ts +8 -0
- package/packages/gateway/dist/tips/facts.d.ts.map +1 -1
- package/packages/gateway/dist/tips/facts.js +8 -2
- package/packages/gateway/dist/tips/facts.js.map +1 -1
- package/packages/gateway/dist/tips/rules.d.ts +2 -0
- package/packages/gateway/dist/tips/rules.d.ts.map +1 -1
- package/packages/gateway/dist/tips/rules.js +15 -0
- package/packages/gateway/dist/tips/rules.js.map +1 -1
- package/packages/gateway/dist/web/access/arrival.d.ts +24 -0
- package/packages/gateway/dist/web/access/arrival.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/arrival.js +18 -0
- package/packages/gateway/dist/web/access/arrival.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-api.d.ts +124 -0
- package/packages/gateway/dist/web/access/cloudflare-api.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-api.js +206 -0
- package/packages/gateway/dist/web/access/cloudflare-api.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts +163 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.js +438 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-token.d.ts +31 -0
- package/packages/gateway/dist/web/access/cloudflare-token.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-token.js +74 -0
- package/packages/gateway/dist/web/access/cloudflare-token.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare.d.ts +145 -0
- package/packages/gateway/dist/web/access/cloudflare.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare.js +474 -0
- package/packages/gateway/dist/web/access/cloudflare.js.map +1 -0
- package/packages/gateway/dist/web/access/index.d.ts +9 -0
- package/packages/gateway/dist/web/access/index.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/index.js +9 -0
- package/packages/gateway/dist/web/access/index.js.map +1 -0
- package/packages/gateway/dist/web/access/ingress.d.ts +30 -0
- package/packages/gateway/dist/web/access/ingress.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/ingress.js +76 -0
- package/packages/gateway/dist/web/access/ingress.js.map +1 -0
- package/packages/gateway/dist/web/access/provider.d.ts +173 -0
- package/packages/gateway/dist/web/access/provider.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/provider.js +11 -0
- package/packages/gateway/dist/web/access/provider.js.map +1 -0
- package/packages/gateway/dist/web/access/registry.d.ts +33 -0
- package/packages/gateway/dist/web/access/registry.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/registry.js +32 -0
- package/packages/gateway/dist/web/access/registry.js.map +1 -0
- package/packages/gateway/dist/web/{tailscale.d.ts → access/tailscale.d.ts} +27 -0
- package/packages/gateway/dist/web/access/tailscale.d.ts.map +1 -0
- package/packages/gateway/dist/web/{tailscale.js → access/tailscale.js} +118 -3
- package/packages/gateway/dist/web/access/tailscale.js.map +1 -0
- package/packages/gateway/dist/web/agents.d.ts +2 -0
- package/packages/gateway/dist/web/agents.d.ts.map +1 -1
- package/packages/gateway/dist/web/agents.js +19 -1
- package/packages/gateway/dist/web/agents.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts +4 -3
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +96 -17
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/attention.d.ts.map +1 -1
- package/packages/gateway/dist/web/attention.js +11 -3
- package/packages/gateway/dist/web/attention.js.map +1 -1
- package/packages/gateway/dist/web/chat.d.ts +23 -0
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +62 -2
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/client-key.d.ts +3 -0
- package/packages/gateway/dist/web/client-key.d.ts.map +1 -1
- package/packages/gateway/dist/web/client-key.js +8 -1
- package/packages/gateway/dist/web/client-key.js.map +1 -1
- package/packages/gateway/dist/web/extension.d.ts +9 -1
- package/packages/gateway/dist/web/extension.d.ts.map +1 -1
- package/packages/gateway/dist/web/extension.js +61 -1
- package/packages/gateway/dist/web/extension.js.map +1 -1
- package/packages/gateway/dist/web/http.d.ts +7 -0
- package/packages/gateway/dist/web/http.d.ts.map +1 -1
- package/packages/gateway/dist/web/http.js +15 -1
- package/packages/gateway/dist/web/http.js.map +1 -1
- package/packages/gateway/dist/web/index.d.ts +1 -1
- package/packages/gateway/dist/web/index.d.ts.map +1 -1
- package/packages/gateway/dist/web/index.js +1 -1
- package/packages/gateway/dist/web/index.js.map +1 -1
- package/packages/gateway/dist/web/onboarding.js +1 -1
- package/packages/gateway/dist/web/onboarding.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts +38 -2
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +576 -145
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/sessions.d.ts +24 -14
- package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
- package/packages/gateway/dist/web/sessions.js +42 -14
- package/packages/gateway/dist/web/sessions.js.map +1 -1
- package/packages/gateway/dist/web/signed-out.d.ts +10 -0
- package/packages/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/packages/gateway/dist/web/signed-out.js +47 -0
- package/packages/gateway/dist/web/signed-out.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 +8 -0
- package/packages/runtime/dist/delegate.d.ts.map +1 -1
- package/packages/runtime/dist/delegate.js +19 -1
- package/packages/runtime/dist/delegate.js.map +1 -1
- package/packages/runtime/dist/loop.d.ts +2 -0
- package/packages/runtime/dist/loop.d.ts.map +1 -1
- package/packages/runtime/dist/loop.js +18 -4
- package/packages/runtime/dist/loop.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/availability.d.ts +2 -2
- package/packages/tools/browser/dist/availability.d.ts.map +1 -1
- package/packages/tools/browser/dist/availability.js +2 -2
- package/packages/tools/browser/dist/availability.js.map +1 -1
- package/packages/tools/browser/dist/controller.d.ts +76 -58
- package/packages/tools/browser/dist/controller.d.ts.map +1 -1
- package/packages/tools/browser/dist/controller.js +751 -219
- package/packages/tools/browser/dist/controller.js.map +1 -1
- package/packages/tools/browser/dist/extension.d.ts +12 -0
- package/packages/tools/browser/dist/extension.d.ts.map +1 -1
- package/packages/tools/browser/dist/extension.js +8 -0
- package/packages/tools/browser/dist/extension.js.map +1 -1
- package/packages/tools/browser/dist/index.d.ts +13 -5
- package/packages/tools/browser/dist/index.d.ts.map +1 -1
- package/packages/tools/browser/dist/index.js +29 -12
- package/packages/tools/browser/dist/index.js.map +1 -1
- package/packages/tools/browser/dist/manager.d.ts +39 -21
- package/packages/tools/browser/dist/manager.d.ts.map +1 -1
- package/packages/tools/browser/dist/manager.js +229 -136
- package/packages/tools/browser/dist/manager.js.map +1 -1
- package/packages/tools/browser/dist/routes.d.ts +130 -0
- package/packages/tools/browser/dist/routes.d.ts.map +1 -0
- package/packages/tools/browser/dist/routes.js +283 -0
- package/packages/tools/browser/dist/routes.js.map +1 -0
- package/packages/tools/browser/dist/service.d.ts +157 -114
- package/packages/tools/browser/dist/service.d.ts.map +1 -1
- package/packages/tools/browser/dist/service.js +379 -390
- package/packages/tools/browser/dist/service.js.map +1 -1
- package/packages/tools/browser/dist/settings.d.ts +88 -0
- package/packages/tools/browser/dist/settings.d.ts.map +1 -0
- package/packages/tools/browser/dist/settings.js +86 -0
- package/packages/tools/browser/dist/settings.js.map +1 -0
- package/packages/tools/browser/dist/telemetry.d.ts +203 -0
- package/packages/tools/browser/dist/telemetry.d.ts.map +1 -0
- package/packages/tools/browser/dist/telemetry.js +142 -0
- package/packages/tools/browser/dist/telemetry.js.map +1 -0
- package/packages/tools/browser/dist/types.d.ts +14 -3
- package/packages/tools/browser/dist/types.d.ts.map +1 -1
- package/packages/tools/browser/dist/types.js +9 -9
- 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-Bac-CdD-.css +1 -0
- package/packages/web/dist/assets/index-DI8bp_D7.js +146 -0
- package/packages/web/dist/assets/{lottie_light-CKJ88Yuk.js → lottie_light-CuiSMqnl.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/node_modules/@buddi/gateway/dist/web/apps.d.ts +0 -18
- package/node_modules/@buddi/gateway/dist/web/apps.d.ts.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/apps.js +0 -84
- package/node_modules/@buddi/gateway/dist/web/apps.js.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/computer.d.ts +0 -153
- package/node_modules/@buddi/tool-browser/dist/computer.d.ts.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/computer.js +0 -392
- package/node_modules/@buddi/tool-browser/dist/computer.js.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/native/buddi-computer +0 -0
- package/node_modules/pino/test/browser-bindings.test.js +0 -114
- package/node_modules/pino/test/browser-redaction.test.js +0 -264
- package/node_modules/pino/test/browser-set-bindings.test.js +0 -99
- package/node_modules/pino/test/caller.test.js +0 -20
- package/node_modules/pino/test/fixtures/caller-loop.js +0 -6
- package/node_modules/pino/test/smoke.js +0 -59
- package/node_modules/pino/test/types/pino-import.tst.cts +0 -30
- package/node_modules/pino/test/types/pino-import.tst.js +0 -73
- package/node_modules/pino/test/types/pino-multistream.tst.ts +0 -49
- package/node_modules/pino/test/types/pino-top-export.tst.ts +0 -32
- package/node_modules/pino/test/types/pino-type-only.tst.ts +0 -77
- package/node_modules/pino/test/types/tsconfig.json +0 -10
- package/packages/gateway/dist/web/apps.d.ts +0 -18
- package/packages/gateway/dist/web/apps.d.ts.map +0 -1
- package/packages/gateway/dist/web/apps.js +0 -84
- package/packages/gateway/dist/web/apps.js.map +0 -1
- package/packages/gateway/dist/web/tailscale.d.ts.map +0 -1
- package/packages/gateway/dist/web/tailscale.js.map +0 -1
- package/packages/tools/browser/dist/computer.d.ts +0 -153
- package/packages/tools/browser/dist/computer.d.ts.map +0 -1
- package/packages/tools/browser/dist/computer.js +0 -392
- package/packages/tools/browser/dist/computer.js.map +0 -1
- package/packages/tools/browser/dist/native/buddi-computer +0 -0
- package/packages/web/dist/assets/index-CN1AXMI1.css +0 -1
- package/packages/web/dist/assets/index-CQRE9LJX.js +0 -145
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { mkdir, readFile, writeFile, rename } from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
2
|
import { FORM_KIND, NATIVE_KIND, fieldBoundTo, secretKindFor, takeDelivered } from './secrets.js';
|
|
5
3
|
import { APP_BEHIND, BrowserPreconditionError, UNTRUSTED, observedLine } from './types.js';
|
|
4
|
+
import { ownerCard, siteOf } from './routes.js';
|
|
5
|
+
import { missionMark } from './telemetry.js';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* is already on the tool context (`ctx.surface`), so the plugin says it rather
|
|
11
|
-
* than leaving a relay to guess. On Telegram the way back is a command in the
|
|
12
|
-
* same chat; everywhere else it is the dashboard's own Settings page, which is
|
|
13
|
-
* where the Stop button lives.
|
|
7
|
+
* Said when the owner has stopped agents' browsing. On Telegram the way back
|
|
8
|
+
* is a command in the same chat; everywhere else the Resume card in the chat
|
|
9
|
+
* itself, or Settings.
|
|
14
10
|
*/
|
|
15
|
-
|
|
11
|
+
export function browserStoppedMessage(surface) {
|
|
12
|
+
return surface?.id === 'telegram'
|
|
13
|
+
? 'The owner stopped agents\' browsing. Tap Resume on the card, or send /browser resume here.'
|
|
14
|
+
: 'The owner stopped agents\' browsing. Tap Resume on the card in this chat to let agents look again.';
|
|
15
|
+
}
|
|
16
|
+
/** Kept for the surfaces that still name it: the owner has the page in their hands. */
|
|
16
17
|
export function browserPausedMessage(surface) {
|
|
17
18
|
return surface?.id === 'telegram'
|
|
18
|
-
? '
|
|
19
|
-
: '
|
|
19
|
+
? 'You have the page. Give it back from the dashboard, or send /browser resume here.'
|
|
20
|
+
: 'You have the page. Give it back when you are done and the agent carries on.';
|
|
20
21
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Said when an observation did not answer and control stays with the agent.
|
|
23
|
-
* A slow page is something the model can wait out itself, so there is nothing
|
|
24
|
-
* for the owner to do and the wording is the same on every surface.
|
|
25
|
-
*/
|
|
22
|
+
/** A page that did not answer after every retry: said once, never as an instruction to retry. */
|
|
26
23
|
export function browserWaitMessage(_surface) {
|
|
27
|
-
return 'The page
|
|
24
|
+
return 'The page did not answer after several tries.';
|
|
28
25
|
}
|
|
29
|
-
/**
|
|
30
|
-
const SCREEN_GONE = /\b(tab|window)\b[^.]*\b(closed|gone)\b|has been closed|target closed/i;
|
|
31
|
-
/** A gone tab the driver can replace by itself ("observe again to continue in a new one") is not a screen lost. */
|
|
32
|
-
const SCREEN_REPLACEABLE = /observe again to continue in a new one/i;
|
|
33
|
-
/** The extension's refusal to act in the tab the owner is viewing (extension commands.ts, `WATCHED`). */
|
|
26
|
+
/** The extension's last word after waiting for the owner to leave their tab (extension commands.ts, `WATCHED`). */
|
|
34
27
|
const OWNER_WATCHING = /You are looking at this tab/i;
|
|
35
|
-
/** What the
|
|
36
|
-
export const OWNER_WATCHING_MESSAGE = 'The owner is looking at that tab
|
|
37
|
-
/**
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
/** What the agent is told instead: no ask, no retry loop; the bar in the tab already asks the owner. */
|
|
29
|
+
export const OWNER_WATCHING_MESSAGE = 'The owner is looking at that tab, and the bar in it asks them whether you may carry on there. Nothing was done. Work on something else for a moment, then try again.';
|
|
30
|
+
/** An observation failure no waiting fixes: the tab or window it was reading is gone. */
|
|
31
|
+
const SCREEN_GONE = /\b(tab|window)\b[^.]*\b(closed|gone)\b|has been closed|target closed/i;
|
|
32
|
+
/** The waits before each re-read when the page gave no answer: 0.5, 1, 2, 4 and 8 seconds (six attempts in all). */
|
|
33
|
+
export const RETRY_DELAYS_MS = [500, 1_000, 2_000, 4_000, 8_000];
|
|
34
|
+
/** Targeting refusals in a row before the task asks the owner whether to keep going. */
|
|
35
|
+
export const MAX_TARGETING_FAILURES = 8;
|
|
36
|
+
/** The task's budget: actions and minutes, renewed by any owner touch in the conversation. */
|
|
37
|
+
export const DEFAULT_MAX_STEPS = 200;
|
|
38
|
+
export const DEFAULT_LIFETIME_MS = 60 * 60_000;
|
|
39
|
+
/** How long a run stays parked on its page waiting for the owner's card. */
|
|
40
|
+
export const PARK_MS = 60 * 60_000;
|
|
41
|
+
/** A route by the mode name the dashboard and Telegram already know. */
|
|
42
|
+
export function modeOf(route) {
|
|
43
|
+
return route === 'chrome' ? 'extension' : route === 'apps' ? 'computer' : 'playwright';
|
|
46
44
|
}
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
45
|
+
/**
|
|
46
|
+
* One conversation's page on one route.
|
|
47
|
+
*
|
|
48
|
+
* Every action returns the page as it is afterwards. Refusals that used to
|
|
49
|
+
* stop the task are retried here (a slow page, a stale ref, a redirect) or
|
|
50
|
+
* become one card the owner answers (an input that may not have landed, the
|
|
51
|
+
* budget). Only the owner's own take-over pauses a page.
|
|
52
|
+
*/
|
|
49
53
|
export class BrowserService {
|
|
50
54
|
driver;
|
|
51
55
|
options;
|
|
@@ -55,81 +59,81 @@ export class BrowserService {
|
|
|
55
59
|
#observation;
|
|
56
60
|
#picture;
|
|
57
61
|
#busy = false;
|
|
58
|
-
/**
|
|
59
|
-
* The screen this session had is gone.
|
|
60
|
-
*
|
|
61
|
-
* Set when a take-over had to close the driver to end the action in flight,
|
|
62
|
-
* and cleared by resume. Belt to `handReady`'s braces: a hand offered over
|
|
63
|
-
* nothing is a live view that never paints its first frame, and the owner
|
|
64
|
-
* has no way to tell that from a slow link.
|
|
65
|
-
*/
|
|
66
62
|
#handless = false;
|
|
67
63
|
#controller;
|
|
68
64
|
#expiry;
|
|
69
65
|
#lastAction;
|
|
70
66
|
#message;
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
#
|
|
67
|
+
#targetingFailures = 0;
|
|
68
|
+
#card;
|
|
69
|
+
/** Where the page last was, so a closed tab or a new request re-opens it rather than stopping. */
|
|
70
|
+
#lastUrl;
|
|
71
|
+
#lastActivity = 0;
|
|
72
|
+
#tail = Promise.resolve();
|
|
75
73
|
#controlTail = Promise.resolve();
|
|
76
|
-
#diskTail = Promise.resolve();
|
|
77
74
|
constructor(driver, options = {}) {
|
|
78
75
|
this.driver = driver;
|
|
79
76
|
this.options = options;
|
|
80
77
|
}
|
|
81
78
|
#now() { return this.options.now?.() ?? Date.now(); }
|
|
82
|
-
|
|
83
|
-
#
|
|
84
|
-
|
|
79
|
+
get #route() { return this.options.route ?? (this.options.allowOpen ? 'apps' : 'own'); }
|
|
80
|
+
#sleep(ms) { return this.options.sleep ? this.options.sleep(ms) : new Promise((resolve) => setTimeout(resolve, ms)); }
|
|
81
|
+
#stamp(observation) { return { ...observation, observedAt: new Date(this.#now()).toISOString() }; }
|
|
82
|
+
#stop(cause, ctx, recovered) {
|
|
83
|
+
this.options.telemetry?.stop(cause, { route: this.#route, ...(ctx?.agentId ? { agent: ctx.agentId } : {}), ...(ctx?.surface?.id ? { surface: ctx.surface.id } : {}), ...missionMark(ctx),
|
|
84
|
+
...(siteOf(this.#observation?.url ?? this.#lastUrl) ? { host: siteOf(this.#observation?.url ?? this.#lastUrl) } : {}), ...(recovered ? { recovered } : {}) });
|
|
85
85
|
}
|
|
86
86
|
async enable() {
|
|
87
87
|
if (this.#enabled)
|
|
88
88
|
return;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
else
|
|
101
|
-
this.#state = 'idle';
|
|
89
|
+
// Take over pressed in the page's own bar is the Canvas button.
|
|
90
|
+
this.driver.onOwnerTakeover?.(() => {
|
|
91
|
+
const id = this.#session?.id;
|
|
92
|
+
if (!id)
|
|
93
|
+
return;
|
|
94
|
+
if (this.options.requestTakeover)
|
|
95
|
+
this.options.requestTakeover(id);
|
|
96
|
+
else
|
|
97
|
+
void this.control('takeover').catch(() => undefined);
|
|
98
|
+
});
|
|
99
|
+
this.#state = 'idle';
|
|
102
100
|
this.#enabled = true;
|
|
103
101
|
}
|
|
104
102
|
status(_scope) {
|
|
105
103
|
const { tree: _tree, targets: _targets, ...page } = this.#observation ?? {};
|
|
106
|
-
const { ownerId:
|
|
104
|
+
const session = this.#session ? (({ ownerId: _o, startedAt: _s, actions: _a, cards: _c, ...rest }) => rest)(this.#session) : undefined;
|
|
107
105
|
return { state: this.#state, enabled: this.#enabled, busy: this.#busy,
|
|
108
|
-
...(
|
|
106
|
+
...(session ? { session: { ...session, route: this.#route }, route: this.#route, mode: modeOf(this.#route) } : {}),
|
|
109
107
|
...(this.#observation ? { page: page } : {}),
|
|
108
|
+
...(this.#card ? { needsOwner: this.#card } : {}),
|
|
110
109
|
lastAction: this.#lastAction, message: this.#message, hasScreenshot: !!this.#picture };
|
|
111
110
|
}
|
|
112
111
|
screenshot(_sessionId) { return this.#picture; }
|
|
112
|
+
/** The card this page waits on, if any. */
|
|
113
|
+
get card() { return this.#card; }
|
|
114
|
+
/** Where this page is, or was. */
|
|
115
|
+
get lastUrl() { return this.#observation?.url ?? this.#lastUrl; }
|
|
116
|
+
/** The latest page, with its tree: what the route's post-processing reads. */
|
|
117
|
+
get observation() { return this.#observation; }
|
|
118
|
+
get busy() { return this.#busy; }
|
|
119
|
+
/** Where this conversation's page was before it was let go, so the next action opens it again there. */
|
|
120
|
+
seed(url) { this.#lastUrl ??= url; }
|
|
121
|
+
/** No action for this long: a page a waiting conversation may take over. */
|
|
122
|
+
idleFor() { return this.#busy || this.#state === 'paused' || this.#card ? 0 : this.#now() - this.#lastActivity; }
|
|
113
123
|
/**
|
|
114
|
-
* The remote hand, and only while the owner holds this screen.
|
|
115
|
-
*
|
|
116
|
-
* Paused is the take-over state, so it is also the only state in which a
|
|
117
|
-
* dashboard may drive: an agent mid-action and a hand on the same page would
|
|
118
|
-
* be two drivers, and the evidence rules here assume exactly one.
|
|
124
|
+
* The remote hand, and only while the owner holds this screen. Paused is the
|
|
125
|
+
* take-over state, the only one in which a dashboard may drive.
|
|
119
126
|
*/
|
|
120
127
|
hand(_scope) {
|
|
121
128
|
if (this.driver.supportsHand === false || !this.driver.hand) {
|
|
122
|
-
return { supported: false, message: this.driver.handMessage ?? 'Take over at the computer for this
|
|
129
|
+
return { supported: false, message: this.driver.handMessage ?? 'Take over at the computer for this route.' };
|
|
123
130
|
}
|
|
124
131
|
if (!this.#session)
|
|
125
|
-
return { supported: true, message: 'No agent is
|
|
132
|
+
return { supported: true, message: 'No agent is looking at this page.' };
|
|
126
133
|
if (this.#state !== 'paused')
|
|
127
134
|
return { supported: true, message: 'Take over first, then you can drive.' };
|
|
128
|
-
// Paused is not the same as paintable. A take-over that interrupted an
|
|
129
|
-
// action closed the screen that action was on, and a hand offered over
|
|
130
|
-
// nothing is a live view that never draws its first frame.
|
|
131
135
|
if (this.#handless || this.driver.handReady?.() === false) {
|
|
132
|
-
return { supported: true, message: this.#message ?? 'There is no screen to drive.
|
|
136
|
+
return { supported: true, message: this.#message ?? 'There is no screen to drive. Give it back and the agent opens the page again.' };
|
|
133
137
|
}
|
|
134
138
|
return { supported: true, hand: this.driver.hand };
|
|
135
139
|
}
|
|
@@ -138,120 +142,178 @@ export class BrowserService {
|
|
|
138
142
|
if (!session || session.ownerId !== input.ownerId || session.agentId !== input.agentId || session.conversationId !== input.previousConversationId)
|
|
139
143
|
return false;
|
|
140
144
|
if (!this.#enabled || this.#busy || !['running', 'paused'].includes(this.#state))
|
|
141
|
-
throw new Error('Wait for
|
|
142
|
-
if (Date.parse(session.expiresAt) <= this.#now())
|
|
143
|
-
return false;
|
|
144
|
-
this.#spent.add(session.requestId);
|
|
145
|
+
throw new Error('Wait for the page to settle before continuing the conversation.');
|
|
145
146
|
session.conversationId = input.conversationId;
|
|
146
147
|
this.#observation = undefined;
|
|
147
148
|
this.#picture = undefined;
|
|
148
|
-
this.#
|
|
149
|
-
this.#message = 'Task continued after conversation rollover. Observe the current page before acting. Human takeover, if active, still requires owner resume.';
|
|
149
|
+
this.#message = 'Task continued after conversation rollover. The next action returns the current page.';
|
|
150
150
|
return true;
|
|
151
151
|
}
|
|
152
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Put the page on a card and wait for the owner. The run stops (the tool's
|
|
154
|
+
* result carries the card) and the page stays open for at least an hour.
|
|
155
|
+
*/
|
|
156
|
+
park(kind, facts = {}) {
|
|
157
|
+
const card = ownerCard(kind, { site: siteOf(this.lastUrl), ...facts });
|
|
158
|
+
this.#card = card;
|
|
159
|
+
if (this.#session)
|
|
160
|
+
this.#session.cards++;
|
|
161
|
+
this.#schedule(Math.max(Date.parse(this.#session?.expiresAt ?? '') || 0, this.#now()) + Math.max(this.options.parkMs ?? PARK_MS, PARK_MS) - this.#now());
|
|
162
|
+
return card;
|
|
163
|
+
}
|
|
164
|
+
#cardResult(card, dispatched, message) {
|
|
165
|
+
return { completed: false, dispatched, needsOwner: card, notice: UNTRUSTED,
|
|
166
|
+
message: message ?? `Waiting for the owner: "${card.title}" Say that in one sentence and stop; the card in the chat has the buttons. The page stays open; you continue when they answer.`,
|
|
167
|
+
...(this.#observation ? { observation: this.#observation } : {}) };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The owner spoke or tapped in this conversation: the budget renews (200
|
|
171
|
+
* actions, an hour) and a waiting card is cleared. Returns the card it
|
|
172
|
+
* cleared, so the caller can act on the answer (take over, use Chrome).
|
|
173
|
+
*/
|
|
174
|
+
renew() {
|
|
175
|
+
const card = this.#card;
|
|
176
|
+
this.#card = undefined;
|
|
177
|
+
this.#targetingFailures = 0;
|
|
178
|
+
if (this.#session) {
|
|
179
|
+
this.#session.steps = 0;
|
|
180
|
+
this.#session.maxSteps = this.options.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
181
|
+
const expiresAt = this.#now() + (this.options.lifetimeMs ?? DEFAULT_LIFETIME_MS);
|
|
182
|
+
this.#session.expiresAt = new Date(expiresAt).toISOString();
|
|
183
|
+
this.#schedule(expiresAt - this.#now() + Math.max(this.options.parkMs ?? PARK_MS, PARK_MS));
|
|
184
|
+
}
|
|
185
|
+
return card;
|
|
186
|
+
}
|
|
187
|
+
#schedule(ms) {
|
|
188
|
+
clearTimeout(this.#expiry);
|
|
189
|
+
this.#expiry = setTimeout(() => { void this.#release('expired'); }, Math.max(1, ms));
|
|
190
|
+
this.#expiry.unref?.();
|
|
191
|
+
}
|
|
192
|
+
#open(request, ctx) {
|
|
193
|
+
const lifetime = this.options.lifetimeMs ?? DEFAULT_LIFETIME_MS;
|
|
194
|
+
if (!this.#session) {
|
|
195
|
+
const expiresAt = this.#now() + lifetime;
|
|
196
|
+
this.#session = { id: randomUUID(), ownerId: ctx.buddi.owner.id, agentId: ctx.agentId, conversationId: ctx.conversationId,
|
|
197
|
+
requestId: request?.id ?? 'unattended', task: (request?.text ?? 'An unattended task').slice(0, 4000),
|
|
198
|
+
expiresAt: new Date(expiresAt).toISOString(), steps: 0, maxSteps: this.options.maxSteps ?? DEFAULT_MAX_STEPS,
|
|
199
|
+
startedAt: this.#now(), actions: 0, cards: 0 };
|
|
200
|
+
this.#schedule(lifetime + Math.max(this.options.parkMs ?? PARK_MS, PARK_MS));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// A new owner message is an owner touch: the same page, a fresh budget.
|
|
204
|
+
if (request && this.#session.requestId !== request.id) {
|
|
205
|
+
this.#session.requestId = request.id;
|
|
206
|
+
this.#session.task = request.text.slice(0, 4000);
|
|
207
|
+
this.renew();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/** One action at a time per page: a second call waits for the first rather than being refused. */
|
|
211
|
+
#serial(run) {
|
|
212
|
+
const next = this.#tail.then(run, run);
|
|
213
|
+
this.#tail = next.catch(() => { });
|
|
214
|
+
return next;
|
|
215
|
+
}
|
|
216
|
+
execute(command, ctx) {
|
|
217
|
+
return this.#serial(() => this.#execute(command, ctx));
|
|
218
|
+
}
|
|
219
|
+
async #execute(command, ctx) {
|
|
153
220
|
ctx.signal?.throwIfAborted();
|
|
154
221
|
const request = ctx.ownerRequest;
|
|
155
|
-
if (!
|
|
156
|
-
|
|
157
|
-
throw new Error('A current authenticated owner request is required.');
|
|
158
|
-
}
|
|
222
|
+
if (!ctx.agentId || !ctx.conversationId)
|
|
223
|
+
throw new Error('A browser action belongs to an agent and a conversation.');
|
|
159
224
|
if (!this.#enabled)
|
|
160
225
|
throw new Error('Browser driving is available through buddi serve (dashboard or Telegram), not a separate CLI process.');
|
|
161
226
|
if (this.#state === 'stopped')
|
|
162
227
|
throw new Error(browserStoppedMessage(ctx.surface));
|
|
163
|
-
if (this.#busy)
|
|
164
|
-
throw new Error('Browser is busy; overlapping actions are refused.');
|
|
165
228
|
if (this.#session && (this.#session.ownerId !== ctx.buddi.owner.id || this.#session.agentId !== ctx.agentId || this.#session.conversationId !== ctx.conversationId)) {
|
|
166
|
-
throw new Error('Another
|
|
229
|
+
throw new Error('Another conversation owns this page.');
|
|
167
230
|
}
|
|
168
|
-
if (this.#spent.has(request.id))
|
|
169
|
-
throw new Error('This browser request has ended. A new owner message is required.');
|
|
170
231
|
if (command.action === 'close') {
|
|
171
|
-
this.#spent.add(request.id);
|
|
172
232
|
await this.#release('idle');
|
|
173
233
|
return { closed: true, notice: UNTRUSTED };
|
|
174
234
|
}
|
|
175
|
-
if (this.#state === 'paused')
|
|
176
|
-
throw new Error('
|
|
177
|
-
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!this.#session && command.action !== 'navigate' && !(this.options.allowOpen && command.action === 'open'))
|
|
184
|
-
throw new Error('Start with navigate, or open an allowed application in computer mode.');
|
|
185
|
-
this.#rekey(request, ctx.agentId, ctx.conversationId, ctx.buddi.owner.id);
|
|
235
|
+
if (this.#state === 'paused') {
|
|
236
|
+
throw new Error('The owner has this page in their hands. Wait for them to give it back; you continue when they do.');
|
|
237
|
+
}
|
|
238
|
+
// Parked on a card: nothing is done until the owner answers it.
|
|
239
|
+
if (this.#card) {
|
|
240
|
+
this.#open(request, ctx);
|
|
241
|
+
if (this.#card)
|
|
242
|
+
return this.#cardResult(this.#card, false);
|
|
186
243
|
}
|
|
244
|
+
let run = command;
|
|
245
|
+
let reopened = false;
|
|
246
|
+
if (!this.#session && command.action !== 'navigate' && command.action !== 'open') {
|
|
247
|
+
// No page yet, or the last one was let go: open it again where it was.
|
|
248
|
+
if (!this.#lastUrl || this.#route === 'apps') {
|
|
249
|
+
this.#stop('start-with-navigate', ctx);
|
|
250
|
+
return { completed: false, dispatched: false, notice: UNTRUSTED, message: 'No page is open in this conversation yet. Navigate to the website first.' };
|
|
251
|
+
}
|
|
252
|
+
this.#stop('request-ended', ctx);
|
|
253
|
+
run = { action: 'navigate', url: this.#lastUrl };
|
|
254
|
+
reopened = true;
|
|
255
|
+
}
|
|
256
|
+
this.#open(request, ctx);
|
|
187
257
|
const active = this.#session;
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
258
|
+
if (active.steps >= active.maxSteps || Date.parse(active.expiresAt) <= this.#now()) {
|
|
259
|
+
this.#stop('budget', ctx);
|
|
260
|
+
return this.#cardResult(this.park('budget'), false);
|
|
261
|
+
}
|
|
262
|
+
// The observation is the latest one unless the agent named another.
|
|
263
|
+
if (['click', 'fill', 'select', 'press', 'scroll'].includes(run.action) && run.observation === undefined && this.#observation) {
|
|
264
|
+
run = { ...run, observation: this.#observation.id };
|
|
191
265
|
}
|
|
192
266
|
++active.steps;
|
|
267
|
+
++active.actions;
|
|
193
268
|
this.#busy = true;
|
|
194
|
-
this.#lastAction =
|
|
269
|
+
this.#lastAction = run.action; // Never record form values here.
|
|
270
|
+
this.#lastActivity = this.#now();
|
|
195
271
|
this.#message = undefined;
|
|
196
272
|
const controller = new AbortController();
|
|
197
273
|
this.#controller = controller;
|
|
198
274
|
const cancel = () => {
|
|
199
275
|
controller.abort(ctx.signal?.reason ?? new Error('Browser action stopped.'));
|
|
200
|
-
this.#
|
|
201
|
-
void this.#release('stopped');
|
|
202
|
-
void this.#persistStop(true).catch(() => { });
|
|
276
|
+
void this.#release('idle');
|
|
203
277
|
};
|
|
204
278
|
ctx.signal?.addEventListener('abort', cancel, { once: true });
|
|
205
279
|
try {
|
|
206
280
|
this.#state = 'starting';
|
|
207
281
|
await this.driver.start();
|
|
208
282
|
controller.signal.throwIfAborted();
|
|
209
|
-
ctx.signal?.throwIfAborted();
|
|
210
283
|
this.#state = 'running';
|
|
211
|
-
await this.driver.perform(
|
|
212
|
-
if (
|
|
213
|
-
this.#
|
|
284
|
+
await this.driver.perform(run);
|
|
285
|
+
if (run.action !== 'observe')
|
|
286
|
+
this.#targetingFailures = 0;
|
|
214
287
|
controller.signal.throwIfAborted();
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
controller.signal.throwIfAborted();
|
|
221
|
-
this.#observation = this.#stamp(observation);
|
|
222
|
-
this.#picture = picture;
|
|
223
|
-
this.#needsObservation = false;
|
|
224
|
-
this.#observationFailures = 0;
|
|
288
|
+
const seen = await this.#look(controller, ctx);
|
|
289
|
+
if (!seen) {
|
|
290
|
+
// Six reads over fifteen seconds and nothing: one card, not a loop.
|
|
291
|
+
this.#stop('observation-failures', ctx, 'card');
|
|
292
|
+
return this.#cardResult(this.park('uncertain'), run.action !== 'observe');
|
|
225
293
|
}
|
|
226
|
-
catch (error) {
|
|
227
|
-
controller.signal.throwIfAborted();
|
|
228
|
-
const cause = error instanceof Error ? error.message : String(error);
|
|
229
|
-
const paused = this.#observationFailed(cause);
|
|
230
|
-
// The extension's final error already says to wait and observe again; do not say it twice.
|
|
231
|
-
// The app pushed behind already says how to bring it back.
|
|
232
|
-
const recovery = paused ? browserPausedMessage(ctx.surface) : APP_BEHIND.test(cause) || /observe again\.?$/i.test(cause.trim()) ? '' : browserWaitMessage(ctx.surface);
|
|
233
|
-
this.#message = `${command.action === 'observe' ? 'Observation failed' : 'Action completed, but observation failed'}: ${cause.replace(/\.$/, '')}.${recovery ? ` ${recovery}` : ''}${command.action === 'observe' ? '' : ' Do not repeat the action; its effect may already have happened.'}`;
|
|
234
|
-
const result = { completed: command.action !== 'observe', observed: false, error: cause,
|
|
235
|
-
state: this.#state, recovery, message: this.#message, notice: UNTRUSTED };
|
|
236
|
-
if (command.action === 'observe')
|
|
237
|
-
throw new ObservationFailure(JSON.stringify(result));
|
|
238
|
-
return result;
|
|
239
|
-
}
|
|
240
|
-
controller.signal.throwIfAborted();
|
|
241
294
|
const observed = observedLine(this.#observation.observedAt);
|
|
295
|
+
if (reopened) {
|
|
296
|
+
const asked = command.action;
|
|
297
|
+
return { completed: false, dispatched: false, notice: UNTRUSTED, observation: this.#observation,
|
|
298
|
+
message: `${observed} No page was open, so I opened ${siteOf(this.#lastUrl) ?? 'the last page'} again. Nothing else was done; ${asked === 'observe' ? 'here it is' : 'act on this page now'}.` };
|
|
299
|
+
}
|
|
242
300
|
return { completed: true, notice: UNTRUSTED, observation: this.#observation, message: this.#message ? `${observed} ${this.#message}` : observed };
|
|
243
301
|
}
|
|
244
302
|
catch (error) {
|
|
245
|
-
if (
|
|
303
|
+
if (controller.signal.aborted)
|
|
246
304
|
throw error;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.#
|
|
305
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
306
|
+
if (error instanceof BrowserPreconditionError)
|
|
307
|
+
return await this.#precondition(controller, error, ctx);
|
|
308
|
+
this.#state = 'running';
|
|
309
|
+
if (['click', 'fill', 'select', 'press'].includes(run.action)) {
|
|
310
|
+
// The input may have landed part-way: the owner looks, or tells the agent to judge from the page.
|
|
311
|
+
this.#stop('uncertain-input', ctx, 'card');
|
|
312
|
+
this.#observation = undefined;
|
|
313
|
+
this.#picture = undefined;
|
|
314
|
+
return this.#cardResult(this.park('uncertain'), true, `${message.replace(/\.$/, '')}. I'm not sure that went through. Say so in one sentence and stop; the card asks the owner whether to look.`);
|
|
254
315
|
}
|
|
316
|
+
this.#message = message;
|
|
255
317
|
throw error;
|
|
256
318
|
}
|
|
257
319
|
finally {
|
|
@@ -262,201 +324,172 @@ export class BrowserService {
|
|
|
262
324
|
}
|
|
263
325
|
}
|
|
264
326
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
* Returns whether it paused.
|
|
327
|
+
* Read the page, re-reading at 0.5, 1, 2, 4 and 8 seconds when it does not
|
|
328
|
+
* answer. A closed tab is opened again at its last address once. False when
|
|
329
|
+
* all six reads failed. The app pushed behind the owner's window is said
|
|
330
|
+
* straight away: open brings it back and no wait helps.
|
|
270
331
|
*/
|
|
271
|
-
#
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
332
|
+
async #look(controller, ctx) {
|
|
333
|
+
const delays = this.options.retryDelays ?? RETRY_DELAYS_MS;
|
|
334
|
+
let reopened = false;
|
|
335
|
+
let counted = false;
|
|
336
|
+
for (let attempt = 0; attempt <= delays.length; attempt++) {
|
|
337
|
+
if (attempt > 0)
|
|
338
|
+
await this.#sleep(delays[attempt - 1]);
|
|
339
|
+
controller.signal.throwIfAborted();
|
|
340
|
+
try {
|
|
341
|
+
const observation = await this.driver.observe();
|
|
342
|
+
const picture = await this.driver.screenshot();
|
|
343
|
+
controller.signal.throwIfAborted();
|
|
344
|
+
this.#observation = this.#stamp(observation);
|
|
345
|
+
this.#picture = picture;
|
|
346
|
+
if (observation.url)
|
|
347
|
+
this.#lastUrl = observation.url;
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
controller.signal.throwIfAborted();
|
|
352
|
+
const cause = error instanceof Error ? error.message : String(error);
|
|
353
|
+
this.#observation = undefined;
|
|
354
|
+
this.#picture = undefined;
|
|
355
|
+
if (APP_BEHIND.test(cause)) {
|
|
356
|
+
this.#stop('app-behind', ctx);
|
|
357
|
+
throw new BrowserPreconditionError(cause);
|
|
358
|
+
}
|
|
359
|
+
if (SCREEN_GONE.test(cause) && !reopened && this.#lastUrl && this.#route !== 'apps') {
|
|
360
|
+
reopened = true;
|
|
361
|
+
this.#stop('screen-gone', ctx);
|
|
362
|
+
try {
|
|
363
|
+
await this.driver.perform({ action: 'navigate', url: this.#lastUrl });
|
|
364
|
+
}
|
|
365
|
+
catch { /* the next read says */ }
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (!counted) {
|
|
369
|
+
counted = true;
|
|
370
|
+
this.#stop('page-not-answered', ctx);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
280
373
|
}
|
|
281
|
-
|
|
282
|
-
this.#state = paused ? 'paused' : 'running';
|
|
283
|
-
return paused;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* A new owner message continues the session under that message's request:
|
|
287
|
-
* the old one is spent, the step budget and the failure count reset, and the
|
|
288
|
-
* expiry runs from now. The session id survives, so the conversation still
|
|
289
|
-
* owns the same screen it always did.
|
|
290
|
-
*/
|
|
291
|
-
#rekey(request, agentId, conversationId, ownerId) {
|
|
292
|
-
const expiresAt = Math.min(request.expiresAt, this.#now() + (this.options.lifetimeMs ?? 20 * 60_000));
|
|
293
|
-
if (this.#session)
|
|
294
|
-
this.#spent.add(this.#session.requestId);
|
|
295
|
-
this.#preconditionFailures = 0;
|
|
296
|
-
this.#session = { id: this.#session?.id ?? randomUUID(), ownerId, agentId,
|
|
297
|
-
conversationId, requestId: request.id, task: request.text.slice(0, 4000),
|
|
298
|
-
expiresAt: new Date(expiresAt).toISOString(), steps: 0, maxSteps: this.options.maxSteps ?? 80 };
|
|
299
|
-
clearTimeout(this.#expiry);
|
|
300
|
-
this.#expiry = setTimeout(() => { void this.#release('expired'); }, Math.max(1, expiresAt - this.#now()));
|
|
301
|
-
this.#expiry.unref?.();
|
|
374
|
+
return false;
|
|
302
375
|
}
|
|
303
376
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
* fresh
|
|
307
|
-
*
|
|
377
|
+
* Refused before anything was dispatched: a stale observation, a ref that
|
|
378
|
+
* no longer matches, a page that moved. The tool looks again and answers
|
|
379
|
+
* with the fresh page; nothing pauses. Eight in a row asks the owner
|
|
380
|
+
* whether to keep going. The owner looking at the tab and the app behind
|
|
381
|
+
* their window are said as what they are.
|
|
308
382
|
*/
|
|
309
|
-
async #precondition(controller, error) {
|
|
383
|
+
async #precondition(controller, error, ctx) {
|
|
384
|
+
this.#state = 'running';
|
|
310
385
|
if (OWNER_WATCHING.test(error.message)) {
|
|
311
|
-
|
|
312
|
-
// moving to another tab does. No pause and no count; the next action
|
|
313
|
-
// must observe first, so the model asks once instead of retrying.
|
|
386
|
+
this.#stop('owner-watching', ctx);
|
|
314
387
|
this.#message = OWNER_WATCHING_MESSAGE;
|
|
315
|
-
|
|
316
|
-
this.#needsObservation = true;
|
|
317
|
-
throw new BrowserPreconditionError(JSON.stringify({ error: OWNER_WATCHING_MESSAGE, dispatched: false,
|
|
318
|
-
recovery: 'Ask the owner now and wait for their answer. Do not retry by yourself.' }));
|
|
388
|
+
throw new BrowserPreconditionError(JSON.stringify({ error: OWNER_WATCHING_MESSAGE, dispatched: false }));
|
|
319
389
|
}
|
|
320
390
|
if (APP_BEHIND.test(error.message)) {
|
|
321
|
-
// The owner's own window came forward (typing in the dashboard does it).
|
|
322
|
-
// Not a targeting failure and nothing for the owner to do: the agent
|
|
323
|
-
// calls open for the same app. No count, no pause, and no recovery
|
|
324
|
-
// observation, which would only be refused the same way.
|
|
325
391
|
this.#message = error.message;
|
|
326
|
-
this.#state = 'running';
|
|
327
392
|
this.#observation = undefined;
|
|
328
393
|
this.#picture = undefined;
|
|
329
|
-
this.#needsObservation = true;
|
|
330
394
|
throw new BrowserPreconditionError(JSON.stringify({ error: error.message, dispatched: false,
|
|
331
|
-
recovery: 'Call browser.act open with the same app now; it needs no approval.
|
|
395
|
+
recovery: 'Call browser.act open with the same app now; it needs no approval. It returns the app as it is.' }));
|
|
332
396
|
}
|
|
397
|
+
const cause = /stale|latest observation/i.test(error.message) ? 'stale-observation'
|
|
398
|
+
: /changed since|moved|redirect|different page/i.test(error.message) ? 'redirect' : 'stale-ref';
|
|
399
|
+
this.#stop(cause, ctx);
|
|
333
400
|
this.#message = error.message;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
this.#
|
|
337
|
-
// Recover evidence, never replay input. Keep this a failed tool result
|
|
338
|
-
// so the runtime skips any remaining sequential calls in this batch.
|
|
339
|
-
try {
|
|
340
|
-
const observation = await this.driver.observe();
|
|
341
|
-
const picture = await this.driver.screenshot();
|
|
342
|
-
controller.signal.throwIfAborted();
|
|
343
|
-
this.#observation = this.#stamp(observation);
|
|
344
|
-
this.#picture = picture;
|
|
345
|
-
this.#observationFailures = 0;
|
|
346
|
-
}
|
|
347
|
-
catch (observationError) {
|
|
348
|
-
controller.signal.throwIfAborted();
|
|
349
|
-
const cause = observationError instanceof Error ? observationError.message : String(observationError);
|
|
350
|
-
const targeting = this.#state === 'paused';
|
|
351
|
-
const paused = this.#observationFailed(cause) || targeting;
|
|
352
|
-
if (paused)
|
|
353
|
-
this.#state = 'paused';
|
|
354
|
-
this.#message += ` Recovery observation failed: ${cause.replace(/\.$/, '')}.${paused ? ' Inspect the selected app/window and this error, then resume and observe. Do not retry while paused.' : APP_BEHIND.test(cause) ? '' : ` ${browserWaitMessage()}`}`;
|
|
401
|
+
if (++this.#targetingFailures >= MAX_TARGETING_FAILURES) {
|
|
402
|
+
this.#stop('targeting-cap', ctx, 'card');
|
|
403
|
+
return this.#cardResult(this.park('budget'), false);
|
|
355
404
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
405
|
+
const seen = await this.#look(controller, ctx).catch(() => false);
|
|
406
|
+
throw new BrowserPreconditionError(JSON.stringify({ error: error.message, dispatched: false,
|
|
407
|
+
...(seen && this.#observation?.observedAt ? { message: `${observedLine(this.#observation.observedAt)} The page changed; here it is now.` } : {}),
|
|
408
|
+
recovery: seen ? 'Nothing was done. Re-evaluate from the page below and act on it; prefer target:{ref:"..."} from it.' : browserWaitMessage(),
|
|
409
|
+
...(seen ? { observation: this.#observation } : {}) }));
|
|
360
410
|
}
|
|
361
411
|
/**
|
|
362
|
-
* The authority shell the secret tools run under:
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* budget — and its start sequence and precondition path. A secret fill is a
|
|
366
|
-
* browser action like any other; only the value's route differs.
|
|
412
|
+
* The authority shell the secret tools run under: the same page, budget and
|
|
413
|
+
* card rules as `execute`. A secret fill is a browser action like any other;
|
|
414
|
+
* only the value's route differs.
|
|
367
415
|
*/
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const request = ctx.ownerRequest;
|
|
371
|
-
if (!request || !request.id || !request.text.trim() || request.expiresAt <= this.#now() ||
|
|
372
|
-
!ctx.agentId || !ctx.conversationId || (ctx.delegationDepth ?? 0) > 0) {
|
|
373
|
-
throw new Error('A current authenticated owner request is required.');
|
|
374
|
-
}
|
|
375
|
-
if (!this.#enabled)
|
|
376
|
-
throw new Error('Browser driving is available through buddi serve (dashboard or Telegram), not a separate CLI process.');
|
|
377
|
-
if (this.#state === 'stopped')
|
|
378
|
-
throw new Error(browserStoppedMessage(ctx.surface));
|
|
379
|
-
if (this.#busy)
|
|
380
|
-
throw new Error('Browser is busy; overlapping actions are refused.');
|
|
381
|
-
if (this.#session && (this.#session.ownerId !== ctx.buddi.owner.id || this.#session.agentId !== ctx.agentId || this.#session.conversationId !== ctx.conversationId)) {
|
|
382
|
-
throw new Error('Another agent/conversation owns the browser. Ask the owner to release it from the dashboard.');
|
|
383
|
-
}
|
|
384
|
-
if (this.#spent.has(request.id))
|
|
385
|
-
throw new Error('This browser request has ended. A new owner message is required.');
|
|
386
|
-
if (this.#state === 'paused')
|
|
387
|
-
throw new Error('Browser is under human control or needs inspection. Wait for the owner to resume in the dashboard, then observe.');
|
|
388
|
-
if (this.#needsObservation)
|
|
389
|
-
throw new Error('A fresh observation is required: observe the current page before acting. Do not replay an earlier action.');
|
|
390
|
-
if (!this.#session)
|
|
391
|
-
throw new Error('Start with navigate, or open an allowed application, and observe before using a secret here.');
|
|
392
|
-
if (this.#session.requestId !== request.id)
|
|
393
|
-
this.#rekey(request, ctx.agentId, ctx.conversationId, ctx.buddi.owner.id);
|
|
394
|
-
const active = this.#session;
|
|
395
|
-
if (!active || Date.parse(active.expiresAt) <= this.#now() || active.steps >= active.maxSteps) {
|
|
396
|
-
await this.#release('expired');
|
|
397
|
-
throw new Error('Browser task reached its time or step limit. Ask the owner for a new request.');
|
|
398
|
-
}
|
|
399
|
-
++active.steps;
|
|
400
|
-
this.#busy = true;
|
|
401
|
-
this.#lastAction = action;
|
|
402
|
-
this.#message = undefined;
|
|
403
|
-
const controller = new AbortController();
|
|
404
|
-
this.#controller = controller;
|
|
405
|
-
const cancel = () => {
|
|
406
|
-
controller.abort(ctx.signal?.reason ?? new Error('Browser action stopped.'));
|
|
407
|
-
this.#spent.add(request.id);
|
|
408
|
-
void this.#release('stopped');
|
|
409
|
-
void this.#persistStop(true).catch(() => { });
|
|
410
|
-
};
|
|
411
|
-
ctx.signal?.addEventListener('abort', cancel, { once: true });
|
|
412
|
-
try {
|
|
413
|
-
this.#state = 'starting';
|
|
414
|
-
await this.driver.start();
|
|
415
|
-
controller.signal.throwIfAborted();
|
|
416
|
+
#under(ctx, action, run) {
|
|
417
|
+
return this.#serial(async () => {
|
|
416
418
|
ctx.signal?.throwIfAborted();
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
if (
|
|
422
|
-
|
|
419
|
+
if (!ctx.agentId || !ctx.conversationId)
|
|
420
|
+
throw new Error('A browser action belongs to an agent and a conversation.');
|
|
421
|
+
if (!this.#enabled)
|
|
422
|
+
throw new Error('Browser driving is available through buddi serve (dashboard or Telegram), not a separate CLI process.');
|
|
423
|
+
if (this.#state === 'stopped')
|
|
424
|
+
throw new Error(browserStoppedMessage(ctx.surface));
|
|
425
|
+
if (this.#session && (this.#session.ownerId !== ctx.buddi.owner.id || this.#session.agentId !== ctx.agentId || this.#session.conversationId !== ctx.conversationId)) {
|
|
426
|
+
throw new Error('Another conversation owns this page.');
|
|
423
427
|
}
|
|
424
|
-
if (
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
428
|
+
if (this.#state === 'paused')
|
|
429
|
+
throw new Error('The owner has this page in their hands. Wait for them to give it back.');
|
|
430
|
+
if (!this.#session)
|
|
431
|
+
throw new Error('Open the page with browser.act navigate before using a secret here.');
|
|
432
|
+
this.#open(ctx.ownerRequest, ctx);
|
|
433
|
+
if (this.#card)
|
|
434
|
+
return this.#cardResult(this.#card, false);
|
|
435
|
+
const active = this.#session;
|
|
436
|
+
if (active.steps >= active.maxSteps || Date.parse(active.expiresAt) <= this.#now()) {
|
|
437
|
+
this.#stop('budget', ctx);
|
|
438
|
+
return this.#cardResult(this.park('budget'), false);
|
|
430
439
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
440
|
+
++active.steps;
|
|
441
|
+
++active.actions;
|
|
442
|
+
this.#busy = true;
|
|
443
|
+
this.#lastAction = action;
|
|
444
|
+
this.#lastActivity = this.#now();
|
|
445
|
+
this.#message = undefined;
|
|
446
|
+
const controller = new AbortController();
|
|
447
|
+
this.#controller = controller;
|
|
448
|
+
const cancel = () => { controller.abort(ctx.signal?.reason ?? new Error('Browser action stopped.')); void this.#release('idle'); };
|
|
449
|
+
ctx.signal?.addEventListener('abort', cancel, { once: true });
|
|
450
|
+
try {
|
|
451
|
+
this.#state = 'starting';
|
|
452
|
+
await this.driver.start();
|
|
453
|
+
controller.signal.throwIfAborted();
|
|
454
|
+
this.#state = 'running';
|
|
455
|
+
return await run(controller);
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
if (controller.signal.aborted)
|
|
459
|
+
throw error;
|
|
460
|
+
if (error instanceof BrowserPreconditionError)
|
|
461
|
+
return await this.#precondition(controller, error, ctx);
|
|
462
|
+
// The value may be part-way into the field: the owner looks.
|
|
463
|
+
this.#state = 'running';
|
|
464
|
+
this.#stop('uncertain-input', ctx, 'card');
|
|
465
|
+
return this.#cardResult(this.park('uncertain'), true, `${error instanceof Error ? error.message.replace(/\.$/, '') : String(error)}. I'm not sure that went through.`);
|
|
466
|
+
}
|
|
467
|
+
finally {
|
|
468
|
+
ctx.signal?.removeEventListener('abort', cancel);
|
|
469
|
+
if (this.#controller === controller)
|
|
470
|
+
this.#controller = undefined;
|
|
471
|
+
this.#busy = false;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
/** After a fill or typing the page changed: answer with it, as every action does. */
|
|
476
|
+
async #after(controller, ctx, result) {
|
|
477
|
+
const seen = await this.#look(controller, ctx).catch(() => false);
|
|
478
|
+
return seen ? { ...result, observation: this.#observation, message: observedLine(this.#observation.observedAt) } : result;
|
|
439
479
|
}
|
|
440
480
|
/**
|
|
441
481
|
* One owner secret into one field of the page this conversation drives
|
|
442
|
-
* (docs/owner-secrets.md §3, §4).
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
* origin, its password mark and its accessible name from the live page — the
|
|
446
|
-
* backend reports, the agent never claims (§8) — then core finds the binding,
|
|
447
|
-
* the destination checks that target against it, the rule is applied and the
|
|
448
|
-
* vault read, and the destination's `deliver` parks the value against the use
|
|
449
|
-
* id. Only then does the driver fill, re-checking the origin once more
|
|
450
|
-
* against what the use was delivered for. The result is `{ filled: true }`
|
|
451
|
-
* or a pending card; a refusal is the refusal's own sentence, and a value
|
|
452
|
-
* appears in none of them.
|
|
482
|
+
* (docs/owner-secrets.md §3, §4). The driver reads the field's frame origin,
|
|
483
|
+
* its password mark and its name from the live page; core finds the binding
|
|
484
|
+
* and the destination checks it; the value crosses only into the fill.
|
|
453
485
|
*/
|
|
454
486
|
async secretFill(input, ctx) {
|
|
455
|
-
return this.#under(ctx, 'secret.fill', async () => {
|
|
487
|
+
return this.#under(ctx, 'secret.fill', async (controller) => {
|
|
456
488
|
if (typeof this.driver.secretFieldInfo !== 'function' || typeof this.driver.secretFillField !== 'function') {
|
|
457
|
-
throw new BrowserPreconditionError('secret.fill works
|
|
489
|
+
throw new BrowserPreconditionError('secret.fill works on web pages (buddi\'s own browser or your Chrome); an app window has no page fields to fill.');
|
|
458
490
|
}
|
|
459
|
-
const
|
|
491
|
+
const observation = input.observation ?? this.#observation?.id ?? '';
|
|
492
|
+
const facts = await this.driver.secretFieldInfo(observation, input.ref);
|
|
460
493
|
const secrets = ctx.buddi?.secrets;
|
|
461
494
|
if (secrets === undefined)
|
|
462
495
|
throw new Error('This plugin has no secrets area; the owner updates the browser plugin to one that declares it.');
|
|
@@ -464,12 +497,10 @@ export class BrowserService {
|
|
|
464
497
|
if (secret === undefined) {
|
|
465
498
|
throw new BrowserPreconditionError(`There is no secret named "${input.name}" bound to this browser's destinations. The owner keeps one in Settings, under Keys and secrets.`);
|
|
466
499
|
}
|
|
467
|
-
// A visible field on an origin the owner bound as browser.field takes
|
|
468
|
-
// that binding; the card then names the field (§3).
|
|
469
500
|
const visibleField = !secret.totp && !facts.password && fieldBoundTo(secret.bindings, facts.origin);
|
|
470
501
|
const kind = secretKindFor(secret.totp, facts.password, visibleField);
|
|
471
502
|
if (kind === FORM_KIND && facts.name.trim() === '') {
|
|
472
|
-
throw new BrowserPreconditionError('That field has no name the page gives it, so it cannot be a form-field destination.
|
|
503
|
+
throw new BrowserPreconditionError('That field has no name the page gives it, so it cannot be a form-field destination. Pick another ref, or ask the owner to bind the secret to the page instead.');
|
|
473
504
|
}
|
|
474
505
|
const named = { origin: facts.origin, field: facts.name };
|
|
475
506
|
const target = kind === FORM_KIND || (visibleField && facts.name.trim() !== '') ? named : facts.origin;
|
|
@@ -482,26 +513,15 @@ export class BrowserService {
|
|
|
482
513
|
const value = takeDelivered(outcome.use);
|
|
483
514
|
if (value === undefined)
|
|
484
515
|
throw new Error('The use delivered nothing to fill with. Ask for the secret again.');
|
|
485
|
-
await this.driver.secretFillField(
|
|
486
|
-
this.#
|
|
487
|
-
return { filled: true };
|
|
516
|
+
await this.driver.secretFillField(observation, input.ref, value, facts.origin);
|
|
517
|
+
return this.#after(controller, ctx, { filled: true });
|
|
488
518
|
});
|
|
489
519
|
}
|
|
490
|
-
/**
|
|
491
|
-
* One owner secret typed into the focused field of the focused app
|
|
492
|
-
* (owner-secrets.md §3, native typing).
|
|
493
|
-
*
|
|
494
|
-
* The bundle id is the backend's answer about whatever app is in front right
|
|
495
|
-
* now, and the helper re-checks it before the first keystroke, so an app
|
|
496
|
-
* switch between the owner's approval and the typing refuses with nothing
|
|
497
|
-
* typed. There is no observed target here — the field is whatever the owner
|
|
498
|
-
* left focused — which is why the destination's loosest rule is a card every
|
|
499
|
-
* time.
|
|
500
|
-
*/
|
|
520
|
+
/** One owner secret typed into the focused field of the focused app (owner-secrets.md §3, native typing). */
|
|
501
521
|
async secretType(input, ctx) {
|
|
502
|
-
return this.#under(ctx, 'secret.type', async () => {
|
|
522
|
+
return this.#under(ctx, 'secret.type', async (controller) => {
|
|
503
523
|
if (typeof this.driver.focusedBundleId !== 'function' || typeof this.driver.nativeType !== 'function') {
|
|
504
|
-
throw new BrowserPreconditionError('secret.type
|
|
524
|
+
throw new BrowserPreconditionError('secret.type types into an app on this machine; a web page takes secret.fill instead.');
|
|
505
525
|
}
|
|
506
526
|
const bundleId = await this.driver.focusedBundleId();
|
|
507
527
|
if (!bundleId)
|
|
@@ -519,32 +539,10 @@ export class BrowserService {
|
|
|
519
539
|
if (value === undefined)
|
|
520
540
|
throw new Error('The use delivered nothing to type. Ask for the secret again.');
|
|
521
541
|
await this.driver.nativeType(value);
|
|
522
|
-
this.#
|
|
523
|
-
return { typed: true };
|
|
542
|
+
return this.#after(controller, ctx, { typed: true });
|
|
524
543
|
});
|
|
525
544
|
}
|
|
526
|
-
|
|
527
|
-
if (!this.options.controlFile)
|
|
528
|
-
return;
|
|
529
|
-
const file = this.options.controlFile;
|
|
530
|
-
const write = async () => {
|
|
531
|
-
await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
532
|
-
const temp = `${file}.${randomUUID()}.tmp`;
|
|
533
|
-
await writeFile(temp, JSON.stringify({ stopped }), { mode: 0o600 });
|
|
534
|
-
await rename(temp, file);
|
|
535
|
-
};
|
|
536
|
-
const next = this.#diskTail.then(write, write);
|
|
537
|
-
this.#diskTail = next.catch(() => { });
|
|
538
|
-
await next;
|
|
539
|
-
}
|
|
540
|
-
/**
|
|
541
|
-
* Stop the action, keep the screen if the driver can.
|
|
542
|
-
*
|
|
543
|
-
* True when there is still something to drive afterwards. A driver with no
|
|
544
|
-
* `interrupt` — or one whose page really did go — has its screen closed
|
|
545
|
-
* instead, which is the old behaviour and still the honest answer when there
|
|
546
|
-
* is nothing left to paint.
|
|
547
|
-
*/
|
|
545
|
+
/** Stop the action, keep the screen if the driver can. True when there is still something to drive. */
|
|
548
546
|
async #interrupt() {
|
|
549
547
|
if (!this.driver.interrupt) {
|
|
550
548
|
await this.driver.close().catch(() => { });
|
|
@@ -560,11 +558,15 @@ export class BrowserService {
|
|
|
560
558
|
return this.driver.handReady?.() !== false;
|
|
561
559
|
}
|
|
562
560
|
async #release(state) {
|
|
563
|
-
|
|
561
|
+
const session = this.#session;
|
|
562
|
+
if (session && this.options.telemetry) {
|
|
563
|
+
this.options.telemetry.record({ type: 'browser.task', outcome: this.#card ? (this.#card.kind === 'budget' ? 'budget' : 'needs-owner') : state === 'stopped' ? 'stopped' : 'done',
|
|
564
|
+
actions: session.actions, seconds: Math.round((this.#now() - session.startedAt) / 1000), cards: session.cards, agent: session.agentId, route: this.#route, ...(session.requestId === 'unattended' ? { mission: true } : {}) });
|
|
565
|
+
}
|
|
566
|
+
if (this.#observation?.url)
|
|
567
|
+
this.#lastUrl = this.#observation.url;
|
|
564
568
|
this.#handless = false;
|
|
565
569
|
this.#state = state;
|
|
566
|
-
if (this.#session)
|
|
567
|
-
this.#spent.add(this.#session.requestId);
|
|
568
570
|
this.#controller?.abort(new Error(`Browser ${state}. An in-flight submission may have completed; inspect before retrying.`));
|
|
569
571
|
clearTimeout(this.#expiry);
|
|
570
572
|
this.#session = undefined;
|
|
@@ -572,8 +574,8 @@ export class BrowserService {
|
|
|
572
574
|
this.#picture = undefined;
|
|
573
575
|
this.#lastAction = undefined;
|
|
574
576
|
this.#message = undefined;
|
|
575
|
-
this.#
|
|
576
|
-
this.#
|
|
577
|
+
this.#card = undefined;
|
|
578
|
+
this.#targetingFailures = 0;
|
|
577
579
|
await this.driver.close();
|
|
578
580
|
}
|
|
579
581
|
/** Only authenticated owner UI handlers call this; it is not an agent tool. */
|
|
@@ -582,59 +584,46 @@ export class BrowserService {
|
|
|
582
584
|
if (!this.#enabled)
|
|
583
585
|
throw new Error('The host browser service is unavailable.');
|
|
584
586
|
if (expectedSessionId !== undefined && this.#session?.id !== expectedSessionId) {
|
|
585
|
-
throw new Error('The
|
|
587
|
+
throw new Error('The page changed. Refresh before controlling it.');
|
|
586
588
|
}
|
|
587
589
|
if (action === 'stop') {
|
|
588
|
-
|
|
589
|
-
const closing = this.#release('stopped');
|
|
590
|
-
await this.#persistStop(true);
|
|
591
|
-
await closing;
|
|
590
|
+
await this.#release('stopped');
|
|
592
591
|
}
|
|
593
592
|
else if (action === 'takeover') {
|
|
594
593
|
this.#state = 'paused';
|
|
595
594
|
this.#message = undefined;
|
|
595
|
+
this.#card = undefined;
|
|
596
596
|
if (this.#busy) {
|
|
597
|
-
//
|
|
598
|
-
//
|
|
599
|
-
// going round on it. That page is the whole point of the button, so
|
|
600
|
-
// the action is abandoned and the page is kept. Every branch of
|
|
601
|
-
// `execute` that would otherwise decide what this failure means is
|
|
602
|
-
// guarded by `controller.signal.aborted`, so aborting here is also
|
|
603
|
-
// what stops the interrupted command from overwriting `paused`.
|
|
597
|
+
// Take over is pressed most often *while* the agent works on a login:
|
|
598
|
+
// the action is abandoned and the page kept, when the driver can.
|
|
604
599
|
this.#controller?.abort(new Error('Owner took control during an action. Inspect the site before retrying.'));
|
|
605
600
|
this.#picture = undefined;
|
|
606
601
|
this.#observation = undefined;
|
|
607
|
-
this.#needsObservation = !!this.#session;
|
|
608
602
|
const kept = await this.#interrupt();
|
|
609
603
|
this.#handless = !kept;
|
|
610
604
|
this.#message = kept
|
|
611
|
-
? 'The in
|
|
612
|
-
: this.driver.preservesWindows ? 'Computer input was interrupted. Your apps remain open.
|
|
605
|
+
? 'The action in flight was stopped; the page is yours. Give it back when you are done.'
|
|
606
|
+
: this.driver.preservesWindows ? 'Computer input was interrupted. Your apps remain open. Give it back when you are done.' : 'The action in flight was stopped and the window closed. Give it back and the agent opens the page again.';
|
|
613
607
|
}
|
|
614
608
|
else {
|
|
615
609
|
await this.driver.takeover?.();
|
|
616
|
-
this.#message = this.driver.preservesWindows ? '
|
|
610
|
+
this.#message = this.driver.preservesWindows ? 'The app is yours. Give it back when you are done.' : 'The page is yours. Give it back when you are done.';
|
|
617
611
|
}
|
|
618
612
|
}
|
|
619
613
|
else if (action === 'resume') {
|
|
620
614
|
if (this.#busy)
|
|
621
|
-
throw new Error('Wait for the interrupted action to settle before
|
|
622
|
-
await this.#persistStop(false);
|
|
615
|
+
throw new Error('Wait for the interrupted action to settle before giving it back.');
|
|
623
616
|
this.driver.resume?.();
|
|
624
617
|
this.#handless = false;
|
|
625
|
-
this.#preconditionFailures = 0;
|
|
626
|
-
this.#observationFailures = 0;
|
|
627
618
|
this.#observation = undefined;
|
|
628
619
|
this.#picture = undefined;
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
await this.#release('idle');
|
|
620
|
+
// The owner acted: a fresh budget, and the agent's next action returns the page as the owner left it.
|
|
621
|
+
this.renew();
|
|
632
622
|
this.#state = this.#session ? 'running' : 'idle';
|
|
633
|
-
this.#message = '
|
|
623
|
+
this.#message = 'Given back. The agent carries on from the page as you left it.';
|
|
634
624
|
}
|
|
635
625
|
else {
|
|
636
|
-
|
|
637
|
-
await this.#release(stopped ? 'stopped' : 'idle');
|
|
626
|
+
await this.#release(this.#state === 'stopped' ? 'stopped' : 'idle');
|
|
638
627
|
}
|
|
639
628
|
return this.status();
|
|
640
629
|
};
|