@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
|
@@ -34,10 +34,16 @@ function validateDefaults(v, where) {
|
|
|
34
34
|
if (o.sync !== undefined && !isStringArray(o.sync)) {
|
|
35
35
|
throw new Error(`fleet: ${where}.sync must be a list of scope names (e.g. [user]).`);
|
|
36
36
|
}
|
|
37
|
+
if (o.config !== undefined && (typeof o.config !== 'object' || o.config === null || Array.isArray(o.config))) {
|
|
38
|
+
throw new Error(`fleet: ${where}.config must be a mapping of config keys to values.`);
|
|
39
|
+
}
|
|
37
40
|
return {
|
|
38
41
|
agents: o.agents,
|
|
39
42
|
sync: o.sync,
|
|
40
43
|
login: validateLogin(o.login, where),
|
|
44
|
+
// `config:` is operator config (`agents devices config`); inert to the
|
|
45
|
+
// reconcile engine but part of the manifest shape.
|
|
46
|
+
config: o.config,
|
|
41
47
|
};
|
|
42
48
|
}
|
|
43
49
|
/** Validate a raw `fleet:` object (already YAML-parsed) into a typed manifest. */
|
|
@@ -58,17 +64,10 @@ export function parseFleetManifest(raw) {
|
|
|
58
64
|
const map = {};
|
|
59
65
|
for (const [name, ov] of Object.entries(o.devices)) {
|
|
60
66
|
// An empty entry (`device: {}`) inherits defaults — represent as {}.
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
if (cfg !== undefined) {
|
|
66
|
-
if (typeof cfg !== 'object' || cfg === null || Array.isArray(cfg)) {
|
|
67
|
-
throw new Error(`fleet: devices.${name}.config must be a mapping of config keys to values.`);
|
|
68
|
-
}
|
|
69
|
-
merged.config = cfg;
|
|
70
|
-
}
|
|
71
|
-
map[name] = merged;
|
|
67
|
+
// (A per-device `config:` here is the LEGACY #2458 store — parsed through
|
|
68
|
+
// so reads stay lossless, folded into the per-device doc by the config
|
|
69
|
+
// migration, never written by current code.)
|
|
70
|
+
map[name] = ov == null ? {} : validateDefaults(ov, `devices.${name}`);
|
|
72
71
|
}
|
|
73
72
|
devices = map;
|
|
74
73
|
}
|
|
@@ -76,6 +75,19 @@ export function parseFleetManifest(raw) {
|
|
|
76
75
|
throw new Error(`fleet: devices must be the string 'all' or a mapping of device -> overrides (got ${JSON.stringify(o.devices)}).`);
|
|
77
76
|
}
|
|
78
77
|
const manifest = { defaults, devices };
|
|
78
|
+
if (o.discovery !== undefined) {
|
|
79
|
+
if (typeof o.discovery !== 'object' || o.discovery === null || Array.isArray(o.discovery)) {
|
|
80
|
+
throw new Error('fleet: discovery must be a mapping of device name to approved or ignored.');
|
|
81
|
+
}
|
|
82
|
+
const discovery = {};
|
|
83
|
+
for (const [name, status] of Object.entries(o.discovery)) {
|
|
84
|
+
if (status !== 'approved' && status !== 'ignored') {
|
|
85
|
+
throw new Error(`fleet: discovery.${name} must be approved or ignored.`);
|
|
86
|
+
}
|
|
87
|
+
discovery[name] = status;
|
|
88
|
+
}
|
|
89
|
+
manifest.discovery = discovery;
|
|
90
|
+
}
|
|
79
91
|
// Additive, backward-compatible extras (captured by `agents fleet capture`).
|
|
80
92
|
if (o.secrets !== undefined) {
|
|
81
93
|
if (typeof o.secrets !== 'object' || o.secrets === null || Array.isArray(o.secrets)) {
|
|
@@ -27,6 +27,14 @@ export interface FleetDefaults {
|
|
|
27
27
|
sync?: string[];
|
|
28
28
|
/** Login propagation strategy. Default `'sync'`. */
|
|
29
29
|
login?: FleetLoginMode;
|
|
30
|
+
/**
|
|
31
|
+
* Fleet-wide config defaults (`agents devices config --fleet <key> <value>`)
|
|
32
|
+
* — the middle layer of the device-config store: built-in default <
|
|
33
|
+
* `fleet.defaults.config` < per-device `devices/<name>/agents.yaml`
|
|
34
|
+
* `config:`. Inert to the reconcile engine (apply never pushes it; it takes
|
|
35
|
+
* effect through the config read path). Names and non-secret values only.
|
|
36
|
+
*/
|
|
37
|
+
config?: Record<string, unknown>;
|
|
30
38
|
}
|
|
31
39
|
/** Per-device override; any omitted field inherits from `defaults`. */
|
|
32
40
|
export interface FleetDeviceOverride {
|
|
@@ -34,12 +42,10 @@ export interface FleetDeviceOverride {
|
|
|
34
42
|
sync?: string[];
|
|
35
43
|
login?: FleetLoginMode;
|
|
36
44
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* LEAK-FREE like the rest of the manifest — names and non-secret values only
|
|
42
|
-
* (a secrets-bundle NAME is fine; a credential value never is).
|
|
45
|
+
* LEGACY home of per-device operator config (#2458); the current store is the
|
|
46
|
+
* per-device doc `devices/<name>/agents.yaml` `config:` block. Existing
|
|
47
|
+
* values are folded into the device doc by lib/devices/config-migration.ts
|
|
48
|
+
* and stripped here — current code never writes this field.
|
|
43
49
|
*/
|
|
44
50
|
config?: Record<string, unknown>;
|
|
45
51
|
}
|
|
@@ -68,6 +74,12 @@ export interface FleetManifest {
|
|
|
68
74
|
};
|
|
69
75
|
/** Routine NAMES that should be active on the fleet (files sync via the repo). */
|
|
70
76
|
routines?: string[];
|
|
77
|
+
/**
|
|
78
|
+
* Portable user decisions for Tailscale discovery. A name maps to `approved`
|
|
79
|
+
* or `ignored`; absence means pending. Connection metadata remains in each
|
|
80
|
+
* machine's local device registry and is never committed.
|
|
81
|
+
*/
|
|
82
|
+
discovery?: Record<string, 'approved' | 'ignored'>;
|
|
71
83
|
}
|
|
72
84
|
/**
|
|
73
85
|
* A device's desired state after merging defaults with its override and
|
|
@@ -118,7 +130,7 @@ export interface DeviceProbe {
|
|
|
118
130
|
note?: string;
|
|
119
131
|
}
|
|
120
132
|
/** One planned action against a device, in a single reconcile dimension. */
|
|
121
|
-
export type FleetActionKind = 'install-cli' | 'upgrade-cli' | 'add-agent' | 'sync-config' | '
|
|
133
|
+
export type FleetActionKind = 'install-cli' | 'upgrade-cli' | 'add-agent' | 'sync-config' | 'needs-login'
|
|
122
134
|
/** Push a declared secrets bundle to the device over SSH. Opt-in only
|
|
123
135
|
* (`--provision-secrets`) and gated on a pinned host key, because this moves
|
|
124
136
|
* credential VALUES to another machine (RUSH-1968). */
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* `runFleetStatusPublish` for the fleet-status mirror); this module is the read
|
|
13
13
|
* side only.
|
|
14
14
|
*/
|
|
15
|
-
import { type UsageSnapshot } from './usage.js';
|
|
15
|
+
import { type UsageSnapshot } from './accounting/usage.js';
|
|
16
16
|
import { type FleetStatusRow } from './fleet-status.js';
|
|
17
17
|
/**
|
|
18
18
|
* The fleet-status union the daemon publishes (own row) and the fleet-status
|
package/dist/lib/fleet-cache.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* `runFleetStatusPublish` for the fleet-status mirror); this module is the read
|
|
13
13
|
* side only.
|
|
14
14
|
*/
|
|
15
|
-
import { readClaudeUsageCache } from './usage.js';
|
|
15
|
+
import { readClaudeUsageCache } from './accounting/usage.js';
|
|
16
16
|
import { readHeadroomEntry } from './usage-refresh.js';
|
|
17
17
|
import { readFleetStatus as readFleetStatusMirror } from './fleet-status.js';
|
|
18
18
|
/**
|
package/dist/lib/format.d.ts
CHANGED
|
@@ -50,6 +50,25 @@ export declare function truncate(s: string, max: number): string;
|
|
|
50
50
|
export declare function relTime(iso: string): string;
|
|
51
51
|
/** Format a millisecond duration as "45s", "3m", "2h 5m", "1d 3h". */
|
|
52
52
|
export declare function humanDuration(ms: number): string;
|
|
53
|
+
/**
|
|
54
|
+
* Human-readable byte size. Previously copy-pasted into five files
|
|
55
|
+
* (`commands/prune.ts`, `commands/share.ts`, `commands/inspect.ts`,
|
|
56
|
+
* `commands/sessions.ts`, `lib/browser/sessions-list.ts`) — this is the
|
|
57
|
+
* canonical home.
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatBytes(n: number): string;
|
|
60
|
+
/**
|
|
61
|
+
* True when an error came from the user cancelling a prompt (Ctrl+C).
|
|
62
|
+
*
|
|
63
|
+
* Lives here rather than in `commands/utils.ts` so `lib/` callers
|
|
64
|
+
* (`drift-sync.ts`, `refresh.ts`) don't have to import upward out of `lib/`
|
|
65
|
+
* into the command layer. `commands/utils.ts` re-exports it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function isPromptCancelled(err: unknown): boolean;
|
|
68
|
+
/** True when stdin/stdout are attached to a real terminal. */
|
|
69
|
+
export declare function isInteractiveTerminal(): boolean;
|
|
70
|
+
/** Parse a comma-separated CLI list, trimming whitespace and dropping empties. */
|
|
71
|
+
export declare function parseCommaSeparatedList(value: string | undefined): string[];
|
|
53
72
|
/**
|
|
54
73
|
* Visible column width of `s`, ignoring ANSI SGR color codes (e.g. chalk
|
|
55
74
|
* wrappers). Matches the full CSI sequence including the `\x1b` escape.
|
package/dist/lib/format.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { readSync } from 'node:fs';
|
|
12
|
-
import { emitFriction } from './events.js';
|
|
12
|
+
import { emitFriction } from './feed/events.js';
|
|
13
13
|
/**
|
|
14
14
|
* Render a fatal error to the right stream. Pure — no I/O, no `process.exit` — so
|
|
15
15
|
* the human-vs-agent split is unit-testable. A `--json` caller gets
|
|
@@ -97,6 +97,49 @@ export function humanDuration(ms) {
|
|
|
97
97
|
const hh = h % 24;
|
|
98
98
|
return hh ? `${d}d ${hh}h` : `${d}d`;
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Human-readable byte size. Previously copy-pasted into five files
|
|
102
|
+
* (`commands/prune.ts`, `commands/share.ts`, `commands/inspect.ts`,
|
|
103
|
+
* `commands/sessions.ts`, `lib/browser/sessions-list.ts`) — this is the
|
|
104
|
+
* canonical home.
|
|
105
|
+
*/
|
|
106
|
+
export function formatBytes(n) {
|
|
107
|
+
if (n < 1024)
|
|
108
|
+
return `${n} B`;
|
|
109
|
+
const units = ['KB', 'MB', 'GB', 'TB'];
|
|
110
|
+
let size = n / 1024;
|
|
111
|
+
let unit = 0;
|
|
112
|
+
while (size >= 1024 && unit < units.length - 1) {
|
|
113
|
+
size /= 1024;
|
|
114
|
+
unit++;
|
|
115
|
+
}
|
|
116
|
+
return `${size < 10 ? size.toFixed(1) : Math.round(size)} ${units[unit]}`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* True when an error came from the user cancelling a prompt (Ctrl+C).
|
|
120
|
+
*
|
|
121
|
+
* Lives here rather than in `commands/utils.ts` so `lib/` callers
|
|
122
|
+
* (`drift-sync.ts`, `refresh.ts`) don't have to import upward out of `lib/`
|
|
123
|
+
* into the command layer. `commands/utils.ts` re-exports it.
|
|
124
|
+
*/
|
|
125
|
+
export function isPromptCancelled(err) {
|
|
126
|
+
return err instanceof Error && (err.name === 'ExitPromptError' ||
|
|
127
|
+
err.message.includes('force closed') ||
|
|
128
|
+
err.message.includes('User force closed'));
|
|
129
|
+
}
|
|
130
|
+
/** True when stdin/stdout are attached to a real terminal. */
|
|
131
|
+
export function isInteractiveTerminal() {
|
|
132
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
133
|
+
}
|
|
134
|
+
/** Parse a comma-separated CLI list, trimming whitespace and dropping empties. */
|
|
135
|
+
export function parseCommaSeparatedList(value) {
|
|
136
|
+
if (!value)
|
|
137
|
+
return [];
|
|
138
|
+
return value
|
|
139
|
+
.split(',')
|
|
140
|
+
.map((item) => item.trim())
|
|
141
|
+
.filter(Boolean);
|
|
142
|
+
}
|
|
100
143
|
/**
|
|
101
144
|
* Visible column width of `s`, ignoring ANSI SGR color codes (e.g. chalk
|
|
102
145
|
* wrappers). Matches the full CSI sequence including the `\x1b` escape.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* yet. This is a starting point: one detector for the most actionable pattern,
|
|
7
7
|
* an agent stuck retrying the SAME denied action instead of adapting.
|
|
8
8
|
*/
|
|
9
|
-
import type { EventRecord } from './events.js';
|
|
9
|
+
import type { EventRecord } from './feed/events.js';
|
|
10
10
|
export interface RepeatedGuardBlockFinding {
|
|
11
11
|
/** Session id the repeated blocks happened in, or 'unknown' when the
|
|
12
12
|
* friction event carried no session (e.g. a guard fired outside any
|
package/dist/lib/git.d.ts
CHANGED
|
@@ -207,6 +207,10 @@ export declare function isGitRepo(dir: string): boolean;
|
|
|
207
207
|
* Shells out to `git rev-parse --show-toplevel`, so it resolves correctly from
|
|
208
208
|
* any subdirectory and for linked worktrees (unlike the root-only, synchronous
|
|
209
209
|
* {@link isGitRepo} above). Throws if `dir` is not inside a git repository.
|
|
210
|
+
*
|
|
211
|
+
* Git prints POSIX separators even on Windows (`C:/Users/...`); we fold them to
|
|
212
|
+
* the native separator so the result is a real filesystem path that compares
|
|
213
|
+
* equal to one built with `path.*`. On POSIX this is a no-op.
|
|
210
214
|
*/
|
|
211
215
|
export declare function getGitRoot(dir: string): Promise<string>;
|
|
212
216
|
/**
|
|
@@ -216,6 +220,10 @@ export declare function getGitRoot(dir: string): Promise<string>;
|
|
|
216
220
|
* worktree: `--show-toplevel` there returns the worktree's own path, but the
|
|
217
221
|
* common git dir (`--git-common-dir`) always points at the primary repo's
|
|
218
222
|
* `.git`, whose parent is the main checkout. Throws if `dir` is not in a repo.
|
|
223
|
+
*
|
|
224
|
+
* Git prints POSIX separators even on Windows (`C:/Users/...`); we fold them to
|
|
225
|
+
* the native separator so the result is a real filesystem path that compares
|
|
226
|
+
* equal to one built with `path.*`. On POSIX this is a no-op.
|
|
219
227
|
*/
|
|
220
228
|
export declare function getMainRepoRoot(dir: string): Promise<string>;
|
|
221
229
|
/**
|
|
@@ -281,7 +289,22 @@ export declare function displayHomePath(dir: string): string;
|
|
|
281
289
|
* 3. Genuinely diverged (local commits not on tracking) → `rebase` onto the
|
|
282
290
|
* tracking ref (same outcome as {@link syncRepoGit}, without a second pull).
|
|
283
291
|
*/
|
|
284
|
-
export
|
|
292
|
+
export interface PullRepoOptions {
|
|
293
|
+
/**
|
|
294
|
+
* `'default-branch-fast-forward'` — strict mode for `projects pull`:
|
|
295
|
+
* - Blocks immediately if the tree is dirty (no remote read needed).
|
|
296
|
+
* - Fetches origin, resolves the remote default branch, and refuses if the
|
|
297
|
+
* current branch is not the remote default.
|
|
298
|
+
* - Refuses if HEAD is ahead of the upstream (local commits not on remote).
|
|
299
|
+
* - Fast-forwards only (`merge --ff-only`). NEVER rebases.
|
|
300
|
+
* - NEVER installs git hook symlinks (read-only model path).
|
|
301
|
+
*
|
|
302
|
+
* `'preserve-local'` (default) — the existing behavior: tolerates dirty trees
|
|
303
|
+
* when the incoming diff does not collide, and rebases a diverged branch.
|
|
304
|
+
*/
|
|
305
|
+
mode?: 'preserve-local' | 'default-branch-fast-forward';
|
|
306
|
+
}
|
|
307
|
+
export declare function pullRepo(dir: string, options?: PullRepoOptions): Promise<{
|
|
285
308
|
success: boolean;
|
|
286
309
|
commit: string;
|
|
287
310
|
error?: string;
|
package/dist/lib/git.js
CHANGED
|
@@ -10,7 +10,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
10
10
|
import * as fs from 'fs';
|
|
11
11
|
import * as os from 'os';
|
|
12
12
|
import * as path from 'path';
|
|
13
|
-
import { IS_WINDOWS, isWindowsAbsolutePath } from './platform/index.js';
|
|
13
|
+
import { IS_WINDOWS, isWindowsAbsolutePath, toNativePath } from './platform/index.js';
|
|
14
14
|
import { getPackageLocalPath } from './state.js';
|
|
15
15
|
import { DEFAULT_SYSTEM_REPO, systemRepoSlug } from './types.js';
|
|
16
16
|
/**
|
|
@@ -658,10 +658,14 @@ export function isGitRepo(dir) {
|
|
|
658
658
|
* Shells out to `git rev-parse --show-toplevel`, so it resolves correctly from
|
|
659
659
|
* any subdirectory and for linked worktrees (unlike the root-only, synchronous
|
|
660
660
|
* {@link isGitRepo} above). Throws if `dir` is not inside a git repository.
|
|
661
|
+
*
|
|
662
|
+
* Git prints POSIX separators even on Windows (`C:/Users/...`); we fold them to
|
|
663
|
+
* the native separator so the result is a real filesystem path that compares
|
|
664
|
+
* equal to one built with `path.*`. On POSIX this is a no-op.
|
|
661
665
|
*/
|
|
662
666
|
export async function getGitRoot(dir) {
|
|
663
667
|
const root = await simpleGit(dir).revparse(['--show-toplevel']);
|
|
664
|
-
return root.trim();
|
|
668
|
+
return toNativePath(root.trim());
|
|
665
669
|
}
|
|
666
670
|
/**
|
|
667
671
|
* Return the absolute path to the **main** working-tree root for `dir`.
|
|
@@ -670,10 +674,14 @@ export async function getGitRoot(dir) {
|
|
|
670
674
|
* worktree: `--show-toplevel` there returns the worktree's own path, but the
|
|
671
675
|
* common git dir (`--git-common-dir`) always points at the primary repo's
|
|
672
676
|
* `.git`, whose parent is the main checkout. Throws if `dir` is not in a repo.
|
|
677
|
+
*
|
|
678
|
+
* Git prints POSIX separators even on Windows (`C:/Users/...`); we fold them to
|
|
679
|
+
* the native separator so the result is a real filesystem path that compares
|
|
680
|
+
* equal to one built with `path.*`. On POSIX this is a no-op.
|
|
673
681
|
*/
|
|
674
682
|
export async function getMainRepoRoot(dir) {
|
|
675
683
|
const common = await simpleGit(dir).raw(['rev-parse', '--path-format=absolute', '--git-common-dir']);
|
|
676
|
-
return path.dirname(common.trim());
|
|
684
|
+
return toNativePath(path.dirname(common.trim()));
|
|
677
685
|
}
|
|
678
686
|
/**
|
|
679
687
|
* Initialize a git repo in an existing directory.
|
|
@@ -863,23 +871,8 @@ export function displayHomePath(dir) {
|
|
|
863
871
|
const rel = dir.startsWith(home) ? '~' + dir.slice(home.length) : dir;
|
|
864
872
|
return rel.replace(/\\/g, '/');
|
|
865
873
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
* A dirty working tree no longer refuses outright: a fast-forward that touches
|
|
869
|
-
* no uncommitted path still runs (see `dirtyTreeRefusal`). It refuses when the
|
|
870
|
-
* branch has local commits to rebase, or when an incoming path is also dirty.
|
|
871
|
-
*
|
|
872
|
-
* Strategy (RUSH-2282):
|
|
873
|
-
* 1. Fetch, then compare HEAD to the resolved tracking ref.
|
|
874
|
-
* 2. Clean behind-only (HEAD is an ancestor of tracking) → `merge --ff-only`
|
|
875
|
-
* against the tracking ref. Never re-enter `git pull` after a bare fetch —
|
|
876
|
-
* multi-entry FETCH_HEAD (concurrent fetch, multi-branch remote) makes
|
|
877
|
-
* `git pull --rebase` die with "Cannot rebase onto multiple branches" even
|
|
878
|
-
* when the checkout is a pure fast-forward.
|
|
879
|
-
* 3. Genuinely diverged (local commits not on tracking) → `rebase` onto the
|
|
880
|
-
* tracking ref (same outcome as {@link syncRepoGit}, without a second pull).
|
|
881
|
-
*/
|
|
882
|
-
export async function pullRepo(dir) {
|
|
874
|
+
export async function pullRepo(dir, options = {}) {
|
|
875
|
+
const strict = options.mode === 'default-branch-fast-forward';
|
|
883
876
|
try {
|
|
884
877
|
const git = simpleGit(dir);
|
|
885
878
|
// A rebase left in progress by an earlier run must be reported as itself.
|
|
@@ -916,14 +909,24 @@ export async function pullRepo(dir) {
|
|
|
916
909
|
};
|
|
917
910
|
}
|
|
918
911
|
const status = await git.status();
|
|
912
|
+
// Strict mode (projects pull): refuse a dirty tree immediately — no fetch
|
|
913
|
+
// needed to know the answer, and the caller must not risk touching staged
|
|
914
|
+
// or modified files with an incoming fast-forward.
|
|
915
|
+
const isDirty = !status.isClean();
|
|
916
|
+
if (strict && isDirty) {
|
|
917
|
+
return {
|
|
918
|
+
success: false,
|
|
919
|
+
commit: '',
|
|
920
|
+
error: `Blocked: dirty working tree. Commit or discard local changes before pulling.\n\n cd ${displayHomePath(dir)} && git status`,
|
|
921
|
+
};
|
|
922
|
+
}
|
|
919
923
|
// A dirty tree is not decided here: whether a fast-forward is safe depends
|
|
920
924
|
// on what is actually incoming, and that needs a fetched upstream ref. The
|
|
921
925
|
// gate therefore sits just before the integrate step below. The exception is
|
|
922
926
|
// a repo with no remote at all — there is nothing to fast-forward from, so
|
|
923
927
|
// the dirt is the whole answer and the resolution below would only fail
|
|
924
928
|
// with a less useful message.
|
|
925
|
-
|
|
926
|
-
if (isDirty && (await git.getRemotes()).length === 0) {
|
|
929
|
+
if (!strict && isDirty && (await git.getRemotes()).length === 0) {
|
|
927
930
|
return {
|
|
928
931
|
success: false,
|
|
929
932
|
commit: '',
|
|
@@ -931,13 +934,13 @@ export async function pullRepo(dir) {
|
|
|
931
934
|
};
|
|
932
935
|
}
|
|
933
936
|
const branch = status.current || 'main';
|
|
934
|
-
// Resolve the upstream ref to fast-forward against.
|
|
935
|
-
//
|
|
937
|
+
// Resolve the upstream ref to fast-forward against.
|
|
938
|
+
// Strict mode: always fetch origin and resolve its default branch — then
|
|
939
|
+
// verify the current branch IS the remote default (refuse otherwise).
|
|
940
|
+
// Preserve-local mode: prefer the local branch's tracking config; only
|
|
941
|
+
// fetch when no tracking is set.
|
|
936
942
|
let tracking = status.tracking;
|
|
937
|
-
if (!tracking) {
|
|
938
|
-
// No tracking config: fetch origin so its HEAD is known, then ask which
|
|
939
|
-
// branch it points at. This path only ever concerns origin — a branch with
|
|
940
|
-
// no upstream has no other remote to consult.
|
|
943
|
+
if (strict || !tracking) {
|
|
941
944
|
try {
|
|
942
945
|
await git.fetch('origin');
|
|
943
946
|
await git.raw(['remote', 'set-head', 'origin', '--auto']);
|
|
@@ -948,6 +951,19 @@ export async function pullRepo(dir) {
|
|
|
948
951
|
tracking = `origin/${branch}`;
|
|
949
952
|
}
|
|
950
953
|
}
|
|
954
|
+
// Strict: the checkout must be on the remote default branch — never pull a
|
|
955
|
+
// feature branch across the fleet unattended.
|
|
956
|
+
if (strict) {
|
|
957
|
+
const sep = tracking.indexOf('/');
|
|
958
|
+
const expectedBranch = sep > 0 ? tracking.slice(sep + 1) : tracking;
|
|
959
|
+
if (branch !== expectedBranch) {
|
|
960
|
+
return {
|
|
961
|
+
success: false,
|
|
962
|
+
commit: '',
|
|
963
|
+
error: `Blocked: HEAD is on "${branch}" but origin defaults to "${expectedBranch}". Switch to "${expectedBranch}" before pulling.`,
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
}
|
|
951
967
|
// Split the remote-tracking ref (<remote>/<branch>) so callers/logs can name
|
|
952
968
|
// the remote. Branch names may contain slashes, so split on the FIRST
|
|
953
969
|
// separator only. The integrate step below uses `tracking` directly (not a
|
|
@@ -983,15 +999,32 @@ export async function pullRepo(dir) {
|
|
|
983
999
|
// around that call would always report "can ff" (RUSH-2282).
|
|
984
1000
|
const aheadCount = parseInt((await git.raw(['rev-list', '--count', `${tracking}..HEAD`])).trim(), 10);
|
|
985
1001
|
const behindCount = parseInt((await git.raw(['rev-list', '--count', `HEAD..${tracking}`])).trim(), 10);
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
//
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1002
|
+
// Both counts are the ONLY inputs to the fast-forward decision, so a count
|
|
1003
|
+
// we cannot read is a refusal, not a reason to guess. Fail here rather than
|
|
1004
|
+
// downstream: an unreadable count used to fall through to the rebase arm in
|
|
1005
|
+
// preserve-local mode, and to a "HEAD diverged" message in strict mode that
|
|
1006
|
+
// named the wrong cause.
|
|
1007
|
+
if (!Number.isFinite(aheadCount) || !Number.isFinite(behindCount)) {
|
|
1008
|
+
return {
|
|
1009
|
+
success: false,
|
|
1010
|
+
commit: '',
|
|
1011
|
+
error: `Could not read how far HEAD is from ${tracking} — 'git rev-list --count' returned no usable count. Check the checkout, then pull again:\n\n cd ${displayHomePath(dir)} && git status`,
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
const canFastForward = aheadCount === 0 && behindCount > 0;
|
|
1015
|
+
// Strict: block if HEAD has local commits not on the remote — fast-forward
|
|
1016
|
+
// requires the local tip to be an ancestor of the remote tip.
|
|
1017
|
+
if (strict && aheadCount > 0) {
|
|
1018
|
+
return {
|
|
1019
|
+
success: false,
|
|
1020
|
+
commit: '',
|
|
1021
|
+
error: `Blocked: HEAD is ${aheadCount} commit${aheadCount === 1 ? '' : 's'} ahead of ${tracking}. Push or discard local commits before pulling.`,
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
// Dirty tree (preserve-local only): same rule `syncRepoGit` applies —
|
|
1025
|
+
// a fast-forward that touches nothing the author is holding may proceed; a
|
|
1026
|
+
// rebase or a colliding path may not. Strict mode already refused above.
|
|
1027
|
+
if (!strict && isDirty) {
|
|
995
1028
|
const refusal = await dirtyTreeRefusal(git, status, tracking);
|
|
996
1029
|
if (refusal) {
|
|
997
1030
|
return {
|
|
@@ -1010,6 +1043,14 @@ export async function pullRepo(dir) {
|
|
|
1010
1043
|
// Diverged (or local-only commits). Rebase onto the tracking tip —
|
|
1011
1044
|
// same outcome as `git pull --rebase <remote> <branch>` without
|
|
1012
1045
|
// re-fetching or consulting FETCH_HEAD.
|
|
1046
|
+
//
|
|
1047
|
+
// PRESERVE-LOCAL ONLY — strict mode can never reach this arm, so the
|
|
1048
|
+
// fleet pull never rewrites history. Strict has already returned for
|
|
1049
|
+
// every case that leaves `canFastForward` false: an identical local and
|
|
1050
|
+
// remote ref, `aheadCount > 0` (which is also what "diverged" means),
|
|
1051
|
+
// and a count that would not parse. That leaves `aheadCount === 0` with
|
|
1052
|
+
// a differing ref, i.e. `behindCount > 0` — a fast-forward. Keep those
|
|
1053
|
+
// three returns above intact if you change this.
|
|
1013
1054
|
await git.raw(['rebase', tracking]);
|
|
1014
1055
|
}
|
|
1015
1056
|
}
|
|
@@ -1028,7 +1069,10 @@ export async function pullRepo(dir) {
|
|
|
1028
1069
|
error: `${verb} onto ${tracking} failed — the pull was rolled back, nothing changed.\n\nResolve the divergence, then pull again:\n\n cd ${displayHomePath(dir)} && git log --oneline HEAD...${tracking}\n\n${err.message}`,
|
|
1029
1070
|
};
|
|
1030
1071
|
}
|
|
1031
|
-
|
|
1072
|
+
// Strict mode never installs git hook symlinks — the command is a read-model
|
|
1073
|
+
// operation (update pointers only; never reconfigure the checkout).
|
|
1074
|
+
if (!strict)
|
|
1075
|
+
installGithooksSymlinks(dir);
|
|
1032
1076
|
const log = await git.log({ maxCount: 1 });
|
|
1033
1077
|
return {
|
|
1034
1078
|
success: true,
|
package/dist/lib/heal.js
CHANGED
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
* `agents prune cleanup`, so a heal pass can never lose work.
|
|
24
24
|
*/
|
|
25
25
|
import { ALL_AGENT_IDS } from './agents.js';
|
|
26
|
-
import { syncResourcesToVersion, listInstalledVersions, isVersionIsolated, getVersionHomePath, getActuallySyncedResources, compareVersions, } from './versions.js';
|
|
26
|
+
import { syncResourcesToVersion, listInstalledVersions, isVersionIsolated, getVersionHomePath, getActuallySyncedResources, compareVersions, } from './installations/versions.js';
|
|
27
27
|
import { diffVersionResources, } from './doctor-diff.js';
|
|
28
|
-
import { discoverPlugins, updatePlugin, readPluginSourceInfo, getUpstreamManifestVersion, } from './plugins.js';
|
|
29
|
-
import { repairPluginManifestFile } from './plugin-marketplace.js';
|
|
28
|
+
import { discoverPlugins, updatePlugin, readPluginSourceInfo, getUpstreamManifestVersion, } from './plugins/plugins.js';
|
|
29
|
+
import { repairPluginManifestFile } from './plugins/plugin-marketplace.js';
|
|
30
30
|
import * as fs from 'fs';
|
|
31
31
|
import * as path from 'path';
|
|
32
32
|
import * as os from 'os';
|
package/dist/lib/hooks.d.ts
CHANGED
|
@@ -386,3 +386,21 @@ export declare function registerHooksToSettings(agentId: AgentId, versionHome: s
|
|
|
386
386
|
* entries removed.
|
|
387
387
|
*/
|
|
388
388
|
export declare function pruneVersionHomeHookEntriesFromSettings(settingsPath: string, agent: AgentId, removedVersion: string): number;
|
|
389
|
+
export interface InstallSessionTrackerHookResult {
|
|
390
|
+
installed: boolean;
|
|
391
|
+
error?: string;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Install the shared SessionStart state-writer hook (`packages/session-tracker`)
|
|
395
|
+
* into the harness's native config. Gated by `supports(agent, 'hooks', version)`;
|
|
396
|
+
* unsupported agents return `installed: false` with a reason instead of throwing.
|
|
397
|
+
*
|
|
398
|
+
* This is the bridge that makes bare `claude` / `codex` / `kimi` launches write
|
|
399
|
+
* `~/.agents/.cache/terminals/sessions/<pid>.json`, not just `agents run` launches.
|
|
400
|
+
*/
|
|
401
|
+
export declare function installSessionTrackerHook(agent: AgentId, version?: string, home?: string): Promise<InstallSessionTrackerHookResult>;
|
|
402
|
+
/**
|
|
403
|
+
* Synchronous variant for callers that cannot be made async (e.g.
|
|
404
|
+
* `syncResourcesToVersion`). Best-effort: failures are returned, not thrown.
|
|
405
|
+
*/
|
|
406
|
+
export declare function installSessionTrackerHookSync(agent: AgentId, version?: string, home?: string): InstallSessionTrackerHookResult;
|
package/dist/lib/hooks.js
CHANGED
|
@@ -13,6 +13,9 @@ import * as os from 'os';
|
|
|
13
13
|
import * as path from 'path';
|
|
14
14
|
import * as yaml from 'yaml';
|
|
15
15
|
import * as TOML from 'smol-toml';
|
|
16
|
+
import { execFile, execFileSync } from 'child_process';
|
|
17
|
+
import { promisify } from 'util';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
16
19
|
import { AGENTS, agentConfigDirName, isAgentHardDeprecated } from './agents.js';
|
|
17
20
|
import { supports, explainSkip, capableAgents } from './capabilities.js';
|
|
18
21
|
import { getHooksDir as getSystemHooksDir, getUserHooksDir, getUserAgentsDir, getSystemAgentsDir, getProjectAgentsDir, getTrashHooksDir, getEnabledExtraRepos, getResolvedRulesDir, getUserRulesDir, getPerfDir } from './state.js';
|
|
@@ -264,7 +267,7 @@ function collapseVersionHookEntries(entries, activeVersionHome) {
|
|
|
264
267
|
return true;
|
|
265
268
|
});
|
|
266
269
|
}
|
|
267
|
-
import { getEffectiveHome, getGlobalDefault, getVersionHomePath, isVersionIsolated, listInstalledVersions, resolveVersion, } from './versions.js';
|
|
270
|
+
import { getEffectiveHome, getGlobalDefault, getVersionHomePath, isVersionIsolated, listInstalledVersions, resolveVersion, } from './installations/versions.js';
|
|
268
271
|
import { generateHookShim, getHookShimPath, isValidHookShimName, parseCacheConfig, removeHookShim } from './hooks/cache.js';
|
|
269
272
|
import { getHookShimsDir } from './state.js';
|
|
270
273
|
function hookContentHash(scriptPath) {
|
|
@@ -3244,3 +3247,112 @@ function registerHooksForHermes(versionHome, manifest, resolveScript, managedPre
|
|
|
3244
3247
|
}
|
|
3245
3248
|
return { registered, errors };
|
|
3246
3249
|
}
|
|
3250
|
+
const execFileAsync = promisify(execFile);
|
|
3251
|
+
function resolveSessionTrackerRoot() {
|
|
3252
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
3253
|
+
// Built/installed layout: dist/lib/ -> dist/session-tracker
|
|
3254
|
+
const built = path.resolve(here, '..', 'session-tracker');
|
|
3255
|
+
if (fs.existsSync(path.join(built, 'dist', 'hook.sh'))) {
|
|
3256
|
+
return built;
|
|
3257
|
+
}
|
|
3258
|
+
// Source layout: apps/cli/src/lib/ -> repo root -> packages/session-tracker
|
|
3259
|
+
const source = path.resolve(here, '..', '..', '..', '..', 'packages', 'session-tracker');
|
|
3260
|
+
if (fs.existsSync(path.join(source, 'src', 'hook.sh'))) {
|
|
3261
|
+
return source;
|
|
3262
|
+
}
|
|
3263
|
+
return null;
|
|
3264
|
+
}
|
|
3265
|
+
function resolveTsxLoader(trackerRoot) {
|
|
3266
|
+
const loader = path.join(trackerRoot, 'node_modules', 'tsx', 'dist', 'cli.mjs');
|
|
3267
|
+
if (fs.existsSync(loader))
|
|
3268
|
+
return loader;
|
|
3269
|
+
return null;
|
|
3270
|
+
}
|
|
3271
|
+
function buildInstallHookInvocation(trackerRoot, agent) {
|
|
3272
|
+
const distScript = path.join(trackerRoot, 'dist', 'install-hook.js');
|
|
3273
|
+
if (fs.existsSync(distScript)) {
|
|
3274
|
+
return { command: process.execPath, args: [distScript, agent] };
|
|
3275
|
+
}
|
|
3276
|
+
const loader = resolveTsxLoader(trackerRoot);
|
|
3277
|
+
if (!loader)
|
|
3278
|
+
return null;
|
|
3279
|
+
return {
|
|
3280
|
+
command: process.execPath,
|
|
3281
|
+
args: [loader, path.join(trackerRoot, 'src', 'install-hook.ts'), agent],
|
|
3282
|
+
};
|
|
3283
|
+
}
|
|
3284
|
+
/**
|
|
3285
|
+
* Install the shared SessionStart state-writer hook (`packages/session-tracker`)
|
|
3286
|
+
* into the harness's native config. Gated by `supports(agent, 'hooks', version)`;
|
|
3287
|
+
* unsupported agents return `installed: false` with a reason instead of throwing.
|
|
3288
|
+
*
|
|
3289
|
+
* This is the bridge that makes bare `claude` / `codex` / `kimi` launches write
|
|
3290
|
+
* `~/.agents/.cache/terminals/sessions/<pid>.json`, not just `agents run` launches.
|
|
3291
|
+
*/
|
|
3292
|
+
export async function installSessionTrackerHook(agent, version, home) {
|
|
3293
|
+
const gate = supports(agent, 'hooks', version);
|
|
3294
|
+
if (!gate.ok) {
|
|
3295
|
+
return { installed: false, error: explainSkip(agent, 'hooks', gate, version) };
|
|
3296
|
+
}
|
|
3297
|
+
const trackerRoot = resolveSessionTrackerRoot();
|
|
3298
|
+
if (!trackerRoot) {
|
|
3299
|
+
return { installed: false, error: 'session-tracker package not found' };
|
|
3300
|
+
}
|
|
3301
|
+
const invocation = buildInstallHookInvocation(trackerRoot, agent);
|
|
3302
|
+
if (!invocation) {
|
|
3303
|
+
return { installed: false, error: 'session-tracker not built and tsx is unavailable' };
|
|
3304
|
+
}
|
|
3305
|
+
try {
|
|
3306
|
+
await execFileAsync(invocation.command, invocation.args, {
|
|
3307
|
+
env: { ...process.env, HOME: home ?? process.env.HOME },
|
|
3308
|
+
encoding: 'utf8',
|
|
3309
|
+
});
|
|
3310
|
+
return { installed: true };
|
|
3311
|
+
}
|
|
3312
|
+
catch (err) {
|
|
3313
|
+
return { installed: false, error: installFailureMessage(err) };
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
/**
|
|
3317
|
+
* The child reports its refusal reason on stdout (its HOOK_SUPPORT table), not
|
|
3318
|
+
* stderr — and a Buffer-typed empty stderr is truthy, so a bare `err.stderr ??
|
|
3319
|
+
* err.message` surfaced an empty string. Prefer the first NON-EMPTY stream.
|
|
3320
|
+
*/
|
|
3321
|
+
function installFailureMessage(err) {
|
|
3322
|
+
const e = err;
|
|
3323
|
+
for (const stream of [e.stderr, e.stdout]) {
|
|
3324
|
+
const text = stream == null ? '' : String(stream).trim();
|
|
3325
|
+
if (text.length > 0)
|
|
3326
|
+
return text;
|
|
3327
|
+
}
|
|
3328
|
+
return e.message;
|
|
3329
|
+
}
|
|
3330
|
+
/**
|
|
3331
|
+
* Synchronous variant for callers that cannot be made async (e.g.
|
|
3332
|
+
* `syncResourcesToVersion`). Best-effort: failures are returned, not thrown.
|
|
3333
|
+
*/
|
|
3334
|
+
export function installSessionTrackerHookSync(agent, version, home) {
|
|
3335
|
+
const gate = supports(agent, 'hooks', version);
|
|
3336
|
+
if (!gate.ok) {
|
|
3337
|
+
return { installed: false, error: explainSkip(agent, 'hooks', gate, version) };
|
|
3338
|
+
}
|
|
3339
|
+
const trackerRoot = resolveSessionTrackerRoot();
|
|
3340
|
+
if (!trackerRoot) {
|
|
3341
|
+
return { installed: false, error: 'session-tracker package not found' };
|
|
3342
|
+
}
|
|
3343
|
+
const invocation = buildInstallHookInvocation(trackerRoot, agent);
|
|
3344
|
+
if (!invocation) {
|
|
3345
|
+
return { installed: false, error: 'session-tracker not built and tsx is unavailable' };
|
|
3346
|
+
}
|
|
3347
|
+
try {
|
|
3348
|
+
execFileSync(invocation.command, invocation.args, {
|
|
3349
|
+
env: { ...process.env, HOME: home ?? process.env.HOME },
|
|
3350
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
3351
|
+
encoding: 'utf8',
|
|
3352
|
+
});
|
|
3353
|
+
return { installed: true };
|
|
3354
|
+
}
|
|
3355
|
+
catch (err) {
|
|
3356
|
+
return { installed: false, error: installFailureMessage(err) };
|
|
3357
|
+
}
|
|
3358
|
+
}
|