@with-logic/elwood 0.2.1 → 0.2.2
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 +565 -1
- package/CONTRIBUTING.md +3 -0
- package/README.md +4 -2
- package/dist/bridge/socket-release.d.ts +15 -0
- package/dist/bridge/socket-release.d.ts.map +1 -0
- package/dist/bridge/socket-release.js +22 -0
- package/dist/bridge/socket-release.js.map +1 -0
- package/dist/claude/composer/border.d.ts +12 -0
- package/dist/claude/composer/border.d.ts.map +1 -0
- package/dist/claude/composer/border.js +12 -0
- package/dist/claude/composer/border.js.map +1 -0
- package/dist/claude/composer/empty-input.d.ts +15 -0
- package/dist/claude/composer/empty-input.d.ts.map +1 -1
- package/dist/claude/composer/empty-input.js +30 -11
- package/dist/claude/composer/empty-input.js.map +1 -1
- package/dist/claude/composer/footer.d.ts +26 -2
- package/dist/claude/composer/footer.d.ts.map +1 -1
- package/dist/claude/composer/footer.js +29 -2
- package/dist/claude/composer/footer.js.map +1 -1
- package/dist/claude/composer/idle.d.ts +14 -0
- package/dist/claude/composer/idle.d.ts.map +1 -0
- package/dist/claude/composer/idle.js +17 -0
- package/dist/claude/composer/idle.js.map +1 -0
- package/dist/claude/composer/last.d.ts +2 -0
- package/dist/claude/composer/last.d.ts.map +1 -0
- package/dist/claude/composer/last.js +15 -0
- package/dist/claude/composer/last.js.map +1 -0
- package/dist/claude/composer/staged-input.d.ts.map +1 -1
- package/dist/claude/composer/staged-input.js +2 -1
- package/dist/claude/composer/staged-input.js.map +1 -1
- package/dist/claude/hooks/stop-failure.d.ts +15 -2
- package/dist/claude/hooks/stop-failure.d.ts.map +1 -1
- package/dist/claude/hooks/stop-failure.js +32 -9
- package/dist/claude/hooks/stop-failure.js.map +1 -1
- package/dist/claude/login/stages.d.ts.map +1 -1
- package/dist/claude/login/stages.js +2 -2
- package/dist/claude/login/stages.js.map +1 -1
- package/dist/claude/model-picker.d.ts +1 -1
- package/dist/claude/model-picker.d.ts.map +1 -1
- package/dist/claude/model-picker.js +27 -10
- package/dist/claude/model-picker.js.map +1 -1
- package/dist/claude/preflight.d.ts +1 -1
- package/dist/claude/preflight.d.ts.map +1 -1
- package/dist/claude/preflight.js +18 -12
- package/dist/claude/preflight.js.map +1 -1
- package/dist/claude/questions/navigation.d.ts.map +1 -1
- package/dist/claude/questions/navigation.js +1 -2
- package/dist/claude/questions/navigation.js.map +1 -1
- package/dist/claude/questions/screen.d.ts.map +1 -1
- package/dist/claude/questions/screen.js +10 -2
- package/dist/claude/questions/screen.js.map +1 -1
- package/dist/claude/screen-table.d.ts +8 -5
- package/dist/claude/screen-table.d.ts.map +1 -1
- package/dist/claude/screen-table.js +20 -12
- package/dist/claude/screen-table.js.map +1 -1
- package/dist/claude/session/bridge.d.ts +2 -1
- package/dist/claude/session/bridge.d.ts.map +1 -1
- package/dist/claude/session/bridge.js +3 -1
- package/dist/claude/session/bridge.js.map +1 -1
- package/dist/claude/session/build.d.ts.map +1 -1
- package/dist/claude/session/build.js +13 -11
- package/dist/claude/session/build.js.map +1 -1
- package/dist/claude/session/cleanup.d.ts +18 -0
- package/dist/claude/session/cleanup.d.ts.map +1 -0
- package/dist/claude/session/cleanup.js +10 -0
- package/dist/claude/session/cleanup.js.map +1 -0
- package/dist/claude/session/index.d.ts.map +1 -1
- package/dist/claude/session/index.js +27 -13
- package/dist/claude/session/index.js.map +1 -1
- package/dist/claude/session/instance.d.ts +7 -8
- package/dist/claude/session/instance.d.ts.map +1 -1
- package/dist/claude/session/instance.js +9 -13
- package/dist/claude/session/instance.js.map +1 -1
- package/dist/claude/session/resume.d.ts.map +1 -1
- package/dist/claude/session/resume.js +14 -5
- package/dist/claude/session/resume.js.map +1 -1
- package/dist/claude/session/transcript.js +2 -2
- package/dist/claude/session/transcript.js.map +1 -1
- package/dist/claude/simple.d.ts +1 -1
- package/dist/claude/simple.d.ts.map +1 -1
- package/dist/claude/simple.js +3 -3
- package/dist/claude/simple.js.map +1 -1
- package/dist/claude/startup-prompts.d.ts +2 -0
- package/dist/claude/startup-prompts.d.ts.map +1 -1
- package/dist/claude/startup-prompts.js +5 -1
- package/dist/claude/startup-prompts.js.map +1 -1
- package/dist/claude/transcript/cursor-io.d.ts +1 -1
- package/dist/claude/transcript/cursor-io.d.ts.map +1 -1
- package/dist/claude/transcript/cursor-io.js +1 -1
- package/dist/claude/transcript/cursor-io.js.map +1 -1
- package/dist/claude/transcript/cursor.d.ts +5 -3
- package/dist/claude/transcript/cursor.d.ts.map +1 -1
- package/dist/claude/transcript/cursor.js +18 -8
- package/dist/claude/transcript/cursor.js.map +1 -1
- package/dist/claude/transcript/drain-context.d.ts +4 -3
- package/dist/claude/transcript/drain-context.d.ts.map +1 -1
- package/dist/claude/transcript/drain-context.js.map +1 -1
- package/dist/claude/transcript/emit.d.ts +2 -1
- package/dist/claude/transcript/emit.d.ts.map +1 -1
- package/dist/claude/transcript/emit.js +1 -0
- package/dist/claude/transcript/emit.js.map +1 -1
- package/dist/claude/transcript/index.d.ts.map +1 -1
- package/dist/claude/transcript/index.js +2 -2
- package/dist/claude/transcript/index.js.map +1 -1
- package/dist/claude/transcript/warnings.d.ts +2 -1
- package/dist/claude/transcript/warnings.d.ts.map +1 -1
- package/dist/claude/transcript/warnings.js +3 -2
- package/dist/claude/transcript/warnings.js.map +1 -1
- package/dist/cli/config/effective.d.ts +2 -2
- package/dist/cli/config/effective.d.ts.map +1 -1
- package/dist/cli/config/effective.js +0 -2
- package/dist/cli/config/effective.js.map +1 -1
- package/dist/cli/interactive/spawn.d.ts +0 -2
- package/dist/cli/interactive/spawn.d.ts.map +1 -1
- package/dist/cli/interactive/spawn.js +27 -24
- package/dist/cli/interactive/spawn.js.map +1 -1
- package/dist/cli/lifecycle/index.d.ts.map +1 -1
- package/dist/cli/lifecycle/index.js +5 -3
- package/dist/cli/lifecycle/index.js.map +1 -1
- package/dist/cli/main-failure.d.ts.map +1 -1
- package/dist/cli/main-failure.js +5 -2
- package/dist/cli/main-failure.js.map +1 -1
- package/dist/cli/models/combined.d.ts.map +1 -1
- package/dist/cli/models/combined.js +3 -2
- package/dist/cli/models/combined.js.map +1 -1
- package/dist/cli/models/render.d.ts.map +1 -1
- package/dist/cli/models/render.js +2 -1
- package/dist/cli/models/render.js.map +1 -1
- package/dist/cli/output/cleanup-error.d.ts +22 -0
- package/dist/cli/output/cleanup-error.d.ts.map +1 -0
- package/dist/cli/output/cleanup-error.js +67 -0
- package/dist/cli/output/cleanup-error.js.map +1 -0
- package/dist/cli/output/types.d.ts +6 -2
- package/dist/cli/output/types.d.ts.map +1 -1
- package/dist/cli/request/agent-detect.d.ts +6 -2
- package/dist/cli/request/agent-detect.d.ts.map +1 -1
- package/dist/cli/request/agent-detect.js +14 -6
- package/dist/cli/request/agent-detect.js.map +1 -1
- package/dist/cli/request/finalize.d.ts +1 -1
- package/dist/cli/request/finalize.d.ts.map +1 -1
- package/dist/cli/request/finalize.js +4 -25
- package/dist/cli/request/finalize.js.map +1 -1
- package/dist/cli/request/index.d.ts.map +1 -1
- package/dist/cli/request/index.js +11 -5
- package/dist/cli/request/index.js.map +1 -1
- package/dist/cli/request/path-replacement.d.ts +27 -0
- package/dist/cli/request/path-replacement.d.ts.map +1 -0
- package/dist/cli/request/path-replacement.js +79 -0
- package/dist/cli/request/path-replacement.js.map +1 -0
- package/dist/cli/request/workspace.d.ts +8 -0
- package/dist/cli/request/workspace.d.ts.map +1 -0
- package/dist/cli/request/workspace.js +50 -0
- package/dist/cli/request/workspace.js.map +1 -0
- package/dist/cli/run/output.d.ts.map +1 -1
- package/dist/cli/run/output.js +2 -1
- package/dist/cli/run/output.js.map +1 -1
- package/dist/cli/run/subscribe.d.ts.map +1 -1
- package/dist/cli/run/subscribe.js +1 -1
- package/dist/cli/run/subscribe.js.map +1 -1
- package/dist/cli/session/index.d.ts +4 -4
- package/dist/cli/session/index.d.ts.map +1 -1
- package/dist/cli/session/index.js +5 -5
- package/dist/cli/session/index.js.map +1 -1
- package/dist/cli/session/launch.d.ts +2 -2
- package/dist/cli/session/launch.d.ts.map +1 -1
- package/dist/cli/session/launch.js +12 -3
- package/dist/cli/session/launch.js.map +1 -1
- package/dist/cli/session/turn-readers.d.ts +14 -0
- package/dist/cli/session/turn-readers.d.ts.map +1 -0
- package/dist/cli/session/turn-readers.js +13 -0
- package/dist/cli/session/turn-readers.js.map +1 -0
- package/dist/codex/config/default-model.d.ts +24 -0
- package/dist/codex/config/default-model.d.ts.map +1 -0
- package/dist/codex/config/default-model.js +133 -0
- package/dist/codex/config/default-model.js.map +1 -0
- package/dist/codex/config/home.d.ts +35 -0
- package/dist/codex/config/home.d.ts.map +1 -0
- package/dist/codex/config/home.js +122 -0
- package/dist/codex/config/home.js.map +1 -0
- package/dist/codex/config/lock.d.ts +17 -11
- package/dist/codex/config/lock.d.ts.map +1 -1
- package/dist/codex/config/lock.js +102 -11
- package/dist/codex/config/lock.js.map +1 -1
- package/dist/codex/config/read.d.ts +16 -0
- package/dist/codex/config/read.d.ts.map +1 -0
- package/dist/codex/config/read.js +75 -0
- package/dist/codex/config/read.js.map +1 -0
- package/dist/codex/config/restore.d.ts +17 -7
- package/dist/codex/config/restore.d.ts.map +1 -1
- package/dist/codex/config/restore.js +33 -20
- package/dist/codex/config/restore.js.map +1 -1
- package/dist/codex/config/transaction.d.ts +6 -4
- package/dist/codex/config/transaction.d.ts.map +1 -1
- package/dist/codex/config/transaction.js +4 -3
- package/dist/codex/config/transaction.js.map +1 -1
- package/dist/codex/images/clipboard-copies.d.ts +39 -0
- package/dist/codex/images/clipboard-copies.d.ts.map +1 -0
- package/dist/codex/images/clipboard-copies.js +91 -0
- package/dist/codex/images/clipboard-copies.js.map +1 -0
- package/dist/codex/model-picker.d.ts +1 -1
- package/dist/codex/model-picker.d.ts.map +1 -1
- package/dist/codex/model-picker.js +16 -6
- package/dist/codex/model-picker.js.map +1 -1
- package/dist/codex/preflight.d.ts +2 -2
- package/dist/codex/preflight.d.ts.map +1 -1
- package/dist/codex/preflight.js +28 -21
- package/dist/codex/preflight.js.map +1 -1
- package/dist/codex/pty.d.ts +25 -3
- package/dist/codex/pty.d.ts.map +1 -1
- package/dist/codex/pty.js +53 -7
- package/dist/codex/pty.js.map +1 -1
- package/dist/codex/questions/candidates.d.ts.map +1 -1
- package/dist/codex/questions/candidates.js +4 -5
- package/dist/codex/questions/candidates.js.map +1 -1
- package/dist/codex/questions/driver.js +2 -2
- package/dist/codex/questions/driver.js.map +1 -1
- package/dist/codex/questions/records.d.ts +1 -1
- package/dist/codex/questions/records.d.ts.map +1 -1
- package/dist/codex/questions/records.js +1 -3
- package/dist/codex/questions/records.js.map +1 -1
- package/dist/codex/screen/clearance.d.ts +6 -0
- package/dist/codex/screen/clearance.d.ts.map +1 -1
- package/dist/codex/screen/clearance.js +10 -0
- package/dist/codex/screen/clearance.js.map +1 -1
- package/dist/codex/screen-table.d.ts.map +1 -1
- package/dist/codex/screen-table.js +6 -2
- package/dist/codex/screen-table.js.map +1 -1
- package/dist/codex/session/bridge.d.ts +1 -0
- package/dist/codex/session/bridge.d.ts.map +1 -1
- package/dist/codex/session/bridge.js +3 -1
- package/dist/codex/session/bridge.js.map +1 -1
- package/dist/codex/session/build.d.ts.map +1 -1
- package/dist/codex/session/build.js +14 -12
- package/dist/codex/session/build.js.map +1 -1
- package/dist/codex/session/cleanup.d.ts +2 -2
- package/dist/codex/session/cleanup.d.ts.map +1 -1
- package/dist/codex/session/cleanup.js +8 -11
- package/dist/codex/session/cleanup.js.map +1 -1
- package/dist/codex/session/config-switch.d.ts +20 -0
- package/dist/codex/session/config-switch.d.ts.map +1 -0
- package/dist/codex/session/config-switch.js +42 -0
- package/dist/codex/session/config-switch.js.map +1 -0
- package/dist/codex/session/hooks.d.ts.map +1 -1
- package/dist/codex/session/hooks.js +7 -0
- package/dist/codex/session/hooks.js.map +1 -1
- package/dist/codex/session/index.d.ts.map +1 -1
- package/dist/codex/session/index.js +34 -16
- package/dist/codex/session/index.js.map +1 -1
- package/dist/codex/session/instance.d.ts +10 -12
- package/dist/codex/session/instance.d.ts.map +1 -1
- package/dist/codex/session/instance.js +42 -37
- package/dist/codex/session/instance.js.map +1 -1
- package/dist/codex/session/readiness.d.ts +11 -0
- package/dist/codex/session/readiness.d.ts.map +1 -0
- package/dist/codex/session/readiness.js +22 -0
- package/dist/codex/session/readiness.js.map +1 -0
- package/dist/codex/session/resume.d.ts.map +1 -1
- package/dist/codex/session/resume.js +9 -4
- package/dist/codex/session/resume.js.map +1 -1
- package/dist/codex/session/transcript.d.ts.map +1 -1
- package/dist/codex/session/transcript.js +12 -1
- package/dist/codex/session/transcript.js.map +1 -1
- package/dist/codex/session/turn-commit.d.ts +58 -0
- package/dist/codex/session/turn-commit.d.ts.map +1 -0
- package/dist/codex/session/turn-commit.js +97 -0
- package/dist/codex/session/turn-commit.js.map +1 -0
- package/dist/codex/session/warnings.d.ts +13 -6
- package/dist/codex/session/warnings.d.ts.map +1 -1
- package/dist/codex/session/warnings.js +36 -9
- package/dist/codex/session/warnings.js.map +1 -1
- package/dist/codex/startup-prompts.d.ts +3 -0
- package/dist/codex/startup-prompts.d.ts.map +1 -1
- package/dist/codex/startup-prompts.js +20 -13
- package/dist/codex/startup-prompts.js.map +1 -1
- package/dist/codex/startup-warnings.d.ts +2 -0
- package/dist/codex/startup-warnings.d.ts.map +1 -1
- package/dist/codex/startup-warnings.js +6 -0
- package/dist/codex/startup-warnings.js.map +1 -1
- package/dist/codex/transcript/payload.d.ts +8 -0
- package/dist/codex/transcript/payload.d.ts.map +1 -0
- package/dist/codex/transcript/payload.js +11 -0
- package/dist/codex/transcript/payload.js.map +1 -0
- package/dist/codex/transcript/rejection.d.ts +15 -0
- package/dist/codex/transcript/rejection.d.ts.map +1 -0
- package/dist/codex/transcript/rejection.js +44 -0
- package/dist/codex/transcript/rejection.js.map +1 -0
- package/dist/codex/transcript/turn-end.d.ts +8 -0
- package/dist/codex/transcript/turn-end.d.ts.map +1 -0
- package/dist/codex/transcript/turn-end.js +17 -0
- package/dist/codex/transcript/turn-end.js.map +1 -0
- package/dist/codex/transcript/watcher.d.ts +5 -2
- package/dist/codex/transcript/watcher.d.ts.map +1 -1
- package/dist/codex/transcript/watcher.js +11 -6
- package/dist/codex/transcript/watcher.js.map +1 -1
- package/dist/codex/trust-retry.d.ts +12 -0
- package/dist/codex/trust-retry.d.ts.map +1 -0
- package/dist/codex/trust-retry.js +12 -0
- package/dist/codex/trust-retry.js.map +1 -0
- package/dist/codex/update/skip-attempt.d.ts +2 -0
- package/dist/codex/update/skip-attempt.d.ts.map +1 -1
- package/dist/codex/update/skip-attempt.js +4 -0
- package/dist/codex/update/skip-attempt.js.map +1 -1
- package/dist/codex/update/tracker.d.ts +2 -0
- package/dist/codex/update/tracker.d.ts.map +1 -1
- package/dist/codex/update/tracker.js +4 -0
- package/dist/codex/update/tracker.js.map +1 -1
- package/dist/core/delay.d.ts +3 -2
- package/dist/core/delay.d.ts.map +1 -1
- package/dist/core/delay.js +3 -2
- package/dist/core/delay.js.map +1 -1
- package/dist/core/errors.d.ts +33 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +51 -7
- package/dist/core/errors.js.map +1 -1
- package/dist/core/images/materialize.d.ts +13 -4
- package/dist/core/images/materialize.d.ts.map +1 -1
- package/dist/core/images/materialize.js +48 -11
- package/dist/core/images/materialize.js.map +1 -1
- package/dist/core/input/abort.d.ts +15 -0
- package/dist/core/input/abort.d.ts.map +1 -1
- package/dist/core/input/abort.js +18 -2
- package/dist/core/input/abort.js.map +1 -1
- package/dist/core/input/constants.d.ts +4 -1
- package/dist/core/input/constants.d.ts.map +1 -1
- package/dist/core/input/constants.js +4 -1
- package/dist/core/input/constants.js.map +1 -1
- package/dist/core/input/index.d.ts +1 -1
- package/dist/core/input/index.d.ts.map +1 -1
- package/dist/core/input/index.js +1 -1
- package/dist/core/input/index.js.map +1 -1
- package/dist/core/models/clearance.d.ts +38 -0
- package/dist/core/models/clearance.d.ts.map +1 -0
- package/dist/core/models/clearance.js +38 -0
- package/dist/core/models/clearance.js.map +1 -0
- package/dist/core/models/close-wait.d.ts +17 -0
- package/dist/core/models/close-wait.d.ts.map +1 -0
- package/dist/core/models/close-wait.js +44 -0
- package/dist/core/models/close-wait.js.map +1 -0
- package/dist/core/models/dialog-region.d.ts +18 -3
- package/dist/core/models/dialog-region.d.ts.map +1 -1
- package/dist/core/models/dialog-region.js +29 -40
- package/dist/core/models/dialog-region.js.map +1 -1
- package/dist/core/models/input.d.ts +10 -1
- package/dist/core/models/input.d.ts.map +1 -1
- package/dist/core/models/input.js +15 -2
- package/dist/core/models/input.js.map +1 -1
- package/dist/core/models/intervention.d.ts +2 -2
- package/dist/core/models/intervention.d.ts.map +1 -1
- package/dist/core/models/intervention.js +6 -3
- package/dist/core/models/intervention.js.map +1 -1
- package/dist/core/models/own-picker.d.ts +21 -0
- package/dist/core/models/own-picker.d.ts.map +1 -0
- package/dist/core/models/own-picker.js +21 -0
- package/dist/core/models/own-picker.js.map +1 -0
- package/dist/core/models/picker.d.ts +34 -4
- package/dist/core/models/picker.d.ts.map +1 -1
- package/dist/core/models/picker.js +50 -44
- package/dist/core/models/picker.js.map +1 -1
- package/dist/core/models/row-block.d.ts +66 -0
- package/dist/core/models/row-block.d.ts.map +1 -0
- package/dist/core/models/row-block.js +87 -0
- package/dist/core/models/row-block.js.map +1 -0
- package/dist/core/models/rows.d.ts +32 -3
- package/dist/core/models/rows.d.ts.map +1 -1
- package/dist/core/models/rows.js +48 -20
- package/dist/core/models/rows.js.map +1 -1
- package/dist/core/models/tui-screen.d.ts +6 -1
- package/dist/core/models/tui-screen.d.ts.map +1 -1
- package/dist/core/models/tui-screen.js +25 -10
- package/dist/core/models/tui-screen.js.map +1 -1
- package/dist/core/models/window.d.ts +49 -0
- package/dist/core/models/window.d.ts.map +1 -0
- package/dist/core/models/window.js +105 -0
- package/dist/core/models/window.js.map +1 -0
- package/dist/core/path-trust.d.ts +11 -0
- package/dist/core/path-trust.d.ts.map +1 -0
- package/dist/core/path-trust.js +21 -0
- package/dist/core/path-trust.js.map +1 -0
- package/dist/core/screen-facts.d.ts +3 -1
- package/dist/core/screen-facts.d.ts.map +1 -1
- package/dist/core/screen-facts.js +1 -0
- package/dist/core/screen-facts.js.map +1 -1
- package/dist/core/simple/boundary-signal.d.ts +41 -6
- package/dist/core/simple/boundary-signal.d.ts.map +1 -1
- package/dist/core/simple/boundary-signal.js +43 -3
- package/dist/core/simple/boundary-signal.js.map +1 -1
- package/dist/core/simple/close.d.ts +2 -1
- package/dist/core/simple/close.d.ts.map +1 -1
- package/dist/core/simple/close.js +10 -2
- package/dist/core/simple/close.js.map +1 -1
- package/dist/core/simple/turn-boundary.d.ts +2 -0
- package/dist/core/simple/turn-boundary.d.ts.map +1 -1
- package/dist/core/simple/turn-boundary.js +1 -1
- package/dist/core/simple/turn-boundary.js.map +1 -1
- package/dist/core/simple/turn-types.d.ts +9 -3
- package/dist/core/simple/turn-types.d.ts.map +1 -1
- package/dist/core/simple/turn-types.js +10 -2
- package/dist/core/simple/turn-types.js.map +1 -1
- package/dist/core/simple/turn.d.ts +2 -0
- package/dist/core/simple/turn.d.ts.map +1 -1
- package/dist/core/simple/turn.js +11 -5
- package/dist/core/simple/turn.js.map +1 -1
- package/dist/core/terminal-options.d.ts +17 -1
- package/dist/core/terminal-options.d.ts.map +1 -1
- package/dist/core/terminal-options.js +20 -8
- package/dist/core/terminal-options.js.map +1 -1
- package/dist/core/transcript/cursor-io.d.ts +8 -0
- package/dist/core/transcript/cursor-io.d.ts.map +1 -1
- package/dist/core/transcript/cursor-io.js +11 -5
- package/dist/core/transcript/cursor-io.js.map +1 -1
- package/dist/core/transcript/cursor.d.ts +28 -4
- package/dist/core/transcript/cursor.d.ts.map +1 -1
- package/dist/core/transcript/cursor.js +53 -7
- package/dist/core/transcript/cursor.js.map +1 -1
- package/dist/core/transcript/drain.d.ts +43 -0
- package/dist/core/transcript/drain.d.ts.map +1 -0
- package/dist/core/transcript/drain.js +67 -0
- package/dist/core/transcript/drain.js.map +1 -0
- package/dist/core/trust/abortable.d.ts +12 -0
- package/dist/core/trust/abortable.d.ts.map +1 -0
- package/dist/core/trust/abortable.js +48 -0
- package/dist/core/trust/abortable.js.map +1 -0
- package/dist/core/trust/allowlist.d.ts +2 -0
- package/dist/core/trust/allowlist.d.ts.map +1 -1
- package/dist/core/trust/allowlist.js +4 -1
- package/dist/core/trust/allowlist.js.map +1 -1
- package/dist/core/trust/blocking.d.ts +11 -0
- package/dist/core/trust/blocking.d.ts.map +1 -1
- package/dist/core/trust/blocking.js +5 -4
- package/dist/core/trust/blocking.js.map +1 -1
- package/dist/core/trust/copy.d.ts.map +1 -1
- package/dist/core/trust/copy.js +7 -1
- package/dist/core/trust/copy.js.map +1 -1
- package/dist/core/trust/deadline.d.ts +24 -0
- package/dist/core/trust/deadline.d.ts.map +1 -0
- package/dist/core/trust/deadline.js +56 -0
- package/dist/core/trust/deadline.js.map +1 -0
- package/dist/core/trust/dialog.d.ts +11 -2
- package/dist/core/trust/dialog.d.ts.map +1 -1
- package/dist/core/trust/dialog.js +12 -3
- package/dist/core/trust/dialog.js.map +1 -1
- package/dist/core/trust/options.d.ts +5 -1
- package/dist/core/trust/options.d.ts.map +1 -1
- package/dist/core/trust/options.js +8 -2
- package/dist/core/trust/options.js.map +1 -1
- package/dist/core/trust/prompts.d.ts +3 -0
- package/dist/core/trust/prompts.d.ts.map +1 -1
- package/dist/core/trust/prompts.js +2 -1
- package/dist/core/trust/prompts.js.map +1 -1
- package/dist/core/trust/responder.d.ts +10 -5
- package/dist/core/trust/responder.d.ts.map +1 -1
- package/dist/core/trust/responder.js +37 -33
- package/dist/core/trust/responder.js.map +1 -1
- package/dist/core/trust/step.d.ts +67 -0
- package/dist/core/trust/step.d.ts.map +1 -0
- package/dist/core/trust/step.js +45 -0
- package/dist/core/trust/step.js.map +1 -0
- package/dist/core/trust/types.d.ts +21 -1
- package/dist/core/trust/types.d.ts.map +1 -1
- package/dist/core/trust/types.js +25 -1
- package/dist/core/trust/types.js.map +1 -1
- package/dist/core/trust/view.d.ts +2 -0
- package/dist/core/trust/view.d.ts.map +1 -1
- package/dist/core/trust/view.js +3 -0
- package/dist/core/trust/view.js.map +1 -1
- package/dist/core/trust/write.d.ts +31 -6
- package/dist/core/trust/write.d.ts.map +1 -1
- package/dist/core/trust/write.js +95 -80
- package/dist/core/trust/write.js.map +1 -1
- package/dist/core/turn-state.d.ts +18 -4
- package/dist/core/turn-state.d.ts.map +1 -1
- package/dist/core/turn-state.js +47 -25
- package/dist/core/turn-state.js.map +1 -1
- package/dist/core/warnings/images.d.ts +22 -0
- package/dist/core/warnings/images.d.ts.map +1 -0
- package/dist/core/warnings/images.js +3 -0
- package/dist/core/warnings/images.js.map +1 -0
- package/dist/core/warnings/index.d.ts +3 -2
- package/dist/core/warnings/index.d.ts.map +1 -1
- package/dist/core/warnings/lifecycle.d.ts +35 -4
- package/dist/core/warnings/lifecycle.d.ts.map +1 -1
- package/dist/core/warnings/lifecycle.js +1 -1
- package/dist/core/warnings/update.d.ts +8 -4
- package/dist/core/warnings/update.d.ts.map +1 -1
- package/dist/core/warnings/update.js +21 -6
- package/dist/core/warnings/update.js.map +1 -1
- package/dist/pty/exit-latch.d.ts +28 -0
- package/dist/pty/exit-latch.d.ts.map +1 -0
- package/dist/pty/exit-latch.js +50 -0
- package/dist/pty/exit-latch.js.map +1 -0
- package/dist/runtime/exit-status.d.ts +7 -0
- package/dist/runtime/exit-status.d.ts.map +1 -0
- package/dist/runtime/exit-status.js +13 -0
- package/dist/runtime/exit-status.js.map +1 -0
- package/dist/runtime/home-guard/index.d.ts +45 -0
- package/dist/runtime/home-guard/index.d.ts.map +1 -0
- package/dist/runtime/home-guard/index.js +69 -0
- package/dist/runtime/home-guard/index.js.map +1 -0
- package/dist/runtime/loop-restore.d.ts +9 -9
- package/dist/runtime/loop-restore.d.ts.map +1 -1
- package/dist/runtime/loop-restore.js +10 -10
- package/dist/runtime/loop-restore.js.map +1 -1
- package/dist/runtime/probe/capped-buffer.d.ts +16 -0
- package/dist/runtime/probe/capped-buffer.d.ts.map +1 -0
- package/dist/runtime/probe/capped-buffer.js +38 -0
- package/dist/runtime/probe/capped-buffer.js.map +1 -0
- package/dist/runtime/probe/capture.d.ts +55 -0
- package/dist/runtime/probe/capture.d.ts.map +1 -0
- package/dist/runtime/probe/capture.js +71 -0
- package/dist/runtime/probe/capture.js.map +1 -0
- package/dist/runtime/{probe-cleanup.d.ts → probe/cleanup.d.ts} +2 -2
- package/dist/runtime/probe/cleanup.d.ts.map +1 -0
- package/dist/runtime/{probe-cleanup.js → probe/cleanup.js} +3 -3
- package/dist/runtime/probe/cleanup.js.map +1 -0
- package/dist/runtime/probe/directory-key.d.ts +26 -0
- package/dist/runtime/probe/directory-key.d.ts.map +1 -0
- package/dist/runtime/probe/directory-key.js +46 -0
- package/dist/runtime/probe/directory-key.js.map +1 -0
- package/dist/runtime/probe/index.d.ts +25 -0
- package/dist/runtime/probe/index.d.ts.map +1 -0
- package/dist/runtime/probe/index.js +153 -0
- package/dist/runtime/probe/index.js.map +1 -0
- package/dist/runtime/probe/lookup.d.ts +12 -0
- package/dist/runtime/probe/lookup.d.ts.map +1 -0
- package/dist/runtime/probe/lookup.js +29 -0
- package/dist/runtime/probe/lookup.js.map +1 -0
- package/dist/runtime/probe/named-pipes.d.ts +35 -0
- package/dist/runtime/probe/named-pipes.d.ts.map +1 -0
- package/dist/runtime/probe/named-pipes.js +167 -0
- package/dist/runtime/probe/named-pipes.js.map +1 -0
- package/dist/runtime/probe/private-directory.d.ts +14 -0
- package/dist/runtime/probe/private-directory.d.ts.map +1 -0
- package/dist/runtime/probe/private-directory.js +50 -0
- package/dist/runtime/probe/private-directory.js.map +1 -0
- package/dist/runtime/probe/results.d.ts +14 -0
- package/dist/runtime/probe/results.d.ts.map +1 -0
- package/dist/runtime/probe/results.js +38 -0
- package/dist/runtime/probe/results.js.map +1 -0
- package/dist/runtime/probe/slots.d.ts +17 -0
- package/dist/runtime/probe/slots.d.ts.map +1 -0
- package/dist/runtime/probe/slots.js +35 -0
- package/dist/runtime/probe/slots.js.map +1 -0
- package/dist/runtime/probe/start.d.ts +64 -0
- package/dist/runtime/probe/start.d.ts.map +1 -0
- package/dist/runtime/probe/start.js +80 -0
- package/dist/runtime/probe/start.js.map +1 -0
- package/dist/runtime/probe-cache.d.ts +19 -0
- package/dist/runtime/probe-cache.d.ts.map +1 -0
- package/dist/runtime/probe-cache.js +56 -0
- package/dist/runtime/probe-cache.js.map +1 -0
- package/dist/runtime/readiness/initial-ready.d.ts +31 -5
- package/dist/runtime/readiness/initial-ready.d.ts.map +1 -1
- package/dist/runtime/readiness/initial-ready.js +64 -18
- package/dist/runtime/readiness/initial-ready.js.map +1 -1
- package/dist/runtime/seams.d.ts +14 -2
- package/dist/runtime/seams.d.ts.map +1 -1
- package/dist/runtime/seams.js +2 -2
- package/dist/runtime/seams.js.map +1 -1
- package/dist/runtime/session/base.d.ts.map +1 -1
- package/dist/runtime/session/base.js +6 -5
- package/dist/runtime/session/base.js.map +1 -1
- package/dist/runtime/session/commands.d.ts +5 -3
- package/dist/runtime/session/commands.d.ts.map +1 -1
- package/dist/runtime/session/commands.js +5 -2
- package/dist/runtime/session/commands.js.map +1 -1
- package/dist/runtime/session/frames.d.ts +12 -2
- package/dist/runtime/session/frames.d.ts.map +1 -1
- package/dist/runtime/session/frames.js +10 -3
- package/dist/runtime/session/frames.js.map +1 -1
- package/dist/runtime/session/image-attach.js +7 -2
- package/dist/runtime/session/image-attach.js.map +1 -1
- package/dist/runtime/session/launch-directory.d.ts +33 -0
- package/dist/runtime/session/launch-directory.d.ts.map +1 -0
- package/dist/runtime/session/launch-directory.js +84 -0
- package/dist/runtime/session/launch-directory.js.map +1 -0
- package/dist/runtime/session/lifecycle.d.ts +3 -3
- package/dist/runtime/session/lifecycle.d.ts.map +1 -1
- package/dist/runtime/session/lifecycle.js +1 -5
- package/dist/runtime/session/lifecycle.js.map +1 -1
- package/dist/runtime/session/loops.d.ts +1 -1
- package/dist/runtime/session/loops.d.ts.map +1 -1
- package/dist/runtime/session/loops.js +6 -3
- package/dist/runtime/session/loops.js.map +1 -1
- package/dist/runtime/session/picker-cleanup.d.ts +6 -21
- package/dist/runtime/session/picker-cleanup.d.ts.map +1 -1
- package/dist/runtime/session/picker-cleanup.js +19 -31
- package/dist/runtime/session/picker-cleanup.js.map +1 -1
- package/dist/runtime/session/picker-hold.d.ts +24 -0
- package/dist/runtime/session/picker-hold.d.ts.map +1 -0
- package/dist/runtime/session/picker-hold.js +42 -0
- package/dist/runtime/session/picker-hold.js.map +1 -0
- package/dist/runtime/session/picker.d.ts +13 -11
- package/dist/runtime/session/picker.d.ts.map +1 -1
- package/dist/runtime/session/picker.js +46 -24
- package/dist/runtime/session/picker.js.map +1 -1
- package/dist/runtime/session/prepare-state.d.ts +6 -0
- package/dist/runtime/session/prepare-state.d.ts.map +1 -0
- package/dist/runtime/session/prepare-state.js +14 -0
- package/dist/runtime/session/prepare-state.js.map +1 -0
- package/dist/runtime/session/questions.d.ts +2 -2
- package/dist/runtime/session/questions.d.ts.map +1 -1
- package/dist/runtime/session/questions.js.map +1 -1
- package/dist/runtime/session/readiness.d.ts +14 -5
- package/dist/runtime/session/readiness.d.ts.map +1 -1
- package/dist/runtime/session/readiness.js +22 -6
- package/dist/runtime/session/readiness.js.map +1 -1
- package/dist/runtime/session/reap.d.ts +11 -7
- package/dist/runtime/session/reap.d.ts.map +1 -1
- package/dist/runtime/session/reap.js +16 -10
- package/dist/runtime/session/reap.js.map +1 -1
- package/dist/runtime/session/runtime-cleanup.d.ts +18 -0
- package/dist/runtime/session/runtime-cleanup.d.ts.map +1 -0
- package/dist/runtime/session/runtime-cleanup.js +18 -0
- package/dist/runtime/session/runtime-cleanup.js.map +1 -0
- package/dist/runtime/session/session-input.d.ts +32 -0
- package/dist/runtime/session/session-input.d.ts.map +1 -0
- package/dist/runtime/session/{picker-input.js → session-input.js} +35 -7
- package/dist/runtime/session/session-input.js.map +1 -0
- package/dist/runtime/session/shutdown-binding.d.ts +12 -1
- package/dist/runtime/session/shutdown-binding.d.ts.map +1 -1
- package/dist/runtime/session/shutdown-binding.js +33 -1
- package/dist/runtime/session/shutdown-binding.js.map +1 -1
- package/dist/runtime/session/shutdown-cleanup.d.ts +17 -0
- package/dist/runtime/session/shutdown-cleanup.d.ts.map +1 -0
- package/dist/runtime/session/shutdown-cleanup.js +49 -0
- package/dist/runtime/session/shutdown-cleanup.js.map +1 -0
- package/dist/runtime/session/shutdown.d.ts +3 -2
- package/dist/runtime/session/shutdown.d.ts.map +1 -1
- package/dist/runtime/session/shutdown.js +13 -24
- package/dist/runtime/session/shutdown.js.map +1 -1
- package/dist/runtime/shell-quote.d.ts +8 -0
- package/dist/runtime/shell-quote.d.ts.map +1 -0
- package/dist/runtime/shell-quote.js +10 -0
- package/dist/runtime/shell-quote.js.map +1 -0
- package/dist/runtime/shell.d.ts +36 -12
- package/dist/runtime/shell.d.ts.map +1 -1
- package/dist/runtime/shell.js +90 -14
- package/dist/runtime/shell.js.map +1 -1
- package/dist/runtime/shutdown/coalesce.d.ts +15 -0
- package/dist/runtime/shutdown/coalesce.d.ts.map +1 -0
- package/dist/runtime/shutdown/coalesce.js +42 -0
- package/dist/runtime/shutdown/coalesce.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/failures.d.ts +24 -0
- package/dist/runtime/shutdown/detached-sweep/failures.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/failures.js +32 -0
- package/dist/runtime/shutdown/detached-sweep/failures.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/index.d.ts +55 -0
- package/dist/runtime/shutdown/detached-sweep/index.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/index.js +129 -0
- package/dist/runtime/shutdown/detached-sweep/index.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/kill.d.ts +37 -0
- package/dist/runtime/shutdown/detached-sweep/kill.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/kill.js +87 -0
- package/dist/runtime/shutdown/detached-sweep/kill.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/record.d.ts +67 -0
- package/dist/runtime/shutdown/detached-sweep/record.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/record.js +111 -0
- package/dist/runtime/shutdown/detached-sweep/record.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/rounds.d.ts +78 -0
- package/dist/runtime/shutdown/detached-sweep/rounds.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/rounds.js +116 -0
- package/dist/runtime/shutdown/detached-sweep/rounds.js.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/survivors.d.ts +40 -0
- package/dist/runtime/shutdown/detached-sweep/survivors.d.ts.map +1 -0
- package/dist/runtime/shutdown/detached-sweep/survivors.js +112 -0
- package/dist/runtime/shutdown/detached-sweep/survivors.js.map +1 -0
- package/dist/runtime/shutdown/leader-group.d.ts +29 -0
- package/dist/runtime/shutdown/leader-group.d.ts.map +1 -0
- package/dist/runtime/shutdown/leader-group.js +35 -0
- package/dist/runtime/shutdown/leader-group.js.map +1 -0
- package/dist/runtime/shutdown/native-read-admission.d.ts +13 -0
- package/dist/runtime/shutdown/native-read-admission.d.ts.map +1 -0
- package/dist/runtime/shutdown/native-read-admission.js +64 -0
- package/dist/runtime/shutdown/native-read-admission.js.map +1 -0
- package/dist/runtime/shutdown/process-table.d.ts +80 -0
- package/dist/runtime/shutdown/process-table.d.ts.map +1 -0
- package/dist/runtime/shutdown/process-table.js +147 -0
- package/dist/runtime/shutdown/process-table.js.map +1 -0
- package/dist/runtime/shutdown/process-tree-ops.d.ts +39 -0
- package/dist/runtime/shutdown/process-tree-ops.d.ts.map +1 -0
- package/dist/runtime/shutdown/process-tree-ops.js +73 -0
- package/dist/runtime/shutdown/process-tree-ops.js.map +1 -0
- package/dist/runtime/shutdown/read-timeout.d.ts +4 -0
- package/dist/runtime/shutdown/read-timeout.d.ts.map +1 -0
- package/dist/runtime/shutdown/read-timeout.js +6 -0
- package/dist/runtime/shutdown/read-timeout.js.map +1 -0
- package/dist/runtime/shutdown/reap-queue.d.ts +10 -0
- package/dist/runtime/shutdown/reap-queue.d.ts.map +1 -0
- package/dist/runtime/shutdown/reap-queue.js +29 -0
- package/dist/runtime/shutdown/reap-queue.js.map +1 -0
- package/dist/runtime/shutdown/reap-tree.d.ts +42 -32
- package/dist/runtime/shutdown/reap-tree.d.ts.map +1 -1
- package/dist/runtime/shutdown/reap-tree.js +78 -71
- package/dist/runtime/shutdown/reap-tree.js.map +1 -1
- package/dist/runtime/shutdown/shared-daemon.d.ts +59 -0
- package/dist/runtime/shutdown/shared-daemon.d.ts.map +1 -0
- package/dist/runtime/shutdown/shared-daemon.js +139 -0
- package/dist/runtime/shutdown/shared-daemon.js.map +1 -0
- package/dist/runtime/shutdown/teardown.d.ts +15 -0
- package/dist/runtime/shutdown/teardown.d.ts.map +1 -1
- package/dist/runtime/shutdown/teardown.js +19 -6
- package/dist/runtime/shutdown/teardown.js.map +1 -1
- package/dist/runtime/shutdown/terminate.d.ts +21 -1
- package/dist/runtime/shutdown/terminate.d.ts.map +1 -1
- package/dist/runtime/shutdown/terminate.js +83 -56
- package/dist/runtime/shutdown/terminate.js.map +1 -1
- package/dist/runtime/startup/buffer.d.ts +26 -7
- package/dist/runtime/startup/buffer.d.ts.map +1 -1
- package/dist/runtime/startup/buffer.js +42 -19
- package/dist/runtime/startup/buffer.js.map +1 -1
- package/dist/runtime/startup/cleanup.d.ts +37 -11
- package/dist/runtime/startup/cleanup.d.ts.map +1 -1
- package/dist/runtime/startup/cleanup.js +55 -25
- package/dist/runtime/startup/cleanup.js.map +1 -1
- package/dist/runtime/startup/index.d.ts +13 -1
- package/dist/runtime/startup/index.d.ts.map +1 -1
- package/dist/runtime/startup/index.js +38 -6
- package/dist/runtime/startup/index.js.map +1 -1
- package/dist/runtime/stream-marker.d.ts +17 -0
- package/dist/runtime/stream-marker.d.ts.map +1 -0
- package/dist/runtime/stream-marker.js +35 -0
- package/dist/runtime/stream-marker.js.map +1 -0
- package/dist/runtime/update/acquire.d.ts +16 -0
- package/dist/runtime/update/acquire.d.ts.map +1 -0
- package/dist/runtime/update/acquire.js +62 -0
- package/dist/runtime/update/acquire.js.map +1 -0
- package/dist/runtime/update/completion.d.ts +12 -0
- package/dist/runtime/update/completion.d.ts.map +1 -0
- package/dist/runtime/update/completion.js +50 -0
- package/dist/runtime/update/completion.js.map +1 -0
- package/dist/runtime/update/lock.d.ts +1 -1
- package/dist/runtime/update/lock.d.ts.map +1 -1
- package/dist/runtime/update/lock.js +21 -38
- package/dist/runtime/update/lock.js.map +1 -1
- package/dist/runtime/update/once.d.ts +16 -13
- package/dist/runtime/update/once.d.ts.map +1 -1
- package/dist/runtime/update/once.js +41 -31
- package/dist/runtime/update/once.js.map +1 -1
- package/dist/runtime/update/owner.js +1 -1
- package/dist/runtime/update/retained-lease.js +1 -1
- package/dist/runtime/update/waiting.d.ts +14 -1
- package/dist/runtime/update/waiting.d.ts.map +1 -1
- package/dist/runtime/update/waiting.js +20 -12
- package/dist/runtime/update/waiting.js.map +1 -1
- package/dist/state/canonical-path.d.ts +5 -0
- package/dist/state/canonical-path.d.ts.map +1 -1
- package/dist/state/canonical-path.js +11 -5
- package/dist/state/canonical-path.js.map +1 -1
- package/dist/state/directories.d.ts +31 -1
- package/dist/state/directories.d.ts.map +1 -1
- package/dist/state/directories.js +75 -13
- package/dist/state/directories.js.map +1 -1
- package/dist/state/files.d.ts +3 -3
- package/dist/state/files.d.ts.map +1 -1
- package/dist/state/files.js +4 -10
- package/dist/state/files.js.map +1 -1
- package/dist/state/launch-ownership.d.ts +4 -2
- package/dist/state/launch-ownership.d.ts.map +1 -1
- package/dist/state/launch-ownership.js +18 -10
- package/dist/state/launch-ownership.js.map +1 -1
- package/dist/state/launch-publication.d.ts +7 -1
- package/dist/state/launch-publication.d.ts.map +1 -1
- package/dist/state/launch-publication.js +14 -2
- package/dist/state/launch-publication.js.map +1 -1
- package/dist/state/loop-store.d.ts +15 -4
- package/dist/state/loop-store.d.ts.map +1 -1
- package/dist/state/loop-store.js +13 -7
- package/dist/state/loop-store.js.map +1 -1
- package/dist/state/preparation/created-directories.d.ts +13 -0
- package/dist/state/preparation/created-directories.d.ts.map +1 -0
- package/dist/state/preparation/created-directories.js +45 -0
- package/dist/state/preparation/created-directories.js.map +1 -0
- package/dist/state/preparation/ignore-sync.d.ts +9 -0
- package/dist/state/preparation/ignore-sync.d.ts.map +1 -0
- package/dist/state/preparation/ignore-sync.js +47 -0
- package/dist/state/preparation/ignore-sync.js.map +1 -0
- package/dist/state/preparation/index.d.ts +25 -0
- package/dist/state/preparation/index.d.ts.map +1 -0
- package/dist/state/preparation/index.js +31 -0
- package/dist/state/preparation/index.js.map +1 -0
- package/dist/state/preparation/install-ignore.d.ts +6 -0
- package/dist/state/preparation/install-ignore.d.ts.map +1 -0
- package/dist/state/preparation/install-ignore.js +87 -0
- package/dist/state/preparation/install-ignore.js.map +1 -0
- package/dist/state/preparation/rollback-parent.d.ts +3 -0
- package/dist/state/preparation/rollback-parent.d.ts.map +1 -0
- package/dist/state/preparation/rollback-parent.js +18 -0
- package/dist/state/preparation/rollback-parent.js.map +1 -0
- package/dist/state/preparation/root-trust.d.ts +3 -0
- package/dist/state/preparation/root-trust.d.ts.map +1 -0
- package/dist/state/preparation/root-trust.js +70 -0
- package/dist/state/preparation/root-trust.js.map +1 -0
- package/dist/state/private-session.d.ts +5 -2
- package/dist/state/private-session.d.ts.map +1 -1
- package/dist/state/private-session.js +21 -9
- package/dist/state/private-session.js.map +1 -1
- package/dist/state/root.d.ts +25 -0
- package/dist/state/root.d.ts.map +1 -0
- package/dist/state/root.js +84 -0
- package/dist/state/root.js.map +1 -0
- package/dist/state/runtime-paths.d.ts +5 -4
- package/dist/state/runtime-paths.d.ts.map +1 -1
- package/dist/state/runtime-paths.js +5 -4
- package/dist/state/runtime-paths.js.map +1 -1
- package/dist/state/setup-failure.d.ts +3 -0
- package/dist/state/setup-failure.d.ts.map +1 -0
- package/dist/state/setup-failure.js +13 -0
- package/dist/state/setup-failure.js.map +1 -0
- package/dist/state/socket-home.d.ts +17 -12
- package/dist/state/socket-home.d.ts.map +1 -1
- package/dist/state/socket-home.js +31 -14
- package/dist/state/socket-home.js.map +1 -1
- package/dist/state/store.d.ts +1 -3
- package/dist/state/store.d.ts.map +1 -1
- package/dist/state/store.js +3 -18
- package/dist/state/store.js.map +1 -1
- package/dist/terminal/headless.d.ts +1 -1
- package/dist/terminal/headless.d.ts.map +1 -1
- package/dist/terminal/headless.js +1 -3
- package/dist/terminal/headless.js.map +1 -1
- package/docs/cli-behavior.md +1218 -28
- package/docs/cli.md +2 -0
- package/docs/codex/cli.md +4 -2
- package/package.json +4 -4
- package/prd/04-architecture.md +32 -0
- package/prd/05-api/5.1-starting-claude.md +17 -1
- package/prd/05-api/5.2-resuming-claude.md +5 -0
- package/prd/05-api/5.3-claude-session-api.md +267 -40
- package/prd/05-api/5.4-events.md +77 -10
- package/prd/05-api/5.5-starting-codex.md +3 -1
- package/prd/05-api/5.6-resuming-codex.md +4 -1
- package/prd/05-api/5.7-codex-session-api.md +87 -5
- package/prd/05-api/5.8-session-api.md +32 -1
- package/prd/06-claude-hook-bridge.md +2 -0
- package/prd/07a-codex-hook-bridge.md +5 -0
- package/prd/08-state.md +63 -7
- package/prd/09-lifecycle.md +126 -35
- package/prd/10-errors.md +11 -4
- package/prd/12-e2e.md +81 -0
- package/prd/12a-cli.md +63 -9
- package/prd/14-conformance.md +52 -35
- package/prd/16-maintainer-review.md +11 -0
- package/dist/claude/model-composer.d.ts +0 -2
- package/dist/claude/model-composer.d.ts.map +0 -1
- package/dist/claude/model-composer.js +0 -12
- package/dist/claude/model-composer.js.map +0 -1
- package/dist/claude/transcript/drain.d.ts +0 -33
- package/dist/claude/transcript/drain.d.ts.map +0 -1
- package/dist/claude/transcript/drain.js +0 -56
- package/dist/claude/transcript/drain.js.map +0 -1
- package/dist/codex/session/cli-exit.d.ts +0 -24
- package/dist/codex/session/cli-exit.d.ts.map +0 -1
- package/dist/codex/session/cli-exit.js +0 -43
- package/dist/codex/session/cli-exit.js.map +0 -1
- package/dist/codex/transcript/drain.d.ts +0 -30
- package/dist/codex/transcript/drain.d.ts.map +0 -1
- package/dist/codex/transcript/drain.js +0 -48
- package/dist/codex/transcript/drain.js.map +0 -1
- package/dist/runtime/probe-cleanup.d.ts.map +0 -1
- package/dist/runtime/probe-cleanup.js.map +0 -1
- package/dist/runtime/probe.d.ts +0 -11
- package/dist/runtime/probe.d.ts.map +0 -1
- package/dist/runtime/probe.js +0 -113
- package/dist/runtime/probe.js.map +0 -1
- package/dist/runtime/session/foreign-picker.d.ts +0 -8
- package/dist/runtime/session/foreign-picker.d.ts.map +0 -1
- package/dist/runtime/session/foreign-picker.js +0 -18
- package/dist/runtime/session/foreign-picker.js.map +0 -1
- package/dist/runtime/session/picker-input.d.ts +0 -17
- package/dist/runtime/session/picker-input.d.ts.map +0 -1
- package/dist/runtime/session/picker-input.js.map +0 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the host process table and finds the process groups a PTY leader's
|
|
3
|
+
* descendants have moved into. Implements PRD §5.3 and §9.4 (C-LIFE-10): Claude and
|
|
4
|
+
* Codex start every hook command with `setsid()`, so a hook runs in its OWN session and
|
|
5
|
+
* process group and a SIGKILL of the leader's group cannot reach it. The parent-pid
|
|
6
|
+
* chain is the only thing tying such a descendant to the leader, and it holds only
|
|
7
|
+
* while every process between them is alive: when any of them exits, the processes
|
|
8
|
+
* below it are reparented to PID 1 and are out of reach. So this walk runs before
|
|
9
|
+
* Elwood kills the leader, and it finds only descendants still linked at that point.
|
|
10
|
+
*/
|
|
11
|
+
import { execFile } from "node:child_process";
|
|
12
|
+
import { promisify } from "node:util";
|
|
13
|
+
import { coalesceUnstarted } from "./coalesce.js";
|
|
14
|
+
import { createAdmittedPsRunner } from "./native-read-admission.js";
|
|
15
|
+
// An absolute path, so a caller's PATH can never substitute another `ps`. macOS is
|
|
16
|
+
// the only supported platform (PRD §2); `-A -o` is POSIX, so Linux CI parses the same.
|
|
17
|
+
export const PS_PATH = "/bin/ps";
|
|
18
|
+
const PS_ARGS = ["-A", "-o", "pid=,ppid=,pgid=,stat=,lstart=,ucomm=,pid="];
|
|
19
|
+
// Only these: in the C locale `lstart` is always `Www Mmm dd hh:mm:ss yyyy`, so where it
|
|
20
|
+
// ends is known, and in UTC a process's start reads the same however the host's zone changes.
|
|
21
|
+
const PS_ENV = { LC_ALL: "C", TZ: "UTC" };
|
|
22
|
+
// About 80 bytes a row: 16 MiB holds over 200,000 processes, yet bounds a runaway `ps`.
|
|
23
|
+
const PS_MAX_OUTPUT_BYTES = 16 * 1024 * 1024;
|
|
24
|
+
// The short name may hold spaces or be empty, and `ps` prints it raw, so a newline in it
|
|
25
|
+
// starts what reads as another row: each row ends with its pid again (docs/cli-behavior.md).
|
|
26
|
+
const ROW = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+ \S+ +\d+ [\d:]+ \d+)\s(.*)\s(\d+)\s*$/;
|
|
27
|
+
/** One process's identity: its pid and start time, which no later process with its pid shares. */
|
|
28
|
+
export function processIdentity(row) {
|
|
29
|
+
return `${row.pid} ${row.startedAt}`;
|
|
30
|
+
}
|
|
31
|
+
/** A row's fields where no read showed them: a live process not stopped, of no known start. */
|
|
32
|
+
export const UNREAD = {
|
|
33
|
+
ppid: 0,
|
|
34
|
+
zombie: false,
|
|
35
|
+
stopped: false,
|
|
36
|
+
startedAt: "",
|
|
37
|
+
name: "",
|
|
38
|
+
shared: false,
|
|
39
|
+
};
|
|
40
|
+
/** Full scans and daemon probes share admission without changing request coalescing. */
|
|
41
|
+
export const runFile = createAdmittedPsRunner(promisify(execFile));
|
|
42
|
+
/** The bounds every `ps` run gets: `timeoutMs`, the output cap, SIGKILL, and `PS_ENV`. */
|
|
43
|
+
export function psRunOptions(timeoutMs) {
|
|
44
|
+
return { timeout: timeoutMs, maxBuffer: PS_MAX_OUTPUT_BYTES, killSignal: "SIGKILL", env: PS_ENV };
|
|
45
|
+
}
|
|
46
|
+
/** Lists every process on the host, rejecting when `ps` fails or exceeds `timeoutMs`. */
|
|
47
|
+
export async function listProcessTable(timeoutMs, run = runFile) {
|
|
48
|
+
const { stdout } = await run(PS_PATH, PS_ARGS, psRunOptions(timeoutMs));
|
|
49
|
+
return parseProcessTable(stdout);
|
|
50
|
+
}
|
|
51
|
+
/** The production listing: concurrent shutdowns share one `ps` per event-loop turn. */
|
|
52
|
+
export const listProcessTableShared = coalesceUnstarted(listProcessTable);
|
|
53
|
+
/**
|
|
54
|
+
* Parses a `PS_ARGS` read (C locale). Throws on a line that is not one whole row: one cut
|
|
55
|
+
* short, or one whose trailing pid is not its first, as a line a newline in a name
|
|
56
|
+
* started is (`ROW`). Throws, too, on a pid listed twice.
|
|
57
|
+
*/
|
|
58
|
+
export function parseProcessTable(stdout) {
|
|
59
|
+
const entries = [];
|
|
60
|
+
const pids = new Set();
|
|
61
|
+
for (const line of stdout.split("\n")) {
|
|
62
|
+
if (line.trim() === "")
|
|
63
|
+
continue;
|
|
64
|
+
const [, pid = "", ppid, pgid, state = "", startedAt = "", name = "", trailingPid] = ROW.exec(line) ?? [];
|
|
65
|
+
if (pid === "" || pid !== trailingPid) {
|
|
66
|
+
throw new Error("process table read has a line that is not one whole row");
|
|
67
|
+
}
|
|
68
|
+
if (pids.has(Number(pid)))
|
|
69
|
+
throw new Error(`process table read lists pid ${pid} twice`);
|
|
70
|
+
pids.add(Number(pid));
|
|
71
|
+
entries.push({
|
|
72
|
+
pid: Number(pid),
|
|
73
|
+
ppid: Number(ppid),
|
|
74
|
+
pgid: Number(pgid),
|
|
75
|
+
zombie: state.startsWith("Z"),
|
|
76
|
+
stopped: state.startsWith("T"),
|
|
77
|
+
startedAt,
|
|
78
|
+
name: name.trim(),
|
|
79
|
+
shared: false,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return entries;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The process groups, other than the leader's own, that hold at least one LIVE
|
|
86
|
+
* descendant of `leaderPid`, each mapped to the rows of its members' parents that sit
|
|
87
|
+
* in OTHER groups (a parent in the same group adds nothing). Descent follows parent
|
|
88
|
+
* pids transitively, so only descendants still linked to the leader when the table was
|
|
89
|
+
* read are found. A returned group holds only descendants: a group lives inside one
|
|
90
|
+
* session, and every member of the leader's session or of a session a descendant
|
|
91
|
+
* created is itself a descendant. Its id is only a snapshot, and is free for reuse
|
|
92
|
+
* once the group is gone, so the parent rows let a caller signal it only once a parent
|
|
93
|
+
* is known to be stopped: a stopped parent cannot reap its exited child, so that child
|
|
94
|
+
* keeps its pid and the group keeps its id. A leader missing from the table is given
|
|
95
|
+
* as a row that is not stopped. The host's group (`hostPid`'s) and the ids `kill(-pgid)`
|
|
96
|
+
* would misroute (`<= 1`) are never returned. Nor is a `shared` process (Codex's daemon
|
|
97
|
+
* or its updater) or anything it started: the walk never descends into one.
|
|
98
|
+
*/
|
|
99
|
+
export function detachedDescendantGroups(table, { leaderPid, hostPid }) {
|
|
100
|
+
const children = childrenByParent(table);
|
|
101
|
+
const leader = table.find((entry) => entry.pid === leaderPid) ?? {
|
|
102
|
+
...UNREAD,
|
|
103
|
+
pid: leaderPid,
|
|
104
|
+
pgid: leaderPid,
|
|
105
|
+
};
|
|
106
|
+
const excluded = new Set([leaderPid, hostPid, leader.pgid]);
|
|
107
|
+
for (const entry of table)
|
|
108
|
+
if (entry.pid === hostPid)
|
|
109
|
+
excluded.add(entry.pgid);
|
|
110
|
+
const groups = new Map();
|
|
111
|
+
const pending = [leader];
|
|
112
|
+
const visited = new Set([leaderPid]);
|
|
113
|
+
for (let parent = pending.pop(); parent !== undefined; parent = pending.pop()) {
|
|
114
|
+
for (const child of children.get(parent.pid) ?? []) {
|
|
115
|
+
if (visited.has(child.pid) || child.shared)
|
|
116
|
+
continue;
|
|
117
|
+
visited.add(child.pid);
|
|
118
|
+
pending.push(child);
|
|
119
|
+
if (child.zombie || child.pgid <= 1 || excluded.has(child.pgid))
|
|
120
|
+
continue;
|
|
121
|
+
const parents = groups.get(child.pgid) ?? new Set();
|
|
122
|
+
if (parent.pgid !== child.pgid)
|
|
123
|
+
parents.add(parent);
|
|
124
|
+
groups.set(child.pgid, parents);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return groups;
|
|
128
|
+
}
|
|
129
|
+
/** The table's rows grouped by their parent's pid, built once per table. */
|
|
130
|
+
export function childrenByParent(table) {
|
|
131
|
+
const built = childIndexes.get(table);
|
|
132
|
+
if (built !== undefined)
|
|
133
|
+
return built;
|
|
134
|
+
const children = new Map();
|
|
135
|
+
for (const entry of table) {
|
|
136
|
+
const siblings = children.get(entry.ppid);
|
|
137
|
+
if (siblings)
|
|
138
|
+
siblings.push(entry);
|
|
139
|
+
else
|
|
140
|
+
children.set(entry.ppid, [entry]);
|
|
141
|
+
}
|
|
142
|
+
childIndexes.set(table, children);
|
|
143
|
+
return children;
|
|
144
|
+
}
|
|
145
|
+
/** Each read's index, built once however many walks from different roots read it. */
|
|
146
|
+
const childIndexes = new WeakMap();
|
|
147
|
+
//# sourceMappingURL=process-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-table.js","sourceRoot":"","sources":["../../../src/runtime/shutdown/process-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System process-group operations and the shared inert test seam.
|
|
3
|
+
* Implements PRD §5.3 and §9.4 (C-LIFE-10).
|
|
4
|
+
*/
|
|
5
|
+
import type { SweepOps } from "./detached-sweep/index.ts";
|
|
6
|
+
/**
|
|
7
|
+
* The process-tree operations teardown performs, injectable so tests never signal real
|
|
8
|
+
* processes: the group reap's SIGKILL, and the detached sweep's SIGSTOP, SIGKILL, the
|
|
9
|
+
* SIGCONT that resumes a group holding Codex's daemon, and table read.
|
|
10
|
+
*/
|
|
11
|
+
export type ProcessTreeOps = SweepOps;
|
|
12
|
+
/** The part of the process-tree ops the group reap uses. */
|
|
13
|
+
export type GroupReapOps = Pick<ProcessTreeOps, "killGroup">;
|
|
14
|
+
export declare const osProcessTreeOps: ProcessTreeOps;
|
|
15
|
+
/** The operations currently selected by the shared shutdown seam. */
|
|
16
|
+
export declare function activeProcessTreeOps(): ProcessTreeOps;
|
|
17
|
+
/**
|
|
18
|
+
* Replaces the process-tree ops. Ops a test leaves out become inert, never the real
|
|
19
|
+
* ones, so faking only the kill cannot leave a real sweep live (see `quietProcessTree`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function setProcessTreeOpsForTests(ops: GroupReapOps & Partial<ProcessTreeOps>): void;
|
|
22
|
+
/**
|
|
23
|
+
* Inert sweep ops for tests: a process tree holding only the group leaders it was asked
|
|
24
|
+
* to stop, each read as stopped with nothing under it. A sweep driven by them signals
|
|
25
|
+
* no real process, finds no descendant, and converges on its second read.
|
|
26
|
+
*/
|
|
27
|
+
export declare function quietProcessTree(): Omit<ProcessTreeOps, "killGroup">;
|
|
28
|
+
export declare function resetProcessTreeOpsForTests(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Swallows the ESRCH raised when the group is already empty (the normal case:
|
|
31
|
+
* the leader and its children exited together) and re-throws any other error —
|
|
32
|
+
* a real failure (e.g. EPERM) that must not be reported as a successful reap.
|
|
33
|
+
* Reads the errno through `errnoCode`, which narrows object-ness first, so a
|
|
34
|
+
* thrown `null`/non-Error is preserved and rethrown rather than triggering a
|
|
35
|
+
* secondary TypeError while inspecting it (C-ERR-01). Exported for focused
|
|
36
|
+
* coverage of both branches without an unsafe real signal.
|
|
37
|
+
*/
|
|
38
|
+
export declare function rethrowUnlessGroupGone(error: unknown): void;
|
|
39
|
+
//# sourceMappingURL=process-tree-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree-ops.d.ts","sourceRoot":"","sources":["../../../src/runtime/shutdown/process-tree-ops.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAI1D;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAK7D,eAAO,MAAM,gBAAgB,EAAE,cAe9B,CAAC;AAOF,qEAAqE;AACrE,wBAAgB,oBAAoB,IAAI,cAAc,CAErD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAE3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAQpE;AAID,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE3D"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System process-group operations and the shared inert test seam.
|
|
3
|
+
* Implements PRD §5.3 and §9.4 (C-LIFE-10).
|
|
4
|
+
*/
|
|
5
|
+
import { errnoCode } from "../../core/errors.js";
|
|
6
|
+
import { UNREAD } from "./process-table.js";
|
|
7
|
+
import { listProcessTableMarkingDaemon } from "./shared-daemon.js";
|
|
8
|
+
// Production uses `process.kill` and `/bin/ps`. One seam covers the group reap AND the
|
|
9
|
+
// detached sweep, so a test that fakes the kill can never leave a real sweep live.
|
|
10
|
+
// Exported for a real-process test that wraps one of them.
|
|
11
|
+
export const osProcessTreeOps = {
|
|
12
|
+
killGroup(pgid) {
|
|
13
|
+
try {
|
|
14
|
+
process.kill(-pgid, "SIGKILL");
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
rethrowUnlessGroupGone(error);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
stopGroup(pgid) {
|
|
21
|
+
process.kill(-pgid, "SIGSTOP");
|
|
22
|
+
},
|
|
23
|
+
continueGroup(pgid) {
|
|
24
|
+
process.kill(-pgid, "SIGCONT");
|
|
25
|
+
},
|
|
26
|
+
listProcesses: (timeoutMs, scope) => listProcessTableMarkingDaemon(timeoutMs, scope),
|
|
27
|
+
};
|
|
28
|
+
// The ops used when a caller does not inject them. A test seam so session lifecycle
|
|
29
|
+
// tests can observe (and neutralize) the group SIGKILL without a real signal, and
|
|
30
|
+
// without every session/terminate call site taking an ops param.
|
|
31
|
+
let activeOps = osProcessTreeOps;
|
|
32
|
+
/** The operations currently selected by the shared shutdown seam. */
|
|
33
|
+
export function activeProcessTreeOps() {
|
|
34
|
+
return activeOps;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Replaces the process-tree ops. Ops a test leaves out become inert, never the real
|
|
38
|
+
* ones, so faking only the kill cannot leave a real sweep live (see `quietProcessTree`).
|
|
39
|
+
*/
|
|
40
|
+
export function setProcessTreeOpsForTests(ops) {
|
|
41
|
+
activeOps = { ...quietProcessTree(), ...ops };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Inert sweep ops for tests: a process tree holding only the group leaders it was asked
|
|
45
|
+
* to stop, each read as stopped with nothing under it. A sweep driven by them signals
|
|
46
|
+
* no real process, finds no descendant, and converges on its second read.
|
|
47
|
+
*/
|
|
48
|
+
export function quietProcessTree() {
|
|
49
|
+
const stopped = new Set();
|
|
50
|
+
return {
|
|
51
|
+
stopGroup: (pgid) => void stopped.add(pgid),
|
|
52
|
+
continueGroup: (pgid) => void stopped.delete(pgid),
|
|
53
|
+
listProcesses: () => Promise.resolve([...stopped].map((pgid) => ({ ...QUIET_ROW, pid: pgid, pgid }))),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const QUIET_ROW = { ...UNREAD, ppid: 1, stopped: true };
|
|
57
|
+
export function resetProcessTreeOpsForTests() {
|
|
58
|
+
activeOps = osProcessTreeOps;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Swallows the ESRCH raised when the group is already empty (the normal case:
|
|
62
|
+
* the leader and its children exited together) and re-throws any other error —
|
|
63
|
+
* a real failure (e.g. EPERM) that must not be reported as a successful reap.
|
|
64
|
+
* Reads the errno through `errnoCode`, which narrows object-ness first, so a
|
|
65
|
+
* thrown `null`/non-Error is preserved and rethrown rather than triggering a
|
|
66
|
+
* secondary TypeError while inspecting it (C-ERR-01). Exported for focused
|
|
67
|
+
* coverage of both branches without an unsafe real signal.
|
|
68
|
+
*/
|
|
69
|
+
export function rethrowUnlessGroupGone(error) {
|
|
70
|
+
if (errnoCode(error) !== "ESRCH")
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=process-tree-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree-ops.js","sourceRoot":"","sources":["../../../src/runtime/shutdown/process-tree-ops.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAYnE,uFAAuF;AACvF,mFAAmF;AACnF,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,SAAS,CAAC,IAAY;QACpB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,SAAS,CAAC,IAAY;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IACD,aAAa,CAAC,IAAY;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IACD,aAAa,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,6BAA6B,CAAC,SAAS,EAAE,KAAK,CAAC;CACrF,CAAC;AAEF,oFAAoF;AACpF,kFAAkF;AAClF,iEAAiE;AACjE,IAAI,SAAS,GAAmB,gBAAgB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,UAAU,oBAAoB;IAClC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAA2C;IACnF,SAAS,GAAG,EAAE,GAAG,gBAAgB,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,OAAO;QACL,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3C,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QAClD,aAAa,EAAE,GAAG,EAAE,CAClB,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAExD,MAAM,UAAU,2BAA2B;IACzC,SAAS,GAAG,gBAAgB,CAAC;AAC/B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,OAAO;QAAE,MAAM,KAAK,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-timeout.d.ts","sourceRoot":"","sources":["../../../src/runtime/shutdown/read-timeout.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAEzD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Builds shutdown read deadline errors (PRD §5.3/§9.4, C-LIFE-10). */
|
|
2
|
+
/** Retain each read's diagnostic message with the shared deadline error code. */
|
|
3
|
+
export function processReadTimeout(message) {
|
|
4
|
+
return Object.assign(new Error(message), { code: "ETIMEDOUT" });
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=read-timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-timeout.js","sourceRoot":"","sources":["../../../src/runtime/shutdown/read-timeout.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session descendant signal passes (PRD §5.3 and §9.4, C-LIFE-10):
|
|
3
|
+
* begin an idle pass in the caller's tick, and serialize every later pass behind it.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SerialDetachedSweepQueue {
|
|
6
|
+
private tail;
|
|
7
|
+
/** Return this attempt’s outcome; release the next pass after either success or failure. */
|
|
8
|
+
run<T>(attempt: () => Promise<T>): Promise<T>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=reap-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reap-queue.d.ts","sourceRoot":"","sources":["../../../src/runtime/shutdown/reap-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,IAAI,CAA4B;IAExC,4FAA4F;IAC5F,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAkB9C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session descendant signal passes (PRD §5.3 and §9.4, C-LIFE-10):
|
|
3
|
+
* begin an idle pass in the caller's tick, and serialize every later pass behind it.
|
|
4
|
+
*/
|
|
5
|
+
export class SerialDetachedSweepQueue {
|
|
6
|
+
tail;
|
|
7
|
+
/** Return this attempt’s outcome; release the next pass after either success or failure. */
|
|
8
|
+
run(attempt) {
|
|
9
|
+
const previous = this.tail;
|
|
10
|
+
const { promise: held, resolve } = Promise.withResolvers();
|
|
11
|
+
this.tail = held;
|
|
12
|
+
const release = () => {
|
|
13
|
+
resolve();
|
|
14
|
+
if (this.tail === held)
|
|
15
|
+
this.tail = undefined;
|
|
16
|
+
};
|
|
17
|
+
let result;
|
|
18
|
+
try {
|
|
19
|
+
result = previous === undefined ? attempt() : previous.then(attempt);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
release();
|
|
23
|
+
return Promise.reject(error);
|
|
24
|
+
}
|
|
25
|
+
void result.then(release, release);
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=reap-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reap-queue.js","sourceRoot":"","sources":["../../../src/runtime/shutdown/reap-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,wBAAwB;IAC3B,IAAI,CAA4B;IAExC,4FAA4F;IAC5F,GAAG,CAAI,OAAyB;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,EAAE,CAAC;YACV,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QAChD,CAAC,CAAC;QACF,IAAI,MAAkB,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;YACV,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -1,42 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Reaps the process tree of a PTY leader on session teardown
|
|
2
|
+
* Reaps the process tree of a PTY leader on session teardown, but Codex's shared
|
|
3
|
+
* app-server daemon, its updater, and what they started (`shared-daemon.ts`).
|
|
3
4
|
* Implements PRD §5.3 and §9.4 (C-LIFE-10): a CLI-spawned helper such as the
|
|
4
5
|
* Claude hook bridge is a descendant of the PTY leader. Because POSIX reparents
|
|
5
6
|
* a surviving descendant to PID 1 the instant its parent exits, a parent-pid
|
|
6
7
|
* walk (`pgrep -P`) cannot find it afterwards — but node-pty starts the leader
|
|
7
8
|
* as its own session/process-group leader, and group membership is inherited
|
|
8
9
|
* and survives reparenting. So we reap by SIGKILLing the leader's process group,
|
|
9
|
-
* which reaches every descendant in one in-process syscall: no
|
|
10
|
-
* PATH lookup, no post-exit reparenting blind spot.
|
|
10
|
+
* which reaches every descendant still IN that group in one in-process syscall: no
|
|
11
|
+
* subprocess, no PATH lookup, no post-exit reparenting blind spot.
|
|
12
|
+
*
|
|
13
|
+
* A descendant that started its own group is outside it: Claude and Codex start every
|
|
14
|
+
* hook with `setsid()` (docs/cli-behavior.md, "Hook and MCP process groups").
|
|
15
|
+
* `sweepDetached` finds those groups by parent pid and kills them, all but the daemon's
|
|
16
|
+
* and its updater's, which other Codex sessions share, so it has to run
|
|
17
|
+
* while that link still exists: before the live leader is SIGKILLed (see
|
|
18
|
+
* `sweepDetachedGroups` in `detached-sweep/index.ts`).
|
|
11
19
|
*/
|
|
12
|
-
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* SIGKILLs the process group led by `leaderPid`, reaping every descendant still
|
|
19
|
-
* in the group — including one already reparented to PID 1. node-pty starts the
|
|
20
|
-
* leader via `setsid()`, so it heads its own session and its pgid equals its pid;
|
|
21
|
-
* that group is always distinct from the host's own group, so this cannot signal
|
|
22
|
-
* the host process. Refuses only pids the kernel would misroute (see
|
|
23
|
-
* `isReapableGroupId`), never an arbitrary numeric floor. An already-dead group
|
|
24
|
-
* (leader and children exited together) is the normal case and its `ESRCH` is
|
|
25
|
-
* swallowed; a real kill failure such as `EPERM` propagates.
|
|
26
|
-
*/
|
|
27
|
-
export declare function reapProcessGroup(leaderPid: number, ops?: ProcessGroupKiller): void;
|
|
28
|
-
export declare function setGroupKillerForTests(killer: ProcessGroupKiller): void;
|
|
29
|
-
export declare function resetGroupKillerForTests(): void;
|
|
30
|
-
/**
|
|
31
|
-
* Swallows the ESRCH raised when the group is already empty (the normal case:
|
|
32
|
-
* the leader and its children exited together) and re-throws any other error —
|
|
33
|
-
* a real failure (e.g. EPERM) that must not be reported as a successful reap.
|
|
34
|
-
* Reads the errno through `errnoCode`, which narrows object-ness first, so a
|
|
35
|
-
* thrown `null`/non-Error is preserved and rethrown rather than triggering a
|
|
36
|
-
* secondary TypeError while inspecting it (C-ERR-01). Exported for focused
|
|
37
|
-
* coverage of both branches without an unsafe real signal.
|
|
38
|
-
*/
|
|
39
|
-
export declare function rethrowUnlessGroupGone(error: unknown): void;
|
|
20
|
+
import { type ProcessTreeOps } from "./process-tree-ops.ts";
|
|
21
|
+
export { reapProcessGroup } from "./leader-group.ts";
|
|
22
|
+
export { osProcessTreeOps, type ProcessTreeOps, quietProcessTree, resetProcessTreeOpsForTests, rethrowUnlessGroupGone, setProcessTreeOpsForTests, } from "./process-tree-ops.ts";
|
|
23
|
+
export type LeaderPtySignalOutcome = "signal-sent" | "leader-group-gone";
|
|
40
24
|
/**
|
|
41
25
|
* Owns a single PTY leader's group reap. A SUCCESSFUL reap MUST happen at most
|
|
42
26
|
* once: `stop()` then a later `teardown()` both want to guarantee the group is
|
|
@@ -51,12 +35,38 @@ export declare class SessionReaper {
|
|
|
51
35
|
private readonly leaderPid;
|
|
52
36
|
private readonly ops;
|
|
53
37
|
private done;
|
|
54
|
-
|
|
38
|
+
private pendingSweeps;
|
|
39
|
+
/** Terminal evidence about the entire group, never inferred merely from leader exit. */
|
|
40
|
+
private leaderGroupGone;
|
|
41
|
+
private readonly detachedSweepQueue;
|
|
42
|
+
/** A detached sweep that failed; once the leader is gone it can never be confirmed. */
|
|
43
|
+
private unresolvedSweep;
|
|
44
|
+
constructor(leaderPid: number, ops?: ProcessTreeOps);
|
|
55
45
|
/**
|
|
56
46
|
* Reap the group once it succeeds; a successful call latches so subsequent
|
|
57
47
|
* calls no-op (no recycled-pgid double-kill). A failed kill does NOT latch and
|
|
58
48
|
* rethrows, keeping the reap retryable on a later lifecycle call.
|
|
59
49
|
*/
|
|
60
50
|
reap(): void;
|
|
51
|
+
/** Dispatch a PTY signal only while this session has not confirmed its group gone. */
|
|
52
|
+
signalLeaderPty(send: () => void): LeaderPtySignalOutcome;
|
|
53
|
+
/**
|
|
54
|
+
* The group reap for an explicit shutdown's retry: it also keeps failing while an
|
|
55
|
+
* earlier detached sweep is unresolved, so a later `stop()`/`kill()`/`teardown()`
|
|
56
|
+
* never reports success for a hook that may still be running. It says nothing about
|
|
57
|
+
* a sweep that never ran: the caller sweeps first, before any SIGKILL it sends to a
|
|
58
|
+
* live leader.
|
|
59
|
+
*/
|
|
60
|
+
reapAndThrowOnDetachedSweepFailure(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Kill the process groups the leader's descendants moved into. Valid only while
|
|
63
|
+
* the leader is alive — afterwards its detached descendants are reparented to
|
|
64
|
+
* PID 1 and cannot be found — so it runs just before the leader is SIGKILLed, with
|
|
65
|
+
* `leaderExited` reporting whether the caller has seen the leader exit. A failure,
|
|
66
|
+
* including a leader exit that left a found group unreached, is kept for
|
|
67
|
+
* `reapAndThrowOnDetachedSweepFailure`, then thrown. Refuses the same misrouted ids
|
|
68
|
+
* as the group reap.
|
|
69
|
+
*/
|
|
70
|
+
sweepDetached(leaderExited: () => boolean): Promise<void>;
|
|
61
71
|
}
|
|
62
72
|
//# sourceMappingURL=reap-tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reap-tree.d.ts","sourceRoot":"","sources":["../../../src/runtime/shutdown/reap-tree.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reap-tree.d.ts","sourceRoot":"","sources":["../../../src/runtime/shutdown/reap-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,KAAK,cAAc,EACnB,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAEzE;;;;;;;;;GASG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAK;IAC1B,wFAAwF;IACxF,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAkC;IACrE,uFAAuF;IACvF,OAAO,CAAC,eAAe,CAA2B;gBAEtC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAE,cAAuC;IAK3E;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAOZ,sFAAsF;IACtF,eAAe,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,sBAAsB;IASzD;;;;;;OAMG;IACH,kCAAkC,IAAI,IAAI;IAK1C;;;;;;;;OAQG;IACG,aAAa,CAAC,YAAY,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAkBhE"}
|
|
@@ -1,80 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Reaps the process tree of a PTY leader on session teardown
|
|
2
|
+
* Reaps the process tree of a PTY leader on session teardown, but Codex's shared
|
|
3
|
+
* app-server daemon, its updater, and what they started (`shared-daemon.ts`).
|
|
3
4
|
* Implements PRD §5.3 and §9.4 (C-LIFE-10): a CLI-spawned helper such as the
|
|
4
5
|
* Claude hook bridge is a descendant of the PTY leader. Because POSIX reparents
|
|
5
6
|
* a surviving descendant to PID 1 the instant its parent exits, a parent-pid
|
|
6
7
|
* walk (`pgrep -P`) cannot find it afterwards — but node-pty starts the leader
|
|
7
8
|
* as its own session/process-group leader, and group membership is inherited
|
|
8
9
|
* and survives reparenting. So we reap by SIGKILLing the leader's process group,
|
|
9
|
-
* which reaches every descendant in one in-process syscall: no
|
|
10
|
-
* PATH lookup, no post-exit reparenting blind spot.
|
|
10
|
+
* which reaches every descendant still IN that group in one in-process syscall: no
|
|
11
|
+
* subprocess, no PATH lookup, no post-exit reparenting blind spot.
|
|
12
|
+
*
|
|
13
|
+
* A descendant that started its own group is outside it: Claude and Codex start every
|
|
14
|
+
* hook with `setsid()` (docs/cli-behavior.md, "Hook and MCP process groups").
|
|
15
|
+
* `sweepDetached` finds those groups by parent pid and kills them, all but the daemon's
|
|
16
|
+
* and its updater's, which other Codex sessions share, so it has to run
|
|
17
|
+
* while that link still exists: before the live leader is SIGKILLed (see
|
|
18
|
+
* `sweepDetachedGroups` in `detached-sweep/index.ts`).
|
|
11
19
|
*/
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* floor silently no-op'd such leaders and leaked their descendants). We instead
|
|
19
|
-
* accept every valid child pid while refusing the two ids a group SIGKILL must
|
|
20
|
-
* never touch:
|
|
21
|
-
* - `pgid <= 1` — pid 0 means "our own group" to `kill(2)`, and pid 1 is
|
|
22
|
-
* `init`/`launchd`; a fake pid 1 in tests once reaped a developer's real apps.
|
|
23
|
-
* - the host's OWN pid — node-pty gives the leader a fresh session via `setsid()`
|
|
24
|
-
* so its pgid can never legitimately equal ours, but if a bad pgid ever did we
|
|
25
|
-
* must not signal `-process.pid` and kill ourselves.
|
|
26
|
-
*/
|
|
27
|
-
function isReapableGroupId(pgid) {
|
|
28
|
-
return Number.isInteger(pgid) && pgid > 1 && pgid !== process.pid;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* SIGKILLs the process group led by `leaderPid`, reaping every descendant still
|
|
32
|
-
* in the group — including one already reparented to PID 1. node-pty starts the
|
|
33
|
-
* leader via `setsid()`, so it heads its own session and its pgid equals its pid;
|
|
34
|
-
* that group is always distinct from the host's own group, so this cannot signal
|
|
35
|
-
* the host process. Refuses only pids the kernel would misroute (see
|
|
36
|
-
* `isReapableGroupId`), never an arbitrary numeric floor. An already-dead group
|
|
37
|
-
* (leader and children exited together) is the normal case and its `ESRCH` is
|
|
38
|
-
* swallowed; a real kill failure such as `EPERM` propagates.
|
|
39
|
-
*/
|
|
40
|
-
export function reapProcessGroup(leaderPid, ops = activeKiller) {
|
|
41
|
-
if (!isReapableGroupId(leaderPid))
|
|
42
|
-
return;
|
|
43
|
-
ops.killGroup(leaderPid);
|
|
44
|
-
}
|
|
45
|
-
const defaultKiller = {
|
|
46
|
-
killGroup(pgid) {
|
|
47
|
-
try {
|
|
48
|
-
process.kill(-pgid, "SIGKILL");
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
rethrowUnlessGroupGone(error);
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
// The killer used when a caller does not inject one. A test seam so session
|
|
56
|
-
// lifecycle tests can observe (and neutralize) the group SIGKILL without a real
|
|
57
|
-
// signal, and without every session/terminate call site taking a killer param.
|
|
58
|
-
let activeKiller = defaultKiller;
|
|
59
|
-
export function setGroupKillerForTests(killer) {
|
|
60
|
-
activeKiller = killer;
|
|
61
|
-
}
|
|
62
|
-
export function resetGroupKillerForTests() {
|
|
63
|
-
activeKiller = defaultKiller;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Swallows the ESRCH raised when the group is already empty (the normal case:
|
|
67
|
-
* the leader and its children exited together) and re-throws any other error —
|
|
68
|
-
* a real failure (e.g. EPERM) that must not be reported as a successful reap.
|
|
69
|
-
* Reads the errno through `errnoCode`, which narrows object-ness first, so a
|
|
70
|
-
* thrown `null`/non-Error is preserved and rethrown rather than triggering a
|
|
71
|
-
* secondary TypeError while inspecting it (C-ERR-01). Exported for focused
|
|
72
|
-
* coverage of both branches without an unsafe real signal.
|
|
73
|
-
*/
|
|
74
|
-
export function rethrowUnlessGroupGone(error) {
|
|
75
|
-
if (errnoCode(error) !== "ESRCH")
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
20
|
+
import { sweepDetachedGroups } from "./detached-sweep/index.js";
|
|
21
|
+
import { isReapableGroupId, reapProcessGroup } from "./leader-group.js";
|
|
22
|
+
import { activeProcessTreeOps } from "./process-tree-ops.js";
|
|
23
|
+
import { SerialDetachedSweepQueue } from "./reap-queue.js";
|
|
24
|
+
export { reapProcessGroup } from "./leader-group.js";
|
|
25
|
+
export { osProcessTreeOps, quietProcessTree, resetProcessTreeOpsForTests, rethrowUnlessGroupGone, setProcessTreeOpsForTests, } from "./process-tree-ops.js";
|
|
78
26
|
/**
|
|
79
27
|
* Owns a single PTY leader's group reap. A SUCCESSFUL reap MUST happen at most
|
|
80
28
|
* once: `stop()` then a later `teardown()` both want to guarantee the group is
|
|
@@ -89,7 +37,13 @@ export class SessionReaper {
|
|
|
89
37
|
leaderPid;
|
|
90
38
|
ops;
|
|
91
39
|
done = false;
|
|
92
|
-
|
|
40
|
+
pendingSweeps = 0;
|
|
41
|
+
/** Terminal evidence about the entire group, never inferred merely from leader exit. */
|
|
42
|
+
leaderGroupGone = false;
|
|
43
|
+
detachedSweepQueue = new SerialDetachedSweepQueue();
|
|
44
|
+
/** A detached sweep that failed; once the leader is gone it can never be confirmed. */
|
|
45
|
+
unresolvedSweep;
|
|
46
|
+
constructor(leaderPid, ops = activeProcessTreeOps()) {
|
|
93
47
|
this.leaderPid = leaderPid;
|
|
94
48
|
this.ops = ops;
|
|
95
49
|
}
|
|
@@ -99,10 +53,63 @@ export class SessionReaper {
|
|
|
99
53
|
* rethrows, keeping the reap retryable on a later lifecycle call.
|
|
100
54
|
*/
|
|
101
55
|
reap() {
|
|
102
|
-
|
|
56
|
+
// The active shutdown owner reaps after its sweep, including any pending confirmation.
|
|
57
|
+
if (this.done || this.leaderGroupGone || this.pendingSweeps > 0)
|
|
103
58
|
return;
|
|
104
59
|
reapProcessGroup(this.leaderPid, this.ops);
|
|
105
60
|
this.done = true;
|
|
106
61
|
}
|
|
62
|
+
/** Dispatch a PTY signal only while this session has not confirmed its group gone. */
|
|
63
|
+
signalLeaderPty(send) {
|
|
64
|
+
if (this.leaderGroupGone) {
|
|
65
|
+
this.reapAndThrowOnDetachedSweepFailure();
|
|
66
|
+
return "leader-group-gone";
|
|
67
|
+
}
|
|
68
|
+
send();
|
|
69
|
+
return "signal-sent";
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The group reap for an explicit shutdown's retry: it also keeps failing while an
|
|
73
|
+
* earlier detached sweep is unresolved, so a later `stop()`/`kill()`/`teardown()`
|
|
74
|
+
* never reports success for a hook that may still be running. It says nothing about
|
|
75
|
+
* a sweep that never ran: the caller sweeps first, before any SIGKILL it sends to a
|
|
76
|
+
* live leader.
|
|
77
|
+
*/
|
|
78
|
+
reapAndThrowOnDetachedSweepFailure() {
|
|
79
|
+
this.reap();
|
|
80
|
+
if (this.unresolvedSweep !== undefined)
|
|
81
|
+
throw this.unresolvedSweep;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Kill the process groups the leader's descendants moved into. Valid only while
|
|
85
|
+
* the leader is alive — afterwards its detached descendants are reparented to
|
|
86
|
+
* PID 1 and cannot be found — so it runs just before the leader is SIGKILLed, with
|
|
87
|
+
* `leaderExited` reporting whether the caller has seen the leader exit. A failure,
|
|
88
|
+
* including a leader exit that left a found group unreached, is kept for
|
|
89
|
+
* `reapAndThrowOnDetachedSweepFailure`, then thrown. Refuses the same misrouted ids
|
|
90
|
+
* as the group reap.
|
|
91
|
+
*/
|
|
92
|
+
async sweepDetached(leaderExited) {
|
|
93
|
+
if (!isReapableGroupId(this.leaderPid))
|
|
94
|
+
return;
|
|
95
|
+
this.pendingSweeps += 1;
|
|
96
|
+
try {
|
|
97
|
+
const failure = await this.detachedSweepQueue.run(() => {
|
|
98
|
+
// A queued request must recheck after the preceding pass has confirmed exit.
|
|
99
|
+
if (this.leaderGroupGone)
|
|
100
|
+
return Promise.resolve(undefined);
|
|
101
|
+
return sweepDetachedGroups(this.leaderPid, this.ops, leaderExited, undefined, () => {
|
|
102
|
+
this.leaderGroupGone = true;
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
if (failure === undefined)
|
|
106
|
+
return;
|
|
107
|
+
this.unresolvedSweep = failure;
|
|
108
|
+
throw failure;
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
this.pendingSweeps -= 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
107
114
|
}
|
|
108
115
|
//# sourceMappingURL=reap-tree.js.map
|