@phnx-labs/agents-cli 1.22.35 → 1.22.38
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 +708 -2
- package/README.md +83 -43
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1212 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/artifacts-setup.d.ts +53 -0
- package/dist/commands/artifacts-setup.js +161 -0
- package/dist/commands/artifacts.d.ts +18 -0
- package/dist/commands/artifacts.js +58 -0
- 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 +17 -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 +86 -42
- 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 +71 -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/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.d.ts +5 -0
- package/dist/commands/setup.js +31 -5
- package/dist/commands/share.d.ts +87 -7
- package/dist/commands/share.js +320 -58
- 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/hygiene.d.ts +90 -0
- package/dist/lib/browser/hygiene.js +146 -0
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +93 -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 +79 -1
- package/dist/lib/browser/service.js +231 -14
- 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 +63 -1
- 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 +21 -7
- package/dist/lib/git.js +122 -18
- 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 +44 -7
- 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/analytics.js +1 -1
- package/dist/lib/share/capture.d.ts +1 -1
- package/dist/lib/share/capture.js +3 -3
- package/dist/lib/share/config.d.ts +6 -2
- package/dist/lib/share/config.js +6 -5
- package/dist/lib/share/delete.js +3 -3
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +51 -1
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +119 -6
- package/dist/lib/share/worker-template.d.ts +12 -1
- package/dist/lib/share/worker-template.js +83 -7
- 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 +16 -14
- package/dist/lib/startup/command-registry.js +26 -37
- 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 +316 -0
- package/dist/lib/tmux/orphan-reap.js +638 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +96 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +16 -1
- package/dist/lib/triggers/webhook.js +10 -0
- package/dist/lib/types.d.ts +47 -35
- 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/set.d.ts +0 -15
- package/dist/commands/set.js +0 -79
- package/dist/commands/setup-share.d.ts +0 -17
- package/dist/commands/setup-share.js +0 -85
- 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
|
@@ -12,9 +12,12 @@ import * as fs from 'fs';
|
|
|
12
12
|
import * as path from 'path';
|
|
13
13
|
import * as yaml from 'yaml';
|
|
14
14
|
import { isDaemonRunning, signalDaemonReload, startDaemon, } from '../lib/daemon.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { findDuplicateMonitor, monitorFingerprint } from '../lib/monitors/fingerprint.js';
|
|
16
|
+
import { gatherFleetMonitors, NO_MONITOR_FANOUT_ENV } from '../lib/monitors/remote.js';
|
|
17
|
+
import { listMonitors, readMonitor, writeMonitor, deleteMonitor, setMonitorEnabled, getMonitorPath, validateMonitor, monitorRunsOnThisDevice, parseInterval, } from '../lib/monitors/config.js';
|
|
18
|
+
import { formatRelativeTime } from '../lib/session/relative-time.js';
|
|
19
|
+
import { evaluateMonitorOnce, POLL_SOURCE_TYPES } from '../lib/monitors/engine.js';
|
|
20
|
+
import { listFires, readState, readLiveness } from '../lib/monitors/state.js';
|
|
18
21
|
import { listRuns, getLatestRun, getRunDir } from '../lib/routines.js';
|
|
19
22
|
import { getMonitorsDir } from '../lib/state.js';
|
|
20
23
|
import { IS_WINDOWS } from '../lib/platform/index.js';
|
|
@@ -72,6 +75,54 @@ function ownerLabel(monitor) {
|
|
|
72
75
|
return monitor.devices.join(',');
|
|
73
76
|
return 'all';
|
|
74
77
|
}
|
|
78
|
+
/** A monitor's evaluation cadence in ms (falls back to the engine default). */
|
|
79
|
+
function monitorIntervalMs(monitor) {
|
|
80
|
+
if (monitor.source.interval)
|
|
81
|
+
return parseInterval(monitor.source.interval) ?? 60_000;
|
|
82
|
+
return 60_000;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* True when an enabled, locally-owned monitor's last poll is far enough past its
|
|
86
|
+
* interval that the engine has plainly stopped checking it (dead engine, swallowed
|
|
87
|
+
* start failure, never picked up). Tolerates a few missed ticks before flagging.
|
|
88
|
+
*/
|
|
89
|
+
function isStalled(monitor, liveness) {
|
|
90
|
+
if (!monitor.enabled || !monitorRunsOnThisDevice(monitor))
|
|
91
|
+
return false;
|
|
92
|
+
if (!liveness)
|
|
93
|
+
return false; // "never polled" is its own state, handled separately
|
|
94
|
+
const staleAfter = Math.max(monitorIntervalMs(monitor) * 3, 90_000);
|
|
95
|
+
return Date.now() - new Date(liveness.lastCheckedAt).getTime() > staleAfter;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The human liveness line for a monitor. This is the RUSH-2485 fix: it makes
|
|
99
|
+
* "the engine has never touched this" (`never polled`) visibly distinct from
|
|
100
|
+
* "polling steadily, condition just isn't matching" (`checked Nx`), from a real
|
|
101
|
+
* fire, and from a stalled engine.
|
|
102
|
+
*/
|
|
103
|
+
function livenessLabel(monitor, state, liveness) {
|
|
104
|
+
const here = monitorRunsOnThisDevice(monitor);
|
|
105
|
+
if (!monitor.enabled)
|
|
106
|
+
return chalk.gray('paused');
|
|
107
|
+
if (!here) {
|
|
108
|
+
// Not owned by this box — this daemon never checks it, so there's no local
|
|
109
|
+
// liveness to report; fall back to fire history if the owner synced it.
|
|
110
|
+
return state?.lastFiredAt ? chalk.gray(`fired ${formatRelativeTime(state.lastFiredAt)}`) : chalk.gray('owned elsewhere');
|
|
111
|
+
}
|
|
112
|
+
if (!liveness)
|
|
113
|
+
return chalk.yellow('never polled');
|
|
114
|
+
if (isStalled(monitor, liveness)) {
|
|
115
|
+
return chalk.red(`STALLED — last poll ${formatRelativeTime(liveness.lastCheckedAt)}`);
|
|
116
|
+
}
|
|
117
|
+
const checkedAgo = formatRelativeTime(liveness.lastCheckedAt);
|
|
118
|
+
if (liveness.lastError) {
|
|
119
|
+
return chalk.red(`checked ${liveness.checkCount}x · error: ${liveness.lastError.replace(/\s+/g, ' ').slice(0, 60)}`);
|
|
120
|
+
}
|
|
121
|
+
if (state?.lastFiredAt) {
|
|
122
|
+
return chalk.green(`fired ${formatRelativeTime(state.lastFiredAt)}`) + chalk.gray(` · checked ${liveness.checkCount}x`);
|
|
123
|
+
}
|
|
124
|
+
return chalk.gray(`checked ${liveness.checkCount}x · last ${checkedAgo} · no match yet`);
|
|
125
|
+
}
|
|
75
126
|
/** Start or reload the background daemon so a newly-added monitor is watched. */
|
|
76
127
|
function ensureDaemonRunning() {
|
|
77
128
|
if (isDaemonRunning()) {
|
|
@@ -88,6 +139,37 @@ function ensureDaemonRunning() {
|
|
|
88
139
|
stderrLine(chalk.yellow('Could not start the daemon. Start it manually with: agents routines start'));
|
|
89
140
|
}
|
|
90
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Assert the postcondition of `add`: the engine actually picked the monitor up.
|
|
144
|
+
* Config acceptance is not enough — RUSH-2485 was a monitor that added cleanly,
|
|
145
|
+
* listed as `on`, and never polled. A poll-model monitor owned by and enabled on
|
|
146
|
+
* this box should show a liveness heartbeat within a couple of engine ticks; wait
|
|
147
|
+
* for it and report the real outcome instead of reporting success on write. A
|
|
148
|
+
* miss is a warning, not a hard failure — a freshly-started daemon may still be
|
|
149
|
+
* booting — but it is surfaced so a dead engine can never masquerade as healthy.
|
|
150
|
+
*/
|
|
151
|
+
async function assertEnginePickup(monitor) {
|
|
152
|
+
const pollSource = POLL_SOURCE_TYPES.has(monitor.source.type);
|
|
153
|
+
if (!monitor.enabled || !monitorRunsOnThisDevice(monitor) || !pollSource)
|
|
154
|
+
return; // nothing to assert here
|
|
155
|
+
const before = readLiveness(monitor.name);
|
|
156
|
+
const baseline = before?.checkCount ?? 0;
|
|
157
|
+
const deadline = Date.now() + 12_000; // a couple of 5s ticks, plus daemon-boot slack
|
|
158
|
+
stderrLine(chalk.gray(' waiting for the engine to poll it…'));
|
|
159
|
+
while (Date.now() < deadline) {
|
|
160
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
161
|
+
const now = readLiveness(monitor.name);
|
|
162
|
+
if (now && now.checkCount > baseline) {
|
|
163
|
+
console.log(chalk.green(` engine picked it up — first poll ${formatRelativeTime(now.lastCheckedAt)}`));
|
|
164
|
+
if (now.lastError) {
|
|
165
|
+
stderrLine(chalk.yellow(` note: that poll errored — ${now.lastError.replace(/\s+/g, ' ').slice(0, 80)}`));
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
stderrLine(chalk.yellow(` the engine has not polled '${monitor.name}' yet.`));
|
|
171
|
+
stderrLine(chalk.yellow(` confirm the daemon is running (agents routines status) and re-check with: agents monitors view ${monitor.name}`));
|
|
172
|
+
}
|
|
91
173
|
/** Validate a single device name against the registered fleet; exit on miss. */
|
|
92
174
|
async function validateDevice(name) {
|
|
93
175
|
const normalized = normalizeHost(name.trim());
|
|
@@ -242,6 +324,58 @@ async function pickMonitor(message, alternatives = []) {
|
|
|
242
324
|
}
|
|
243
325
|
}
|
|
244
326
|
/** Register the `agents monitors` command tree. */
|
|
327
|
+
/**
|
|
328
|
+
* Refuse a monitor that duplicates one already in play — same NAME (which
|
|
329
|
+
* `writeMonitor` would silently overwrite) or same BEHAVIOR under any name, on
|
|
330
|
+
* this box or any other. Exits the process on a refusal.
|
|
331
|
+
*
|
|
332
|
+
* Shared by BOTH `add` paths. The file path (`add ./watcher.yml`) returns early
|
|
333
|
+
* and used to skip the guard entirely, so a duplicate could be walked straight
|
|
334
|
+
* in through a YAML file — the one input an agent is most likely to generate.
|
|
335
|
+
*/
|
|
336
|
+
async function guardAgainstDuplicateMonitor(config, force) {
|
|
337
|
+
if (force)
|
|
338
|
+
return;
|
|
339
|
+
const existing = listMonitors();
|
|
340
|
+
const sameName = existing.find((m) => m.name === config.name);
|
|
341
|
+
if (sameName) {
|
|
342
|
+
stderrLine(chalk.red(`Monitor '${config.name}' already exists — adding would overwrite it.`));
|
|
343
|
+
stderrLine(chalk.gray(` Inspect it: agents monitors view ${config.name}`));
|
|
344
|
+
stderrLine(chalk.gray(` Replace it: agents monitors add ${config.name} ... --force`));
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
const duplicate = findDuplicateMonitor(config, existing);
|
|
348
|
+
if (duplicate) {
|
|
349
|
+
stderrLine(chalk.red(`Monitor '${duplicate}' already watches this exact source and fires the same action.`));
|
|
350
|
+
stderrLine(chalk.gray(' Adding it again would fire the same trigger twice.'));
|
|
351
|
+
stderrLine(chalk.gray(` Inspect it: agents monitors view ${duplicate}`));
|
|
352
|
+
stderrLine(chalk.gray(` Add anyway: agents monitors add ${config.name} ... --force`));
|
|
353
|
+
process.exit(1);
|
|
354
|
+
}
|
|
355
|
+
// The case a local check cannot see: another agent, on another box, already
|
|
356
|
+
// watching this same work item with these same arguments. One work item, two
|
|
357
|
+
// triggers. Identity is the arguments, so the claim has to be fleet-wide —
|
|
358
|
+
// different arguments (another PR) are not a clash and still pass.
|
|
359
|
+
if (process.env[NO_MONITOR_FANOUT_ENV])
|
|
360
|
+
return;
|
|
361
|
+
const fleet = await gatherFleetMonitors();
|
|
362
|
+
const mine = monitorFingerprint(config);
|
|
363
|
+
const clash = fleet.monitors.find((r) => monitorFingerprint(r.monitor) === mine);
|
|
364
|
+
if (clash) {
|
|
365
|
+
stderrLine(chalk.red(`Monitor '${clash.monitor.name}' on ${chalk.bold(clash.machine)} already watches this exact source and fires the same action.`));
|
|
366
|
+
stderrLine(chalk.gray(' Two boxes watching one work item is a double trigger.'));
|
|
367
|
+
stderrLine(chalk.gray(` Inspect it: agents ssh ${clash.machine} 'agents monitors view ${clash.monitor.name}'`));
|
|
368
|
+
stderrLine(chalk.gray(` Add anyway: agents monitors add ${config.name} ... --force`));
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}
|
|
371
|
+
// Never treat "could not ask" as "no duplicate".
|
|
372
|
+
if (fleet.discoveryFailed) {
|
|
373
|
+
stderrLine(chalk.yellow(' Note: could not reach the device registry — the fleet was not checked for duplicates.'));
|
|
374
|
+
}
|
|
375
|
+
else if (fleet.skipped.length > 0) {
|
|
376
|
+
stderrLine(chalk.yellow(` Note: could not check ${fleet.skipped.join(', ')} — a duplicate there would not have been caught.`));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
245
379
|
export function registerMonitorsCommands(program) {
|
|
246
380
|
const monitorsCmd = program
|
|
247
381
|
.command('monitors')
|
|
@@ -315,11 +449,12 @@ export function registerMonitorsCommands(program) {
|
|
|
315
449
|
.option('--notify [channel]', 'Notify the owner (notify.owner); [channel] overrides the owner channel')
|
|
316
450
|
.option('--webhook-out <url>', 'POST the event to this URL')
|
|
317
451
|
// PLACEMENT / hygiene
|
|
318
|
-
.option('--device <name>', 'OWNER (not body placement) — the single machine that evaluates + fires (exactly-once). See docs/
|
|
452
|
+
.option('--device <name>', 'OWNER (not body placement) — the single machine that evaluates + fires (exactly-once). See docs/concepts.md#placement.')
|
|
319
453
|
.option('--devices <list>', 'Allowlist (comma-separated): each device fires independently')
|
|
320
454
|
.option('--run-on <host>', 'BODY placement — execute the ACTION on this machine over SSH (same idea as run --where device:<host>)')
|
|
321
455
|
.option('--rate-limit <spec>', 'Auto-pause if it fires more than N/<interval> (e.g. 5/1m)')
|
|
322
456
|
.option('--disabled', 'Create the monitor paused (enable later with resume)')
|
|
457
|
+
.option('--force', 'Overwrite a same-named monitor, or add one that duplicates an existing watcher')
|
|
323
458
|
.action(async (nameOrPath, options) => {
|
|
324
459
|
// File mode: a single arg pointing at an existing .yml with no source flags.
|
|
325
460
|
const hasSourceFlag = Boolean(options.watch || options.poll || options.pollHttp || options.on || options.ws || options.watchFile || options.watchDevice);
|
|
@@ -342,9 +477,11 @@ export function registerMonitorsCommands(program) {
|
|
|
342
477
|
stderrLine(chalk.red(` - ${err}`));
|
|
343
478
|
process.exit(1);
|
|
344
479
|
}
|
|
480
|
+
await guardAgainstDuplicateMonitor(config, options.force === true);
|
|
345
481
|
writeMonitor(config);
|
|
346
482
|
console.log(chalk.green(`Monitor '${name}' added`));
|
|
347
483
|
ensureDaemonRunning();
|
|
484
|
+
await assertEnginePickup(config);
|
|
348
485
|
return;
|
|
349
486
|
}
|
|
350
487
|
if (!nameOrPath) {
|
|
@@ -413,10 +550,12 @@ export function registerMonitorsCommands(program) {
|
|
|
413
550
|
if (condition.mode === 'match' && condition.match && /^(issued|success|ok|pass(ed)?|done|ready)$/i.test(condition.match)) {
|
|
414
551
|
stderrLine(chalk.yellow(` Note: --match '${condition.match}' only fires on success — it stays silent if the source breaks or never matches.`));
|
|
415
552
|
}
|
|
553
|
+
await guardAgainstDuplicateMonitor(config, options.force === true);
|
|
416
554
|
writeMonitor(config);
|
|
417
555
|
console.log(chalk.green(`Monitor '${nameOrPath}' added`));
|
|
418
556
|
console.log(chalk.gray(` ${sourceLabel(source)} → [${condition.mode}] → ${actionLabel(action)} · owner: ${ownerLabel(config)}`));
|
|
419
557
|
ensureDaemonRunning();
|
|
558
|
+
await assertEnginePickup(config);
|
|
420
559
|
});
|
|
421
560
|
// ─── list ────────────────────────────────────────────────────────────────────
|
|
422
561
|
monitorsCmd
|
|
@@ -428,16 +567,28 @@ export function registerMonitorsCommands(program) {
|
|
|
428
567
|
if (options.json) {
|
|
429
568
|
const payload = monitors.map((m) => {
|
|
430
569
|
const state = readState(m.name);
|
|
570
|
+
const liveness = readLiveness(m.name);
|
|
431
571
|
return {
|
|
432
572
|
name: m.name,
|
|
433
573
|
enabled: m.enabled,
|
|
434
574
|
source: m.source,
|
|
435
575
|
condition: m.condition,
|
|
436
|
-
action
|
|
576
|
+
// Full action, not just `type`: the cross-machine duplicate guard
|
|
577
|
+
// fingerprints source+condition+action, so a type-only action made
|
|
578
|
+
// every `--run` monitor unmatchable and the fleet check inert for
|
|
579
|
+
// exactly the case it exists for. `source` already ships whole.
|
|
580
|
+
action: m.action,
|
|
437
581
|
owner: ownerLabel(m),
|
|
438
582
|
runsHere: monitorRunsOnThisDevice(m),
|
|
439
583
|
lastSeenAt: state?.lastSeenAt ?? null,
|
|
440
584
|
lastFiredAt: state?.lastFiredAt ?? null,
|
|
585
|
+
// Liveness heartbeat (RUSH-2485): distinguishes never-polled from
|
|
586
|
+
// polling-not-matching from a stalled engine.
|
|
587
|
+
lastCheckedAt: liveness?.lastCheckedAt ?? null,
|
|
588
|
+
checkCount: liveness?.checkCount ?? 0,
|
|
589
|
+
lastError: liveness?.lastError ?? null,
|
|
590
|
+
consecutiveErrors: liveness?.consecutiveErrors ?? 0,
|
|
591
|
+
stalled: isStalled(m, liveness),
|
|
441
592
|
};
|
|
442
593
|
});
|
|
443
594
|
stdoutJson(payload);
|
|
@@ -451,12 +602,12 @@ export function registerMonitorsCommands(program) {
|
|
|
451
602
|
console.log(chalk.bold('Monitors\n'));
|
|
452
603
|
for (const m of monitors) {
|
|
453
604
|
const state = readState(m.name);
|
|
605
|
+
const liveness = readLiveness(m.name);
|
|
454
606
|
const enabled = m.enabled ? chalk.green('on') : chalk.gray('off');
|
|
455
607
|
const here = monitorRunsOnThisDevice(m);
|
|
456
608
|
const owner = here ? ownerLabel(m) : chalk.gray(ownerLabel(m));
|
|
457
|
-
const lastFired = state?.lastFiredAt ? `fired ${state.lastFiredAt}` : chalk.gray('never fired');
|
|
458
609
|
console.log(` ${chalk.cyan(m.name.padEnd(22))} ${enabled.padEnd(3)} ${sourceLabel(m.source)}`);
|
|
459
|
-
console.log(` ${' '.repeat(22)} ${chalk.gray(`[${m.condition.mode}]`)} → ${actionLabel(m.action)} ${chalk.gray(`owner: ${owner}`)} ${
|
|
610
|
+
console.log(` ${' '.repeat(22)} ${chalk.gray(`[${m.condition.mode}]`)} → ${actionLabel(m.action)} ${chalk.gray(`owner: ${owner}`)} ${livenessLabel(m, state, liveness)}`);
|
|
460
611
|
}
|
|
461
612
|
console.log();
|
|
462
613
|
});
|
|
@@ -477,6 +628,7 @@ export function registerMonitorsCommands(program) {
|
|
|
477
628
|
process.exit(1);
|
|
478
629
|
}
|
|
479
630
|
const state = readState(name);
|
|
631
|
+
const liveness = readLiveness(name);
|
|
480
632
|
const recentFires = listFires(name).slice(-5);
|
|
481
633
|
if (options.json) {
|
|
482
634
|
stdoutJson({
|
|
@@ -485,14 +637,30 @@ export function registerMonitorsCommands(program) {
|
|
|
485
637
|
owner: ownerLabel(monitor),
|
|
486
638
|
runsHere: monitorRunsOnThisDevice(monitor),
|
|
487
639
|
state,
|
|
640
|
+
liveness,
|
|
641
|
+
stalled: isStalled(monitor, liveness),
|
|
488
642
|
recentFires,
|
|
489
643
|
});
|
|
490
644
|
return;
|
|
491
645
|
}
|
|
492
646
|
console.log(chalk.bold(`Monitor: ${name}\n`));
|
|
493
647
|
console.log(yaml.stringify(monitor));
|
|
648
|
+
// Liveness first (RUSH-2485): the heartbeat is the answer to "is this thing
|
|
649
|
+
// actually running?" — it renders even when the monitor has never fired.
|
|
650
|
+
console.log(chalk.bold('Liveness'));
|
|
651
|
+
console.log(` ${livenessLabel(monitor, state, liveness)}`);
|
|
652
|
+
if (liveness) {
|
|
653
|
+
console.log(chalk.gray(` last checked: ${liveness.lastCheckedAt} (${formatRelativeTime(liveness.lastCheckedAt)})`));
|
|
654
|
+
console.log(chalk.gray(` checks: ${liveness.checkCount}`));
|
|
655
|
+
if (liveness.lastError) {
|
|
656
|
+
console.log(chalk.red(` last error: ${liveness.lastError.replace(/\s+/g, ' ').slice(0, 200)} (${liveness.consecutiveErrors} in a row)`));
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
else if (monitor.enabled && monitorRunsOnThisDevice(monitor)) {
|
|
660
|
+
console.log(chalk.yellow(' The engine has not polled this monitor yet. If this persists, the daemon may not have picked it up — check: agents routines status'));
|
|
661
|
+
}
|
|
494
662
|
if (state) {
|
|
495
|
-
console.log(chalk.bold('
|
|
663
|
+
console.log(chalk.bold('\nWatched state'));
|
|
496
664
|
console.log(chalk.gray(` last seen: ${state.lastSeenAt}`));
|
|
497
665
|
if (state.lastFiredAt)
|
|
498
666
|
console.log(chalk.gray(` last fired: ${state.lastFiredAt}`));
|
|
@@ -566,19 +734,29 @@ export function registerMonitorsCommands(program) {
|
|
|
566
734
|
if (!name)
|
|
567
735
|
return;
|
|
568
736
|
}
|
|
737
|
+
// getMonitorPath is user-layer only: edits always land in the user dir,
|
|
738
|
+
// never the pull-only system mirror. Editing a system built-in (no user
|
|
739
|
+
// copy yet) materializes one, prefilled with the built-in's own config.
|
|
569
740
|
let monitorPath = getMonitorPath(name);
|
|
570
741
|
if (!monitorPath) {
|
|
571
742
|
const dir = getMonitorsDir();
|
|
572
743
|
fs.mkdirSync(dir, { recursive: true });
|
|
573
744
|
monitorPath = safeJoin(dir, `${name}.yml`);
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
745
|
+
const builtIn = readMonitor(name);
|
|
746
|
+
if (builtIn) {
|
|
747
|
+
fs.writeFileSync(monitorPath, yaml.stringify(builtIn), 'utf-8');
|
|
748
|
+
console.log(chalk.gray(`Editing a copy of built-in monitor '${name}' in your user dir: ${monitorPath}`));
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
const template = yaml.stringify({
|
|
752
|
+
name,
|
|
753
|
+
source: { type: 'poll', command: 'echo hello', interval: '1m' },
|
|
754
|
+
condition: { mode: 'on-change' },
|
|
755
|
+
action: { type: 'notify' },
|
|
756
|
+
});
|
|
757
|
+
fs.writeFileSync(monitorPath, template, 'utf-8');
|
|
758
|
+
console.log(chalk.gray(`Created new monitor file: ${monitorPath}`));
|
|
759
|
+
}
|
|
582
760
|
}
|
|
583
761
|
const editor = process.env.EDITOR || process.env.VISUAL || (IS_WINDOWS ? 'notepad' : 'vi');
|
|
584
762
|
const parts = editor.split(/\s+/).filter(Boolean);
|
|
@@ -772,6 +950,11 @@ export function registerMonitorsCommands(program) {
|
|
|
772
950
|
stderrLine(chalk.gray('Daemon reloaded'));
|
|
773
951
|
}
|
|
774
952
|
}
|
|
953
|
+
else if (readMonitor(name)) {
|
|
954
|
+
// Resolvable but not in the user dir: a pull-only system built-in.
|
|
955
|
+
stderrLine(chalk.red(`Monitor '${name}' is a built-in and can't be removed; pause it with: agents monitors pause ${name}`));
|
|
956
|
+
process.exit(1);
|
|
957
|
+
}
|
|
775
958
|
else {
|
|
776
959
|
stderrLine(chalk.red(`Monitor '${name}' not found`));
|
|
777
960
|
process.exit(1);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agents open` — resolve an `agents://` deep link, and manage the OS handler
|
|
3
|
+
* that routes such links here.
|
|
4
|
+
*
|
|
5
|
+
* agents open agents://session/<id> resume that session in a terminal
|
|
6
|
+
* agents open register register the agents:// scheme with the OS
|
|
7
|
+
* agents open unregister remove the handler
|
|
8
|
+
* agents open status report whether the handler is registered
|
|
9
|
+
*
|
|
10
|
+
* A rendered artifact (plan/report) embeds `agents://session/<id>` in its
|
|
11
|
+
* provenance line; clicking it hands the URL to the OS, which invokes
|
|
12
|
+
* `agents open <url>`. This command parses it (lib/deeplink/url.ts) and hands the
|
|
13
|
+
* session id to the existing resume dispatcher, which resolves the owning host
|
|
14
|
+
* and opens the terminal with the cursor in the input bar. The id is passed as
|
|
15
|
+
* argv, never interpolated into a shell.
|
|
16
|
+
*/
|
|
17
|
+
import type { Command } from 'commander';
|
|
18
|
+
export declare function registerOpenCommand(program: Command): void;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { parseAgentsUrl } from '../lib/deeplink/url.js';
|
|
3
|
+
import { registerAgentsUrlScheme, unregisterAgentsUrlScheme, agentsUrlSchemeStatus, } from '../lib/deeplink/register.js';
|
|
4
|
+
export function registerOpenCommand(program) {
|
|
5
|
+
const open = program
|
|
6
|
+
.command('open [url]')
|
|
7
|
+
.description('Resume a session from an agents:// deep link, or register/unregister/status the OS URL-scheme handler.')
|
|
8
|
+
.action(async (url) => {
|
|
9
|
+
if (!url) {
|
|
10
|
+
open.help();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await handleUrl(url);
|
|
14
|
+
});
|
|
15
|
+
open
|
|
16
|
+
.command('register')
|
|
17
|
+
.description('Register the agents:// URL scheme with the OS so artifact links resume sessions (idempotent).')
|
|
18
|
+
.action(() => {
|
|
19
|
+
const status = registerAgentsUrlScheme();
|
|
20
|
+
if (status.registered) {
|
|
21
|
+
console.log(chalk.green('agents:// scheme registered.') + chalk.gray(` ${status.detail}`));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(chalk.yellow('Could not register the agents:// scheme.') + chalk.gray(` ${status.detail}`));
|
|
25
|
+
process.exitCode = 1;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
open
|
|
29
|
+
.command('unregister')
|
|
30
|
+
.description('Remove the agents:// URL scheme handler.')
|
|
31
|
+
.action(() => {
|
|
32
|
+
const status = unregisterAgentsUrlScheme();
|
|
33
|
+
console.log(chalk.gray(status.detail));
|
|
34
|
+
});
|
|
35
|
+
open
|
|
36
|
+
.command('status')
|
|
37
|
+
.description('Report whether the agents:// URL scheme handler is registered.')
|
|
38
|
+
.action(() => {
|
|
39
|
+
const status = agentsUrlSchemeStatus();
|
|
40
|
+
const label = status.registered ? chalk.green('registered') : chalk.yellow('not registered');
|
|
41
|
+
console.log(`agents:// handler: ${label} ${chalk.gray(`(${status.platform})`)}`);
|
|
42
|
+
console.log(chalk.gray(` ${status.detail}`));
|
|
43
|
+
if (!status.registered)
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async function handleUrl(url) {
|
|
48
|
+
const parsed = parseAgentsUrl(url);
|
|
49
|
+
if ('error' in parsed) {
|
|
50
|
+
console.error(chalk.red(`Not a valid agents:// link: ${parsed.error}`));
|
|
51
|
+
process.exitCode = 2;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Lazy-import the resume dispatcher so `register`/`status` stay cold-start cheap.
|
|
55
|
+
const { dispatchSessionLifecycleInPlace } = await import('./sessions-resume.js');
|
|
56
|
+
await dispatchSessionLifecycleInPlace(parsed.id, parsed.host ? [parsed.host] : []);
|
|
57
|
+
}
|
|
@@ -6,15 +6,13 @@
|
|
|
6
6
|
* hooks from configured registries or GitHub sources.
|
|
7
7
|
*/
|
|
8
8
|
import * as fs from 'fs';
|
|
9
|
-
import * as path from 'path';
|
|
10
9
|
import chalk from 'chalk';
|
|
11
10
|
import ora from 'ora';
|
|
12
|
-
import { getAgentsDir, getEnabledExtraRepos } from '../lib/state.js';
|
|
13
11
|
import { AGENTS, getAllCliStates, agentLabel, } from '../lib/agents.js';
|
|
14
12
|
import { capableAgents } from '../lib/capabilities.js';
|
|
15
13
|
import { DEFAULT_REGISTRIES } from '../lib/types.js';
|
|
16
|
-
import { getRegistries, setRegistry, removeRegistry, search as searchRegistries, resolvePackage, validatedNpmSpec, validatedPyPISpec,
|
|
17
|
-
import { cloneRepo
|
|
14
|
+
import { getRegistries, setRegistry, removeRegistry, search as searchRegistries, resolvePackage, validatedNpmSpec, validatedPyPISpec, verifySkillIntegrity, } from '../lib/registry.js';
|
|
15
|
+
import { cloneRepo } from '../lib/git.js';
|
|
18
16
|
import { discoverCommands, resolveCommandSource, installCommand, installCommandCentrally, } from '../lib/commands.js';
|
|
19
17
|
import { discoverSkillsFromRepo, installSkill, installSkillCentrally, } from '../lib/skills.js';
|
|
20
18
|
import { discoverHooksFromRepo, installHooks, installHooksCentrally, } from '../lib/hooks.js';
|
|
@@ -328,109 +326,6 @@ When to use:
|
|
|
328
326
|
}
|
|
329
327
|
});
|
|
330
328
|
// ==========================================================================
|
|
331
|
-
// PUBLISH COMMAND (self-hosted, git-index skill registry)
|
|
332
|
-
// ==========================================================================
|
|
333
|
-
program
|
|
334
|
-
.command('publish')
|
|
335
|
-
.description('Generate a skills-index.json for a git repo and push it, making its skills discoverable via agents search/install')
|
|
336
|
-
.option('--repo <alias>', 'Publish an extra repo added via `agents repo add` (default: your ~/.agents repo)')
|
|
337
|
-
.option('--name <name>', 'Registry name to suggest in the output (default: the repo name)')
|
|
338
|
-
.option('--branch <branch>', 'Branch to push the index to and reference in the raw URL (default: the repo\'s current branch)')
|
|
339
|
-
.option('--dry-run', 'Write the index and print the URL without committing or pushing')
|
|
340
|
-
.addHelpText('after', `
|
|
341
|
-
Publish walks a repo's skills/ directory, records a sha256 of every SKILL.md,
|
|
342
|
-
and writes skills-index.json at the repo root — a flat index that 'agents search'
|
|
343
|
-
and 'agents install' can consume directly from raw.githubusercontent.com. No
|
|
344
|
-
hosted infrastructure: the index is just a file committed to your GitHub repo.
|
|
345
|
-
|
|
346
|
-
Examples:
|
|
347
|
-
# Publish your ~/.agents repo's skills
|
|
348
|
-
agents publish
|
|
349
|
-
|
|
350
|
-
# Publish an extra repo added via 'agents repo add'
|
|
351
|
-
agents publish --repo team-skills
|
|
352
|
-
|
|
353
|
-
# Preview the index without pushing
|
|
354
|
-
agents publish --dry-run
|
|
355
|
-
|
|
356
|
-
After publishing, share the printed 'agents registry add skill ...' command so
|
|
357
|
-
others can search and install your skills. Installs verify each SKILL.md against
|
|
358
|
-
the sha256 in the index and abort on mismatch.
|
|
359
|
-
`)
|
|
360
|
-
.action(async (options) => {
|
|
361
|
-
// Resolve the target repo: an extra repo by alias, else the primary ~/.agents repo.
|
|
362
|
-
let repoDir;
|
|
363
|
-
if (options.repo) {
|
|
364
|
-
const extra = getEnabledExtraRepos().find((r) => r.alias === options.repo);
|
|
365
|
-
if (!extra) {
|
|
366
|
-
console.log(chalk.red(`No enabled extra repo aliased '${options.repo}'.`));
|
|
367
|
-
console.log(chalk.gray('Add one with: agents repo add <source> --as <alias>'));
|
|
368
|
-
process.exit(1);
|
|
369
|
-
}
|
|
370
|
-
repoDir = extra.dir;
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
repoDir = getAgentsDir();
|
|
374
|
-
}
|
|
375
|
-
if (!isGitRepo(repoDir)) {
|
|
376
|
-
console.log(chalk.red(`${repoDir} is not a git repository.`));
|
|
377
|
-
console.log(chalk.gray('publish commits + pushes the index, so the repo needs a GitHub remote.'));
|
|
378
|
-
process.exit(1);
|
|
379
|
-
}
|
|
380
|
-
const remoteUrl = await getRemoteUrl(repoDir);
|
|
381
|
-
const repoSlug = remoteUrl ? parseOwnerRepoFromRemote(remoteUrl) : null;
|
|
382
|
-
if (!repoSlug) {
|
|
383
|
-
console.log(chalk.red(`Could not resolve an 'owner/repo' from the git remote of ${repoDir}.`));
|
|
384
|
-
console.log(chalk.gray(` Remote: ${remoteUrl || '(none)'} — publish needs a GitHub origin.`));
|
|
385
|
-
process.exit(1);
|
|
386
|
-
}
|
|
387
|
-
const spinner = ora('Building skills index...').start();
|
|
388
|
-
const index = buildSkillIndex(repoDir, repoSlug, { generatedAt: new Date().toISOString() });
|
|
389
|
-
spinner.stop();
|
|
390
|
-
if (index.skills.length === 0) {
|
|
391
|
-
console.log(chalk.yellow(`No skills found under ${repoDir}/skills.`));
|
|
392
|
-
console.log(chalk.gray('Add a skill (a directory with a SKILL.md) and re-run publish.'));
|
|
393
|
-
process.exit(1);
|
|
394
|
-
}
|
|
395
|
-
const indexPath = path.join(repoDir, 'skills-index.json');
|
|
396
|
-
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2) + '\n', 'utf-8');
|
|
397
|
-
console.log(chalk.bold(`\nIndexed ${index.skills.length} skill(s) into skills-index.json:`));
|
|
398
|
-
for (const s of index.skills) {
|
|
399
|
-
console.log(` ${chalk.cyan(s.name)} ${chalk.gray(`sha256:${s.sha256?.slice(0, 12)}…`)}`);
|
|
400
|
-
}
|
|
401
|
-
// The branch the URL references must be the branch the index actually
|
|
402
|
-
// lands on. In a real push that's whatever commitAndPush reports back
|
|
403
|
-
// (the requested --branch, else the checked-out branch); in a dry run we
|
|
404
|
-
// resolve it the same way without pushing.
|
|
405
|
-
let urlBranch;
|
|
406
|
-
if (options.dryRun) {
|
|
407
|
-
urlBranch = options.branch || (await getCurrentBranch(repoDir));
|
|
408
|
-
console.log(chalk.gray(`\nDry run — wrote ${indexPath} but did not commit or push.`));
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
const pushSpinner = ora('Committing and pushing skills-index.json...').start();
|
|
412
|
-
const result = await commitAndPush(repoDir, 'chore: update skills-index.json (agents publish)', options.branch);
|
|
413
|
-
if (!result.success) {
|
|
414
|
-
pushSpinner.fail(`Push failed: ${result.error}`);
|
|
415
|
-
console.log(chalk.gray('The index was written locally — commit and push it manually to publish.'));
|
|
416
|
-
process.exit(1);
|
|
417
|
-
}
|
|
418
|
-
// commitAndPush always reports the pushed branch on success; the `??`
|
|
419
|
-
// only satisfies the optional return type, it is not a behavior path.
|
|
420
|
-
urlBranch = result.branch ?? (await getCurrentBranch(repoDir));
|
|
421
|
-
pushSpinner.succeed(`Pushed skills-index.json to ${urlBranch}`);
|
|
422
|
-
}
|
|
423
|
-
const rawUrl = `https://raw.githubusercontent.com/${repoSlug}/${urlBranch}/skills-index.json`;
|
|
424
|
-
const registryName = options.name || repoSlug.split('/')[1] || 'my-skills';
|
|
425
|
-
console.log(chalk.bold('\nPublished. Share these with anyone who wants your skills:\n'));
|
|
426
|
-
console.log(chalk.gray(' Index URL:'));
|
|
427
|
-
console.log(` ${rawUrl}`);
|
|
428
|
-
console.log(chalk.gray('\n Register + search + install:'));
|
|
429
|
-
console.log(` ${chalk.green(`agents registry add skill ${registryName} ${rawUrl}`)}`);
|
|
430
|
-
console.log(` ${chalk.green(`agents search ${index.skills[0].name} --type skill`)}`);
|
|
431
|
-
console.log(` ${chalk.green(`agents install skill:${index.skills[0].name} --agents claude,codex,cursor`)}`);
|
|
432
|
-
});
|
|
433
|
-
// ==========================================================================
|
|
434
329
|
// INSTALL COMMAND (unified package installation)
|
|
435
330
|
// ==========================================================================
|
|
436
331
|
program
|
package/dist/commands/plugins.js
CHANGED
|
@@ -282,10 +282,11 @@ Examples:
|
|
|
282
282
|
}
|
|
283
283
|
console.log();
|
|
284
284
|
});
|
|
285
|
-
// agents
|
|
285
|
+
// Deprecated: superseded by `agents sync --plugin <name>`. Kept as a warned,
|
|
286
|
+
// functional alias so old muscle-memory and scripts don't break.
|
|
286
287
|
pluginsCmd
|
|
287
|
-
.command('sync <name> [agent]')
|
|
288
|
-
.description('
|
|
288
|
+
.command('sync <name> [agent]', { hidden: true })
|
|
289
|
+
.description('Deprecated — use `agents sync --plugin <name>` instead.')
|
|
289
290
|
.option('--allow-exec-surfaces', 'Enable the plugin even when it ships hooks/, .mcp.json, bin/, scripts/, settings.json, or permissions/')
|
|
290
291
|
.addHelpText('after', `
|
|
291
292
|
Examples:
|
|
@@ -302,6 +303,8 @@ Examples:
|
|
|
302
303
|
agents plugins sync hivemind claude --allow-exec-surfaces
|
|
303
304
|
`)
|
|
304
305
|
.action(async (name, agentArg, options) => {
|
|
306
|
+
console.warn(chalk.yellow('`agents plugins sync` is deprecated — use `agents sync --plugin` instead:'));
|
|
307
|
+
console.warn(chalk.gray(` agents sync --plugin ${name}`));
|
|
305
308
|
const plugin = getPlugin(name);
|
|
306
309
|
if (!plugin) {
|
|
307
310
|
console.log(chalk.red(`Plugin '${name}' not found`));
|