@phnx-labs/agents-cli 1.22.39 → 1.22.41
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 +316 -0
- package/README.md +116 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -27
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +259 -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.d.ts +15 -0
- package/dist/commands/browser.js +318 -131
- 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 +16 -3
- 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 +160 -215
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +12 -23
- 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 +158 -159
- 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 +14 -0
- package/dist/commands/sessions-picker.js +209 -13
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-share.d.ts +25 -0
- package/dist/commands/sessions-share.js +166 -0
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +144 -180
- package/dist/commands/setup-browser.js +1 -1
- 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-preferences.js +2 -2
- 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 +186 -64
- 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 +25 -34
- 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 +5 -1
- package/dist/lib/browser/chrome.js +12 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +3 -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 +69 -5
- package/dist/lib/browser/profiles.js +135 -13
- 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 +137 -2
- package/dist/lib/browser/service.js +492 -54
- 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 +19 -1
- 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 +2 -1
- package/dist/lib/config-keys.js +8 -4
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +5 -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 +104 -0
- package/dist/lib/daemon-webhooks.js +215 -0
- package/dist/lib/device-config.d.ts +85 -75
- package/dist/lib/device-config.js +280 -142
- 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 +10 -5
- package/dist/lib/devices/pool.js +5 -7
- 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 +4 -4
- package/dist/lib/exec.js +11 -11
- 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} +13 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
- 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 +3 -3
- package/dist/lib/observe-aliases.js +3 -21
- 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-key.js +7 -0
- 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 +261 -67
- 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 +4 -4
- package/dist/lib/secrets/bundles.js +8 -8
- package/dist/lib/secrets/headless.d.ts +16 -0
- package/dist/lib/secrets/headless.js +21 -0
- 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 +21 -17
- package/dist/lib/secrets/remote.js +39 -23
- 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/share-html.d.ts +55 -0
- package/dist/lib/session/share-html.js +319 -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/settings-manifest.d.ts +2 -0
- package/dist/lib/settings-manifest.js +81 -3
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +120 -0
- package/dist/lib/share/publish.js +243 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +4 -4
- package/dist/lib/smart-launch.js +6 -4
- 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 +6 -147
- package/dist/lib/startup/command-registry.js +40 -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 +38 -3
- package/dist/lib/triggers/handlers.js +58 -7
- package/dist/lib/triggers/webhook.d.ts +113 -5
- package/dist/lib/triggers/webhook.js +223 -44
- package/dist/lib/types.d.ts +19 -7
- 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/dist/lib/wrap.d.ts +33 -0
- package/dist/lib/wrap.js +70 -0
- 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
|
@@ -4,7 +4,7 @@ const SHELL_WRAPPERS = new Set(['bash', 'sh', 'zsh', 'dash', 'ksh']);
|
|
|
4
4
|
const PROGRAM_WRAPPERS = new Set(['command', 'builtin', 'env', 'nohup', 'sudo']);
|
|
5
5
|
const MAX_NESTED_DEPTH = 3;
|
|
6
6
|
const SUDO_OPTIONS_WITH_VALUE = new Set([
|
|
7
|
-
'-C', '--close-from', '-D', '--chdir', '-g', '--group', '-h', '--
|
|
7
|
+
'-C', '--close-from', '-D', '--chdir', '-g', '--group', '-h', '--device',
|
|
8
8
|
'-p', '--prompt', '-R', '--chroot', '-r', '--role', '-t', '--type',
|
|
9
9
|
'-T', '--command-timeout', '-u', '--user',
|
|
10
10
|
]);
|
|
@@ -208,15 +208,15 @@ const GH_ISSUE_URL_RE = /https:\/\/github\.com\/[^\s"'()<>]+\/issues\/(\d+)/;
|
|
|
208
208
|
* Flags of `teams create` / `teams add` that take a value, so the value is not
|
|
209
209
|
* mistaken for the positional team name. Mirrors their value-taking flags in
|
|
210
210
|
* `commands/teams.ts` — most are `.option('… <x>')` registrations, but
|
|
211
|
-
* `--device
|
|
212
|
-
* `.option(` alone would wrongly drop
|
|
211
|
+
* `--device` comes from `addHostOption`, so auditing this list against
|
|
212
|
+
* `.option(` alone would wrongly drop it. A flag missing here degrades to "no
|
|
213
213
|
* team detected", never to a wrong one.
|
|
214
214
|
*/
|
|
215
215
|
const TEAM_VALUE_FLAGS = [
|
|
216
216
|
'-d', '--description', '--use-worktree', '--devices', '--hosts', '--repo',
|
|
217
217
|
'-n', '--name', '-m', '--mode', '-e', '--effort', '--model', '--env',
|
|
218
218
|
'--cwd', '--worktree', '--after', '--task-type', '--cloud', '--branch',
|
|
219
|
-
'--device',
|
|
219
|
+
'--device',
|
|
220
220
|
];
|
|
221
221
|
/**
|
|
222
222
|
* One flag value: a quoted string or a bare token. `-d "sessions lineage"` is the
|
|
@@ -319,11 +319,11 @@ export function detectSpawnedTeam(command) {
|
|
|
319
319
|
if (!m)
|
|
320
320
|
return undefined;
|
|
321
321
|
const name = m[1];
|
|
322
|
-
// A single character is a doc placeholder (`agents teams create t --
|
|
322
|
+
// A single character is a doc placeholder (`agents teams create t --device <box>`)
|
|
323
323
|
// far more often than a real team, and an English article is prose. Both used to
|
|
324
324
|
// land in the index as a team name, and now that the name is rendered on the row
|
|
325
325
|
// a wrong one is worse than none.
|
|
326
|
-
// A single character is a doc placeholder (`agents teams create t --
|
|
326
|
+
// A single character is a doc placeholder (`agents teams create t --device <name>`)
|
|
327
327
|
// far more often than a real team; an all-digits token is a flag value or a list
|
|
328
328
|
// index that leaked through, never a name someone typed. Both had reached the
|
|
329
329
|
// index, and now that the name is rendered a wrong one is worse than none.
|
|
@@ -69,7 +69,7 @@ export declare function filterTeamSessions(sessions: SessionMeta[], showTeams: b
|
|
|
69
69
|
* record backs the origin ({@link TeamOrigin.source} === `'meta'`).
|
|
70
70
|
*
|
|
71
71
|
* `source` is newer than the rest of {@link TeamOrigin}, so a row that arrived
|
|
72
|
-
* from a pre-`source` peer over the `--
|
|
72
|
+
* from a pre-`source` peer over the `--device` fan-out carries none. There the
|
|
73
73
|
* meta-only fields settle it: the entrypoint fallback is a bare `{ handle }`, so
|
|
74
74
|
* any `team` / `mode` / `parentSessionId` / `startedAt` means a real teammate
|
|
75
75
|
* record produced it — otherwise a genuine teammate from an unupgraded peer
|
|
@@ -184,7 +184,7 @@ export function filterTeamSessions(sessions, showTeams) {
|
|
|
184
184
|
* record backs the origin ({@link TeamOrigin.source} === `'meta'`).
|
|
185
185
|
*
|
|
186
186
|
* `source` is newer than the rest of {@link TeamOrigin}, so a row that arrived
|
|
187
|
-
* from a pre-`source` peer over the `--
|
|
187
|
+
* from a pre-`source` peer over the `--device` fan-out carries none. There the
|
|
188
188
|
* meta-only fields settle it: the entrypoint fallback is a bare `{ handle }`, so
|
|
189
189
|
* any `team` / `mode` / `parentSessionId` / `startedAt` means a real teammate
|
|
190
190
|
* record produced it — otherwise a genuine teammate from an unupgraded peer
|
|
@@ -173,11 +173,11 @@ export interface SessionMeta {
|
|
|
173
173
|
gitBranch?: string;
|
|
174
174
|
messageCount?: number;
|
|
175
175
|
tokenCount?: number;
|
|
176
|
-
/** Real generated (output) tokens — excludes cache-read/-write context (issue: `agents output`). */
|
|
176
|
+
/** Real generated (output) tokens — excludes cache-read/-write context (issue: `agents insights output`). */
|
|
177
177
|
outputTokens?: number;
|
|
178
178
|
/**
|
|
179
179
|
* Uncached input tokens, cache-read tokens, and cache-write (cache-creation)
|
|
180
|
-
* tokens — the burn split `agents output` reports, kept only for harnesses that
|
|
180
|
+
* tokens — the burn split `agents insights output` reports, kept only for harnesses that
|
|
181
181
|
* record a per-message cache split (Claude/Codex/Gemini/Droid). Undefined for
|
|
182
182
|
* harnesses that expose no split (RUSH-2287).
|
|
183
183
|
*/
|
|
@@ -188,7 +188,7 @@ export interface SessionMeta {
|
|
|
188
188
|
costUsd?: number;
|
|
189
189
|
/**
|
|
190
190
|
* USD cost priced as if caching were off — cache read/write billed at the full
|
|
191
|
-
* input rate. Backs `agents output --pricing no-cache` (RUSH-2287). Undefined
|
|
191
|
+
* input rate. Backs `agents insights output --pricing no-cache` (RUSH-2287). Undefined
|
|
192
192
|
* when the harness records no cache split (then no-cache == actual by definition).
|
|
193
193
|
*/
|
|
194
194
|
costUsdNoCache?: number;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `String.length` is the wrong ruler for a terminal: it over-counts ANSI colour
|
|
5
5
|
* escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
|
|
6
6
|
* two cells. The result is the drifting, wrapping session-table line users see
|
|
7
|
-
* under tmux and over `--
|
|
7
|
+
* under tmux and over `--device` SSH. Every renderer that sizes a session-table
|
|
8
8
|
* cell measures and truncates through this module so alignment is computed once,
|
|
9
9
|
* correctly, from the same source of truth.
|
|
10
10
|
*/
|
|
@@ -22,7 +22,7 @@ export declare function truncateToWidth(s: string, max: number): string;
|
|
|
22
22
|
export declare function padToWidth(s: string, width: number): string;
|
|
23
23
|
/**
|
|
24
24
|
* Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
|
|
25
|
-
* `--
|
|
25
|
+
* `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
|
|
26
26
|
* the TTY's reported width, then to `fallback`. Clamped to a sane band so a
|
|
27
27
|
* bogus value can't produce a 0-wide or absurdly long table.
|
|
28
28
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `String.length` is the wrong ruler for a terminal: it over-counts ANSI colour
|
|
5
5
|
* escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
|
|
6
6
|
* two cells. The result is the drifting, wrapping session-table line users see
|
|
7
|
-
* under tmux and over `--
|
|
7
|
+
* under tmux and over `--device` SSH. Every renderer that sizes a session-table
|
|
8
8
|
* cell measures and truncates through this module so alignment is computed once,
|
|
9
9
|
* correctly, from the same source of truth.
|
|
10
10
|
*/
|
|
@@ -88,7 +88,7 @@ export function padToWidth(s, width) {
|
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
90
|
* Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
|
|
91
|
-
* `--
|
|
91
|
+
* `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
|
|
92
92
|
* the TTY's reported width, then to `fallback`. Clamped to a sane band so a
|
|
93
93
|
* bogus value can't produce a 0-wide or absurdly long table.
|
|
94
94
|
*/
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* version home. It never overwrites a value the target already has: scalars
|
|
14
14
|
* keep the target's value, objects merge recursively, arrays union. That makes
|
|
15
15
|
* the operation idempotent and safe to run on every `agents add` / `agents use`.
|
|
16
|
+
* (One scoped exception: the 'claude-trust' strategy promotes a stamped-default
|
|
17
|
+
* `hasTrustDialogAccepted: false` to `true` — see the note on that entry.)
|
|
16
18
|
*/
|
|
17
19
|
import type { AgentId } from './types.js';
|
|
18
20
|
export interface CarryForwardResult {
|
|
@@ -13,16 +13,26 @@
|
|
|
13
13
|
* version home. It never overwrites a value the target already has: scalars
|
|
14
14
|
* keep the target's value, objects merge recursively, arrays union. That makes
|
|
15
15
|
* the operation idempotent and safe to run on every `agents add` / `agents use`.
|
|
16
|
+
* (One scoped exception: the 'claude-trust' strategy promotes a stamped-default
|
|
17
|
+
* `hasTrustDialogAccepted: false` to `true` — see the note on that entry.)
|
|
16
18
|
*/
|
|
17
19
|
import * as fs from 'fs';
|
|
18
20
|
import * as path from 'path';
|
|
19
21
|
import * as TOML from 'smol-toml';
|
|
22
|
+
import { atomicWriteFileSync } from './fs-atomic.js';
|
|
20
23
|
import { getBackupsDir } from './state.js';
|
|
21
24
|
const SETTINGS_MANIFEST = {
|
|
22
25
|
claude: [
|
|
23
26
|
{ rel: '.claude/settings.json', strategy: 'json-merge' },
|
|
24
27
|
{ rel: '.claude/settings.local.json', strategy: 'copy-if-absent' },
|
|
25
28
|
{ rel: '.claude/keybindings.json', strategy: 'copy-if-absent' },
|
|
29
|
+
// `.claude.json` holds the login (oauthAccount) and per-session stats, so it
|
|
30
|
+
// must never merge wholesale — but it is also where Claude records workspace
|
|
31
|
+
// trust (`projects[<path>].hasTrustDialogAccepted`). Without carrying that,
|
|
32
|
+
// every newly pinned version re-shows the trust dialog once per project
|
|
33
|
+
// (issue #2776). The 'claude-trust' strategy projects ONLY the trust flags
|
|
34
|
+
// out of the source file; credentials and stats stay per-version.
|
|
35
|
+
{ rel: '.claude.json', strategy: 'claude-trust' },
|
|
26
36
|
],
|
|
27
37
|
codex: [
|
|
28
38
|
{
|
|
@@ -33,9 +43,10 @@ const SETTINGS_MANIFEST = {
|
|
|
33
43
|
// `.codex/auth.json` is deliberately NOT carried forward. Copying it seeded
|
|
34
44
|
// every new Codex version with the current default's ChatGPT token, so two
|
|
35
45
|
// installed versions always reported the same account and could never sign
|
|
36
|
-
// into separate accounts. Claude
|
|
37
|
-
//
|
|
38
|
-
//
|
|
46
|
+
// into separate accounts. Claude never merges `.claude.json` for the same
|
|
47
|
+
// reason (its 'claude-trust' entry extracts only the trust flags) — a
|
|
48
|
+
// version home holds its own login, keeping accounts per-version. A fresh
|
|
49
|
+
// Codex version installs signed-out; run `codex login`
|
|
39
50
|
// (or `agents run codex --version <v>`) inside it to authenticate.
|
|
40
51
|
{ rel: '.codex/instructions.md', strategy: 'copy-if-absent' },
|
|
41
52
|
{ rel: '.codex/hooks.json', strategy: 'copy-if-absent' },
|
|
@@ -70,6 +81,21 @@ export function fillGaps(target, source) {
|
|
|
70
81
|
}
|
|
71
82
|
return out;
|
|
72
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Project paths the source `.claude.json` records an accepted trust dialog for.
|
|
86
|
+
* Only an explicit `true` counts: Claude Code never persists a decline (the
|
|
87
|
+
* dialog exits without writing), so `false` is only ever the stamped default —
|
|
88
|
+
* not a user decision worth propagating. Verified against Claude Code
|
|
89
|
+
* 2.1.219/2.1.220 (decline paths exit via code 1 / code 0 without a config
|
|
90
|
+
* write); if a future Claude Code starts persisting declines, this premise —
|
|
91
|
+
* and the false→true promotion in the 'claude-trust' case — must be revisited.
|
|
92
|
+
*/
|
|
93
|
+
function trustedClaudeProjects(source) {
|
|
94
|
+
const projects = isPlainObject(source.projects) ? source.projects : {};
|
|
95
|
+
return Object.entries(projects)
|
|
96
|
+
.filter(([, project]) => isPlainObject(project) && project.hasTrustDialogAccepted === true)
|
|
97
|
+
.map(([projectPath]) => projectPath);
|
|
98
|
+
}
|
|
73
99
|
function stripStateKeys(obj, stateKeys) {
|
|
74
100
|
if (!stateKeys?.length)
|
|
75
101
|
return obj;
|
|
@@ -128,6 +154,58 @@ export function carryForwardSettings(agent, fromHome, toHome) {
|
|
|
128
154
|
result.applied.push(entry.rel);
|
|
129
155
|
break;
|
|
130
156
|
}
|
|
157
|
+
case 'claude-trust': {
|
|
158
|
+
// Projection, not a merge: pull ONLY `projects[<path>].hasTrustDialogAccepted`
|
|
159
|
+
// out of the source `.claude.json`. Everything else in that file
|
|
160
|
+
// (oauthAccount, onboarding state, per-session stats) stays per-version.
|
|
161
|
+
// Trust granted anywhere wins over the target's stamped-default `false`
|
|
162
|
+
// (headless runs create project entries with the flag unset-as-false
|
|
163
|
+
// without ever showing the dialog), but a target entry's other keys
|
|
164
|
+
// are preserved untouched.
|
|
165
|
+
const source = JSON.parse(fs.readFileSync(sourcePath, 'utf-8'));
|
|
166
|
+
const trusted = trustedClaudeProjects(source);
|
|
167
|
+
if (trusted.length === 0)
|
|
168
|
+
break;
|
|
169
|
+
const targetExists = fs.existsSync(targetPath);
|
|
170
|
+
const parsedTarget = targetExists
|
|
171
|
+
? JSON.parse(fs.readFileSync(targetPath, 'utf-8'))
|
|
172
|
+
: {};
|
|
173
|
+
// A target that isn't an object (or whose `projects` isn't) is not
|
|
174
|
+
// ours to repair — skip rather than clobber it with a rebuilt shape.
|
|
175
|
+
if (!isPlainObject(parsedTarget))
|
|
176
|
+
break;
|
|
177
|
+
const targetObj = parsedTarget;
|
|
178
|
+
if ('projects' in targetObj && !isPlainObject(targetObj.projects))
|
|
179
|
+
break;
|
|
180
|
+
const targetProjects = isPlainObject(targetObj.projects) ? { ...targetObj.projects } : {};
|
|
181
|
+
let changed = false;
|
|
182
|
+
for (const projectPath of trusted) {
|
|
183
|
+
const existing = isPlainObject(targetProjects[projectPath])
|
|
184
|
+
? targetProjects[projectPath]
|
|
185
|
+
: {};
|
|
186
|
+
if (existing.hasTrustDialogAccepted === true)
|
|
187
|
+
continue;
|
|
188
|
+
targetProjects[projectPath] = { ...existing, hasTrustDialogAccepted: true };
|
|
189
|
+
changed = true;
|
|
190
|
+
}
|
|
191
|
+
if (!changed)
|
|
192
|
+
break;
|
|
193
|
+
if (targetExists) {
|
|
194
|
+
backupFile(backupRoot, toHome, entry.rel);
|
|
195
|
+
result.backupDir = backupRoot;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
// Atomic (tmp + rename): a running Claude session rewrites this exact
|
|
201
|
+
// file (it holds the login and session stats), so a plain write risks
|
|
202
|
+
// a reader seeing a partial file. The OUTSIDE `.claude.json` is the
|
|
203
|
+
// real file (the INSIDE `.claude/.claude.json` symlink resolves to it
|
|
204
|
+
// and survives the rename).
|
|
205
|
+
atomicWriteFileSync(targetPath, JSON.stringify({ ...targetObj, projects: targetProjects }, null, 2) + '\n');
|
|
206
|
+
result.applied.push(entry.rel);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
131
209
|
case 'json-merge':
|
|
132
210
|
case 'toml-merge': {
|
|
133
211
|
const parse = entry.strategy === 'json-merge'
|
|
@@ -8,6 +8,12 @@ export type DeleteFn = (url: string, headers: Record<string, string>) => Promise
|
|
|
8
8
|
export type CheckFn = (url: string) => Promise<{
|
|
9
9
|
status: number;
|
|
10
10
|
}>;
|
|
11
|
+
/** DI seam for tests — override the real HTTP GET of the revisions listing route. */
|
|
12
|
+
export type RevisionsFetchFn = (url: string) => Promise<{
|
|
13
|
+
status: number;
|
|
14
|
+
contentType: string;
|
|
15
|
+
body: string;
|
|
16
|
+
}>;
|
|
11
17
|
export interface DeleteEndpoint {
|
|
12
18
|
baseUrl: string;
|
|
13
19
|
token: string;
|
|
@@ -59,6 +65,11 @@ export declare function deleteObject(endpoint: DeleteEndpoint, key: string, opts
|
|
|
59
65
|
export interface DeleteShareOptions {
|
|
60
66
|
/** Skip deleting the sibling `<slug>.png` OG cover (default: delete it too). */
|
|
61
67
|
keepCover?: boolean;
|
|
68
|
+
/** Skip deleting the target's retained revisions (`<key>/rev-*`, RUSH-2683
|
|
69
|
+
* revision retention) — default: delete them too. A republished-then-deleted
|
|
70
|
+
* share would otherwise leave its prior world-readable versions live for up
|
|
71
|
+
* to the bucket's lifecycle max-age (see docs/share.md §Revisions). */
|
|
72
|
+
keepRevisions?: boolean;
|
|
62
73
|
/** Treat an already-missing target as a no-op success instead of an error
|
|
63
74
|
* (mirrors SQL's `DROP ... IF EXISTS`). Default: missing target is an error. */
|
|
64
75
|
ifExists?: boolean;
|
|
@@ -72,6 +83,8 @@ export interface DeleteShareOptions {
|
|
|
72
83
|
deleter?: DeleteFn;
|
|
73
84
|
/** DI seam for tests — override the real HTTP existence check. */
|
|
74
85
|
checker?: CheckFn;
|
|
86
|
+
/** DI seam for tests — override the real HTTP GET of the revisions listing route. */
|
|
87
|
+
fetchRevisions?: RevisionsFetchFn;
|
|
75
88
|
}
|
|
76
89
|
export interface DeleteShareResult {
|
|
77
90
|
key: string;
|
|
@@ -86,6 +99,14 @@ export interface DeleteShareResult {
|
|
|
86
99
|
existedBefore: boolean;
|
|
87
100
|
verified404: boolean;
|
|
88
101
|
};
|
|
102
|
+
/** Retained revisions of this target that were also deleted (omitted when
|
|
103
|
+
* there were none, or `keepRevisions` was passed). */
|
|
104
|
+
revisions?: Array<{
|
|
105
|
+
key: string;
|
|
106
|
+
url: string;
|
|
107
|
+
existedBefore: boolean;
|
|
108
|
+
verified404: boolean;
|
|
109
|
+
}>;
|
|
89
110
|
}
|
|
90
111
|
/** Delete one share target (page + by default its OG cover) and verify both
|
|
91
112
|
* are gone. Throws on an unverified takedown — never reports success for an
|
package/dist/lib/share/delete.js
CHANGED
|
@@ -61,6 +61,33 @@ async function defaultDelete(url, headers) {
|
|
|
61
61
|
const res = await fetch(url, { method: 'DELETE', headers });
|
|
62
62
|
return { ok: res.ok, status: res.status };
|
|
63
63
|
}
|
|
64
|
+
async function defaultRevisionsFetch(url) {
|
|
65
|
+
const res = await fetch(url, { headers: { accept: 'application/json' } });
|
|
66
|
+
return { status: res.status, contentType: res.headers.get('content-type') ?? '', body: await res.text() };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* List the R2 keys of a slug's retained revisions via the Worker's
|
|
70
|
+
* `?revisions=json` route (worker-template.ts `renderRevisions`). Best-effort:
|
|
71
|
+
* any failure to reach or parse the route (an endpoint provisioned before
|
|
72
|
+
* revisions existed, a network blip) yields an empty list rather than
|
|
73
|
+
* throwing — purging revisions is a safety improvement on top of the primary
|
|
74
|
+
* delete contract (take the canonical page down), never a reason to fail it.
|
|
75
|
+
*/
|
|
76
|
+
async function listRevisionKeys(endpoint, key, fetchRevisions) {
|
|
77
|
+
try {
|
|
78
|
+
const url = `${endpoint.baseUrl.replace(/\/+$/, '')}/${key}?revisions=json`;
|
|
79
|
+
const res = await fetchRevisions(url);
|
|
80
|
+
if (res.status !== 200 || !/application\/json/i.test(res.contentType))
|
|
81
|
+
return [];
|
|
82
|
+
const data = JSON.parse(res.body);
|
|
83
|
+
if (!Array.isArray(data.revisions))
|
|
84
|
+
return [];
|
|
85
|
+
return data.revisions.map((r) => String(r.key ?? '')).filter(Boolean);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
64
91
|
/**
|
|
65
92
|
* Delete one R2 object behind the share Worker and assert the postcondition.
|
|
66
93
|
* `{"ok":true}` from the Worker is not evidence a page came down — R2 delete is
|
|
@@ -123,5 +150,20 @@ export async function deleteShare(target, opts = {}) {
|
|
|
123
150
|
throw new Error(`Cover delete reported success but ${cover.url} still resolves — takedown NOT verified. Retry, or pass --keep-cover and delete it manually.`);
|
|
124
151
|
}
|
|
125
152
|
}
|
|
153
|
+
if (!opts.keepRevisions) {
|
|
154
|
+
const revisionKeys = await listRevisionKeys(endpoint, resolved.key, opts.fetchRevisions ?? defaultRevisionsFetch);
|
|
155
|
+
if (revisionKeys.length > 0) {
|
|
156
|
+
const revisions = [];
|
|
157
|
+
for (const revisionKey of revisionKeys) {
|
|
158
|
+
const rev = await deleteObject(endpoint, revisionKey, { deleter: opts.deleter, checker: opts.checker });
|
|
159
|
+
revisions.push({ key: rev.key, url: rev.url, existedBefore: rev.existedBefore, verified404: rev.verified404 });
|
|
160
|
+
}
|
|
161
|
+
result.revisions = revisions;
|
|
162
|
+
const stillUp = revisions.filter((r) => r.existedBefore && !r.verified404);
|
|
163
|
+
if (stillUp.length > 0) {
|
|
164
|
+
throw new Error(`Delete reported success but ${stillUp.length} retained revision(s) still resolve — takedown NOT verified. Retry, or pass --keep-revisions and delete them manually.`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
126
168
|
return result;
|
|
127
169
|
}
|
|
@@ -45,6 +45,27 @@ export interface PublishOptions {
|
|
|
45
45
|
uploader?: PutFn;
|
|
46
46
|
/** DI seam for tests — override cover capture (returns a PNG buffer or null). */
|
|
47
47
|
capturer?: (htmlPath: string) => Promise<Buffer | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Human display title, shown instead of the slug in the gallery and
|
|
50
|
+
* `agents artifacts share list`. When omitted, one is derived (HTML `<title>`,
|
|
51
|
+
* else a Markdown frontmatter `title:`, else the filename) — a share always
|
|
52
|
+
* carries a label, never a blocking prompt (see {@link deriveLabel}).
|
|
53
|
+
*/
|
|
54
|
+
label?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Structured metadata (`--meta key=value`, repeatable). Keys are validated by
|
|
57
|
+
* {@link parseMetaEntries} — lowercase `[a-z0-9-]`, and may not collide with
|
|
58
|
+
* {@link RESERVED_META_KEYS}, which the CLI sets automatically.
|
|
59
|
+
*/
|
|
60
|
+
meta?: Record<string, string>;
|
|
61
|
+
/**
|
|
62
|
+
* Skip revision retention on this publish — overwrite an existing slug's
|
|
63
|
+
* object in place with no `<slug>/rev-<ts>` backup of the version it replaces
|
|
64
|
+
* (default: keep it; see docs/share.md §Revisions).
|
|
65
|
+
*/
|
|
66
|
+
noRevision?: boolean;
|
|
67
|
+
/** DI seam for tests — override provenance auto-capture (agent/session/host/repo/date). */
|
|
68
|
+
provenance?: ShareProvenance;
|
|
48
69
|
}
|
|
49
70
|
export interface PublishResult {
|
|
50
71
|
url: string;
|
|
@@ -52,7 +73,87 @@ export interface PublishResult {
|
|
|
52
73
|
coverUrl?: string;
|
|
53
74
|
/** True when the page was published with `visibility=unlisted`. */
|
|
54
75
|
unlisted?: boolean;
|
|
76
|
+
/** The label stored with this share — explicit (`--label`) or derived. */
|
|
77
|
+
label?: string;
|
|
78
|
+
/** Whether `label` came from `--label` or was auto-derived. */
|
|
79
|
+
labelSource?: 'explicit' | 'derived';
|
|
80
|
+
}
|
|
81
|
+
export interface ShareProvenance {
|
|
82
|
+
/** Harness/agent name (`AGENTS_AGENT_NAME`), when publishing from an agent run. */
|
|
83
|
+
agent?: string;
|
|
84
|
+
/** Session id (`AGENTS_SESSION_ID` / `AGENT_SESSION_ID`), when publishing from an agent run. */
|
|
85
|
+
session?: string;
|
|
86
|
+
/** The machine the publish ran from (`os.hostname()`) — always present. */
|
|
87
|
+
host?: string;
|
|
88
|
+
/** git repo name at publish time, absent outside a git checkout — never invented. */
|
|
89
|
+
repo?: string;
|
|
90
|
+
/** ISO date (`yyyy-mm-dd`) this publish happened, from the local clock. */
|
|
91
|
+
date?: string;
|
|
55
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Reserved `customMetadata` keys the CLI sets automatically from the exec env,
|
|
95
|
+
* git, and the local clock (plus `label`/`label-source`) — a `--meta key=value`
|
|
96
|
+
* may not target any of these (see {@link parseMetaEntries}).
|
|
97
|
+
*/
|
|
98
|
+
export declare const RESERVED_META_KEYS: readonly ["agent", "session", "host", "repo", "date", "label", "label-source"];
|
|
99
|
+
/**
|
|
100
|
+
* Auto-capture publish provenance from the exec env, git, and the local clock.
|
|
101
|
+
* Every field is present only when the environment genuinely carries it — a
|
|
102
|
+
* human running the command by hand outside a git repo yields `session`/`agent`/
|
|
103
|
+
* `repo` all undefined, never an invented value. `host` is always present
|
|
104
|
+
* (`os.hostname()` never fails to return something real about where the publish
|
|
105
|
+
* ran, so it isn't "invented" in the same sense).
|
|
106
|
+
*/
|
|
107
|
+
export declare function resolveShareProvenance(opts?: {
|
|
108
|
+
env?: NodeJS.ProcessEnv;
|
|
109
|
+
hostname?: string;
|
|
110
|
+
dir?: string;
|
|
111
|
+
now?: Date;
|
|
112
|
+
}): ShareProvenance;
|
|
113
|
+
/**
|
|
114
|
+
* Parse repeated `--meta key=value` CLI args into a validated metadata record.
|
|
115
|
+
* Keys are lowercase `[a-z0-9-]`, up to 64 characters, and may not collide with
|
|
116
|
+
* {@link RESERVED_META_KEYS} (the provenance the CLI sets automatically, plus
|
|
117
|
+
* label/label-source) — throws naming the offending pair on any violation.
|
|
118
|
+
*/
|
|
119
|
+
export declare function parseMetaEntries(pairs: string[]): Record<string, string>;
|
|
120
|
+
/** Throws when the combined `customMetadata` payload would exceed {@link MAX_METADATA_BYTES}. */
|
|
121
|
+
export declare function assertMetadataSize(customMetadata: Record<string, string>): void;
|
|
122
|
+
/**
|
|
123
|
+
* Collapse a label to a single line before it goes into the `x-share-label`
|
|
124
|
+
* header or public customMetadata. `<title>[^<]{1,200}</title>` matches
|
|
125
|
+
* newlines (`[^<]` excludes only `<`), and `.trim()` only strips leading/
|
|
126
|
+
* trailing whitespace, not embedded newlines — a multi-line `<title>` (or an
|
|
127
|
+
* explicit `--label`/`--title` the caller typed with a literal newline) was
|
|
128
|
+
* previously passed straight into `Headers.set()` unsanitized, which throws
|
|
129
|
+
* an unhandled `TypeError: Invalid value` and crashes the publish outright.
|
|
130
|
+
*/
|
|
131
|
+
export declare function sanitizeLabel(text: string): string;
|
|
132
|
+
/**
|
|
133
|
+
* Make a free-text value safe to put in an HTTP header.
|
|
134
|
+
*
|
|
135
|
+
* `fetch` encodes header values as a **ByteString**, so any code point above 255
|
|
136
|
+
* throws `TypeError: Cannot convert argument to a ByteString` — an unhandled
|
|
137
|
+
* crash with a stack trace, mid-publish, after the body has already been read.
|
|
138
|
+
* Reproduced by publishing a session whose title ended in `…` (U+2026), and
|
|
139
|
+
* reachable by any emoji, curly quote, accented name, or CJK text in a `--label`,
|
|
140
|
+
* a `--meta` value, or a repo name.
|
|
141
|
+
*
|
|
142
|
+
* The transliterations above cover what actually shows up; anything else outside
|
|
143
|
+
* latin1 is dropped, and a value that transliterates to nothing at all (a title
|
|
144
|
+
* written entirely in a non-latin script) degrades to a marker rather than an
|
|
145
|
+
* empty header. Lossy on purpose: carrying full Unicode needs percent-encoding
|
|
146
|
+
* here AND a matching decode in the Worker, which every already-deployed Worker
|
|
147
|
+
* would render as `%E2%80%A6` until its operator ran `agents artifacts share
|
|
148
|
+
* update` — tracked as RUSH-2786.
|
|
149
|
+
*/
|
|
150
|
+
export declare function toHeaderValue(text: string): string;
|
|
151
|
+
/**
|
|
152
|
+
* Best-effort human title when `--label` is omitted: the HTML `<title>`, else a
|
|
153
|
+
* Markdown frontmatter `title:`, else the filename. Always returns something —
|
|
154
|
+
* a headless publish must never hang waiting on a prompt for one.
|
|
155
|
+
*/
|
|
156
|
+
export declare function deriveLabel(filePath: string, body: Buffer): string;
|
|
56
157
|
/** Default auto-expire for unflagged publishes — accidental links decay (RUSH-2443). */
|
|
57
158
|
export declare const DEFAULT_SHARE_EXPIRE = "30d";
|
|
58
159
|
/** `30d` / `12h` / `2026-08-01` → an absolute ISO timestamp (or undefined). */
|
|
@@ -68,6 +169,25 @@ export interface SensitiveHit {
|
|
|
68
169
|
/** Short redacted sample so the error names *what* was found without dumping it. */
|
|
69
170
|
sample: string;
|
|
70
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Mask every email address in `text`, so a page can be published without tripping
|
|
174
|
+
* {@link scanShareContent}.
|
|
175
|
+
*
|
|
176
|
+
* Lives here, beside the scanner, rather than in `lib/redact.ts`: it exists solely
|
|
177
|
+
* to satisfy this gate, and sharing {@link EMAIL_RE} is what makes the masking
|
|
178
|
+
* *sufficient* to clear it rather than merely reducing the hit count. Two copies of
|
|
179
|
+
* the pattern in two modules would drift, and the failure mode of that drift is a
|
|
180
|
+
* refused publish at runtime.
|
|
181
|
+
*
|
|
182
|
+
* Deliberately NOT part of `redactSecrets`: an email is not a credential, and a
|
|
183
|
+
* transcript rendered for a private gist or local review reads better with the real
|
|
184
|
+
* author addresses intact. It only becomes a leak once the text is PUBLISHED — a
|
|
185
|
+
* world-readable page carrying seven of them is the RUSH-2428 incident.
|
|
186
|
+
*
|
|
187
|
+
* The whole address goes, domain included — a personal domain identifies its owner
|
|
188
|
+
* as surely as the local part does, and keeping it would buy the reader nothing.
|
|
189
|
+
*/
|
|
190
|
+
export declare function redactEmails(text: string): string;
|
|
71
191
|
/**
|
|
72
192
|
* Scan a text body for email addresses and credential-shaped strings. Returns
|
|
73
193
|
* the first few hits (deduped by kind+sample). Binary / non-text bodies yield
|