@openagt/dashboard 0.0.0-stage → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +125 -2
- package/dist/agent-id.d.ts +13 -0
- package/dist/agent-id.d.ts.map +1 -0
- package/dist/agent-id.js +20 -0
- package/dist/agent-id.js.map +1 -0
- package/dist/agent-locks.d.ts +3 -0
- package/dist/agent-locks.d.ts.map +1 -0
- package/dist/agent-locks.js +40 -0
- package/dist/agent-locks.js.map +1 -0
- package/dist/agent-view.d.ts +39 -0
- package/dist/agent-view.d.ts.map +1 -0
- package/dist/agent-view.js +45 -0
- package/dist/agent-view.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +11 -0
- package/dist/bin.js.map +1 -0
- package/dist/branch-name.d.ts +8 -0
- package/dist/branch-name.d.ts.map +1 -0
- package/dist/branch-name.js +20 -0
- package/dist/branch-name.js.map +1 -0
- package/dist/bridge-browser.d.ts +217 -0
- package/dist/bridge-browser.d.ts.map +1 -0
- package/dist/bridge-browser.js +520 -0
- package/dist/bridge-browser.js.map +1 -0
- package/dist/browser-stream.d.ts +20 -0
- package/dist/browser-stream.d.ts.map +1 -0
- package/dist/browser-stream.js +51 -0
- package/dist/browser-stream.js.map +1 -0
- package/dist/browser.d.ts +16 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +38 -0
- package/dist/browser.js.map +1 -0
- package/dist/built-in.d.ts +38 -0
- package/dist/built-in.d.ts.map +1 -0
- package/dist/built-in.js +119 -0
- package/dist/built-in.js.map +1 -0
- package/dist/chrome-extension/background.js +532 -0
- package/dist/chrome-extension/content.js +1475 -0
- package/dist/chrome-extension/driver-plan.js +41 -0
- package/dist/chrome-extension/fingerprint.js +43 -0
- package/dist/chrome-extension/manifest.json +31 -0
- package/dist/chrome-extension/options.html +48 -0
- package/dist/chrome-extension/options.js +122 -0
- package/dist/cli.d.ts +43 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +186 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +16 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +30 -0
- package/dist/client.js.map +1 -0
- package/dist/cloud-run-state.d.ts +27 -0
- package/dist/cloud-run-state.d.ts.map +1 -0
- package/dist/cloud-run-state.js +36 -0
- package/dist/cloud-run-state.js.map +1 -0
- package/dist/cloud-scratch-refs.d.ts +85 -0
- package/dist/cloud-scratch-refs.d.ts.map +1 -0
- package/dist/cloud-scratch-refs.js +275 -0
- package/dist/cloud-scratch-refs.js.map +1 -0
- package/dist/cloud-work.d.ts +66 -0
- package/dist/cloud-work.d.ts.map +1 -0
- package/dist/cloud-work.js +204 -0
- package/dist/cloud-work.js.map +1 -0
- package/dist/daemon-runtime.d.ts +42 -0
- package/dist/daemon-runtime.d.ts.map +1 -0
- package/dist/daemon-runtime.js +183 -0
- package/dist/daemon-runtime.js.map +1 -0
- package/dist/daemon-services.d.ts +37 -0
- package/dist/daemon-services.d.ts.map +1 -0
- package/dist/daemon-services.js +126 -0
- package/dist/daemon-services.js.map +1 -0
- package/dist/daemon-tick.d.ts +68 -0
- package/dist/daemon-tick.d.ts.map +1 -0
- package/dist/daemon-tick.js +97 -0
- package/dist/daemon-tick.js.map +1 -0
- package/dist/daemon.d.ts +65 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +202 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dashboard/activity.d.ts +41 -0
- package/dist/dashboard/activity.d.ts.map +1 -0
- package/dist/dashboard/activity.js +56 -0
- package/dist/dashboard/activity.js.map +1 -0
- package/dist/dashboard/agent-handoff.d.ts +244 -0
- package/dist/dashboard/agent-handoff.d.ts.map +1 -0
- package/dist/dashboard/agent-handoff.js +310 -0
- package/dist/dashboard/agent-handoff.js.map +1 -0
- package/dist/dashboard/bridge-endpoints.d.ts +158 -0
- package/dist/dashboard/bridge-endpoints.d.ts.map +1 -0
- package/dist/dashboard/bridge-endpoints.js +382 -0
- package/dist/dashboard/bridge-endpoints.js.map +1 -0
- package/dist/dashboard/bridge-question.d.ts +33 -0
- package/dist/dashboard/bridge-question.d.ts.map +1 -0
- package/dist/dashboard/bridge-question.js +20 -0
- package/dist/dashboard/bridge-question.js.map +1 -0
- package/dist/dashboard/bridge-sessions.d.ts +25 -0
- package/dist/dashboard/bridge-sessions.d.ts.map +1 -0
- package/dist/dashboard/bridge-sessions.js +46 -0
- package/dist/dashboard/bridge-sessions.js.map +1 -0
- package/dist/dashboard/bridge-starts.d.ts +61 -0
- package/dist/dashboard/bridge-starts.d.ts.map +1 -0
- package/dist/dashboard/bridge-starts.js +94 -0
- package/dist/dashboard/bridge-starts.js.map +1 -0
- package/dist/dashboard/bridge-store.d.ts +179 -0
- package/dist/dashboard/bridge-store.d.ts.map +1 -0
- package/dist/dashboard/bridge-store.js +262 -0
- package/dist/dashboard/bridge-store.js.map +1 -0
- package/dist/dashboard/bundle.d.ts +12 -0
- package/dist/dashboard/bundle.d.ts.map +1 -0
- package/dist/dashboard/bundle.js +22 -0
- package/dist/dashboard/bundle.js.map +1 -0
- package/dist/dashboard/cache.d.ts +47 -0
- package/dist/dashboard/cache.d.ts.map +1 -0
- package/dist/dashboard/cache.js +87 -0
- package/dist/dashboard/cache.js.map +1 -0
- package/dist/dashboard/content-type.d.ts +3 -0
- package/dist/dashboard/content-type.d.ts.map +1 -0
- package/dist/dashboard/content-type.js +31 -0
- package/dist/dashboard/content-type.js.map +1 -0
- package/dist/dashboard/dashboard.d.ts +38 -0
- package/dist/dashboard/dashboard.d.ts.map +1 -0
- package/dist/dashboard/dashboard.js +42 -0
- package/dist/dashboard/dashboard.js.map +1 -0
- package/dist/dashboard/docs.d.ts +39 -0
- package/dist/dashboard/docs.d.ts.map +1 -0
- package/dist/dashboard/docs.js +59 -0
- package/dist/dashboard/docs.js.map +1 -0
- package/dist/dashboard/git-status.d.ts +44 -0
- package/dist/dashboard/git-status.d.ts.map +1 -0
- package/dist/dashboard/git-status.js +37 -0
- package/dist/dashboard/git-status.js.map +1 -0
- package/dist/dashboard/http.d.ts +29 -0
- package/dist/dashboard/http.d.ts.map +1 -0
- package/dist/dashboard/http.js +74 -0
- package/dist/dashboard/http.js.map +1 -0
- package/dist/dashboard/index.d.ts +24 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +23 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/interventions.d.ts +67 -0
- package/dist/dashboard/interventions.d.ts.map +1 -0
- package/dist/dashboard/interventions.js +169 -0
- package/dist/dashboard/interventions.js.map +1 -0
- package/dist/dashboard/keyed-watcher.d.ts +29 -0
- package/dist/dashboard/keyed-watcher.d.ts.map +1 -0
- package/dist/dashboard/keyed-watcher.js +42 -0
- package/dist/dashboard/keyed-watcher.js.map +1 -0
- package/dist/dashboard/keys.d.ts +31 -0
- package/dist/dashboard/keys.d.ts.map +1 -0
- package/dist/dashboard/keys.js +37 -0
- package/dist/dashboard/keys.js.map +1 -0
- package/dist/dashboard/models.d.ts +25 -0
- package/dist/dashboard/models.d.ts.map +1 -0
- package/dist/dashboard/models.js +30 -0
- package/dist/dashboard/models.js.map +1 -0
- package/dist/dashboard/module-host.d.ts +44 -0
- package/dist/dashboard/module-host.d.ts.map +1 -0
- package/dist/dashboard/module-host.js +91 -0
- package/dist/dashboard/module-host.js.map +1 -0
- package/dist/dashboard/module-serve.d.ts +15 -0
- package/dist/dashboard/module-serve.d.ts.map +1 -0
- package/dist/dashboard/module-serve.js +45 -0
- package/dist/dashboard/module-serve.js.map +1 -0
- package/dist/dashboard/open-in-app.d.ts +43 -0
- package/dist/dashboard/open-in-app.d.ts.map +1 -0
- package/dist/dashboard/open-in-app.js +98 -0
- package/dist/dashboard/open-in-app.js.map +1 -0
- package/dist/dashboard/open-questions.d.ts +45 -0
- package/dist/dashboard/open-questions.d.ts.map +1 -0
- package/dist/dashboard/open-questions.js +62 -0
- package/dist/dashboard/open-questions.js.map +1 -0
- package/dist/dashboard/overview.d.ts +78 -0
- package/dist/dashboard/overview.d.ts.map +1 -0
- package/dist/dashboard/overview.js +87 -0
- package/dist/dashboard/overview.js.map +1 -0
- package/dist/dashboard/projects.d.ts +101 -0
- package/dist/dashboard/projects.d.ts.map +1 -0
- package/dist/dashboard/projects.js +63 -0
- package/dist/dashboard/projects.js.map +1 -0
- package/dist/dashboard/pull-requests.d.ts +127 -0
- package/dist/dashboard/pull-requests.d.ts.map +1 -0
- package/dist/dashboard/pull-requests.js +137 -0
- package/dist/dashboard/pull-requests.js.map +1 -0
- package/dist/dashboard/queue.d.ts +17 -0
- package/dist/dashboard/queue.d.ts.map +1 -0
- package/dist/dashboard/queue.js +19 -0
- package/dist/dashboard/queue.js.map +1 -0
- package/dist/dashboard/quota.d.ts +53 -0
- package/dist/dashboard/quota.d.ts.map +1 -0
- package/dist/dashboard/quota.js +42 -0
- package/dist/dashboard/quota.js.map +1 -0
- package/dist/dashboard/relay-endpoints.d.ts +32 -0
- package/dist/dashboard/relay-endpoints.d.ts.map +1 -0
- package/dist/dashboard/relay-endpoints.js +115 -0
- package/dist/dashboard/relay-endpoints.js.map +1 -0
- package/dist/dashboard/remote-run.d.ts +95 -0
- package/dist/dashboard/remote-run.d.ts.map +1 -0
- package/dist/dashboard/remote-run.js +235 -0
- package/dist/dashboard/remote-run.js.map +1 -0
- package/dist/dashboard/rpc-serve.d.ts +106 -0
- package/dist/dashboard/rpc-serve.d.ts.map +1 -0
- package/dist/dashboard/rpc-serve.js +180 -0
- package/dist/dashboard/rpc-serve.js.map +1 -0
- package/dist/dashboard/run-inbox.d.ts +31 -0
- package/dist/dashboard/run-inbox.d.ts.map +1 -0
- package/dist/dashboard/run-inbox.js +51 -0
- package/dist/dashboard/run-inbox.js.map +1 -0
- package/dist/dashboard/server.d.ts +105 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +231 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/dashboard/static.d.ts +9 -0
- package/dist/dashboard/static.d.ts.map +1 -0
- package/dist/dashboard/static.js +54 -0
- package/dist/dashboard/static.js.map +1 -0
- package/dist/dashboard/types.d.ts +135 -0
- package/dist/dashboard/types.d.ts.map +1 -0
- package/dist/dashboard/types.js +2 -0
- package/dist/dashboard/types.js.map +1 -0
- package/dist/dashboard/web-start-endpoints.d.ts +32 -0
- package/dist/dashboard/web-start-endpoints.d.ts.map +1 -0
- package/dist/dashboard/web-start-endpoints.js +75 -0
- package/dist/dashboard/web-start-endpoints.js.map +1 -0
- package/dist/dashboard-bundle/assets/client-CbBRB9m4.js +9 -0
- package/dist/dashboard-bundle/assets/jsx-runtime-By8HlURe.js +1 -0
- package/dist/dashboard-bundle/assets/main-B98UOA3_.js +140 -0
- package/dist/dashboard-bundle/assets/main-ByRjbCiA.css +2 -0
- package/dist/dashboard-bundle/assets/module-v213KWfH.js +21 -0
- package/dist/dashboard-bundle/assets/react-CZI7_Jkm.js +1 -0
- package/dist/dashboard-bundle/assets/react-dom-cJyBB_A4.js +1 -0
- package/dist/dashboard-bundle/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/dist/dashboard-bundle/host/module.js +1 -0
- package/dist/dashboard-bundle/host/react-dom-client.js +1 -0
- package/dist/dashboard-bundle/host/react-dom.js +1 -0
- package/dist/dashboard-bundle/host/react-jsx-runtime.js +1 -0
- package/dist/dashboard-bundle/host/react.js +1 -0
- package/dist/dashboard-bundle/index.html +42 -0
- package/dist/dashboard-bundle/logo-animated.svg +34 -0
- package/dist/dashboard-bundle/logo.svg +16 -0
- package/dist/dashboard-rpc/context.d.ts +56 -0
- package/dist/dashboard-rpc/context.d.ts.map +1 -0
- package/dist/dashboard-rpc/context.js +106 -0
- package/dist/dashboard-rpc/context.js.map +1 -0
- package/dist/dashboard-rpc/control.d.ts +124 -0
- package/dist/dashboard-rpc/control.d.ts.map +1 -0
- package/dist/dashboard-rpc/control.js +284 -0
- package/dist/dashboard-rpc/control.js.map +1 -0
- package/dist/dashboard-rpc/devices.d.ts +9 -0
- package/dist/dashboard-rpc/devices.d.ts.map +1 -0
- package/dist/dashboard-rpc/devices.js +12 -0
- package/dist/dashboard-rpc/devices.js.map +1 -0
- package/dist/dashboard-rpc/events-tail.d.ts +68 -0
- package/dist/dashboard-rpc/events-tail.d.ts.map +1 -0
- package/dist/dashboard-rpc/events-tail.js +257 -0
- package/dist/dashboard-rpc/events-tail.js.map +1 -0
- package/dist/dashboard-rpc/events.d.ts +39 -0
- package/dist/dashboard-rpc/events.d.ts.map +1 -0
- package/dist/dashboard-rpc/events.js +47 -0
- package/dist/dashboard-rpc/events.js.map +1 -0
- package/dist/dashboard-rpc/index.d.ts +29 -0
- package/dist/dashboard-rpc/index.d.ts.map +1 -0
- package/dist/dashboard-rpc/index.js +40 -0
- package/dist/dashboard-rpc/index.js.map +1 -0
- package/dist/dashboard-rpc/models.d.ts +4 -0
- package/dist/dashboard-rpc/models.d.ts.map +1 -0
- package/dist/dashboard-rpc/models.js +8 -0
- package/dist/dashboard-rpc/models.js.map +1 -0
- package/dist/dashboard-rpc/modules.d.ts +45 -0
- package/dist/dashboard-rpc/modules.d.ts.map +1 -0
- package/dist/dashboard-rpc/modules.js +79 -0
- package/dist/dashboard-rpc/modules.js.map +1 -0
- package/dist/dashboard-rpc/preferences.d.ts +41 -0
- package/dist/dashboard-rpc/preferences.d.ts.map +1 -0
- package/dist/dashboard-rpc/preferences.js +65 -0
- package/dist/dashboard-rpc/preferences.js.map +1 -0
- package/dist/dashboard-rpc/projects.d.ts +85 -0
- package/dist/dashboard-rpc/projects.d.ts.map +1 -0
- package/dist/dashboard-rpc/projects.js +129 -0
- package/dist/dashboard-rpc/projects.js.map +1 -0
- package/dist/dashboard-rpc/quota.d.ts +4 -0
- package/dist/dashboard-rpc/quota.d.ts.map +1 -0
- package/dist/dashboard-rpc/quota.js +15 -0
- package/dist/dashboard-rpc/quota.js.map +1 -0
- package/dist/dashboard-rpc/reads.d.ts +185 -0
- package/dist/dashboard-rpc/reads.d.ts.map +1 -0
- package/dist/dashboard-rpc/reads.js +370 -0
- package/dist/dashboard-rpc/reads.js.map +1 -0
- package/dist/dashboard-rpc/relay-agent.d.ts +9 -0
- package/dist/dashboard-rpc/relay-agent.d.ts.map +1 -0
- package/dist/dashboard-rpc/relay-agent.js +21 -0
- package/dist/dashboard-rpc/relay-agent.js.map +1 -0
- package/dist/dashboard-rpc/relay-dispatch.d.ts +9 -0
- package/dist/dashboard-rpc/relay-dispatch.d.ts.map +1 -0
- package/dist/dashboard-rpc/relay-dispatch.js +24 -0
- package/dist/dashboard-rpc/relay-dispatch.js.map +1 -0
- package/dist/dashboard-rpc/stream-forward.d.ts +17 -0
- package/dist/dashboard-rpc/stream-forward.d.ts.map +1 -0
- package/dist/dashboard-rpc/stream-forward.js +38 -0
- package/dist/dashboard-rpc/stream-forward.js.map +1 -0
- package/dist/dashboard-rpc/test-context.d.ts +23 -0
- package/dist/dashboard-rpc/test-context.d.ts.map +1 -0
- package/dist/dashboard-rpc/test-context.js +43 -0
- package/dist/dashboard-rpc/test-context.js.map +1 -0
- package/dist/driver-names.d.ts +22 -0
- package/dist/driver-names.d.ts.map +1 -0
- package/dist/driver-names.js +29 -0
- package/dist/driver-names.js.map +1 -0
- package/dist/error-message.d.ts +8 -0
- package/dist/error-message.d.ts.map +1 -0
- package/dist/error-message.js +10 -0
- package/dist/error-message.js.map +1 -0
- package/dist/event-stream.d.ts +33 -0
- package/dist/event-stream.d.ts.map +1 -0
- package/dist/event-stream.js +104 -0
- package/dist/event-stream.js.map +1 -0
- package/dist/events.d.ts +236 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +5 -0
- package/dist/events.js.map +1 -0
- package/dist/format-bytes.d.ts +3 -0
- package/dist/format-bytes.d.ts.map +1 -0
- package/dist/format-bytes.js +18 -0
- package/dist/format-bytes.js.map +1 -0
- package/dist/has-remote.d.ts +8 -0
- package/dist/has-remote.d.ts.map +1 -0
- package/dist/has-remote.js +10 -0
- package/dist/has-remote.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +31 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +54 -0
- package/dist/install.js.map +1 -0
- package/dist/jsonl-tail.d.ts +59 -0
- package/dist/jsonl-tail.d.ts.map +1 -0
- package/dist/jsonl-tail.js +152 -0
- package/dist/jsonl-tail.js.map +1 -0
- package/dist/loopback-host.d.ts +20 -0
- package/dist/loopback-host.d.ts.map +1 -0
- package/dist/loopback-host.js +31 -0
- package/dist/loopback-host.js.map +1 -0
- package/dist/module-server.d.ts +56 -0
- package/dist/module-types/dashboard/components/DiffStat.d.ts +6 -0
- package/dist/module-types/dashboard/components/DriverModelMenu.d.ts +23 -0
- package/dist/module-types/dashboard/components/LinkActions.d.ts +26 -0
- package/dist/module-types/dashboard/components/Markdown.d.ts +4 -0
- package/dist/module-types/dashboard/components/SettingsRows.d.ts +37 -0
- package/dist/module-types/dashboard/components/StartAgentButton.d.ts +39 -0
- package/dist/module-types/dashboard/components/ui/badge.d.ts +2 -0
- package/dist/module-types/dashboard/components/ui/button.d.ts +10 -0
- package/dist/module-types/dashboard/components/ui/card.d.ts +5 -0
- package/dist/module-types/dashboard/components/ui/checkbox.d.ts +7 -0
- package/dist/module-types/dashboard/components/ui/dropdown-menu.d.ts +16 -0
- package/dist/module-types/dashboard/components/ui/input.d.ts +2 -0
- package/dist/module-types/dashboard/components/ui/option-label.d.ts +4 -0
- package/dist/module-types/dashboard/components/ui/popover.d.ts +8 -0
- package/dist/module-types/dashboard/components/ui/scroll-area.d.ts +10 -0
- package/dist/module-types/dashboard/components/ui/separator.d.ts +3 -0
- package/dist/module-types/dashboard/components/ui/skeleton.d.ts +2 -0
- package/dist/module-types/dashboard/components/ui/slider.d.ts +9 -0
- package/dist/module-types/dashboard/components/ui/tooltip.d.ts +11 -0
- package/dist/module-types/dashboard/lib/agent-settings.d.ts +2 -0
- package/dist/module-types/dashboard/lib/draft-handoff.d.ts +15 -0
- package/dist/module-types/dashboard/lib/format-date.d.ts +51 -0
- package/dist/module-types/dashboard/lib/host-services.d.ts +12 -0
- package/dist/module-types/dashboard/lib/models.d.ts +24 -0
- package/dist/module-types/dashboard/lib/route.d.ts +38 -0
- package/dist/module-types/dashboard/lib/rpc.d.ts +31 -0
- package/dist/module-types/dashboard/lib/use-action.d.ts +25 -0
- package/dist/module-types/dashboard/lib/use-async.d.ts +45 -0
- package/dist/module-types/dashboard/lib/use-modules.d.ts +79 -0
- package/dist/module-types/dashboard/lib/utils.d.ts +3 -0
- package/dist/module-types/dashboard/module/index.d.ts +335 -0
- package/dist/module-types/dashboard/rpc/models.d.ts +2 -0
- package/dist/module-types/dashboard/rpc/modules.d.ts +5 -0
- package/dist/module-types/src/agent-id.d.ts +12 -0
- package/dist/module-types/src/agent-locks.d.ts +2 -0
- package/dist/module-types/src/agent-view.d.ts +38 -0
- package/dist/module-types/src/bridge-browser.d.ts +216 -0
- package/dist/module-types/src/browser-stream.d.ts +19 -0
- package/dist/module-types/src/browser.d.ts +15 -0
- package/dist/module-types/src/built-in.d.ts +37 -0
- package/dist/module-types/src/client.d.ts +15 -0
- package/dist/module-types/src/cloud-run-state.d.ts +26 -0
- package/dist/module-types/src/dashboard/activity.d.ts +40 -0
- package/dist/module-types/src/dashboard/agent-handoff.d.ts +243 -0
- package/dist/module-types/src/dashboard/bridge-endpoints.d.ts +157 -0
- package/dist/module-types/src/dashboard/bridge-question.d.ts +32 -0
- package/dist/module-types/src/dashboard/bridge-store.d.ts +178 -0
- package/dist/module-types/src/dashboard/cache.d.ts +46 -0
- package/dist/module-types/src/dashboard/content-type.d.ts +2 -0
- package/dist/module-types/src/dashboard/dashboard.d.ts +37 -0
- package/dist/module-types/src/dashboard/docs.d.ts +38 -0
- package/dist/module-types/src/dashboard/git-status.d.ts +43 -0
- package/dist/module-types/src/dashboard/http.d.ts +28 -0
- package/dist/module-types/src/dashboard/interventions.d.ts +66 -0
- package/dist/module-types/src/dashboard/keyed-watcher.d.ts +28 -0
- package/dist/module-types/src/dashboard/keys.d.ts +30 -0
- package/dist/module-types/src/dashboard/models.d.ts +24 -0
- package/dist/module-types/src/dashboard/module-host.d.ts +43 -0
- package/dist/module-types/src/dashboard/module-serve.d.ts +14 -0
- package/dist/module-types/src/dashboard/open-in-app.d.ts +42 -0
- package/dist/module-types/src/dashboard/open-questions.d.ts +44 -0
- package/dist/module-types/src/dashboard/overview.d.ts +77 -0
- package/dist/module-types/src/dashboard/projects.d.ts +100 -0
- package/dist/module-types/src/dashboard/pull-requests.d.ts +126 -0
- package/dist/module-types/src/dashboard/queue.d.ts +16 -0
- package/dist/module-types/src/dashboard/quota.d.ts +52 -0
- package/dist/module-types/src/dashboard/remote-run.d.ts +94 -0
- package/dist/module-types/src/dashboard/rpc-serve.d.ts +105 -0
- package/dist/module-types/src/dashboard/run-inbox.d.ts +30 -0
- package/dist/module-types/src/dashboard/types.d.ts +134 -0
- package/dist/module-types/src/dashboard-rpc/context.d.ts +55 -0
- package/dist/module-types/src/dashboard-rpc/control.d.ts +123 -0
- package/dist/module-types/src/dashboard-rpc/devices.d.ts +8 -0
- package/dist/module-types/src/dashboard-rpc/events-tail.d.ts +67 -0
- package/dist/module-types/src/dashboard-rpc/events.d.ts +38 -0
- package/dist/module-types/src/dashboard-rpc/index.d.ts +28 -0
- package/dist/module-types/src/dashboard-rpc/models.d.ts +3 -0
- package/dist/module-types/src/dashboard-rpc/modules.d.ts +44 -0
- package/dist/module-types/src/dashboard-rpc/preferences.d.ts +40 -0
- package/dist/module-types/src/dashboard-rpc/projects.d.ts +84 -0
- package/dist/module-types/src/dashboard-rpc/quota.d.ts +3 -0
- package/dist/module-types/src/dashboard-rpc/reads.d.ts +184 -0
- package/dist/module-types/src/dashboard-rpc/relay-agent.d.ts +8 -0
- package/dist/module-types/src/dashboard-rpc/stream-forward.d.ts +16 -0
- package/dist/module-types/src/driver-names.d.ts +21 -0
- package/dist/module-types/src/error-message.d.ts +7 -0
- package/dist/module-types/src/event-stream.d.ts +32 -0
- package/dist/module-types/src/events.d.ts +235 -0
- package/dist/module-types/src/format-bytes.d.ts +2 -0
- package/dist/module-types/src/has-remote.d.ts +7 -0
- package/dist/module-types/src/index.d.ts +41 -0
- package/dist/module-types/src/jsonl-tail.d.ts +58 -0
- package/dist/module-types/src/loopback-host.d.ts +19 -0
- package/dist/module-types/src/node-fs.d.ts +32 -0
- package/dist/module-types/src/open-choices.d.ts +14 -0
- package/dist/module-types/src/openagent-dir.d.ts +10 -0
- package/dist/module-types/src/openagent-gitignore.d.ts +11 -0
- package/dist/module-types/src/pick-directory.d.ts +29 -0
- package/dist/module-types/src/preference-defaults.d.ts +42 -0
- package/dist/module-types/src/project-commands.d.ts +23 -0
- package/dist/module-types/src/project-errors.d.ts +59 -0
- package/dist/module-types/src/project-hooks.d.ts +129 -0
- package/dist/module-types/src/project-modules.d.ts +49 -0
- package/dist/module-types/src/project-presets.d.ts +29 -0
- package/dist/module-types/src/project.d.ts +28 -0
- package/dist/module-types/src/publish-levels.d.ts +32 -0
- package/dist/module-types/src/quota-boundary.d.ts +64 -0
- package/dist/module-types/src/quota-poller.d.ts +82 -0
- package/dist/module-types/src/registry.d.ts +226 -0
- package/dist/module-types/src/store/agent-checkout.d.ts +53 -0
- package/dist/module-types/src/store/agent-store.d.ts +266 -0
- package/dist/module-types/src/store/branches.d.ts +163 -0
- package/dist/module-types/src/store/git-host.d.ts +113 -0
- package/dist/module-types/src/store/index.d.ts +9 -0
- package/dist/module-types/src/store/provided.d.ts +16 -0
- package/dist/module-types/src/store/queue.d.ts +45 -0
- package/dist/module-types/src/store/repository.d.ts +32 -0
- package/dist/module-types/src/store/run-record.d.ts +21 -0
- package/dist/module-types/src/store/runs.d.ts +107 -0
- package/dist/module-types/src/store/tickets.d.ts +72 -0
- package/dist/module-types/src/terminal.d.ts +3 -0
- package/dist/module-types/src/worktrees.d.ts +89 -0
- package/dist/module.css +50 -0
- package/dist/node-fs.d.ts +33 -0
- package/dist/node-fs.d.ts.map +1 -0
- package/dist/node-fs.js +57 -0
- package/dist/node-fs.js.map +1 -0
- package/dist/open-choices.d.ts +15 -0
- package/dist/open-choices.d.ts.map +1 -0
- package/dist/open-choices.js +31 -0
- package/dist/open-choices.js.map +1 -0
- package/dist/openagent-dir.d.ts +11 -0
- package/dist/openagent-dir.d.ts.map +1 -0
- package/dist/openagent-dir.js +11 -0
- package/dist/openagent-dir.js.map +1 -0
- package/dist/openagent-gitignore.d.ts +12 -0
- package/dist/openagent-gitignore.d.ts.map +1 -0
- package/dist/openagent-gitignore.js +19 -0
- package/dist/openagent-gitignore.js.map +1 -0
- package/dist/pick-directory.d.ts +30 -0
- package/dist/pick-directory.d.ts.map +1 -0
- package/dist/pick-directory.js +102 -0
- package/dist/pick-directory.js.map +1 -0
- package/dist/preference-defaults.d.ts +43 -0
- package/dist/preference-defaults.d.ts.map +1 -0
- package/dist/preference-defaults.js +34 -0
- package/dist/preference-defaults.js.map +1 -0
- package/dist/project-commands.d.ts +24 -0
- package/dist/project-commands.d.ts.map +1 -0
- package/dist/project-commands.js +57 -0
- package/dist/project-commands.js.map +1 -0
- package/dist/project-errors.d.ts +60 -0
- package/dist/project-errors.d.ts.map +1 -0
- package/dist/project-errors.js +51 -0
- package/dist/project-errors.js.map +1 -0
- package/dist/project-hooks.d.ts +130 -0
- package/dist/project-hooks.d.ts.map +1 -0
- package/dist/project-hooks.js +232 -0
- package/dist/project-hooks.js.map +1 -0
- package/dist/project-modules.d.ts +50 -0
- package/dist/project-modules.d.ts.map +1 -0
- package/dist/project-modules.js +110 -0
- package/dist/project-modules.js.map +1 -0
- package/dist/project-pass.d.ts +32 -0
- package/dist/project-pass.d.ts.map +1 -0
- package/dist/project-pass.js +45 -0
- package/dist/project-pass.js.map +1 -0
- package/dist/project-presets.d.ts +30 -0
- package/dist/project-presets.d.ts.map +1 -0
- package/dist/project-presets.js +74 -0
- package/dist/project-presets.js.map +1 -0
- package/dist/project.d.ts +29 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +41 -0
- package/dist/project.js.map +1 -0
- package/dist/publish-levels.d.ts +33 -0
- package/dist/publish-levels.d.ts.map +1 -0
- package/dist/publish-levels.js +53 -0
- package/dist/publish-levels.js.map +1 -0
- package/dist/quota-boundary.d.ts +65 -0
- package/dist/quota-boundary.d.ts.map +1 -0
- package/dist/quota-boundary.js +135 -0
- package/dist/quota-boundary.js.map +1 -0
- package/dist/quota-poller.d.ts +83 -0
- package/dist/quota-poller.d.ts.map +1 -0
- package/dist/quota-poller.js +118 -0
- package/dist/quota-poller.js.map +1 -0
- package/dist/registry.d.ts +227 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +364 -0
- package/dist/registry.js.map +1 -0
- package/dist/remove-files.d.ts +24 -0
- package/dist/remove-files.d.ts.map +1 -0
- package/dist/remove-files.js +98 -0
- package/dist/remove-files.js.map +1 -0
- package/dist/request-path.d.ts +10 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +16 -0
- package/dist/request-path.js.map +1 -0
- package/dist/store/agent-checkout.d.ts +54 -0
- package/dist/store/agent-checkout.d.ts.map +1 -0
- package/dist/store/agent-checkout.js +61 -0
- package/dist/store/agent-checkout.js.map +1 -0
- package/dist/store/agent-store.d.ts +267 -0
- package/dist/store/agent-store.d.ts.map +1 -0
- package/dist/store/agent-store.js +190 -0
- package/dist/store/agent-store.js.map +1 -0
- package/dist/store/branches.d.ts +164 -0
- package/dist/store/branches.d.ts.map +1 -0
- package/dist/store/branches.js +187 -0
- package/dist/store/branches.js.map +1 -0
- package/dist/store/git-host.d.ts +114 -0
- package/dist/store/git-host.d.ts.map +1 -0
- package/dist/store/git-host.js +103 -0
- package/dist/store/git-host.js.map +1 -0
- package/dist/store/index.d.ts +10 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +10 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/provided.d.ts +17 -0
- package/dist/store/provided.d.ts.map +1 -0
- package/dist/store/provided.js +37 -0
- package/dist/store/provided.js.map +1 -0
- package/dist/store/queue.d.ts +46 -0
- package/dist/store/queue.d.ts.map +1 -0
- package/dist/store/queue.js +61 -0
- package/dist/store/queue.js.map +1 -0
- package/dist/store/repository.d.ts +33 -0
- package/dist/store/repository.d.ts.map +1 -0
- package/dist/store/repository.js +25 -0
- package/dist/store/repository.js.map +1 -0
- package/dist/store/run-record.d.ts +22 -0
- package/dist/store/run-record.d.ts.map +1 -0
- package/dist/store/run-record.js +108 -0
- package/dist/store/run-record.js.map +1 -0
- package/dist/store/runs.d.ts +108 -0
- package/dist/store/runs.d.ts.map +1 -0
- package/dist/store/runs.js +146 -0
- package/dist/store/runs.js.map +1 -0
- package/dist/store/test-branches.d.ts +18 -0
- package/dist/store/test-branches.d.ts.map +1 -0
- package/dist/store/test-branches.js +59 -0
- package/dist/store/test-branches.js.map +1 -0
- package/dist/store/test-runs.d.ts +15 -0
- package/dist/store/test-runs.d.ts.map +1 -0
- package/dist/store/test-runs.js +37 -0
- package/dist/store/test-runs.js.map +1 -0
- package/dist/store/tickets.d.ts +73 -0
- package/dist/store/tickets.d.ts.map +1 -0
- package/dist/store/tickets.js +67 -0
- package/dist/store/tickets.js.map +1 -0
- package/dist/terminal.d.ts +4 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +97 -0
- package/dist/terminal.js.map +1 -0
- package/dist/update-check.d.ts +44 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +71 -0
- package/dist/update-check.js.map +1 -0
- package/dist/worktrees.d.ts +90 -0
- package/dist/worktrees.d.ts.map +1 -0
- package/dist/worktrees.js +123 -0
- package/dist/worktrees.js.map +1 -0
- package/package.json +103 -3
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { listProjects } from './registry.js';
|
|
3
|
+
import { startDaemonTick, DAEMON_TICK_MS } from './daemon-tick.js';
|
|
4
|
+
import { DATA_BRANCH, branchReach, pullFileBranch } from '@openagt/agent-data';
|
|
5
|
+
import { startCloudScratchSweep } from './cloud-scratch-refs.js';
|
|
6
|
+
import { adoptCloudWork, startCloudWorkAdoption } from './cloud-work.js';
|
|
7
|
+
import { providerProblems } from './store/provided.js';
|
|
8
|
+
import { projectGitHost } from './store/git-host.js';
|
|
9
|
+
/**
|
|
10
|
+
* Everything the daemon runs in the background beside serving the dashboard: the data sync (#1599),
|
|
11
|
+
* the cloud-scratch sweep (#1547) and the cloud work adoption (#1601). None of them starts a run
|
|
12
|
+
* (#1774).
|
|
13
|
+
*
|
|
14
|
+
* All of it used to sit inline in `runDaemon`, which meant its body was a lifecycle narrative with
|
|
15
|
+
* ~200 lines of service wiring in the middle of it; the daemon body is left with the sequence it
|
|
16
|
+
* actually owns.
|
|
17
|
+
*
|
|
18
|
+
* They share one clock (E4). Each used to own a `setInterval`, so six intervals ran side by side
|
|
19
|
+
* with no single place to look when a sweep was not running; now each declares how many ticks it
|
|
20
|
+
* wants between turns and `daemon-tick.ts` fires them.
|
|
21
|
+
*/
|
|
22
|
+
/** Ticks between cloud work adoption passes: a ten-minute job. */
|
|
23
|
+
const TEN_MINUTES_EVERY = Math.round((10 * 60 * 1000) / DAEMON_TICK_MS);
|
|
24
|
+
/**
|
|
25
|
+
* Ticks between cloud-scratch sweeps (#1547): hourly. The refs it deletes have to sit for a day
|
|
26
|
+
* first, so a finer cadence would only spend `ls-remote` round-trips asking the same question.
|
|
27
|
+
*/
|
|
28
|
+
const CLOUD_SCRATCH_EVERY = Math.round((60 * 60 * 1000) / DAEMON_TICK_MS);
|
|
29
|
+
/**
|
|
30
|
+
* One project's data-sync turn (#1599): converge the `agent-data` branch — the skills' branch,
|
|
31
|
+
* which carries the tickets, the queue and the `logs` skill's runs — with
|
|
32
|
+
* origin through the shared branch library, one pull, and set or clear the project's `data-sync`
|
|
33
|
+
* error by the outcome. The clear is unconditional on success, so the error lives exactly as long
|
|
34
|
+
* as the condition — the next tick after the user fixes the remote, it is gone. A branch that stays
|
|
35
|
+
* on this machine (no remote, or the person does not share it) is no error: the project carries why,
|
|
36
|
+
* for as long as that holds. The daemon knows
|
|
37
|
+
* nothing of what is on the branch (#1774): a skill's own setup makes its files.
|
|
38
|
+
*/
|
|
39
|
+
export async function syncProjectData(path, errors, log) {
|
|
40
|
+
const result = await pullFileBranch(path, DATA_BRANCH, { log });
|
|
41
|
+
if (result.ok) {
|
|
42
|
+
errors.setReach(path, result.reach);
|
|
43
|
+
errors.clear(path, 'data-sync');
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
errors.setReach(path, await branchReach(path));
|
|
47
|
+
log(`[openagent] data sync: ${result.error}`);
|
|
48
|
+
errors.set(path, 'data-sync', result.error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* One project's provider check (#1820), on the data sync's clock: a kind of the project's data
|
|
53
|
+
* that packages declare but none is settled to provide (several declare it and the project's
|
|
54
|
+
* package.json names none, or names one that does not declare it) is the project's `provider`
|
|
55
|
+
* error, every such kind on its own line; every kind settled clears it. OpenAgent never picks
|
|
56
|
+
* the first declarer silently: the project says, or nothing provides and the banner says why.
|
|
57
|
+
*/
|
|
58
|
+
export async function checkProviders(path, errors) {
|
|
59
|
+
const problems = await providerProblems(path);
|
|
60
|
+
if (problems.length === 0)
|
|
61
|
+
errors.clear(path, 'provider');
|
|
62
|
+
else
|
|
63
|
+
errors.set(path, 'provider', problems.join('\n'));
|
|
64
|
+
}
|
|
65
|
+
/** The registered projects as dashboard summaries. */
|
|
66
|
+
async function listSummaries(env) {
|
|
67
|
+
const records = await listProjects(undefined, env).catch(() => []);
|
|
68
|
+
return Promise.all(records.map(async (p) => ({ id: p.id, path: p.path, name: basename(p.path), activated: true, gitHost: (await projectGitHost(p.path).catch(() => undefined)) !== undefined })));
|
|
69
|
+
}
|
|
70
|
+
export function startBackgroundServices(deps) {
|
|
71
|
+
const { env, log } = deps;
|
|
72
|
+
const projects = () => listSummaries(env);
|
|
73
|
+
// Delete the scratch refs a web hand-off leaves on origin (#1547): the pre-hand-off `cloud-*`
|
|
74
|
+
// ref and the run branch, one dead pair per web run. Daemon-side rather than in the driver,
|
|
75
|
+
// because session creation only signals "created", not "clone finished" — a driver deleting its
|
|
76
|
+
// own ref races the provisioning and can strand the session. The sweep waits out that race
|
|
77
|
+
// (~a day) and only deletes refs whose work is provably on the default branch.
|
|
78
|
+
const cloudScratch = startCloudScratchSweep({ projects, log });
|
|
79
|
+
// Adopt the branch a cloud session actually worked on (#1601): match each settled web run to
|
|
80
|
+
// the `claude/*` head descending from its hand-off anchor, record the branch and PR on the
|
|
81
|
+
// run's archive, and open the armed draft PR the session never did. Daemon-side by necessity:
|
|
82
|
+
// the branch does not exist yet when the wrapper ends — the cloud VM is still provisioning.
|
|
83
|
+
const cloudWork = startCloudWorkAdoption({ projects, log, adopt: cwd => adoptCloudWork(cwd) });
|
|
84
|
+
// One clock for every background job (E4). Each says how many ticks it wants between turns
|
|
85
|
+
// instead of owning an interval, so there is one place to look when the answer to "why is
|
|
86
|
+
// nothing happening" is that a sweep is not running — and the ratios are exact rather than six
|
|
87
|
+
// timers drifting apart.
|
|
88
|
+
const clock = startDaemonTick({
|
|
89
|
+
log,
|
|
90
|
+
jobs: [
|
|
91
|
+
// The eager data pull (#1582): converge every project's data checkout on what other
|
|
92
|
+
// machines and cloud sessions pushed, and carry out anything a failed cycle left local.
|
|
93
|
+
// Its start-up turn is also what creates the checkout on a fresh clone. A project that
|
|
94
|
+
// cannot converge is recorded as such for the dashboard (#1599).
|
|
95
|
+
{
|
|
96
|
+
name: 'data sync',
|
|
97
|
+
every: 2,
|
|
98
|
+
run: async () => {
|
|
99
|
+
for (const project of await projects().catch(() => [])) {
|
|
100
|
+
// Taken off the list since this turn began: a sync would make its records' checkout again,
|
|
101
|
+
// right after a person asked for it to go.
|
|
102
|
+
if (!(await listProjects(undefined, env).catch(() => [])).some(listed => listed.id === project.id))
|
|
103
|
+
continue;
|
|
104
|
+
await syncProjectData(project.path, deps.projectErrors, log);
|
|
105
|
+
await checkProviders(project.path, deps.projectErrors);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
// Hourly. Its start-up turn is what starts a `cloud-*` ref's one-day clock (#1547): the
|
|
110
|
+
// sweep ages those refs from when it first saw them, so the sooner it looks, the sooner
|
|
111
|
+
// a leftover can go.
|
|
112
|
+
{ name: 'cloud scratch sweep', every: CLOUD_SCRATCH_EVERY, run: () => cloudScratch.tick() },
|
|
113
|
+
// Ten minutes: the cloud session it waits on lives minutes-to-hours itself, and the pass
|
|
114
|
+
// costs an `ls-remote` per project only while a settled web run is actually waiting.
|
|
115
|
+
{ name: 'cloud work adoption', every: TEN_MINUTES_EVERY, run: () => cloudWork.tick() },
|
|
116
|
+
],
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
quiesce: async () => {
|
|
120
|
+
await clock.stop();
|
|
121
|
+
cloudScratch.stop();
|
|
122
|
+
cloudWork.stop();
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=daemon-services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-services.js","sourceRoot":"","sources":["../src/daemon-services.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The daemon's one background clock (E4).
|
|
3
|
+
*
|
|
4
|
+
* Every sweep used to own a timer: one `setInterval`, one unref call and one overlap guard
|
|
5
|
+
* each, and no single place to look when the answer to "why is nothing happening" is that a
|
|
6
|
+
* sweep is not running.
|
|
7
|
+
*
|
|
8
|
+
* One interval fires, and each job says how often it wants a turn. A job's cadence stops being a
|
|
9
|
+
* duration it has to reason about and becomes a small integer: how many ticks between turns.
|
|
10
|
+
*
|
|
11
|
+
* The base interval is the finest cadence anything needs. Anything slower is that many ticks —
|
|
12
|
+
* exact by construction, because the ratios are integers rather than two timers drifting apart.
|
|
13
|
+
*/
|
|
14
|
+
/** One thing the daemon does on a schedule. */
|
|
15
|
+
export interface TickJob {
|
|
16
|
+
/** For the log line when it throws. */
|
|
17
|
+
name: string;
|
|
18
|
+
/**
|
|
19
|
+
* Ticks between turns. `1` is every tick, `20` is every twentieth. A tick is the interval
|
|
20
|
+
* coming round, not a turn that ran, so a slow job on the same clock cannot stretch this out.
|
|
21
|
+
*
|
|
22
|
+
* Its own turn is *skipped* rather than queued, so a slow job never accumulates a backlog of
|
|
23
|
+
* missed turns to work through.
|
|
24
|
+
*/
|
|
25
|
+
every?: number;
|
|
26
|
+
/** Run one turn. Awaited, so a long job holds the tick rather than overlapping the next one. */
|
|
27
|
+
run: () => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Run on the very first tick, which fires at start-up rather than one interval later.
|
|
30
|
+
*
|
|
31
|
+
* On by default, because the case most of these exist for is a machine that was off while
|
|
32
|
+
* something happened. A job that only makes sense once the daemon has been up a while says so.
|
|
33
|
+
*/
|
|
34
|
+
onStart?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** The running clock. */
|
|
37
|
+
export interface DaemonTick {
|
|
38
|
+
/** Run one tick now, awaiting it. The tests drive the clock through this. */
|
|
39
|
+
tick: () => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Stop the clock, and resolve when the turn already in flight has finished. Awaiting it is how
|
|
42
|
+
* a shutdown knows the sweeps have let go of the repo — clearing the interval only stops the
|
|
43
|
+
* *next* turn, and these jobs commit and push.
|
|
44
|
+
*/
|
|
45
|
+
stop: () => Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/** How often the clock fires. The finest cadence any job asks for; everything else is a multiple. */
|
|
48
|
+
export declare const DAEMON_TICK_MS = 30000;
|
|
49
|
+
/** What {@link startDaemonTick} needs. */
|
|
50
|
+
export interface DaemonTickOptions {
|
|
51
|
+
jobs: readonly TickJob[];
|
|
52
|
+
/** Override the base interval (tests). */
|
|
53
|
+
intervalMs?: number;
|
|
54
|
+
log: (message: string) => void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Start the clock and return the handle that stops it.
|
|
58
|
+
*
|
|
59
|
+
* A job that throws costs its own turn and nothing else: the others in the same tick still run,
|
|
60
|
+
* and the failure is logged once with the job's name, because a sweep failing silently is
|
|
61
|
+
* indistinguishable from one that is not scheduled at all.
|
|
62
|
+
*
|
|
63
|
+
* Overlapping ticks join the one already running rather than being dropped, so awaiting `tick()`
|
|
64
|
+
* means the tick finished — which is what lets a test drive this deterministically. The timer is
|
|
65
|
+
* unref'd: background work is never the reason the process stays up.
|
|
66
|
+
*/
|
|
67
|
+
export declare function startDaemonTick(opts: DaemonTickOptions): DaemonTick;
|
|
68
|
+
//# sourceMappingURL=daemon-tick.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-tick.d.ts","sourceRoot":"","sources":["../src/daemon-tick.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,OAAO;IACtB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gGAAgG;IAChG,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,yBAAyB;AACzB,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB;;;;OAIG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,qGAAqG;AACrG,eAAO,MAAM,cAAc,QAAS,CAAA;AAEpC,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CA2EnE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { errorMessage } from './error-message.js';
|
|
2
|
+
/** How often the clock fires. The finest cadence any job asks for; everything else is a multiple. */
|
|
3
|
+
export const DAEMON_TICK_MS = 30_000;
|
|
4
|
+
/** Ticks between a job's turns, defaulted and floored. */
|
|
5
|
+
function cadence(job) {
|
|
6
|
+
return Math.max(1, job.every ?? 1);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Start the clock and return the handle that stops it.
|
|
10
|
+
*
|
|
11
|
+
* A job that throws costs its own turn and nothing else: the others in the same tick still run,
|
|
12
|
+
* and the failure is logged once with the job's name, because a sweep failing silently is
|
|
13
|
+
* indistinguishable from one that is not scheduled at all.
|
|
14
|
+
*
|
|
15
|
+
* Overlapping ticks join the one already running rather than being dropped, so awaiting `tick()`
|
|
16
|
+
* means the tick finished — which is what lets a test drive this deterministically. The timer is
|
|
17
|
+
* unref'd: background work is never the reason the process stays up.
|
|
18
|
+
*/
|
|
19
|
+
export function startDaemonTick(opts) {
|
|
20
|
+
let stopped = false;
|
|
21
|
+
/**
|
|
22
|
+
* Which tick is running now. Advanced by {@link elapsedWhileBusy} as well as by one, so it
|
|
23
|
+
* stays a count of how many times the interval has *come round* rather than how many turns
|
|
24
|
+
* happened to run (#1607).
|
|
25
|
+
*/
|
|
26
|
+
let tickNow = -1;
|
|
27
|
+
/**
|
|
28
|
+
* Interval firings that arrived while a turn was in flight. Time passed for them, so they count
|
|
29
|
+
* towards every cadence — the turn they would each have had is folded into the next one.
|
|
30
|
+
*/
|
|
31
|
+
let elapsedWhileBusy = 0;
|
|
32
|
+
let inflight;
|
|
33
|
+
/**
|
|
34
|
+
* The tick each job last took a turn on, seeded so tick 0 is already due for a job that wants
|
|
35
|
+
* the start-up turn and one whole cadence away for a job that sits it out.
|
|
36
|
+
*/
|
|
37
|
+
const lastTurn = opts.jobs.map(job => (job.onStart === false ? 0 : -cadence(job)));
|
|
38
|
+
const runTick = async (n) => {
|
|
39
|
+
for (const [index, job] of opts.jobs.entries()) {
|
|
40
|
+
if (stopped)
|
|
41
|
+
return;
|
|
42
|
+
// Ticks *since this job's own last turn*, rather than `n % every`: when the clock jumps
|
|
43
|
+
// over the tick a job's cadence would have landed on, the job is due at the next turn
|
|
44
|
+
// instead of waiting a whole further cadence for the modulo to come round again.
|
|
45
|
+
if (n - lastTurn[index] < cadence(job))
|
|
46
|
+
continue;
|
|
47
|
+
// Claimed before the run, not after: a missed turn is skipped rather than queued, and a job
|
|
48
|
+
// that throws has still had its turn.
|
|
49
|
+
lastTurn[index] = n;
|
|
50
|
+
try {
|
|
51
|
+
await job.run();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
opts.log(`[openagent] ${job.name} failed this tick: ${errorMessage(err)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const tick = () => {
|
|
59
|
+
if (stopped)
|
|
60
|
+
return Promise.resolve();
|
|
61
|
+
// A caller that arrives mid-turn joins it without moving the clock: `tick()` means "run a
|
|
62
|
+
// turn now" — the daemon's shutdown and the tests drive it, and neither is elapsed time.
|
|
63
|
+
// Only the interval is, and it says so through `elapsedWhileBusy`.
|
|
64
|
+
if (inflight)
|
|
65
|
+
return inflight;
|
|
66
|
+
tickNow += 1 + elapsedWhileBusy;
|
|
67
|
+
elapsedWhileBusy = 0;
|
|
68
|
+
inflight = runTick(tickNow).finally(() => {
|
|
69
|
+
inflight = undefined;
|
|
70
|
+
});
|
|
71
|
+
return inflight;
|
|
72
|
+
};
|
|
73
|
+
void tick();
|
|
74
|
+
const timer = setInterval(() => {
|
|
75
|
+
// The clock moved whether or not a turn can start. Counting a firing that lands on a busy
|
|
76
|
+
// daemon is the whole point: without it a long job — a data sync failing slowly against an
|
|
77
|
+
// unreachable remote — stretched every `every: N` cadence by its own duration, because a
|
|
78
|
+
// cadence was measured in turns that ran rather than in time that passed (#1607).
|
|
79
|
+
if (inflight) {
|
|
80
|
+
elapsedWhileBusy++;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
void tick();
|
|
84
|
+
}, opts.intervalMs ?? DAEMON_TICK_MS);
|
|
85
|
+
timer.unref?.();
|
|
86
|
+
return {
|
|
87
|
+
tick,
|
|
88
|
+
stop: async () => {
|
|
89
|
+
stopped = true;
|
|
90
|
+
clearInterval(timer);
|
|
91
|
+
// The turn in flight stops at the next job boundary, but the job it is inside runs to the
|
|
92
|
+
// end — so wait it out rather than leaving a sweep mid-commit.
|
|
93
|
+
await inflight?.catch(() => { });
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=daemon-tick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-tick.js","sourceRoot":"","sources":["../src/daemon-tick.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { isLoopbackHost } from './loopback-host.js';
|
|
2
|
+
import { type BridgeBrowser, type BridgeBrowserOptions } from './bridge-browser.js';
|
|
3
|
+
/**
|
|
4
|
+
* The dashboard process (#302). It is a pure projection of files: a run's tool keeps the run's
|
|
5
|
+
* card and diary in the run's checkout, and the dashboard *tails* them, pushing each new line to
|
|
6
|
+
* connected browsers. No run<->dashboard IPC: the files are the seam. The daemon runs no agent
|
|
7
|
+
* (#1774): a Start is the project's own `start` hook line, and what a person says to a run goes
|
|
8
|
+
* into the run's inbox file, or through the `resume` hook line once the run has ended.
|
|
9
|
+
*
|
|
10
|
+
* It runs in the foreground and only in the foreground: Ctrl-C closes the dashboard. A run is
|
|
11
|
+
* not the daemon's process, so it goes on to its end. There is no detached mode, so there is no
|
|
12
|
+
* liveness record, no machine-global state file, and no second process to find, reuse or stop.
|
|
13
|
+
*
|
|
14
|
+
* Its own `cwd` is just the home project it streams by default.
|
|
15
|
+
*/
|
|
16
|
+
/** The default dashboard port the daemon binds. */
|
|
17
|
+
export declare const DEFAULT_DAEMON_PORT = 4200;
|
|
18
|
+
/** The default bind host (#1051): localhost only, so the daemon is unreachable off the machine. */
|
|
19
|
+
export declare const DEFAULT_DAEMON_HOST = "127.0.0.1";
|
|
20
|
+
/**
|
|
21
|
+
* True when `host` is a loopback address the browser reaches without leaving the machine (#1051).
|
|
22
|
+
* Defined in its own leaf module so the dashboard's RPC mount can share the one definition without
|
|
23
|
+
* importing this one back (a cycle); re-exported here for the callers that already had it.
|
|
24
|
+
*/
|
|
25
|
+
export { isLoopbackHost };
|
|
26
|
+
/** Where the dashboard came up, reported to {@link RunDaemonOptions.onListening}. */
|
|
27
|
+
export interface DaemonState {
|
|
28
|
+
/** The daemon process id. */
|
|
29
|
+
pid: number;
|
|
30
|
+
/** The port the dashboard is bound to. */
|
|
31
|
+
port: number;
|
|
32
|
+
/** The URL to open. */
|
|
33
|
+
url: string;
|
|
34
|
+
/** ISO timestamp the daemon started. */
|
|
35
|
+
startedAt: string;
|
|
36
|
+
/** The host the dashboard is bound to (#1051). */
|
|
37
|
+
host?: string;
|
|
38
|
+
}
|
|
39
|
+
/** True when a process with this id is still running (best-effort, signal 0). The store's
|
|
40
|
+
* {@link isPidAlive} under the daemon's historical public name -- the two were byte-identical. */
|
|
41
|
+
export { isPidAlive as isProcessAlive } from './store/index.js';
|
|
42
|
+
/** Options for {@link runDaemon}. */
|
|
43
|
+
export interface RunDaemonOptions {
|
|
44
|
+
/** Port to bind. Default {@link DEFAULT_DAEMON_PORT}; pass `0` for an ephemeral port. */
|
|
45
|
+
port?: number;
|
|
46
|
+
/** Host to bind (#1051). Default {@link DEFAULT_DAEMON_HOST}; a non-loopback address generates and
|
|
47
|
+
* requires the shared token, and every route is then gated behind it. */
|
|
48
|
+
host?: string;
|
|
49
|
+
/** Shut the daemon down when this aborts (in addition to SIGINT/SIGTERM). For tests. */
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
/** Env the registry is read from. Default `process.env`; injectable for tests. */
|
|
52
|
+
env?: NodeJS.ProcessEnv;
|
|
53
|
+
/** Called once the server has bound, before it blocks. The only way a caller learns the port. */
|
|
54
|
+
onListening?: (state: DaemonState) => void;
|
|
55
|
+
/** How the bridge browser is launched (#1332); default the real Chrome for Testing. For tests. */
|
|
56
|
+
bridgeBrowser?: (opts: BridgeBrowserOptions) => Promise<BridgeBrowser>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The daemon body, run in the foreground by bare `openagent`. Serves the built dashboard bundle
|
|
60
|
+
* (#405/#426): the SPA reads each run's files over an event stream, so the daemon just serves
|
|
61
|
+
* the files and runs the project's hooks. Resolves on SIGINT/SIGTERM after tearing the dashboard
|
|
62
|
+
* down.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runDaemon(cwd: string, opts?: RunDaemonOptions): Promise<void>;
|
|
65
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,OAAO,EAA4D,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAK7I;;;;;;;;;;;;GAYG;AAEH,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,OAAO,CAAA;AAEvC,mGAAmG;AACnG,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAE9C;;;;GAIG;AACH,OAAO,EAAE,cAAc,EAAE,CAAA;AAEzB,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAOD;kGACkG;AAClG,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE/D,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;6EACyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wFAAwF;IACxF,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,iGAAiG;IACjG,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IAC1C,kGAAkG;IAClG,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;CACvE;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HvF"}
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { OPENAGENT_DIR } from './openagent-dir.js';
|
|
4
|
+
import { startDashboard } from './dashboard/index.js';
|
|
5
|
+
import { createProjectRuntime } from './daemon-runtime.js';
|
|
6
|
+
import { defaultQuotaSource } from './dashboard/quota.js';
|
|
7
|
+
import { defaultModelsSource } from './dashboard/models.js';
|
|
8
|
+
import { startBackgroundServices } from './daemon-services.js';
|
|
9
|
+
import { projectErrorStore } from './project-errors.js';
|
|
10
|
+
import { resolveDashboardBundle } from './dashboard/bundle.js';
|
|
11
|
+
import { ensureDaemonToken, listProjects, nodeRegistryFs, readPreferences, registryPreferencesStore } from './registry.js';
|
|
12
|
+
import { isLoopbackHost } from './loopback-host.js';
|
|
13
|
+
import { bridgeSessionsFrom } from './dashboard/bridge-sessions.js';
|
|
14
|
+
import { bridgeQuestions } from './dashboard/bridge-store.js';
|
|
15
|
+
import { bridgeBrowserDir, bridgeBrowserOwner, startBridgeBrowser } from './bridge-browser.js';
|
|
16
|
+
import { runProjectHooks } from './project-hooks.js';
|
|
17
|
+
import { readAllAgents } from './store/index.js';
|
|
18
|
+
/**
|
|
19
|
+
* The dashboard process (#302). It is a pure projection of files: a run's tool keeps the run's
|
|
20
|
+
* card and diary in the run's checkout, and the dashboard *tails* them, pushing each new line to
|
|
21
|
+
* connected browsers. No run<->dashboard IPC: the files are the seam. The daemon runs no agent
|
|
22
|
+
* (#1774): a Start is the project's own `start` hook line, and what a person says to a run goes
|
|
23
|
+
* into the run's inbox file, or through the `resume` hook line once the run has ended.
|
|
24
|
+
*
|
|
25
|
+
* It runs in the foreground and only in the foreground: Ctrl-C closes the dashboard. A run is
|
|
26
|
+
* not the daemon's process, so it goes on to its end. There is no detached mode, so there is no
|
|
27
|
+
* liveness record, no machine-global state file, and no second process to find, reuse or stop.
|
|
28
|
+
*
|
|
29
|
+
* Its own `cwd` is just the home project it streams by default.
|
|
30
|
+
*/
|
|
31
|
+
/** The default dashboard port the daemon binds. */
|
|
32
|
+
export const DEFAULT_DAEMON_PORT = 4200;
|
|
33
|
+
/** The default bind host (#1051): localhost only, so the daemon is unreachable off the machine. */
|
|
34
|
+
export const DEFAULT_DAEMON_HOST = '127.0.0.1';
|
|
35
|
+
/**
|
|
36
|
+
* True when `host` is a loopback address the browser reaches without leaving the machine (#1051).
|
|
37
|
+
* Defined in its own leaf module so the dashboard's RPC mount can share the one definition without
|
|
38
|
+
* importing this one back (a cycle); re-exported here for the callers that already had it.
|
|
39
|
+
*/
|
|
40
|
+
export { isLoopbackHost };
|
|
41
|
+
/** The `.openagent/` directory for a workspace. */
|
|
42
|
+
function daemonDir(cwd) {
|
|
43
|
+
return join(cwd, OPENAGENT_DIR);
|
|
44
|
+
}
|
|
45
|
+
/** True when a process with this id is still running (best-effort, signal 0). The store's
|
|
46
|
+
* {@link isPidAlive} under the daemon's historical public name -- the two were byte-identical. */
|
|
47
|
+
export { isPidAlive as isProcessAlive } from './store/index.js';
|
|
48
|
+
/**
|
|
49
|
+
* The daemon body, run in the foreground by bare `openagent`. Serves the built dashboard bundle
|
|
50
|
+
* (#405/#426): the SPA reads each run's files over an event stream, so the daemon just serves
|
|
51
|
+
* the files and runs the project's hooks. Resolves on SIGINT/SIGTERM after tearing the dashboard
|
|
52
|
+
* down.
|
|
53
|
+
*/
|
|
54
|
+
export async function runDaemon(cwd, opts = {}) {
|
|
55
|
+
const port = opts.port ?? DEFAULT_DAEMON_PORT;
|
|
56
|
+
const host = opts.host ?? DEFAULT_DAEMON_HOST;
|
|
57
|
+
const env = opts.env ?? process.env;
|
|
58
|
+
// #1051: a non-loopback bind reaches the network, where a daemon that spawns processes is RCE for
|
|
59
|
+
// anyone who finds the port, so generate + persist the shared token the request guard requires. A
|
|
60
|
+
// loopback bind needs none, so the local zero-config path stays byte-identical.
|
|
61
|
+
const token = isLoopbackHost(host) ? undefined : await ensureDaemonToken(undefined, env);
|
|
62
|
+
// The browser bridge (#1237). Opt-in, because it opens the daemon's one route reachable from
|
|
63
|
+
// another origin. It reuses the same shared token (#1051) rather than minting a second one: the two
|
|
64
|
+
// guard the same daemon, so a second secret would be another thing to rotate and leak without
|
|
65
|
+
// narrowing anything. On a loopback bind that secret may not exist yet, hence ensure, not read.
|
|
66
|
+
const bridgeOn = (await readPreferences(undefined, env).catch(() => ({}))).bridge === true;
|
|
67
|
+
const bridgeToken = bridgeOn ? await ensureDaemonToken(undefined, env) : undefined;
|
|
68
|
+
// The project's own `.openagent/` — where its hooks file sits, and where a run's tool keeps
|
|
69
|
+
// the run's card and diary inside the run's checkout. Created up front so the daemon works as the
|
|
70
|
+
// very first command in a fresh workspace, before any run has made the directory.
|
|
71
|
+
await mkdir(daemonDir(cwd), { recursive: true });
|
|
72
|
+
// Everything the dashboard drives per project (a run's start, project install, the device
|
|
73
|
+
// relay) lives in the runtime, so this body stays about the daemon's own lifecycle.
|
|
74
|
+
const runtime = createProjectRuntime({ cwd, env });
|
|
75
|
+
// Known only once the dashboard listens; the bridge browser is told it (#1332).
|
|
76
|
+
let daemonUrl;
|
|
77
|
+
// The daemon serves the built dashboard bundle (#405/#426): the SPA reads each run's files over
|
|
78
|
+
// `GET /_rpc/events`, so there is no in-process event stream to feed here. The runtime's RPCs reach the browser through the
|
|
79
|
+
// dashboard context the mount is wired with. A missing bundle (a broken install) surfaces as a
|
|
80
|
+
// 503 from the server.
|
|
81
|
+
const clientBundleDir = await resolveDashboardBundle();
|
|
82
|
+
// The long-lived meter the usage panel draws (#685), owned here so it stops with the daemon.
|
|
83
|
+
const quota = defaultQuotaSource();
|
|
84
|
+
// The per-project error state (#1500): the background services write it, the dashboard reads it.
|
|
85
|
+
const projectErrors = projectErrorStore();
|
|
86
|
+
// The bridge browser (#1332): the daemon's own Chrome for Testing with the extension installed,
|
|
87
|
+
// so a web run no longer needs the user's Chrome open. Created here, launched only once the
|
|
88
|
+
// dashboard listens (the extension is told the daemon's address) and the preference says so.
|
|
89
|
+
// It needs the bridge: without the token there is nothing to hand the extension.
|
|
90
|
+
const bridgeBrowser = bridgeBrowserOwner(async (report) => {
|
|
91
|
+
if (!bridgeToken || !daemonUrl) {
|
|
92
|
+
// The token is minted at boot, from the bridge preference as it stood then (above). A bridge
|
|
93
|
+
// switched on since is a restart away; a bridge that is off wants switching on first.
|
|
94
|
+
const bridgeOnNow = (await readPreferences(undefined, env).catch(() => ({}))).bridge === true;
|
|
95
|
+
throw new Error(bridgeOnNow
|
|
96
|
+
? 'the browser bridge was switched on after the dashboard started — restart the dashboard, and the browser launches on its own'
|
|
97
|
+
: 'turn the browser bridge on, then restart the dashboard');
|
|
98
|
+
}
|
|
99
|
+
return (opts.bridgeBrowser ?? (o => startBridgeBrowser(o)))({ daemonUrl, token: bridgeToken, dir: bridgeBrowserDir(env), report });
|
|
100
|
+
}, console.log);
|
|
101
|
+
const dashboard = await startDashboard({
|
|
102
|
+
host,
|
|
103
|
+
port,
|
|
104
|
+
quota,
|
|
105
|
+
// Which models each coding agent offers: asked on the menu's first read, then kept.
|
|
106
|
+
models: defaultModelsSource(),
|
|
107
|
+
onStart: runtime.onStart,
|
|
108
|
+
onAddProject: runtime.onAddProject,
|
|
109
|
+
onRemoveProject: runtime.onRemoveProject,
|
|
110
|
+
// Relay an agent to/from a connected device (#1067): the events source streams an agent this daemon
|
|
111
|
+
// is relaying, `remote` lets the read RPCs forward a remote agent's reads/steer/push to its device
|
|
112
|
+
// (slice 2), and the `/_relay/*` endpoints let another daemon run + read + steer a session here.
|
|
113
|
+
eventsSource: runtime.remoteEventsSource,
|
|
114
|
+
remote: runtime.remoteAgents,
|
|
115
|
+
relay: { tailEvents: runtime.tailRelayEvents, rpc: runtime.onRelayRpc },
|
|
116
|
+
// The browser bridge (#1237): absent unless the preference is on, which 404s every route.
|
|
117
|
+
...(bridgeToken ? { bridgeToken, bridgeSessions: () => listBridgeSessions(env) } : {}),
|
|
118
|
+
// The bridge browser follows its switch (#1332): on launches it, off closes it, without a restart.
|
|
119
|
+
preferences: registryPreferencesStore(nodeRegistryFs(), env, written => {
|
|
120
|
+
if (written.bridgeBrowser === true)
|
|
121
|
+
void bridgeBrowser.start();
|
|
122
|
+
if (written.bridgeBrowser === false)
|
|
123
|
+
void bridgeBrowser.stop();
|
|
124
|
+
}),
|
|
125
|
+
projectErrors: projectErrors.read,
|
|
126
|
+
bridgeBrowser,
|
|
127
|
+
...(token ? { token } : {}),
|
|
128
|
+
...(clientBundleDir ? { clientBundleDir } : {}),
|
|
129
|
+
});
|
|
130
|
+
daemonUrl = dashboard.url;
|
|
131
|
+
try {
|
|
132
|
+
const actualPort = Number(new URL(dashboard.url).port) || port;
|
|
133
|
+
opts.onListening?.({ pid: process.pid, port: actualPort, host, url: dashboard.url, startedAt: new Date().toISOString() });
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
// Startup failed after the port was bound. Tear the server down, or it keeps the event loop
|
|
137
|
+
// alive: a zombie process squatting the port.
|
|
138
|
+
await dashboard.close();
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
// The bridge browser comes up in the background (#1332): its first launch downloads Chrome,
|
|
142
|
+
// and the dashboard must not wait on that. Read here rather than with the bridge preference
|
|
143
|
+
// above: the launch needs the address the dashboard only has now.
|
|
144
|
+
if ((await readPreferences(undefined, env).catch(() => ({}))).bridgeBrowser === true)
|
|
145
|
+
void bridgeBrowser.start();
|
|
146
|
+
// Each project's open hooks (#1774): the lines its own `.openagent/hooks.yml` names, run in
|
|
147
|
+
// the project once the dashboard listens, so a slow line never delays the URL. The daemon names
|
|
148
|
+
// no tool; the file does. Bounded and logged, never a reason the daemon did not come up.
|
|
149
|
+
for (const record of await listProjects(undefined, env).catch(() => [])) {
|
|
150
|
+
await runProjectHooks(record.path, 'open', { log: console.log });
|
|
151
|
+
}
|
|
152
|
+
// Everything that runs in the background beside serving the dashboard: the data sync and the
|
|
153
|
+
// cloud sweeps.
|
|
154
|
+
const services = startBackgroundServices({
|
|
155
|
+
env,
|
|
156
|
+
projectErrors,
|
|
157
|
+
log: console.log,
|
|
158
|
+
});
|
|
159
|
+
await waitForShutdown(opts.signal);
|
|
160
|
+
await services.quiesce();
|
|
161
|
+
// Each project's close hooks (#1774), the counterpart of the open hooks above. A run in flight
|
|
162
|
+
// is not the daemon's process: it goes on to its end, and the next dashboard shows it.
|
|
163
|
+
for (const record of await listProjects(undefined, env).catch(() => [])) {
|
|
164
|
+
await runProjectHooks(record.path, 'close', { log: console.log });
|
|
165
|
+
}
|
|
166
|
+
// Stopped here as well as by the dashboard: a broken install serves 503s without ever taking
|
|
167
|
+
// ownership of the source we handed in, and that poller would go on reading by itself.
|
|
168
|
+
quota.stop();
|
|
169
|
+
// The daemon's browser goes with the daemon (#1332): left running it would keep serving a
|
|
170
|
+
// daemon that is gone, and the next daemon would find its profile held.
|
|
171
|
+
await bridgeBrowser.stop();
|
|
172
|
+
await runtime.dispose();
|
|
173
|
+
await dashboard.close();
|
|
174
|
+
}
|
|
175
|
+
/** Resolve on SIGINT/SIGTERM, or when the optional abort signal fires. */
|
|
176
|
+
function waitForShutdown(signal) {
|
|
177
|
+
return new Promise(resolvePromise => {
|
|
178
|
+
if (signal?.aborted)
|
|
179
|
+
return resolvePromise();
|
|
180
|
+
const done = () => {
|
|
181
|
+
process.off('SIGINT', done);
|
|
182
|
+
process.off('SIGTERM', done);
|
|
183
|
+
signal?.removeEventListener('abort', done);
|
|
184
|
+
resolvePromise();
|
|
185
|
+
};
|
|
186
|
+
process.once('SIGINT', done);
|
|
187
|
+
process.once('SIGTERM', done);
|
|
188
|
+
signal?.addEventListener('abort', done, { once: true });
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The cloud sessions the browser bridge's Driver tab should be serving (#1237, #1332).
|
|
193
|
+
*
|
|
194
|
+
* Across every registered project, because a cloud agent is not tied to the daemon's home
|
|
195
|
+
* checkout, and best-effort per project so one unreadable repo cannot empty the list.
|
|
196
|
+
*/
|
|
197
|
+
async function listBridgeSessions(env) {
|
|
198
|
+
const projects = await listProjects(undefined, env).catch(() => []);
|
|
199
|
+
const agents = (await Promise.all(projects.map(p => readAllAgents(p.path).catch(() => [])))).flat();
|
|
200
|
+
return bridgeSessionsFrom(agents, new Date(), bridgeQuestions().pendingAnswerSessions());
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type AgentMeta, type AgentStatus } from '../store/index.js';
|
|
2
|
+
import type { ProjectSummary, ProjectionRead } from './projects.js';
|
|
3
|
+
export { activityKey } from './keys.js';
|
|
4
|
+
/**
|
|
5
|
+
* One agent lifecycle event worth a passing mention. Two kinds: an agent `started` (entered
|
|
6
|
+
* `running`) or `finished` (reached a terminal status). The card is not shown for these — they
|
|
7
|
+
* only drive notifications — so the fields are just what a notification line needs.
|
|
8
|
+
*/
|
|
9
|
+
export interface Activity {
|
|
10
|
+
projectId: string;
|
|
11
|
+
projectName: string;
|
|
12
|
+
/** The agent this is about. */
|
|
13
|
+
agentId: string;
|
|
14
|
+
/** `started` = the agent entered `running`; `finished` = it reached a terminal status. */
|
|
15
|
+
kind: 'started' | 'finished';
|
|
16
|
+
/** What the agent is building (its `intent`), for the notification body; may be absent. */
|
|
17
|
+
title?: string;
|
|
18
|
+
/** The finished agent's terminal status (`finished` only), so a stop reads differently from a done. */
|
|
19
|
+
status?: AgentStatus;
|
|
20
|
+
/** When the agent last changed, ISO, for ordering and the baseline diff. */
|
|
21
|
+
updatedAt?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Injectable seam so {@link buildActivity} is unit-testable off disk. */
|
|
24
|
+
export interface ActivityDeps {
|
|
25
|
+
/** A project's runs, live prepended to the archived history, newest-first. Defaults to disk. */
|
|
26
|
+
readAgents?: (cwd: string) => Promise<AgentMeta[]>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build the cross-project activity feed: for each registered project's most recent agents, one
|
|
30
|
+
* item per agent reflecting where it is now (`started` while it runs, `finished` once it lands),
|
|
31
|
+
* newest first. Forgiving — a project whose agents cannot be read simply contributes nothing, and
|
|
32
|
+
* comes back named as one that was *not* read whole (#1623), since "nothing happened there" and
|
|
33
|
+
* "I could not look" are the same empty list to everyone but the notification watcher.
|
|
34
|
+
*
|
|
35
|
+
* The `started` and `finished` items for one agent carry distinct keys ({@link activityKey}), so a
|
|
36
|
+
* run that is still going notifies once (started) and again when it lands (finished). An agent that
|
|
37
|
+
* both starts and finishes between two polls is only ever seen terminal, so it notifies once
|
|
38
|
+
* (finished) — one quick agent, one line.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildActivity(projects: ProjectSummary[], deps?: ActivityDeps): Promise<ProjectionRead<Activity>>;
|
|
41
|
+
//# sourceMappingURL=activity.d.ts.map
|