@phnx-labs/agents-cli 1.22.35 → 1.22.37
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 +666 -2
- package/README.md +75 -35
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1211 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/attach.js +17 -4
- package/dist/commands/audit.d.ts +8 -8
- package/dist/commands/audit.js +57 -47
- package/dist/commands/browser.js +15 -11
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +0 -11
- package/dist/commands/computer-actions.js +33 -0
- package/dist/commands/computer-sessions-picker.d.ts +21 -0
- package/dist/commands/computer-sessions-picker.js +141 -0
- package/dist/commands/computer.d.ts +16 -0
- package/dist/commands/computer.js +37 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +401 -0
- package/dist/commands/cp.d.ts +84 -0
- package/dist/commands/cp.js +231 -0
- package/dist/commands/daemon.js +243 -14
- package/dist/commands/detach-core.d.ts +1 -1
- package/dist/commands/detach-core.js +12 -2
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +64 -5
- package/dist/commands/events.d.ts +24 -12
- package/dist/commands/events.js +144 -28
- package/dist/commands/exec.js +85 -41
- package/dist/commands/feed.d.ts +1 -1
- package/dist/commands/feed.js +16 -8
- package/dist/commands/focus.d.ts +33 -1
- package/dist/commands/focus.js +177 -17
- package/dist/commands/funnel.d.ts +1 -1
- package/dist/commands/go.js +9 -8
- package/dist/commands/harness-wizard.d.ts +1 -0
- package/dist/commands/harness-wizard.js +18 -20
- package/dist/commands/harness.d.ts +2 -0
- package/dist/commands/harness.js +59 -26
- package/dist/commands/hooks.js +0 -11
- package/dist/commands/inspect.d.ts +94 -1
- package/dist/commands/inspect.js +866 -40
- package/dist/commands/lease.d.ts +4 -4
- package/dist/commands/lease.js +6 -6
- package/dist/commands/login.js +0 -13
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +2 -2
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/memory.js +7 -2
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +37 -6
- package/dist/commands/models.js +4 -0
- package/dist/commands/monitors.d.ts +0 -1
- package/dist/commands/monitors.js +199 -16
- package/dist/commands/open.d.ts +18 -0
- package/dist/commands/open.js +57 -0
- package/dist/commands/packages.js +2 -107
- package/dist/commands/plugins.js +6 -3
- package/dist/commands/profiles.d.ts +1 -0
- package/dist/commands/profiles.js +16 -160
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +125 -5
- package/dist/commands/reconnect.js +9 -3
- package/dist/commands/repo.js +42 -1
- package/dist/commands/resource-view.d.ts +17 -0
- package/dist/commands/resource-view.js +36 -14
- package/dist/commands/resume.js +9 -2
- package/dist/commands/routines.d.ts +0 -2
- package/dist/commands/routines.js +473 -289
- package/dist/commands/secrets.js +52 -9
- package/dist/commands/sessions-export.d.ts +47 -0
- package/dist/commands/sessions-export.js +116 -6
- package/dist/commands/sessions-import.d.ts +17 -0
- package/dist/commands/sessions-import.js +114 -6
- package/dist/commands/sessions-migrate.d.ts +27 -0
- package/dist/commands/sessions-migrate.js +50 -9
- package/dist/commands/sessions-picker.js +23 -4
- package/dist/commands/sessions-resume.d.ts +5 -3
- package/dist/commands/sessions-resume.js +30 -8
- package/dist/commands/sessions-watch.d.ts +2 -0
- package/dist/commands/sessions-watch.js +53 -0
- package/dist/commands/sessions.d.ts +66 -3
- package/dist/commands/sessions.js +298 -47
- package/dist/commands/set.d.ts +1 -1
- package/dist/commands/set.js +2 -2
- package/dist/commands/setup-browser.js +2 -2
- package/dist/commands/setup-mine.js +0 -1
- package/dist/commands/setup-preferences.js +1 -1
- package/dist/commands/setup-share.js +34 -4
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +26 -0
- package/dist/commands/share.d.ts +67 -0
- package/dist/commands/share.js +275 -12
- package/dist/commands/skills.js +0 -11
- package/dist/commands/snapshot.js +1 -1
- package/dist/commands/ssh.d.ts +18 -0
- package/dist/commands/ssh.js +549 -210
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +212 -32
- package/dist/commands/teams.d.ts +13 -0
- package/dist/commands/teams.js +187 -30
- package/dist/commands/tickets.d.ts +2 -0
- package/dist/commands/tickets.js +43 -0
- package/dist/commands/update.js +2 -4
- package/dist/commands/usage.js +5 -3
- package/dist/commands/versions.js +11 -5
- package/dist/commands/view.js +15 -7
- package/dist/commands/webhook.d.ts +2 -2
- package/dist/commands/webhook.js +7 -7
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -1264
- package/dist/lib/account-catalog.d.ts +18 -0
- package/dist/lib/account-catalog.js +38 -0
- package/dist/lib/account-provider-registry.d.ts +18 -0
- package/dist/lib/account-provider-registry.js +59 -0
- package/dist/lib/account-registry.d.ts +40 -0
- package/dist/lib/account-registry.js +239 -0
- package/dist/lib/account-schema.d.ts +44 -0
- package/dist/lib/account-schema.js +91 -0
- package/dist/lib/account-state-service.d.ts +21 -0
- package/dist/lib/account-state-service.js +60 -0
- package/dist/lib/activity.d.ts +1 -1
- package/dist/lib/activity.js +8 -1
- package/dist/lib/add-dir.d.ts +80 -0
- package/dist/lib/add-dir.js +241 -0
- package/dist/lib/agent-cli-commands.d.ts +11 -0
- package/dist/lib/agent-cli-commands.js +30 -0
- package/dist/lib/agents.js +44 -36
- package/dist/lib/answer-router.js +1 -1
- package/dist/lib/audit/log.d.ts +10 -27
- package/dist/lib/audit/log.js +20 -33
- package/dist/lib/auth-health.d.ts +9 -2
- package/dist/lib/auth-health.js +42 -9
- package/dist/lib/auto-pull-worker.js +7 -3
- package/dist/lib/auto-pull.d.ts +44 -3
- package/dist/lib/auto-pull.js +88 -5
- package/dist/lib/binary-shadow.d.ts +28 -0
- package/dist/lib/binary-shadow.js +121 -0
- package/dist/lib/brand.js +9 -3
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +81 -4
- package/dist/lib/browser/profiles.d.ts +3 -2
- package/dist/lib/browser/profiles.js +65 -22
- package/dist/lib/browser/service.d.ts +4 -0
- package/dist/lib/browser/service.js +30 -3
- package/dist/lib/browser/sessions-list.d.ts +22 -2
- package/dist/lib/browser/sessions-list.js +54 -6
- package/dist/lib/browser/stream.d.ts +2 -0
- package/dist/lib/browser/stream.js +1 -0
- package/dist/lib/browser/types.d.ts +19 -0
- package/dist/lib/byok-usage.d.ts +9 -2
- package/dist/lib/byok-usage.js +133 -31
- package/dist/lib/cli-entry.d.ts +11 -0
- package/dist/lib/cli-entry.js +46 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +2 -2
- package/dist/lib/cloud/registry.js +1 -1
- package/dist/lib/cloud/types.d.ts +1 -1
- package/dist/lib/commands.d.ts +2 -0
- package/dist/lib/commands.js +2 -0
- package/dist/lib/computer/sessions-list.d.ts +150 -0
- package/dist/lib/computer/sessions-list.js +363 -0
- package/dist/lib/config-keys.d.ts +86 -0
- package/dist/lib/config-keys.js +193 -0
- package/dist/lib/config-machine-keys.d.ts +12 -0
- package/dist/lib/config-machine-keys.js +17 -0
- package/dist/lib/config-transfer.js +3 -4
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/cli.js +3 -3
- package/dist/lib/daemon-health.d.ts +22 -0
- package/dist/lib/daemon-health.js +33 -3
- package/dist/lib/daemon-services.d.ts +50 -0
- package/dist/lib/daemon-services.js +147 -0
- package/dist/lib/daemon-ticks.d.ts +35 -66
- package/dist/lib/daemon-ticks.js +77 -159
- package/dist/lib/daemon.d.ts +72 -4
- package/dist/lib/daemon.js +792 -202
- package/dist/lib/deeplink/register.d.ts +49 -0
- package/dist/lib/deeplink/register.js +253 -0
- package/dist/lib/deeplink/url.d.ts +34 -0
- package/dist/lib/deeplink/url.js +78 -0
- package/dist/lib/device-config.d.ts +124 -29
- package/dist/lib/device-config.js +346 -141
- package/dist/lib/devices/config-migration.d.ts +42 -0
- package/dist/lib/devices/config-migration.js +203 -0
- package/dist/lib/devices/connect.js +14 -7
- package/dist/lib/devices/doctor-findings.d.ts +4 -1
- package/dist/lib/devices/doctor-findings.js +20 -1
- package/dist/lib/devices/harness-inventory.d.ts +11 -2
- package/dist/lib/devices/harness-inventory.js +0 -0
- package/dist/lib/devices/health.d.ts +1 -1
- package/dist/lib/devices/health.js +1 -1
- package/dist/lib/devices/pending.d.ts +22 -1
- package/dist/lib/devices/pending.js +67 -2
- package/dist/lib/devices/registry.d.ts +0 -25
- package/dist/lib/devices/registry.js +2 -83
- package/dist/lib/devices/resolve-profile.d.ts +20 -0
- package/dist/lib/devices/resolve-profile.js +44 -0
- package/dist/lib/devices/rollout-verify.d.ts +101 -0
- package/dist/lib/devices/rollout-verify.js +193 -0
- package/dist/lib/devices/ssh-config.js +10 -6
- package/dist/lib/event-families.d.ts +28 -0
- package/dist/lib/event-families.js +159 -0
- package/dist/lib/event-stream.d.ts +9 -1
- package/dist/lib/event-stream.js +26 -9
- package/dist/lib/events.d.ts +9 -1
- package/dist/lib/events.js +21 -6
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +219 -121
- package/dist/lib/feed-broadcast.d.ts +25 -0
- package/dist/lib/feed-broadcast.js +33 -0
- package/dist/lib/feed.d.ts +1 -1
- package/dist/lib/feed.js +12 -2
- package/dist/lib/fleet/capture.js +15 -0
- package/dist/lib/fleet/manifest.js +9 -0
- package/dist/lib/fleet/types.d.ts +9 -0
- package/dist/lib/fleet-status.js +10 -8
- package/dist/lib/git.d.ts +20 -6
- package/dist/lib/git.js +121 -17
- package/dist/lib/hosts/dispatch.d.ts +8 -3
- package/dist/lib/hosts/dispatch.js +29 -3
- package/dist/lib/hosts/logs.d.ts +2 -2
- package/dist/lib/hosts/logs.js +2 -2
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.d.ts +2 -3
- package/dist/lib/hosts/passthrough.js +10 -24
- package/dist/lib/hosts/progress.js +2 -2
- package/dist/lib/hosts/providers/devices.d.ts +3 -3
- package/dist/lib/hosts/providers/devices.js +18 -12
- package/dist/lib/hosts/ready.d.ts +5 -1
- package/dist/lib/hosts/ready.js +9 -3
- package/dist/lib/hosts/reconcile.d.ts +2 -2
- package/dist/lib/hosts/reconcile.js +2 -2
- package/dist/lib/hosts/registry.js +14 -9
- package/dist/lib/hosts/remote-cmd.js +1 -1
- package/dist/lib/hosts/remote-os.d.ts +9 -6
- package/dist/lib/hosts/remote-os.js +13 -6
- package/dist/lib/hosts/routing-flag.d.ts +23 -0
- package/dist/lib/hosts/routing-flag.js +41 -0
- package/dist/lib/hosts/run-target.js +1 -1
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/tasks.d.ts +6 -6
- package/dist/lib/hosts/tasks.js +4 -4
- package/dist/lib/hosts/types.js +1 -2
- package/dist/lib/installations/resolve.js +2 -8
- package/dist/lib/isolation-boundary-report.js +0 -1
- package/dist/lib/linear-cache.d.ts +7 -0
- package/dist/lib/linear-cache.js +31 -4
- package/dist/lib/linear-project-counts.d.ts +1 -1
- package/dist/lib/linear-project-counts.js +2 -3
- package/dist/lib/linear-projects.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-target.d.ts +1 -1
- package/dist/lib/mailbox-target.js +1 -1
- package/dist/lib/manifest.js +7 -4
- 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/snapshot.d.ts +3 -2
- package/dist/lib/menubar/snapshot.js +6 -2
- package/dist/lib/migrate-fold.d.ts +33 -0
- package/dist/lib/migrate-fold.js +130 -0
- package/dist/lib/migrate.d.ts +34 -34
- package/dist/lib/migrate.js +106 -128
- package/dist/lib/model-tier-overrides.d.ts +1 -1
- package/dist/lib/model-tier-overrides.js +15 -2
- package/dist/lib/monitors/config.d.ts +17 -3
- package/dist/lib/monitors/config.js +52 -18
- package/dist/lib/monitors/engine.d.ts +32 -1
- package/dist/lib/monitors/engine.js +94 -11
- package/dist/lib/monitors/fingerprint.d.ts +46 -0
- package/dist/lib/monitors/fingerprint.js +100 -0
- package/dist/lib/monitors/remote.d.ts +47 -0
- package/dist/lib/monitors/remote.js +81 -0
- package/dist/lib/monitors/state.d.ts +39 -0
- package/dist/lib/monitors/state.js +56 -0
- package/dist/lib/onepassword.d.ts +17 -0
- package/dist/lib/onepassword.js +52 -22
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/picker.d.ts +14 -2
- package/dist/lib/picker.js +35 -13
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +1 -1
- package/dist/lib/pr-land-detach.d.ts +32 -0
- package/dist/lib/pr-land-detach.js +79 -0
- package/dist/lib/profiles-presets.js +13 -0
- package/dist/lib/profiles.d.ts +2 -0
- package/dist/lib/profiles.js +44 -1
- package/dist/lib/project-focus.d.ts +1 -1
- package/dist/lib/project-focus.js +1 -1
- package/dist/lib/project-probe.d.ts +4 -1
- package/dist/lib/project-probe.js +5 -4
- package/dist/lib/project-resources.js +2 -18
- package/dist/lib/project-root.d.ts +16 -0
- package/dist/lib/project-root.js +20 -2
- package/dist/lib/projects.d.ts +20 -1
- package/dist/lib/projects.js +78 -1
- package/dist/lib/refresh-coordinator.d.ts +24 -0
- package/dist/lib/refresh-coordinator.js +52 -0
- package/dist/lib/registry.d.ts +2 -2
- package/dist/lib/registry.js +1 -1
- package/dist/lib/resource-aliases.d.ts +13 -0
- package/dist/lib/resource-aliases.js +26 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +16 -0
- package/dist/lib/resources.js +66 -10
- package/dist/lib/rotate.d.ts +3 -4
- package/dist/lib/rotate.js +4 -5
- package/dist/lib/routine-activation.d.ts +22 -2
- package/dist/lib/routine-activation.js +63 -16
- package/dist/lib/routine-context.d.ts +9 -2
- package/dist/lib/routine-context.js +21 -6
- package/dist/lib/routines-project.d.ts +58 -48
- package/dist/lib/routines-project.js +190 -159
- package/dist/lib/routines.d.ts +41 -6
- package/dist/lib/routines.js +92 -34
- package/dist/lib/run-defaults.d.ts +5 -0
- package/dist/lib/run-defaults.js +11 -1
- package/dist/lib/runner.d.ts +10 -8
- package/dist/lib/runner.js +122 -39
- 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.d.ts +10 -3
- package/dist/lib/secrets/agent.js +43 -8
- package/dist/lib/secrets/bundles.d.ts +1 -0
- package/dist/lib/secrets/bundles.js +92 -80
- package/dist/lib/secrets/index.js +32 -9
- package/dist/lib/secrets/install-helper.d.ts +4 -4
- package/dist/lib/secrets/install-helper.js +4 -4
- package/dist/lib/secrets/push.d.ts +40 -6
- package/dist/lib/secrets/push.js +58 -11
- package/dist/lib/secrets/read-backoff.d.ts +1 -1
- package/dist/lib/secrets/read-backoff.js +1 -1
- package/dist/lib/secrets/remote.d.ts +24 -0
- package/dist/lib/secrets/remote.js +54 -4
- package/dist/lib/self-update.d.ts +108 -0
- package/dist/lib/self-update.js +276 -1
- package/dist/lib/session/active.d.ts +89 -5
- package/dist/lib/session/active.js +165 -10
- package/dist/lib/session/actor-sidecar.d.ts +1 -1
- package/dist/lib/session/actor-sidecar.js +2 -1
- package/dist/lib/session/db.d.ts +176 -2
- package/dist/lib/session/db.js +484 -17
- package/dist/lib/session/discover.js +27 -4
- package/dist/lib/session/hook-sessions.js +2 -2
- package/dist/lib/session/host-link.d.ts +2 -2
- package/dist/lib/session/host-link.js +2 -2
- package/dist/lib/session/pid-registry.d.ts +21 -0
- package/dist/lib/session/pid-registry.js +57 -0
- package/dist/lib/session/remote-active.js +15 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/session-cache.d.ts +14 -7
- package/dist/lib/session/session-cache.js +51 -9
- package/dist/lib/session/state.d.ts +2 -2
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/sync/config.d.ts +10 -10
- package/dist/lib/session/sync/config.js +10 -10
- package/dist/lib/session/sync/r2.d.ts +34 -0
- package/dist/lib/session/sync/r2.js +123 -0
- package/dist/lib/session/throughput.d.ts +1 -1
- package/dist/lib/session/throughput.js +1 -1
- package/dist/lib/session/types.d.ts +23 -1
- package/dist/lib/session/types.js +15 -0
- package/dist/lib/session/viewing-in.d.ts +1 -1
- package/dist/lib/session/viewing-in.js +1 -1
- package/dist/lib/session/watch.d.ts +101 -0
- package/dist/lib/session/watch.js +242 -0
- package/dist/lib/share/config.d.ts +4 -0
- package/dist/lib/share/config.js +1 -0
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +50 -0
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +116 -3
- package/dist/lib/share/worker-template.js +71 -6
- package/dist/lib/shims.d.ts +17 -3
- package/dist/lib/shims.js +98 -26
- package/dist/lib/signin-badge.js +3 -2
- package/dist/lib/skills.js +2 -0
- package/dist/lib/smart-launch.d.ts +8 -8
- package/dist/lib/smart-launch.js +80 -59
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +1 -1
- package/dist/lib/staleness/prune.d.ts +88 -0
- package/dist/lib/staleness/prune.js +69 -0
- package/dist/lib/staleness/registry.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.js +34 -2
- package/dist/lib/staleness/writers/hooks.js +16 -0
- package/dist/lib/staleness/writers/kinds.d.ts +6 -0
- package/dist/lib/staleness/writers/skills.js +19 -0
- package/dist/lib/staleness/writers/subagents.d.ts +2 -3
- package/dist/lib/staleness/writers/subagents.js +0 -4
- package/dist/lib/staleness/writers/types.d.ts +32 -0
- package/dist/lib/startup/command-registry.d.ts +6 -12
- package/dist/lib/startup/command-registry.js +11 -31
- package/dist/lib/startup/dev-build.d.ts +10 -0
- package/dist/lib/startup/dev-build.js +13 -1
- package/dist/lib/startup/spellcheck.d.ts +18 -0
- package/dist/lib/startup/spellcheck.js +45 -0
- package/dist/lib/state.d.ts +36 -9
- package/dist/lib/state.js +96 -46
- package/dist/lib/subagents-registry.d.ts +0 -7
- package/dist/lib/subagents-registry.js +38 -65
- package/dist/lib/subagents.d.ts +0 -33
- package/dist/lib/subagents.js +0 -75
- package/dist/lib/sync-umbrella.js +1 -1
- package/dist/lib/teams/agents.d.ts +41 -1
- package/dist/lib/teams/agents.js +187 -9
- package/dist/lib/teams/api.d.ts +11 -1
- package/dist/lib/teams/api.js +11 -2
- package/dist/lib/teams/delivery.d.ts +41 -0
- package/dist/lib/teams/delivery.js +60 -0
- package/dist/lib/teams/registry.d.ts +14 -0
- package/dist/lib/teams/registry.js +51 -1
- package/dist/lib/teams/remoteWorktree.d.ts +19 -0
- package/dist/lib/teams/remoteWorktree.js +29 -0
- package/dist/lib/teams/scheduler.d.ts +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/teams/worktree.d.ts +24 -0
- package/dist/lib/teams/worktree.js +42 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
- package/dist/lib/terminal/engine.d.ts +4 -0
- package/dist/lib/terminal/engine.js +8 -2
- package/dist/lib/terminal/types.d.ts +21 -2
- package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
- package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
- package/dist/lib/tickets/list.d.ts +53 -0
- package/dist/lib/tickets/list.js +153 -0
- package/dist/lib/tmux/orphan-reap.d.ts +320 -0
- package/dist/lib/tmux/orphan-reap.js +644 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +95 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +6 -1
- package/dist/lib/types.d.ts +46 -34
- package/dist/lib/usage-fleet.d.ts +32 -0
- package/dist/lib/usage-fleet.js +125 -0
- package/dist/lib/usage-refresh.d.ts +3 -3
- package/dist/lib/usage-refresh.js +19 -16
- package/dist/lib/usage.d.ts +51 -47
- package/dist/lib/usage.js +145 -153
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/versions.d.ts +56 -13
- package/dist/lib/versions.js +195 -45
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +3 -3
- package/dist/lib/watchdog/rotate.d.ts +6 -6
- package/dist/lib/watchdog/rotate.js +6 -6
- package/dist/lib/workflows.d.ts +1 -1
- package/dist/lib/yaml-io.d.ts +47 -0
- package/dist/lib/yaml-io.js +55 -0
- package/package.json +2 -1
- package/scripts/install-helper.js +2 -2
- package/scripts/postinstall.js +23 -20
- package/dist/commands/defaults.d.ts +0 -7
- package/dist/commands/defaults.js +0 -107
- package/dist/commands/export.d.ts +0 -11
- package/dist/commands/export.js +0 -215
- package/dist/commands/helper.d.ts +0 -12
- package/dist/commands/helper.js +0 -87
- package/dist/commands/hosts.d.ts +0 -11
- package/dist/commands/hosts.js +0 -330
- package/dist/commands/lock.d.ts +0 -12
- package/dist/commands/lock.js +0 -70
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/pull.js +0 -39
- package/dist/commands/push.d.ts +0 -14
- package/dist/commands/push.js +0 -30
- package/dist/commands/wallet.d.ts +0 -20
- package/dist/commands/wallet.js +0 -216
- package/dist/commands/worktree.d.ts +0 -19
- package/dist/commands/worktree.js +0 -272
- package/dist/lib/account-labels.d.ts +0 -24
- package/dist/lib/account-labels.js +0 -72
- package/dist/lib/auto-dispatch-linear.d.ts +0 -18
- package/dist/lib/auto-dispatch-linear.js +0 -107
- package/dist/lib/auto-dispatch-provider.d.ts +0 -10
- package/dist/lib/auto-dispatch-provider.js +0 -30
- package/dist/lib/auto-dispatch.d.ts +0 -93
- package/dist/lib/auto-dispatch.js +0 -128
- package/dist/lib/export.d.ts +0 -72
- package/dist/lib/export.js +0 -269
- package/dist/lib/lock.d.ts +0 -93
- package/dist/lib/lock.js +0 -207
- package/dist/lib/wallet/index.d.ts +0 -78
- package/dist/lib/wallet/index.js +0 -253
package/dist/lib/projects.js
CHANGED
|
@@ -272,6 +272,83 @@ export function projectBasePath(def, forRemote) {
|
|
|
272
272
|
return undefined;
|
|
273
273
|
return forRemote ? base : expandLocalHome(base);
|
|
274
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Every directory a project binds, ordered: `primary` first, then each
|
|
277
|
+
* `repos[]` entry that carries a local `path` (joined with its `subpath`).
|
|
278
|
+
* Deduped by resolved path, so a repo row pointing at the primary collapses.
|
|
279
|
+
*
|
|
280
|
+
* The repos[] walk and the dedupe are shared; the three things the two callers
|
|
281
|
+
* genuinely disagree on are parameters rather than guesses, because collapsing
|
|
282
|
+
* them would change one caller's meaning:
|
|
283
|
+
*
|
|
284
|
+
* - **primary** — spawning anchors on the cwd an agent lands in
|
|
285
|
+
* (`defaultPath ?? root`); probing anchors on `root`, so a monorepo
|
|
286
|
+
* subproject still probes its checkout rather than its subdirectory.
|
|
287
|
+
* - **keepMissing** — probing KEEPS a missing directory, because reporting
|
|
288
|
+
* `✗ missing` across the fleet is the whole job. A local spawn drops it: a
|
|
289
|
+
* grant for a path that is not on this box is noise the harness rejects.
|
|
290
|
+
* - **joinSubpath** — a spawn grants the subdirectory the project declares it
|
|
291
|
+
* cares about; a probe wants the repo root, since git status is a
|
|
292
|
+
* whole-checkout question.
|
|
293
|
+
*/
|
|
294
|
+
function projectDirList(def, opts) {
|
|
295
|
+
const raw = [
|
|
296
|
+
opts.primary,
|
|
297
|
+
...(def.repos ?? []).map((r) => {
|
|
298
|
+
if (!r.path)
|
|
299
|
+
return undefined;
|
|
300
|
+
if (!opts.joinSubpath || !r.subpath)
|
|
301
|
+
return r.path;
|
|
302
|
+
return `${r.path.replace(/\/+$/, '')}/${r.subpath.replace(/^\/+/, '')}`;
|
|
303
|
+
}),
|
|
304
|
+
].filter((p) => typeof p === 'string' && p.length > 0);
|
|
305
|
+
const seen = new Set();
|
|
306
|
+
const out = [];
|
|
307
|
+
for (const p of raw) {
|
|
308
|
+
// Dedupe on the absolute local path so `~/src/x` and an already-expanded
|
|
309
|
+
// `/home/me/src/x` in a hand-edited def collapse to one entry.
|
|
310
|
+
const abs = path.resolve(expandLocalHome(p));
|
|
311
|
+
if (seen.has(abs))
|
|
312
|
+
continue;
|
|
313
|
+
seen.add(abs);
|
|
314
|
+
if (!opts.keepMissing && !fs.existsSync(abs))
|
|
315
|
+
continue;
|
|
316
|
+
out.push(opts.forRemote ? toHomeRelative(abs) : abs);
|
|
317
|
+
}
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The directories `projects status` probes across the fleet: the repo root plus
|
|
322
|
+
* every bound checkout, home-relative so each host re-roots them, and including
|
|
323
|
+
* directories absent here so a peer can still answer `✗ missing` for them.
|
|
324
|
+
*/
|
|
325
|
+
export function projectProbeTargets(def) {
|
|
326
|
+
return projectDirList(def, {
|
|
327
|
+
primary: def.root,
|
|
328
|
+
forRemote: true,
|
|
329
|
+
keepMissing: true,
|
|
330
|
+
joinSubpath: false,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The directories an agent spawned on this project should reach: the cwd first
|
|
335
|
+
* (`resolveDefinedProjectPath`, so cwd behavior is unchanged), then every other
|
|
336
|
+
* bound repo. `forRemote` keeps them `~/…` so the remote shell re-roots them at
|
|
337
|
+
* its own `$HOME`; locally they are absolute and filtered to what exists.
|
|
338
|
+
*
|
|
339
|
+
* Callers pass the resolved primary so a `--project slug@worktree` run grants
|
|
340
|
+
* the sibling repos alongside the worktree it actually landed in.
|
|
341
|
+
*/
|
|
342
|
+
export function projectDirsAbs(def, opts) {
|
|
343
|
+
return projectDirList(def, {
|
|
344
|
+
primary: opts.primary ?? projectBasePath(def, opts.forRemote),
|
|
345
|
+
forRemote: opts.forRemote,
|
|
346
|
+
// A remote spawn must not be filtered by THIS box's filesystem: the target
|
|
347
|
+
// host has its own checkouts, and a dir missing here may well be there.
|
|
348
|
+
keepMissing: opts.forRemote,
|
|
349
|
+
joinSubpath: true,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
275
352
|
function projectRootsAbs(defs) {
|
|
276
353
|
const out = [];
|
|
277
354
|
const push = (name, raw) => {
|
|
@@ -329,7 +406,7 @@ function isUnder(child, parent) {
|
|
|
329
406
|
* with `expandLocalHome` and resolved, so this matches sessions whose cwd shares
|
|
330
407
|
* this machine's home layout. A session recorded on a different-home machine
|
|
331
408
|
* (`/Users/x/…` vs `/home/x/…`) will not match until the fleet-wide,
|
|
332
|
-
* home-relative variant lands (see the deferred item in docs/
|
|
409
|
+
* home-relative variant lands (see the deferred item in docs/projects.md).
|
|
333
410
|
*/
|
|
334
411
|
export function projectNameForCwd(cwd, defs) {
|
|
335
412
|
if (!cwd)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare function setRefreshLockRootForTest(root: string | null): string | null;
|
|
2
|
+
export interface RefreshLeaseOptions<T> {
|
|
3
|
+
scope: string;
|
|
4
|
+
key: string;
|
|
5
|
+
/**
|
|
6
|
+
* Re-read the shared result after taking the lease. If another process
|
|
7
|
+
* refreshed it while this caller waited, return that value instead of
|
|
8
|
+
* repeating the provider request.
|
|
9
|
+
*/
|
|
10
|
+
readCompleted: () => T | null;
|
|
11
|
+
isCompleted: (value: T) => boolean;
|
|
12
|
+
refresh: () => Promise<T>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Serialize refresh work across every agents-cli process on this device.
|
|
16
|
+
*
|
|
17
|
+
* In-process promise maps only protect one Node process. Factory, the daemon,
|
|
18
|
+
* `agents view`, and `agents usage` are separate processes, so they need an
|
|
19
|
+
* OS-visible lease. The result is re-read after lock acquisition: a waiter
|
|
20
|
+
* consumes the winner's publication and never calls the provider a second
|
|
21
|
+
* time. `proper-lockfile` supplies heartbeat + stale-owner recovery while an
|
|
22
|
+
* async provider request is in flight.
|
|
23
|
+
*/
|
|
24
|
+
export declare function withRefreshLease<T>(options: RefreshLeaseOptions<T>): Promise<T>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import lockfile from 'proper-lockfile';
|
|
5
|
+
import { getCacheDir } from './state.js';
|
|
6
|
+
const REFRESH_LOCK_STALE_MS = 2 * 60_000;
|
|
7
|
+
let refreshLockRootOverride = null;
|
|
8
|
+
export function setRefreshLockRootForTest(root) {
|
|
9
|
+
const previous = refreshLockRootOverride;
|
|
10
|
+
refreshLockRootOverride = root;
|
|
11
|
+
return previous;
|
|
12
|
+
}
|
|
13
|
+
function lockTarget(scope, key) {
|
|
14
|
+
const digest = createHash('sha256').update(`${scope}\0${key}`).digest('hex');
|
|
15
|
+
return path.join(refreshLockRootOverride ?? getCacheDir(), 'refresh-locks', scope, `${digest}.lock`);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Serialize refresh work across every agents-cli process on this device.
|
|
19
|
+
*
|
|
20
|
+
* In-process promise maps only protect one Node process. Factory, the daemon,
|
|
21
|
+
* `agents view`, and `agents usage` are separate processes, so they need an
|
|
22
|
+
* OS-visible lease. The result is re-read after lock acquisition: a waiter
|
|
23
|
+
* consumes the winner's publication and never calls the provider a second
|
|
24
|
+
* time. `proper-lockfile` supplies heartbeat + stale-owner recovery while an
|
|
25
|
+
* async provider request is in flight.
|
|
26
|
+
*/
|
|
27
|
+
export async function withRefreshLease(options) {
|
|
28
|
+
const target = lockTarget(options.scope, options.key);
|
|
29
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
30
|
+
try {
|
|
31
|
+
await fs.writeFile(target, '', { flag: 'wx', mode: 0o600 });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error?.code !== 'EEXIST')
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
const release = await lockfile.lock(target, {
|
|
38
|
+
realpath: false,
|
|
39
|
+
stale: REFRESH_LOCK_STALE_MS,
|
|
40
|
+
update: REFRESH_LOCK_STALE_MS / 4,
|
|
41
|
+
retries: { retries: 240, minTimeout: 25, maxTimeout: 500, factor: 1.2 },
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
const completed = options.readCompleted();
|
|
45
|
+
if (completed !== null && options.isCompleted(completed))
|
|
46
|
+
return completed;
|
|
47
|
+
return await options.refresh();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await release();
|
|
51
|
+
}
|
|
52
|
+
}
|
package/dist/lib/registry.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export interface SkillIndexEntry {
|
|
|
56
56
|
tags?: string[];
|
|
57
57
|
author?: string;
|
|
58
58
|
installs?: number;
|
|
59
|
-
/** Lowercase hex sha256 of the skill's SKILL.md
|
|
59
|
+
/** Lowercase hex sha256 of the skill's SKILL.md supplied by the registry index. */
|
|
60
60
|
sha256?: string;
|
|
61
61
|
}
|
|
62
62
|
/** Raw shape of the skill index document served by Hermes and compatible registries. */
|
|
@@ -100,7 +100,7 @@ export declare function parseOwnerRepoFromRemote(remoteUrl: string): string | nu
|
|
|
100
100
|
/**
|
|
101
101
|
* Walk a repo's skills/ and build a flat {@link SkillIndexDocument}. Each entry
|
|
102
102
|
* carries the sha256 of its SKILL.md so install can verify integrity after
|
|
103
|
-
* cloning
|
|
103
|
+
* cloning.
|
|
104
104
|
*
|
|
105
105
|
* `repoSlug` is the 'owner/repo' the skills are published under, written into
|
|
106
106
|
* each entry's `repo` field so {@link skillEntryToGitSource} resolves it to
|
package/dist/lib/registry.js
CHANGED
|
@@ -493,7 +493,7 @@ export function parseOwnerRepoFromRemote(remoteUrl) {
|
|
|
493
493
|
/**
|
|
494
494
|
* Walk a repo's skills/ and build a flat {@link SkillIndexDocument}. Each entry
|
|
495
495
|
* carries the sha256 of its SKILL.md so install can verify integrity after
|
|
496
|
-
* cloning
|
|
496
|
+
* cloning.
|
|
497
497
|
*
|
|
498
498
|
* `repoSlug` is the 'owner/repo' the skills are published under, written into
|
|
499
499
|
* each entry's `repo` field so {@link skillEntryToGitSource} resolves it to
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a resource's frontmatter `aliases:` value into a clean list.
|
|
3
|
+
*
|
|
4
|
+
* A skill (SKILL.md) or command file may declare `aliases:` — alternate names
|
|
5
|
+
* that {@link resolveResource} matches in addition to the canonical file/dir name
|
|
6
|
+
* (the canonical name always wins a collision). The value is a YAML list or a
|
|
7
|
+
* comma/space-separated string, mirroring the command frontmatter `agents:` field.
|
|
8
|
+
*
|
|
9
|
+
* This lives in its own leaf module so `skills.ts` and `commands.ts` (which parse
|
|
10
|
+
* the frontmatter) and `resources.ts` (which resolves by alias) all share one
|
|
11
|
+
* definition without an import cycle.
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeAliases(raw: unknown): string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a resource's frontmatter `aliases:` value into a clean list.
|
|
3
|
+
*
|
|
4
|
+
* A skill (SKILL.md) or command file may declare `aliases:` — alternate names
|
|
5
|
+
* that {@link resolveResource} matches in addition to the canonical file/dir name
|
|
6
|
+
* (the canonical name always wins a collision). The value is a YAML list or a
|
|
7
|
+
* comma/space-separated string, mirroring the command frontmatter `agents:` field.
|
|
8
|
+
*
|
|
9
|
+
* This lives in its own leaf module so `skills.ts` and `commands.ts` (which parse
|
|
10
|
+
* the frontmatter) and `resources.ts` (which resolves by alias) all share one
|
|
11
|
+
* definition without an import cycle.
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeAliases(raw) {
|
|
14
|
+
const tokens = Array.isArray(raw)
|
|
15
|
+
? raw
|
|
16
|
+
: typeof raw === 'string'
|
|
17
|
+
? raw.split(/[,\s]+/)
|
|
18
|
+
: [];
|
|
19
|
+
const out = [];
|
|
20
|
+
for (const token of tokens) {
|
|
21
|
+
const name = String(token).trim();
|
|
22
|
+
if (name && !out.includes(name))
|
|
23
|
+
out.push(name);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
@@ -9,7 +9,7 @@ import type { AgentId } from '../types.js';
|
|
|
9
9
|
export type { AgentId };
|
|
10
10
|
/** Resource origin. Precedence (highest first): project > user > plugin > system. */
|
|
11
11
|
export type Layer = 'system' | 'user' | 'project' | 'plugin';
|
|
12
|
-
export type ResourceKind = 'command' | 'hook' | 'skill' | 'rule' | 'mcp' | 'permission' | 'subagent' | 'workflow' | 'memory';
|
|
12
|
+
export type ResourceKind = 'command' | 'hook' | 'skill' | 'rule' | 'mcp' | 'permission' | 'subagent' | 'workflow' | 'memory' | 'plugin';
|
|
13
13
|
/** A resolved resource with its origin layer. */
|
|
14
14
|
export interface ResolvedItem<T> {
|
|
15
15
|
name: string;
|
package/dist/lib/resources.d.ts
CHANGED
|
@@ -32,7 +32,23 @@ export interface ResolvedResource {
|
|
|
32
32
|
* repo (or has no commits).
|
|
33
33
|
*/
|
|
34
34
|
readonly snapshotSha: string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Alternate names this resource declares in its frontmatter `aliases:`, which
|
|
37
|
+
* {@link resolveResource} matches in addition to the canonical name. Lazily
|
|
38
|
+
* read from disk on first access and memoized, so listing resources never pays
|
|
39
|
+
* for it unless a caller inspects an alias. `undefined` when the resource
|
|
40
|
+
* declares none (or for a kind that doesn't support aliases — only `skills` and
|
|
41
|
+
* `commands` do), mirroring {@link snapshotSha} so a strict `toEqual` on a
|
|
42
|
+
* ResolvedResource ignores the absent field.
|
|
43
|
+
*/
|
|
44
|
+
readonly aliases: string[] | undefined;
|
|
35
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* The declared frontmatter `aliases:` of a single resource, or `[]` for a kind
|
|
48
|
+
* that doesn't support aliases. Only `skills` (SKILL.md) and `commands` carry
|
|
49
|
+
* them today. `resourcePath` is the skill directory or the command file.
|
|
50
|
+
*/
|
|
51
|
+
export declare function resourceAliases(kind: ResourceKind, resourcePath: string): string[];
|
|
36
52
|
/**
|
|
37
53
|
* True when `rawName` (a filename with its extension already stripped) names a
|
|
38
54
|
* directory doc rather than a resource of `kind`. Exported so every enumerator
|
package/dist/lib/resources.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
import { AGENTS, listInstalledMcpsWithScope } from './agents.js';
|
|
8
|
-
import { listInstalledCommandsWithScope } from './commands.js';
|
|
9
|
-
import { listInstalledSkillsWithScope } from './skills.js';
|
|
8
|
+
import { listInstalledCommandsWithScope, parseCommandMetadata } from './commands.js';
|
|
9
|
+
import { listInstalledSkillsWithScope, parseSkillMetadata } from './skills.js';
|
|
10
10
|
import { listOnDiskHooks } from './resource-inventory.js';
|
|
11
11
|
import { listInstalledInstructionsWithScope } from './rules/rules.js';
|
|
12
12
|
import { getEffectiveHome } from './versions.js';
|
|
@@ -16,13 +16,37 @@ import { isCapable } from './capabilities.js';
|
|
|
16
16
|
import { getProjectAgentsDir, getUserAgentsDir, getSystemAgentsDir, getEnabledExtraRepos, } from './state.js';
|
|
17
17
|
import { isNameActiveInResourceProfile } from './resource-profiles.js';
|
|
18
18
|
import { resolveSnapshotSha } from './git.js';
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* The declared frontmatter `aliases:` of a single resource, or `[]` for a kind
|
|
21
|
+
* that doesn't support aliases. Only `skills` (SKILL.md) and `commands` carry
|
|
22
|
+
* them today. `resourcePath` is the skill directory or the command file.
|
|
23
|
+
*/
|
|
24
|
+
export function resourceAliases(kind, resourcePath) {
|
|
25
|
+
if (kind === 'skills')
|
|
26
|
+
return parseSkillMetadata(resourcePath)?.aliases ?? [];
|
|
27
|
+
if (kind === 'commands')
|
|
28
|
+
return parseCommandMetadata(resourcePath)?.aliases ?? [];
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
/** Build a ResolvedResource with lazy, memoized `snapshotSha` and `aliases` getters. */
|
|
32
|
+
function withProvenance(base, kind) {
|
|
33
|
+
let aliasesComputed = false;
|
|
34
|
+
let aliasesCache;
|
|
21
35
|
return {
|
|
22
36
|
...base,
|
|
23
37
|
get snapshotSha() {
|
|
24
38
|
return resolveSnapshotSha(base.repoRoot);
|
|
25
39
|
},
|
|
40
|
+
get aliases() {
|
|
41
|
+
if (!aliasesComputed) {
|
|
42
|
+
const found = resourceAliases(kind, base.path);
|
|
43
|
+
// Undefined (not []) when none, so a strict toEqual on a ResolvedResource
|
|
44
|
+
// ignores it — the same convention snapshotSha uses.
|
|
45
|
+
aliasesCache = found.length > 0 ? found : undefined;
|
|
46
|
+
aliasesComputed = true;
|
|
47
|
+
}
|
|
48
|
+
return aliasesCache;
|
|
49
|
+
},
|
|
26
50
|
};
|
|
27
51
|
}
|
|
28
52
|
function profiledKind(kind) {
|
|
@@ -92,7 +116,7 @@ export function resolveResource(kind, name, cwd) {
|
|
|
92
116
|
const exactPath = path.join(dir, name);
|
|
93
117
|
if (fs.existsSync(exactPath)) {
|
|
94
118
|
if (resourceIsActive(kind, name, source)) {
|
|
95
|
-
return withProvenance({ name, path: exactPath, source, repoRoot });
|
|
119
|
+
return withProvenance({ name, path: exactPath, source, repoRoot }, kind);
|
|
96
120
|
}
|
|
97
121
|
continue;
|
|
98
122
|
}
|
|
@@ -104,12 +128,44 @@ export function resolveResource(kind, name, cwd) {
|
|
|
104
128
|
const withExt = exactPath + ext;
|
|
105
129
|
if (fs.existsSync(withExt)) {
|
|
106
130
|
if (resourceIsActive(kind, name, source)) {
|
|
107
|
-
return withProvenance({ name, path: withExt, source, repoRoot });
|
|
131
|
+
return withProvenance({ name, path: withExt, source, repoRoot }, kind);
|
|
108
132
|
}
|
|
109
133
|
continue;
|
|
110
134
|
}
|
|
111
135
|
}
|
|
112
136
|
}
|
|
137
|
+
// Alias fallback (skills/commands only). A resource may declare `aliases:` in
|
|
138
|
+
// its frontmatter; match `name` against those AFTER every layer's canonical
|
|
139
|
+
// lookup above has missed, so a canonical resource named `name` always wins a
|
|
140
|
+
// collision regardless of layer. Layer precedence still applies among aliases,
|
|
141
|
+
// and entries are sorted so a same-layer alias collision resolves deterministically.
|
|
142
|
+
if (kind === 'skills' || kind === 'commands') {
|
|
143
|
+
for (const [dir, source, repoRoot] of candidates) {
|
|
144
|
+
if (!fs.existsSync(dir))
|
|
145
|
+
continue;
|
|
146
|
+
let entries;
|
|
147
|
+
try {
|
|
148
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
154
|
+
if (entry.name.startsWith('.'))
|
|
155
|
+
continue;
|
|
156
|
+
const rawName = entry.name.replace(/\.(md|yaml|yml)$/, '');
|
|
157
|
+
if (isDirectoryDoc(kind, rawName))
|
|
158
|
+
continue;
|
|
159
|
+
const resourcePath = path.join(dir, entry.name);
|
|
160
|
+
if (!resourceAliases(kind, resourcePath).includes(name))
|
|
161
|
+
continue;
|
|
162
|
+
if (!resourceIsActive(kind, rawName, source))
|
|
163
|
+
continue;
|
|
164
|
+
// Resolve to the canonical resource (its real name), not the alias.
|
|
165
|
+
return withProvenance({ name: rawName, path: resourcePath, source, repoRoot }, kind);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
113
169
|
return null;
|
|
114
170
|
}
|
|
115
171
|
/**
|
|
@@ -190,7 +246,7 @@ export function listResources(kind, cwd) {
|
|
|
190
246
|
path: full,
|
|
191
247
|
source,
|
|
192
248
|
repoRoot,
|
|
193
|
-
}));
|
|
249
|
+
}, kind));
|
|
194
250
|
continue;
|
|
195
251
|
}
|
|
196
252
|
if (!stat.isDirectory() || HOOK_GROUP_SKIP.has(name))
|
|
@@ -231,7 +287,7 @@ export function listResources(kind, cwd) {
|
|
|
231
287
|
path: path.join(full, script),
|
|
232
288
|
source,
|
|
233
289
|
repoRoot,
|
|
234
|
-
}));
|
|
290
|
+
}, kind));
|
|
235
291
|
}
|
|
236
292
|
}
|
|
237
293
|
else {
|
|
@@ -246,7 +302,7 @@ export function listResources(kind, cwd) {
|
|
|
246
302
|
path: full,
|
|
247
303
|
source,
|
|
248
304
|
repoRoot,
|
|
249
|
-
}));
|
|
305
|
+
}, kind));
|
|
250
306
|
}
|
|
251
307
|
}
|
|
252
308
|
}
|
|
@@ -282,7 +338,7 @@ export function listResources(kind, cwd) {
|
|
|
282
338
|
path: path.join(dir, entry.name),
|
|
283
339
|
source,
|
|
284
340
|
repoRoot,
|
|
285
|
-
}));
|
|
341
|
+
}, kind));
|
|
286
342
|
}
|
|
287
343
|
}
|
|
288
344
|
return results;
|
package/dist/lib/rotate.d.ts
CHANGED
|
@@ -106,10 +106,9 @@ export declare function isLaunchableSignedIn(signedIn: boolean, presence: Pick<C
|
|
|
106
106
|
/**
|
|
107
107
|
* How old a usage snapshot may be and still settle a routing DECISION.
|
|
108
108
|
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* whole run. Measured case — `yosemite-s1` held snapshots 26h to 2.7 days old
|
|
109
|
+
* A display may show an older cached bar, but the router choosing an account
|
|
110
|
+
* from one costs the whole run. Measured case: `yosemite-s1` held snapshots 26
|
|
111
|
+
* hours to 2.7 days old
|
|
113
112
|
* with a failing refresh, so balanced read `muqsit@getrush.ai` as 48% used and
|
|
114
113
|
* launched into it while the account was actually at its weekly cap.
|
|
115
114
|
*/
|
package/dist/lib/rotate.js
CHANGED
|
@@ -103,10 +103,9 @@ function isAvailableEligible(candidate) {
|
|
|
103
103
|
/**
|
|
104
104
|
* How old a usage snapshot may be and still settle a routing DECISION.
|
|
105
105
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* whole run. Measured case — `yosemite-s1` held snapshots 26h to 2.7 days old
|
|
106
|
+
* A display may show an older cached bar, but the router choosing an account
|
|
107
|
+
* from one costs the whole run. Measured case: `yosemite-s1` held snapshots 26
|
|
108
|
+
* hours to 2.7 days old
|
|
110
109
|
* with a failing refresh, so balanced read `muqsit@getrush.ai` as 48% used and
|
|
111
110
|
* launched into it while the account was actually at its weekly cap.
|
|
112
111
|
*/
|
|
@@ -588,7 +587,7 @@ export async function collectRunCandidates(agent) {
|
|
|
588
587
|
home,
|
|
589
588
|
cliVersion: version,
|
|
590
589
|
info,
|
|
591
|
-
}))
|
|
590
|
+
})));
|
|
592
591
|
return rows.map(({ home: _home, info, ...candidate }) => {
|
|
593
592
|
const usageKey = getUsageLookupKey(info);
|
|
594
593
|
const usage = usageKey ? usageByKey.get(usageKey) : undefined;
|
|
@@ -3,8 +3,6 @@ export declare function normalizeRoutineNames(names: Iterable<string>): string[]
|
|
|
3
3
|
export declare function enabledRoutineNames(): string[] | null;
|
|
4
4
|
export declare function routineEnabledOnThisDevice(name: string): boolean | null;
|
|
5
5
|
export declare function replaceEnabledRoutines(names: Iterable<string>): string[];
|
|
6
|
-
/** Add newly introduced replacements to an already-materialized device manifest. */
|
|
7
|
-
export declare function addEnabledRoutinesOnUpgrade(names: Iterable<string>): boolean;
|
|
8
6
|
/**
|
|
9
7
|
* Add or remove one routine on this machine. `legacyEnabledNames` seeds the
|
|
10
8
|
* manifest the first time an upgraded host changes activation, preserving every
|
|
@@ -13,4 +11,26 @@ export declare function addEnabledRoutinesOnUpgrade(names: Iterable<string>): bo
|
|
|
13
11
|
export declare function setRoutineEnabledOnThisDevice(name: string, enabled: boolean, legacyEnabledNames?: Iterable<string>): string[];
|
|
14
12
|
/** Read-only fleet view from synced device documents. Never writes a peer file. */
|
|
15
13
|
export declare function devicesWithRoutineEnabled(name: string): string[];
|
|
14
|
+
/** Which devices enable which routines, read in one pass. */
|
|
15
|
+
export interface RoutineDeviceIndex {
|
|
16
|
+
/** Routine name → the devices whose allowlist names it, sorted. */
|
|
17
|
+
byRoutine: Map<string, string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* True when at least one device document declares a `routines:` list. Until
|
|
20
|
+
* then no routine is "dark" — the fleet simply has not materialized its
|
|
21
|
+
* activation state yet, and saying "will not fire" would be wrong.
|
|
22
|
+
*/
|
|
23
|
+
materialized: boolean;
|
|
24
|
+
/** Device files that could not be read, reported instead of thrown. */
|
|
25
|
+
errors: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build the whole fleet's activation map in one pass over `devices/`.
|
|
29
|
+
*
|
|
30
|
+
* `devicesWithRoutineEnabled` answers this for a single routine and throws on a
|
|
31
|
+
* corrupt peer file — the right contract for a command acting on one routine,
|
|
32
|
+
* the wrong one for a listing, where a single unreadable device document would
|
|
33
|
+
* blank out every row (and re-walking `devices/` per routine is quadratic).
|
|
34
|
+
*/
|
|
35
|
+
export declare function routineDeviceIndex(): RoutineDeviceIndex;
|
|
16
36
|
export declare function currentRoutineDevice(): string;
|
|
@@ -26,22 +26,6 @@ export function replaceEnabledRoutines(names) {
|
|
|
26
26
|
updateMeta((meta) => ({ ...meta, deviceRoutines: normalized }));
|
|
27
27
|
return normalized;
|
|
28
28
|
}
|
|
29
|
-
/** Add newly introduced replacements to an already-materialized device manifest. */
|
|
30
|
-
export function addEnabledRoutinesOnUpgrade(names) {
|
|
31
|
-
const additions = normalizeRoutineNames(names);
|
|
32
|
-
let changed = false;
|
|
33
|
-
updateMeta((meta) => {
|
|
34
|
-
if (!Array.isArray(meta.deviceRoutines))
|
|
35
|
-
return meta;
|
|
36
|
-
const current = normalizeRoutineNames(meta.deviceRoutines);
|
|
37
|
-
const next = normalizeRoutineNames([...current, ...additions]);
|
|
38
|
-
if (next.length === current.length && next.every((name, index) => name === current[index]))
|
|
39
|
-
return meta;
|
|
40
|
-
changed = true;
|
|
41
|
-
return { ...meta, deviceRoutines: next };
|
|
42
|
-
});
|
|
43
|
-
return changed;
|
|
44
|
-
}
|
|
45
29
|
/**
|
|
46
30
|
* Add or remove one routine on this machine. `legacyEnabledNames` seeds the
|
|
47
31
|
* manifest the first time an upgraded host changes activation, preserving every
|
|
@@ -89,6 +73,69 @@ export function devicesWithRoutineEnabled(name) {
|
|
|
89
73
|
}
|
|
90
74
|
return devices.sort();
|
|
91
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Build the whole fleet's activation map in one pass over `devices/`.
|
|
78
|
+
*
|
|
79
|
+
* `devicesWithRoutineEnabled` answers this for a single routine and throws on a
|
|
80
|
+
* corrupt peer file — the right contract for a command acting on one routine,
|
|
81
|
+
* the wrong one for a listing, where a single unreadable device document would
|
|
82
|
+
* blank out every row (and re-walking `devices/` per routine is quadratic).
|
|
83
|
+
*/
|
|
84
|
+
export function routineDeviceIndex() {
|
|
85
|
+
const byRoutine = new Map();
|
|
86
|
+
const errors = [];
|
|
87
|
+
let materialized = false;
|
|
88
|
+
const devicesDir = path.join(getUserAgentsDir(), 'devices');
|
|
89
|
+
if (!fs.existsSync(devicesDir))
|
|
90
|
+
return { byRoutine, materialized, errors };
|
|
91
|
+
let entries;
|
|
92
|
+
try {
|
|
93
|
+
entries = fs.readdirSync(devicesDir, { withFileTypes: true });
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
return { byRoutine, materialized, errors: [`${devicesDir}: ${err.message}`] };
|
|
97
|
+
}
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
if (!entry.isDirectory())
|
|
100
|
+
continue;
|
|
101
|
+
const file = path.join(devicesDir, entry.name, 'agents.yaml');
|
|
102
|
+
if (!fs.existsSync(file))
|
|
103
|
+
continue;
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = yaml.parse(fs.readFileSync(file, 'utf-8'));
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
errors.push(`${file}: ${err.message.split('\n')[0]}`);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
113
|
+
errors.push(`${file}: expected a YAML map`);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const routines = parsed.routines;
|
|
117
|
+
if (routines === undefined)
|
|
118
|
+
continue;
|
|
119
|
+
if (!Array.isArray(routines) || routines.some((routine) => typeof routine !== 'string')) {
|
|
120
|
+
errors.push(`${file}: routines must be a string list`);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
materialized = true;
|
|
124
|
+
// Same normalization the writers use (`replaceEnabledRoutines`), so a device
|
|
125
|
+
// that lists a routine twice, or with stray whitespace, cannot make the index
|
|
126
|
+
// disagree with `enabledRoutineNames` about what that device enables.
|
|
127
|
+
for (const name of normalizeRoutineNames(routines)) {
|
|
128
|
+
const devices = byRoutine.get(name);
|
|
129
|
+
if (devices)
|
|
130
|
+
devices.push(entry.name);
|
|
131
|
+
else
|
|
132
|
+
byRoutine.set(name, [entry.name]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
for (const devices of byRoutine.values())
|
|
136
|
+
devices.sort();
|
|
137
|
+
return { byRoutine, materialized, errors };
|
|
138
|
+
}
|
|
92
139
|
export function currentRoutineDevice() {
|
|
93
140
|
return machineId();
|
|
94
141
|
}
|
|
@@ -104,8 +104,15 @@ export interface ResolvedExecutionContext {
|
|
|
104
104
|
export declare function expandTargetHome(home: string, p: string): string;
|
|
105
105
|
/** Rewrite an absolute path under the target home to its portable `~/…` form; pass others through. */
|
|
106
106
|
export declare function toTargetPortable(home: string, abs: string): string;
|
|
107
|
-
/**
|
|
108
|
-
|
|
107
|
+
/**
|
|
108
|
+
* True for a bare relative path (not absolute, not home-anchored) ON THE TARGET.
|
|
109
|
+
*
|
|
110
|
+
* `isAbsolute` is evaluated in the TARGET's own path flavour (see
|
|
111
|
+
* {@link targetPath}), not this process's platform — a Windows-shaped absolute
|
|
112
|
+
* cwd (`C:\Users\x\override`) dispatched from a POSIX daemon must still be
|
|
113
|
+
* recognized as absolute, or it is misread as project-relative.
|
|
114
|
+
*/
|
|
115
|
+
export declare function isBareRelative(home: string, p: string): boolean;
|
|
109
116
|
/**
|
|
110
117
|
* Resolve the working directory a routine's run lands in and verify its
|
|
111
118
|
* structural + filesystem readiness for the given placement. Pure of global
|
|
@@ -70,9 +70,16 @@ export function toTargetPortable(home, abs) {
|
|
|
70
70
|
return '~/' + rel.split(tp.sep).join('/');
|
|
71
71
|
return abs;
|
|
72
72
|
}
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
/**
|
|
74
|
+
* True for a bare relative path (not absolute, not home-anchored) ON THE TARGET.
|
|
75
|
+
*
|
|
76
|
+
* `isAbsolute` is evaluated in the TARGET's own path flavour (see
|
|
77
|
+
* {@link targetPath}), not this process's platform — a Windows-shaped absolute
|
|
78
|
+
* cwd (`C:\Users\x\override`) dispatched from a POSIX daemon must still be
|
|
79
|
+
* recognized as absolute, or it is misread as project-relative.
|
|
80
|
+
*/
|
|
81
|
+
export function isBareRelative(home, p) {
|
|
82
|
+
return !targetPath(home).isAbsolute(p) && !p.startsWith('~') && !p.startsWith('$HOME');
|
|
76
83
|
}
|
|
77
84
|
/**
|
|
78
85
|
* True when `child` is `base` or strictly beneath it (no `..` escape).
|
|
@@ -154,7 +161,7 @@ export function resolveRoutineExecutionContext(input) {
|
|
|
154
161
|
if (cwd === undefined) {
|
|
155
162
|
return finalize(projBase, 'project_path_missing');
|
|
156
163
|
}
|
|
157
|
-
if (isBareRelative(cwd)) {
|
|
164
|
+
if (isBareRelative(targetHome, cwd)) {
|
|
158
165
|
const baseAbs = expandTargetHome(targetHome, projBase);
|
|
159
166
|
// Target-side join: `path.resolve` would use this host's separator and,
|
|
160
167
|
// for a target home this host does not consider absolute, prepend the
|
|
@@ -188,8 +195,16 @@ export function resolveRoutineExecutionContext(input) {
|
|
|
188
195
|
const abs = expandTargetHome(targetHome, cwd);
|
|
189
196
|
return finalize(toTargetPortable(targetHome, abs), 'cwd_missing');
|
|
190
197
|
}
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
// Absolute in EITHER path flavour — a Windows daemon resolving a POSIX
|
|
199
|
+
// target cwd (or the reverse) must not fall through to bare-relative join.
|
|
200
|
+
// Do not `path.resolve` on the local platform: on win32 that rewrites
|
|
201
|
+
// `/home/u/override` to `D:\home\u\override` and falsely flags
|
|
202
|
+
// cwd_not_portable (Windows CI, cross-platform schedule).
|
|
203
|
+
const cwdIsAbsolute = targetPath(targetHome).isAbsolute(cwd) ||
|
|
204
|
+
path.posix.isAbsolute(cwd) ||
|
|
205
|
+
path.win32.isAbsolute(cwd);
|
|
206
|
+
if (cwdIsAbsolute) {
|
|
207
|
+
const resolved = cwd;
|
|
193
208
|
if (isInside(targetHome, resolved)) {
|
|
194
209
|
// Normalize an absolute-under-home path to its portable form on save.
|
|
195
210
|
return finalize(toTargetPortable(targetHome, resolved), 'cwd_missing');
|