@phnx-labs/agents-cli 1.22.35 → 1.22.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +666 -2
- package/README.md +75 -35
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1211 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/attach.js +17 -4
- package/dist/commands/audit.d.ts +8 -8
- package/dist/commands/audit.js +57 -47
- package/dist/commands/browser.js +15 -11
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +0 -11
- package/dist/commands/computer-actions.js +33 -0
- package/dist/commands/computer-sessions-picker.d.ts +21 -0
- package/dist/commands/computer-sessions-picker.js +141 -0
- package/dist/commands/computer.d.ts +16 -0
- package/dist/commands/computer.js +37 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +401 -0
- package/dist/commands/cp.d.ts +84 -0
- package/dist/commands/cp.js +231 -0
- package/dist/commands/daemon.js +243 -14
- package/dist/commands/detach-core.d.ts +1 -1
- package/dist/commands/detach-core.js +12 -2
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +64 -5
- package/dist/commands/events.d.ts +24 -12
- package/dist/commands/events.js +144 -28
- package/dist/commands/exec.js +85 -41
- package/dist/commands/feed.d.ts +1 -1
- package/dist/commands/feed.js +16 -8
- package/dist/commands/focus.d.ts +33 -1
- package/dist/commands/focus.js +177 -17
- package/dist/commands/funnel.d.ts +1 -1
- package/dist/commands/go.js +9 -8
- package/dist/commands/harness-wizard.d.ts +1 -0
- package/dist/commands/harness-wizard.js +18 -20
- package/dist/commands/harness.d.ts +2 -0
- package/dist/commands/harness.js +59 -26
- package/dist/commands/hooks.js +0 -11
- package/dist/commands/inspect.d.ts +94 -1
- package/dist/commands/inspect.js +866 -40
- package/dist/commands/lease.d.ts +4 -4
- package/dist/commands/lease.js +6 -6
- package/dist/commands/login.js +0 -13
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +2 -2
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/memory.js +7 -2
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +37 -6
- package/dist/commands/models.js +4 -0
- package/dist/commands/monitors.d.ts +0 -1
- package/dist/commands/monitors.js +199 -16
- package/dist/commands/open.d.ts +18 -0
- package/dist/commands/open.js +57 -0
- package/dist/commands/packages.js +2 -107
- package/dist/commands/plugins.js +6 -3
- package/dist/commands/profiles.d.ts +1 -0
- package/dist/commands/profiles.js +16 -160
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +125 -5
- package/dist/commands/reconnect.js +9 -3
- package/dist/commands/repo.js +42 -1
- package/dist/commands/resource-view.d.ts +17 -0
- package/dist/commands/resource-view.js +36 -14
- package/dist/commands/resume.js +9 -2
- package/dist/commands/routines.d.ts +0 -2
- package/dist/commands/routines.js +473 -289
- package/dist/commands/secrets.js +52 -9
- package/dist/commands/sessions-export.d.ts +47 -0
- package/dist/commands/sessions-export.js +116 -6
- package/dist/commands/sessions-import.d.ts +17 -0
- package/dist/commands/sessions-import.js +114 -6
- package/dist/commands/sessions-migrate.d.ts +27 -0
- package/dist/commands/sessions-migrate.js +50 -9
- package/dist/commands/sessions-picker.js +23 -4
- package/dist/commands/sessions-resume.d.ts +5 -3
- package/dist/commands/sessions-resume.js +30 -8
- package/dist/commands/sessions-watch.d.ts +2 -0
- package/dist/commands/sessions-watch.js +53 -0
- package/dist/commands/sessions.d.ts +66 -3
- package/dist/commands/sessions.js +298 -47
- package/dist/commands/set.d.ts +1 -1
- package/dist/commands/set.js +2 -2
- package/dist/commands/setup-browser.js +2 -2
- package/dist/commands/setup-mine.js +0 -1
- package/dist/commands/setup-preferences.js +1 -1
- package/dist/commands/setup-share.js +34 -4
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +26 -0
- package/dist/commands/share.d.ts +67 -0
- package/dist/commands/share.js +275 -12
- package/dist/commands/skills.js +0 -11
- package/dist/commands/snapshot.js +1 -1
- package/dist/commands/ssh.d.ts +18 -0
- package/dist/commands/ssh.js +549 -210
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +212 -32
- package/dist/commands/teams.d.ts +13 -0
- package/dist/commands/teams.js +187 -30
- package/dist/commands/tickets.d.ts +2 -0
- package/dist/commands/tickets.js +43 -0
- package/dist/commands/update.js +2 -4
- package/dist/commands/usage.js +5 -3
- package/dist/commands/versions.js +11 -5
- package/dist/commands/view.js +15 -7
- package/dist/commands/webhook.d.ts +2 -2
- package/dist/commands/webhook.js +7 -7
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -1264
- package/dist/lib/account-catalog.d.ts +18 -0
- package/dist/lib/account-catalog.js +38 -0
- package/dist/lib/account-provider-registry.d.ts +18 -0
- package/dist/lib/account-provider-registry.js +59 -0
- package/dist/lib/account-registry.d.ts +40 -0
- package/dist/lib/account-registry.js +239 -0
- package/dist/lib/account-schema.d.ts +44 -0
- package/dist/lib/account-schema.js +91 -0
- package/dist/lib/account-state-service.d.ts +21 -0
- package/dist/lib/account-state-service.js +60 -0
- package/dist/lib/activity.d.ts +1 -1
- package/dist/lib/activity.js +8 -1
- package/dist/lib/add-dir.d.ts +80 -0
- package/dist/lib/add-dir.js +241 -0
- package/dist/lib/agent-cli-commands.d.ts +11 -0
- package/dist/lib/agent-cli-commands.js +30 -0
- package/dist/lib/agents.js +44 -36
- package/dist/lib/answer-router.js +1 -1
- package/dist/lib/audit/log.d.ts +10 -27
- package/dist/lib/audit/log.js +20 -33
- package/dist/lib/auth-health.d.ts +9 -2
- package/dist/lib/auth-health.js +42 -9
- package/dist/lib/auto-pull-worker.js +7 -3
- package/dist/lib/auto-pull.d.ts +44 -3
- package/dist/lib/auto-pull.js +88 -5
- package/dist/lib/binary-shadow.d.ts +28 -0
- package/dist/lib/binary-shadow.js +121 -0
- package/dist/lib/brand.js +9 -3
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +81 -4
- package/dist/lib/browser/profiles.d.ts +3 -2
- package/dist/lib/browser/profiles.js +65 -22
- package/dist/lib/browser/service.d.ts +4 -0
- package/dist/lib/browser/service.js +30 -3
- package/dist/lib/browser/sessions-list.d.ts +22 -2
- package/dist/lib/browser/sessions-list.js +54 -6
- package/dist/lib/browser/stream.d.ts +2 -0
- package/dist/lib/browser/stream.js +1 -0
- package/dist/lib/browser/types.d.ts +19 -0
- package/dist/lib/byok-usage.d.ts +9 -2
- package/dist/lib/byok-usage.js +133 -31
- package/dist/lib/cli-entry.d.ts +11 -0
- package/dist/lib/cli-entry.js +46 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +2 -2
- package/dist/lib/cloud/registry.js +1 -1
- package/dist/lib/cloud/types.d.ts +1 -1
- package/dist/lib/commands.d.ts +2 -0
- package/dist/lib/commands.js +2 -0
- package/dist/lib/computer/sessions-list.d.ts +150 -0
- package/dist/lib/computer/sessions-list.js +363 -0
- package/dist/lib/config-keys.d.ts +86 -0
- package/dist/lib/config-keys.js +193 -0
- package/dist/lib/config-machine-keys.d.ts +12 -0
- package/dist/lib/config-machine-keys.js +17 -0
- package/dist/lib/config-transfer.js +3 -4
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/cli.js +3 -3
- package/dist/lib/daemon-health.d.ts +22 -0
- package/dist/lib/daemon-health.js +33 -3
- package/dist/lib/daemon-services.d.ts +50 -0
- package/dist/lib/daemon-services.js +147 -0
- package/dist/lib/daemon-ticks.d.ts +35 -66
- package/dist/lib/daemon-ticks.js +77 -159
- package/dist/lib/daemon.d.ts +72 -4
- package/dist/lib/daemon.js +792 -202
- package/dist/lib/deeplink/register.d.ts +49 -0
- package/dist/lib/deeplink/register.js +253 -0
- package/dist/lib/deeplink/url.d.ts +34 -0
- package/dist/lib/deeplink/url.js +78 -0
- package/dist/lib/device-config.d.ts +124 -29
- package/dist/lib/device-config.js +346 -141
- package/dist/lib/devices/config-migration.d.ts +42 -0
- package/dist/lib/devices/config-migration.js +203 -0
- package/dist/lib/devices/connect.js +14 -7
- package/dist/lib/devices/doctor-findings.d.ts +4 -1
- package/dist/lib/devices/doctor-findings.js +20 -1
- package/dist/lib/devices/harness-inventory.d.ts +11 -2
- package/dist/lib/devices/harness-inventory.js +0 -0
- package/dist/lib/devices/health.d.ts +1 -1
- package/dist/lib/devices/health.js +1 -1
- package/dist/lib/devices/pending.d.ts +22 -1
- package/dist/lib/devices/pending.js +67 -2
- package/dist/lib/devices/registry.d.ts +0 -25
- package/dist/lib/devices/registry.js +2 -83
- package/dist/lib/devices/resolve-profile.d.ts +20 -0
- package/dist/lib/devices/resolve-profile.js +44 -0
- package/dist/lib/devices/rollout-verify.d.ts +101 -0
- package/dist/lib/devices/rollout-verify.js +193 -0
- package/dist/lib/devices/ssh-config.js +10 -6
- package/dist/lib/event-families.d.ts +28 -0
- package/dist/lib/event-families.js +159 -0
- package/dist/lib/event-stream.d.ts +9 -1
- package/dist/lib/event-stream.js +26 -9
- package/dist/lib/events.d.ts +9 -1
- package/dist/lib/events.js +21 -6
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +219 -121
- package/dist/lib/feed-broadcast.d.ts +25 -0
- package/dist/lib/feed-broadcast.js +33 -0
- package/dist/lib/feed.d.ts +1 -1
- package/dist/lib/feed.js +12 -2
- package/dist/lib/fleet/capture.js +15 -0
- package/dist/lib/fleet/manifest.js +9 -0
- package/dist/lib/fleet/types.d.ts +9 -0
- package/dist/lib/fleet-status.js +10 -8
- package/dist/lib/git.d.ts +20 -6
- package/dist/lib/git.js +121 -17
- package/dist/lib/hosts/dispatch.d.ts +8 -3
- package/dist/lib/hosts/dispatch.js +29 -3
- package/dist/lib/hosts/logs.d.ts +2 -2
- package/dist/lib/hosts/logs.js +2 -2
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.d.ts +2 -3
- package/dist/lib/hosts/passthrough.js +10 -24
- package/dist/lib/hosts/progress.js +2 -2
- package/dist/lib/hosts/providers/devices.d.ts +3 -3
- package/dist/lib/hosts/providers/devices.js +18 -12
- package/dist/lib/hosts/ready.d.ts +5 -1
- package/dist/lib/hosts/ready.js +9 -3
- package/dist/lib/hosts/reconcile.d.ts +2 -2
- package/dist/lib/hosts/reconcile.js +2 -2
- package/dist/lib/hosts/registry.js +14 -9
- package/dist/lib/hosts/remote-cmd.js +1 -1
- package/dist/lib/hosts/remote-os.d.ts +9 -6
- package/dist/lib/hosts/remote-os.js +13 -6
- package/dist/lib/hosts/routing-flag.d.ts +23 -0
- package/dist/lib/hosts/routing-flag.js +41 -0
- package/dist/lib/hosts/run-target.js +1 -1
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/tasks.d.ts +6 -6
- package/dist/lib/hosts/tasks.js +4 -4
- package/dist/lib/hosts/types.js +1 -2
- package/dist/lib/installations/resolve.js +2 -8
- package/dist/lib/isolation-boundary-report.js +0 -1
- package/dist/lib/linear-cache.d.ts +7 -0
- package/dist/lib/linear-cache.js +31 -4
- package/dist/lib/linear-project-counts.d.ts +1 -1
- package/dist/lib/linear-project-counts.js +2 -3
- package/dist/lib/linear-projects.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-target.d.ts +1 -1
- package/dist/lib/mailbox-target.js +1 -1
- package/dist/lib/manifest.js +7 -4
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/snapshot.d.ts +3 -2
- package/dist/lib/menubar/snapshot.js +6 -2
- package/dist/lib/migrate-fold.d.ts +33 -0
- package/dist/lib/migrate-fold.js +130 -0
- package/dist/lib/migrate.d.ts +34 -34
- package/dist/lib/migrate.js +106 -128
- package/dist/lib/model-tier-overrides.d.ts +1 -1
- package/dist/lib/model-tier-overrides.js +15 -2
- package/dist/lib/monitors/config.d.ts +17 -3
- package/dist/lib/monitors/config.js +52 -18
- package/dist/lib/monitors/engine.d.ts +32 -1
- package/dist/lib/monitors/engine.js +94 -11
- package/dist/lib/monitors/fingerprint.d.ts +46 -0
- package/dist/lib/monitors/fingerprint.js +100 -0
- package/dist/lib/monitors/remote.d.ts +47 -0
- package/dist/lib/monitors/remote.js +81 -0
- package/dist/lib/monitors/state.d.ts +39 -0
- package/dist/lib/monitors/state.js +56 -0
- package/dist/lib/onepassword.d.ts +17 -0
- package/dist/lib/onepassword.js +52 -22
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/picker.d.ts +14 -2
- package/dist/lib/picker.js +35 -13
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +1 -1
- package/dist/lib/pr-land-detach.d.ts +32 -0
- package/dist/lib/pr-land-detach.js +79 -0
- package/dist/lib/profiles-presets.js +13 -0
- package/dist/lib/profiles.d.ts +2 -0
- package/dist/lib/profiles.js +44 -1
- package/dist/lib/project-focus.d.ts +1 -1
- package/dist/lib/project-focus.js +1 -1
- package/dist/lib/project-probe.d.ts +4 -1
- package/dist/lib/project-probe.js +5 -4
- package/dist/lib/project-resources.js +2 -18
- package/dist/lib/project-root.d.ts +16 -0
- package/dist/lib/project-root.js +20 -2
- package/dist/lib/projects.d.ts +20 -1
- package/dist/lib/projects.js +78 -1
- package/dist/lib/refresh-coordinator.d.ts +24 -0
- package/dist/lib/refresh-coordinator.js +52 -0
- package/dist/lib/registry.d.ts +2 -2
- package/dist/lib/registry.js +1 -1
- package/dist/lib/resource-aliases.d.ts +13 -0
- package/dist/lib/resource-aliases.js +26 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +16 -0
- package/dist/lib/resources.js +66 -10
- package/dist/lib/rotate.d.ts +3 -4
- package/dist/lib/rotate.js +4 -5
- package/dist/lib/routine-activation.d.ts +22 -2
- package/dist/lib/routine-activation.js +63 -16
- package/dist/lib/routine-context.d.ts +9 -2
- package/dist/lib/routine-context.js +21 -6
- package/dist/lib/routines-project.d.ts +58 -48
- package/dist/lib/routines-project.js +190 -159
- package/dist/lib/routines.d.ts +41 -6
- package/dist/lib/routines.js +92 -34
- package/dist/lib/run-defaults.d.ts +5 -0
- package/dist/lib/run-defaults.js +11 -1
- package/dist/lib/runner.d.ts +10 -8
- package/dist/lib/runner.js +122 -39
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.d.ts +10 -3
- package/dist/lib/secrets/agent.js +43 -8
- package/dist/lib/secrets/bundles.d.ts +1 -0
- package/dist/lib/secrets/bundles.js +92 -80
- package/dist/lib/secrets/index.js +32 -9
- package/dist/lib/secrets/install-helper.d.ts +4 -4
- package/dist/lib/secrets/install-helper.js +4 -4
- package/dist/lib/secrets/push.d.ts +40 -6
- package/dist/lib/secrets/push.js +58 -11
- package/dist/lib/secrets/read-backoff.d.ts +1 -1
- package/dist/lib/secrets/read-backoff.js +1 -1
- package/dist/lib/secrets/remote.d.ts +24 -0
- package/dist/lib/secrets/remote.js +54 -4
- package/dist/lib/self-update.d.ts +108 -0
- package/dist/lib/self-update.js +276 -1
- package/dist/lib/session/active.d.ts +89 -5
- package/dist/lib/session/active.js +165 -10
- package/dist/lib/session/actor-sidecar.d.ts +1 -1
- package/dist/lib/session/actor-sidecar.js +2 -1
- package/dist/lib/session/db.d.ts +176 -2
- package/dist/lib/session/db.js +484 -17
- package/dist/lib/session/discover.js +27 -4
- package/dist/lib/session/hook-sessions.js +2 -2
- package/dist/lib/session/host-link.d.ts +2 -2
- package/dist/lib/session/host-link.js +2 -2
- package/dist/lib/session/pid-registry.d.ts +21 -0
- package/dist/lib/session/pid-registry.js +57 -0
- package/dist/lib/session/remote-active.js +15 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/session-cache.d.ts +14 -7
- package/dist/lib/session/session-cache.js +51 -9
- package/dist/lib/session/state.d.ts +2 -2
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/sync/config.d.ts +10 -10
- package/dist/lib/session/sync/config.js +10 -10
- package/dist/lib/session/sync/r2.d.ts +34 -0
- package/dist/lib/session/sync/r2.js +123 -0
- package/dist/lib/session/throughput.d.ts +1 -1
- package/dist/lib/session/throughput.js +1 -1
- package/dist/lib/session/types.d.ts +23 -1
- package/dist/lib/session/types.js +15 -0
- package/dist/lib/session/viewing-in.d.ts +1 -1
- package/dist/lib/session/viewing-in.js +1 -1
- package/dist/lib/session/watch.d.ts +101 -0
- package/dist/lib/session/watch.js +242 -0
- package/dist/lib/share/config.d.ts +4 -0
- package/dist/lib/share/config.js +1 -0
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +50 -0
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +116 -3
- package/dist/lib/share/worker-template.js +71 -6
- package/dist/lib/shims.d.ts +17 -3
- package/dist/lib/shims.js +98 -26
- package/dist/lib/signin-badge.js +3 -2
- package/dist/lib/skills.js +2 -0
- package/dist/lib/smart-launch.d.ts +8 -8
- package/dist/lib/smart-launch.js +80 -59
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +1 -1
- package/dist/lib/staleness/prune.d.ts +88 -0
- package/dist/lib/staleness/prune.js +69 -0
- package/dist/lib/staleness/registry.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.js +34 -2
- package/dist/lib/staleness/writers/hooks.js +16 -0
- package/dist/lib/staleness/writers/kinds.d.ts +6 -0
- package/dist/lib/staleness/writers/skills.js +19 -0
- package/dist/lib/staleness/writers/subagents.d.ts +2 -3
- package/dist/lib/staleness/writers/subagents.js +0 -4
- package/dist/lib/staleness/writers/types.d.ts +32 -0
- package/dist/lib/startup/command-registry.d.ts +6 -12
- package/dist/lib/startup/command-registry.js +11 -31
- package/dist/lib/startup/dev-build.d.ts +10 -0
- package/dist/lib/startup/dev-build.js +13 -1
- package/dist/lib/startup/spellcheck.d.ts +18 -0
- package/dist/lib/startup/spellcheck.js +45 -0
- package/dist/lib/state.d.ts +36 -9
- package/dist/lib/state.js +96 -46
- package/dist/lib/subagents-registry.d.ts +0 -7
- package/dist/lib/subagents-registry.js +38 -65
- package/dist/lib/subagents.d.ts +0 -33
- package/dist/lib/subagents.js +0 -75
- package/dist/lib/sync-umbrella.js +1 -1
- package/dist/lib/teams/agents.d.ts +41 -1
- package/dist/lib/teams/agents.js +187 -9
- package/dist/lib/teams/api.d.ts +11 -1
- package/dist/lib/teams/api.js +11 -2
- package/dist/lib/teams/delivery.d.ts +41 -0
- package/dist/lib/teams/delivery.js +60 -0
- package/dist/lib/teams/registry.d.ts +14 -0
- package/dist/lib/teams/registry.js +51 -1
- package/dist/lib/teams/remoteWorktree.d.ts +19 -0
- package/dist/lib/teams/remoteWorktree.js +29 -0
- package/dist/lib/teams/scheduler.d.ts +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/teams/worktree.d.ts +24 -0
- package/dist/lib/teams/worktree.js +42 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
- package/dist/lib/terminal/engine.d.ts +4 -0
- package/dist/lib/terminal/engine.js +8 -2
- package/dist/lib/terminal/types.d.ts +21 -2
- package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
- package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
- package/dist/lib/tickets/list.d.ts +53 -0
- package/dist/lib/tickets/list.js +153 -0
- package/dist/lib/tmux/orphan-reap.d.ts +320 -0
- package/dist/lib/tmux/orphan-reap.js +644 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +95 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +6 -1
- package/dist/lib/types.d.ts +46 -34
- package/dist/lib/usage-fleet.d.ts +32 -0
- package/dist/lib/usage-fleet.js +125 -0
- package/dist/lib/usage-refresh.d.ts +3 -3
- package/dist/lib/usage-refresh.js +19 -16
- package/dist/lib/usage.d.ts +51 -47
- package/dist/lib/usage.js +145 -153
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/versions.d.ts +56 -13
- package/dist/lib/versions.js +195 -45
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +3 -3
- package/dist/lib/watchdog/rotate.d.ts +6 -6
- package/dist/lib/watchdog/rotate.js +6 -6
- package/dist/lib/workflows.d.ts +1 -1
- package/dist/lib/yaml-io.d.ts +47 -0
- package/dist/lib/yaml-io.js +55 -0
- package/package.json +2 -1
- package/scripts/install-helper.js +2 -2
- package/scripts/postinstall.js +23 -20
- package/dist/commands/defaults.d.ts +0 -7
- package/dist/commands/defaults.js +0 -107
- package/dist/commands/export.d.ts +0 -11
- package/dist/commands/export.js +0 -215
- package/dist/commands/helper.d.ts +0 -12
- package/dist/commands/helper.js +0 -87
- package/dist/commands/hosts.d.ts +0 -11
- package/dist/commands/hosts.js +0 -330
- package/dist/commands/lock.d.ts +0 -12
- package/dist/commands/lock.js +0 -70
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/pull.js +0 -39
- package/dist/commands/push.d.ts +0 -14
- package/dist/commands/push.js +0 -30
- package/dist/commands/wallet.d.ts +0 -20
- package/dist/commands/wallet.js +0 -216
- package/dist/commands/worktree.d.ts +0 -19
- package/dist/commands/worktree.js +0 -272
- package/dist/lib/account-labels.d.ts +0 -24
- package/dist/lib/account-labels.js +0 -72
- package/dist/lib/auto-dispatch-linear.d.ts +0 -18
- package/dist/lib/auto-dispatch-linear.js +0 -107
- package/dist/lib/auto-dispatch-provider.d.ts +0 -10
- package/dist/lib/auto-dispatch-provider.js +0 -30
- package/dist/lib/auto-dispatch.d.ts +0 -93
- package/dist/lib/auto-dispatch.js +0 -128
- package/dist/lib/export.d.ts +0 -72
- package/dist/lib/export.js +0 -269
- package/dist/lib/lock.d.ts +0 -93
- package/dist/lib/lock.js +0 -207
- package/dist/lib/wallet/index.d.ts +0 -78
- package/dist/lib/wallet/index.js +0 -253
package/dist/lib/onepassword.js
CHANGED
|
@@ -79,6 +79,7 @@ const IMPORTABLE_FIELD_TYPES = new Set([
|
|
|
79
79
|
'URL', 'url',
|
|
80
80
|
]);
|
|
81
81
|
const SKIP_FIELD_LABELS = new Set(['username', 'notesPlain', 'notes']);
|
|
82
|
+
const NOTES_FIELD_LABELS = new Set(['notesplain', 'notes']);
|
|
82
83
|
function pickBestField(fields) {
|
|
83
84
|
const dominated = fields.filter((f) => IMPORTABLE_FIELD_TYPES.has(f.type) &&
|
|
84
85
|
f.value &&
|
|
@@ -97,6 +98,52 @@ function pickBestField(fields) {
|
|
|
97
98
|
// Fall back to first importable field
|
|
98
99
|
return dominated[0];
|
|
99
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* The item's notes, if any — a NOTES-purpose field (1Password's `notesPlain`)
|
|
103
|
+
* or a field labelled notes/notesPlain, whichever carries a non-empty value.
|
|
104
|
+
* Returns undefined when the item has no notes. This is descriptive metadata
|
|
105
|
+
* only; it is deliberately independent of value selection and is never picked
|
|
106
|
+
* as the secret value (see SKIP_FIELD_LABELS / pickBestField).
|
|
107
|
+
*/
|
|
108
|
+
function pickNotes(fields) {
|
|
109
|
+
const notes = fields.find((f) => f.value != null &&
|
|
110
|
+
f.value.trim() !== '' &&
|
|
111
|
+
(f.purpose?.toUpperCase() === 'NOTES' ||
|
|
112
|
+
NOTES_FIELD_LABELS.has(f.label?.toLowerCase() || '')));
|
|
113
|
+
const value = notes?.value?.trim();
|
|
114
|
+
return value ? value : undefined;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Pure transform from a fetched 1Password item to an importable secret (or the
|
|
118
|
+
* reason it was skipped). Split out of extractSecrets so the field-selection
|
|
119
|
+
* and notes-extraction logic is exercised directly by tests without shelling
|
|
120
|
+
* out to `op`.
|
|
121
|
+
*/
|
|
122
|
+
export function itemToSecret(item) {
|
|
123
|
+
const field = pickBestField(item.fields || []);
|
|
124
|
+
if (!field) {
|
|
125
|
+
return { skipped: { itemTitle: item.title, fieldLabel: '*', reason: 'no importable fields' } };
|
|
126
|
+
}
|
|
127
|
+
if (field.value.includes('\n')) {
|
|
128
|
+
return {
|
|
129
|
+
skipped: {
|
|
130
|
+
itemTitle: item.title,
|
|
131
|
+
fieldLabel: field.label,
|
|
132
|
+
reason: 'contains newlines (keychain limitation)',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const secret = {
|
|
137
|
+
envKey: toEnvKey(item.title),
|
|
138
|
+
itemTitle: item.title,
|
|
139
|
+
fieldLabel: field.label,
|
|
140
|
+
value: field.value,
|
|
141
|
+
};
|
|
142
|
+
const description = pickNotes(item.fields || []);
|
|
143
|
+
if (description)
|
|
144
|
+
secret.description = description;
|
|
145
|
+
return { secret };
|
|
146
|
+
}
|
|
100
147
|
export function extractSecrets(items, vaultName) {
|
|
101
148
|
const secrets = [];
|
|
102
149
|
const skipped = [];
|
|
@@ -113,30 +160,13 @@ export function extractSecrets(items, vaultName) {
|
|
|
113
160
|
});
|
|
114
161
|
continue;
|
|
115
162
|
}
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
skipped.push(
|
|
119
|
-
itemTitle: item.title,
|
|
120
|
-
fieldLabel: '*',
|
|
121
|
-
reason: 'no importable fields',
|
|
122
|
-
});
|
|
123
|
-
continue;
|
|
163
|
+
const result = itemToSecret(item);
|
|
164
|
+
if ('skipped' in result) {
|
|
165
|
+
skipped.push(result.skipped);
|
|
124
166
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
itemTitle: item.title,
|
|
128
|
-
fieldLabel: field.label,
|
|
129
|
-
reason: 'contains newlines (keychain limitation)',
|
|
130
|
-
});
|
|
131
|
-
continue;
|
|
167
|
+
else {
|
|
168
|
+
secrets.push(result.secret);
|
|
132
169
|
}
|
|
133
|
-
const envKey = toEnvKey(item.title);
|
|
134
|
-
secrets.push({
|
|
135
|
-
envKey,
|
|
136
|
-
itemTitle: item.title,
|
|
137
|
-
fieldLabel: field.label,
|
|
138
|
-
value: field.value,
|
|
139
|
-
});
|
|
140
170
|
}
|
|
141
171
|
return { secrets, skipped };
|
|
142
172
|
}
|
package/dist/lib/open-url.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Open a URL in the user's default browser, cross-platform. Best-effort and
|
|
3
|
-
* detached — never throws and never blocks the caller. Shared by `agents lease`
|
|
3
|
+
* detached — never throws and never blocks the caller. Shared by `agents devices lease`
|
|
4
4
|
* (Hetzner console) and `agents fleet login` (the local login dashboard).
|
|
5
5
|
*/
|
|
6
6
|
import { spawn } from 'child_process';
|
package/dist/lib/picker.d.ts
CHANGED
|
@@ -5,13 +5,25 @@
|
|
|
5
5
|
* for selecting items in the terminal. Used by session picker, command
|
|
6
6
|
* picker, and other interactive selection flows.
|
|
7
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Custom inquirer prompt for searchable, scrollable selection lists.
|
|
10
|
+
*
|
|
11
|
+
* Extends @inquirer/core to support type-ahead filtering, column-aligned
|
|
12
|
+
* display, and keyboard navigation. Used by sessions, teams, and other
|
|
13
|
+
* interactive pickers throughout the CLI.
|
|
14
|
+
*/
|
|
15
|
+
import { Separator } from '@inquirer/core';
|
|
8
16
|
/** Configuration for the interactive picker prompt. */
|
|
9
17
|
export interface PickerConfig<T> {
|
|
10
18
|
message: string;
|
|
11
19
|
/** Optional dim hint line rendered directly under the header (above the rows). */
|
|
12
20
|
subtitle?: string;
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The row pool. A {@link Separator} entry renders as a non-selectable divider
|
|
23
|
+
* (used for group headers) — navigation skips it and it is never returned.
|
|
24
|
+
*/
|
|
25
|
+
items: Array<T | Separator>;
|
|
26
|
+
filter: (query: string) => Array<T | Separator>;
|
|
15
27
|
labelFor: (item: T, query: string) => string;
|
|
16
28
|
buildPreview?: (item: T) => string;
|
|
17
29
|
shortIdFor?: (item: T) => string;
|
package/dist/lib/picker.js
CHANGED
|
@@ -139,17 +139,39 @@ export function itemPicker(config) {
|
|
|
139
139
|
const prefix = usePrefix({ status, theme });
|
|
140
140
|
const results = useMemo(() => {
|
|
141
141
|
const filtered = cfg.filter(searchTerm).slice(0, 50);
|
|
142
|
-
return filtered.map((item) => (
|
|
143
|
-
|
|
144
|
-
label: cfg.labelFor(item, searchTerm)
|
|
145
|
-
}));
|
|
142
|
+
return filtered.map((item) => Separator.isSeparator(item)
|
|
143
|
+
? item
|
|
144
|
+
: { value: item, label: cfg.labelFor(item, searchTerm) });
|
|
146
145
|
}, [searchTerm]);
|
|
146
|
+
// A row is selectable unless it is a divider (Separator). Navigation and the
|
|
147
|
+
// initial cursor skip dividers, and enter never resolves one.
|
|
148
|
+
const isSelectable = (i) => i >= 0 && i < results.length && !Separator.isSeparator(results[i]);
|
|
149
|
+
const firstSelectable = () => {
|
|
150
|
+
for (let i = 0; i < results.length; i++)
|
|
151
|
+
if (isSelectable(i))
|
|
152
|
+
return i;
|
|
153
|
+
return -1;
|
|
154
|
+
};
|
|
155
|
+
const nextSelectable = (from, dir) => {
|
|
156
|
+
if (results.length === 0)
|
|
157
|
+
return -1;
|
|
158
|
+
let i = from;
|
|
159
|
+
for (let n = 0; n < results.length; n++) {
|
|
160
|
+
i = (i + dir + results.length) % results.length;
|
|
161
|
+
if (isSelectable(i))
|
|
162
|
+
return i;
|
|
163
|
+
}
|
|
164
|
+
return -1;
|
|
165
|
+
};
|
|
147
166
|
const [active, setActive] = useState(0);
|
|
167
|
+
// Keep the cursor on a selectable row: after a filter change the old index can
|
|
168
|
+
// land past the end or on a divider, so snap to the first selectable row.
|
|
148
169
|
useEffect(() => {
|
|
149
|
-
if (active
|
|
150
|
-
setActive(
|
|
170
|
+
if (!isSelectable(active))
|
|
171
|
+
setActive(firstSelectable());
|
|
151
172
|
}, [results]);
|
|
152
|
-
const
|
|
173
|
+
const activeRow = results[active];
|
|
174
|
+
const selected = activeRow && !Separator.isSeparator(activeRow) ? activeRow : undefined;
|
|
153
175
|
useKeypress((key, rl) => {
|
|
154
176
|
if (isEnterKey(key)) {
|
|
155
177
|
if (selected) {
|
|
@@ -165,16 +187,16 @@ export function itemPicker(config) {
|
|
|
165
187
|
}
|
|
166
188
|
if (isUpKey(key)) {
|
|
167
189
|
rl.clearLine(0);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
const target = nextSelectable(active, -1);
|
|
191
|
+
if (target >= 0)
|
|
192
|
+
setActive(target);
|
|
171
193
|
return;
|
|
172
194
|
}
|
|
173
195
|
if (isDownKey(key)) {
|
|
174
196
|
rl.clearLine(0);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
197
|
+
const target = nextSelectable(active, 1);
|
|
198
|
+
if (target >= 0)
|
|
199
|
+
setActive(target);
|
|
178
200
|
return;
|
|
179
201
|
}
|
|
180
202
|
setSearchTerm(rl.line);
|
package/dist/lib/placement.d.ts
CHANGED
|
@@ -81,6 +81,6 @@ export declare function placementFromHostStrategy(strategy: 'local' | 'host' | '
|
|
|
81
81
|
/** One-line human form for logs / help. */
|
|
82
82
|
export declare function formatPlacement(p: Placement): string;
|
|
83
83
|
/**
|
|
84
|
-
* Short matrix for help footers and docs. Keep in sync with
|
|
84
|
+
* Short matrix for help footers and docs. Keep in sync with concepts.md.
|
|
85
85
|
*/
|
|
86
86
|
export declare const PLACEMENT_MATRIX: string;
|
package/dist/lib/placement.js
CHANGED
|
@@ -176,7 +176,7 @@ export function formatPlacement(p) {
|
|
|
176
176
|
return p.kind;
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
|
-
* Short matrix for help footers and docs. Keep in sync with
|
|
179
|
+
* Short matrix for help footers and docs. Keep in sync with concepts.md.
|
|
180
180
|
*/
|
|
181
181
|
export const PLACEMENT_MATRIX = `
|
|
182
182
|
Intent Flag / path
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot of the current branch's open PR (if any), for the headless-exit
|
|
3
|
+
* fail-loud path. Returns null when there is no open PR or `gh` cannot answer.
|
|
4
|
+
*/
|
|
5
|
+
export interface BranchOpenPr {
|
|
6
|
+
number: number;
|
|
7
|
+
url: string;
|
|
8
|
+
state: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pure classifier: should the exit path warn about this open PR?
|
|
12
|
+
* Warn when the PR exists and is still OPEN.
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldWarnOrphanedOpenPr(pr: BranchOpenPr | null): boolean;
|
|
15
|
+
/** Human-readable warning for an open PR the exiting run left unattended. */
|
|
16
|
+
export declare function formatOrphanedOpenPrWarning(pr: BranchOpenPr): string;
|
|
17
|
+
/**
|
|
18
|
+
* Probe `cwd` for an open PR on the current branch via `gh pr view`.
|
|
19
|
+
* Fail-open: any error / missing gh → null (never block the run's exit).
|
|
20
|
+
*/
|
|
21
|
+
export declare function getBranchOpenPr(cwd: string, execFileAsync: (file: string, args: string[], opts: {
|
|
22
|
+
cwd: string;
|
|
23
|
+
timeout: number;
|
|
24
|
+
maxBuffer: number;
|
|
25
|
+
}) => Promise<{
|
|
26
|
+
stdout: string;
|
|
27
|
+
}>): Promise<BranchOpenPr | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Headless-exit fail-loud: if the cwd's branch has an OPEN PR, print a loud
|
|
30
|
+
* stderr warning. Never throws.
|
|
31
|
+
*/
|
|
32
|
+
export declare function warnOrphanedOpenPr(cwd?: string): Promise<void>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless-exit warning for an open PR left behind by a run (RUSH-2394).
|
|
3
|
+
*
|
|
4
|
+
* A headless agent that backgrounds `gh pr checks --watch` and exits strands its
|
|
5
|
+
* own PR: that watcher is a child of the agent's process tree, so it dies with
|
|
6
|
+
* the agent and nothing merges on green. This module is the fail-loud half of
|
|
7
|
+
* that story — it probes the run's branch for an OPEN PR on exit and says so.
|
|
8
|
+
*
|
|
9
|
+
* The `agents pr land --detach` lander this warning used to point at was removed
|
|
10
|
+
* with the `agents pr` command group (RUSH-2472): merge-on-green is a monitor
|
|
11
|
+
* (`agents monitors`), not a bespoke command with its own scheduler. The
|
|
12
|
+
* reusable CI/review polling it will run on lives in lib/teams/pr-watch.ts, so
|
|
13
|
+
* this module keeps only the exit-path warning and names no specific command.
|
|
14
|
+
*/
|
|
15
|
+
import { execFile } from 'child_process';
|
|
16
|
+
import { promisify } from 'util';
|
|
17
|
+
const execFileAsyncDefault = promisify(execFile);
|
|
18
|
+
/**
|
|
19
|
+
* Pure classifier: should the exit path warn about this open PR?
|
|
20
|
+
* Warn when the PR exists and is still OPEN.
|
|
21
|
+
*/
|
|
22
|
+
export function shouldWarnOrphanedOpenPr(pr) {
|
|
23
|
+
if (!pr)
|
|
24
|
+
return false;
|
|
25
|
+
return pr.state.toUpperCase() === 'OPEN';
|
|
26
|
+
}
|
|
27
|
+
/** Human-readable warning for an open PR the exiting run left unattended. */
|
|
28
|
+
export function formatOrphanedOpenPrWarning(pr) {
|
|
29
|
+
const lines = [
|
|
30
|
+
'',
|
|
31
|
+
chalkRed('WARNING: open PR left unattended (RUSH-2394)'),
|
|
32
|
+
` ${pr.url}`,
|
|
33
|
+
` PR #${pr.number} is still OPEN and nothing is watching it. A background`,
|
|
34
|
+
' `gh pr checks --watch` child dies when a headless agent exits, so the PR',
|
|
35
|
+
' will sit green and unmerged.',
|
|
36
|
+
' Merge it once CI is green and a non-author review has cleared it, or set up',
|
|
37
|
+
' a merge-on-green monitor (`agents monitors`) that outlives this process.',
|
|
38
|
+
'',
|
|
39
|
+
];
|
|
40
|
+
return lines.join('\n');
|
|
41
|
+
}
|
|
42
|
+
/** Tiny chalk-free red for environments where chalk is not wanted on the exit path. */
|
|
43
|
+
function chalkRed(s) {
|
|
44
|
+
// Match warn-unpushed: bold red when stderr is a TTY; plain otherwise.
|
|
45
|
+
if (process.stderr.isTTY)
|
|
46
|
+
return `\u001b[1m\u001b[31m${s}\u001b[0m`;
|
|
47
|
+
return s;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Probe `cwd` for an open PR on the current branch via `gh pr view`.
|
|
51
|
+
* Fail-open: any error / missing gh → null (never block the run's exit).
|
|
52
|
+
*/
|
|
53
|
+
export async function getBranchOpenPr(cwd, execFileAsync) {
|
|
54
|
+
try {
|
|
55
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'view', '--json', 'number,url,state'], { cwd, timeout: 5000, maxBuffer: 512 * 1024 });
|
|
56
|
+
const raw = JSON.parse(stdout);
|
|
57
|
+
if (!raw?.number || !raw?.url || !raw?.state)
|
|
58
|
+
return null;
|
|
59
|
+
return { number: Number(raw.number), url: String(raw.url), state: String(raw.state) };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Headless-exit fail-loud: if the cwd's branch has an OPEN PR, print a loud
|
|
67
|
+
* stderr warning. Never throws.
|
|
68
|
+
*/
|
|
69
|
+
export async function warnOrphanedOpenPr(cwd = process.cwd()) {
|
|
70
|
+
try {
|
|
71
|
+
const pr = await getBranchOpenPr(cwd, (file, args, opts) => execFileAsyncDefault(file, args, opts).then((r) => ({ stdout: String(r.stdout ?? '') })));
|
|
72
|
+
if (!shouldWarnOrphanedOpenPr(pr))
|
|
73
|
+
return;
|
|
74
|
+
process.stderr.write(formatOrphanedOpenPrWarning(pr));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Advisory only — never break the run's exit.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -190,6 +190,19 @@ export const PRESETS = [
|
|
|
190
190
|
ANTHROPIC_SMALL_FAST_MODEL: 'claude-3-5-haiku-latest',
|
|
191
191
|
},
|
|
192
192
|
},
|
|
193
|
+
{
|
|
194
|
+
name: 'deepinfra',
|
|
195
|
+
description: 'DeepInfra direct API through its OpenAI-compatible endpoint, hosted by Codex.',
|
|
196
|
+
provider: 'deepinfra',
|
|
197
|
+
host: 'codex',
|
|
198
|
+
authEnvVar: 'OPENAI_API_KEY',
|
|
199
|
+
signupUrl: 'https://deepinfra.com/dash/api_keys',
|
|
200
|
+
docPath: 'deepinfra',
|
|
201
|
+
env: {
|
|
202
|
+
OPENAI_BASE_URL: 'https://api.deepinfra.com/v1/openai',
|
|
203
|
+
OPENAI_MODEL: 'deepseek-ai/DeepSeek-V3',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
193
206
|
// ----- Gateway / enterprise / self-hosted -----
|
|
194
207
|
{
|
|
195
208
|
name: 'proxy',
|
package/dist/lib/profiles.d.ts
CHANGED
package/dist/lib/profiles.js
CHANGED
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import * as fs from 'fs';
|
|
9
9
|
import * as path from 'path';
|
|
10
|
+
import * as crypto from 'node:crypto';
|
|
10
11
|
import * as yaml from 'yaml';
|
|
11
12
|
import { getUserAgentsDir } from './state.js';
|
|
12
|
-
import { getKeychainToken, hasKeychainToken, keychainItemName } from './secrets/profiles.js';
|
|
13
|
+
import { deleteKeychainToken, getKeychainToken, hasKeychainToken, keychainItemName } from './secrets/profiles.js';
|
|
13
14
|
import { getPreset } from './profiles-presets.js';
|
|
14
15
|
import { MODEL_TIERS, isTierToken } from './model-tiers.js';
|
|
16
|
+
import { addAccount, findAccount, resolveCredentialAccount } from './account-registry.js';
|
|
17
|
+
import { atomicWriteFileSync } from './fs-atomic.js';
|
|
18
|
+
import { listAccountProviders } from './account-provider-registry.js';
|
|
15
19
|
const PROFILE_NAME_PATTERN = /^[a-z0-9][a-z0-9-_]{0,48}$/i;
|
|
16
20
|
/** Get the directory where profile YAML files are stored. */
|
|
17
21
|
export function getProfilesDir() {
|
|
@@ -55,8 +59,43 @@ export function readProfile(name) {
|
|
|
55
59
|
if (!parsed.env || typeof parsed.env !== 'object') {
|
|
56
60
|
parsed.env = {};
|
|
57
61
|
}
|
|
62
|
+
migrateLegacyProfileAuth(parsed, file);
|
|
58
63
|
return parsed;
|
|
59
64
|
}
|
|
65
|
+
function migrateLegacyProfileAuth(profile, file) {
|
|
66
|
+
if (!profile.auth || profile.account)
|
|
67
|
+
return;
|
|
68
|
+
if (!profile.provider) {
|
|
69
|
+
throw new Error(`Profile '${profile.name}' owns a legacy credential without a provider. Add a durable account with 'agents accounts add', then set account: <name> in ${file}.`);
|
|
70
|
+
}
|
|
71
|
+
const provider = listAccountProviders().includes(profile.provider) ? profile.provider : 'proxy';
|
|
72
|
+
const suffix = crypto.createHash('sha256').update(profile.auth.keychainItem).digest('hex').slice(0, 8);
|
|
73
|
+
const accountName = `legacy-${profile.provider}-${suffix}`;
|
|
74
|
+
if (!findAccount(accountName)) {
|
|
75
|
+
const kind = profile.auth.envVar.includes('BEARER_TOKEN') ? 'bearer-token' : 'api-key';
|
|
76
|
+
addAccount(accountName, provider, kind, getKeychainToken(profile.auth.keychainItem));
|
|
77
|
+
}
|
|
78
|
+
const migratedAccount = findAccount(accountName);
|
|
79
|
+
const oldItem = profile.auth.keychainItem;
|
|
80
|
+
profile.account = migratedAccount.id;
|
|
81
|
+
profile.provider = provider;
|
|
82
|
+
delete profile.auth;
|
|
83
|
+
delete profile.authOptional;
|
|
84
|
+
atomicWriteFileSync(file, yaml.stringify(profile));
|
|
85
|
+
const stillReferenced = fs.readdirSync(path.dirname(file))
|
|
86
|
+
.filter(entry => /\.ya?ml$/.test(entry) && path.join(path.dirname(file), entry) !== file)
|
|
87
|
+
.some(entry => {
|
|
88
|
+
try {
|
|
89
|
+
const other = yaml.parse(fs.readFileSync(path.join(path.dirname(file), entry), 'utf8'));
|
|
90
|
+
return other?.auth?.keychainItem === oldItem;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
if (!stillReferenced)
|
|
97
|
+
deleteKeychainToken(oldItem);
|
|
98
|
+
}
|
|
60
99
|
/** Write a profile to disk atomically (write-to-tmp then rename). */
|
|
61
100
|
export function writeProfile(profile) {
|
|
62
101
|
validateProfileName(profile.name);
|
|
@@ -437,6 +476,10 @@ export function renameProfile(oldName, newName) {
|
|
|
437
476
|
*/
|
|
438
477
|
export function resolveProfileEnv(profile) {
|
|
439
478
|
const env = { ...profile.env };
|
|
479
|
+
if (profile.account) {
|
|
480
|
+
const account = resolveCredentialAccount(profile.account, profile.host.agent, profile.provider);
|
|
481
|
+
Object.assign(env, account.env);
|
|
482
|
+
}
|
|
440
483
|
if (profile.auth) {
|
|
441
484
|
// Optional auth (host manages its own login) with no stored token: inject
|
|
442
485
|
// nothing and let the host use its own credentials. Only required auth
|
|
@@ -46,6 +46,6 @@ export declare function formatFocusCount(n: number): string;
|
|
|
46
46
|
* One scannable focus line: path + count, with a single unit trailer so the
|
|
47
47
|
* bare integer is never mistaken for commits or minutes.
|
|
48
48
|
*
|
|
49
|
-
* apps/cli/src 2.3k · apps/cli/docs 302 · apps/
|
|
49
|
+
* apps/cli/src 2.3k · apps/cli/docs 302 · apps/ext/src 245 file-touches (7d)
|
|
50
50
|
*/
|
|
51
51
|
export declare function formatFocusAreas(areas: FocusArea[], windowDays: number): string;
|
|
@@ -92,7 +92,7 @@ export function formatFocusCount(n) {
|
|
|
92
92
|
* One scannable focus line: path + count, with a single unit trailer so the
|
|
93
93
|
* bare integer is never mistaken for commits or minutes.
|
|
94
94
|
*
|
|
95
|
-
* apps/cli/src 2.3k · apps/cli/docs 302 · apps/
|
|
95
|
+
* apps/cli/src 2.3k · apps/cli/docs 302 · apps/ext/src 245 file-touches (7d)
|
|
96
96
|
*/
|
|
97
97
|
export function formatFocusAreas(areas, windowDays) {
|
|
98
98
|
if (areas.length === 0)
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* and offline-safe. The fleet half (`--fleet`) just runs this probe on every
|
|
12
12
|
* peer via the canonical `remote-agents-json` SSH fan-out.
|
|
13
13
|
*/
|
|
14
|
-
import type
|
|
14
|
+
import { type ProjectDef } from './projects.js';
|
|
15
15
|
/** The on-disk state of one workspace repo on one machine. */
|
|
16
16
|
export interface RepoWorkspaceStatus {
|
|
17
17
|
/** The probed path, echoed home-relative (re-roots per machine). */
|
|
@@ -52,6 +52,9 @@ export declare function probeProjectWorkspaces(paths: string[]): RepoWorkspaceSt
|
|
|
52
52
|
* probe echoes, so a hand-edited def (absolute path under home, trailing
|
|
53
53
|
* slash) matches its probe rows exactly — `writeProjectDef` normalizes on
|
|
54
54
|
* write, but defs are hand-editable YAML and never silently drop a row.
|
|
55
|
+
*
|
|
56
|
+
* The walk itself lives in `projects.ts` so the probe and the spawn grants read
|
|
57
|
+
* one definition of "the project's directories" instead of two that drift.
|
|
55
58
|
*/
|
|
56
59
|
export declare function workspaceTargetsForDef(def: ProjectDef): string[];
|
|
57
60
|
/**
|
|
@@ -16,6 +16,7 @@ import * as path from 'path';
|
|
|
16
16
|
import { execFileSync } from 'child_process';
|
|
17
17
|
import chalk from 'chalk';
|
|
18
18
|
import { expandLocalHome, toHomeRelative } from './project-root.js';
|
|
19
|
+
import { projectProbeTargets } from './projects.js';
|
|
19
20
|
/** Per-call git budget. A read-only git call taking >3s is wedged by any
|
|
20
21
|
* definition (NFS stall, index lock) — and the fleet fan-out SIGKILLs the SSH
|
|
21
22
|
* hop at 12s, so a probe must fit inside that budget to avoid a slow peer
|
|
@@ -87,12 +88,12 @@ export function probeProjectWorkspaces(paths) {
|
|
|
87
88
|
* probe echoes, so a hand-edited def (absolute path under home, trailing
|
|
88
89
|
* slash) matches its probe rows exactly — `writeProjectDef` normalizes on
|
|
89
90
|
* write, but defs are hand-editable YAML and never silently drop a row.
|
|
91
|
+
*
|
|
92
|
+
* The walk itself lives in `projects.ts` so the probe and the spawn grants read
|
|
93
|
+
* one definition of "the project's directories" instead of two that drift.
|
|
90
94
|
*/
|
|
91
95
|
export function workspaceTargetsForDef(def) {
|
|
92
|
-
|
|
93
|
-
.filter((p) => typeof p === 'string' && p.length > 0)
|
|
94
|
-
.map((p) => toHomeRelative(expandLocalHome(p)));
|
|
95
|
-
return [...new Set(targets)];
|
|
96
|
+
return projectProbeTargets(def);
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
99
|
* Parse a peer's `projects probe --json` stdout, tagging each row with the
|
|
@@ -30,7 +30,7 @@ export function syncProjectResourcesToAgent(agent, version, projectAgentsDir) {
|
|
|
30
30
|
}
|
|
31
31
|
syncProjectCommands(agent, version, projectAgentsDir, agentRoot, result, next);
|
|
32
32
|
syncProjectSkills(agent, version, projectAgentsDir, agentRoot, result, next);
|
|
33
|
-
syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot,
|
|
33
|
+
syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, result, next);
|
|
34
34
|
syncProjectWorkflows(agent, version, projectAgentsDir, projectRoot, agentRoot, result, next);
|
|
35
35
|
if (next.size > 0 || manifest) {
|
|
36
36
|
writeProjectManifest(agentRoot, Array.from(next).sort());
|
|
@@ -258,7 +258,7 @@ function readProjectSubagents(projectAgentsDir) {
|
|
|
258
258
|
}
|
|
259
259
|
return map;
|
|
260
260
|
}
|
|
261
|
-
function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot,
|
|
261
|
+
function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, result, manifestPaths) {
|
|
262
262
|
if (!supports(agent, 'subagents', version).ok)
|
|
263
263
|
return;
|
|
264
264
|
const target = subagentTarget(agent);
|
|
@@ -266,8 +266,6 @@ function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, age
|
|
|
266
266
|
return;
|
|
267
267
|
const all = readProjectSubagents(projectAgentsDir);
|
|
268
268
|
const dir = target.dir(projectRoot);
|
|
269
|
-
const targetDirRel = toPosixRel(path.relative(agentRoot, dir));
|
|
270
|
-
const hadManagedTarget = manifest?.paths.some((rel) => rel === targetDirRel || rel.startsWith(targetDirRel + '/')) ?? false;
|
|
271
269
|
for (const sub of all.values()) {
|
|
272
270
|
const occupied = target.occupied(dir, sub.name);
|
|
273
271
|
const existing = occupied.find((entry) => pathExists(entry.path));
|
|
@@ -283,20 +281,6 @@ function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, age
|
|
|
283
281
|
// Malformed source or unsupported transform; skip this item.
|
|
284
282
|
}
|
|
285
283
|
}
|
|
286
|
-
const syncedNames = result.synced
|
|
287
|
-
.filter((name) => name.startsWith('subagents/'))
|
|
288
|
-
.map((name) => name.slice('subagents/'.length))
|
|
289
|
-
.filter((name) => all.has(name))
|
|
290
|
-
.map((name) => all.get(name));
|
|
291
|
-
if (target.finalize && (syncedNames.length > 0 || hadManagedTarget)) {
|
|
292
|
-
target.finalize(dir, syncedNames);
|
|
293
|
-
for (const entry of target.finalizeOccupied?.(dir) ?? []) {
|
|
294
|
-
// Same normalization as record(): this is the one manifest write that
|
|
295
|
-
// doesn't funnel through it (the parent subagent index, e.g. Kimi's
|
|
296
|
-
// agents/_agents-cli.yaml).
|
|
297
|
-
manifestPaths.add(toPosixRel(path.relative(agentRoot, entry.path)));
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
284
|
}
|
|
301
285
|
function workflowManagedRelPaths(agent, projectRoot, name, workflowDir) {
|
|
302
286
|
if (agent === 'kimi')
|
|
@@ -110,3 +110,19 @@ export declare function resolveProjectRef(ref: string, opts: {
|
|
|
110
110
|
forRemote: boolean;
|
|
111
111
|
cwd?: string;
|
|
112
112
|
}): Promise<string>;
|
|
113
|
+
/**
|
|
114
|
+
* Resolve a `--project` ref to the cwd an agent lands in PLUS the other
|
|
115
|
+
* directories that project binds, so a spawn can grant them.
|
|
116
|
+
*
|
|
117
|
+
* `cwd` is exactly what `resolveProjectRef` returns — this never changes where
|
|
118
|
+
* an agent starts. `extraDirs` is every other `repos[].path`, and is empty for
|
|
119
|
+
* a convention-resolved project (no definition means no bound repos) and for a
|
|
120
|
+
* definition that binds only its primary checkout.
|
|
121
|
+
*/
|
|
122
|
+
export declare function resolveProjectDirs(ref: string, opts: {
|
|
123
|
+
forRemote: boolean;
|
|
124
|
+
cwd?: string;
|
|
125
|
+
}): Promise<{
|
|
126
|
+
cwd: string;
|
|
127
|
+
extraDirs: string[];
|
|
128
|
+
}>;
|
package/dist/lib/project-root.js
CHANGED
|
@@ -17,7 +17,7 @@ import * as fs from 'fs';
|
|
|
17
17
|
import { readMeta, updateMeta } from './state.js';
|
|
18
18
|
import { getMainRepoRoot } from './git.js';
|
|
19
19
|
import { toPosix } from './platform/index.js';
|
|
20
|
-
import { loadProjectDef, resolveDefinedProjectPath } from './projects.js';
|
|
20
|
+
import { loadProjectDef, projectDirsAbs, resolveDefinedProjectPath } from './projects.js';
|
|
21
21
|
import { shellQuote } from './ssh-exec.js';
|
|
22
22
|
const HOME = process.env.HOME ?? os.homedir();
|
|
23
23
|
/** Rewrite an absolute path under the local home to a `~/`-relative string; pass others through. */
|
|
@@ -157,7 +157,7 @@ export async function ensureProjectRoot(cwd) {
|
|
|
157
157
|
if (!inferred) {
|
|
158
158
|
throw new Error('Could not determine your projects root. Run once from inside a project ' +
|
|
159
159
|
'(a git repo under your projects dir) so it can be inferred, or set it:\n' +
|
|
160
|
-
' agents
|
|
160
|
+
' agents config set project.root ~/src/github.com/<you>');
|
|
161
161
|
}
|
|
162
162
|
updateMeta({ projectRoot: inferred });
|
|
163
163
|
process.stderr.write(`[project] cached projects root: ${inferred}\n`);
|
|
@@ -216,3 +216,21 @@ export async function resolveProjectRef(ref, opts) {
|
|
|
216
216
|
}
|
|
217
217
|
return resolved;
|
|
218
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Resolve a `--project` ref to the cwd an agent lands in PLUS the other
|
|
221
|
+
* directories that project binds, so a spawn can grant them.
|
|
222
|
+
*
|
|
223
|
+
* `cwd` is exactly what `resolveProjectRef` returns — this never changes where
|
|
224
|
+
* an agent starts. `extraDirs` is every other `repos[].path`, and is empty for
|
|
225
|
+
* a convention-resolved project (no definition means no bound repos) and for a
|
|
226
|
+
* definition that binds only its primary checkout.
|
|
227
|
+
*/
|
|
228
|
+
export async function resolveProjectDirs(ref, opts) {
|
|
229
|
+
const resolved = await resolveProjectRef(ref, opts);
|
|
230
|
+
const { slug } = parseProjectRef(ref);
|
|
231
|
+
const def = slug ? loadProjectDef(slug) : undefined;
|
|
232
|
+
if (!def)
|
|
233
|
+
return { cwd: resolved, extraDirs: [] };
|
|
234
|
+
const all = projectDirsAbs(def, { forRemote: opts.forRemote, primary: resolved });
|
|
235
|
+
return { cwd: resolved, extraDirs: all.filter((d) => d !== resolved) };
|
|
236
|
+
}
|
package/dist/lib/projects.d.ts
CHANGED
|
@@ -151,6 +151,25 @@ export declare function removeProjectDef(name: string): boolean;
|
|
|
151
151
|
* expanded against the local home. Returns undefined when neither is set.
|
|
152
152
|
*/
|
|
153
153
|
export declare function projectBasePath(def: ProjectDef, forRemote: boolean): string | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* The directories `projects status` probes across the fleet: the repo root plus
|
|
156
|
+
* every bound checkout, home-relative so each host re-roots them, and including
|
|
157
|
+
* directories absent here so a peer can still answer `✗ missing` for them.
|
|
158
|
+
*/
|
|
159
|
+
export declare function projectProbeTargets(def: ProjectDef): string[];
|
|
160
|
+
/**
|
|
161
|
+
* The directories an agent spawned on this project should reach: the cwd first
|
|
162
|
+
* (`resolveDefinedProjectPath`, so cwd behavior is unchanged), then every other
|
|
163
|
+
* bound repo. `forRemote` keeps them `~/…` so the remote shell re-roots them at
|
|
164
|
+
* its own `$HOME`; locally they are absolute and filtered to what exists.
|
|
165
|
+
*
|
|
166
|
+
* Callers pass the resolved primary so a `--project slug@worktree` run grants
|
|
167
|
+
* the sibling repos alongside the worktree it actually landed in.
|
|
168
|
+
*/
|
|
169
|
+
export declare function projectDirsAbs(def: ProjectDef, opts: {
|
|
170
|
+
forRemote: boolean;
|
|
171
|
+
primary?: string;
|
|
172
|
+
}): string[];
|
|
154
173
|
/**
|
|
155
174
|
* Which defined project a session belongs to, derived from its working
|
|
156
175
|
* directory. A session whose `cwd` sits inside a project's repo root (or a
|
|
@@ -162,7 +181,7 @@ export declare function projectBasePath(def: ProjectDef, forRemote: boolean): st
|
|
|
162
181
|
* with `expandLocalHome` and resolved, so this matches sessions whose cwd shares
|
|
163
182
|
* this machine's home layout. A session recorded on a different-home machine
|
|
164
183
|
* (`/Users/x/…` vs `/home/x/…`) will not match until the fleet-wide,
|
|
165
|
-
* home-relative variant lands (see the deferred item in docs/
|
|
184
|
+
* home-relative variant lands (see the deferred item in docs/projects.md).
|
|
166
185
|
*/
|
|
167
186
|
export declare function projectNameForCwd(cwd: string | undefined, defs: ProjectDef[]): string | undefined;
|
|
168
187
|
/**
|