@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
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getShellEnv } from "../../../../utils/shell.js";
|
|
1
|
+
import { join } from "node:path";
|
|
3
2
|
import { encodedSessionId } from "../../../session-sidecar-store.js";
|
|
4
3
|
import { SettingsManager } from "../../../settings-manager.js";
|
|
5
4
|
import { isAnthropicBashEnabled } from "../anthropic-bash/index.js";
|
|
6
5
|
import { isEvalOnlyRouting } from "../eval-only-routing.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { createCheckpointedFileRestoreHandler } from "./durable-file.js";
|
|
10
|
-
import { acquireTerminalLease, releaseTerminalLease } from "./manifest-lease.js";
|
|
6
|
+
import { buildToolContext, bundleSinks, createBundle, sessionKeyOf, } from "./extension-state.js";
|
|
7
|
+
import { currentLeaseToken, releaseTerminalLease, retireLeaseToken } from "./manifest-lease.js";
|
|
11
8
|
import { MonitorNotifier } from "./monitor-notify.js";
|
|
9
|
+
import { terminalStateDir } from "./monitor-state-dir.js";
|
|
12
10
|
import { MONITOR_STATUS_KEY } from "./monitor-status.js";
|
|
13
11
|
import { MonitorStatusTicker } from "./monitor-status-ticker.js";
|
|
14
|
-
import {
|
|
12
|
+
import { TerminalNotifier } from "./notify.js";
|
|
15
13
|
import { buildTerminalPromptSection } from "./prompt.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
14
|
+
import { createDigestSlot, registerRestoreDigestRenderer } from "./restore-digest.js";
|
|
15
|
+
import { detachPersistence, flushRestoreDigest, startPersistence, stopPersistence } from "./restore-session.js";
|
|
16
|
+
import { claimParkedBundle, parkBundle, teardownParkedBundle } from "./session-bundle.js";
|
|
18
17
|
import { loadTerminalSettings, TERMINAL_SETTINGS_DEFAULTS } from "./settings.js";
|
|
19
18
|
import { TERMINAL_BASH_TOOL, TERMINAL_COMPANION_TOOLS } from "./shared.js";
|
|
20
19
|
import { TerminalManifestWriter } from "./terminal-manifest.js";
|
|
@@ -23,141 +22,7 @@ import { createBashInputTool } from "./tools/bash-input.js";
|
|
|
23
22
|
import { createBashOutputTool } from "./tools/bash-output.js";
|
|
24
23
|
import { createBashResizeTool } from "./tools/bash-resize.js";
|
|
25
24
|
import { createKillBashTool } from "./tools/kill-bash.js";
|
|
26
|
-
import { bindTerminalManifestWriter, createMonitorTool
|
|
27
|
-
/** Tests and SDK callers may hand partial contexts without a session manager. */
|
|
28
|
-
function sessionKeyOf(ctx) {
|
|
29
|
-
return ctx?.sessionManager?.getSessionId?.();
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Per-session persistence dir for the terminal lease + manifest; undefined when the context
|
|
33
|
-
* carries no durable session dir (SDK/in-memory sessions must not persist terminal state).
|
|
34
|
-
*/
|
|
35
|
-
function terminalStateDir(ctx) {
|
|
36
|
-
const sessionDir = ctx?.sessionManager?.getSessionDir?.();
|
|
37
|
-
if (sessionDir === undefined || sessionDir.length === 0 || !isAbsolute(sessionDir))
|
|
38
|
-
return undefined;
|
|
39
|
-
return join(sessionDir, "extensions", "terminal");
|
|
40
|
-
}
|
|
41
|
-
function createBundle(state) {
|
|
42
|
-
return new TerminalSessionBundle({
|
|
43
|
-
maxSessions: state.settings.maxSessions,
|
|
44
|
-
scrollback: state.settings.scrollback,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
/** Sinks read the live instance state at call time, so notifier swaps need no re-bind. */
|
|
48
|
-
function bundleSinks(pi, state) {
|
|
49
|
-
return {
|
|
50
|
-
onMonitorEvent: (event) => state.monitorNotifier?.notifyEvent(event),
|
|
51
|
-
onMonitorEnded: (event) => {
|
|
52
|
-
pi.events?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);
|
|
53
|
-
pi.rpc?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);
|
|
54
|
-
},
|
|
55
|
-
onMonitorState: (snapshot, transition = true) => {
|
|
56
|
-
if (!state.parked)
|
|
57
|
-
state.statusTicker.sync(snapshot);
|
|
58
|
-
const payload = {
|
|
59
|
-
activeCount: snapshot.length,
|
|
60
|
-
monitors: snapshot.map((entry) => ({
|
|
61
|
-
id: entry.id,
|
|
62
|
-
description: entry.description,
|
|
63
|
-
paused: entry.paused,
|
|
64
|
-
startedAtMs: entry.startedAtMs,
|
|
65
|
-
command: entry.command,
|
|
66
|
-
filter: entry.filter,
|
|
67
|
-
persistent: entry.persistent,
|
|
68
|
-
deadlineMs: entry.deadlineMs,
|
|
69
|
-
fireCount: entry.fireCount,
|
|
70
|
-
lastFiredAtMs: entry.lastFiredAtMs,
|
|
71
|
-
})),
|
|
72
|
-
};
|
|
73
|
-
pi.events?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);
|
|
74
|
-
pi.rpc?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);
|
|
75
|
-
if (!transition)
|
|
76
|
-
return;
|
|
77
|
-
pi.events?.emit(WAKE_SOURCE_STATE_EVENT, {
|
|
78
|
-
source: "terminal-monitors",
|
|
79
|
-
activeCount: snapshot.length,
|
|
80
|
-
monitors: snapshot.map((entry) => ({
|
|
81
|
-
id: entry.id,
|
|
82
|
-
description: entry.description,
|
|
83
|
-
startedAtMs: entry.startedAtMs,
|
|
84
|
-
})),
|
|
85
|
-
});
|
|
86
|
-
if (state.manifestWriter)
|
|
87
|
-
void state.manifestWriter.observeMonitorState(snapshot);
|
|
88
|
-
},
|
|
89
|
-
onBackgroundState: (snapshot) => {
|
|
90
|
-
pi.events?.emit(WAKE_SOURCE_STATE_EVENT, {
|
|
91
|
-
source: "terminal-background-sessions",
|
|
92
|
-
activeCount: snapshot.length,
|
|
93
|
-
items: snapshot,
|
|
94
|
-
});
|
|
95
|
-
const writer = state.manifestWriter;
|
|
96
|
-
if (!writer)
|
|
97
|
-
return;
|
|
98
|
-
for (const entry of snapshot) {
|
|
99
|
-
if (state.recordedBackgroundIds.has(entry.id))
|
|
100
|
-
continue;
|
|
101
|
-
state.recordedBackgroundIds.add(entry.id);
|
|
102
|
-
void writer.recordBackgroundStart(entry.id, entry.description ?? entry.id, entry.startedAtMs);
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
onBackgroundExit: (id, runtime) => {
|
|
106
|
-
state.recordedBackgroundIds.delete(id);
|
|
107
|
-
if (state.manifestWriter)
|
|
108
|
-
void state.manifestWriter.recordBackgroundExit(id);
|
|
109
|
-
state.notifier?.notifyCompletion(id, runtime);
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function buildToolContext(pi, state) {
|
|
114
|
-
const requireBundle = () => {
|
|
115
|
-
// Lazily create a bundle so the tools work even when invoked directly (e.g. via the
|
|
116
|
-
// SDK) before `session_start` initializes one. `session_start` replaces it with a
|
|
117
|
-
// settings-configured bundle and tears down any earlier one.
|
|
118
|
-
if (!state.bundle) {
|
|
119
|
-
state.bundle = createBundle(state);
|
|
120
|
-
state.bundle.monitors.setParked(state.parked);
|
|
121
|
-
state.bundle.bind(bundleSinks(pi, state));
|
|
122
|
-
}
|
|
123
|
-
return state.bundle;
|
|
124
|
-
};
|
|
125
|
-
return {
|
|
126
|
-
get manager() {
|
|
127
|
-
return requireBundle().manager;
|
|
128
|
-
},
|
|
129
|
-
get cwd() {
|
|
130
|
-
return state.ctx?.cwd ?? process.cwd();
|
|
131
|
-
},
|
|
132
|
-
get shellPath() {
|
|
133
|
-
return state.shellPath;
|
|
134
|
-
},
|
|
135
|
-
get defaultCols() {
|
|
136
|
-
return state.settings.defaultCols;
|
|
137
|
-
},
|
|
138
|
-
get defaultRows() {
|
|
139
|
-
return state.settings.defaultRows;
|
|
140
|
-
},
|
|
141
|
-
get timeoutAction() {
|
|
142
|
-
return state.settings.timeoutAction;
|
|
143
|
-
},
|
|
144
|
-
get monitorRegistry() {
|
|
145
|
-
return requireBundle().monitors;
|
|
146
|
-
},
|
|
147
|
-
getEnv: () => getShellEnv(),
|
|
148
|
-
getSessionContext: () => state.ctx,
|
|
149
|
-
// Exit listeners registered before a reload reach the post-reload owner through the
|
|
150
|
-
// shared bundle, so this must dispatch via the bundle, never the instance notifier.
|
|
151
|
-
onBackgroundStart: (id, description, startedAtMs) => {
|
|
152
|
-
state.bundle?.notifyBackgroundStart(id, description, startedAtMs);
|
|
153
|
-
},
|
|
154
|
-
onBackgroundExit: (id, runtime) => {
|
|
155
|
-
state.bundle?.notifyBackgroundExit(id, runtime);
|
|
156
|
-
},
|
|
157
|
-
onMonitorRearmed: (id) => state.monitorNotifier?.rearm(id),
|
|
158
|
-
onMonitorsResumed: (ids) => state.monitorNotifier?.resume(ids),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
25
|
+
import { bindTerminalManifestWriter, createMonitorTool } from "./tools/monitor.js";
|
|
161
26
|
function shouldStepAside(ctx) {
|
|
162
27
|
return isAnthropicBashEnabled() && ctx?.model?.api === "anthropic-messages";
|
|
163
28
|
}
|
|
@@ -188,160 +53,6 @@ function syncToolset(pi, state) {
|
|
|
188
53
|
state.steppedAside = stepAside;
|
|
189
54
|
pi.setActiveTools([...active]);
|
|
190
55
|
}
|
|
191
|
-
/** Send one model-visible terminal reminder; suppressed by notify `off` and non-interactive modes. */
|
|
192
|
-
function sendTerminalReminder(pi, state, sentence) {
|
|
193
|
-
getTerminalNotificationDelivery({
|
|
194
|
-
sendMessage: (message, options) => pi.sendMessage(message, options),
|
|
195
|
-
getContext: () => state.ctx,
|
|
196
|
-
getMode: () => state.settings.notify,
|
|
197
|
-
})?.send(`<system-reminder>${sentence}</system-reminder>`);
|
|
198
|
-
}
|
|
199
|
-
function clauseWithDescriptions(label, count, descriptions) {
|
|
200
|
-
return descriptions.length > 0 ? `${label} ${count} (${descriptions.join(", ")})` : `${label} ${count}`;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* The ONE coalesced restore digest. Counts come from the restore orchestrator; descriptions
|
|
204
|
-
* are attributed per manifest entry so the sentence stays a single message however many
|
|
205
|
-
* monitors there are. Empty clauses are omitted; undefined when there is nothing to report.
|
|
206
|
-
*/
|
|
207
|
-
function restoreDigestSentence(digest, restoredDescriptions, lostDescriptions) {
|
|
208
|
-
const clauses = [];
|
|
209
|
-
if (digest.restored > 0)
|
|
210
|
-
clauses.push(clauseWithDescriptions("restored", digest.restored, restoredDescriptions));
|
|
211
|
-
if (digest.lost > 0)
|
|
212
|
-
clauses.push(clauseWithDescriptions("lost", digest.lost, lostDescriptions));
|
|
213
|
-
if (digest.expired > 0)
|
|
214
|
-
clauses.push(`expired ${digest.expired}`);
|
|
215
|
-
if (digest.muted > 0)
|
|
216
|
-
clauses.push(`${digest.muted} still muted`);
|
|
217
|
-
if (clauses.length === 0)
|
|
218
|
-
return undefined;
|
|
219
|
-
return `Terminal state after restart: ${clauses.join("; ")}.`;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Non-reload startup: acquire the persistence lease, then restore from the manifest and
|
|
223
|
-
* deliver EXACTLY ONE coalesced digest. A live foreign holder keeps its lease and gets one
|
|
224
|
-
* attached-elsewhere reminder; an unreadable manifest fails closed with one notice and no
|
|
225
|
-
* restore attempt. Only the lease owner records manifest state afterwards.
|
|
226
|
-
*/
|
|
227
|
-
async function adoptPersistedTerminalState(pi, state, toolCtx, bundle, sessionKey) {
|
|
228
|
-
const ctx = state.ctx;
|
|
229
|
-
const dir = terminalStateDir(ctx);
|
|
230
|
-
if (dir === undefined || !ctx?.sessionManager)
|
|
231
|
-
return;
|
|
232
|
-
const lease = await acquireTerminalLease({ dir, encodedSessionId: sessionKey });
|
|
233
|
-
if (!lease.acquired) {
|
|
234
|
-
sendTerminalReminder(pi, state, `Terminal monitors for this session are attached in another live process (pid ${lease.holder.pid}); nothing was restored here.`);
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
state.lease = { path: lease.path, pid: lease.pid };
|
|
238
|
-
const writer = new TerminalManifestWriter({ session: ctx.sessionManager });
|
|
239
|
-
state.manifestWriter = writer;
|
|
240
|
-
state.recordedBackgroundIds.clear();
|
|
241
|
-
bindTerminalManifestWriter(sessionKey, writer);
|
|
242
|
-
// The real durability handlers, built from what this restore site already owns: the live
|
|
243
|
-
// registry/manager of the bundle created for this generation, plus the manifest writer.
|
|
244
|
-
// Each monitor's REAL outcome is recorded so the digest attributes descriptions correctly.
|
|
245
|
-
const nowMs = Date.now();
|
|
246
|
-
const outcomesById = new Map();
|
|
247
|
-
const registry = bundle.monitors;
|
|
248
|
-
const record = (handler) => {
|
|
249
|
-
return async (monitor) => {
|
|
250
|
-
const result = await handler(monitor);
|
|
251
|
-
outcomesById.set(monitor.monitorId, result.outcome);
|
|
252
|
-
// Re-adopt every entry that is LIVE in this generation, so the next persist rewrites
|
|
253
|
-
// the manifest with it instead of erasing it: `restored` and `muted` both describe a
|
|
254
|
-
// live monitor (a mute only silences delivery). `lost`/`expired`/`attachedElsewhere`
|
|
255
|
-
// are deliberately not adopted — nothing is running for them here.
|
|
256
|
-
if (result.outcome === "restored" || result.outcome === "muted") {
|
|
257
|
-
writer.adoptRestored(monitor);
|
|
258
|
-
// Re-bind the persisted fire budget so a restart cannot hand the watch a fresh window.
|
|
259
|
-
registry.adoptFireWindow(monitor.monitorId, monitor.fireWindow);
|
|
260
|
-
}
|
|
261
|
-
return result;
|
|
262
|
-
};
|
|
263
|
-
};
|
|
264
|
-
const restartableCommand = createRestartableCommandHandler({ ctx: toolCtx, registry });
|
|
265
|
-
// The file handler re-binds the mon_ id to the fresh runtime id; capture that id here so a
|
|
266
|
-
// persisted mute is re-applied by the runtime id the registry can actually resolve.
|
|
267
|
-
let freshFileRuntimeId;
|
|
268
|
-
const checkpointedFile = createCheckpointedFileRestoreHandler({
|
|
269
|
-
registry,
|
|
270
|
-
writer,
|
|
271
|
-
bindMonitorId: (monitorId, runtimeId) => {
|
|
272
|
-
freshFileRuntimeId = runtimeId;
|
|
273
|
-
bundle.manager.bindMonitorId(monitorId, runtimeId);
|
|
274
|
-
},
|
|
275
|
-
now: () => nowMs,
|
|
276
|
-
});
|
|
277
|
-
const handlers = {
|
|
278
|
-
"restartable-command": record(restartableCommand),
|
|
279
|
-
"checkpointed-file": record(async (monitor) => {
|
|
280
|
-
freshFileRuntimeId = undefined;
|
|
281
|
-
const result = await checkpointedFile(monitor);
|
|
282
|
-
if (result.outcome !== "restored" || freshFileRuntimeId === undefined)
|
|
283
|
-
return result;
|
|
284
|
-
return { ...result, outcome: reapplyPersistedMute(registry, monitor, freshFileRuntimeId) };
|
|
285
|
-
}),
|
|
286
|
-
};
|
|
287
|
-
const digest = await restoreTerminalState({ manifest: writer.store, handlers, now: () => nowMs });
|
|
288
|
-
let manifest = null;
|
|
289
|
-
let unreadable = digest.storeError;
|
|
290
|
-
if (!unreadable) {
|
|
291
|
-
try {
|
|
292
|
-
manifest = await writer.store.read();
|
|
293
|
-
}
|
|
294
|
-
catch {
|
|
295
|
-
unreadable = true;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (unreadable) {
|
|
299
|
-
sendTerminalReminder(pi, state, "Terminal state after restart: the persisted terminal manifest is corrupt; nothing was restored here (fail closed).");
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
if (manifest === null)
|
|
303
|
-
return; // nothing was ever persisted for this session
|
|
304
|
-
const restoredDescriptions = [];
|
|
305
|
-
const lostDescriptions = [];
|
|
306
|
-
for (const monitor of manifest.monitors) {
|
|
307
|
-
// Same boundary as the restore orchestrator: at the deadline the entry is expired.
|
|
308
|
-
if (monitor.expiresAt !== null && monitor.expiresAt <= nowMs)
|
|
309
|
-
continue;
|
|
310
|
-
const outcome = outcomesById.get(monitor.monitorId);
|
|
311
|
-
// Only `restored` and `lost` carry descriptions; a muted restore is reported by its own
|
|
312
|
-
// count clause, so naming it under either list would desync the clause counts.
|
|
313
|
-
if (outcome === "restored")
|
|
314
|
-
restoredDescriptions.push(monitor.description);
|
|
315
|
-
else if (outcome === undefined || outcome === "lost")
|
|
316
|
-
lostDescriptions.push(monitor.description);
|
|
317
|
-
}
|
|
318
|
-
for (const background of manifest.backgroundSessions)
|
|
319
|
-
lostDescriptions.push(background.command);
|
|
320
|
-
const sentence = restoreDigestSentence(digest, restoredDescriptions, lostDescriptions);
|
|
321
|
-
if (sentence !== undefined)
|
|
322
|
-
sendTerminalReminder(pi, state, sentence);
|
|
323
|
-
}
|
|
324
|
-
/** Detach the manifest recorder without writing (a reload keeps live state instead). */
|
|
325
|
-
function detachManifestWriter(state, sessionKey) {
|
|
326
|
-
state.manifestWriter = null;
|
|
327
|
-
state.recordedBackgroundIds.clear();
|
|
328
|
-
if (sessionKey !== undefined)
|
|
329
|
-
unbindTerminalManifestWriter(sessionKey);
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Shutdown view of the manifest: recordShutdown absorbs pending checkpoints, marks every
|
|
333
|
-
* live monitor `suspended`, and persists in one write. Detach FIRST so bundle teardown's
|
|
334
|
-
* empty-registry sync cannot touch the recorder afterwards.
|
|
335
|
-
*/
|
|
336
|
-
async function suspendAndFlushManifest(state, sessionKey) {
|
|
337
|
-
const writer = state.manifestWriter;
|
|
338
|
-
// Final live-state sync: the shutdown write must carry each watch's burned fire window.
|
|
339
|
-
if (writer && state.bundle)
|
|
340
|
-
await writer.observeMonitorState(state.bundle.monitors.snapshot());
|
|
341
|
-
detachManifestWriter(state, sessionKey);
|
|
342
|
-
if (writer)
|
|
343
|
-
await writer.recordShutdown();
|
|
344
|
-
}
|
|
345
56
|
export function registerTerminalExtension(pi) {
|
|
346
57
|
const state = {
|
|
347
58
|
bundle: null,
|
|
@@ -362,7 +73,12 @@ export function registerTerminalExtension(pi) {
|
|
|
362
73
|
noticeShown: false,
|
|
363
74
|
lease: null,
|
|
364
75
|
manifestWriter: null,
|
|
76
|
+
ensurePersistence: null,
|
|
365
77
|
recordedBackgroundIds: new Set(),
|
|
78
|
+
keeper: null,
|
|
79
|
+
digestSlot: createDigestSlot(),
|
|
80
|
+
generation: 0,
|
|
81
|
+
restoreInFlight: Promise.resolve(),
|
|
366
82
|
parked: false,
|
|
367
83
|
};
|
|
368
84
|
const toolCtx = buildToolContext(pi, state);
|
|
@@ -372,6 +88,7 @@ export function registerTerminalExtension(pi) {
|
|
|
372
88
|
pi.registerTool(createBashResizeTool(toolCtx));
|
|
373
89
|
pi.registerTool(createKillBashTool(toolCtx));
|
|
374
90
|
pi.registerTool(createMonitorTool(toolCtx));
|
|
91
|
+
registerRestoreDigestRenderer(pi);
|
|
375
92
|
pi.on("session_start", async (event, ctx) => {
|
|
376
93
|
state.ctx = ctx;
|
|
377
94
|
const settingsManager = SettingsManager.create(ctx.cwd);
|
|
@@ -406,18 +123,21 @@ export function registerTerminalExtension(pi) {
|
|
|
406
123
|
}
|
|
407
124
|
state.bundle ??= createBundle(state);
|
|
408
125
|
state.bundle.bind(bundleSinks(pi, state));
|
|
409
|
-
|
|
126
|
+
const holdsLease = sessionKey !== undefined && currentLeaseToken(encodedSessionId(sessionKey)) !== undefined;
|
|
127
|
+
if (event.reason === "reload" && holdsLease) {
|
|
410
128
|
// Park/claim and the lease stay untouched: the same pid keeps holding it. The
|
|
411
129
|
// reload generation only rebinds the recorder so manifest coverage continues.
|
|
412
130
|
if (sessionKey !== undefined && terminalStateDir(ctx) !== undefined) {
|
|
413
131
|
const writer = new TerminalManifestWriter({ session: ctx.sessionManager });
|
|
132
|
+
// SF-2: seed from disk so the first post-reload write keeps the pre-reload entries.
|
|
133
|
+
await writer.seedFromDisk();
|
|
414
134
|
state.manifestWriter = writer;
|
|
415
135
|
state.recordedBackgroundIds.clear();
|
|
416
136
|
bindTerminalManifestWriter(sessionKey, writer);
|
|
417
137
|
}
|
|
418
138
|
}
|
|
419
139
|
else if (sessionKey !== undefined) {
|
|
420
|
-
await
|
|
140
|
+
await startPersistence({ pi, state, toolCtx, sessionKey });
|
|
421
141
|
}
|
|
422
142
|
syncToolset(pi, state);
|
|
423
143
|
});
|
|
@@ -435,11 +155,13 @@ export function registerTerminalExtension(pi) {
|
|
|
435
155
|
pi.on("model_select", async (event, ctx) => {
|
|
436
156
|
state.ctx = { ...ctx, model: event.model };
|
|
437
157
|
syncToolset(pi, state);
|
|
158
|
+
flushRestoreDigest(pi, state);
|
|
438
159
|
});
|
|
439
160
|
pi.on("input", (event) => {
|
|
440
161
|
if (event.source === "extension")
|
|
441
162
|
return;
|
|
442
163
|
state.monitorNotifier?.noteActivity();
|
|
164
|
+
flushRestoreDigest(pi, state);
|
|
443
165
|
const resumed = state.bundle?.monitors.resume() ?? [];
|
|
444
166
|
if (resumed.length > 0)
|
|
445
167
|
state.monitorNotifier?.resume(resumed.map((monitor) => monitor.id));
|
|
@@ -464,26 +186,28 @@ export function registerTerminalExtension(pi) {
|
|
|
464
186
|
// Keep state.bundle referenced: exit listeners captured by this instance's tool
|
|
465
187
|
// context still route through the shared bundle after the new owner claims it.
|
|
466
188
|
// The lease is deliberately NOT released: the same pid keeps it across the reload.
|
|
467
|
-
|
|
189
|
+
state.keeper?.stop();
|
|
190
|
+
state.keeper = null;
|
|
191
|
+
detachPersistence(state, sessionKey);
|
|
468
192
|
state.bundle.park();
|
|
469
193
|
await parkBundle(sessionKey, state.bundle);
|
|
470
194
|
return;
|
|
471
195
|
}
|
|
196
|
+
const inheritedLease = state.lease === null;
|
|
472
197
|
if (sessionKey !== undefined)
|
|
473
|
-
await
|
|
474
|
-
|
|
475
|
-
state.lease = null;
|
|
476
|
-
if (lease !== null) {
|
|
477
|
-
await releaseTerminalLease(lease);
|
|
478
|
-
}
|
|
479
|
-
else if (sessionKey !== undefined) {
|
|
198
|
+
await stopPersistence(state, sessionKey);
|
|
199
|
+
if (inheritedLease && sessionKey !== undefined) {
|
|
480
200
|
const dir = terminalStateDir(ctx) ?? terminalStateDir(state.ctx);
|
|
481
201
|
// A reload generation inherits the pre-reload lease without re-acquiring it;
|
|
482
202
|
// releasing by (path, own pid) removes exactly that file and no foreign holder's.
|
|
483
203
|
if (dir !== undefined) {
|
|
204
|
+
const token = currentLeaseToken(encodedSessionId(sessionKey));
|
|
205
|
+
if (token !== undefined)
|
|
206
|
+
retireLeaseToken(token);
|
|
484
207
|
await releaseTerminalLease({
|
|
485
208
|
path: join(dir, `${encodedSessionId(sessionKey)}.lease`),
|
|
486
209
|
pid: process.pid,
|
|
210
|
+
...(token === undefined ? {} : { token }),
|
|
487
211
|
});
|
|
488
212
|
}
|
|
489
213
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbsolute, join } from \"node:path\";\nimport { getShellEnv } from \"../../../../utils/shell.ts\";\nimport { encodedSessionId } from \"../../../session-sidecar-store.ts\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isAnthropicBashEnabled } from \"../anthropic-bash/index.ts\";\nimport { isEvalOnlyRouting } from \"../eval-only-routing.ts\";\nimport {\n\tTERMINAL_MONITOR_ENDED_EVENT,\n\tTERMINAL_MONITOR_STATE_EVENT,\n\tWAKE_SOURCE_STATE_EVENT,\n} from \"../monitor-state-event.ts\";\nimport { createRestartableCommandHandler } from \"./durable-command.ts\";\nimport { createCheckpointedFileRestoreHandler } from \"./durable-file.ts\";\nimport { acquireTerminalLease, releaseTerminalLease } from \"./manifest-lease.ts\";\nimport { MonitorNotifier } from \"./monitor-notify.ts\";\nimport { MONITOR_STATUS_KEY } from \"./monitor-status.ts\";\nimport { MonitorStatusTicker } from \"./monitor-status-ticker.ts\";\nimport { getTerminalNotificationDelivery, TerminalNotifier } from \"./notify.ts\";\nimport { buildTerminalPromptSection } from \"./prompt.ts\";\nimport {\n\ttype RestoreDigest,\n\ttype RestoreHandler,\n\ttype RestoreHandlers,\n\ttype RestoreOutcome,\n\treapplyPersistedMute,\n\trestoreTerminalState,\n} from \"./restore.ts\";\nimport type { TerminalRuntimeSession } from \"./runtime-session.ts\";\nimport {\n\tclaimParkedBundle,\n\tparkBundle,\n\ttype TerminalEventSinks,\n\tTerminalSessionBundle,\n\tteardownParkedBundle,\n} from \"./session-bundle.ts\";\nimport { loadTerminalSettings, type ResolvedTerminalSettings, TERMINAL_SETTINGS_DEFAULTS } from \"./settings.ts\";\nimport { TERMINAL_BASH_TOOL, TERMINAL_COMPANION_TOOLS } from \"./shared.ts\";\nimport { type ManifestMonitor, TerminalManifestWriter } from \"./terminal-manifest.ts\";\nimport { createPtyBashTool } from \"./tools/bash.ts\";\nimport { createBashInputTool } from \"./tools/bash-input.ts\";\nimport { createBashOutputTool } from \"./tools/bash-output.ts\";\nimport { createBashResizeTool } from \"./tools/bash-resize.ts\";\nimport type { TerminalToolContext } from \"./tools/context.ts\";\nimport { createKillBashTool } from \"./tools/kill-bash.ts\";\nimport { bindTerminalManifestWriter, createMonitorTool, unbindTerminalManifestWriter } from \"./tools/monitor.ts\";\n\ninterface TerminalExtensionState {\n\tbundle: TerminalSessionBundle | null;\n\tsettings: ResolvedTerminalSettings;\n\tnotifier: TerminalNotifier | null;\n\tmonitorNotifier: MonitorNotifier | null;\n\tstatusTicker: MonitorStatusTicker;\n\tctx: ExtensionContext | undefined;\n\tshellPath: string | undefined;\n\tsteppedAside: boolean;\n\tnoticeShown: boolean;\n\t/** Set only when this generation acquired the persistence lease (non-reload starts). */\n\tlease: { path: string; pid: number } | null;\n\t/** Manifest recorder; present only while this process owns the session's lease. */\n\tmanifestWriter: TerminalManifestWriter | null;\n\trecordedBackgroundIds: Set<string>;\n\tparked: boolean;\n}\n\n/** Tests and SDK callers may hand partial contexts without a session manager. */\nfunction sessionKeyOf(ctx: ExtensionContext | undefined): string | undefined {\n\treturn ctx?.sessionManager?.getSessionId?.();\n}\n\n/**\n * Per-session persistence dir for the terminal lease + manifest; undefined when the context\n * carries no durable session dir (SDK/in-memory sessions must not persist terminal state).\n */\nfunction terminalStateDir(ctx: ExtensionContext | undefined): string | undefined {\n\tconst sessionDir = ctx?.sessionManager?.getSessionDir?.();\n\tif (sessionDir === undefined || sessionDir.length === 0 || !isAbsolute(sessionDir)) return undefined;\n\treturn join(sessionDir, \"extensions\", \"terminal\");\n}\n\nfunction createBundle(state: TerminalExtensionState): TerminalSessionBundle {\n\treturn new TerminalSessionBundle({\n\t\tmaxSessions: state.settings.maxSessions,\n\t\tscrollback: state.settings.scrollback,\n\t});\n}\n\n/** Sinks read the live instance state at call time, so notifier swaps need no re-bind. */\nfunction bundleSinks(pi: ExtensionAPI, state: TerminalExtensionState): TerminalEventSinks {\n\treturn {\n\t\tonMonitorEvent: (event) => state.monitorNotifier?.notifyEvent(event),\n\t\tonMonitorEnded: (event) => {\n\t\t\tpi.events?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);\n\t\t\tpi.rpc?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);\n\t\t},\n\t\tonMonitorState: (snapshot, transition = true) => {\n\t\t\tif (!state.parked) state.statusTicker.sync(snapshot);\n\t\t\tconst payload = {\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\tmonitors: snapshot.map((entry) => ({\n\t\t\t\t\tid: entry.id,\n\t\t\t\t\tdescription: entry.description,\n\t\t\t\t\tpaused: entry.paused,\n\t\t\t\t\tstartedAtMs: entry.startedAtMs,\n\t\t\t\t\tcommand: entry.command,\n\t\t\t\t\tfilter: entry.filter,\n\t\t\t\t\tpersistent: entry.persistent,\n\t\t\t\t\tdeadlineMs: entry.deadlineMs,\n\t\t\t\t\tfireCount: entry.fireCount,\n\t\t\t\t\tlastFiredAtMs: entry.lastFiredAtMs,\n\t\t\t\t})),\n\t\t\t};\n\t\t\tpi.events?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);\n\t\t\tpi.rpc?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);\n\t\t\tif (!transition) return;\n\t\t\tpi.events?.emit(WAKE_SOURCE_STATE_EVENT, {\n\t\t\t\tsource: \"terminal-monitors\",\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\tmonitors: snapshot.map((entry) => ({\n\t\t\t\t\tid: entry.id,\n\t\t\t\t\tdescription: entry.description,\n\t\t\t\t\tstartedAtMs: entry.startedAtMs,\n\t\t\t\t})),\n\t\t\t});\n\t\t\tif (state.manifestWriter) void state.manifestWriter.observeMonitorState(snapshot);\n\t\t},\n\t\tonBackgroundState: (snapshot) => {\n\t\t\tpi.events?.emit(WAKE_SOURCE_STATE_EVENT, {\n\t\t\t\tsource: \"terminal-background-sessions\",\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\titems: snapshot,\n\t\t\t});\n\t\t\tconst writer = state.manifestWriter;\n\t\t\tif (!writer) return;\n\t\t\tfor (const entry of snapshot) {\n\t\t\t\tif (state.recordedBackgroundIds.has(entry.id)) continue;\n\t\t\t\tstate.recordedBackgroundIds.add(entry.id);\n\t\t\t\tvoid writer.recordBackgroundStart(entry.id, entry.description ?? entry.id, entry.startedAtMs);\n\t\t\t}\n\t\t},\n\t\tonBackgroundExit: (id, runtime) => {\n\t\t\tstate.recordedBackgroundIds.delete(id);\n\t\t\tif (state.manifestWriter) void state.manifestWriter.recordBackgroundExit(id);\n\t\t\tstate.notifier?.notifyCompletion(id, runtime);\n\t\t},\n\t};\n}\n\nfunction buildToolContext(pi: ExtensionAPI, state: TerminalExtensionState): TerminalToolContext {\n\tconst requireBundle = (): TerminalSessionBundle => {\n\t\t// Lazily create a bundle so the tools work even when invoked directly (e.g. via the\n\t\t// SDK) before `session_start` initializes one. `session_start` replaces it with a\n\t\t// settings-configured bundle and tears down any earlier one.\n\t\tif (!state.bundle) {\n\t\t\tstate.bundle = createBundle(state);\n\t\t\tstate.bundle.monitors.setParked(state.parked);\n\t\t\tstate.bundle.bind(bundleSinks(pi, state));\n\t\t}\n\t\treturn state.bundle;\n\t};\n\treturn {\n\t\tget manager() {\n\t\t\treturn requireBundle().manager;\n\t\t},\n\t\tget cwd() {\n\t\t\treturn state.ctx?.cwd ?? process.cwd();\n\t\t},\n\t\tget shellPath() {\n\t\t\treturn state.shellPath;\n\t\t},\n\t\tget defaultCols() {\n\t\t\treturn state.settings.defaultCols;\n\t\t},\n\t\tget defaultRows() {\n\t\t\treturn state.settings.defaultRows;\n\t\t},\n\t\tget timeoutAction() {\n\t\t\treturn state.settings.timeoutAction;\n\t\t},\n\t\tget monitorRegistry() {\n\t\t\treturn requireBundle().monitors;\n\t\t},\n\t\tgetEnv: () => getShellEnv(),\n\t\tgetSessionContext: () => state.ctx,\n\t\t// Exit listeners registered before a reload reach the post-reload owner through the\n\t\t// shared bundle, so this must dispatch via the bundle, never the instance notifier.\n\t\tonBackgroundStart: (id: string, description: string, startedAtMs: number) => {\n\t\t\tstate.bundle?.notifyBackgroundStart(id, description, startedAtMs);\n\t\t},\n\t\tonBackgroundExit: (id: string, runtime: TerminalRuntimeSession) => {\n\t\t\tstate.bundle?.notifyBackgroundExit(id, runtime);\n\t\t},\n\t\tonMonitorRearmed: (id: string) => state.monitorNotifier?.rearm(id),\n\t\tonMonitorsResumed: (ids: readonly string[]) => state.monitorNotifier?.resume(ids),\n\t};\n}\n\nfunction shouldStepAside(ctx: ExtensionContext | undefined): boolean {\n\treturn isAnthropicBashEnabled() && ctx?.model?.api === \"anthropic-messages\";\n}\n\n/**\n * Keep the tool surface consistent with anthropic-bash. When native Anthropic bash is active,\n * the provider replaces the PTY `bash` function, but the companions stay active because `monitor`\n * creates its own PTY session and bash_output/input/resize/kill operate on that shared registry.\n * Otherwise the PTY `bash` + companions are (re)activated. Re-evaluated on session_start AND\n * model_select.\n */\nfunction syncToolset(pi: ExtensionAPI, state: TerminalExtensionState): void {\n\tconst stepAside = shouldStepAside(state.ctx);\n\tconst active = new Set(pi.getActiveTools());\n\tif (stepAside) {\n\t\tfor (const companion of TERMINAL_COMPANION_TOOLS) active.add(companion);\n\t\tif (!state.noticeShown) {\n\t\t\tstate.ctx?.ui.notify(\"native Anthropic bash active — monitor sessions remain available\", \"info\");\n\t\t\tstate.noticeShown = true;\n\t\t}\n\t} else {\n\t\tactive.add(TERMINAL_BASH_TOOL);\n\t\tfor (const companion of TERMINAL_COMPANION_TOOLS) active.add(companion);\n\t\tstate.noticeShown = false;\n\t}\n\tstate.steppedAside = stepAside;\n\tpi.setActiveTools([...active]);\n}\n\n/** Send one model-visible terminal reminder; suppressed by notify `off` and non-interactive modes. */\nfunction sendTerminalReminder(pi: ExtensionAPI, state: TerminalExtensionState, sentence: string): void {\n\tgetTerminalNotificationDelivery({\n\t\tsendMessage: (message, options) => pi.sendMessage(message, options),\n\t\tgetContext: () => state.ctx,\n\t\tgetMode: () => state.settings.notify,\n\t})?.send(`<system-reminder>${sentence}</system-reminder>`);\n}\n\nfunction clauseWithDescriptions(label: string, count: number, descriptions: readonly string[]): string {\n\treturn descriptions.length > 0 ? `${label} ${count} (${descriptions.join(\", \")})` : `${label} ${count}`;\n}\n\n/**\n * The ONE coalesced restore digest. Counts come from the restore orchestrator; descriptions\n * are attributed per manifest entry so the sentence stays a single message however many\n * monitors there are. Empty clauses are omitted; undefined when there is nothing to report.\n */\nfunction restoreDigestSentence(\n\tdigest: RestoreDigest,\n\trestoredDescriptions: readonly string[],\n\tlostDescriptions: readonly string[],\n): string | undefined {\n\tconst clauses: string[] = [];\n\tif (digest.restored > 0) clauses.push(clauseWithDescriptions(\"restored\", digest.restored, restoredDescriptions));\n\tif (digest.lost > 0) clauses.push(clauseWithDescriptions(\"lost\", digest.lost, lostDescriptions));\n\tif (digest.expired > 0) clauses.push(`expired ${digest.expired}`);\n\tif (digest.muted > 0) clauses.push(`${digest.muted} still muted`);\n\tif (clauses.length === 0) return undefined;\n\treturn `Terminal state after restart: ${clauses.join(\"; \")}.`;\n}\n\n/**\n * Non-reload startup: acquire the persistence lease, then restore from the manifest and\n * deliver EXACTLY ONE coalesced digest. A live foreign holder keeps its lease and gets one\n * attached-elsewhere reminder; an unreadable manifest fails closed with one notice and no\n * restore attempt. Only the lease owner records manifest state afterwards.\n */\nasync function adoptPersistedTerminalState(\n\tpi: ExtensionAPI,\n\tstate: TerminalExtensionState,\n\ttoolCtx: TerminalToolContext,\n\tbundle: TerminalSessionBundle,\n\tsessionKey: string,\n): Promise<void> {\n\tconst ctx = state.ctx;\n\tconst dir = terminalStateDir(ctx);\n\tif (dir === undefined || !ctx?.sessionManager) return;\n\tconst lease = await acquireTerminalLease({ dir, encodedSessionId: sessionKey });\n\tif (!lease.acquired) {\n\t\tsendTerminalReminder(\n\t\t\tpi,\n\t\t\tstate,\n\t\t\t`Terminal monitors for this session are attached in another live process (pid ${lease.holder.pid}); nothing was restored here.`,\n\t\t);\n\t\treturn;\n\t}\n\tstate.lease = { path: lease.path, pid: lease.pid };\n\tconst writer = new TerminalManifestWriter({ session: ctx.sessionManager });\n\tstate.manifestWriter = writer;\n\tstate.recordedBackgroundIds.clear();\n\tbindTerminalManifestWriter(sessionKey, writer);\n\n\t// The real durability handlers, built from what this restore site already owns: the live\n\t// registry/manager of the bundle created for this generation, plus the manifest writer.\n\t// Each monitor's REAL outcome is recorded so the digest attributes descriptions correctly.\n\tconst nowMs = Date.now();\n\tconst outcomesById = new Map<string, RestoreOutcome>();\n\tconst registry = bundle.monitors;\n\tconst record = (handler: RestoreHandler): RestoreHandler => {\n\t\treturn async (monitor: ManifestMonitor) => {\n\t\t\tconst result = await handler(monitor);\n\t\t\toutcomesById.set(monitor.monitorId, result.outcome);\n\t\t\t// Re-adopt every entry that is LIVE in this generation, so the next persist rewrites\n\t\t\t// the manifest with it instead of erasing it: `restored` and `muted` both describe a\n\t\t\t// live monitor (a mute only silences delivery). `lost`/`expired`/`attachedElsewhere`\n\t\t\t// are deliberately not adopted — nothing is running for them here.\n\t\t\tif (result.outcome === \"restored\" || result.outcome === \"muted\") {\n\t\t\t\twriter.adoptRestored(monitor);\n\t\t\t\t// Re-bind the persisted fire budget so a restart cannot hand the watch a fresh window.\n\t\t\t\tregistry.adoptFireWindow(monitor.monitorId, monitor.fireWindow);\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t};\n\tconst restartableCommand = createRestartableCommandHandler({ ctx: toolCtx, registry });\n\t// The file handler re-binds the mon_ id to the fresh runtime id; capture that id here so a\n\t// persisted mute is re-applied by the runtime id the registry can actually resolve.\n\tlet freshFileRuntimeId: string | undefined;\n\tconst checkpointedFile = createCheckpointedFileRestoreHandler({\n\t\tregistry,\n\t\twriter,\n\t\tbindMonitorId: (monitorId, runtimeId) => {\n\t\t\tfreshFileRuntimeId = runtimeId;\n\t\t\tbundle.manager.bindMonitorId(monitorId, runtimeId);\n\t\t},\n\t\tnow: () => nowMs,\n\t});\n\tconst handlers: RestoreHandlers = {\n\t\t\"restartable-command\": record(restartableCommand),\n\t\t\"checkpointed-file\": record(async (monitor) => {\n\t\t\tfreshFileRuntimeId = undefined;\n\t\t\tconst result = await checkpointedFile(monitor);\n\t\t\tif (result.outcome !== \"restored\" || freshFileRuntimeId === undefined) return result;\n\t\t\treturn { ...result, outcome: reapplyPersistedMute(registry, monitor, freshFileRuntimeId) };\n\t\t}),\n\t};\n\tconst digest = await restoreTerminalState({ manifest: writer.store, handlers, now: () => nowMs });\n\n\tlet manifest = null;\n\tlet unreadable = digest.storeError;\n\tif (!unreadable) {\n\t\ttry {\n\t\t\tmanifest = await writer.store.read();\n\t\t} catch {\n\t\t\tunreadable = true;\n\t\t}\n\t}\n\tif (unreadable) {\n\t\tsendTerminalReminder(\n\t\t\tpi,\n\t\t\tstate,\n\t\t\t\"Terminal state after restart: the persisted terminal manifest is corrupt; nothing was restored here (fail closed).\",\n\t\t);\n\t\treturn;\n\t}\n\tif (manifest === null) return; // nothing was ever persisted for this session\n\n\tconst restoredDescriptions: string[] = [];\n\tconst lostDescriptions: string[] = [];\n\tfor (const monitor of manifest.monitors) {\n\t\t// Same boundary as the restore orchestrator: at the deadline the entry is expired.\n\t\tif (monitor.expiresAt !== null && monitor.expiresAt <= nowMs) continue;\n\t\tconst outcome = outcomesById.get(monitor.monitorId);\n\t\t// Only `restored` and `lost` carry descriptions; a muted restore is reported by its own\n\t\t// count clause, so naming it under either list would desync the clause counts.\n\t\tif (outcome === \"restored\") restoredDescriptions.push(monitor.description);\n\t\telse if (outcome === undefined || outcome === \"lost\") lostDescriptions.push(monitor.description);\n\t}\n\tfor (const background of manifest.backgroundSessions) lostDescriptions.push(background.command);\n\tconst sentence = restoreDigestSentence(digest, restoredDescriptions, lostDescriptions);\n\tif (sentence !== undefined) sendTerminalReminder(pi, state, sentence);\n}\n\n/** Detach the manifest recorder without writing (a reload keeps live state instead). */\nfunction detachManifestWriter(state: TerminalExtensionState, sessionKey: string | undefined): void {\n\tstate.manifestWriter = null;\n\tstate.recordedBackgroundIds.clear();\n\tif (sessionKey !== undefined) unbindTerminalManifestWriter(sessionKey);\n}\n\n/**\n * Shutdown view of the manifest: recordShutdown absorbs pending checkpoints, marks every\n * live monitor `suspended`, and persists in one write. Detach FIRST so bundle teardown's\n * empty-registry sync cannot touch the recorder afterwards.\n */\nasync function suspendAndFlushManifest(state: TerminalExtensionState, sessionKey: string): Promise<void> {\n\tconst writer = state.manifestWriter;\n\t// Final live-state sync: the shutdown write must carry each watch's burned fire window.\n\tif (writer && state.bundle) await writer.observeMonitorState(state.bundle.monitors.snapshot());\n\tdetachManifestWriter(state, sessionKey);\n\tif (writer) await writer.recordShutdown();\n}\n\nexport function registerTerminalExtension(pi: ExtensionAPI): void {\n\tconst state: TerminalExtensionState = {\n\t\tbundle: null,\n\t\tsettings: TERMINAL_SETTINGS_DEFAULTS,\n\t\tnotifier: null,\n\t\tmonitorNotifier: null,\n\t\tstatusTicker: new MonitorStatusTicker({\n\t\t\trender: (status) => {\n\t\t\t\tconst ctx = state.ctx;\n\t\t\t\tctx?.ui.setStatus(\n\t\t\t\t\tMONITOR_STATUS_KEY,\n\t\t\t\t\tstatus === undefined || ctx.mode !== \"tui\"\n\t\t\t\t\t\t? status\n\t\t\t\t\t\t: ctx.ui.theme.bg(\"selectedBg\", ctx.ui.theme.fg(\"text\", status)),\n\t\t\t\t);\n\t\t\t},\n\t\t}),\n\t\tctx: undefined,\n\t\tshellPath: undefined,\n\t\tsteppedAside: false,\n\t\tnoticeShown: false,\n\t\tlease: null,\n\t\tmanifestWriter: null,\n\t\trecordedBackgroundIds: new Set(),\n\t\tparked: false,\n\t};\n\tconst toolCtx = buildToolContext(pi, state);\n\n\tpi.registerTool(createPtyBashTool(toolCtx));\n\tpi.registerTool(createBashOutputTool(toolCtx));\n\tpi.registerTool(createBashInputTool(toolCtx));\n\tpi.registerTool(createBashResizeTool(toolCtx));\n\tpi.registerTool(createKillBashTool(toolCtx));\n\tpi.registerTool(createMonitorTool(toolCtx));\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tstate.ctx = ctx;\n\t\tconst settingsManager = SettingsManager.create(ctx.cwd);\n\t\tstate.settings = loadTerminalSettings(settingsManager);\n\t\tstate.shellPath = settingsManager.getShellPath();\n\t\tstate.notifier = new TerminalNotifier({\n\t\t\tsendMessage: (message, options) => pi.sendMessage(message, options),\n\t\t\tgetContext: () => state.ctx,\n\t\t\tgetMode: () => state.settings.notify,\n\t\t});\n\t\tstate.monitorNotifier?.dispose();\n\t\tstate.monitorNotifier = new MonitorNotifier({\n\t\t\tsendMessage: (message, options) => pi.sendMessage(message, options),\n\t\t\tgetContext: () => state.ctx,\n\t\t\tgetMode: () => state.settings.notify,\n\t\t\tgetSettings: () => state.settings.monitor,\n\t\t\tpauseMonitors: (ids) => state.bundle?.monitors.pause(ids) ?? [],\n\t\t});\n\t\tconst sessionKey = sessionKeyOf(ctx);\n\t\tif (event.reason === \"reload\") {\n\t\t\tconst claimed = sessionKey === undefined ? undefined : claimParkedBundle(sessionKey);\n\t\t\tif (claimed) {\n\t\t\t\tawait state.bundle?.teardown();\n\t\t\t\tstate.bundle = claimed;\n\t\t\t}\n\t\t} else {\n\t\t\tif (sessionKey !== undefined) await teardownParkedBundle(sessionKey);\n\t\t\tawait state.bundle?.teardown();\n\t\t\tstate.bundle = createBundle(state);\n\t\t}\n\t\tstate.bundle ??= createBundle(state);\n\t\tstate.bundle.bind(bundleSinks(pi, state));\n\t\tif (event.reason === \"reload\") {\n\t\t\t// Park/claim and the lease stay untouched: the same pid keeps holding it. The\n\t\t\t// reload generation only rebinds the recorder so manifest coverage continues.\n\t\t\tif (sessionKey !== undefined && terminalStateDir(ctx) !== undefined) {\n\t\t\t\tconst writer = new TerminalManifestWriter({ session: ctx.sessionManager });\n\t\t\t\tstate.manifestWriter = writer;\n\t\t\t\tstate.recordedBackgroundIds.clear();\n\t\t\t\tbindTerminalManifestWriter(sessionKey, writer);\n\t\t\t}\n\t\t} else if (sessionKey !== undefined) {\n\t\t\tawait adoptPersistedTerminalState(pi, state, toolCtx, state.bundle, sessionKey);\n\t\t}\n\t\tsyncToolset(pi, state);\n\t});\n\n\tpi.on(\"session_parked\", () => {\n\t\tstate.parked = true;\n\t\tstate.bundle?.monitors.setParked(true);\n\t\tstate.statusTicker.stop();\n\t});\n\n\tpi.on(\"session_resumed\", () => {\n\t\tstate.parked = false;\n\t\tstate.bundle?.monitors.setParked(false);\n\t\tif (state.bundle) state.statusTicker.sync(state.bundle.monitors.snapshot());\n\t});\n\n\tpi.on(\"model_select\", async (event, ctx) => {\n\t\tstate.ctx = { ...ctx, model: event.model };\n\t\tsyncToolset(pi, state);\n\t});\n\n\tpi.on(\"input\", (event) => {\n\t\tif (event.source === \"extension\") return;\n\t\tstate.monitorNotifier?.noteActivity();\n\t\tconst resumed = state.bundle?.monitors.resume() ?? [];\n\t\tif (resumed.length > 0) state.monitorNotifier?.resume(resumed.map((monitor) => monitor.id));\n\t});\n\n\tpi.on(\"tool_call\", () => {\n\t\tstate.monitorNotifier?.noteActivity();\n\t});\n\n\tpi.on(\n\t\t\"before_agent_start\",\n\t\tasync (event) => {\n\t\t\tif (state.steppedAside) return undefined;\n\t\t\treturn {\n\t\t\t\tsystemPrompt: `${event.systemPrompt}\\n${buildTerminalPromptSection({ evalOnly: isEvalOnlyRouting(pi) })}`,\n\t\t\t};\n\t\t},\n\t\t{ previewSafe: true },\n\t);\n\n\tpi.on(\"session_shutdown\", async (event, ctx) => {\n\t\tstate.monitorNotifier?.dispose();\n\t\tstate.monitorNotifier = null;\n\t\tstate.notifier = null;\n\t\tstate.statusTicker.stop();\n\t\tconst sessionKey = sessionKeyOf(ctx) ?? sessionKeyOf(state.ctx);\n\t\tif (event.reason === \"reload\" && state.bundle && sessionKey !== undefined) {\n\t\t\t// Keep state.bundle referenced: exit listeners captured by this instance's tool\n\t\t\t// context still route through the shared bundle after the new owner claims it.\n\t\t\t// The lease is deliberately NOT released: the same pid keeps it across the reload.\n\t\t\tdetachManifestWriter(state, sessionKey);\n\t\t\tstate.bundle.park();\n\t\t\tawait parkBundle(sessionKey, state.bundle);\n\t\t\treturn;\n\t\t}\n\t\tif (sessionKey !== undefined) await suspendAndFlushManifest(state, sessionKey);\n\t\tconst lease = state.lease;\n\t\tstate.lease = null;\n\t\tif (lease !== null) {\n\t\t\tawait releaseTerminalLease(lease);\n\t\t} else if (sessionKey !== undefined) {\n\t\t\tconst dir = terminalStateDir(ctx) ?? terminalStateDir(state.ctx);\n\t\t\t// A reload generation inherits the pre-reload lease without re-acquiring it;\n\t\t\t// releasing by (path, own pid) removes exactly that file and no foreign holder's.\n\t\t\tif (dir !== undefined) {\n\t\t\t\tawait releaseTerminalLease({\n\t\t\t\t\tpath: join(dir, `${encodedSessionId(sessionKey)}.lease`),\n\t\t\t\t\tpid: process.pid,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tconst bundle = state.bundle;\n\t\tstate.bundle = null;\n\t\tawait bundle?.teardown();\n\t\tif (sessionKey !== undefined) await teardownParkedBundle(sessionKey);\n\t});\n}\n\nexport default registerTerminalExtension;\n"]}
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { encodedSessionId } from \"../../../session-sidecar-store.ts\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isAnthropicBashEnabled } from \"../anthropic-bash/index.ts\";\nimport { isEvalOnlyRouting } from \"../eval-only-routing.ts\";\nimport {\n\tbuildToolContext,\n\tbundleSinks,\n\tcreateBundle,\n\tsessionKeyOf,\n\ttype TerminalExtensionState,\n} from \"./extension-state.ts\";\nimport { currentLeaseToken, releaseTerminalLease, retireLeaseToken } from \"./manifest-lease.ts\";\nimport { MonitorNotifier } from \"./monitor-notify.ts\";\nimport { terminalStateDir } from \"./monitor-state-dir.ts\";\nimport { MONITOR_STATUS_KEY } from \"./monitor-status.ts\";\nimport { MonitorStatusTicker } from \"./monitor-status-ticker.ts\";\nimport { TerminalNotifier } from \"./notify.ts\";\nimport { buildTerminalPromptSection } from \"./prompt.ts\";\nimport { createDigestSlot, registerRestoreDigestRenderer } from \"./restore-digest.ts\";\nimport { detachPersistence, flushRestoreDigest, startPersistence, stopPersistence } from \"./restore-session.ts\";\nimport { claimParkedBundle, parkBundle, teardownParkedBundle } from \"./session-bundle.ts\";\nimport { loadTerminalSettings, TERMINAL_SETTINGS_DEFAULTS } from \"./settings.ts\";\nimport { TERMINAL_BASH_TOOL, TERMINAL_COMPANION_TOOLS } from \"./shared.ts\";\nimport { TerminalManifestWriter } from \"./terminal-manifest.ts\";\nimport { createPtyBashTool } from \"./tools/bash.ts\";\nimport { createBashInputTool } from \"./tools/bash-input.ts\";\nimport { createBashOutputTool } from \"./tools/bash-output.ts\";\nimport { createBashResizeTool } from \"./tools/bash-resize.ts\";\nimport { createKillBashTool } from \"./tools/kill-bash.ts\";\nimport { bindTerminalManifestWriter, createMonitorTool } from \"./tools/monitor.ts\";\n\nfunction shouldStepAside(ctx: ExtensionContext | undefined): boolean {\n\treturn isAnthropicBashEnabled() && ctx?.model?.api === \"anthropic-messages\";\n}\n\n/**\n * Keep the tool surface consistent with anthropic-bash. When native Anthropic bash is active,\n * the provider replaces the PTY `bash` function, but the companions stay active because `monitor`\n * creates its own PTY session and bash_output/input/resize/kill operate on that shared registry.\n * Otherwise the PTY `bash` + companions are (re)activated. Re-evaluated on session_start AND\n * model_select.\n */\nfunction syncToolset(pi: ExtensionAPI, state: TerminalExtensionState): void {\n\tconst stepAside = shouldStepAside(state.ctx);\n\tconst active = new Set(pi.getActiveTools());\n\tif (stepAside) {\n\t\tfor (const companion of TERMINAL_COMPANION_TOOLS) active.add(companion);\n\t\tif (!state.noticeShown) {\n\t\t\tstate.ctx?.ui.notify(\"native Anthropic bash active — monitor sessions remain available\", \"info\");\n\t\t\tstate.noticeShown = true;\n\t\t}\n\t} else {\n\t\tactive.add(TERMINAL_BASH_TOOL);\n\t\tfor (const companion of TERMINAL_COMPANION_TOOLS) active.add(companion);\n\t\tstate.noticeShown = false;\n\t}\n\tstate.steppedAside = stepAside;\n\tpi.setActiveTools([...active]);\n}\n\nexport function registerTerminalExtension(pi: ExtensionAPI): void {\n\tconst state: TerminalExtensionState = {\n\t\tbundle: null,\n\t\tsettings: TERMINAL_SETTINGS_DEFAULTS,\n\t\tnotifier: null,\n\t\tmonitorNotifier: null,\n\t\tstatusTicker: new MonitorStatusTicker({\n\t\t\trender: (status) => {\n\t\t\t\tconst ctx = state.ctx;\n\t\t\t\tctx?.ui.setStatus(\n\t\t\t\t\tMONITOR_STATUS_KEY,\n\t\t\t\t\tstatus === undefined || ctx.mode !== \"tui\"\n\t\t\t\t\t\t? status\n\t\t\t\t\t\t: ctx.ui.theme.bg(\"selectedBg\", ctx.ui.theme.fg(\"text\", status)),\n\t\t\t\t);\n\t\t\t},\n\t\t}),\n\t\tctx: undefined,\n\t\tshellPath: undefined,\n\t\tsteppedAside: false,\n\t\tnoticeShown: false,\n\t\tlease: null,\n\t\tmanifestWriter: null,\n\t\tensurePersistence: null,\n\t\trecordedBackgroundIds: new Set(),\n\t\tkeeper: null,\n\t\tdigestSlot: createDigestSlot(),\n\t\tgeneration: 0,\n\t\trestoreInFlight: Promise.resolve(),\n\t\tparked: false,\n\t};\n\tconst toolCtx = buildToolContext(pi, state);\n\n\tpi.registerTool(createPtyBashTool(toolCtx));\n\tpi.registerTool(createBashOutputTool(toolCtx));\n\tpi.registerTool(createBashInputTool(toolCtx));\n\tpi.registerTool(createBashResizeTool(toolCtx));\n\tpi.registerTool(createKillBashTool(toolCtx));\n\tpi.registerTool(createMonitorTool(toolCtx));\n\tregisterRestoreDigestRenderer(pi);\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tstate.ctx = ctx;\n\t\tconst settingsManager = SettingsManager.create(ctx.cwd);\n\t\tstate.settings = loadTerminalSettings(settingsManager);\n\t\tstate.shellPath = settingsManager.getShellPath();\n\t\tstate.notifier = new TerminalNotifier({\n\t\t\tsendMessage: (message, options) => pi.sendMessage(message, options),\n\t\t\tgetContext: () => state.ctx,\n\t\t\tgetMode: () => state.settings.notify,\n\t\t});\n\t\tstate.monitorNotifier?.dispose();\n\t\tstate.monitorNotifier = new MonitorNotifier({\n\t\t\tsendMessage: (message, options) => pi.sendMessage(message, options),\n\t\t\tgetContext: () => state.ctx,\n\t\t\tgetMode: () => state.settings.notify,\n\t\t\tgetSettings: () => state.settings.monitor,\n\t\t\tpauseMonitors: (ids) => state.bundle?.monitors.pause(ids) ?? [],\n\t\t});\n\t\tconst sessionKey = sessionKeyOf(ctx);\n\t\tif (event.reason === \"reload\") {\n\t\t\tconst claimed = sessionKey === undefined ? undefined : claimParkedBundle(sessionKey);\n\t\t\tif (claimed) {\n\t\t\t\tawait state.bundle?.teardown();\n\t\t\t\tstate.bundle = claimed;\n\t\t\t}\n\t\t} else {\n\t\t\tif (sessionKey !== undefined) await teardownParkedBundle(sessionKey);\n\t\t\tawait state.bundle?.teardown();\n\t\t\tstate.bundle = createBundle(state);\n\t\t}\n\t\tstate.bundle ??= createBundle(state);\n\t\tstate.bundle.bind(bundleSinks(pi, state));\n\t\tconst holdsLease = sessionKey !== undefined && currentLeaseToken(encodedSessionId(sessionKey)) !== undefined;\n\t\tif (event.reason === \"reload\" && holdsLease) {\n\t\t\t// Park/claim and the lease stay untouched: the same pid keeps holding it. The\n\t\t\t// reload generation only rebinds the recorder so manifest coverage continues.\n\t\t\tif (sessionKey !== undefined && terminalStateDir(ctx) !== undefined) {\n\t\t\t\tconst writer = new TerminalManifestWriter({ session: ctx.sessionManager });\n\t\t\t\t// SF-2: seed from disk so the first post-reload write keeps the pre-reload entries.\n\t\t\t\tawait writer.seedFromDisk();\n\t\t\t\tstate.manifestWriter = writer;\n\t\t\t\tstate.recordedBackgroundIds.clear();\n\t\t\t\tbindTerminalManifestWriter(sessionKey, writer);\n\t\t\t}\n\t\t} else if (sessionKey !== undefined) {\n\t\t\tawait startPersistence({ pi, state, toolCtx, sessionKey });\n\t\t}\n\t\tsyncToolset(pi, state);\n\t});\n\n\tpi.on(\"session_parked\", () => {\n\t\tstate.parked = true;\n\t\tstate.bundle?.monitors.setParked(true);\n\t\tstate.statusTicker.stop();\n\t});\n\n\tpi.on(\"session_resumed\", () => {\n\t\tstate.parked = false;\n\t\tstate.bundle?.monitors.setParked(false);\n\t\tif (state.bundle) state.statusTicker.sync(state.bundle.monitors.snapshot());\n\t});\n\n\tpi.on(\"model_select\", async (event, ctx) => {\n\t\tstate.ctx = { ...ctx, model: event.model };\n\t\tsyncToolset(pi, state);\n\t\tflushRestoreDigest(pi, state);\n\t});\n\n\tpi.on(\"input\", (event) => {\n\t\tif (event.source === \"extension\") return;\n\t\tstate.monitorNotifier?.noteActivity();\n\t\tflushRestoreDigest(pi, state);\n\t\tconst resumed = state.bundle?.monitors.resume() ?? [];\n\t\tif (resumed.length > 0) state.monitorNotifier?.resume(resumed.map((monitor) => monitor.id));\n\t});\n\n\tpi.on(\"tool_call\", () => {\n\t\tstate.monitorNotifier?.noteActivity();\n\t});\n\n\tpi.on(\n\t\t\"before_agent_start\",\n\t\tasync (event) => {\n\t\t\tif (state.steppedAside) return undefined;\n\t\t\treturn {\n\t\t\t\tsystemPrompt: `${event.systemPrompt}\\n${buildTerminalPromptSection({ evalOnly: isEvalOnlyRouting(pi) })}`,\n\t\t\t};\n\t\t},\n\t\t{ previewSafe: true },\n\t);\n\n\tpi.on(\"session_shutdown\", async (event, ctx) => {\n\t\tstate.monitorNotifier?.dispose();\n\t\tstate.monitorNotifier = null;\n\t\tstate.notifier = null;\n\t\tstate.statusTicker.stop();\n\t\tconst sessionKey = sessionKeyOf(ctx) ?? sessionKeyOf(state.ctx);\n\t\tif (event.reason === \"reload\" && state.bundle && sessionKey !== undefined) {\n\t\t\t// Keep state.bundle referenced: exit listeners captured by this instance's tool\n\t\t\t// context still route through the shared bundle after the new owner claims it.\n\t\t\t// The lease is deliberately NOT released: the same pid keeps it across the reload.\n\t\t\tstate.keeper?.stop();\n\t\t\tstate.keeper = null;\n\t\t\tdetachPersistence(state, sessionKey);\n\t\t\tstate.bundle.park();\n\t\t\tawait parkBundle(sessionKey, state.bundle);\n\t\t\treturn;\n\t\t}\n\t\tconst inheritedLease = state.lease === null;\n\t\tif (sessionKey !== undefined) await stopPersistence(state, sessionKey);\n\t\tif (inheritedLease && sessionKey !== undefined) {\n\t\t\tconst dir = terminalStateDir(ctx) ?? terminalStateDir(state.ctx);\n\t\t\t// A reload generation inherits the pre-reload lease without re-acquiring it;\n\t\t\t// releasing by (path, own pid) removes exactly that file and no foreign holder's.\n\t\t\tif (dir !== undefined) {\n\t\t\t\tconst token = currentLeaseToken(encodedSessionId(sessionKey));\n\t\t\t\tif (token !== undefined) retireLeaseToken(token);\n\t\t\t\tawait releaseTerminalLease({\n\t\t\t\t\tpath: join(dir, `${encodedSessionId(sessionKey)}.lease`),\n\t\t\t\t\tpid: process.pid,\n\t\t\t\t\t...(token === undefined ? {} : { token }),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tconst bundle = state.bundle;\n\t\tstate.bundle = null;\n\t\tawait bundle?.teardown();\n\t\tif (sessionKey !== undefined) await teardownParkedBundle(sessionKey);\n\t});\n}\n\nexport default registerTerminalExtension;\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-level primitives for the terminal lease. On a filesystem with hard links a lease file is
|
|
3
|
+
* never visible half-written: it is written to a private temp file first and then published with
|
|
4
|
+
* `link` (exclusive: fails with EEXIST when a lease exists) or `rename` (replace). Every removal of
|
|
5
|
+
* a lease, by an acquire or by the GC, goes through `reclaimInspected`: under an exclusive
|
|
6
|
+
* `<lease>.lock`, and only while the file still holds exactly the record that was judged stale, so
|
|
7
|
+
* a fresh lease another process just published is never deleted. A reclaim lock records the
|
|
8
|
+
* holder's identity (pid, boot and start instant); it is broken only when that process is gone or its
|
|
9
|
+
* pid now belongs to another process, and only if it still holds the record that was judged stale.
|
|
10
|
+
*/
|
|
11
|
+
export declare function errorCode(error: unknown): string | undefined;
|
|
12
|
+
export declare function unlinkIfPresent(path: string): Promise<void>;
|
|
13
|
+
export declare function readLeaseText(path: string): Promise<string | undefined>;
|
|
14
|
+
/** Publish `content` at `path` only if nothing is there; throws EEXIST otherwise. Never half-written. */
|
|
15
|
+
export declare function publishExclusive(path: string, content: string): Promise<void>;
|
|
16
|
+
export declare function publishReplace(path: string, content: string): Promise<void>;
|
|
17
|
+
export interface LockProbes {
|
|
18
|
+
readonly isProcessAlive?: (pid: number) => boolean;
|
|
19
|
+
readonly readProcessStartMs?: (pid: number) => Promise<number | undefined>;
|
|
20
|
+
}
|
|
21
|
+
/** Who holds a reclaim lock: the same identity a lease records, so a reused pid is never mistaken for it. */
|
|
22
|
+
export interface ReclaimLockHolder {
|
|
23
|
+
readonly pid: number;
|
|
24
|
+
readonly bootAtMs: number;
|
|
25
|
+
readonly processStartedAtMs: number;
|
|
26
|
+
}
|
|
27
|
+
type LockState = {
|
|
28
|
+
readonly state: "free";
|
|
29
|
+
} | {
|
|
30
|
+
readonly state: "held";
|
|
31
|
+
readonly holder?: ReclaimLockHolder;
|
|
32
|
+
} | {
|
|
33
|
+
readonly state: "stale";
|
|
34
|
+
readonly raw: string;
|
|
35
|
+
};
|
|
36
|
+
/** Whether a reclaim lock is held by the very process that wrote it; a dead or reused pid is stale. */
|
|
37
|
+
export declare function reclaimLockState(lock: string, probes?: LockProbes): Promise<LockState>;
|
|
38
|
+
/** Remove a stale lock only if it still holds `raw`; a lock someone took meanwhile is put back. */
|
|
39
|
+
export declare function breakStaleLock(lock: string, raw: string): Promise<void>;
|
|
40
|
+
export type ReclaimOutcome = {
|
|
41
|
+
readonly outcome: "removed" | "changed";
|
|
42
|
+
} | {
|
|
43
|
+
readonly outcome: "busy";
|
|
44
|
+
readonly holder?: ReclaimLockHolder;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Remove the lease at `path` only if it still holds `inspected`: `removed`, `changed` (another
|
|
48
|
+
* process replaced it meanwhile; left alone), or `busy` with the live process reclaiming it now.
|
|
49
|
+
*/
|
|
50
|
+
export declare function reclaimInspected(path: string, inspected: string, probes?: LockProbes): Promise<ReclaimOutcome>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=lease-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-file.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/lease-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK5D;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjE;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO7E;AAaD,yGAAyG;AACzG,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBnF;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjF;AAWD,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC3E;AAED,6GAA6G;AAC7G,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACpC;AAED,KAAK,SAAS,GACX;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBrD,uGAAuG;AACvG,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,UAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAwBhG;AAED,mGAAmG;AACnG,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB7E;AAsBD,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,GAC3C;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAErE;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,UAAe,GACrB,OAAO,CAAC,cAAc,CAAC,CAYzB"}
|