@phnx-labs/agents-cli 1.22.119 → 1.22.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +236 -0
- package/README.md +19 -2
- package/dist/bootstrap.d.ts +0 -15
- package/dist/bootstrap.js +10 -409
- package/dist/cli/command-registry.d.ts +0 -58
- package/dist/cli/command-registry.js +2 -74
- package/dist/commands/accounts.d.ts +0 -17
- package/dist/commands/accounts.js +1 -52
- package/dist/commands/alias.d.ts +0 -12
- package/dist/commands/alias.js +0 -6
- package/dist/commands/apply.d.ts +0 -15
- package/dist/commands/apply.js +0 -63
- package/dist/commands/audit.d.ts +0 -12
- package/dist/commands/audit.js +0 -13
- package/dist/commands/auth.js +4 -12
- package/dist/commands/beta.d.ts +0 -6
- package/dist/commands/beta.js +2 -6
- package/dist/commands/browser-sessions-picker.d.ts +0 -8
- package/dist/commands/browser-sessions-picker.js +0 -26
- package/dist/commands/browser.d.ts +0 -57
- package/dist/commands/browser.js +0 -80
- package/dist/commands/budget.d.ts +0 -13
- package/dist/commands/budget.js +0 -2
- package/dist/commands/cli.d.ts +0 -12
- package/dist/commands/cli.js +0 -4
- package/dist/commands/cloud.d.ts +0 -9
- package/dist/commands/cloud.js +0 -43
- package/dist/commands/commands.d.ts +0 -9
- package/dist/commands/commands.js +0 -18
- package/dist/commands/computer-sessions-picker.d.ts +0 -11
- package/dist/commands/computer-sessions-picker.js +0 -29
- package/dist/commands/computer.d.ts +0 -62
- package/dist/commands/computer.js +3 -114
- package/dist/commands/config.d.ts +0 -14
- package/dist/commands/config.js +21 -60
- package/dist/commands/cost.d.ts +0 -11
- package/dist/commands/cost.js +1 -17
- package/dist/commands/daemon-test-harness.d.ts +0 -32
- package/dist/commands/daemon-test-harness.js +1 -36
- package/dist/commands/daemon.d.ts +0 -46
- package/dist/commands/daemon.js +8 -255
- package/dist/commands/detach-core.d.ts +0 -28
- package/dist/commands/detach-core.js +0 -30
- package/dist/commands/detach.d.ts +1 -12
- package/dist/commands/detach.js +16 -52
- package/dist/commands/device-config-test-harness.js +0 -12
- package/dist/commands/doctor.d.ts +0 -103
- package/dist/commands/doctor.js +3 -279
- package/dist/commands/events.d.ts +0 -29
- package/dist/commands/events.js +1 -55
- package/dist/commands/exec.d.ts +0 -163
- package/dist/commands/exec.js +15 -964
- package/dist/commands/factory.d.ts +0 -6
- package/dist/commands/factory.js +0 -2
- package/dist/commands/feed-watch.js +0 -20
- package/dist/commands/feed.d.ts +0 -38
- package/dist/commands/feed.js +1 -151
- package/dist/commands/feedback.d.ts +0 -5
- package/dist/commands/feedback.js +0 -5
- package/dist/commands/fleet-capture.d.ts +0 -12
- package/dist/commands/fleet-capture.js +1 -39
- package/dist/commands/focus.d.ts +6 -94
- package/dist/commands/focus.js +13 -183
- package/dist/commands/fork.d.ts +0 -21
- package/dist/commands/fork.js +0 -45
- package/dist/commands/funnel.d.ts +0 -3
- package/dist/commands/go.d.ts +2 -71
- package/dist/commands/go.js +5 -99
- package/dist/commands/harness-hooks.d.ts +0 -41
- package/dist/commands/harness-hooks.js +0 -48
- package/dist/commands/harness-wizard.d.ts +0 -137
- package/dist/commands/harness-wizard.js +0 -109
- package/dist/commands/harness.d.ts +0 -63
- package/dist/commands/harness.js +0 -103
- package/dist/commands/hooks.d.ts +0 -9
- package/dist/commands/hooks.js +0 -26
- package/dist/commands/humans.d.ts +0 -8
- package/dist/commands/humans.js +0 -8
- package/dist/commands/import.d.ts +0 -22
- package/dist/commands/import.js +0 -79
- package/dist/commands/insights.d.ts +0 -37
- package/dist/commands/insights.js +3 -115
- package/dist/commands/inspect.d.ts +0 -117
- package/dist/commands/inspect.js +2 -448
- package/dist/commands/lease.d.ts +0 -28
- package/dist/commands/lease.js +0 -43
- package/dist/commands/logs.d.ts +0 -23
- package/dist/commands/logs.js +0 -30
- package/dist/commands/mailboxes.d.ts +0 -18
- package/dist/commands/mailboxes.js +0 -29
- package/dist/commands/mcp.d.ts +0 -9
- package/dist/commands/mcp.js +0 -53
- package/dist/commands/memory.d.ts +0 -7
- package/dist/commands/memory.js +0 -7
- package/dist/commands/menubar.d.ts +0 -8
- package/dist/commands/menubar.js +0 -24
- package/dist/commands/message.d.ts +0 -23
- package/dist/commands/message.js +0 -50
- package/dist/commands/mine.d.ts +0 -22
- package/dist/commands/mine.js +0 -21
- package/dist/commands/models.d.ts +0 -8
- package/dist/commands/models.js +0 -33
- package/dist/commands/modes.d.ts +0 -10
- package/dist/commands/modes.js +0 -13
- package/dist/commands/monitors.d.ts +0 -9
- package/dist/commands/monitors.js +3 -160
- package/dist/commands/open.d.ts +0 -26
- package/dist/commands/open.js +0 -10
- package/dist/commands/output.d.ts +0 -18
- package/dist/commands/output.js +1 -34
- package/dist/commands/packages-materialize.d.ts +0 -11
- package/dist/commands/packages-materialize.js +0 -3
- package/dist/commands/packages.d.ts +0 -10
- package/dist/commands/packages.js +0 -50
- package/dist/commands/perf.d.ts +0 -41
- package/dist/commands/perf.js +0 -55
- package/dist/commands/permissions.d.ts +0 -9
- package/dist/commands/permissions.js +0 -43
- package/dist/commands/plugins.d.ts +0 -14
- package/dist/commands/plugins.js +2 -55
- package/dist/commands/profiles.d.ts +0 -25
- package/dist/commands/profiles.js +0 -27
- package/dist/commands/projects-todo.d.ts +2 -0
- package/dist/commands/projects-todo.js +132 -0
- package/dist/commands/projects.d.ts +0 -85
- package/dist/commands/projects.js +344 -291
- package/dist/commands/prune.js +0 -30
- package/dist/commands/ps-roster.d.ts +92 -0
- package/dist/commands/ps-roster.js +744 -0
- package/dist/commands/ps.d.ts +6 -0
- package/dist/commands/ps.js +98 -0
- package/dist/commands/refresh-rules.d.ts +0 -13
- package/dist/commands/refresh-rules.js +0 -14
- package/dist/commands/reminders.d.ts +0 -7
- package/dist/commands/repo.d.ts +0 -89
- package/dist/commands/repo.js +7 -205
- package/dist/commands/resource-view.d.ts +0 -33
- package/dist/commands/resource-view.js +0 -49
- package/dist/commands/resume.d.ts +1 -19
- package/dist/commands/resume.js +0 -50
- package/dist/commands/route.d.ts +0 -10
- package/dist/commands/route.js +0 -19
- package/dist/commands/routines.d.ts +0 -42
- package/dist/commands/routines.js +5 -290
- package/dist/commands/routines.test-fixture.d.ts +0 -34
- package/dist/commands/routines.test-fixture.js +4 -100
- package/dist/commands/rules.d.ts +0 -9
- package/dist/commands/rules.js +1 -6
- package/dist/commands/run-account-picker.d.ts +0 -59
- package/dist/commands/run-account-picker.js +0 -71
- package/dist/commands/run-broadcast.d.ts +0 -9
- package/dist/commands/run-broadcast.js +0 -7
- package/dist/commands/run-cloud.d.ts +0 -15
- package/dist/commands/run-cloud.js +0 -37
- package/dist/commands/run-device-picker.d.ts +0 -25
- package/dist/commands/run-device-picker.js +1 -53
- package/dist/commands/secrets-passthrough.d.ts +0 -31
- package/dist/commands/secrets-passthrough.js +0 -10
- package/dist/commands/send.d.ts +0 -20
- package/dist/commands/send.js +14 -18
- package/dist/commands/sessions-backfill.d.ts +0 -7
- package/dist/commands/sessions-backfill.js +1 -16
- package/dist/commands/sessions-backup-setup.js +0 -11
- package/dist/commands/sessions-bookmark.d.ts +0 -8
- package/dist/commands/sessions-bookmark.js +0 -28
- package/dist/commands/sessions-browser.d.ts +2 -117
- package/dist/commands/sessions-browser.js +5 -243
- package/dist/commands/sessions-export.d.ts +1 -26
- package/dist/commands/sessions-export.js +3 -81
- package/dist/commands/sessions-import.d.ts +0 -14
- package/dist/commands/sessions-import.js +0 -59
- package/dist/commands/sessions-inject.d.ts +0 -60
- package/dist/commands/sessions-inject.js +3 -96
- package/dist/commands/sessions-migrate.d.ts +2 -37
- package/dist/commands/sessions-migrate.js +7 -159
- package/dist/commands/sessions-optimize.d.ts +0 -12
- package/dist/commands/sessions-picker-factory.d.ts +0 -7
- package/dist/commands/sessions-picker-factory.js +0 -8
- package/dist/commands/sessions-picker.d.ts +4 -103
- package/dist/commands/sessions-picker.js +13 -352
- package/dist/commands/sessions-render.d.ts +1 -2
- package/dist/commands/sessions-render.js +3 -7
- package/dist/commands/sessions-resume.d.ts +1 -24
- package/dist/commands/sessions-resume.js +2 -65
- package/dist/commands/sessions-share.d.ts +1 -9
- package/dist/commands/sessions-share.js +1 -45
- package/dist/commands/sessions-stats.d.ts +0 -24
- package/dist/commands/sessions-stats.js +0 -49
- package/dist/commands/sessions-stop.d.ts +1 -20
- package/dist/commands/sessions-stop.js +4 -9
- package/dist/commands/sessions-tail.d.ts +1 -19
- package/dist/commands/sessions-tail.js +3 -36
- package/dist/commands/sessions-trace.d.ts +5 -36
- package/dist/commands/sessions-trace.js +7 -82
- package/dist/commands/sessions.d.ts +1 -666
- package/dist/commands/sessions.js +30 -2279
- package/dist/commands/sessions.test-fixture.d.ts +0 -9
- package/dist/commands/sessions.test-fixture.js +8 -23
- package/dist/commands/setup-accounts.d.ts +0 -6
- package/dist/commands/setup-browser.d.ts +0 -23
- package/dist/commands/setup-browser.js +0 -28
- package/dist/commands/setup-computer.d.ts +0 -16
- package/dist/commands/setup-computer.js +0 -28
- package/dist/commands/setup-fleet.d.ts +0 -8
- package/dist/commands/setup-fleet.js +0 -11
- package/dist/commands/setup-mine.d.ts +0 -14
- package/dist/commands/setup-mine.js +0 -25
- package/dist/commands/setup-preferences.d.ts +0 -47
- package/dist/commands/setup-preferences.js +0 -53
- package/dist/commands/setup-secrets.d.ts +2 -24
- package/dist/commands/setup-secrets.js +0 -24
- package/dist/commands/setup-term.d.ts +0 -21
- package/dist/commands/setup-term.js +0 -21
- package/dist/commands/setup-terminal.d.ts +0 -1
- package/dist/commands/setup-terminal.js +0 -1
- package/dist/commands/setup-tools.d.ts +2 -0
- package/dist/commands/setup-tools.js +73 -0
- package/dist/commands/setup.d.ts +0 -20
- package/dist/commands/setup.js +4 -57
- package/dist/commands/skills.d.ts +0 -9
- package/dist/commands/skills.js +1 -22
- package/dist/commands/snapshot.d.ts +0 -9
- package/dist/commands/snapshot.js +0 -10
- package/dist/commands/ssh.d.ts +0 -64
- package/dist/commands/ssh.js +9 -420
- package/dist/commands/status.d.ts +0 -12
- package/dist/commands/status.js +0 -26
- package/dist/commands/subagents.d.ts +0 -8
- package/dist/commands/subagents.js +0 -31
- package/dist/commands/sync.d.ts +0 -37
- package/dist/commands/sync.js +0 -256
- package/dist/commands/teams-picker.d.ts +0 -3
- package/dist/commands/teams-picker.js +0 -34
- package/dist/commands/teams.d.ts +1 -76
- package/dist/commands/teams.js +9 -477
- package/dist/commands/tmux.d.ts +0 -25
- package/dist/commands/tmux.js +0 -46
- package/dist/commands/traces.js +0 -19
- package/dist/commands/trash.d.ts +0 -17
- package/dist/commands/trash.js +1 -11
- package/dist/commands/uninstall.d.ts +0 -9
- package/dist/commands/uninstall.js +0 -6
- package/dist/commands/update.d.ts +0 -22
- package/dist/commands/update.js +0 -44
- package/dist/commands/upgrade.d.ts +0 -1
- package/dist/commands/upgrade.js +0 -1
- package/dist/commands/utils.d.ts +0 -85
- package/dist/commands/utils.js +1 -95
- package/dist/commands/versions.d.ts +0 -16
- package/dist/commands/versions.js +0 -134
- package/dist/commands/view.d.ts +0 -90
- package/dist/commands/view.js +4 -343
- package/dist/commands/watchdog.d.ts +0 -19
- package/dist/commands/watchdog.js +3 -43
- package/dist/commands/webhook.d.ts +0 -8
- package/dist/commands/webhook.js +0 -14
- package/dist/commands/workflows.d.ts +0 -8
- package/dist/commands/workflows.js +0 -6
- package/dist/index.d.ts +0 -25
- package/dist/index.js +5 -119
- package/dist/lib/account-capabilities.d.ts +0 -34
- package/dist/lib/account-capabilities.js +0 -32
- package/dist/lib/account-catalog.d.ts +0 -128
- package/dist/lib/account-catalog.js +8 -154
- package/dist/lib/account-provider-registry.d.ts +0 -14
- package/dist/lib/account-provider-registry.js +0 -8
- package/dist/lib/account-registry.d.ts +0 -74
- package/dist/lib/account-registry.js +14 -189
- package/dist/lib/account-schema.d.ts +0 -19
- package/dist/lib/account-schema.js +0 -43
- package/dist/lib/accounting/account-launch.d.ts +0 -15
- package/dist/lib/accounting/account-launch.js +1 -3
- package/dist/lib/accounting/account-pool-collect.d.ts +0 -26
- package/dist/lib/accounting/account-pool-collect.js +0 -42
- package/dist/lib/accounting/account-pool.d.ts +0 -41
- package/dist/lib/accounting/account-pool.js +0 -17
- package/dist/lib/accounting/capacity.d.ts +0 -32
- package/dist/lib/accounting/capacity.js +0 -32
- package/dist/lib/accounting/rotate.d.ts +0 -518
- package/dist/lib/accounting/rotate.js +4 -598
- package/dist/lib/accounting/usage-ingest.d.ts +0 -1
- package/dist/lib/accounting/usage-ingest.js +0 -44
- package/dist/lib/accounting/usage-sync.d.ts +0 -60
- package/dist/lib/accounting/usage-sync.js +4 -51
- package/dist/lib/accounting/usage.d.ts +0 -632
- package/dist/lib/accounting/usage.js +14 -1055
- package/dist/lib/accounts/add.d.ts +0 -60
- package/dist/lib/accounts/add.js +0 -127
- package/dist/lib/accounts/auth-operation-lock.d.ts +0 -1
- package/dist/lib/accounts/auth-operation-lock.js +0 -4
- package/dist/lib/accounts/migrate.d.ts +0 -9
- package/dist/lib/accounts/migrate.js +3 -42
- package/dist/lib/accounts/slots.d.ts +0 -25
- package/dist/lib/accounts/slots.js +1 -49
- package/dist/lib/acp/client.d.ts +0 -16
- package/dist/lib/acp/client.js +0 -29
- package/dist/lib/acp/harnesses.d.ts +0 -15
- package/dist/lib/acp/harnesses.js +0 -16
- package/dist/lib/acp/run.d.ts +0 -8
- package/dist/lib/acp/run.js +0 -8
- package/dist/lib/actor.d.ts +1 -71
- package/dist/lib/actor.js +1 -99
- package/dist/lib/add-dir.d.ts +0 -46
- package/dist/lib/add-dir.js +1 -70
- package/dist/lib/address.d.ts +0 -17
- package/dist/lib/address.js +0 -15
- package/dist/lib/agent-cli-commands.d.ts +0 -10
- package/dist/lib/agent-cli-commands.js +0 -10
- package/dist/lib/agent-modes.d.ts +0 -29
- package/dist/lib/agent-modes.js +0 -31
- package/dist/lib/agent-spec/agents.d.ts +0 -426
- package/dist/lib/agent-spec/agents.js +37 -924
- package/dist/lib/agent-spec/index.d.ts +0 -5
- package/dist/lib/agent-spec/index.js +0 -14
- package/dist/lib/agent-spec/materialize.d.ts +0 -10
- package/dist/lib/agent-spec/materialize.js +2 -139
- package/dist/lib/agent-spec/package-resolve.d.ts +0 -8
- package/dist/lib/agent-spec/package-resolve.js +1 -44
- package/dist/lib/agent-spec/package-schema.d.ts +0 -2
- package/dist/lib/agent-spec/package-schema.js +0 -11
- package/dist/lib/agent-spec/package-types.d.ts +0 -27
- package/dist/lib/agent-spec/package-types.js +0 -1
- package/dist/lib/agent-spec/primitives.d.ts +0 -18
- package/dist/lib/agent-spec/primitives.js +0 -27
- package/dist/lib/agent-spec/provider.js +0 -2
- package/dist/lib/agent-spec/resolve.d.ts +0 -23
- package/dist/lib/agent-spec/resolve.js +0 -41
- package/dist/lib/agent-spec/types.d.ts +0 -34
- package/dist/lib/agent-spec/types.js +0 -6
- package/dist/lib/agents.d.ts +0 -1
- package/dist/lib/agents.js +0 -1
- package/dist/lib/analytics/mix-commands.d.ts +0 -23
- package/dist/lib/analytics/mix-commands.js +0 -26
- package/dist/lib/analytics/recipes.d.ts +0 -1
- package/dist/lib/analytics/recipes.js +5 -10
- package/dist/lib/analytics/usage-db.js +4 -6
- package/dist/lib/answer-router.d.ts +0 -61
- package/dist/lib/answer-router.js +0 -57
- package/dist/lib/app-bundle-install.d.ts +0 -13
- package/dist/lib/app-bundle-install.js +0 -50
- package/dist/lib/artifact-actions.d.ts +0 -15
- package/dist/lib/artifact-actions.js +0 -18
- package/dist/lib/artifacts-client.d.ts +0 -10
- package/dist/lib/artifacts-client.js +0 -17
- package/dist/lib/ask-classifier.d.ts +0 -38
- package/dist/lib/ask-classifier.js +0 -27
- package/dist/lib/audit/log.d.ts +0 -47
- package/dist/lib/audit/log.js +1 -59
- package/dist/lib/auth-health.d.ts +0 -213
- package/dist/lib/auth-health.js +16 -266
- package/dist/lib/auth-mint.d.ts +0 -83
- package/dist/lib/auth-mint.js +8 -85
- package/dist/lib/auto-pull-worker.d.ts +0 -10
- package/dist/lib/auto-pull-worker.js +3 -48
- package/dist/lib/auto-pull.d.ts +0 -64
- package/dist/lib/auto-pull.js +0 -79
- package/dist/lib/beta.d.ts +0 -9
- package/dist/lib/beta.js +0 -9
- package/dist/lib/binary-shadow.d.ts +0 -22
- package/dist/lib/binary-shadow.js +4 -34
- package/dist/lib/boot-profile.d.ts +0 -10
- package/dist/lib/boot-profile.js +1 -31
- package/dist/lib/brand.d.ts +0 -20
- package/dist/lib/brand.js +0 -50
- package/dist/lib/browser/context.d.ts +0 -54
- package/dist/lib/browser/context.js +0 -49
- package/dist/lib/browser/paths.d.ts +0 -21
- package/dist/lib/browser/paths.js +0 -26
- package/dist/lib/browser/record.d.ts +0 -34
- package/dist/lib/browser/record.js +0 -38
- package/dist/lib/browser/sessions-list.d.ts +1 -79
- package/dist/lib/browser/sessions-list.js +2 -98
- package/dist/lib/browser-client.d.ts +0 -112
- package/dist/lib/browser-client.js +1 -90
- package/dist/lib/budget/config.d.ts +0 -6
- package/dist/lib/budget/config.js +0 -29
- package/dist/lib/budget/enforce.d.ts +0 -50
- package/dist/lib/budget/enforce.js +0 -27
- package/dist/lib/budget/ledger.d.ts +0 -23
- package/dist/lib/budget/ledger.js +0 -28
- package/dist/lib/budget/live-cloud.d.ts +0 -26
- package/dist/lib/budget/live-cloud.js +0 -12
- package/dist/lib/budget/live-team.d.ts +0 -17
- package/dist/lib/budget/live-team.js +1 -35
- package/dist/lib/budget/preflight.d.ts +0 -51
- package/dist/lib/budget/preflight.js +0 -36
- package/dist/lib/byok-usage.d.ts +0 -20
- package/dist/lib/byok-usage.js +1 -24
- package/dist/lib/capabilities.d.ts +0 -24
- package/dist/lib/capabilities.js +0 -29
- package/dist/lib/catchup.d.ts +0 -87
- package/dist/lib/catchup.js +1 -81
- package/dist/lib/channels/owner-forward.d.ts +0 -70
- package/dist/lib/channels/owner-forward.js +1 -43
- package/dist/lib/channels/owner-sink.js +0 -21
- package/dist/lib/channels/providers/desktop.d.ts +0 -37
- package/dist/lib/channels/providers/desktop.js +0 -72
- package/dist/lib/channels/providers/index.d.ts +0 -1
- package/dist/lib/channels/providers/index.js +2 -6
- package/dist/lib/channels/providers/mailbox.js +0 -7
- package/dist/lib/channels/providers/openclaw-telegram.js +0 -8
- package/dist/lib/channels/providers/rush.d.ts +0 -2
- package/dist/lib/channels/providers/rush.js +0 -26
- package/dist/lib/channels/providers/session.d.ts +2 -0
- package/dist/lib/channels/providers/session.js +26 -0
- package/dist/lib/channels/registry.d.ts +0 -27
- package/dist/lib/channels/registry.js +0 -10
- package/dist/lib/channels/resolve.d.ts +0 -19
- package/dist/lib/channels/resolve.js +0 -2
- package/dist/lib/channels/send.d.ts +0 -50
- package/dist/lib/channels/send.js +0 -25
- package/dist/lib/checkpoint.d.ts +0 -36
- package/dist/lib/checkpoint.js +0 -28
- package/dist/lib/claude-account-token.d.ts +0 -98
- package/dist/lib/claude-account-token.js +7 -169
- package/dist/lib/claude-statusline.d.ts +0 -41
- package/dist/lib/claude-statusline.js +0 -68
- package/dist/lib/cli-entry.d.ts +0 -26
- package/dist/lib/cli-entry.js +1 -61
- package/dist/lib/cli-resources.d.ts +31 -89
- package/dist/lib/cli-resources.js +116 -152
- package/dist/lib/cloud/antigravity.d.ts +0 -29
- package/dist/lib/cloud/antigravity.js +0 -36
- package/dist/lib/cloud/codex.d.ts +0 -8
- package/dist/lib/cloud/codex.js +0 -41
- package/dist/lib/cloud/cursor.d.ts +0 -5
- package/dist/lib/cloud/cursor.js +2 -7
- package/dist/lib/cloud/dispatch.d.ts +0 -13
- package/dist/lib/cloud/dispatch.js +1 -48
- package/dist/lib/cloud/factory.d.ts +0 -52
- package/dist/lib/cloud/factory.js +3 -67
- package/dist/lib/cloud/host.d.ts +0 -39
- package/dist/lib/cloud/host.js +5 -48
- package/dist/lib/cloud/registry.d.ts +0 -25
- package/dist/lib/cloud/registry.js +0 -29
- package/dist/lib/cloud/rush.d.ts +0 -47
- package/dist/lib/cloud/rush.js +1 -82
- package/dist/lib/cloud/session-index.d.ts +0 -27
- package/dist/lib/cloud/session-index.js +1 -32
- package/dist/lib/cloud/store.d.ts +0 -18
- package/dist/lib/cloud/store.js +0 -28
- package/dist/lib/cloud/stream.d.ts +0 -14
- package/dist/lib/cloud/stream.js +0 -25
- package/dist/lib/cloud/types.d.ts +0 -168
- package/dist/lib/cloud/types.js +0 -46
- package/dist/lib/cloudflare/creds.d.ts +0 -2
- package/dist/lib/cloudflare/creds.js +0 -14
- package/dist/lib/cloudflare/provision.d.ts +0 -8
- package/dist/lib/cloudflare/provision.js +1 -19
- package/dist/lib/codex-home.d.ts +0 -60
- package/dist/lib/codex-home.js +2 -72
- package/dist/lib/codex-policy.d.ts +0 -10
- package/dist/lib/codex-policy.js +0 -13
- package/dist/lib/command-skills.d.ts +0 -10
- package/dist/lib/command-skills.js +0 -10
- package/dist/lib/commands.d.ts +0 -74
- package/dist/lib/commands.js +0 -112
- package/dist/lib/comms-render.d.ts +0 -5
- package/dist/lib/comms-render.js +0 -5
- package/dist/lib/computer/context.d.ts +0 -23
- package/dist/lib/computer/context.js +0 -14
- package/dist/lib/computer/policy.d.ts +0 -20
- package/dist/lib/computer/policy.js +0 -53
- package/dist/lib/computer/record.d.ts +0 -33
- package/dist/lib/computer/record.js +1 -48
- package/dist/lib/computer/sessions-list.d.ts +1 -128
- package/dist/lib/computer/sessions-list.js +6 -165
- package/dist/lib/computer-client.d.ts +0 -106
- package/dist/lib/computer-client.js +5 -86
- package/dist/lib/concurrency.d.ts +0 -14
- package/dist/lib/concurrency.js +0 -3
- package/dist/lib/config-drift.d.ts +0 -31
- package/dist/lib/config-drift.js +0 -32
- package/dist/lib/config-keys.d.ts +1 -65
- package/dist/lib/config-keys.js +6 -52
- package/dist/lib/config-transfer.d.ts +0 -14
- package/dist/lib/config-transfer.js +0 -26
- package/dist/lib/convert.d.ts +0 -17
- package/dist/lib/convert.js +0 -18
- package/dist/lib/crabbox/cli.d.ts +0 -156
- package/dist/lib/crabbox/cli.js +1 -188
- package/dist/lib/crabbox/config.d.ts +0 -18
- package/dist/lib/crabbox/config.js +1 -19
- package/dist/lib/crabbox/lease.d.ts +0 -93
- package/dist/lib/crabbox/lease.js +4 -148
- package/dist/lib/crabbox/progress.d.ts +0 -56
- package/dist/lib/crabbox/progress.js +2 -49
- package/dist/lib/crabbox/runtimes.d.ts +0 -94
- package/dist/lib/crabbox/runtimes.js +1 -111
- package/dist/lib/crabbox/setup-copy.d.ts +0 -64
- package/dist/lib/crabbox/setup-copy.js +1 -53
- package/dist/lib/daemon/account-state-daemon-service.d.ts +0 -48
- package/dist/lib/daemon/account-state-daemon-service.js +2 -63
- package/dist/lib/daemon/attention-notify-service.d.ts +0 -12
- package/dist/lib/daemon/attention-notify-service.js +1 -24
- package/dist/lib/daemon/auth-sync-service.d.ts +0 -28
- package/dist/lib/daemon/auth-sync-service.js +0 -56
- package/dist/lib/daemon/catchup-service.d.ts +0 -34
- package/dist/lib/daemon/catchup-service.js +0 -30
- package/dist/lib/daemon/daemon.d.ts +0 -374
- package/dist/lib/daemon/daemon.js +44 -1049
- package/dist/lib/daemon/daemon.test-fixture.d.ts +0 -19
- package/dist/lib/daemon/daemon.test-fixture.js +1 -24
- package/dist/lib/daemon/device-probe-service.d.ts +0 -16
- package/dist/lib/daemon/device-probe-service.js +0 -20
- package/dist/lib/daemon/feed-stream-service.d.ts +0 -15
- package/dist/lib/daemon/feed-stream-service.js +0 -20
- package/dist/lib/daemon/harness-update-service.d.ts +2 -61
- package/dist/lib/daemon/harness-update-service.js +6 -86
- package/dist/lib/daemon/heartbeat-service.d.ts +0 -1
- package/dist/lib/daemon/heartbeat-service.js +0 -1
- package/dist/lib/daemon/leaked-daemons.d.ts +0 -46
- package/dist/lib/daemon/leaked-daemons.js +2 -78
- package/dist/lib/daemon/monitor-engine-service.d.ts +0 -13
- package/dist/lib/daemon/monitor-engine-service.js +3 -15
- package/dist/lib/daemon/runner.d.ts +0 -194
- package/dist/lib/daemon/runner.js +39 -760
- package/dist/lib/daemon/self-heal-service.d.ts +18 -17
- package/dist/lib/daemon/self-heal-service.js +83 -37
- package/dist/lib/daemon/self-update-service.d.ts +1 -131
- package/dist/lib/daemon/self-update-service.js +26 -189
- package/dist/lib/daemon/service.d.ts +0 -73
- package/dist/lib/daemon/service.js +0 -34
- package/dist/lib/daemon/session-index-service.d.ts +0 -12
- package/dist/lib/daemon/session-index-service.js +0 -23
- package/dist/lib/daemon/session-state-service.d.ts +0 -8
- package/dist/lib/daemon/session-state-service.js +0 -8
- package/dist/lib/daemon/session-summarizer-service.d.ts +0 -14
- package/dist/lib/daemon/session-summarizer-service.js +1 -19
- package/dist/lib/daemon/session-title-service.d.ts +0 -25
- package/dist/lib/daemon/session-title-service.js +0 -32
- package/dist/lib/daemon/state-dir-check-service.d.ts +0 -24
- package/dist/lib/daemon/state-dir-check-service.js +0 -29
- package/dist/lib/daemon/supervisor.d.ts +0 -112
- package/dist/lib/daemon/supervisor.js +4 -147
- package/dist/lib/daemon/testdata/process-view-daemon.js +0 -2
- package/dist/lib/daemon/testdata/process-view-start.js +0 -5
- package/dist/lib/daemon/tmux-reap-service.d.ts +0 -1
- package/dist/lib/daemon/tmux-reap-service.js +0 -1
- package/dist/lib/daemon/usage-sync-service.d.ts +0 -23
- package/dist/lib/daemon/usage-sync-service.js +0 -26
- package/dist/lib/daemon/watchdog-service.d.ts +0 -9
- package/dist/lib/daemon/watchdog-service.js +0 -13
- package/dist/lib/daemon/webhook-receiver-service.d.ts +0 -1
- package/dist/lib/daemon/webhook-receiver-service.js +0 -1
- package/dist/lib/daemon-health.d.ts +0 -55
- package/dist/lib/daemon-health.js +4 -77
- package/dist/lib/daemon-services.d.ts +0 -36
- package/dist/lib/daemon-services.js +0 -45
- package/dist/lib/daemon-ticks.d.ts +0 -126
- package/dist/lib/daemon-ticks.js +1 -156
- package/dist/lib/daemon-webhooks.d.ts +0 -57
- package/dist/lib/daemon-webhooks.js +2 -54
- package/dist/lib/deeplink/register.d.ts +0 -15
- package/dist/lib/deeplink/register.js +0 -60
- package/dist/lib/deeplink/url.d.ts +0 -24
- package/dist/lib/deeplink/url.js +1 -33
- package/dist/lib/device-config.d.ts +1 -192
- package/dist/lib/device-config.js +86 -240
- package/dist/lib/devices/config-migration.d.ts +0 -43
- package/dist/lib/devices/config-migration.js +7 -127
- package/dist/lib/devices/connect.d.ts +0 -168
- package/dist/lib/devices/connect.js +6 -254
- package/dist/lib/devices/device-docs.d.ts +0 -24
- package/dist/lib/devices/device-docs.js +0 -46
- package/dist/lib/devices/discovery-policy.d.ts +0 -30
- package/dist/lib/devices/discovery-policy.js +3 -34
- package/dist/lib/devices/doctor-findings.d.ts +0 -109
- package/dist/lib/devices/doctor-findings.js +30 -326
- package/dist/lib/devices/doctor-overview-cache.d.ts +0 -33
- package/dist/lib/devices/doctor-overview-cache.js +0 -81
- package/dist/lib/devices/fleet-divergence.d.ts +0 -89
- package/dist/lib/devices/fleet-divergence.js +1 -60
- package/dist/lib/devices/fleet-inventory.d.ts +0 -27
- package/dist/lib/devices/fleet-inventory.js +0 -38
- package/dist/lib/devices/fleet.d.ts +0 -95
- package/dist/lib/devices/fleet.js +0 -79
- package/dist/lib/devices/harness-inventory.d.ts +0 -75
- package/dist/lib/devices/harness-inventory.js +0 -101
- package/dist/lib/devices/health-report.d.ts +0 -37
- package/dist/lib/devices/health-report.js +0 -73
- package/dist/lib/devices/health.d.ts +0 -71
- package/dist/lib/devices/health.js +2 -82
- package/dist/lib/devices/interactive-host.d.ts +0 -10
- package/dist/lib/devices/interactive-host.js +0 -34
- package/dist/lib/devices/known-hosts.d.ts +0 -45
- package/dist/lib/devices/known-hosts.js +0 -77
- package/dist/lib/devices/pending.d.ts +0 -31
- package/dist/lib/devices/pending.js +7 -67
- package/dist/lib/devices/pool.d.ts +0 -36
- package/dist/lib/devices/pool.js +0 -30
- package/dist/lib/devices/reachability.d.ts +0 -25
- package/dist/lib/devices/reachability.js +0 -14
- package/dist/lib/devices/registry.d.ts +0 -141
- package/dist/lib/devices/registry.js +4 -151
- package/dist/lib/devices/resolve-profile.d.ts +0 -18
- package/dist/lib/devices/resolve-profile.js +0 -18
- package/dist/lib/devices/resolve-target.d.ts +0 -20
- package/dist/lib/devices/resolve-target.js +1 -51
- package/dist/lib/devices/rollout-verify.d.ts +1 -81
- package/dist/lib/devices/rollout-verify.js +0 -77
- package/dist/lib/devices/self-host.d.ts +0 -7
- package/dist/lib/devices/self-host.js +1 -29
- package/dist/lib/devices/ssh-config.d.ts +0 -18
- package/dist/lib/devices/ssh-config.js +0 -9
- package/dist/lib/devices/stats-cache.d.ts +0 -48
- package/dist/lib/devices/stats-cache.js +0 -80
- package/dist/lib/devices/sync.d.ts +0 -97
- package/dist/lib/devices/sync.js +0 -88
- package/dist/lib/devices/tailscale.d.ts +0 -18
- package/dist/lib/devices/tailscale.js +1 -38
- package/dist/lib/devices/terminfo.d.ts +0 -27
- package/dist/lib/devices/terminfo.js +2 -64
- package/dist/lib/devices/worker-pick.d.ts +0 -15
- package/dist/lib/devices/worker-pick.js +0 -48
- package/dist/lib/diff-text.d.ts +0 -18
- package/dist/lib/diff-text.js +0 -15
- package/dist/lib/doctor-diff.d.ts +0 -79
- package/dist/lib/doctor-diff.js +2 -181
- package/dist/lib/drift-sync.d.ts +0 -29
- package/dist/lib/drift-sync.js +0 -40
- package/dist/lib/drift.d.ts +0 -43
- package/dist/lib/drift.js +0 -31
- package/dist/lib/event-families.d.ts +0 -17
- package/dist/lib/event-families.js +0 -33
- package/dist/lib/event-provenance.d.ts +0 -4
- package/dist/lib/event-provenance.js +0 -5
- package/dist/lib/event-stream.d.ts +0 -29
- package/dist/lib/event-stream.js +0 -36
- package/dist/lib/events-ingest.d.ts +0 -27
- package/dist/lib/events-ingest.js +0 -54
- package/dist/lib/exec-account-home.d.ts +0 -24
- package/dist/lib/exec-account-home.js +0 -41
- package/dist/lib/exec-bounded.d.ts +1 -37
- package/dist/lib/exec-bounded.js +10 -46
- package/dist/lib/exec.d.ts +3 -583
- package/dist/lib/exec.js +18 -1025
- package/dist/lib/factory/snapshot.js +1 -15
- package/dist/lib/feed/activity-stream.d.ts +0 -27
- package/dist/lib/feed/activity-stream.js +4 -80
- package/dist/lib/feed/activity.d.ts +1 -243
- package/dist/lib/feed/activity.js +8 -273
- package/dist/lib/feed/answer.d.ts +0 -103
- package/dist/lib/feed/answer.js +0 -267
- package/dist/lib/feed/attention.d.ts +0 -56
- package/dist/lib/feed/attention.js +0 -161
- package/dist/lib/feed/envelope.d.ts +2 -17
- package/dist/lib/feed/envelope.js +0 -14
- package/dist/lib/feed/events.d.ts +0 -118
- package/dist/lib/feed/events.js +13 -213
- package/dist/lib/feed/feed.d.ts +1 -250
- package/dist/lib/feed/feed.js +24 -334
- package/dist/lib/feed/hub-server.d.ts +0 -100
- package/dist/lib/feed/hub-server.js +1 -191
- package/dist/lib/feed/hub.d.ts +0 -53
- package/dist/lib/feed/hub.js +0 -89
- package/dist/lib/feed/pr-status.d.ts +1 -19
- package/dist/lib/feed/pr-status.js +0 -18
- package/dist/lib/feed/tool-activity.d.ts +0 -59
- package/dist/lib/feed/tool-activity.js +1 -119
- package/dist/lib/feed/tools.d.ts +0 -100
- package/dist/lib/feed/tools.js +0 -89
- package/dist/lib/feed/watch.d.ts +0 -33
- package/dist/lib/feed/watch.js +2 -94
- package/dist/lib/feed-broadcast.d.ts +0 -148
- package/dist/lib/feed-broadcast.js +1 -283
- package/dist/lib/feed-outcome.d.ts +0 -50
- package/dist/lib/feed-outcome.js +1 -67
- package/dist/lib/feed-policy.d.ts +0 -6
- package/dist/lib/feed-policy.js +1 -27
- package/dist/lib/feed-post.d.ts +0 -61
- package/dist/lib/feed-post.js +4 -61
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -64
- package/dist/lib/fleet/apply.js +0 -125
- package/dist/lib/fleet/auth-sync.d.ts +0 -48
- package/dist/lib/fleet/auth-sync.js +4 -49
- package/dist/lib/fleet/capture.d.ts +0 -26
- package/dist/lib/fleet/capture.js +1 -36
- package/dist/lib/fleet/manifest.d.ts +0 -38
- package/dist/lib/fleet/manifest.js +0 -40
- package/dist/lib/fleet/types.d.ts +1 -138
- package/dist/lib/fleet/types.js +0 -12
- package/dist/lib/fleet-cache.d.ts +0 -12
- package/dist/lib/fleet-cache.js +0 -24
- package/dist/lib/fleet-shared-state.d.ts +6 -59
- package/dist/lib/fleet-shared-state.js +5 -51
- package/dist/lib/fleet-status.d.ts +0 -27
- package/dist/lib/fleet-status.js +0 -48
- package/dist/lib/format.d.ts +0 -74
- package/dist/lib/format.js +3 -77
- package/dist/lib/friction-heuristics.d.ts +0 -20
- package/dist/lib/friction-heuristics.js +0 -8
- package/dist/lib/fs-atomic.d.ts +0 -51
- package/dist/lib/fs-atomic.js +8 -66
- package/dist/lib/fs-walk.d.ts +0 -13
- package/dist/lib/fs-walk.js +0 -22
- package/dist/lib/fuzzy.d.ts +0 -29
- package/dist/lib/fuzzy.js +0 -31
- package/dist/lib/gemini-settings.js +0 -12
- package/dist/lib/git.d.ts +0 -366
- package/dist/lib/git.js +7 -574
- package/dist/lib/github/ci-failure.d.ts +30 -0
- package/dist/lib/github/ci-failure.js +95 -0
- package/dist/lib/github/gh-overload.d.ts +0 -38
- package/dist/lib/github/gh-overload.js +3 -55
- package/dist/lib/github/pr-mergeable.d.ts +3 -34
- package/dist/lib/github/pr-mergeable.js +2 -42
- package/dist/lib/github/pr-verdict.d.ts +0 -44
- package/dist/lib/github/pr-verdict.js +0 -36
- package/dist/lib/github/project-prs.d.ts +135 -105
- package/dist/lib/github/project-prs.js +530 -170
- package/dist/lib/github/release-drift.d.ts +45 -0
- package/dist/lib/github/release-drift.js +91 -0
- package/dist/lib/github/rest.d.ts +0 -50
- package/dist/lib/github/rest.js +0 -49
- package/dist/lib/github/viewer.d.ts +27 -0
- package/dist/lib/github/viewer.js +101 -0
- package/dist/lib/goose-commands.d.ts +0 -29
- package/dist/lib/goose-commands.js +3 -48
- package/dist/lib/harness/adapter.d.ts +0 -151
- package/dist/lib/harness/adapter.js +0 -41
- package/dist/lib/harness/adapters/claude.d.ts +0 -8
- package/dist/lib/harness/adapters/claude.js +0 -89
- package/dist/lib/harness/adapters/codex.js +0 -18
- package/dist/lib/harness/adapters/copilot.js +0 -3
- package/dist/lib/harness/adapters/cursor.js +0 -16
- package/dist/lib/harness/adapters/droid.js +0 -3
- package/dist/lib/harness/adapters/kimi.js +0 -19
- package/dist/lib/harness/adapters/muse.js +0 -9
- package/dist/lib/harness/adapters/opencode.js +0 -2
- package/dist/lib/harness/exec-config-version.d.ts +0 -2
- package/dist/lib/harness/exec-config-version.js +0 -13
- package/dist/lib/harness/index.js +0 -10
- package/dist/lib/harness-auth-capabilities.d.ts +0 -26
- package/dist/lib/harness-auth-capabilities.js +0 -18
- package/dist/lib/harness-connection-test.d.ts +0 -27
- package/dist/lib/harness-connection-test.js +2 -20
- package/dist/lib/heal.d.ts +0 -45
- package/dist/lib/heal.js +2 -82
- package/dist/lib/help.d.ts +0 -32
- package/dist/lib/help.js +0 -41
- package/dist/lib/helper-download.d.ts +0 -85
- package/dist/lib/helper-download.js +0 -95
- package/dist/lib/helper-versions.d.ts +0 -51
- package/dist/lib/helper-versions.js +1 -45
- package/dist/lib/hooks/cache.d.ts +0 -40
- package/dist/lib/hooks/cache.js +8 -122
- package/dist/lib/hooks/install.d.ts +0 -253
- package/dist/lib/hooks/install.js +49 -822
- package/dist/lib/hooks/match.d.ts +0 -24
- package/dist/lib/hooks/match.js +0 -31
- package/dist/lib/hooks/profile.d.ts +0 -21
- package/dist/lib/hooks/profile.js +0 -28
- package/dist/lib/hosts/credential-transport.d.ts +0 -6
- package/dist/lib/hosts/credential-transport.js +0 -17
- package/dist/lib/hosts/credentials.d.ts +0 -35
- package/dist/lib/hosts/credentials.js +0 -38
- package/dist/lib/hosts/dispatch.d.ts +0 -140
- package/dist/lib/hosts/dispatch.js +0 -176
- package/dist/lib/hosts/logs.d.ts +0 -25
- package/dist/lib/hosts/logs.js +1 -51
- package/dist/lib/hosts/option.d.ts +0 -12
- package/dist/lib/hosts/option.js +0 -12
- package/dist/lib/hosts/passthrough.d.ts +0 -129
- package/dist/lib/hosts/passthrough.js +12 -249
- package/dist/lib/hosts/progress.d.ts +0 -90
- package/dist/lib/hosts/progress.js +5 -115
- package/dist/lib/hosts/providers/devices.d.ts +0 -19
- package/dist/lib/hosts/providers/devices.js +1 -34
- package/dist/lib/hosts/providers/local.d.ts +0 -14
- package/dist/lib/hosts/providers/local.js +0 -22
- package/dist/lib/hosts/ready.d.ts +0 -99
- package/dist/lib/hosts/ready.js +0 -101
- package/dist/lib/hosts/reconcile.d.ts +0 -38
- package/dist/lib/hosts/reconcile.js +1 -50
- package/dist/lib/hosts/reconnect.d.ts +0 -75
- package/dist/lib/hosts/reconnect.js +0 -98
- package/dist/lib/hosts/registry.d.ts +0 -74
- package/dist/lib/hosts/registry.js +0 -110
- package/dist/lib/hosts/remote-cmd.d.ts +1 -228
- package/dist/lib/hosts/remote-cmd.js +19 -294
- package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +0 -1
- package/dist/lib/hosts/remote-cmd.test-fixture.js +0 -12
- package/dist/lib/hosts/remote-os.d.ts +0 -19
- package/dist/lib/hosts/remote-os.js +0 -22
- package/dist/lib/hosts/remote-session-id.d.ts +0 -22
- package/dist/lib/hosts/remote-session-id.js +0 -24
- package/dist/lib/hosts/routing-flag.d.ts +0 -21
- package/dist/lib/hosts/routing-flag.js +0 -21
- package/dist/lib/hosts/run-target.d.ts +0 -53
- package/dist/lib/hosts/run-target.js +0 -56
- package/dist/lib/hosts/session-index.d.ts +1 -53
- package/dist/lib/hosts/session-index.js +2 -59
- package/dist/lib/hosts/session-marker.d.ts +0 -31
- package/dist/lib/hosts/session-marker.js +0 -32
- package/dist/lib/hosts/ssh-config.d.ts +0 -25
- package/dist/lib/hosts/ssh-config.js +1 -32
- package/dist/lib/hosts/tasks.d.ts +0 -54
- package/dist/lib/hosts/tasks.js +0 -35
- package/dist/lib/hosts/types.d.ts +0 -39
- package/dist/lib/hosts/types.js +0 -22
- package/dist/lib/humans.d.ts +0 -21
- package/dist/lib/humans.js +0 -30
- package/dist/lib/identity/client.d.ts +1 -35
- package/dist/lib/identity/client.js +3 -29
- package/dist/lib/identity/index.d.ts +3 -27
- package/dist/lib/identity/index.js +8 -24
- package/dist/lib/import.d.ts +0 -104
- package/dist/lib/import.js +1 -137
- package/dist/lib/installations/active-check.d.ts +0 -53
- package/dist/lib/installations/active-check.js +0 -49
- package/dist/lib/installations/index.d.ts +0 -9
- package/dist/lib/installations/index.js +0 -9
- package/dist/lib/installations/installation-lock.js +0 -8
- package/dist/lib/installations/launch-gate.d.ts +0 -56
- package/dist/lib/installations/launch-gate.js +0 -83
- package/dist/lib/installations/migrate.d.ts +0 -100
- package/dist/lib/installations/migrate.js +105 -572
- package/dist/lib/installations/native-command.d.ts +0 -1
- package/dist/lib/installations/native-command.js +0 -6
- package/dist/lib/installations/resolve.d.ts +0 -24
- package/dist/lib/installations/resolve.js +0 -24
- package/dist/lib/installations/shims.d.ts +0 -395
- package/dist/lib/installations/shims.js +30 -957
- package/dist/lib/installations/store.d.ts +0 -199
- package/dist/lib/installations/store.js +1 -297
- package/dist/lib/installations/strategies.d.ts +0 -44
- package/dist/lib/installations/strategies.js +0 -87
- package/dist/lib/installations/types.d.ts +1 -67
- package/dist/lib/installations/types.js +0 -6
- package/dist/lib/installations/update-cancellation.d.ts +0 -74
- package/dist/lib/installations/update-cancellation.js +0 -74
- package/dist/lib/installations/update-policy.d.ts +0 -57
- package/dist/lib/installations/update-policy.js +0 -62
- package/dist/lib/installations/update-runtime.d.ts +0 -88
- package/dist/lib/installations/update-runtime.js +1 -127
- package/dist/lib/installations/update.d.ts +0 -53
- package/dist/lib/installations/update.js +0 -95
- package/dist/lib/installations/versions.d.ts +0 -310
- package/dist/lib/installations/versions.js +14 -837
- package/dist/lib/isolation-boundary-report.d.ts +0 -7
- package/dist/lib/isolation-boundary-report.js +0 -7
- package/dist/lib/launch-identity.d.ts +0 -8
- package/dist/lib/launch-identity.js +0 -8
- package/dist/lib/linear-autoclose.d.ts +0 -25
- package/dist/lib/linear-autoclose.js +0 -19
- package/dist/lib/linear-cache.d.ts +0 -57
- package/dist/lib/linear-cache.js +1 -81
- package/dist/lib/linear-project-counts.d.ts +0 -83
- package/dist/lib/linear-project-counts.js +2 -64
- package/dist/lib/linear-projects.d.ts +0 -62
- package/dist/lib/linear-projects.js +0 -85
- package/dist/lib/linear-rate-limit.d.ts +0 -21
- package/dist/lib/linear-rate-limit.js +1 -93
- package/dist/lib/linux-userns.d.ts +1 -42
- package/dist/lib/linux-userns.js +0 -47
- package/dist/lib/lock-compromise.d.ts +0 -7
- package/dist/lib/lock-compromise.js +0 -7
- package/dist/lib/log-follow.d.ts +0 -2
- package/dist/lib/log-follow.js +5 -15
- package/dist/lib/loop.d.ts +0 -106
- package/dist/lib/loop.js +0 -135
- package/dist/lib/machine-id.d.ts +0 -19
- package/dist/lib/machine-id.js +0 -19
- package/dist/lib/mailbox-gc.d.ts +0 -7
- package/dist/lib/mailbox-gc.js +0 -25
- package/dist/lib/mailbox-target.d.ts +0 -31
- package/dist/lib/mailbox-target.js +0 -27
- package/dist/lib/mailbox.d.ts +0 -77
- package/dist/lib/mailbox.js +5 -105
- package/dist/lib/manifest.d.ts +0 -4
- package/dist/lib/manifest.js +0 -36
- package/dist/lib/markdown.d.ts +0 -3
- package/dist/lib/markdown.js +0 -9
- package/dist/lib/mcp-registry.d.ts +1 -50
- package/dist/lib/mcp-registry.js +0 -64
- package/dist/lib/mcp.d.ts +0 -115
- package/dist/lib/mcp.js +3 -199
- package/dist/lib/memory-cache.d.ts +0 -11
- package/dist/lib/memory-cache.js +0 -9
- package/dist/lib/memory.d.ts +0 -52
- package/dist/lib/memory.js +12 -74
- package/dist/lib/menubar/download-menubar.d.ts +0 -35
- package/dist/lib/menubar/download-menubar.js +0 -38
- package/dist/lib/menubar/install-menubar.d.ts +0 -405
- package/dist/lib/menubar/install-menubar.js +25 -667
- package/dist/lib/menubar/migrate-prefs.d.ts +0 -47
- package/dist/lib/menubar/migrate-prefs.js +1 -70
- package/dist/lib/menubar/notify-desktop.d.ts +0 -82
- package/dist/lib/menubar/notify-desktop.js +0 -68
- package/dist/lib/menubar/resolve-version.d.ts +0 -41
- package/dist/lib/menubar/resolve-version.js +2 -44
- package/dist/lib/menubar/snapshot.d.ts +13 -66
- package/dist/lib/menubar/snapshot.js +45 -39
- package/dist/lib/merged-resources.d.ts +0 -10
- package/dist/lib/merged-resources.js +0 -10
- package/dist/lib/migrate-fold.d.ts +0 -31
- package/dist/lib/migrate-fold.js +6 -38
- package/dist/lib/model-tier-overrides.d.ts +0 -30
- package/dist/lib/model-tier-overrides.js +0 -14
- package/dist/lib/model-tiers.d.ts +0 -43
- package/dist/lib/model-tiers.js +5 -78
- package/dist/lib/models.d.ts +0 -145
- package/dist/lib/models.js +3 -333
- package/dist/lib/monitors/config.d.ts +0 -187
- package/dist/lib/monitors/config.js +4 -101
- package/dist/lib/monitors/dispatch.d.ts +0 -22
- package/dist/lib/monitors/dispatch.js +0 -35
- package/dist/lib/monitors/engine.d.ts +1 -53
- package/dist/lib/monitors/engine.js +17 -106
- package/dist/lib/monitors/fingerprint.d.ts +0 -43
- package/dist/lib/monitors/fingerprint.js +0 -57
- package/dist/lib/monitors/pid-watch.d.ts +0 -31
- package/dist/lib/monitors/pid-watch.js +0 -31
- package/dist/lib/monitors/remote.d.ts +0 -52
- package/dist/lib/monitors/remote.js +0 -42
- package/dist/lib/monitors/sources/command.d.ts +2 -9
- package/dist/lib/monitors/sources/command.js +13 -34
- package/dist/lib/monitors/sources/device.d.ts +0 -10
- package/dist/lib/monitors/sources/device.js +0 -14
- package/dist/lib/monitors/sources/failure.d.ts +0 -27
- package/dist/lib/monitors/sources/failure.js +0 -27
- package/dist/lib/monitors/sources/file.d.ts +0 -10
- package/dist/lib/monitors/sources/file.js +0 -11
- package/dist/lib/monitors/sources/http.d.ts +0 -7
- package/dist/lib/monitors/sources/http.js +0 -9
- package/dist/lib/monitors/sources/index.d.ts +0 -9
- package/dist/lib/monitors/sources/index.js +0 -9
- package/dist/lib/monitors/sources/poll.d.ts +0 -8
- package/dist/lib/monitors/sources/poll.js +0 -8
- package/dist/lib/monitors/sources/types.d.ts +0 -18
- package/dist/lib/monitors/sources/types.js +0 -8
- package/dist/lib/monitors/sources/webhook.d.ts +0 -7
- package/dist/lib/monitors/sources/webhook.js +0 -7
- package/dist/lib/monitors/sources/ws.d.ts +0 -10
- package/dist/lib/monitors/sources/ws.js +3 -13
- package/dist/lib/monitors/state.d.ts +0 -132
- package/dist/lib/monitors/state.js +2 -86
- package/dist/lib/native-accounts.d.ts +0 -32
- package/dist/lib/native-accounts.js +0 -17
- package/dist/lib/net-close.d.ts +0 -9
- package/dist/lib/net-close.js +0 -5
- package/dist/lib/notify.d.ts +0 -47
- package/dist/lib/notify.js +0 -30
- package/dist/lib/onepassword.d.ts +0 -14
- package/dist/lib/onepassword.js +0 -12
- package/dist/lib/open-url.d.ts +0 -38
- package/dist/lib/open-url.js +1 -69
- package/dist/lib/openclaw-keychain.js +2 -7
- package/dist/lib/operator.d.ts +0 -9
- package/dist/lib/operator.js +0 -34
- package/dist/lib/origin-machine.d.ts +0 -16
- package/dist/lib/origin-machine.js +0 -16
- package/dist/lib/output/git-output.d.ts +0 -31
- package/dist/lib/output/git-output.js +4 -43
- package/dist/lib/overdue.d.ts +0 -35
- package/dist/lib/overdue.js +0 -60
- package/dist/lib/owner-message.d.ts +0 -20
- package/dist/lib/owner-message.js +1 -40
- package/dist/lib/packages/output-home.d.ts +0 -28
- package/dist/lib/packages/output-home.js +0 -114
- package/dist/lib/paths.d.ts +0 -26
- package/dist/lib/paths.js +1 -27
- package/dist/lib/percentile.d.ts +0 -11
- package/dist/lib/percentile.js +0 -11
- package/dist/lib/perf/db.d.ts +0 -16
- package/dist/lib/perf/db.js +3 -32
- package/dist/lib/perf/spool.d.ts +0 -12
- package/dist/lib/perf/spool.js +0 -13
- package/dist/lib/perf/types.d.ts +0 -26
- package/dist/lib/perf/types.js +0 -1
- package/dist/lib/permissions-registry.d.ts +0 -48
- package/dist/lib/permissions-registry.js +0 -108
- package/dist/lib/permissions.d.ts +0 -215
- package/dist/lib/permissions.js +4 -407
- package/dist/lib/picker.d.ts +0 -124
- package/dist/lib/picker.js +0 -140
- package/dist/lib/placement.d.ts +0 -57
- package/dist/lib/placement.js +0 -47
- package/dist/lib/platform/exec.d.ts +0 -73
- package/dist/lib/platform/exec.js +0 -80
- package/dist/lib/platform/index.d.ts +0 -14
- package/dist/lib/platform/index.js +0 -14
- package/dist/lib/platform/ipc.d.ts +0 -10
- package/dist/lib/platform/ipc.js +0 -13
- package/dist/lib/platform/links.d.ts +0 -14
- package/dist/lib/platform/links.js +0 -25
- package/dist/lib/platform/paths.d.ts +0 -48
- package/dist/lib/platform/paths.js +0 -52
- package/dist/lib/platform/posixpath.d.ts +0 -18
- package/dist/lib/platform/posixpath.js +0 -62
- package/dist/lib/platform/process.d.ts +0 -67
- package/dist/lib/platform/process.js +5 -99
- package/dist/lib/platform/winpath.d.ts +0 -50
- package/dist/lib/platform/winpath.js +0 -81
- package/dist/lib/plugins/plugin-marketplace.d.ts +0 -165
- package/dist/lib/plugins/plugin-marketplace.js +10 -238
- package/dist/lib/plugins/plugins.d.ts +0 -238
- package/dist/lib/plugins/plugins.js +20 -454
- package/dist/lib/plugins/skills.d.ts +0 -86
- package/dist/lib/plugins/skills.js +1 -139
- package/dist/lib/pr-land-detach.d.ts +0 -17
- package/dist/lib/pr-land-detach.js +0 -30
- package/dist/lib/pricing/cost.d.ts +0 -29
- package/dist/lib/pricing/cost.js +0 -38
- package/dist/lib/pricing/index.d.ts +0 -6
- package/dist/lib/pricing/index.js +0 -6
- package/dist/lib/pricing/table.d.ts +0 -8
- package/dist/lib/pricing/table.js +3 -56
- package/dist/lib/probe.d.ts +0 -5
- package/dist/lib/probe.js +0 -40
- package/dist/lib/profiles-presets.d.ts +0 -20
- package/dist/lib/profiles-presets.js +1 -36
- package/dist/lib/profiles.d.ts +0 -185
- package/dist/lib/profiles.js +1 -158
- package/dist/lib/project-doctor.d.ts +0 -29
- package/dist/lib/project-doctor.js +0 -26
- package/dist/lib/project-focus.d.ts +0 -41
- package/dist/lib/project-focus.js +0 -49
- package/dist/lib/project-import.d.ts +0 -41
- package/dist/lib/project-import.js +0 -36
- package/dist/lib/project-key.d.ts +0 -65
- package/dist/lib/project-key.js +0 -70
- package/dist/lib/project-launch.d.ts +0 -49
- package/dist/lib/project-launch.js +2 -91
- package/dist/lib/project-probe.d.ts +0 -86
- package/dist/lib/project-probe.js +1 -88
- package/dist/lib/project-pull.d.ts +0 -96
- package/dist/lib/project-pull.js +0 -122
- package/dist/lib/project-resources.d.ts +0 -44
- package/dist/lib/project-resources.js +7 -171
- package/dist/lib/project-root.d.ts +0 -95
- package/dist/lib/project-root.js +0 -101
- package/dist/lib/project-schedule.d.ts +0 -43
- package/dist/lib/project-schedule.js +0 -52
- package/dist/lib/project-status.d.ts +0 -108
- package/dist/lib/project-status.js +0 -117
- package/dist/lib/projects.d.ts +0 -197
- package/dist/lib/projects.js +1 -213
- package/dist/lib/pwsh.d.ts +0 -41
- package/dist/lib/pwsh.js +0 -51
- package/dist/lib/quick-todo.d.ts +84 -0
- package/dist/lib/quick-todo.js +243 -0
- package/dist/lib/reconcile-and-repair.d.ts +0 -78
- package/dist/lib/reconcile-and-repair.js +3 -66
- package/dist/lib/redact.d.ts +0 -29
- package/dist/lib/redact.js +0 -54
- package/dist/lib/refresh-coordinator.d.ts +0 -15
- package/dist/lib/refresh-coordinator.js +0 -10
- package/dist/lib/refresh.d.ts +0 -39
- package/dist/lib/refresh.js +0 -45
- package/dist/lib/registry.d.ts +0 -65
- package/dist/lib/registry.js +0 -127
- package/dist/lib/reminders.d.ts +0 -21
- package/dist/lib/reminders.js +0 -30
- package/dist/lib/remote-agents-json.d.ts +0 -44
- package/dist/lib/remote-agents-json.js +1 -44
- package/dist/lib/reserved-stores.d.ts +0 -28
- package/dist/lib/reserved-stores.js +2 -28
- package/dist/lib/resource-aliases.d.ts +0 -12
- package/dist/lib/resource-aliases.js +0 -12
- package/dist/lib/resource-content-diff.d.ts +0 -28
- package/dist/lib/resource-content-diff.js +7 -34
- package/dist/lib/resource-inventory.d.ts +0 -51
- package/dist/lib/resource-inventory.js +0 -45
- package/dist/lib/resource-patterns.d.ts +0 -32
- package/dist/lib/resource-patterns.js +0 -34
- package/dist/lib/resource-profiles.d.ts +0 -7
- package/dist/lib/resource-profiles.js +0 -11
- package/dist/lib/resources/types.d.ts +0 -50
- package/dist/lib/resources/types.js +0 -7
- package/dist/lib/resources/workflows.d.ts +0 -7
- package/dist/lib/resources/workflows.js +0 -13
- package/dist/lib/resources.d.ts +0 -65
- package/dist/lib/resources.js +0 -78
- package/dist/lib/routers.d.ts +0 -67
- package/dist/lib/routers.js +0 -60
- package/dist/lib/routine-activation.d.ts +0 -23
- package/dist/lib/routine-activation.js +0 -24
- package/dist/lib/routine-context.d.ts +1 -91
- package/dist/lib/routine-context.js +0 -107
- package/dist/lib/routine-notify-owner.d.ts +0 -79
- package/dist/lib/routine-notify-owner.js +1 -103
- package/dist/lib/routine-notify.d.ts +0 -70
- package/dist/lib/routine-notify.js +1 -75
- package/dist/lib/routine-process-cleanup.d.ts +0 -1
- package/dist/lib/routine-process-cleanup.js +1 -4
- package/dist/lib/routine-readiness.d.ts +0 -63
- package/dist/lib/routine-readiness.js +4 -86
- package/dist/lib/routines-format.d.ts +0 -40
- package/dist/lib/routines-format.js +0 -67
- package/dist/lib/routines-placement.d.ts +0 -33
- package/dist/lib/routines-placement.js +0 -40
- package/dist/lib/routines-project.d.ts +0 -57
- package/dist/lib/routines-project.js +6 -80
- package/dist/lib/rules/compile.d.ts +0 -66
- package/dist/lib/rules/compile.js +6 -118
- package/dist/lib/rules/compose.d.ts +0 -56
- package/dist/lib/rules/compose.js +2 -83
- package/dist/lib/rules/rules.d.ts +0 -23
- package/dist/lib/rules/rules.js +0 -35
- package/dist/lib/rules/run-sync.d.ts +0 -16
- package/dist/lib/rules/run-sync.js +1 -44
- package/dist/lib/run-config.d.ts +0 -7
- package/dist/lib/run-config.js +0 -8
- package/dist/lib/run-defaults.d.ts +0 -14
- package/dist/lib/run-defaults.js +0 -14
- package/dist/lib/run-notify.d.ts +0 -18
- package/dist/lib/run-notify.js +0 -36
- package/dist/lib/run-trace-sync.d.ts +0 -21
- package/dist/lib/run-trace-sync.js +2 -66
- package/dist/lib/rush-session.d.ts +0 -26
- package/dist/lib/rush-session.js +0 -28
- package/dist/lib/sandbox.d.ts +0 -45
- package/dist/lib/sandbox.js +5 -93
- package/dist/lib/scheduler.d.ts +0 -28
- package/dist/lib/scheduler.js +0 -45
- package/dist/lib/scheduling/routines.d.ts +0 -652
- package/dist/lib/scheduling/routines.js +8 -475
- package/dist/lib/secrets-cli.d.ts +3 -8
- package/dist/lib/secrets-cli.js +1 -19
- package/dist/lib/secrets-client.d.ts +0 -117
- package/dist/lib/secrets-client.js +4 -275
- package/dist/lib/secrets-policy.d.ts +0 -142
- package/dist/lib/secrets-policy.js +4 -237
- package/dist/lib/secrets-types.d.ts +0 -87
- package/dist/lib/secrets-types.js +0 -13
- package/dist/lib/self-heal/checks/hook-manifest.js +0 -25
- package/dist/lib/self-heal/checks/hook-runtime.js +0 -5
- package/dist/lib/self-heal/checks/install-staging.d.ts +0 -1
- package/dist/lib/self-heal/checks/install-staging.js +1 -28
- package/dist/lib/self-heal/checks/menubar-helper.js +0 -5
- package/dist/lib/self-heal/checks/path.js +0 -9
- package/dist/lib/self-heal/checks/resources.js +0 -5
- package/dist/lib/self-heal/checks/shadowing.js +2 -16
- package/dist/lib/self-heal/checks/shims.js +0 -14
- package/dist/lib/self-heal/child.d.ts +12 -0
- package/dist/lib/self-heal/child.js +23 -0
- package/dist/lib/self-heal/registry.d.ts +0 -9
- package/dist/lib/self-heal/registry.js +0 -16
- package/dist/lib/self-heal/types.d.ts +0 -12
- package/dist/lib/self-heal/types.js +0 -15
- package/dist/lib/self-update.d.ts +0 -312
- package/dist/lib/self-update.js +9 -360
- package/dist/lib/service-manifest.d.ts +0 -39
- package/dist/lib/service-manifest.js +0 -72
- package/dist/lib/session/active.d.ts +13 -869
- package/dist/lib/session/active.js +20 -976
- package/dist/lib/session/actor-sidecar.d.ts +1 -32
- package/dist/lib/session/actor-sidecar.js +1 -41
- package/dist/lib/session/bookmarks.d.ts +0 -33
- package/dist/lib/session/bookmarks.js +0 -37
- package/dist/lib/session/bundle.d.ts +0 -86
- package/dist/lib/session/bundle.js +0 -54
- package/dist/lib/session/claude-accounts.d.ts +0 -40
- package/dist/lib/session/claude-accounts.js +0 -49
- package/dist/lib/session/cloud.d.ts +1 -23
- package/dist/lib/session/cloud.js +0 -26
- package/dist/lib/session/db.d.ts +5 -658
- package/dist/lib/session/db.js +22 -1443
- package/dist/lib/session/detached.d.ts +0 -21
- package/dist/lib/session/detached.js +0 -29
- package/dist/lib/session/discover.d.ts +3 -420
- package/dist/lib/session/discover.js +30 -1123
- package/dist/lib/session/fork.d.ts +1 -41
- package/dist/lib/session/fork.js +0 -19
- package/dist/lib/session/ghostty-tabs.d.ts +0 -24
- package/dist/lib/session/ghostty-tabs.js +0 -37
- package/dist/lib/session/glance-files.d.ts +19 -0
- package/dist/lib/session/glance-files.js +258 -0
- package/dist/lib/session/hook-sessions.d.ts +0 -33
- package/dist/lib/session/hook-sessions.js +4 -99
- package/dist/lib/session/host-link.d.ts +1 -94
- package/dist/lib/session/host-link.js +1 -81
- package/dist/lib/session/inject-target.d.ts +8 -0
- package/dist/lib/session/inject-target.js +32 -0
- package/dist/lib/session/inject.d.ts +0 -15
- package/dist/lib/session/inject.js +0 -15
- package/dist/lib/session/live-metadata.d.ts +1 -34
- package/dist/lib/session/live-metadata.js +1 -73
- package/dist/lib/session/local-tmux-attach.d.ts +0 -37
- package/dist/lib/session/local-tmux-attach.js +1 -76
- package/dist/lib/session/migrate-targets.d.ts +0 -46
- package/dist/lib/session/migrate-targets.js +0 -24
- package/dist/lib/session/migrations.d.ts +0 -12
- package/dist/lib/session/migrations.js +1 -20
- package/dist/lib/session/mirror.d.ts +0 -32
- package/dist/lib/session/mirror.js +0 -77
- package/dist/lib/session/origin-machine.js +0 -3
- package/dist/lib/session/pid-registry.d.ts +0 -80
- package/dist/lib/session/pid-registry.js +2 -81
- package/dist/lib/session/presence.d.ts +0 -39
- package/dist/lib/session/presence.js +2 -52
- package/dist/lib/session/process-view.d.ts +0 -11
- package/dist/lib/session/process-view.js +0 -25
- package/dist/lib/session/projection.d.ts +0 -3
- package/dist/lib/session/projection.js +0 -10
- package/dist/lib/session/provenance.d.ts +1 -37
- package/dist/lib/session/provenance.js +0 -69
- package/dist/lib/session/recovery.d.ts +1 -40
- package/dist/lib/session/recovery.js +2 -80
- package/dist/lib/session/relative-time.js +0 -3
- package/dist/lib/session/remote/peer-stream.d.ts +0 -42
- package/dist/lib/session/remote/peer-stream.js +0 -64
- package/dist/lib/session/remote/remote-bundle.d.ts +0 -6
- package/dist/lib/session/remote/remote-bundle.js +0 -21
- package/dist/lib/session/remote/remote-list.d.ts +1 -110
- package/dist/lib/session/remote/remote-list.js +5 -139
- package/dist/lib/session/remote/remote.d.ts +0 -98
- package/dist/lib/session/remote/remote.js +3 -119
- package/dist/lib/session/remote/watch.d.ts +1 -34
- package/dist/lib/session/remote/watch.js +12 -72
- package/dist/lib/session/remote-active.d.ts +0 -35
- package/dist/lib/session/remote-active.js +0 -48
- package/dist/lib/session/remote-bundle.js +0 -2
- package/dist/lib/session/remote-list.js +0 -2
- package/dist/lib/session/remote-preview-cache.d.ts +0 -7
- package/dist/lib/session/remote-preview-cache.js +1 -76
- package/dist/lib/session/remote.js +0 -2
- package/dist/lib/session/resume-command.d.ts +0 -6
- package/dist/lib/session/resume-command.js +0 -6
- package/dist/lib/session/resume-owner.d.ts +1 -52
- package/dist/lib/session/resume-owner.js +0 -56
- package/dist/lib/session/run-names.d.ts +0 -24
- package/dist/lib/session/run-names.js +0 -26
- package/dist/lib/session/session-cache.d.ts +2 -146
- package/dist/lib/session/session-cache.js +26 -203
- package/dist/lib/session/short-id.js +0 -3
- package/dist/lib/session/sync/agents.d.ts +0 -68
- package/dist/lib/session/sync/agents.js +0 -0
- package/dist/lib/session/sync/backend.d.ts +0 -39
- package/dist/lib/session/sync/backend.js +0 -45
- package/dist/lib/session/sync/config.d.ts +0 -27
- package/dist/lib/session/sync/config.js +0 -56
- package/dist/lib/session/sync/managed-config.d.ts +0 -17
- package/dist/lib/session/sync/managed-config.js +0 -17
- package/dist/lib/session/sync/managed-key.d.ts +0 -38
- package/dist/lib/session/sync/managed-key.js +1 -42
- package/dist/lib/session/sync/net-client.d.ts +0 -36
- package/dist/lib/session/sync/net-client.js +0 -30
- package/dist/lib/session/sync/provision.d.ts +0 -2
- package/dist/lib/session/sync/provision.js +0 -13
- package/dist/lib/session/sync/r2.d.ts +0 -20
- package/dist/lib/session/sync/r2.js +0 -20
- package/dist/lib/session/sync/transcript-crypto.d.ts +0 -37
- package/dist/lib/session/sync/transcript-crypto.js +5 -37
- package/dist/lib/session/sync/worker-template.d.ts +0 -5
- package/dist/lib/session/sync/worker-template.js +0 -40
- package/dist/lib/session/testdata/pid-registry-namespace.js +0 -2
- package/dist/lib/session/testdata/process-view-private.js +0 -1
- package/dist/lib/session/throughput.d.ts +0 -24
- package/dist/lib/session/throughput.js +1 -25
- package/dist/lib/session/timeline-pass.d.ts +1 -63
- package/dist/lib/session/timeline-pass.js +161 -148
- package/dist/lib/session/title.d.ts +0 -182
- package/dist/lib/session/title.js +0 -139
- package/dist/lib/session/tool-index.d.ts +2 -21
- package/dist/lib/session/tool-index.js +3 -75
- package/dist/lib/session/tool-store.d.ts +2 -48
- package/dist/lib/session/tool-store.js +1 -33
- package/dist/lib/session/viewing-in.d.ts +0 -67
- package/dist/lib/session/viewing-in.js +1 -71
- package/dist/lib/session/watch.js +0 -2
- package/dist/lib/session/width.js +0 -3
- package/dist/lib/sessions-client.d.ts +0 -46
- package/dist/lib/sessions-client.js +36 -113
- package/dist/lib/settings-manifest.d.ts +1 -17
- package/dist/lib/settings-manifest.js +4 -57
- package/dist/lib/setup-tool-install.d.ts +0 -1
- package/dist/lib/setup-tool-install.js +2 -7
- package/dist/lib/setup-tool-status.d.ts +0 -3
- package/dist/lib/setup-tool-status.js +4 -14
- package/dist/lib/sha256-asset.d.ts +0 -20
- package/dist/lib/sha256-asset.js +0 -20
- package/dist/lib/share-runtime.d.ts +0 -10
- package/dist/lib/share-runtime.js +1 -27
- package/dist/lib/shim-heal.d.ts +0 -15
- package/dist/lib/shim-heal.js +3 -29
- package/dist/lib/signin-badge.d.ts +0 -72
- package/dist/lib/signin-badge.js +0 -86
- package/dist/lib/sink-format.d.ts +0 -32
- package/dist/lib/sink-format.js +0 -14
- package/dist/lib/smart-launch.d.ts +0 -75
- package/dist/lib/smart-launch.js +1 -83
- package/dist/lib/snapshot.d.ts +0 -46
- package/dist/lib/snapshot.js +5 -31
- package/dist/lib/spinner.d.ts +0 -37
- package/dist/lib/spinner.js +0 -37
- package/dist/lib/sqlite.d.ts +0 -13
- package/dist/lib/sqlite.js +3 -71
- package/dist/lib/ssh-exec.d.ts +0 -209
- package/dist/lib/ssh-exec.js +11 -248
- package/dist/lib/ssh-tunnel.d.ts +0 -43
- package/dist/lib/ssh-tunnel.js +2 -48
- package/dist/lib/staleness/checkers/commands.d.ts +0 -4
- package/dist/lib/staleness/checkers/commands.js +0 -4
- package/dist/lib/staleness/checkers/hooks.d.ts +0 -10
- package/dist/lib/staleness/checkers/hooks.js +0 -15
- package/dist/lib/staleness/checkers/mcp.d.ts +0 -9
- package/dist/lib/staleness/checkers/mcp.js +0 -9
- package/dist/lib/staleness/checkers/permissions.d.ts +0 -12
- package/dist/lib/staleness/checkers/permissions.js +0 -13
- package/dist/lib/staleness/checkers/plugins.d.ts +0 -8
- package/dist/lib/staleness/checkers/plugins.js +0 -8
- package/dist/lib/staleness/checkers/rules.d.ts +0 -15
- package/dist/lib/staleness/checkers/rules.js +0 -26
- package/dist/lib/staleness/checkers/skills.d.ts +0 -4
- package/dist/lib/staleness/checkers/skills.js +0 -4
- package/dist/lib/staleness/checkers/subagents.d.ts +0 -9
- package/dist/lib/staleness/checkers/subagents.js +0 -9
- package/dist/lib/staleness/checkers/types.d.ts +0 -34
- package/dist/lib/staleness/checkers/types.js +0 -19
- package/dist/lib/staleness/checkers/workflows.d.ts +0 -7
- package/dist/lib/staleness/checkers/workflows.js +0 -7
- package/dist/lib/staleness/detectors/commands.js +0 -17
- package/dist/lib/staleness/detectors/hooks.js +1 -6
- package/dist/lib/staleness/detectors/mcp.js +0 -4
- package/dist/lib/staleness/detectors/permissions.js +10 -23
- package/dist/lib/staleness/detectors/rules.js +0 -6
- package/dist/lib/staleness/detectors/skills.d.ts +0 -1
- package/dist/lib/staleness/detectors/skills.js +1 -12
- package/dist/lib/staleness/detectors/types.d.ts +0 -10
- package/dist/lib/staleness/fingerprint.d.ts +0 -19
- package/dist/lib/staleness/fingerprint.js +0 -35
- package/dist/lib/staleness/index.d.ts +0 -28
- package/dist/lib/staleness/index.js +1 -45
- package/dist/lib/staleness/layers.d.ts +0 -23
- package/dist/lib/staleness/layers.js +0 -34
- package/dist/lib/staleness/prune.d.ts +0 -71
- package/dist/lib/staleness/prune.js +2 -27
- package/dist/lib/staleness/registry.d.ts +0 -10
- package/dist/lib/staleness/registry.js +3 -33
- package/dist/lib/staleness/types.d.ts +0 -36
- package/dist/lib/staleness/types.js +0 -5
- package/dist/lib/staleness/writers/commands.js +1 -48
- package/dist/lib/staleness/writers/hooks.js +1 -18
- package/dist/lib/staleness/writers/kinds.d.ts +0 -12
- package/dist/lib/staleness/writers/kinds.js +0 -1
- package/dist/lib/staleness/writers/lazy-map.d.ts +0 -11
- package/dist/lib/staleness/writers/mcp.js +0 -13
- package/dist/lib/staleness/writers/plugins.js +0 -4
- package/dist/lib/staleness/writers/rules.d.ts +0 -1
- package/dist/lib/staleness/writers/rules.js +1 -19
- package/dist/lib/staleness/writers/skills.js +3 -14
- package/dist/lib/staleness/writers/sources.d.ts +0 -11
- package/dist/lib/staleness/writers/sources.js +0 -32
- package/dist/lib/staleness/writers/subagents.js +0 -16
- package/dist/lib/staleness/writers/types.d.ts +0 -58
- package/dist/lib/staleness/writers/workflows.js +1 -1
- package/dist/lib/standalone-tools.d.ts +24 -0
- package/dist/lib/standalone-tools.js +58 -0
- package/dist/lib/star-nudge.d.ts +0 -32
- package/dist/lib/star-nudge.js +2 -36
- package/dist/lib/startup/command-registry.d.ts +0 -45
- package/dist/lib/startup/command-registry.js +1 -46
- package/dist/lib/startup/dev-build.d.ts +0 -9
- package/dist/lib/startup/dev-build.js +1 -42
- package/dist/lib/startup/root-command.d.ts +0 -19
- package/dist/lib/startup/root-command.js +0 -19
- package/dist/lib/startup/spellcheck.d.ts +0 -13
- package/dist/lib/startup/spellcheck.js +0 -13
- package/dist/lib/state.d.ts +0 -376
- package/dist/lib/state.js +19 -737
- package/dist/lib/storage/selection.d.ts +0 -40
- package/dist/lib/storage/selection.js +0 -29
- package/dist/lib/subagents-registry.d.ts +0 -56
- package/dist/lib/subagents-registry.js +0 -99
- package/dist/lib/subagents.d.ts +0 -128
- package/dist/lib/subagents.js +1 -158
- package/dist/lib/summarizer/config.d.ts +0 -37
- package/dist/lib/summarizer/config.js +0 -37
- package/dist/lib/summarizer/pass.d.ts +0 -20
- package/dist/lib/summarizer/pass.js +1 -34
- package/dist/lib/summarizer/summarize.d.ts +1 -49
- package/dist/lib/summarizer/summarize.js +0 -35
- package/dist/lib/sync-passphrase.d.ts +0 -16
- package/dist/lib/sync-passphrase.js +1 -18
- package/dist/lib/sync-status.d.ts +0 -72
- package/dist/lib/sync-status.js +0 -55
- package/dist/lib/sync-umbrella.d.ts +0 -54
- package/dist/lib/sync-umbrella.js +0 -48
- package/dist/lib/system-run-sync.d.ts +0 -5
- package/dist/lib/system-run-sync.js +1 -31
- package/dist/lib/teams/agents.d.ts +1 -444
- package/dist/lib/teams/agents.js +11 -871
- package/dist/lib/teams/api.d.ts +2 -52
- package/dist/lib/teams/api.js +4 -63
- package/dist/lib/teams/debug.d.ts +0 -6
- package/dist/lib/teams/debug.js +0 -6
- package/dist/lib/teams/delivery.d.ts +0 -41
- package/dist/lib/teams/delivery.js +0 -32
- package/dist/lib/teams/file_ops.d.ts +0 -11
- package/dist/lib/teams/file_ops.js +0 -11
- package/dist/lib/teams/forEach.d.ts +0 -76
- package/dist/lib/teams/forEach.js +1 -77
- package/dist/lib/teams/index.d.ts +1 -7
- package/dist/lib/teams/index.js +1 -7
- package/dist/lib/teams/parsers.d.ts +0 -4
- package/dist/lib/teams/parsers.js +0 -81
- package/dist/lib/teams/persistence.d.ts +0 -2
- package/dist/lib/teams/persistence.js +0 -12
- package/dist/lib/teams/placement-probe.d.ts +0 -12
- package/dist/lib/teams/placement-probe.js +1 -51
- package/dist/lib/teams/pr-watch.d.ts +0 -107
- package/dist/lib/teams/pr-watch.js +1 -107
- package/dist/lib/teams/registry.d.ts +0 -36
- package/dist/lib/teams/registry.js +0 -47
- package/dist/lib/teams/remoteWorktree.d.ts +0 -50
- package/dist/lib/teams/remoteWorktree.js +1 -96
- package/dist/lib/teams/scheduler.d.ts +0 -111
- package/dist/lib/teams/scheduler.js +2 -125
- package/dist/lib/teams/summarizer.d.ts +0 -22
- package/dist/lib/teams/summarizer.js +6 -50
- package/dist/lib/teams/supervisor.d.ts +0 -38
- package/dist/lib/teams/supervisor.js +0 -21
- package/dist/lib/teams/worktree.d.ts +0 -95
- package/dist/lib/teams/worktree.js +3 -110
- package/dist/lib/template.d.ts +0 -21
- package/dist/lib/template.js +0 -23
- package/dist/lib/term-client.d.ts +0 -26
- package/dist/lib/term-client.js +0 -48
- package/dist/lib/term-driver.d.ts +0 -5
- package/dist/lib/term-driver.js +0 -8
- package/dist/lib/terminal/backends/ghostty.d.ts +0 -2
- package/dist/lib/terminal/backends/ghostty.js +0 -12
- package/dist/lib/terminal/backends/index.d.ts +0 -17
- package/dist/lib/terminal/backends/index.js +0 -15
- package/dist/lib/terminal/backends/iterm.d.ts +0 -2
- package/dist/lib/terminal/backends/iterm.js +0 -10
- package/dist/lib/terminal/backends/terminal-app.d.ts +0 -10
- package/dist/lib/terminal/backends/terminal-app.js +0 -30
- package/dist/lib/terminal/backends/tmux.d.ts +0 -10
- package/dist/lib/terminal/backends/tmux.js +0 -2
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +0 -25
- package/dist/lib/terminal/backends/vscodium-agent.js +0 -36
- package/dist/lib/terminal/engine.d.ts +0 -17
- package/dist/lib/terminal/engine.js +0 -10
- package/dist/lib/terminal/index.d.ts +0 -8
- package/dist/lib/terminal/inject.d.ts +1 -173
- package/dist/lib/terminal/inject.js +0 -146
- package/dist/lib/terminal/policy.d.ts +0 -8
- package/dist/lib/terminal/policy.js +0 -1
- package/dist/lib/terminal/preferred.d.ts +0 -66
- package/dist/lib/terminal/preferred.js +0 -30
- package/dist/lib/terminal/quote.d.ts +0 -8
- package/dist/lib/terminal/quote.js +0 -8
- package/dist/lib/terminal/resolve.d.ts +0 -46
- package/dist/lib/terminal/resolve.js +0 -30
- package/dist/lib/terminal/run-surface.d.ts +0 -56
- package/dist/lib/terminal/run-surface.js +0 -46
- package/dist/lib/terminal/shell.d.ts +0 -3
- package/dist/lib/terminal/shell.js +0 -13
- package/dist/lib/terminal/transport.d.ts +0 -14
- package/dist/lib/terminal/transport.js +1 -30
- package/dist/lib/terminal/types.d.ts +0 -40
- package/dist/lib/terminal/types.js +0 -10
- package/dist/lib/text/relative-time.d.ts +0 -36
- package/dist/lib/text/relative-time.js +0 -43
- package/dist/lib/text/short-id.d.ts +0 -16
- package/dist/lib/text/short-id.js +0 -16
- package/dist/lib/text/width.d.ts +0 -24
- package/dist/lib/text/width.js +10 -52
- package/dist/lib/tmux/binary.d.ts +0 -36
- package/dist/lib/tmux/binary.js +0 -28
- package/dist/lib/tmux/index.d.ts +0 -5
- package/dist/lib/tmux/index.js +0 -5
- package/dist/lib/tmux/orphan-reap.d.ts +0 -253
- package/dist/lib/tmux/orphan-reap.js +3 -299
- package/dist/lib/tmux/paths.d.ts +0 -14
- package/dist/lib/tmux/paths.js +0 -14
- package/dist/lib/tmux/session.d.ts +0 -263
- package/dist/lib/tmux/session.js +6 -344
- package/dist/lib/traces/backend.d.ts +0 -20
- package/dist/lib/traces/backend.js +0 -23
- package/dist/lib/traces/classify.d.ts +0 -20
- package/dist/lib/traces/classify.js +0 -7
- package/dist/lib/traces/insights.d.ts +1 -84
- package/dist/lib/traces/insights.js +0 -126
- package/dist/lib/traces/phenotype.d.ts +0 -69
- package/dist/lib/traces/phenotype.js +0 -150
- package/dist/lib/traces/provision.d.ts +0 -1
- package/dist/lib/traces/provision.js +0 -5
- package/dist/lib/traces/schema2-build.d.ts +3 -60
- package/dist/lib/traces/schema2-build.js +8 -149
- package/dist/lib/traces/schema2-danger.d.ts +0 -30
- package/dist/lib/traces/schema2-danger.js +1 -63
- package/dist/lib/traces/schema2.d.ts +0 -11
- package/dist/lib/traces/segments.d.ts +0 -44
- package/dist/lib/traces/segments.js +0 -65
- package/dist/lib/traces/sync.d.ts +2 -239
- package/dist/lib/traces/sync.js +15 -237
- package/dist/lib/traces/worker-template.d.ts +0 -3
- package/dist/lib/traces/worker-template.js +0 -29
- package/dist/lib/triggers/handlers.d.ts +0 -82
- package/dist/lib/triggers/handlers.js +0 -75
- package/dist/lib/triggers/webhook.d.ts +0 -158
- package/dist/lib/triggers/webhook.js +0 -143
- package/dist/lib/types.d.ts +0 -736
- package/dist/lib/types.js +0 -50
- package/dist/lib/uninstall.d.ts +0 -17
- package/dist/lib/uninstall.js +0 -75
- package/dist/lib/usage-backoff.d.ts +0 -20
- package/dist/lib/usage-backoff.js +3 -60
- package/dist/lib/usage-refresh.d.ts +0 -154
- package/dist/lib/usage-refresh.js +8 -212
- package/dist/lib/verbs.d.ts +0 -12
- package/dist/lib/verbs.js +0 -12
- package/dist/lib/version-duplicates.d.ts +0 -6
- package/dist/lib/version-duplicates.js +0 -6
- package/dist/lib/version.d.ts +0 -55
- package/dist/lib/version.js +1 -58
- package/dist/lib/view-types.d.ts +0 -48
- package/dist/lib/warn-unpushed.d.ts +0 -27
- package/dist/lib/warn-unpushed.js +1 -45
- package/dist/lib/watchdog/history.d.ts +0 -1
- package/dist/lib/watchdog/history.js +0 -3
- package/dist/lib/watchdog/index.js +0 -2
- package/dist/lib/watchdog/log.d.ts +0 -19
- package/dist/lib/watchdog/log.js +0 -34
- package/dist/lib/watchdog/read.d.ts +0 -27
- package/dist/lib/watchdog/read.js +3 -58
- package/dist/lib/watchdog/rotate.d.ts +0 -139
- package/dist/lib/watchdog/rotate.js +2 -151
- package/dist/lib/watchdog/runner.d.ts +0 -125
- package/dist/lib/watchdog/runner.js +3 -223
- package/dist/lib/watchdog/service.d.ts +0 -1
- package/dist/lib/watchdog/service.js +0 -2
- package/dist/lib/watchdog/watchdog-agent.d.ts +0 -31
- package/dist/lib/watchdog/watchdog-agent.js +0 -27
- package/dist/lib/watchdog/watchdog.d.ts +0 -7
- package/dist/lib/watchdog/watchdog.js +0 -10
- package/dist/lib/watchdog/watchdogTail.js +0 -7
- package/dist/lib/whats-new.d.ts +0 -10
- package/dist/lib/whats-new.js +0 -21
- package/dist/lib/workflows-registry.d.ts +0 -45
- package/dist/lib/workflows-registry.js +0 -60
- package/dist/lib/workflows.d.ts +0 -282
- package/dist/lib/workflows.js +3 -213
- package/dist/lib/worktree/held.d.ts +0 -89
- package/dist/lib/worktree/held.js +1 -103
- package/dist/lib/wrap.d.ts +0 -32
- package/dist/lib/wrap.js +0 -32
- package/dist/lib/yaml-io.d.ts +0 -45
- package/dist/lib/yaml-io.js +0 -47
- package/dist/session-tracker/dist/adapters/claude.js +0 -2
- package/dist/session-tracker/dist/hook.sh +4 -37
- package/dist/session-tracker/dist/index.d.ts +0 -7
- package/dist/session-tracker/dist/index.js +0 -5
- package/dist/session-tracker/dist/install-hook.d.ts +0 -5
- package/dist/session-tracker/dist/install-hook.js +1 -15
- package/dist/session-tracker/dist/prune-state.js +0 -4
- package/dist/session-tracker/dist/reader.js +0 -4
- package/dist/session-tracker/dist/state-file.d.ts +0 -3
- package/dist/session-tracker/dist/state-file.js +3 -8
- package/package.json +3 -4
- package/scripts/postinstall.js +8 -116
- package/dist/lib/session/artifacts.d.ts +0 -14
- package/dist/lib/session/artifacts.js +0 -101
- package/dist/lib/session/bash-command.d.ts +0 -63
- package/dist/lib/session/bash-command.js +0 -490
- package/dist/lib/session/digest.d.ts +0 -66
- package/dist/lib/session/digest.js +0 -328
- package/dist/lib/session/highlights.d.ts +0 -151
- package/dist/lib/session/highlights.js +0 -391
- package/dist/lib/session/insights.d.ts +0 -165
- package/dist/lib/session/insights.js +0 -563
- package/dist/lib/session/linear.d.ts +0 -19
- package/dist/lib/session/linear.js +0 -99
- package/dist/lib/session/parse.d.ts +0 -224
- package/dist/lib/session/parse.js +0 -2408
- package/dist/lib/session/prompt.d.ts +0 -213
- package/dist/lib/session/prompt.js +0 -601
- package/dist/lib/session/render.d.ts +0 -133
- package/dist/lib/session/render.js +0 -1047
- package/dist/lib/session/share-html.d.ts +0 -35
- package/dist/lib/session/share-html.js +0 -319
- package/dist/lib/session/shell-programs.d.ts +0 -33
- package/dist/lib/session/shell-programs.js +0 -380
- package/dist/lib/session/state.d.ts +0 -269
- package/dist/lib/session/state.js +0 -777
- package/dist/lib/session/stream-render.d.ts +0 -4
- package/dist/lib/session/stream-render.js +0 -131
- package/dist/lib/session/tail.d.ts +0 -88
- package/dist/lib/session/tail.js +0 -294
- package/dist/lib/session/team-filter.d.ts +0 -129
- package/dist/lib/session/team-filter.js +0 -269
- package/dist/lib/session/timeline.d.ts +0 -172
- package/dist/lib/session/timeline.js +0 -636
- package/dist/lib/session/tool-calls.d.ts +0 -132
- package/dist/lib/session/tool-calls.js +0 -674
- package/dist/lib/session/trajectory-compare.d.ts +0 -48
- package/dist/lib/session/trajectory-compare.js +0 -116
- package/dist/lib/session/trajectory-html.d.ts +0 -19
- package/dist/lib/session/trajectory-html.js +0 -771
- package/dist/lib/session/trajectory-lineage.d.ts +0 -93
- package/dist/lib/session/trajectory-lineage.js +0 -195
- package/dist/lib/session/trajectory-text.d.ts +0 -38
- package/dist/lib/session/trajectory-text.js +0 -284
- package/dist/lib/session/trajectory.d.ts +0 -145
- package/dist/lib/session/trajectory.js +0 -394
- package/dist/lib/session/types.d.ts +0 -627
- package/dist/lib/session/types.js +0 -43
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Job execution engine for routines.
|
|
3
|
-
*
|
|
4
|
-
* Builds agent-specific CLI commands from job configs, spawns them with
|
|
5
|
-
* sandboxed or unsandboxed environments, captures stdout to log files,
|
|
6
|
-
* enforces timeouts, and extracts the final assistant report from the
|
|
7
|
-
* agent's stream-JSON output.
|
|
8
|
-
*
|
|
9
|
-
* Version/account selection mirrors `agents run`: when a routine does not pin
|
|
10
|
-
* `version:`, the runner uses the configured run strategy (default `balanced`)
|
|
11
|
-
* to pick a healthy install, pins the absolute binary via `getBinaryPath`, and
|
|
12
|
-
* arms same-agent failover across other healthy accounts when a rate/usage
|
|
13
|
-
* limit is detected mid-run (foreground `executeJob` only — detached daemon
|
|
14
|
-
* fires once with the pre-flight pick).
|
|
15
|
-
*/
|
|
16
1
|
import { spawn, execFileSync } from 'child_process';
|
|
17
2
|
import * as fs from 'fs';
|
|
18
3
|
import * as fsp from 'fs/promises';
|
|
@@ -60,7 +45,7 @@ function recordRoutineAuthOutcome(agent, accountName, version, outcome) {
|
|
|
60
45
|
: null;
|
|
61
46
|
recordRunAuthOutcome({ agent, accountId, version: version ?? null, account: accountName, outcome });
|
|
62
47
|
}
|
|
63
|
-
catch {
|
|
48
|
+
catch { }
|
|
64
49
|
}
|
|
65
50
|
export class RoutineAlreadyRunningError extends Error {
|
|
66
51
|
constructor(jobName, runId) {
|
|
@@ -70,26 +55,7 @@ export class RoutineAlreadyRunningError extends Error {
|
|
|
70
55
|
}
|
|
71
56
|
const ROUTINE_LAUNCH_LOCK_STALE_MS = 30_000;
|
|
72
57
|
const ROUTINE_LAUNCH_LOCK_WAIT_MS = 10_000;
|
|
73
|
-
|
|
74
|
-
* The prior run of this routine that still holds the active-run slot, or null.
|
|
75
|
-
*
|
|
76
|
-
* ONLY a run still marked `running` can hold the slot. Every terminal status —
|
|
77
|
-
* completed / failed / timeout / missed / blocked / skipped — releases it the
|
|
78
|
-
* moment it is reached (RUSH-2640). A `failed`/`timeout` record used to keep the
|
|
79
|
-
* slot while its pid stayed alive, but that conflated two different operations:
|
|
80
|
-
* cleaning up a leftover process group (reapTerminalRoutineProcesses's job) with
|
|
81
|
-
* occupying the slot. A daemon-launched run that reached a terminal state while
|
|
82
|
-
* still carrying the daemon's own pid (a host run that threw `target_unreachable`
|
|
83
|
-
* before spawning a child) then held the slot forever, because the daemon never
|
|
84
|
-
* dies and `isPidOurs` never went false — every later scheduled slot was refused
|
|
85
|
-
* with `already has an active run` while the routine was silently dead.
|
|
86
|
-
*
|
|
87
|
-
* A `running` record is also aged out past its own timeout: a run cannot
|
|
88
|
-
* legitimately outlive its configured deadline, so past that window it is a
|
|
89
|
-
* wedged record (a daemon that died mid-run, a missed child-exit event, a reused
|
|
90
|
-
* pid an old record without `spawnedAt` reads as "ours"), not a live run — and it
|
|
91
|
-
* never holds the slot regardless of what its recorded pid now points at.
|
|
92
|
-
*/
|
|
58
|
+
// Only a live, within-timeout running record holds the slot; dead/stale running and terminal records release it.
|
|
93
59
|
function activeRoutineRun(config) {
|
|
94
60
|
const timeoutMs = parseTimeout(config.timeout) || 10 * 60 * 1000;
|
|
95
61
|
const now = Date.now();
|
|
@@ -102,9 +68,6 @@ function activeRoutineRun(config) {
|
|
|
102
68
|
const limit = run.timeoutMs ?? timeoutMs;
|
|
103
69
|
if (Number.isFinite(startedAt) && now - startedAt >= limit)
|
|
104
70
|
continue;
|
|
105
|
-
// A provisional launcher claim carries no child pid yet — trust it until the
|
|
106
|
-
// timeout window above elapses. A record with a child pid is active only
|
|
107
|
-
// while that pid is genuinely ours (alive with the same birth time).
|
|
108
71
|
if (!run.pid)
|
|
109
72
|
return run;
|
|
110
73
|
if (isPidOurs(run.pid, run.spawnedAt))
|
|
@@ -112,14 +75,6 @@ function activeRoutineRun(config) {
|
|
|
112
75
|
}
|
|
113
76
|
return null;
|
|
114
77
|
}
|
|
115
|
-
/**
|
|
116
|
-
* Consecutive trailing `skipped`/`active_run` records — a routine that keeps
|
|
117
|
-
* being refused because a prior run "still owns" the slot. After the slot is
|
|
118
|
-
* released correctly on terminal states (see {@link activeRoutineRun}) this can
|
|
119
|
-
* only accumulate for a genuine long-overlap or a new wedge; either way it means
|
|
120
|
-
* the routine has stopped firing on schedule and should be surfaced, not left to
|
|
121
|
-
* pile up silently. `runs` is oldest→newest (listRuns sorts by run id).
|
|
122
|
-
*/
|
|
123
78
|
export function activeRunSkipStreak(runs) {
|
|
124
79
|
let streak = 0;
|
|
125
80
|
for (let i = runs.length - 1; i >= 0; i--) {
|
|
@@ -132,38 +87,17 @@ export function activeRunSkipStreak(runs) {
|
|
|
132
87
|
}
|
|
133
88
|
return streak;
|
|
134
89
|
}
|
|
135
|
-
/** How many consecutive active-run skips before a routine's stall is surfaced. */
|
|
136
90
|
const SKIP_STREAK_ALERT_THRESHOLD = 3;
|
|
137
|
-
|
|
138
|
-
* The pid to stamp on a launcher's provisional active claim, or null when the
|
|
139
|
-
* launcher is this box's routines daemon.
|
|
140
|
-
*
|
|
141
|
-
* The claim pid exists so a launcher that dies between claiming the slot and
|
|
142
|
-
* spawning the child releases the slot quickly (`isPidOurs` goes false) instead
|
|
143
|
-
* of wedging it for the full timeout. That fast recovery only helps a SHORT-LIVED
|
|
144
|
-
* foreground launcher (`agents routines run`): the daemon never dies between
|
|
145
|
-
* claim and spawn, and recording ITS pid is actively harmful — the daemon
|
|
146
|
-
* outlives every run, so `isPidOurs` never goes false and a claim finalized to a
|
|
147
|
-
* terminal state before its child spawned kept the slot and drew
|
|
148
|
-
* `reapTerminalRoutineProcesses` at the daemon's own process group on every tick
|
|
149
|
-
* (RUSH-2640, requirement: never record the daemon's own pid as a run's pid). So
|
|
150
|
-
* the daemon records no claim pid; the timeout window bounds a daemon that
|
|
151
|
-
* crashes mid-claim instead.
|
|
152
|
-
*/
|
|
91
|
+
// The long-lived daemon never records its own pid as a provisional child claim.
|
|
153
92
|
export function launcherClaimPid() {
|
|
154
93
|
try {
|
|
155
|
-
// Mirrors daemon.ts readDaemonPid() (PID_FILE = 'daemon.pid'); read directly
|
|
156
|
-
// rather than importing it to avoid a runner<->daemon import cycle.
|
|
157
94
|
const daemonPid = parseInt(fs.readFileSync(path.join(getDaemonDir(), 'daemon.pid'), 'utf-8').trim(), 10);
|
|
158
95
|
if (Number.isFinite(daemonPid) && daemonPid === process.pid)
|
|
159
96
|
return null;
|
|
160
97
|
}
|
|
161
|
-
catch {
|
|
98
|
+
catch { }
|
|
162
99
|
return process.pid;
|
|
163
100
|
}
|
|
164
|
-
/** Serialize concurrent launches of one routine on this box (the on-disk claim
|
|
165
|
-
* primitive `claimRunSlot` is what holds across processes; this lock only makes
|
|
166
|
-
* the allocate→spawn window atomic within this process's launch paths). */
|
|
167
101
|
async function withRoutineLock(config, launch) {
|
|
168
102
|
const target = path.join(getJobRunsDir(config.name), '.launch-claim');
|
|
169
103
|
ensureLockTarget(target, '', 0o700);
|
|
@@ -184,13 +118,6 @@ async function withRoutineLock(config, launch) {
|
|
|
184
118
|
await release();
|
|
185
119
|
}
|
|
186
120
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Reject placement/body combinations the runner cannot execute — before the
|
|
189
|
-
* attempt is allocated, so an invalid config (host+workflow, cloud+command, …)
|
|
190
|
-
* throws cleanly rather than allocating a run record it can never satisfy. These
|
|
191
|
-
* mirror the defensive guards inside `executeJobOnHost`/`executeJobOnCloud`;
|
|
192
|
-
* `validateJob` already rejects the same combinations at add/edit time.
|
|
193
|
-
*/
|
|
194
121
|
function assertRunnablePlacement(config) {
|
|
195
122
|
const strategy = resolveHostStrategy(config);
|
|
196
123
|
if (strategy === 'host' || strategy === 'fleet') {
|
|
@@ -210,7 +137,6 @@ function assertRunnablePlacement(config) {
|
|
|
210
137
|
throw new Error(`Routine '${config.name}' uses 'command:', which can't execute in the cloud yet — remove 'hostStrategy: cloud' or 'command:'.`);
|
|
211
138
|
}
|
|
212
139
|
}
|
|
213
|
-
/** Write a pre-execution terminal record (blocked/skipped) that spawns nothing. */
|
|
214
140
|
function writeTerminalRecord(config, runId, status, trigger, extra) {
|
|
215
141
|
fs.mkdirSync(getRunDir(config.name, runId), { recursive: true });
|
|
216
142
|
const now = new Date().toISOString();
|
|
@@ -236,7 +162,6 @@ function writeTerminalRecord(config, runId, status, trigger, extra) {
|
|
|
236
162
|
writeRunMeta(meta);
|
|
237
163
|
return meta;
|
|
238
164
|
}
|
|
239
|
-
/** Persist the cross-entry-point active claim before releasing the launch lock. */
|
|
240
165
|
function writeActiveClaim(config, attempt) {
|
|
241
166
|
const now = new Date().toISOString();
|
|
242
167
|
const meta = {
|
|
@@ -245,17 +170,7 @@ function writeActiveClaim(config, attempt) {
|
|
|
245
170
|
...runProvenance(config),
|
|
246
171
|
...attempt.stamp,
|
|
247
172
|
...(config.workflow ? { workflow: config.workflow } : config.command ? { command: config.command } : config.agent ? { agent: config.agent } : {}),
|
|
248
|
-
// The launcher owns this provisional claim until the command/agent child
|
|
249
|
-
// replaces it with its own pid. Recording a SHORT-LIVED foreground launcher's
|
|
250
|
-
// pid makes a crash between lock release and child spawn recoverable instead
|
|
251
|
-
// of wedging the routine for its full configured timeout. The long-lived
|
|
252
|
-
// daemon records no pid here (see launcherClaimPid): its pid never dies, so
|
|
253
|
-
// recording it wedged the slot forever and mis-aimed the process reaper at the
|
|
254
|
-
// daemon itself (RUSH-2640).
|
|
255
173
|
pid: launcherClaimPid(),
|
|
256
|
-
// `isPidOurs` compares this value with the OS process birth time. The
|
|
257
|
-
// daemon may have been alive for days before claiming a routine, so the
|
|
258
|
-
// claim must carry the launcher's birth, not the claim timestamp.
|
|
259
174
|
spawnedAt: Date.now() - process.uptime() * 1000,
|
|
260
175
|
status: 'running',
|
|
261
176
|
startedAt: now,
|
|
@@ -266,24 +181,11 @@ function writeActiveClaim(config, attempt) {
|
|
|
266
181
|
writeRunMeta(meta);
|
|
267
182
|
return meta;
|
|
268
183
|
}
|
|
269
|
-
|
|
270
|
-
* Allocate a routine attempt BEFORE any placement / version / sandbox / preflight
|
|
271
|
-
* / dispatch work, so every rejected, skipped, or blocked fire leaves exactly one
|
|
272
|
-
* visible terminal record. Runs inside {@link withRoutineLock}. Enforces, in order:
|
|
273
|
-
*
|
|
274
|
-
* 1. single-fire — a scheduled slot atomically claims its (routine, UTC) run
|
|
275
|
-
* directory; a duplicate cron delivery for the same slot returns the original
|
|
276
|
-
* attempt and spawns nothing.
|
|
277
|
-
* 2. non-overlap — a prior run of this routine that is still active makes this
|
|
278
|
-
* attempt a `skipped`/`active_run` record linking the live run.
|
|
279
|
-
* 3. readiness — an unresolved/blocked execution context (bad cwd, non-portable
|
|
280
|
-
* path, missing project base, …) makes this a `blocked` record.
|
|
281
|
-
*/
|
|
184
|
+
// Schedule and catchup deliveries atomically claim the same (routine, UTC slot).
|
|
282
185
|
function allocateRoutineAttempt(config, trigger) {
|
|
283
186
|
const scheduledForIso = trigger.scheduledFor
|
|
284
187
|
? (typeof trigger.scheduledFor === 'string' ? trigger.scheduledFor : trigger.scheduledFor.toISOString())
|
|
285
188
|
: undefined;
|
|
286
|
-
// 1. Slot claim (schedule/catchup). Manual/webhook/event fires get a fresh id.
|
|
287
189
|
let runId;
|
|
288
190
|
if (scheduledForIso) {
|
|
289
191
|
runId = slotRunId(scheduledForIso);
|
|
@@ -305,7 +207,6 @@ function allocateRoutineAttempt(config, trigger) {
|
|
|
305
207
|
runId = generateRunId();
|
|
306
208
|
fs.mkdirSync(getRunDir(config.name, runId), { recursive: true });
|
|
307
209
|
}
|
|
308
|
-
// 2. Non-overlap: a prior run of THIS routine is still live.
|
|
309
210
|
const active = activeRoutineRun(config);
|
|
310
211
|
if (active && active.runId !== runId) {
|
|
311
212
|
return {
|
|
@@ -327,10 +228,6 @@ function allocateRoutineAttempt(config, trigger) {
|
|
|
327
228
|
}),
|
|
328
229
|
};
|
|
329
230
|
}
|
|
330
|
-
// Gate on deprecation alone, not ROUTINE_AGENT_IDS membership — a retired
|
|
331
|
-
// harness leaves the command table (gemini did), and the legacy routine must
|
|
332
|
-
// still land a visible 'blocked' record, never a generic buildJobCommand
|
|
333
|
-
// failure (RUSH-2202).
|
|
334
231
|
if (!config.workflow && config.agent && !isCustomHarnessName(config.agent) && isAgentHardDeprecated(config.agent)) {
|
|
335
232
|
const reason = hardDeprecationError(config.agent);
|
|
336
233
|
return {
|
|
@@ -354,9 +251,6 @@ function allocateRoutineAttempt(config, trigger) {
|
|
|
354
251
|
}),
|
|
355
252
|
};
|
|
356
253
|
}
|
|
357
|
-
// 3. Readiness: resolve the execution context for the routine's placement.
|
|
358
|
-
// Local placement inspects this box's filesystem; host/fleet/cloud defer
|
|
359
|
-
// existence (the remote fs is unreachable here) and enforce portability only.
|
|
360
254
|
const mode = resolveHostStrategy(config);
|
|
361
255
|
const ctx = resolveJobExecutionContext(config, {
|
|
362
256
|
mode,
|
|
@@ -381,14 +275,6 @@ function allocateRoutineAttempt(config, trigger) {
|
|
|
381
275
|
}
|
|
382
276
|
return { proceed: true, attempt: { runId, stamp } };
|
|
383
277
|
}
|
|
384
|
-
/**
|
|
385
|
-
* Emit a loud, once-per-wedge warning when a routine has been refused its slot
|
|
386
|
-
* for {@link SKIP_STREAK_ALERT_THRESHOLD} consecutive scheduled runs. Fires only
|
|
387
|
-
* when the streak first reaches the threshold (not on every later skip), so a
|
|
388
|
-
* genuinely-stalled routine surfaces once instead of piling up silent `skipped`
|
|
389
|
-
* records the way RUSH-2640 did. Runs on the daemon's own stderr, so it lands in
|
|
390
|
-
* the daemon log the operator reads.
|
|
391
|
-
*/
|
|
392
278
|
function surfaceWedgedRoutine(config, terminal) {
|
|
393
279
|
if (terminal.status !== 'skipped' || terminal.skipReason !== 'active_run')
|
|
394
280
|
return;
|
|
@@ -399,13 +285,6 @@ function surfaceWedgedRoutine(config, terminal) {
|
|
|
399
285
|
process.stderr.write(`[agents] routine '${config.name}' skipped ${streak} consecutive scheduled runs — ` +
|
|
400
286
|
`its active-run slot is still held by ${stuck}; the routine is not firing on schedule.\n`);
|
|
401
287
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Claim one routine attempt under the short launch lock, then execute after
|
|
404
|
-
* releasing it. The persisted `running` claim makes a concurrent entry point
|
|
405
|
-
* skip immediately instead of waiting for a foreground run to finish. `run` is
|
|
406
|
-
* the placement/command/agent dispatch, invoked only when the attempt proceeds;
|
|
407
|
-
* `wrapTerminal` adapts a pre-spawn terminal record into the caller's return type.
|
|
408
|
-
*/
|
|
409
288
|
async function runWithAttempt(config, trigger, run, wrapTerminal) {
|
|
410
289
|
const claimed = await withRoutineLock(config, async () => {
|
|
411
290
|
const alloc = allocateRoutineAttempt(config, trigger);
|
|
@@ -436,96 +315,42 @@ async function runWithAttempt(config, trigger, run, wrapTerminal) {
|
|
|
436
315
|
}));
|
|
437
316
|
}
|
|
438
317
|
}
|
|
318
|
+
// Never signal this process; timeout callbacks own their child, while reconciliation birth-time-verifies recorded pids before calling here.
|
|
439
319
|
function terminateRoutineTree(pid) {
|
|
440
320
|
if (!pid)
|
|
441
321
|
return;
|
|
442
|
-
// Never take THIS process down. Both kills below are unconditional SIGKILLs,
|
|
443
|
-
// so a RunMeta naming the reaper's own pid -- a reused pid, a record written
|
|
444
|
-
// by the process now doing the reaping, or a hand-written fixture -- makes the
|
|
445
|
-
// reaper SIGKILL itself, and via `-pid` its whole process group with it. There
|
|
446
|
-
// is no recovery from that: the run is never finalized, and on the daemon it
|
|
447
|
-
// takes the scheduler down mid-sweep. daemon.ts:457 already refuses to evict an
|
|
448
|
-
// incumbent whose pid is `process.pid` for exactly this reason; the reap path
|
|
449
|
-
// needs the same guard. Skipping the kill still lets the caller finalize the
|
|
450
|
-
// run record, which is the part that matters.
|
|
451
322
|
if (pid === process.pid)
|
|
452
323
|
return;
|
|
453
324
|
if (process.platform === 'win32') {
|
|
454
325
|
killTree(pid);
|
|
455
326
|
return;
|
|
456
327
|
}
|
|
457
|
-
// Detached spawn makes the child a new process-group leader; kill the group.
|
|
458
|
-
// If setsid has not landed yet (or the pid is not a leader), -pid fails with
|
|
459
|
-
// ESRCH and the child stays up — also kill the pid itself.
|
|
460
328
|
try {
|
|
461
329
|
process.kill(-pid, 'SIGKILL');
|
|
462
330
|
}
|
|
463
|
-
catch {
|
|
331
|
+
catch { }
|
|
464
332
|
try {
|
|
465
333
|
process.kill(pid, 'SIGKILL');
|
|
466
334
|
}
|
|
467
|
-
catch {
|
|
335
|
+
catch { }
|
|
468
336
|
}
|
|
469
|
-
/**
|
|
470
|
-
* Where each agent's transcript files live under an overlay HOME, mirroring
|
|
471
|
-
* `SESSION_ROOT_SPECS` (session/discover.ts) — the CLI's own source of truth
|
|
472
|
-
* for which on-disk trees hold live session files. Kept in this shape (not a
|
|
473
|
-
* shared import) because `archiveRoutineTranscripts` only needs a flat
|
|
474
|
-
* root+ext pair to `walkForFiles`, not the version-home/backup fan-out
|
|
475
|
-
* `getAgentSessionDirs` does for live discovery.
|
|
476
|
-
*
|
|
477
|
-
* `opencode` is deliberately absent: `SESSION_ROOT_SPECS` itself has no entry
|
|
478
|
-
* for it — its transcripts live in one incrementally-scanned SQLite db
|
|
479
|
-
* (`scanOpenCodeIncremental`), not a per-session file tree — so there is
|
|
480
|
-
* nothing here to mirror without inventing a new discovery path.
|
|
481
|
-
*/
|
|
482
337
|
const ROUTINE_TRANSCRIPT_SPECS = {
|
|
483
338
|
claude: [{ root: ['.claude', 'projects'], ext: '.jsonl' }],
|
|
484
339
|
codex: [{ root: ['.codex', 'sessions'], ext: '.jsonl' }],
|
|
485
340
|
cursor: [{ root: ['.cursor', 'projects'], ext: '.jsonl' }],
|
|
486
341
|
antigravity: [{ root: ['.gemini', 'antigravity-cli', 'conversations'], ext: '.db' }],
|
|
487
342
|
droid: [{ root: ['.factory', 'sessions'], ext: '.jsonl' }],
|
|
488
|
-
// Kimi splits a session across two files (session/discover.ts:4382-4384):
|
|
489
|
-
// state.json (title/timestamps) and agents/main/wire.jsonl (the actual
|
|
490
|
-
// conversation). Both extensions are needed — .json alone archives only
|
|
491
|
-
// the metadata shell and silently drops every message.
|
|
492
343
|
kimi: [
|
|
493
344
|
{ root: ['.kimi-code', 'sessions'], ext: '.json' },
|
|
494
345
|
{ root: ['.kimi-code', 'sessions'], ext: '.jsonl' },
|
|
495
346
|
],
|
|
496
347
|
grok: [{ root: ['.grok', 'sessions'], ext: '.json' }],
|
|
497
|
-
// Muse: ~/.local/share/muse/sessions/YYYY/MM/DD/<uuid>/session.jsonl
|
|
498
348
|
muse: [{ root: ['.local', 'share', 'muse', 'sessions'], ext: '.jsonl' }],
|
|
499
349
|
};
|
|
500
|
-
/**
|
|
501
|
-
* Working directory for a routine's LOCAL child, resolved from its explicit
|
|
502
|
-
* `project`/`cwd` execution anchor via {@link resolveJobExecutionContext} — never
|
|
503
|
-
* inferred from `repo` (which is external repository identity only) and never the
|
|
504
|
-
* daemon's launch cwd. A command routine with neither field lands in `$HOME`
|
|
505
|
-
* (housekeeping); an unresolved/blocked agent context also falls back to `$HOME`
|
|
506
|
-
* so a caller that reaches this (past the readiness gate) has a valid directory,
|
|
507
|
-
* but the gate should have paused such a routine before it ever spawned.
|
|
508
|
-
*/
|
|
509
350
|
export function routineSpawnCwd(config) {
|
|
510
351
|
const ctx = resolveJobExecutionContext(config, { mode: 'local' });
|
|
511
352
|
return ctx.absoluteCwd ?? os.homedir();
|
|
512
353
|
}
|
|
513
|
-
/**
|
|
514
|
-
* Bake the daemon-job argv skeleton from AGENT_COMMANDS.
|
|
515
|
-
*
|
|
516
|
-
* The two tables used to be independent copies of the same launch decision.
|
|
517
|
-
* Argv now comes from AGENT_COMMANDS.base / promptFlag / jsonFlags / modeFlags.
|
|
518
|
-
* Two documented exceptions, not a second table:
|
|
519
|
-
* - kimi uses `--prompt` (long form). `-p` is the exec alias; combining
|
|
520
|
-
* either with --plan/--auto/--yolo aborts, so routineModeArgs emits no
|
|
521
|
-
* mode flag. The daemon has always spawned the long form.
|
|
522
|
-
* - claude places `--verbose` (from jsonFlags) before the prompt and bakes
|
|
523
|
-
* modeFlags.plan so claudeAdapter.routineModeArgs can splice
|
|
524
|
-
* plan → acceptEdits / auto / skip.
|
|
525
|
-
*
|
|
526
|
-
* Returns undefined when `agent` is outside ROUTINE_AGENT_IDS (grok and every
|
|
527
|
-
* other harness the daemon does not fire locally).
|
|
528
|
-
*/
|
|
529
354
|
export function bakeRoutineArgv(agent) {
|
|
530
355
|
if (!ROUTINE_AGENT_IDS.includes(agent))
|
|
531
356
|
return undefined;
|
|
@@ -552,50 +377,26 @@ export function bakeRoutineArgv(agent) {
|
|
|
552
377
|
}
|
|
553
378
|
return cmd;
|
|
554
379
|
}
|
|
555
|
-
/** Build the full CLI argv for executing a job, applying mode, model, and permission flags. */
|
|
556
380
|
export function buildJobCommand(config, resolvedPrompt, forwardAccount = true) {
|
|
557
|
-
// Workflow branch: delegate to `agents run <workflow>` which handles subagent
|
|
558
|
-
// injection, WORKFLOW.md orchestration, and model selection via frontmatter.
|
|
559
|
-
// appendModelAndReasoning is intentionally skipped — the workflow frontmatter
|
|
560
|
-
// owns model selection. No --timeout flag: the runner enforces its own SIGTERM/SIGKILL.
|
|
561
381
|
if (config.workflow) {
|
|
562
382
|
const cmd = ['agents', 'run', config.workflow, resolvedPrompt, '--mode', config.mode];
|
|
563
383
|
if (config.account && forwardAccount)
|
|
564
384
|
cmd.push('--account', config.account);
|
|
565
385
|
return cmd;
|
|
566
386
|
}
|
|
567
|
-
// Past the workflow branch this is an agent (or resume) job — command jobs never
|
|
568
|
-
// reach buildJobCommand (execute*Job branches out first), and validateJob guarantees agent.
|
|
569
387
|
const agent = config.agent;
|
|
570
|
-
// Resume branch: reopen an EXISTING session via `agents run <agent> --resume <id>`
|
|
571
|
-
// instead of starting fresh. The real session resumes with its full prior context
|
|
572
|
-
// (index-based lookup, cwd-independent) and `resolvedPrompt` becomes its next turn —
|
|
573
|
-
// so a self-scheduled wake (e.g. /hibernate) is handled by the session that scheduled
|
|
574
|
-
// it, not a fresh, context-less agent that would refuse an "opaque" instruction.
|
|
575
388
|
if (config.resume) {
|
|
576
389
|
const cmd = ['agents', 'run', agent, '--resume', config.resume, resolvedPrompt, '--mode', config.mode];
|
|
577
390
|
if (config.account && forwardAccount)
|
|
578
391
|
cmd.push('--account', config.account);
|
|
579
392
|
return cmd;
|
|
580
393
|
}
|
|
581
|
-
// Custom-harness branch: delegate to `agents run <name>`, which owns profile
|
|
582
|
-
// resolution (host binary, model env, provider auth) — the same delegation
|
|
583
|
-
// the workflow and resume branches use. The profile pins its own version and
|
|
584
|
-
// auth, so no command template, binary pinning, or account-env injection
|
|
585
|
-
// applies here.
|
|
586
394
|
if (isCustomHarnessName(agent)) {
|
|
587
395
|
const cmd = ['agents', 'run', agent, resolvedPrompt, '--mode', config.mode];
|
|
588
396
|
if (config.account && forwardAccount)
|
|
589
397
|
cmd.push('--account', config.account);
|
|
590
398
|
return cmd;
|
|
591
399
|
}
|
|
592
|
-
// Native slot accounts share one managed binary version, so the baked
|
|
593
|
-
// harness argv cannot identify which login to spawn. Dispatch through
|
|
594
|
-
// `agents run <agent>#<name>` (the same seam as resume/custom) so T5
|
|
595
|
-
// spawn-time resolution selects the slot. `--account` is an agents-cli
|
|
596
|
-
// flag; the harness binary would ignore or reject it.
|
|
597
|
-
// Provider/durable-pinned accounts stay on the harness argv + env-injection
|
|
598
|
-
// path: `#name` is a native selector and would not inject their bundle.
|
|
599
400
|
if (config.account && forwardAccount && !findAccount(config.account)) {
|
|
600
401
|
const spec = config.version
|
|
601
402
|
? `${agent}@${config.version}#${config.account}`
|
|
@@ -604,29 +405,18 @@ export function buildJobCommand(config, resolvedPrompt, forwardAccount = true) {
|
|
|
604
405
|
}
|
|
605
406
|
const template = bakeRoutineArgv(agent);
|
|
606
407
|
if (!template) {
|
|
607
|
-
// A name outside both tables was either never valid or was a custom
|
|
608
|
-
// harness whose profile has since been deleted — validateJob accepted it
|
|
609
|
-
// against a profile that existed then. Name the repair, not just the miss.
|
|
610
408
|
throw new Error(`Unsupported agent for daemon jobs: ${agent}. ` +
|
|
611
409
|
`If '${agent}' was a custom harness, its profile no longer exists on this device — ` +
|
|
612
410
|
`recreate it (agents harness add ${agent} ...) or point the routine at another agent.`);
|
|
613
411
|
}
|
|
614
412
|
let cmd = template.map((part) => part.replace('{prompt}', resolvedPrompt));
|
|
615
|
-
// Canonicalize mode (accepts legacy `full` as alias for `skip`).
|
|
616
413
|
const mode = normalizeMode(config.mode);
|
|
617
|
-
// Routine launch-arg quirks (the harness axis of Move 3): each per-agent arm
|
|
618
|
-
// moves to its harness adapter; runner appends model/reasoning flags after,
|
|
619
|
-
// exactly as every arm did. Agents with no routine quirk have no adapter
|
|
620
|
-
// override, so they skip both — the old behavior for an entry with no arm.
|
|
621
414
|
const routineAdapter = resolveHarnessAdapter(agent);
|
|
622
415
|
if (routineAdapter.routineModeArgs) {
|
|
623
416
|
routineAdapter.routineModeArgs(cmd, { mode, config, resolveHeadlessMode });
|
|
624
417
|
appendModelAndReasoning(cmd, config);
|
|
625
418
|
}
|
|
626
|
-
//
|
|
627
|
-
// (workspace_roots). Claude / Kimi / Cursor take --add-dir; Grok gets rules
|
|
628
|
-
// (+ sandbox widen when GROK_SANDBOX is on). Reject leading '-' so a routine
|
|
629
|
-
// YAML can't smuggle an argv flag past the sandbox as an allow.dirs entry.
|
|
419
|
+
// A leading dash would turn a YAML directory into an injected harness flag.
|
|
630
420
|
if (config.allow?.dirs?.length && agent !== 'codex') {
|
|
631
421
|
for (const dir of config.allow.dirs) {
|
|
632
422
|
if (dir.startsWith('-')) {
|
|
@@ -639,16 +429,7 @@ export function buildJobCommand(config, resolvedPrompt, forwardAccount = true) {
|
|
|
639
429
|
}
|
|
640
430
|
return cmd;
|
|
641
431
|
}
|
|
642
|
-
/**
|
|
643
|
-
* Append the agent's canonical model flag and reasoning flags to a command.
|
|
644
|
-
*
|
|
645
|
-
* Pass-through model resolution: validates against the installed (agent, version)
|
|
646
|
-
* catalog when possible and writes a warning to stderr on miss, but never blocks.
|
|
647
|
-
* Reasoning level (config.config.reasoning) maps to per-agent flags via models.ts.
|
|
648
|
-
*/
|
|
649
432
|
function appendModelAndReasoning(cmd, config) {
|
|
650
|
-
// Only called from buildJobCommand's agent path AFTER the custom-harness
|
|
651
|
-
// branch returned — config.agent is a native id here.
|
|
652
433
|
const agent = config.agent;
|
|
653
434
|
const model = config.config?.model;
|
|
654
435
|
if (model) {
|
|
@@ -677,35 +458,10 @@ function appendModelAndReasoning(cmd, config) {
|
|
|
677
458
|
function generateRunId() {
|
|
678
459
|
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
679
460
|
}
|
|
680
|
-
/**
|
|
681
|
-
* Agents whose config dir `buildExecEnv` relocates OUT of the sandbox overlay HOME
|
|
682
|
-
* into their per-version home (exec.ts: CLAUDE_CONFIG_DIR / CODEX_HOME). A routine
|
|
683
|
-
* spawned for one of these writes its transcript under the version home, NOT the overlay
|
|
684
|
-
* the sandbox generated — so the archiver has to read it there. Both are version-pinned
|
|
685
|
-
* (never self-updating), so `RunMeta.version` names a real home.
|
|
686
|
-
*
|
|
687
|
-
* Scoped to the agents whose archived transcript the DISCOVERY side can already index as
|
|
688
|
-
* origin='routine' — `readRoutineArchiveMeta` (session/discover.ts) has a branch for
|
|
689
|
-
* claude and codex but not kimi. Kimi also relocates (KIMI_CODE_HOME) and hits the same
|
|
690
|
-
* bug, but archiving it here without a discovery branch would only copy files that are
|
|
691
|
-
* never indexed; adding a kimi reader (its session spans state.json + wire.jsonl under a
|
|
692
|
-
* `session_<uuid>` dir) is the separate follow-up that lets kimi join this set. Muse
|
|
693
|
-
* (XDG, self-updating) and copilot (no transcript spec) are likewise out of scope.
|
|
694
|
-
*/
|
|
695
461
|
const CONFIG_DIR_RELOCATED_AGENTS = new Set(['claude', 'codex']);
|
|
696
|
-
/** Whether this run's transcript lands in a SHARED per-version home (accumulating every
|
|
697
|
-
* session that version+account ever ran) rather than the run's own disposable overlay. */
|
|
698
462
|
function usesSharedTranscriptHome(agent, version) {
|
|
699
463
|
return Boolean(version) && CONFIG_DIR_RELOCATED_AGENTS.has(agent);
|
|
700
464
|
}
|
|
701
|
-
/**
|
|
702
|
-
* The directories the child actually writes a transcript to for one spec — resolved to
|
|
703
|
-
* match `buildExecEnv` (exec.ts), the single decision-point for where the transcript
|
|
704
|
-
* lands, so the archiver can never drift from it. For a config-dir-relocated agent that
|
|
705
|
-
* is the per-version home (`.claude`, `.codex`, …); for everyone else it is the sandbox
|
|
706
|
-
* overlay HOME. Codex may run from a SUN_LEN-safe short home on macOS (codex-home.ts),
|
|
707
|
-
* so both candidates are returned and the caller skips whichever does not exist.
|
|
708
|
-
*/
|
|
709
465
|
function routineTranscriptSourceRoots(agent, version, overlayHome, spec) {
|
|
710
466
|
if (usesSharedTranscriptHome(agent, version)) {
|
|
711
467
|
const roots = [path.join(getVersionHomePath(agent, version), ...spec.root)];
|
|
@@ -716,22 +472,13 @@ function routineTranscriptSourceRoots(agent, version, overlayHome, spec) {
|
|
|
716
472
|
}
|
|
717
473
|
return [path.join(overlayHome, ...spec.root)];
|
|
718
474
|
}
|
|
719
|
-
/** Path of the per-run baseline recorded before spawn (see {@link snapshotRoutineTranscriptBase}). */
|
|
720
475
|
function transcriptBasePath(runDir) {
|
|
721
476
|
return path.join(runDir, '.transcript-base.json');
|
|
722
477
|
}
|
|
723
|
-
|
|
724
|
-
* Record every transcript file already present in the child's transcript dirs BEFORE
|
|
725
|
-
* the run spawns. When the transcript lands in a shared per-version home, this baseline
|
|
726
|
-
* is what lets the archiver copy only the file THIS run produced instead of sweeping in
|
|
727
|
-
* every sibling session that home holds (which would mis-tag them all `origin='routine'`
|
|
728
|
-
* under this run's name). Called once per run, before spawn.
|
|
729
|
-
*/
|
|
478
|
+
// Shared version homes contain sibling transcripts, so snapshot before spawn and archive only newly-created files.
|
|
730
479
|
export function snapshotRoutineTranscriptBase(meta, runDir, overlayHome) {
|
|
731
480
|
if (!meta.agent)
|
|
732
481
|
return;
|
|
733
|
-
// A host/cloud custom-harness run records the harness name, which has no
|
|
734
|
-
// transcript spec — the null-specs guard below skips it, as before.
|
|
735
482
|
const specs = ROUTINE_TRANSCRIPT_SPECS[meta.agent];
|
|
736
483
|
if (!specs)
|
|
737
484
|
return;
|
|
@@ -750,12 +497,8 @@ export function snapshotRoutineTranscriptBase(meta, runDir, overlayHome) {
|
|
|
750
497
|
fs.writeFileSync(transcriptBasePath(runDir), JSON.stringify([...preexisting]), { mode: 0o600 });
|
|
751
498
|
}
|
|
752
499
|
catch {
|
|
753
|
-
// Best-effort: a missing baseline is handled conservatively at archive time
|
|
754
|
-
// (a shared home is skipped rather than bulk-copied).
|
|
755
500
|
}
|
|
756
501
|
}
|
|
757
|
-
/** Read the pre-spawn baseline. `null` means none was recorded (older run or a failed
|
|
758
|
-
* snapshot) — the archiver then refuses to bulk-copy a shared home. */
|
|
759
502
|
function readTranscriptBase(runDir) {
|
|
760
503
|
try {
|
|
761
504
|
const arr = JSON.parse(fs.readFileSync(transcriptBasePath(runDir), 'utf-8'));
|
|
@@ -763,24 +506,18 @@ function readTranscriptBase(runDir) {
|
|
|
763
506
|
return new Set(arr.filter((x) => typeof x === 'string'));
|
|
764
507
|
}
|
|
765
508
|
catch {
|
|
766
|
-
// No baseline file, or it was unreadable/corrupt.
|
|
767
509
|
}
|
|
768
510
|
return null;
|
|
769
511
|
}
|
|
770
512
|
export function archiveRoutineTranscripts(meta, runDir, overlayHome) {
|
|
771
513
|
if (!meta.agent)
|
|
772
514
|
return;
|
|
773
|
-
// A host/cloud custom-harness run records the harness name, which has no
|
|
774
|
-
// transcript spec — the null-specs guard below skips it, as before.
|
|
775
515
|
const specs = ROUTINE_TRANSCRIPT_SPECS[meta.agent];
|
|
776
516
|
if (!specs)
|
|
777
517
|
return;
|
|
778
518
|
const home = overlayHome ?? getJobHomePath(meta.jobName);
|
|
779
519
|
const shared = usesSharedTranscriptHome(meta.agent, meta.version);
|
|
780
520
|
const base = readTranscriptBase(runDir);
|
|
781
|
-
// A shared per-version home holds every session that version+account ran, so without a
|
|
782
|
-
// per-run baseline we cannot tell this run's transcript from a sibling's — copy nothing
|
|
783
|
-
// rather than mis-tag them all. A disposable overlay is this run's alone, so copy all.
|
|
784
521
|
if (shared && base === null)
|
|
785
522
|
return;
|
|
786
523
|
for (const spec of specs) {
|
|
@@ -789,7 +526,6 @@ export function archiveRoutineTranscripts(meta, runDir, overlayHome) {
|
|
|
789
526
|
if (!fs.existsSync(sourceRoot))
|
|
790
527
|
continue;
|
|
791
528
|
for (const sourcePath of walkForFiles(sourceRoot, spec.ext, 100_000)) {
|
|
792
|
-
// Skip files that predate this run (a sibling session in the shared home).
|
|
793
529
|
if (base?.has(sourcePath))
|
|
794
530
|
continue;
|
|
795
531
|
const rel = path.relative(sourceRoot, sourcePath);
|
|
@@ -802,31 +538,17 @@ export function archiveRoutineTranscripts(meta, runDir, overlayHome) {
|
|
|
802
538
|
fs.chmodSync(destPath, 0o600);
|
|
803
539
|
}
|
|
804
540
|
catch {
|
|
805
|
-
// The process already reached a terminal state; a concurrently removed
|
|
806
|
-
// transcript should not rewrite that outcome.
|
|
807
541
|
}
|
|
808
542
|
}
|
|
809
543
|
}
|
|
810
544
|
}
|
|
811
545
|
}
|
|
812
|
-
/**
|
|
813
|
-
* Build the argv for a command-mode routine: run the shell string directly
|
|
814
|
-
* through the platform shell. No agent binary, no rotation, no sandbox.
|
|
815
|
-
*/
|
|
816
546
|
function buildShellCommand(command) {
|
|
817
547
|
return process.platform === 'win32'
|
|
818
548
|
? ['cmd', '/c', command]
|
|
819
549
|
: ['/bin/sh', '-c', command];
|
|
820
550
|
}
|
|
821
|
-
|
|
822
|
-
* Real (un-sandboxed) environment for a command routine. Command routines do
|
|
823
|
-
* `npm i -g` / `git pull` and need the actual $HOME / $PATH, not the sandbox
|
|
824
|
-
* overlay. Only TZ is injected when the routine pins a timezone.
|
|
825
|
-
*
|
|
826
|
-
* The current binary's directory is prepended to PATH so bare `agents` invocations
|
|
827
|
-
* resolve to the same install on Windows (where shell-function injection is not
|
|
828
|
-
* available) and as a fallback on POSIX for invocations like `command agents`.
|
|
829
|
-
*/
|
|
551
|
+
// Command routines inherit real HOME/base PATH then prepend this CLI's bin; only agent routines receive overlay/version-home isolation.
|
|
830
552
|
function commandSpawnEnv(config) {
|
|
831
553
|
const env = { ...process.env };
|
|
832
554
|
if (config.timezone)
|
|
@@ -839,49 +561,24 @@ function commandSpawnEnv(config) {
|
|
|
839
561
|
}
|
|
840
562
|
return env;
|
|
841
563
|
}
|
|
842
|
-
/** POSIX single-quote a string so it is safe to embed in a `/bin/sh -c` script. */
|
|
843
564
|
function shSingleQuote(s) {
|
|
844
565
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
845
566
|
}
|
|
846
|
-
|
|
847
|
-
* Build a POSIX shell function that forwards `agents <sub...>` to the SAME binary
|
|
848
|
-
* currently running. Command routines shell out to the bare name `agents`
|
|
849
|
-
* (e.g. `agents repo pull system`); without this, the routine resolves `agents`
|
|
850
|
-
* through its inherited PATH, which can pick up a stale install in an nvm/system
|
|
851
|
-
* Node prefix that shadows the current binary (RUSH-2431).
|
|
852
|
-
*
|
|
853
|
-
* Uses getCliLaunch so the relaunch is correct for both JS installs
|
|
854
|
-
* (`node <entry> <sub...>`) and compiled standalone binaries (`<bin> <sub...>`).
|
|
855
|
-
*/
|
|
567
|
+
// Bind bare `agents` inside a command routine to the exact binary running this daemon.
|
|
856
568
|
function agentsShellFunction() {
|
|
857
569
|
const launch = getCliLaunch(['__ac_placeholder__']);
|
|
858
570
|
const parts = [launch.command];
|
|
859
|
-
// JS installs: getCliLaunch returns [node, entryScript, placeholder].
|
|
860
|
-
// Standalone: it returns [binary, placeholder].
|
|
861
571
|
if (launch.args.length > 0 && launch.args[0] !== '__ac_placeholder__' && fs.existsSync(launch.args[0])) {
|
|
862
572
|
parts.push(launch.args[0]);
|
|
863
573
|
}
|
|
864
574
|
const invocation = parts.map(shSingleQuote).join(' ');
|
|
865
575
|
return `agents() { ${invocation} "$@"; }`;
|
|
866
576
|
}
|
|
867
|
-
/**
|
|
868
|
-
* Wrap a command-routine shell string so any bare `agents` invocation resolves
|
|
869
|
-
* to the current binary. On POSIX this injects an `agents` shell function; on
|
|
870
|
-
* Windows it is left unchanged and commandSpawnEnv prepends the current binary's
|
|
871
|
-
* directory to PATH instead.
|
|
872
|
-
*/
|
|
873
577
|
function wrapCommandRoutine(command) {
|
|
874
578
|
if (process.platform === 'win32')
|
|
875
579
|
return command;
|
|
876
580
|
return `${agentsShellFunction()}\n${command}`;
|
|
877
581
|
}
|
|
878
|
-
/**
|
|
879
|
-
* Detached command routines write their own exit code to `<runDir>/exit-code`
|
|
880
|
-
* (see the wrapper in executeCommandJobDetached). `monitorRunningJobs` reads it
|
|
881
|
-
* to recover the true terminal status when the daemon restarted between spawn and
|
|
882
|
-
* exit and so missed the in-process `child.on('exit')`. Returns null when the
|
|
883
|
-
* file is absent/unparseable (child killed or crashed before writing it).
|
|
884
|
-
*/
|
|
885
582
|
function readCommandExitCode(runDir) {
|
|
886
583
|
try {
|
|
887
584
|
const raw = fs.readFileSync(path.join(runDir, 'exit-code'), 'utf-8').trim();
|
|
@@ -893,10 +590,9 @@ function readCommandExitCode(runDir) {
|
|
|
893
590
|
return null;
|
|
894
591
|
}
|
|
895
592
|
}
|
|
896
|
-
/** Claude's own local auth check; unlike account metadata it cannot mistake identity for a usable login. */
|
|
897
593
|
export function claudeVersionIsAuthenticated(version) {
|
|
898
594
|
if (!isVersionInstalled('claude', version))
|
|
899
|
-
return true;
|
|
595
|
+
return true;
|
|
900
596
|
const binary = getBinaryPath('claude', version);
|
|
901
597
|
if (!binary)
|
|
902
598
|
return false;
|
|
@@ -914,28 +610,13 @@ export function claudeVersionIsAuthenticated(version) {
|
|
|
914
610
|
return false;
|
|
915
611
|
}
|
|
916
612
|
}
|
|
917
|
-
/**
|
|
918
|
-
* Resolve the version/account chain for a routine the same way `agents run`
|
|
919
|
-
* does: honor an explicit `version:` pin; otherwise use the configured run
|
|
920
|
-
* strategy (default `balanced`) so credit-exhausted / rate-limited accounts
|
|
921
|
-
* are skipped pre-flight, and synthesize a same-agent failover chain from the
|
|
922
|
-
* other healthy accounts for mid-run rate limits.
|
|
923
|
-
*
|
|
924
|
-
* Workflows are left alone — `agents run <workflow>` owns selection.
|
|
925
|
-
*/
|
|
926
613
|
export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {}) {
|
|
927
614
|
if (config.workflow) {
|
|
928
615
|
return { chain: [], rotation: null, pinned: false };
|
|
929
616
|
}
|
|
930
617
|
if (config.agent && isCustomHarnessName(config.agent)) {
|
|
931
|
-
// A custom harness pins its own version/auth in the profile, so there is
|
|
932
|
-
// no version/account chain to resolve here — `agents run <name>` owns it
|
|
933
|
-
// (matching exec's "strategy ignored: custom harness pins its own
|
|
934
|
-
// version/auth").
|
|
935
618
|
return { chain: [], rotation: null, pinned: false };
|
|
936
619
|
}
|
|
937
|
-
// resolveRoutineLaunch is only called for agent jobs (workflow returns above;
|
|
938
|
-
// command jobs branch out of execute*Job before reaching this).
|
|
939
620
|
const agent = config.agent;
|
|
940
621
|
const { findAccount, findUnifiedAccount, resolveAccountSelection, resolveCredentialAccount } = await import('../account-registry.js');
|
|
941
622
|
const meta = (deps.readMeta ?? readMeta)();
|
|
@@ -946,27 +627,16 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
946
627
|
? (explicitCredential ? config.account : undefined)
|
|
947
628
|
: resolveAccountSelection(undefined, agent, meta)?.id;
|
|
948
629
|
if (selectedCredential) {
|
|
949
|
-
// A default/binding may resolve to a native account — never route that
|
|
950
|
-
// through the provider credential path (it has no bundle to resolve).
|
|
951
630
|
const unified = findUnifiedAccount(selectedCredential, meta);
|
|
952
631
|
if (unified?.kind !== 'native')
|
|
953
632
|
(deps.resolveCredentialAccount ?? resolveCredentialAccount)(selectedCredential, agent);
|
|
954
633
|
}
|
|
955
634
|
if (config.account && !explicitCredential) {
|
|
956
|
-
// A native routine account is named by its durable name; the version matcher
|
|
957
|
-
// keys on the identity (email/accountKey), so translate before resolving,
|
|
958
|
-
// and refuse a login that belongs to a different harness. Scope the lookup to
|
|
959
|
-
// the routine's own harness: `identityLabel` defaults to the login's email, so
|
|
960
|
-
// `account: <email>` matches every harness that identity is signed into, and
|
|
961
|
-
// un-scoped this resolved whichever row the store ordered first — then rejected
|
|
962
|
-
// it on the very next line.
|
|
963
635
|
const unified = findUnifiedAccount(config.account, meta, undefined, agent);
|
|
964
636
|
if (unified?.kind === 'native' && unified.agent !== agent) {
|
|
965
637
|
throw new Error(`Routine '${config.name}' account '${config.account}' is a ${unified.agent} login and cannot authenticate ${agent}.`);
|
|
966
638
|
}
|
|
967
639
|
const identity = unified?.kind === 'native' ? unified.identityKey : config.account;
|
|
968
|
-
// Prefer the full candidate so a slot-sourced native account (shared
|
|
969
|
-
// managed-install `version`) still carries its name for `--account`.
|
|
970
640
|
const accountVersion = deps.resolveAccountVersion
|
|
971
641
|
? await deps.resolveAccountVersion(agent, identity)
|
|
972
642
|
: (await (deps.resolveAccountCandidate ?? resolveAccountCandidate)(agent, identity))?.version ?? null;
|
|
@@ -978,9 +648,6 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
978
648
|
chain: [{ agent, version: config.version ?? accountVersion }],
|
|
979
649
|
rotation: null,
|
|
980
650
|
pinned: true,
|
|
981
|
-
// Post-T5 every native slot on a harness shares the managed binary
|
|
982
|
-
// version, so the version pin is no longer enough — forward `--account`
|
|
983
|
-
// (name or `#name`) so spawn resolves the selected slot.
|
|
984
651
|
forwardAccount: true,
|
|
985
652
|
};
|
|
986
653
|
}
|
|
@@ -998,9 +665,6 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
998
665
|
...(config.account ? { forwardAccount: explicitCredential } : {}),
|
|
999
666
|
};
|
|
1000
667
|
}
|
|
1001
|
-
// A per-routine strategy travels with the definition and beats the firing
|
|
1002
|
-
// box's ambient run.<agent>.strategy — otherwise selection policy silently
|
|
1003
|
-
// depends on whichever device fires the job (RUSH-2719).
|
|
1004
668
|
const strategy = config.strategy ?? getConfiguredRunStrategy(agent, cwd);
|
|
1005
669
|
let version;
|
|
1006
670
|
let rotation = null;
|
|
@@ -1013,10 +677,6 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
1013
677
|
exhausted = resolved.exhausted;
|
|
1014
678
|
noVerifiedUsage = resolved.noVerifiedUsage ?? false;
|
|
1015
679
|
if (noVerifiedUsage) {
|
|
1016
|
-
// Entirely stale usage (PHNX-2526): a routine is unattended, so there is
|
|
1017
|
-
// no picker to divert to — it fails loud below rather than launch on a
|
|
1018
|
-
// stale number. Do NOT log `rotation.picked` as a pick; it is the refused
|
|
1019
|
-
// stale candidate, kept only for the failover chain.
|
|
1020
680
|
process.stderr.write(`[agents] routine ${config.name}: ${strategy} found no ${agent} account with fresh usage — refusing to route on stale data\n`);
|
|
1021
681
|
}
|
|
1022
682
|
else if (rotation) {
|
|
@@ -1044,16 +704,9 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
1044
704
|
catch (err) {
|
|
1045
705
|
process.stderr.write(`[agents] routine ${config.name}: strategy ${strategy} skipped: ${err.message}\n`);
|
|
1046
706
|
}
|
|
1047
|
-
// Zero healthy accounts is NOT a "fall back to the default pin" case — that
|
|
1048
|
-
// pin is exactly the exhausted account an unattended routine would hammer
|
|
1049
|
-
// every tick (RUSH-2132). Throwing fails the job run (nonzero), and the
|
|
1050
|
-
// message text is the contract the Factory watchdog tail-detects.
|
|
1051
707
|
if (exhausted) {
|
|
1052
708
|
throw new Error(formatNoHealthyAccountError(agent, strategy, exhausted));
|
|
1053
709
|
}
|
|
1054
|
-
// Entirely stale usage is also NOT a "fall back to the default pin" case — the
|
|
1055
|
-
// default is exactly the account whose stale number can't be trusted. Fail the
|
|
1056
|
-
// run loud (NO_VERIFIED_USAGE) rather than hammer it every tick (PHNX-2526).
|
|
1057
710
|
if (noVerifiedUsage) {
|
|
1058
711
|
throw new Error(formatNoVerifiedUsageError(agent, strategy, rotation?.healthy ?? []));
|
|
1059
712
|
}
|
|
@@ -1094,11 +747,6 @@ export async function resolveRoutineLaunch(config, cwd = process.cwd(), deps = {
|
|
|
1094
747
|
pinned: false,
|
|
1095
748
|
};
|
|
1096
749
|
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Rewrite `cmd[0]` to the absolute binary for `agent@version` when installed.
|
|
1099
|
-
* Bypasses the bare-name shim so a sandboxed HOME / missing default pin cannot
|
|
1100
|
-
* surface as "agents: no version of X configured".
|
|
1101
|
-
*/
|
|
1102
750
|
export function pinJobBinary(cmd, agent, version) {
|
|
1103
751
|
if (!version || cmd.length === 0)
|
|
1104
752
|
return cmd;
|
|
@@ -1111,27 +759,6 @@ export function pinJobBinary(cmd, agent, version) {
|
|
|
1111
759
|
next[0] = binary;
|
|
1112
760
|
return next;
|
|
1113
761
|
}
|
|
1114
|
-
/**
|
|
1115
|
-
* Whether a job's command is dispatched through `agents run` (so `cmd[0] === 'agents'`)
|
|
1116
|
-
* rather than the agent binary directly. True for workflow jobs and for resume jobs.
|
|
1117
|
-
* Such commands must NOT be binary-pinned (pinning rewrites cmd[0] to the agent binary,
|
|
1118
|
-
* producing a broken `<binary> run …`) and must not receive a version-pinned spawn env.
|
|
1119
|
-
*/
|
|
1120
|
-
/**
|
|
1121
|
-
* Assert a routine's account can be dispatched to the resolved placement, BEFORE
|
|
1122
|
-
* any off-box dispatch (placement is resolved before {@link resolveRoutineLaunch}),
|
|
1123
|
-
* at the top of both the foreground and detached paths:
|
|
1124
|
-
*
|
|
1125
|
-
* - **native** account → rejected for host AND cloud: a native login is a
|
|
1126
|
-
* device-local harness credential that cannot be forwarded off-box.
|
|
1127
|
-
* - **provider** account + **cloud** → rejected (fail loud): the cloud dispatch
|
|
1128
|
-
* has no secure way to inject a device-local provider bundle yet.
|
|
1129
|
-
* - **provider** account + **host** → allowed: the host dispatch forwards the
|
|
1130
|
-
* account NAME (the remote resolves its own local bundle — no secret copied).
|
|
1131
|
-
*
|
|
1132
|
-
* `account` is injectable so the guard is unit-tested for both modes without a
|
|
1133
|
-
* registry or a real dispatch.
|
|
1134
|
-
*/
|
|
1135
762
|
export async function assertRoutineAccountLocalForPlacement(config, mode, deps = {}) {
|
|
1136
763
|
if (!config.account)
|
|
1137
764
|
return;
|
|
@@ -1147,7 +774,6 @@ export async function assertRoutineAccountLocalForPlacement(config, mode, deps =
|
|
|
1147
774
|
throw new Error(`Routine '${config.name}' account '${config.account}' is a device-local ${account.agent} login and cannot run on a ${mode} placement. Use a provider account, or place this routine on the device that holds the login.`);
|
|
1148
775
|
}
|
|
1149
776
|
if (mode === 'cloud' && account?.kind === 'provider') {
|
|
1150
|
-
// RUSH-2689: cloud+provider injection not yet implemented.
|
|
1151
777
|
throw new Error(`Routine '${config.name}' account '${config.account}' is a provider credential; cloud placement cannot securely inject it (RUSH-2689). Run this routine locally or on a host that holds the bundle.`);
|
|
1152
778
|
}
|
|
1153
779
|
}
|
|
@@ -1160,12 +786,6 @@ export async function dispatchPlacedJob(config, target, attempt, deps = {}) {
|
|
|
1160
786
|
}
|
|
1161
787
|
return (deps.cloud ?? executeJobOnCloud)(config, { detached: false }, attempt);
|
|
1162
788
|
}
|
|
1163
|
-
/**
|
|
1164
|
-
* Build the options passed to `dispatchPromptToHost` for a host routine. Split
|
|
1165
|
-
* out so the execution boundary is unit-testable: it MUST forward the routine's
|
|
1166
|
-
* `account` by name (the remote resolves its own local bundle; no secret copied)
|
|
1167
|
-
* — dropping it silently ran the remote under the wrong identity.
|
|
1168
|
-
*/
|
|
1169
789
|
export function buildHostDispatchOptions(config, ctx) {
|
|
1170
790
|
return {
|
|
1171
791
|
agent: config.agent,
|
|
@@ -1174,7 +794,7 @@ export function buildHostDispatchOptions(config, ctx) {
|
|
|
1174
794
|
effort: config.effort,
|
|
1175
795
|
model: config.config?.model,
|
|
1176
796
|
account: config.account,
|
|
1177
|
-
timeout: config.timeout,
|
|
797
|
+
timeout: config.timeout,
|
|
1178
798
|
remoteCwd: ctx.remoteCwd,
|
|
1179
799
|
name: config.name,
|
|
1180
800
|
cwd: ctx.runDir,
|
|
@@ -1206,11 +826,6 @@ export function mergeRoutineProviderEnv(env, config, agent) {
|
|
|
1206
826
|
Object.assign(env, resolveCredentialAccount(unified.name, agent).env);
|
|
1207
827
|
return env;
|
|
1208
828
|
}
|
|
1209
|
-
/**
|
|
1210
|
-
* Merge sandbox/base env with the canonical per-version exec env
|
|
1211
|
-
* (CLAUDE_CONFIG_DIR / CODEX_HOME / …) so routines share account isolation
|
|
1212
|
-
* with `agents run`.
|
|
1213
|
-
*/
|
|
1214
829
|
export function buildRoutineSpawnEnv(baseEnv, agent, version, timezone, overlayHome) {
|
|
1215
830
|
const execEnv = buildExecEnv({
|
|
1216
831
|
agent,
|
|
@@ -1225,29 +840,9 @@ export function buildRoutineSpawnEnv(baseEnv, agent, version, timezone, overlayH
|
|
|
1225
840
|
if (v !== undefined)
|
|
1226
841
|
out[k] = v;
|
|
1227
842
|
}
|
|
1228
|
-
// CLAUDE_CODE_OAUTH_TOKEN comes in two flavours, and only one is safe for a
|
|
1229
|
-
// routine. KEEP a per-account `claude setup-token` (long-lived, NON-rotating,
|
|
1230
|
-
// keyed to this home's own account) that buildExecEnv injected from the reserved
|
|
1231
|
-
// `auth` bundle (resolveClaudeSetupToken) — that is the durable cure for the
|
|
1232
|
-
// single-use-refresh-token revocation storm: a setup-token never rotates, so a
|
|
1233
|
-
// scheduled routine can't land on a sibling home's just-rotated-out credential.
|
|
1234
|
-
// STRIP an INHERITED ambient value instead: buildExecEnv spreads process.env
|
|
1235
|
-
// (exec.ts) and sanitizeProcessEnv leaves credentials, so a daemon env that
|
|
1236
|
-
// happens to carry a shared/rotating CLAUDE_CODE_OAUTH_TOKEN would otherwise make
|
|
1237
|
-
// every routine run on that one token — the RUSH-1822 fleet-wide-logout path.
|
|
1238
|
-
// Distinguish by value: only the resolved setup-token survives.
|
|
1239
|
-
// Authoritative: buildExecEnv injects the setup-token but then spreads the caller
|
|
1240
|
-
// env over it, so an ambient CLAUDE_CODE_OAUTH_TOKEN would win — re-assert here.
|
|
1241
843
|
const setupToken = agent === 'claude' && version
|
|
1242
844
|
? resolveClaudeSetupToken(getVersionHomePath('claude', version))
|
|
1243
845
|
: null;
|
|
1244
|
-
// A headed device (personal or desktop — the user's own interactive box or a
|
|
1245
|
-
// headed always-on box) uses the per-version login for EVERY run, routines
|
|
1246
|
-
// included — the setup-token is a worker-only credential (RUSH-2395, mirrors
|
|
1247
|
-
// the claude adapter's headed-device branch). On a headed box, only strip an
|
|
1248
|
-
// inherited copy of the account's OWN setup-token by value so a leaked ambient
|
|
1249
|
-
// value can't override the login; a token the user set deliberately is a
|
|
1250
|
-
// different string and survives.
|
|
1251
846
|
if (isHeadedDeviceRole(selfConfiguredDeviceRole())) {
|
|
1252
847
|
if (setupToken && out.CLAUDE_CODE_OAUTH_TOKEN === setupToken)
|
|
1253
848
|
delete out.CLAUDE_CODE_OAUTH_TOKEN;
|
|
@@ -1259,8 +854,6 @@ export function buildRoutineSpawnEnv(baseEnv, agent, version, timezone, overlayH
|
|
|
1259
854
|
delete out.CLAUDE_CODE_OAUTH_TOKEN;
|
|
1260
855
|
}
|
|
1261
856
|
if (agent === 'cursor' && overlayHome) {
|
|
1262
|
-
// prepareJobHome links this host's Cursor auth file here. Pin XDG_CONFIG_HOME
|
|
1263
|
-
// to the overlay so an ambient value cannot bypass the routine sandbox.
|
|
1264
857
|
out.XDG_CONFIG_HOME = path.join(overlayHome, '.config');
|
|
1265
858
|
}
|
|
1266
859
|
if (overlayHome && agent === 'claude')
|
|
@@ -1271,13 +864,7 @@ export function buildRoutineSpawnEnv(baseEnv, agent, version, timezone, overlayH
|
|
|
1271
864
|
out.TZ = timezone;
|
|
1272
865
|
return out;
|
|
1273
866
|
}
|
|
1274
|
-
/**
|
|
1275
|
-
* Spawn one attempt, capture logs to `attemptLogPath`, enforce timeout.
|
|
1276
|
-
* Rate-limit scanning uses only this attempt's log (not prior failover output).
|
|
1277
|
-
* The attempt log is also appended into `combinedLogPath` for a continuous trail.
|
|
1278
|
-
*/
|
|
1279
867
|
function spawnJobAttempt(cmd, env, attemptLogPath, timeoutMs, combinedLogPath, cwd = os.homedir()) {
|
|
1280
|
-
// Isolate this attempt's output so detectRateLimit never sees prior attempts.
|
|
1281
868
|
fs.writeFileSync(attemptLogPath, '', { mode: 0o600 });
|
|
1282
869
|
const stdoutFd = fs.openSync(attemptLogPath, 'a', 0o600);
|
|
1283
870
|
return new Promise((resolve) => {
|
|
@@ -1294,17 +881,17 @@ function spawnJobAttempt(cmd, env, attemptLogPath, timeoutMs, combinedLogPath, c
|
|
|
1294
881
|
try {
|
|
1295
882
|
fs.closeSync(stdoutFd);
|
|
1296
883
|
}
|
|
1297
|
-
catch {
|
|
884
|
+
catch { }
|
|
1298
885
|
let logText = '';
|
|
1299
886
|
try {
|
|
1300
887
|
logText = fs.readFileSync(attemptLogPath, 'utf-8');
|
|
1301
888
|
}
|
|
1302
|
-
catch {
|
|
889
|
+
catch { }
|
|
1303
890
|
if (combinedLogPath) {
|
|
1304
891
|
try {
|
|
1305
892
|
fs.appendFileSync(combinedLogPath, logText);
|
|
1306
893
|
}
|
|
1307
|
-
catch {
|
|
894
|
+
catch { }
|
|
1308
895
|
}
|
|
1309
896
|
resolve({ ...result, logText });
|
|
1310
897
|
};
|
|
@@ -1313,13 +900,13 @@ function spawnJobAttempt(cmd, env, attemptLogPath, timeoutMs, combinedLogPath, c
|
|
|
1313
900
|
if (child.pid)
|
|
1314
901
|
process.kill(-child.pid, 'SIGTERM');
|
|
1315
902
|
}
|
|
1316
|
-
catch {
|
|
903
|
+
catch { }
|
|
1317
904
|
setTimeout(() => {
|
|
1318
905
|
try {
|
|
1319
906
|
if (child.pid)
|
|
1320
907
|
process.kill(-child.pid, 'SIGKILL');
|
|
1321
908
|
}
|
|
1322
|
-
catch {
|
|
909
|
+
catch { }
|
|
1323
910
|
}, 5000);
|
|
1324
911
|
finish({
|
|
1325
912
|
exitCode: null,
|
|
@@ -1350,51 +937,18 @@ function spawnJobAttempt(cmd, env, attemptLogPath, timeoutMs, combinedLogPath, c
|
|
|
1350
937
|
child.unref();
|
|
1351
938
|
});
|
|
1352
939
|
}
|
|
1353
|
-
/**
|
|
1354
|
-
* Execute a job synchronously (waits for completion or timeout before resolving).
|
|
1355
|
-
*
|
|
1356
|
-
* When `config.loop` is set the job is routed through the loop driver (`runLoop`
|
|
1357
|
-
* from loop.ts) instead of a single spawn — same driver as `agents run --loop` and
|
|
1358
|
-
* workflow `loop:` blocks (issue #400). The optional `deps` parameter provides
|
|
1359
|
-
* injectable seams (runIteration, sleep, writeCheckpoint) used by tests; production
|
|
1360
|
-
* callers omit it and get the defaults.
|
|
1361
|
-
*
|
|
1362
|
-
* Single-shot path: pre-flight version/account selection + mid-run rate-limit
|
|
1363
|
-
* failover across healthy same-agent accounts (RUSH-1016).
|
|
1364
|
-
*/
|
|
1365
|
-
/**
|
|
1366
|
-
* Actor provenance for a routine run (RUSH-2020): `actor` is the routine's
|
|
1367
|
-
* CREATOR (carried from the job config), `triggeredBy` is whoever kicked off THIS
|
|
1368
|
-
* run (`resolveActor().id` — a person for a manual run, `UNRESOLVED@<host>` for an
|
|
1369
|
-
* unattended scheduled fire). Spread into every RunMeta so a fired cron traces
|
|
1370
|
-
* back to the person who scheduled it.
|
|
1371
|
-
*/
|
|
1372
940
|
function runProvenance(config) {
|
|
1373
941
|
return { ...(config.actor ? { actor: config.actor } : {}), triggeredBy: resolveActor().id };
|
|
1374
942
|
}
|
|
1375
|
-
/**
|
|
1376
|
-
* Inject the routine creator's actor into a run's base env so the fired agent
|
|
1377
|
-
* INHERITS it (the `AGENTS_ACTOR` path in actor.ts) instead of re-resolving to
|
|
1378
|
-
* `UNRESOLVED@<host>` on an unattended fire — so its session, events, and commits
|
|
1379
|
-
* all attribute to the person who scheduled the routine (RUSH-2020). Mutates and
|
|
1380
|
-
* returns the same env object for call-site brevity.
|
|
1381
|
-
*/
|
|
1382
943
|
function injectRoutineActor(env, config) {
|
|
1383
944
|
if (config.actor && !env.AGENTS_ACTOR)
|
|
1384
945
|
env.AGENTS_ACTOR = config.actor;
|
|
1385
946
|
return env;
|
|
1386
947
|
}
|
|
1387
948
|
export async function executeJob(config, deps, trigger = { kind: 'manual' }) {
|
|
1388
|
-
// Unified attempt: allocate + persist the run record (or a terminal blocked/
|
|
1389
|
-
// skipped record) BEFORE placement, version selection, sandbox, or preflight —
|
|
1390
|
-
// and hold the active-run claim so a manual run cannot overlap a scheduled one.
|
|
1391
949
|
return runWithAttempt(config, trigger, (attempt) => executeJobPlaced(config, deps, attempt), (meta) => ({ meta, reportPath: null }));
|
|
1392
950
|
}
|
|
1393
951
|
async function executeJobPlaced(config, deps, attempt) {
|
|
1394
|
-
// Placement (hostStrategy / bare host:) — body may run on another machine
|
|
1395
|
-
// over SSH or in the cloud; local version selection / sandbox / spawn then
|
|
1396
|
-
// do not apply. Sync callers (manual `routines run`, catchup) follow the
|
|
1397
|
-
// remote run to completion when possible.
|
|
1398
952
|
{
|
|
1399
953
|
const { resolvePlacementTarget } = await import('../routines-placement.js');
|
|
1400
954
|
const target = await resolvePlacementTarget(config);
|
|
@@ -1402,9 +956,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1402
956
|
if (placed)
|
|
1403
957
|
return placed;
|
|
1404
958
|
}
|
|
1405
|
-
// Command-mode: run a plain shell command directly (no agent, no rotation,
|
|
1406
|
-
// no pinning, no sandbox overlay). Reuses the run-record machinery so
|
|
1407
|
-
// list/runs/overdue keep working.
|
|
1408
959
|
if (config.command) {
|
|
1409
960
|
return executeCommandJobForeground(config, attempt);
|
|
1410
961
|
}
|
|
@@ -1419,14 +970,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1419
970
|
schedule: config.schedule,
|
|
1420
971
|
});
|
|
1421
972
|
const resolvedPrompt = resolveJobPrompt(config);
|
|
1422
|
-
// Resume must run against the REAL home: `--resume <id>` resolves the session from
|
|
1423
|
-
// the agent's config dir, and the sandbox overlay home has only a freshly-generated
|
|
1424
|
-
// config with no session store. So a resume job is never sandboxed, regardless of
|
|
1425
|
-
// `config.sandbox` (see the resume branch in buildJobCommand).
|
|
1426
|
-
// Resume needs the REAL home (session store); a custom harness needs it too —
|
|
1427
|
-
// the delegated `agents run <name>` resolves ~/.agents (profiles, setup
|
|
1428
|
-
// sentinel, version homes) from HOME, which the overlay would hide. Exec
|
|
1429
|
-
// still isolates the run in the host version home it swaps HOME into.
|
|
1430
973
|
const useSandbox = config.sandbox !== false && !config.resume && !(config.agent && isCustomHarnessName(config.agent));
|
|
1431
974
|
const overlayHome = useSandbox ? prepareJobHome(config, primaryVersion) : undefined;
|
|
1432
975
|
const runId = attempt.runId;
|
|
@@ -1435,13 +978,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1435
978
|
const baseEnv = injectRoutineActor(useSandbox
|
|
1436
979
|
? buildSpawnEnv(overlayHome, config.env)
|
|
1437
980
|
: { ...process.env }, config);
|
|
1438
|
-
// Workflows run via `agents run <workflow>` which delegates to claude under the hood.
|
|
1439
|
-
// Use 'claude' as the effective agent for report extraction and metadata when workflow is set.
|
|
1440
|
-
// (command jobs branched out earlier, so config.agent is set on the non-workflow path.)
|
|
1441
|
-
// Custom harness/profile name (e.g. `deepseek`) stays on harnessName; the
|
|
1442
|
-
// HOST CLI is effectiveAgent. The loop path spawns in-process via runLoop
|
|
1443
|
-
// and never re-enters `agents run`, so it must stamp harnessName itself
|
|
1444
|
-
// (PHNX-2935) — same field commands/exec.ts sets on ExecOptions.
|
|
1445
981
|
const harnessName = !config.workflow && config.agent && isCustomHarnessName(config.agent)
|
|
1446
982
|
? config.agent
|
|
1447
983
|
: undefined;
|
|
@@ -1470,17 +1006,8 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1470
1006
|
exitCode: null,
|
|
1471
1007
|
};
|
|
1472
1008
|
writeRunMeta(meta);
|
|
1473
|
-
// Baseline the child's transcript dirs BEFORE spawning so archiveRoutineTranscripts
|
|
1474
|
-
// copies only THIS run's transcript out of a shared per-version home (RUSH-2271).
|
|
1475
1009
|
snapshotRoutineTranscriptBase(meta, runDir, overlayHome);
|
|
1476
|
-
// Auth preflight: if the resolved account is provably signed out (revoked or
|
|
1477
|
-
// unconfigured), record a terminal `blocked`/`agent_auth_failed` run with the
|
|
1478
|
-
// re-login repair instead of spawning a doomed run that 401s and burns a
|
|
1479
|
-
// session (PHNX-3415). `blocked` (readiness rejection, no body ran) is kept
|
|
1480
|
-
// distinct from `failed` (a body ran and errored) per RT-7. Cache-only + fails
|
|
1481
|
-
// OPEN — see fireTimeAuthReadiness.
|
|
1482
1010
|
const preflightVersion = launch.chain[0]?.version;
|
|
1483
|
-
// Dynamic import breaks the routine-readiness -> scheduling/routines -> runner cycle.
|
|
1484
1011
|
const { fireTimeAuthReadiness } = await import('../routine-readiness.js');
|
|
1485
1012
|
const authBlocker = preflightVersion ? fireTimeAuthReadiness(effectiveAgent, preflightVersion) : null;
|
|
1486
1013
|
if (authBlocker) {
|
|
@@ -1493,14 +1020,11 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1493
1020
|
return { meta, reportPath: null };
|
|
1494
1021
|
}
|
|
1495
1022
|
const timeoutMs = parseTimeout(config.timeout) || 10 * 60 * 1000;
|
|
1496
|
-
// Loop path: delegate to runLoop (same driver as `agents run --loop` / workflow loop:).
|
|
1497
1023
|
if (config.loop) {
|
|
1498
1024
|
const spawnEnv = buildRoutineSpawnEnv(baseEnv, effectiveAgent, primaryVersion, config.timezone, overlayHome);
|
|
1499
1025
|
const execOptions = {
|
|
1500
1026
|
agent: effectiveAgent,
|
|
1501
1027
|
harnessName,
|
|
1502
|
-
// Routine-supported self-updating CLIs (Cursor/Droid) use one global
|
|
1503
|
-
// binary; a versioned shim would point at a nonexistent isolated install.
|
|
1504
1028
|
version: isSelfUpdatingAgent(effectiveAgent) ? undefined : primaryVersion,
|
|
1505
1029
|
prompt: resolvedPrompt,
|
|
1506
1030
|
mode: normalizeMode(config.mode),
|
|
@@ -1531,11 +1055,8 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1531
1055
|
archiveRoutineTranscripts(meta, runDir, overlayHome);
|
|
1532
1056
|
return { meta, reportPath: null };
|
|
1533
1057
|
}
|
|
1534
|
-
// Single-shot path: build the command once, then walk the launch chain on
|
|
1535
|
-
// rate/usage-limit failures (same detectRateLimit patterns as agents run).
|
|
1536
1058
|
const baseCmd = buildJobCommand(config, resolvedPrompt, launch.forwardAccount !== false);
|
|
1537
1059
|
const stdoutPath = path.join(runDir, 'stdout.log');
|
|
1538
|
-
// Truncate the log for a clean run; failover attempts append.
|
|
1539
1060
|
fs.writeFileSync(stdoutPath, '', { mode: 0o600 });
|
|
1540
1061
|
const chain = launch.chain.length > 0
|
|
1541
1062
|
? launch.chain
|
|
@@ -1549,11 +1070,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1549
1070
|
if (i === 0) {
|
|
1550
1071
|
process.stderr.write(`[agents] routine ${config.name}: running ${label}\n`);
|
|
1551
1072
|
}
|
|
1552
|
-
// A rate-limit failover spawns the NEXT chain entry, whose version/account has
|
|
1553
|
-
// its own per-version transcript home. Re-point meta.version at the attempt that
|
|
1554
|
-
// is about to run and re-baseline that home, so the archiver reads the transcript
|
|
1555
|
-
// where THIS attempt writes it — not chain[0]'s home (RUSH-2271). The pre-loop
|
|
1556
|
-
// snapshot already covered chain[0]; this makes every later attempt correct too.
|
|
1557
1073
|
meta.version = attemptVersion;
|
|
1558
1074
|
snapshotRoutineTranscriptBase(meta, runDir, overlayHome);
|
|
1559
1075
|
const viaAgentsRun = dispatchesViaAgentsRun(config);
|
|
@@ -1570,7 +1086,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1570
1086
|
return e;
|
|
1571
1087
|
})()
|
|
1572
1088
|
: buildRoutineSpawnEnv(baseEnv, attemptAgent, attemptVersion, config.timezone, overlayHome);
|
|
1573
|
-
// Remaining timeout budget shared across failover attempts.
|
|
1574
1089
|
const elapsed = Date.now() - Date.parse(meta.startedAt);
|
|
1575
1090
|
const remaining = Math.max(1_000, timeoutMs - (Number.isFinite(elapsed) ? elapsed : 0));
|
|
1576
1091
|
const attemptLogPath = path.join(runDir, `stdout.attempt-${i}.log`);
|
|
@@ -1586,24 +1101,15 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1586
1101
|
return { meta, reportPath };
|
|
1587
1102
|
}
|
|
1588
1103
|
if (attempt.status === 'completed') {
|
|
1589
|
-
// Exit code alone is unreliable for auth: a logged-out Claude can exit 0
|
|
1590
|
-
// with a `result` event carrying is_error:true (terminal_reason
|
|
1591
|
-
// "completed"). Consult the SAME structural signal the detached path uses
|
|
1592
|
-
// so both paths agree — raw text is deliberately NOT used here, so a
|
|
1593
|
-
// genuinely-completed run that merely mentions an auth phrase stays a
|
|
1594
|
-
// success (processFailed:false).
|
|
1595
1104
|
if (isAuthFailureFromLog(attempt.logText, effectiveAgent, { processFailed: false })) {
|
|
1596
1105
|
const reason = authFailureReason(attempt.logText) ?? 'authentication_failed';
|
|
1597
1106
|
recordRoutineAuthOutcome(attemptAgent, config.account, attemptVersion, { ok: false, verdict: 'revoked', detail: reason });
|
|
1598
1107
|
finalizeRunMeta(meta, 'failed', attempt.exitCode ?? 1, { errorMessage: `auth_failed: ${reason}` });
|
|
1599
1108
|
writeRunMeta(meta);
|
|
1600
1109
|
timer.end({ status: 'failed', exitCode: meta.exitCode ?? undefined, runId, error: `auth_failed: ${reason}` });
|
|
1601
|
-
// Never persist the login-error text as the report.
|
|
1602
1110
|
archiveRoutineTranscripts(meta, runDir, overlayHome);
|
|
1603
1111
|
return { meta, reportPath: null };
|
|
1604
1112
|
}
|
|
1605
|
-
// A clean routine completion is real auth evidence — record it so a worker's
|
|
1606
|
-
// token reads `last used ok` and a stale failure fact is cleared (PHNX-4116).
|
|
1607
1113
|
recordRoutineAuthOutcome(attemptAgent, config.account, attemptVersion, { ok: true });
|
|
1608
1114
|
finalizeRunMeta(meta, 'completed', 0);
|
|
1609
1115
|
writeRunMeta(meta);
|
|
@@ -1612,7 +1118,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1612
1118
|
archiveRoutineTranscripts(meta, runDir, overlayHome);
|
|
1613
1119
|
return { meta, reportPath };
|
|
1614
1120
|
}
|
|
1615
|
-
// Failed — cascade only on rate/usage limit when more chain entries remain.
|
|
1616
1121
|
const isLast = i === chain.length - 1;
|
|
1617
1122
|
const rateLimited = detectRateLimit(attempt.logText) || (attempt.error ? detectRateLimit(attempt.error) : false);
|
|
1618
1123
|
if (!isLast && rateLimited) {
|
|
@@ -1622,11 +1127,6 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1622
1127
|
fs.appendFileSync(stdoutPath, `\n[agents] ${label} hit rate/usage limit — failover → ${nextLabel}\n`);
|
|
1623
1128
|
continue;
|
|
1624
1129
|
}
|
|
1625
|
-
// Auth failure — the agent is logged out / token revoked. Unlike a rate
|
|
1626
|
-
// limit it is not self-healing by failover (every chain entry on the same
|
|
1627
|
-
// account fails identically), so rate-limit is classified first (above) and
|
|
1628
|
-
// auth only when NOT rate-limited. Classified so the failure is visible and,
|
|
1629
|
-
// critically, so the login-error text is never persisted as the report.
|
|
1630
1130
|
const authFailed = !rateLimited && (isAuthFailureFromLog(attempt.logText, effectiveAgent, { processFailed: true }) ||
|
|
1631
1131
|
(attempt.error ? detectAuthFailure(attempt.error) : false));
|
|
1632
1132
|
if (attempt.error) {
|
|
@@ -1650,24 +1150,15 @@ async function executeJobPlaced(config, deps, attempt) {
|
|
|
1650
1150
|
runId,
|
|
1651
1151
|
...(failureErrorMessage ? { error: failureErrorMessage } : {}),
|
|
1652
1152
|
});
|
|
1653
|
-
// On auth failure the last assistant text IS the login error — never persist
|
|
1654
|
-
// it as report.md; it would otherwise be injected into the next run's prompt
|
|
1655
|
-
// via {last_report}.
|
|
1656
1153
|
const reportPath = authFailed ? null : extractAndSaveReport(stdoutPath, effectiveAgent, runDir);
|
|
1657
1154
|
archiveRoutineTranscripts(meta, runDir, overlayHome);
|
|
1658
1155
|
return { meta, reportPath };
|
|
1659
1156
|
}
|
|
1660
|
-
// Unreachable: chain is always non-empty, but keep a safe fallback.
|
|
1661
1157
|
finalizeRunMeta(meta, 'failed', 1);
|
|
1662
1158
|
writeRunMeta(meta);
|
|
1663
1159
|
timer.end({ status: 'failed', exitCode: 1, runId });
|
|
1664
1160
|
return { meta, reportPath: null };
|
|
1665
1161
|
}
|
|
1666
|
-
/**
|
|
1667
|
-
* Dispatch a routine to the agent's native cloud provider (or the configured
|
|
1668
|
-
* default). Writes a local run record with `cloudTaskId` so list/runs still
|
|
1669
|
-
* work; does not wait for cloud completion on the detached path.
|
|
1670
|
-
*/
|
|
1671
1162
|
async function executeJobOnCloud(config, opts, attempt) {
|
|
1672
1163
|
if (config.workflow) {
|
|
1673
1164
|
throw new Error(`Routine '${config.name}' runs a workflow bundle, which can't execute in the cloud yet — remove 'hostStrategy: cloud' or 'workflow:'.`);
|
|
@@ -1720,20 +1211,15 @@ async function executeJobOnCloud(config, opts, attempt) {
|
|
|
1720
1211
|
try {
|
|
1721
1212
|
insertTask(task);
|
|
1722
1213
|
}
|
|
1723
|
-
catch {
|
|
1214
|
+
catch { }
|
|
1724
1215
|
meta.cloudTaskId = task.id;
|
|
1725
1216
|
meta.cloudProvider = task.provider;
|
|
1726
|
-
// Terminal cloud responses (e.g. antigravity) finalize immediately.
|
|
1727
|
-
// Async providers leave the run `running` with the cloud task id for
|
|
1728
|
-
// the user to follow via `agents cloud status`.
|
|
1729
1217
|
if (task.status === 'completed') {
|
|
1730
1218
|
finalizeRunMeta(meta, 'completed', 0);
|
|
1731
1219
|
}
|
|
1732
1220
|
else if (task.status === 'failed' || task.status === 'cancelled') {
|
|
1733
1221
|
finalizeRunMeta(meta, 'failed', 1, { errorMessage: task.summary ?? `cloud ${task.status}` });
|
|
1734
1222
|
}
|
|
1735
|
-
// Non-terminal statuses stay `running` for both detached and sync paths;
|
|
1736
|
-
// the user follows via `agents cloud status <id>`.
|
|
1737
1223
|
writeRunMeta(meta);
|
|
1738
1224
|
timer.end({ status: meta.status, exitCode: meta.exitCode ?? undefined, runId });
|
|
1739
1225
|
return { meta, reportPath: null };
|
|
@@ -1779,7 +1265,7 @@ async function executeJobOnHost(config, opts, attempt) {
|
|
|
1779
1265
|
...runProvenance(config),
|
|
1780
1266
|
...attempt.stamp,
|
|
1781
1267
|
agent: config.agent,
|
|
1782
|
-
pid: null,
|
|
1268
|
+
pid: null,
|
|
1783
1269
|
spawnedAt: Date.now(),
|
|
1784
1270
|
status: 'running',
|
|
1785
1271
|
startedAt: new Date().toISOString(),
|
|
@@ -1790,8 +1276,6 @@ async function executeJobOnHost(config, opts, attempt) {
|
|
|
1790
1276
|
writeRunMeta(meta);
|
|
1791
1277
|
const { task, exitCode } = await dispatchPromptToHost(host, buildHostDispatchOptions(config, { remoteCwd, runDir, detached: opts.detached }));
|
|
1792
1278
|
meta.hostTaskId = task.id;
|
|
1793
|
-
// Sync path: a real exit code finalizes now. -1 (follow window closed) and
|
|
1794
|
-
// the detached path leave the meta `running` for the monitor to reconcile.
|
|
1795
1279
|
if (!opts.detached && exitCode !== null && exitCode !== undefined && exitCode !== -1) {
|
|
1796
1280
|
finalizeRunMeta(meta, exitCode === 0 ? 'completed' : 'failed', exitCode);
|
|
1797
1281
|
}
|
|
@@ -1799,7 +1283,6 @@ async function executeJobOnHost(config, opts, attempt) {
|
|
|
1799
1283
|
timer.end({ status: meta.status, exitCode: meta.exitCode ?? undefined, runId });
|
|
1800
1284
|
return { meta, reportPath: null };
|
|
1801
1285
|
}
|
|
1802
|
-
/** Spawn a job as a detached process and return immediately with run metadata. */
|
|
1803
1286
|
async function executeCommandJobForeground(config, attempt) {
|
|
1804
1287
|
const timer = createTimer('agent.run', {
|
|
1805
1288
|
jobName: config.name,
|
|
@@ -1845,7 +1328,7 @@ async function executeCommandJobForeground(config, attempt) {
|
|
|
1845
1328
|
try {
|
|
1846
1329
|
fs.closeSync(stdoutFd);
|
|
1847
1330
|
}
|
|
1848
|
-
catch {
|
|
1331
|
+
catch { }
|
|
1849
1332
|
resolve(r);
|
|
1850
1333
|
};
|
|
1851
1334
|
const timeoutTimer = setTimeout(() => {
|
|
@@ -1853,13 +1336,13 @@ async function executeCommandJobForeground(config, attempt) {
|
|
|
1853
1336
|
if (child.pid)
|
|
1854
1337
|
process.kill(-child.pid, 'SIGTERM');
|
|
1855
1338
|
}
|
|
1856
|
-
catch {
|
|
1339
|
+
catch { }
|
|
1857
1340
|
setTimeout(() => {
|
|
1858
1341
|
try {
|
|
1859
1342
|
if (child.pid)
|
|
1860
1343
|
process.kill(-child.pid, 'SIGKILL');
|
|
1861
1344
|
}
|
|
1862
|
-
catch {
|
|
1345
|
+
catch { }
|
|
1863
1346
|
}, 5000);
|
|
1864
1347
|
finish({ exitCode: null, status: 'timeout' });
|
|
1865
1348
|
}, timeoutMs);
|
|
@@ -1885,25 +1368,18 @@ async function executeCommandJobForeground(config, attempt) {
|
|
|
1885
1368
|
});
|
|
1886
1369
|
return { meta, reportPath: null };
|
|
1887
1370
|
}
|
|
1888
|
-
/** Invoke a lifecycle hook without letting a caller error break run finalization. */
|
|
1889
1371
|
function safeHook(fn) {
|
|
1890
1372
|
if (!fn)
|
|
1891
1373
|
return;
|
|
1892
1374
|
try {
|
|
1893
1375
|
fn();
|
|
1894
1376
|
}
|
|
1895
|
-
catch {
|
|
1377
|
+
catch { }
|
|
1896
1378
|
}
|
|
1897
|
-
/** Spawn a job as a detached process and return immediately with run metadata. */
|
|
1898
1379
|
export async function executeJobDetached(config, hooks, trigger = { kind: 'manual' }) {
|
|
1899
1380
|
return runWithAttempt(config, trigger, (attempt) => executeJobDetachedClaimed(config, attempt, hooks), (meta) => meta);
|
|
1900
1381
|
}
|
|
1901
1382
|
async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
1902
|
-
// Placement (hostStrategy / bare host:) — dispatch off-box and return; the
|
|
1903
|
-
// monitor finalizes host: runs, cloud runs stay terminal when dispatch ends.
|
|
1904
|
-
// Either way the in-process onFinish hook does not fire for off-box routines
|
|
1905
|
-
// (the monitor tick observes an already-finalized record), so notify-desktop
|
|
1906
|
-
// sends the finish notification only for local detached runs below (RUSH-2030).
|
|
1907
1383
|
{
|
|
1908
1384
|
const { resolvePlacementTarget } = await import('../routines-placement.js');
|
|
1909
1385
|
const target = await resolvePlacementTarget(config);
|
|
@@ -1923,15 +1399,9 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
1923
1399
|
return meta;
|
|
1924
1400
|
}
|
|
1925
1401
|
}
|
|
1926
|
-
// Command-mode: fire a plain shell command detached (no agent, no rotation,
|
|
1927
|
-
// no pinning, no sandbox overlay). Still writes a run record so the daemon,
|
|
1928
|
-
// list/runs, and overdue tracking keep working.
|
|
1929
1402
|
if (config.command) {
|
|
1930
1403
|
return executeCommandJobDetached(config, attempt, hooks);
|
|
1931
1404
|
}
|
|
1932
|
-
// Pre-flight: pick a healthy version/account so the daemon does not launch
|
|
1933
|
-
// into a credit-exhausted install. Detached cannot mid-run failover (no exit
|
|
1934
|
-
// wait); the next schedule tick re-selects if this attempt still fails.
|
|
1935
1405
|
const launch = await resolveRoutineLaunch(config);
|
|
1936
1406
|
const version = launch.chain[0]?.version ?? config.version;
|
|
1937
1407
|
const timer = createTimer('agent.run', {
|
|
@@ -1944,19 +1414,9 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
1944
1414
|
});
|
|
1945
1415
|
const resolvedPrompt = resolveJobPrompt(config);
|
|
1946
1416
|
let cmd = buildJobCommand(config, resolvedPrompt, launch.forwardAccount !== false);
|
|
1947
|
-
// workflow AND resume dispatch through `agents run` — never binary-pin them (pinning
|
|
1948
|
-
// rewrites cmd[0] to the agent binary → broken `<binary> run …`).
|
|
1949
1417
|
if (!dispatchesViaAgentsRun(config) && version && config.agent) {
|
|
1950
1418
|
cmd = pinJobBinary(cmd, config.agent, version);
|
|
1951
1419
|
}
|
|
1952
|
-
// Resume must run against the REAL home: `--resume <id>` resolves the session from
|
|
1953
|
-
// the agent's config dir, and the sandbox overlay home has only a freshly-generated
|
|
1954
|
-
// config with no session store. So a resume job is never sandboxed, regardless of
|
|
1955
|
-
// `config.sandbox` (see the resume branch in buildJobCommand).
|
|
1956
|
-
// Resume needs the REAL home (session store); a custom harness needs it too —
|
|
1957
|
-
// the delegated `agents run <name>` resolves ~/.agents (profiles, setup
|
|
1958
|
-
// sentinel, version homes) from HOME, which the overlay would hide. Exec
|
|
1959
|
-
// still isolates the run in the host version home it swaps HOME into.
|
|
1960
1420
|
const useSandbox = config.sandbox !== false && !config.resume && !(config.agent && isCustomHarnessName(config.agent));
|
|
1961
1421
|
const overlayHome = useSandbox ? prepareJobHome(config, version) : undefined;
|
|
1962
1422
|
const runId = attempt.runId;
|
|
@@ -1975,10 +1435,8 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
1975
1435
|
e.TZ = config.timezone;
|
|
1976
1436
|
return e;
|
|
1977
1437
|
})()
|
|
1978
|
-
// Non-command path only: config.agent is always set here (command/workflow branch earlier).
|
|
1979
1438
|
: buildRoutineSpawnEnv(baseEnv, config.agent, version, config.timezone, overlayHome);
|
|
1980
1439
|
// RUSH-2860: if this host holds gh auth, the sandbox child MUST see it —
|
|
1981
|
-
// otherwise monitors runs records ok while every gh call inside fails.
|
|
1982
1440
|
if (useSandbox)
|
|
1983
1441
|
assertSandboxForwardsHostGhAuth(spawnEnv);
|
|
1984
1442
|
const effectiveAgent = config.workflow
|
|
@@ -2002,15 +1460,8 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2002
1460
|
completedAt: null,
|
|
2003
1461
|
exitCode: null,
|
|
2004
1462
|
};
|
|
2005
|
-
// Baseline the child's transcript dirs BEFORE spawning so archiveRoutineTranscripts
|
|
2006
|
-
// copies only THIS run's transcript out of a shared per-version home (RUSH-2271).
|
|
2007
1463
|
snapshotRoutineTranscriptBase(meta, runDir, overlayHome);
|
|
2008
|
-
// Auth preflight (mirrors executeJob): a provably signed-out resolved account
|
|
2009
|
-
// records a terminal `blocked`/`agent_auth_failed` run with the re-login repair
|
|
2010
|
-
// instead of spawning a doomed run that 401s and burns a session (PHNX-3415).
|
|
2011
|
-
// Cache-only + fails OPEN — see fireTimeAuthReadiness.
|
|
2012
1464
|
const preflightVersion = launch.chain[0]?.version;
|
|
2013
|
-
// Dynamic import breaks the routine-readiness -> scheduling/routines -> runner cycle.
|
|
2014
1465
|
const { fireTimeAuthReadiness } = await import('../routine-readiness.js');
|
|
2015
1466
|
const authBlocker = preflightVersion ? fireTimeAuthReadiness(effectiveAgent, preflightVersion) : null;
|
|
2016
1467
|
if (authBlocker) {
|
|
@@ -2018,7 +1469,7 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2018
1469
|
try {
|
|
2019
1470
|
fs.closeSync(stdoutFd);
|
|
2020
1471
|
}
|
|
2021
|
-
catch {
|
|
1472
|
+
catch { }
|
|
2022
1473
|
meta.readiness = authBlocker;
|
|
2023
1474
|
finalizeRunMeta(meta, 'blocked', null, { errorMessage: `blocked: ${authBlocker.code} — ${authBlocker.message}` });
|
|
2024
1475
|
writeRunMeta(meta);
|
|
@@ -2042,14 +1493,10 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2042
1493
|
finalizeRunMeta(meta, status, exitCode, errorMessage ? { errorMessage } : undefined);
|
|
2043
1494
|
writeRunMeta(meta);
|
|
2044
1495
|
archiveRoutineTranscripts(meta, runDir, overlayHome);
|
|
2045
|
-
// Never persist the report on an auth failure — the last assistant text is
|
|
2046
|
-
// the login error, which would poison the next run's {last_report} prompt.
|
|
2047
1496
|
const isAuthFailure = !!errorMessage && errorMessage.startsWith('auth_failed:');
|
|
2048
1497
|
if (status !== 'timeout' && !isAuthFailure)
|
|
2049
1498
|
extractAndSaveReport(stdoutPath, effectiveAgent, runDir);
|
|
2050
1499
|
timer.end({ status, exitCode: exitCode ?? undefined, runId, ...(errorMessage ? { error: errorMessage } : {}) });
|
|
2051
|
-
// Fire the finish/output notification AFTER the report is written so the hook
|
|
2052
|
-
// can read report.md (RUSH-2030). Best-effort; never breaks finalization.
|
|
2053
1500
|
safeHook(hooks?.onFinish ? () => hooks.onFinish(meta) : undefined);
|
|
2054
1501
|
};
|
|
2055
1502
|
timeoutTimer = setTimeout(() => {
|
|
@@ -2061,10 +1508,7 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2061
1508
|
try {
|
|
2062
1509
|
logText = fs.readFileSync(stdoutPath, 'utf-8');
|
|
2063
1510
|
}
|
|
2064
|
-
catch {
|
|
2065
|
-
// processFailed gates the raw-text fallback so a COMPLETED run (exit 0) that
|
|
2066
|
-
// merely mentions an auth phrase is never misclassified; the structural
|
|
2067
|
-
// marker still catches an exit-0 auth failure on its own.
|
|
1511
|
+
catch { }
|
|
2068
1512
|
if (isAuthFailureFromLog(logText, effectiveAgent, { processFailed: (code ?? 1) !== 0 })) {
|
|
2069
1513
|
const reason = authFailureReason(logText) ?? 'authentication_failed';
|
|
2070
1514
|
recordRoutineAuthOutcome(effectiveAgent, config.account, meta.version, { ok: false, verdict: 'revoked', detail: reason });
|
|
@@ -2073,7 +1517,6 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2073
1517
|
}
|
|
2074
1518
|
const inferred = inferFinalStatusFromLog(stdoutPath, effectiveAgent);
|
|
2075
1519
|
const finalStatus = inferred ? inferred.status : (code === 0 ? 'completed' : 'failed');
|
|
2076
|
-
// A clean completion clears any stale auth-failure fact for this account.
|
|
2077
1520
|
if (finalStatus === 'completed')
|
|
2078
1521
|
recordRoutineAuthOutcome(effectiveAgent, config.account, meta.version, { ok: true });
|
|
2079
1522
|
if (inferred) {
|
|
@@ -2087,7 +1530,7 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2087
1530
|
try {
|
|
2088
1531
|
fs.closeSync(stdoutFd);
|
|
2089
1532
|
}
|
|
2090
|
-
catch {
|
|
1533
|
+
catch { }
|
|
2091
1534
|
settle('failed', 1, err.message);
|
|
2092
1535
|
process.stderr.write(`[agents] daemon: spawn failed for job "${config.name}": ${err.message}\n`);
|
|
2093
1536
|
});
|
|
@@ -2095,17 +1538,11 @@ async function executeJobDetachedClaimed(config, attempt, hooks) {
|
|
|
2095
1538
|
try {
|
|
2096
1539
|
fs.closeSync(stdoutFd);
|
|
2097
1540
|
}
|
|
2098
|
-
catch {
|
|
1541
|
+
catch { }
|
|
2099
1542
|
meta.pid = child.pid || null;
|
|
2100
1543
|
writeRunMeta(meta);
|
|
2101
1544
|
return { ...meta };
|
|
2102
1545
|
}
|
|
2103
|
-
/**
|
|
2104
|
-
* Detached (fire-and-forget) execution for a command-mode routine. Mirrors the
|
|
2105
|
-
* agent detached flow: write an initial running record, spawn the shell command
|
|
2106
|
-
* un-sandboxed, unref, then record the pid. The daemon does not wait for exit;
|
|
2107
|
-
* `monitorRunningJobs` reaps the record on the next tick.
|
|
2108
|
-
*/
|
|
2109
1546
|
function executeCommandJobDetached(config, attempt, hooks) {
|
|
2110
1547
|
const timer = createTimer('agent.run', {
|
|
2111
1548
|
jobName: config.name,
|
|
@@ -2117,14 +1554,7 @@ function executeCommandJobDetached(config, attempt, hooks) {
|
|
|
2117
1554
|
fs.mkdirSync(runDir, { recursive: true });
|
|
2118
1555
|
const stdoutPath = path.join(runDir, 'stdout.log');
|
|
2119
1556
|
const stdoutFd = fs.openSync(stdoutPath, 'w', 0o600);
|
|
2120
|
-
// Wrap the shell so the child records its own exit code to <runDir>/exit-code.
|
|
2121
|
-
// The in-process `child.on('exit')` below writes the terminal record while the
|
|
2122
|
-
// daemon is alive (the common case); the file lets monitorRunningJobs recover
|
|
2123
|
-
// the real status if the daemon restarted between spawn and exit. (win32 relies
|
|
2124
|
-
// on the exit event only.)
|
|
2125
1557
|
const exitCodePath = path.join(runDir, 'exit-code');
|
|
2126
|
-
// Run the command in a SUBSHELL `( … )` so that if it calls `exit`, only the
|
|
2127
|
-
// subshell exits — the outer shell still captures `$?` and writes the file.
|
|
2128
1558
|
const wrappedCommand = wrapCommandRoutine(config.command);
|
|
2129
1559
|
const cmd = process.platform === 'win32'
|
|
2130
1560
|
? buildShellCommand(wrappedCommand)
|
|
@@ -2150,9 +1580,6 @@ function executeCommandJobDetached(config, attempt, hooks) {
|
|
|
2150
1580
|
...backgroundSpawnOptions({ cwd: routineSpawnCwd(config), fdStdio: true }),
|
|
2151
1581
|
env,
|
|
2152
1582
|
});
|
|
2153
|
-
// Record the real terminal status ourselves — the daemon stays alive after this
|
|
2154
|
-
// fire-and-forget call, so the exit event fires here. (monitorRunningJobs no
|
|
2155
|
-
// longer force-fails command jobs; it reads exit-code only on the restart edge.)
|
|
2156
1583
|
let settled = false;
|
|
2157
1584
|
let timeoutTimer;
|
|
2158
1585
|
const settle = (status, exitCode, errorMessage) => {
|
|
@@ -2164,8 +1591,6 @@ function executeCommandJobDetached(config, attempt, hooks) {
|
|
|
2164
1591
|
finalizeRunMeta(meta, status, exitCode, errorMessage ? { errorMessage } : undefined);
|
|
2165
1592
|
writeRunMeta(meta);
|
|
2166
1593
|
timer.end({ status, exitCode: exitCode ?? undefined, runId, ...(errorMessage ? { error: errorMessage } : {}) });
|
|
2167
|
-
// Finish notification (RUSH-2030). For command routines the threshold only
|
|
2168
|
-
// surfaces failures, decided in routine-notify.ts. Best-effort.
|
|
2169
1594
|
safeHook(hooks?.onFinish ? () => hooks.onFinish(meta) : undefined);
|
|
2170
1595
|
};
|
|
2171
1596
|
timeoutTimer = setTimeout(() => {
|
|
@@ -2181,7 +1606,7 @@ function executeCommandJobDetached(config, attempt, hooks) {
|
|
|
2181
1606
|
try {
|
|
2182
1607
|
fs.closeSync(stdoutFd);
|
|
2183
1608
|
}
|
|
2184
|
-
catch {
|
|
1609
|
+
catch { }
|
|
2185
1610
|
meta.pid = child.pid || null;
|
|
2186
1611
|
writeRunMeta(meta);
|
|
2187
1612
|
return { ...meta };
|
|
@@ -2202,7 +1627,6 @@ function extractAndSaveReport(stdoutPath, agentType, runDir) {
|
|
|
2202
1627
|
}
|
|
2203
1628
|
return null;
|
|
2204
1629
|
}
|
|
2205
|
-
/** Extract the final assistant message from a stream-JSON log file as a markdown report. */
|
|
2206
1630
|
export function extractReport(stdoutPath, agentType) {
|
|
2207
1631
|
if (!fs.existsSync(stdoutPath))
|
|
2208
1632
|
return null;
|
|
@@ -2230,7 +1654,7 @@ export function extractReport(stdoutPath, agentType) {
|
|
|
2230
1654
|
}
|
|
2231
1655
|
}
|
|
2232
1656
|
}
|
|
2233
|
-
catch {
|
|
1657
|
+
catch { }
|
|
2234
1658
|
}
|
|
2235
1659
|
return lastMessage || null;
|
|
2236
1660
|
}
|
|
@@ -2238,20 +1662,12 @@ export function extractReport(stdoutPath, agentType) {
|
|
|
2238
1662
|
return null;
|
|
2239
1663
|
}
|
|
2240
1664
|
}
|
|
2241
|
-
/** Derive the final status of a detached run by reading the agent's stream-json
|
|
2242
|
-
* tail. Detached children fire-and-forget, so we never see their exit code
|
|
2243
|
-
* directly — but Claude's stream-json terminates with a `type: result` line
|
|
2244
|
-
* that carries `is_error`. If we find it, the run completed cleanly (modulo
|
|
2245
|
-
* agent-reported error). If not, the process likely died mid-stream and the
|
|
2246
|
-
* caller should treat the run as failed. */
|
|
2247
1665
|
export function inferFinalStatusFromLog(stdoutPath, agent) {
|
|
2248
1666
|
if (!fs.existsSync(stdoutPath))
|
|
2249
1667
|
return null;
|
|
2250
1668
|
try {
|
|
2251
1669
|
const content = fs.readFileSync(stdoutPath, 'utf-8');
|
|
2252
1670
|
const lines = content.split('\n').filter((l) => l.trim());
|
|
2253
|
-
// Walk backwards over the last few lines — the result marker is always
|
|
2254
|
-
// at the tail. Cap the scan so a huge stdout doesn't iterate forever.
|
|
2255
1671
|
for (let i = lines.length - 1, scanned = 0; i >= 0 && scanned < 20; i--, scanned++) {
|
|
2256
1672
|
try {
|
|
2257
1673
|
const parsed = JSON.parse(lines[i]);
|
|
@@ -2262,7 +1678,6 @@ export function inferFinalStatusFromLog(stdoutPath, agent) {
|
|
|
2262
1678
|
}
|
|
2263
1679
|
}
|
|
2264
1680
|
catch {
|
|
2265
|
-
// malformed JSONL line — keep scanning
|
|
2266
1681
|
}
|
|
2267
1682
|
}
|
|
2268
1683
|
return null;
|
|
@@ -2272,19 +1687,7 @@ export function inferFinalStatusFromLog(stdoutPath, agent) {
|
|
|
2272
1687
|
}
|
|
2273
1688
|
}
|
|
2274
1689
|
const MAX_WALL_CLOCK_MS = 24 * 60 * 60 * 1000;
|
|
2275
|
-
/**
|
|
2276
|
-
* Verify that a PID still belongs to the process we spawned, not a recycled
|
|
2277
|
-
* OS PID. Uses the recorded `spawnedAt` (epoch ms) from meta.json and
|
|
2278
|
-
* compares against the process's actual start time via `ps`. Returns true
|
|
2279
|
-
* when the PID is alive AND plausibly ours.
|
|
2280
|
-
*/
|
|
2281
|
-
/** Bound the identity `ps` — a hung `ps` must never freeze its caller for long (matches routine-process-cleanup's probe). */
|
|
2282
1690
|
const PS_IDENTITY_TIMEOUT_MS = 5_000;
|
|
2283
|
-
/**
|
|
2284
|
-
* Pure: does a `ps -o etime=` value place the process's birth within 30s of when
|
|
2285
|
-
* we recorded spawning it? An empty/unknown reading conservatively reads as ours
|
|
2286
|
-
* — never reap a run on a doubtful identity probe.
|
|
2287
|
-
*/
|
|
2288
1691
|
function etimeIndicatesOurs(etime, spawnedAt) {
|
|
2289
1692
|
if (!etime)
|
|
2290
1693
|
return true;
|
|
@@ -2301,17 +1704,6 @@ function etimeIndicatesOurs(etime, spawnedAt) {
|
|
|
2301
1704
|
const processStartMs = Date.now() - uptimeSec * 1000;
|
|
2302
1705
|
return Math.abs(processStartMs - spawnedAt) < 30_000;
|
|
2303
1706
|
}
|
|
2304
|
-
/**
|
|
2305
|
-
* Synchronous identity check for callers OTHER than the periodic heartbeat tick:
|
|
2306
|
-
* the `agents routines list/status` builders and stop-time enumeration (both in
|
|
2307
|
-
* short-lived CLI processes), plus the scheduler's fire-time slot-claim
|
|
2308
|
-
* (`activeRoutineRun`) and status projection (`isRunGenuinelyInFlight`). Those
|
|
2309
|
-
* last two DO run in-process on the daemon's event loop, but are event-driven
|
|
2310
|
-
* (they fire when a job is dispatched, not on a fixed cadence) and the `ps` here
|
|
2311
|
-
* is now bounded to {@link PS_IDENTITY_TIMEOUT_MS} — they are not the
|
|
2312
|
-
* unconditional every-tick scan PHNX-3695 targets. The heartbeat tick's own scan
|
|
2313
|
-
* uses the non-blocking {@link isPidOursAsync} instead.
|
|
2314
|
-
*/
|
|
2315
1707
|
function isPidOurs(pid, spawnedAt) {
|
|
2316
1708
|
try {
|
|
2317
1709
|
process.kill(pid, 0);
|
|
@@ -2331,13 +1723,6 @@ function isPidOurs(pid, spawnedAt) {
|
|
|
2331
1723
|
return true;
|
|
2332
1724
|
}
|
|
2333
1725
|
}
|
|
2334
|
-
/**
|
|
2335
|
-
* Async, deadline-bounded twin of {@link isPidOurs} for the daemon's heartbeat
|
|
2336
|
-
* tick (`reapExitedRunningJobs`) — the `ps` probe runs on the shared event loop,
|
|
2337
|
-
* so it MUST NOT block it (PHNX-3695). Same semantics: dead pid → not ours;
|
|
2338
|
-
* no recorded `spawnedAt` or Windows → assume ours; a failed/empty probe reads
|
|
2339
|
-
* as ours (conservative — never reap on a doubtful probe).
|
|
2340
|
-
*/
|
|
2341
1726
|
async function isPidOursAsync(pid, spawnedAt) {
|
|
2342
1727
|
if (!isAlive(pid))
|
|
2343
1728
|
return false;
|
|
@@ -2347,23 +1732,10 @@ async function isPidOursAsync(pid, spawnedAt) {
|
|
|
2347
1732
|
return true;
|
|
2348
1733
|
const res = await execFileBounded('ps', ['-p', String(pid), '-o', 'etime='], { timeoutMs: PS_IDENTITY_TIMEOUT_MS });
|
|
2349
1734
|
if (res.code !== 0)
|
|
2350
|
-
return true;
|
|
1735
|
+
return true;
|
|
2351
1736
|
return etimeIndicatesOurs(res.stdout.trim(), spawnedAt);
|
|
2352
1737
|
}
|
|
2353
|
-
|
|
2354
|
-
* Finalize one `host:`-placed run by healing its host-task sidecar against the
|
|
2355
|
-
* remote `.exit` (lib/hosts/reconcile.ts). Mutates + persists the meta only
|
|
2356
|
-
* when the sidecar reached a terminal state.
|
|
2357
|
-
*/
|
|
2358
|
-
/** Apply a healed host-task's terminal state to the local run record. Shared by the sync and async host reconcilers. */
|
|
2359
|
-
function applyHealedHostRun(meta, healed,
|
|
2360
|
-
// The routine-end emit acquires the event-log file lock. On the daemon
|
|
2361
|
-
// heartbeat tick (finalizeHostRunAsync) that MUST be the async, non-blocking
|
|
2362
|
-
// variant, or the synchronous `withFileLock` (lockSync + Atomics.wait, up to
|
|
2363
|
-
// 30s under contention) freezes the whole event loop — the exact wedge PHNX-3695
|
|
2364
|
-
// targets, on a path guard-no-sync-io does not scan (PHNX-3727). The sync CLI
|
|
2365
|
-
// path (finalizeHostRun) keeps the default synchronous emit.
|
|
2366
|
-
emit = emitRoutineEnd) {
|
|
1738
|
+
function applyHealedHostRun(meta, healed, emit = emitRoutineEnd) {
|
|
2367
1739
|
if (healed.status !== 'completed' && healed.status !== 'failed')
|
|
2368
1740
|
return;
|
|
2369
1741
|
finalizeRunMeta(meta, healed.status, healed.exitCode ?? (healed.status === 'completed' ? 0 : 1), { completedAt: healed.finishedAt ?? undefined });
|
|
@@ -2377,35 +1749,17 @@ function finalizeHostRun(meta) {
|
|
|
2377
1749
|
return;
|
|
2378
1750
|
applyHealedHostRun(meta, reconcileHostTask(task));
|
|
2379
1751
|
}
|
|
2380
|
-
catch {
|
|
1752
|
+
catch { }
|
|
2381
1753
|
}
|
|
2382
|
-
/**
|
|
2383
|
-
* Async twin of {@link finalizeHostRun} for the daemon heartbeat tick
|
|
2384
|
-
* (PHNX-3695). A `host:`-placed run's remote `.exit` is read over ssh; on the
|
|
2385
|
-
* tick that read MUST be async (`reconcileHostTaskAsync` → `sshExecAsync`) or a
|
|
2386
|
-
* single 6s ssh timeout freezes the whole event loop — the exact bug class this
|
|
2387
|
-
* effort targets, worse than the local `ps` probe.
|
|
2388
|
-
*/
|
|
2389
1754
|
async function finalizeHostRunAsync(meta) {
|
|
2390
1755
|
try {
|
|
2391
1756
|
const task = loadHostTask(meta.hostTaskId);
|
|
2392
1757
|
if (!task)
|
|
2393
1758
|
return;
|
|
2394
|
-
// Tick path: emit through the async, non-blocking file lock (PHNX-3727).
|
|
2395
1759
|
applyHealedHostRun(meta, await reconcileHostTaskAsync(task), (m) => { void emitRoutineEndAsync(m); });
|
|
2396
1760
|
}
|
|
2397
|
-
catch {
|
|
1761
|
+
catch { }
|
|
2398
1762
|
}
|
|
2399
|
-
/**
|
|
2400
|
-
* PIDs of the in-flight detached routine children on THIS device — every local
|
|
2401
|
-
* run record still marked `running` whose spawned process is genuinely alive
|
|
2402
|
-
* (`isPidOurs`, so a dead-and-reused pid does not count). These are the `unref`'d
|
|
2403
|
-
* spawns that survive a daemon exit in their own process group (SING-11a): a
|
|
2404
|
-
* takeover must not kill them and `stopDaemon` reports them rather than pretending
|
|
2405
|
-
* the process tree is clean (SING-12). Scoped to `getRunsDir()`, which is under
|
|
2406
|
-
* this state dir's HOME, so a different state dir's children are invisible here.
|
|
2407
|
-
* `host:`-placed runs have no local pid and are excluded.
|
|
2408
|
-
*/
|
|
2409
1763
|
export function listLiveRoutineChildren() {
|
|
2410
1764
|
const runsDir = getRunsDir();
|
|
2411
1765
|
if (!fs.existsSync(runsDir))
|
|
@@ -2438,25 +1792,11 @@ export function listLiveRoutineChildren() {
|
|
|
2438
1792
|
if (isPidOurs(meta.pid, meta.spawnedAt))
|
|
2439
1793
|
pids.push(meta.pid);
|
|
2440
1794
|
}
|
|
2441
|
-
catch {
|
|
1795
|
+
catch { }
|
|
2442
1796
|
}
|
|
2443
1797
|
}
|
|
2444
1798
|
return pids;
|
|
2445
1799
|
}
|
|
2446
|
-
/**
|
|
2447
|
-
* Whether a run record marked `running` is genuinely in flight right now. A
|
|
2448
|
-
* `running` status alone is not enough: `writeActiveClaim` stamps a provisional
|
|
2449
|
-
* claim as `running` with `pid: null` BEFORE the child spawns, and
|
|
2450
|
-
* `monitorRunningJobs()` does not reap a null-pid record (it has no process to
|
|
2451
|
-
* probe, and ages it out only past the configured timeout — up to a week). So a
|
|
2452
|
-
* daemon crash in that spawn window leaves a `running` record for a run that is
|
|
2453
|
-
* not running (RUSH-2640). A caller answering "is one running now?" MUST gate on
|
|
2454
|
-
* this, mirroring `listLiveRoutineChildren`'s local-liveness test:
|
|
2455
|
-
* - a local child is in flight only while its pid is still ours (alive, same
|
|
2456
|
-
* birth time — a dead-and-reused pid does not count);
|
|
2457
|
-
* - a `host:`-placed run has no local pid by design and is in flight until its
|
|
2458
|
-
* remote `.exit` is reconciled (`finalizeHostRun`).
|
|
2459
|
-
*/
|
|
2460
1800
|
export function isRunGenuinelyInFlight(meta) {
|
|
2461
1801
|
if (meta.status !== 'running')
|
|
2462
1802
|
return false;
|
|
@@ -2466,39 +1806,10 @@ export function isRunGenuinelyInFlight(meta) {
|
|
|
2466
1806
|
return false;
|
|
2467
1807
|
return isPidOurs(meta.pid, meta.spawnedAt);
|
|
2468
1808
|
}
|
|
2469
|
-
/**
|
|
2470
|
-
* Reconcile ONE `running` record once its process identity is known (`ours` =
|
|
2471
|
-
* the recorded pid is still genuinely the child we spawned). Shared verbatim by
|
|
2472
|
-
* the synchronous {@link monitorRunningJobs} (off-loop callers) and the async
|
|
2473
|
-
* {@link reapExitedRunningJobs} (daemon heartbeat tick) so there is one copy of
|
|
2474
|
-
* the finalize/timeout/report logic — only the surrounding directory/`ps` IO
|
|
2475
|
-
* differs by sync-vs-async flavor. Caller has already confirmed `meta.status`
|
|
2476
|
-
* is `running`. The finalize/report/archive helpers stay synchronous: they run
|
|
2477
|
-
* ONLY when a run actually transitions (times out or its process exited), a
|
|
2478
|
-
* conditional/rare event, not the every-tick scan the loop-starvation fix
|
|
2479
|
-
* (PHNX-3695) targets. The one exception is the `routine.end` EVENT emit, whose
|
|
2480
|
-
* file lock CAN block for up to 30s under contention even on that rare path — so
|
|
2481
|
-
* the emitter is injected: the off-loop sync caller passes `emitRoutineEnd`
|
|
2482
|
-
* (synchronous, so a short-lived CLI process flushes it before exit), the daemon
|
|
2483
|
-
* tick passes a fire-and-forget `emitRoutineEndAsync` (the long-lived daemon
|
|
2484
|
-
* flushes it, and the shared event loop is never blocked on the lock).
|
|
2485
|
-
*/
|
|
2486
1809
|
function reconcileRunningRecord(meta, jobRunsPath, runDirName, ours, emitEnd) {
|
|
2487
|
-
// Host-placed runs (meta.hostTaskId) are handled by the caller, sync or async
|
|
2488
|
-
// — their remote `.exit` read is ssh I/O that must stay off the daemon tick's
|
|
2489
|
-
// event loop (finalizeHostRunAsync). Records reaching here are local-pid runs.
|
|
2490
1810
|
const runDirPath = path.join(jobRunsPath, runDirName);
|
|
2491
1811
|
const stdoutPath = path.join(runDirPath, 'stdout.log');
|
|
2492
|
-
// Command-mode records carry no agent; there is no stream-json report to
|
|
2493
|
-
// parse or extract. Reap them on pid liveness alone.
|
|
2494
1812
|
const isCommandRun = Boolean(meta.command) || !meta.agent;
|
|
2495
|
-
// Age-out runs FIRST, before the null-pid guard below, so a wedged record
|
|
2496
|
-
// still marked `running` past its deadline is always finalized — a
|
|
2497
|
-
// provisional launcher claim whose daemon crashed before spawning a child
|
|
2498
|
-
// (pid null), or an old record whose recorded pid was reused, would
|
|
2499
|
-
// otherwise linger as `running` forever (RUSH-2640). Only kill a process
|
|
2500
|
-
// group that is genuinely still ours; terminating a reused pid would kill
|
|
2501
|
-
// an unrelated process, and a null pid has nothing to kill.
|
|
2502
1813
|
const wallClockMs = Date.now() - Date.parse(meta.startedAt);
|
|
2503
1814
|
const timeoutMs = meta.timeoutMs ?? MAX_WALL_CLOCK_MS;
|
|
2504
1815
|
if (Number.isFinite(wallClockMs) && wallClockMs > timeoutMs) {
|
|
@@ -2517,11 +1828,6 @@ function reconcileRunningRecord(meta, jobRunsPath, runDirName, ours, emitEnd) {
|
|
|
2517
1828
|
return;
|
|
2518
1829
|
if (!ours) {
|
|
2519
1830
|
if (isCommandRun) {
|
|
2520
|
-
// Command routines normally record their own terminal status via
|
|
2521
|
-
// child.on('exit') (so this record would already be non-'running' and
|
|
2522
|
-
// skipped above). Reaching here means the daemon restarted mid-run and
|
|
2523
|
-
// missed the exit event — recover the true code from the exit-code file
|
|
2524
|
-
// the child wrote; its absence means the child was killed/crashed.
|
|
2525
1831
|
const ec = readCommandExitCode(runDirPath);
|
|
2526
1832
|
finalizeRunMeta(meta, ec === 0 ? 'completed' : 'failed', ec);
|
|
2527
1833
|
}
|
|
@@ -2542,15 +1848,6 @@ function reconcileRunningRecord(meta, jobRunsPath, runDirName, ours, emitEnd) {
|
|
|
2542
1848
|
}
|
|
2543
1849
|
}
|
|
2544
1850
|
}
|
|
2545
|
-
/**
|
|
2546
|
-
* Scan all runs marked "running" and finalize any whose process has exited.
|
|
2547
|
-
*
|
|
2548
|
-
* SYNCHRONOUS — for OFF-loop callers only (the `agents routines list/status`
|
|
2549
|
-
* builders and CLI best-effort orphan reaps), which run in short-lived CLI
|
|
2550
|
-
* processes where a bounded synchronous `ps`/scan cannot starve a served event
|
|
2551
|
-
* loop. The daemon's own heartbeat tick MUST use {@link reapExitedRunningJobs}
|
|
2552
|
-
* instead — a sync scan there would freeze the shared event loop (PHNX-3695).
|
|
2553
|
-
*/
|
|
2554
1851
|
export function monitorRunningJobs() {
|
|
2555
1852
|
const runsDir = getRunsDir();
|
|
2556
1853
|
if (!fs.existsSync(runsDir))
|
|
@@ -2565,8 +1862,6 @@ export function monitorRunningJobs() {
|
|
|
2565
1862
|
.filter((e) => e.isDirectory());
|
|
2566
1863
|
}
|
|
2567
1864
|
catch (err) {
|
|
2568
|
-
// A retention/cleanup pass may remove a job directory after the root
|
|
2569
|
-
// snapshot. The next monitor sweep observes the remaining state.
|
|
2570
1865
|
if (err.code === 'ENOENT')
|
|
2571
1866
|
continue;
|
|
2572
1867
|
throw err;
|
|
@@ -2579,27 +1874,17 @@ export function monitorRunningJobs() {
|
|
|
2579
1874
|
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
|
|
2580
1875
|
if (meta.status !== 'running')
|
|
2581
1876
|
continue;
|
|
2582
|
-
// `host:`-placed run — no local pid; reconcile against the remote `.exit`.
|
|
2583
1877
|
if (meta.hostTaskId) {
|
|
2584
1878
|
finalizeHostRun(meta);
|
|
2585
1879
|
continue;
|
|
2586
1880
|
}
|
|
2587
1881
|
const ours = meta.pid ? isPidOurs(meta.pid, meta.spawnedAt) : false;
|
|
2588
|
-
// Sync emit: an off-loop CLI process must flush the event before it exits.
|
|
2589
1882
|
reconcileRunningRecord(meta, jobRunsPath, runDirEntry.name, ours, emitRoutineEnd);
|
|
2590
1883
|
}
|
|
2591
|
-
catch {
|
|
1884
|
+
catch { }
|
|
2592
1885
|
}
|
|
2593
1886
|
}
|
|
2594
1887
|
}
|
|
2595
|
-
/**
|
|
2596
|
-
* Async, non-blocking twin of {@link monitorRunningJobs} for the daemon's
|
|
2597
|
-
* heartbeat tick (PHNX-3695). Identical reconciliation via
|
|
2598
|
-
* {@link reconcileRunningRecord}, but the directory walk uses `fs/promises` and
|
|
2599
|
-
* the pid-identity probe uses the deadline-bounded {@link isPidOursAsync}, so
|
|
2600
|
-
* the every-tick scan never freezes the shared event loop — the freeze that
|
|
2601
|
-
* left the browser IPC `version` probe unanswered.
|
|
2602
|
-
*/
|
|
2603
1888
|
export async function reapExitedRunningJobs() {
|
|
2604
1889
|
const runsDir = getRunsDir();
|
|
2605
1890
|
let jobDirs;
|
|
@@ -2607,7 +1892,7 @@ export async function reapExitedRunningJobs() {
|
|
|
2607
1892
|
jobDirs = await fsp.readdir(runsDir, { withFileTypes: true });
|
|
2608
1893
|
}
|
|
2609
1894
|
catch {
|
|
2610
|
-
return;
|
|
1895
|
+
return;
|
|
2611
1896
|
}
|
|
2612
1897
|
for (const jobDir of jobDirs) {
|
|
2613
1898
|
if (!jobDir.isDirectory())
|
|
@@ -2618,8 +1903,6 @@ export async function reapExitedRunningJobs() {
|
|
|
2618
1903
|
runDirs = await fsp.readdir(jobRunsPath, { withFileTypes: true });
|
|
2619
1904
|
}
|
|
2620
1905
|
catch {
|
|
2621
|
-
// A retention/cleanup pass may remove a job directory after the root
|
|
2622
|
-
// snapshot. The next sweep observes the remaining state.
|
|
2623
1906
|
continue;
|
|
2624
1907
|
}
|
|
2625
1908
|
for (const runDirEntry of runDirs) {
|
|
@@ -2630,18 +1913,14 @@ export async function reapExitedRunningJobs() {
|
|
|
2630
1913
|
const meta = JSON.parse(raw);
|
|
2631
1914
|
if (meta.status !== 'running')
|
|
2632
1915
|
continue;
|
|
2633
|
-
// `host:`-placed run — read its remote `.exit` over ssh ASYNC so a slow
|
|
2634
|
-
// host never freezes the tick's event loop (PHNX-3695).
|
|
2635
1916
|
if (meta.hostTaskId) {
|
|
2636
1917
|
await finalizeHostRunAsync(meta);
|
|
2637
1918
|
continue;
|
|
2638
1919
|
}
|
|
2639
1920
|
const ours = meta.pid ? await isPidOursAsync(meta.pid, meta.spawnedAt) : false;
|
|
2640
|
-
// Fire-and-forget async emit: the event-log lock must never block the
|
|
2641
|
-
// daemon tick's shared event loop; the long-lived daemon still flushes it.
|
|
2642
1921
|
reconcileRunningRecord(meta, jobRunsPath, runDirEntry.name, ours, (m) => { void emitRoutineEndAsync(m); });
|
|
2643
1922
|
}
|
|
2644
|
-
catch {
|
|
1923
|
+
catch { }
|
|
2645
1924
|
}
|
|
2646
1925
|
}
|
|
2647
1926
|
}
|