@phnx-labs/agents-cli 1.22.38 → 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 +302 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +46 -27
- 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 +47 -4
- 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 +161 -216
- 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 +318 -48
- 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 +12 -3
- package/dist/lib/config-keys.js +29 -6
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +6 -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 +116 -72
- package/dist/lib/device-config.js +366 -132
- 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 +61 -0
- package/dist/lib/devices/pool.js +83 -0
- 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 +8 -5
- package/dist/lib/exec.js +19 -13
- 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} +49 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +265 -38
- 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 +36 -6
- package/dist/lib/smart-launch.js +65 -8
- 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
package/dist/lib/exec.js
CHANGED
|
@@ -10,11 +10,11 @@ import * as fs from 'fs';
|
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import { ALL_MODES } from './types.js';
|
|
12
12
|
import { AGENTS, findInPath } from './agents.js';
|
|
13
|
-
import { parseTimeout } from './routines.js';
|
|
14
|
-
import { compareVersions, getBinaryPath, getVersionHomePath, isVersionInstalled, listInstalledVersions, resolveVersion } from './versions.js';
|
|
13
|
+
import { parseTimeout } from './scheduling/routines.js';
|
|
14
|
+
import { compareVersions, getBinaryPath, getVersionHomePath, isVersionInstalled, listInstalledVersions, resolveVersion } from './installations/versions.js';
|
|
15
15
|
import { resolveModel, buildReasoningFlags } from './models.js';
|
|
16
16
|
import { isTierToken, resolveTier } from './model-tiers.js';
|
|
17
|
-
import { createTimer, redactPrompt, redactArgs } from './events.js';
|
|
17
|
+
import { createTimer, redactPrompt, redactArgs } from './feed/events.js';
|
|
18
18
|
import { sanitizeProcessEnv } from './secrets/bundles.js';
|
|
19
19
|
import { resolveActor, actorEnv } from './actor.js';
|
|
20
20
|
import { expandLocalHome } from './project-root.js';
|
|
@@ -29,6 +29,8 @@ import { recordRunName } from './session/run-names.js';
|
|
|
29
29
|
import { mailboxDir, isValidMailboxId } from './mailbox.js';
|
|
30
30
|
import { composeWin32CommandLine } from './platform/index.js';
|
|
31
31
|
import { isTmuxInstalled } from './tmux/binary.js';
|
|
32
|
+
import { isTmuxEnabled } from './device-config.js';
|
|
33
|
+
import { machineId } from './machine-id.js';
|
|
32
34
|
import { shellQuote } from './ssh-exec.js';
|
|
33
35
|
import { resolveClaudeSetupToken } from './claude-account-token.js';
|
|
34
36
|
import { codexEditWritableRoots, codexPolicyArgs } from './codex-policy.js';
|
|
@@ -257,10 +259,10 @@ export function parseExecEnv(entries) {
|
|
|
257
259
|
* alongside the agent's real session id (terminals/sessions/<pid>.json), so it
|
|
258
260
|
* is what maps a launch to its exact session even when the hook runs under a
|
|
259
261
|
* different pid (tmux pane leaf / cmd.exe wrapper) — and, across an SSH hop, what
|
|
260
|
-
* lets a `--
|
|
262
|
+
* lets a `--device` launcher resolve the remote-coined id for agents that never
|
|
261
263
|
* accept a forced `--session-id`.
|
|
262
264
|
*
|
|
263
|
-
* ADOPT a caller-supplied `AGENT_LAUNCH_ID` (a `--
|
|
265
|
+
* ADOPT a caller-supplied `AGENT_LAUNCH_ID` (a `--device` launcher forwards one via
|
|
264
266
|
* `--env` so it controls the key end-to-end); MINT a fresh one otherwise (every
|
|
265
267
|
* local run, which passes none). A malformed inbound value is ignored in favour
|
|
266
268
|
* of a fresh mint — the key must be a real correlation id, never an empty string.
|
|
@@ -471,7 +473,7 @@ export function buildExecEnv(options) {
|
|
|
471
473
|
// (events.ts::resolveProvenance) reads AGENTS_PARENT_SESSION_ID and stamps it on
|
|
472
474
|
// every event the child emits. `options.sessionId` is the CHILD's id, so read the
|
|
473
475
|
// spawner from the live env; guard a same-session resume from naming itself parent.
|
|
474
|
-
// Local-spawn scope here; forwarding it across the `--
|
|
476
|
+
// Local-spawn scope here; forwarding it across the `--device` SSH hop is Phase 4.
|
|
475
477
|
const spawnerSessionId = process.env.AGENTS_SESSION_ID || process.env.AGENT_SESSION_ID;
|
|
476
478
|
if (spawnerSessionId && spawnerSessionId !== options.sessionId) {
|
|
477
479
|
result.AGENTS_PARENT_SESSION_ID = spawnerSessionId;
|
|
@@ -1292,7 +1294,7 @@ export function shouldRecapDeadPane(status, interactive) {
|
|
|
1292
1294
|
* Why this is not `status ?? 0`: an interactive run whose tmux server died mid-
|
|
1293
1295
|
* work landed on exactly those unknown branches and returned 0, so `agents run`
|
|
1294
1296
|
* printed a failure banner while handing its caller a success code. The same
|
|
1295
|
-
* "1 if unknown" rule already governs the `--
|
|
1297
|
+
* "1 if unknown" rule already governs the `--device` follow path
|
|
1296
1298
|
* (`docs/specifications.md` §Agent execution, exit-code table).
|
|
1297
1299
|
*
|
|
1298
1300
|
* @param pane What `paneExitStatus` read back for the agent pane.
|
|
@@ -1327,12 +1329,13 @@ export function isPaneKnownAliveFromQueryResult(code, stdout) {
|
|
|
1327
1329
|
* focus` re-attach a live session without forking it. Pure so the gate is unit-
|
|
1328
1330
|
* tested independently of the (side-effecting) spawn.
|
|
1329
1331
|
*
|
|
1330
|
-
* All
|
|
1332
|
+
* All seven guards must pass:
|
|
1331
1333
|
* - interactive — a headless `-p` run has no TTY to attach; keep bare spawn.
|
|
1332
1334
|
* - not Windows — no tmux path on win32.
|
|
1333
1335
|
* - not already in tmux — nesting tmux-in-tmux is pointless and confusing.
|
|
1334
1336
|
* - not --raw — explicit opt-out.
|
|
1335
1337
|
* - not AGENTS_NO_TMUX=1 — env opt-out (CI, scripts, the shim passthrough path).
|
|
1338
|
+
* - tmux.enabled — this device's durable opt-out, for a box whose tmux is broken.
|
|
1336
1339
|
* - tmux installed — otherwise there is nothing to wrap with.
|
|
1337
1340
|
*/
|
|
1338
1341
|
export function shouldWrapInTmux(ctx) {
|
|
@@ -1346,6 +1349,8 @@ export function shouldWrapInTmux(ctx) {
|
|
|
1346
1349
|
return false;
|
|
1347
1350
|
if (ctx.noTmuxEnv)
|
|
1348
1351
|
return false;
|
|
1352
|
+
if (!ctx.configEnabled)
|
|
1353
|
+
return false;
|
|
1349
1354
|
if (!ctx.tmuxAvailable)
|
|
1350
1355
|
return false;
|
|
1351
1356
|
return true;
|
|
@@ -1459,7 +1464,7 @@ async function runInTmux(options, executable, args) {
|
|
|
1459
1464
|
const idSeed = (options.sessionId ?? randomUUID()).slice(0, 8);
|
|
1460
1465
|
const name = slugifyName(`ag-${options.agent}-${idSeed}`);
|
|
1461
1466
|
const RED = '\x1b[31m', GRAY = '\x1b[90m', OFF = '\x1b[0m';
|
|
1462
|
-
const NO_TMUX_TIP = `${GRAY} Tip: re-run with --no-tmux to launch the agent directly and see its full output.${OFF}\n\n`;
|
|
1467
|
+
const NO_TMUX_TIP = `${GRAY} Tip: re-run with --no-tmux to launch the agent directly and see its full output.\n If tmux is broken on this machine, turn the wrap off for good: agents config set devices.${machineId()}.tmux off${OFF}\n\n`;
|
|
1463
1468
|
// Recap a dead pane's tail into THIS shell's stderr. The pane-died hook
|
|
1464
1469
|
// detaches the client the instant the agent exits, so a fast failure (a
|
|
1465
1470
|
// gutted install that dies with ENOENT, a bad flag, a crash on startup) would
|
|
@@ -1530,7 +1535,7 @@ async function runInTmux(options, executable, args) {
|
|
|
1530
1535
|
// agent finished or was killed. MUST NOT be reported as success: a caller
|
|
1531
1536
|
// scripting `agents run` would count a run killed mid-work as a clean
|
|
1532
1537
|
// finish. Tear down so no orphan session is left, say so, and exit non-zero
|
|
1533
|
-
// — the same "1 if unknown" rule the `--
|
|
1538
|
+
// — the same "1 if unknown" rule the `--device` follow path already uses.
|
|
1534
1539
|
await killSession(name, socket).catch(() => { });
|
|
1535
1540
|
// One computation feeds both the banner and the return value — printing a
|
|
1536
1541
|
// code the caller does not receive is the same defect in miniature.
|
|
@@ -1658,7 +1663,7 @@ async function runInTmux(options, executable, args) {
|
|
|
1658
1663
|
return resolveAfterAttach(pane);
|
|
1659
1664
|
}
|
|
1660
1665
|
/**
|
|
1661
|
-
* Print the run's resolved session id as a one-line stdout sentinel so a `--
|
|
1666
|
+
* Print the run's resolved session id as a one-line stdout sentinel so a `--device`
|
|
1662
1667
|
* launcher can relate the remote-created session back to itself (see the
|
|
1663
1668
|
* `emitSessionId` option and hosts/session-marker.ts).
|
|
1664
1669
|
*
|
|
@@ -1731,7 +1736,7 @@ async function spawnAgent(options) {
|
|
|
1731
1736
|
// That id is the join key that reconciles this launch's pid-registry entry
|
|
1732
1737
|
// with the hook's authoritative session id even when the hook runs under a
|
|
1733
1738
|
// different pid (tmux pane leaf / cmd.exe wrapper) — see pid-registry.ts and
|
|
1734
|
-
// session/hook-sessions.ts. ADOPT a launch id a `--
|
|
1739
|
+
// session/hook-sessions.ts. ADOPT a launch id a `--device` launcher already
|
|
1735
1740
|
// forwarded (via `--env AGENT_LAUNCH_ID=…`) so ONE correlation key spans the
|
|
1736
1741
|
// SSH hop and the launcher can resolve this run's real session id for every
|
|
1737
1742
|
// agent, not just Claude (RUSH-2034); mint a fresh one for every local run.
|
|
@@ -1766,6 +1771,7 @@ async function spawnAgent(options) {
|
|
|
1766
1771
|
inTmux: !!process.env.TMUX,
|
|
1767
1772
|
raw: options.raw === true,
|
|
1768
1773
|
noTmuxEnv: process.env.AGENTS_NO_TMUX === '1',
|
|
1774
|
+
configEnabled: isTmuxEnabled(),
|
|
1769
1775
|
tmuxAvailable: isTmuxInstalled(),
|
|
1770
1776
|
})) {
|
|
1771
1777
|
timer.mark('startup');
|
|
@@ -1913,7 +1919,7 @@ async function spawnAgent(options) {
|
|
|
1913
1919
|
// Budget kill resolves with a DISTINCT non-zero exit so CI/headless and
|
|
1914
1920
|
// teams/cloud can tell a budget termination apart from a normal failure.
|
|
1915
1921
|
const exitCode = budgetKilled ? BUDGET_KILL_EXIT_CODE : (code ?? 0);
|
|
1916
|
-
// Relate the session id back to a `--
|
|
1922
|
+
// Relate the session id back to a `--device` launcher (see the emitSessionId
|
|
1917
1923
|
// doc). Claude's id is the one we forced; every other agent coined its own,
|
|
1918
1924
|
// which the SessionStart hook recorded under this run's launchId — resolve
|
|
1919
1925
|
// and print it as a one-line sentinel that rides the followed log home.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ActiveSession } from '../session/active.js';
|
|
2
|
-
import { serializeActiveSessionsForJson } from '
|
|
2
|
+
import { serializeActiveSessionsForJson } from '../session/active.js';
|
|
3
3
|
import { readAuthHealthCache, type AuthVerdict } from '../auth-health.js';
|
|
4
4
|
import { readStatsCache } from '../devices/stats-cache.js';
|
|
5
5
|
export declare const FACTORY_PROJECTS: readonly [{
|
|
@@ -17,7 +17,7 @@ import { execFile as execFileCallback } from 'child_process';
|
|
|
17
17
|
import { promisify } from 'util';
|
|
18
18
|
import * as yaml from 'yaml';
|
|
19
19
|
import { getActiveSessions } from '../session/active.js';
|
|
20
|
-
import { serializeActiveSessionsForJson } from '
|
|
20
|
+
import { serializeActiveSessionsForJson } from '../session/active.js';
|
|
21
21
|
import { readAuthHealthCache } from '../auth-health.js';
|
|
22
22
|
import { readStatsCache } from '../devices/stats-cache.js';
|
|
23
23
|
const execFile = promisify(execFileCallback);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActorKind } from '
|
|
1
|
+
import type { ActorKind } from '../actor.js';
|
|
2
2
|
import type { EventRecord } from './events.js';
|
|
3
3
|
/** Recognizable milestone events, ordered first in any activity lane. */
|
|
4
4
|
export type MilestoneEvent = 'plan.created' | 'pr.opened' | 'pr.merged' | 'worktree.created' | 'worktree.removed' | 'commit.created' | 'pushed' | 'subagent.spawned' | 'artifact.created' | 'task.completed' | 'checklist.created'
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
import * as fs from 'fs';
|
|
21
21
|
import * as path from 'path';
|
|
22
22
|
import * as yaml from 'yaml';
|
|
23
|
-
import { stringifyDoc } from '
|
|
23
|
+
import { stringifyDoc } from '../yaml-io.js';
|
|
24
24
|
import chalk from 'chalk';
|
|
25
|
-
import { relTime, truncate } from '
|
|
26
|
-
import { getActivityDir, getUserAgentsDir } from '
|
|
27
|
-
import { normalizeHost } from '
|
|
28
|
-
import { projectKeyFromCwd } from '
|
|
29
|
-
import { stampProvenance } from '
|
|
30
|
-
import { pythonToolRegistryLiteral, pythonValueFlagsLiteral, } from '
|
|
25
|
+
import { relTime, truncate } from '../format.js';
|
|
26
|
+
import { getActivityDir, getUserAgentsDir } from '../state.js';
|
|
27
|
+
import { normalizeHost } from '../machine-id.js';
|
|
28
|
+
import { projectKeyFromCwd } from '../project-key.js';
|
|
29
|
+
import { stampProvenance } from '../event-provenance.js';
|
|
30
|
+
import { pythonToolRegistryLiteral, pythonValueFlagsLiteral, } from '../session/bash-command.js';
|
|
31
31
|
/** The set of milestone events, for tier classification and ordering. */
|
|
32
32
|
export const MILESTONE_EVENTS = [
|
|
33
33
|
'plan.created',
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* - Permissions: logs dir is 0700, files are 0600 (owner-only)
|
|
12
12
|
* - Performance tracking: withTiming() wrapper for any async function
|
|
13
13
|
*/
|
|
14
|
-
import type { ActorKind } from '
|
|
14
|
+
import type { ActorKind } from '../actor.js';
|
|
15
15
|
export type EventLevel = 'audit' | 'warn' | 'info' | 'debug';
|
|
16
|
-
export type EventType = 'agent.run.start' | 'agent.run.end' | 'agent.spawn.start' | 'agent.spawn.end' | 'run.dispatched' | 'daemon.start' | 'daemon.stop' | 'daemon.error' | 'daemon.info' | 'routine.start' | 'routine.end' | 'watchdog.action' | 'version.install' | 'version.switch' | 'version.remove' | 'skill.install' | 'skill.remove' | 'browser.launch' | 'browser.close' | 'browser.navigate' | 'browser.screenshot' | 'computer.action' | 'secrets.get' | 'secrets.unlocked' | 'secrets.create' | 'secrets.import' | 'secrets.export' | 'secrets.view' | 'secrets.lease-denied' | 'secrets.lease-expire' | 'secrets.set' | 'secrets.delete' | 'secrets.rename' | 'cloud.dispatch' | 'cloud.complete' | 'cloud.cancel' | 'cloud.message' | 'teams.create' | 'teams.add' | 'teams.start' | 'teams.complete' | 'teams.disband' | 'hook.fire' | 'hook.complete' | 'hook.error' | 'mcp.add' | 'mcp.remove' | 'mcp.register' | 'resource.sync' | 'rotation.resolved' | 'command.start' | 'command.end' | 'perf.timing' | 'session.start' | 'session.end' | 'webhook.received' | 'webhook.authorized' | 'webhook.rejected' | 'webhook.matched' | 'webhook.fired' | 'webhook.handler.start' | 'webhook.handler.end' | 'plan.created' | 'pr.opened' | 'pr.merged' | 'worktree.created' | 'worktree.removed' | 'commit.created' | 'pushed' | 'subagent.spawned' | 'artifact.created' | 'task.completed' | 'checklist.created' | 'status.posted' | 'file.edited' | 'factory.command' | 'factory.action' | 'factory.uri' | 'factory.launch' | 'friction' | 'error' | 'warn' | 'info' | 'debug';
|
|
16
|
+
export type EventType = 'agent.run.start' | 'agent.run.end' | 'agent.spawn.start' | 'agent.spawn.end' | 'run.dispatched' | 'daemon.start' | 'daemon.stop' | 'daemon.error' | 'daemon.info' | 'routine.start' | 'routine.end' | 'watchdog.action' | 'version.install' | 'version.switch' | 'version.remove' | 'skill.install' | 'skill.remove' | 'browser.launch' | 'browser.close' | 'browser.navigate' | 'browser.screenshot' | 'computer.action' | 'secrets.get' | 'secrets.unlocked' | 'secrets.create' | 'secrets.import' | 'secrets.export' | 'secrets.view' | 'secrets.lease-denied' | 'secrets.lease-expire' | 'secrets.set' | 'secrets.delete' | 'secrets.rename' | 'cloud.dispatch' | 'cloud.complete' | 'cloud.cancel' | 'cloud.message' | 'teams.create' | 'teams.add' | 'teams.start' | 'teams.complete' | 'teams.disband' | 'hook.fire' | 'hook.complete' | 'hook.error' | 'mcp.add' | 'mcp.remove' | 'mcp.register' | 'resource.sync' | 'rotation.resolved' | 'command.start' | 'command.end' | 'perf.timing' | 'session.start' | 'session.end' | 'webhook.received' | 'webhook.authorized' | 'webhook.rejected' | 'webhook.matched' | 'webhook.fired' | 'webhook.failed' | 'webhook.handler.start' | 'webhook.handler.end' | 'plan.created' | 'pr.opened' | 'pr.merged' | 'worktree.created' | 'worktree.removed' | 'commit.created' | 'pushed' | 'subagent.spawned' | 'artifact.created' | 'task.completed' | 'checklist.created' | 'status.posted' | 'file.edited' | 'factory.command' | 'factory.action' | 'factory.uri' | 'factory.launch' | 'friction' | 'error' | 'warn' | 'info' | 'debug';
|
|
17
17
|
/** Every known event kind. Derived from {@link EVENT_TYPE_TABLE}, never hand-listed. */
|
|
18
18
|
export declare const EVENT_TYPES: readonly EventType[];
|
|
19
19
|
/** Runtime guard for an event kind arriving from outside this process. */
|
|
@@ -16,14 +16,14 @@ import * as path from 'path';
|
|
|
16
16
|
import * as os from 'os';
|
|
17
17
|
import { createHash } from 'node:crypto';
|
|
18
18
|
import { gzipSync, gunzipSync } from 'node:zlib';
|
|
19
|
-
import { ensureLockTarget, withFileLock } from '
|
|
20
|
-
import { getUserAgentsDir } from '
|
|
21
|
-
import { stampProvenance, resetEventProvenanceForTest } from '
|
|
19
|
+
import { ensureLockTarget, withFileLock } from '../fs-atomic.js';
|
|
20
|
+
import { getUserAgentsDir } from '../state.js';
|
|
21
|
+
import { stampProvenance, resetEventProvenanceForTest } from '../event-provenance.js';
|
|
22
22
|
/** Lazy perf warehouse write — avoids a hard cycle at module load. */
|
|
23
23
|
function recordPerfTiming(payload) {
|
|
24
24
|
try {
|
|
25
25
|
// Dynamic import keeps events.ts free of a load-time dependency on perf/db.
|
|
26
|
-
void import('
|
|
26
|
+
void import('../perf/spool.js').then(({ recordSample }) => {
|
|
27
27
|
recordSample({
|
|
28
28
|
kind: 'perf.timing',
|
|
29
29
|
label: payload.label,
|
|
@@ -128,7 +128,7 @@ const EVENT_TYPE_TABLE = {
|
|
|
128
128
|
'perf.timing': true,
|
|
129
129
|
'session.start': true, 'session.end': true,
|
|
130
130
|
'webhook.received': true, 'webhook.authorized': true, 'webhook.rejected': true, 'webhook.matched': true,
|
|
131
|
-
'webhook.fired': true, 'webhook.handler.start': true, 'webhook.handler.end': true,
|
|
131
|
+
'webhook.fired': true, 'webhook.failed': true, 'webhook.handler.start': true, 'webhook.handler.end': true,
|
|
132
132
|
'plan.created': true, 'pr.opened': true, 'pr.merged': true, 'worktree.created': true,
|
|
133
133
|
'worktree.removed': true, 'commit.created': true, 'pushed': true, 'subagent.spawned': true,
|
|
134
134
|
'artifact.created': true, 'task.completed': true, 'checklist.created': true, 'status.posted': true,
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
import * as fs from 'fs';
|
|
25
25
|
import * as path from 'path';
|
|
26
26
|
import * as yaml from 'yaml';
|
|
27
|
-
import { stringifyDoc } from '
|
|
28
|
-
import { getFeedDir, getUserAgentsDir } from '
|
|
29
|
-
import { isAdmin, isHighConsequenceAllowed, isKnownOperator } from '
|
|
30
|
-
import { projectKeyFromCwd } from '
|
|
27
|
+
import { stringifyDoc } from '../yaml-io.js';
|
|
28
|
+
import { getFeedDir, getUserAgentsDir } from '../state.js';
|
|
29
|
+
import { isAdmin, isHighConsequenceAllowed, isKnownOperator } from '../operator.js';
|
|
30
|
+
import { projectKeyFromCwd } from '../project-key.js';
|
|
31
31
|
/**
|
|
32
32
|
* Stable block id for a session. One block per session -- a new question
|
|
33
33
|
* replaces the previous one (the agent can only ask one question at a time).
|
package/dist/lib/feed-policy.js
CHANGED
|
@@ -16,7 +16,7 @@ import * as fs from 'fs';
|
|
|
16
16
|
import * as path from 'path';
|
|
17
17
|
import * as yaml from 'yaml';
|
|
18
18
|
import { getUserAgentsDir } from './state.js';
|
|
19
|
-
import { recordAnswer, recordDefaulted, recordMessageReceipt, recordParked, } from './feed.js';
|
|
19
|
+
import { recordAnswer, recordDefaulted, recordMessageReceipt, recordParked, } from './feed/feed.js';
|
|
20
20
|
import { enqueue, mailboxDir } from './mailbox.js';
|
|
21
21
|
const POLICY_FILE = 'feed-policy.yaml';
|
|
22
22
|
const COST_RANK = { low: 0, medium: 1, high: 2 };
|
package/dist/lib/feed-post.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ActivityEvent, type Attachment } from './activity.js';
|
|
1
|
+
import { type ActivityEvent, type Attachment } from './feed/activity.js';
|
|
2
2
|
import { type PidSessionEntry } from './session/pid-registry.js';
|
|
3
3
|
/** Soft cap so a runaway agent can't flood the activity lane with essays. */
|
|
4
4
|
export declare const STATUS_POST_MAX_CHARS = 500;
|
package/dist/lib/feed-post.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import * as fs from 'fs';
|
|
17
17
|
import * as path from 'path';
|
|
18
18
|
import { spawnSync } from 'child_process';
|
|
19
|
-
import { appendActivityEvent, readRecentActivity, } from './activity.js';
|
|
19
|
+
import { appendActivityEvent, readRecentActivity, } from './feed/activity.js';
|
|
20
20
|
import { resolveProjectNameForCwd, listProjectDefs } from './projects.js';
|
|
21
21
|
import { getHistoryDir } from './state.js';
|
|
22
22
|
import { machineId } from './machine-id.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OpenBlock, FeedAskStats } from './feed.js';
|
|
1
|
+
import type { OpenBlock, FeedAskStats } from './feed/feed.js';
|
|
2
2
|
import type { Classification } from './ask-classifier.js';
|
|
3
3
|
import type { ActiveSession } from './session/active.js';
|
|
4
4
|
import type { SessionMeta } from './session/types.js';
|
|
@@ -45,12 +45,6 @@ export interface SourceAuth {
|
|
|
45
45
|
/** The captured file payloads, keyed by agent. */
|
|
46
46
|
filesByAgent: Map<string, AuthFilePayload[]>;
|
|
47
47
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Can we propagate `agent`'s login to a target on `targetPlatform`? False when
|
|
50
|
-
* the agent has no portable file, the source can't provide it (bound / not
|
|
51
|
-
* signed in), or the target consumes credentials from its own keychain.
|
|
52
|
-
*/
|
|
53
|
-
export declare function canPushLogin(agent: string, targetPlatform: string | undefined, src: SourceAuth): boolean;
|
|
54
48
|
export interface DiffContext {
|
|
55
49
|
/** agents-cli version the source is on — the fleet target version. */
|
|
56
50
|
targetCliVersion: string;
|
package/dist/lib/fleet/apply.js
CHANGED
|
@@ -13,7 +13,7 @@ import { deviceIdentityArgs, sshTargetFor } from '../devices/connect.js';
|
|
|
13
13
|
import { readyProbe, bootstrapAgentsCli } from '../hosts/ready.js';
|
|
14
14
|
import { buildRemoteAgentsInvocation } from '../hosts/remote-cmd.js';
|
|
15
15
|
import { sshExec } from '../ssh-exec.js';
|
|
16
|
-
import {
|
|
16
|
+
import { hasPortableAuthFiles } from './auth-sync.js';
|
|
17
17
|
/** Strip a version suffix from an agent spec: `claude@latest` -> `claude`. */
|
|
18
18
|
export function agentIdOf(spec) {
|
|
19
19
|
return spec.split('@')[0].trim();
|
|
@@ -88,20 +88,6 @@ export function parseInstalledVersions(stdout) {
|
|
|
88
88
|
return undefined;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Can we propagate `agent`'s login to a target on `targetPlatform`? False when
|
|
93
|
-
* the agent has no portable file, the source can't provide it (bound / not
|
|
94
|
-
* signed in), or the target consumes credentials from its own keychain.
|
|
95
|
-
*/
|
|
96
|
-
export function canPushLogin(agent, targetPlatform, src) {
|
|
97
|
-
if (!isPropagatableAgent(agent))
|
|
98
|
-
return false;
|
|
99
|
-
if (src.bound.has(agent))
|
|
100
|
-
return false;
|
|
101
|
-
if (targetPlatform === 'macos' && KEYCHAIN_BOUND_ON_MAC.has(agent))
|
|
102
|
-
return false;
|
|
103
|
-
return src.available.has(agent);
|
|
104
|
-
}
|
|
105
91
|
/** Pure: desired vs probed -> per-device diff + flat action list. */
|
|
106
92
|
export function diffFleet(desired, probes, ctx) {
|
|
107
93
|
const devices = [];
|
|
@@ -143,28 +129,24 @@ export function diffFleet(desired, probes, ctx) {
|
|
|
143
129
|
rowActions.push({ device: d.device, kind: 'sync-config', detail: `sync config (${d.sync.join(', ')})` });
|
|
144
130
|
}
|
|
145
131
|
// login — per agent id, not per spec: `claude@all` names one id many times,
|
|
146
|
-
// but login
|
|
132
|
+
// but a login is established once per agent (its credential is version-shared).
|
|
147
133
|
if (d.login === 'sync') {
|
|
148
134
|
for (const id of [...new Set(d.agents.map(agentIdOf))]) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
rowActions.push({ device: d.device, kind: 'needs-login', agent: id, detail: `${id} login uses a single-use rotating refresh token — log in on ${d.device} itself` });
|
|
158
|
-
}
|
|
159
|
-
else if (isPropagatableAgent(id) &&
|
|
160
|
-
(ctx.sourceAuth.bound.has(id) || (probe.platform === 'macos' && KEYCHAIN_BOUND_ON_MAC.has(id)))) {
|
|
161
|
-
// A login-propagation candidate we still can't push: the source token
|
|
162
|
-
// is keychain-bound (unextractable), or the macOS target consumes its
|
|
163
|
-
// own keychain. Surface those as manual — don't fake. Agents that were
|
|
164
|
-
// never propagation candidates (no portable file), or a source that
|
|
165
|
-
// simply isn't signed in, are silently skipped the same on every OS.
|
|
135
|
+
// SING-1b: a native OAuth / session login MUST NOT be copied between
|
|
136
|
+
// devices — a rotating token invalidates the fleet on its next refresh
|
|
137
|
+
// (droid/WorkOS collapsed 10 boxes to 1 overnight). `apply` therefore no
|
|
138
|
+
// longer propagates any login; it surfaces per-box login / portable
|
|
139
|
+
// provider-account guidance for every agent that has a login to
|
|
140
|
+
// establish. An agent with no portable login file, or a source that
|
|
141
|
+
// isn't signed in, is silently skipped the same on every OS.
|
|
142
|
+
if (hasPortableAuthFiles(id)) {
|
|
166
143
|
loginBlocked.push(id);
|
|
167
|
-
rowActions.push({
|
|
144
|
+
rowActions.push({
|
|
145
|
+
device: d.device,
|
|
146
|
+
kind: 'needs-login',
|
|
147
|
+
agent: id,
|
|
148
|
+
detail: `${id}: a native OAuth login can't be copied between devices (SING-1b) — log in on ${d.device} itself, or sync a portable provider account (agents accounts sync)`,
|
|
149
|
+
});
|
|
168
150
|
}
|
|
169
151
|
}
|
|
170
152
|
}
|
|
@@ -414,17 +396,8 @@ export function reconcileDevice(row, device, ctx) {
|
|
|
414
396
|
steps.push({ kind: 'sync-config', ok: syncOk, detail: `sync config (${row.desired.sync.join(', ') || 'default'})` });
|
|
415
397
|
ok = ok && syncOk;
|
|
416
398
|
}
|
|
417
|
-
// 4. login
|
|
418
|
-
|
|
419
|
-
if (pushAgents.length > 0) {
|
|
420
|
-
const files = [];
|
|
421
|
-
for (const agent of pushAgents)
|
|
422
|
-
files.push(...(ctx.sourceAuth.filesByAgent.get(agent) ?? []));
|
|
423
|
-
const bundle = buildAuthBundle(ctx.source, files);
|
|
424
|
-
const r = sshAgents(['apply', '--recv-auth'], JSON.stringify(bundle));
|
|
425
|
-
steps.push({ kind: 'push-login', ok: r.code === 0, detail: `propagate login: ${pushAgents.join(', ')}` });
|
|
426
|
-
ok = ok && r.code === 0;
|
|
427
|
-
}
|
|
399
|
+
// 4. Native login materialization does not exist. Every agent that needs a login is surfaced as
|
|
400
|
+
// `needs-login` (per-box login / portable-account guidance) in the diff above.
|
|
428
401
|
// 5. secrets provisioning — LAST, and deliberately so. It is the most
|
|
429
402
|
// sensitive mutation apply performs (credential VALUES crossing to another
|
|
430
403
|
// machine), so every lower-risk step above is already recorded before we
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* A source machine that is already signed in to a set of harnesses has portable
|
|
6
|
-
* credential files on disk (verified per-agent locations below). `snapshotAuth`
|
|
7
|
-
* captures those; `materializeAuth` writes them into the corresponding paths on
|
|
8
|
-
* a target device. Transport is the caller's job — `apply` streams the bundle
|
|
9
|
-
* over the existing (encrypted, authenticated) SSH channel via `sshExec`'s
|
|
10
|
-
* stdin `input`, so no app-layer crypto is layered on top of SSH here.
|
|
2
|
+
* Native-login inventory for `agents apply` and `agents fleet login`.
|
|
3
|
+
* Native OAuth/session files are identified only to report device readiness;
|
|
4
|
+
* agents-cli never serializes or materializes them on another device.
|
|
11
5
|
*
|
|
12
6
|
* Honest boundary: on macOS, claude and antigravity keep their tokens in the
|
|
13
7
|
* login keychain, ACL-bound to the harness process — unreadable by us. Those are
|
|
14
8
|
* classified `bound` and surfaced for a one-time manual login, never faked.
|
|
15
9
|
*/
|
|
16
|
-
import type {
|
|
10
|
+
import type { AuthSnapshotResult } from './types.js';
|
|
17
11
|
/** A portable credential file location, relative to $HOME. */
|
|
18
12
|
interface AuthFileSpec {
|
|
19
13
|
rel: string;
|
|
@@ -37,10 +31,18 @@ export declare const KEYCHAIN_BOUND_ON_MAC: ReadonlySet<string>;
|
|
|
37
31
|
* made. See also `remote-login.ts` and `usage.ts` for the per-machine-login policy.
|
|
38
32
|
*/
|
|
39
33
|
export declare const SINGLE_USE_ROTATING_REFRESH_AGENTS: ReadonlySet<string>;
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Whether `agent`'s login may be copied between machines by `apply`. Always
|
|
36
|
+
* **false** now (RUSH-2527): every `FLEET_AUTH_FILES` entry is a native,
|
|
37
|
+
* rotating OAuth / session login, and the fleet-auth contract forbids copying any
|
|
38
|
+
* of them between devices (`docs/specifications.md` SING-1b) — not just the
|
|
39
|
+
* single-use-rotating subset (`SINGLE_USE_ROTATING_REFRESH_AGENTS`) that first
|
|
40
|
+
* motivated this gate. `apply` therefore never propagates a login; it surfaces
|
|
41
|
+
* per-box login / portable-account guidance instead. `snapshotAuth` reads no
|
|
42
|
+
* credential file as a result, so a native login never leaves its origin box.
|
|
43
|
+
* The `agent` parameter is retained for the stable call signature.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isCredentialSafeToPropagate(_agent: string): boolean;
|
|
44
46
|
/** True when the agent stores credentials in portable files we can read. This
|
|
45
47
|
* does NOT mean it is safe to propagate — check {@link isCredentialSafeToPropagate}. */
|
|
46
48
|
export declare function hasPortableAuthFiles(agent: string): boolean;
|
|
@@ -113,25 +115,4 @@ export interface SnapshotOptions {
|
|
|
113
115
|
* propagate, not an error.
|
|
114
116
|
*/
|
|
115
117
|
export declare function snapshotAuth(agents: string[], opts: SnapshotOptions): AuthSnapshotResult;
|
|
116
|
-
/** Assemble the plaintext bundle shipped to a target. */
|
|
117
|
-
export declare function buildAuthBundle(source: string, files: AuthFilePayload[]): AuthBundle;
|
|
118
|
-
export interface MaterializeOptions {
|
|
119
|
-
/** Home directory to write credential files into. */
|
|
120
|
-
home: string;
|
|
121
|
-
}
|
|
122
|
-
export interface MaterializeResult {
|
|
123
|
-
/** Agent ids that received at least one file. */
|
|
124
|
-
written: string[];
|
|
125
|
-
/** `rel: reason` for any file that failed. */
|
|
126
|
-
errors: string[];
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Write a captured auth bundle into a target home. Parent dirs are created; the
|
|
130
|
-
* captured POSIX mode is restored (0600 for credentials). Writing through an
|
|
131
|
-
* existing symlink lands in the agent's active version home, which is exactly
|
|
132
|
-
* what per-version credential carry-forward expects.
|
|
133
|
-
*/
|
|
134
|
-
export declare function materializeAuth(bundle: AuthBundle, opts: MaterializeOptions): MaterializeResult;
|
|
135
|
-
/** Parse + validate a bundle received on stdin (the remote `--_recv-auth` path). */
|
|
136
|
-
export declare function parseAuthBundle(raw: string): AuthBundle;
|
|
137
118
|
export {};
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* A source machine that is already signed in to a set of harnesses has portable
|
|
6
|
-
* credential files on disk (verified per-agent locations below). `snapshotAuth`
|
|
7
|
-
* captures those; `materializeAuth` writes them into the corresponding paths on
|
|
8
|
-
* a target device. Transport is the caller's job — `apply` streams the bundle
|
|
9
|
-
* over the existing (encrypted, authenticated) SSH channel via `sshExec`'s
|
|
10
|
-
* stdin `input`, so no app-layer crypto is layered on top of SSH here.
|
|
2
|
+
* Native-login inventory for `agents apply` and `agents fleet login`.
|
|
3
|
+
* Native OAuth/session files are identified only to report device readiness;
|
|
4
|
+
* agents-cli never serializes or materializes them on another device.
|
|
11
5
|
*
|
|
12
6
|
* Honest boundary: on macOS, claude and antigravity keep their tokens in the
|
|
13
7
|
* login keychain, ACL-bound to the harness process — unreadable by us. Those are
|
|
@@ -44,11 +38,19 @@ export const KEYCHAIN_BOUND_ON_MAC = new Set(['claude', 'antigravity']);
|
|
|
44
38
|
* made. See also `remote-login.ts` and `usage.ts` for the per-machine-login policy.
|
|
45
39
|
*/
|
|
46
40
|
export const SINGLE_USE_ROTATING_REFRESH_AGENTS = new Set(['droid']);
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Whether `agent`'s login may be copied between machines by `apply`. Always
|
|
43
|
+
* **false** now (RUSH-2527): every `FLEET_AUTH_FILES` entry is a native,
|
|
44
|
+
* rotating OAuth / session login, and the fleet-auth contract forbids copying any
|
|
45
|
+
* of them between devices (`docs/specifications.md` SING-1b) — not just the
|
|
46
|
+
* single-use-rotating subset (`SINGLE_USE_ROTATING_REFRESH_AGENTS`) that first
|
|
47
|
+
* motivated this gate. `apply` therefore never propagates a login; it surfaces
|
|
48
|
+
* per-box login / portable-account guidance instead. `snapshotAuth` reads no
|
|
49
|
+
* credential file as a result, so a native login never leaves its origin box.
|
|
50
|
+
* The `agent` parameter is retained for the stable call signature.
|
|
51
|
+
*/
|
|
52
|
+
export function isCredentialSafeToPropagate(_agent) {
|
|
53
|
+
return false;
|
|
52
54
|
}
|
|
53
55
|
/** True when the agent stores credentials in portable files we can read. This
|
|
54
56
|
* does NOT mean it is safe to propagate — check {@link isCredentialSafeToPropagate}. */
|
|
@@ -185,64 +187,3 @@ export function snapshotAuth(agents, opts) {
|
|
|
185
187
|
}
|
|
186
188
|
return { files, bound };
|
|
187
189
|
}
|
|
188
|
-
/** Assemble the plaintext bundle shipped to a target. */
|
|
189
|
-
export function buildAuthBundle(source, files) {
|
|
190
|
-
return { v: 1, source, files };
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Write a captured auth bundle into a target home. Parent dirs are created; the
|
|
194
|
-
* captured POSIX mode is restored (0600 for credentials). Writing through an
|
|
195
|
-
* existing symlink lands in the agent's active version home, which is exactly
|
|
196
|
-
* what per-version credential carry-forward expects.
|
|
197
|
-
*/
|
|
198
|
-
export function materializeAuth(bundle, opts) {
|
|
199
|
-
const written = new Set();
|
|
200
|
-
const errors = [];
|
|
201
|
-
for (const f of bundle.files) {
|
|
202
|
-
const abs = path.join(opts.home, f.rel);
|
|
203
|
-
try {
|
|
204
|
-
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
205
|
-
fs.writeFileSync(abs, Buffer.from(f.contentB64, 'base64'));
|
|
206
|
-
fs.chmodSync(abs, f.mode || 0o600);
|
|
207
|
-
written.add(f.agent);
|
|
208
|
-
}
|
|
209
|
-
catch (e) {
|
|
210
|
-
errors.push(`${f.rel}: ${e.message}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return { written: [...written], errors };
|
|
214
|
-
}
|
|
215
|
-
/** Parse + validate a bundle received on stdin (the remote `--_recv-auth` path). */
|
|
216
|
-
export function parseAuthBundle(raw) {
|
|
217
|
-
let doc;
|
|
218
|
-
try {
|
|
219
|
-
doc = JSON.parse(raw);
|
|
220
|
-
}
|
|
221
|
-
catch (e) {
|
|
222
|
-
throw new Error(`auth bundle is not valid JSON: ${e.message}`);
|
|
223
|
-
}
|
|
224
|
-
if (typeof doc !== 'object' || doc === null)
|
|
225
|
-
throw new Error('auth bundle must be an object.');
|
|
226
|
-
const o = doc;
|
|
227
|
-
if (o.v !== 1)
|
|
228
|
-
throw new Error(`unsupported auth bundle version ${JSON.stringify(o.v)}.`);
|
|
229
|
-
if (typeof o.source !== 'string')
|
|
230
|
-
throw new Error('auth bundle missing source.');
|
|
231
|
-
if (!Array.isArray(o.files))
|
|
232
|
-
throw new Error('auth bundle missing files[].');
|
|
233
|
-
for (const f of o.files) {
|
|
234
|
-
if (typeof f !== 'object' || f === null ||
|
|
235
|
-
typeof f.agent !== 'string' ||
|
|
236
|
-
typeof f.rel !== 'string' ||
|
|
237
|
-
typeof f.contentB64 !== 'string' ||
|
|
238
|
-
typeof f.mode !== 'number') {
|
|
239
|
-
throw new Error('auth bundle has a malformed file entry.');
|
|
240
|
-
}
|
|
241
|
-
// Reject path traversal — rel must stay under $HOME.
|
|
242
|
-
const rel = f.rel;
|
|
243
|
-
if (rel.startsWith('/') || rel.split('/').includes('..')) {
|
|
244
|
-
throw new Error(`auth bundle rejected unsafe path: ${rel}`);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return doc;
|
|
248
|
-
}
|
|
@@ -28,12 +28,11 @@ export function captureFleet(prev, inputs) {
|
|
|
28
28
|
// when the manifest didn't already pin one for that device.
|
|
29
29
|
//
|
|
30
30
|
// A device absent from `inputs.devices` drops OUT of the roster — that is the
|
|
31
|
-
// intended "live state is the source of truth for WHICH devices exist".
|
|
32
|
-
// `
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
// dropped device's `config:` forward — config only, never its roster fields.
|
|
31
|
+
// intended "live state is the source of truth for WHICH devices exist". A
|
|
32
|
+
// leftover `config:` on an override is the LEGACY #2458 store (folded into
|
|
33
|
+
// per-device docs by migrateDeviceConfigStores). Carry it forward so a
|
|
34
|
+
// capture from a box that has not seen a peer cannot re-strip a not-yet-
|
|
35
|
+
// migrated peer's settings. Config only, never its roster fields.
|
|
37
36
|
const devices = {};
|
|
38
37
|
for (const [name, prevOverride] of Object.entries(prevDevices)) {
|
|
39
38
|
if (inputs.devices.includes(name))
|
|
@@ -56,6 +55,9 @@ export function captureFleet(prev, inputs) {
|
|
|
56
55
|
defaults: prev?.defaults ?? inputs.defaults ?? {},
|
|
57
56
|
devices,
|
|
58
57
|
};
|
|
58
|
+
if (prev?.discovery && Object.keys(prev.discovery).length > 0) {
|
|
59
|
+
manifest.discovery = { ...prev.discovery };
|
|
60
|
+
}
|
|
59
61
|
const bundles = inputs.secretsBundles ?? prev?.secrets?.bundles;
|
|
60
62
|
if (bundles && bundles.length > 0)
|
|
61
63
|
manifest.secrets = { bundles: [...bundles].sort() };
|