@songsid/agend 2.3.4-beta.7 → 2.3.5-alpha.3
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/README.md +2 -0
- package/README.zh-TW.md +2 -0
- package/THIRD_PARTY_NOTICES.md +53 -0
- package/dist/agent-endpoint.d.ts +5 -1
- package/dist/agent-endpoint.js +12 -2
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/auth-api.d.ts +21 -0
- package/dist/auth-api.js +89 -2
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/web-authority.d.ts +12 -2
- package/dist/authority/web-authority.js +25 -4
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/claude-code.d.ts +15 -12
- package/dist/backend/claude-code.js +152 -133
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-package.d.ts +5 -2
- package/dist/backend/codex-package.js +1 -5
- package/dist/backend/codex-package.js.map +1 -1
- package/dist/backend/codex.d.ts +136 -113
- package/dist/backend/codex.js +1281 -1219
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok-model-cache.d.ts +7 -0
- package/dist/backend/grok-model-cache.js +65 -0
- package/dist/backend/grok-model-cache.js.map +1 -0
- package/dist/backend/grok.d.ts +2 -0
- package/dist/backend/grok.js +22 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/native-pane.d.ts +9 -0
- package/dist/backend/native-pane.js +59 -0
- package/dist/backend/native-pane.js.map +1 -0
- package/dist/backend/types.d.ts +7 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +2 -0
- package/dist/channel/mcp-tools.js +1 -1
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +71 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +67 -5
- package/dist/daemon.js +823 -266
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +15 -3
- package/dist/delivery-consumed-watch.js +23 -1
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-outbox.d.ts +5 -0
- package/dist/delivery-outbox.js +32 -4
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +2 -35
- package/dist/delivery-reconciliation.js +2 -156
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/fleet-context.d.ts +2 -2
- package/dist/fleet-level-config.d.ts +1 -1
- package/dist/fleet-level-config.js +2 -0
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +238 -3
- package/dist/fleet-manager.js +1826 -104
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-windows-runtime.d.ts +92 -0
- package/dist/fleet-windows-runtime.js +380 -0
- package/dist/fleet-windows-runtime.js.map +1 -0
- package/dist/general-binding.d.ts +85 -0
- package/dist/general-binding.js +298 -0
- package/dist/general-binding.js.map +1 -0
- package/dist/general-host-owner.d.ts +8 -0
- package/dist/general-host-owner.js +26 -0
- package/dist/general-host-owner.js.map +1 -0
- package/dist/general-instance.d.ts +7 -0
- package/dist/general-instance.js +20 -3
- package/dist/general-instance.js.map +1 -1
- package/dist/general-role.d.ts +5 -0
- package/dist/general-role.js +26 -0
- package/dist/general-role.js.map +1 -0
- package/dist/instance-config-impact.js +4 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +21 -3
- package/dist/instance-lifecycle.js +378 -162
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +2 -0
- package/dist/instructions.js +6 -0
- package/dist/instructions.js.map +1 -1
- package/dist/local-pane-endpoint.d.ts +46 -0
- package/dist/local-pane-endpoint.js +189 -0
- package/dist/local-pane-endpoint.js.map +1 -0
- package/dist/local-pane-launcher.d.ts +2 -0
- package/dist/local-pane-launcher.js +38 -0
- package/dist/local-pane-launcher.js.map +1 -0
- package/dist/local-pane-stage.ps1 +101 -0
- package/dist/locale.js +85 -0
- package/dist/locale.js.map +1 -1
- package/dist/model-catalog-defaults.d.ts +14 -0
- package/dist/model-catalog-defaults.js +20 -0
- package/dist/model-catalog-defaults.js.map +1 -0
- package/dist/native-agent-admission.d.ts +7 -0
- package/dist/native-agent-admission.js +26 -0
- package/dist/native-agent-admission.js.map +1 -0
- package/dist/native-daemon-client.d.ts +13 -0
- package/dist/native-daemon-client.js +28 -0
- package/dist/native-daemon-client.js.map +1 -0
- package/dist/native-instance-api.d.ts +14 -0
- package/dist/native-instance-api.js +205 -0
- package/dist/native-instance-api.js.map +1 -0
- package/dist/native-instance-input.d.ts +84 -0
- package/dist/native-instance-input.js +54 -0
- package/dist/native-instance-input.js.map +1 -0
- package/dist/native-instance-registry.d.ts +32 -0
- package/dist/native-instance-registry.js +105 -0
- package/dist/native-instance-registry.js.map +1 -0
- package/dist/native-mcp.d.ts +40 -0
- package/dist/native-mcp.js +278 -0
- package/dist/native-mcp.js.map +1 -0
- package/dist/native-model-catalog.d.ts +5 -0
- package/dist/native-model-catalog.js +76 -0
- package/dist/native-model-catalog.js.map +1 -0
- package/dist/native-pane-crash-budget.d.ts +20 -0
- package/dist/native-pane-crash-budget.js +60 -0
- package/dist/native-pane-crash-budget.js.map +1 -0
- package/dist/native-pane-create.d.ts +26 -0
- package/dist/native-pane-create.js +53 -0
- package/dist/native-pane-create.js.map +1 -0
- package/dist/native-pane-lifecycle.d.ts +65 -0
- package/dist/native-pane-lifecycle.js +230 -0
- package/dist/native-pane-lifecycle.js.map +1 -0
- package/dist/native-pane-manager.d.ts +59 -0
- package/dist/native-pane-manager.js +584 -0
- package/dist/native-pane-manager.js.map +1 -0
- package/dist/native-pane-output-log.d.ts +15 -0
- package/dist/native-pane-output-log.js +108 -0
- package/dist/native-pane-output-log.js.map +1 -0
- package/dist/native-pane-reconciliation.d.ts +4 -0
- package/dist/native-pane-reconciliation.js +40 -0
- package/dist/native-pane-reconciliation.js.map +1 -0
- package/dist/native-pane-recovery.d.ts +12 -0
- package/dist/native-pane-recovery.js +10 -0
- package/dist/native-pane-recovery.js.map +1 -0
- package/dist/native-pane-tools.d.ts +2 -0
- package/dist/native-pane-tools.js +14 -0
- package/dist/native-pane-tools.js.map +1 -0
- package/dist/needs-you-hub.d.ts +2 -0
- package/dist/needs-you-hub.js +2 -1
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +19 -1
- package/dist/needs-you.js +12 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +16 -2
- package/dist/outbound-handlers.js +67 -3
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +38 -0
- package/dist/outbound-schemas.js +12 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-port.d.ts +118 -0
- package/dist/pane-port.js +2 -0
- package/dist/pane-port.js.map +1 -0
- package/dist/public-web-gateway.js +9 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +5 -0
- package/dist/public-web-link.js +4 -0
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.js +9 -5
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +1 -0
- package/dist/quickstart.js +4 -1
- package/dist/quickstart.js.map +1 -1
- package/dist/runtime-api.d.ts +8 -0
- package/dist/runtime-api.js +96 -0
- package/dist/runtime-api.js.map +1 -0
- package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +21 -0
- package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +2 -0
- package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +19 -0
- package/dist/runtime-assets/@xterm/addon-serialize/package.json +29 -0
- package/dist/runtime-assets/@xterm/headless/LICENSE +21 -0
- package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +2 -0
- package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +46 -0
- package/dist/runtime-assets/@xterm/headless/package.json +29 -0
- package/dist/runtime-assets/node-pty/CONPTY-LICENSE +21 -0
- package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +503 -0
- package/dist/runtime-assets/node-pty/LICENSE +69 -0
- package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +16 -0
- package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +47 -0
- package/dist/runtime-assets/node-pty/lib/index.js +52 -0
- package/dist/runtime-assets/node-pty/lib/interfaces.js +7 -0
- package/dist/runtime-assets/node-pty/lib/shared/conout.js +11 -0
- package/dist/runtime-assets/node-pty/lib/terminal.js +190 -0
- package/dist/runtime-assets/node-pty/lib/types.js +7 -0
- package/dist/runtime-assets/node-pty/lib/unixTerminal.js +346 -0
- package/dist/runtime-assets/node-pty/lib/utils.js +39 -0
- package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +125 -0
- package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +320 -0
- package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +199 -0
- package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +22 -0
- package/dist/runtime-assets/node-pty/package.json +64 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/dist/runtime-bundle.d.ts +17 -0
- package/dist/runtime-bundle.js +150 -0
- package/dist/runtime-bundle.js.map +1 -0
- package/dist/runtime-cli.d.ts +2 -0
- package/dist/runtime-cli.js +117 -0
- package/dist/runtime-cli.js.map +1 -0
- package/dist/runtime-client-store.d.ts +49 -0
- package/dist/runtime-client-store.js +292 -0
- package/dist/runtime-client-store.js.map +1 -0
- package/dist/runtime-client.d.ts +100 -0
- package/dist/runtime-client.js +700 -0
- package/dist/runtime-client.js.map +1 -0
- package/dist/runtime-coordinator.d.ts +82 -0
- package/dist/runtime-coordinator.js +864 -0
- package/dist/runtime-coordinator.js.map +1 -0
- package/dist/runtime-general-protocol.d.ts +22 -0
- package/dist/runtime-general-protocol.js +57 -0
- package/dist/runtime-general-protocol.js.map +1 -0
- package/dist/runtime-general-workspace.d.ts +17 -0
- package/dist/runtime-general-workspace.js +213 -0
- package/dist/runtime-general-workspace.js.map +1 -0
- package/dist/runtime-pane-assets.d.ts +17 -0
- package/dist/runtime-pane-assets.js +23 -0
- package/dist/runtime-pane-assets.js.map +1 -0
- package/dist/runtime-pane-boot.d.ts +2 -0
- package/dist/runtime-pane-boot.js +24 -0
- package/dist/runtime-pane-boot.js.map +1 -0
- package/dist/runtime-pane-codex-index.d.ts +1 -0
- package/dist/runtime-pane-codex-index.js +47 -0
- package/dist/runtime-pane-codex-index.js.map +1 -0
- package/dist/runtime-pane-config.d.ts +16 -0
- package/dist/runtime-pane-config.js +54 -0
- package/dist/runtime-pane-config.js.map +1 -0
- package/dist/runtime-pane-host.d.ts +44 -0
- package/dist/runtime-pane-host.js +424 -0
- package/dist/runtime-pane-host.js.map +1 -0
- package/dist/runtime-pane-job-owner.d.ts +1 -0
- package/dist/runtime-pane-job-owner.js +29 -0
- package/dist/runtime-pane-job-owner.js.map +1 -0
- package/dist/runtime-pane-job.ps1 +116 -0
- package/dist/runtime-pane-link.d.ts +40 -0
- package/dist/runtime-pane-link.js +246 -0
- package/dist/runtime-pane-link.js.map +1 -0
- package/dist/runtime-pane-mcp-protocol.d.ts +32 -0
- package/dist/runtime-pane-mcp-protocol.js +39 -0
- package/dist/runtime-pane-mcp-protocol.js.map +1 -0
- package/dist/runtime-pane-mcp-relay.d.ts +17 -0
- package/dist/runtime-pane-mcp-relay.js +70 -0
- package/dist/runtime-pane-mcp-relay.js.map +1 -0
- package/dist/runtime-pane-mcp.d.ts +51 -0
- package/dist/runtime-pane-mcp.js +150 -0
- package/dist/runtime-pane-mcp.js.map +1 -0
- package/dist/runtime-pane-native.d.ts +45 -0
- package/dist/runtime-pane-native.js +65 -0
- package/dist/runtime-pane-native.js.map +1 -0
- package/dist/runtime-pane-output.d.ts +19 -0
- package/dist/runtime-pane-output.js +53 -0
- package/dist/runtime-pane-output.js.map +1 -0
- package/dist/runtime-pane-port.d.ts +139 -0
- package/dist/runtime-pane-port.js +558 -0
- package/dist/runtime-pane-port.js.map +1 -0
- package/dist/runtime-pane-private.d.ts +14 -0
- package/dist/runtime-pane-private.js +51 -0
- package/dist/runtime-pane-private.js.map +1 -0
- package/dist/runtime-pane-private.ps1 +14 -0
- package/dist/runtime-pane-process.d.ts +4 -0
- package/dist/runtime-pane-process.js +108 -0
- package/dist/runtime-pane-process.js.map +1 -0
- package/dist/runtime-pane-protocol.d.ts +172 -0
- package/dist/runtime-pane-protocol.js +195 -0
- package/dist/runtime-pane-protocol.js.map +1 -0
- package/dist/runtime-pane-screen.d.ts +19 -0
- package/dist/runtime-pane-screen.js +76 -0
- package/dist/runtime-pane-screen.js.map +1 -0
- package/dist/runtime-pane-service.d.ts +11 -0
- package/dist/runtime-pane-service.js +221 -0
- package/dist/runtime-pane-service.js.map +1 -0
- package/dist/runtime-pane-stdio-protocol.d.ts +54 -0
- package/dist/runtime-pane-stdio-protocol.js +94 -0
- package/dist/runtime-pane-stdio-protocol.js.map +1 -0
- package/dist/runtime-pane-stdio.d.ts +3 -0
- package/dist/runtime-pane-stdio.js +123 -0
- package/dist/runtime-pane-stdio.js.map +1 -0
- package/dist/runtime-pane-store.d.ts +33 -0
- package/dist/runtime-pane-store.js +164 -0
- package/dist/runtime-pane-store.js.map +1 -0
- package/dist/runtime-pane-transcript-protocol.d.ts +43 -0
- package/dist/runtime-pane-transcript-protocol.js +58 -0
- package/dist/runtime-pane-transcript-protocol.js.map +1 -0
- package/dist/runtime-pane-transcript.d.ts +45 -0
- package/dist/runtime-pane-transcript.js +605 -0
- package/dist/runtime-pane-transcript.js.map +1 -0
- package/dist/runtime-pane-worker.d.ts +1 -0
- package/dist/runtime-pane-worker.js +154 -0
- package/dist/runtime-pane-worker.js.map +1 -0
- package/dist/runtime-protocol.d.ts +149 -0
- package/dist/runtime-protocol.js +19 -0
- package/dist/runtime-protocol.js.map +1 -0
- package/dist/runtime-switches.d.ts +79 -0
- package/dist/runtime-switches.js +90 -0
- package/dist/runtime-switches.js.map +1 -0
- package/dist/runtime-transcript-delta-reader.d.ts +23 -0
- package/dist/runtime-transcript-delta-reader.js +74 -0
- package/dist/runtime-transcript-delta-reader.js.map +1 -0
- package/dist/runtime-transcript-source.d.ts +36 -0
- package/dist/runtime-transcript-source.js +189 -0
- package/dist/runtime-transcript-source.js.map +1 -0
- package/dist/runtime-windows-bridge.d.ts +41 -0
- package/dist/runtime-windows-bridge.js +157 -0
- package/dist/runtime-windows-bridge.js.map +1 -0
- package/dist/settings-api.d.ts +5 -0
- package/dist/settings-api.js +95 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +1 -0
- package/dist/settings-baseline.js +1 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.js +28 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +16 -1
- package/dist/settings-confirmation.js +47 -9
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.d.ts +4 -0
- package/dist/settings-effect.js +58 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +1 -0
- package/dist/settings-http-confirmation.js +15 -2
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-request-capability.d.ts +2 -0
- package/dist/settings-request-capability.js +4 -0
- package/dist/settings-request-capability.js.map +1 -1
- package/dist/settings-route-lifetime.d.ts +14 -0
- package/dist/settings-route-lifetime.js +48 -0
- package/dist/settings-route-lifetime.js.map +1 -0
- package/dist/settings-transaction.d.ts +4 -0
- package/dist/settings-transaction.js +9 -0
- package/dist/settings-transaction.js.map +1 -1
- package/dist/setup-form.js +6 -3
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.js +3 -0
- package/dist/setup-i18n.js.map +1 -1
- package/dist/tmux-control.d.ts +2 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +2 -1
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-pane-host.d.ts +26 -0
- package/dist/tmux-pane-host.js +25 -0
- package/dist/tmux-pane-host.js.map +1 -0
- package/dist/tool-permissions.js +2 -1
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.js +3 -0
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-delta-reader.d.ts +1 -1
- package/dist/transcript-delta-reader.js +1 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/transcript-monitor.d.ts +3 -0
- package/dist/transcript-monitor.js +22 -46
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-needles.d.ts +35 -0
- package/dist/transcript-needles.js +158 -0
- package/dist/transcript-needles.js.map +1 -0
- package/dist/transcript-records.d.ts +21 -0
- package/dist/transcript-records.js +140 -0
- package/dist/transcript-records.js.map +1 -0
- package/dist/transcript-sources.d.ts +5 -0
- package/dist/transcript-sources.js +8 -79
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/ui/agent-proposals.js +90 -0
- package/dist/ui/agent-runtime.js +106 -0
- package/dist/ui/chat-store.js +13 -2
- package/dist/ui/chat-strings.js +48 -0
- package/dist/ui/cli-picker.js +42 -0
- package/dist/ui/general-location.js +71 -0
- package/dist/ui/native-instance-settings.js +47 -0
- package/dist/ui/native-pane-recovery.js +45 -0
- package/dist/ui/panel-chat.js +63 -32
- package/dist/ui/panel-details.js +2 -1
- package/dist/ui/panel-fleet.js +99 -18
- package/dist/ui/panel-needs.js +154 -3
- package/dist/ui/panel-runtimes.js +231 -0
- package/dist/ui/panel-settings.js +19 -9
- package/dist/ui/panel-windows-agent.js +86 -0
- package/dist/ui/panel-windows-cli.js +143 -0
- package/dist/ui/provider-marks.js +83 -0
- package/dist/ui/runtime-catalog.js +55 -0
- package/dist/ui/settings-catalog.js +37 -10
- package/dist/ui/settings-confirm.js +3 -1
- package/dist/ui/settings-dialogs.js +22 -7
- package/dist/ui/settings-model.js +2 -1
- package/dist/ui/settings-outside.js +176 -0
- package/dist/ui/settings-registry.js +6 -0
- package/dist/ui/settings-strings.js +16 -0
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-route.js +6 -2
- package/dist/ui/shared/app-shell.js +3 -2
- package/dist/ui/shared/app-store.js +1 -0
- package/dist/ui/shared/app-stream.js +3 -1
- package/dist/ui/shared/app.css +301 -0
- package/dist/ui/shared/app.js +4 -0
- package/dist/ui/shared/header-tools.js +6 -4
- package/dist/ui/shared/instance-nav.js +33 -7
- package/dist/ui/shared/instance-switch.js +4 -3
- package/dist/ui/shared/qrcode.module.js +2237 -0
- package/dist/ui/shared/signin.js +39 -5
- package/dist/ui/shared/ui-menu.js +28 -8
- package/dist/ui/shared/vendor/qrcode-generator.LICENSE +27 -0
- package/dist/ui/shared/vendor/vendor.json +19 -2
- package/dist/ui/shared/view-strings.js +8 -0
- package/dist/ui/windows-agents-nav.js +2 -0
- package/dist/ui/windows-cli-catalog.js +79 -0
- package/dist/web-api.d.ts +37 -0
- package/dist/web-api.js +248 -6
- package/dist/web-api.js.map +1 -1
- package/dist/web-chat-history.d.ts +19 -2
- package/dist/web-chat-history.js +72 -3
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-only-fleet.d.ts +20 -0
- package/dist/web-only-fleet.js +21 -0
- package/dist/web-only-fleet.js.map +1 -1
- package/dist/web-remote-access.d.ts +152 -0
- package/dist/web-remote-access.js +368 -0
- package/dist/web-remote-access.js.map +1 -0
- package/dist/web-session.d.ts +7 -0
- package/dist/web-session.js +2 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-shell-routes.d.ts +4 -1
- package/dist/web-shell-routes.js +7 -2
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/windows-agents.d.ts +124 -0
- package/dist/windows-agents.js +487 -0
- package/dist/windows-agents.js.map +1 -0
- package/dist/windows-cli-api.d.ts +23 -0
- package/dist/windows-cli-api.js +158 -0
- package/dist/windows-cli-api.js.map +1 -0
- package/dist/windows-cli-providers.d.ts +115 -0
- package/dist/windows-cli-providers.js +429 -0
- package/dist/windows-cli-providers.js.map +1 -0
- package/dist/windows-cli-worker.d.ts +58 -0
- package/dist/windows-cli-worker.js +479 -0
- package/dist/windows-cli-worker.js.map +1 -0
- package/dist/windows-cli.d.ts +115 -0
- package/dist/windows-cli.js +402 -0
- package/dist/windows-cli.js.map +1 -0
- package/dist/windows-native-mcp.d.ts +19 -0
- package/dist/windows-native-mcp.js +143 -0
- package/dist/windows-native-mcp.js.map +1 -0
- package/dist/windows-pane-mcp.d.ts +26 -0
- package/dist/windows-pane-mcp.js +187 -0
- package/dist/windows-pane-mcp.js.map +1 -0
- package/package.json +9 -3
- package/templates/runtime-assets/conpty-LICENSE +21 -0
- package/templates/runtime-assets/conpty-NOTICE.md +503 -0
- package/templates/runtime-assets/local-pane-stage.ps1 +101 -0
- package/templates/runtime-assets/runtime-pane-job.ps1 +116 -0
- package/templates/runtime-assets/runtime-pane-private.ps1 +14 -0
- package/templates/runtime-assets/xterm-LICENSE +21 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import { t } from "./locale.js";
|
|
2
|
+
import { loadGeneralKnowledge } from "./runtime-general-workspace.js";
|
|
3
|
+
import { generalWorkspaceUpgrade, validateGeneralWorkspaceReceipt } from "./runtime-general-protocol.js";
|
|
4
|
+
import { NativePaneRecoveryError } from "./native-pane-recovery.js";
|
|
5
|
+
/** Fleet-owned native launch registry. No process IDs, credentials or provider paths cross this boundary. */
|
|
6
|
+
import { lstatSync, readFileSync, mkdirSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
import { atomicWriteFileSync } from "./atomic-write.js";
|
|
10
|
+
import { runtimeJobDigest } from "./runtime-client-store.js";
|
|
11
|
+
import { RuntimeNativePaneLifecycle } from "./native-pane-lifecycle.js";
|
|
12
|
+
import { assertAuditedNativePaneVersion } from "./runtime-pane-native.js";
|
|
13
|
+
import { PaneMcpAuthorityLease } from "./runtime-pane-mcp.js";
|
|
14
|
+
import { validateRuntimePaneLaunch, validateRuntimePaneSnapshot, validateRuntimePaneSessionProof } from "./runtime-pane-protocol.js";
|
|
15
|
+
import { validatePaneMcpBody } from "./runtime-pane-mcp-protocol.js";
|
|
16
|
+
const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
|
|
17
|
+
export class NativePaneManager {
|
|
18
|
+
options;
|
|
19
|
+
bindings = new Map();
|
|
20
|
+
preparing = new Set();
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
directory(id) {
|
|
25
|
+
if (!UUID.test(id))
|
|
26
|
+
throw Error("Invalid native agent identity");
|
|
27
|
+
const root = join(this.options.home, "native-panes");
|
|
28
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
29
|
+
const stat = lstatSync(root);
|
|
30
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || process.getuid && (stat.uid !== process.getuid() || !!(stat.mode & 0o077)))
|
|
31
|
+
throw Error("Unsafe native pane registry");
|
|
32
|
+
const directory = join(root, id);
|
|
33
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
34
|
+
const own = lstatSync(directory);
|
|
35
|
+
if (!own.isDirectory() || own.isSymbolicLink() || process.getuid && (own.uid !== process.getuid() || !!(own.mode & 0o077)))
|
|
36
|
+
throw Error("Unsafe native pane registry");
|
|
37
|
+
return directory;
|
|
38
|
+
}
|
|
39
|
+
load(file) {
|
|
40
|
+
try {
|
|
41
|
+
const stat = lstatSync(file);
|
|
42
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 128 * 1024 || process.getuid && (stat.uid !== process.getuid() || !!(stat.mode & 0o077)))
|
|
43
|
+
throw Error("Unsafe native launch manifest");
|
|
44
|
+
const value = JSON.parse(readFileSync(file, "utf8"));
|
|
45
|
+
if (value?.version !== 1 || !/^([a-f0-9]{64})$/.test(value.configuration) || Object.keys(value).some(key => !["version", "machineId", "configuration", "launch", "exited", "fresh"].includes(key)) || value.machineId !== "local" && !UUID.test(value.machineId))
|
|
46
|
+
throw Error("Invalid native launch manifest");
|
|
47
|
+
validateRuntimePaneLaunch(value.launch);
|
|
48
|
+
if (!value.launch.launchId || !UUID.test(value.launch.launchId))
|
|
49
|
+
throw Error("Native launch identity is missing");
|
|
50
|
+
if (value.exited) {
|
|
51
|
+
const exit = validateRuntimePaneSnapshot(value.exited);
|
|
52
|
+
if (exit.state !== "exited" || exit.agentId !== value.launch.agentId || exit.instance !== value.launch.instance || exit.paneId !== value.launch.paneId || exit.launchId !== value.launch.launchId)
|
|
53
|
+
throw Error("Native exit manifest scope differs");
|
|
54
|
+
}
|
|
55
|
+
if (value.fresh) {
|
|
56
|
+
const fresh = value.fresh, previous = validateRuntimePaneSnapshot(fresh.previous);
|
|
57
|
+
if (Object.keys(fresh).some(key => !["previous", "automatic", "announced", "previousLaunch", "sessionId", "decisionLaunchId"].includes(key)) || typeof fresh.automatic !== "boolean" || fresh.announced !== undefined && fresh.announced !== true
|
|
58
|
+
|| !["claude-code", "codex"].includes(value.launch.cli) || value.launch.sessionId !== undefined || previous.state !== "exited" || previous.noLaunch || !previous.sessionId && (value.launch.cli !== "codex" || fresh.automatic)
|
|
59
|
+
|| previous.agentId !== value.launch.agentId || previous.instance !== value.launch.instance || previous.launchId === value.launch.launchId || previous.sessionId === value.launch.launchId)
|
|
60
|
+
throw Error("Invalid fresh pane intent");
|
|
61
|
+
if (value.launch.cli === "codex") {
|
|
62
|
+
const old = validateRuntimePaneLaunch(fresh.previousLaunch);
|
|
63
|
+
if (old.cli !== "codex" || old.agentId !== previous.agentId || old.instance !== previous.instance || old.paneId !== previous.paneId || old.launchId !== previous.launchId
|
|
64
|
+
|| (typeof fresh.decisionLaunchId !== "string" || !UUID.test(fresh.decisionLaunchId) || fresh.decisionLaunchId === value.launch.launchId)
|
|
65
|
+
|| fresh.sessionId !== undefined && (typeof fresh.sessionId !== "string" || !UUID.test(fresh.sessionId) || fresh.sessionId === previous.sessionId))
|
|
66
|
+
throw Error("Invalid fresh Codex binding");
|
|
67
|
+
}
|
|
68
|
+
else if (fresh.previousLaunch !== undefined || fresh.sessionId !== undefined || fresh.decisionLaunchId !== undefined)
|
|
69
|
+
throw Error("Unexpected Claude fresh binding");
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (error.code === "ENOENT")
|
|
75
|
+
return null;
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
save(file, value) { atomicWriteFileSync(file, JSON.stringify(value), { mode: 0o600 }); }
|
|
80
|
+
configurationHash(agent, config) {
|
|
81
|
+
return runtimeJobDigest({ cli: agent.cli, cwd: agent.cwd, sandbox: config.native_sandbox, model: config.model || "", prompt: config.systemPrompt || "", workflow: config.workflow ?? null,
|
|
82
|
+
...(config.general_topic ? { general: true, binding: config.native_general_binding } : {}) });
|
|
83
|
+
}
|
|
84
|
+
newManifest(name, config, agent, machineId, resume = true, identity) {
|
|
85
|
+
const launch = validateRuntimePaneLaunch({ cli: agent.cli, cwd: agent.cwd, sandbox: config.native_sandbox, instructions: this.options.instructions(name, config),
|
|
86
|
+
...(config.model ? { model: config.model } : {}), agentId: agent.id, instance: name, paneId: identity?.paneId ?? randomUUID(), launchId: identity?.launchId ?? randomUUID(),
|
|
87
|
+
columns: 120, rows: 40, ...(resume && agent.threadId ? { sessionId: agent.threadId } : {}), mcpTools: this.options.menu(name).map(tool => tool.name),
|
|
88
|
+
...(config.general_topic ? { generalWorkspace: { bindingId: config.native_general_binding, packHash: loadGeneralKnowledge(agent.cli).hash } } : {}) });
|
|
89
|
+
return { version: 1, machineId, configuration: this.configurationHash(agent, config), launch };
|
|
90
|
+
}
|
|
91
|
+
freshIntent(file, manifest, automatic, config, agent) {
|
|
92
|
+
const previous = manifest.exited?.sessionId ? manifest.exited : manifest.launch.cli === "codex" ? manifest.fresh?.previous ?? manifest.exited : undefined;
|
|
93
|
+
const previousLaunch = manifest.exited?.sessionId ? manifest.launch : manifest.fresh?.previousLaunch ?? manifest.launch;
|
|
94
|
+
if (!previous || !previous.sessionId && (agent.cli !== "codex" || automatic) || !manifest.exited || !["claude-code", "codex"].includes(manifest.launch.cli))
|
|
95
|
+
throw Error("A fresh conversation requires its previous positive exit");
|
|
96
|
+
// The previous launch can have obsolete cold settings; only its positive exit is carried into this decision.
|
|
97
|
+
const next = { ...this.newManifest(manifest.launch.instance, config, agent, manifest.machineId, false), fresh: { previous, automatic, ...(agent.cli === "codex" ? { previousLaunch, decisionLaunchId: manifest.launch.launchId } : {}) } };
|
|
98
|
+
this.save(file, next);
|
|
99
|
+
return next;
|
|
100
|
+
}
|
|
101
|
+
bindFreshCodex(file, manifest, observed) {
|
|
102
|
+
const fresh = manifest.fresh, launch = manifest.launch;
|
|
103
|
+
if (launch.cli !== "codex" || !fresh || !observed.sessionId || observed.sessionId === fresh.previous.sessionId
|
|
104
|
+
|| observed.launchId !== launch.launchId || observed.paneId !== launch.paneId || observed.agentId !== launch.agentId || observed.instance !== launch.instance
|
|
105
|
+
|| fresh.sessionId !== undefined && fresh.sessionId !== observed.sessionId)
|
|
106
|
+
throw Error("Fresh Codex observed identity differs");
|
|
107
|
+
const next = { ...manifest, fresh: { ...fresh, sessionId: observed.sessionId } };
|
|
108
|
+
this.save(file, next);
|
|
109
|
+
this.options.store.pinFreshCodexSession(launch.agentId, fresh.previous, observed);
|
|
110
|
+
return next;
|
|
111
|
+
}
|
|
112
|
+
recordExit(file, manifest, snapshot) {
|
|
113
|
+
if (manifest.launch.cli === "codex" && manifest.fresh?.sessionId && snapshot.sessionId !== undefined && snapshot.sessionId !== manifest.fresh.sessionId)
|
|
114
|
+
throw Error("Fresh Codex exit conversation differs");
|
|
115
|
+
let next = manifest;
|
|
116
|
+
if (manifest.launch.cli === "codex" && manifest.fresh && snapshot.sessionId && snapshot.sessionId !== manifest.fresh.previous.sessionId
|
|
117
|
+
&& this.options.store.get(snapshot.agentId).threadId !== snapshot.sessionId)
|
|
118
|
+
next = this.bindFreshCodex(file, manifest, snapshot);
|
|
119
|
+
next = { ...next, exited: snapshot };
|
|
120
|
+
this.save(file, next);
|
|
121
|
+
const profile = this.options.store.get(snapshot.agentId);
|
|
122
|
+
if (!snapshot.noLaunch && !profile.threadId && snapshot.sessionId && profile.activeId)
|
|
123
|
+
this.options.store.pinPaneSession(snapshot.agentId, snapshot.launchId, snapshot.sessionId);
|
|
124
|
+
if (this.options.store.get(snapshot.agentId).activeId) {
|
|
125
|
+
if (!snapshot.noLaunch && next.launch.cli === "codex" && next.fresh?.previous.sessionId && !snapshot.sessionId)
|
|
126
|
+
this.options.store.releaseUnpinnedCodexPane(snapshot.agentId, next.fresh.previous, snapshot);
|
|
127
|
+
else
|
|
128
|
+
this.options.store.releasePane(snapshot.agentId, snapshot);
|
|
129
|
+
}
|
|
130
|
+
if (!snapshot.noLaunch && (!snapshot.sessionId || !profile.threadId))
|
|
131
|
+
this.options.store.setPaneRecovery(snapshot.agentId, { kind: "session-unconfirmed", launchId: snapshot.launchId, sessionId: this.options.store.get(snapshot.agentId).threadId, ...(next.launch.cli === "codex" ? { provider: "codex" } : {}) });
|
|
132
|
+
return next;
|
|
133
|
+
}
|
|
134
|
+
async sessionState(endpoint, previous, supported) {
|
|
135
|
+
if (!previous.sessionId)
|
|
136
|
+
return "unknown"; // A positive process exit is independent of a provider conversation pin.
|
|
137
|
+
if (!supported)
|
|
138
|
+
throw new NativePaneRecoveryError({ kind: "host-upgrade", launchId: previous.launchId }); // Use the existing host-upgrade recovery, never a conversation decision.
|
|
139
|
+
const raw = await endpoint.call({ action: "session-proof", paneId: previous.paneId, launchId: previous.launchId });
|
|
140
|
+
try {
|
|
141
|
+
const proof = validateRuntimePaneSessionProof(raw);
|
|
142
|
+
if (runtimeJobDigest(proof.snapshot) === runtimeJobDigest(previous))
|
|
143
|
+
return proof.state;
|
|
144
|
+
}
|
|
145
|
+
catch { /* A reachable malformed result cannot prove absence. */ }
|
|
146
|
+
return "unknown";
|
|
147
|
+
}
|
|
148
|
+
/** Prepare metadata and helper authority first; acquire() alone may reserve and spawn. */
|
|
149
|
+
async prepare(name, config, assertCurrent) {
|
|
150
|
+
const id = config.native_agent_id;
|
|
151
|
+
if (!id || !UUID.test(id) || this.preparing.has(id))
|
|
152
|
+
throw Error("Native pane preparation already has an owner or lacks an identity");
|
|
153
|
+
this.preparing.add(id);
|
|
154
|
+
try {
|
|
155
|
+
return await this.prepareOwned(name, config, assertCurrent);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
if (error instanceof NativePaneRecoveryError) {
|
|
159
|
+
assertCurrent();
|
|
160
|
+
this.options.store.setPaneRecovery(id, error.recovery);
|
|
161
|
+
}
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
this.preparing.delete(id);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async prepareOwned(name, config, assertCurrent) {
|
|
169
|
+
config = structuredClone(config);
|
|
170
|
+
assertCurrent();
|
|
171
|
+
this.options.admit(name, config);
|
|
172
|
+
const id = config.native_agent_id;
|
|
173
|
+
if (!id || !UUID.test(id))
|
|
174
|
+
throw Error("Native pane profile is missing");
|
|
175
|
+
let agent = this.options.store.get(id);
|
|
176
|
+
if (agent.fleet_instance !== name || agent.machineId !== config.machine_id || agent.cli !== config.backend || agent.cwd !== config.working_directory)
|
|
177
|
+
throw Error("Native pane profile scope differs");
|
|
178
|
+
if (config.general_topic && (!agent.machineId || !UUID.test(config.native_general_binding ?? "")))
|
|
179
|
+
throw Error("Windows General requires its prepared paired-machine binding");
|
|
180
|
+
const directory = this.directory(id), file = join(directory, "active.json");
|
|
181
|
+
let manifest = this.load(file);
|
|
182
|
+
if (manifest && (manifest.launch.agentId !== id || manifest.launch.instance !== name || manifest.machineId !== (agent.machineId ?? "local")))
|
|
183
|
+
throw Error("Native launch manifest scope differs");
|
|
184
|
+
if (this.bindings.has(id))
|
|
185
|
+
throw Error("Native pane still has a coordinator owner");
|
|
186
|
+
const missingSession = () => new NativePaneRecoveryError({ kind: "session-unconfirmed", launchId: manifest.launch.launchId, sessionId: agent.threadId, ...(agent.cli === "codex" ? { provider: "codex" } : {}) });
|
|
187
|
+
const endpoint = await this.options.endpoint(agent);
|
|
188
|
+
assertCurrent();
|
|
189
|
+
this.options.admit(name, config);
|
|
190
|
+
if (endpoint.machineId !== (agent.machineId ?? "local"))
|
|
191
|
+
throw Error("Native endpoint machine scope differs");
|
|
192
|
+
assertAuditedNativePaneVersion(agent.cli, endpoint.version(agent.cli));
|
|
193
|
+
const inventory = await endpoint.call({ action: "list" });
|
|
194
|
+
assertCurrent();
|
|
195
|
+
this.options.admit(name, config);
|
|
196
|
+
if (!inventory || typeof inventory !== "object" || !UUID.test(inventory.hostBootId) || !Array.isArray(inventory.panes) || inventory.panes.length > 4096)
|
|
197
|
+
throw Error("Native host identity is unconfirmed");
|
|
198
|
+
const latest = this.options.store.get(id);
|
|
199
|
+
if (runtimeJobDigest({ id: latest.id, cli: latest.cli, cwd: latest.cwd, machineId: latest.machineId, activeId: latest.activeId, paneLaunchId: latest.paneLaunchId, threadId: latest.threadId, paused: latest.paused }) !== runtimeJobDigest({ id: agent.id, cli: agent.cli, cwd: agent.cwd, machineId: agent.machineId, activeId: agent.activeId, paneLaunchId: agent.paneLaunchId, threadId: agent.threadId, paused: agent.paused }))
|
|
200
|
+
throw Error("Native profile changed during host observation");
|
|
201
|
+
const hostBootId = inventory.hostBootId, panes = inventory.panes.map(validateRuntimePaneSnapshot);
|
|
202
|
+
if (inventory.capabilities?.openDisposition !== true)
|
|
203
|
+
throw new NativePaneRecoveryError({ kind: "host-upgrade", ...(manifest ? { launchId: manifest.launch.launchId } : {}) });
|
|
204
|
+
if (config.general_topic && inventory.capabilities?.generalWorkspace !== true)
|
|
205
|
+
throw new NativePaneRecoveryError({ kind: "host-upgrade", ...(manifest ? { launchId: manifest.launch.launchId } : {}) });
|
|
206
|
+
const sameAgent = panes.filter(row => row.agentId === id && row.state !== "exited");
|
|
207
|
+
if (sameAgent.length > 1 || sameAgent.some(row => !manifest || row.paneId !== manifest.launch.paneId || row.launchId !== manifest.launch.launchId || row.instance !== name))
|
|
208
|
+
throw Error("Another live or unknown native pane must be reconciled first");
|
|
209
|
+
let preparedFresh = false;
|
|
210
|
+
if (manifest && !manifest.exited && !agent.activeId && !panes.some(row => row.paneId === manifest.launch.paneId)) {
|
|
211
|
+
// Factory metadata alone is not an open: reserve() and the pane receipt precede every RPC which may spawn.
|
|
212
|
+
try {
|
|
213
|
+
lstatSync(join(directory, `${manifest.launch.launchId}.pane.json`));
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
if (error.code !== "ENOENT")
|
|
217
|
+
throw error;
|
|
218
|
+
if (manifest.fresh)
|
|
219
|
+
preparedFresh = true;
|
|
220
|
+
else
|
|
221
|
+
manifest = null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (manifest && !manifest.exited && !preparedFresh) {
|
|
225
|
+
const matches = panes.filter(row => row.paneId === manifest.launch.paneId);
|
|
226
|
+
if (matches.length > 1)
|
|
227
|
+
throw Error("Native host returned duplicate retained panes");
|
|
228
|
+
const ended = matches[0], old = manifest.launch;
|
|
229
|
+
if (ended?.state === "exited") {
|
|
230
|
+
const session = agent.threadId ?? old.sessionId ?? ended.sessionId ?? (old.cli === "claude-code" ? old.launchId : undefined);
|
|
231
|
+
if (manifest.fresh && agent.cli === "codex" && ended.sessionId && ended.sessionId !== manifest.fresh.previous.sessionId) {
|
|
232
|
+
manifest = this.bindFreshCodex(file, manifest, ended);
|
|
233
|
+
agent = this.options.store.get(id);
|
|
234
|
+
}
|
|
235
|
+
const pendingCodex = agent.cli === "codex" && manifest.fresh && !manifest.fresh.sessionId && agent.threadId === manifest.fresh.previous.sessionId && !ended.sessionId;
|
|
236
|
+
if (ended.agentId !== id || ended.instance !== name || ended.launchId !== old.launchId || session !== undefined && ended.sessionId !== session && !pendingCodex && agent.threadId !== ended.sessionId)
|
|
237
|
+
throw Error("Native retained exit scope differs");
|
|
238
|
+
// The host reconciles exact helper exits before listing. Persist its positive evidence before releasing the slot.
|
|
239
|
+
manifest = { ...manifest, exited: ended };
|
|
240
|
+
this.save(file, manifest);
|
|
241
|
+
}
|
|
242
|
+
else if (!ended || ended.state === "unknown" || ended.hostBootId !== hostBootId) {
|
|
243
|
+
throw new NativePaneRecoveryError({ kind: "exit-unconfirmed", launchId: old.launchId, ...(ended ? { hostBootId: ended.hostBootId } : {}) });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (manifest?.exited) {
|
|
247
|
+
if (!manifest.exited.noLaunch && !manifest.exited.sessionId) {
|
|
248
|
+
// The process is positively gone even if it exited before reporting its first provider UUID.
|
|
249
|
+
manifest = this.recordExit(file, manifest, manifest.exited);
|
|
250
|
+
agent = this.options.store.get(id);
|
|
251
|
+
throw missingSession();
|
|
252
|
+
}
|
|
253
|
+
if (!manifest.exited.noLaunch && manifest.exited.sessionId && !agent.threadId && agent.activeId) {
|
|
254
|
+
this.options.store.pinPaneSession(id, manifest.exited.launchId, manifest.exited.sessionId);
|
|
255
|
+
agent = this.options.store.get(id);
|
|
256
|
+
}
|
|
257
|
+
if (!manifest.exited.noLaunch && !agent.threadId)
|
|
258
|
+
throw new NativePaneRecoveryError({ kind: "exit-unconfirmed", launchId: manifest.launch.launchId, hostBootId: manifest.exited.hostBootId });
|
|
259
|
+
if (agent.activeId) {
|
|
260
|
+
this.options.store.releasePane(id, manifest.exited);
|
|
261
|
+
agent = this.options.store.get(id);
|
|
262
|
+
}
|
|
263
|
+
if (!manifest.exited.noLaunch) {
|
|
264
|
+
const epoch = endpoint.epoch(), before = runtimeJobDigest(agent);
|
|
265
|
+
// RPC failures stay retryable; only a reachable result can hold the session. Older hosts use the upgrade hold.
|
|
266
|
+
const state = await this.sessionState(endpoint, manifest.exited, inventory.capabilities?.[agent.cli === "codex" ? "codexSessionProof" : "claudeSessionProof"] === true);
|
|
267
|
+
assertCurrent();
|
|
268
|
+
this.options.admit(name, config);
|
|
269
|
+
if (!endpoint.online() || endpoint.epoch() !== epoch || runtimeJobDigest(this.options.store.get(id)) !== before)
|
|
270
|
+
throw Error("Native profile or transport changed during session proof");
|
|
271
|
+
if (state === "absent" && !manifest.fresh) {
|
|
272
|
+
manifest = this.freshIntent(file, manifest, true, config, agent);
|
|
273
|
+
preparedFresh = true;
|
|
274
|
+
}
|
|
275
|
+
else if (state !== "saved")
|
|
276
|
+
throw missingSession();
|
|
277
|
+
else
|
|
278
|
+
manifest = null;
|
|
279
|
+
}
|
|
280
|
+
else if (manifest.fresh)
|
|
281
|
+
throw missingSession();
|
|
282
|
+
else
|
|
283
|
+
manifest = null;
|
|
284
|
+
}
|
|
285
|
+
if (preparedFresh && manifest?.fresh) {
|
|
286
|
+
// No open receipt/reservation exists: refresh the unlaunched intent's settings, retaining its chosen UUIDs.
|
|
287
|
+
const current = this.newManifest(name, config, agent, manifest.machineId, false, manifest.launch);
|
|
288
|
+
const refreshed = { ...manifest, configuration: current.configuration, launch: current.launch };
|
|
289
|
+
if (runtimeJobDigest(refreshed) !== runtimeJobDigest(manifest))
|
|
290
|
+
this.save(file, refreshed);
|
|
291
|
+
manifest = refreshed;
|
|
292
|
+
if (agent.cli === "claude-code")
|
|
293
|
+
this.options.store.replacePaneSession(id, manifest.fresh.previous, manifest.launch.launchId);
|
|
294
|
+
agent = this.options.store.get(id);
|
|
295
|
+
}
|
|
296
|
+
// Hot identity metadata and bundled instruction-template edits do not retire a live pane on coordinator update.
|
|
297
|
+
const configurationHash = this.configurationHash(agent, config);
|
|
298
|
+
if (config.general_topic && (!manifest || preparedFresh)) {
|
|
299
|
+
const request = { action: "general-workspace", bindingId: config.native_general_binding, instance: name, cli: agent.cli, packHash: loadGeneralKnowledge(agent.cli).hash };
|
|
300
|
+
const epoch = endpoint.epoch(), before = runtimeJobDigest(agent), raw = await endpoint.call(request);
|
|
301
|
+
assertCurrent();
|
|
302
|
+
this.options.admit(name, config);
|
|
303
|
+
if (!endpoint.online() || endpoint.epoch() !== epoch || runtimeJobDigest(this.options.store.get(id)) !== before)
|
|
304
|
+
throw Error("General profile or transport changed during workspace preparation");
|
|
305
|
+
if (generalWorkspaceUpgrade(raw, request))
|
|
306
|
+
throw new NativePaneRecoveryError({ kind: "host-upgrade" });
|
|
307
|
+
if (validateGeneralWorkspaceReceipt(raw, request).cwd.toLowerCase() !== agent.cwd.toLowerCase())
|
|
308
|
+
throw Error("General workspace does not match its retained profile");
|
|
309
|
+
}
|
|
310
|
+
if (manifest) {
|
|
311
|
+
const old = manifest.launch;
|
|
312
|
+
if (manifest.configuration !== configurationHash)
|
|
313
|
+
throw Error("Retained native launch settings differ; close its owned pane before applying changes");
|
|
314
|
+
if (agent.activeId && agent.paneLaunchId !== old.launchId)
|
|
315
|
+
throw Error("Native profile has a different active owner");
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
if (agent.activeId)
|
|
319
|
+
throw Error("Native profile outcome is unknown; no replacement was started");
|
|
320
|
+
manifest = this.newManifest(name, config, agent, endpoint.machineId);
|
|
321
|
+
this.save(file, manifest);
|
|
322
|
+
}
|
|
323
|
+
let retained = manifest;
|
|
324
|
+
const launch = retained.launch;
|
|
325
|
+
let daemon, binding, closed = false;
|
|
326
|
+
const current = () => {
|
|
327
|
+
if (closed || !endpoint.online() || this.bindings.get(id) !== binding)
|
|
328
|
+
return false;
|
|
329
|
+
const observed = binding.native.snapshot();
|
|
330
|
+
if (observed?.state === "unknown" || observed?.state === "exited")
|
|
331
|
+
return false;
|
|
332
|
+
try {
|
|
333
|
+
if (!daemon || !this.options.published(name, daemon))
|
|
334
|
+
assertCurrent();
|
|
335
|
+
this.options.admit(name, config);
|
|
336
|
+
const now = this.options.config(name), profile = this.options.store.get(id);
|
|
337
|
+
return !!now && now.native_adapter === "pane" && now.native_agent_id === id && now.machine_id === agent.machineId && now.backend === launch.cli && now.working_directory === launch.cwd && (now.model || undefined) === launch.model && now.native_sandbox === launch.sandbox
|
|
338
|
+
&& profile.paneLaunchId === launch.launchId && profile.activeId === launch.launchId && !profile.paused;
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const owned = () => !!daemon && current() && this.options.published(name, daemon);
|
|
345
|
+
const lease = new PaneMcpAuthorityLease(join(directory, `${launch.launchId}.mcp.json`), {
|
|
346
|
+
machineId: endpoint.machineId, owner: { hostBootId, paneId: launch.paneId, launchId: launch.launchId, agentId: id, instance: name }, current, transportEpoch: () => endpoint.epoch(),
|
|
347
|
+
menu: () => this.options.menu(name), allowed: (tool, args) => current() && this.options.allowed(name, tool, args),
|
|
348
|
+
invoke: (input, proof) => { if (!owned() || !proof())
|
|
349
|
+
throw Error("Native daemon is not published"); return this.options.invoke(daemon, input, () => owned() && proof(), name); },
|
|
350
|
+
responseWritten: operationId => daemon?.paneToolResponseWritten(operationId, owned),
|
|
351
|
+
toolFailed: details => daemon?.logNativeToolFailure(details),
|
|
352
|
+
});
|
|
353
|
+
const native = new RuntimeNativePaneLifecycle({ endpoint, launch, receiptFile: join(directory, `${launch.launchId}.pane.json`), ...(launch.cli === "codex" && retained.fresh ? { freshPrevious: retained.fresh.previous } : {}),
|
|
354
|
+
admit: () => { assertCurrent(); this.options.admit(name, config); }, reserve: launchId => { this.options.store.reservePane(id, launchId); }, pin: (launchId, sessionId) => {
|
|
355
|
+
if (launch.cli === "codex" && retained.fresh) {
|
|
356
|
+
const observed = native.port.ownedSnapshot();
|
|
357
|
+
if (!observed || observed.launchId !== launchId || observed.sessionId !== sessionId)
|
|
358
|
+
throw Error("Fresh Codex observation differs");
|
|
359
|
+
retained = this.bindFreshCodex(file, retained, observed);
|
|
360
|
+
}
|
|
361
|
+
else
|
|
362
|
+
this.options.store.pinPaneSession(id, launchId, sessionId);
|
|
363
|
+
},
|
|
364
|
+
exited: snapshot => { retained = this.recordExit(file, retained, snapshot); }, mcpProof: () => lease.serving() ? "alive" : "unknown",
|
|
365
|
+
bindDaemon: value => binding.bind(value), acquired: async () => {
|
|
366
|
+
this.options.store.setPaneRecovery(id, undefined);
|
|
367
|
+
if (retained.fresh && !retained.fresh.announced) {
|
|
368
|
+
retained = { ...retained, fresh: { ...retained.fresh, announced: true } };
|
|
369
|
+
this.save(file, retained);
|
|
370
|
+
if (retained.fresh.automatic)
|
|
371
|
+
await this.options.freshNotice?.(name, launch.cli);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
releaseAuthority: () => { closed = true; lease.close(); if (this.bindings.get(id) === binding)
|
|
375
|
+
this.bindings.delete(id); }, });
|
|
376
|
+
const snapshot = native.port.ownedSnapshot();
|
|
377
|
+
if (agent.threadId && snapshot?.sessionId !== agent.threadId && launch.sessionId !== agent.threadId
|
|
378
|
+
&& !(retained.fresh && (launch.cli === "codex" ? retained.fresh.previous.sessionId === agent.threadId : launch.launchId === agent.threadId)))
|
|
379
|
+
throw Error("Native profile conversation pin differs from its launch receipt");
|
|
380
|
+
binding = { native, lease, bind: value => { if (daemon && daemon !== value)
|
|
381
|
+
throw Error("Native daemon binding changed"); daemon = value; } };
|
|
382
|
+
this.bindings.set(id, binding);
|
|
383
|
+
return native;
|
|
384
|
+
}
|
|
385
|
+
/** Administrator chooses a new conversation for this exact stopped, held pin. No provider files are changed. */
|
|
386
|
+
async startFresh(name, config, launchId, sessionId, assertCurrent) {
|
|
387
|
+
config = structuredClone(config);
|
|
388
|
+
const id = config.native_agent_id;
|
|
389
|
+
if (!id || this.preparing.has(id) || this.bindings.has(id))
|
|
390
|
+
throw Error("Native pane preparation still has an owner");
|
|
391
|
+
this.preparing.add(id);
|
|
392
|
+
try {
|
|
393
|
+
assertCurrent();
|
|
394
|
+
this.options.admit(name, config);
|
|
395
|
+
const agent = this.options.store.get(id), file = join(this.directory(id), "active.json"), manifest = this.load(file);
|
|
396
|
+
// A replay consumes its already-committed UUID only after the original decision's proof is rechecked.
|
|
397
|
+
const replay = !!(manifest?.fresh && !manifest.exited && !manifest.fresh.announced && (manifest.fresh.decisionLaunchId ?? manifest.fresh.previous.launchId) === launchId && (manifest.fresh.previous.sessionId ?? null) === sessionId);
|
|
398
|
+
const previous = replay ? manifest.fresh.previous : manifest?.exited?.sessionId ? manifest.exited : manifest?.fresh?.previous ?? manifest?.exited;
|
|
399
|
+
const targetLaunchId = replay ? (manifest.fresh.decisionLaunchId ?? previous?.launchId) : manifest?.exited?.launchId;
|
|
400
|
+
if (!manifest || !previous || !["claude-code", "codex"].includes(manifest.launch.cli) || targetLaunchId !== launchId || (previous.sessionId ?? null) !== sessionId || (agent.threadId ?? null) !== sessionId
|
|
401
|
+
|| agent.activeId || agent.paneLaunchId || agent.fleet_instance !== name || agent.cwd !== config.working_directory || agent.cli !== config.backend || agent.machineId !== config.machine_id
|
|
402
|
+
|| manifest.machineId !== (agent.machineId ?? "local") || manifest.launch.instance !== name || manifest.launch.agentId !== id
|
|
403
|
+
|| agent.paneRecovery?.kind !== "session-unconfirmed" || agent.paneRecovery.launchId !== launchId || (agent.paneRecovery.sessionId ?? null) !== sessionId)
|
|
404
|
+
throw Error(t("native_pane.changed"));
|
|
405
|
+
const unopened = () => {
|
|
406
|
+
if (!replay)
|
|
407
|
+
return;
|
|
408
|
+
try {
|
|
409
|
+
lstatSync(join(this.directory(id), `${manifest.launch.launchId}.pane.json`));
|
|
410
|
+
throw Error("Fresh pane launch outcome is unconfirmed");
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
if (error.code !== "ENOENT")
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
unopened();
|
|
418
|
+
const endpoint = await this.options.endpoint(agent);
|
|
419
|
+
assertCurrent();
|
|
420
|
+
this.options.admit(name, config);
|
|
421
|
+
if (endpoint.machineId !== manifest.machineId)
|
|
422
|
+
throw Error("Native fresh-session machine differs");
|
|
423
|
+
assertAuditedNativePaneVersion(agent.cli, endpoint.version(agent.cli));
|
|
424
|
+
const epoch = endpoint.epoch();
|
|
425
|
+
const raw = await endpoint.call({ action: "list" });
|
|
426
|
+
assertCurrent();
|
|
427
|
+
this.options.admit(name, config);
|
|
428
|
+
if (!endpoint.online() || endpoint.epoch() !== epoch)
|
|
429
|
+
throw Error("Native fresh-session transport changed");
|
|
430
|
+
if (!raw || typeof raw !== "object" || !Array.isArray(raw.panes) || raw.panes.map(validateRuntimePaneSnapshot).some((row) => row.agentId === id && row.state !== "exited"))
|
|
431
|
+
throw Error("A native process exit is still unconfirmed");
|
|
432
|
+
const state = await this.sessionState(endpoint, previous, raw.capabilities?.[agent.cli === "codex" ? "codexSessionProof" : "claudeSessionProof"] === true);
|
|
433
|
+
assertCurrent();
|
|
434
|
+
this.options.admit(name, config);
|
|
435
|
+
unopened();
|
|
436
|
+
if (!endpoint.online() || endpoint.epoch() !== epoch)
|
|
437
|
+
throw Error("Native fresh-session transport changed");
|
|
438
|
+
if (runtimeJobDigest(this.options.store.get(id)) !== runtimeJobDigest(agent))
|
|
439
|
+
throw Error(t("native_pane.changed"));
|
|
440
|
+
if (state === "saved") {
|
|
441
|
+
if (replay || previous !== manifest.exited) {
|
|
442
|
+
// The unused intent never opened. Return to its exact positive exit; the original per-launch receipt is untouched.
|
|
443
|
+
const prior = this.newManifest(name, config, agent, manifest.machineId, true, previous);
|
|
444
|
+
if (agent.cli === "codex" && manifest.fresh?.previousLaunch)
|
|
445
|
+
prior.launch = manifest.fresh.previousLaunch;
|
|
446
|
+
this.save(file, { ...prior, exited: previous });
|
|
447
|
+
}
|
|
448
|
+
this.options.store.setPaneRecovery(id, undefined);
|
|
449
|
+
throw Error(t("native_pane.saved_available"));
|
|
450
|
+
}
|
|
451
|
+
const next = replay ? { ...manifest, ...this.newManifest(name, config, agent, manifest.machineId, false, manifest.launch), fresh: manifest.fresh }
|
|
452
|
+
: this.freshIntent(file, manifest, false, config, agent);
|
|
453
|
+
if (replay)
|
|
454
|
+
this.save(file, next);
|
|
455
|
+
if (agent.cli === "claude-code")
|
|
456
|
+
this.options.store.replacePaneSession(id, previous, next.launch.launchId);
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
if (error instanceof NativePaneRecoveryError) {
|
|
460
|
+
assertCurrent();
|
|
461
|
+
this.options.store.setPaneRecovery(id, error.recovery);
|
|
462
|
+
}
|
|
463
|
+
throw error;
|
|
464
|
+
}
|
|
465
|
+
finally {
|
|
466
|
+
this.preparing.delete(id);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/** Explicit admin attestation, bound to the held launch; no keys, tool calls or process signals. */
|
|
470
|
+
async recover(name, config, launchId, confirmedStopped, assertCurrent) {
|
|
471
|
+
const id = config.native_agent_id;
|
|
472
|
+
if (!id || !UUID.test(id) || this.preparing.has(id))
|
|
473
|
+
throw Error("Native pane preparation is in flight");
|
|
474
|
+
this.preparing.add(id);
|
|
475
|
+
try {
|
|
476
|
+
assertCurrent();
|
|
477
|
+
this.options.admit(name, config);
|
|
478
|
+
const agent = this.options.store.get(id), file = join(this.directory(id), "active.json"), manifest = this.load(file);
|
|
479
|
+
if (agent.paneRecovery?.kind === "session-unconfirmed")
|
|
480
|
+
throw Error(t("native_pane.refresh_for_session"));
|
|
481
|
+
if (confirmedStopped !== true || !manifest || manifest.launch.launchId !== launchId || agent.activeId !== launchId || agent.paneLaunchId !== launchId
|
|
482
|
+
|| manifest.launch.agentId !== id || manifest.launch.instance !== name || manifest.machineId !== (agent.machineId ?? "local") || agent.fleet_instance !== name)
|
|
483
|
+
throw Error(t("native_pane.changed"));
|
|
484
|
+
const pin = agent.threadId ?? manifest.launch.sessionId ?? (manifest.launch.cli === "claude-code" ? manifest.launch.launchId : undefined);
|
|
485
|
+
if (!pin)
|
|
486
|
+
throw Error(t("native_pane.no_pin"));
|
|
487
|
+
const bound = this.bindings.get(id)?.native.port.ownedSnapshot();
|
|
488
|
+
if (bound && bound.launchId !== launchId)
|
|
489
|
+
throw Error("Native recovery has another coordinator owner");
|
|
490
|
+
const endpoint = await this.options.endpoint(agent);
|
|
491
|
+
assertCurrent();
|
|
492
|
+
this.options.admit(name, config);
|
|
493
|
+
if (endpoint.machineId !== manifest.machineId)
|
|
494
|
+
throw Error("Native recovery machine differs");
|
|
495
|
+
const raw = await endpoint.call({ action: "list" });
|
|
496
|
+
assertCurrent();
|
|
497
|
+
this.options.admit(name, config);
|
|
498
|
+
if (!raw || typeof raw !== "object" || !Array.isArray(raw.panes) || raw.capabilities?.recovery !== true)
|
|
499
|
+
throw new NativePaneRecoveryError({ kind: "host-upgrade", launchId });
|
|
500
|
+
const rows = raw.panes.map(validateRuntimePaneSnapshot), pane = rows.find(row => row.paneId === manifest.launch.paneId);
|
|
501
|
+
// A host can die after recording Codex's UUID but before its profile commit. Bind it only AFTER the exact recovered exit.
|
|
502
|
+
const pendingFresh = manifest.launch.cli === "codex" && manifest.fresh && agent.threadId === manifest.fresh.previous.sessionId
|
|
503
|
+
&& (pane?.sessionId ? pane.sessionId !== pin && (!manifest.fresh.sessionId || manifest.fresh.sessionId === pane.sessionId) : !manifest.fresh.sessionId);
|
|
504
|
+
if (rows.filter(row => row.paneId === manifest.launch.paneId).length !== 1 || !pane || pane.launchId !== launchId || pane.agentId !== id || pane.instance !== name
|
|
505
|
+
|| pane.sessionId !== pin && !pendingFresh || rows.some(row => row.agentId === id && row.paneId !== pane.paneId && row.state !== "exited"))
|
|
506
|
+
throw Error(t("native_pane.scope"));
|
|
507
|
+
const ended = validateRuntimePaneSnapshot(await endpoint.call({ action: "recover", paneId: pane.paneId, launchId, hostBootId: pane.hostBootId, confirmedStopped: true }));
|
|
508
|
+
assertCurrent();
|
|
509
|
+
this.options.admit(name, config);
|
|
510
|
+
if (ended.state !== "exited" || ended.paneId !== pane.paneId || ended.launchId !== launchId || ended.agentId !== id || ended.instance !== name || ended.hostBootId !== pane.hostBootId
|
|
511
|
+
|| pane.sessionId !== ended.sessionId)
|
|
512
|
+
throw Error("Native recovery exit scope differs");
|
|
513
|
+
const binding = this.bindings.get(id);
|
|
514
|
+
if (binding)
|
|
515
|
+
await binding.native.port.recordConfirmedExit(ended, assertCurrent);
|
|
516
|
+
assertCurrent();
|
|
517
|
+
this.options.admit(name, config);
|
|
518
|
+
this.save(file, { ...manifest, exited: ended });
|
|
519
|
+
if (!agent.threadId)
|
|
520
|
+
this.options.store.pinPaneSession(id, launchId, pin);
|
|
521
|
+
if (!this.bindings.has(id))
|
|
522
|
+
this.recordExit(file, manifest, ended);
|
|
523
|
+
this.options.store.setPaneRecovery(id, manifest.launch.cli === "codex" && manifest.fresh && !ended.sessionId ? { kind: "session-unconfirmed", provider: "codex", launchId, sessionId: pin } : undefined);
|
|
524
|
+
}
|
|
525
|
+
finally {
|
|
526
|
+
this.preparing.delete(id);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/** Close only the retained exact launch. Offline, missing, or unknown exit remains reserved. */
|
|
530
|
+
async closeRetained(name, config, assertCurrent) {
|
|
531
|
+
assertCurrent();
|
|
532
|
+
const id = config.native_agent_id;
|
|
533
|
+
if (!id || !UUID.test(id))
|
|
534
|
+
throw Error("Native close profile is missing");
|
|
535
|
+
const agent = this.options.store.get(id), directory = this.directory(id), file = join(directory, "active.json"), manifest = this.load(file);
|
|
536
|
+
if (agent.fleet_instance !== name || agent.machineId !== config.machine_id)
|
|
537
|
+
throw Error("Native close profile scope differs");
|
|
538
|
+
const bound = this.bindings.get(id);
|
|
539
|
+
if (bound) {
|
|
540
|
+
await bound.native.release("close");
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
if (!manifest) {
|
|
544
|
+
if (agent.activeId)
|
|
545
|
+
throw Error("Native close intent is unconfirmed");
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
if (manifest.machineId !== (agent.machineId ?? "local") || manifest.launch.instance !== name || manifest.launch.agentId !== id)
|
|
549
|
+
throw Error("Native close manifest scope differs");
|
|
550
|
+
if (manifest.exited) {
|
|
551
|
+
if (agent.activeId)
|
|
552
|
+
this.recordExit(file, manifest, manifest.exited);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const receiptFile = join(directory, `${manifest.launch.launchId}.pane.json`);
|
|
556
|
+
// No open intent or reservation was ever committed: this prepared factory cannot have started a process.
|
|
557
|
+
try {
|
|
558
|
+
lstatSync(receiptFile);
|
|
559
|
+
}
|
|
560
|
+
catch (error) {
|
|
561
|
+
if (error.code !== "ENOENT")
|
|
562
|
+
throw error;
|
|
563
|
+
if (!agent.activeId)
|
|
564
|
+
return;
|
|
565
|
+
throw Error("Native open intent is missing; its process outcome is unknown");
|
|
566
|
+
}
|
|
567
|
+
const endpoint = await this.options.endpoint(agent, true);
|
|
568
|
+
assertCurrent();
|
|
569
|
+
if (endpoint.machineId !== manifest.machineId)
|
|
570
|
+
throw Error("Native close endpoint differs");
|
|
571
|
+
const native = new RuntimeNativePaneLifecycle({ endpoint, launch: manifest.launch, receiptFile,
|
|
572
|
+
admit: assertCurrent, reserve: () => { throw Error("Close never reserves a new launch"); }, pin: () => { }, mcpProof: () => "unknown", releaseAuthority: () => { },
|
|
573
|
+
exited: snapshot => { this.recordExit(file, manifest, snapshot); },
|
|
574
|
+
});
|
|
575
|
+
await native.release("close");
|
|
576
|
+
}
|
|
577
|
+
async handle(machineId, raw, transport) {
|
|
578
|
+
const body = validatePaneMcpBody(raw), binding = this.bindings.get(body.owner.agentId);
|
|
579
|
+
if (!binding)
|
|
580
|
+
throw Error("Native pane tool owner is unavailable");
|
|
581
|
+
return binding.lease.handle(machineId, body, transport);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
//# sourceMappingURL=native-pane-manager.js.map
|