@phnx-labs/agents-cli 1.22.39 → 1.22.41
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/CHANGELOG.md +316 -0
- package/README.md +116 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -27
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +259 -0
- package/dist/commands/accounts.d.ts +20 -0
- package/dist/commands/accounts.js +186 -25
- package/dist/commands/apply.d.ts +3 -3
- package/dist/commands/apply.js +20 -63
- package/dist/commands/browser.d.ts +15 -0
- package/dist/commands/browser.js +318 -131
- package/dist/commands/budget.d.ts +7 -6
- package/dist/commands/budget.js +8 -7
- package/dist/commands/cloud.js +17 -20
- package/dist/commands/commands.js +1 -1
- package/dist/commands/computer-actions.d.ts +1 -35
- package/dist/commands/computer-actions.js +13 -181
- package/dist/commands/computer.d.ts +28 -3
- package/dist/commands/computer.js +93 -65
- package/dist/commands/config.js +16 -3
- package/dist/commands/cost.d.ts +2 -1
- package/dist/commands/cost.js +7 -6
- package/dist/commands/daemon.js +151 -4
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +19 -11
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.d.ts +2 -50
- package/dist/commands/exec.js +160 -215
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +12 -23
- package/dist/commands/fleet-capture.js +25 -27
- package/dist/commands/focus.d.ts +2 -3
- package/dist/commands/focus.js +34 -9
- package/dist/commands/go.js +15 -5
- package/dist/commands/harness.d.ts +3 -3
- package/dist/commands/harness.js +53 -5
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/insights.d.ts +5 -5
- package/dist/commands/insights.js +15 -9
- package/dist/commands/inspect.d.ts +2 -3
- package/dist/commands/inspect.js +4 -16
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +9 -9
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/memory.js +1 -1
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +7 -7
- package/dist/commands/mine.d.ts +11 -8
- package/dist/commands/mine.js +11 -10
- package/dist/commands/models.js +1 -1
- package/dist/commands/modes.js +1 -1
- package/dist/commands/monitors.js +23 -6
- package/dist/commands/output.d.ts +7 -6
- package/dist/commands/output.js +11 -10
- package/dist/commands/packages.js +4 -4
- package/dist/commands/perf.js +1 -1
- package/dist/commands/permissions.js +49 -32
- package/dist/commands/plugins.d.ts +1 -1
- package/dist/commands/plugins.js +3 -3
- package/dist/commands/profiles.d.ts +6 -9
- package/dist/commands/profiles.js +8 -321
- package/dist/commands/projects.d.ts +9 -0
- package/dist/commands/projects.js +140 -8
- package/dist/commands/prune.js +5 -13
- package/dist/commands/refresh-rules.js +1 -1
- package/dist/commands/repo.d.ts +5 -7
- package/dist/commands/repo.js +34 -18
- package/dist/commands/resource-view.js +4 -0
- package/dist/commands/resume.d.ts +11 -7
- package/dist/commands/resume.js +82 -98
- package/dist/commands/route.d.ts +12 -0
- package/dist/commands/route.js +261 -0
- package/dist/commands/routines.d.ts +2 -3
- package/dist/commands/routines.js +120 -145
- package/dist/commands/rules.js +1 -1
- package/dist/commands/run-account-picker.d.ts +1 -1
- package/dist/commands/run-account-picker.js +2 -2
- package/dist/commands/run-broadcast.d.ts +21 -0
- package/dist/commands/run-broadcast.js +89 -0
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-vault.d.ts +10 -0
- package/dist/commands/{login.js → secrets-vault.js} +34 -14
- package/dist/commands/secrets.d.ts +4 -4
- package/dist/commands/secrets.js +158 -159
- package/dist/commands/sessions-backfill.js +1 -1
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +9 -5
- package/dist/commands/sessions-export.js +2 -2
- package/dist/commands/sessions-inject.js +4 -5
- package/dist/commands/sessions-migrate.js +16 -27
- package/dist/commands/sessions-picker.d.ts +14 -0
- package/dist/commands/sessions-picker.js +209 -13
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-share.d.ts +25 -0
- package/dist/commands/sessions-share.js +166 -0
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +144 -180
- package/dist/commands/setup-browser.js +1 -1
- package/dist/commands/setup-computer.js +1 -1
- package/dist/commands/setup-fleet.js +3 -0
- package/dist/commands/setup-mine.d.ts +7 -3
- package/dist/commands/setup-mine.js +13 -8
- package/dist/commands/setup-preferences.js +2 -2
- package/dist/commands/setup-secrets.js +2 -2
- package/dist/commands/setup-watchdog.js +2 -2
- package/dist/commands/setup.js +7 -2
- package/dist/commands/share.d.ts +65 -0
- package/dist/commands/share.js +253 -20
- package/dist/commands/skills.js +3 -3
- package/dist/commands/snapshot.d.ts +2 -2
- package/dist/commands/snapshot.js +9 -9
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +186 -64
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/sync.js +24 -9
- package/dist/commands/teams.d.ts +2 -2
- package/dist/commands/teams.js +9 -18
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/trash.js +1 -1
- package/dist/commands/usage.d.ts +1 -1
- package/dist/commands/usage.js +2 -2
- package/dist/commands/utils.d.ts +4 -14
- package/dist/commands/utils.js +6 -27
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +9 -77
- package/dist/commands/view.js +23 -8
- package/dist/commands/watchdog.js +1 -1
- package/dist/commands/webhook.js +25 -34
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/account-capabilities.d.ts +39 -0
- package/dist/lib/account-capabilities.js +59 -0
- package/dist/lib/account-catalog.js +1 -1
- package/dist/lib/account-registry.d.ts +66 -0
- package/dist/lib/account-registry.js +151 -5
- package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
- package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
- package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
- package/dist/lib/{usage.js → accounting/usage.js} +11 -11
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +72 -4
- package/dist/lib/agents.js +231 -199
- package/dist/lib/answer-router.d.ts +2 -2
- package/dist/lib/ask-classifier.d.ts +1 -1
- package/dist/lib/ask-classifier.js +1 -1
- package/dist/lib/audit/log.js +1 -1
- package/dist/lib/auth-health.d.ts +1 -1
- package/dist/lib/auth-health.js +2 -2
- package/dist/lib/brand.js +1 -1
- package/dist/lib/browser/caller-identity.d.ts +28 -0
- package/dist/lib/browser/caller-identity.js +156 -0
- package/dist/lib/browser/cdp.js +5 -1
- package/dist/lib/browser/chrome.js +12 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +3 -2
- package/dist/lib/browser/hygiene.d.ts +10 -2
- package/dist/lib/browser/hygiene.js +7 -4
- package/dist/lib/browser/ipc.d.ts +22 -2
- package/dist/lib/browser/ipc.js +185 -21
- package/dist/lib/browser/profiles.d.ts +69 -5
- package/dist/lib/browser/profiles.js +135 -13
- package/dist/lib/browser/remote-control.d.ts +2 -2
- package/dist/lib/browser/remote-control.js +3 -3
- package/dist/lib/browser/runtime-state.d.ts +79 -0
- package/dist/lib/browser/runtime-state.js +119 -1
- package/dist/lib/browser/service.d.ts +137 -2
- package/dist/lib/browser/service.js +492 -54
- package/dist/lib/browser/sessions-list.d.ts +2 -1
- package/dist/lib/browser/sessions-list.js +4 -13
- package/dist/lib/browser/types.d.ts +19 -1
- package/dist/lib/budget/config.js +1 -1
- package/dist/lib/budget/ledger.js +1 -1
- package/dist/lib/byok-usage.js +1 -1
- package/dist/lib/capabilities.js +3 -15
- package/dist/lib/catchup.d.ts +1 -1
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloud/host.d.ts +3 -3
- package/dist/lib/cloud/host.js +5 -5
- package/dist/lib/cloud/rush.d.ts +9 -21
- package/dist/lib/cloud/rush.js +33 -120
- package/dist/lib/cloud/types.d.ts +2 -2
- package/dist/lib/commands.js +3 -13
- package/dist/lib/computer/actions.d.ts +36 -0
- package/dist/lib/computer/actions.js +162 -0
- package/dist/lib/computer/dispatch.d.ts +2 -2
- package/dist/lib/computer/dispatch.js +2 -2
- package/dist/lib/computer/sessions-list.d.ts +3 -3
- package/dist/lib/computer/sessions-list.js +2 -2
- package/dist/lib/config-keys.d.ts +2 -1
- package/dist/lib/config-keys.js +8 -4
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +5 -2
- package/dist/lib/crabbox/lease.js +9 -1
- package/dist/lib/crabbox/runtimes.d.ts +32 -7
- package/dist/lib/crabbox/runtimes.js +72 -30
- package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
- package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/daemon-ticks.d.ts +25 -0
- package/dist/lib/daemon-ticks.js +31 -1
- package/dist/lib/daemon-webhooks.d.ts +104 -0
- package/dist/lib/daemon-webhooks.js +215 -0
- package/dist/lib/device-config.d.ts +85 -75
- package/dist/lib/device-config.js +280 -142
- package/dist/lib/devices/config-migration.d.ts +29 -34
- package/dist/lib/devices/config-migration.js +209 -130
- package/dist/lib/devices/connect.d.ts +2 -2
- package/dist/lib/devices/connect.js +2 -2
- package/dist/lib/devices/discovery-policy.d.ts +30 -0
- package/dist/lib/devices/discovery-policy.js +101 -0
- package/dist/lib/devices/fleet-inventory.js +8 -3
- package/dist/lib/devices/harness-inventory.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.js +12 -3
- package/dist/lib/devices/known-hosts.js +1 -1
- package/dist/lib/devices/pool.d.ts +10 -5
- package/dist/lib/devices/pool.js +5 -7
- package/dist/lib/devices/registry.d.ts +1 -1
- package/dist/lib/devices/registry.js +1 -1
- package/dist/lib/devices/resolve-profile.d.ts +2 -2
- package/dist/lib/devices/resolve-profile.js +2 -2
- package/dist/lib/devices/resolve-target.d.ts +1 -1
- package/dist/lib/devices/resolve-target.js +4 -4
- package/dist/lib/devices/self-host.d.ts +1 -1
- package/dist/lib/devices/self-host.js +3 -3
- package/dist/lib/devices/ssh-config.d.ts +1 -1
- package/dist/lib/devices/stats-cache.js +1 -1
- package/dist/lib/devices/sync.d.ts +3 -1
- package/dist/lib/devices/sync.js +3 -3
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.js +2 -2
- package/dist/lib/event-families.d.ts +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +2 -2
- package/dist/lib/events-ingest.js +2 -2
- package/dist/lib/exec.d.ts +4 -4
- package/dist/lib/exec.js +11 -11
- package/dist/lib/factory/snapshot.d.ts +1 -1
- package/dist/lib/factory/snapshot.js +1 -1
- package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
- package/dist/lib/{activity.js → feed/activity.js} +7 -7
- package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
- package/dist/lib/{events.js → feed/events.js} +5 -5
- package/dist/lib/{feed.js → feed/feed.js} +4 -4
- package/dist/lib/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +1 -1
- package/dist/lib/feed-post.d.ts +1 -1
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -6
- package/dist/lib/fleet/apply.js +18 -45
- package/dist/lib/fleet/auth-sync.d.ts +16 -35
- package/dist/lib/fleet/auth-sync.js +16 -75
- package/dist/lib/fleet/capture.js +8 -6
- package/dist/lib/fleet/manifest.js +23 -11
- package/dist/lib/fleet/types.d.ts +19 -7
- package/dist/lib/fleet-cache.d.ts +1 -1
- package/dist/lib/fleet-cache.js +1 -1
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.js +44 -1
- package/dist/lib/friction-heuristics.d.ts +1 -1
- package/dist/lib/git.d.ts +24 -1
- package/dist/lib/git.js +82 -38
- package/dist/lib/heal.js +3 -3
- package/dist/lib/hooks.d.ts +18 -0
- package/dist/lib/hooks.js +113 -1
- package/dist/lib/hosts/credentials.d.ts +30 -10
- package/dist/lib/hosts/credentials.js +38 -26
- package/dist/lib/hosts/dispatch.d.ts +3 -3
- package/dist/lib/hosts/dispatch.js +3 -3
- package/dist/lib/hosts/option.d.ts +3 -3
- package/dist/lib/hosts/option.js +7 -8
- package/dist/lib/hosts/passthrough.d.ts +17 -17
- package/dist/lib/hosts/passthrough.js +67 -50
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconcile.d.ts +1 -1
- package/dist/lib/hosts/reconcile.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +1 -1
- package/dist/lib/hosts/reconnect.js +2 -2
- package/dist/lib/hosts/registry.d.ts +5 -5
- package/dist/lib/hosts/registry.js +5 -5
- package/dist/lib/hosts/remote-cmd.d.ts +10 -10
- package/dist/lib/hosts/remote-cmd.js +25 -18
- package/dist/lib/hosts/remote-os.d.ts +4 -4
- package/dist/lib/hosts/remote-os.js +4 -4
- package/dist/lib/hosts/remote-session-id.d.ts +2 -2
- package/dist/lib/hosts/remote-session-id.js +2 -2
- package/dist/lib/hosts/routing-flag.d.ts +3 -3
- package/dist/lib/hosts/routing-flag.js +4 -5
- package/dist/lib/hosts/run-target.d.ts +4 -4
- package/dist/lib/hosts/run-target.js +4 -4
- package/dist/lib/hosts/session-index.d.ts +2 -2
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/session-marker.d.ts +1 -1
- package/dist/lib/hosts/session-marker.js +1 -1
- package/dist/lib/hosts/types.d.ts +2 -2
- package/dist/lib/hosts/types.js +2 -2
- package/dist/lib/import.js +1 -1
- package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/strategies.js +1 -1
- package/dist/lib/installations/update.js +2 -2
- package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
- package/dist/lib/{versions.js → installations/versions.js} +51 -31
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/linear-projects.d.ts +28 -0
- package/dist/lib/linear-projects.js +30 -0
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-gc.js +1 -1
- package/dist/lib/mailbox.js +1 -1
- package/dist/lib/mcp-registry.d.ts +62 -0
- package/dist/lib/mcp-registry.js +177 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +124 -307
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +24 -6
- package/dist/lib/menubar/snapshot.d.ts +7 -0
- package/dist/lib/menubar/snapshot.js +8 -6
- package/dist/lib/models.js +1 -1
- package/dist/lib/monitors/config.d.ts +12 -0
- package/dist/lib/monitors/config.js +3 -0
- package/dist/lib/monitors/dispatch.js +26 -5
- package/dist/lib/monitors/engine.js +10 -0
- package/dist/lib/monitors/sources/webhook.d.ts +1 -1
- package/dist/lib/monitors/state.d.ts +42 -0
- package/dist/lib/monitors/state.js +30 -0
- package/dist/lib/notify.d.ts +1 -1
- package/dist/lib/observe-aliases.d.ts +3 -3
- package/dist/lib/observe-aliases.js +3 -21
- package/dist/lib/output/git-output.js +2 -2
- package/dist/lib/overdue.d.ts +1 -1
- package/dist/lib/overdue.js +1 -1
- package/dist/lib/permissions-registry.d.ts +65 -0
- package/dist/lib/permissions-registry.js +599 -0
- package/dist/lib/permissions.d.ts +24 -13
- package/dist/lib/permissions.js +52 -271
- package/dist/lib/picker.d.ts +16 -0
- package/dist/lib/picker.js +33 -3
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +4 -4
- package/dist/lib/platform/paths.d.ts +8 -0
- package/dist/lib/platform/paths.js +11 -0
- package/dist/lib/platform/posixpath.js +3 -3
- package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
- package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
- package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
- package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
- package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
- package/dist/lib/{skills.js → plugins/skills.js} +7 -7
- package/dist/lib/pricing/cost.d.ts +1 -1
- package/dist/lib/pricing/cost.js +1 -1
- package/dist/lib/profiles-presets.d.ts +1 -1
- package/dist/lib/profiles-presets.js +1 -1
- package/dist/lib/profiles.js +2 -2
- package/dist/lib/project-import.js +4 -1
- package/dist/lib/project-key.js +7 -0
- package/dist/lib/project-launch.d.ts +1 -1
- package/dist/lib/project-launch.js +3 -3
- package/dist/lib/project-pull.d.ts +128 -0
- package/dist/lib/project-pull.js +384 -0
- package/dist/lib/project-root.d.ts +2 -2
- package/dist/lib/project-root.js +2 -2
- package/dist/lib/project-status.js +1 -1
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +29 -6
- package/dist/lib/refresh.d.ts +12 -1
- package/dist/lib/refresh.js +16 -9
- package/dist/lib/registry.d.ts +9 -2
- package/dist/lib/registry.js +11 -4
- package/dist/lib/resources.d.ts +2 -2
- package/dist/lib/resources.js +2 -2
- package/dist/lib/routers.d.ts +81 -0
- package/dist/lib/routers.js +153 -0
- package/dist/lib/routine-context.d.ts +1 -0
- package/dist/lib/routine-context.js +7 -2
- package/dist/lib/routine-notify-owner.d.ts +1 -1
- package/dist/lib/routine-notify.d.ts +1 -1
- package/dist/lib/routine-notify.js +1 -1
- package/dist/lib/routine-process-cleanup.d.ts +1 -1
- package/dist/lib/routine-readiness.d.ts +1 -1
- package/dist/lib/routine-readiness.js +11 -4
- package/dist/lib/routines-placement.d.ts +12 -2
- package/dist/lib/routines-placement.js +20 -3
- package/dist/lib/routines-project.d.ts +1 -1
- package/dist/lib/routines-project.js +1 -1
- package/dist/lib/rules/compile.d.ts +1 -0
- package/dist/lib/rules/compile.js +10 -2
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/run-notify.js +1 -1
- package/dist/lib/runner.d.ts +80 -2
- package/dist/lib/runner.js +261 -67
- package/dist/lib/sandbox.d.ts +1 -1
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.js +1 -1
- package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
- package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.js +2 -2
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +4 -4
- package/dist/lib/secrets/bundles.js +8 -8
- package/dist/lib/secrets/headless.d.ts +16 -0
- package/dist/lib/secrets/headless.js +21 -0
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.d.ts +1 -1
- package/dist/lib/secrets/list-filter.js +2 -2
- package/dist/lib/secrets/push.d.ts +1 -1
- package/dist/lib/secrets/push.js +10 -12
- package/dist/lib/secrets/remote.d.ts +21 -17
- package/dist/lib/secrets/remote.js +39 -23
- package/dist/lib/secrets/vault.js +2 -2
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/self-update.d.ts +39 -4
- package/dist/lib/self-update.js +78 -25
- package/dist/lib/serve/control.d.ts +1 -1
- package/dist/lib/serve/control.js +4 -4
- package/dist/lib/serve/data.d.ts +1 -1
- package/dist/lib/serve/data.js +1 -1
- package/dist/lib/serve/stream.js +1 -1
- package/dist/lib/service-manifest.d.ts +29 -0
- package/dist/lib/service-manifest.js +80 -0
- package/dist/lib/session/active.d.ts +59 -7
- package/dist/lib/session/active.js +158 -17
- package/dist/lib/session/bash-command.js +1 -1
- package/dist/lib/session/claude-accounts.d.ts +1 -1
- package/dist/lib/session/claude-accounts.js +1 -1
- package/dist/lib/session/db.d.ts +10 -2
- package/dist/lib/session/db.js +25 -6
- package/dist/lib/session/discover.d.ts +77 -0
- package/dist/lib/session/discover.js +130 -25
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/inject.d.ts +1 -1
- package/dist/lib/session/insights.d.ts +1 -1
- package/dist/lib/session/insights.js +1 -1
- package/dist/lib/session/live-metadata.d.ts +15 -0
- package/dist/lib/session/live-metadata.js +76 -0
- package/dist/lib/session/migrate-targets.d.ts +1 -1
- package/dist/lib/session/recovery.d.ts +1 -1
- package/dist/lib/session/recovery.js +2 -2
- package/dist/lib/session/remote-active.d.ts +10 -1
- package/dist/lib/session/remote-active.js +8 -3
- package/dist/lib/session/remote-bundle.d.ts +1 -1
- package/dist/lib/session/remote-bundle.js +2 -2
- package/dist/lib/session/remote-list.d.ts +15 -4
- package/dist/lib/session/remote-list.js +40 -3
- package/dist/lib/session/remote.d.ts +5 -5
- package/dist/lib/session/remote.js +13 -17
- package/dist/lib/session/resume-command.d.ts +3 -2
- package/dist/lib/session/resume-command.js +4 -3
- package/dist/lib/session/resume-owner.d.ts +3 -3
- package/dist/lib/session/resume-owner.js +3 -3
- package/dist/lib/session/session-cache.d.ts +12 -0
- package/dist/lib/session/session-cache.js +2 -0
- package/dist/lib/session/share-html.d.ts +55 -0
- package/dist/lib/session/share-html.js +319 -0
- package/dist/lib/session/shell-programs.js +1 -1
- package/dist/lib/session/state.js +5 -5
- package/dist/lib/session/team-filter.d.ts +1 -1
- package/dist/lib/session/team-filter.js +1 -1
- package/dist/lib/session/types.d.ts +3 -3
- package/dist/lib/session/width.d.ts +2 -2
- package/dist/lib/session/width.js +2 -2
- package/dist/lib/settings-manifest.d.ts +2 -0
- package/dist/lib/settings-manifest.js +81 -3
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +120 -0
- package/dist/lib/share/publish.js +243 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +4 -4
- package/dist/lib/smart-launch.js +6 -4
- package/dist/lib/snapshot.d.ts +4 -4
- package/dist/lib/snapshot.js +2 -2
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +2 -2
- package/dist/lib/ssh-tunnel.d.ts +10 -10
- package/dist/lib/ssh-tunnel.js +12 -12
- package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
- package/dist/lib/staleness/checkers/hooks.js +1 -1
- package/dist/lib/staleness/detectors/permissions.js +0 -23
- package/dist/lib/staleness/detectors/plugins.js +1 -1
- package/dist/lib/staleness/fingerprint.js +1 -1
- package/dist/lib/staleness/layers.d.ts +1 -1
- package/dist/lib/staleness/layers.js +1 -1
- package/dist/lib/staleness/writers/mcp.js +3 -1
- package/dist/lib/staleness/writers/plugins.js +1 -1
- package/dist/lib/staleness/writers/types.d.ts +8 -0
- package/dist/lib/startup/command-registry.d.ts +6 -147
- package/dist/lib/startup/command-registry.js +40 -303
- package/dist/lib/startup/dev-build.d.ts +0 -21
- package/dist/lib/startup/dev-build.js +29 -8
- package/dist/lib/state.d.ts +19 -1
- package/dist/lib/state.js +120 -51
- package/dist/lib/subagents.js +1 -1
- package/dist/lib/sync-status.js +1 -1
- package/dist/lib/sync-umbrella.d.ts +6 -1
- package/dist/lib/sync-umbrella.js +9 -4
- package/dist/lib/teams/agents.js +2 -2
- package/dist/lib/teams/registry.js +1 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
- package/dist/lib/terminal/engine.js +1 -1
- package/dist/lib/terminal/index.d.ts +4 -0
- package/dist/lib/terminal/index.js +3 -0
- package/dist/lib/terminal/inject.d.ts +2 -2
- package/dist/lib/terminal/inject.js +2 -2
- package/dist/lib/terminal/transport.js +1 -1
- package/dist/lib/tmux/index.d.ts +1 -1
- package/dist/lib/tmux/index.js +1 -1
- package/dist/lib/tmux/session.d.ts +21 -5
- package/dist/lib/tmux/session.js +76 -22
- package/dist/lib/triggers/handlers.d.ts +38 -3
- package/dist/lib/triggers/handlers.js +58 -7
- package/dist/lib/triggers/webhook.d.ts +113 -5
- package/dist/lib/triggers/webhook.js +223 -44
- package/dist/lib/types.d.ts +19 -7
- package/dist/lib/usage-fleet.d.ts +1 -1
- package/dist/lib/usage-fleet.js +1 -1
- package/dist/lib/usage-refresh.d.ts +1 -1
- package/dist/lib/usage-refresh.js +3 -3
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/view-types.d.ts +56 -0
- package/dist/lib/view-types.js +1 -0
- package/dist/lib/watchdog/rotate.d.ts +2 -2
- package/dist/lib/watchdog/rotate.js +3 -3
- package/dist/lib/watchdog/runner.d.ts +2 -3
- package/dist/lib/watchdog/runner.js +3 -4
- package/dist/lib/workflows.js +1 -1
- package/dist/lib/wrap.d.ts +33 -0
- package/dist/lib/wrap.js +70 -0
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -2
- package/dist/commands/bench.d.ts +0 -2
- package/dist/commands/bench.js +0 -101
- package/dist/commands/cp.d.ts +0 -84
- package/dist/commands/cp.js +0 -231
- package/dist/commands/login.d.ts +0 -2
- package/dist/lib/resources/commands.d.ts +0 -46
- package/dist/lib/resources/commands.js +0 -211
- package/dist/lib/resources/hooks.d.ts +0 -16
- package/dist/lib/resources/hooks.js +0 -153
- package/dist/lib/resources/mcp.d.ts +0 -34
- package/dist/lib/resources/mcp.js +0 -250
- package/dist/lib/resources/memory.d.ts +0 -15
- package/dist/lib/resources/memory.js +0 -46
- package/dist/lib/resources/permissions.d.ts +0 -13
- package/dist/lib/resources/permissions.js +0 -202
- package/dist/lib/resources/rules.d.ts +0 -46
- package/dist/lib/resources/rules.js +0 -179
- package/dist/lib/resources/skills.d.ts +0 -37
- package/dist/lib/resources/skills.js +0 -247
- package/dist/lib/resources/subagents.d.ts +0 -46
- package/dist/lib/resources/subagents.js +0 -202
- /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-box hosted webhook receivers: config + daemon host (RUSH-2548).
|
|
3
|
+
*
|
|
4
|
+
* `~/.agents/daemon/webhooks.yaml` declares which signed webhook receivers THIS
|
|
5
|
+
* box hosts — bundle, local port, rate limit, and an optional public Tailscale
|
|
6
|
+
* Funnel port. The daemon's `webhook-receiver` service reads it and binds one
|
|
7
|
+
* receiver per entry, drawing each receiver's signing secret from the broker /
|
|
8
|
+
* machine-local file store (no `AGENTS_SECRETS_PASSPHRASE`, no `nohup`). An
|
|
9
|
+
* absent or empty file hosts nothing, so an unconfigured box binds nothing.
|
|
10
|
+
*
|
|
11
|
+
* This is per-box operational state (a public receiver runs on exactly one box),
|
|
12
|
+
* so it is deliberately NOT part of the fleet-synced device config — it mirrors
|
|
13
|
+
* `services.yaml` / daemon-services.ts, not `agents config`.
|
|
14
|
+
*/
|
|
15
|
+
import { type WebhookSecrets } from './triggers/webhook.js';
|
|
16
|
+
import { type FunnelPort } from './funnel.js';
|
|
17
|
+
export declare const DEFAULT_WEBHOOK_PORT = 8787;
|
|
18
|
+
export declare const DEFAULT_WEBHOOK_RATE_LIMIT = 60;
|
|
19
|
+
/** Optional public exposure for a hosted receiver via Tailscale Funnel. */
|
|
20
|
+
export interface HostedReceiverFunnel {
|
|
21
|
+
/** Public HTTPS port (Funnel allows 443 / 8443 / 10000). */
|
|
22
|
+
publicPort: FunnelPort;
|
|
23
|
+
}
|
|
24
|
+
/** One receiver this box hosts. */
|
|
25
|
+
export interface HostedReceiverConfig {
|
|
26
|
+
/** Secrets bundle holding GITHUB_WEBHOOK_SECRET, LINEAR_WEBHOOK_SECRET, and/or
|
|
27
|
+
* SLACK_SIGNING_SECRET (a Slack receiver also carries SLACK_BOT_TOKEN when the
|
|
28
|
+
* agent replies with the Slack Web API rather than `agents send`). */
|
|
29
|
+
bundle: string;
|
|
30
|
+
/** Local bind port (default 8787). */
|
|
31
|
+
port?: number;
|
|
32
|
+
/** Accepted deliveries per source per minute (default 60). */
|
|
33
|
+
rateLimit?: number;
|
|
34
|
+
/** Public Funnel exposure; omit to bind localhost only. */
|
|
35
|
+
funnel?: HostedReceiverFunnel;
|
|
36
|
+
}
|
|
37
|
+
export interface DaemonWebhooksConfig {
|
|
38
|
+
receivers: HostedReceiverConfig[];
|
|
39
|
+
}
|
|
40
|
+
/** Path to `~/.agents/daemon/webhooks.yaml`. */
|
|
41
|
+
export declare function getDaemonWebhooksConfigPath(): string;
|
|
42
|
+
/**
|
|
43
|
+
* Read the hosted-receivers config. A missing or malformed file yields an empty
|
|
44
|
+
* receiver list — never throws — so a box with no config hosts nothing.
|
|
45
|
+
*/
|
|
46
|
+
export declare function readDaemonWebhooksConfig(): DaemonWebhooksConfig;
|
|
47
|
+
/** Write the hosted-receivers config, creating the daemon config dir if needed. */
|
|
48
|
+
export declare function writeDaemonWebhooksConfig(cfg: DaemonWebhooksConfig): void;
|
|
49
|
+
/** The port a receiver binds — its identity, since one port hosts one receiver. */
|
|
50
|
+
export declare function hostedReceiverPort(receiver: HostedReceiverConfig): number;
|
|
51
|
+
/**
|
|
52
|
+
* Declare a receiver on this box, replacing any existing entry on the same port.
|
|
53
|
+
* Port is the identity because two receivers cannot bind one port — a second
|
|
54
|
+
* `add` on a port is an edit, never a silently ignored duplicate.
|
|
55
|
+
*/
|
|
56
|
+
export declare function addHostedReceiver(receiver: HostedReceiverConfig): DaemonWebhooksConfig;
|
|
57
|
+
/**
|
|
58
|
+
* Drop the receiver bound to `port`. Returns the removed entry, or null when
|
|
59
|
+
* nothing was declared there. The caller is responsible for taking down any
|
|
60
|
+
* public Funnel the removed entry declared — leaving it up would keep a public
|
|
61
|
+
* `https://<host>.ts.net` route pointed at a port nothing serves.
|
|
62
|
+
*/
|
|
63
|
+
export declare function removeHostedReceiver(port: number): HostedReceiverConfig | null;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a receiver's signing secrets from its bundle. Reads `agentOnly` (no
|
|
66
|
+
* Touch ID — the daemon is a background service, SEC-13): a broker-held or
|
|
67
|
+
* file-store bundle resolves silently; a locked bundle THROWS the actionable
|
|
68
|
+
* unlock message, which fails the receiver LOUD rather than binding with no
|
|
69
|
+
* verifiable signature. Throws when neither webhook secret is present.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveReceiverSecrets(bundle: string): WebhookSecrets;
|
|
72
|
+
export interface HostedWebhookReceivers {
|
|
73
|
+
/** Number of receivers actually bound. */
|
|
74
|
+
count: number;
|
|
75
|
+
/** Stop every hosted receiver. Idempotent. */
|
|
76
|
+
close(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
type Logger = (level: string, message: string) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Start every receiver declared in `webhooks.yaml`. A receiver that cannot start
|
|
81
|
+
* — an unreadable secret (locked bundle, no webhook secret) or a failed bind
|
|
82
|
+
* (the port is already taken by a foreground `agents webhooks serve`, another
|
|
83
|
+
* daemon, or anything else) — is skipped with a loud WARN and does NOT take the
|
|
84
|
+
* others, or the daemon, down. Returns a handle that stops them all.
|
|
85
|
+
*
|
|
86
|
+
* This is async because a bind failure is only observable asynchronously:
|
|
87
|
+
* `server.listen()` surfaces EADDRINUSE as an `'error'` event, so a `try/catch`
|
|
88
|
+
* around the start call never sees it and the event reaches the process-level
|
|
89
|
+
* `uncaughtException` handler (`index.ts`), which exits 1 for the supervisor to
|
|
90
|
+
* restart — a crash loop that would take the secrets broker, scheduler,
|
|
91
|
+
* monitors, browser IPC, and self-heal down with it. `waitForListening` is what
|
|
92
|
+
* turns that into one skipped receiver.
|
|
93
|
+
*/
|
|
94
|
+
export declare function startHostedWebhookReceivers(opts: {
|
|
95
|
+
log: Logger;
|
|
96
|
+
/**
|
|
97
|
+
* How a receiver's signing secrets are resolved. Defaults to
|
|
98
|
+
* `resolveReceiverSecrets` (the real broker read). Injectable for the same
|
|
99
|
+
* reason `FireWebhookOptions.dispatch` is — so a test can exercise the bind
|
|
100
|
+
* path against real sockets without a machine-local secrets bundle.
|
|
101
|
+
*/
|
|
102
|
+
resolveSecrets?: (bundle: string) => WebhookSecrets;
|
|
103
|
+
}): Promise<HostedWebhookReceivers>;
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-box hosted webhook receivers: config + daemon host (RUSH-2548).
|
|
3
|
+
*
|
|
4
|
+
* `~/.agents/daemon/webhooks.yaml` declares which signed webhook receivers THIS
|
|
5
|
+
* box hosts — bundle, local port, rate limit, and an optional public Tailscale
|
|
6
|
+
* Funnel port. The daemon's `webhook-receiver` service reads it and binds one
|
|
7
|
+
* receiver per entry, drawing each receiver's signing secret from the broker /
|
|
8
|
+
* machine-local file store (no `AGENTS_SECRETS_PASSPHRASE`, no `nohup`). An
|
|
9
|
+
* absent or empty file hosts nothing, so an unconfigured box binds nothing.
|
|
10
|
+
*
|
|
11
|
+
* This is per-box operational state (a public receiver runs on exactly one box),
|
|
12
|
+
* so it is deliberately NOT part of the fleet-synced device config — it mirrors
|
|
13
|
+
* `services.yaml` / daemon-services.ts, not `agents config`.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import * as yaml from 'yaml';
|
|
18
|
+
import { exec } from 'child_process';
|
|
19
|
+
import { getDaemonConfigDir, getRuntimeStateDir } from './state.js';
|
|
20
|
+
import { atomicWriteFileSync } from './fs-atomic.js';
|
|
21
|
+
import { readAndResolveBundleEnv } from './secrets/bundles.js';
|
|
22
|
+
import { startWebhookServer, createFileDeliveryStore, waitForListening } from './triggers/webhook.js';
|
|
23
|
+
import { buildFunnelUpCommand, FUNNEL_PORTS } from './funnel.js';
|
|
24
|
+
export const DEFAULT_WEBHOOK_PORT = 8787;
|
|
25
|
+
export const DEFAULT_WEBHOOK_RATE_LIMIT = 60;
|
|
26
|
+
/** Path to `~/.agents/daemon/webhooks.yaml`. */
|
|
27
|
+
export function getDaemonWebhooksConfigPath() {
|
|
28
|
+
return path.join(getDaemonConfigDir(), 'webhooks.yaml');
|
|
29
|
+
}
|
|
30
|
+
function coerceReceiver(item) {
|
|
31
|
+
if (!item || typeof item !== 'object')
|
|
32
|
+
return null;
|
|
33
|
+
const obj = item;
|
|
34
|
+
if (typeof obj.bundle !== 'string' || obj.bundle.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
const rc = { bundle: obj.bundle };
|
|
37
|
+
if (typeof obj.port === 'number' && Number.isInteger(obj.port) && obj.port > 0)
|
|
38
|
+
rc.port = obj.port;
|
|
39
|
+
if (typeof obj.rateLimit === 'number' && Number.isInteger(obj.rateLimit) && obj.rateLimit > 0)
|
|
40
|
+
rc.rateLimit = obj.rateLimit;
|
|
41
|
+
const funnel = obj.funnel;
|
|
42
|
+
// A publicPort Funnel cannot serve is dropped rather than carried forward — the
|
|
43
|
+
// receiver still binds localhost, and `daemon webhooks add` rejects it up front.
|
|
44
|
+
if (funnel && typeof funnel === 'object' && FUNNEL_PORTS.includes(funnel.publicPort)) {
|
|
45
|
+
rc.funnel = { publicPort: funnel.publicPort };
|
|
46
|
+
}
|
|
47
|
+
return rc;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Read the hosted-receivers config. A missing or malformed file yields an empty
|
|
51
|
+
* receiver list — never throws — so a box with no config hosts nothing.
|
|
52
|
+
*/
|
|
53
|
+
export function readDaemonWebhooksConfig() {
|
|
54
|
+
try {
|
|
55
|
+
const raw = fs.readFileSync(getDaemonWebhooksConfigPath(), 'utf-8');
|
|
56
|
+
const parsed = yaml.parse(raw);
|
|
57
|
+
const list = parsed && Array.isArray(parsed.receivers) ? parsed.receivers : [];
|
|
58
|
+
const receivers = list.map(coerceReceiver).filter((r) => r !== null);
|
|
59
|
+
return { receivers };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { receivers: [] };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Write the hosted-receivers config, creating the daemon config dir if needed. */
|
|
66
|
+
export function writeDaemonWebhooksConfig(cfg) {
|
|
67
|
+
fs.mkdirSync(getDaemonConfigDir(), { recursive: true });
|
|
68
|
+
const out = yaml.stringify({ receivers: cfg.receivers }, { sortMapEntries: false });
|
|
69
|
+
atomicWriteFileSync(getDaemonWebhooksConfigPath(), out, 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
/** The port a receiver binds — its identity, since one port hosts one receiver. */
|
|
72
|
+
export function hostedReceiverPort(receiver) {
|
|
73
|
+
return receiver.port ?? DEFAULT_WEBHOOK_PORT;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Declare a receiver on this box, replacing any existing entry on the same port.
|
|
77
|
+
* Port is the identity because two receivers cannot bind one port — a second
|
|
78
|
+
* `add` on a port is an edit, never a silently ignored duplicate.
|
|
79
|
+
*/
|
|
80
|
+
export function addHostedReceiver(receiver) {
|
|
81
|
+
const port = hostedReceiverPort(receiver);
|
|
82
|
+
const existing = readDaemonWebhooksConfig().receivers.filter((r) => hostedReceiverPort(r) !== port);
|
|
83
|
+
const next = { receivers: [...existing, receiver] };
|
|
84
|
+
writeDaemonWebhooksConfig(next);
|
|
85
|
+
return next;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Drop the receiver bound to `port`. Returns the removed entry, or null when
|
|
89
|
+
* nothing was declared there. The caller is responsible for taking down any
|
|
90
|
+
* public Funnel the removed entry declared — leaving it up would keep a public
|
|
91
|
+
* `https://<host>.ts.net` route pointed at a port nothing serves.
|
|
92
|
+
*/
|
|
93
|
+
export function removeHostedReceiver(port) {
|
|
94
|
+
const { receivers } = readDaemonWebhooksConfig();
|
|
95
|
+
const removed = receivers.find((r) => hostedReceiverPort(r) === port);
|
|
96
|
+
if (!removed)
|
|
97
|
+
return null;
|
|
98
|
+
writeDaemonWebhooksConfig({ receivers: receivers.filter((r) => hostedReceiverPort(r) !== port) });
|
|
99
|
+
return removed;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a receiver's signing secrets from its bundle. Reads `agentOnly` (no
|
|
103
|
+
* Touch ID — the daemon is a background service, SEC-13): a broker-held or
|
|
104
|
+
* file-store bundle resolves silently; a locked bundle THROWS the actionable
|
|
105
|
+
* unlock message, which fails the receiver LOUD rather than binding with no
|
|
106
|
+
* verifiable signature. Throws when neither webhook secret is present.
|
|
107
|
+
*/
|
|
108
|
+
export function resolveReceiverSecrets(bundle) {
|
|
109
|
+
const { env } = readAndResolveBundleEnv(bundle, { caller: 'daemon webhook-receiver', agentOnly: true });
|
|
110
|
+
const secrets = {};
|
|
111
|
+
if (env.GITHUB_WEBHOOK_SECRET)
|
|
112
|
+
secrets.github = env.GITHUB_WEBHOOK_SECRET;
|
|
113
|
+
if (env.LINEAR_WEBHOOK_SECRET)
|
|
114
|
+
secrets.linear = env.LINEAR_WEBHOOK_SECRET;
|
|
115
|
+
if (env.SLACK_SIGNING_SECRET)
|
|
116
|
+
secrets.slack = env.SLACK_SIGNING_SECRET;
|
|
117
|
+
if (!secrets.github && !secrets.linear && !secrets.slack) {
|
|
118
|
+
throw new Error(`bundle '${bundle}' has none of GITHUB_WEBHOOK_SECRET, LINEAR_WEBHOOK_SECRET, or SLACK_SIGNING_SECRET`);
|
|
119
|
+
}
|
|
120
|
+
return secrets;
|
|
121
|
+
}
|
|
122
|
+
/** Best-effort funnel reconcile: bring the declared public port up, log on failure. */
|
|
123
|
+
function reconcileFunnel(publicPort, localPort, log) {
|
|
124
|
+
let command;
|
|
125
|
+
try {
|
|
126
|
+
command = buildFunnelUpCommand(publicPort, localPort);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
log('WARN', `webhook funnel skipped (port ${publicPort}): ${err.message}`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
exec(command, (err) => {
|
|
133
|
+
if (err) {
|
|
134
|
+
log('WARN', `webhook funnel reconcile failed (public ${publicPort} -> localhost:${localPort}); binding localhost only: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
log('INFO', `webhook funnel up: public ${publicPort} -> localhost:${localPort}`);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Start every receiver declared in `webhooks.yaml`. A receiver that cannot start
|
|
143
|
+
* — an unreadable secret (locked bundle, no webhook secret) or a failed bind
|
|
144
|
+
* (the port is already taken by a foreground `agents webhooks serve`, another
|
|
145
|
+
* daemon, or anything else) — is skipped with a loud WARN and does NOT take the
|
|
146
|
+
* others, or the daemon, down. Returns a handle that stops them all.
|
|
147
|
+
*
|
|
148
|
+
* This is async because a bind failure is only observable asynchronously:
|
|
149
|
+
* `server.listen()` surfaces EADDRINUSE as an `'error'` event, so a `try/catch`
|
|
150
|
+
* around the start call never sees it and the event reaches the process-level
|
|
151
|
+
* `uncaughtException` handler (`index.ts`), which exits 1 for the supervisor to
|
|
152
|
+
* restart — a crash loop that would take the secrets broker, scheduler,
|
|
153
|
+
* monitors, browser IPC, and self-heal down with it. `waitForListening` is what
|
|
154
|
+
* turns that into one skipped receiver.
|
|
155
|
+
*/
|
|
156
|
+
export async function startHostedWebhookReceivers(opts) {
|
|
157
|
+
const { log } = opts;
|
|
158
|
+
const resolveSecrets = opts.resolveSecrets ?? resolveReceiverSecrets;
|
|
159
|
+
const { receivers } = readDaemonWebhooksConfig();
|
|
160
|
+
const servers = [];
|
|
161
|
+
for (const receiver of receivers) {
|
|
162
|
+
const port = receiver.port ?? DEFAULT_WEBHOOK_PORT;
|
|
163
|
+
let secrets;
|
|
164
|
+
try {
|
|
165
|
+
secrets = resolveSecrets(receiver.bundle);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
log('WARN', `webhook receiver on :${port} skipped: ${err.message}`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
let server = null;
|
|
172
|
+
try {
|
|
173
|
+
server = startWebhookServer({
|
|
174
|
+
host: '127.0.0.1',
|
|
175
|
+
port,
|
|
176
|
+
secrets,
|
|
177
|
+
rateLimitPerMinute: receiver.rateLimit ?? DEFAULT_WEBHOOK_RATE_LIMIT,
|
|
178
|
+
// Per-port durable delivery dedup so replays survive a daemon restart and
|
|
179
|
+
// two receivers on distinct ports never share a dedup ledger.
|
|
180
|
+
deliveryStore: createFileDeliveryStore(path.join(getRuntimeStateDir(), 'webhook', `deliveries-${port}.json`)),
|
|
181
|
+
// Logged at MATCH time, before dispatch — a `run.command` handler can
|
|
182
|
+
// block on a shelled-out agent run for minutes, and that must never
|
|
183
|
+
// delay the log that says a delivery fired (RUSH-2722).
|
|
184
|
+
onMatch: (webhook, matchedJobNames, matchedHandlerNames) => {
|
|
185
|
+
const parts = [];
|
|
186
|
+
if (matchedJobNames.length)
|
|
187
|
+
parts.push(`routines ${matchedJobNames.join(', ')}`);
|
|
188
|
+
if (matchedHandlerNames.length)
|
|
189
|
+
parts.push(`handlers ${matchedHandlerNames.join(', ')}`);
|
|
190
|
+
log('INFO', `webhook ${webhook.source}:${webhook.event} ${parts.length ? `fired ${parts.join('; ')}` : 'no match'}`);
|
|
191
|
+
},
|
|
192
|
+
// The 202 ack means no HTTP status carries a settle failure — the daemon
|
|
193
|
+
// log is where it surfaces, so it is never swallowed.
|
|
194
|
+
onDeliveryError: (webhook, err) => {
|
|
195
|
+
log('WARN', `webhook ${webhook.source}:${webhook.event} dispatch failed after ack: ${err.message}`);
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
await waitForListening(server);
|
|
199
|
+
servers.push(server);
|
|
200
|
+
log('INFO', `webhook receiver bound on 127.0.0.1:${port} (bundle ${receiver.bundle})`);
|
|
201
|
+
if (receiver.funnel)
|
|
202
|
+
reconcileFunnel(receiver.funnel.publicPort, port, log);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
// Close the half-started server so a failed bind leaks no handle, and keep
|
|
206
|
+
// going: one unusable receiver must not cost the others their ingress.
|
|
207
|
+
server?.close(() => { });
|
|
208
|
+
log('WARN', `webhook receiver on :${port} failed to bind: ${err.message}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
count: servers.length,
|
|
213
|
+
close: () => Promise.all(servers.map((s) => new Promise((resolve) => s.close(() => resolve())))).then(() => undefined),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
@@ -1,55 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Device/user config keys — typed read/write over the
|
|
2
|
+
* Device/user config keys — typed read/write over the three-layer store.
|
|
3
3
|
*
|
|
4
4
|
* One registry (`CONFIG_KEYS`) maps each CLI dotted name to where it lives:
|
|
5
|
-
* - user scope
|
|
6
|
-
*
|
|
7
|
-
* - device scope
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* browser.remote-control, scheduler.enabled,
|
|
16
|
-
* daemon.enabled).
|
|
5
|
+
* - user scope → central `~/.agents/agents.yaml` under `config:` (syncs
|
|
6
|
+
* fleet-wide via `agents repo push/pull`)
|
|
7
|
+
* - device scope → the per-device TRACKED doc
|
|
8
|
+
* `~/.agents/devices/<name>/agents.yaml` under `config:` —
|
|
9
|
+
* conflict-free by construction (each machine writes only
|
|
10
|
+
* its own folder, and the churny auto-written pins no longer
|
|
11
|
+
* share the file)
|
|
12
|
+
* - fleet layer → central `~/.agents/agents.yaml` under
|
|
13
|
+
* `fleet.defaults.config` — fleet-wide defaults written by
|
|
14
|
+
* `agents devices config --fleet <key> <value>`
|
|
17
15
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* not just churn.
|
|
16
|
+
* Read order for a device-scope key: built-in default < fleet.defaults.config
|
|
17
|
+
* < per-device config:. Names and non-secret values only (a secrets-bundle
|
|
18
|
+
* NAME is fine; a credential never is).
|
|
22
19
|
*
|
|
23
20
|
* The device registry (`~/.agents/.history/devices/registry.json`) stays the
|
|
24
21
|
* DISCOVERY cache (address, tailscale snapshot, reachability); the profile
|
|
25
22
|
* fields config can override (ssh.*, platform, user) are overlaid onto it at
|
|
26
23
|
* read time by `lib/devices/resolve-profile.ts`.
|
|
27
24
|
*
|
|
28
|
-
* Legacy stores (
|
|
29
|
-
*
|
|
30
|
-
* by `lib/devices/config-migration.ts`, invoked on the first
|
|
31
|
-
* process — after migration there is ONE read path
|
|
25
|
+
* Legacy stores (central `fleet.devices.<name>.config`, legacy auto-launch.json,
|
|
26
|
+
* doc-level defaultBrowserProfile, pins in tracked docs) are folded into this
|
|
27
|
+
* layout once by `lib/devices/config-migration.ts`, invoked on the first
|
|
28
|
+
* read/write in a process — after migration there is ONE read path per layer,
|
|
29
|
+
* no fallback branches.
|
|
32
30
|
*
|
|
33
31
|
* Unset always means today's behavior (the documented default).
|
|
34
32
|
*/
|
|
35
33
|
/** Which tier of the agents.yaml store a key lives in. */
|
|
36
34
|
export type ConfigScope = 'user' | 'device';
|
|
37
35
|
/**
|
|
38
|
-
* For a device-scope key: WHO READS IT
|
|
36
|
+
* For a device-scope key: WHO READS IT. Storage is still the three-layer
|
|
37
|
+
* store (per-device doc / fleet.defaults.config); visibility only gates
|
|
38
|
+
* whether a PEER may read or write the key.
|
|
39
39
|
*
|
|
40
|
-
* - `shared` — a
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* - `machine` — only the owning box ever reads it, so it belongs in that box's
|
|
45
|
-
* own gitignored doc and must never reach the fleet-shared file. Storing these
|
|
46
|
-
* centrally is what makes 13 machines write one tracked path.
|
|
47
|
-
*
|
|
48
|
-
* Declaring this is MANDATORY for a device-scope key — the union below makes
|
|
49
|
-
* omitting it a compile error, mirroring how `META_KEY_SCOPE` (lib/state.ts) uses
|
|
50
|
-
* an exhaustive `Record<keyof Meta, ...>`. Before this, a new key picked its home
|
|
51
|
-
* by hand with no signal, which is how operator config drifted into the shared
|
|
52
|
-
* file twice.
|
|
40
|
+
* - `shared` — a peer reads it (ssh.*, platform, role, caps), so any box
|
|
41
|
+
* may set it for any device. Lands in that device's tracked doc.
|
|
42
|
+
* - `machine` — only the owning box ever reads it (scheduler, daemon, tmux,
|
|
43
|
+
* browser consent). Refused for a peer — run it on that box instead.
|
|
53
44
|
*/
|
|
54
45
|
export type ConfigVisibility = 'shared' | 'machine';
|
|
55
46
|
/** Value type of a config key — drives validation and `--json` rendering. */
|
|
@@ -79,17 +70,21 @@ export type ConfigKeySpec = (ConfigKeySpecBase & {
|
|
|
79
70
|
scope: 'device';
|
|
80
71
|
visibility: ConfigVisibility;
|
|
81
72
|
});
|
|
73
|
+
/** Which layer set a key's effective value (`default` = unset, built-in behavior). */
|
|
74
|
+
export type ConfigSource = 'user' | 'device' | 'fleet' | 'default';
|
|
82
75
|
/** A key with its resolved value and the layer that set it. */
|
|
83
76
|
export interface ConfigEntry {
|
|
84
77
|
spec: ConfigKeySpec;
|
|
85
|
-
/** The
|
|
78
|
+
/** The effective value, or undefined when unset (unset = default behavior). */
|
|
86
79
|
value: unknown;
|
|
87
|
-
/** Which layer set
|
|
88
|
-
|
|
80
|
+
/** Which layer set the effective value. */
|
|
81
|
+
source: ConfigSource;
|
|
89
82
|
}
|
|
90
|
-
/** Options scoping a read/write
|
|
83
|
+
/** Options scoping a read/write: a specific device (default: this machine), or the fleet-defaults layer. */
|
|
91
84
|
export interface ConfigTarget {
|
|
92
85
|
device?: string;
|
|
86
|
+
/** Write/read the fleet-wide defaults layer (central fleet.defaults.config). */
|
|
87
|
+
fleet?: boolean;
|
|
93
88
|
}
|
|
94
89
|
/** Roles a device can be marked with — see the `role` key below. */
|
|
95
90
|
declare const DEVICE_ROLES: readonly ["worker", "personal"];
|
|
@@ -99,40 +94,31 @@ export declare const CONFIG_KEYS: readonly ConfigKeySpec[];
|
|
|
99
94
|
/** Look up a key spec by CLI dotted name, or throw listing the known keys. */
|
|
100
95
|
export declare function configKeySpec(name: string): ConfigKeySpec;
|
|
101
96
|
/**
|
|
102
|
-
* Fold the legacy
|
|
97
|
+
* Fold the legacy config/pins stores into the current layout, once per
|
|
103
98
|
* process. A failure is loud but non-fatal — config reads must keep working,
|
|
104
99
|
* and the next process retries the fold. Honors AGENTS_SKIP_MIGRATION=1, the
|
|
105
100
|
* same gate bootstrap's runMigration uses (tests pin it so a fork never folds
|
|
106
101
|
* the developer's real ~/.agents as a side effect).
|
|
107
|
-
*
|
|
108
|
-
* Call this ONLY from a lifecycle entry point (daemon boot, `runMigration`).
|
|
109
|
-
* It must never hang off a config read or write: `~/.agents/agents.yaml` is a
|
|
110
|
-
* tracked file shared by every machine in the fleet, so a migration on the read
|
|
111
|
-
* path means an ordinary `agents config get` can dirty the shared file. That is
|
|
112
|
-
* what left yosemite-s0 unable to pull — 13 machines each rewriting one tracked
|
|
113
|
-
* path, on nearly every command.
|
|
114
102
|
*/
|
|
115
103
|
export declare function ensureDeviceConfigMigrated(): void;
|
|
104
|
+
/** The fleet-defaults config layer (central `fleet.defaults.config`; {} when unset). */
|
|
105
|
+
export declare function readFleetConfigDefaults(): Record<string, unknown>;
|
|
116
106
|
/**
|
|
117
|
-
* The
|
|
118
|
-
*
|
|
119
|
-
*
|
|
107
|
+
* The effective device-scope config block for `device`: fleet.defaults.config
|
|
108
|
+
* overlaid with the per-device doc's config:. This is the single read path
|
|
109
|
+
* post-migration — the profile resolver (`lib/devices/resolve-profile.ts`)
|
|
120
110
|
* goes through here. Deliberately does NOT auto-trigger the migration: it
|
|
121
|
-
* serves the hot dial/render paths
|
|
122
|
-
* are new — they never existed in the legacy stores. Keys with legacy data are
|
|
123
|
-
* read through the public API below, which triggers the fold.
|
|
111
|
+
* serves the hot dial/render paths. Sync and cheap (small local files).
|
|
124
112
|
*/
|
|
125
113
|
export declare function readDeviceConfigValues(device: string): Record<string, unknown>;
|
|
126
|
-
/** Get one config key's value and the layer that set it. */
|
|
114
|
+
/** Get one config key's effective value and the layer that set it. */
|
|
127
115
|
export declare function getConfigValue(name: string, opts?: ConfigTarget): ConfigEntry;
|
|
128
116
|
/**
|
|
129
|
-
* List every known key with its value and the layer that set it.
|
|
117
|
+
* List every known key with its effective value and the layer that set it.
|
|
130
118
|
*
|
|
131
|
-
* Listing a PEER omits its machine-local keys rather than throwing
|
|
132
|
-
* live
|
|
133
|
-
*
|
|
134
|
-
* `agents devices config <peer>` should still show everything it CAN resolve.
|
|
135
|
-
* Asking for such a key by name still errors, with the `agents ssh` fix named.
|
|
119
|
+
* Listing a PEER omits its machine-local keys rather than throwing — those
|
|
120
|
+
* values live on that box and are unknowable from here, but a bulk listing
|
|
121
|
+
* must not hard-fail. Asking for such a key by name still errors.
|
|
136
122
|
*/
|
|
137
123
|
export declare function listConfig(opts?: ConfigTarget): ConfigEntry[];
|
|
138
124
|
/** List user-scope config keys with their values. Used to show inherited settings
|
|
@@ -140,9 +126,14 @@ export declare function listConfig(opts?: ConfigTarget): ConfigEntry[];
|
|
|
140
126
|
export declare function listUserConfig(): ConfigEntry[];
|
|
141
127
|
/** Resolve the explicit usage host, falling back to the user's interactive host. */
|
|
142
128
|
export declare function resolveUsagePrimaryHost(): string | null;
|
|
143
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Set a config key (validated). Device-scope keys target this machine unless
|
|
131
|
+
* `opts.device` names a peer; `opts.fleet` writes the fleet-wide defaults layer
|
|
132
|
+
* instead. User-scope keys reject `fleet` (they are already fleet-wide).
|
|
133
|
+
*/
|
|
144
134
|
export declare function setConfigValue(name: string, value: unknown, opts?: ConfigTarget): void;
|
|
145
|
-
/** Unset a config key — restores
|
|
135
|
+
/** Unset a config key — restores the next layer down (fleet default, then the
|
|
136
|
+
* built-in default). No-op when already unset at that layer. */
|
|
146
137
|
export declare function unsetConfigValue(name: string, opts?: ConfigTarget): void;
|
|
147
138
|
/** A role an operator marked a device with (`agents devices role <name> <role>`). */
|
|
148
139
|
export type ConfiguredDeviceRole = (typeof DEVICE_ROLES)[number];
|
|
@@ -159,13 +150,18 @@ export declare function configuredDeviceRole(name: string): ConfiguredDeviceRole
|
|
|
159
150
|
/** Mark a device's role fleet-wide; `undefined` clears the mark. */
|
|
160
151
|
export declare function setConfiguredDeviceRole(name: string, role: ConfiguredDeviceRole | undefined): void;
|
|
161
152
|
/**
|
|
162
|
-
* Every device an
|
|
163
|
-
*
|
|
153
|
+
* Every device with an effective role, keyed by device name. Layers like every
|
|
154
|
+
* other device-scope key: the fleet default (central fleet.defaults.config)
|
|
155
|
+
* applies fleet-wide and the per-device doc wins on conflict. `roster` (the
|
|
156
|
+
* registered device names) lets a fleet default reach devices that have no doc
|
|
157
|
+
* of their own; without it only devices with docs are considered — so a
|
|
158
|
+
* fleet-wide `role` default would silently miss a doc-less device and drop it
|
|
159
|
+
* from the worker allowlist. Mirrors {@link loadAutoLaunchPreferences}.
|
|
164
160
|
*/
|
|
165
|
-
export declare function listConfiguredDeviceRoles(): Record<string, ConfiguredDeviceRole>;
|
|
161
|
+
export declare function listConfiguredDeviceRoles(roster?: string[]): Record<string, ConfiguredDeviceRole>;
|
|
166
162
|
/** The configured automatic-placement pool mode. Unset means `workers`. */
|
|
167
163
|
export declare function autoPoolMode(): AutoPoolMode;
|
|
168
|
-
/** A device's auto-launch flags, as read by
|
|
164
|
+
/** A device's auto-launch flags, as read by Factory's launch ranking. */
|
|
169
165
|
export interface AutoLaunchPreference {
|
|
170
166
|
enabled?: boolean;
|
|
171
167
|
preferred?: boolean;
|
|
@@ -173,16 +169,22 @@ export interface AutoLaunchPreference {
|
|
|
173
169
|
/** True if the device is enabled for auto-launch. Unset defaults to true. */
|
|
174
170
|
export declare function isAutoLaunchEnabled(name: string): boolean;
|
|
175
171
|
/** Set whether a device is enabled for auto-launch. Setting the default
|
|
176
|
-
* (enabled) removes the key to keep the
|
|
172
|
+
* (enabled) removes the key to keep the doc minimal. */
|
|
177
173
|
export declare function setAutoLaunchEnabled(name: string, enabled: boolean): void;
|
|
178
174
|
/** True if the device is preferred for auto-launch ranking. */
|
|
179
175
|
export declare function isAutoLaunchPreferred(name: string): boolean;
|
|
180
176
|
/** Set whether a device is preferred for auto-launch. Setting the default
|
|
181
|
-
* (not preferred) removes the key to keep the
|
|
177
|
+
* (not preferred) removes the key to keep the doc minimal. */
|
|
182
178
|
export declare function setAutoLaunchPreferred(name: string, preferred: boolean): void;
|
|
183
|
-
/**
|
|
184
|
-
*
|
|
185
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Every device's effective auto-launch flags, keyed by device name — the shape
|
|
181
|
+
* the menu-bar snapshot consumes. Layers like every other device-scope key: the
|
|
182
|
+
* fleet default (central fleet.defaults.config) applies fleet-wide and the
|
|
183
|
+
* per-device doc wins on conflict. `roster` (the registered device names) lets
|
|
184
|
+
* a fleet default reach devices that have no doc of their own; without it only
|
|
185
|
+
* devices with docs are listed.
|
|
186
|
+
*/
|
|
187
|
+
export declare function loadAutoLaunchPreferences(roster?: string[]): Record<string, AutoLaunchPreference>;
|
|
186
188
|
/** True unless this machine's config disables the routines scheduler. */
|
|
187
189
|
export declare function isSchedulerEnabled(): boolean;
|
|
188
190
|
/**
|
|
@@ -212,10 +214,18 @@ export declare function isDaemonEnabled(): boolean;
|
|
|
212
214
|
*/
|
|
213
215
|
export declare function assertDaemonEnabled(): void;
|
|
214
216
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
217
|
+
* Idle window (ms) the browser-task reaper (`browser/hygiene.ts`) uses on THIS
|
|
218
|
+
* machine, or `null` when idle reaping is off (`browser.task-idle-minutes=0`)
|
|
219
|
+
* — session-dead reaping is unaffected either way. Unset means the default 30
|
|
220
|
+
* minutes. Read by the daemon's periodic tick and, as the fallback when a
|
|
221
|
+
* caller omits `--idle-minutes`, by the `gc` IPC action.
|
|
222
|
+
*/
|
|
223
|
+
export declare function resolveBrowserTaskIdleMs(): number | null;
|
|
224
|
+
/**
|
|
225
|
+
* Read the effective `agents.max-concurrent` cap for each named device (fleet
|
|
226
|
+
* defaults layered under the per-device doc; no SSH). Devices without a cap
|
|
227
|
+
* are omitted — uncapped is the default. Used as an input to host ranking
|
|
228
|
+
* (teams placement, AGI EXT auto-launch), never as a remote probe.
|
|
219
229
|
*/
|
|
220
230
|
export declare function readMaxConcurrentCaps(devices: string[]): Record<string, number>;
|
|
221
231
|
export {};
|