@phnx-labs/agents-cli 1.22.120 → 1.22.121
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 +227 -0
- package/README.md +19 -2
- package/dist/bootstrap.d.ts +0 -15
- package/dist/bootstrap.js +10 -409
- package/dist/cli/command-registry.d.ts +0 -58
- package/dist/cli/command-registry.js +2 -74
- package/dist/commands/accounts.d.ts +0 -17
- package/dist/commands/accounts.js +1 -52
- package/dist/commands/alias.d.ts +0 -12
- package/dist/commands/alias.js +0 -6
- package/dist/commands/apply.d.ts +0 -15
- package/dist/commands/apply.js +0 -63
- package/dist/commands/audit.d.ts +0 -12
- package/dist/commands/audit.js +0 -13
- package/dist/commands/auth.js +4 -12
- package/dist/commands/beta.d.ts +0 -6
- package/dist/commands/beta.js +2 -6
- package/dist/commands/browser-sessions-picker.d.ts +0 -8
- package/dist/commands/browser-sessions-picker.js +0 -26
- package/dist/commands/browser.d.ts +0 -57
- package/dist/commands/browser.js +0 -80
- package/dist/commands/budget.d.ts +0 -13
- package/dist/commands/budget.js +0 -2
- package/dist/commands/cli.d.ts +0 -12
- package/dist/commands/cli.js +0 -4
- package/dist/commands/cloud.d.ts +0 -9
- package/dist/commands/cloud.js +0 -43
- package/dist/commands/commands.d.ts +0 -9
- package/dist/commands/commands.js +0 -18
- package/dist/commands/computer-sessions-picker.d.ts +0 -11
- package/dist/commands/computer-sessions-picker.js +0 -29
- package/dist/commands/computer.d.ts +0 -62
- package/dist/commands/computer.js +3 -114
- package/dist/commands/config.d.ts +0 -14
- package/dist/commands/config.js +21 -60
- package/dist/commands/cost.d.ts +0 -11
- package/dist/commands/cost.js +1 -17
- package/dist/commands/daemon-test-harness.d.ts +0 -32
- package/dist/commands/daemon-test-harness.js +1 -36
- package/dist/commands/daemon.d.ts +0 -46
- package/dist/commands/daemon.js +8 -255
- package/dist/commands/detach-core.d.ts +0 -28
- package/dist/commands/detach-core.js +0 -30
- package/dist/commands/detach.d.ts +1 -12
- package/dist/commands/detach.js +16 -52
- package/dist/commands/device-config-test-harness.js +0 -12
- package/dist/commands/doctor.d.ts +0 -103
- package/dist/commands/doctor.js +3 -279
- package/dist/commands/events.d.ts +0 -29
- package/dist/commands/events.js +1 -55
- package/dist/commands/exec.d.ts +0 -163
- package/dist/commands/exec.js +15 -964
- package/dist/commands/factory.d.ts +0 -6
- package/dist/commands/factory.js +0 -2
- package/dist/commands/feed-watch.js +0 -20
- package/dist/commands/feed.d.ts +0 -38
- package/dist/commands/feed.js +1 -151
- package/dist/commands/feedback.d.ts +0 -5
- package/dist/commands/feedback.js +0 -5
- package/dist/commands/fleet-capture.d.ts +0 -12
- package/dist/commands/fleet-capture.js +1 -39
- package/dist/commands/focus.d.ts +6 -94
- package/dist/commands/focus.js +13 -183
- package/dist/commands/fork.d.ts +0 -21
- package/dist/commands/fork.js +0 -45
- package/dist/commands/funnel.d.ts +0 -3
- package/dist/commands/go.d.ts +2 -71
- package/dist/commands/go.js +5 -99
- package/dist/commands/harness-hooks.d.ts +0 -41
- package/dist/commands/harness-hooks.js +0 -48
- package/dist/commands/harness-wizard.d.ts +0 -137
- package/dist/commands/harness-wizard.js +0 -109
- package/dist/commands/harness.d.ts +0 -63
- package/dist/commands/harness.js +0 -103
- package/dist/commands/hooks.d.ts +0 -9
- package/dist/commands/hooks.js +0 -26
- package/dist/commands/humans.d.ts +0 -8
- package/dist/commands/humans.js +0 -8
- package/dist/commands/import.d.ts +0 -22
- package/dist/commands/import.js +0 -79
- package/dist/commands/insights.d.ts +0 -37
- package/dist/commands/insights.js +3 -115
- package/dist/commands/inspect.d.ts +0 -117
- package/dist/commands/inspect.js +2 -448
- package/dist/commands/lease.d.ts +0 -28
- package/dist/commands/lease.js +0 -43
- package/dist/commands/logs.d.ts +0 -23
- package/dist/commands/logs.js +0 -30
- package/dist/commands/mailboxes.d.ts +0 -18
- package/dist/commands/mailboxes.js +0 -29
- package/dist/commands/mcp.d.ts +0 -9
- package/dist/commands/mcp.js +0 -53
- package/dist/commands/memory.d.ts +0 -7
- package/dist/commands/memory.js +0 -7
- package/dist/commands/menubar.d.ts +0 -8
- package/dist/commands/menubar.js +0 -24
- package/dist/commands/message.d.ts +0 -23
- package/dist/commands/message.js +0 -50
- package/dist/commands/mine.d.ts +0 -22
- package/dist/commands/mine.js +0 -21
- package/dist/commands/models.d.ts +0 -8
- package/dist/commands/models.js +0 -33
- package/dist/commands/modes.d.ts +0 -10
- package/dist/commands/modes.js +0 -13
- package/dist/commands/monitors.d.ts +0 -9
- package/dist/commands/monitors.js +3 -160
- package/dist/commands/open.d.ts +0 -26
- package/dist/commands/open.js +0 -10
- package/dist/commands/output.d.ts +0 -18
- package/dist/commands/output.js +1 -34
- package/dist/commands/packages-materialize.d.ts +0 -11
- package/dist/commands/packages-materialize.js +0 -3
- package/dist/commands/packages.d.ts +0 -10
- package/dist/commands/packages.js +0 -50
- package/dist/commands/perf.d.ts +0 -41
- package/dist/commands/perf.js +0 -55
- package/dist/commands/permissions.d.ts +0 -9
- package/dist/commands/permissions.js +0 -43
- package/dist/commands/plugins.d.ts +0 -14
- package/dist/commands/plugins.js +2 -55
- package/dist/commands/profiles.d.ts +0 -25
- package/dist/commands/profiles.js +0 -27
- package/dist/commands/projects-todo.d.ts +2 -0
- package/dist/commands/projects-todo.js +132 -0
- package/dist/commands/projects.d.ts +0 -85
- package/dist/commands/projects.js +344 -291
- package/dist/commands/prune.js +0 -30
- package/dist/commands/ps-roster.d.ts +92 -0
- package/dist/commands/ps-roster.js +744 -0
- package/dist/commands/ps.d.ts +6 -0
- package/dist/commands/ps.js +98 -0
- package/dist/commands/refresh-rules.d.ts +0 -13
- package/dist/commands/refresh-rules.js +0 -14
- package/dist/commands/reminders.d.ts +0 -7
- package/dist/commands/repo.d.ts +0 -89
- package/dist/commands/repo.js +7 -205
- package/dist/commands/resource-view.d.ts +0 -33
- package/dist/commands/resource-view.js +0 -49
- package/dist/commands/resume.d.ts +1 -19
- package/dist/commands/resume.js +0 -50
- package/dist/commands/route.d.ts +0 -10
- package/dist/commands/route.js +0 -19
- package/dist/commands/routines.d.ts +0 -42
- package/dist/commands/routines.js +5 -290
- package/dist/commands/routines.test-fixture.d.ts +0 -34
- package/dist/commands/routines.test-fixture.js +4 -100
- package/dist/commands/rules.d.ts +0 -9
- package/dist/commands/rules.js +1 -6
- package/dist/commands/run-account-picker.d.ts +0 -59
- package/dist/commands/run-account-picker.js +0 -71
- package/dist/commands/run-broadcast.d.ts +0 -9
- package/dist/commands/run-broadcast.js +0 -7
- package/dist/commands/run-cloud.d.ts +0 -15
- package/dist/commands/run-cloud.js +0 -37
- package/dist/commands/run-device-picker.d.ts +0 -25
- package/dist/commands/run-device-picker.js +1 -53
- package/dist/commands/secrets-passthrough.d.ts +0 -31
- package/dist/commands/secrets-passthrough.js +0 -10
- package/dist/commands/send.d.ts +0 -20
- package/dist/commands/send.js +14 -18
- package/dist/commands/sessions-backfill.d.ts +0 -7
- package/dist/commands/sessions-backfill.js +1 -16
- package/dist/commands/sessions-backup-setup.js +0 -11
- package/dist/commands/sessions-bookmark.d.ts +0 -8
- package/dist/commands/sessions-bookmark.js +0 -28
- package/dist/commands/sessions-browser.d.ts +2 -117
- package/dist/commands/sessions-browser.js +5 -243
- package/dist/commands/sessions-export.d.ts +1 -26
- package/dist/commands/sessions-export.js +3 -81
- package/dist/commands/sessions-import.d.ts +0 -14
- package/dist/commands/sessions-import.js +0 -59
- package/dist/commands/sessions-inject.d.ts +0 -60
- package/dist/commands/sessions-inject.js +3 -96
- package/dist/commands/sessions-migrate.d.ts +2 -37
- package/dist/commands/sessions-migrate.js +7 -159
- package/dist/commands/sessions-optimize.d.ts +0 -12
- package/dist/commands/sessions-picker-factory.d.ts +0 -7
- package/dist/commands/sessions-picker-factory.js +0 -8
- package/dist/commands/sessions-picker.d.ts +4 -103
- package/dist/commands/sessions-picker.js +13 -352
- package/dist/commands/sessions-render.d.ts +1 -2
- package/dist/commands/sessions-render.js +3 -7
- package/dist/commands/sessions-resume.d.ts +1 -24
- package/dist/commands/sessions-resume.js +2 -65
- package/dist/commands/sessions-share.d.ts +1 -9
- package/dist/commands/sessions-share.js +1 -45
- package/dist/commands/sessions-stats.d.ts +0 -24
- package/dist/commands/sessions-stats.js +0 -49
- package/dist/commands/sessions-stop.d.ts +1 -20
- package/dist/commands/sessions-stop.js +4 -9
- package/dist/commands/sessions-tail.d.ts +1 -19
- package/dist/commands/sessions-tail.js +3 -36
- package/dist/commands/sessions-trace.d.ts +5 -36
- package/dist/commands/sessions-trace.js +7 -82
- package/dist/commands/sessions.d.ts +1 -666
- package/dist/commands/sessions.js +30 -2279
- package/dist/commands/sessions.test-fixture.d.ts +0 -9
- package/dist/commands/sessions.test-fixture.js +8 -23
- package/dist/commands/setup-accounts.d.ts +0 -6
- package/dist/commands/setup-browser.d.ts +0 -23
- package/dist/commands/setup-browser.js +0 -28
- package/dist/commands/setup-computer.d.ts +0 -16
- package/dist/commands/setup-computer.js +0 -28
- package/dist/commands/setup-fleet.d.ts +0 -8
- package/dist/commands/setup-fleet.js +0 -11
- package/dist/commands/setup-mine.d.ts +0 -14
- package/dist/commands/setup-mine.js +0 -25
- package/dist/commands/setup-preferences.d.ts +0 -47
- package/dist/commands/setup-preferences.js +0 -53
- package/dist/commands/setup-secrets.d.ts +2 -24
- package/dist/commands/setup-secrets.js +0 -24
- package/dist/commands/setup-term.d.ts +0 -21
- package/dist/commands/setup-term.js +0 -21
- package/dist/commands/setup-terminal.d.ts +0 -1
- package/dist/commands/setup-terminal.js +0 -1
- package/dist/commands/setup-tools.d.ts +2 -0
- package/dist/commands/setup-tools.js +73 -0
- package/dist/commands/setup.d.ts +0 -20
- package/dist/commands/setup.js +4 -57
- package/dist/commands/skills.d.ts +0 -9
- package/dist/commands/skills.js +1 -22
- package/dist/commands/snapshot.d.ts +0 -9
- package/dist/commands/snapshot.js +0 -10
- package/dist/commands/ssh.d.ts +0 -64
- package/dist/commands/ssh.js +9 -420
- package/dist/commands/status.d.ts +0 -12
- package/dist/commands/status.js +0 -26
- package/dist/commands/subagents.d.ts +0 -8
- package/dist/commands/subagents.js +0 -31
- package/dist/commands/sync.d.ts +0 -37
- package/dist/commands/sync.js +0 -256
- package/dist/commands/teams-picker.d.ts +0 -3
- package/dist/commands/teams-picker.js +0 -34
- package/dist/commands/teams.d.ts +1 -76
- package/dist/commands/teams.js +9 -477
- package/dist/commands/tmux.d.ts +0 -25
- package/dist/commands/tmux.js +0 -46
- package/dist/commands/traces.js +0 -19
- package/dist/commands/trash.d.ts +0 -17
- package/dist/commands/trash.js +1 -11
- package/dist/commands/uninstall.d.ts +0 -9
- package/dist/commands/uninstall.js +0 -6
- package/dist/commands/update.d.ts +0 -22
- package/dist/commands/update.js +0 -44
- package/dist/commands/upgrade.d.ts +0 -1
- package/dist/commands/upgrade.js +0 -1
- package/dist/commands/utils.d.ts +0 -85
- package/dist/commands/utils.js +1 -95
- package/dist/commands/versions.d.ts +0 -16
- package/dist/commands/versions.js +0 -134
- package/dist/commands/view.d.ts +0 -90
- package/dist/commands/view.js +4 -343
- package/dist/commands/watchdog.d.ts +0 -19
- package/dist/commands/watchdog.js +3 -43
- package/dist/commands/webhook.d.ts +0 -8
- package/dist/commands/webhook.js +0 -14
- package/dist/commands/workflows.d.ts +0 -8
- package/dist/commands/workflows.js +0 -6
- package/dist/index.d.ts +0 -25
- package/dist/index.js +5 -119
- package/dist/lib/account-capabilities.d.ts +0 -34
- package/dist/lib/account-capabilities.js +0 -32
- package/dist/lib/account-catalog.d.ts +0 -128
- package/dist/lib/account-catalog.js +8 -154
- package/dist/lib/account-provider-registry.d.ts +0 -14
- package/dist/lib/account-provider-registry.js +0 -8
- package/dist/lib/account-registry.d.ts +0 -74
- package/dist/lib/account-registry.js +14 -189
- package/dist/lib/account-schema.d.ts +0 -19
- package/dist/lib/account-schema.js +0 -43
- package/dist/lib/accounting/account-launch.d.ts +0 -15
- package/dist/lib/accounting/account-launch.js +1 -3
- package/dist/lib/accounting/account-pool-collect.d.ts +0 -26
- package/dist/lib/accounting/account-pool-collect.js +0 -42
- package/dist/lib/accounting/account-pool.d.ts +0 -41
- package/dist/lib/accounting/account-pool.js +0 -17
- package/dist/lib/accounting/capacity.d.ts +0 -32
- package/dist/lib/accounting/capacity.js +0 -32
- package/dist/lib/accounting/rotate.d.ts +0 -518
- package/dist/lib/accounting/rotate.js +4 -598
- package/dist/lib/accounting/usage-ingest.d.ts +0 -1
- package/dist/lib/accounting/usage-ingest.js +0 -44
- package/dist/lib/accounting/usage-sync.d.ts +0 -60
- package/dist/lib/accounting/usage-sync.js +4 -51
- package/dist/lib/accounting/usage.d.ts +0 -632
- package/dist/lib/accounting/usage.js +14 -1055
- package/dist/lib/accounts/add.d.ts +0 -60
- package/dist/lib/accounts/add.js +0 -127
- package/dist/lib/accounts/auth-operation-lock.d.ts +0 -1
- package/dist/lib/accounts/auth-operation-lock.js +0 -4
- package/dist/lib/accounts/migrate.d.ts +0 -9
- package/dist/lib/accounts/migrate.js +3 -42
- package/dist/lib/accounts/slots.d.ts +0 -25
- package/dist/lib/accounts/slots.js +1 -49
- package/dist/lib/acp/client.d.ts +0 -16
- package/dist/lib/acp/client.js +0 -29
- package/dist/lib/acp/harnesses.d.ts +0 -15
- package/dist/lib/acp/harnesses.js +0 -16
- package/dist/lib/acp/run.d.ts +0 -8
- package/dist/lib/acp/run.js +0 -8
- package/dist/lib/actor.d.ts +1 -71
- package/dist/lib/actor.js +1 -99
- package/dist/lib/add-dir.d.ts +0 -46
- package/dist/lib/add-dir.js +1 -70
- package/dist/lib/address.d.ts +0 -17
- package/dist/lib/address.js +0 -15
- package/dist/lib/agent-cli-commands.d.ts +0 -10
- package/dist/lib/agent-cli-commands.js +0 -10
- package/dist/lib/agent-modes.d.ts +0 -29
- package/dist/lib/agent-modes.js +0 -31
- package/dist/lib/agent-spec/agents.d.ts +0 -426
- package/dist/lib/agent-spec/agents.js +37 -924
- package/dist/lib/agent-spec/index.d.ts +0 -5
- package/dist/lib/agent-spec/index.js +0 -14
- package/dist/lib/agent-spec/materialize.d.ts +0 -10
- package/dist/lib/agent-spec/materialize.js +2 -139
- package/dist/lib/agent-spec/package-resolve.d.ts +0 -8
- package/dist/lib/agent-spec/package-resolve.js +1 -44
- package/dist/lib/agent-spec/package-schema.d.ts +0 -2
- package/dist/lib/agent-spec/package-schema.js +0 -11
- package/dist/lib/agent-spec/package-types.d.ts +0 -27
- package/dist/lib/agent-spec/package-types.js +0 -1
- package/dist/lib/agent-spec/primitives.d.ts +0 -18
- package/dist/lib/agent-spec/primitives.js +0 -27
- package/dist/lib/agent-spec/provider.js +0 -2
- package/dist/lib/agent-spec/resolve.d.ts +0 -23
- package/dist/lib/agent-spec/resolve.js +0 -41
- package/dist/lib/agent-spec/types.d.ts +0 -34
- package/dist/lib/agent-spec/types.js +0 -6
- package/dist/lib/agents.d.ts +0 -1
- package/dist/lib/agents.js +0 -1
- package/dist/lib/analytics/mix-commands.d.ts +0 -23
- package/dist/lib/analytics/mix-commands.js +0 -26
- package/dist/lib/analytics/recipes.d.ts +0 -1
- package/dist/lib/analytics/recipes.js +5 -10
- package/dist/lib/analytics/usage-db.js +4 -6
- package/dist/lib/answer-router.d.ts +0 -61
- package/dist/lib/answer-router.js +0 -57
- package/dist/lib/app-bundle-install.d.ts +0 -13
- package/dist/lib/app-bundle-install.js +0 -50
- package/dist/lib/artifact-actions.d.ts +0 -15
- package/dist/lib/artifact-actions.js +0 -18
- package/dist/lib/artifacts-client.d.ts +0 -10
- package/dist/lib/artifacts-client.js +0 -17
- package/dist/lib/ask-classifier.d.ts +0 -38
- package/dist/lib/ask-classifier.js +0 -27
- package/dist/lib/audit/log.d.ts +0 -47
- package/dist/lib/audit/log.js +1 -59
- package/dist/lib/auth-health.d.ts +0 -213
- package/dist/lib/auth-health.js +16 -266
- package/dist/lib/auth-mint.d.ts +0 -83
- package/dist/lib/auth-mint.js +8 -85
- package/dist/lib/auto-pull-worker.d.ts +0 -10
- package/dist/lib/auto-pull-worker.js +3 -48
- package/dist/lib/auto-pull.d.ts +0 -64
- package/dist/lib/auto-pull.js +0 -79
- package/dist/lib/beta.d.ts +0 -9
- package/dist/lib/beta.js +0 -9
- package/dist/lib/binary-shadow.d.ts +0 -22
- package/dist/lib/binary-shadow.js +4 -34
- package/dist/lib/boot-profile.d.ts +0 -10
- package/dist/lib/boot-profile.js +1 -31
- package/dist/lib/brand.d.ts +0 -20
- package/dist/lib/brand.js +0 -50
- package/dist/lib/browser/context.d.ts +0 -54
- package/dist/lib/browser/context.js +0 -49
- package/dist/lib/browser/paths.d.ts +0 -21
- package/dist/lib/browser/paths.js +0 -26
- package/dist/lib/browser/record.d.ts +0 -34
- package/dist/lib/browser/record.js +0 -38
- package/dist/lib/browser/sessions-list.d.ts +1 -79
- package/dist/lib/browser/sessions-list.js +2 -98
- package/dist/lib/browser-client.d.ts +0 -112
- package/dist/lib/browser-client.js +1 -90
- package/dist/lib/budget/config.d.ts +0 -6
- package/dist/lib/budget/config.js +0 -29
- package/dist/lib/budget/enforce.d.ts +0 -50
- package/dist/lib/budget/enforce.js +0 -27
- package/dist/lib/budget/ledger.d.ts +0 -23
- package/dist/lib/budget/ledger.js +0 -28
- package/dist/lib/budget/live-cloud.d.ts +0 -26
- package/dist/lib/budget/live-cloud.js +0 -12
- package/dist/lib/budget/live-team.d.ts +0 -17
- package/dist/lib/budget/live-team.js +1 -35
- package/dist/lib/budget/preflight.d.ts +0 -51
- package/dist/lib/budget/preflight.js +0 -36
- package/dist/lib/byok-usage.d.ts +0 -20
- package/dist/lib/byok-usage.js +1 -24
- package/dist/lib/capabilities.d.ts +0 -24
- package/dist/lib/capabilities.js +0 -29
- package/dist/lib/catchup.d.ts +0 -87
- package/dist/lib/catchup.js +1 -81
- package/dist/lib/channels/owner-forward.d.ts +0 -70
- package/dist/lib/channels/owner-forward.js +1 -43
- package/dist/lib/channels/owner-sink.js +0 -21
- package/dist/lib/channels/providers/desktop.d.ts +0 -37
- package/dist/lib/channels/providers/desktop.js +0 -72
- package/dist/lib/channels/providers/index.d.ts +0 -1
- package/dist/lib/channels/providers/index.js +2 -6
- package/dist/lib/channels/providers/mailbox.js +0 -7
- package/dist/lib/channels/providers/openclaw-telegram.js +0 -8
- package/dist/lib/channels/providers/rush.d.ts +0 -2
- package/dist/lib/channels/providers/rush.js +0 -26
- package/dist/lib/channels/providers/session.d.ts +2 -0
- package/dist/lib/channels/providers/session.js +26 -0
- package/dist/lib/channels/registry.d.ts +0 -27
- package/dist/lib/channels/registry.js +0 -10
- package/dist/lib/channels/resolve.d.ts +0 -19
- package/dist/lib/channels/resolve.js +0 -2
- package/dist/lib/channels/send.d.ts +0 -50
- package/dist/lib/channels/send.js +0 -25
- package/dist/lib/checkpoint.d.ts +0 -36
- package/dist/lib/checkpoint.js +0 -28
- package/dist/lib/claude-account-token.d.ts +0 -98
- package/dist/lib/claude-account-token.js +7 -169
- package/dist/lib/claude-statusline.d.ts +0 -41
- package/dist/lib/claude-statusline.js +0 -68
- package/dist/lib/cli-entry.d.ts +0 -26
- package/dist/lib/cli-entry.js +1 -61
- package/dist/lib/cli-resources.d.ts +31 -89
- package/dist/lib/cli-resources.js +116 -152
- package/dist/lib/cloud/antigravity.d.ts +0 -29
- package/dist/lib/cloud/antigravity.js +0 -36
- package/dist/lib/cloud/codex.d.ts +0 -8
- package/dist/lib/cloud/codex.js +0 -41
- package/dist/lib/cloud/cursor.d.ts +0 -5
- package/dist/lib/cloud/cursor.js +2 -7
- package/dist/lib/cloud/dispatch.d.ts +0 -13
- package/dist/lib/cloud/dispatch.js +1 -48
- package/dist/lib/cloud/factory.d.ts +0 -52
- package/dist/lib/cloud/factory.js +3 -67
- package/dist/lib/cloud/host.d.ts +0 -39
- package/dist/lib/cloud/host.js +5 -48
- package/dist/lib/cloud/registry.d.ts +0 -25
- package/dist/lib/cloud/registry.js +0 -29
- package/dist/lib/cloud/rush.d.ts +0 -47
- package/dist/lib/cloud/rush.js +1 -82
- package/dist/lib/cloud/session-index.d.ts +0 -27
- package/dist/lib/cloud/session-index.js +1 -32
- package/dist/lib/cloud/store.d.ts +0 -18
- package/dist/lib/cloud/store.js +0 -28
- package/dist/lib/cloud/stream.d.ts +0 -14
- package/dist/lib/cloud/stream.js +0 -25
- package/dist/lib/cloud/types.d.ts +0 -168
- package/dist/lib/cloud/types.js +0 -46
- package/dist/lib/cloudflare/creds.d.ts +0 -2
- package/dist/lib/cloudflare/creds.js +0 -14
- package/dist/lib/cloudflare/provision.d.ts +0 -8
- package/dist/lib/cloudflare/provision.js +1 -19
- package/dist/lib/codex-home.d.ts +0 -60
- package/dist/lib/codex-home.js +2 -72
- package/dist/lib/codex-policy.d.ts +0 -10
- package/dist/lib/codex-policy.js +0 -13
- package/dist/lib/command-skills.d.ts +0 -10
- package/dist/lib/command-skills.js +0 -10
- package/dist/lib/commands.d.ts +0 -74
- package/dist/lib/commands.js +0 -112
- package/dist/lib/comms-render.d.ts +0 -5
- package/dist/lib/comms-render.js +0 -5
- package/dist/lib/computer/context.d.ts +0 -23
- package/dist/lib/computer/context.js +0 -14
- package/dist/lib/computer/policy.d.ts +0 -20
- package/dist/lib/computer/policy.js +0 -53
- package/dist/lib/computer/record.d.ts +0 -33
- package/dist/lib/computer/record.js +1 -48
- package/dist/lib/computer/sessions-list.d.ts +1 -128
- package/dist/lib/computer/sessions-list.js +6 -165
- package/dist/lib/computer-client.d.ts +0 -106
- package/dist/lib/computer-client.js +5 -86
- package/dist/lib/concurrency.d.ts +0 -14
- package/dist/lib/concurrency.js +0 -3
- package/dist/lib/config-drift.d.ts +0 -31
- package/dist/lib/config-drift.js +0 -32
- package/dist/lib/config-keys.d.ts +1 -65
- package/dist/lib/config-keys.js +6 -52
- package/dist/lib/config-transfer.d.ts +0 -14
- package/dist/lib/config-transfer.js +0 -26
- package/dist/lib/convert.d.ts +0 -17
- package/dist/lib/convert.js +0 -18
- package/dist/lib/crabbox/cli.d.ts +0 -156
- package/dist/lib/crabbox/cli.js +1 -188
- package/dist/lib/crabbox/config.d.ts +0 -18
- package/dist/lib/crabbox/config.js +1 -19
- package/dist/lib/crabbox/lease.d.ts +0 -93
- package/dist/lib/crabbox/lease.js +4 -148
- package/dist/lib/crabbox/progress.d.ts +0 -56
- package/dist/lib/crabbox/progress.js +2 -49
- package/dist/lib/crabbox/runtimes.d.ts +0 -94
- package/dist/lib/crabbox/runtimes.js +1 -111
- package/dist/lib/crabbox/setup-copy.d.ts +0 -64
- package/dist/lib/crabbox/setup-copy.js +1 -53
- package/dist/lib/daemon/account-state-daemon-service.d.ts +0 -48
- package/dist/lib/daemon/account-state-daemon-service.js +2 -63
- package/dist/lib/daemon/attention-notify-service.d.ts +0 -12
- package/dist/lib/daemon/attention-notify-service.js +1 -24
- package/dist/lib/daemon/auth-sync-service.d.ts +0 -28
- package/dist/lib/daemon/auth-sync-service.js +0 -56
- package/dist/lib/daemon/catchup-service.d.ts +0 -34
- package/dist/lib/daemon/catchup-service.js +0 -30
- package/dist/lib/daemon/daemon.d.ts +0 -374
- package/dist/lib/daemon/daemon.js +44 -1049
- package/dist/lib/daemon/daemon.test-fixture.d.ts +0 -19
- package/dist/lib/daemon/daemon.test-fixture.js +1 -24
- package/dist/lib/daemon/device-probe-service.d.ts +0 -16
- package/dist/lib/daemon/device-probe-service.js +0 -20
- package/dist/lib/daemon/feed-stream-service.d.ts +0 -15
- package/dist/lib/daemon/feed-stream-service.js +0 -20
- package/dist/lib/daemon/harness-update-service.d.ts +2 -61
- package/dist/lib/daemon/harness-update-service.js +6 -86
- package/dist/lib/daemon/heartbeat-service.d.ts +0 -1
- package/dist/lib/daemon/heartbeat-service.js +0 -1
- package/dist/lib/daemon/leaked-daemons.d.ts +0 -46
- package/dist/lib/daemon/leaked-daemons.js +2 -78
- package/dist/lib/daemon/monitor-engine-service.d.ts +0 -13
- package/dist/lib/daemon/monitor-engine-service.js +3 -15
- package/dist/lib/daemon/runner.d.ts +0 -194
- package/dist/lib/daemon/runner.js +39 -760
- package/dist/lib/daemon/self-heal-service.d.ts +18 -17
- package/dist/lib/daemon/self-heal-service.js +83 -37
- package/dist/lib/daemon/self-update-service.d.ts +1 -131
- package/dist/lib/daemon/self-update-service.js +26 -189
- package/dist/lib/daemon/service.d.ts +0 -73
- package/dist/lib/daemon/service.js +0 -34
- package/dist/lib/daemon/session-index-service.d.ts +0 -12
- package/dist/lib/daemon/session-index-service.js +0 -23
- package/dist/lib/daemon/session-state-service.d.ts +0 -8
- package/dist/lib/daemon/session-state-service.js +0 -8
- package/dist/lib/daemon/session-summarizer-service.d.ts +0 -14
- package/dist/lib/daemon/session-summarizer-service.js +1 -19
- package/dist/lib/daemon/session-title-service.d.ts +0 -25
- package/dist/lib/daemon/session-title-service.js +0 -32
- package/dist/lib/daemon/state-dir-check-service.d.ts +0 -24
- package/dist/lib/daemon/state-dir-check-service.js +0 -29
- package/dist/lib/daemon/supervisor.d.ts +0 -112
- package/dist/lib/daemon/supervisor.js +4 -147
- package/dist/lib/daemon/testdata/process-view-daemon.js +0 -2
- package/dist/lib/daemon/testdata/process-view-start.js +0 -5
- package/dist/lib/daemon/tmux-reap-service.d.ts +0 -1
- package/dist/lib/daemon/tmux-reap-service.js +0 -1
- package/dist/lib/daemon/usage-sync-service.d.ts +0 -23
- package/dist/lib/daemon/usage-sync-service.js +0 -26
- package/dist/lib/daemon/watchdog-service.d.ts +0 -9
- package/dist/lib/daemon/watchdog-service.js +0 -13
- package/dist/lib/daemon/webhook-receiver-service.d.ts +0 -1
- package/dist/lib/daemon/webhook-receiver-service.js +0 -1
- package/dist/lib/daemon-health.d.ts +0 -55
- package/dist/lib/daemon-health.js +4 -77
- package/dist/lib/daemon-services.d.ts +0 -36
- package/dist/lib/daemon-services.js +0 -45
- package/dist/lib/daemon-ticks.d.ts +0 -126
- package/dist/lib/daemon-ticks.js +1 -156
- package/dist/lib/daemon-webhooks.d.ts +0 -57
- package/dist/lib/daemon-webhooks.js +2 -54
- package/dist/lib/deeplink/register.d.ts +0 -15
- package/dist/lib/deeplink/register.js +0 -60
- package/dist/lib/deeplink/url.d.ts +0 -24
- package/dist/lib/deeplink/url.js +1 -33
- package/dist/lib/device-config.d.ts +1 -192
- package/dist/lib/device-config.js +86 -240
- package/dist/lib/devices/config-migration.d.ts +0 -43
- package/dist/lib/devices/config-migration.js +7 -127
- package/dist/lib/devices/connect.d.ts +0 -168
- package/dist/lib/devices/connect.js +6 -254
- package/dist/lib/devices/device-docs.d.ts +0 -24
- package/dist/lib/devices/device-docs.js +0 -46
- package/dist/lib/devices/discovery-policy.d.ts +0 -30
- package/dist/lib/devices/discovery-policy.js +3 -34
- package/dist/lib/devices/doctor-findings.d.ts +0 -109
- package/dist/lib/devices/doctor-findings.js +30 -326
- package/dist/lib/devices/doctor-overview-cache.d.ts +0 -33
- package/dist/lib/devices/doctor-overview-cache.js +0 -81
- package/dist/lib/devices/fleet-divergence.d.ts +0 -89
- package/dist/lib/devices/fleet-divergence.js +1 -60
- package/dist/lib/devices/fleet-inventory.d.ts +0 -27
- package/dist/lib/devices/fleet-inventory.js +0 -38
- package/dist/lib/devices/fleet.d.ts +0 -95
- package/dist/lib/devices/fleet.js +0 -79
- package/dist/lib/devices/harness-inventory.d.ts +0 -75
- package/dist/lib/devices/harness-inventory.js +0 -101
- package/dist/lib/devices/health-report.d.ts +0 -37
- package/dist/lib/devices/health-report.js +0 -73
- package/dist/lib/devices/health.d.ts +0 -71
- package/dist/lib/devices/health.js +2 -82
- package/dist/lib/devices/interactive-host.d.ts +0 -10
- package/dist/lib/devices/interactive-host.js +0 -34
- package/dist/lib/devices/known-hosts.d.ts +0 -45
- package/dist/lib/devices/known-hosts.js +0 -77
- package/dist/lib/devices/pending.d.ts +0 -31
- package/dist/lib/devices/pending.js +7 -67
- package/dist/lib/devices/pool.d.ts +0 -36
- package/dist/lib/devices/pool.js +0 -30
- package/dist/lib/devices/reachability.d.ts +0 -25
- package/dist/lib/devices/reachability.js +0 -14
- package/dist/lib/devices/registry.d.ts +0 -141
- package/dist/lib/devices/registry.js +4 -151
- package/dist/lib/devices/resolve-profile.d.ts +0 -18
- package/dist/lib/devices/resolve-profile.js +0 -18
- package/dist/lib/devices/resolve-target.d.ts +0 -20
- package/dist/lib/devices/resolve-target.js +1 -51
- package/dist/lib/devices/rollout-verify.d.ts +1 -81
- package/dist/lib/devices/rollout-verify.js +0 -77
- package/dist/lib/devices/self-host.d.ts +0 -7
- package/dist/lib/devices/self-host.js +1 -29
- package/dist/lib/devices/ssh-config.d.ts +0 -18
- package/dist/lib/devices/ssh-config.js +0 -9
- package/dist/lib/devices/stats-cache.d.ts +0 -48
- package/dist/lib/devices/stats-cache.js +0 -80
- package/dist/lib/devices/sync.d.ts +0 -97
- package/dist/lib/devices/sync.js +0 -88
- package/dist/lib/devices/tailscale.d.ts +0 -18
- package/dist/lib/devices/tailscale.js +1 -38
- package/dist/lib/devices/terminfo.d.ts +0 -27
- package/dist/lib/devices/terminfo.js +2 -64
- package/dist/lib/devices/worker-pick.d.ts +0 -15
- package/dist/lib/devices/worker-pick.js +0 -48
- package/dist/lib/diff-text.d.ts +0 -18
- package/dist/lib/diff-text.js +0 -15
- package/dist/lib/doctor-diff.d.ts +0 -79
- package/dist/lib/doctor-diff.js +2 -181
- package/dist/lib/drift-sync.d.ts +0 -29
- package/dist/lib/drift-sync.js +0 -40
- package/dist/lib/drift.d.ts +0 -43
- package/dist/lib/drift.js +0 -31
- package/dist/lib/event-families.d.ts +0 -17
- package/dist/lib/event-families.js +0 -33
- package/dist/lib/event-provenance.d.ts +0 -4
- package/dist/lib/event-provenance.js +0 -5
- package/dist/lib/event-stream.d.ts +0 -29
- package/dist/lib/event-stream.js +0 -36
- package/dist/lib/events-ingest.d.ts +0 -27
- package/dist/lib/events-ingest.js +0 -54
- package/dist/lib/exec-account-home.d.ts +0 -24
- package/dist/lib/exec-account-home.js +0 -41
- package/dist/lib/exec-bounded.d.ts +1 -37
- package/dist/lib/exec-bounded.js +10 -46
- package/dist/lib/exec.d.ts +3 -583
- package/dist/lib/exec.js +18 -1025
- package/dist/lib/factory/snapshot.js +1 -15
- package/dist/lib/feed/activity-stream.d.ts +0 -27
- package/dist/lib/feed/activity-stream.js +4 -80
- package/dist/lib/feed/activity.d.ts +1 -243
- package/dist/lib/feed/activity.js +8 -273
- package/dist/lib/feed/answer.d.ts +0 -103
- package/dist/lib/feed/answer.js +0 -267
- package/dist/lib/feed/attention.d.ts +0 -56
- package/dist/lib/feed/attention.js +0 -161
- package/dist/lib/feed/envelope.d.ts +2 -17
- package/dist/lib/feed/envelope.js +0 -14
- package/dist/lib/feed/events.d.ts +0 -118
- package/dist/lib/feed/events.js +13 -213
- package/dist/lib/feed/feed.d.ts +1 -250
- package/dist/lib/feed/feed.js +24 -334
- package/dist/lib/feed/hub-server.d.ts +0 -100
- package/dist/lib/feed/hub-server.js +1 -191
- package/dist/lib/feed/hub.d.ts +0 -53
- package/dist/lib/feed/hub.js +0 -89
- package/dist/lib/feed/pr-status.d.ts +1 -19
- package/dist/lib/feed/pr-status.js +0 -18
- package/dist/lib/feed/tool-activity.d.ts +0 -59
- package/dist/lib/feed/tool-activity.js +1 -119
- package/dist/lib/feed/tools.d.ts +0 -100
- package/dist/lib/feed/tools.js +0 -89
- package/dist/lib/feed/watch.d.ts +0 -33
- package/dist/lib/feed/watch.js +2 -94
- package/dist/lib/feed-broadcast.d.ts +0 -148
- package/dist/lib/feed-broadcast.js +1 -283
- package/dist/lib/feed-outcome.d.ts +0 -50
- package/dist/lib/feed-outcome.js +1 -67
- package/dist/lib/feed-policy.d.ts +0 -6
- package/dist/lib/feed-policy.js +1 -27
- package/dist/lib/feed-post.d.ts +0 -61
- package/dist/lib/feed-post.js +4 -61
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -64
- package/dist/lib/fleet/apply.js +0 -125
- package/dist/lib/fleet/auth-sync.d.ts +0 -48
- package/dist/lib/fleet/auth-sync.js +4 -49
- package/dist/lib/fleet/capture.d.ts +0 -26
- package/dist/lib/fleet/capture.js +1 -36
- package/dist/lib/fleet/manifest.d.ts +0 -38
- package/dist/lib/fleet/manifest.js +0 -40
- package/dist/lib/fleet/types.d.ts +1 -138
- package/dist/lib/fleet/types.js +0 -12
- package/dist/lib/fleet-cache.d.ts +0 -12
- package/dist/lib/fleet-cache.js +0 -24
- package/dist/lib/fleet-shared-state.d.ts +6 -59
- package/dist/lib/fleet-shared-state.js +5 -51
- package/dist/lib/fleet-status.d.ts +0 -27
- package/dist/lib/fleet-status.js +0 -48
- package/dist/lib/format.d.ts +0 -74
- package/dist/lib/format.js +3 -77
- package/dist/lib/friction-heuristics.d.ts +0 -20
- package/dist/lib/friction-heuristics.js +0 -8
- package/dist/lib/fs-atomic.d.ts +0 -51
- package/dist/lib/fs-atomic.js +8 -66
- package/dist/lib/fs-walk.d.ts +0 -13
- package/dist/lib/fs-walk.js +0 -22
- package/dist/lib/fuzzy.d.ts +0 -29
- package/dist/lib/fuzzy.js +0 -31
- package/dist/lib/gemini-settings.js +0 -12
- package/dist/lib/git.d.ts +0 -366
- package/dist/lib/git.js +7 -574
- package/dist/lib/github/ci-failure.d.ts +30 -0
- package/dist/lib/github/ci-failure.js +95 -0
- package/dist/lib/github/gh-overload.d.ts +0 -38
- package/dist/lib/github/gh-overload.js +3 -55
- package/dist/lib/github/pr-mergeable.d.ts +3 -34
- package/dist/lib/github/pr-mergeable.js +2 -42
- package/dist/lib/github/pr-verdict.d.ts +0 -44
- package/dist/lib/github/pr-verdict.js +0 -36
- package/dist/lib/github/project-prs.d.ts +135 -105
- package/dist/lib/github/project-prs.js +530 -170
- package/dist/lib/github/release-drift.d.ts +45 -0
- package/dist/lib/github/release-drift.js +91 -0
- package/dist/lib/github/rest.d.ts +0 -50
- package/dist/lib/github/rest.js +0 -49
- package/dist/lib/github/viewer.d.ts +27 -0
- package/dist/lib/github/viewer.js +101 -0
- package/dist/lib/goose-commands.d.ts +0 -29
- package/dist/lib/goose-commands.js +3 -48
- package/dist/lib/harness/adapter.d.ts +0 -151
- package/dist/lib/harness/adapter.js +0 -41
- package/dist/lib/harness/adapters/claude.d.ts +0 -8
- package/dist/lib/harness/adapters/claude.js +0 -89
- package/dist/lib/harness/adapters/codex.js +0 -18
- package/dist/lib/harness/adapters/copilot.js +0 -3
- package/dist/lib/harness/adapters/cursor.js +0 -16
- package/dist/lib/harness/adapters/droid.js +0 -3
- package/dist/lib/harness/adapters/kimi.js +0 -19
- package/dist/lib/harness/adapters/muse.js +0 -9
- package/dist/lib/harness/adapters/opencode.js +0 -2
- package/dist/lib/harness/exec-config-version.d.ts +0 -2
- package/dist/lib/harness/exec-config-version.js +0 -13
- package/dist/lib/harness/index.js +0 -10
- package/dist/lib/harness-auth-capabilities.d.ts +0 -26
- package/dist/lib/harness-auth-capabilities.js +0 -18
- package/dist/lib/harness-connection-test.d.ts +0 -27
- package/dist/lib/harness-connection-test.js +2 -20
- package/dist/lib/heal.d.ts +0 -45
- package/dist/lib/heal.js +2 -82
- package/dist/lib/help.d.ts +0 -32
- package/dist/lib/help.js +0 -41
- package/dist/lib/helper-download.d.ts +0 -85
- package/dist/lib/helper-download.js +0 -95
- package/dist/lib/helper-versions.d.ts +0 -51
- package/dist/lib/helper-versions.js +1 -45
- package/dist/lib/hooks/cache.d.ts +0 -40
- package/dist/lib/hooks/cache.js +8 -122
- package/dist/lib/hooks/install.d.ts +0 -253
- package/dist/lib/hooks/install.js +49 -822
- package/dist/lib/hooks/match.d.ts +0 -24
- package/dist/lib/hooks/match.js +0 -31
- package/dist/lib/hooks/profile.d.ts +0 -21
- package/dist/lib/hooks/profile.js +0 -28
- package/dist/lib/hosts/credential-transport.d.ts +0 -6
- package/dist/lib/hosts/credential-transport.js +0 -17
- package/dist/lib/hosts/credentials.d.ts +0 -35
- package/dist/lib/hosts/credentials.js +0 -38
- package/dist/lib/hosts/dispatch.d.ts +0 -140
- package/dist/lib/hosts/dispatch.js +0 -176
- package/dist/lib/hosts/logs.d.ts +0 -25
- package/dist/lib/hosts/logs.js +1 -51
- package/dist/lib/hosts/option.d.ts +0 -12
- package/dist/lib/hosts/option.js +0 -12
- package/dist/lib/hosts/passthrough.d.ts +0 -129
- package/dist/lib/hosts/passthrough.js +12 -249
- package/dist/lib/hosts/progress.d.ts +0 -90
- package/dist/lib/hosts/progress.js +5 -115
- package/dist/lib/hosts/providers/devices.d.ts +0 -19
- package/dist/lib/hosts/providers/devices.js +1 -34
- package/dist/lib/hosts/providers/local.d.ts +0 -14
- package/dist/lib/hosts/providers/local.js +0 -22
- package/dist/lib/hosts/ready.d.ts +0 -99
- package/dist/lib/hosts/ready.js +0 -101
- package/dist/lib/hosts/reconcile.d.ts +0 -38
- package/dist/lib/hosts/reconcile.js +1 -50
- package/dist/lib/hosts/reconnect.d.ts +0 -75
- package/dist/lib/hosts/reconnect.js +0 -98
- package/dist/lib/hosts/registry.d.ts +0 -74
- package/dist/lib/hosts/registry.js +0 -110
- package/dist/lib/hosts/remote-cmd.d.ts +1 -228
- package/dist/lib/hosts/remote-cmd.js +19 -294
- package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +0 -1
- package/dist/lib/hosts/remote-cmd.test-fixture.js +0 -12
- package/dist/lib/hosts/remote-os.d.ts +0 -19
- package/dist/lib/hosts/remote-os.js +0 -22
- package/dist/lib/hosts/remote-session-id.d.ts +0 -22
- package/dist/lib/hosts/remote-session-id.js +0 -24
- package/dist/lib/hosts/routing-flag.d.ts +0 -21
- package/dist/lib/hosts/routing-flag.js +0 -21
- package/dist/lib/hosts/run-target.d.ts +0 -53
- package/dist/lib/hosts/run-target.js +0 -56
- package/dist/lib/hosts/session-index.d.ts +1 -53
- package/dist/lib/hosts/session-index.js +2 -59
- package/dist/lib/hosts/session-marker.d.ts +0 -31
- package/dist/lib/hosts/session-marker.js +0 -32
- package/dist/lib/hosts/ssh-config.d.ts +0 -25
- package/dist/lib/hosts/ssh-config.js +1 -32
- package/dist/lib/hosts/tasks.d.ts +0 -54
- package/dist/lib/hosts/tasks.js +0 -35
- package/dist/lib/hosts/types.d.ts +0 -39
- package/dist/lib/hosts/types.js +0 -22
- package/dist/lib/humans.d.ts +0 -21
- package/dist/lib/humans.js +0 -30
- package/dist/lib/identity/client.d.ts +1 -35
- package/dist/lib/identity/client.js +3 -29
- package/dist/lib/identity/index.d.ts +3 -27
- package/dist/lib/identity/index.js +8 -24
- package/dist/lib/import.d.ts +0 -104
- package/dist/lib/import.js +1 -137
- package/dist/lib/installations/active-check.d.ts +0 -53
- package/dist/lib/installations/active-check.js +0 -49
- package/dist/lib/installations/index.d.ts +0 -9
- package/dist/lib/installations/index.js +0 -9
- package/dist/lib/installations/installation-lock.js +0 -8
- package/dist/lib/installations/launch-gate.d.ts +0 -56
- package/dist/lib/installations/launch-gate.js +0 -83
- package/dist/lib/installations/migrate.d.ts +0 -100
- package/dist/lib/installations/migrate.js +105 -572
- package/dist/lib/installations/native-command.d.ts +0 -1
- package/dist/lib/installations/native-command.js +0 -6
- package/dist/lib/installations/resolve.d.ts +0 -24
- package/dist/lib/installations/resolve.js +0 -24
- package/dist/lib/installations/shims.d.ts +0 -395
- package/dist/lib/installations/shims.js +30 -957
- package/dist/lib/installations/store.d.ts +0 -199
- package/dist/lib/installations/store.js +1 -297
- package/dist/lib/installations/strategies.d.ts +0 -44
- package/dist/lib/installations/strategies.js +0 -87
- package/dist/lib/installations/types.d.ts +1 -67
- package/dist/lib/installations/types.js +0 -6
- package/dist/lib/installations/update-cancellation.d.ts +0 -74
- package/dist/lib/installations/update-cancellation.js +0 -74
- package/dist/lib/installations/update-policy.d.ts +0 -57
- package/dist/lib/installations/update-policy.js +0 -62
- package/dist/lib/installations/update-runtime.d.ts +0 -88
- package/dist/lib/installations/update-runtime.js +1 -127
- package/dist/lib/installations/update.d.ts +0 -53
- package/dist/lib/installations/update.js +0 -95
- package/dist/lib/installations/versions.d.ts +0 -310
- package/dist/lib/installations/versions.js +14 -837
- package/dist/lib/isolation-boundary-report.d.ts +0 -7
- package/dist/lib/isolation-boundary-report.js +0 -7
- package/dist/lib/launch-identity.d.ts +0 -8
- package/dist/lib/launch-identity.js +0 -8
- package/dist/lib/linear-autoclose.d.ts +0 -25
- package/dist/lib/linear-autoclose.js +0 -19
- package/dist/lib/linear-cache.d.ts +0 -57
- package/dist/lib/linear-cache.js +1 -81
- package/dist/lib/linear-project-counts.d.ts +0 -83
- package/dist/lib/linear-project-counts.js +2 -64
- package/dist/lib/linear-projects.d.ts +0 -62
- package/dist/lib/linear-projects.js +0 -85
- package/dist/lib/linear-rate-limit.d.ts +0 -21
- package/dist/lib/linear-rate-limit.js +1 -93
- package/dist/lib/linux-userns.d.ts +1 -42
- package/dist/lib/linux-userns.js +0 -47
- package/dist/lib/lock-compromise.d.ts +0 -7
- package/dist/lib/lock-compromise.js +0 -7
- package/dist/lib/log-follow.d.ts +0 -2
- package/dist/lib/log-follow.js +5 -15
- package/dist/lib/loop.d.ts +0 -106
- package/dist/lib/loop.js +0 -135
- package/dist/lib/machine-id.d.ts +0 -19
- package/dist/lib/machine-id.js +0 -19
- package/dist/lib/mailbox-gc.d.ts +0 -7
- package/dist/lib/mailbox-gc.js +0 -25
- package/dist/lib/mailbox-target.d.ts +0 -31
- package/dist/lib/mailbox-target.js +0 -27
- package/dist/lib/mailbox.d.ts +0 -77
- package/dist/lib/mailbox.js +5 -105
- package/dist/lib/manifest.d.ts +0 -4
- package/dist/lib/manifest.js +0 -36
- package/dist/lib/markdown.d.ts +0 -3
- package/dist/lib/markdown.js +0 -9
- package/dist/lib/mcp-registry.d.ts +1 -50
- package/dist/lib/mcp-registry.js +0 -64
- package/dist/lib/mcp.d.ts +0 -115
- package/dist/lib/mcp.js +3 -199
- package/dist/lib/memory-cache.d.ts +0 -11
- package/dist/lib/memory-cache.js +0 -9
- package/dist/lib/memory.d.ts +0 -52
- package/dist/lib/memory.js +12 -74
- package/dist/lib/menubar/download-menubar.d.ts +0 -35
- package/dist/lib/menubar/download-menubar.js +0 -38
- package/dist/lib/menubar/install-menubar.d.ts +0 -405
- package/dist/lib/menubar/install-menubar.js +25 -667
- package/dist/lib/menubar/migrate-prefs.d.ts +0 -47
- package/dist/lib/menubar/migrate-prefs.js +1 -70
- package/dist/lib/menubar/notify-desktop.d.ts +0 -82
- package/dist/lib/menubar/notify-desktop.js +0 -68
- package/dist/lib/menubar/resolve-version.d.ts +0 -41
- package/dist/lib/menubar/resolve-version.js +2 -44
- package/dist/lib/menubar/snapshot.d.ts +13 -66
- package/dist/lib/menubar/snapshot.js +45 -39
- package/dist/lib/merged-resources.d.ts +0 -10
- package/dist/lib/merged-resources.js +0 -10
- package/dist/lib/migrate-fold.d.ts +0 -31
- package/dist/lib/migrate-fold.js +6 -38
- package/dist/lib/model-tier-overrides.d.ts +0 -30
- package/dist/lib/model-tier-overrides.js +0 -14
- package/dist/lib/model-tiers.d.ts +0 -43
- package/dist/lib/model-tiers.js +5 -78
- package/dist/lib/models.d.ts +0 -145
- package/dist/lib/models.js +3 -333
- package/dist/lib/monitors/config.d.ts +0 -187
- package/dist/lib/monitors/config.js +4 -101
- package/dist/lib/monitors/dispatch.d.ts +0 -22
- package/dist/lib/monitors/dispatch.js +0 -35
- package/dist/lib/monitors/engine.d.ts +1 -53
- package/dist/lib/monitors/engine.js +17 -106
- package/dist/lib/monitors/fingerprint.d.ts +0 -43
- package/dist/lib/monitors/fingerprint.js +0 -57
- package/dist/lib/monitors/pid-watch.d.ts +0 -31
- package/dist/lib/monitors/pid-watch.js +0 -31
- package/dist/lib/monitors/remote.d.ts +0 -52
- package/dist/lib/monitors/remote.js +0 -42
- package/dist/lib/monitors/sources/command.d.ts +2 -9
- package/dist/lib/monitors/sources/command.js +13 -34
- package/dist/lib/monitors/sources/device.d.ts +0 -10
- package/dist/lib/monitors/sources/device.js +0 -14
- package/dist/lib/monitors/sources/failure.d.ts +0 -27
- package/dist/lib/monitors/sources/failure.js +0 -27
- package/dist/lib/monitors/sources/file.d.ts +0 -10
- package/dist/lib/monitors/sources/file.js +0 -11
- package/dist/lib/monitors/sources/http.d.ts +0 -7
- package/dist/lib/monitors/sources/http.js +0 -9
- package/dist/lib/monitors/sources/index.d.ts +0 -9
- package/dist/lib/monitors/sources/index.js +0 -9
- package/dist/lib/monitors/sources/poll.d.ts +0 -8
- package/dist/lib/monitors/sources/poll.js +0 -8
- package/dist/lib/monitors/sources/types.d.ts +0 -18
- package/dist/lib/monitors/sources/types.js +0 -8
- package/dist/lib/monitors/sources/webhook.d.ts +0 -7
- package/dist/lib/monitors/sources/webhook.js +0 -7
- package/dist/lib/monitors/sources/ws.d.ts +0 -10
- package/dist/lib/monitors/sources/ws.js +3 -13
- package/dist/lib/monitors/state.d.ts +0 -132
- package/dist/lib/monitors/state.js +2 -86
- package/dist/lib/native-accounts.d.ts +0 -32
- package/dist/lib/native-accounts.js +0 -17
- package/dist/lib/net-close.d.ts +0 -9
- package/dist/lib/net-close.js +0 -5
- package/dist/lib/notify.d.ts +0 -47
- package/dist/lib/notify.js +0 -30
- package/dist/lib/onepassword.d.ts +0 -14
- package/dist/lib/onepassword.js +0 -12
- package/dist/lib/open-url.d.ts +0 -38
- package/dist/lib/open-url.js +1 -69
- package/dist/lib/openclaw-keychain.js +2 -7
- package/dist/lib/operator.d.ts +0 -9
- package/dist/lib/operator.js +0 -34
- package/dist/lib/origin-machine.d.ts +0 -16
- package/dist/lib/origin-machine.js +0 -16
- package/dist/lib/output/git-output.d.ts +0 -31
- package/dist/lib/output/git-output.js +4 -43
- package/dist/lib/overdue.d.ts +0 -35
- package/dist/lib/overdue.js +0 -60
- package/dist/lib/owner-message.d.ts +0 -20
- package/dist/lib/owner-message.js +1 -40
- package/dist/lib/packages/output-home.d.ts +0 -28
- package/dist/lib/packages/output-home.js +0 -114
- package/dist/lib/paths.d.ts +0 -26
- package/dist/lib/paths.js +1 -27
- package/dist/lib/percentile.d.ts +0 -11
- package/dist/lib/percentile.js +0 -11
- package/dist/lib/perf/db.d.ts +0 -16
- package/dist/lib/perf/db.js +3 -32
- package/dist/lib/perf/spool.d.ts +0 -12
- package/dist/lib/perf/spool.js +0 -13
- package/dist/lib/perf/types.d.ts +0 -26
- package/dist/lib/perf/types.js +0 -1
- package/dist/lib/permissions-registry.d.ts +0 -48
- package/dist/lib/permissions-registry.js +0 -108
- package/dist/lib/permissions.d.ts +0 -215
- package/dist/lib/permissions.js +4 -407
- package/dist/lib/picker.d.ts +0 -124
- package/dist/lib/picker.js +0 -140
- package/dist/lib/placement.d.ts +0 -57
- package/dist/lib/placement.js +0 -47
- package/dist/lib/platform/exec.d.ts +0 -73
- package/dist/lib/platform/exec.js +0 -80
- package/dist/lib/platform/index.d.ts +0 -14
- package/dist/lib/platform/index.js +0 -14
- package/dist/lib/platform/ipc.d.ts +0 -10
- package/dist/lib/platform/ipc.js +0 -13
- package/dist/lib/platform/links.d.ts +0 -14
- package/dist/lib/platform/links.js +0 -25
- package/dist/lib/platform/paths.d.ts +0 -48
- package/dist/lib/platform/paths.js +0 -52
- package/dist/lib/platform/posixpath.d.ts +0 -18
- package/dist/lib/platform/posixpath.js +0 -62
- package/dist/lib/platform/process.d.ts +0 -67
- package/dist/lib/platform/process.js +5 -99
- package/dist/lib/platform/winpath.d.ts +0 -50
- package/dist/lib/platform/winpath.js +0 -81
- package/dist/lib/plugins/plugin-marketplace.d.ts +0 -165
- package/dist/lib/plugins/plugin-marketplace.js +10 -238
- package/dist/lib/plugins/plugins.d.ts +0 -238
- package/dist/lib/plugins/plugins.js +20 -454
- package/dist/lib/plugins/skills.d.ts +0 -86
- package/dist/lib/plugins/skills.js +1 -139
- package/dist/lib/pr-land-detach.d.ts +0 -17
- package/dist/lib/pr-land-detach.js +0 -30
- package/dist/lib/pricing/cost.d.ts +0 -29
- package/dist/lib/pricing/cost.js +0 -38
- package/dist/lib/pricing/index.d.ts +0 -6
- package/dist/lib/pricing/index.js +0 -6
- package/dist/lib/pricing/table.d.ts +0 -8
- package/dist/lib/pricing/table.js +3 -56
- package/dist/lib/probe.d.ts +0 -5
- package/dist/lib/probe.js +0 -40
- package/dist/lib/profiles-presets.d.ts +0 -20
- package/dist/lib/profiles-presets.js +1 -36
- package/dist/lib/profiles.d.ts +0 -185
- package/dist/lib/profiles.js +1 -158
- package/dist/lib/project-doctor.d.ts +0 -29
- package/dist/lib/project-doctor.js +0 -26
- package/dist/lib/project-focus.d.ts +0 -41
- package/dist/lib/project-focus.js +0 -49
- package/dist/lib/project-import.d.ts +0 -41
- package/dist/lib/project-import.js +0 -36
- package/dist/lib/project-key.d.ts +0 -65
- package/dist/lib/project-key.js +0 -70
- package/dist/lib/project-launch.d.ts +0 -49
- package/dist/lib/project-launch.js +2 -91
- package/dist/lib/project-probe.d.ts +0 -86
- package/dist/lib/project-probe.js +1 -88
- package/dist/lib/project-pull.d.ts +0 -96
- package/dist/lib/project-pull.js +0 -122
- package/dist/lib/project-resources.d.ts +0 -44
- package/dist/lib/project-resources.js +7 -171
- package/dist/lib/project-root.d.ts +0 -95
- package/dist/lib/project-root.js +0 -101
- package/dist/lib/project-schedule.d.ts +0 -43
- package/dist/lib/project-schedule.js +0 -52
- package/dist/lib/project-status.d.ts +0 -108
- package/dist/lib/project-status.js +0 -117
- package/dist/lib/projects.d.ts +0 -197
- package/dist/lib/projects.js +1 -213
- package/dist/lib/pwsh.d.ts +0 -41
- package/dist/lib/pwsh.js +0 -51
- package/dist/lib/quick-todo.d.ts +84 -0
- package/dist/lib/quick-todo.js +243 -0
- package/dist/lib/reconcile-and-repair.d.ts +0 -78
- package/dist/lib/reconcile-and-repair.js +3 -66
- package/dist/lib/redact.d.ts +0 -29
- package/dist/lib/redact.js +0 -54
- package/dist/lib/refresh-coordinator.d.ts +0 -15
- package/dist/lib/refresh-coordinator.js +0 -10
- package/dist/lib/refresh.d.ts +0 -39
- package/dist/lib/refresh.js +0 -45
- package/dist/lib/registry.d.ts +0 -65
- package/dist/lib/registry.js +0 -127
- package/dist/lib/reminders.d.ts +0 -21
- package/dist/lib/reminders.js +0 -30
- package/dist/lib/remote-agents-json.d.ts +0 -44
- package/dist/lib/remote-agents-json.js +1 -44
- package/dist/lib/reserved-stores.d.ts +0 -28
- package/dist/lib/reserved-stores.js +2 -28
- package/dist/lib/resource-aliases.d.ts +0 -12
- package/dist/lib/resource-aliases.js +0 -12
- package/dist/lib/resource-content-diff.d.ts +0 -28
- package/dist/lib/resource-content-diff.js +7 -34
- package/dist/lib/resource-inventory.d.ts +0 -51
- package/dist/lib/resource-inventory.js +0 -45
- package/dist/lib/resource-patterns.d.ts +0 -32
- package/dist/lib/resource-patterns.js +0 -34
- package/dist/lib/resource-profiles.d.ts +0 -7
- package/dist/lib/resource-profiles.js +0 -11
- package/dist/lib/resources/types.d.ts +0 -50
- package/dist/lib/resources/types.js +0 -7
- package/dist/lib/resources/workflows.d.ts +0 -7
- package/dist/lib/resources/workflows.js +0 -13
- package/dist/lib/resources.d.ts +0 -65
- package/dist/lib/resources.js +0 -78
- package/dist/lib/routers.d.ts +0 -67
- package/dist/lib/routers.js +0 -60
- package/dist/lib/routine-activation.d.ts +0 -23
- package/dist/lib/routine-activation.js +0 -24
- package/dist/lib/routine-context.d.ts +1 -91
- package/dist/lib/routine-context.js +0 -107
- package/dist/lib/routine-notify-owner.d.ts +0 -79
- package/dist/lib/routine-notify-owner.js +1 -103
- package/dist/lib/routine-notify.d.ts +0 -70
- package/dist/lib/routine-notify.js +1 -75
- package/dist/lib/routine-process-cleanup.d.ts +0 -1
- package/dist/lib/routine-process-cleanup.js +1 -4
- package/dist/lib/routine-readiness.d.ts +0 -63
- package/dist/lib/routine-readiness.js +4 -86
- package/dist/lib/routines-format.d.ts +0 -40
- package/dist/lib/routines-format.js +0 -67
- package/dist/lib/routines-placement.d.ts +0 -33
- package/dist/lib/routines-placement.js +0 -40
- package/dist/lib/routines-project.d.ts +0 -57
- package/dist/lib/routines-project.js +6 -80
- package/dist/lib/rules/compile.d.ts +0 -66
- package/dist/lib/rules/compile.js +6 -118
- package/dist/lib/rules/compose.d.ts +0 -56
- package/dist/lib/rules/compose.js +2 -83
- package/dist/lib/rules/rules.d.ts +0 -23
- package/dist/lib/rules/rules.js +0 -35
- package/dist/lib/rules/run-sync.d.ts +0 -16
- package/dist/lib/rules/run-sync.js +1 -44
- package/dist/lib/run-config.d.ts +0 -7
- package/dist/lib/run-config.js +0 -8
- package/dist/lib/run-defaults.d.ts +0 -14
- package/dist/lib/run-defaults.js +0 -14
- package/dist/lib/run-notify.d.ts +0 -18
- package/dist/lib/run-notify.js +0 -36
- package/dist/lib/run-trace-sync.d.ts +0 -21
- package/dist/lib/run-trace-sync.js +2 -66
- package/dist/lib/rush-session.d.ts +0 -26
- package/dist/lib/rush-session.js +0 -28
- package/dist/lib/sandbox.d.ts +0 -45
- package/dist/lib/sandbox.js +5 -93
- package/dist/lib/scheduler.d.ts +0 -28
- package/dist/lib/scheduler.js +0 -45
- package/dist/lib/scheduling/routines.d.ts +0 -652
- package/dist/lib/scheduling/routines.js +8 -475
- package/dist/lib/secrets-cli.d.ts +3 -8
- package/dist/lib/secrets-cli.js +1 -19
- package/dist/lib/secrets-client.d.ts +0 -117
- package/dist/lib/secrets-client.js +4 -275
- package/dist/lib/secrets-policy.d.ts +0 -142
- package/dist/lib/secrets-policy.js +4 -237
- package/dist/lib/secrets-types.d.ts +0 -87
- package/dist/lib/secrets-types.js +0 -13
- package/dist/lib/self-heal/checks/hook-manifest.js +0 -25
- package/dist/lib/self-heal/checks/hook-runtime.js +0 -5
- package/dist/lib/self-heal/checks/install-staging.d.ts +0 -1
- package/dist/lib/self-heal/checks/install-staging.js +1 -28
- package/dist/lib/self-heal/checks/menubar-helper.js +0 -5
- package/dist/lib/self-heal/checks/path.js +0 -9
- package/dist/lib/self-heal/checks/resources.js +0 -5
- package/dist/lib/self-heal/checks/shadowing.js +2 -16
- package/dist/lib/self-heal/checks/shims.js +0 -14
- package/dist/lib/self-heal/child.d.ts +12 -0
- package/dist/lib/self-heal/child.js +23 -0
- package/dist/lib/self-heal/registry.d.ts +0 -9
- package/dist/lib/self-heal/registry.js +0 -16
- package/dist/lib/self-heal/types.d.ts +0 -12
- package/dist/lib/self-heal/types.js +0 -15
- package/dist/lib/self-update.d.ts +0 -312
- package/dist/lib/self-update.js +9 -360
- package/dist/lib/service-manifest.d.ts +0 -39
- package/dist/lib/service-manifest.js +0 -72
- package/dist/lib/session/active.d.ts +13 -869
- package/dist/lib/session/active.js +17 -976
- package/dist/lib/session/actor-sidecar.d.ts +1 -32
- package/dist/lib/session/actor-sidecar.js +1 -41
- package/dist/lib/session/bookmarks.d.ts +0 -33
- package/dist/lib/session/bookmarks.js +0 -37
- package/dist/lib/session/bundle.d.ts +0 -86
- package/dist/lib/session/bundle.js +0 -54
- package/dist/lib/session/claude-accounts.d.ts +0 -40
- package/dist/lib/session/claude-accounts.js +0 -49
- package/dist/lib/session/cloud.d.ts +1 -23
- package/dist/lib/session/cloud.js +0 -26
- package/dist/lib/session/db.d.ts +5 -658
- package/dist/lib/session/db.js +22 -1443
- package/dist/lib/session/detached.d.ts +0 -21
- package/dist/lib/session/detached.js +0 -29
- package/dist/lib/session/discover.d.ts +3 -420
- package/dist/lib/session/discover.js +30 -1123
- package/dist/lib/session/fork.d.ts +1 -41
- package/dist/lib/session/fork.js +0 -19
- package/dist/lib/session/ghostty-tabs.d.ts +0 -24
- package/dist/lib/session/ghostty-tabs.js +0 -37
- package/dist/lib/session/glance-files.d.ts +19 -0
- package/dist/lib/session/glance-files.js +258 -0
- package/dist/lib/session/hook-sessions.d.ts +0 -33
- package/dist/lib/session/hook-sessions.js +4 -99
- package/dist/lib/session/host-link.d.ts +1 -94
- package/dist/lib/session/host-link.js +1 -81
- package/dist/lib/session/inject-target.d.ts +8 -0
- package/dist/lib/session/inject-target.js +32 -0
- package/dist/lib/session/inject.d.ts +0 -15
- package/dist/lib/session/inject.js +0 -15
- package/dist/lib/session/live-metadata.d.ts +1 -34
- package/dist/lib/session/live-metadata.js +1 -73
- package/dist/lib/session/local-tmux-attach.d.ts +0 -37
- package/dist/lib/session/local-tmux-attach.js +1 -76
- package/dist/lib/session/migrate-targets.d.ts +0 -46
- package/dist/lib/session/migrate-targets.js +0 -24
- package/dist/lib/session/migrations.d.ts +0 -12
- package/dist/lib/session/migrations.js +1 -20
- package/dist/lib/session/mirror.d.ts +0 -32
- package/dist/lib/session/mirror.js +0 -77
- package/dist/lib/session/origin-machine.js +0 -3
- package/dist/lib/session/pid-registry.d.ts +0 -80
- package/dist/lib/session/pid-registry.js +2 -81
- package/dist/lib/session/presence.d.ts +0 -39
- package/dist/lib/session/presence.js +2 -52
- package/dist/lib/session/process-view.d.ts +0 -11
- package/dist/lib/session/process-view.js +0 -25
- package/dist/lib/session/projection.d.ts +0 -3
- package/dist/lib/session/projection.js +0 -10
- package/dist/lib/session/provenance.d.ts +1 -37
- package/dist/lib/session/provenance.js +0 -69
- package/dist/lib/session/recovery.d.ts +1 -40
- package/dist/lib/session/recovery.js +2 -80
- package/dist/lib/session/relative-time.js +0 -3
- package/dist/lib/session/remote/peer-stream.d.ts +0 -42
- package/dist/lib/session/remote/peer-stream.js +0 -64
- package/dist/lib/session/remote/remote-bundle.d.ts +0 -6
- package/dist/lib/session/remote/remote-bundle.js +0 -21
- package/dist/lib/session/remote/remote-list.d.ts +1 -110
- package/dist/lib/session/remote/remote-list.js +5 -139
- package/dist/lib/session/remote/remote.d.ts +0 -98
- package/dist/lib/session/remote/remote.js +3 -119
- package/dist/lib/session/remote/watch.d.ts +1 -34
- package/dist/lib/session/remote/watch.js +12 -72
- package/dist/lib/session/remote-active.d.ts +0 -35
- package/dist/lib/session/remote-active.js +0 -48
- package/dist/lib/session/remote-bundle.js +0 -2
- package/dist/lib/session/remote-list.js +0 -2
- package/dist/lib/session/remote-preview-cache.d.ts +0 -7
- package/dist/lib/session/remote-preview-cache.js +1 -76
- package/dist/lib/session/remote.js +0 -2
- package/dist/lib/session/resume-command.d.ts +0 -6
- package/dist/lib/session/resume-command.js +0 -6
- package/dist/lib/session/resume-owner.d.ts +1 -52
- package/dist/lib/session/resume-owner.js +0 -56
- package/dist/lib/session/run-names.d.ts +0 -24
- package/dist/lib/session/run-names.js +0 -26
- package/dist/lib/session/session-cache.d.ts +2 -146
- package/dist/lib/session/session-cache.js +26 -203
- package/dist/lib/session/short-id.js +0 -3
- package/dist/lib/session/sync/agents.d.ts +0 -68
- package/dist/lib/session/sync/agents.js +0 -0
- package/dist/lib/session/sync/backend.d.ts +0 -39
- package/dist/lib/session/sync/backend.js +0 -45
- package/dist/lib/session/sync/config.d.ts +0 -27
- package/dist/lib/session/sync/config.js +0 -56
- package/dist/lib/session/sync/managed-config.d.ts +0 -17
- package/dist/lib/session/sync/managed-config.js +0 -17
- package/dist/lib/session/sync/managed-key.d.ts +0 -38
- package/dist/lib/session/sync/managed-key.js +1 -42
- package/dist/lib/session/sync/net-client.d.ts +0 -36
- package/dist/lib/session/sync/net-client.js +0 -30
- package/dist/lib/session/sync/provision.d.ts +0 -2
- package/dist/lib/session/sync/provision.js +0 -13
- package/dist/lib/session/sync/r2.d.ts +0 -20
- package/dist/lib/session/sync/r2.js +0 -20
- package/dist/lib/session/sync/transcript-crypto.d.ts +0 -37
- package/dist/lib/session/sync/transcript-crypto.js +5 -37
- package/dist/lib/session/sync/worker-template.d.ts +0 -5
- package/dist/lib/session/sync/worker-template.js +0 -40
- package/dist/lib/session/testdata/pid-registry-namespace.js +0 -2
- package/dist/lib/session/testdata/process-view-private.js +0 -1
- package/dist/lib/session/throughput.d.ts +0 -24
- package/dist/lib/session/throughput.js +1 -25
- package/dist/lib/session/timeline-pass.d.ts +1 -63
- package/dist/lib/session/timeline-pass.js +161 -148
- package/dist/lib/session/title.d.ts +0 -182
- package/dist/lib/session/title.js +0 -139
- package/dist/lib/session/tool-index.d.ts +2 -21
- package/dist/lib/session/tool-index.js +3 -75
- package/dist/lib/session/tool-store.d.ts +2 -48
- package/dist/lib/session/tool-store.js +1 -33
- package/dist/lib/session/viewing-in.d.ts +0 -67
- package/dist/lib/session/viewing-in.js +1 -71
- package/dist/lib/session/watch.js +0 -2
- package/dist/lib/session/width.js +0 -3
- package/dist/lib/sessions-client.d.ts +0 -46
- package/dist/lib/sessions-client.js +36 -113
- package/dist/lib/settings-manifest.d.ts +1 -17
- package/dist/lib/settings-manifest.js +4 -57
- package/dist/lib/setup-tool-install.d.ts +0 -1
- package/dist/lib/setup-tool-install.js +2 -7
- package/dist/lib/setup-tool-status.d.ts +0 -3
- package/dist/lib/setup-tool-status.js +4 -14
- package/dist/lib/sha256-asset.d.ts +0 -20
- package/dist/lib/sha256-asset.js +0 -20
- package/dist/lib/share-runtime.d.ts +0 -10
- package/dist/lib/share-runtime.js +1 -27
- package/dist/lib/shim-heal.d.ts +0 -15
- package/dist/lib/shim-heal.js +3 -29
- package/dist/lib/signin-badge.d.ts +0 -72
- package/dist/lib/signin-badge.js +0 -86
- package/dist/lib/sink-format.d.ts +0 -32
- package/dist/lib/sink-format.js +0 -14
- package/dist/lib/smart-launch.d.ts +0 -75
- package/dist/lib/smart-launch.js +1 -83
- package/dist/lib/snapshot.d.ts +0 -46
- package/dist/lib/snapshot.js +5 -31
- package/dist/lib/spinner.d.ts +0 -37
- package/dist/lib/spinner.js +0 -37
- package/dist/lib/sqlite.d.ts +0 -13
- package/dist/lib/sqlite.js +3 -71
- package/dist/lib/ssh-exec.d.ts +0 -209
- package/dist/lib/ssh-exec.js +11 -248
- package/dist/lib/ssh-tunnel.d.ts +0 -43
- package/dist/lib/ssh-tunnel.js +2 -48
- package/dist/lib/staleness/checkers/commands.d.ts +0 -4
- package/dist/lib/staleness/checkers/commands.js +0 -4
- package/dist/lib/staleness/checkers/hooks.d.ts +0 -10
- package/dist/lib/staleness/checkers/hooks.js +0 -15
- package/dist/lib/staleness/checkers/mcp.d.ts +0 -9
- package/dist/lib/staleness/checkers/mcp.js +0 -9
- package/dist/lib/staleness/checkers/permissions.d.ts +0 -12
- package/dist/lib/staleness/checkers/permissions.js +0 -13
- package/dist/lib/staleness/checkers/plugins.d.ts +0 -8
- package/dist/lib/staleness/checkers/plugins.js +0 -8
- package/dist/lib/staleness/checkers/rules.d.ts +0 -15
- package/dist/lib/staleness/checkers/rules.js +0 -26
- package/dist/lib/staleness/checkers/skills.d.ts +0 -4
- package/dist/lib/staleness/checkers/skills.js +0 -4
- package/dist/lib/staleness/checkers/subagents.d.ts +0 -9
- package/dist/lib/staleness/checkers/subagents.js +0 -9
- package/dist/lib/staleness/checkers/types.d.ts +0 -34
- package/dist/lib/staleness/checkers/types.js +0 -19
- package/dist/lib/staleness/checkers/workflows.d.ts +0 -7
- package/dist/lib/staleness/checkers/workflows.js +0 -7
- package/dist/lib/staleness/detectors/commands.js +0 -17
- package/dist/lib/staleness/detectors/hooks.js +1 -6
- package/dist/lib/staleness/detectors/mcp.js +0 -4
- package/dist/lib/staleness/detectors/permissions.js +10 -23
- package/dist/lib/staleness/detectors/rules.js +0 -6
- package/dist/lib/staleness/detectors/skills.d.ts +0 -1
- package/dist/lib/staleness/detectors/skills.js +1 -12
- package/dist/lib/staleness/detectors/types.d.ts +0 -10
- package/dist/lib/staleness/fingerprint.d.ts +0 -19
- package/dist/lib/staleness/fingerprint.js +0 -35
- package/dist/lib/staleness/index.d.ts +0 -28
- package/dist/lib/staleness/index.js +1 -45
- package/dist/lib/staleness/layers.d.ts +0 -23
- package/dist/lib/staleness/layers.js +0 -34
- package/dist/lib/staleness/prune.d.ts +0 -71
- package/dist/lib/staleness/prune.js +2 -27
- package/dist/lib/staleness/registry.d.ts +0 -10
- package/dist/lib/staleness/registry.js +3 -33
- package/dist/lib/staleness/types.d.ts +0 -36
- package/dist/lib/staleness/types.js +0 -5
- package/dist/lib/staleness/writers/commands.js +1 -48
- package/dist/lib/staleness/writers/hooks.js +1 -18
- package/dist/lib/staleness/writers/kinds.d.ts +0 -12
- package/dist/lib/staleness/writers/kinds.js +0 -1
- package/dist/lib/staleness/writers/lazy-map.d.ts +0 -11
- package/dist/lib/staleness/writers/mcp.js +0 -13
- package/dist/lib/staleness/writers/plugins.js +0 -4
- package/dist/lib/staleness/writers/rules.d.ts +0 -1
- package/dist/lib/staleness/writers/rules.js +1 -19
- package/dist/lib/staleness/writers/skills.js +3 -14
- package/dist/lib/staleness/writers/sources.d.ts +0 -11
- package/dist/lib/staleness/writers/sources.js +0 -32
- package/dist/lib/staleness/writers/subagents.js +0 -16
- package/dist/lib/staleness/writers/types.d.ts +0 -58
- package/dist/lib/staleness/writers/workflows.js +1 -1
- package/dist/lib/standalone-tools.d.ts +24 -0
- package/dist/lib/standalone-tools.js +58 -0
- package/dist/lib/star-nudge.d.ts +0 -32
- package/dist/lib/star-nudge.js +2 -36
- package/dist/lib/startup/command-registry.d.ts +0 -45
- package/dist/lib/startup/command-registry.js +1 -46
- package/dist/lib/startup/dev-build.d.ts +0 -9
- package/dist/lib/startup/dev-build.js +1 -42
- package/dist/lib/startup/root-command.d.ts +0 -19
- package/dist/lib/startup/root-command.js +0 -19
- package/dist/lib/startup/spellcheck.d.ts +0 -13
- package/dist/lib/startup/spellcheck.js +0 -13
- package/dist/lib/state.d.ts +0 -376
- package/dist/lib/state.js +19 -737
- package/dist/lib/storage/selection.d.ts +0 -40
- package/dist/lib/storage/selection.js +0 -29
- package/dist/lib/subagents-registry.d.ts +0 -56
- package/dist/lib/subagents-registry.js +0 -99
- package/dist/lib/subagents.d.ts +0 -128
- package/dist/lib/subagents.js +1 -158
- package/dist/lib/summarizer/config.d.ts +0 -37
- package/dist/lib/summarizer/config.js +0 -37
- package/dist/lib/summarizer/pass.d.ts +0 -20
- package/dist/lib/summarizer/pass.js +1 -34
- package/dist/lib/summarizer/summarize.d.ts +1 -49
- package/dist/lib/summarizer/summarize.js +0 -35
- package/dist/lib/sync-passphrase.d.ts +0 -16
- package/dist/lib/sync-passphrase.js +1 -18
- package/dist/lib/sync-status.d.ts +0 -72
- package/dist/lib/sync-status.js +0 -55
- package/dist/lib/sync-umbrella.d.ts +0 -54
- package/dist/lib/sync-umbrella.js +0 -48
- package/dist/lib/system-run-sync.d.ts +0 -5
- package/dist/lib/system-run-sync.js +1 -31
- package/dist/lib/teams/agents.d.ts +1 -444
- package/dist/lib/teams/agents.js +11 -871
- package/dist/lib/teams/api.d.ts +2 -52
- package/dist/lib/teams/api.js +4 -63
- package/dist/lib/teams/debug.d.ts +0 -6
- package/dist/lib/teams/debug.js +0 -6
- package/dist/lib/teams/delivery.d.ts +0 -41
- package/dist/lib/teams/delivery.js +0 -32
- package/dist/lib/teams/file_ops.d.ts +0 -11
- package/dist/lib/teams/file_ops.js +0 -11
- package/dist/lib/teams/forEach.d.ts +0 -76
- package/dist/lib/teams/forEach.js +1 -77
- package/dist/lib/teams/index.d.ts +1 -7
- package/dist/lib/teams/index.js +1 -7
- package/dist/lib/teams/parsers.d.ts +0 -4
- package/dist/lib/teams/parsers.js +0 -81
- package/dist/lib/teams/persistence.d.ts +0 -2
- package/dist/lib/teams/persistence.js +0 -12
- package/dist/lib/teams/placement-probe.d.ts +0 -12
- package/dist/lib/teams/placement-probe.js +1 -51
- package/dist/lib/teams/pr-watch.d.ts +0 -107
- package/dist/lib/teams/pr-watch.js +1 -107
- package/dist/lib/teams/registry.d.ts +0 -36
- package/dist/lib/teams/registry.js +0 -47
- package/dist/lib/teams/remoteWorktree.d.ts +0 -50
- package/dist/lib/teams/remoteWorktree.js +1 -96
- package/dist/lib/teams/scheduler.d.ts +0 -111
- package/dist/lib/teams/scheduler.js +2 -125
- package/dist/lib/teams/summarizer.d.ts +0 -22
- package/dist/lib/teams/summarizer.js +6 -50
- package/dist/lib/teams/supervisor.d.ts +0 -38
- package/dist/lib/teams/supervisor.js +0 -21
- package/dist/lib/teams/worktree.d.ts +0 -95
- package/dist/lib/teams/worktree.js +3 -110
- package/dist/lib/template.d.ts +0 -21
- package/dist/lib/template.js +0 -23
- package/dist/lib/term-client.d.ts +0 -26
- package/dist/lib/term-client.js +0 -48
- package/dist/lib/term-driver.d.ts +0 -5
- package/dist/lib/term-driver.js +0 -8
- package/dist/lib/terminal/backends/ghostty.d.ts +0 -2
- package/dist/lib/terminal/backends/ghostty.js +0 -12
- package/dist/lib/terminal/backends/index.d.ts +0 -17
- package/dist/lib/terminal/backends/index.js +0 -15
- package/dist/lib/terminal/backends/iterm.d.ts +0 -2
- package/dist/lib/terminal/backends/iterm.js +0 -10
- package/dist/lib/terminal/backends/terminal-app.d.ts +0 -10
- package/dist/lib/terminal/backends/terminal-app.js +0 -30
- package/dist/lib/terminal/backends/tmux.d.ts +0 -10
- package/dist/lib/terminal/backends/tmux.js +0 -2
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +0 -25
- package/dist/lib/terminal/backends/vscodium-agent.js +0 -36
- package/dist/lib/terminal/engine.d.ts +0 -17
- package/dist/lib/terminal/engine.js +0 -10
- package/dist/lib/terminal/index.d.ts +0 -8
- package/dist/lib/terminal/inject.d.ts +1 -173
- package/dist/lib/terminal/inject.js +0 -146
- package/dist/lib/terminal/policy.d.ts +0 -8
- package/dist/lib/terminal/policy.js +0 -1
- package/dist/lib/terminal/preferred.d.ts +0 -66
- package/dist/lib/terminal/preferred.js +0 -30
- package/dist/lib/terminal/quote.d.ts +0 -8
- package/dist/lib/terminal/quote.js +0 -8
- package/dist/lib/terminal/resolve.d.ts +0 -46
- package/dist/lib/terminal/resolve.js +0 -30
- package/dist/lib/terminal/run-surface.d.ts +0 -56
- package/dist/lib/terminal/run-surface.js +0 -46
- package/dist/lib/terminal/shell.d.ts +0 -3
- package/dist/lib/terminal/shell.js +0 -13
- package/dist/lib/terminal/transport.d.ts +0 -14
- package/dist/lib/terminal/transport.js +1 -30
- package/dist/lib/terminal/types.d.ts +0 -40
- package/dist/lib/terminal/types.js +0 -10
- package/dist/lib/text/relative-time.d.ts +0 -36
- package/dist/lib/text/relative-time.js +0 -43
- package/dist/lib/text/short-id.d.ts +0 -16
- package/dist/lib/text/short-id.js +0 -16
- package/dist/lib/text/width.d.ts +0 -24
- package/dist/lib/text/width.js +10 -52
- package/dist/lib/tmux/binary.d.ts +0 -36
- package/dist/lib/tmux/binary.js +0 -28
- package/dist/lib/tmux/index.d.ts +0 -5
- package/dist/lib/tmux/index.js +0 -5
- package/dist/lib/tmux/orphan-reap.d.ts +0 -253
- package/dist/lib/tmux/orphan-reap.js +3 -299
- package/dist/lib/tmux/paths.d.ts +0 -14
- package/dist/lib/tmux/paths.js +0 -14
- package/dist/lib/tmux/session.d.ts +0 -263
- package/dist/lib/tmux/session.js +6 -344
- package/dist/lib/traces/backend.d.ts +0 -20
- package/dist/lib/traces/backend.js +0 -23
- package/dist/lib/traces/classify.d.ts +0 -20
- package/dist/lib/traces/classify.js +0 -7
- package/dist/lib/traces/insights.d.ts +1 -84
- package/dist/lib/traces/insights.js +0 -126
- package/dist/lib/traces/phenotype.d.ts +0 -69
- package/dist/lib/traces/phenotype.js +0 -150
- package/dist/lib/traces/provision.d.ts +0 -1
- package/dist/lib/traces/provision.js +0 -5
- package/dist/lib/traces/schema2-build.d.ts +3 -60
- package/dist/lib/traces/schema2-build.js +8 -149
- package/dist/lib/traces/schema2-danger.d.ts +0 -30
- package/dist/lib/traces/schema2-danger.js +1 -63
- package/dist/lib/traces/schema2.d.ts +0 -11
- package/dist/lib/traces/segments.d.ts +0 -44
- package/dist/lib/traces/segments.js +0 -65
- package/dist/lib/traces/sync.d.ts +2 -239
- package/dist/lib/traces/sync.js +15 -237
- package/dist/lib/traces/worker-template.d.ts +0 -3
- package/dist/lib/traces/worker-template.js +0 -29
- package/dist/lib/triggers/handlers.d.ts +0 -82
- package/dist/lib/triggers/handlers.js +0 -75
- package/dist/lib/triggers/webhook.d.ts +0 -158
- package/dist/lib/triggers/webhook.js +0 -143
- package/dist/lib/types.d.ts +0 -736
- package/dist/lib/types.js +0 -50
- package/dist/lib/uninstall.d.ts +0 -17
- package/dist/lib/uninstall.js +0 -75
- package/dist/lib/usage-backoff.d.ts +0 -20
- package/dist/lib/usage-backoff.js +3 -60
- package/dist/lib/usage-refresh.d.ts +0 -154
- package/dist/lib/usage-refresh.js +8 -212
- package/dist/lib/verbs.d.ts +0 -12
- package/dist/lib/verbs.js +0 -12
- package/dist/lib/version-duplicates.d.ts +0 -6
- package/dist/lib/version-duplicates.js +0 -6
- package/dist/lib/version.d.ts +0 -55
- package/dist/lib/version.js +1 -58
- package/dist/lib/view-types.d.ts +0 -48
- package/dist/lib/warn-unpushed.d.ts +0 -27
- package/dist/lib/warn-unpushed.js +1 -45
- package/dist/lib/watchdog/history.d.ts +0 -1
- package/dist/lib/watchdog/history.js +0 -3
- package/dist/lib/watchdog/index.js +0 -2
- package/dist/lib/watchdog/log.d.ts +0 -19
- package/dist/lib/watchdog/log.js +0 -34
- package/dist/lib/watchdog/read.d.ts +0 -27
- package/dist/lib/watchdog/read.js +3 -58
- package/dist/lib/watchdog/rotate.d.ts +0 -139
- package/dist/lib/watchdog/rotate.js +2 -151
- package/dist/lib/watchdog/runner.d.ts +0 -125
- package/dist/lib/watchdog/runner.js +3 -223
- package/dist/lib/watchdog/service.d.ts +0 -1
- package/dist/lib/watchdog/service.js +0 -2
- package/dist/lib/watchdog/watchdog-agent.d.ts +0 -31
- package/dist/lib/watchdog/watchdog-agent.js +0 -27
- package/dist/lib/watchdog/watchdog.d.ts +0 -7
- package/dist/lib/watchdog/watchdog.js +0 -10
- package/dist/lib/watchdog/watchdogTail.js +0 -7
- package/dist/lib/whats-new.d.ts +0 -10
- package/dist/lib/whats-new.js +0 -21
- package/dist/lib/workflows-registry.d.ts +0 -45
- package/dist/lib/workflows-registry.js +0 -60
- package/dist/lib/workflows.d.ts +0 -282
- package/dist/lib/workflows.js +3 -213
- package/dist/lib/worktree/held.d.ts +0 -89
- package/dist/lib/worktree/held.js +1 -103
- package/dist/lib/wrap.d.ts +0 -32
- package/dist/lib/wrap.js +0 -32
- package/dist/lib/yaml-io.d.ts +0 -45
- package/dist/lib/yaml-io.js +0 -47
- package/dist/session-tracker/dist/adapters/claude.js +0 -2
- package/dist/session-tracker/dist/hook.sh +4 -37
- package/dist/session-tracker/dist/index.d.ts +0 -7
- package/dist/session-tracker/dist/index.js +0 -5
- package/dist/session-tracker/dist/install-hook.d.ts +0 -5
- package/dist/session-tracker/dist/install-hook.js +1 -15
- package/dist/session-tracker/dist/prune-state.js +0 -4
- package/dist/session-tracker/dist/reader.js +0 -4
- package/dist/session-tracker/dist/state-file.d.ts +0 -3
- package/dist/session-tracker/dist/state-file.js +3 -8
- package/package.json +3 -4
- package/scripts/postinstall.js +8 -116
- package/dist/lib/session/artifacts.d.ts +0 -14
- package/dist/lib/session/artifacts.js +0 -101
- package/dist/lib/session/bash-command.d.ts +0 -63
- package/dist/lib/session/bash-command.js +0 -490
- package/dist/lib/session/digest.d.ts +0 -66
- package/dist/lib/session/digest.js +0 -328
- package/dist/lib/session/highlights.d.ts +0 -151
- package/dist/lib/session/highlights.js +0 -391
- package/dist/lib/session/insights.d.ts +0 -165
- package/dist/lib/session/insights.js +0 -563
- package/dist/lib/session/linear.d.ts +0 -19
- package/dist/lib/session/linear.js +0 -99
- package/dist/lib/session/parse.d.ts +0 -224
- package/dist/lib/session/parse.js +0 -2408
- package/dist/lib/session/prompt.d.ts +0 -213
- package/dist/lib/session/prompt.js +0 -601
- package/dist/lib/session/render.d.ts +0 -133
- package/dist/lib/session/render.js +0 -1047
- package/dist/lib/session/share-html.d.ts +0 -35
- package/dist/lib/session/share-html.js +0 -319
- package/dist/lib/session/shell-programs.d.ts +0 -33
- package/dist/lib/session/shell-programs.js +0 -380
- package/dist/lib/session/state.d.ts +0 -269
- package/dist/lib/session/state.js +0 -777
- package/dist/lib/session/stream-render.d.ts +0 -4
- package/dist/lib/session/stream-render.js +0 -131
- package/dist/lib/session/tail.d.ts +0 -88
- package/dist/lib/session/tail.js +0 -294
- package/dist/lib/session/team-filter.d.ts +0 -129
- package/dist/lib/session/team-filter.js +0 -269
- package/dist/lib/session/timeline.d.ts +0 -172
- package/dist/lib/session/timeline.js +0 -636
- package/dist/lib/session/tool-calls.d.ts +0 -132
- package/dist/lib/session/tool-calls.js +0 -674
- package/dist/lib/session/trajectory-compare.d.ts +0 -48
- package/dist/lib/session/trajectory-compare.js +0 -116
- package/dist/lib/session/trajectory-html.d.ts +0 -19
- package/dist/lib/session/trajectory-html.js +0 -771
- package/dist/lib/session/trajectory-lineage.d.ts +0 -93
- package/dist/lib/session/trajectory-lineage.js +0 -195
- package/dist/lib/session/trajectory-text.d.ts +0 -38
- package/dist/lib/session/trajectory-text.js +0 -284
- package/dist/lib/session/trajectory.d.ts +0 -145
- package/dist/lib/session/trajectory.js +0 -394
- package/dist/lib/session/types.d.ts +0 -627
- package/dist/lib/session/types.js +0 -43
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core agent configuration and detection module.
|
|
3
|
-
*
|
|
4
|
-
* Defines the canonical registry of current and legacy AI coding agents (Claude,
|
|
5
|
-
* Codex, Gemini, Cursor, OpenCode, OpenClaw, Copilot, Amp, Goose, Grok)
|
|
6
|
-
* with their CLI commands, config paths, capability flags, and MCP integration
|
|
7
|
-
* points.
|
|
8
|
-
*
|
|
9
|
-
* Provides functions for detecting installed CLIs, resolving version-managed binaries,
|
|
10
|
-
* reading account/auth info, and managing MCP server registrations across agents.
|
|
11
|
-
*/
|
|
12
1
|
import { execFile } from 'child_process';
|
|
13
2
|
import { promisify } from 'util';
|
|
14
3
|
import * as crypto from 'crypto';
|
|
@@ -30,11 +19,6 @@ import { MCP_TARGETS } from '../mcp-registry.js';
|
|
|
30
19
|
import { VERSION_RE } from './primitives.js';
|
|
31
20
|
const execFileAsync = promisify(execFile);
|
|
32
21
|
const HOME = os.homedir();
|
|
33
|
-
/**
|
|
34
|
-
* Minimum Codex CLI version that supports hooks.
|
|
35
|
-
* Mirrored on `AGENTS.codex.capabilities.hooks.since` -- kept exported for
|
|
36
|
-
* legacy import sites that haven't migrated to `supports()` yet.
|
|
37
|
-
*/
|
|
38
22
|
export const CODEX_HOOKS_MIN_VERSION = '0.116.0';
|
|
39
23
|
const CLI_VERSION_CACHE_PATH = getCliVersionCachePath();
|
|
40
24
|
let cliVersionCache = null;
|
|
@@ -45,7 +29,6 @@ function loadCliVersionCache() {
|
|
|
45
29
|
cliVersionCache = JSON.parse(fs.readFileSync(CLI_VERSION_CACHE_PATH, 'utf-8'));
|
|
46
30
|
}
|
|
47
31
|
catch {
|
|
48
|
-
/* missing or corrupt cache, rebuild */
|
|
49
32
|
cliVersionCache = {};
|
|
50
33
|
}
|
|
51
34
|
return cliVersionCache;
|
|
@@ -60,19 +43,12 @@ function saveCliVersionCache() {
|
|
|
60
43
|
fs.writeFileSync(CLI_VERSION_CACHE_PATH, JSON.stringify(cliVersionCache));
|
|
61
44
|
}
|
|
62
45
|
catch {
|
|
63
|
-
/* best-effort cache persist */
|
|
64
46
|
}
|
|
65
47
|
}
|
|
66
48
|
function pathIsWithin(candidate, directory) {
|
|
67
49
|
const relative = path.relative(directory, candidate);
|
|
68
50
|
return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));
|
|
69
51
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Resolve a PATH candidate to the immutable native executable agents-cli may
|
|
72
|
-
* safely register. An adopted launcher can live outside the shims directory
|
|
73
|
-
* while resolving back into it; in that case its durable adoption record is
|
|
74
|
-
* the source of truth for the original executable.
|
|
75
|
-
*/
|
|
76
52
|
export function resolveNativeBinaryPath(command, candidate, options = {}) {
|
|
77
53
|
const shimsDir = options.shimsDir ?? getShimsDir();
|
|
78
54
|
const historyDir = options.historyDir ?? getHistoryDir();
|
|
@@ -88,10 +64,10 @@ export function resolveNativeBinaryPath(command, candidate, options = {}) {
|
|
|
88
64
|
canonicalShimsDir = fs.realpathSync(shimsDir);
|
|
89
65
|
}
|
|
90
66
|
catch {
|
|
91
|
-
/* An absent shims dir cannot make an existing native binary invalid. */
|
|
92
67
|
}
|
|
93
68
|
if (!pathIsWithin(canonicalCandidate, canonicalShimsDir))
|
|
94
69
|
return canonicalCandidate;
|
|
70
|
+
// A shim resolves only to its recorded original; never recurse into the shim tree.
|
|
95
71
|
const recordPath = path.join(historyDir, 'adopted-launchers', command);
|
|
96
72
|
try {
|
|
97
73
|
const [original] = fs.readFileSync(recordPath, 'utf-8').split(/\r?\n/, 1);
|
|
@@ -125,10 +101,6 @@ export function findInPath(command, options = {}) {
|
|
|
125
101
|
const stat = fs.statSync(full);
|
|
126
102
|
if (!stat.isFile())
|
|
127
103
|
continue;
|
|
128
|
-
// A shell only runs an executable file; `which` skips a mode-644 namesake and
|
|
129
|
-
// so must this, or a stray non-executable `secrets`/`claude` file earlier on
|
|
130
|
-
// PATH would shadow the real binary further down. On win32 the mode bit is
|
|
131
|
-
// meaningless (PATHEXT decides), so the check is POSIX-only.
|
|
132
104
|
if (process.platform !== 'win32')
|
|
133
105
|
fs.accessSync(full, fs.constants.X_OK);
|
|
134
106
|
const native = resolveNativeBinaryPath(command, full, options);
|
|
@@ -136,17 +108,11 @@ export function findInPath(command, options = {}) {
|
|
|
136
108
|
return native;
|
|
137
109
|
}
|
|
138
110
|
catch {
|
|
139
|
-
/* not in this dir */
|
|
140
111
|
}
|
|
141
112
|
}
|
|
142
113
|
}
|
|
143
114
|
return null;
|
|
144
115
|
}
|
|
145
|
-
/** Grok-specific binary resolution.
|
|
146
|
-
* Grok does not live in node_modules/.bin. Its versioned binaries live in each
|
|
147
|
-
* managed version home under `.grok/downloads/`, so detection must not follow
|
|
148
|
-
* the host ~/.grok config symlink.
|
|
149
|
-
*/
|
|
150
116
|
function resolveGrokBinary(version) {
|
|
151
117
|
if (version && version !== 'latest') {
|
|
152
118
|
const binaryPath = getBinaryPath('grok', version);
|
|
@@ -236,13 +202,6 @@ function splitCommandLine(command) {
|
|
|
236
202
|
}
|
|
237
203
|
return args;
|
|
238
204
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Master registry of all supported agents keyed by AgentId.
|
|
241
|
-
*
|
|
242
|
-
* Each entry defines the agent's CLI command, npm package, config directory layout,
|
|
243
|
-
* instructions file name, slash-command format, and capability flags. This is the
|
|
244
|
-
* single source of truth for agent metadata consumed throughout the codebase.
|
|
245
|
-
*/
|
|
246
205
|
export const AGENTS = {
|
|
247
206
|
claude: {
|
|
248
207
|
id: 'claude',
|
|
@@ -269,15 +228,11 @@ export const AGENTS = {
|
|
|
269
228
|
variableSyntax: '$ARGUMENTS',
|
|
270
229
|
supportsHooks: true,
|
|
271
230
|
nativePluginSkills: true,
|
|
231
|
+
// Harness-owned skill directories survive orphan cleanup.
|
|
272
232
|
ownedSkillDirs: ['synced'],
|
|
273
|
-
// Claude Code grew a native `claude --cloud "<prompt>"` (Anthropic-managed
|
|
274
|
-
// infra, claude.ai/code; requires claude.ai subscription auth). Routing
|
|
275
|
-
// still goes to Rush Cloud deliberately — it keeps cloud tasks in one
|
|
276
|
-
// tracked fleet (agents cloud list/status/logs) regardless of harness.
|
|
277
233
|
cloudProvider: 'rush',
|
|
278
234
|
capabilities: { hooks: true, mcp: true, mcpHttp: true, mcpHeaders: true, allowlist: true, skills: true, commands: true, plugins: true, subagents: true, rules: { file: 'CLAUDE.md' }, workflows: true, memory: true, modes: ['plan', 'edit', 'auto', 'skip'], rulesImports: true, interactiveRepl: true },
|
|
279
235
|
},
|
|
280
|
-
// codex hooks: gated to >= 0.116.0 (introduced [features] codex_hooks flag).
|
|
281
236
|
codex: {
|
|
282
237
|
id: 'codex',
|
|
283
238
|
name: 'Codex',
|
|
@@ -303,8 +258,6 @@ export const AGENTS = {
|
|
|
303
258
|
variableSyntax: '$ARGUMENTS',
|
|
304
259
|
supportsHooks: true,
|
|
305
260
|
cloudProvider: 'codex',
|
|
306
|
-
// Subagents: multi-agent plumbing since 0.117.0; custom agents as
|
|
307
|
-
// ~/.codex/agents/*.toml (name, description, developer_instructions).
|
|
308
261
|
capabilities: { hooks: { since: '0.116.0' }, mcp: true, mcpHttp: true, mcpHeaders: false, allowlist: { since: '0.138.0' }, skills: true, commands: { until: '0.117.0' }, plugins: { since: '0.128.0' }, subagents: { since: '0.117.0' }, rules: { file: 'AGENTS.md' }, workflows: false, memory: true, modes: ['plan', 'edit', 'auto', 'skip'], interactiveRepl: true },
|
|
309
262
|
},
|
|
310
263
|
cursor: {
|
|
@@ -327,28 +280,13 @@ export const AGENTS = {
|
|
|
327
280
|
commandsDir: path.join(HOME, '.cursor', 'commands'),
|
|
328
281
|
commandsSubdir: 'commands',
|
|
329
282
|
skillsDir: path.join(HOME, '.cursor', 'skills'),
|
|
330
|
-
// Hooks: ~/.cursor/hooks.json (`{ "version": 1, "hooks": { event: [{ command }] } }`).
|
|
331
|
-
// CLI hooks since 2026-01-16. See registerHooksForCursor — only CLI-fired events.
|
|
332
283
|
hooksDir: 'hooks',
|
|
333
|
-
// Plugins: `.cursor-plugin/plugin.json` (re-enabled in CLI 2026-05). Mirror the
|
|
334
|
-
// Claude marketplace layout into ~/.cursor/plugins/ and copy the manifest into
|
|
335
|
-
// pluginManifestDir so Cursor's native loader sees it (same pattern as droid/
|
|
336
|
-
// codex).
|
|
337
284
|
pluginManifestDir: '.cursor-plugin',
|
|
338
285
|
instructionsFile: '.cursorrules',
|
|
339
286
|
format: 'markdown',
|
|
340
287
|
variableSyntax: '$ARGUMENTS',
|
|
341
288
|
supportsHooks: true,
|
|
342
|
-
|
|
343
|
-
// (user), Markdown with YAML frontmatter (name, description, model, readonly,
|
|
344
|
-
// is_background — no `color`). Shipped in cursor-agent CLI 2026.01 (Cursor 2.4,
|
|
345
|
-
// 2026-01-22); cursor-agent uses CalVer build tags (e.g. 2025.11.25-<hash>), so
|
|
346
|
-
// gate at `>= 2026.1.22`. The `agents sync` path enforces this (versions.ts skips
|
|
347
|
-
// + warns for pre-2.4 installs); the direct `subagents add --agents cursor` path
|
|
348
|
-
// writes unconditionally, same as the other since-gated agents.
|
|
349
|
-
// See transformSubagentForCursor / https://cursor.com/docs/subagents.
|
|
350
|
-
// Current cursor-agent builds open their interactive TUI with no argv.
|
|
351
|
-
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '2026.1.22' }, rules: { file: '.cursorrules' }, workflows: false, memory: false, modes: ['plan', 'edit', 'skip'], interactiveRepl: true }, // allowlist: ~/.cursor/cli-config.json
|
|
289
|
+
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '2026.1.22' }, rules: { file: '.cursorrules' }, workflows: false, memory: false, modes: ['plan', 'edit', 'skip'], interactiveRepl: true },
|
|
352
290
|
},
|
|
353
291
|
opencode: {
|
|
354
292
|
id: 'opencode',
|
|
@@ -368,11 +306,6 @@ export const AGENTS = {
|
|
|
368
306
|
commandsDir: path.join(HOME, '.opencode', 'commands'),
|
|
369
307
|
commandsSubdir: 'commands',
|
|
370
308
|
skillsDir: path.join(HOME, '.opencode', 'skills'),
|
|
371
|
-
// Plugins: TS/JS modules auto-loaded from ~/.config/opencode/plugins/ (global)
|
|
372
|
-
// and .opencode/plugins/ (project). Not Claude marketplace format — see
|
|
373
|
-
// installOpenCodePlugin in plugins.ts. OpenCode v1.18.4 exposes lifecycle
|
|
374
|
-
// hooks through plugin modules (event/tool/etc. functions), not a native
|
|
375
|
-
// opencode.json shell-command hooks block.
|
|
376
309
|
hooksDir: 'hooks',
|
|
377
310
|
instructionsFile: 'AGENTS.md',
|
|
378
311
|
format: 'markdown',
|
|
@@ -395,29 +328,15 @@ export const AGENTS = {
|
|
|
395
328
|
cliCommand: 'openclaw',
|
|
396
329
|
npmPackage: 'openclaw',
|
|
397
330
|
configDir: path.join(HOME, '.openclaw'),
|
|
398
|
-
commandsDir: '',
|
|
331
|
+
commandsDir: '',
|
|
399
332
|
commandsSubdir: '',
|
|
400
333
|
skillsDir: path.join(HOME, '.openclaw', 'skills'),
|
|
401
|
-
nativeCommandRuntime: true,
|
|
334
|
+
nativeCommandRuntime: true,
|
|
402
335
|
hooksDir: 'hooks',
|
|
403
|
-
instructionsFile: 'workspace/AGENTS.md',
|
|
336
|
+
instructionsFile: 'workspace/AGENTS.md',
|
|
404
337
|
format: 'markdown',
|
|
405
338
|
variableSyntax: '{{ARGUMENTS}}',
|
|
406
|
-
// hooks: NOT supported. OpenClaw only exposes a fixed set of internal,
|
|
407
|
-
// named hooks (e.g. `boot-md`, which runs BOOT.md on gateway restart) —
|
|
408
|
-
// there is no general event->shell-command registration surface (no
|
|
409
|
-
// PreToolUse/PostToolUse/UserPromptSubmit equivalent an agents-cli
|
|
410
|
-
// hooks.yaml manifest could target). registerHooksToSettings has no
|
|
411
|
-
// `openclaw` case and silently no-ops (RUSH-2122: capability claimed
|
|
412
|
-
// hooks:true with zero hooks ever installed). Flip back to `true` only
|
|
413
|
-
// alongside a real registerHooksForOpenClaw implementation.
|
|
414
339
|
supportsHooks: false,
|
|
415
|
-
// allowlist: maps blanket (whole-tool) rules to ~/.openclaw/openclaw.json
|
|
416
|
-
// tools.alsoAllow (allow) / tools.deny (deny). OpenClaw gates at tool
|
|
417
|
-
// granularity only, so sub-command/path/domain patterns are skipped.
|
|
418
|
-
// OpenClaw is self-updating (no pinned since), so `true` is correct.
|
|
419
|
-
// Workflows sync as Lobster `.lobster` files under `.openclaw/workflows/`;
|
|
420
|
-
// the Lobster tool runs them by receiving the file path as `pipeline`.
|
|
421
340
|
capabilities: { hooks: false, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: false, plugins: true, subagents: true, rules: { file: 'workspace/AGENTS.md' }, workflows: true, memory: true, modes: ['plan', 'edit', 'skip'], interactiveRepl: true },
|
|
422
341
|
},
|
|
423
342
|
copilot: {
|
|
@@ -438,21 +357,12 @@ export const AGENTS = {
|
|
|
438
357
|
commandsDir: path.join(HOME, '.copilot', 'commands'),
|
|
439
358
|
commandsSubdir: 'commands',
|
|
440
359
|
skillsDir: path.join(HOME, '.copilot', 'skills'),
|
|
441
|
-
// Hooks: user-level `~/.copilot/hooks/*.json` (GA @github/copilot, every
|
|
442
|
-
// 1.x). Schema `{ "version": 1, "hooks": { event: [...] } }` with camelCase
|
|
443
|
-
// event names (sessionStart, preToolUse, …). See registerHooksForCopilot.
|
|
444
360
|
hooksDir: 'hooks',
|
|
445
|
-
// Copilot reads a plugin's manifest from the plugin ROOT (plugin.json),
|
|
446
|
-
// not `.claude-plugin/plugin.json`. Mirror it there. Verified against the
|
|
447
|
-
// GitHub Copilot CLI (1.0.56): `copilot plugin install` produces an
|
|
448
|
-
// installed plugin dir whose manifest sits at the root.
|
|
449
361
|
pluginManifestDir: '.',
|
|
450
362
|
instructionsFile: 'AGENTS.md',
|
|
451
363
|
format: 'markdown',
|
|
452
364
|
variableSyntax: '$ARGUMENTS',
|
|
453
365
|
supportsHooks: true,
|
|
454
|
-
// interactiveRepl: false — copilot requires a prompt for meaningful work; bare invocation
|
|
455
|
-
// opens a welcome screen but not a persistent coding REPL suitable for agents focus.
|
|
456
366
|
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '0.0.353' }, rules: { file: 'AGENTS.md' }, workflows: false, memory: false, modes: ['plan', 'edit', 'auto', 'skip'], interactiveRepl: false },
|
|
457
367
|
},
|
|
458
368
|
amp: {
|
|
@@ -478,7 +388,6 @@ export const AGENTS = {
|
|
|
478
388
|
format: 'markdown',
|
|
479
389
|
variableSyntax: '$ARGUMENTS',
|
|
480
390
|
supportsHooks: false,
|
|
481
|
-
// interactiveRepl: false — amp requires a prompt; bare invocation exits immediately.
|
|
482
391
|
capabilities: { hooks: false, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, memory: false, modes: ['plan', 'edit'], interactiveRepl: false },
|
|
483
392
|
},
|
|
484
393
|
goose: {
|
|
@@ -499,38 +408,15 @@ export const AGENTS = {
|
|
|
499
408
|
configDir: path.join(HOME, '.config', 'goose'),
|
|
500
409
|
commandsDir: path.join(HOME, '.config', 'goose', 'commands'),
|
|
501
410
|
commandsSubdir: 'commands',
|
|
502
|
-
// Goose reads skills directly from central ~/.agents/skills/ via the Summon
|
|
503
|
-
// extension (block-goose-cli ≥ 1.25.0). No per-version copy is written.
|
|
504
411
|
skillsDir: path.join(HOME, '.agents', 'skills'),
|
|
505
412
|
nativeAgentsSkillsDir: true,
|
|
506
|
-
// Hooks: Open Plugins format — auto-discovered from
|
|
507
|
-
// ~/.agents/plugins/<name>/hooks/hooks.json (shipped block-goose-cli
|
|
508
|
-
// ≥ 1.34.0). See registerHooksForGoose.
|
|
509
413
|
hooksDir: 'hooks',
|
|
510
414
|
instructionsFile: 'AGENTS.md',
|
|
511
415
|
format: 'markdown',
|
|
512
416
|
variableSyntax: '$ARGUMENTS',
|
|
513
417
|
supportsHooks: true,
|
|
514
|
-
// Plugins: Open Plugins under ~/.agents/plugins/<name>/ (same layout as
|
|
515
|
-
// agents-cli source). Version isolation copies into versionHome/.agents/plugins/.
|
|
516
|
-
// Workflows sync as Goose recipe YAML. Permissions are NOT supported:
|
|
517
|
-
// permission.yaml gates whole tools, so canonical rules cannot round-trip.
|
|
518
|
-
// Commands: a Goose slash command is a recipe YAML under
|
|
519
|
-
// ~/.config/goose/commands/<name>.yaml, registered in ~/.config/goose/config.yaml
|
|
520
|
-
// under `slash_commands: [{ command, recipe_path }]` (see goose-commands.ts).
|
|
521
|
-
// Subagents: recipe YAML named agents under ~/.config/goose/agents/<name>.yaml
|
|
522
|
-
// (goose auto-discovers and delegates to them by name in autonomous mode).
|
|
523
418
|
capabilities: { hooks: { since: '1.34.0' }, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: false, skills: { since: '1.25.0' }, commands: true, plugins: true, subagents: true, rules: { file: 'AGENTS.md' }, workflows: true, memory: false, modes: ['edit'], interactiveRepl: true },
|
|
524
419
|
},
|
|
525
|
-
// Google Antigravity CLI (`agy`) — official replacement for Gemini CLI as of IO 2026.
|
|
526
|
-
// configDir nests inside `~/.gemini/` since agy shares the parent dir with the Gemini
|
|
527
|
-
// CLI but isolates its own state in the `antigravity-cli/` subdir. Per-version HOME
|
|
528
|
-
// isolation works because the shim's configDirName carries the full nested path.
|
|
529
|
-
// Auth: Google OAuth on first launch, or ANTIGRAVITY_API_KEY env var for headless.
|
|
530
|
-
// Hooks: JSON entries under a top-level `hooks` key in settings.json; events are
|
|
531
|
-
// before_tool_call, after_model_call, on_loop_stop, on_error. Plugins are the
|
|
532
|
-
// renamed Gemini CLI extensions. Permissions live in settings.json under a
|
|
533
|
-
// `permissions` key with allow/deny arrays.
|
|
534
420
|
antigravity: {
|
|
535
421
|
id: 'antigravity',
|
|
536
422
|
name: 'Antigravity',
|
|
@@ -557,16 +443,8 @@ export const AGENTS = {
|
|
|
557
443
|
variableSyntax: '{{args}}',
|
|
558
444
|
supportsHooks: true,
|
|
559
445
|
cloudProvider: 'antigravity',
|
|
560
|
-
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '1.0.16' }, rules: { file: 'AGENTS.md' }, workflows: { since: '1.0.6' }, memory: false, modes: ['edit', 'skip'], rulesImports: false, interactiveRepl: true },
|
|
446
|
+
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '1.0.16' }, rules: { file: 'AGENTS.md' }, workflows: { since: '1.0.6' }, memory: false, modes: ['edit', 'skip'], rulesImports: false, interactiveRepl: true },
|
|
561
447
|
},
|
|
562
|
-
// xAI Grok Build CLI (`grok`) — early beta, SuperGrok Heavy. Auth via OAuth on
|
|
563
|
-
// first launch, or XAI_API_KEY env var for headless. MCP servers configured inline
|
|
564
|
-
// under [mcp_servers] in ~/.grok/config.toml. Hooks auto-discovered from
|
|
565
|
-
// ~/.grok/hooks/ (+ project .grok/hooks/) — events PreToolUse, PostToolUse, etc.
|
|
566
|
-
// Plugins live in ~/.grok/plugins/ with marketplaces. Permissions: --allow/--deny
|
|
567
|
-
// CLI flags or [permission] TOML block in ~/.grok/config.toml.
|
|
568
|
-
// Workflows (native Rhai orchestration) enabled by default as of v0.2.111 —
|
|
569
|
-
// projected into ~/.grok/workflows/<name>.rhai (under GROK_HOME isolation).
|
|
570
448
|
grok: {
|
|
571
449
|
id: 'grok',
|
|
572
450
|
name: 'Grok',
|
|
@@ -583,10 +461,6 @@ export const AGENTS = {
|
|
|
583
461
|
npmPackage: '',
|
|
584
462
|
installScript: 'curl -fsSL https://x.ai/cli/install.sh | bash',
|
|
585
463
|
configDir: path.join(HOME, '.grok'),
|
|
586
|
-
// Grok discovers file-based slash commands from ~/.agents/commands/ (the
|
|
587
|
-
// cross-agent compat dir it mirrors from Claude Code) as well as the legacy
|
|
588
|
-
// ~/.claude/commands/ symlink. We write there directly so the per-agent
|
|
589
|
-
// install path and the central user repo stay in sync.
|
|
590
464
|
commandsDir: path.join(HOME, '.agents', 'commands'),
|
|
591
465
|
commandsSubdir: path.join('..', '.agents', 'commands'),
|
|
592
466
|
skillsDir: path.join(HOME, '.grok', 'skills'),
|
|
@@ -600,30 +474,20 @@ export const AGENTS = {
|
|
|
600
474
|
mcp: true,
|
|
601
475
|
mcpHttp: false,
|
|
602
476
|
mcpHeaders: false,
|
|
603
|
-
allowlist: true,
|
|
477
|
+
allowlist: true,
|
|
604
478
|
skills: true,
|
|
605
|
-
commands: true,
|
|
479
|
+
commands: true,
|
|
606
480
|
plugins: true,
|
|
607
|
-
subagents: true,
|
|
481
|
+
subagents: true,
|
|
608
482
|
rules: { file: 'AGENTS.md' },
|
|
609
|
-
// Native workflows (`.rhai` under ~/.grok/workflows/) shipped on-by-default
|
|
610
|
-
// in v0.2.111 (2026-07-22). See transformWorkflowForGrok in workflows.ts.
|
|
611
483
|
workflows: { since: '0.2.111' },
|
|
612
484
|
memory: true,
|
|
613
485
|
modes: ['plan', 'edit', 'skip'],
|
|
614
|
-
// grok's `--permission-mode plan` silently stalls a headless `-p` run at
|
|
615
|
-
// its ExitPlanMode gate (no TTY to approve). Headless plan auto-downgrades
|
|
616
|
-
// to auto (→ edit via resolveMode). Interactive plan is unaffected.
|
|
617
486
|
headlessPlan: false,
|
|
618
487
|
rulesImports: true,
|
|
619
488
|
interactiveRepl: true,
|
|
620
489
|
},
|
|
621
490
|
},
|
|
622
|
-
// Kimi Code CLI (`kimi`) — Moonshot AI coding agent.
|
|
623
|
-
// Install: `curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash`
|
|
624
|
-
// or: `npm install -g @moonshot-ai/kimi-code`
|
|
625
|
-
// Config: `~/.kimi-code/config.toml`, `~/.kimi-code/mcp.json`,
|
|
626
|
-
// `~/.kimi-code/skills/`, `~/.kimi-code/hooks/`
|
|
627
491
|
kimi: {
|
|
628
492
|
id: 'kimi',
|
|
629
493
|
name: 'Kimi',
|
|
@@ -658,66 +522,16 @@ export const AGENTS = {
|
|
|
658
522
|
skills: true,
|
|
659
523
|
commands: false,
|
|
660
524
|
plugins: true,
|
|
661
|
-
// Claude-shaped agent markdown under ~/.kimi-code/agents/. kimi-code
|
|
662
|
-
// discovers that dir from `USER_BRAND_DIRS = ["agents"]` (agent-file
|
|
663
|
-
// discovery, added in 0.29.0); 0.28.x and older compile their four agent
|
|
664
|
-
// profiles into the bundle with no filesystem loader at all, so a synced
|
|
665
|
-
// file there is never read.
|
|
666
525
|
subagents: { since: '0.29.0' },
|
|
667
526
|
rules: { file: 'AGENTS.md' },
|
|
668
527
|
workflows: true,
|
|
669
528
|
memory: false,
|
|
670
529
|
modes: ['plan', 'edit', 'auto', 'skip'],
|
|
671
|
-
// kimi's headless `-p` refuses to combine with `--plan` (`Cannot combine
|
|
672
|
-
// --prompt with --plan`). Headless plan auto-downgrades to auto (kimi -p
|
|
673
|
-
// auto-runs). Interactive plan is unaffected.
|
|
674
530
|
headlessPlan: false,
|
|
675
531
|
rulesImports: false,
|
|
676
532
|
interactiveRepl: true,
|
|
677
533
|
},
|
|
678
534
|
},
|
|
679
|
-
// Factory AI Droid CLI (`droid`) — agentic coding CLI from factory.ai.
|
|
680
|
-
// Install: `curl -fsSL https://app.factory.ai/cli | sh` (no npm package).
|
|
681
|
-
// Binary is NOT in node_modules/.bin — the shim resolves the fixed install
|
|
682
|
-
// path ~/.local/bin/droid directly (see the droid branch in shims.ts).
|
|
683
|
-
// Config: `~/.factory/` (settings.json, mcp.json, droids/, commands/, hooks/,
|
|
684
|
-
// plugins/). Memory: native AGENTS.md. Subagents = custom droids (top-level
|
|
685
|
-
// .md files in ~/.factory/droids/). Config isolation rides the ~/.factory
|
|
686
|
-
// symlink switch (no FACTORY_HOME env var exists). Headless:
|
|
687
|
-
// `droid exec "<prompt>"` with --auto low|medium|high, -o stream-json,
|
|
688
|
-
// -m <model>, -r <effort>.
|
|
689
|
-
//
|
|
690
|
-
// Hooks: Claude-shaped. settings.json carries a top-level `hooks` object keyed
|
|
691
|
-
// by event (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart,
|
|
692
|
-
// SessionEnd, Stop, SubagentStop, Notification, PreCompact), each an array of
|
|
693
|
-
// `{ matcher?, hooks: [{ type: "command", command, timeout? }] }` matcher
|
|
694
|
-
// groups — verified against the droid binary's zod schema. So the Claude
|
|
695
|
-
// registrar is reused verbatim, just targeting `.factory/settings.json`.
|
|
696
|
-
//
|
|
697
|
-
// Plugins: native `droid plugin` command group + ~/.factory/plugins/ with the
|
|
698
|
-
// same marketplace layout Claude uses (known_marketplaces.json +
|
|
699
|
-
// marketplaces/<name>/plugins/<plugin>/). Droid's plugin manifest dir is
|
|
700
|
-
// `.factory-plugin/` (it also reads `.claude-plugin/` for compatibility) — set
|
|
701
|
-
// pluginManifestDir so syncPluginToVersion mirrors the manifest into it, the
|
|
702
|
-
// same pattern codex uses with `.codex-plugin`.
|
|
703
|
-
//
|
|
704
|
-
// Workflows / Factory Missions (RUSH-1864, probed droid v0.177.0; ticket cited
|
|
705
|
-
// v0.161.0 — self-updating, no pinnable semver): Factory ships genuine multi-
|
|
706
|
-
// step orchestration ("Missions") via `/missions` (interactive) and
|
|
707
|
-
// `droid exec --mission` (headless; optional `-f <prompt.md>` is a *prompt*
|
|
708
|
-
// file, not a named mission template). Docs:
|
|
709
|
-
// https://docs.factory.ai/cli/features/missions and
|
|
710
|
-
// https://docs.factory.ai/docs/droid-exec/overview (Mission Mode).
|
|
711
|
-
//
|
|
712
|
-
// Mission state may land under `~/.factory/missions/<sessionId>/` at runtime
|
|
713
|
-
// (`getMissionsDir` = join(home, ".factory", "missions") + per-session
|
|
714
|
-
// mission.md / features.json / progress_log.jsonl) — that is **session
|
|
715
|
-
// runtime state**, not a discovery directory of installable named workflows.
|
|
716
|
-
// There is no discoverMission / template registry, and a cold install has no
|
|
717
|
-
// `~/.factory/missions/` until a mission is run. agents-cli's workflows
|
|
718
|
-
// capability means "sync WORKFLOW.md into an auto-discovered dir" — Droid
|
|
719
|
-
// has no such dir, so workflows stays false (invoke-only; do not fabricate a
|
|
720
|
-
// writer target).
|
|
721
535
|
droid: {
|
|
722
536
|
id: 'droid',
|
|
723
537
|
name: 'Droid',
|
|
@@ -744,8 +558,6 @@ export const AGENTS = {
|
|
|
744
558
|
format: 'markdown',
|
|
745
559
|
variableSyntax: '$ARGUMENTS',
|
|
746
560
|
supportsHooks: true,
|
|
747
|
-
// Factory Droid Computers (cloud VMs) reached via `droid computer ssh` +
|
|
748
|
-
// remote headless `droid exec`.
|
|
749
561
|
cloudProvider: 'factory',
|
|
750
562
|
capabilities: {
|
|
751
563
|
hooks: true,
|
|
@@ -758,7 +570,6 @@ export const AGENTS = {
|
|
|
758
570
|
plugins: true,
|
|
759
571
|
subagents: true,
|
|
760
572
|
rules: { file: 'AGENTS.md' },
|
|
761
|
-
// Factory Missions are invoke-only — no installable discovery dir (RUSH-1864).
|
|
762
573
|
workflows: false,
|
|
763
574
|
memory: false,
|
|
764
575
|
modes: ['plan', 'edit', 'auto', 'skip'],
|
|
@@ -766,9 +577,6 @@ export const AGENTS = {
|
|
|
766
577
|
interactiveRepl: true,
|
|
767
578
|
},
|
|
768
579
|
},
|
|
769
|
-
// Nous Hermes Agent. Config lives under ~/.hermes/config.yaml; MCP servers
|
|
770
|
-
// are YAML `mcp_servers`, skills are local SKILL.md directories, and durable
|
|
771
|
-
// memory is file-backed.
|
|
772
580
|
hermes: {
|
|
773
581
|
id: 'hermes',
|
|
774
582
|
name: 'Hermes',
|
|
@@ -793,24 +601,11 @@ export const AGENTS = {
|
|
|
793
601
|
format: 'markdown',
|
|
794
602
|
variableSyntax: '$ARGUMENTS',
|
|
795
603
|
supportsHooks: true,
|
|
796
|
-
// Plugins: Hermes loads plugins from a flat `~/.hermes/plugins/<name>/` dir
|
|
797
|
-
// with a `plugin.yaml` manifest; a plugin only loads once its name is in the
|
|
798
|
-
// `plugins.enabled` allowlist in `~/.hermes/config.yaml` (deny-list
|
|
799
|
-
// `plugins.disabled` wins). Not the Claude marketplace layout, so it installs
|
|
800
|
-
// via a flat-copy branch (mirrors goose) plus a YAML allowlist toggle.
|
|
801
|
-
// See https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins
|
|
802
604
|
capabilities: {
|
|
803
|
-
// Lifecycle hooks land in ~/.hermes/config.yaml under a `hooks:` block
|
|
804
|
-
// (YAML, shared with `mcp_servers`); gated to Hermes ≥ 0.11.0 which
|
|
805
|
-
// introduced the configurable hook runner.
|
|
806
605
|
hooks: { since: '0.11.0' },
|
|
807
606
|
mcp: true,
|
|
808
607
|
mcpHttp: true,
|
|
809
608
|
mcpHeaders: false,
|
|
810
|
-
// Permissions: ~/.hermes/config.yaml carries `command_allowlist` for
|
|
811
|
-
// always-approved command globs and `approvals.deny` for unconditional
|
|
812
|
-
// command blocks. It is command-glob only; session `/tools` toggles are
|
|
813
|
-
// intentionally not persisted by agents-cli.
|
|
814
609
|
allowlist: true,
|
|
815
610
|
skills: true,
|
|
816
611
|
commands: false,
|
|
@@ -824,16 +619,6 @@ export const AGENTS = {
|
|
|
824
619
|
interactiveRepl: true,
|
|
825
620
|
},
|
|
826
621
|
},
|
|
827
|
-
// Meta Muse Code (`muse`) — first-class harness for Meta's coding agent (terminal/CI), built on
|
|
828
|
-
// Muse Spark. Native binary via curl installer (self-updating; no npm package).
|
|
829
|
-
// Config: `~/.config/muse/settings.json` (requires `"schema_version": 1`).
|
|
830
|
-
// Sessions: `~/.local/share/muse/sessions/YYYY/MM/DD/<uuid>/session.jsonl`.
|
|
831
|
-
// Skills: `~/.config/muse/skills` + `~/.agents/skills` + project `.agents/skills`.
|
|
832
|
-
// MCP: `mcp_servers` in settings.json (stdio / streamable_http transports).
|
|
833
|
-
// Headless: `muse exec "<prompt>"` with --model, --reasoning-effort, --json,
|
|
834
|
-
// --yolo / --disable-approval / --disable-sandbox. Auth: META_API_KEY or
|
|
835
|
-
// browser OAuth stored at `~/.config/muse/auth.json`. Default model:
|
|
836
|
-
// muse-spark-1.2. Docs: https://dev.meta.ai/docs/muse-code
|
|
837
622
|
muse: {
|
|
838
623
|
id: 'muse',
|
|
839
624
|
name: 'Muse',
|
|
@@ -858,59 +643,26 @@ export const AGENTS = {
|
|
|
858
643
|
instructionsFile: 'AGENTS.md',
|
|
859
644
|
format: 'markdown',
|
|
860
645
|
variableSyntax: '$ARGUMENTS',
|
|
861
|
-
// Muse hooks use the Claude-shaped settings.json hooks block (matcher +
|
|
862
|
-
// command groups) under ~/.config/muse/settings.json, plus project
|
|
863
|
-
// `.muse/hooks.json`. registerHooksForClaude is reused with Muse's config
|
|
864
|
-
// dir and schema_version: 1.
|
|
865
646
|
supportsHooks: true,
|
|
866
|
-
// Claude-compatible marketplace layout + native `.muse-plugin/` manifest.
|
|
867
647
|
pluginManifestDir: '.muse-plugin',
|
|
868
648
|
capabilities: {
|
|
869
|
-
// Hooks: Claude-compatible event→matcher→command groups in settings.json.
|
|
870
649
|
hooks: true,
|
|
871
650
|
mcp: true,
|
|
872
651
|
mcpHttp: true,
|
|
873
652
|
mcpHeaders: true,
|
|
874
|
-
// Muse's safety model is approval-mode + OS sandbox (CLI flags), not a
|
|
875
|
-
// Claude-style tool-name allow/deny list. No settings.permissions writer.
|
|
876
653
|
allowlist: false,
|
|
877
654
|
skills: true,
|
|
878
|
-
// No slash-command file dir; skills double as reusable workflows.
|
|
879
655
|
commands: false,
|
|
880
|
-
// Plugins: Claude marketplace + .muse-plugin (syncPluginToVersion).
|
|
881
656
|
plugins: true,
|
|
882
|
-
// Runtime multi-agent / subagents exist, but there is no installable
|
|
883
|
-
// subagent-definition directory for agents-cli to sync into (capability
|
|
884
|
-
// table must stay truthful — see subagents-registry completeness).
|
|
885
657
|
subagents: false,
|
|
886
658
|
rules: { file: 'AGENTS.md' },
|
|
887
659
|
workflows: false,
|
|
888
|
-
// Portable memory at <repo>/.agents/memory/ + personal scopes.
|
|
889
660
|
memory: true,
|
|
890
661
|
modes: ['plan', 'edit', 'auto', 'skip'],
|
|
891
662
|
rulesImports: false,
|
|
892
663
|
interactiveRepl: true,
|
|
893
664
|
},
|
|
894
665
|
},
|
|
895
|
-
// Warp Agent CLI (`warp`) — Warp's standalone interactive TUI coding agent
|
|
896
|
-
// (docs.warp.dev/cli). Installed by the official cross-platform installer
|
|
897
|
-
// `curl -fsSL https://app.warp.dev/download/agent-cli | bash` (Windows: the
|
|
898
|
-
// sibling agent-cli.ps1), which drops a self-updating `warp` binary at
|
|
899
|
-
// ~/.local/bin/warp — NOT the older `oz` platform runner (brew cask `oz` /
|
|
900
|
-
// apt `oz-stable`), a separate headless product that no longer matches this
|
|
901
|
-
// CLI. Config lives under `~/.warp/` (`.mcp.json`, `skills/`, `tui/`). It is
|
|
902
|
-
// interactive-only: bare `warp` opens the TUI (streamed responses, diffs,
|
|
903
|
-
// inline approvals). There is NO headless one-shot form — the documented
|
|
904
|
-
// flags are --api-key / --auto-approve / --resume <token> /
|
|
905
|
-
// --set-provider-api-key / --clear-provider-api-key / --version / --help; no
|
|
906
|
-
// -p/--prompt, no --model (model is the `/model` picker), no JSON output.
|
|
907
|
-
// Auth: interactive browser sign-in on launch, or the `WARP_API_KEY` env
|
|
908
|
-
// token / `--api-key` for CI. Rules/context file is `AGENTS.md` (also reads
|
|
909
|
-
// WARP.md / CLAUDE.md). Conversations sync SERVER-SIDE to the Warp/Oz
|
|
910
|
-
// platform (resume a prior one with `warp --resume <token>`), so there is no
|
|
911
|
-
// local transcript for `agents sessions` to index — warp is intentionally
|
|
912
|
-
// absent from SESSION_AGENTS.
|
|
913
|
-
// Docs: https://docs.warp.dev/cli/quickstart
|
|
914
666
|
warp: {
|
|
915
667
|
id: 'warp',
|
|
916
668
|
name: 'Warp',
|
|
@@ -934,57 +686,27 @@ export const AGENTS = {
|
|
|
934
686
|
instructionsFile: 'AGENTS.md',
|
|
935
687
|
format: 'markdown',
|
|
936
688
|
variableSyntax: '$ARGUMENTS',
|
|
937
|
-
// Warp has no event->shell-command hook registration surface (its startup
|
|
938
|
-
// flags are --api-key/--auto-approve/--resume/--set-provider-api-key/
|
|
939
|
-
// --clear-provider-api-key — no hooks).
|
|
940
689
|
supportsHooks: false,
|
|
941
690
|
capabilities: {
|
|
942
691
|
hooks: false,
|
|
943
|
-
// MCP: Warp reads the Claude `{ "mcpServers": {...} }` schema from
|
|
944
|
-
// `.warp/.mcp.json` (user `~/.warp/.mcp.json`, project `<root>/.warp/.mcp.json`),
|
|
945
|
-
// stdio + http with headers, same schema as Claude's .mcp.json.
|
|
946
692
|
mcp: true,
|
|
947
693
|
mcpHttp: true,
|
|
948
694
|
mcpHeaders: true,
|
|
949
|
-
// Autonomy is a single toggle (`--auto-approve`), not a Claude-style
|
|
950
|
-
// tool-name allow/deny list agents-cli can write — so no allowlist writer
|
|
951
|
-
// (mirrors muse).
|
|
952
695
|
allowlist: false,
|
|
953
|
-
// Skills searched in `.agents/skills/`, `.warp/skills/`, `.claude/skills/`,
|
|
954
|
-
// `.codex/skills/`.
|
|
955
696
|
skills: true,
|
|
956
|
-
// Slash-commands are native/server-managed (no droppable markdown
|
|
957
|
-
// command-file directory for agents-cli to sync into).
|
|
958
697
|
commands: false,
|
|
959
|
-
// No Claude marketplace / plugin manifest support.
|
|
960
698
|
plugins: false,
|
|
961
|
-
// Cloud agents are server-side; no installable subagent-definition
|
|
962
|
-
// directory to sync into (keeps the table truthful).
|
|
963
699
|
subagents: false,
|
|
964
700
|
rules: { file: 'AGENTS.md' },
|
|
965
701
|
workflows: false,
|
|
966
702
|
memory: false,
|
|
967
|
-
// No per-run permission flag beyond `--auto-approve`; the single `edit`
|
|
968
|
-
// mode maps to no flags (mirrors hermes).
|
|
969
703
|
modes: ['edit'],
|
|
970
704
|
rulesImports: false,
|
|
971
|
-
// Bare `warp` opens the interactive TUI (its only run form).
|
|
972
705
|
interactiveRepl: true,
|
|
973
706
|
},
|
|
974
707
|
},
|
|
975
708
|
};
|
|
976
|
-
/** All current and legacy agent IDs derived from the AGENTS registry. */
|
|
977
709
|
export const ALL_AGENT_IDS = Object.keys(AGENTS);
|
|
978
|
-
/**
|
|
979
|
-
* Agents the routine daemon can fire locally. Lives here (not runner.ts) so
|
|
980
|
-
* routines.ts can import it for schedule-time validation without a circular
|
|
981
|
-
* import (runner.ts already imports from routines.ts).
|
|
982
|
-
*
|
|
983
|
-
* This is a curated subset of AGENT_COMMANDS, not "every harness that can run
|
|
984
|
-
* headlessly". Expanding it is a product change. Argv itself is baked from
|
|
985
|
-
* AGENT_COMMANDS in daemon/runner.ts bakeRoutineArgv — do not reintroduce a
|
|
986
|
-
* second token table.
|
|
987
|
-
*/
|
|
988
710
|
export const ROUTINE_AGENT_IDS = Object.freeze([
|
|
989
711
|
'claude',
|
|
990
712
|
'codex',
|
|
@@ -993,62 +715,30 @@ export const ROUTINE_AGENT_IDS = Object.freeze([
|
|
|
993
715
|
'droid',
|
|
994
716
|
'muse',
|
|
995
717
|
]);
|
|
996
|
-
/** Agents that can receive managed installs, imports, and resource sync writes. */
|
|
997
718
|
export const MANAGED_AGENT_IDS = ALL_AGENT_IDS.filter((id) => !AGENTS[id].deprecated?.hard);
|
|
998
|
-
/**
|
|
999
|
-
* A self-updating agent is a single global binary installed by an official
|
|
1000
|
-
* `curl … | sh` / `brew install` script that carries NO version token — the
|
|
1001
|
-
* installer can only ever fetch the *current* release, and the binary then keeps
|
|
1002
|
-
* itself up to date in place (droid, grok, antigravity, cursor, hermes,
|
|
1003
|
-
* goose). There is no semver to pin, so agents-cli must not model these as
|
|
1004
|
-
* having multiple installable version-homes the way it does for npm-packaged
|
|
1005
|
-
* agents (claude, codex, kimi, …).
|
|
1006
|
-
*
|
|
1007
|
-
* The predicate is `!npmPackage && installScript && !installScript.includes('VERSION')`:
|
|
1008
|
-
* - `npmPackage` empty → not installed from npm, so `agents add x@1.2.3`
|
|
1009
|
-
* can't resolve a registry version.
|
|
1010
|
-
* - `installScript` present → it IS installed by a script (not unmanaged).
|
|
1011
|
-
* - no `VERSION` placeholder → the script has no slot for a pinned version
|
|
1012
|
-
* (contrast: an installer templated with `VERSION`
|
|
1013
|
-
* could pin, and is NOT self-updating).
|
|
1014
|
-
*
|
|
1015
|
-
* Route every "is this a pinnable, multi-version agent?" decision through here —
|
|
1016
|
-
* never a scattered `agent === 'droid'`.
|
|
1017
|
-
*/
|
|
1018
719
|
export function isSelfUpdatingAgent(agent) {
|
|
1019
720
|
const cfg = AGENTS[agent];
|
|
1020
721
|
return !cfg.npmPackage && !!cfg.installScript && !cfg.installScript.includes('VERSION');
|
|
1021
722
|
}
|
|
1022
723
|
export function isAgentHardDeprecated(agent) {
|
|
1023
|
-
// Tolerate ids outside the registry (legacy YAML, test fixtures): an unknown
|
|
1024
|
-
// agent is not hard-deprecated — its own validation rejects it elsewhere.
|
|
1025
724
|
return AGENTS[agent]?.deprecated?.hard === true;
|
|
1026
725
|
}
|
|
1027
|
-
// Capability-filtered agent lists used to live here as `*_CAPABLE_AGENTS`
|
|
1028
|
-
// constants. They were a frequent source of silent-skip bugs (e.g. grok
|
|
1029
|
-
// rules sync gated on `COMMANDS_CAPABLE_AGENTS`). Use `capableAgents(cap)`
|
|
1030
|
-
// from `./capabilities.js` instead — it consults the AgentConfig matrix
|
|
1031
|
-
// directly, so a single source of truth drives every gate.
|
|
1032
|
-
/** Get the chalk color function for an agent. Works for any AgentId or SessionAgentId. */
|
|
1033
726
|
export function colorAgent(agentId) {
|
|
1034
727
|
const agent = AGENTS[agentId];
|
|
1035
728
|
if (!agent)
|
|
1036
729
|
return chalk.white;
|
|
1037
730
|
return chalk[agent.color];
|
|
1038
731
|
}
|
|
1039
|
-
/** Return the agent's display name, colored. */
|
|
1040
732
|
export function agentLabel(agentId) {
|
|
1041
733
|
const agent = AGENTS[agentId];
|
|
1042
734
|
if (!agent)
|
|
1043
735
|
return agentId;
|
|
1044
736
|
return chalk[agent.color](agent.name);
|
|
1045
737
|
}
|
|
1046
|
-
/** Check whether the given agent's CLI binary is present on PATH. */
|
|
1047
738
|
export async function isCliInstalled(agentId) {
|
|
1048
739
|
const agent = AGENTS[agentId];
|
|
1049
740
|
return findInPath(agent.cliCommand) !== null;
|
|
1050
741
|
}
|
|
1051
|
-
/** Return the installed CLI version for the given agent, or null if not found. */
|
|
1052
742
|
export async function getCliVersion(agentId) {
|
|
1053
743
|
const agent = AGENTS[agentId];
|
|
1054
744
|
const binaryPath = findInPath(agent.cliCommand);
|
|
@@ -1056,18 +746,15 @@ export async function getCliVersion(agentId) {
|
|
|
1056
746
|
return null;
|
|
1057
747
|
return getCachedVersionForBinary(agentId, binaryPath);
|
|
1058
748
|
}
|
|
1059
|
-
/** Return the absolute path to the agent's CLI binary on PATH, or null. */
|
|
1060
749
|
export async function getCliPath(agentId) {
|
|
1061
750
|
return findInPath(AGENTS[agentId].cliCommand);
|
|
1062
751
|
}
|
|
1063
|
-
/** Look up version from cache by (binary, mtime). On miss or stale, spawn `--version` and cache. */
|
|
1064
752
|
async function getCachedVersionForBinary(agentId, binaryPath) {
|
|
1065
753
|
let mtime = 0;
|
|
1066
754
|
try {
|
|
1067
755
|
mtime = fs.statSync(binaryPath).mtimeMs;
|
|
1068
756
|
}
|
|
1069
757
|
catch {
|
|
1070
|
-
/* binary vanished between findInPath and statSync */
|
|
1071
758
|
return null;
|
|
1072
759
|
}
|
|
1073
760
|
const cache = loadCliVersionCache();
|
|
@@ -1078,10 +765,6 @@ async function getCachedVersionForBinary(agentId, binaryPath) {
|
|
|
1078
765
|
const agent = AGENTS[agentId];
|
|
1079
766
|
let version = null;
|
|
1080
767
|
try {
|
|
1081
|
-
// probeCapture, not bare execFileAsync: a probed harness can fork its own
|
|
1082
|
-
// children (copilot's platform-binary downloader), and a timeout kill of
|
|
1083
|
-
// the direct child would orphan them mid-write (RUSH-3028). The probe runs
|
|
1084
|
-
// in its own process group and the whole group is reaped on settle.
|
|
1085
768
|
const { stdout } = await probeCapture(agent.cliCommand, ['--version'], 3000);
|
|
1086
769
|
const versionRe = agent.versionStdoutMatch === 'openclaw'
|
|
1087
770
|
? /openclaw\/(\d+\.\d+\.\d+)/
|
|
@@ -1090,32 +773,18 @@ async function getCachedVersionForBinary(agentId, binaryPath) {
|
|
|
1090
773
|
version = match ? match[1] : stdout.trim();
|
|
1091
774
|
}
|
|
1092
775
|
catch {
|
|
1093
|
-
/* version command failed */
|
|
1094
776
|
version = null;
|
|
1095
777
|
}
|
|
1096
|
-
// Skip persisting null results — the most common cause is a transient
|
|
1097
|
-
// `--version` failure (slow startup, stdout race, etc.). A sticky-null
|
|
1098
|
-
// entry kept users in a broken state where every subsequent
|
|
1099
|
-
// `getCachedVersionForBinary` short-circuited to null forever, even
|
|
1100
|
-
// after the binary started working. Re-probing on the next call costs
|
|
1101
|
-
// one execFile; persisting null costs the whole feature.
|
|
1102
778
|
if (version !== null) {
|
|
1103
779
|
cache[agentId] = { binaryPath, mtime, version };
|
|
1104
780
|
saveCliVersionCache();
|
|
1105
781
|
}
|
|
1106
782
|
return version;
|
|
1107
783
|
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Resolve the full CLI state for an agent: whether it is installed, its version,
|
|
1110
|
-
* and the path to the binary. Checks version-managed installs first, then falls
|
|
1111
|
-
* back to a plain PATH lookup.
|
|
1112
|
-
*/
|
|
1113
784
|
export async function getCliState(agentId) {
|
|
1114
|
-
// Fast path: if version-managed, derive state from filesystem (no subprocesses)
|
|
1115
785
|
const agent = AGENTS[agentId];
|
|
1116
786
|
const agentVersionsDir = path.join(getVersionsDir(), agentId);
|
|
1117
787
|
if (fs.existsSync(agentVersionsDir)) {
|
|
1118
|
-
// Use resolved version (project manifest -> global default)
|
|
1119
788
|
const resolvedVer = resolveVersion(agentId, process.cwd());
|
|
1120
789
|
if (resolvedVer) {
|
|
1121
790
|
const binaryPath = path.join(agentVersionsDir, resolvedVer, 'node_modules', '.bin', agent.cliCommand);
|
|
@@ -1128,7 +797,6 @@ export async function getCliState(agentId) {
|
|
|
1128
797
|
};
|
|
1129
798
|
}
|
|
1130
799
|
}
|
|
1131
|
-
// Fallback: if no default set or resolved version not installed, return first available
|
|
1132
800
|
const entries = fs.readdirSync(agentVersionsDir, { withFileTypes: true });
|
|
1133
801
|
for (const entry of entries) {
|
|
1134
802
|
if (entry.isDirectory()) {
|
|
@@ -1146,20 +814,9 @@ export async function getCliState(agentId) {
|
|
|
1146
814
|
}
|
|
1147
815
|
return getUnmanagedCliState(agentId);
|
|
1148
816
|
}
|
|
1149
|
-
/**
|
|
1150
|
-
* Resolve the agent's OWN install — the one agents-cli does not manage — by plain
|
|
1151
|
-
* PATH lookup, ignoring the version dirs entirely.
|
|
1152
|
-
*
|
|
1153
|
-
* Callers that specifically mean "the user's own globally-installed CLI" must use
|
|
1154
|
-
* this rather than `getCliState`, whose managed fast path reports an installed
|
|
1155
|
-
* version (any version dir, in readdir order) and would therefore hand back an
|
|
1156
|
-
* isolated copy — a copy that is deliberately unreachable from PATH — labelled as
|
|
1157
|
-
* the global install.
|
|
1158
|
-
*/
|
|
1159
817
|
export async function getUnmanagedCliState(agentId) {
|
|
818
|
+
// This path must never relabel an isolated managed version as the user's global install.
|
|
1160
819
|
const agent = AGENTS[agentId];
|
|
1161
|
-
// Grok (and any future harness with unmanagedBinary: 'grok-downloads')
|
|
1162
|
-
// keeps versioned binaries under ~/.grok/downloads/, not on PATH.
|
|
1163
820
|
if (agent.unmanagedBinary === 'grok-downloads') {
|
|
1164
821
|
const grokBin = resolveGrokBinary();
|
|
1165
822
|
if (!grokBin) {
|
|
@@ -1181,7 +838,6 @@ export async function getUnmanagedCliState(agentId) {
|
|
|
1181
838
|
path: binaryPath,
|
|
1182
839
|
};
|
|
1183
840
|
}
|
|
1184
|
-
/** Resolve CLI state for all registered agents in parallel. */
|
|
1185
841
|
export async function getAllCliStates() {
|
|
1186
842
|
const states = {};
|
|
1187
843
|
const results = await Promise.all(ALL_AGENT_IDS.map(async (agentId) => ({
|
|
@@ -1193,16 +849,7 @@ export async function getAllCliStates() {
|
|
|
1193
849
|
}
|
|
1194
850
|
return states;
|
|
1195
851
|
}
|
|
1196
|
-
/**
|
|
1197
|
-
* Agents that `agents setup` probes for pre-existing native installations
|
|
1198
|
-
* (i.e., a config dir present before agents-cli took over). Derived from
|
|
1199
|
-
* `sessionDir` so a new harness cannot be walkable yet missing from setup.
|
|
1200
|
-
*/
|
|
1201
852
|
export const UNMANAGED_DETECTION_CANDIDATES = ALL_AGENT_IDS.filter((id) => AGENTS[id].sessionDir !== null);
|
|
1202
|
-
/**
|
|
1203
|
-
* Detect existing agent installations that are NOT yet managed by agents-cli.
|
|
1204
|
-
* Returns agents whose config dir exists as a real directory (not a symlink).
|
|
1205
|
-
*/
|
|
1206
853
|
export async function getUnmanagedAgentInstalls() {
|
|
1207
854
|
const unmanaged = [];
|
|
1208
855
|
for (const agentId of UNMANAGED_DETECTION_CANDIDATES) {
|
|
@@ -1215,50 +862,26 @@ export async function getUnmanagedAgentInstalls() {
|
|
|
1215
862
|
}
|
|
1216
863
|
}
|
|
1217
864
|
catch {
|
|
1218
|
-
// Config dir doesn't exist
|
|
1219
865
|
}
|
|
1220
866
|
}
|
|
1221
867
|
return unmanaged;
|
|
1222
868
|
}
|
|
1223
|
-
/** Create the agent's slash-commands directory if it does not exist. */
|
|
1224
869
|
export function ensureCommandsDir(agentId) {
|
|
1225
870
|
const agent = AGENTS[agentId];
|
|
1226
871
|
if (!fs.existsSync(agent.commandsDir)) {
|
|
1227
872
|
fs.mkdirSync(agent.commandsDir, { recursive: true });
|
|
1228
873
|
}
|
|
1229
874
|
}
|
|
1230
|
-
/** Create the agent's skills directory if it does not exist. */
|
|
1231
875
|
export function ensureSkillsDir(agentId) {
|
|
1232
876
|
const agent = AGENTS[agentId];
|
|
1233
877
|
if (!fs.existsSync(agent.skillsDir)) {
|
|
1234
878
|
fs.mkdirSync(agent.skillsDir, { recursive: true });
|
|
1235
879
|
}
|
|
1236
880
|
}
|
|
1237
|
-
/**
|
|
1238
|
-
* The agent's config-dir name relative to $HOME — e.g. '.claude',
|
|
1239
|
-
* '.gemini/antigravity-cli', '.config/amp', '.kimi-code'.
|
|
1240
|
-
*
|
|
1241
|
-
* Path segment to join onto a (version) home root when locating an agent's
|
|
1242
|
-
* commands/skills/plugins. Do NOT hardcode `.${agentId}`: it is wrong for
|
|
1243
|
-
* every agent whose config dir is nested or under ~/.config — antigravity
|
|
1244
|
-
* (~/.gemini/antigravity-cli), amp (~/.config/amp), goose (~/.config/goose),
|
|
1245
|
-
* kimi (~/.kimi-code). Mirrors the shim configDirName derivation in shims.ts.
|
|
1246
|
-
*
|
|
1247
|
-
* Relativized against the module-level HOME constant (the same value used to
|
|
1248
|
-
* build every `configDir`), NOT a fresh `os.homedir()` — so the result stays a
|
|
1249
|
-
* clean relative name even when HOME is overridden after module load (tests,
|
|
1250
|
-
* sandboxes). Using `os.homedir()` here would yield `../../real/home/.claude`.
|
|
1251
|
-
*/
|
|
1252
881
|
export function agentConfigDirName(agentId) {
|
|
882
|
+
// Use import-time HOME: nested config dirs and later HOME overrides must stay relative.
|
|
1253
883
|
return path.relative(HOME, AGENTS[agentId].configDir);
|
|
1254
884
|
}
|
|
1255
|
-
/**
|
|
1256
|
-
* Human-readable label for a Claude account's organizationType as read from
|
|
1257
|
-
* .claude.json's oauthAccount ("claude_team" -> "Team"). Unrecognized values
|
|
1258
|
-
* (future tiers) are rendered by stripping the "claude_" prefix and
|
|
1259
|
-
* title-casing the rest — an unfamiliar-but-visible label beats silence.
|
|
1260
|
-
* Returns null for missing input.
|
|
1261
|
-
*/
|
|
1262
885
|
export function formatClaudeOrgLabel(orgType) {
|
|
1263
886
|
if (!orgType)
|
|
1264
887
|
return null;
|
|
@@ -1278,22 +901,13 @@ export function formatClaudeOrgLabel(orgType) {
|
|
|
1278
901
|
.map((w) => w[0].toUpperCase() + w.slice(1))
|
|
1279
902
|
.join(' ');
|
|
1280
903
|
}
|
|
1281
|
-
/**
|
|
1282
|
-
* Short badge identifying which ORG an account belongs to — "Turing Labs" for a
|
|
1283
|
-
* multi-seat Team/Enterprise org, whose name is real identity that disambiguates
|
|
1284
|
-
* a Team seat from a same-email personal plan. Returns null for personal plans
|
|
1285
|
-
* (Max/Pro/Free): the tier label now lives in the aligned plan column, so a badge
|
|
1286
|
-
* would only duplicate it, and a personal org's name is auto-generated boilerplate
|
|
1287
|
-
* ("<email>'s Organization"), not identity. Also null when the account carries no
|
|
1288
|
-
* organizationType (signed out, non-Claude agents, configs predating the field).
|
|
1289
|
-
*/
|
|
1290
904
|
export function accountOrgBadge(info) {
|
|
905
|
+
// Personal org names are boilerplate; only named multi-seat orgs disambiguate identity.
|
|
1291
906
|
const isMultiSeat = info?.organizationType === 'claude_team' || info?.organizationType === 'claude_enterprise';
|
|
1292
907
|
if (isMultiSeat && info?.organizationName)
|
|
1293
908
|
return info.organizationName;
|
|
1294
909
|
return null;
|
|
1295
910
|
}
|
|
1296
|
-
/** Agents whose local credential formats expose enough state for account selection. */
|
|
1297
911
|
export const ACCOUNT_INSPECTION_AGENT_IDS = [
|
|
1298
912
|
'claude',
|
|
1299
913
|
'codex',
|
|
@@ -1306,15 +920,9 @@ export const ACCOUNT_INSPECTION_AGENT_IDS = [
|
|
|
1306
920
|
'muse',
|
|
1307
921
|
];
|
|
1308
922
|
const ACCOUNT_INSPECTION_AGENTS = new Set(ACCOUNT_INSPECTION_AGENT_IDS);
|
|
1309
|
-
/** Whether agents-cli can determine this agent's per-version sign-in state. */
|
|
1310
923
|
export function supportsAccountInspection(agentId) {
|
|
1311
924
|
return ACCOUNT_INSPECTION_AGENTS.has(agentId);
|
|
1312
925
|
}
|
|
1313
|
-
/**
|
|
1314
|
-
* Human-readable account identity shared by every account-aware surface.
|
|
1315
|
-
* Prefer email, append a multi-seat Claude organization name when present,
|
|
1316
|
-
* then fall back to a non-secret account id or a generic signed-in label.
|
|
1317
|
-
*/
|
|
1318
926
|
export function accountDisplayLabel(info) {
|
|
1319
927
|
if (!info)
|
|
1320
928
|
return '';
|
|
@@ -1326,26 +934,10 @@ export function accountDisplayLabel(info) {
|
|
|
1326
934
|
return info.accountId ? `id:${info.accountId}` : 'signed in';
|
|
1327
935
|
return '';
|
|
1328
936
|
}
|
|
1329
|
-
/** Return the email address associated with the agent's auth config, or null. */
|
|
1330
937
|
export async function getAccountEmail(agentId, home) {
|
|
1331
938
|
const info = await getAccountInfo(agentId, home);
|
|
1332
939
|
return info.email;
|
|
1333
940
|
}
|
|
1334
|
-
/**
|
|
1335
|
-
* Extract full account information (identity, plan, usage status, credits) from
|
|
1336
|
-
* the agent's local auth/config files. Supports Claude, Codex, and Gemini.
|
|
1337
|
-
*/
|
|
1338
|
-
/**
|
|
1339
|
-
* Resolve a file-auth agent's credential file. Sign-in is account-global, but
|
|
1340
|
-
* each installed version gets an isolated home; the credential physically lives
|
|
1341
|
-
* only in the home the user logged in under (the one the `~/.<config>` symlink
|
|
1342
|
-
* targets). Check the per-version `base` first, then fall back to the active
|
|
1343
|
-
* config location under the real HOME so every installed version reflects the
|
|
1344
|
-
* true account state (droid/antigravity/kimi all stored login per-version-home
|
|
1345
|
-
* and showed non-active versions as "not signed in"). Returns the first
|
|
1346
|
-
* existing path, or null.
|
|
1347
|
-
*/
|
|
1348
|
-
/** True when `dir` is under the per-account slot root (`~/.agents/.history/accounts/`). */
|
|
1349
941
|
export function isAccountSlotDir(dir) {
|
|
1350
942
|
const root = path.resolve(getHistoryDir(), 'accounts');
|
|
1351
943
|
const resolved = path.resolve(dir);
|
|
@@ -1357,9 +949,7 @@ function resolveAccountCredentialPath(base, ...segments) {
|
|
|
1357
949
|
if (fs.existsSync(perVersion))
|
|
1358
950
|
return perVersion;
|
|
1359
951
|
}
|
|
1360
|
-
catch {
|
|
1361
|
-
// A slot is the account's own HOME (PHNX-3940 T5). Never inherit another
|
|
1362
|
-
// account's adopted ~/.<config> — that is the cross-account leak.
|
|
952
|
+
catch { }
|
|
1363
953
|
if (isAccountSlotDir(base))
|
|
1364
954
|
return null;
|
|
1365
955
|
const active = path.join(process.env.AGENTS_REAL_HOME || os.homedir(), ...segments);
|
|
@@ -1368,22 +958,10 @@ function resolveAccountCredentialPath(base, ...segments) {
|
|
|
1368
958
|
if (fs.existsSync(active))
|
|
1369
959
|
return active;
|
|
1370
960
|
}
|
|
1371
|
-
catch {
|
|
961
|
+
catch { }
|
|
1372
962
|
}
|
|
1373
963
|
return null;
|
|
1374
964
|
}
|
|
1375
|
-
/**
|
|
1376
|
-
* The on-disk credential file(s) each account-inspectable agent authenticates
|
|
1377
|
-
* from, expressed as path segments under a home. Mirrors the exact files
|
|
1378
|
-
* {@link getAccountInfo} reads, so a presence check here matches what a real
|
|
1379
|
-
* launch would find. Each entry is a list of alternatives — the FIRST that
|
|
1380
|
-
* exists counts as present (claude writes either `.claude/.claude.json` under
|
|
1381
|
-
* the shimmed config dir or a home-level `.claude.json`). Agents whose login is
|
|
1382
|
-
* stored only in the OS keychain on some platforms (antigravity, and claude's
|
|
1383
|
-
* token) still expose a credential FILE — the presence of that file is the
|
|
1384
|
-
* signal we key off; its absence on BOTH the per-version home and the active
|
|
1385
|
-
* home is what makes a logged-out claim provable.
|
|
1386
|
-
*/
|
|
1387
965
|
const CREDENTIAL_FILE_SEGMENTS = {
|
|
1388
966
|
claude: [['.claude', '.claude.json'], ['.claude.json']],
|
|
1389
967
|
codex: [['.codex', 'auth.json']],
|
|
@@ -1392,14 +970,9 @@ const CREDENTIAL_FILE_SEGMENTS = {
|
|
|
1392
970
|
droid: [['.factory', 'auth.v2.file']],
|
|
1393
971
|
antigravity: [['.gemini', 'antigravity-cli', 'antigravity-oauth-token']],
|
|
1394
972
|
opencode: [['.local', 'share', 'opencode', 'auth.json']],
|
|
1395
|
-
// Muse Code stores OAuth / API credentials at ~/.config/muse/auth.json
|
|
1396
|
-
// (or META_API_KEY in the environment, which is not a file).
|
|
1397
973
|
muse: [['.config', 'muse', 'auth.json']],
|
|
1398
|
-
// With AGENT_CLI_CREDENTIAL_STORE=file, Cursor stores both OAuth tokens at
|
|
1399
|
-
// ~/.cursor/auth.json. cli-config.json holds account metadata only.
|
|
1400
974
|
cursor: [['.cursor', 'auth.json']],
|
|
1401
975
|
};
|
|
1402
|
-
/** Whether an agent's credential file exists under a given home. */
|
|
1403
976
|
function credentialFileExistsUnder(agentId, home) {
|
|
1404
977
|
const alternatives = CREDENTIAL_FILE_SEGMENTS[agentId];
|
|
1405
978
|
if (!alternatives)
|
|
@@ -1415,47 +988,18 @@ function credentialFileExistsUnder(agentId, home) {
|
|
|
1415
988
|
});
|
|
1416
989
|
if (!hasSegment)
|
|
1417
990
|
return false;
|
|
1418
|
-
// Claude's `.claude.json` is account METADATA Claude Code writes on any
|
|
1419
|
-
// launch, not the credential itself — a version can carry stale identity
|
|
1420
|
-
// there (e.g. install-time carry-forward) with no usable credential behind
|
|
1421
|
-
// it: a failed OAuth refresh blanks `.credentials.json`, and a Linux worker
|
|
1422
|
-
// can be missing BOTH `.credentials.json` and the `.oauth_token` setup-token
|
|
1423
|
-
// file entirely (PHNX-3502). `credentialPresence` promises to mirror what a
|
|
1424
|
-
// real launch would find, so it must fail whenever `isClaudeCredentialFileBlank`
|
|
1425
|
-
// — the SAME floor `getAccountInfo` applies — would. On macOS that floor is a
|
|
1426
|
-
// no-op (Keychain-only, always "not blank"), so this reduces to the identity
|
|
1427
|
-
// check above, unchanged.
|
|
1428
991
|
if (agentId === 'claude')
|
|
1429
992
|
return !isClaudeCredentialFileBlank(home);
|
|
1430
993
|
return true;
|
|
1431
994
|
}
|
|
1432
|
-
/**
|
|
1433
|
-
* File-presence probe for an agent's credential, split by location: whether it
|
|
1434
|
-
* exists in a SPECIFIC version home (`perVersion`) and whether it exists under
|
|
1435
|
-
* the active/global HOME (`active`). A logged-out claim is only *provable* when
|
|
1436
|
-
* BOTH are absent — a version that merely lacks its own copy but shares the
|
|
1437
|
-
* global login is signed in, not logged out. Pure file existence; no decrypt,
|
|
1438
|
-
* no network, no keychain prompt. Agents with no inspectable identity return
|
|
1439
|
-
* `{ perVersion: false, active: false }` and must NEVER yield a provable-logout
|
|
1440
|
-
* claim (the caller gates on {@link supportsAccountInspection}).
|
|
1441
|
-
*/
|
|
1442
995
|
export function credentialPresence(agentId, versionHome) {
|
|
996
|
+
// Logout is provable only for a known location when both isolated and active copies are absent.
|
|
1443
997
|
const realHome = process.env.AGENTS_REAL_HOME || os.homedir();
|
|
1444
998
|
const perVersion = credentialFileExistsUnder(agentId, versionHome);
|
|
1445
999
|
const active = credentialFileExistsUnder(agentId, realHome);
|
|
1446
1000
|
const knownLocation = (CREDENTIAL_FILE_SEGMENTS[agentId]?.length ?? 0) > 0;
|
|
1447
1001
|
return { perVersion, active, knownLocation };
|
|
1448
1002
|
}
|
|
1449
|
-
/**
|
|
1450
|
-
* Factory Droid stores its OAuth credential encrypted at ~/.factory/auth.v2.file
|
|
1451
|
-
* (AES-256-GCM, format `ivB64:tagB64:ctB64`) with the 32-byte key base64-stored
|
|
1452
|
-
* in ~/.factory/auth.v2.key. On the keyfile-v2 source there is no OS-keychain /
|
|
1453
|
-
* device binding — the key is on disk — so we can decrypt locally with no
|
|
1454
|
-
* network call. Every failure (missing key file — e.g. a keyring-v2/legacy
|
|
1455
|
-
* login with no on-disk key, a bad GCM tag, or malformed JSON) returns null.
|
|
1456
|
-
* Never throws. Shared by account identity below and the Droid usage fetcher
|
|
1457
|
-
* in usage.ts.
|
|
1458
|
-
*/
|
|
1459
1003
|
export function decryptDroidAuthPayload(base) {
|
|
1460
1004
|
const filePath = resolveAccountCredentialPath(base, '.factory', 'auth.v2.file');
|
|
1461
1005
|
const keyPath = resolveAccountCredentialPath(base, '.factory', 'auth.v2.key');
|
|
@@ -1463,16 +1007,8 @@ export function decryptDroidAuthPayload(base) {
|
|
|
1463
1007
|
return null;
|
|
1464
1008
|
return decryptDroidAuthFile(filePath, keyPath);
|
|
1465
1009
|
}
|
|
1466
|
-
/**
|
|
1467
|
-
* Decrypt a Droid `auth.v2.file` (AES-256-GCM `ivB64:tagB64:ctB64`) using the
|
|
1468
|
-
* raw 32-byte key stored base64 in `auth.v2.key`, given the EXACT paths to both.
|
|
1469
|
-
* Same crypto as decryptDroidAuthPayload but without the account-global HOME
|
|
1470
|
-
* fallback, so the identity of a SPECIFIC version home resolves against only
|
|
1471
|
-
* that home's files (carryForwardAuthFiles needs per-dir identity). Returns null
|
|
1472
|
-
* on any failure (missing file/key, wrong key length, bad GCM tag, malformed
|
|
1473
|
-
* JSON). Never throws.
|
|
1474
|
-
*/
|
|
1475
1010
|
function decryptDroidAuthFile(filePath, keyPath) {
|
|
1011
|
+
// Exact paths deliberately bypass active-HOME fallback for per-directory carry-forward identity.
|
|
1476
1012
|
try {
|
|
1477
1013
|
const blob = fs.readFileSync(filePath, 'utf-8').trim();
|
|
1478
1014
|
const key = Buffer.from(fs.readFileSync(keyPath, 'utf-8').trim(), 'base64');
|
|
@@ -1494,26 +1030,8 @@ function decryptDroidAuthFile(filePath, keyPath) {
|
|
|
1494
1030
|
return null;
|
|
1495
1031
|
}
|
|
1496
1032
|
}
|
|
1497
|
-
/**
|
|
1498
|
-
* Stable account identity for a *file-auth* agent's credential directory
|
|
1499
|
-
* (droid / kimi / antigravity), or null when the directory holds no decodable
|
|
1500
|
-
* account claim. Unlike a naive top-level JSON key-scan (which matched NO real
|
|
1501
|
-
* credential file), this decrypts / decodes each agent's REAL on-disk format so
|
|
1502
|
-
* the identity resolves against production credentials:
|
|
1503
|
-
* - droid: AES-256-GCM auth.v2.file (+ auth.v2.key) -> WorkOS access-token JWT
|
|
1504
|
-
* -> email / org_id / sub.
|
|
1505
|
-
* - kimi: credentials/kimi-code.json -> access-token JWT -> user_id / sub.
|
|
1506
|
-
* - antigravity: antigravity-oauth-token -> token.refresh_token -> JWT sub
|
|
1507
|
-
* when the token is a JWT, else a SHA-256 hash of the raw refresh-token
|
|
1508
|
-
* value (opaque Google consumer tokens are stable per login — hashed so
|
|
1509
|
-
* the identity key, which is persisted as a usage-cache key, never carries
|
|
1510
|
-
* a live credential).
|
|
1511
|
-
* Two directories for the SAME account compare equal; two DIFFERENT accounts
|
|
1512
|
-
* compare distinct. Used by carryForwardAuthFiles to refuse overwriting one
|
|
1513
|
-
* account's login with a credential that belongs to a DIFFERENT account
|
|
1514
|
-
* (RUSH-1764). Never throws.
|
|
1515
|
-
*/
|
|
1516
1033
|
export function readAuthAccountIdentity(agent, configDir) {
|
|
1034
|
+
// Identity claims outlive JWT authorization; credential usability is decided elsewhere.
|
|
1517
1035
|
try {
|
|
1518
1036
|
switch (agent) {
|
|
1519
1037
|
case 'droid': {
|
|
@@ -1542,9 +1060,6 @@ export function readAuthAccountIdentity(agent, configDir) {
|
|
|
1542
1060
|
return null;
|
|
1543
1061
|
const claims = decodeJwtPayload(refreshToken);
|
|
1544
1062
|
const sub = normalizeIdentityPart(claims?.sub ?? claims?.user_id);
|
|
1545
|
-
// An opaque (non-JWT) Google refresh token IS the credential — hash it
|
|
1546
|
-
// so the identity key stays stable per login without embedding a live
|
|
1547
|
-
// secret (the key is persisted as a usage-cache filename key).
|
|
1548
1063
|
const fallback = crypto.createHash('sha256').update(refreshToken).digest('hex').slice(0, 16);
|
|
1549
1064
|
return buildIdentityKey(agent, [['sub', sub ?? fallback]]);
|
|
1550
1065
|
}
|
|
@@ -1556,15 +1071,6 @@ export function readAuthAccountIdentity(agent, configDir) {
|
|
|
1556
1071
|
return null;
|
|
1557
1072
|
}
|
|
1558
1073
|
}
|
|
1559
|
-
/**
|
|
1560
|
-
* Derive Droid account identity from the decrypted credential. The
|
|
1561
|
-
* `access_token` is a WorkOS JWT carrying an `email` claim (plus org_id /
|
|
1562
|
-
* role). We decode the claim WITHOUT verifying `exp`: the email is stable
|
|
1563
|
-
* identity for display, not an authorization decision, so an expired token
|
|
1564
|
-
* still yields the right address. Returns null when the credential can't be
|
|
1565
|
-
* decrypted or has no decodable claims, so the caller falls back to the
|
|
1566
|
-
* file-presence signed-in signal.
|
|
1567
|
-
*/
|
|
1568
1074
|
function decryptDroidCredential(base) {
|
|
1569
1075
|
const cred = decryptDroidAuthPayload(base);
|
|
1570
1076
|
const claims = typeof cred?.access_token === 'string' ? decodeJwtPayload(cred.access_token) : null;
|
|
@@ -1577,38 +1083,18 @@ function decryptDroidCredential(base) {
|
|
|
1577
1083
|
};
|
|
1578
1084
|
}
|
|
1579
1085
|
let cachedAgyKeychainSignedIn;
|
|
1580
|
-
/**
|
|
1581
|
-
* Antigravity (`agy`) stores its OAuth token via the Go keyring library
|
|
1582
|
-
* (zalando/go-keyring), which is platform-split:
|
|
1583
|
-
*
|
|
1584
|
-
* - macOS: login keychain, service `gemini`, account `antigravity` — no file.
|
|
1585
|
-
* - Linux with Secret Service (libsecret / gnome-keyring): attributes
|
|
1586
|
-
* service=`gemini`, username=`antigravity` (go-keyring's Secret Service
|
|
1587
|
-
* mapping of service+user). Prefer this over the file when a keyring
|
|
1588
|
-
* daemon is running.
|
|
1589
|
-
* - Linux without Secret Service: file fallback at
|
|
1590
|
-
* `~/.gemini/antigravity-cli/antigravity-oauth-token`.
|
|
1591
|
-
*
|
|
1592
|
-
* Probe the OS keyring for existence after the file check. On macOS,
|
|
1593
|
-
* `security find-generic-password` without `-w` is metadata-only (never
|
|
1594
|
-
* prompts). On Linux, `secret-tool lookup` exit 0 means the item exists
|
|
1595
|
-
* (stdout is the secret — discarded, never logged). Cached per process —
|
|
1596
|
-
* the keyring is account-global, so one probe covers every installed version.
|
|
1597
|
-
* Returns false when the platform has no probe (Windows) or the tool is
|
|
1598
|
-
* missing. Guard with `AGENTS_NO_KEYCHAIN_PROBE=1` for hermetic tests.
|
|
1599
|
-
*/
|
|
1600
1086
|
export function antigravityOsKeyringProbe(platform = process.platform) {
|
|
1601
1087
|
if (platform === 'darwin') {
|
|
1602
1088
|
return {
|
|
1603
1089
|
cmd: 'security',
|
|
1090
|
+
// Omitting -w makes this a metadata-only probe that never reads the secret.
|
|
1604
1091
|
args: ['find-generic-password', '-s', 'gemini', '-a', 'antigravity'],
|
|
1605
1092
|
};
|
|
1606
1093
|
}
|
|
1607
1094
|
if (platform === 'linux') {
|
|
1608
|
-
// go-keyring secret_service attributes: "service" + "username" (not
|
|
1609
|
-
// "account" — that flag is the macOS security(1) spelling of the same user).
|
|
1610
1095
|
return {
|
|
1611
1096
|
cmd: 'secret-tool',
|
|
1097
|
+
// go-keyring maps the user to username, not the macOS account spelling.
|
|
1612
1098
|
args: ['lookup', 'service', 'gemini', 'username', 'antigravity'],
|
|
1613
1099
|
};
|
|
1614
1100
|
}
|
|
@@ -1619,8 +1105,6 @@ export function __resetAntigravityKeychainCacheForTest() {
|
|
|
1619
1105
|
cachedAgyKeychainSignedIn = undefined;
|
|
1620
1106
|
}
|
|
1621
1107
|
async function antigravityKeychainSignedIn() {
|
|
1622
|
-
// Test isolation first (before cache): real OS keyrings can't be sandboxed
|
|
1623
|
-
// per-test. Same spirit as AGENTS_REAL_HOME. Not cached, so tests can toggle.
|
|
1624
1108
|
if (process.env.AGENTS_NO_KEYCHAIN_PROBE === '1')
|
|
1625
1109
|
return false;
|
|
1626
1110
|
if (cachedAgyKeychainSignedIn !== undefined)
|
|
@@ -1631,47 +1115,21 @@ async function antigravityKeychainSignedIn() {
|
|
|
1631
1115
|
return false;
|
|
1632
1116
|
}
|
|
1633
1117
|
try {
|
|
1634
|
-
// Discard stdout: Linux secret-tool lookup prints the secret value.
|
|
1635
1118
|
await execFileAsync(probe.cmd, probe.args, {
|
|
1636
1119
|
timeout: 3000,
|
|
1637
|
-
// encoding so stdout is a string we can drop without ever logging it
|
|
1638
1120
|
encoding: 'utf8',
|
|
1639
1121
|
});
|
|
1640
1122
|
cachedAgyKeychainSignedIn = true;
|
|
1641
1123
|
}
|
|
1642
1124
|
catch {
|
|
1643
|
-
// Missing tool (ENOENT), missing item, locked collection, timeout → signed out.
|
|
1644
1125
|
cachedAgyKeychainSignedIn = false;
|
|
1645
1126
|
}
|
|
1646
1127
|
return cachedAgyKeychainSignedIn;
|
|
1647
1128
|
}
|
|
1648
|
-
/** The XDG base dirs OpenCode reads, and the env var that overrides each. */
|
|
1649
1129
|
const OPENCODE_XDG_DIRS = {
|
|
1650
1130
|
data: { env: 'XDG_DATA_HOME', fallback: ['.local', 'share'] },
|
|
1651
1131
|
state: { env: 'XDG_STATE_HOME', fallback: ['.local', 'state'] },
|
|
1652
1132
|
};
|
|
1653
|
-
/**
|
|
1654
|
-
* Resolve one of OpenCode's (sst/opencode) XDG-rooted files.
|
|
1655
|
-
*
|
|
1656
|
-
* OpenCode keeps provider credentials under `$XDG_DATA_HOME/opencode/` and TUI
|
|
1657
|
-
* state under `$XDG_STATE_HOME/opencode/`, defaulting to `~/.local/share` and
|
|
1658
|
-
* `~/.local/state` on EVERY platform — its `xdg-basedir` dependency does not
|
|
1659
|
-
* special-case macOS, so there is no `~/Library/Application Support` variant.
|
|
1660
|
-
* Both roots are account-global (not per-version), matching how
|
|
1661
|
-
* `session/discover.ts` already resolves `~/.local/share/opencode/opencode.db`.
|
|
1662
|
-
*
|
|
1663
|
-
* Resolution order, first existing wins:
|
|
1664
|
-
* 1. `<base>/<fallback>/opencode/<file>` — the passed per-version home. This is
|
|
1665
|
-
* primarily a test hook (suites write a hermetic file under a temp home)
|
|
1666
|
-
* but also covers any relocated install.
|
|
1667
|
-
* 2. `$XDG_<KIND>_HOME/opencode/<file>` — an explicit XDG override, exactly
|
|
1668
|
-
* what OpenCode itself honours.
|
|
1669
|
-
* 3. `<realHome>/<fallback>/opencode/<file>` — the active default, under
|
|
1670
|
-
* `AGENTS_REAL_HOME` or `os.homedir()`, so every installed version reflects
|
|
1671
|
-
* the one account-global state (same fallback shape as
|
|
1672
|
-
* resolveAccountCredentialPath).
|
|
1673
|
-
* Returns the first existing path, or null. Never throws.
|
|
1674
|
-
*/
|
|
1675
1133
|
export function resolveOpenCodeXdgPath(base, kind, file) {
|
|
1676
1134
|
const { env, fallback } = OPENCODE_XDG_DIRS[kind];
|
|
1677
1135
|
const candidates = [path.join(base, ...fallback, 'opencode', file)];
|
|
@@ -1685,23 +1143,15 @@ export function resolveOpenCodeXdgPath(base, kind, file) {
|
|
|
1685
1143
|
if (fs.existsSync(candidate))
|
|
1686
1144
|
return candidate;
|
|
1687
1145
|
}
|
|
1688
|
-
catch {
|
|
1146
|
+
catch { }
|
|
1689
1147
|
}
|
|
1690
1148
|
return null;
|
|
1691
1149
|
}
|
|
1692
1150
|
function resolveOpenCodeAuthPath(base) {
|
|
1693
1151
|
return resolveOpenCodeXdgPath(base, 'data', 'auth.json');
|
|
1694
1152
|
}
|
|
1695
|
-
/**
|
|
1696
|
-
* Validate one OpenCode auth.json entry against its discriminated union
|
|
1697
|
-
* (`type: 'oauth' | 'api' | 'wellknown'`) and confirm the credential actually
|
|
1698
|
-
* carries its required secret field(s) non-empty. This guards against a
|
|
1699
|
-
* corrupt/half-written entry reading as signed-in — the same "must have a real
|
|
1700
|
-
* credential" floor grok/antigravity apply. We only INSPECT the shape here; the
|
|
1701
|
-
* secret values (`access`/`refresh`/`key`/`token`) are never read out or
|
|
1702
|
-
* surfaced anywhere.
|
|
1703
|
-
*/
|
|
1704
1153
|
function isValidOpenCodeCredential(value) {
|
|
1154
|
+
// Only complete auth.json discriminated-union credentials establish a login.
|
|
1705
1155
|
if (!value || typeof value !== 'object')
|
|
1706
1156
|
return false;
|
|
1707
1157
|
const cred = value;
|
|
@@ -1713,19 +1163,6 @@ function isValidOpenCodeCredential(value) {
|
|
|
1713
1163
|
default: return false;
|
|
1714
1164
|
}
|
|
1715
1165
|
}
|
|
1716
|
-
/**
|
|
1717
|
-
* The human identity an OpenCode `type: 'oauth'` credential carries in its
|
|
1718
|
-
* access token, when that token is a JWT. Provider-agnostic by shape: the
|
|
1719
|
-
* OpenAI-issued token OpenCode stores under its `openai` provider carries the
|
|
1720
|
-
* same namespaced claims Codex's own `auth.json` does (`…/profile.email`,
|
|
1721
|
-
* `…/auth.chatgpt_plan_type`), so the extraction is shared with `case 'codex'`
|
|
1722
|
-
* rather than reinvented. A plain `email` claim is accepted too, for providers
|
|
1723
|
-
* that issue an ordinary OIDC token.
|
|
1724
|
-
*
|
|
1725
|
-
* Only claims are read — the token itself is never returned or logged. A
|
|
1726
|
-
* non-JWT credential (Anthropic's `sk-ant-oat…` opaque token, any `type: 'api'`
|
|
1727
|
-
* key) simply yields nothing.
|
|
1728
|
-
*/
|
|
1729
1166
|
function openCodeOauthIdentity(cred) {
|
|
1730
1167
|
const access = cred?.access;
|
|
1731
1168
|
if (typeof access !== 'string' || access.length === 0)
|
|
@@ -1743,29 +1180,8 @@ function openCodeOauthIdentity(cred) {
|
|
|
1743
1180
|
: null;
|
|
1744
1181
|
return { email, plan };
|
|
1745
1182
|
}
|
|
1746
|
-
/**
|
|
1747
|
-
* OpenCode's account identity, read from `auth.json`.
|
|
1748
|
-
*
|
|
1749
|
-
* The provider join (`"meta+openai+opencode-go"`) is the stable key: OpenCode is
|
|
1750
|
-
* a multi-provider harness, so "which providers are configured" is what actually
|
|
1751
|
-
* identifies an install, and `session/discover.ts` indexes sessions by it.
|
|
1752
|
-
* Providers that sign in over OAuth additionally hand OpenCode a token with real
|
|
1753
|
-
* identity claims, so the email and plan are surfaced alongside it instead of
|
|
1754
|
-
* leaving `agents view` showing a bare `id:` key for a login that knows exactly
|
|
1755
|
-
* whose it is. Providers are walked in sorted order so a multi-OAuth install
|
|
1756
|
-
* resolves to the same email on every machine.
|
|
1757
|
-
*
|
|
1758
|
-
* This is the ONLY correct source for an OpenCode "account". OpenCode's SQLite
|
|
1759
|
-
* `opencode.db` also carries `account`/`account_state`/`control_account` tables,
|
|
1760
|
-
* but on a real, actively-used install (yosemite-s1, 1.16.0, 35 applied
|
|
1761
|
-
* migrations) all three are permanently empty — no migration ever populates
|
|
1762
|
-
* them, and no session has ever written a row. Reading from them instead of
|
|
1763
|
-
* `auth.json` always yields `undefined`, credential or not.
|
|
1764
|
-
*
|
|
1765
|
-
* Sync (`fs.readFileSync`), no network. Returns undefined when `auth.json` is
|
|
1766
|
-
* missing, unreadable, or carries no valid credential.
|
|
1767
|
-
*/
|
|
1768
1183
|
export function resolveOpenCodeIdentity(base) {
|
|
1184
|
+
// auth.json, not empty SQLite account tables, is authoritative; sorted providers form the stable key.
|
|
1769
1185
|
const authPath = resolveOpenCodeAuthPath(base);
|
|
1770
1186
|
if (!authPath)
|
|
1771
1187
|
return undefined;
|
|
@@ -1793,24 +1209,11 @@ export function resolveOpenCodeIdentity(base) {
|
|
|
1793
1209
|
return undefined;
|
|
1794
1210
|
}
|
|
1795
1211
|
}
|
|
1796
|
-
/**
|
|
1797
|
-
* The provider join alone — the value `session/discover.ts` indexes sessions by,
|
|
1798
|
-
* kept as its own entry point so callers that only need the key do not have to
|
|
1799
|
-
* know about the OAuth claim walk.
|
|
1800
|
-
*/
|
|
1801
1212
|
export function resolveOpenCodeAccountId(base) {
|
|
1802
1213
|
return resolveOpenCodeIdentity(base)?.providers;
|
|
1803
1214
|
}
|
|
1804
|
-
/**
|
|
1805
|
-
* Whether a Muse Code `~/.config/muse/auth.json` document holds any usable
|
|
1806
|
-
* access token. Live shape from `muse login` (device OAuth, Muse Code 0.1.0):
|
|
1807
|
-
* { schema_version: 1, providers: { meta: { access_token, api_key, user_email, … } } }
|
|
1808
|
-
* Also accept top-level or one-level-nested tokens for older/alternate writers.
|
|
1809
|
-
* Recurses into objects so `providers.meta.access_token` is found — a flat
|
|
1810
|
-
* one-level walk only saw `providers` and reported signed-out after a successful
|
|
1811
|
-
* login (balanced then excluded the account). Never returns the secret itself.
|
|
1812
|
-
*/
|
|
1813
1215
|
function museAuthHasToken(value, depth = 0) {
|
|
1216
|
+
// Live auth nests under providers.meta; bounded recursion also accepts older nested writers.
|
|
1814
1217
|
if (depth > 4)
|
|
1815
1218
|
return false;
|
|
1816
1219
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
@@ -1826,7 +1229,6 @@ function museAuthHasToken(value, depth = 0) {
|
|
|
1826
1229
|
}
|
|
1827
1230
|
return false;
|
|
1828
1231
|
}
|
|
1829
|
-
/** Best-effort email from a Muse auth.json (providers.meta.user_email, etc.). */
|
|
1830
1232
|
function museAuthEmail(value, depth = 0) {
|
|
1831
1233
|
if (depth > 4)
|
|
1832
1234
|
return null;
|
|
@@ -1846,46 +1248,16 @@ function museAuthEmail(value, depth = 0) {
|
|
|
1846
1248
|
}
|
|
1847
1249
|
return null;
|
|
1848
1250
|
}
|
|
1849
|
-
/**
|
|
1850
|
-
* Whether a Claude version home's credential file is present but carries no
|
|
1851
|
-
* token — the "must have a real credential" floor (see
|
|
1852
|
-
* `isValidOpenCodeCredential`) applied to claude.
|
|
1853
|
-
*
|
|
1854
|
-
* A FAILED OAuth refresh leaves exactly this state behind: Claude Code rewrites
|
|
1855
|
-
* `.claude/.credentials.json` with `accessToken: ""`, `refreshToken: ""` and
|
|
1856
|
-
* `expiresAt: 0`, keeping only the descriptive fields (`subscriptionType`,
|
|
1857
|
-
* `rateLimitTier`, `refreshTokenExpiresAt`). Everything we derive from
|
|
1858
|
-
* `.claude.json` — email, plan — still looks healthy, so the install reported
|
|
1859
|
-
* `signedIn: true`, `agents view` drew usage bars for it, and balanced rotation
|
|
1860
|
-
* (whose `authValid` is just "email present") kept picking it — every pick dying
|
|
1861
|
-
* at spawn on "OAuth session expired and could not be refreshed".
|
|
1862
|
-
*
|
|
1863
|
-
* Only decidable off macOS: there the login Keychain is the canonical store and
|
|
1864
|
-
* this file is not authoritative, and probing the Keychain would raise an
|
|
1865
|
-
* authorization sheet per installed version on every `agents run` — the reason
|
|
1866
|
-
* rotation stopped calling `isClaudeAuthValid` at all. Off macOS the file IS the
|
|
1867
|
-
* only store, so a missing or token-less file is proof of signed-out — unless a
|
|
1868
|
-
* Linux setup-token (`.claude/.oauth_token`) is present, which the shim exports
|
|
1869
|
-
* as `CLAUDE_CODE_OAUTH_TOKEN` and can authenticate the run without
|
|
1870
|
-
* `.credentials.json`. `platform` is a parameter so both branches are testable
|
|
1871
|
-
* on any host.
|
|
1872
|
-
*
|
|
1873
|
-
* Sync, no Keychain, no network — safe on the `agents run` hot path.
|
|
1874
|
-
*/
|
|
1875
1251
|
export function isClaudeCredentialFileBlank(base, platform = process.platform) {
|
|
1252
|
+
// macOS uses Keychain; on Linux absence means logged out while corrupt data fails open.
|
|
1876
1253
|
if (platform === 'darwin')
|
|
1877
1254
|
return false;
|
|
1878
|
-
// A per-version setup-token is a real credential on Linux even when
|
|
1879
|
-
// `.credentials.json` was never written (the shim's `$CLAUDE_CONFIG_DIR/.oauth_token`
|
|
1880
|
-
// fallback). Treat it as signed-in so rotation does not skip a worker that
|
|
1881
|
-
// authenticates from an attached setup-token.
|
|
1882
1255
|
try {
|
|
1883
1256
|
const token = fs.readFileSync(path.join(base, '.claude', '.oauth_token'), 'utf-8').trim();
|
|
1884
1257
|
if (token.length > 0)
|
|
1885
1258
|
return false;
|
|
1886
1259
|
}
|
|
1887
1260
|
catch {
|
|
1888
|
-
/* absent — fall through to the credentials.json floor */
|
|
1889
1261
|
}
|
|
1890
1262
|
try {
|
|
1891
1263
|
const raw = fs.readFileSync(path.join(base, '.claude', '.credentials.json'), 'utf-8');
|
|
@@ -1896,30 +1268,15 @@ export function isClaudeCredentialFileBlank(base, platform = process.platform) {
|
|
|
1896
1268
|
return !nonEmpty(oauth.accessToken) && !nonEmpty(oauth.refreshToken);
|
|
1897
1269
|
}
|
|
1898
1270
|
catch (err) {
|
|
1899
|
-
// Off macOS the file IS the store. Missing it means this home cannot
|
|
1900
|
-
// authenticate (a newly installed default with leftover `.claude.json`
|
|
1901
|
-
// oauthAccount is the PHNX-2685 false-healthy case). A corrupt file is
|
|
1902
|
-
// not positive evidence of a blank credential — leave the existing
|
|
1903
|
-
// signal alone rather than declaring a working install signed out.
|
|
1904
1271
|
if (err.code === 'ENOENT')
|
|
1905
1272
|
return true;
|
|
1906
1273
|
return false;
|
|
1907
1274
|
}
|
|
1908
1275
|
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Read a Claude home's config and account identity. Returns null when the home has
|
|
1911
|
-
* no readable `.claude.json`, or has one with no `oauthAccount` (never signed in).
|
|
1912
|
-
*
|
|
1913
|
-
* Sync because the session scanner calls it once per home on a hot path, and the
|
|
1914
|
-
* file is a few KB of local JSON. No Keychain access — see `getAccountInfo`.
|
|
1915
|
-
*/
|
|
1916
1276
|
export function readClaudeHomeConfig(base) {
|
|
1917
|
-
// Claude reads/writes config at $CLAUDE_CONFIG_DIR/.claude.json when set, falling
|
|
1918
|
-
// back to $HOME/.claude.json. Our shim sets CLAUDE_CONFIG_DIR to the per-version
|
|
1919
|
-
// .claude dir, so prefer that file; fall back to home-level for versions ever
|
|
1920
|
-
// launched without the shim (IDE extension, direct binary).
|
|
1921
1277
|
const configDirFile = path.join(base, '.claude', '.claude.json');
|
|
1922
1278
|
const homeLevelFile = path.join(base, '.claude.json');
|
|
1279
|
+
// Version-home config takes precedence over the legacy home-level file.
|
|
1923
1280
|
const activeFile = fs.existsSync(configDirFile) ? configDirFile : homeLevelFile;
|
|
1924
1281
|
let config;
|
|
1925
1282
|
try {
|
|
@@ -1934,15 +1291,8 @@ export function readClaudeHomeConfig(base) {
|
|
|
1934
1291
|
const email = normalizeIdentityPart(oa.emailAddress);
|
|
1935
1292
|
let accountId = normalizeIdentityPart(oa.accountUuid);
|
|
1936
1293
|
let organizationId = normalizeIdentityPart(oa.organizationUuid);
|
|
1937
|
-
// Worker slot provisioned from a durable setup-token: only the email was
|
|
1938
|
-
// seeded on disk (seedClaudeWorkerHomeIdentity), so accountUuid/organizationUuid
|
|
1939
|
-
// are absent and both accountKey and usageKey would be null — the row reads
|
|
1940
|
-
// "not connected here" (PHNX-3940, sibling worker-identity diagnosis). Complete
|
|
1941
|
-
// the identity from the fleet-synced registry row for this email, keyed exactly
|
|
1942
|
-
// as a headed login's home carries it. Guarded on email-only so a headed home
|
|
1943
|
-
// (uuids on disk) never pays the readMeta() read, and fails CLOSED to email-only
|
|
1944
|
-
// when zero or several rows match (registeredNativeAccountForEmail never guesses).
|
|
1945
1294
|
if (email && !accountId && !organizationId) {
|
|
1295
|
+
// Email-only worker homes accept one exact registry match; ambiguity fails closed.
|
|
1946
1296
|
const registered = registeredNativeAccountForEmail(readMeta(), 'claude', email);
|
|
1947
1297
|
const parts = registered ? parseNativeIdentityKey('claude', registered.identityKey) : null;
|
|
1948
1298
|
if (parts) {
|
|
@@ -1959,6 +1309,7 @@ export function readClaudeHomeConfig(base) {
|
|
|
1959
1309
|
organizationId,
|
|
1960
1310
|
organizationName: oa.organizationName ?? null,
|
|
1961
1311
|
organizationType: oa.organizationType ?? null,
|
|
1312
|
+
// Usage is org-scoped; account routing is account+org scoped.
|
|
1962
1313
|
usageKey: buildIdentityKey('claude', [['org', organizationId]]),
|
|
1963
1314
|
accountKey: buildIdentityKey('claude', [
|
|
1964
1315
|
['account', accountId],
|
|
@@ -1968,6 +1319,7 @@ export function readClaudeHomeConfig(base) {
|
|
|
1968
1319
|
};
|
|
1969
1320
|
}
|
|
1970
1321
|
export async function getAccountInfo(agentId, home) {
|
|
1322
|
+
// Group accounts by stable provider/org identity, never display text or stale metadata.
|
|
1971
1323
|
const base = home || os.homedir();
|
|
1972
1324
|
const empty = {
|
|
1973
1325
|
accountKey: null,
|
|
@@ -1985,42 +1337,21 @@ export async function getAccountInfo(agentId, home) {
|
|
|
1985
1337
|
const configFiles = {
|
|
1986
1338
|
claude: path.join(base, '.claude.json'),
|
|
1987
1339
|
codex: path.join(base, '.codex', 'auth.json'),
|
|
1988
|
-
// OpenCode keeps every session in ONE sqlite file rather than a directory of
|
|
1989
|
-
// per-session transcripts, so the session-file walk resolveLastActive runs
|
|
1990
|
-
// for other agents finds nothing. Its mtime fallback is the right read here:
|
|
1991
|
-
// opencode.db is written on every turn, so it tracks real activity.
|
|
1992
1340
|
opencode: resolveOpenCodeXdgPath(base, 'data', 'opencode.db') ?? undefined,
|
|
1993
1341
|
};
|
|
1994
1342
|
const lastActive = resolveLastActive(agentId, base, configFiles[agentId]);
|
|
1995
1343
|
try {
|
|
1996
1344
|
switch (agentId) {
|
|
1997
1345
|
case 'claude': {
|
|
1998
|
-
// Identity extraction is shared with the session scanner's account
|
|
1999
|
-
// attribution — see readClaudeHomeConfig. A home with no readable config or
|
|
2000
|
-
// no oauthAccount is signed out, which is what the pre-refactor code
|
|
2001
|
-
// produced when JSON.parse threw or oauthAccount was absent.
|
|
2002
1346
|
const claudeHome = readClaudeHomeConfig(base);
|
|
2003
1347
|
if (!claudeHome)
|
|
2004
1348
|
return { ...empty, lastActive };
|
|
2005
1349
|
const { config: data, identity } = claudeHome;
|
|
2006
1350
|
const oa = data.oauthAccount;
|
|
2007
1351
|
const { accountId, organizationId, email, accountKey, usageKey } = identity;
|
|
2008
|
-
// Credential floor: a blanked credential file means this home cannot
|
|
2009
|
-
// authenticate, whatever `.claude.json` still says. Report it signed out
|
|
2010
|
-
// so `agents view` prompts a re-login and rotation routes around it,
|
|
2011
|
-
// instead of handing runs to an install that dies at spawn.
|
|
2012
1352
|
if (email && isClaudeCredentialFileBlank(base)) {
|
|
2013
1353
|
return { ...empty, lastActive };
|
|
2014
1354
|
}
|
|
2015
|
-
// Plan tier is derived from .claude.json's organizationType, which carries
|
|
2016
|
-
// the TRUE tier (claude_max → "Max", claude_pro → "Pro", claude_team →
|
|
2017
|
-
// "Team") and is already in-hand from the config we just read — no Keychain
|
|
2018
|
-
// prompt. billingType only distinguishes "has a Stripe subscription" and so
|
|
2019
|
-
// mislabels every Max account as "Pro"; keep it as a fallback for older
|
|
2020
|
-
// configs predating organizationType. (Reading subscriptionType from the
|
|
2021
|
-
// keychain item would force a macOS Keychain ACL prompt on every `agents
|
|
2022
|
-
// run`, so we deliberately avoid it — organizationType gives us the tier
|
|
2023
|
-
// without that cost.)
|
|
2024
1355
|
let plan = formatClaudeOrgLabel(oa?.organizationType);
|
|
2025
1356
|
if (!plan) {
|
|
2026
1357
|
if (oa?.billingType === 'stripe_subscription') {
|
|
@@ -2030,16 +1361,8 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2030
1361
|
plan = oa.billingType;
|
|
2031
1362
|
}
|
|
2032
1363
|
}
|
|
2033
|
-
// usageStatus is NOT derived from cachedExtraUsageDisabledReason. That
|
|
2034
|
-
// field reports why pay-as-you-go overage is off (out_of_credits = no
|
|
2035
|
-
// overage credits purchased; org_level_disabled = admin turned overage
|
|
2036
|
-
// off), which says nothing about whether the account is throttled — a
|
|
2037
|
-
// Pro account at 5% weekly usage with overage disabled is fully usable.
|
|
2038
|
-
// Real throttle state comes from the live usage windows; callers derive
|
|
2039
|
-
// it via deriveUsageStatusFromSnapshot(). Here we only report whether
|
|
2040
|
-
// the account is signed in at all. Overage state stays visible through
|
|
2041
|
-
// overageCredits below.
|
|
2042
1364
|
const usageStatus = email ? 'available' : null;
|
|
1365
|
+
// Overage credit display is independent of the subscription throttle status.
|
|
2043
1366
|
let overageCredits = null;
|
|
2044
1367
|
const orgId = oa?.organizationUuid;
|
|
2045
1368
|
const creditCache = orgId && data.overageCreditGrantCache?.[orgId];
|
|
@@ -2074,7 +1397,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2074
1397
|
if (!decoded)
|
|
2075
1398
|
return { ...empty, lastActive };
|
|
2076
1399
|
const email = decoded.email || null;
|
|
2077
|
-
// Plan and subscription from OpenAI auth claim
|
|
2078
1400
|
const authClaim = decoded['https://api.openai.com/auth'] || {};
|
|
2079
1401
|
const accountId = normalizeIdentityPart(authClaim.chatgpt_account_id);
|
|
2080
1402
|
const userId = normalizeIdentityPart(authClaim.chatgpt_user_id || authClaim.user_id);
|
|
@@ -2086,7 +1408,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2086
1408
|
]);
|
|
2087
1409
|
const rawPlan = authClaim.chatgpt_plan_type;
|
|
2088
1410
|
const plan = rawPlan ? rawPlan.charAt(0).toUpperCase() + rawPlan.slice(1) : null;
|
|
2089
|
-
// Subscription status: expired = out_of_credits
|
|
2090
1411
|
let usageStatus = null;
|
|
2091
1412
|
const activeUntil = authClaim.chatgpt_subscription_active_until;
|
|
2092
1413
|
if (activeUntil) {
|
|
@@ -2108,12 +1429,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2108
1429
|
};
|
|
2109
1430
|
}
|
|
2110
1431
|
case 'cursor': {
|
|
2111
|
-
// Cursor CLI keeps account metadata in ~/.cursor/cli-config.json
|
|
2112
|
-
// (authInfo: { email, userId, authId }) and its OAuth tokens SEPARATELY
|
|
2113
|
-
// in ~/.cursor/auth.json ({ accessToken, refreshToken }). Presence
|
|
2114
|
-
// of an access token is the signed-in signal; email/ids come from
|
|
2115
|
-
// cli-config. authId is the OAuth subject (e.g. "google-oauth2|<n>") — the
|
|
2116
|
-
// same value the usage endpoint keys on (see getCursorUsageInfo).
|
|
2117
1432
|
const cfgPath = resolveAccountCredentialPath(base, '.cursor', 'cli-config.json');
|
|
2118
1433
|
if (!cfgPath)
|
|
2119
1434
|
return { ...empty, lastActive };
|
|
@@ -2131,11 +1446,8 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2131
1446
|
const tok = JSON.parse(fs.readFileSync(authPath, 'utf-8'));
|
|
2132
1447
|
hasToken = typeof tok?.accessToken === 'string' && tok.accessToken.length > 0;
|
|
2133
1448
|
}
|
|
2134
|
-
catch {
|
|
1449
|
+
catch { }
|
|
2135
1450
|
}
|
|
2136
|
-
// cli-config survives logout and may describe a different keychain
|
|
2137
|
-
// account. Without this version's file token, its identity is stale
|
|
2138
|
-
// metadata rather than a usable managed login.
|
|
2139
1451
|
if (!hasToken)
|
|
2140
1452
|
return { ...empty, lastActive };
|
|
2141
1453
|
const accountKey = buildIdentityKey(agentId, [['user', accountId]]);
|
|
@@ -2145,13 +1457,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2145
1457
|
return { ...empty, lastActive };
|
|
2146
1458
|
}
|
|
2147
1459
|
case 'grok': {
|
|
2148
|
-
// Grok stores auth in ~/.grok/auth.json as a map keyed by
|
|
2149
|
-
// "<oidc_issuer>::<client_id>" -> { email, user_id, refresh_token,
|
|
2150
|
-
// create_time, expires_at, team_id, ... }. (Older builds wrote a flat
|
|
2151
|
-
// object with a top-level email.) The old code only read a TOP-LEVEL
|
|
2152
|
-
// `email`, so the current nested format always looked signed-out even
|
|
2153
|
-
// when logged in. Read the newest account record: a refresh token means
|
|
2154
|
-
// signed in, and we surface the email/ids like claude/codex.
|
|
2155
1460
|
const authPath = resolveAccountCredentialPath(base, '.grok', 'auth.json');
|
|
2156
1461
|
if (!authPath)
|
|
2157
1462
|
return { ...empty, lastActive };
|
|
@@ -2174,40 +1479,21 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2174
1479
|
return { ...empty, lastActive };
|
|
2175
1480
|
}
|
|
2176
1481
|
case 'antigravity': {
|
|
2177
|
-
// Antigravity (`agy`) stores a consumer Google OAuth grant (access +
|
|
2178
|
-
// refresh token, no id_token) — presence of a refresh token is the only
|
|
2179
|
-
// signed-in signal we can derive without a network call. Storage is
|
|
2180
|
-
// platform-split via go-keyring:
|
|
2181
|
-
// - file ~/.gemini/antigravity-cli/antigravity-oauth-token (Linux
|
|
2182
|
-
// fallback when no Secret Service is available)
|
|
2183
|
-
// - macOS keychain / Linux libsecret (service gemini + user
|
|
2184
|
-
// antigravity) when a keyring daemon is present
|
|
2185
|
-
// Check the file first, then the OS keyring probe.
|
|
2186
1482
|
const tokenPath = resolveAccountCredentialPath(base, '.gemini', 'antigravity-cli', 'antigravity-oauth-token');
|
|
2187
1483
|
if (tokenPath) {
|
|
2188
1484
|
const data = JSON.parse(await fs.promises.readFile(tokenPath, 'utf-8'));
|
|
2189
1485
|
if (typeof data?.token?.refresh_token === 'string' && data.token.refresh_token) {
|
|
2190
|
-
// A stable account/usage key (derived from the refresh token — see
|
|
2191
|
-
// readAuthAccountIdentity) lets `agents view` dedupe and cache the
|
|
2192
|
-
// per-model quota bars for this login.
|
|
2193
1486
|
const identity = readAuthAccountIdentity('antigravity', path.dirname(tokenPath));
|
|
2194
1487
|
return { ...empty, signedIn: true, lastActive, accountKey: identity, usageKey: identity };
|
|
2195
1488
|
}
|
|
2196
1489
|
}
|
|
2197
1490
|
if (await antigravityKeychainSignedIn()) {
|
|
2198
|
-
// Keyring-only login (the macOS case): the OS keyring holds exactly
|
|
2199
|
-
// ONE antigravity credential, so a stable singleton key identifies it
|
|
2200
|
-
// for usage-cache dedup without reading the secret value here.
|
|
2201
1491
|
const identity = buildIdentityKey('antigravity', [['sub', 'keychain']]);
|
|
2202
1492
|
return { ...empty, signedIn: true, lastActive, accountKey: identity, usageKey: identity };
|
|
2203
1493
|
}
|
|
2204
1494
|
return { ...empty, lastActive };
|
|
2205
1495
|
}
|
|
2206
1496
|
case 'kimi': {
|
|
2207
|
-
// Kimi Code stores OAuth credentials at
|
|
2208
|
-
// ~/.kimi-code/credentials/kimi-code.json. The access token is a JWT
|
|
2209
|
-
// whose payload carries an opaque user_id (no email), so we report
|
|
2210
|
-
// signed-in state plus a stable account key for usage dedup.
|
|
2211
1497
|
const credPath = resolveAccountCredentialPath(base, '.kimi-code', 'credentials', 'kimi-code.json');
|
|
2212
1498
|
if (!credPath)
|
|
2213
1499
|
return { ...empty, lastActive };
|
|
@@ -2221,15 +1507,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2221
1507
|
return { ...empty, signedIn: true, accountId: userId, accountKey, lastActive };
|
|
2222
1508
|
}
|
|
2223
1509
|
case 'droid': {
|
|
2224
|
-
// Factory Droid stores auth at ~/.factory/auth.v2.file (AES-256-GCM,
|
|
2225
|
-
// decrypted with the on-disk ~/.factory/auth.v2.key). We decrypt locally
|
|
2226
|
-
// — no network — and surface the email/org/role from the WorkOS
|
|
2227
|
-
// access-token JWT, same as claude/codex/grok. If the credential can't be
|
|
2228
|
-
// decrypted (a keyring-v2/legacy login with no on-disk key, or a decrypt
|
|
2229
|
-
// failure) we fall back to the file-presence signed-in signal so the row
|
|
2230
|
-
// still reads as logged in — the conservative floor antigravity/kimi use.
|
|
2231
|
-
// `.factory` is the config dir on every platform (macOS/Linux
|
|
2232
|
-
// ~/.factory, Windows %USERPROFILE%\.factory).
|
|
2233
1510
|
const decoded = decryptDroidCredential(base);
|
|
2234
1511
|
if (decoded?.email) {
|
|
2235
1512
|
const organizationId = decoded.orgId;
|
|
@@ -2244,24 +1521,16 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2244
1521
|
lastActive,
|
|
2245
1522
|
};
|
|
2246
1523
|
}
|
|
1524
|
+
// An unreadable encrypted payload still counts conservatively when its auth file exists.
|
|
2247
1525
|
const authPath = resolveAccountCredentialPath(base, '.factory', 'auth.v2.file');
|
|
2248
1526
|
if (!authPath)
|
|
2249
1527
|
return { ...empty, lastActive };
|
|
2250
1528
|
return { ...empty, signedIn: true, lastActive };
|
|
2251
1529
|
}
|
|
2252
1530
|
case 'opencode': {
|
|
2253
|
-
// OpenCode's auth.json is a record keyed by provider id ->
|
|
2254
|
-
// { type: 'oauth'|'api'|'wellknown', ...secret fields }. The provider
|
|
2255
|
-
// join is the identity key (see resolveOpenCodeIdentity), and an OAuth
|
|
2256
|
-
// provider's token additionally carries the real account email and plan
|
|
2257
|
-
// — so the row shows who is signed in rather than only a bare `id:` key.
|
|
2258
|
-
// Secrets are never read out; only JWT claims are.
|
|
2259
1531
|
const identity = resolveOpenCodeIdentity(base);
|
|
2260
1532
|
if (!identity)
|
|
2261
1533
|
return { ...empty, lastActive };
|
|
2262
|
-
// Keyed on providers, not email: OpenCode bills through whichever
|
|
2263
|
-
// provider credentials are configured, so two installs sharing one
|
|
2264
|
-
// email but different provider sets are genuinely different accounts.
|
|
2265
1534
|
const accountKey = buildIdentityKey(agentId, [['providers', identity.providers]]);
|
|
2266
1535
|
return {
|
|
2267
1536
|
...empty,
|
|
@@ -2274,9 +1543,6 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2274
1543
|
};
|
|
2275
1544
|
}
|
|
2276
1545
|
case 'muse': {
|
|
2277
|
-
// Muse Code authenticates with META_API_KEY (env, highest priority) or
|
|
2278
|
-
// a stored OAuth/API credential at ~/.config/muse/auth.json. Live file
|
|
2279
|
-
// shape nests under providers.meta (access_token + optional user_email).
|
|
2280
1546
|
if (process.env.META_API_KEY?.trim() || process.env.MODEL_API_KEY?.trim()) {
|
|
2281
1547
|
const accountKey = buildIdentityKey(agentId, [['auth', 'env']]);
|
|
2282
1548
|
return { ...empty, signedIn: true, accountId: 'env', accountKey, lastActive };
|
|
@@ -2305,24 +1571,11 @@ export async function getAccountInfo(agentId, home) {
|
|
|
2305
1571
|
}
|
|
2306
1572
|
}
|
|
2307
1573
|
catch {
|
|
2308
|
-
/* auth/config file missing or unreadable */
|
|
2309
1574
|
return { ...empty, lastActive };
|
|
2310
1575
|
}
|
|
2311
1576
|
}
|
|
2312
|
-
// Fresh window for the cached session walk. Matches USAGE_CACHE_FRESH_MS in
|
|
2313
|
-
// usage.ts (5 minutes) so a launch storm reuses both probes for the same period.
|
|
2314
1577
|
const LAST_ACTIVE_CACHE_FRESH_MS = 5 * 60 * 1000;
|
|
2315
1578
|
const getLastActiveCachePath = () => path.join(getCacheDir(), 'last-active.json');
|
|
2316
|
-
/**
|
|
2317
|
-
* Determine when the agent was last used by checking session file mtimes,
|
|
2318
|
-
* falling back to config mtime.
|
|
2319
|
-
*
|
|
2320
|
-
* The session walk stats every transcript under the home's session dir —
|
|
2321
|
-
* thousands of files on long-lived installs — and `agents run` rotation calls
|
|
2322
|
-
* this once per installed version on every launch. The walk result is cached
|
|
2323
|
-
* on disk for a short window so back-to-back launches skip it entirely.
|
|
2324
|
-
* Cache read/write is best-effort: any failure falls back to walking.
|
|
2325
|
-
*/
|
|
2326
1579
|
export function resolveLastActive(agentId, base, configPath, cachePath = getLastActiveCachePath(), now = new Date()) {
|
|
2327
1580
|
const sessionDir = getSessionDir(agentId, base);
|
|
2328
1581
|
const sessionExt = getSessionExtension(agentId);
|
|
@@ -2337,14 +1590,10 @@ export function resolveLastActive(agentId, base, configPath, cachePath = getLast
|
|
|
2337
1590
|
if (fresh) {
|
|
2338
1591
|
if (entry.mtimeMs !== null)
|
|
2339
1592
|
return new Date(entry.mtimeMs);
|
|
2340
|
-
// Fresh entry with no sessions: fall through to the config mtime below.
|
|
2341
1593
|
}
|
|
2342
1594
|
else {
|
|
2343
1595
|
const mtimeMs = latestFileMtimeMs(sessionDir, sessionExt);
|
|
2344
1596
|
cache[key] = { mtimeMs, computedAt: now.getTime() };
|
|
2345
|
-
// Stale entries are never served, so drop them on write — keeps homes
|
|
2346
|
-
// that no longer exist (removed versions, test temp dirs) from
|
|
2347
|
-
// accumulating in the file.
|
|
2348
1597
|
for (const [k, v] of Object.entries(cache)) {
|
|
2349
1598
|
if (k !== key && !(typeof v?.computedAt === 'number' && now.getTime() - v.computedAt < LAST_ACTIVE_CACHE_FRESH_MS)) {
|
|
2350
1599
|
delete cache[k];
|
|
@@ -2364,7 +1613,6 @@ export function resolveLastActive(agentId, base, configPath, cachePath = getLast
|
|
|
2364
1613
|
return null;
|
|
2365
1614
|
}
|
|
2366
1615
|
}
|
|
2367
|
-
/** Read the entire last-active cache file. Missing or corrupt file reads as empty. */
|
|
2368
1616
|
function readLastActiveCacheFile(cachePath) {
|
|
2369
1617
|
if (!fs.existsSync(cachePath))
|
|
2370
1618
|
return {};
|
|
@@ -2376,29 +1624,21 @@ function readLastActiveCacheFile(cachePath) {
|
|
|
2376
1624
|
return {};
|
|
2377
1625
|
}
|
|
2378
1626
|
}
|
|
2379
|
-
/** Write the entire last-active cache. Best-effort; a failed write just means the next call walks again. */
|
|
2380
1627
|
function writeLastActiveCacheFile(cache, cachePath) {
|
|
2381
1628
|
try {
|
|
2382
1629
|
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
2383
1630
|
fs.writeFileSync(cachePath, JSON.stringify(cache), 'utf-8');
|
|
2384
1631
|
}
|
|
2385
1632
|
catch {
|
|
2386
|
-
/* best-effort */
|
|
2387
1633
|
}
|
|
2388
1634
|
}
|
|
2389
|
-
/** Return the root directory where the agent stores session files, or null if unknown. */
|
|
2390
1635
|
function getSessionDir(agentId, base) {
|
|
2391
1636
|
const rel = AGENTS[agentId].sessionDir;
|
|
2392
1637
|
return rel ? path.join(base, ...rel) : null;
|
|
2393
1638
|
}
|
|
2394
|
-
/** Return the file extension used for session files by the given agent. */
|
|
2395
1639
|
function getSessionExtension(agentId) {
|
|
2396
1640
|
return AGENTS[agentId].sessionFileExt;
|
|
2397
1641
|
}
|
|
2398
|
-
/**
|
|
2399
|
-
* Quick count of session files for an agent (without full DB scan).
|
|
2400
|
-
* Used during init to show approximate session count to user.
|
|
2401
|
-
*/
|
|
2402
1642
|
export function countSessionFiles(agentId) {
|
|
2403
1643
|
const sessionDir = getSessionDir(agentId, HOME);
|
|
2404
1644
|
const ext = getSessionExtension(agentId);
|
|
@@ -2418,13 +1658,11 @@ export function countSessionFiles(agentId) {
|
|
|
2418
1658
|
}
|
|
2419
1659
|
}
|
|
2420
1660
|
catch {
|
|
2421
|
-
// Permission denied or other error
|
|
2422
1661
|
}
|
|
2423
1662
|
};
|
|
2424
1663
|
walk(sessionDir);
|
|
2425
1664
|
return count;
|
|
2426
1665
|
}
|
|
2427
|
-
/** Decode the payload section of a JWT token without verifying its signature. */
|
|
2428
1666
|
export function decodeJwtPayload(token) {
|
|
2429
1667
|
const payload = token.split('.')[1];
|
|
2430
1668
|
if (!payload)
|
|
@@ -2436,7 +1674,6 @@ export function decodeJwtPayload(token) {
|
|
|
2436
1674
|
return null;
|
|
2437
1675
|
}
|
|
2438
1676
|
}
|
|
2439
|
-
/** Extract the default organization ID from a Codex/OpenAI auth claim. */
|
|
2440
1677
|
function getCodexDefaultOrgId(authClaim) {
|
|
2441
1678
|
const organizations = authClaim?.organizations;
|
|
2442
1679
|
if (!Array.isArray(organizations))
|
|
@@ -2444,14 +1681,12 @@ function getCodexDefaultOrgId(authClaim) {
|
|
|
2444
1681
|
const first = organizations[0];
|
|
2445
1682
|
return typeof first?.id === 'string' ? first.id : null;
|
|
2446
1683
|
}
|
|
2447
|
-
/** Trim and normalize an identity string, returning null for empty or non-string values. */
|
|
2448
1684
|
function normalizeIdentityPart(value) {
|
|
2449
1685
|
if (typeof value !== 'string')
|
|
2450
1686
|
return null;
|
|
2451
1687
|
const trimmed = value.trim();
|
|
2452
1688
|
return trimmed || null;
|
|
2453
1689
|
}
|
|
2454
|
-
/** Build a composite identity key like "claude:account=abc:org=xyz" from labeled parts. */
|
|
2455
1690
|
function buildIdentityKey(agentId, parts) {
|
|
2456
1691
|
const encoded = parts
|
|
2457
1692
|
.filter(([, value]) => value)
|
|
@@ -2460,7 +1695,6 @@ function buildIdentityKey(agentId, parts) {
|
|
|
2460
1695
|
return null;
|
|
2461
1696
|
return `${agentId}:${encoded.join(':')}`;
|
|
2462
1697
|
}
|
|
2463
|
-
/** Register an MCP server with an agent's CLI via `mcp add`. */
|
|
2464
1698
|
export async function registerMcp(agentId, name, command, scope = 'user', transport = 'stdio', options) {
|
|
2465
1699
|
const agent = AGENTS[agentId];
|
|
2466
1700
|
if (!supports(agentId, 'mcp').ok) {
|
|
@@ -2485,7 +1719,6 @@ export async function registerMcp(agentId, name, command, scope = 'user', transp
|
|
|
2485
1719
|
return { success: false, error: 'CLI not installed' };
|
|
2486
1720
|
}
|
|
2487
1721
|
try {
|
|
2488
|
-
// Use explicit binary path when provided (bypasses shim for version-managed agents)
|
|
2489
1722
|
const bin = options?.binary || agent.cliCommand;
|
|
2490
1723
|
let args;
|
|
2491
1724
|
if (transport === 'http') {
|
|
@@ -2505,13 +1738,7 @@ export async function registerMcp(agentId, name, command, scope = 'user', transp
|
|
|
2505
1738
|
const commandArgs = splitCommandLine(command);
|
|
2506
1739
|
args = ['mcp', 'add', name, '--', ...commandArgs];
|
|
2507
1740
|
}
|
|
2508
|
-
// When home is specified, override HOME so MCP config writes to the version's config dir
|
|
2509
1741
|
const env = options?.home ? { ...process.env, HOME: options.home } : undefined;
|
|
2510
|
-
// On Windows a bare command name / `.cmd` wrapper (the npm-installed agent
|
|
2511
|
-
// CLI) can't be exec'd directly — it needs shell:true for PATHEXT/cmd. Off
|
|
2512
|
-
// Windows this is always false, so the no-shell argv path is unchanged.
|
|
2513
|
-
// RUSH-1752: when shell is needed, compose a fully-quoted command line and
|
|
2514
|
-
// pass EMPTY argv so user-controlled MCP command/args never reach cmd.exe unescaped.
|
|
2515
1742
|
const spec = execFileShellSpec(bin, args);
|
|
2516
1743
|
await execFileAsync(spec.command, spec.args, { ...(env ? { env } : {}), shell: spec.shell });
|
|
2517
1744
|
return { success: true };
|
|
@@ -2520,7 +1747,6 @@ export async function registerMcp(agentId, name, command, scope = 'user', transp
|
|
|
2520
1747
|
return { success: false, error: err.message };
|
|
2521
1748
|
}
|
|
2522
1749
|
}
|
|
2523
|
-
/** Unregister (remove) a named MCP server from an agent's CLI config. */
|
|
2524
1750
|
export async function unregisterMcp(agentId, name, options) {
|
|
2525
1751
|
const agent = AGENTS[agentId];
|
|
2526
1752
|
if (!supports(agentId, 'mcp').ok) {
|
|
@@ -2540,9 +1766,8 @@ export async function unregisterMcp(agentId, name, options) {
|
|
|
2540
1766
|
}
|
|
2541
1767
|
try {
|
|
2542
1768
|
const bin = options?.binary || agent.cliCommand;
|
|
1769
|
+
// HOME selects the version-owned MCP config for CLI-backed removal.
|
|
2543
1770
|
const env = options?.home ? { ...process.env, HOME: options.home } : undefined;
|
|
2544
|
-
// RUSH-1752: same shell-safe path as registerMcp — attacker-controlled MCP
|
|
2545
|
-
// `name` must not reach cmd.exe unescaped when shell:true is required.
|
|
2546
1771
|
const spec = execFileShellSpec(bin, ['mcp', 'remove', name]);
|
|
2547
1772
|
await execFileAsync(spec.command, spec.args, { ...(env ? { env } : {}), shell: spec.shell });
|
|
2548
1773
|
return { success: true };
|
|
@@ -2551,10 +1776,6 @@ export async function unregisterMcp(agentId, name, options) {
|
|
|
2551
1776
|
return { success: false, error: err.message };
|
|
2552
1777
|
}
|
|
2553
1778
|
}
|
|
2554
|
-
/**
|
|
2555
|
-
* Register an MCP server across multiple agent targets, including both direct
|
|
2556
|
-
* (non-version-managed) agents and specific version-managed installs.
|
|
2557
|
-
*/
|
|
2558
1779
|
export async function registerMcpToTargets(targets, name, command, scope = 'user', transport = 'stdio', options = {}) {
|
|
2559
1780
|
const results = [];
|
|
2560
1781
|
for (const agentId of targets.directAgents) {
|
|
@@ -2573,10 +1794,6 @@ export async function registerMcpToTargets(targets, name, command, scope = 'user
|
|
|
2573
1794
|
}
|
|
2574
1795
|
return results;
|
|
2575
1796
|
}
|
|
2576
|
-
/**
|
|
2577
|
-
* Unregister an MCP server from multiple agent targets, including both direct
|
|
2578
|
-
* agents and specific version-managed installs.
|
|
2579
|
-
*/
|
|
2580
1797
|
export async function unregisterMcpFromTargets(targets, name) {
|
|
2581
1798
|
const results = [];
|
|
2582
1799
|
for (const agentId of targets.directAgents) {
|
|
@@ -2674,19 +1891,10 @@ function removeMcpFromConfig(agentId, name, home) {
|
|
|
2674
1891
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
2675
1892
|
}
|
|
2676
1893
|
}
|
|
2677
|
-
/**
|
|
2678
|
-
* Extract version from npm package specification.
|
|
2679
|
-
* Examples: @scope/package@latest -> latest
|
|
2680
|
-
* @scope/package@1.2.3 -> 1.2.3
|
|
2681
|
-
* some-package -> undefined
|
|
2682
|
-
*/
|
|
2683
1894
|
function extractNpmVersion(args) {
|
|
2684
|
-
// Find npm package argument (looks like @scope/package@version or package@version)
|
|
2685
1895
|
for (const arg of args) {
|
|
2686
|
-
// Match @scope/package@version or package@version
|
|
2687
1896
|
const match = arg.match(/@([^@]+)$|^([^@]+)@(.+)$/);
|
|
2688
1897
|
if (match) {
|
|
2689
|
-
// @scope/package@version pattern
|
|
2690
1898
|
const versionMatch = arg.match(/@([^@/]+)$/);
|
|
2691
1899
|
if (versionMatch) {
|
|
2692
1900
|
return versionMatch[1];
|
|
@@ -2695,16 +1903,8 @@ function extractNpmVersion(args) {
|
|
|
2695
1903
|
}
|
|
2696
1904
|
return undefined;
|
|
2697
1905
|
}
|
|
2698
|
-
/**
|
|
2699
|
-
* Strip JSON comments for JSONC parsing.
|
|
2700
|
-
* Only removes comments outside of strings.
|
|
2701
|
-
*
|
|
2702
|
-
* Exported because the MCP writer needs the SAME parser the reader uses: a
|
|
2703
|
-
* naive `//`-to-end-of-line regex eats the `//` inside
|
|
2704
|
-
* `"$schema": "https://opencode.ai/config.json"`, which every opencode-generated
|
|
2705
|
-
* config carries.
|
|
2706
|
-
*/
|
|
2707
1906
|
export function stripJsonComments(content) {
|
|
1907
|
+
// Strip comments only outside strings so schema and MCP URLs survive JSONC parsing.
|
|
2708
1908
|
let result = '';
|
|
2709
1909
|
let inString = false;
|
|
2710
1910
|
let escape = false;
|
|
@@ -2731,21 +1931,18 @@ export function stripJsonComments(content) {
|
|
|
2731
1931
|
continue;
|
|
2732
1932
|
}
|
|
2733
1933
|
if (!inString) {
|
|
2734
|
-
// Check for single-line comment
|
|
2735
1934
|
if (char === '/' && next === '/') {
|
|
2736
|
-
// Skip until end of line
|
|
2737
1935
|
while (i < content.length && content[i] !== '\n') {
|
|
2738
1936
|
i++;
|
|
2739
1937
|
}
|
|
2740
1938
|
continue;
|
|
2741
1939
|
}
|
|
2742
|
-
// Check for multi-line comment
|
|
2743
1940
|
if (char === '/' && next === '*') {
|
|
2744
1941
|
i += 2;
|
|
2745
1942
|
while (i < content.length && !(content[i] === '*' && content[i + 1] === '/')) {
|
|
2746
1943
|
i++;
|
|
2747
1944
|
}
|
|
2748
|
-
i += 2;
|
|
1945
|
+
i += 2;
|
|
2749
1946
|
continue;
|
|
2750
1947
|
}
|
|
2751
1948
|
}
|
|
@@ -2754,32 +1951,22 @@ export function stripJsonComments(content) {
|
|
|
2754
1951
|
}
|
|
2755
1952
|
return result;
|
|
2756
1953
|
}
|
|
2757
|
-
/**
|
|
2758
|
-
* Parse MCP servers from a JSON/JSONC config file.
|
|
2759
|
-
*/
|
|
2760
1954
|
function parseMcpFromJsonConfig(configPath) {
|
|
2761
1955
|
if (!fs.existsSync(configPath)) {
|
|
2762
1956
|
return {};
|
|
2763
1957
|
}
|
|
2764
1958
|
try {
|
|
2765
1959
|
let content = fs.readFileSync(configPath, 'utf-8');
|
|
2766
|
-
// Handle JSONC (JSON with comments)
|
|
2767
1960
|
if (configPath.endsWith('.jsonc')) {
|
|
2768
1961
|
content = stripJsonComments(content);
|
|
2769
1962
|
}
|
|
2770
1963
|
const config = JSON.parse(content);
|
|
2771
|
-
// Claude uses mcpServers, others may use mcp_servers or mcp
|
|
2772
1964
|
return config.mcpServers || config.mcp_servers || config.mcp || {};
|
|
2773
1965
|
}
|
|
2774
1966
|
catch {
|
|
2775
|
-
/* JSON config corrupt or unreadable */
|
|
2776
1967
|
return {};
|
|
2777
1968
|
}
|
|
2778
1969
|
}
|
|
2779
|
-
/**
|
|
2780
|
-
* Parse MCP servers from a TOML config file (Codex).
|
|
2781
|
-
* Codex stores MCPs as [mcp_servers.ServerName] sections.
|
|
2782
|
-
*/
|
|
2783
1970
|
function parseMcpFromTomlConfig(configPath) {
|
|
2784
1971
|
if (!fs.existsSync(configPath)) {
|
|
2785
1972
|
return {};
|
|
@@ -2787,12 +1974,10 @@ function parseMcpFromTomlConfig(configPath) {
|
|
|
2787
1974
|
try {
|
|
2788
1975
|
const content = fs.readFileSync(configPath, 'utf-8');
|
|
2789
1976
|
const config = TOML.parse(content);
|
|
2790
|
-
// Codex uses mcp_servers as a table with server names as keys
|
|
2791
1977
|
const mcpServers = config.mcp_servers;
|
|
2792
1978
|
return mcpServers || {};
|
|
2793
1979
|
}
|
|
2794
1980
|
catch {
|
|
2795
|
-
/* TOML config corrupt or unreadable */
|
|
2796
1981
|
return {};
|
|
2797
1982
|
}
|
|
2798
1983
|
}
|
|
@@ -2806,14 +1991,9 @@ function parseMcpFromYamlConfig(configPath) {
|
|
|
2806
1991
|
return mcpServers || {};
|
|
2807
1992
|
}
|
|
2808
1993
|
catch {
|
|
2809
|
-
/* YAML config corrupt or unreadable */
|
|
2810
1994
|
return {};
|
|
2811
1995
|
}
|
|
2812
1996
|
}
|
|
2813
|
-
/**
|
|
2814
|
-
* Parse MCP servers from OpenCode's JSONC config.
|
|
2815
|
-
* OpenCode stores MCPs in the "mcp" object with different structure.
|
|
2816
|
-
*/
|
|
2817
1997
|
function parseMcpFromOpenCodeConfig(configPath) {
|
|
2818
1998
|
if (!fs.existsSync(configPath)) {
|
|
2819
1999
|
return {};
|
|
@@ -2824,18 +2004,15 @@ function parseMcpFromOpenCodeConfig(configPath) {
|
|
|
2824
2004
|
const mcpConfig = config.mcp;
|
|
2825
2005
|
if (!mcpConfig)
|
|
2826
2006
|
return {};
|
|
2827
|
-
// Convert OpenCode format to our McpConfigEntry format
|
|
2828
2007
|
const result = {};
|
|
2829
2008
|
for (const [name, entry] of Object.entries(mcpConfig)) {
|
|
2830
2009
|
if (entry.type === 'local' && entry.command) {
|
|
2831
|
-
// Local MCP: command is an array like ["npx", "-y", "@pkg@version"]
|
|
2832
2010
|
result[name] = {
|
|
2833
2011
|
command: entry.command[0],
|
|
2834
2012
|
args: entry.command.slice(1),
|
|
2835
2013
|
};
|
|
2836
2014
|
}
|
|
2837
2015
|
else if (entry.type === 'remote' && entry.url) {
|
|
2838
|
-
// Remote MCP: HTTP URL
|
|
2839
2016
|
result[name] = {
|
|
2840
2017
|
url: entry.url,
|
|
2841
2018
|
};
|
|
@@ -2844,43 +2021,24 @@ function parseMcpFromOpenCodeConfig(configPath) {
|
|
|
2844
2021
|
return result;
|
|
2845
2022
|
}
|
|
2846
2023
|
catch {
|
|
2847
|
-
/* OpenCode JSONC config corrupt or unreadable */
|
|
2848
2024
|
return {};
|
|
2849
2025
|
}
|
|
2850
2026
|
}
|
|
2851
|
-
/**
|
|
2852
|
-
* Get user-scoped MCP config path for an agent.
|
|
2853
|
-
*
|
|
2854
|
-
* All three MCP path resolvers read `MCP_TARGETS`, so the file the writer
|
|
2855
|
-
* targets, the file the parser reads, and the file the staleness detector
|
|
2856
|
-
* watches cannot drift apart. An agent with no MCP target keeps the historical
|
|
2857
|
-
* settings.json default so old configs still parse.
|
|
2858
|
-
*/
|
|
2859
2027
|
export function getUserMcpConfigPath(agentId) {
|
|
2860
2028
|
return getMcpConfigPathForHome(agentId, HOME);
|
|
2861
2029
|
}
|
|
2862
|
-
/**
|
|
2863
|
-
* Get MCP config path for a specific HOME directory (used for version-managed agents).
|
|
2864
|
-
*/
|
|
2865
2030
|
export function getMcpConfigPathForHome(agentId, home) {
|
|
2866
2031
|
const target = MCP_TARGETS[agentId];
|
|
2867
2032
|
if (target)
|
|
2868
2033
|
return target.home(home);
|
|
2869
2034
|
return path.join(home, agentConfigDirName(agentId), 'settings.json');
|
|
2870
2035
|
}
|
|
2871
|
-
/**
|
|
2872
|
-
* Get project-scoped MCP config path for an agent.
|
|
2873
|
-
*/
|
|
2874
2036
|
export function getProjectMcpConfigPath(agentId, cwd = process.cwd()) {
|
|
2875
2037
|
const target = MCP_TARGETS[agentId];
|
|
2876
2038
|
if (target)
|
|
2877
2039
|
return target.project(cwd);
|
|
2878
2040
|
return path.join(cwd, `.${agentId}`, 'settings.json');
|
|
2879
2041
|
}
|
|
2880
|
-
/**
|
|
2881
|
-
* Parse MCP servers from OpenClaw's JSON config.
|
|
2882
|
-
* OpenClaw stores MCPs under mcp.servers with a similar structure to other agents.
|
|
2883
|
-
*/
|
|
2884
2042
|
function parseMcpFromOpenClawConfig(configPath) {
|
|
2885
2043
|
if (!fs.existsSync(configPath)) {
|
|
2886
2044
|
return {};
|
|
@@ -2888,7 +2046,6 @@ function parseMcpFromOpenClawConfig(configPath) {
|
|
|
2888
2046
|
try {
|
|
2889
2047
|
const content = fs.readFileSync(configPath, 'utf-8');
|
|
2890
2048
|
const config = JSON.parse(content);
|
|
2891
|
-
// OpenClaw uses mcp.servers for MCP configuration
|
|
2892
2049
|
const mcpServers = config.mcp?.servers;
|
|
2893
2050
|
if (!mcpServers)
|
|
2894
2051
|
return {};
|
|
@@ -2911,17 +2068,10 @@ function parseMcpFromOpenClawConfig(configPath) {
|
|
|
2911
2068
|
return result;
|
|
2912
2069
|
}
|
|
2913
2070
|
catch {
|
|
2914
|
-
/* OpenClaw JSON config corrupt or unreadable */
|
|
2915
2071
|
return {};
|
|
2916
2072
|
}
|
|
2917
2073
|
}
|
|
2918
|
-
/**
|
|
2919
|
-
* Parse MCP config based on agent type.
|
|
2920
|
-
*/
|
|
2921
2074
|
export function parseMcpConfig(agentId, configPath) {
|
|
2922
|
-
// Dispatch on the registry's declared format, not the agent id, so the parser
|
|
2923
|
-
// can never disagree with the writer about a file's serialization -- grok's
|
|
2924
|
-
// TOML config was previously read as JSON and always came back empty.
|
|
2925
2075
|
switch (MCP_TARGETS[agentId]?.format) {
|
|
2926
2076
|
case 'toml':
|
|
2927
2077
|
return parseMcpFromTomlConfig(configPath);
|
|
@@ -2932,26 +2082,17 @@ export function parseMcpConfig(agentId, configPath) {
|
|
|
2932
2082
|
case 'yaml':
|
|
2933
2083
|
return parseMcpFromYamlConfig(configPath);
|
|
2934
2084
|
default:
|
|
2935
|
-
// claude-json / antigravity-json / muse-json all live in a JSON object;
|
|
2936
|
-
// parseMcpFromJsonConfig accepts mcpServers | mcp_servers | mcp. Agents
|
|
2937
|
-
// with no declared format fall here too, matching prior behavior.
|
|
2938
2085
|
return parseMcpFromJsonConfig(configPath);
|
|
2939
2086
|
}
|
|
2940
2087
|
}
|
|
2941
|
-
/**
|
|
2942
|
-
* List installed MCP servers with scope information.
|
|
2943
|
-
* Pass options.home to read from a version-managed agent's home directory.
|
|
2944
|
-
*/
|
|
2945
2088
|
export function listInstalledMcpsWithScope(agentId, cwd = process.cwd(), options) {
|
|
2946
2089
|
const results = [];
|
|
2947
|
-
// Helper to build full command string
|
|
2948
2090
|
const buildCommand = (config) => {
|
|
2949
2091
|
if (config.command && config.args?.length) {
|
|
2950
2092
|
return `${config.command} ${config.args.join(' ')}`;
|
|
2951
2093
|
}
|
|
2952
2094
|
return config.command || (config.args ? config.args.join(' ') : undefined);
|
|
2953
2095
|
};
|
|
2954
|
-
// User-scoped MCPs (version-aware when home is provided)
|
|
2955
2096
|
const userConfigPath = options?.home
|
|
2956
2097
|
? getMcpConfigPathForHome(agentId, options.home)
|
|
2957
2098
|
: getUserMcpConfigPath(agentId);
|
|
@@ -2964,11 +2105,9 @@ export function listInstalledMcpsWithScope(agentId, cwd = process.cwd(), options
|
|
|
2964
2105
|
version: config.args ? extractNpmVersion(config.args) : undefined,
|
|
2965
2106
|
});
|
|
2966
2107
|
}
|
|
2967
|
-
// Project-scoped MCPs
|
|
2968
2108
|
const projectConfigPath = getProjectMcpConfigPath(agentId, cwd);
|
|
2969
2109
|
const projectMcps = parseMcpConfig(agentId, projectConfigPath);
|
|
2970
2110
|
for (const [name, config] of Object.entries(projectMcps)) {
|
|
2971
|
-
// Skip if already in user scope (project can override, but we show both)
|
|
2972
2111
|
results.push({
|
|
2973
2112
|
name,
|
|
2974
2113
|
scope: 'project',
|
|
@@ -2978,7 +2117,6 @@ export function listInstalledMcpsWithScope(agentId, cwd = process.cwd(), options
|
|
|
2978
2117
|
}
|
|
2979
2118
|
return results;
|
|
2980
2119
|
}
|
|
2981
|
-
/** Map of agent name aliases and shorthand identifiers to canonical AgentId values. */
|
|
2982
2120
|
const AGENT_NAME_ALIASES = {
|
|
2983
2121
|
claude: 'claude',
|
|
2984
2122
|
'claude-code': 'claude',
|
|
@@ -3026,14 +2164,8 @@ const AGENT_NAME_ALIASES = {
|
|
|
3026
2164
|
'warp-agent': 'warp',
|
|
3027
2165
|
'warp-cli': 'warp',
|
|
3028
2166
|
};
|
|
3029
|
-
/**
|
|
3030
|
-
* Resolve a user-provided agent name (alias, shorthand, or canonical) to its AgentId.
|
|
3031
|
-
* Tolerates a single typo (insertion/deletion/substitution/transposition) against
|
|
3032
|
-
* canonical ids and aliases — `cladue` -> claude, `kim` -> kimi, `codx` -> codex —
|
|
3033
|
-
* but only when the correction is unambiguous (all distance-1 candidates agree on
|
|
3034
|
-
* one agent). Two-letter shorthands are excluded as fuzzy candidates.
|
|
3035
|
-
*/
|
|
3036
2167
|
export function resolveAgentName(input) {
|
|
2168
|
+
// Resolve exact names first; fuzzy 3+ character matches must be one edit and one target.
|
|
3037
2169
|
const lower = input.toLowerCase();
|
|
3038
2170
|
const exact = AGENT_NAME_ALIASES[lower] ?? (AGENTS[lower] ? lower : null);
|
|
3039
2171
|
if (exact || lower.length < 3)
|
|
@@ -3049,19 +2181,11 @@ export function resolveAgentName(input) {
|
|
|
3049
2181
|
}
|
|
3050
2182
|
return hits.size === 1 ? hits.values().next().value : null;
|
|
3051
2183
|
}
|
|
3052
|
-
/** Check whether the input string matches any known agent name or alias. */
|
|
3053
2184
|
export function isAgentName(input) {
|
|
3054
2185
|
return resolveAgentName(input) !== null;
|
|
3055
2186
|
}
|
|
3056
|
-
/**
|
|
3057
|
-
* Split a CLI-provided `<agent>[@<version>][#<label>]` spec into its bare agent
|
|
3058
|
-
* id, optional exact version token, and optional account label, the same way
|
|
3059
|
-
* `agents run` does — NOT the
|
|
3060
|
-
* agent-spec qualifier engine (`@latest`/`@all`), which enumerates installed
|
|
3061
|
-
* versions for read/diagnostic commands, not a single launch target. Returns an
|
|
3062
|
-
* error message rather than throwing so callers decide exit-vs-continue.
|
|
3063
|
-
*/
|
|
3064
2187
|
export function parseAgentVersionSpec(raw) {
|
|
2188
|
+
// This parses one run target, not the diagnostic selector grammar with @all/@latest.
|
|
3065
2189
|
const labelParts = raw.split('#');
|
|
3066
2190
|
if (labelParts.length > 2) {
|
|
3067
2191
|
return { error: `Invalid agent spec '${raw}': at most one '#label' is allowed` };
|
|
@@ -3084,11 +2208,6 @@ export function parseAgentVersionSpec(raw) {
|
|
|
3084
2208
|
}
|
|
3085
2209
|
return { agent, ...(rawVersion ? { version: rawVersion } : {}), ...(rawLabel ? { label: rawLabel } : {}) };
|
|
3086
2210
|
}
|
|
3087
|
-
/**
|
|
3088
|
-
* Build the deprecation notice lines for an agent, or null if it isn't
|
|
3089
|
-
* deprecated. Split from the printer so tests can assert the content without
|
|
3090
|
-
* capturing stdout. Lines are plain (uncolored) text.
|
|
3091
|
-
*/
|
|
3092
2211
|
export function deprecationNotice(agent) {
|
|
3093
2212
|
const dep = AGENTS[agent].deprecated;
|
|
3094
2213
|
if (!dep)
|
|
@@ -3126,11 +2245,6 @@ export function hardDeprecationNotice(agent) {
|
|
|
3126
2245
|
export function hardDeprecationError(agent) {
|
|
3127
2246
|
return hardDeprecationNotice(agent)?.join('\n') ?? `${AGENTS[agent].name} is no longer supported.`;
|
|
3128
2247
|
}
|
|
3129
|
-
/**
|
|
3130
|
-
* Print a deprecation warning (yellow) if the agent's registry entry carries a
|
|
3131
|
-
* `deprecated` marker; no-op otherwise. Call from any user entry point that
|
|
3132
|
-
* acts on a chosen agent — install (`agents add`) and `agents teams add`.
|
|
3133
|
-
*/
|
|
3134
2248
|
export function warnAgentDeprecated(agent) {
|
|
3135
2249
|
const lines = deprecationNotice(agent);
|
|
3136
2250
|
if (!lines)
|
|
@@ -3138,7 +2252,6 @@ export function warnAgentDeprecated(agent) {
|
|
|
3138
2252
|
for (const line of lines)
|
|
3139
2253
|
console.log(chalk.yellow(line));
|
|
3140
2254
|
}
|
|
3141
|
-
/** Format an error message for an unrecognized agent name, listing valid options. */
|
|
3142
2255
|
export function formatAgentError(agentName, validAgents = ALL_AGENT_IDS) {
|
|
3143
2256
|
return `Unknown agent '${agentName}'. Valid agents: ${validAgents.join(', ')}`;
|
|
3144
2257
|
}
|