@phnx-labs/agents-cli 1.22.39 → 1.22.40
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 +294 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -26
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +260 -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.js +206 -94
- 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 +9 -12
- 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 +72 -63
- 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 +13 -0
- package/dist/commands/sessions-picker.js +182 -8
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +142 -180
- 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-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 +11 -25
- 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 +1 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +2 -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 +67 -3
- package/dist/lib/browser/profiles.js +129 -7
- 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 +113 -1
- package/dist/lib/browser/service.js +454 -40
- 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 +18 -0
- 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 +102 -0
- package/dist/lib/daemon-webhooks.js +210 -0
- package/dist/lib/device-config.d.ts +85 -75
- package/dist/lib/device-config.js +279 -141
- 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 +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- 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-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 +241 -62
- 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 +3 -3
- package/dist/lib/secrets/bundles.js +7 -7
- 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 +12 -10
- package/dist/lib/secrets/remote.js +21 -14
- 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/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/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +82 -0
- package/dist/lib/share/publish.js +170 -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 +5 -147
- package/dist/lib/startup/command-registry.js +38 -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 +1 -1
- package/dist/lib/triggers/handlers.js +2 -2
- package/dist/lib/triggers/webhook.d.ts +36 -2
- package/dist/lib/triggers/webhook.js +97 -42
- package/dist/lib/types.d.ts +18 -6
- 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/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
|
@@ -10,17 +10,137 @@ import * as fs from 'fs';
|
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import * as yaml from 'yaml';
|
|
12
12
|
import { Cron } from 'croner';
|
|
13
|
-
import { getRoutinesDir, getSystemRoutinesDir, getRunsDir, ensureAgentsDir, getProjectRoutinesDir } from '
|
|
13
|
+
import { getRoutinesDir, getSystemRoutinesDir, getRunsDir, ensureAgentsDir, getProjectRoutinesDir } from '../state.js';
|
|
14
14
|
import * as os from 'os';
|
|
15
|
-
import { safeJoin, isSafeSegmentName } from '
|
|
16
|
-
import { isSafeProjectName, loadProjectDef, projectBasePath } from '
|
|
17
|
-
import { resolveRoutineExecutionContext, } from '
|
|
18
|
-
import { atomicWriteFileSync } from '
|
|
19
|
-
import { ALL_AGENT_IDS, ROUTINE_AGENT_IDS } from '
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
15
|
+
import { safeJoin, isSafeSegmentName } from '../paths.js';
|
|
16
|
+
import { isSafeProjectName, loadProjectDef, projectBasePath } from '../projects.js';
|
|
17
|
+
import { resolveRoutineExecutionContext, } from '../routine-context.js';
|
|
18
|
+
import { atomicWriteFileSync } from '../fs-atomic.js';
|
|
19
|
+
import { ALL_AGENT_IDS, ROUTINE_AGENT_IDS } from '../agents.js';
|
|
20
|
+
import { RUN_STRATEGIES } from '../accounting/rotate.js';
|
|
21
|
+
import { machineId, normalizeHost } from '../machine-id.js';
|
|
22
|
+
import { resolveActor } from '../actor.js';
|
|
23
|
+
import { percentile } from '../percentile.js';
|
|
24
|
+
import { enabledRoutineNames, devicesWithRoutineEnabled, replaceEnabledRoutines, routineEnabledOnThisDevice, setRoutineEnabledOnThisDevice, } from '../routine-activation.js';
|
|
25
|
+
import { humanizeCron, humanizeNextRun } from '../routines-format.js';
|
|
26
|
+
import { discoverProjectRoutines } from '../routines-project.js';
|
|
27
|
+
import { listProjectDefs } from '../projects.js';
|
|
28
|
+
import { monitorRunningJobs } from '../runner.js';
|
|
29
|
+
import { JobScheduler } from '../scheduler.js';
|
|
30
|
+
import { detectOverdueJobs } from '../overdue.js';
|
|
31
|
+
export function fireConditionLabel(job) {
|
|
32
|
+
if (job.schedule)
|
|
33
|
+
return humanizeCron(job.schedule, job.timezone);
|
|
34
|
+
if (job.trigger) {
|
|
35
|
+
if (job.trigger.type === 'github_event') {
|
|
36
|
+
const scope = job.trigger.repo
|
|
37
|
+
? ` (${job.trigger.repo}${job.trigger.branch ? `@${job.trigger.branch}` : ''})`
|
|
38
|
+
: '';
|
|
39
|
+
const filters = [
|
|
40
|
+
job.trigger.action ? `action=${job.trigger.action}` : null,
|
|
41
|
+
job.trigger.label ? `label=${job.trigger.label}` : null,
|
|
42
|
+
].filter(Boolean).join(', ');
|
|
43
|
+
return `on github:${job.trigger.event}${scope}${filters ? ` (${filters})` : ''}`;
|
|
44
|
+
}
|
|
45
|
+
const filters = [
|
|
46
|
+
job.trigger.action ? `action=${job.trigger.action}` : null,
|
|
47
|
+
job.trigger.teamKey ? `team=${job.trigger.teamKey}` : null,
|
|
48
|
+
job.trigger.label ? `label=${job.trigger.label}` : null,
|
|
49
|
+
job.trigger.stateTo ? `stateTo=${job.trigger.stateTo}` : null,
|
|
50
|
+
job.trigger.stateFrom ? `stateFrom=${job.trigger.stateFrom}` : null,
|
|
51
|
+
].filter(Boolean).join(', ');
|
|
52
|
+
return `on linear:${job.trigger.event}${filters ? ` (${filters})` : ''}`;
|
|
53
|
+
}
|
|
54
|
+
return '-';
|
|
55
|
+
}
|
|
56
|
+
export function nextRunForDisplay(job, scheduler) {
|
|
57
|
+
if (isPastOneShotRoutine(job))
|
|
58
|
+
return null;
|
|
59
|
+
return scheduler.getNextRun(job.name);
|
|
60
|
+
}
|
|
61
|
+
export function nextRunLabel(job, scheduler, now) {
|
|
62
|
+
if (isPastOneShotRoutine(job))
|
|
63
|
+
return 'expired';
|
|
64
|
+
return humanizeNextRun(scheduler.getNextRun(job.name) ?? null, now, job.timezone);
|
|
65
|
+
}
|
|
66
|
+
export function localLatestRun(job) {
|
|
67
|
+
return jobRunsOnThisDevice(job) ? getLatestRun(job.name) : null;
|
|
68
|
+
}
|
|
69
|
+
export function listJobsForDisplay(cwd) {
|
|
70
|
+
const jobs = listJobs(cwd);
|
|
71
|
+
const seen = new Set(jobs.map((j) => j.name));
|
|
72
|
+
for (const discovered of discoverProjectRoutines()) {
|
|
73
|
+
if (seen.has(discovered.name))
|
|
74
|
+
continue;
|
|
75
|
+
seen.add(discovered.name);
|
|
76
|
+
jobs.push(discovered.config);
|
|
77
|
+
}
|
|
78
|
+
return jobs;
|
|
79
|
+
}
|
|
80
|
+
export function buildRoutineListJson() {
|
|
81
|
+
try {
|
|
82
|
+
monitorRunningJobs();
|
|
83
|
+
}
|
|
84
|
+
catch { /* best-effort orphan reap */ }
|
|
85
|
+
const jobs = listJobsForDisplay(process.cwd());
|
|
86
|
+
if (jobs.length === 0)
|
|
87
|
+
return [];
|
|
88
|
+
const scheduler = new JobScheduler(async () => { });
|
|
89
|
+
scheduler.loadAll();
|
|
90
|
+
try {
|
|
91
|
+
const overdueSet = new Set();
|
|
92
|
+
try {
|
|
93
|
+
for (const job of detectOverdueJobs())
|
|
94
|
+
overdueSet.add(job.name);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Best-effort indicator; never block the list on detection errors.
|
|
98
|
+
}
|
|
99
|
+
const now = new Date();
|
|
100
|
+
const knownProjectNames = new Set(listProjectDefs().map((project) => project.name));
|
|
101
|
+
return jobs.map((job) => {
|
|
102
|
+
const latestRun = localLatestRun(job);
|
|
103
|
+
const enabledDevices = devicesWithRoutineEnabled(job.name);
|
|
104
|
+
return {
|
|
105
|
+
name: job.name,
|
|
106
|
+
agent: job.agent ?? null,
|
|
107
|
+
workflow: job.workflow ?? null,
|
|
108
|
+
command: job.command ?? null,
|
|
109
|
+
repo: job.repo ?? null,
|
|
110
|
+
schedule: job.schedule ?? null,
|
|
111
|
+
scheduleHuman: fireConditionLabel(job),
|
|
112
|
+
trigger: job.trigger ?? null,
|
|
113
|
+
timezone: job.timezone ?? null,
|
|
114
|
+
devices: enabledDevices,
|
|
115
|
+
enabledDevices,
|
|
116
|
+
host: job.host ?? null,
|
|
117
|
+
hostStrategy: resolveHostStrategy(job),
|
|
118
|
+
source: job.source ?? null,
|
|
119
|
+
sourceRepo: job.source?.repo ?? job.repo ?? null,
|
|
120
|
+
sourceBranch: job.source?.branch ?? null,
|
|
121
|
+
runOnce: Boolean(job.runOnce),
|
|
122
|
+
catchup: job.catchup !== false,
|
|
123
|
+
oneShot: isOneShotRoutine(job),
|
|
124
|
+
expired: isPastOneShotRoutine(job, now),
|
|
125
|
+
runsHere: jobRunsOnThisDevice(job),
|
|
126
|
+
enabled: job.enabled,
|
|
127
|
+
overdue: overdueSet.has(job.name),
|
|
128
|
+
nextRun: nextRunForDisplay(job, scheduler)?.toISOString() ?? null,
|
|
129
|
+
nextRunHuman: nextRunLabel(job, scheduler, now),
|
|
130
|
+
lastStatus: latestRun?.status ?? null,
|
|
131
|
+
exitCode: latestRun?.exitCode ?? null,
|
|
132
|
+
failureReason: latestRun?.errorMessage ?? null,
|
|
133
|
+
lastRunStartedAt: latestRun?.startedAt ?? null,
|
|
134
|
+
lastRunCompletedAt: latestRun?.completedAt ?? null,
|
|
135
|
+
projects: job.projects ?? [],
|
|
136
|
+
projectGroup: computeProjectGroup(job.projects, knownProjectNames),
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
scheduler.stopAll();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
24
144
|
export const HOST_STRATEGIES = ['local', 'host', 'fleet', 'cloud'];
|
|
25
145
|
/** Canonical set of accepted GitHub trigger events — single source for validation. */
|
|
26
146
|
export const GITHUB_TRIGGER_EVENTS = [
|
|
@@ -230,11 +350,18 @@ export function finalizeRunMeta(meta, status, exitCode, opts) {
|
|
|
230
350
|
* `normalizeHost` so `Yosemite-S0`, `yosemite-s0.tailnet.ts.net`, and
|
|
231
351
|
* `yosemite-s0` all agree. Every fire path (cron scheduler, webhook,
|
|
232
352
|
* catchup/overdue, manual run) gates on this.
|
|
353
|
+
*
|
|
354
|
+
* A monitor-dispatched job ({@link JobConfig.dispatchedBy} `=== 'monitor'`) skips
|
|
355
|
+
* the routine activation manifest: it is not a routine, so its name can never be
|
|
356
|
+
* a member and the lookup could only ever answer "not activated here"
|
|
357
|
+
* (RUSH-2681). Its ownership was already decided by the monitor's `device:` pin.
|
|
233
358
|
*/
|
|
234
359
|
export function jobRunsOnThisDevice(config) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
360
|
+
if (config.dispatchedBy !== 'monitor') {
|
|
361
|
+
const activated = routineEnabledOnThisDevice(config.name);
|
|
362
|
+
if (activated !== null)
|
|
363
|
+
return activated;
|
|
364
|
+
}
|
|
238
365
|
const owner = routineOwnerDevice(config);
|
|
239
366
|
// Unrestricted: no pin means fleet-wide by design (`watchdog`, `check-updates`).
|
|
240
367
|
if (owner === null)
|
|
@@ -346,7 +473,7 @@ export function checkJobDeviceEligibility(config) {
|
|
|
346
473
|
// refuse the run for exactly the same reason.
|
|
347
474
|
const firstHost = routineOwnerDevice(config) ?? allowed[0] ?? 'HOST';
|
|
348
475
|
const message = `Job '${config.name}' can only run on: ${allowedLabel}`;
|
|
349
|
-
const suggestion = `agents routines run ${config.name} --
|
|
476
|
+
const suggestion = `agents routines run ${config.name} --device ${firstHost}`;
|
|
350
477
|
return { message, suggestion, allowedLabel, firstHost };
|
|
351
478
|
}
|
|
352
479
|
/** Default values applied to every job config when fields are omitted. */
|
|
@@ -499,6 +626,18 @@ export function readJobFileResult(filePath) {
|
|
|
499
626
|
&& !Array.isArray(parsed.devices)) {
|
|
500
627
|
return { config: null, problem: '`devices:` must be a list — routine is inert' };
|
|
501
628
|
}
|
|
629
|
+
// Fail closed on `dispatchedBy`. It is a runtime-only marker set by
|
|
630
|
+
// lib/monitors/dispatch.ts on a job that has no definition file, and it makes
|
|
631
|
+
// `jobRunsOnThisDevice` SKIP this device's routine activation manifest. A
|
|
632
|
+
// routine YAML carrying it would therefore fire on every box regardless of
|
|
633
|
+
// activation, on every path (scheduler, overdue, webhook) — the same
|
|
634
|
+
// unrestricted-and-silent outcome the `devices:` guard above exists to
|
|
635
|
+
// prevent, and the daemon's load path never calls validateJob. It is never
|
|
636
|
+
// written back (writeJob deletes it), so its presence here means hand-authored
|
|
637
|
+
// state, not drift.
|
|
638
|
+
if (Object.prototype.hasOwnProperty.call(parsed, 'dispatchedBy')) {
|
|
639
|
+
return { config: null, problem: '`dispatchedBy:` is a runtime-only monitor marker, not a routine field — routine is inert' };
|
|
640
|
+
}
|
|
502
641
|
return {
|
|
503
642
|
config: {
|
|
504
643
|
...JOB_DEFAULTS,
|
|
@@ -556,6 +695,10 @@ export function writeJob(config) {
|
|
|
556
695
|
if (output.catchup === true || output.catchup === undefined)
|
|
557
696
|
delete output.catchup;
|
|
558
697
|
delete output.devices;
|
|
698
|
+
// Runtime-only monitor marker — a definition on disk must never carry it (see
|
|
699
|
+
// the read-side guard in readJobFileResult), so strip it at the one schema
|
|
700
|
+
// boundary rather than trusting every caller.
|
|
701
|
+
delete output.dispatchedBy;
|
|
559
702
|
// Persist projects in canonical form: deduplicated, first-seen order, field
|
|
560
703
|
// omitted when nothing survives. This is the schema boundary, so a routine
|
|
561
704
|
// written from any path (add, edit, enable/disable re-write) lands canonical
|
|
@@ -739,6 +882,17 @@ export function validateJob(config) {
|
|
|
739
882
|
errors.push(`resume is only supported for agents with native --resume (${RESUMABLE_AGENTS.join(', ')}); got '${config.agent}'`);
|
|
740
883
|
}
|
|
741
884
|
}
|
|
885
|
+
if (config.strategy !== undefined) {
|
|
886
|
+
if (!RUN_STRATEGIES.includes(config.strategy)) {
|
|
887
|
+
errors.push(`strategy must be one of: ${RUN_STRATEGIES.join(', ')}`);
|
|
888
|
+
}
|
|
889
|
+
if (!hasAgent) {
|
|
890
|
+
errors.push('strategy only applies to agent routines (drop it for workflow/command routines)');
|
|
891
|
+
}
|
|
892
|
+
if (config.version) {
|
|
893
|
+
errors.push(`strategy ${config.strategy} conflicts with version ${config.version} — an exact pin leaves nothing to select; drop strategy or the version pin`);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
742
896
|
if (config.mode && !['plan', 'edit', 'auto', 'skip', 'full'].includes(config.mode)) {
|
|
743
897
|
errors.push("mode must be plan, edit, auto, or skip ('full' accepted as alias for skip)");
|
|
744
898
|
}
|
|
@@ -773,6 +927,11 @@ export function validateJob(config) {
|
|
|
773
927
|
if (strategy === 'host' && (!config.host || config.host.trim() === '')) {
|
|
774
928
|
errors.push("hostStrategy: host requires host: (set via --run-on or host: in YAML)");
|
|
775
929
|
}
|
|
930
|
+
// `host: auto` is fire-time fleet placement (resolveDeviceAuto), never a
|
|
931
|
+
// literal SSH target — it is only meaningful under hostStrategy: fleet.
|
|
932
|
+
if (config.host === 'auto' && strategy !== 'fleet') {
|
|
933
|
+
errors.push("host: auto requires hostStrategy: fleet (set via --run-on auto) — 'auto' is a fire-time device pick, not a machine name");
|
|
934
|
+
}
|
|
776
935
|
// Remote placement (host/fleet/cloud) can't carry workflow/loop/command yet —
|
|
777
936
|
// those live on the firing machine.
|
|
778
937
|
if (strategy === 'host' || strategy === 'fleet' || strategy === 'cloud') {
|
|
Binary file
|
|
Binary file
|
|
@@ -1439,7 +1439,7 @@ export async function ensureAgentRunning(timeoutMs = 5000) {
|
|
|
1439
1439
|
// hosts it and it holds no unlocks. Evicting a daemon-hosted broker orphans
|
|
1440
1440
|
// the daemon's socket and starts the Touch ID storm — see
|
|
1441
1441
|
// shouldClientEvictSkewedBroker.
|
|
1442
|
-
const { isDaemonRunning } = await import('../daemon.js');
|
|
1442
|
+
const { isDaemonRunning } = await import('../daemon/daemon.js');
|
|
1443
1443
|
if (!shouldClientEvictSkewedBroker(isDaemonRunning(), (await agentStatus()).length))
|
|
1444
1444
|
return true;
|
|
1445
1445
|
await teardownStaleBroker();
|
|
@@ -1454,7 +1454,7 @@ export async function ensureAgentRunning(timeoutMs = 5000) {
|
|
|
1454
1454
|
// backbone rather than a separate launchd service. If bringing the daemon up
|
|
1455
1455
|
// makes the broker answer, we're done.
|
|
1456
1456
|
try {
|
|
1457
|
-
const { ensureDaemonStarted } = await import('../daemon.js');
|
|
1457
|
+
const { ensureDaemonStarted } = await import('../daemon/daemon.js');
|
|
1458
1458
|
if (ensureDaemonStarted()) {
|
|
1459
1459
|
const d0 = Date.now() + timeoutMs;
|
|
1460
1460
|
while (Date.now() < d0) {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* underlying resolve emits its own `secrets.get`.
|
|
34
34
|
* - `secrets.view` — a bundle's (masked) metadata was inspected via `view`.
|
|
35
35
|
*/
|
|
36
|
-
import { emit } from '../events.js';
|
|
36
|
+
import { emit } from '../feed/events.js';
|
|
37
37
|
import { recordSecretUsage } from './usage-db.js';
|
|
38
38
|
/**
|
|
39
39
|
* Map each audit event onto the usage-DB kind it is counted as. `secrets.get` is
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* bytes land. A file-backed bundle is discovered by the presence of its
|
|
15
15
|
* metadata item in the file store.
|
|
16
16
|
* - `vault`: a single age-encrypted ~/.agents/vault.age file unlocked by
|
|
17
|
-
* `agents
|
|
17
|
+
* `agents secrets vault unlock`; intended for user-managed cross-machine file sync.
|
|
18
18
|
*
|
|
19
19
|
* Server-backed cross-machine sync is handled by src/lib/secrets/sync.ts via
|
|
20
20
|
* an explicit encrypted export/import flow; the bundle layer also supports the
|
|
@@ -281,13 +281,13 @@ export declare function filterAgentHitBySubsetAndExpiry(hit: {
|
|
|
281
281
|
env: Record<string, string>;
|
|
282
282
|
};
|
|
283
283
|
/**
|
|
284
|
-
* Guard for remote-bundle callers (`bundle@host` / `--
|
|
284
|
+
* Guard for remote-bundle callers (`bundle@host` / `--device`) — the SSH
|
|
285
285
|
* resolver in `remoteResolveEnv` does not thread --keys or --allow-expired
|
|
286
286
|
* yet. Silently applying them would inject the full remote env or an expired
|
|
287
287
|
* value, defeating the least-privilege intent, so we fail loud.
|
|
288
288
|
*
|
|
289
289
|
* Exported so `agents run --secrets bundle@host` and `agents secrets exec
|
|
290
|
-
* --
|
|
290
|
+
* --device` share the exact same error text; the tests exercise this helper
|
|
291
291
|
* directly instead of driving the whole CLI.
|
|
292
292
|
*/
|
|
293
293
|
export declare function assertRemoteBundleFlagsUnsupported(bundleName: string, host: string, opts: {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* bytes land. A file-backed bundle is discovered by the presence of its
|
|
15
15
|
* metadata item in the file store.
|
|
16
16
|
* - `vault`: a single age-encrypted ~/.agents/vault.age file unlocked by
|
|
17
|
-
* `agents
|
|
17
|
+
* `agents secrets vault unlock`; intended for user-managed cross-machine file sync.
|
|
18
18
|
*
|
|
19
19
|
* Server-backed cross-machine sync is handled by src/lib/secrets/sync.ts via
|
|
20
20
|
* an explicit encrypted export/import flow; the bundle layer also supports the
|
|
@@ -27,7 +27,7 @@ import * as yaml from 'yaml';
|
|
|
27
27
|
import { deleteKeychainToken, getKeychainToken, getKeychainTokens, hasKeychainToken, isKeychainBackendOverridden, keychainServiceAlias, keychainUsesFileFallback, listKeychainItems, parseBundleValue, resolveRef, secretsKeychainItem, setKeychainToken, } from './index.js';
|
|
28
28
|
import { fileStore } from './filestore.js';
|
|
29
29
|
import { getVaultSession, vaultDeleteItem, vaultExists, vaultGetItems, vaultGetItem, vaultHasItem, vaultListItems, vaultSetItems, vaultSetItem, } from './vault.js';
|
|
30
|
-
import { emit } from '../events.js';
|
|
30
|
+
import { emit } from '../feed/events.js';
|
|
31
31
|
import { emitSecretAudit } from './audit.js';
|
|
32
32
|
import { readMeta, getHelpersDir } from '../state.js';
|
|
33
33
|
import { assertNameActiveInResourceProfile, filterNamesForActiveResourceProfile } from '../resource-profiles.js';
|
|
@@ -111,7 +111,7 @@ export function bundleBackend(name) {
|
|
|
111
111
|
function assertVaultBackendUsable(name) {
|
|
112
112
|
if (getVaultSession().loggedIn)
|
|
113
113
|
return;
|
|
114
|
-
throw new Error(`Synced bundle '${name}' needs an active login. Run: agents
|
|
114
|
+
throw new Error(`Synced bundle '${name}' needs an active login. Run: agents secrets vault unlock`);
|
|
115
115
|
}
|
|
116
116
|
/** Allowed values for a secret's `type` metadata field. */
|
|
117
117
|
export const SECRET_TYPES = [
|
|
@@ -280,7 +280,7 @@ export function readBundle(name) {
|
|
|
280
280
|
throw new BundleUndecryptableError(`Bundle '${name}': failed to decrypt — wrong AGENTS_SECRETS_PASSPHRASE or tampered file store. (${err.message})`);
|
|
281
281
|
}
|
|
282
282
|
if (vaultExists() && !getVaultSession().loggedIn) {
|
|
283
|
-
throw new Error(`Synced secrets are locked. Run: agents
|
|
283
|
+
throw new Error(`Synced secrets are locked. Run: agents secrets vault unlock`);
|
|
284
284
|
}
|
|
285
285
|
// Distinguish a genuinely-absent bundle from a present-but-unreadable one
|
|
286
286
|
// (a locked login keychain, or a legacy ACL'd metadata item before first
|
|
@@ -1065,13 +1065,13 @@ export function filterAgentHitBySubsetAndExpiry(hit, opts) {
|
|
|
1065
1065
|
return { bundle: hit.bundle, env };
|
|
1066
1066
|
}
|
|
1067
1067
|
/**
|
|
1068
|
-
* Guard for remote-bundle callers (`bundle@host` / `--
|
|
1068
|
+
* Guard for remote-bundle callers (`bundle@host` / `--device`) — the SSH
|
|
1069
1069
|
* resolver in `remoteResolveEnv` does not thread --keys or --allow-expired
|
|
1070
1070
|
* yet. Silently applying them would inject the full remote env or an expired
|
|
1071
1071
|
* value, defeating the least-privilege intent, so we fail loud.
|
|
1072
1072
|
*
|
|
1073
1073
|
* Exported so `agents run --secrets bundle@host` and `agents secrets exec
|
|
1074
|
-
* --
|
|
1074
|
+
* --device` share the exact same error text; the tests exercise this helper
|
|
1075
1075
|
* directly instead of driving the whole CLI.
|
|
1076
1076
|
*/
|
|
1077
1077
|
export function assertRemoteBundleFlagsUnsupported(bundleName, host, opts, flagLabels) {
|
|
@@ -1365,7 +1365,7 @@ export function readAndResolveBundleEnv(name, opts = {}) {
|
|
|
1365
1365
|
const json = metaFetched.get(metaItem);
|
|
1366
1366
|
if (json === undefined) {
|
|
1367
1367
|
if (vaultExists() && !getVaultSession().loggedIn) {
|
|
1368
|
-
throw new Error(`Synced secrets are locked. Run: agents
|
|
1368
|
+
throw new Error(`Synced secrets are locked. Run: agents secrets vault unlock`);
|
|
1369
1369
|
}
|
|
1370
1370
|
throw new Error(`Secrets bundle '${name}' not found.`);
|
|
1371
1371
|
}
|
|
@@ -73,7 +73,7 @@ function spawnKeychainHelper(bin, args, opts, timeoutMs) {
|
|
|
73
73
|
if (keychainDaemonBootEnabled && !keychainDaemonBootAttempted) {
|
|
74
74
|
keychainDaemonBootAttempted = true;
|
|
75
75
|
// Fire-and-forget: daemon start must not block the foreground secrets op.
|
|
76
|
-
import('../daemon.js')
|
|
76
|
+
import('../daemon/daemon.js')
|
|
77
77
|
.then(({ ensureDaemonStarted }) => ensureDaemonStarted())
|
|
78
78
|
.catch(() => { });
|
|
79
79
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Filters for `agents secrets list`.
|
|
3
3
|
*
|
|
4
|
-
* The listing had no filtering at all: `--
|
|
4
|
+
* The listing had no filtering at all: `--device`/`--device` pick a machine and
|
|
5
5
|
* `--json` picks a format, but nothing selected over the bundles themselves. On
|
|
6
6
|
* a fleet with fifty-odd bundles the answerable questions — which ones read with
|
|
7
7
|
* no Touch ID at all, which hold a raw literal, which have already expired, what
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Filters for `agents secrets list`.
|
|
3
3
|
*
|
|
4
|
-
* The listing had no filtering at all: `--
|
|
4
|
+
* The listing had no filtering at all: `--device`/`--device` pick a machine and
|
|
5
5
|
* `--json` picks a format, but nothing selected over the bundles themselves. On
|
|
6
6
|
* a fleet with fifty-odd bundles the answerable questions — which ones read with
|
|
7
7
|
* no Touch ID at all, which hold a raw literal, which have already expired, what
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* unknown value is a loud error naming the valid set (never a silent ignore),
|
|
18
18
|
* and every axis narrows independently so they AND-compose.
|
|
19
19
|
*/
|
|
20
|
-
import { parseCommaSeparatedList } from '
|
|
20
|
+
import { parseCommaSeparatedList } from '../format.js';
|
|
21
21
|
// From the leaf module, NOT discover.js — the latter imports `../sqlite.js`, so
|
|
22
22
|
// reaching through it for one parser would pull node:sqlite into every `agents
|
|
23
23
|
// secrets` invocation and print Node's SQLite ExperimentalWarning on stderr.
|
|
@@ -31,7 +31,7 @@ export interface PushBundleOptions {
|
|
|
31
31
|
* what pushed operators toward exporting the master key fleet-wide (RUSH-1968).
|
|
32
32
|
*/
|
|
33
33
|
passphrase?: string;
|
|
34
|
-
/** Label for the audit trail — `export --
|
|
34
|
+
/** Label for the audit trail — `export --device` vs `fleet apply`. */
|
|
35
35
|
operation: string;
|
|
36
36
|
/** Preserve an automation account's permanent prompt-free policy remotely. */
|
|
37
37
|
policyNever?: boolean;
|
package/dist/lib/secrets/push.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Push one bundle's values to a remote host over SSH — the provisioning
|
|
3
|
-
* primitive behind `agents secrets export --
|
|
3
|
+
* primitive behind `agents secrets export --device` and, from RUSH-1968, behind
|
|
4
4
|
* `agents fleet apply --provision-secrets`.
|
|
5
5
|
*
|
|
6
|
-
* This logic used to live inline in the `export --
|
|
6
|
+
* This logic used to live inline in the `export --device` command action. It moved
|
|
7
7
|
* here because `lib/fleet/apply.ts` needs it and a lib MUST NOT import a command
|
|
8
8
|
* module — and because the absence of a callable primitive is part of why
|
|
9
9
|
* `fleet apply` never provisioned secrets at all, leaving an operator to
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* interleaving stray lines into it.
|
|
18
18
|
* - **Resolve once, push N times.** `resolveBundleForPush` is separate because
|
|
19
19
|
* reading a bundle can prompt (Touch ID); doing it per host would prompt per
|
|
20
|
-
* host. `export --
|
|
20
|
+
* host. `export --device a,b,c` resolves once and pushes three times.
|
|
21
21
|
*/
|
|
22
22
|
import { sshExec } from '../ssh-exec.js';
|
|
23
23
|
import { remoteShellFor, buildWindowsStdinImportCommand } from '../hosts/remote-cmd.js';
|
|
@@ -89,6 +89,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
89
89
|
const { remoteCmd, input } = buildRemoteFileImportCommand(bundle, resolved.dotenv, {
|
|
90
90
|
passphrase: opts.passphrase ?? '',
|
|
91
91
|
force: opts.force,
|
|
92
|
+
policyNever: opts.policyNever,
|
|
92
93
|
});
|
|
93
94
|
return { kind: 'ssh', remoteCmd, input, multiplex: false };
|
|
94
95
|
}
|
|
@@ -100,7 +101,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
100
101
|
// the wire over ssh stdin.
|
|
101
102
|
return {
|
|
102
103
|
kind: 'ssh',
|
|
103
|
-
remoteCmd: buildWindowsStdinImportCommand(bundle, { force: opts.force }),
|
|
104
|
+
remoteCmd: buildWindowsStdinImportCommand(bundle, { force: opts.force, policyNever: opts.policyNever }),
|
|
104
105
|
input: resolved.dotenv,
|
|
105
106
|
multiplex: false,
|
|
106
107
|
};
|
|
@@ -110,7 +111,11 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
110
111
|
// path the READ inverse (`remoteResolveEnv`) uses.
|
|
111
112
|
return {
|
|
112
113
|
kind: 'remote-secrets',
|
|
113
|
-
args: [
|
|
114
|
+
args: [
|
|
115
|
+
'import', bundle, '--from', '-',
|
|
116
|
+
...(opts.force ? ['--force'] : []),
|
|
117
|
+
...(opts.policyNever ? ['--policy', 'never', '--i-understand'] : []),
|
|
118
|
+
],
|
|
114
119
|
input: resolved.dotenv,
|
|
115
120
|
multiplex: false,
|
|
116
121
|
};
|
|
@@ -158,13 +163,6 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
|
|
|
158
163
|
: `pushed '${bundle}' but could not verify it on the remote: ${verdict.reason}`);
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
|
-
if (opts.policyNever) {
|
|
162
|
-
const policy = remoteSecretsRaw(host, ['policy', bundle, 'never', '--i-understand'], { osLookupName: host, secret: true });
|
|
163
|
-
if (policy.code !== 0) {
|
|
164
|
-
const msg = (policy.stderr || policy.stdout || '').trim();
|
|
165
|
-
return fail(`pushed '${bundle}' but could not set remote policy never${msg ? `: ${msg}` : ''}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
166
|
for (const step of planLiteralRestoration(bundle, opts.literalValues)) {
|
|
169
167
|
const removed = remoteSecretsRaw(host, step.removeArgs, { osLookupName: host, secret: true });
|
|
170
168
|
if (removed.code !== 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Remote secrets — read and use `agents secrets` bundles that live on another
|
|
3
|
-
* host, over the same hardened SSH path that `agents secrets export --
|
|
3
|
+
* host, over the same hardened SSH path that `agents secrets export --device`
|
|
4
4
|
* (the write inverse) already uses.
|
|
5
5
|
*
|
|
6
6
|
* This is the READ / USE direction:
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* inject it ephemerally — never written to this machine's keychain.
|
|
11
11
|
*
|
|
12
12
|
* Trust model: relies on the operator's existing SSH access to the host (same
|
|
13
|
-
* boundary as `export --
|
|
13
|
+
* boundary as `export --device` / `run --device`). Bundle names are shell-quoted
|
|
14
14
|
* into the remote command; resolved VALUES return over ssh stdout; a forwarded
|
|
15
15
|
* file-backend passphrase travels over ssh stdin (first line) so it never lands
|
|
16
16
|
* in argv / `ps` / remote shell history. Nothing is persisted locally.
|
|
@@ -27,9 +27,8 @@ import { type SshExecResult } from '../ssh-exec.js';
|
|
|
27
27
|
* - **Managed pinned host keys.** Verify against the CLI-owned known_hosts
|
|
28
28
|
* store (`known-hosts.ts`), not `~/.ssh/known_hosts`. A CHANGED key on a
|
|
29
29
|
* known host is refused (`StrictHostKeyChecking` `yes` once pinned,
|
|
30
|
-
* `accept-new`
|
|
31
|
-
*
|
|
32
|
-
* key can never receive or return a secret.
|
|
30
|
+
* `accept-new` before that). Callers that copy durable provider credentials
|
|
31
|
+
* must separately require an existing pin before invoking this transport.
|
|
33
32
|
* - **No multiplex reuse.** `multiplex: false` — a credential channel never
|
|
34
33
|
* leaves a persistent `ControlMaster` socket lingering (60s `ControlPersist`)
|
|
35
34
|
* that any other `agents` invocation to that host would silently reuse.
|
|
@@ -38,6 +37,8 @@ export declare function credentialTransportSshOpts(target: string): {
|
|
|
38
37
|
hostKeyOpts: string[];
|
|
39
38
|
multiplex: false;
|
|
40
39
|
};
|
|
40
|
+
/** Refuse durable credential transfer until the destination SSH key is pinned. */
|
|
41
|
+
export declare function assertCredentialTransportHostPinned(target: string, pinned?: boolean): void;
|
|
41
42
|
/**
|
|
42
43
|
* Trust boundary for a remote-resolved env map. A peer's `secrets export` output
|
|
43
44
|
* is untrusted input: a compromised or misconfigured host could return keys that
|
|
@@ -56,9 +57,9 @@ export declare function credentialTransportSshOpts(target: string): {
|
|
|
56
57
|
*/
|
|
57
58
|
export declare function isDangerousRemoteEnvKey(name: string): boolean;
|
|
58
59
|
/**
|
|
59
|
-
* Resolve a `--
|
|
60
|
+
* Resolve a `--device` value to an ssh target STRING for the remote-secrets path.
|
|
60
61
|
* Delegates to the single host/device resolver (`resolveHost`, RUSH-1967) so a
|
|
61
|
-
* name here dials the exact same box `run --
|
|
62
|
+
* name here dials the exact same box `run --device` does; on a miss, treats the
|
|
62
63
|
* value as a raw ssh target and validates it against injection. Named distinctly
|
|
63
64
|
* from `../devices/resolve-target.ts` (which returns richer shapes) so importing
|
|
64
65
|
* the wrong one can't silently change which machine you dial.
|
|
@@ -67,7 +68,7 @@ export declare function resolveHostSshTarget(nameOrAlias: string): Promise<strin
|
|
|
67
68
|
/**
|
|
68
69
|
* Merge `--host <single>` / `--hosts <a,b,c>` (and their `--device` / `--devices`
|
|
69
70
|
* aliases) into an ordered, de-duplicated list. All four flags compose; any alone
|
|
70
|
-
* works. `--device`/`--devices` resolve identically to `--
|
|
71
|
+
* works. `--device`/`--devices` resolve identically to `--device`/`--hosts` so the
|
|
71
72
|
* fleet-wide `--device` vocabulary (see `agents run --device`, `agents feed --host`)
|
|
72
73
|
* works on the secrets remote commands too. Empty when none is set.
|
|
73
74
|
*/
|
|
@@ -109,7 +110,7 @@ export declare function remoteSecretsRaw(target: string, args: string[], opts?:
|
|
|
109
110
|
* appear (the macOS file-store guard then hard-errors "needs
|
|
110
111
|
* AGENTS_SECRETS_PASSPHRASE") — this inherits the caller's real terminal, so the
|
|
111
112
|
* remote sees a genuine TTY and its hidden passphrase prompt surfaces and reads
|
|
112
|
-
* the keystrokes. This is the transport for `unlock --
|
|
113
|
+
* the keystrokes. This is the transport for `unlock --device`: you type the remote
|
|
113
114
|
* bundle's passphrase at your own terminal. Output is NOT captured (it streams
|
|
114
115
|
* to the terminal); only the exit code is returned.
|
|
115
116
|
*/
|
|
@@ -203,7 +204,7 @@ export declare function verifyRemoteKeychainPush(target: string, bundle: string,
|
|
|
203
204
|
}): RemoteKeychainWriteVerification;
|
|
204
205
|
/**
|
|
205
206
|
* The `bash -lc` command + stdin payload that drives a **file-backed** remote
|
|
206
|
-
* import for `secrets export --
|
|
207
|
+
* import for `secrets export --device … --remote-backend file`.
|
|
207
208
|
*
|
|
208
209
|
* The file store is passphrase-free by default: with `AGENTS_SECRETS_PASSPHRASE`
|
|
209
210
|
* unset the remote `agents secrets import --backend file` auto-provisions the
|
|
@@ -226,6 +227,7 @@ export declare function verifyRemoteKeychainPush(target: string, bundle: string,
|
|
|
226
227
|
export declare function buildRemoteFileImportCommand(bundle: string, dotenv: string, opts?: {
|
|
227
228
|
passphrase?: string;
|
|
228
229
|
force?: boolean;
|
|
230
|
+
policyNever?: boolean;
|
|
229
231
|
}): {
|
|
230
232
|
remoteCmd: string;
|
|
231
233
|
input: string;
|