@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
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project
|
|
2
|
+
* Project routine discovery, source tracking, and user-layer sync.
|
|
3
3
|
*
|
|
4
|
-
* Project YAML under `<project>/.agents/routines/*.yml`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Project YAML under `<project>/.agents/routines/*.yml` never fires on its own
|
|
5
|
+
* (a cloned repo must not auto-run agent prompts). A routine has exactly one
|
|
6
|
+
* state — enabled or disabled — owned by this device's `meta.deviceRoutines`
|
|
7
|
+
* list, never by the project YAML's own `enabled:` field. `agents routines
|
|
8
|
+
* enable <name>` materialises the routine into `~/.agents/routines/` with
|
|
9
|
+
* `source:` provenance (so the daemon, which loads only user + system layers,
|
|
10
|
+
* can see it) and flips the device flag on — one action. `discoverProjectRoutines`
|
|
11
|
+
* surfaces not-yet-materialised routines from the user's registered projects so
|
|
12
|
+
* `list` shows them as disabled. `syncProjectRoutines` refreshes materialised
|
|
13
|
+
* copies from their source YAML (also invoked on daemon SIGHUP).
|
|
10
14
|
*/
|
|
11
|
-
import { type JobSource } from './routines.js';
|
|
15
|
+
import { type JobConfig, type JobSource } from './routines.js';
|
|
12
16
|
/** Expand `~/…` and resolve to an absolute path. */
|
|
13
17
|
export declare function expandProjectPath(p: string): string;
|
|
14
18
|
/** Store paths home-relative when under $HOME so they travel across machines. */
|
|
15
19
|
export declare function displayProjectPath(abs: string): string;
|
|
16
|
-
/** Project roots currently opted into daemon firing (absolute paths). */
|
|
17
|
-
export declare function listEnabledProjectRoots(): string[];
|
|
18
|
-
/** True when this project root is on the opt-in allowlist. */
|
|
19
|
-
export declare function isProjectRoutinesEnabled(projectRoot: string): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* True when the project's own `agents.yaml` opts into project routines:
|
|
22
|
-
* `routines: { enable: true }`. This is an additional source of opt-in that
|
|
23
|
-
* still requires the project to be present on disk; it does not auto-enable
|
|
24
|
-
* every clone — the project must declare it, and `sync` / `enable-project`
|
|
25
|
-
* still materialises consent into the user layer.
|
|
26
|
-
*/
|
|
27
|
-
export declare function projectAgentsYamlEnablesRoutines(projectRoot: string): boolean;
|
|
28
20
|
/** Resolve the project root (parent of `.agents/`) from a cwd, or null. */
|
|
29
21
|
export declare function resolveProjectRoot(cwd?: string): string | null;
|
|
30
|
-
/**
|
|
31
|
-
* Opt a project root into daemon firing. Returns true when newly added,
|
|
32
|
-
* false when it was already enabled.
|
|
33
|
-
*/
|
|
34
|
-
export declare function enableProjectRoutines(projectRoot: string): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Remove a project root from the opt-in allowlist. Optionally deletes the
|
|
37
|
-
* user-layer copies that were materialised from it.
|
|
38
|
-
*/
|
|
39
|
-
export declare function disableProjectRoutines(projectRoot: string, opts?: {
|
|
40
|
-
removeSynced?: boolean;
|
|
41
|
-
}): {
|
|
42
|
-
removed: boolean;
|
|
43
|
-
deletedJobs: string[];
|
|
44
|
-
};
|
|
45
22
|
/** Git provenance for a project root (best-effort; never throws). */
|
|
46
23
|
export declare function readProjectGitSource(projectRoot: string): Pick<JobSource, 'repo' | 'branch' | 'commit'>;
|
|
47
24
|
/** List project routine YAML files (name + absolute path). */
|
|
@@ -63,11 +40,15 @@ export interface SyncProjectResult {
|
|
|
63
40
|
}>;
|
|
64
41
|
}
|
|
65
42
|
/**
|
|
66
|
-
*
|
|
43
|
+
* Refresh one project's already-materialised routines from its source YAML.
|
|
67
44
|
* - Overwrites user copies that already carry matching `source.projectPath`
|
|
68
45
|
* - Never clobbers a hand-authored user routine (no source / different source)
|
|
69
46
|
* - Removes user copies from this project whose YAML disappeared
|
|
70
|
-
*
|
|
47
|
+
*
|
|
48
|
+
* Sync NEVER touches the device enable flag: a routine's enabled/disabled state
|
|
49
|
+
* is owned solely by `meta.deviceRoutines` (via `agents routines enable/disable`),
|
|
50
|
+
* never by the project YAML's own `enabled:` field. That is what keeps a cloned
|
|
51
|
+
* repo from auto-firing — refreshing a definition can never turn it on.
|
|
71
52
|
*/
|
|
72
53
|
export declare function syncProjectRoutines(projectRoot: string): SyncProjectResult;
|
|
73
54
|
export interface SyncAllResult {
|
|
@@ -75,23 +56,52 @@ export interface SyncAllResult {
|
|
|
75
56
|
/** Project roots that were listed but missing on disk. */
|
|
76
57
|
missing: string[];
|
|
77
58
|
}
|
|
59
|
+
/** Distinct project roots that already have at least one materialised routine. */
|
|
60
|
+
export declare function materialisedProjectRoots(): string[];
|
|
78
61
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
62
|
+
* Refresh every materialised project routine from its source YAML. The set of
|
|
63
|
+
* roots is derived from what the user has already enabled/materialised (their
|
|
64
|
+
* `source.projectPath`), not from any allowlist — enabling a routine is the only
|
|
65
|
+
* thing that brings its project into the refresh set. Also runs on daemon SIGHUP.
|
|
82
66
|
*/
|
|
83
67
|
export declare function syncAllProjectRoutines(opts?: {
|
|
84
68
|
extraRoots?: string[];
|
|
85
69
|
}): SyncAllResult;
|
|
70
|
+
/** A project routine available to enable, not yet materialised on this device. */
|
|
71
|
+
export interface DiscoveredProjectRoutine {
|
|
72
|
+
name: string;
|
|
73
|
+
projectRoot: string;
|
|
74
|
+
file: string;
|
|
75
|
+
/** Display config for `list` (always disabled — enablement is a local act). */
|
|
76
|
+
config: JobConfig;
|
|
77
|
+
}
|
|
86
78
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
79
|
+
* Project routines from registered projects that are NOT already materialised
|
|
80
|
+
* in the user layer. These surface in `agents routines list` as disabled rows so
|
|
81
|
+
* the single enabled/disabled model is visible, and `enable <name>` resolves a
|
|
82
|
+
* name against them. A routine whose name already exists as a user/system
|
|
83
|
+
* routine is omitted (that materialised copy is the live one).
|
|
89
84
|
*/
|
|
90
|
-
export declare function
|
|
85
|
+
export declare function discoverProjectRoutines(): DiscoveredProjectRoutine[];
|
|
86
|
+
/**
|
|
87
|
+
* Resolve a routine name to a project source for `enable <name>`: first the cwd
|
|
88
|
+
* project, then registered projects. Returns null when the name matches no
|
|
89
|
+
* project routine, or throws-by-return when it is ambiguous across projects.
|
|
90
|
+
*/
|
|
91
|
+
export declare function findProjectRoutine(name: string, cwd?: string): {
|
|
91
92
|
projectRoot: string;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}>;
|
|
96
|
-
enabled: boolean;
|
|
93
|
+
file: string;
|
|
94
|
+
} | {
|
|
95
|
+
ambiguous: string[];
|
|
97
96
|
} | null;
|
|
97
|
+
/**
|
|
98
|
+
* Materialise one project routine into the user layer WITHOUT enabling it. The
|
|
99
|
+
* caller (`agents routines enable`) flips the device flag separately, so a
|
|
100
|
+
* materialise can never by itself make a routine fire. Returns the written
|
|
101
|
+
* config, or an error string.
|
|
102
|
+
*/
|
|
103
|
+
export declare function materialiseProjectRoutine(projectRoot: string, name: string): {
|
|
104
|
+
job: JobConfig;
|
|
105
|
+
} | {
|
|
106
|
+
error: string;
|
|
107
|
+
};
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project
|
|
2
|
+
* Project routine discovery, source tracking, and user-layer sync.
|
|
3
3
|
*
|
|
4
|
-
* Project YAML under `<project>/.agents/routines/*.yml`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Project YAML under `<project>/.agents/routines/*.yml` never fires on its own
|
|
5
|
+
* (a cloned repo must not auto-run agent prompts). A routine has exactly one
|
|
6
|
+
* state — enabled or disabled — owned by this device's `meta.deviceRoutines`
|
|
7
|
+
* list, never by the project YAML's own `enabled:` field. `agents routines
|
|
8
|
+
* enable <name>` materialises the routine into `~/.agents/routines/` with
|
|
9
|
+
* `source:` provenance (so the daemon, which loads only user + system layers,
|
|
10
|
+
* can see it) and flips the device flag on — one action. `discoverProjectRoutines`
|
|
11
|
+
* surfaces not-yet-materialised routines from the user's registered projects so
|
|
12
|
+
* `list` shows them as disabled. `syncProjectRoutines` refreshes materialised
|
|
13
|
+
* copies from their source YAML (also invoked on daemon SIGHUP).
|
|
10
14
|
*/
|
|
11
15
|
import * as fs from 'fs';
|
|
12
16
|
import * as os from 'os';
|
|
13
17
|
import * as path from 'path';
|
|
14
18
|
import * as yaml from 'yaml';
|
|
15
19
|
import { execFileSync } from 'child_process';
|
|
16
|
-
import { getProjectAgentsDir, getProjectRoutinesDir,
|
|
17
|
-
import { readJob, writeJob,
|
|
20
|
+
import { getProjectAgentsDir, getProjectRoutinesDir, ensureAgentsDir, } from './state.js';
|
|
21
|
+
import { readJob, writeJob, deleteJob, listJobs, validateJob, } from './routines.js';
|
|
18
22
|
import { parseOwnerRepoFromRemote } from './registry.js';
|
|
23
|
+
import { listProjectDefs, projectDirsAbs } from './projects.js';
|
|
19
24
|
import { isSafeSegmentName } from './paths.js';
|
|
20
25
|
/** Expand `~/…` and resolve to an absolute path. */
|
|
21
26
|
export function expandProjectPath(p) {
|
|
@@ -36,52 +41,6 @@ export function displayProjectPath(abs) {
|
|
|
36
41
|
}
|
|
37
42
|
return resolved;
|
|
38
43
|
}
|
|
39
|
-
/** Project roots currently opted into daemon firing (absolute paths). */
|
|
40
|
-
export function listEnabledProjectRoots() {
|
|
41
|
-
const meta = readMeta();
|
|
42
|
-
const raw = meta.routines?.projects ?? [];
|
|
43
|
-
const out = [];
|
|
44
|
-
const seen = new Set();
|
|
45
|
-
for (const p of raw) {
|
|
46
|
-
if (typeof p !== 'string' || p.trim() === '')
|
|
47
|
-
continue;
|
|
48
|
-
const abs = expandProjectPath(p);
|
|
49
|
-
if (seen.has(abs))
|
|
50
|
-
continue;
|
|
51
|
-
seen.add(abs);
|
|
52
|
-
out.push(abs);
|
|
53
|
-
}
|
|
54
|
-
return out;
|
|
55
|
-
}
|
|
56
|
-
/** True when this project root is on the opt-in allowlist. */
|
|
57
|
-
export function isProjectRoutinesEnabled(projectRoot) {
|
|
58
|
-
const abs = expandProjectPath(projectRoot);
|
|
59
|
-
return listEnabledProjectRoots().some((p) => p === abs);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* True when the project's own `agents.yaml` opts into project routines:
|
|
63
|
-
* `routines: { enable: true }`. This is an additional source of opt-in that
|
|
64
|
-
* still requires the project to be present on disk; it does not auto-enable
|
|
65
|
-
* every clone — the project must declare it, and `sync` / `enable-project`
|
|
66
|
-
* still materialises consent into the user layer.
|
|
67
|
-
*/
|
|
68
|
-
export function projectAgentsYamlEnablesRoutines(projectRoot) {
|
|
69
|
-
const agentsYaml = path.join(expandProjectPath(projectRoot), 'agents.yaml');
|
|
70
|
-
if (!fs.existsSync(agentsYaml))
|
|
71
|
-
return false;
|
|
72
|
-
try {
|
|
73
|
-
const parsed = yaml.parse(fs.readFileSync(agentsYaml, 'utf-8'));
|
|
74
|
-
if (!parsed || typeof parsed !== 'object')
|
|
75
|
-
return false;
|
|
76
|
-
const routines = parsed.routines;
|
|
77
|
-
if (!routines || typeof routines !== 'object')
|
|
78
|
-
return false;
|
|
79
|
-
return routines.enable === true;
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
44
|
/** Resolve the project root (parent of `.agents/`) from a cwd, or null. */
|
|
86
45
|
export function resolveProjectRoot(cwd = process.cwd()) {
|
|
87
46
|
const agentsDir = getProjectAgentsDir(cwd);
|
|
@@ -89,63 +48,6 @@ export function resolveProjectRoot(cwd = process.cwd()) {
|
|
|
89
48
|
return null;
|
|
90
49
|
return path.dirname(agentsDir);
|
|
91
50
|
}
|
|
92
|
-
/**
|
|
93
|
-
* Opt a project root into daemon firing. Returns true when newly added,
|
|
94
|
-
* false when it was already enabled.
|
|
95
|
-
*/
|
|
96
|
-
export function enableProjectRoutines(projectRoot) {
|
|
97
|
-
const abs = expandProjectPath(projectRoot);
|
|
98
|
-
const stored = displayProjectPath(abs);
|
|
99
|
-
let added = false;
|
|
100
|
-
updateMeta((meta) => {
|
|
101
|
-
const projects = [...(meta.routines?.projects ?? [])];
|
|
102
|
-
const already = projects.some((p) => expandProjectPath(p) === abs);
|
|
103
|
-
if (already)
|
|
104
|
-
return meta;
|
|
105
|
-
projects.push(stored);
|
|
106
|
-
added = true;
|
|
107
|
-
return {
|
|
108
|
-
...meta,
|
|
109
|
-
routines: {
|
|
110
|
-
...(meta.routines ?? {}),
|
|
111
|
-
projects,
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
});
|
|
115
|
-
return added;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Remove a project root from the opt-in allowlist. Optionally deletes the
|
|
119
|
-
* user-layer copies that were materialised from it.
|
|
120
|
-
*/
|
|
121
|
-
export function disableProjectRoutines(projectRoot, opts = {}) {
|
|
122
|
-
const abs = expandProjectPath(projectRoot);
|
|
123
|
-
let removed = false;
|
|
124
|
-
updateMeta((meta) => {
|
|
125
|
-
const projects = meta.routines?.projects ?? [];
|
|
126
|
-
const next = projects.filter((p) => expandProjectPath(p) !== abs);
|
|
127
|
-
if (next.length === projects.length)
|
|
128
|
-
return meta;
|
|
129
|
-
removed = true;
|
|
130
|
-
return {
|
|
131
|
-
...meta,
|
|
132
|
-
routines: {
|
|
133
|
-
...(meta.routines ?? {}),
|
|
134
|
-
projects: next,
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
});
|
|
138
|
-
const deletedJobs = [];
|
|
139
|
-
if (opts.removeSynced) {
|
|
140
|
-
for (const job of listJobs()) {
|
|
141
|
-
if (job.source?.kind === 'project' && expandProjectPath(job.source.projectPath) === abs) {
|
|
142
|
-
if (deleteJob(job.name))
|
|
143
|
-
deletedJobs.push(job.name);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return { removed, deletedJobs };
|
|
148
|
-
}
|
|
149
51
|
/** Git provenance for a project root (best-effort; never throws). */
|
|
150
52
|
export function readProjectGitSource(projectRoot) {
|
|
151
53
|
const abs = expandProjectPath(projectRoot);
|
|
@@ -216,11 +118,15 @@ function readProjectJobFile(filePath) {
|
|
|
216
118
|
}
|
|
217
119
|
}
|
|
218
120
|
/**
|
|
219
|
-
*
|
|
121
|
+
* Refresh one project's already-materialised routines from its source YAML.
|
|
220
122
|
* - Overwrites user copies that already carry matching `source.projectPath`
|
|
221
123
|
* - Never clobbers a hand-authored user routine (no source / different source)
|
|
222
124
|
* - Removes user copies from this project whose YAML disappeared
|
|
223
|
-
*
|
|
125
|
+
*
|
|
126
|
+
* Sync NEVER touches the device enable flag: a routine's enabled/disabled state
|
|
127
|
+
* is owned solely by `meta.deviceRoutines` (via `agents routines enable/disable`),
|
|
128
|
+
* never by the project YAML's own `enabled:` field. That is what keeps a cloned
|
|
129
|
+
* repo from auto-firing — refreshing a definition can never turn it on.
|
|
224
130
|
*/
|
|
225
131
|
export function syncProjectRoutines(projectRoot) {
|
|
226
132
|
ensureAgentsDir();
|
|
@@ -244,37 +150,41 @@ export function syncProjectRoutines(projectRoot) {
|
|
|
244
150
|
const seenNames = new Set();
|
|
245
151
|
for (const file of files) {
|
|
246
152
|
seenNames.add(file.name);
|
|
153
|
+
// Refresh only routines the user already materialised from THIS project.
|
|
154
|
+
// A project file with no existing user-layer copy is "available, not
|
|
155
|
+
// enabled" — it surfaces via `discoverProjectRoutines` and is materialised
|
|
156
|
+
// by `agents routines enable <name>`, never auto-pulled by a refresh.
|
|
157
|
+
const existing = readJob(file.name);
|
|
158
|
+
if (!existing)
|
|
159
|
+
continue;
|
|
160
|
+
const existingSource = existing.source;
|
|
161
|
+
const fromThisProject = existingSource?.kind === 'project'
|
|
162
|
+
&& expandProjectPath(existingSource.projectPath) === abs;
|
|
163
|
+
if (!fromThisProject) {
|
|
164
|
+
result.skipped.push({
|
|
165
|
+
name: file.name,
|
|
166
|
+
reason: existingSource
|
|
167
|
+
? `user-layer routine already exists from another source (${existingSource.projectPath})`
|
|
168
|
+
: 'user-layer routine already exists (hand-authored); not overwriting without source match',
|
|
169
|
+
});
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
247
172
|
const job = readProjectJobFile(file.path);
|
|
248
173
|
if (!job) {
|
|
249
174
|
result.errors.push({ name: file.name, error: 'unreadable or invalid YAML' });
|
|
250
175
|
continue;
|
|
251
176
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
&& expandProjectPath(existingSource.projectPath) === abs;
|
|
257
|
-
if (!fromThisProject) {
|
|
258
|
-
result.skipped.push({
|
|
259
|
-
name: file.name,
|
|
260
|
-
reason: existingSource
|
|
261
|
-
? `user-layer routine already exists from another source (${existingSource.projectPath})`
|
|
262
|
-
: 'user-layer routine already exists (hand-authored); not overwriting without source match',
|
|
263
|
-
});
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
// Preserve user-layer devices pin when project YAML omits it (same overlay
|
|
267
|
-
// semantics as listJobs project discovery).
|
|
268
|
-
if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
|
|
269
|
-
job.devices = existing.devices;
|
|
270
|
-
}
|
|
271
|
-
// Carry the original creation stamp across. A sync rebuilds the config
|
|
272
|
-
// from the PROJECT yaml, which never carries `createdAt`, so without this
|
|
273
|
-
// every `agents routines sync` would re-stamp it to now — walking the
|
|
274
|
-
// overdue floor forward and hiding real missed fires for project routines.
|
|
275
|
-
if (existing.createdAt)
|
|
276
|
-
job.createdAt = existing.createdAt;
|
|
177
|
+
// Preserve user-layer devices pin when project YAML omits it (same overlay
|
|
178
|
+
// semantics as listJobs project discovery).
|
|
179
|
+
if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
|
|
180
|
+
job.devices = existing.devices;
|
|
277
181
|
}
|
|
182
|
+
// Carry the original creation stamp across. A sync rebuilds the config
|
|
183
|
+
// from the PROJECT yaml, which never carries `createdAt`, so without this
|
|
184
|
+
// every `agents routines sync` would re-stamp it to now — walking the
|
|
185
|
+
// overdue floor forward and hiding real missed fires for project routines.
|
|
186
|
+
if (existing.createdAt)
|
|
187
|
+
job.createdAt = existing.createdAt;
|
|
278
188
|
// Surface repo for list/display when project has a GitHub origin.
|
|
279
189
|
if (git.repo && !job.repo)
|
|
280
190
|
job.repo = git.repo;
|
|
@@ -286,8 +196,9 @@ export function syncProjectRoutines(projectRoot) {
|
|
|
286
196
|
continue;
|
|
287
197
|
}
|
|
288
198
|
try {
|
|
199
|
+
// Refresh the definition only. Enablement lives in meta.deviceRoutines and
|
|
200
|
+
// is never derived from the project YAML here.
|
|
289
201
|
writeJob(job);
|
|
290
|
-
setJobEnabled(job.name, job.enabled);
|
|
291
202
|
result.synced.push(file.name);
|
|
292
203
|
}
|
|
293
204
|
catch (err) {
|
|
@@ -307,13 +218,23 @@ export function syncProjectRoutines(projectRoot) {
|
|
|
307
218
|
}
|
|
308
219
|
return result;
|
|
309
220
|
}
|
|
221
|
+
/** Distinct project roots that already have at least one materialised routine. */
|
|
222
|
+
export function materialisedProjectRoots() {
|
|
223
|
+
const roots = new Set();
|
|
224
|
+
for (const job of listJobs()) {
|
|
225
|
+
if (job.source?.kind === 'project')
|
|
226
|
+
roots.add(expandProjectPath(job.source.projectPath));
|
|
227
|
+
}
|
|
228
|
+
return [...roots];
|
|
229
|
+
}
|
|
310
230
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
231
|
+
* Refresh every materialised project routine from its source YAML. The set of
|
|
232
|
+
* roots is derived from what the user has already enabled/materialised (their
|
|
233
|
+
* `source.projectPath`), not from any allowlist — enabling a routine is the only
|
|
234
|
+
* thing that brings its project into the refresh set. Also runs on daemon SIGHUP.
|
|
314
235
|
*/
|
|
315
236
|
export function syncAllProjectRoutines(opts = {}) {
|
|
316
|
-
const roots = new Set(
|
|
237
|
+
const roots = new Set(materialisedProjectRoots());
|
|
317
238
|
for (const r of opts.extraRoots ?? [])
|
|
318
239
|
roots.add(expandProjectPath(r));
|
|
319
240
|
const projects = [];
|
|
@@ -328,22 +249,132 @@ export function syncAllProjectRoutines(opts = {}) {
|
|
|
328
249
|
return { projects, missing };
|
|
329
250
|
}
|
|
330
251
|
/**
|
|
331
|
-
*
|
|
332
|
-
* project
|
|
252
|
+
* Absolute local checkout roots for every registered project, deduped. This is
|
|
253
|
+
* the discovery universe for project routines: bounded to projects the user
|
|
254
|
+
* registered (`agents projects`), never an arbitrary filesystem scan.
|
|
333
255
|
*/
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
256
|
+
function registeredProjectRoots() {
|
|
257
|
+
const roots = new Set();
|
|
258
|
+
for (const def of listProjectDefs()) {
|
|
259
|
+
for (const dir of projectDirsAbs(def, { forRemote: false })) {
|
|
260
|
+
if (dir)
|
|
261
|
+
roots.add(path.resolve(dir));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return [...roots];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Project routines from registered projects that are NOT already materialised
|
|
268
|
+
* in the user layer. These surface in `agents routines list` as disabled rows so
|
|
269
|
+
* the single enabled/disabled model is visible, and `enable <name>` resolves a
|
|
270
|
+
* name against them. A routine whose name already exists as a user/system
|
|
271
|
+
* routine is omitted (that materialised copy is the live one).
|
|
272
|
+
*/
|
|
273
|
+
export function discoverProjectRoutines() {
|
|
274
|
+
const materialisedNames = new Set(listJobs().map((j) => j.name));
|
|
275
|
+
const out = [];
|
|
276
|
+
const seen = new Set();
|
|
277
|
+
for (const root of registeredProjectRoots()) {
|
|
278
|
+
const files = listProjectRoutineFiles(root).filter((f) => !materialisedNames.has(f.name) && !seen.has(f.name));
|
|
279
|
+
if (files.length === 0)
|
|
280
|
+
continue;
|
|
281
|
+
const git = readProjectGitSource(root); // once per root, not per routine
|
|
282
|
+
for (const file of files) {
|
|
283
|
+
const job = readProjectJobFile(file.path);
|
|
284
|
+
if (!job)
|
|
285
|
+
continue;
|
|
286
|
+
seen.add(file.name);
|
|
287
|
+
job.name = file.name;
|
|
288
|
+
job.source = {
|
|
289
|
+
kind: 'project',
|
|
290
|
+
projectPath: expandProjectPath(root),
|
|
291
|
+
...(git.repo ? { repo: git.repo } : {}),
|
|
292
|
+
...(git.branch ? { branch: git.branch } : {}),
|
|
293
|
+
...(git.commit ? { commit: git.commit } : {}),
|
|
294
|
+
};
|
|
295
|
+
if (git.repo && !job.repo)
|
|
296
|
+
job.repo = git.repo;
|
|
297
|
+
job.enabled = false; // available, not enabled — never inferred from the repo YAML
|
|
298
|
+
out.push({ name: file.name, projectRoot: expandProjectPath(root), file: file.path, config: job });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return out;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Resolve a routine name to a project source for `enable <name>`: first the cwd
|
|
305
|
+
* project, then registered projects. Returns null when the name matches no
|
|
306
|
+
* project routine, or throws-by-return when it is ambiguous across projects.
|
|
307
|
+
*/
|
|
308
|
+
export function findProjectRoutine(name, cwd = process.cwd()) {
|
|
309
|
+
const cwdRoot = resolveProjectRoot(cwd);
|
|
310
|
+
if (cwdRoot) {
|
|
311
|
+
const match = listProjectRoutineFiles(cwdRoot).find((f) => f.name === name);
|
|
312
|
+
if (match)
|
|
313
|
+
return { projectRoot: expandProjectPath(cwdRoot), file: match.path };
|
|
314
|
+
}
|
|
315
|
+
const hits = [];
|
|
316
|
+
const seenRoots = new Set();
|
|
317
|
+
for (const root of registeredProjectRoots()) {
|
|
318
|
+
const abs = expandProjectPath(root);
|
|
319
|
+
if (seenRoots.has(abs))
|
|
320
|
+
continue;
|
|
321
|
+
seenRoots.add(abs);
|
|
322
|
+
const match = listProjectRoutineFiles(abs).find((f) => f.name === name);
|
|
323
|
+
if (match)
|
|
324
|
+
hits.push({ projectRoot: abs, file: match.path });
|
|
325
|
+
}
|
|
326
|
+
if (hits.length === 0)
|
|
343
327
|
return null;
|
|
344
|
-
|
|
345
|
-
projectRoot
|
|
346
|
-
|
|
347
|
-
|
|
328
|
+
if (hits.length > 1)
|
|
329
|
+
return { ambiguous: hits.map((h) => displayProjectPath(h.projectRoot)) };
|
|
330
|
+
return hits[0];
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Materialise one project routine into the user layer WITHOUT enabling it. The
|
|
334
|
+
* caller (`agents routines enable`) flips the device flag separately, so a
|
|
335
|
+
* materialise can never by itself make a routine fire. Returns the written
|
|
336
|
+
* config, or an error string.
|
|
337
|
+
*/
|
|
338
|
+
export function materialiseProjectRoutine(projectRoot, name) {
|
|
339
|
+
ensureAgentsDir();
|
|
340
|
+
const abs = expandProjectPath(projectRoot);
|
|
341
|
+
const match = listProjectRoutineFiles(abs).find((f) => f.name === name);
|
|
342
|
+
if (!match)
|
|
343
|
+
return { error: `no routine '${name}' under ${displayProjectPath(abs)}/.agents/routines` };
|
|
344
|
+
const job = readProjectJobFile(match.path);
|
|
345
|
+
if (!job)
|
|
346
|
+
return { error: `routine '${name}' is unreadable or invalid YAML` };
|
|
347
|
+
const existing = readJob(name);
|
|
348
|
+
if (existing) {
|
|
349
|
+
const src = existing.source;
|
|
350
|
+
const fromThisProject = src?.kind === 'project' && expandProjectPath(src.projectPath) === abs;
|
|
351
|
+
if (!fromThisProject) {
|
|
352
|
+
return {
|
|
353
|
+
error: src
|
|
354
|
+
? `a routine named '${name}' already exists from another source (${src.projectPath})`
|
|
355
|
+
: `a hand-authored routine named '${name}' already exists; rename one before enabling`,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (existing.createdAt)
|
|
359
|
+
job.createdAt = existing.createdAt;
|
|
360
|
+
if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
|
|
361
|
+
job.devices = existing.devices;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const git = readProjectGitSource(abs);
|
|
365
|
+
job.name = name;
|
|
366
|
+
job.source = {
|
|
367
|
+
kind: 'project',
|
|
368
|
+
projectPath: abs,
|
|
369
|
+
...(git.repo ? { repo: git.repo } : {}),
|
|
370
|
+
...(git.branch ? { branch: git.branch } : {}),
|
|
371
|
+
...(git.commit ? { commit: git.commit } : {}),
|
|
348
372
|
};
|
|
373
|
+
if (git.repo && !job.repo)
|
|
374
|
+
job.repo = git.repo;
|
|
375
|
+
const errors = validateJob(job);
|
|
376
|
+
if (errors.length > 0)
|
|
377
|
+
return { error: errors.join('; ') };
|
|
378
|
+
writeJob(job);
|
|
379
|
+
return { job };
|
|
349
380
|
}
|
package/dist/lib/routines.d.ts
CHANGED
|
@@ -543,15 +543,14 @@ export declare function checkJobDeviceEligibility(config: Pick<JobConfig, 'name'
|
|
|
543
543
|
/**
|
|
544
544
|
* List all job configs, scanning project > user > system routine dirs.
|
|
545
545
|
* Higher layers shadow lower ones of the same name (first-seen wins): a project
|
|
546
|
-
* routine shadows a user routine, and a user routine shadows a
|
|
547
|
-
*
|
|
546
|
+
* routine shadows a user routine, and a user routine shadows a system routine
|
|
547
|
+
* (`~/.agents/.system/routines/`, shipped via gh:phnx-labs/.agents-system).
|
|
548
548
|
* When a same-name project routine wins for inspection, the user-layer
|
|
549
549
|
* `devices` allowlist is overlaid only if the project routine does not declare
|
|
550
550
|
* its own allowlist, so CWD project discovery cannot hide an operational fleet
|
|
551
551
|
* pin or erase a project-authored one.
|
|
552
552
|
* Project discovery is opt-in via `cwd`; the daemon (which calls `listJobs()`
|
|
553
|
-
* with no argument) sees user + system routines
|
|
554
|
-
* every install unless the user overrides or disables it by name.
|
|
553
|
+
* with no argument) sees user + system routines.
|
|
555
554
|
*/
|
|
556
555
|
export declare function listJobs(cwd?: string): JobConfig[];
|
|
557
556
|
/**
|
|
@@ -560,10 +559,29 @@ export declare function listJobs(cwd?: string): JobConfig[];
|
|
|
560
559
|
* the project routine does not declare its own allowlist, for the same reason
|
|
561
560
|
* as listJobs().
|
|
562
561
|
* Project discovery is opt-in via `cwd`; daemon callers pass no argument and
|
|
563
|
-
* resolve user + system routines
|
|
564
|
-
* built-in system routine).
|
|
562
|
+
* resolve user + system routines.
|
|
565
563
|
*/
|
|
566
564
|
export declare function readJob(name: string, cwd?: string): JobConfig | null;
|
|
565
|
+
/**
|
|
566
|
+
* The outcome of reading one routine file: a config, or the reason it is inert.
|
|
567
|
+
* Every `problem` here means the daemon will not run the routine.
|
|
568
|
+
*/
|
|
569
|
+
export type RoutineReadResult = {
|
|
570
|
+
config: JobConfig;
|
|
571
|
+
problem: null;
|
|
572
|
+
} | {
|
|
573
|
+
config: null;
|
|
574
|
+
problem: string;
|
|
575
|
+
};
|
|
576
|
+
/**
|
|
577
|
+
* Read one routine file, preserving WHY it failed.
|
|
578
|
+
*
|
|
579
|
+
* `readJobFile` collapses all four fail-closed paths to `null`, which is right
|
|
580
|
+
* for the loaders (an inert routine must not run) but leaves a broken routine
|
|
581
|
+
* invisible in every view — the one routine an operator most needs to see. Same
|
|
582
|
+
* reading, reason kept, for diagnostic surfaces like `agents inspect --routines`.
|
|
583
|
+
*/
|
|
584
|
+
export declare function readJobFileResult(filePath: string): RoutineReadResult;
|
|
567
585
|
/** Write a job config to disk, omitting fields that match defaults.
|
|
568
586
|
*
|
|
569
587
|
* Updates the one existing supported extension (.yml or .yaml) atomically.
|
|
@@ -732,6 +750,23 @@ export declare function discoverJobsFromRepo(repoPath: string): Array<{
|
|
|
732
750
|
}>;
|
|
733
751
|
/** Check whether a job with the given name exists on disk. */
|
|
734
752
|
export declare function jobExists(name: string): boolean;
|
|
753
|
+
/**
|
|
754
|
+
* True when `sourcePath` already IS the canonical user-layer file for `name`.
|
|
755
|
+
*
|
|
756
|
+
* `agents routines add <file>` copies a definition into the routines dir, but
|
|
757
|
+
* users routinely point it at the file that already lives there — the release
|
|
758
|
+
* train's own `~/.agents/routines/release-train.yml`. `writeJob` would then
|
|
759
|
+
* re-serialize that file in place and, per {@link serializeJob}, delete every
|
|
760
|
+
* key absent from the canonical output — silently dropping the legacy
|
|
761
|
+
* `devices:` pin from config tracked in the git-backed `~/.agents` repo
|
|
762
|
+
* (RUSH-2517). Callers use this to skip the write when there is nothing to
|
|
763
|
+
* copy.
|
|
764
|
+
*
|
|
765
|
+
* Compares real paths so a symlinked `~/.agents` (the normal layout) still
|
|
766
|
+
* matches, and falls back to a resolved-path compare when either side cannot be
|
|
767
|
+
* realpath'd.
|
|
768
|
+
*/
|
|
769
|
+
export declare function isCanonicalRoutineSource(sourcePath: string, name: string): boolean;
|
|
735
770
|
/** Get the filesystem path of a job's YAML config file, or null if not found. */
|
|
736
771
|
export declare function getJobPath(name: string): string | null;
|
|
737
772
|
/**
|