@phnx-labs/agents-cli 1.22.38 → 1.22.40
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 +302 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +46 -27
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +260 -0
- package/dist/commands/accounts.d.ts +20 -0
- package/dist/commands/accounts.js +186 -25
- package/dist/commands/apply.d.ts +3 -3
- package/dist/commands/apply.js +20 -63
- package/dist/commands/browser.js +206 -94
- package/dist/commands/budget.d.ts +7 -6
- package/dist/commands/budget.js +8 -7
- package/dist/commands/cloud.js +17 -20
- package/dist/commands/commands.js +1 -1
- package/dist/commands/computer-actions.d.ts +1 -35
- package/dist/commands/computer-actions.js +13 -181
- package/dist/commands/computer.d.ts +28 -3
- package/dist/commands/computer.js +93 -65
- package/dist/commands/config.js +47 -4
- package/dist/commands/cost.d.ts +2 -1
- package/dist/commands/cost.js +7 -6
- package/dist/commands/daemon.js +151 -4
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +19 -11
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.d.ts +2 -50
- package/dist/commands/exec.js +161 -216
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +9 -12
- package/dist/commands/fleet-capture.js +25 -27
- package/dist/commands/focus.d.ts +2 -3
- package/dist/commands/focus.js +34 -9
- package/dist/commands/go.js +15 -5
- package/dist/commands/harness.d.ts +3 -3
- package/dist/commands/harness.js +53 -5
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/insights.d.ts +5 -5
- package/dist/commands/insights.js +15 -9
- package/dist/commands/inspect.d.ts +2 -3
- package/dist/commands/inspect.js +4 -16
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +9 -9
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/memory.js +1 -1
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +7 -7
- package/dist/commands/mine.d.ts +11 -8
- package/dist/commands/mine.js +11 -10
- package/dist/commands/models.js +1 -1
- package/dist/commands/modes.js +1 -1
- package/dist/commands/monitors.js +23 -6
- package/dist/commands/output.d.ts +7 -6
- package/dist/commands/output.js +11 -10
- package/dist/commands/packages.js +4 -4
- package/dist/commands/perf.js +1 -1
- package/dist/commands/permissions.js +49 -32
- package/dist/commands/plugins.d.ts +1 -1
- package/dist/commands/plugins.js +3 -3
- package/dist/commands/profiles.d.ts +6 -9
- package/dist/commands/profiles.js +8 -321
- package/dist/commands/projects.d.ts +9 -0
- package/dist/commands/projects.js +140 -8
- package/dist/commands/prune.js +5 -13
- package/dist/commands/refresh-rules.js +1 -1
- package/dist/commands/repo.d.ts +5 -7
- package/dist/commands/repo.js +34 -18
- package/dist/commands/resource-view.js +4 -0
- package/dist/commands/resume.d.ts +11 -7
- package/dist/commands/resume.js +82 -98
- package/dist/commands/route.d.ts +12 -0
- package/dist/commands/route.js +261 -0
- package/dist/commands/routines.d.ts +2 -3
- package/dist/commands/routines.js +120 -145
- package/dist/commands/rules.js +1 -1
- package/dist/commands/run-account-picker.d.ts +1 -1
- package/dist/commands/run-account-picker.js +2 -2
- package/dist/commands/run-broadcast.d.ts +21 -0
- package/dist/commands/run-broadcast.js +89 -0
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-vault.d.ts +10 -0
- package/dist/commands/{login.js → secrets-vault.js} +34 -14
- package/dist/commands/secrets.d.ts +4 -4
- package/dist/commands/secrets.js +72 -63
- package/dist/commands/sessions-backfill.js +1 -1
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +9 -5
- package/dist/commands/sessions-export.js +2 -2
- package/dist/commands/sessions-inject.js +4 -5
- package/dist/commands/sessions-migrate.js +16 -27
- package/dist/commands/sessions-picker.d.ts +13 -0
- package/dist/commands/sessions-picker.js +182 -8
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +142 -180
- package/dist/commands/setup-computer.js +1 -1
- package/dist/commands/setup-fleet.js +3 -0
- package/dist/commands/setup-mine.d.ts +7 -3
- package/dist/commands/setup-mine.js +13 -8
- package/dist/commands/setup-secrets.js +2 -2
- package/dist/commands/setup-watchdog.js +2 -2
- package/dist/commands/setup.js +7 -2
- package/dist/commands/share.d.ts +65 -0
- package/dist/commands/share.js +253 -20
- package/dist/commands/skills.js +3 -3
- package/dist/commands/snapshot.d.ts +2 -2
- package/dist/commands/snapshot.js +9 -9
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +318 -48
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/sync.js +24 -9
- package/dist/commands/teams.d.ts +2 -2
- package/dist/commands/teams.js +9 -18
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/trash.js +1 -1
- package/dist/commands/usage.d.ts +1 -1
- package/dist/commands/usage.js +2 -2
- package/dist/commands/utils.d.ts +4 -14
- package/dist/commands/utils.js +6 -27
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +9 -77
- package/dist/commands/view.js +23 -8
- package/dist/commands/watchdog.js +1 -1
- package/dist/commands/webhook.js +11 -25
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/account-capabilities.d.ts +39 -0
- package/dist/lib/account-capabilities.js +59 -0
- package/dist/lib/account-catalog.js +1 -1
- package/dist/lib/account-registry.d.ts +66 -0
- package/dist/lib/account-registry.js +151 -5
- package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
- package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
- package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
- package/dist/lib/{usage.js → accounting/usage.js} +11 -11
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +72 -4
- package/dist/lib/agents.js +231 -199
- package/dist/lib/answer-router.d.ts +2 -2
- package/dist/lib/ask-classifier.d.ts +1 -1
- package/dist/lib/ask-classifier.js +1 -1
- package/dist/lib/audit/log.js +1 -1
- package/dist/lib/auth-health.d.ts +1 -1
- package/dist/lib/auth-health.js +2 -2
- package/dist/lib/brand.js +1 -1
- package/dist/lib/browser/caller-identity.d.ts +28 -0
- package/dist/lib/browser/caller-identity.js +156 -0
- package/dist/lib/browser/cdp.js +1 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +2 -2
- package/dist/lib/browser/hygiene.d.ts +10 -2
- package/dist/lib/browser/hygiene.js +7 -4
- package/dist/lib/browser/ipc.d.ts +22 -2
- package/dist/lib/browser/ipc.js +185 -21
- package/dist/lib/browser/profiles.d.ts +67 -3
- package/dist/lib/browser/profiles.js +129 -7
- package/dist/lib/browser/remote-control.d.ts +2 -2
- package/dist/lib/browser/remote-control.js +3 -3
- package/dist/lib/browser/runtime-state.d.ts +79 -0
- package/dist/lib/browser/runtime-state.js +119 -1
- package/dist/lib/browser/service.d.ts +113 -1
- package/dist/lib/browser/service.js +454 -40
- package/dist/lib/browser/sessions-list.d.ts +2 -1
- package/dist/lib/browser/sessions-list.js +4 -13
- package/dist/lib/browser/types.d.ts +18 -0
- package/dist/lib/budget/config.js +1 -1
- package/dist/lib/budget/ledger.js +1 -1
- package/dist/lib/byok-usage.js +1 -1
- package/dist/lib/capabilities.js +3 -15
- package/dist/lib/catchup.d.ts +1 -1
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloud/host.d.ts +3 -3
- package/dist/lib/cloud/host.js +5 -5
- package/dist/lib/cloud/rush.d.ts +9 -21
- package/dist/lib/cloud/rush.js +33 -120
- package/dist/lib/cloud/types.d.ts +2 -2
- package/dist/lib/commands.js +3 -13
- package/dist/lib/computer/actions.d.ts +36 -0
- package/dist/lib/computer/actions.js +162 -0
- package/dist/lib/computer/dispatch.d.ts +2 -2
- package/dist/lib/computer/dispatch.js +2 -2
- package/dist/lib/computer/sessions-list.d.ts +3 -3
- package/dist/lib/computer/sessions-list.js +2 -2
- package/dist/lib/config-keys.d.ts +12 -3
- package/dist/lib/config-keys.js +29 -6
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +6 -2
- package/dist/lib/crabbox/lease.js +9 -1
- package/dist/lib/crabbox/runtimes.d.ts +32 -7
- package/dist/lib/crabbox/runtimes.js +72 -30
- package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
- package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/daemon-ticks.d.ts +25 -0
- package/dist/lib/daemon-ticks.js +31 -1
- package/dist/lib/daemon-webhooks.d.ts +102 -0
- package/dist/lib/daemon-webhooks.js +210 -0
- package/dist/lib/device-config.d.ts +116 -72
- package/dist/lib/device-config.js +366 -132
- package/dist/lib/devices/config-migration.d.ts +29 -34
- package/dist/lib/devices/config-migration.js +209 -130
- package/dist/lib/devices/connect.d.ts +2 -2
- package/dist/lib/devices/connect.js +2 -2
- package/dist/lib/devices/discovery-policy.d.ts +30 -0
- package/dist/lib/devices/discovery-policy.js +101 -0
- package/dist/lib/devices/fleet-inventory.js +8 -3
- package/dist/lib/devices/harness-inventory.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.js +12 -3
- package/dist/lib/devices/known-hosts.js +1 -1
- package/dist/lib/devices/pool.d.ts +61 -0
- package/dist/lib/devices/pool.js +83 -0
- package/dist/lib/devices/registry.d.ts +1 -1
- package/dist/lib/devices/registry.js +1 -1
- package/dist/lib/devices/resolve-profile.d.ts +2 -2
- package/dist/lib/devices/resolve-profile.js +2 -2
- package/dist/lib/devices/resolve-target.d.ts +1 -1
- package/dist/lib/devices/resolve-target.js +4 -4
- package/dist/lib/devices/self-host.d.ts +1 -1
- package/dist/lib/devices/self-host.js +3 -3
- package/dist/lib/devices/ssh-config.d.ts +1 -1
- package/dist/lib/devices/stats-cache.js +1 -1
- package/dist/lib/devices/sync.d.ts +3 -1
- package/dist/lib/devices/sync.js +3 -3
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.js +2 -2
- package/dist/lib/event-families.d.ts +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +2 -2
- package/dist/lib/events-ingest.js +2 -2
- package/dist/lib/exec.d.ts +8 -5
- package/dist/lib/exec.js +19 -13
- package/dist/lib/factory/snapshot.d.ts +1 -1
- package/dist/lib/factory/snapshot.js +1 -1
- package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
- package/dist/lib/{activity.js → feed/activity.js} +7 -7
- package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
- package/dist/lib/{events.js → feed/events.js} +5 -5
- package/dist/lib/{feed.js → feed/feed.js} +4 -4
- package/dist/lib/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +1 -1
- package/dist/lib/feed-post.d.ts +1 -1
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -6
- package/dist/lib/fleet/apply.js +18 -45
- package/dist/lib/fleet/auth-sync.d.ts +16 -35
- package/dist/lib/fleet/auth-sync.js +16 -75
- package/dist/lib/fleet/capture.js +8 -6
- package/dist/lib/fleet/manifest.js +23 -11
- package/dist/lib/fleet/types.d.ts +19 -7
- package/dist/lib/fleet-cache.d.ts +1 -1
- package/dist/lib/fleet-cache.js +1 -1
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.js +44 -1
- package/dist/lib/friction-heuristics.d.ts +1 -1
- package/dist/lib/git.d.ts +24 -1
- package/dist/lib/git.js +82 -38
- package/dist/lib/heal.js +3 -3
- package/dist/lib/hooks.d.ts +18 -0
- package/dist/lib/hooks.js +113 -1
- package/dist/lib/hosts/credentials.d.ts +30 -10
- package/dist/lib/hosts/credentials.js +38 -26
- package/dist/lib/hosts/dispatch.d.ts +3 -3
- package/dist/lib/hosts/dispatch.js +3 -3
- package/dist/lib/hosts/option.d.ts +3 -3
- package/dist/lib/hosts/option.js +7 -8
- package/dist/lib/hosts/passthrough.d.ts +17 -17
- package/dist/lib/hosts/passthrough.js +67 -50
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconcile.d.ts +1 -1
- package/dist/lib/hosts/reconcile.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +1 -1
- package/dist/lib/hosts/reconnect.js +2 -2
- package/dist/lib/hosts/registry.d.ts +5 -5
- package/dist/lib/hosts/registry.js +5 -5
- package/dist/lib/hosts/remote-cmd.d.ts +10 -10
- package/dist/lib/hosts/remote-cmd.js +25 -18
- package/dist/lib/hosts/remote-os.d.ts +4 -4
- package/dist/lib/hosts/remote-os.js +4 -4
- package/dist/lib/hosts/remote-session-id.d.ts +2 -2
- package/dist/lib/hosts/remote-session-id.js +2 -2
- package/dist/lib/hosts/routing-flag.d.ts +3 -3
- package/dist/lib/hosts/routing-flag.js +4 -5
- package/dist/lib/hosts/run-target.d.ts +4 -4
- package/dist/lib/hosts/run-target.js +4 -4
- package/dist/lib/hosts/session-index.d.ts +2 -2
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/session-marker.d.ts +1 -1
- package/dist/lib/hosts/session-marker.js +1 -1
- package/dist/lib/hosts/types.d.ts +2 -2
- package/dist/lib/hosts/types.js +2 -2
- package/dist/lib/import.js +1 -1
- package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +49 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +265 -38
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/strategies.js +1 -1
- package/dist/lib/installations/update.js +2 -2
- package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
- package/dist/lib/{versions.js → installations/versions.js} +51 -31
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/linear-projects.d.ts +28 -0
- package/dist/lib/linear-projects.js +30 -0
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-gc.js +1 -1
- package/dist/lib/mailbox.js +1 -1
- package/dist/lib/mcp-registry.d.ts +62 -0
- package/dist/lib/mcp-registry.js +177 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +124 -307
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +24 -6
- package/dist/lib/menubar/snapshot.d.ts +7 -0
- package/dist/lib/menubar/snapshot.js +8 -6
- package/dist/lib/models.js +1 -1
- package/dist/lib/monitors/config.d.ts +12 -0
- package/dist/lib/monitors/config.js +3 -0
- package/dist/lib/monitors/dispatch.js +26 -5
- package/dist/lib/monitors/engine.js +10 -0
- package/dist/lib/monitors/sources/webhook.d.ts +1 -1
- package/dist/lib/monitors/state.d.ts +42 -0
- package/dist/lib/monitors/state.js +30 -0
- package/dist/lib/notify.d.ts +1 -1
- package/dist/lib/observe-aliases.d.ts +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- package/dist/lib/output/git-output.js +2 -2
- package/dist/lib/overdue.d.ts +1 -1
- package/dist/lib/overdue.js +1 -1
- package/dist/lib/permissions-registry.d.ts +65 -0
- package/dist/lib/permissions-registry.js +599 -0
- package/dist/lib/permissions.d.ts +24 -13
- package/dist/lib/permissions.js +52 -271
- package/dist/lib/picker.d.ts +16 -0
- package/dist/lib/picker.js +33 -3
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +4 -4
- package/dist/lib/platform/paths.d.ts +8 -0
- package/dist/lib/platform/paths.js +11 -0
- package/dist/lib/platform/posixpath.js +3 -3
- package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
- package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
- package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
- package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
- package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
- package/dist/lib/{skills.js → plugins/skills.js} +7 -7
- package/dist/lib/pricing/cost.d.ts +1 -1
- package/dist/lib/pricing/cost.js +1 -1
- package/dist/lib/profiles-presets.d.ts +1 -1
- package/dist/lib/profiles-presets.js +1 -1
- package/dist/lib/profiles.js +2 -2
- package/dist/lib/project-import.js +4 -1
- package/dist/lib/project-launch.d.ts +1 -1
- package/dist/lib/project-launch.js +3 -3
- package/dist/lib/project-pull.d.ts +128 -0
- package/dist/lib/project-pull.js +384 -0
- package/dist/lib/project-root.d.ts +2 -2
- package/dist/lib/project-root.js +2 -2
- package/dist/lib/project-status.js +1 -1
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +29 -6
- package/dist/lib/refresh.d.ts +12 -1
- package/dist/lib/refresh.js +16 -9
- package/dist/lib/registry.d.ts +9 -2
- package/dist/lib/registry.js +11 -4
- package/dist/lib/resources.d.ts +2 -2
- package/dist/lib/resources.js +2 -2
- package/dist/lib/routers.d.ts +81 -0
- package/dist/lib/routers.js +153 -0
- package/dist/lib/routine-context.d.ts +1 -0
- package/dist/lib/routine-context.js +7 -2
- package/dist/lib/routine-notify-owner.d.ts +1 -1
- package/dist/lib/routine-notify.d.ts +1 -1
- package/dist/lib/routine-notify.js +1 -1
- package/dist/lib/routine-process-cleanup.d.ts +1 -1
- package/dist/lib/routine-readiness.d.ts +1 -1
- package/dist/lib/routine-readiness.js +11 -4
- package/dist/lib/routines-placement.d.ts +12 -2
- package/dist/lib/routines-placement.js +20 -3
- package/dist/lib/routines-project.d.ts +1 -1
- package/dist/lib/routines-project.js +1 -1
- package/dist/lib/rules/compile.d.ts +1 -0
- package/dist/lib/rules/compile.js +10 -2
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/run-notify.js +1 -1
- package/dist/lib/runner.d.ts +80 -2
- package/dist/lib/runner.js +241 -62
- package/dist/lib/sandbox.d.ts +1 -1
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.js +1 -1
- package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
- package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.js +2 -2
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +3 -3
- package/dist/lib/secrets/bundles.js +7 -7
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.d.ts +1 -1
- package/dist/lib/secrets/list-filter.js +2 -2
- package/dist/lib/secrets/push.d.ts +1 -1
- package/dist/lib/secrets/push.js +10 -12
- package/dist/lib/secrets/remote.d.ts +12 -10
- package/dist/lib/secrets/remote.js +21 -14
- package/dist/lib/secrets/vault.js +2 -2
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/self-update.d.ts +39 -4
- package/dist/lib/self-update.js +78 -25
- package/dist/lib/serve/control.d.ts +1 -1
- package/dist/lib/serve/control.js +4 -4
- package/dist/lib/serve/data.d.ts +1 -1
- package/dist/lib/serve/data.js +1 -1
- package/dist/lib/serve/stream.js +1 -1
- package/dist/lib/service-manifest.d.ts +29 -0
- package/dist/lib/service-manifest.js +80 -0
- package/dist/lib/session/active.d.ts +59 -7
- package/dist/lib/session/active.js +158 -17
- package/dist/lib/session/bash-command.js +1 -1
- package/dist/lib/session/claude-accounts.d.ts +1 -1
- package/dist/lib/session/claude-accounts.js +1 -1
- package/dist/lib/session/db.d.ts +10 -2
- package/dist/lib/session/db.js +25 -6
- package/dist/lib/session/discover.d.ts +77 -0
- package/dist/lib/session/discover.js +130 -25
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/inject.d.ts +1 -1
- package/dist/lib/session/insights.d.ts +1 -1
- package/dist/lib/session/insights.js +1 -1
- package/dist/lib/session/live-metadata.d.ts +15 -0
- package/dist/lib/session/live-metadata.js +76 -0
- package/dist/lib/session/migrate-targets.d.ts +1 -1
- package/dist/lib/session/recovery.d.ts +1 -1
- package/dist/lib/session/recovery.js +2 -2
- package/dist/lib/session/remote-active.d.ts +10 -1
- package/dist/lib/session/remote-active.js +8 -3
- package/dist/lib/session/remote-bundle.d.ts +1 -1
- package/dist/lib/session/remote-bundle.js +2 -2
- package/dist/lib/session/remote-list.d.ts +15 -4
- package/dist/lib/session/remote-list.js +40 -3
- package/dist/lib/session/remote.d.ts +5 -5
- package/dist/lib/session/remote.js +13 -17
- package/dist/lib/session/resume-command.d.ts +3 -2
- package/dist/lib/session/resume-command.js +4 -3
- package/dist/lib/session/resume-owner.d.ts +3 -3
- package/dist/lib/session/resume-owner.js +3 -3
- package/dist/lib/session/session-cache.d.ts +12 -0
- package/dist/lib/session/session-cache.js +2 -0
- package/dist/lib/session/shell-programs.js +1 -1
- package/dist/lib/session/state.js +5 -5
- package/dist/lib/session/team-filter.d.ts +1 -1
- package/dist/lib/session/team-filter.js +1 -1
- package/dist/lib/session/types.d.ts +3 -3
- package/dist/lib/session/width.d.ts +2 -2
- package/dist/lib/session/width.js +2 -2
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +82 -0
- package/dist/lib/share/publish.js +170 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +36 -6
- package/dist/lib/smart-launch.js +65 -8
- package/dist/lib/snapshot.d.ts +4 -4
- package/dist/lib/snapshot.js +2 -2
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +2 -2
- package/dist/lib/ssh-tunnel.d.ts +10 -10
- package/dist/lib/ssh-tunnel.js +12 -12
- package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
- package/dist/lib/staleness/checkers/hooks.js +1 -1
- package/dist/lib/staleness/detectors/permissions.js +0 -23
- package/dist/lib/staleness/detectors/plugins.js +1 -1
- package/dist/lib/staleness/fingerprint.js +1 -1
- package/dist/lib/staleness/layers.d.ts +1 -1
- package/dist/lib/staleness/layers.js +1 -1
- package/dist/lib/staleness/writers/mcp.js +3 -1
- package/dist/lib/staleness/writers/plugins.js +1 -1
- package/dist/lib/staleness/writers/types.d.ts +8 -0
- package/dist/lib/startup/command-registry.d.ts +5 -147
- package/dist/lib/startup/command-registry.js +38 -303
- package/dist/lib/startup/dev-build.d.ts +0 -21
- package/dist/lib/startup/dev-build.js +29 -8
- package/dist/lib/state.d.ts +19 -1
- package/dist/lib/state.js +120 -51
- package/dist/lib/subagents.js +1 -1
- package/dist/lib/sync-status.js +1 -1
- package/dist/lib/sync-umbrella.d.ts +6 -1
- package/dist/lib/sync-umbrella.js +9 -4
- package/dist/lib/teams/agents.js +2 -2
- package/dist/lib/teams/registry.js +1 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
- package/dist/lib/terminal/engine.js +1 -1
- package/dist/lib/terminal/index.d.ts +4 -0
- package/dist/lib/terminal/index.js +3 -0
- package/dist/lib/terminal/inject.d.ts +2 -2
- package/dist/lib/terminal/inject.js +2 -2
- package/dist/lib/terminal/transport.js +1 -1
- package/dist/lib/tmux/index.d.ts +1 -1
- package/dist/lib/tmux/index.js +1 -1
- package/dist/lib/tmux/session.d.ts +21 -5
- package/dist/lib/tmux/session.js +76 -22
- package/dist/lib/triggers/handlers.d.ts +1 -1
- package/dist/lib/triggers/handlers.js +2 -2
- package/dist/lib/triggers/webhook.d.ts +36 -2
- package/dist/lib/triggers/webhook.js +97 -42
- package/dist/lib/types.d.ts +18 -6
- package/dist/lib/usage-fleet.d.ts +1 -1
- package/dist/lib/usage-fleet.js +1 -1
- package/dist/lib/usage-refresh.d.ts +1 -1
- package/dist/lib/usage-refresh.js +3 -3
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/view-types.d.ts +56 -0
- package/dist/lib/view-types.js +1 -0
- package/dist/lib/watchdog/rotate.d.ts +2 -2
- package/dist/lib/watchdog/rotate.js +3 -3
- package/dist/lib/watchdog/runner.d.ts +2 -3
- package/dist/lib/watchdog/runner.js +3 -4
- package/dist/lib/workflows.js +1 -1
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -2
- package/dist/commands/bench.d.ts +0 -2
- package/dist/commands/bench.js +0 -101
- package/dist/commands/cp.d.ts +0 -84
- package/dist/commands/cp.js +0 -231
- package/dist/commands/login.d.ts +0 -2
- package/dist/lib/resources/commands.d.ts +0 -46
- package/dist/lib/resources/commands.js +0 -211
- package/dist/lib/resources/hooks.d.ts +0 -16
- package/dist/lib/resources/hooks.js +0 -153
- package/dist/lib/resources/mcp.d.ts +0 -34
- package/dist/lib/resources/mcp.js +0 -250
- package/dist/lib/resources/memory.d.ts +0 -15
- package/dist/lib/resources/memory.js +0 -46
- package/dist/lib/resources/permissions.d.ts +0 -13
- package/dist/lib/resources/permissions.js +0 -202
- package/dist/lib/resources/rules.d.ts +0 -46
- package/dist/lib/resources/rules.js +0 -179
- package/dist/lib/resources/skills.d.ts +0 -37
- package/dist/lib/resources/skills.js +0 -247
- package/dist/lib/resources/subagents.d.ts +0 -46
- package/dist/lib/resources/subagents.js +0 -202
- /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative permission-target registry.
|
|
3
|
+
*
|
|
4
|
+
* Every allowlist-capable agent gets ONE entry (`PERMISSION_TARGETS`) describing
|
|
5
|
+
* where its permissions live and how to read that file back into the canonical
|
|
6
|
+
* `PermissionSet`. `agents permissions list <agent>` and the config-file import
|
|
7
|
+
* behind `agents permissions add <path>` used to dispatch through hand-written
|
|
8
|
+
* 3-arm switches while
|
|
9
|
+
* `applyPermissionsToVersion` wrote 13 harnesses, so permissions were written
|
|
10
|
+
* for cursor, antigravity, grok, kimi, droid, copilot, kiro, openclaw and
|
|
11
|
+
* hermes and then reported as absent for all ten (RUSH-2676).
|
|
12
|
+
*
|
|
13
|
+
* The key set is pinned to `capableAgents('allowlist')` by
|
|
14
|
+
* `permissions-registry.test.ts`, mirroring `SUBAGENT_TARGETS` — the pattern the
|
|
15
|
+
* repo's own AGENTS.md names for cross-harness capabilities. A newly added
|
|
16
|
+
* allowlist harness cannot be written-but-unreadable: it must land an entry here
|
|
17
|
+
* in the same change.
|
|
18
|
+
*
|
|
19
|
+
* This module also OWNS the canonical<->native tool vocabularies. `permissions.ts`
|
|
20
|
+
* imports them for the forward (canonical -> native) serializers, and the reverse
|
|
21
|
+
* projections below are derived from the same tables, so the two directions
|
|
22
|
+
* cannot drift into disagreeing about what `developer__shell` or `fs_read` means.
|
|
23
|
+
*
|
|
24
|
+
* ## Every reverse projection is lossy, and says how
|
|
25
|
+
*
|
|
26
|
+
* The forward direction discards information — several canonical tools collapse
|
|
27
|
+
* onto one native id (`Read`/`Grep`/`Glob` all become Kiro's `fs_read`), and
|
|
28
|
+
* pattern grammars differ (`git:*` becomes `git *`). Reading back therefore
|
|
29
|
+
* recovers a permission set that GRANTS THE SAME ACCESS, not the byte-identical
|
|
30
|
+
* strings that were written. Each target documents its own collapse. Callers that
|
|
31
|
+
* need a faithful record of what agents-cli installed should read the central
|
|
32
|
+
* `~/.agents/permissions/` set, not a harness's config.
|
|
33
|
+
*/
|
|
34
|
+
import * as fs from 'fs';
|
|
35
|
+
import * as os from 'os';
|
|
36
|
+
import * as path from 'path';
|
|
37
|
+
import * as yaml from 'yaml';
|
|
38
|
+
import * as TOML from 'smol-toml';
|
|
39
|
+
// ── canonical <-> native tool vocabularies (single source of truth) ──────────
|
|
40
|
+
/** Canonical tool (lowercased) -> Grok's lowercase tool vocabulary. */
|
|
41
|
+
export const GROK_TOOL_BY_CANONICAL = {
|
|
42
|
+
bash: 'bash',
|
|
43
|
+
read: 'read',
|
|
44
|
+
write: 'edit',
|
|
45
|
+
grep: 'grep',
|
|
46
|
+
webfetch: 'webfetch',
|
|
47
|
+
};
|
|
48
|
+
/** Canonical tool -> Kiro CLI v3 capability id. */
|
|
49
|
+
export const KIRO_CAPABILITY_BY_TOOL = {
|
|
50
|
+
bash: 'shell',
|
|
51
|
+
read: 'fs_read',
|
|
52
|
+
grep: 'fs_read',
|
|
53
|
+
glob: 'fs_read',
|
|
54
|
+
write: 'fs_write',
|
|
55
|
+
edit: 'fs_write',
|
|
56
|
+
notebookedit: 'fs_write',
|
|
57
|
+
webfetch: 'web_fetch',
|
|
58
|
+
websearch: 'web_search',
|
|
59
|
+
mcp: 'mcp',
|
|
60
|
+
subagent: 'subagent',
|
|
61
|
+
skill: 'skill',
|
|
62
|
+
};
|
|
63
|
+
/** Canonical tool -> OpenClaw tool id (tool-level granularity only). */
|
|
64
|
+
export const CANONICAL_TO_OPENCLAW_TOOL = {
|
|
65
|
+
bash: 'exec',
|
|
66
|
+
read: 'read',
|
|
67
|
+
write: 'write',
|
|
68
|
+
edit: 'write',
|
|
69
|
+
webfetch: 'web_fetch',
|
|
70
|
+
websearch: 'web_search',
|
|
71
|
+
};
|
|
72
|
+
/** Canonical tool -> Antigravity's action namespace. */
|
|
73
|
+
export const ANTIGRAVITY_ACTION_BY_TOOL = {
|
|
74
|
+
bash: 'command',
|
|
75
|
+
read: 'read_file',
|
|
76
|
+
write: 'write_file',
|
|
77
|
+
webfetch: 'read_url',
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Invert a forward map, keeping the FIRST canonical tool that maps to each
|
|
81
|
+
* native id. Several canonical tools collapse onto one native id, so the
|
|
82
|
+
* inverse must pick a representative; declaration order in the forward table is
|
|
83
|
+
* that choice, which is why `read` (declared before `grep`/`glob`) represents
|
|
84
|
+
* Kiro's `fs_read`.
|
|
85
|
+
*/
|
|
86
|
+
function invertFirstWins(forward) {
|
|
87
|
+
const out = {};
|
|
88
|
+
for (const [canonical, native] of Object.entries(forward)) {
|
|
89
|
+
if (!native)
|
|
90
|
+
continue;
|
|
91
|
+
if (!(native in out))
|
|
92
|
+
out[native] = canonical;
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
const CANONICAL_BY_GROK_TOOL = invertFirstWins(GROK_TOOL_BY_CANONICAL);
|
|
97
|
+
const CANONICAL_BY_KIRO_CAPABILITY = invertFirstWins(KIRO_CAPABILITY_BY_TOOL);
|
|
98
|
+
const CANONICAL_BY_OPENCLAW_TOOL = invertFirstWins(CANONICAL_TO_OPENCLAW_TOOL);
|
|
99
|
+
const CANONICAL_BY_ANTIGRAVITY_ACTION = invertFirstWins(ANTIGRAVITY_ACTION_BY_TOOL);
|
|
100
|
+
/** Canonical TitleCase spelling for a lowercased canonical tool name. */
|
|
101
|
+
const CANONICAL_TOOL_CASE = {
|
|
102
|
+
bash: 'Bash',
|
|
103
|
+
read: 'Read',
|
|
104
|
+
write: 'Write',
|
|
105
|
+
edit: 'Edit',
|
|
106
|
+
grep: 'Grep',
|
|
107
|
+
glob: 'Glob',
|
|
108
|
+
notebookedit: 'NotebookEdit',
|
|
109
|
+
webfetch: 'WebFetch',
|
|
110
|
+
websearch: 'WebSearch',
|
|
111
|
+
mcp: 'Mcp',
|
|
112
|
+
subagent: 'Subagent',
|
|
113
|
+
skill: 'Skill',
|
|
114
|
+
};
|
|
115
|
+
function titleCaseTool(lower) {
|
|
116
|
+
return CANONICAL_TOOL_CASE[lower] ?? lower;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Inverse of the serializers' `normalizeBashPattern`: native grammars spell a
|
|
120
|
+
* command's arg-glob `git *`, canonical spells it `git:*`. `*` stays `*`.
|
|
121
|
+
*/
|
|
122
|
+
function denormalizeBashPattern(pattern) {
|
|
123
|
+
if (pattern === '*' || pattern === '**')
|
|
124
|
+
return '*';
|
|
125
|
+
if (pattern.endsWith(' *'))
|
|
126
|
+
return `${pattern.slice(0, -2)}:*`;
|
|
127
|
+
return pattern;
|
|
128
|
+
}
|
|
129
|
+
/** Build a canonical rule string, collapsing a blanket pattern to the tool's wildcard. */
|
|
130
|
+
function canonicalRule(lowerTool, pattern) {
|
|
131
|
+
const tool = titleCaseTool(lowerTool);
|
|
132
|
+
if (pattern === null)
|
|
133
|
+
return lowerTool === 'bash' ? 'Bash(*)' : `${tool}(**)`;
|
|
134
|
+
return `${tool}(${pattern})`;
|
|
135
|
+
}
|
|
136
|
+
/** Assemble a PermissionSet, dropping empty arrays so callers can test truthiness. */
|
|
137
|
+
function permissionSet(allow, deny) {
|
|
138
|
+
const uniqueAllow = [...new Set(allow)];
|
|
139
|
+
const uniqueDeny = [...new Set(deny)];
|
|
140
|
+
if (uniqueAllow.length === 0 && uniqueDeny.length === 0)
|
|
141
|
+
return null;
|
|
142
|
+
return {
|
|
143
|
+
name: 'exported',
|
|
144
|
+
allow: uniqueAllow,
|
|
145
|
+
...(uniqueDeny.length ? { deny: uniqueDeny } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// ── file readers ─────────────────────────────────────────────────────────────
|
|
149
|
+
/**
|
|
150
|
+
* Strip JSON comments for JSONC parsing, only OUTSIDE string literals.
|
|
151
|
+
*
|
|
152
|
+
* A naive `//`-to-end-of-line regex destroys
|
|
153
|
+
* `"$schema": "https://opencode.ai/config.json"` — which every
|
|
154
|
+
* opencode-generated config carries — so the file then fails to parse and its
|
|
155
|
+
* permissions read back as absent, the very defect this registry exists to fix.
|
|
156
|
+
* Exported so `permissions.ts` shares this one implementation instead of
|
|
157
|
+
* keeping its own copy.
|
|
158
|
+
*/
|
|
159
|
+
export function stripJsonComments(content) {
|
|
160
|
+
let result = '';
|
|
161
|
+
let inString = false;
|
|
162
|
+
let escape = false;
|
|
163
|
+
let i = 0;
|
|
164
|
+
while (i < content.length) {
|
|
165
|
+
const char = content[i];
|
|
166
|
+
const next = content[i + 1];
|
|
167
|
+
if (escape) {
|
|
168
|
+
result += char;
|
|
169
|
+
escape = false;
|
|
170
|
+
i++;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (char === '\\' && inString) {
|
|
174
|
+
result += char;
|
|
175
|
+
escape = true;
|
|
176
|
+
i++;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (char === '"') {
|
|
180
|
+
inString = !inString;
|
|
181
|
+
result += char;
|
|
182
|
+
i++;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (!inString) {
|
|
186
|
+
if (char === '/' && next === '/') {
|
|
187
|
+
while (i < content.length && content[i] !== '\n') {
|
|
188
|
+
i++;
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (char === '/' && next === '*') {
|
|
193
|
+
i += 2;
|
|
194
|
+
while (i < content.length && !(content[i] === '*' && content[i + 1] === '/')) {
|
|
195
|
+
i++;
|
|
196
|
+
}
|
|
197
|
+
i += 2;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
result += char;
|
|
202
|
+
i++;
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
function readJson(configPath) {
|
|
207
|
+
if (!fs.existsSync(configPath))
|
|
208
|
+
return null;
|
|
209
|
+
try {
|
|
210
|
+
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
211
|
+
const parsed = JSON.parse(configPath.endsWith('.jsonc') ? stripJsonComments(raw) : raw);
|
|
212
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
213
|
+
? parsed
|
|
214
|
+
: null;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function readYaml(configPath) {
|
|
221
|
+
if (!fs.existsSync(configPath))
|
|
222
|
+
return null;
|
|
223
|
+
try {
|
|
224
|
+
const parsed = yaml.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
225
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
226
|
+
? parsed
|
|
227
|
+
: null;
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function readToml(configPath) {
|
|
234
|
+
if (!fs.existsSync(configPath))
|
|
235
|
+
return null;
|
|
236
|
+
try {
|
|
237
|
+
return TOML.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/** `preferred` unless it is absent and `alternate` exists. */
|
|
244
|
+
function existingOr(preferred, alternate) {
|
|
245
|
+
return !fs.existsSync(preferred) && fs.existsSync(alternate) ? alternate : preferred;
|
|
246
|
+
}
|
|
247
|
+
/** Every string in `value` when it is a string array, else []. */
|
|
248
|
+
function stringList(value) {
|
|
249
|
+
return Array.isArray(value) ? value.filter((v) => typeof v === 'string') : [];
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Single source of truth for where each allowlist-capable agent stores
|
|
253
|
+
* permissions and how to read them back. Keys MUST equal
|
|
254
|
+
* `capableAgents('allowlist')` — pinned by `permissions-registry.test.ts`.
|
|
255
|
+
*/
|
|
256
|
+
export const PERMISSION_TARGETS = {
|
|
257
|
+
claude: {
|
|
258
|
+
home: (h) => path.join(h, '.claude', 'settings.json'),
|
|
259
|
+
project: (cwd) => path.join(cwd, '.claude', 'settings.json'),
|
|
260
|
+
lossyBecause: 'canonical Write(...) is written as Edit(...), so it reads back as Edit',
|
|
261
|
+
toCanonical(configPath) {
|
|
262
|
+
const config = readJson(configPath);
|
|
263
|
+
const perms = config?.permissions;
|
|
264
|
+
if (!perms || typeof perms !== 'object' || Array.isArray(perms))
|
|
265
|
+
return null;
|
|
266
|
+
const p = perms;
|
|
267
|
+
const set = permissionSet(stringList(p.allow), stringList(p.deny));
|
|
268
|
+
const dirs = stringList(p.additionalDirectories);
|
|
269
|
+
if (set && dirs.length)
|
|
270
|
+
set.additionalDirectories = dirs;
|
|
271
|
+
return set;
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
opencode: {
|
|
275
|
+
// OpenCode accepts either extension and `openCodeConfigPath` probes both, so
|
|
276
|
+
// an existing `opencode.json` must be found rather than shadowed by the
|
|
277
|
+
// `.jsonc` default.
|
|
278
|
+
home: (h) => existingOr(path.join(h, '.config', 'opencode', 'opencode.jsonc'), path.join(h, '.config', 'opencode', 'opencode.json')),
|
|
279
|
+
project: (cwd) => existingOr(path.join(cwd, 'opencode.jsonc'), path.join(cwd, 'opencode.json')),
|
|
280
|
+
// BOTH spellings, for home and project. The preferred one needs an entry
|
|
281
|
+
// too: `home('')`/`project('')` resolve it through `existingOr`, which
|
|
282
|
+
// probes, so leaving it out left `opencode.jsonc` detection cwd-dependent.
|
|
283
|
+
altSuffixes: [
|
|
284
|
+
path.join('.config', 'opencode', 'opencode.jsonc'),
|
|
285
|
+
path.join('.config', 'opencode', 'opencode.json'),
|
|
286
|
+
'opencode.jsonc',
|
|
287
|
+
'opencode.json',
|
|
288
|
+
],
|
|
289
|
+
lossyBecause: 'OpenCode gates Bash only, so non-Bash rules were never written',
|
|
290
|
+
toCanonical(configPath) {
|
|
291
|
+
const config = readJson(configPath);
|
|
292
|
+
const permission = config?.permission;
|
|
293
|
+
if (!permission || typeof permission !== 'object' || Array.isArray(permission))
|
|
294
|
+
return null;
|
|
295
|
+
const bash = permission.bash;
|
|
296
|
+
if (!bash || typeof bash !== 'object' || Array.isArray(bash))
|
|
297
|
+
return null;
|
|
298
|
+
const allow = [];
|
|
299
|
+
const deny = [];
|
|
300
|
+
for (const [pattern, action] of Object.entries(bash)) {
|
|
301
|
+
if (action === 'allow')
|
|
302
|
+
allow.push(`Bash(${pattern})`);
|
|
303
|
+
else if (action === 'deny')
|
|
304
|
+
deny.push(`Bash(${pattern})`);
|
|
305
|
+
}
|
|
306
|
+
return permissionSet(allow, deny);
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
codex: {
|
|
310
|
+
home: (h) => path.join(h, '.codex', 'config.toml'),
|
|
311
|
+
project: (cwd) => path.join(cwd, '.codex', 'config.toml'),
|
|
312
|
+
lossyBecause: 'Codex has no rule list — its sandbox mode is widened into representative blanket grants',
|
|
313
|
+
toCanonical(configPath) {
|
|
314
|
+
const config = readToml(configPath);
|
|
315
|
+
if (!config)
|
|
316
|
+
return null;
|
|
317
|
+
const allow = [];
|
|
318
|
+
const sandboxMode = config.sandbox_mode;
|
|
319
|
+
if (config.approval_policy === 'never' || sandboxMode === 'danger-full-access') {
|
|
320
|
+
allow.push('Bash(*)', 'Read(**)', 'Write(**)', 'Edit(**)');
|
|
321
|
+
}
|
|
322
|
+
else if (sandboxMode === 'workspace-write') {
|
|
323
|
+
allow.push('Bash(*)', 'Read(**)');
|
|
324
|
+
}
|
|
325
|
+
const sw = config.sandbox_workspace_write;
|
|
326
|
+
if (sw && typeof sw === 'object' && !Array.isArray(sw) && sw.network_access) {
|
|
327
|
+
allow.push('WebSearch(*)', 'WebFetch(*)');
|
|
328
|
+
}
|
|
329
|
+
return permissionSet(allow, []);
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
cursor: {
|
|
333
|
+
home: (h) => path.join(h, '.cursor', 'cli-config.json'),
|
|
334
|
+
lossyBecause: 'canonical Bash reads back from Shell(...) and Edit was written as Write(...)',
|
|
335
|
+
toCanonical(configPath) {
|
|
336
|
+
const config = readJson(configPath);
|
|
337
|
+
const perms = config?.permissions;
|
|
338
|
+
if (!perms || typeof perms !== 'object' || Array.isArray(perms))
|
|
339
|
+
return null;
|
|
340
|
+
const p = perms;
|
|
341
|
+
// Cursor spells Bash as Shell(...) and canonical WebSearch as WebFetch(...).
|
|
342
|
+
const back = (rule) => rule.startsWith('Shell') ? rule.replace(/^Shell/, 'Bash') : rule;
|
|
343
|
+
return permissionSet(stringList(p.allow).map(back), stringList(p.deny).map(back));
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
antigravity: {
|
|
347
|
+
home: (h) => path.join(h, '.gemini', 'antigravity-cli', 'settings.json'),
|
|
348
|
+
lossyBecause: 'only command/read_file/write_file/read_url map, so other canonical tools were never written',
|
|
349
|
+
toCanonical(configPath) {
|
|
350
|
+
const config = readJson(configPath);
|
|
351
|
+
const perms = config?.permissions;
|
|
352
|
+
if (!perms || typeof perms !== 'object' || Array.isArray(perms))
|
|
353
|
+
return null;
|
|
354
|
+
const p = perms;
|
|
355
|
+
const back = (entries) => {
|
|
356
|
+
const out = [];
|
|
357
|
+
for (const entry of entries) {
|
|
358
|
+
const m = entry.match(/^(\w+)\((.*)\)$/);
|
|
359
|
+
if (!m)
|
|
360
|
+
continue;
|
|
361
|
+
const lowerTool = CANONICAL_BY_ANTIGRAVITY_ACTION[m[1]];
|
|
362
|
+
if (!lowerTool)
|
|
363
|
+
continue;
|
|
364
|
+
const pattern = lowerTool === 'bash' ? denormalizeBashPattern(m[2]) : m[2];
|
|
365
|
+
out.push(canonicalRule(lowerTool, pattern));
|
|
366
|
+
}
|
|
367
|
+
return out;
|
|
368
|
+
};
|
|
369
|
+
return permissionSet(back(stringList(p.allow)), back(stringList(p.deny)));
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
grok: {
|
|
373
|
+
home: (h) => path.join(h, '.grok', 'config.toml'),
|
|
374
|
+
lossyBecause: 'canonical Write is written as Grok `edit`, so it reads back as Edit',
|
|
375
|
+
toCanonical(configPath) {
|
|
376
|
+
const config = readToml(configPath);
|
|
377
|
+
const permission = config?.permission;
|
|
378
|
+
if (!permission || typeof permission !== 'object' || Array.isArray(permission))
|
|
379
|
+
return null;
|
|
380
|
+
const rules = permission.rules;
|
|
381
|
+
if (!Array.isArray(rules))
|
|
382
|
+
return null;
|
|
383
|
+
const allow = [];
|
|
384
|
+
const deny = [];
|
|
385
|
+
for (const rule of rules) {
|
|
386
|
+
if (!rule || typeof rule !== 'object' || Array.isArray(rule))
|
|
387
|
+
continue;
|
|
388
|
+
const r = rule;
|
|
389
|
+
if (typeof r.tool !== 'string')
|
|
390
|
+
continue;
|
|
391
|
+
const lowerTool = CANONICAL_BY_GROK_TOOL[r.tool];
|
|
392
|
+
if (!lowerTool)
|
|
393
|
+
continue;
|
|
394
|
+
const raw = typeof r.pattern === 'string' ? r.pattern : null;
|
|
395
|
+
const pattern = raw === null ? null : lowerTool === 'bash' ? denormalizeBashPattern(raw) : raw;
|
|
396
|
+
const canonical = canonicalRule(lowerTool, pattern);
|
|
397
|
+
if (r.action === 'deny')
|
|
398
|
+
deny.push(canonical);
|
|
399
|
+
else if (r.action === 'allow')
|
|
400
|
+
allow.push(canonical);
|
|
401
|
+
}
|
|
402
|
+
return permissionSet(allow, deny);
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
kimi: {
|
|
406
|
+
home: (h) => path.join(h, '.kimi-code', 'config.toml'),
|
|
407
|
+
lossyBecause: 'each Bash arg-glob was written as two picomatch patterns, which collapse back to one rule',
|
|
408
|
+
toCanonical(configPath) {
|
|
409
|
+
const config = readToml(configPath);
|
|
410
|
+
const permission = config?.permission;
|
|
411
|
+
if (!permission || typeof permission !== 'object' || Array.isArray(permission))
|
|
412
|
+
return null;
|
|
413
|
+
const rules = permission.rules;
|
|
414
|
+
if (!Array.isArray(rules))
|
|
415
|
+
return null;
|
|
416
|
+
const allow = [];
|
|
417
|
+
const deny = [];
|
|
418
|
+
for (const rule of rules) {
|
|
419
|
+
if (!rule || typeof rule !== 'object' || Array.isArray(rule))
|
|
420
|
+
continue;
|
|
421
|
+
const r = rule;
|
|
422
|
+
if (typeof r.pattern !== 'string')
|
|
423
|
+
continue;
|
|
424
|
+
const canonical = kimiPatternToCanonical(r.pattern);
|
|
425
|
+
if (!canonical)
|
|
426
|
+
continue;
|
|
427
|
+
if (r.decision === 'deny')
|
|
428
|
+
deny.push(canonical);
|
|
429
|
+
else if (r.decision === 'allow')
|
|
430
|
+
allow.push(canonical);
|
|
431
|
+
}
|
|
432
|
+
return permissionSet(allow, deny);
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
droid: {
|
|
436
|
+
home: (h) => path.join(h, '.factory', 'settings.json'),
|
|
437
|
+
lossyBecause: 'Droid gates shell commands only, so non-Bash rules were never written',
|
|
438
|
+
toCanonical(configPath) {
|
|
439
|
+
const config = readJson(configPath);
|
|
440
|
+
if (!config)
|
|
441
|
+
return null;
|
|
442
|
+
const back = (commands) => commands.map((c) => (c === '*' ? 'Bash(*)' : `Bash(${denormalizeBashPattern(c)})`));
|
|
443
|
+
return permissionSet(back(stringList(config.commandAllowlist)), back(stringList(config.commandDenylist)));
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
copilot: {
|
|
447
|
+
home: (h) => path.join(h, '.copilot', 'permissions-config.json'),
|
|
448
|
+
lossyBecause: 'approvals are per working directory and read/write are whole-tool kinds with no path',
|
|
449
|
+
toCanonical(configPath) {
|
|
450
|
+
const config = readJson(configPath);
|
|
451
|
+
const locations = config?.locations;
|
|
452
|
+
if (!locations || typeof locations !== 'object' || Array.isArray(locations))
|
|
453
|
+
return null;
|
|
454
|
+
const allow = [];
|
|
455
|
+
// Copilot records approvals per location; the canonical set has no location
|
|
456
|
+
// axis, so every location's approvals union into one allow list.
|
|
457
|
+
for (const location of Object.values(locations)) {
|
|
458
|
+
if (!location || typeof location !== 'object' || Array.isArray(location))
|
|
459
|
+
continue;
|
|
460
|
+
const approvals = location.tool_approvals;
|
|
461
|
+
if (!Array.isArray(approvals))
|
|
462
|
+
continue;
|
|
463
|
+
for (const approval of approvals) {
|
|
464
|
+
if (!approval || typeof approval !== 'object' || Array.isArray(approval))
|
|
465
|
+
continue;
|
|
466
|
+
const a = approval;
|
|
467
|
+
if (a.kind === 'commands') {
|
|
468
|
+
for (const id of stringList(a.commandIdentifiers))
|
|
469
|
+
allow.push(`Bash(${id})`);
|
|
470
|
+
}
|
|
471
|
+
else if (a.kind === 'read') {
|
|
472
|
+
allow.push('Read(**)');
|
|
473
|
+
}
|
|
474
|
+
else if (a.kind === 'write') {
|
|
475
|
+
allow.push('Write(**)');
|
|
476
|
+
}
|
|
477
|
+
else if (a.kind === 'mcp' && typeof a.serverName === 'string') {
|
|
478
|
+
allow.push(`Mcp(${typeof a.toolName === 'string' ? `${a.serverName}.${a.toolName}` : a.serverName})`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// Copilot's config records approvals (grants) only — it has no deny list.
|
|
483
|
+
return permissionSet(allow, []);
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
kiro: {
|
|
487
|
+
home: (h) => path.join(h, '.kiro', 'settings', 'permissions.yaml'),
|
|
488
|
+
lossyBecause: 'Read/Grep/Glob share fs_read and Write/Edit/NotebookEdit share fs_write',
|
|
489
|
+
toCanonical(configPath) {
|
|
490
|
+
const config = readYaml(configPath);
|
|
491
|
+
const rules = config?.rules;
|
|
492
|
+
if (!Array.isArray(rules))
|
|
493
|
+
return null;
|
|
494
|
+
const allow = [];
|
|
495
|
+
const deny = [];
|
|
496
|
+
for (const rule of rules) {
|
|
497
|
+
if (!rule || typeof rule !== 'object' || Array.isArray(rule))
|
|
498
|
+
continue;
|
|
499
|
+
const r = rule;
|
|
500
|
+
if (typeof r.capability !== 'string')
|
|
501
|
+
continue;
|
|
502
|
+
const lowerTool = CANONICAL_BY_KIRO_CAPABILITY[r.capability];
|
|
503
|
+
if (!lowerTool)
|
|
504
|
+
continue;
|
|
505
|
+
const matches = stringList(r.match);
|
|
506
|
+
const canonicals = matches.length
|
|
507
|
+
? matches.map((m) => canonicalRule(lowerTool, lowerTool === 'bash' ? denormalizeBashPattern(m) : m))
|
|
508
|
+
: [canonicalRule(lowerTool, null)];
|
|
509
|
+
if (r.effect === 'deny')
|
|
510
|
+
deny.push(...canonicals);
|
|
511
|
+
else if (r.effect === 'allow')
|
|
512
|
+
allow.push(...canonicals);
|
|
513
|
+
}
|
|
514
|
+
return permissionSet(allow, deny);
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
openclaw: {
|
|
518
|
+
home: (h) => path.join(h, '.openclaw', 'openclaw.json'),
|
|
519
|
+
lossyBecause: 'OpenClaw gates whole tools, so only blanket rules were written and all read back as blanket',
|
|
520
|
+
toCanonical(configPath) {
|
|
521
|
+
const config = readJson(configPath);
|
|
522
|
+
const tools = config?.tools;
|
|
523
|
+
if (!tools || typeof tools !== 'object' || Array.isArray(tools))
|
|
524
|
+
return null;
|
|
525
|
+
const t = tools;
|
|
526
|
+
const back = (ids) => ids.flatMap((id) => {
|
|
527
|
+
const lowerTool = CANONICAL_BY_OPENCLAW_TOOL[id];
|
|
528
|
+
return lowerTool ? [canonicalRule(lowerTool, null)] : [];
|
|
529
|
+
});
|
|
530
|
+
// `tools.allow` is OpenClaw's absolute allowlist and is never written by
|
|
531
|
+
// agents-cli (see convertToOpenClawFormat), so it is not read back either.
|
|
532
|
+
return permissionSet(back(stringList(t.alsoAllow)), back(stringList(t.deny)));
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
hermes: {
|
|
536
|
+
home: (h) => path.join(h, '.hermes', 'config.yaml'),
|
|
537
|
+
lossyBecause: 'Hermes gates shell commands only, so non-Bash rules were never written',
|
|
538
|
+
toCanonical(configPath) {
|
|
539
|
+
const config = readYaml(configPath);
|
|
540
|
+
if (!config)
|
|
541
|
+
return null;
|
|
542
|
+
const approvals = config.approvals;
|
|
543
|
+
const denyList = approvals && typeof approvals === 'object' && !Array.isArray(approvals)
|
|
544
|
+
? stringList(approvals.deny)
|
|
545
|
+
: [];
|
|
546
|
+
const back = (commands) => commands.map((c) => (c === '*' ? 'Bash(*)' : `Bash(${denormalizeBashPattern(c)})`));
|
|
547
|
+
return permissionSet(back(stringList(config.command_allowlist)), back(denyList));
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Invert `kimiBashPatterns` + `canonicalToKimiRules`.
|
|
553
|
+
*
|
|
554
|
+
* Kimi writes a bare tool name for a blanket grant (`Bash`, `Read`), and expands
|
|
555
|
+
* one canonical `cmd:*` into TWO picomatch patterns (`Bash(cmd*)` and
|
|
556
|
+
* `Bash(cmd*/**)`) so slash-bearing arguments match. Both collapse back to the
|
|
557
|
+
* single canonical rule, and the caller dedupes.
|
|
558
|
+
*/
|
|
559
|
+
function kimiPatternToCanonical(pattern) {
|
|
560
|
+
const m = pattern.match(/^([\w-]+)\((.*)\)$/);
|
|
561
|
+
if (!m) {
|
|
562
|
+
// Bare tool name — a blanket grant, or an MCP tool id Kimi matches by name.
|
|
563
|
+
const lower = pattern.toLowerCase();
|
|
564
|
+
return lower in CANONICAL_TOOL_CASE ? canonicalRule(lower, null) : pattern;
|
|
565
|
+
}
|
|
566
|
+
const lowerTool = m[1].toLowerCase();
|
|
567
|
+
let arg = m[2];
|
|
568
|
+
if (lowerTool === 'bash') {
|
|
569
|
+
if (arg.endsWith('*/**'))
|
|
570
|
+
arg = arg.slice(0, -'*/**'.length) + ':*';
|
|
571
|
+
else if (arg.endsWith('*'))
|
|
572
|
+
arg = arg.slice(0, -1) + ':*';
|
|
573
|
+
if (arg === ':*')
|
|
574
|
+
return 'Bash(*)';
|
|
575
|
+
}
|
|
576
|
+
return canonicalRule(lowerTool, arg);
|
|
577
|
+
}
|
|
578
|
+
/** The registry entry for `agent`, or undefined when it stores no permissions. */
|
|
579
|
+
export function permissionTarget(agent) {
|
|
580
|
+
return PERMISSION_TARGETS[agent];
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Read `agent`'s permissions from `home` (a version home or the real HOME) and
|
|
584
|
+
* project them to canonical form. `scope: 'project'` reads the repo-local file
|
|
585
|
+
* for the harnesses that have one, and returns null for those that do not.
|
|
586
|
+
*/
|
|
587
|
+
export function readCanonicalPermissions(agent, scope = 'user', cwd, home) {
|
|
588
|
+
const target = PERMISSION_TARGETS[agent];
|
|
589
|
+
if (!target)
|
|
590
|
+
return null;
|
|
591
|
+
if (scope === 'project') {
|
|
592
|
+
if (!target.project)
|
|
593
|
+
return null;
|
|
594
|
+
return target.toCanonical(target.project(cwd ?? process.cwd()));
|
|
595
|
+
}
|
|
596
|
+
// os.homedir() -- not `process.env.HOME ?? ''`, which resolved a RELATIVE
|
|
597
|
+
// path (`.grok/config.toml`) when HOME is unset, as it is on Windows.
|
|
598
|
+
return target.toCanonical(target.home(home ?? os.homedir()));
|
|
599
|
+
}
|
|
@@ -165,15 +165,6 @@ export declare function convertToAntigravityFormat(set: PermissionSet): {
|
|
|
165
165
|
deny?: string[];
|
|
166
166
|
};
|
|
167
167
|
};
|
|
168
|
-
export interface GoosePermissionConfig {
|
|
169
|
-
user: {
|
|
170
|
-
always_allow: string[];
|
|
171
|
-
ask_before: string[];
|
|
172
|
-
never_allow: string[];
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/** Convert canonical permissions to Goose's per-tool permission.yaml shape. */
|
|
176
|
-
export declare function convertToGooseFormat(set: PermissionSet): GoosePermissionConfig;
|
|
177
168
|
/**
|
|
178
169
|
* Convert canonical permission set to Grok format.
|
|
179
170
|
* Grok reads ~/.grok/config.toml with
|
|
@@ -260,11 +251,21 @@ export declare function mergeCodexSandboxWrite(existing: Record<string, unknown>
|
|
|
260
251
|
*/
|
|
261
252
|
export declare function convertToCodexFormat(set: PermissionSet, cwd?: string): CodexPermissions;
|
|
262
253
|
/**
|
|
263
|
-
* Read agent
|
|
254
|
+
* Read an agent's currently installed permissions.
|
|
255
|
+
*
|
|
256
|
+
* claude/opencode/codex return their NATIVE shape, because `agents permissions
|
|
257
|
+
* list` renders those three specially — Codex especially, whose config records a
|
|
258
|
+
* sandbox mode rather than a rule list, so its own fields say more than the
|
|
259
|
+
* blanket grants that mode widens into.
|
|
260
|
+
*
|
|
261
|
+
* Every other allowlist-capable harness returns the canonical `PermissionSet`
|
|
262
|
+
* that `PERMISSION_TARGETS` reads back. Before RUSH-2676 they returned `null`,
|
|
263
|
+
* so permissions written for cursor, antigravity, grok, kimi, droid,
|
|
264
|
+
* copilot, kiro, openclaw and hermes were reported as absent.
|
|
264
265
|
*/
|
|
265
266
|
export declare function readAgentPermissions(agentId: AgentId, scope?: 'user' | 'project', cwd?: string, options?: {
|
|
266
267
|
home?: string;
|
|
267
|
-
}): ClaudePermissions | OpenCodePermissions | CodexPermissions | null;
|
|
268
|
+
}): ClaudePermissions | OpenCodePermissions | CodexPermissions | PermissionSet | null;
|
|
268
269
|
/**
|
|
269
270
|
* Apply a permission set to Claude's settings.json.
|
|
270
271
|
*/
|
|
@@ -300,10 +301,20 @@ export declare function openCodeToCanonical(perms: OpenCodePermissions): Permiss
|
|
|
300
301
|
*/
|
|
301
302
|
export declare function codexToCanonical(perms: CodexPermissions): PermissionSet;
|
|
302
303
|
/**
|
|
303
|
-
* Export permissions from a specific config file path to canonical format
|
|
304
|
-
*
|
|
304
|
+
* Export permissions from a specific config file path to canonical format,
|
|
305
|
+
* auto-detecting the harness from the path.
|
|
306
|
+
*
|
|
307
|
+
* Detection walks `PERMISSION_TARGETS` and matches each harness's own declared
|
|
308
|
+
* filename + parent directory, so it covers all 13 rather than the three
|
|
309
|
+
* hardcoded `.claude`/`.opencode`/`.codex` fragments it used to know about.
|
|
305
310
|
*/
|
|
306
311
|
export declare function exportPermissionsFromPath(filePath: string): PermissionSet | null;
|
|
312
|
+
/**
|
|
313
|
+
* Which harness owns `filePath`, by comparing against the trailing path segments
|
|
314
|
+
* each registry target declares. Longer (more specific) suffixes win, so
|
|
315
|
+
* `.kiro/settings/permissions.yaml` is never mistaken for a bare `permissions.yaml`.
|
|
316
|
+
*/
|
|
317
|
+
export declare function detectPermissionAgentFromPath(filePath: string): AgentId | null;
|
|
307
318
|
/**
|
|
308
319
|
* Get the default permission set from central storage.
|
|
309
320
|
*/
|