@phnx-labs/agents-cli 1.22.34 → 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 +672 -2
- package/README.md +82 -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 +85 -0
- package/dist/commands/share.js +379 -8
- 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/codex-policy.d.ts +9 -1
- package/dist/lib/codex-policy.js +17 -2
- 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 +220 -122
- 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-key.d.ts +17 -0
- package/dist/lib/project-key.js +26 -0
- 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/delete.d.ts +93 -0
- package/dist/lib/share/delete.js +127 -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 +136 -27
- 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 +14 -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
|
@@ -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');
|
|
@@ -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
|
}
|