@code-yeongyu/senpi 2026.9.24-3 → 2026.9.25
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 +26 -0
- package/dist/bundle/chunks/{app-server-command-OTRHYRIB.js → app-server-command-RB6QUPRI.js} +1 -1
- package/dist/bundle/chunks/{chunk-UM43CBL4.js → chunk-JJ3NJZBD.js} +118 -111
- package/dist/bundle/chunks/chunk-SGYEOIOJ.js +8 -0
- package/dist/bundle/chunks/chunk-YS5YEX4S.js +2 -0
- package/dist/bundle/chunks/{cli-main-TX6I4X4F.js → cli-main-KO53KYDN.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-UI5Q6FGY.js → interactive-mode-ABDNLJSI.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-D6HMI3RQ.js → multi-session-host-JV3MNWXZ.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-3UWH3ZZS.js → package-manager-cli-ZYYAVCXU.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-LXIZHJSJ.js → rpc-mode-Q2OUJURB.js} +1 -1
- package/dist/bundle/chunks/runtime-session-XBT646O5.js +2 -0
- package/dist/bundle/chunks/session-worker.js +184 -177
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts +7 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +23 -4
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts +11 -16
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.js +97 -43
- package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.js +11 -4
- package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension-state.d.ts +26 -0
- package/dist/core/extensions/builtin/terminal/extension-state.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/extension-state.js +151 -0
- package/dist/core/extensions/builtin/terminal/extension-state.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +32 -308
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/lease-file.d.ts +52 -0
- package/dist/core/extensions/builtin/terminal/lease-file.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-file.js +205 -0
- package/dist/core/extensions/builtin/terminal/lease-file.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts +33 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.js +110 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts +1 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.js +6 -0
- package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts +48 -4
- package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manifest-lease.js +141 -59
- package/dist/core/extensions/builtin/terminal/manifest-lease.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +15 -10
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts +11 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.js +28 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts +41 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.js +131 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-identity.d.ts +21 -0
- package/dist/core/extensions/builtin/terminal/process-identity.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-identity.js +34 -0
- package/dist/core/extensions/builtin/terminal/process-identity.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts +6 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.js +60 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/prompt.js +8 -4
- package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/restore-digest.d.ts +54 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.js +133 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-session.d.ts +56 -0
- package/dist/core/extensions/builtin/terminal/restore-session.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-session.js +238 -0
- package/dist/core/extensions/builtin/terminal/restore-session.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore.d.ts +52 -19
- package/dist/core/extensions/builtin/terminal/restore.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/restore.js +63 -138
- package/dist/core/extensions/builtin/terminal/restore.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +17 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-activity.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/session-activity.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/session-activity.js +41 -0
- package/dist/core/extensions/builtin/terminal/session-activity.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/shared.d.ts +14 -0
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +14 -0
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts +15 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js +148 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts +15 -2
- package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest.js +62 -11
- package/dist/core/extensions/builtin/terminal/terminal-manifest.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts +17 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.js +81 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +16 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts +27 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js +75 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts +35 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js +67 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +14 -35
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +30 -110
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts +7 -6
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/first-turn.js +8 -8
- package/dist/core/extensions/builtin/todotools/first-turn.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +1 -1
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js +1 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js +4 -0
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.js +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +6 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/docs/extensions.md +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-desktop-engine/README.md +31 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts +38 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js +117 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js +3 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts +42 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js +79 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/check-prebuild-fresh.mjs +160 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.d.ts +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.js +23 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/prebuilds/darwin-arm64/senpi-desktop-engine +0 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/package.json +53 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/package.json +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts +38 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts +28 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js +102 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts +14 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js +71 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts +7 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js +4 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts +66 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js +8 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts +59 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/package.json +45 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/README.md +27 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/package.json +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/package.json +44 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cerebras.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts +2 -0
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +6 -0
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-native.js +5 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-native.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts +11 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js +24 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts +2 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-types.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts +4 -5
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.js +11 -16
- package/node_modules/@earendil-works/pi-pty/dist/session.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +22 -7
- package/dist/bundle/chunks/chunk-GFUZPFHN.js +0 -2
- package/dist/bundle/chunks/chunk-JBOV6VNK.js +0 -8
- package/dist/bundle/chunks/runtime-session-F3EXC44D.js +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-identity.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/process-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAEjD,gHAAgH;AAChH,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AAEhD,MAAM,YAAY,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1E,MAAM,UAAU,eAAe,CAAC,GAAG,GAAiB,IAAI,CAAC,GAAG;IAC3D,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAE3E;;;GAGG;AACH,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAE9E,oGAAoG;AACpG,MAAM,UAAU,qBAAqB,CAAC,GAAkB;IACvD,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,aAAiC;IAC3E,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,KAAK,CAAC;IACjF,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,IAAI,yBAAyB,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,gBAAoC;IACzF,IAAI,gBAAgB,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,KAAK,CAAC;IACvF,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,gBAAgB,CAAC,IAAI,0BAA0B,CAAC;AAC/E,CAAC","sourcesContent":["import { uptime as osUptimeSeconds } from \"node:os\";\n\n/**\n * Two boot instants further apart than this belong to different boots. `os.uptime()` is\n * integral seconds on every platform, and a laptop's sleep is accounted in uptime, so the\n * only drift left is sub-second rounding on either side.\n */\nexport const BOOT_INSTANT_TOLERANCE_MS = 120_000;\n\n/** Two process start instants further apart than this are different processes (ps/lstart is second-precise). */\nexport const PROCESS_START_TOLERANCE_MS = 3_000;\n\nconst wholeSeconds = (ms: number): number => Math.round(ms / 1000) * 1000;\n\nexport function processBootAtMs(now: () => number = Date.now): number {\n\treturn wholeSeconds(now() - osUptimeSeconds() * 1000);\n}\n\nconst floorToSecond = (ms: number): number => Math.floor(ms / 1000) * 1000;\n\n/**\n * Captured once at load: `process.uptime()` runs on a monotonic clock that stops during a Linux\n * suspend, so recomputing later would drift by every suspend and read our own live lease as reused.\n */\nconst OWN_START_AT_LOAD = floorToSecond(Date.now() - process.uptime() * 1000);\n\n/** Floored like `ps -o lstart`, which truncates to the second: rounding up could land after now. */\nexport function ownProcessStartedAtMs(now?: () => number): number {\n\treturn now === undefined ? OWN_START_AT_LOAD : floorToSecond(now() - process.uptime() * 1000);\n}\n\nexport function sameBoot(bootAtMs: number, otherBootAtMs: number | undefined): boolean {\n\tif (otherBootAtMs === undefined || !Number.isFinite(otherBootAtMs)) return false;\n\treturn Math.abs(bootAtMs - otherBootAtMs) <= BOOT_INSTANT_TOLERANCE_MS;\n}\n\nexport function sameProcessStart(startedAtMs: number, otherStartedAtMs: number | undefined): boolean {\n\tif (otherStartedAtMs === undefined || !Number.isFinite(otherStartedAtMs)) return false;\n\treturn Math.abs(startedAtMs - otherStartedAtMs) <= PROCESS_START_TOLERANCE_MS;\n}\n\nexport interface ChildProcessIdentity {\n\treadonly pid: number;\n\treadonly processGroupId?: number;\n\treadonly startedAtMs: number;\n\treadonly bootAtMs: number;\n\treadonly argv: readonly string[];\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When the process currently wearing `pid` started, as the OS reports it; `undefined` when the
|
|
3
|
+
* platform cannot say. Spawns on darwin/win32, so callers keep it off every hot path.
|
|
4
|
+
*/
|
|
5
|
+
export declare function readProcessStartMs(pid: number): Promise<number | undefined>;
|
|
6
|
+
//# sourceMappingURL=process-start-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-start-probe.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/process-start-probe.ts"],"names":[],"mappings":"AAwCA;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAejF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
const LINUX_CLOCK_TICKS_PER_SECOND = 100;
|
|
4
|
+
async function linuxProcessStartMs(pid) {
|
|
5
|
+
const [stat, systemStat] = await Promise.all([
|
|
6
|
+
readFile(`/proc/${pid}/stat`, "utf8"),
|
|
7
|
+
readFile("/proc/stat", "utf8"),
|
|
8
|
+
]);
|
|
9
|
+
const afterComm = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
|
|
10
|
+
const startTicks = Number(afterComm[19]);
|
|
11
|
+
const bootSeconds = Number(/^btime (\d+)/m.exec(systemStat)?.[1]);
|
|
12
|
+
if (!Number.isFinite(startTicks) || !Number.isFinite(bootSeconds))
|
|
13
|
+
return undefined;
|
|
14
|
+
return Math.round((bootSeconds + startTicks / LINUX_CLOCK_TICKS_PER_SECOND) * 1000);
|
|
15
|
+
}
|
|
16
|
+
function execText(command, args) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
execFile(command, [...args], { encoding: "utf8", timeout: 5_000, windowsHide: true }, (error, stdout) => {
|
|
19
|
+
if (error)
|
|
20
|
+
reject(error);
|
|
21
|
+
else
|
|
22
|
+
resolve(stdout);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async function darwinProcessStartMs(pid) {
|
|
27
|
+
const text = (await execText("ps", ["-o", "lstart=", "-p", String(pid)])).trim();
|
|
28
|
+
if (text.length === 0)
|
|
29
|
+
return undefined;
|
|
30
|
+
const parsed = new Date(text).getTime();
|
|
31
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
32
|
+
}
|
|
33
|
+
async function windowsProcessStartMs(pid) {
|
|
34
|
+
const script = `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().ToString('o')`;
|
|
35
|
+
const text = (await execText("powershell", ["-NoProfile", "-NonInteractive", "-Command", script])).trim();
|
|
36
|
+
const parsed = new Date(text).getTime();
|
|
37
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* When the process currently wearing `pid` started, as the OS reports it; `undefined` when the
|
|
41
|
+
* platform cannot say. Spawns on darwin/win32, so callers keep it off every hot path.
|
|
42
|
+
*/
|
|
43
|
+
export async function readProcessStartMs(pid) {
|
|
44
|
+
try {
|
|
45
|
+
switch (process.platform) {
|
|
46
|
+
case "linux":
|
|
47
|
+
return await linuxProcessStartMs(pid);
|
|
48
|
+
case "darwin":
|
|
49
|
+
return await darwinProcessStartMs(pid);
|
|
50
|
+
case "win32":
|
|
51
|
+
return await windowsProcessStartMs(pid);
|
|
52
|
+
default:
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=process-start-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-start-probe.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/process-start-probe.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\n\nconst LINUX_CLOCK_TICKS_PER_SECOND = 100;\n\nasync function linuxProcessStartMs(pid: number): Promise<number | undefined> {\n\tconst [stat, systemStat] = await Promise.all([\n\t\treadFile(`/proc/${pid}/stat`, \"utf8\"),\n\t\treadFile(\"/proc/stat\", \"utf8\"),\n\t]);\n\tconst afterComm = stat.slice(stat.lastIndexOf(\")\") + 2).split(\" \");\n\tconst startTicks = Number(afterComm[19]);\n\tconst bootSeconds = Number(/^btime (\\d+)/m.exec(systemStat)?.[1]);\n\tif (!Number.isFinite(startTicks) || !Number.isFinite(bootSeconds)) return undefined;\n\treturn Math.round((bootSeconds + startTicks / LINUX_CLOCK_TICKS_PER_SECOND) * 1000);\n}\n\nfunction execText(command: string, args: readonly string[]): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\texecFile(command, [...args], { encoding: \"utf8\", timeout: 5_000, windowsHide: true }, (error, stdout) => {\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(stdout);\n\t\t});\n\t});\n}\n\nasync function darwinProcessStartMs(pid: number): Promise<number | undefined> {\n\tconst text = (await execText(\"ps\", [\"-o\", \"lstart=\", \"-p\", String(pid)])).trim();\n\tif (text.length === 0) return undefined;\n\tconst parsed = new Date(text).getTime();\n\treturn Number.isFinite(parsed) ? parsed : undefined;\n}\n\nasync function windowsProcessStartMs(pid: number): Promise<number | undefined> {\n\tconst script = `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().ToString('o')`;\n\tconst text = (await execText(\"powershell\", [\"-NoProfile\", \"-NonInteractive\", \"-Command\", script])).trim();\n\tconst parsed = new Date(text).getTime();\n\treturn Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * When the process currently wearing `pid` started, as the OS reports it; `undefined` when the\n * platform cannot say. Spawns on darwin/win32, so callers keep it off every hot path.\n */\nexport async function readProcessStartMs(pid: number): Promise<number | undefined> {\n\ttry {\n\t\tswitch (process.platform) {\n\t\t\tcase \"linux\":\n\t\t\t\treturn await linuxProcessStartMs(pid);\n\t\t\tcase \"darwin\":\n\t\t\t\treturn await darwinProcessStartMs(pid);\n\t\t\tcase \"win32\":\n\t\t\t\treturn await windowsProcessStartMs(pid);\n\t\t\tdefault:\n\t\t\t\treturn undefined;\n\t\t}\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/prompt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/prompt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CA+CjF"}
|
|
@@ -30,16 +30,20 @@ manual \`&\` backgrounding — use the built-in session tools:
|
|
|
30
30
|
events while you keep working; command exit always delivers a summary. One-shot gate: wait
|
|
31
31
|
inside the command and print one sentinel (\`until <cond>; do sleep 1; done;
|
|
32
32
|
printf 'READY\\n'\`). Stream: \`tail -n 0 -F | grep --line-buffered\`. Filter noise at the
|
|
33
|
-
source and stop with \`kill_bash\`.
|
|
33
|
+
source and stop with \`kill_bash\`. Persistent command watches are re-run after a restart with
|
|
34
|
+
\`SENPI_MONITOR_RESTORED=1\`; keep any baseline in \`$SENPI_MONITOR_STATE_DIR\` so a move during
|
|
35
|
+
downtime (at most \`$SENPI_MONITOR_DOWNTIME_MS\` ms) is still reported:
|
|
36
|
+
\`b="$SENPI_MONITOR_STATE_DIR/base"; p=$(cat "$b" 2>/dev/null || git rev-parse origin/main | tee "$b"); while sleep 30; do git fetch -q || true; n=$(git rev-parse origin/main); [ "$n" != "$p" ] && { echo "MOVED $p..$n"; p=$n; echo "$p" > "$b"; }; done\`.
|
|
37
|
+
A watch whose command exits is not restarted, so keep failures inside the loop non-fatal.
|
|
34
38
|
- \`${monitor}({ description, path, event?, persistent? })\` natively watches one regular file and
|
|
35
39
|
fires once — prefer it over a shell poll loop. \`"create"\` (the default) fires only when the file
|
|
36
40
|
appears after registration, so watch an already-existing file with \`"modify"\`; registration needs
|
|
37
41
|
the parent directory to exist already, so poll with a \`command\` when the run creates that
|
|
38
42
|
directory too. This branch takes no \`filter\`.
|
|
39
43
|
A standing watch is marked \`persistent: true\`: it has no deadline, survives a session restart
|
|
40
|
-
(the
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
(the file is rescanned and any change missed while detached reported), expires 7 days after
|
|
45
|
+
creation, is capped at 5 per session, and is accounted for in one restart-report line on
|
|
46
|
+
session start.
|
|
43
47
|
Identical updates are deduped; repeated monitor-only wakes pause the noisy monitor(s) that
|
|
44
48
|
caused them, not all monitors. Completion still wakes the session, and
|
|
45
49
|
\`${monitor}({ action: "rearm", bash_id })\` resumes one while \`${monitor}({ action: "rearm" })\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/prompt.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAA8B;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,OAAO;;;;;;MAMF,IAAI;;;;;;;;MAQJ,OAAO;;QAEL,OAAO
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/prompt.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAA8B;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,OAAO;;;;;;MAMF,IAAI;;;;;;;;MAQJ,OAAO;;QAEL,OAAO;;;;;;;;;;QAUP,OAAO;;;;;;;;;;;MAWT,OAAO,wDAAwD,OAAO;;;;;;CAM3E,CAAC;AACF,CAAC","sourcesContent":["export interface TerminalPromptOptions {\n\t/** True when the session routes shell tools through eval cells, so call shapes must be `tool.<name>(`. */\n\treadonly evalOnly: boolean;\n}\n\n/**\n * System-prompt guidance for the persistent-terminal tool suite (CC-close, snake_case).\n *\n * `bash` and `monitor` leave the model's direct tool list whenever the session has an\n * `eval` tool, so their call shapes are rendered per branch: a hardcoded direct shape\n * would teach a call the model cannot make. The steering companions\n * (`bash_output`/`bash_input`/`bash_resize`/`kill_bash`) stay directly callable in both.\n */\nexport function buildTerminalPromptSection(options: TerminalPromptOptions): string {\n\tconst bash = options.evalOnly ? \"tool.bash\" : \"bash\";\n\tconst monitor = options.evalOnly ? \"tool.monitor\" : \"monitor\";\n\treturn `\n## Persistent terminal sessions\n\nThe \\`bash\\` tool is PTY-backed. For long-running or interactive work, do NOT use tmux or\nmanual \\`&\\` backgrounding — use the built-in session tools:\n\n- \\`${bash}({ command, run_in_background: true })\\` starts a persistent session and returns a\n \\`bash_id\\` immediately. Foreground calls still block and return output; their \\`timeout\\`\n (seconds) is a kill deadline. Background sessions ignore \\`timeout\\` and live until they\n exit or you call \\`kill_bash\\`.\n- \\`bash_output({ bash_id, filter, view })\\` peeks at a session without blocking: new output\n since the last read, the status line, or a rendered full-screen snapshot of TUIs via\n \\`view: \"screen\"\\`. Completion arrives as a notification carrying the exit code and output\n tail — peeking is for steering, never for waiting.\n- \\`${monitor}\\` subscribes you to a change. Pass \\`command\\` XOR \\`path\\` — one branch per call,\n never both:\n - \\`${monitor}({ description, command, filter?, timeout_ms?, persistent? })\\` watches a command:\n newline-terminated PTY output lines (stderr included) matching \\`filter\\` arrive as injected\n events while you keep working; command exit always delivers a summary. One-shot gate: wait\n inside the command and print one sentinel (\\`until <cond>; do sleep 1; done;\n printf 'READY\\\\n'\\`). Stream: \\`tail -n 0 -F | grep --line-buffered\\`. Filter noise at the\n source and stop with \\`kill_bash\\`. Persistent command watches are re-run after a restart with\n \\`SENPI_MONITOR_RESTORED=1\\`; keep any baseline in \\`$SENPI_MONITOR_STATE_DIR\\` so a move during\n downtime (at most \\`$SENPI_MONITOR_DOWNTIME_MS\\` ms) is still reported:\n \\`b=\"$SENPI_MONITOR_STATE_DIR/base\"; p=$(cat \"$b\" 2>/dev/null || git rev-parse origin/main | tee \"$b\"); while sleep 30; do git fetch -q || true; n=$(git rev-parse origin/main); [ \"$n\" != \"$p\" ] && { echo \"MOVED $p..$n\"; p=$n; echo \"$p\" > \"$b\"; }; done\\`.\n A watch whose command exits is not restarted, so keep failures inside the loop non-fatal.\n - \\`${monitor}({ description, path, event?, persistent? })\\` natively watches one regular file and\n fires once — prefer it over a shell poll loop. \\`\"create\"\\` (the default) fires only when the file\n appears after registration, so watch an already-existing file with \\`\"modify\"\\`; registration needs\n the parent directory to exist already, so poll with a \\`command\\` when the run creates that\n directory too. This branch takes no \\`filter\\`.\n A standing watch is marked \\`persistent: true\\`: it has no deadline, survives a session restart\n (the file is rescanned and any change missed while detached reported), expires 7 days after\n creation, is capped at 5 per session, and is accounted for in one restart-report line on\n session start.\n Identical updates are deduped; repeated monitor-only wakes pause the noisy monitor(s) that\n caused them, not all monitors. Completion still wakes the session, and\n \\`${monitor}({ action: \"rearm\", bash_id })\\` resumes one while \\`${monitor}({ action: \"rearm\" })\\`\n resumes all paused monitors; real user input also resumes paused monitors.\n- \\`bash_input({ bash_id, input, keys, submit })\\` sends stdin or named keys (e.g.\n \\`[\"ctrl+c\"]\\`, \\`[\"enter\"]\\`) to steer a REPL or interrupt a process.\n- \\`bash_resize({ bash_id, cols, rows })\\` resizes the PTY so full-screen programs reflow.\n- \\`kill_bash({ bash_id })\\` (or \\`{ all: true }\\`) tears the session tree down with no orphans.\n`;\n}\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE restore digest a generation sends after a restart: a single sentence naming every
|
|
3
|
+
* monitor and background session, structured details for the TUI renderer, and a pending slot
|
|
4
|
+
* so a digest decided before a model is bound is delivered later instead of dropped.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExtensionAPI, MessageRenderer } from "../../types.ts";
|
|
7
|
+
import type { BackgroundRestoreResult, MonitorRestoreResult, RestoreDigest } from "./restore.ts";
|
|
8
|
+
export declare const RESTORE_DIGEST_CUSTOM_TYPE = "senpi-terminal:restore-digest";
|
|
9
|
+
export type RestoreDigestOutcome = "decided" | "deferred" | "corrupt";
|
|
10
|
+
export interface RestoreDigestDetails {
|
|
11
|
+
readonly generation: number;
|
|
12
|
+
readonly outcome: RestoreDigestOutcome;
|
|
13
|
+
readonly downtimeMs: number;
|
|
14
|
+
readonly downtimeIsUpperBound: true;
|
|
15
|
+
readonly holder?: {
|
|
16
|
+
readonly pid: number;
|
|
17
|
+
};
|
|
18
|
+
readonly actionable: boolean;
|
|
19
|
+
readonly monitors: readonly MonitorRestoreResult[];
|
|
20
|
+
readonly backgroundSessions: readonly BackgroundRestoreResult[];
|
|
21
|
+
}
|
|
22
|
+
export interface RestoreDigestMessage {
|
|
23
|
+
readonly customType: typeof RESTORE_DIGEST_CUSTOM_TYPE;
|
|
24
|
+
readonly content: string;
|
|
25
|
+
readonly display: true;
|
|
26
|
+
readonly details: RestoreDigestDetails;
|
|
27
|
+
}
|
|
28
|
+
/** The slice of `ExtensionContext` delivery needs; `ExtensionContext` satisfies it. */
|
|
29
|
+
export interface RestoreDigestContext {
|
|
30
|
+
readonly model: unknown;
|
|
31
|
+
readonly ui?: {
|
|
32
|
+
notify(message: string, type?: "info" | "warning" | "error"): void;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface DigestSlot {
|
|
36
|
+
set(message: RestoreDigestMessage): void;
|
|
37
|
+
pending(): RestoreDigestMessage | undefined;
|
|
38
|
+
/** Deliver the pending message; `deliver` returning false keeps it pending for a later flush. */
|
|
39
|
+
flush(deliver: (message: RestoreDigestMessage) => boolean): boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Wake the agent only when something needs a decision: a lost watch, an orphan, a live background job. */
|
|
42
|
+
export declare function isActionable(digest: Pick<RestoreDigest, "results" | "backgroundSessions">): boolean;
|
|
43
|
+
export declare function buildRestoreDigest(digest: RestoreDigest, meta: {
|
|
44
|
+
readonly generation: number;
|
|
45
|
+
readonly outcome: RestoreDigestOutcome;
|
|
46
|
+
readonly holderPid?: number;
|
|
47
|
+
}): RestoreDigestMessage;
|
|
48
|
+
export declare function createDigestSlot(): DigestSlot;
|
|
49
|
+
/** Returns false (message stays pending) while no model is bound: a turn without one cannot run. */
|
|
50
|
+
export declare function deliverRestoreDigest(pi: Pick<ExtensionAPI, "sendMessage">, ctx: RestoreDigestContext | undefined, message: RestoreDigestMessage): boolean;
|
|
51
|
+
export declare function registerRestoreDigestRenderer(pi: {
|
|
52
|
+
registerMessageRenderer(customType: string, renderer: MessageRenderer<RestoreDigestDetails>): void;
|
|
53
|
+
}): void;
|
|
54
|
+
//# sourceMappingURL=restore-digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore-digest.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/restore-digest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEjG,eAAO,MAAM,0BAA0B,kCAAkC,CAAC;AAI1E,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACnD,QAAQ,CAAC,kBAAkB,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAChE;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,UAAU,EAAE,OAAO,0BAA0B,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACvC;AAED,uFAAuF;AACvF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrF;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACzC,OAAO,IAAI,oBAAoB,GAAG,SAAS,CAAC;IAC5C,iGAAiG;IACjG,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,GAAG,OAAO,CAAC;CACpE;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,oBAAoB,CAAC,GAAG,OAAO,CAKnG;AAmCD,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxG,oBAAoB,CA0BtB;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAqB7C;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,CACnC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EACrC,GAAG,EAAE,oBAAoB,GAAG,SAAS,EACrC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAMT;AA0BD,wBAAgB,6BAA6B,CAAC,EAAE,EAAE;IACjD,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC;CACnG,GAAG,IAAI,CAEP"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE restore digest a generation sends after a restart: a single sentence naming every
|
|
3
|
+
* monitor and background session, structured details for the TUI renderer, and a pending slot
|
|
4
|
+
* so a digest decided before a model is bound is delivered later instead of dropped.
|
|
5
|
+
*/
|
|
6
|
+
import { noticeMessageRenderer } from "../../notice/index.js";
|
|
7
|
+
import { formatElapsedSeconds } from "./monitor-status.js";
|
|
8
|
+
export const RESTORE_DIGEST_CUSTOM_TYPE = "senpi-terminal:restore-digest";
|
|
9
|
+
const PREFIX = "Terminal state after restart";
|
|
10
|
+
const BUCKETS = ["restored", "muted", "lost", "completed", "attachedElsewhere", "expired"];
|
|
11
|
+
/** Wake the agent only when something needs a decision: a lost watch, an orphan, a live background job. */
|
|
12
|
+
export function isActionable(digest) {
|
|
13
|
+
return (digest.results.some((result) => result.outcome === "lost" || result.orphan !== undefined) ||
|
|
14
|
+
digest.backgroundSessions.some((session) => session.outcome === "running"));
|
|
15
|
+
}
|
|
16
|
+
const label = (result) => `${result.monitorId} "${result.description}"`;
|
|
17
|
+
const outcomeName = (outcome) => outcome.replace(/[A-Z]/g, (letter) => ` ${letter.toLowerCase()}`);
|
|
18
|
+
const downtimeNote = (ms) => (ms > 0 ? ` (offline up to ${formatElapsedSeconds(ms / 1000)})` : "");
|
|
19
|
+
function orphanNote(orphan) {
|
|
20
|
+
return `orphan pid ${orphan.pid} ${orphan.action === "killed" ? "killed" : "left running"}`;
|
|
21
|
+
}
|
|
22
|
+
function sentenceEntry(result) {
|
|
23
|
+
const revived = result.outcome === "restored" || result.outcome === "muted";
|
|
24
|
+
const fallback = revived ? (result.kind === "file" ? "rechecked" : "respawned") : undefined;
|
|
25
|
+
const notes = [result.reason ?? fallback, result.orphan && orphanNote(result.orphan)].filter((note) => note);
|
|
26
|
+
return notes.length > 0 ? `${label(result)} (${notes.join(", ")})` : label(result);
|
|
27
|
+
}
|
|
28
|
+
function backgroundEntry(session) {
|
|
29
|
+
if (session.outcome === "exited")
|
|
30
|
+
return `${session.id} exited`;
|
|
31
|
+
const pid = session.pid === undefined ? "" : `pid ${session.pid}, `;
|
|
32
|
+
return `${session.id} "${session.command}" still running (${pid}output not captured)`;
|
|
33
|
+
}
|
|
34
|
+
function decidedSentence(digest) {
|
|
35
|
+
const clauses = [];
|
|
36
|
+
for (const outcome of BUCKETS) {
|
|
37
|
+
const entries = digest.results.filter((result) => result.outcome === outcome).map(sentenceEntry);
|
|
38
|
+
if (entries.length > 0)
|
|
39
|
+
clauses.push(`${outcomeName(outcome)} ${entries.length} - ${entries.join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
if (digest.backgroundSessions.length > 0) {
|
|
42
|
+
clauses.push(`background: ${digest.backgroundSessions.map(backgroundEntry).join(", ")}`);
|
|
43
|
+
}
|
|
44
|
+
return `${PREFIX}${downtimeNote(digest.downtimeMs)}: ${clauses.join("; ") || "nothing to restore"}.`;
|
|
45
|
+
}
|
|
46
|
+
export function buildRestoreDigest(digest, meta) {
|
|
47
|
+
const outcome = meta.outcome === "decided" && digest.storeError ? "corrupt" : meta.outcome;
|
|
48
|
+
const holder = meta.holderPid === undefined ? undefined : `pid ${meta.holderPid}`;
|
|
49
|
+
const content = outcome === "deferred"
|
|
50
|
+
? holder === undefined
|
|
51
|
+
? `${PREFIX}: waiting for the session lease; monitors come back here once it is acquired.`
|
|
52
|
+
: `${PREFIX}: monitors held by ${holder}; they come back here when that process exits.`
|
|
53
|
+
: outcome === "corrupt"
|
|
54
|
+
? `${PREFIX}: the saved monitor state was unreadable, nothing was restored.`
|
|
55
|
+
: decidedSentence(digest);
|
|
56
|
+
return {
|
|
57
|
+
customType: RESTORE_DIGEST_CUSTOM_TYPE,
|
|
58
|
+
content,
|
|
59
|
+
display: true,
|
|
60
|
+
details: {
|
|
61
|
+
generation: meta.generation,
|
|
62
|
+
outcome,
|
|
63
|
+
downtimeMs: digest.downtimeMs,
|
|
64
|
+
downtimeIsUpperBound: true,
|
|
65
|
+
...(meta.holderPid === undefined ? {} : { holder: { pid: meta.holderPid } }),
|
|
66
|
+
actionable: isActionable(digest),
|
|
67
|
+
monitors: digest.results,
|
|
68
|
+
backgroundSessions: digest.backgroundSessions,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function createDigestSlot() {
|
|
73
|
+
let pendingMessage;
|
|
74
|
+
// Exactly one decided digest per generation: once one is delivered, later ones are ignored,
|
|
75
|
+
// and a deferred note never displaces a decided digest still waiting for a model.
|
|
76
|
+
let decidedDelivered = false;
|
|
77
|
+
const isDecided = (message) => message.details.outcome !== "deferred";
|
|
78
|
+
return {
|
|
79
|
+
set(message) {
|
|
80
|
+
if (decidedDelivered)
|
|
81
|
+
return;
|
|
82
|
+
if (!isDecided(message) && pendingMessage !== undefined && isDecided(pendingMessage))
|
|
83
|
+
return;
|
|
84
|
+
pendingMessage = message;
|
|
85
|
+
},
|
|
86
|
+
pending: () => pendingMessage,
|
|
87
|
+
flush(deliver) {
|
|
88
|
+
const message = pendingMessage;
|
|
89
|
+
if (message === undefined || !deliver(message))
|
|
90
|
+
return false;
|
|
91
|
+
pendingMessage = undefined;
|
|
92
|
+
if (isDecided(message))
|
|
93
|
+
decidedDelivered = true;
|
|
94
|
+
return true;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** Returns false (message stays pending) while no model is bound: a turn without one cannot run. */
|
|
99
|
+
export function deliverRestoreDigest(pi, ctx, message) {
|
|
100
|
+
if (ctx?.model === undefined)
|
|
101
|
+
return false;
|
|
102
|
+
ctx.ui?.notify(message.content, "info");
|
|
103
|
+
const actionable = message.details.actionable;
|
|
104
|
+
pi.sendMessage(message, { triggerTurn: actionable, deliverAs: actionable ? "followUp" : "nextTurn" });
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
function monitorLine(result) {
|
|
108
|
+
const reason = result.reason === undefined ? "" : `: ${result.reason}`;
|
|
109
|
+
const orphan = result.orphan === undefined ? "" : ` (${orphanNote(result.orphan)})`;
|
|
110
|
+
const tone = result.outcome === "lost" || result.orphan !== undefined ? "warning" : "dim";
|
|
111
|
+
return { text: `${label(result)} ${outcomeName(result.outcome)}${reason}${orphan}`, tone };
|
|
112
|
+
}
|
|
113
|
+
const renderRestoreDigest = noticeMessageRenderer((message) => {
|
|
114
|
+
const details = message.details;
|
|
115
|
+
if (details === undefined)
|
|
116
|
+
return undefined;
|
|
117
|
+
const sessions = details.backgroundSessions;
|
|
118
|
+
const counts = `${details.monitors.length} monitors · ${sessions.length} background sessions`;
|
|
119
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
120
|
+
return {
|
|
121
|
+
title: `${PREFIX}${downtimeNote(details.downtimeMs)}`,
|
|
122
|
+
tone: details.actionable ? "warning" : "accent",
|
|
123
|
+
why: details.outcome === "decided" ? counts : content.slice(PREFIX.length + 2),
|
|
124
|
+
extra: [
|
|
125
|
+
...details.monitors.map(monitorLine),
|
|
126
|
+
...sessions.map((session) => ({ text: backgroundEntry(session), tone: "dim" })),
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
export function registerRestoreDigestRenderer(pi) {
|
|
131
|
+
pi.registerMessageRenderer(RESTORE_DIGEST_CUSTOM_TYPE, renderRestoreDigest);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=restore-digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore-digest.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/restore-digest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ONE restore digest a generation sends after a restart: a single sentence naming every\n * monitor and background session, structured details for the TUI renderer, and a pending slot\n * so a digest decided before a model is bound is delivered later instead of dropped.\n */\n\nimport { noticeMessageRenderer } from \"../../notice/index.ts\";\nimport type { NoticeLine } from \"../../notice/spec.ts\";\nimport type { ExtensionAPI, MessageRenderer } from \"../../types.ts\";\nimport { formatElapsedSeconds } from \"./monitor-status.ts\";\nimport type { BackgroundRestoreResult, MonitorRestoreResult, RestoreDigest } from \"./restore.ts\";\n\nexport const RESTORE_DIGEST_CUSTOM_TYPE = \"senpi-terminal:restore-digest\";\nconst PREFIX = \"Terminal state after restart\";\nconst BUCKETS = [\"restored\", \"muted\", \"lost\", \"completed\", \"attachedElsewhere\", \"expired\"] as const;\n\nexport type RestoreDigestOutcome = \"decided\" | \"deferred\" | \"corrupt\";\n\nexport interface RestoreDigestDetails {\n\treadonly generation: number;\n\treadonly outcome: RestoreDigestOutcome;\n\treadonly downtimeMs: number;\n\treadonly downtimeIsUpperBound: true;\n\treadonly holder?: { readonly pid: number };\n\treadonly actionable: boolean;\n\treadonly monitors: readonly MonitorRestoreResult[];\n\treadonly backgroundSessions: readonly BackgroundRestoreResult[];\n}\n\nexport interface RestoreDigestMessage {\n\treadonly customType: typeof RESTORE_DIGEST_CUSTOM_TYPE;\n\treadonly content: string;\n\treadonly display: true;\n\treadonly details: RestoreDigestDetails;\n}\n\n/** The slice of `ExtensionContext` delivery needs; `ExtensionContext` satisfies it. */\nexport interface RestoreDigestContext {\n\treadonly model: unknown;\n\treadonly ui?: { notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void };\n}\n\nexport interface DigestSlot {\n\tset(message: RestoreDigestMessage): void;\n\tpending(): RestoreDigestMessage | undefined;\n\t/** Deliver the pending message; `deliver` returning false keeps it pending for a later flush. */\n\tflush(deliver: (message: RestoreDigestMessage) => boolean): boolean;\n}\n\n/** Wake the agent only when something needs a decision: a lost watch, an orphan, a live background job. */\nexport function isActionable(digest: Pick<RestoreDigest, \"results\" | \"backgroundSessions\">): boolean {\n\treturn (\n\t\tdigest.results.some((result) => result.outcome === \"lost\" || result.orphan !== undefined) ||\n\t\tdigest.backgroundSessions.some((session) => session.outcome === \"running\")\n\t);\n}\n\nconst label = (result: MonitorRestoreResult) => `${result.monitorId} \"${result.description}\"`;\nconst outcomeName = (outcome: string) => outcome.replace(/[A-Z]/g, (letter) => ` ${letter.toLowerCase()}`);\nconst downtimeNote = (ms: number) => (ms > 0 ? ` (offline up to ${formatElapsedSeconds(ms / 1000)})` : \"\");\n\nfunction orphanNote(orphan: NonNullable<MonitorRestoreResult[\"orphan\"]>): string {\n\treturn `orphan pid ${orphan.pid} ${orphan.action === \"killed\" ? \"killed\" : \"left running\"}`;\n}\n\nfunction sentenceEntry(result: MonitorRestoreResult): string {\n\tconst revived = result.outcome === \"restored\" || result.outcome === \"muted\";\n\tconst fallback = revived ? (result.kind === \"file\" ? \"rechecked\" : \"respawned\") : undefined;\n\tconst notes = [result.reason ?? fallback, result.orphan && orphanNote(result.orphan)].filter((note) => note);\n\treturn notes.length > 0 ? `${label(result)} (${notes.join(\", \")})` : label(result);\n}\n\nfunction backgroundEntry(session: BackgroundRestoreResult): string {\n\tif (session.outcome === \"exited\") return `${session.id} exited`;\n\tconst pid = session.pid === undefined ? \"\" : `pid ${session.pid}, `;\n\treturn `${session.id} \"${session.command}\" still running (${pid}output not captured)`;\n}\n\nfunction decidedSentence(digest: RestoreDigest): string {\n\tconst clauses: string[] = [];\n\tfor (const outcome of BUCKETS) {\n\t\tconst entries = digest.results.filter((result) => result.outcome === outcome).map(sentenceEntry);\n\t\tif (entries.length > 0) clauses.push(`${outcomeName(outcome)} ${entries.length} - ${entries.join(\", \")}`);\n\t}\n\tif (digest.backgroundSessions.length > 0) {\n\t\tclauses.push(`background: ${digest.backgroundSessions.map(backgroundEntry).join(\", \")}`);\n\t}\n\treturn `${PREFIX}${downtimeNote(digest.downtimeMs)}: ${clauses.join(\"; \") || \"nothing to restore\"}.`;\n}\n\nexport function buildRestoreDigest(\n\tdigest: RestoreDigest,\n\tmeta: { readonly generation: number; readonly outcome: RestoreDigestOutcome; readonly holderPid?: number },\n): RestoreDigestMessage {\n\tconst outcome = meta.outcome === \"decided\" && digest.storeError ? \"corrupt\" : meta.outcome;\n\tconst holder = meta.holderPid === undefined ? undefined : `pid ${meta.holderPid}`;\n\tconst content =\n\t\toutcome === \"deferred\"\n\t\t\t? holder === undefined\n\t\t\t\t? `${PREFIX}: waiting for the session lease; monitors come back here once it is acquired.`\n\t\t\t\t: `${PREFIX}: monitors held by ${holder}; they come back here when that process exits.`\n\t\t\t: outcome === \"corrupt\"\n\t\t\t\t? `${PREFIX}: the saved monitor state was unreadable, nothing was restored.`\n\t\t\t\t: decidedSentence(digest);\n\treturn {\n\t\tcustomType: RESTORE_DIGEST_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tgeneration: meta.generation,\n\t\t\toutcome,\n\t\t\tdowntimeMs: digest.downtimeMs,\n\t\t\tdowntimeIsUpperBound: true,\n\t\t\t...(meta.holderPid === undefined ? {} : { holder: { pid: meta.holderPid } }),\n\t\t\tactionable: isActionable(digest),\n\t\t\tmonitors: digest.results,\n\t\t\tbackgroundSessions: digest.backgroundSessions,\n\t\t},\n\t};\n}\n\nexport function createDigestSlot(): DigestSlot {\n\tlet pendingMessage: RestoreDigestMessage | undefined;\n\t// Exactly one decided digest per generation: once one is delivered, later ones are ignored,\n\t// and a deferred note never displaces a decided digest still waiting for a model.\n\tlet decidedDelivered = false;\n\tconst isDecided = (message: RestoreDigestMessage) => message.details.outcome !== \"deferred\";\n\treturn {\n\t\tset(message) {\n\t\t\tif (decidedDelivered) return;\n\t\t\tif (!isDecided(message) && pendingMessage !== undefined && isDecided(pendingMessage)) return;\n\t\t\tpendingMessage = message;\n\t\t},\n\t\tpending: () => pendingMessage,\n\t\tflush(deliver) {\n\t\t\tconst message = pendingMessage;\n\t\t\tif (message === undefined || !deliver(message)) return false;\n\t\t\tpendingMessage = undefined;\n\t\t\tif (isDecided(message)) decidedDelivered = true;\n\t\t\treturn true;\n\t\t},\n\t};\n}\n\n/** Returns false (message stays pending) while no model is bound: a turn without one cannot run. */\nexport function deliverRestoreDigest(\n\tpi: Pick<ExtensionAPI, \"sendMessage\">,\n\tctx: RestoreDigestContext | undefined,\n\tmessage: RestoreDigestMessage,\n): boolean {\n\tif (ctx?.model === undefined) return false;\n\tctx.ui?.notify(message.content, \"info\");\n\tconst actionable = message.details.actionable;\n\tpi.sendMessage(message, { triggerTurn: actionable, deliverAs: actionable ? \"followUp\" : \"nextTurn\" });\n\treturn true;\n}\n\nfunction monitorLine(result: MonitorRestoreResult): NoticeLine {\n\tconst reason = result.reason === undefined ? \"\" : `: ${result.reason}`;\n\tconst orphan = result.orphan === undefined ? \"\" : ` (${orphanNote(result.orphan)})`;\n\tconst tone = result.outcome === \"lost\" || result.orphan !== undefined ? \"warning\" : \"dim\";\n\treturn { text: `${label(result)} ${outcomeName(result.outcome)}${reason}${orphan}`, tone };\n}\n\nconst renderRestoreDigest: MessageRenderer<RestoreDigestDetails> = noticeMessageRenderer((message) => {\n\tconst details = message.details;\n\tif (details === undefined) return undefined;\n\tconst sessions = details.backgroundSessions;\n\tconst counts = `${details.monitors.length} monitors · ${sessions.length} background sessions`;\n\tconst content = typeof message.content === \"string\" ? message.content : \"\";\n\treturn {\n\t\ttitle: `${PREFIX}${downtimeNote(details.downtimeMs)}`,\n\t\ttone: details.actionable ? \"warning\" : \"accent\",\n\t\twhy: details.outcome === \"decided\" ? counts : content.slice(PREFIX.length + 2),\n\t\textra: [\n\t\t\t...details.monitors.map(monitorLine),\n\t\t\t...sessions.map((session): NoticeLine => ({ text: backgroundEntry(session), tone: \"dim\" })),\n\t\t],\n\t};\n});\n\nexport function registerRestoreDigestRenderer(pi: {\n\tregisterMessageRenderer(customType: string, renderer: MessageRenderer<RestoreDigestDetails>): void;\n}): void {\n\tpi.registerMessageRenderer(RESTORE_DIGEST_CUSTOM_TYPE, renderRestoreDigest);\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A session's persistence lifecycle across process restarts: take the per-session lease, restore
|
|
3
|
+
* the persisted monitors on a detached promise (session_start never waits on a grace window), and
|
|
4
|
+
* deliver ONE decided digest through a slot that holds it until a model is bound. A live foreign
|
|
5
|
+
* holder defers everything: the footer says who holds the monitors, and a lease keeper takes the
|
|
6
|
+
* session over the moment that process exits, running the same restore exactly once. Monitors
|
|
7
|
+
* created while waiting are queued and reach the manifest after the takeover.
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
|
|
10
|
+
import { type LeaseKeeper } from "./lease-keeper.ts";
|
|
11
|
+
import { type DigestSlot } from "./restore-digest.ts";
|
|
12
|
+
import type { TerminalSessionBundle } from "./session-bundle.ts";
|
|
13
|
+
import { TerminalManifestWriter } from "./terminal-manifest.ts";
|
|
14
|
+
import type { TerminalToolContext } from "./tools/context.ts";
|
|
15
|
+
export declare const RESTORE_STATUS_KEY = "terminal-restore";
|
|
16
|
+
/** Test-only timing overrides; production uses the modules' own defaults. */
|
|
17
|
+
export declare const restoreSessionTestHooks: {
|
|
18
|
+
keeperIntervalMs?: number;
|
|
19
|
+
graceMs?: number;
|
|
20
|
+
};
|
|
21
|
+
export interface PersistenceState {
|
|
22
|
+
ctx: ExtensionContext | undefined;
|
|
23
|
+
readonly settings: {
|
|
24
|
+
readonly notify: string;
|
|
25
|
+
};
|
|
26
|
+
bundle: TerminalSessionBundle | null;
|
|
27
|
+
lease: {
|
|
28
|
+
path: string;
|
|
29
|
+
pid: number;
|
|
30
|
+
token: string;
|
|
31
|
+
} | null;
|
|
32
|
+
manifestWriter: TerminalManifestWriter | null;
|
|
33
|
+
ensurePersistence: (() => Promise<void>) | null;
|
|
34
|
+
recordedBackgroundIds: Set<string>;
|
|
35
|
+
keeper: LeaseKeeper | null;
|
|
36
|
+
digestSlot: DigestSlot;
|
|
37
|
+
generation: number;
|
|
38
|
+
restoreInFlight: Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
/** Settles once this session's current generation has decided its restore (or had nothing to decide). */
|
|
41
|
+
export declare function whenRestoreDecided(sessionKey: string): Promise<void>;
|
|
42
|
+
export declare function flushRestoreDigest(pi: ExtensionAPI, state: PersistenceState): void;
|
|
43
|
+
interface StartOptions {
|
|
44
|
+
readonly pi: ExtensionAPI;
|
|
45
|
+
readonly state: PersistenceState;
|
|
46
|
+
readonly toolCtx: TerminalToolContext;
|
|
47
|
+
readonly sessionKey: string;
|
|
48
|
+
}
|
|
49
|
+
/** Non-reload session_start (and a reload that does not hold the lease): take ownership or wait for it. */
|
|
50
|
+
export declare function startPersistence({ pi, state, toolCtx, sessionKey }: StartOptions): Promise<void>;
|
|
51
|
+
/** session_shutdown (not reload): stop waiting, finish any restore, suspend and flush, release. */
|
|
52
|
+
export declare function stopPersistence(state: PersistenceState, sessionKey: string): Promise<void>;
|
|
53
|
+
/** Detach the manifest recorder without writing (a reload keeps live state instead). */
|
|
54
|
+
export declare function detachPersistence(state: PersistenceState, sessionKey: string | undefined): void;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=restore-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore-session.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/restore-session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWxE,OAAO,EAAwC,KAAK,UAAU,EAAwB,MAAM,qBAAqB,CAAC;AAClH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAA+B,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAE7F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAIrD,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,CAAC;AAE3F,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3D,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,iBAAiB,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAaD,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAOlF;AA0DD,UAAU,YAAY;IACrB,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,2GAA2G;AAC3G,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHtG;AAED,mGAAmG;AACnG,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhG;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAK/F"}
|