@timurproko/a1 0.2.7-dev.1249 → 0.2.7-dev.1255
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 +11 -36
- package/bin/cli.js +2 -17
- package/bin/ui.js +10 -51
- package/dist/app/session-shell/clipboard-diagnostics.d.ts +2 -2
- package/dist/app/session-shell/clipboard-image.d.ts +0 -1
- package/dist/app/session-shell/clipboard-image.js +1 -1
- package/dist/app/session-shell/dialog-coordinator.d.ts +6 -5
- package/dist/app/session-shell/dialog-coordinator.js +3 -4
- package/dist/app/session-shell/dock-chrome.d.ts +11 -6
- package/dist/app/session-shell/dock-chrome.js +5 -8
- package/dist/app/session-shell/editor-hyperlink-budget.d.ts +0 -2
- package/dist/app/session-shell/editor-hyperlink-budget.js +1 -1
- package/dist/app/session-shell/exit-notice.d.ts +3 -3
- package/dist/app/session-shell/exit-notice.js +10 -10
- package/dist/app/session-shell/extension-surface.d.ts +8 -7
- package/dist/app/session-shell/helper-pool.d.ts +3 -4
- package/dist/app/session-shell/helper-pool.js +1 -1
- package/dist/app/session-shell/image-preparation-client.d.ts +4 -3
- package/dist/app/session-shell/image-preparation.d.ts +0 -2
- package/dist/app/session-shell/image-preparation.js +2 -2
- package/dist/app/session-shell/image-source.d.ts +2 -3
- package/dist/app/session-shell/image-source.js +2 -2
- package/dist/app/session-shell/input-surface-switch.d.ts +9 -7
- package/dist/app/session-shell/input-surface-switch.js +1 -2
- package/dist/app/session-shell/login-interaction.d.ts +5 -4
- package/dist/app/session-shell/login-interaction.js +2 -3
- package/dist/app/session-shell/paste-executor.d.ts +4 -8
- package/dist/app/session-shell/paste-executor.js +2 -2
- package/dist/app/session-shell/paste-protocol.d.ts +2 -2
- package/dist/app/session-shell/path-chip-presentation.d.ts +0 -5
- package/dist/app/session-shell/path-chip-presentation.js +3 -3
- package/dist/app/session-shell/prompt-chips.d.ts +8 -7
- package/dist/app/session-shell/prompt-history-controller.d.ts +3 -3
- package/dist/app/session-shell/prompt-submission.d.ts +7 -6
- package/dist/app/session-shell/prompt-submission.js +7 -28
- package/dist/app/session-shell/quit-outro-effects.d.ts +3 -3
- package/dist/app/session-shell/quit-outro-effects.js +1 -4
- package/dist/app/session-shell/quit-outro.d.ts +9 -12
- package/dist/app/session-shell/quit-outro.js +11 -11
- package/dist/app/session-shell/response-copy-protocol.d.ts +3 -2
- package/dist/app/session-shell/response-copy-transport.d.ts +2 -14
- package/dist/app/session-shell/response-copy-transport.js +2 -3
- package/dist/app/session-shell/session-lifecycle.d.ts +3 -3
- package/dist/app/session-shell/session-lifecycle.js +2 -4
- package/dist/app/session-shell/session-shell-root.d.ts +74 -120
- package/dist/app/session-shell/session-shell-root.js +82 -115
- package/dist/app/session-shell/session-shell.d.ts +13 -16
- package/dist/app/session-shell/session-shell.js +149 -314
- package/dist/app/session-shell/session-viewport-controller.d.ts +7 -6
- package/dist/app/session-shell/session-viewport-controller.js +5 -8
- package/dist/app/session-shell/settings-bindings.d.ts +24 -2
- package/dist/app/session-shell/settings-bindings.js +24 -0
- package/dist/app/session-shell/share-operation.d.ts +3 -3
- package/dist/app/session-shell/share-operation.js +4 -6
- package/dist/app/session-shell/shell-clipboard.d.ts +59 -0
- package/dist/app/session-shell/shell-clipboard.js +119 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +8 -4
- package/dist/app/session-shell/shell-editor-factory.js +13 -15
- package/dist/app/session-shell/shell-host.d.ts +16 -17
- package/dist/app/session-shell/shell-host.js +20 -37
- package/dist/app/session-shell/shell-layout.d.ts +2 -2
- package/dist/app/session-shell/shell-prompt-suggestions.d.ts +26 -0
- package/dist/app/session-shell/shell-prompt-suggestions.js +48 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +1 -6
- package/dist/app/session-shell/suggestion-surface.js +1 -1
- package/dist/app/session-shell/system-clipboard.d.ts +2 -14
- package/dist/app/session-shell/system-clipboard.js +2 -7
- package/dist/app/session-shell/transcript-document.d.ts +12 -10
- package/dist/app/session-shell/transcript-document.js +15 -41
- package/dist/app/session-shell/viewport-layout.d.ts +2 -2
- package/dist/app/session-shell/workflow-output.d.ts +5 -3
- package/dist/app/session-shell/workflow-output.js +13 -15
- package/dist/app/session-shell/workflow-router.d.ts +1 -3
- package/dist/app/session-shell/workflow-router.js +1 -4
- package/dist/cli/dispatch.d.ts +1 -11
- package/dist/cli/dispatch.js +5 -92
- package/dist/cli/package-messages.d.ts +0 -1
- package/dist/cli/package-messages.js +1 -1
- package/dist/cli/session-context.d.ts +1 -1
- package/dist/cli/session-context.js +5 -7
- package/dist/cli/uninstall.d.ts +4 -7
- package/dist/cli/uninstall.js +6 -35
- package/dist/cli/version-stats.js +4 -7
- package/dist/composition/owned-settings.d.ts +2 -2
- package/dist/composition/owned-settings.js +0 -4
- package/dist/composition/owned-ui.d.ts +3 -25
- package/dist/composition/owned-ui.js +37 -113
- package/dist/composition/reference-selection-options.d.ts +1 -1
- package/dist/composition/reference-selection-options.js +1 -1
- package/dist/composition/release-update-observation.d.ts +4 -4
- package/dist/composition/release-update-observation.js +17 -47
- package/dist/composition/session-backend.d.ts +0 -1
- package/dist/composition/session-runtime-registry.d.ts +5 -4
- package/dist/composition/settings-route-host.d.ts +0 -7
- package/dist/composition/settings-route-host.js +7 -20
- package/dist/composition/settings-search-input.d.ts +2 -1
- package/dist/composition/startup-route.d.ts +2 -3
- package/dist/composition/startup-route.js +2 -3
- package/dist/contracts/owned-ui/extension-ui.d.ts +2 -1
- package/dist/contracts/owned-ui/index.d.ts +2 -1
- package/dist/contracts/owned-ui/model.d.ts +0 -3
- package/dist/contracts/owned-ui/session-presenters.d.ts +3 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +1 -4
- package/dist/contracts/owned-ui/shell-components.d.ts +543 -0
- package/dist/contracts/presentation/component.d.ts +17 -0
- package/dist/contracts/presentation/component.js +8 -0
- package/dist/contracts/presentation/index.d.ts +6 -15
- package/dist/contracts/presentation/index.js +2 -0
- package/dist/contracts/presentation/terminal.d.ts +290 -0
- package/dist/contracts/presentation/theme.d.ts +46 -0
- package/dist/features/launch/development-launch.js +1 -2
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/intent.d.ts +1 -3
- package/dist/features/launch/intent.js +2 -4
- package/dist/features/launch/runtime-selection.d.ts +2 -2
- package/dist/features/launch/runtime-selection.js +2 -2
- package/dist/features/launch/session-context.d.ts +2 -2
- package/dist/features/owned-ui/project-trust-prompt.d.ts +2 -2
- package/dist/features/owned-ui/project-trust-prompt.js +1 -1
- package/dist/features/owned-ui/reference-screen-app.d.ts +0 -2
- package/dist/features/owned-ui/reference-screen-app.js +2 -9
- package/dist/features/owned-ui/release-note-state.d.ts +2 -1
- package/dist/features/owned-ui/settings-app.d.ts +0 -6
- package/dist/features/owned-ui/settings-app.js +42 -254
- package/dist/features/owned-ui/settings-edits.d.ts +31 -0
- package/dist/features/owned-ui/settings-edits.js +139 -0
- package/dist/features/owned-ui/settings-scroll-rail.d.ts +29 -0
- package/dist/features/owned-ui/settings-scroll-rail.js +79 -0
- package/dist/features/owned-ui/settings-search-input.d.ts +2 -1
- package/dist/features/prompt-history/service.d.ts +3 -2
- package/dist/foundation/launch-context/index.d.ts +0 -12
- package/dist/foundation/launch-context/index.js +0 -26
- package/dist/foundation/lifecycle/claim-gate.d.ts +9 -0
- package/dist/foundation/lifecycle/claim-gate.js +37 -0
- package/dist/foundation/lifecycle/index.d.ts +5 -9
- package/dist/foundation/lifecycle/index.js +3 -4
- package/dist/foundation/lifecycle/model.d.ts +2 -59
- package/dist/foundation/lifecycle/model.js +0 -35
- package/dist/foundation/lifecycle/paths.d.ts +0 -24
- package/dist/foundation/lifecycle/paths.js +0 -40
- package/dist/foundation/lifecycle/process-liveness.d.ts +8 -0
- package/dist/foundation/lifecycle/process-liveness.js +18 -0
- package/dist/foundation/lifecycle/session-claim-lock.d.ts +1 -1
- package/dist/foundation/lifecycle/session-claim-lock.js +2 -2
- package/dist/foundation/lifecycle/session-repository-context.d.ts +6 -6
- package/dist/foundation/lifecycle/session-repository-context.js +2 -3
- package/dist/foundation/release/automatic-update.d.ts +6 -17
- package/dist/foundation/release/automatic-update.js +23 -44
- package/dist/foundation/release/bootstrap.d.ts +2 -25
- package/dist/foundation/release/bootstrap.js +37 -348
- package/dist/foundation/release/dependency-certification.d.ts +1 -2
- package/dist/foundation/release/dependency-certification.js +1 -1
- package/dist/foundation/release/early-accent.d.ts +2 -2
- package/dist/foundation/release/early-accent.js +1 -1
- package/dist/foundation/release/index.d.ts +10 -17
- package/dist/foundation/release/index.js +7 -11
- package/dist/foundation/release/latest-release.d.ts +3 -19
- package/dist/foundation/release/latest-release.js +11 -12
- package/dist/foundation/release/ordinary-launch-selection.d.ts +1 -1
- package/dist/foundation/release/ordinary-launch-selection.js +1 -1
- package/dist/foundation/release/process-liveness.d.ts +2 -0
- package/dist/foundation/release/process-liveness.js +12 -0
- package/dist/foundation/release/release-gc.d.ts +13 -10
- package/dist/foundation/release/release-gc.js +37 -101
- package/dist/foundation/release/{cohort-state.d.ts → release-state.d.ts} +44 -69
- package/dist/foundation/release/{cohort-state.js → release-state.js} +38 -70
- package/dist/foundation/release/release-store.d.ts +2 -2
- package/dist/foundation/release/release-store.js +2 -2
- package/dist/foundation/release/restart-certification.js +1 -1
- package/dist/foundation/release/update-activation.d.ts +2 -9
- package/dist/foundation/release/update-activation.js +30 -45
- package/dist/foundation/release/update-execution-lease.d.ts +2 -3
- package/dist/foundation/release/update-execution-lease.js +2 -2
- package/dist/foundation/release/update-launch.d.ts +2 -4
- package/dist/foundation/release/update-launch.js +0 -7
- package/dist/foundation/release/update-recovery.js +1 -1
- package/dist/foundation/release/update-transaction.d.ts +1 -1
- package/dist/foundation/release/update-transaction.js +5 -2
- package/dist/foundation/release/update.d.ts +2 -12
- package/dist/foundation/release/update.js +37 -214
- package/dist/foundation/session-writer-lock/index.d.ts +14 -6
- package/dist/foundation/session-writer-lock/index.js +48 -103
- package/dist/foundation/startup/startup-budget.d.ts +5 -5
- package/dist/foundation/startup/startup-budget.js +2 -2
- package/dist/foundation/startup/startup-runtime.d.ts +1 -1
- package/dist/foundation/terminal-cleanup/exit-notice.d.ts +6 -0
- package/dist/foundation/terminal-cleanup/exit-notice.js +36 -0
- package/dist/foundation/terminal-cleanup/index.d.ts +2 -1
- package/dist/foundation/terminal-cleanup/index.js +2 -1
- package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +0 -5
- package/dist/foundation/terminal-cleanup/terminal-reset.js +0 -5
- package/dist/integrations/pi/components/editor-interaction.d.ts +4 -12
- package/dist/integrations/pi/components/index.d.ts +15 -9
- package/dist/integrations/pi/components/index.js +9 -5
- package/dist/integrations/pi/components/lazy-selectors.d.ts +2 -10
- package/dist/integrations/pi/components/lazy-selectors.js +1 -1
- package/dist/integrations/pi/components/modal-frame.d.ts +5 -22
- package/dist/integrations/pi/components/modal-frame.js +3 -23
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +4 -3
- package/dist/integrations/pi/components/prompt-input-port.d.ts +2 -19
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +3 -2
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +1 -4
- package/dist/integrations/pi/components/shell-footer-status.d.ts +3 -3
- package/dist/integrations/pi/components/shell-footer-status.js +5 -4
- package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +6 -8
- package/dist/integrations/pi/components/shell-presenters-info.js +6 -19
- package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +1 -1
- package/dist/integrations/pi/components/shell-presenters-transcript.js +1 -1
- package/dist/integrations/pi/components/shell-session-info-reference.d.ts +2 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +33 -229
- package/dist/integrations/pi/components/shell-shared-facade.js +8 -1
- package/dist/integrations/pi/components/skills-command.d.ts +1 -9
- package/dist/integrations/pi/components/skills-command.js +5 -5
- package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +2 -5
- package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -16
- package/dist/integrations/pi/components/theme.d.ts +9 -2
- package/dist/integrations/pi/components/theme.js +17 -2
- package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +1 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.js +6 -8
- package/dist/integrations/pi/engine/adapter.d.ts +3 -6
- package/dist/integrations/pi/engine/adapter.js +4 -28
- package/dist/integrations/pi/engine/changelog.d.ts +2 -2
- package/dist/integrations/pi/engine/changelog.js +3 -3
- package/dist/integrations/pi/engine/compaction-progress.d.ts +2 -3
- package/dist/integrations/pi/engine/compaction-progress.js +1 -1
- package/dist/integrations/pi/engine/conformance.d.ts +2 -1
- package/dist/integrations/pi/engine/default-model-setting.d.ts +0 -2
- package/dist/integrations/pi/engine/default-model-setting.js +1 -2
- package/dist/integrations/pi/engine/diagnostics-state.d.ts +0 -1
- package/dist/integrations/pi/engine/diagnostics-state.js +0 -14
- package/dist/integrations/pi/engine/event-delivery.d.ts +2 -1
- package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -1
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/message-values.d.ts +0 -1
- package/dist/integrations/pi/engine/message-values.js +1 -1
- package/dist/integrations/pi/engine/pending-delivery.d.ts +0 -4
- package/dist/integrations/pi/engine/pending-delivery.js +3 -3
- package/dist/integrations/pi/engine/ports.d.ts +7 -1
- package/dist/integrations/pi/engine/ports.js +4 -0
- package/dist/integrations/pi/engine/project-trust-preflight.d.ts +2 -1
- package/dist/integrations/pi/engine/prompt-suggestions.d.ts +3 -3
- package/dist/integrations/pi/engine/prompt-suggestions.js +0 -40
- package/dist/integrations/pi/engine/provider-authentication.d.ts +1 -1
- package/dist/integrations/pi/engine/public-main-entry.d.ts +1 -5
- package/dist/integrations/pi/engine/public-main-entry.js +1 -1
- package/dist/integrations/pi/engine/repository-pr-rest.d.ts +1 -9
- package/dist/integrations/pi/engine/repository-pr-rest.js +2 -2
- package/dist/integrations/pi/engine/repository-pr.d.ts +1 -3
- package/dist/integrations/pi/engine/repository-pr.js +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +2 -1
- package/dist/integrations/pi/engine/session-integration.d.ts +1 -1
- package/dist/integrations/pi/engine/session-runtime.d.ts +4 -3
- package/dist/integrations/pi/engine/session-runtime.js +0 -2
- package/dist/integrations/pi/engine/settings-bridge.d.ts +0 -2
- package/dist/integrations/pi/engine/settings-bridge.js +1 -1
- package/dist/integrations/pi/engine/settings-port.d.ts +3 -2
- package/dist/integrations/pi/engine/transcript-projection.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-contexts.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.js +1 -1
- package/dist/integrations/pi/engine/workflow-support.d.ts +0 -6
- package/dist/integrations/pi/engine/workflow-support.js +4 -18
- package/dist/integrations/pi/engine/workflows.d.ts +5 -5
- package/dist/integrations/pi/session-presenters/components.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/components.js +75 -0
- package/dist/integrations/pi/session-presenters/index.d.ts +1 -0
- package/dist/integrations/pi/session-presenters/index.js +1 -0
- package/dist/integrations/pi/session-presenters/presentation.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/presentation.js +10 -0
- package/dist/integrations/pi/session-presenters/presenters.d.ts +2 -1
- package/dist/integrations/pi/session-presenters/presenters.js +3 -1
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -2
- package/dist/integrations/pi/tui-runtime/adapter.js +23 -32
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +22 -166
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +5 -40
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -0
- package/dist/integrations/pi/tui-runtime/index.js +1 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +4 -6
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -8
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +3 -9
- package/dist/integrations/pi/tui-runtime/runtime-factory.d.ts +3 -0
- package/dist/integrations/pi/tui-runtime/runtime-factory.js +11 -0
- package/dist/product-identity.d.ts +4 -6
- package/dist/product-identity.js +6 -11
- package/dist/product-identity.json +1 -40
- package/dist/runtime-payload-inventory.json +0 -3
- package/dist/ui/components/index.d.ts +4 -4
- package/dist/ui/components/index.js +2 -2
- package/dist/ui/components/selection-copy.d.ts +0 -1
- package/dist/ui/components/selection-copy.js +0 -12
- package/dist/ui/components/submitted-prompt.d.ts +3 -13
- package/dist/ui/components/submitted-prompt.js +8 -41
- package/dist/ui/components/theme.d.ts +4 -19
- package/dist/ui/components/theme.js +6 -0
- package/dist/ui/components/transcript-viewport.d.ts +1 -3
- package/dist/ui/components/transcript-viewport.js +1 -4
- package/dist/ui/settings/declarations.d.ts +2 -97
- package/dist/ui/settings/declarations.js +2 -78
- package/dist/ui/settings/early-accent.js +1 -1
- package/dist/ui/settings/index.d.ts +3 -5
- package/dist/ui/settings/index.js +2 -3
- package/dist/ui/settings/manager.d.ts +0 -4
- package/dist/ui/settings/manager.js +6 -62
- package/dist/ui/settings/resolution.d.ts +6 -18
- package/dist/ui/settings/resolution.js +4 -103
- package/dist/ui/settings/sections.d.ts +0 -4
- package/dist/ui/settings/sections.js +1 -1
- package/docs/architecture/boundaries.md +23 -40
- package/docs/architecture/code-documentation.md +2 -2
- package/docs/architecture/internal-naming.md +11 -17
- package/docs/architecture/project-structure.md +13 -16
- package/docs/architecture/resource-and-data-policy.md +16 -31
- package/docs/architecture/toolchain.md +14 -19
- package/docs/architecture/ui-reference-provenance.md +2 -2
- package/docs/ci-release-runbook.md +5 -5
- package/docs/features/launch-profiles.md +11 -17
- package/docs/features/prompt-history.md +10 -11
- package/docs/local-worktree-cleanup.md +28 -1
- package/docs/manual-owned-ui-checkpoint.md +0 -1
- package/docs/validation.md +5 -11
- package/docs/worktree-link-recovery.md +6 -6
- package/package.json +7 -20
- package/bin/guardian.js +0 -42
- package/bin/supervisor.js +0 -7
- package/bin/tab-launch-context.d.ts +0 -27
- package/bin/tab-launch-context.js +0 -94
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +0 -38
- package/dist/app/session-shell/resident-tab-coordinator.js +0 -77
- package/dist/cli/tabs-request.d.ts +0 -7
- package/dist/cli/tabs.d.ts +0 -14
- package/dist/cli/tabs.js +0 -151
- package/dist/composition/resident-tab-bridge.d.ts +0 -41
- package/dist/composition/resident-tab-bridge.js +0 -209
- package/dist/composition/utility-tab.d.ts +0 -28
- package/dist/composition/utility-tab.js +0 -244
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +0 -28
- package/dist/features/owned-ui/plus-menu-dialog.js +0 -89
- package/dist/features/resident-tab/auto-name.d.ts +0 -11
- package/dist/features/resident-tab/auto-name.js +0 -44
- package/dist/features/resident-tab/index.d.ts +0 -5
- package/dist/features/resident-tab/index.js +0 -7
- package/dist/features/resident-tab/shortcut-bindings-file.d.ts +0 -8
- package/dist/features/resident-tab/shortcut-bindings-file.js +0 -40
- package/dist/features/resident-tab/shortcut-declarations.d.ts +0 -13
- package/dist/features/resident-tab/shortcut-declarations.js +0 -26
- package/dist/features/resident-tab/shortcut-projection.d.ts +0 -29
- package/dist/features/resident-tab/shortcut-projection.js +0 -64
- package/dist/features/resident-tab/status-deriver.d.ts +0 -10
- package/dist/features/resident-tab/status-deriver.js +0 -12
- package/dist/foundation/launch-guardian/exit-watcher.d.ts +0 -14
- package/dist/foundation/launch-guardian/exit-watcher.js +0 -103
- package/dist/foundation/launch-guardian/index.d.ts +0 -2
- package/dist/foundation/launch-guardian/index.js +0 -1
- package/dist/foundation/launch-guardian/main.d.ts +0 -39
- package/dist/foundation/launch-guardian/main.js +0 -232
- package/dist/foundation/lifecycle/commands.d.ts +0 -40
- package/dist/foundation/lifecycle/launch-instance.d.ts +0 -46
- package/dist/foundation/lifecycle/launch-instance.js +0 -134
- package/dist/foundation/lifecycle/native-claim-gate.d.ts +0 -5
- package/dist/foundation/lifecycle/native-claim-gate.js +0 -41
- package/dist/foundation/lifecycle/supervisor-startup.d.ts +0 -30
- package/dist/foundation/lifecycle/supervisor-startup.js +0 -106
- package/dist/foundation/process-containment/addon-containment.d.ts +0 -20
- package/dist/foundation/process-containment/addon-containment.js +0 -139
- package/dist/foundation/process-containment/addon-process-inspector.d.ts +0 -11
- package/dist/foundation/process-containment/addon-process-inspector.js +0 -36
- package/dist/foundation/process-containment/addon.d.ts +0 -47
- package/dist/foundation/process-containment/addon.js +0 -57
- package/dist/foundation/process-containment/artifact.d.ts +0 -1
- package/dist/foundation/process-containment/artifact.js +0 -35
- package/dist/foundation/process-containment/contracts.d.ts +0 -33
- package/dist/foundation/process-containment/contracts.js +0 -35
- package/dist/foundation/process-containment/index.d.ts +0 -9
- package/dist/foundation/process-containment/index.js +0 -7
- package/dist/foundation/process-containment/linux-process-inspector.d.ts +0 -7
- package/dist/foundation/process-containment/linux-process-inspector.js +0 -27
- package/dist/foundation/process-containment/native-process-inspector.d.ts +0 -4
- package/dist/foundation/process-containment/native-process-inspector.js +0 -21
- package/dist/foundation/protocol/client.d.ts +0 -18
- package/dist/foundation/protocol/client.js +0 -130
- package/dist/foundation/protocol/index.d.ts +0 -3
- package/dist/foundation/protocol/index.js +0 -2
- package/dist/foundation/protocol/messages.d.ts +0 -90
- package/dist/foundation/protocol/messages.js +0 -100
- package/dist/foundation/release/cohort-selection.d.ts +0 -33
- package/dist/foundation/release/cohort-selection.js +0 -67
- package/dist/foundation/release/endpoint-lock.d.ts +0 -2
- package/dist/foundation/release/endpoint-lock.js +0 -37
- package/dist/foundation/release/endpoint-recovery.d.ts +0 -10
- package/dist/foundation/release/endpoint-recovery.js +0 -45
- package/dist/foundation/release/endpoints.d.ts +0 -32
- package/dist/foundation/release/endpoints.js +0 -152
- package/dist/foundation/release/prepared-update-activation.d.ts +0 -3
- package/dist/foundation/release/prepared-update-activation.js +0 -27
- package/dist/foundation/release/process-cleanup.d.ts +0 -14
- package/dist/foundation/release/process-cleanup.js +0 -76
- package/dist/foundation/release/supervisor-identity.d.ts +0 -15
- package/dist/foundation/release/supervisor-identity.js +0 -63
- package/dist/foundation/resident-tabs/boot-identity.d.ts +0 -6
- package/dist/foundation/resident-tabs/boot-identity.js +0 -16
- package/dist/foundation/resident-tabs/bounded-host-command.d.ts +0 -20
- package/dist/foundation/resident-tabs/bounded-host-command.js +0 -62
- package/dist/foundation/resident-tabs/bridge-client.d.ts +0 -73
- package/dist/foundation/resident-tabs/bridge-client.js +0 -327
- package/dist/foundation/resident-tabs/continuity.d.ts +0 -12
- package/dist/foundation/resident-tabs/continuity.js +0 -63
- package/dist/foundation/resident-tabs/doctor.d.ts +0 -28
- package/dist/foundation/resident-tabs/doctor.js +0 -166
- package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +0 -27
- package/dist/foundation/resident-tabs/draft-checkpoint.js +0 -145
- package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +0 -36
- package/dist/foundation/resident-tabs/ensure-terminal-host.js +0 -151
- package/dist/foundation/resident-tabs/fault-injection.d.ts +0 -8
- package/dist/foundation/resident-tabs/fault-injection.js +0 -26
- package/dist/foundation/resident-tabs/fixture-control.d.ts +0 -7
- package/dist/foundation/resident-tabs/fixture-control.js +0 -35
- package/dist/foundation/resident-tabs/host-entry.js +0 -17
- package/dist/foundation/resident-tabs/index.d.ts +0 -15
- package/dist/foundation/resident-tabs/index.js +0 -10
- package/dist/foundation/resident-tabs/maintenance.d.ts +0 -39
- package/dist/foundation/resident-tabs/maintenance.js +0 -75
- package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +0 -34
- package/dist/foundation/resident-tabs/progress-observation-schema.js +0 -1
- package/dist/foundation/resident-tabs/progress-observation.d.ts +0 -4
- package/dist/foundation/resident-tabs/progress-observation.js +0 -150
- package/dist/foundation/resident-tabs/prompt-journal.d.ts +0 -63
- package/dist/foundation/resident-tabs/prompt-journal.js +0 -213
- package/dist/foundation/resident-tabs/protocol.d.ts +0 -12
- package/dist/foundation/resident-tabs/protocol.js +0 -195
- package/dist/foundation/resident-tabs/recovery.d.ts +0 -26
- package/dist/foundation/resident-tabs/recovery.js +0 -205
- package/dist/foundation/resident-tabs/release-holds.d.ts +0 -28
- package/dist/foundation/resident-tabs/release-holds.js +0 -78
- package/dist/foundation/resident-tabs/routes.d.ts +0 -5
- package/dist/foundation/resident-tabs/routes.js +0 -5
- package/dist/foundation/resident-tabs/routing.d.ts +0 -11
- package/dist/foundation/resident-tabs/routing.js +0 -10
- package/dist/foundation/resident-tabs/runtime-control.d.ts +0 -38
- package/dist/foundation/resident-tabs/runtime-control.js +0 -74
- package/dist/foundation/resident-tabs/session-sync.d.ts +0 -14
- package/dist/foundation/resident-tabs/session-sync.js +0 -37
- package/dist/foundation/resident-tabs/settings.d.ts +0 -16
- package/dist/foundation/resident-tabs/settings.js +0 -60
- package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +0 -14
- package/dist/foundation/resident-tabs/terminal-host-artifact.js +0 -78
- package/dist/foundation/resident-tabs/zip-archive.d.ts +0 -9
- package/dist/foundation/resident-tabs/zip-archive.js +0 -56
- package/dist/foundation/storage/control-store.d.ts +0 -20
- package/dist/foundation/storage/control-store.js +0 -331
- package/dist/foundation/storage/index.d.ts +0 -1
- package/dist/foundation/storage/index.js +0 -1
- package/dist/foundation/supervision/index.d.ts +0 -3
- package/dist/foundation/supervision/index.js +0 -3
- package/dist/foundation/supervision/main.d.ts +0 -1
- package/dist/foundation/supervision/main.js +0 -86
- package/dist/foundation/supervision/paths.d.ts +0 -1
- package/dist/foundation/supervision/paths.js +0 -1
- package/dist/foundation/supervision/server.d.ts +0 -46
- package/dist/foundation/supervision/server.js +0 -611
- package/dist/integrations/pi/components/components.d.ts +0 -4
- package/dist/integrations/pi/components/components.js +0 -48
- package/dist/integrations/pi/components/conformance.d.ts +0 -18
- package/dist/integrations/pi/components/conformance.js +0 -70
- package/dist/integrations/pi/components/shell-components.d.ts +0 -7
- package/dist/integrations/pi/components/shell-components.js +0 -7
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +0 -33
- package/dist/integrations/pi/components/upstream/theme/theme-controller.js +0 -114
- package/dist/integrations/pi/engine/offline-settings-port.d.ts +0 -23
- package/dist/integrations/pi/engine/offline-settings-port.js +0 -54
- package/dist/native/darwin-arm64/manifest.json +0 -23
- package/dist/native/darwin-arm64/process-guardian.node +0 -0
- package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10500
- package/dist/native/darwin-arm64/terminal-host.manifest.json +0 -46
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +0 -23
- package/dist/native/darwin-x64/process-guardian.node +0 -0
- package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10737
- package/dist/native/darwin-x64/terminal-host.manifest.json +0 -46
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +0 -23
- package/dist/native/linux-x64/process-guardian.node +0 -0
- package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -11226
- package/dist/native/linux-x64/terminal-host.manifest.json +0 -46
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +0 -23
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10757
- package/dist/native/win32-x64/terminal-host.manifest.json +0 -46
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/ui/settings/migrations.d.ts +0 -19
- package/dist/ui/settings/migrations.js +0 -209
- package/dist/ui/settings/progress-palette.generated.d.ts +0 -139
- package/dist/ui/settings/progress-palette.generated.js +0 -139
- package/docs/architecture/evidence/resident-tabs/linux-x64.md +0 -37
- package/docs/architecture/evidence/resident-tabs/macos-arm64.md +0 -36
- package/docs/architecture/evidence/resident-tabs/macos-x64.md +0 -35
- package/docs/architecture/evidence/resident-tabs/windows-x64.md +0 -36
- package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +0 -70
- package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +0 -32
- package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +0 -115
- package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +0 -48
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +0 -125
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +0 -56
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +0 -174
- package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +0 -18
- package/docs/architecture/native-fixture-isolation.md +0 -23
- package/docs/architecture/process-guardian-provenance.md +0 -36
- package/docs/architecture/resident-tabs-requirements.md +0 -18
- package/docs/architecture/resident-tabs.md +0 -668
- package/docs/architecture/terminal-host-proof-gate.md +0 -34
- package/docs/architecture/terminal-host-provenance.md +0 -81
- package/docs/architecture/terminal-host-spike-evidence.md +0 -39
- package/docs/launch-recovery.md +0 -23
- package/docs/manual-launch-instance-acceptance.md +0 -43
- package/docs/manual-resident-tabs-acceptance.md +0 -51
- /package/dist/{cli/tabs-request.js → contracts/owned-ui/shell-components.js} +0 -0
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.d.ts +0 -0
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.js +0 -0
- /package/dist/{foundation/lifecycle/commands.js → contracts/presentation/terminal.js} +0 -0
- /package/dist/{foundation/resident-tabs/host-entry.d.ts → contracts/presentation/theme.js} +0 -0
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { chmod, lstat, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { createConnection, createServer } from "node:net";
|
|
4
|
-
import { platform } from "node:os";
|
|
5
|
-
import { dirname } from "node:path";
|
|
6
|
-
import { assertLaunchInstanceOutcome, assertNativeProcessIdentity, assertProcessContainmentIdentity, } from "../lifecycle/index.js";
|
|
7
|
-
import { encodeFrame, isCommandMessage, isControlHello, LineFrameDecoder, localControlHello, MAX_CONTROL_FRAME_BYTES, negotiateControlFeatures } from "../protocol/index.js";
|
|
8
|
-
import { listRecordedEndpoints, readEndpointMetadata, supervisorProcessState, currentSupervisorStartIdentity, withEndpointLock, processIsAlive } from "../release/index.js";
|
|
9
|
-
import { ControlStore } from "../storage/index.js";
|
|
10
|
-
import { resolveProductPaths } from "./paths.js";
|
|
11
|
-
import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
|
|
12
|
-
const WINDOWS_METADATA_REPLACE_RETRY_DELAYS_MS = [5, 10, 20, 40, 80, 160];
|
|
13
|
-
/** Atomically replaces endpoint metadata while tolerating bounded Windows reader sharing. */
|
|
14
|
-
export async function commitEndpointMetadata(path, source, operations = {}) {
|
|
15
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
16
|
-
const write = operations.write ?? writeFile;
|
|
17
|
-
const replace = operations.replace ?? rename;
|
|
18
|
-
const remove = operations.remove ?? rm;
|
|
19
|
-
const wait = operations.wait ?? (delayMs => new Promise(resolvePromise => setTimeout(resolvePromise, delayMs)));
|
|
20
|
-
let committed = false;
|
|
21
|
-
try {
|
|
22
|
-
await write(temporary, source, { mode: 0o600 });
|
|
23
|
-
for (let attempt = 0;; attempt += 1) {
|
|
24
|
-
try {
|
|
25
|
-
await replace(temporary, path);
|
|
26
|
-
committed = true;
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
const delayMs = WINDOWS_METADATA_REPLACE_RETRY_DELAYS_MS[attempt];
|
|
31
|
-
if ((operations.platform ?? platform()) !== "win32" || delayMs === undefined || !isWindowsSharingViolation(error))
|
|
32
|
-
throw error;
|
|
33
|
-
await wait(delayMs);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
finally {
|
|
38
|
-
if (!committed)
|
|
39
|
-
await remove(temporary, { force: true }).catch(() => undefined);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/** Owns one release-cohort endpoint and the authenticated launch instances registered through it. */
|
|
43
|
-
export class SupervisorServer {
|
|
44
|
-
id = randomUUID();
|
|
45
|
-
bootNonce;
|
|
46
|
-
pidStartIdentity = currentSupervisorStartIdentity();
|
|
47
|
-
startedAt = new Date().toISOString();
|
|
48
|
-
paths;
|
|
49
|
-
#server = null;
|
|
50
|
-
#ownsEndpoint = false;
|
|
51
|
-
#instances = new Map();
|
|
52
|
-
#instanceOwners = new Map();
|
|
53
|
-
#clientIds = new Map();
|
|
54
|
-
#clientInstances = new Map();
|
|
55
|
-
#uncertainInstances = new Set();
|
|
56
|
-
#reconciliations = new Map();
|
|
57
|
-
#revision = 0;
|
|
58
|
-
#clients = new Set();
|
|
59
|
-
#results = new Map();
|
|
60
|
-
#metadataWrites = Promise.resolve();
|
|
61
|
-
#closing = false;
|
|
62
|
-
#superseded = false;
|
|
63
|
-
#supersededPoll = null;
|
|
64
|
-
store;
|
|
65
|
-
release;
|
|
66
|
-
terminateProcess;
|
|
67
|
-
reconciliationDeadlineMs;
|
|
68
|
-
shutdownDeadlineMs;
|
|
69
|
-
readActiveReleaseId;
|
|
70
|
-
supersededPollMs;
|
|
71
|
-
constructor(store, paths = resolveProductPaths(), release, bootNonce = randomUUID(), terminateProcess = code => process.exit(code), reconciliationDeadlineMs = 3_000, shutdownDeadlineMs = 1_500,
|
|
72
|
-
/**
|
|
73
|
-
* Which release new sessions start on. A cohort that is no longer that release keeps
|
|
74
|
-
* serving the instances it already has, takes no new ones, and exits when its last one
|
|
75
|
-
* leaves. Absent, this supervisor never considers itself superseded.
|
|
76
|
-
*/
|
|
77
|
-
readActiveReleaseId = null, supersededPollMs = 1_000) {
|
|
78
|
-
this.store = store;
|
|
79
|
-
this.release = release;
|
|
80
|
-
this.terminateProcess = terminateProcess;
|
|
81
|
-
this.reconciliationDeadlineMs = reconciliationDeadlineMs;
|
|
82
|
-
this.shutdownDeadlineMs = shutdownDeadlineMs;
|
|
83
|
-
this.readActiveReleaseId = readActiveReleaseId;
|
|
84
|
-
this.supersededPollMs = supersededPollMs;
|
|
85
|
-
this.bootNonce = bootNonce;
|
|
86
|
-
this.paths = paths;
|
|
87
|
-
for (const instance of store.loadActiveLaunchInstances(bootNonce))
|
|
88
|
-
this.#instances.set(instance.id, instance);
|
|
89
|
-
}
|
|
90
|
-
snapshot() {
|
|
91
|
-
return {
|
|
92
|
-
revision: this.#revision,
|
|
93
|
-
activeInstances: [...this.#instances.values()].flatMap(instance => {
|
|
94
|
-
if (instance.state !== "requested" && instance.state !== "active" && instance.state !== "stopping")
|
|
95
|
-
return [];
|
|
96
|
-
return [{ id: instance.id, profileId: instance.profileId, state: instance.state }];
|
|
97
|
-
}),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
async listen() {
|
|
101
|
-
await withEndpointLock(this.paths.endpointMetadataPath, async () => {
|
|
102
|
-
if (this.#server)
|
|
103
|
-
throw new Error("supervisor is already listening");
|
|
104
|
-
await mkdir(this.paths.runtimeDir, { recursive: true, mode: 0o700 });
|
|
105
|
-
await mkdir(this.paths.endpointsDir, { recursive: true, mode: 0o700 });
|
|
106
|
-
const recorded = await readEndpointMetadata(this.paths.endpointMetadataPath);
|
|
107
|
-
if (recorded && await supervisorProcessState(recorded) !== "gone") {
|
|
108
|
-
throw Object.assign(new Error("another supervisor still owns this endpoint"), { code: "EADDRINUSE" });
|
|
109
|
-
}
|
|
110
|
-
if (platform() !== "win32") {
|
|
111
|
-
if (this.paths.endpointDirectory)
|
|
112
|
-
await ensureManagedEndpointDirectory(dirname(this.paths.endpoint));
|
|
113
|
-
const existing = await lstat(this.paths.endpoint).catch(error => {
|
|
114
|
-
if (error.code === "ENOENT")
|
|
115
|
-
return null;
|
|
116
|
-
throw error;
|
|
117
|
-
});
|
|
118
|
-
if (existing) {
|
|
119
|
-
if (await endpointIsLive(this.paths.endpoint)) {
|
|
120
|
-
throw Object.assign(new Error(PRODUCT_TEXT.diagnostic(`supervisor already owns ${this.paths.endpoint}`)), { code: "EADDRINUSE" });
|
|
121
|
-
}
|
|
122
|
-
await rm(this.paths.endpoint, { force: true });
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
const server = createServer(socket => this.#attach(socket));
|
|
126
|
-
this.#server = server;
|
|
127
|
-
await new Promise((resolve, reject) => {
|
|
128
|
-
server.once("error", reject);
|
|
129
|
-
server.listen(this.paths.endpoint, () => {
|
|
130
|
-
this.#ownsEndpoint = true;
|
|
131
|
-
server.off("error", reject);
|
|
132
|
-
resolve();
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
// Concurrency: only the bound winner may reconcile shared control data. Other cohort boots
|
|
136
|
-
// remain protected even when temporarily unresponsive; their instances never become ours.
|
|
137
|
-
await withEndpointLock(this.paths.databasePath, async () => {
|
|
138
|
-
// Concurrency: all cohorts sharing SQLite serialize boot reconciliation plus publication, so a new
|
|
139
|
-
// cohort cannot insert instances between another cohort's inventory and stale-row update.
|
|
140
|
-
const protectedBoots = [];
|
|
141
|
-
for (const other of await listRecordedEndpoints(this.paths)) {
|
|
142
|
-
if (other.paths.endpointMetadataPath !== this.paths.endpointMetadataPath
|
|
143
|
-
&& await supervisorProcessState(other.metadata) !== "gone")
|
|
144
|
-
protectedBoots.push(other.metadata.bootNonce);
|
|
145
|
-
}
|
|
146
|
-
this.store.reconcilePriorBootLaunchInstances(this.bootNonce, new Date().toISOString(), protectedBoots);
|
|
147
|
-
await this.#writeEndpointMetadata();
|
|
148
|
-
});
|
|
149
|
-
if (this.readActiveReleaseId) {
|
|
150
|
-
const poll = setInterval(() => void this.#refreshCohortRole(), this.supersededPollMs);
|
|
151
|
-
poll.unref();
|
|
152
|
-
this.#supersededPoll = poll;
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
// Invariant: superseding a cohort never interrupts its held instances; it retires only when empty.
|
|
157
|
-
async #refreshCohortRole() {
|
|
158
|
-
if (this.#closing || !this.readActiveReleaseId)
|
|
159
|
-
return;
|
|
160
|
-
const active = await this.readActiveReleaseId().catch(() => null);
|
|
161
|
-
if (active === null)
|
|
162
|
-
return;
|
|
163
|
-
this.#superseded = active !== this.release.releaseId;
|
|
164
|
-
if (this.#superseded && this.#instances.size === 0)
|
|
165
|
-
await this.retire();
|
|
166
|
-
}
|
|
167
|
-
/** Whether new sessions start on some other release. */
|
|
168
|
-
get superseded() {
|
|
169
|
-
return this.#superseded;
|
|
170
|
-
}
|
|
171
|
-
/** Leaves, taking this cohort's own endpoint artifacts with it. */
|
|
172
|
-
async retire() {
|
|
173
|
-
if (this.#closing)
|
|
174
|
-
return;
|
|
175
|
-
await this.close(false);
|
|
176
|
-
}
|
|
177
|
-
async close(stopAgents = false) {
|
|
178
|
-
if (this.#closing)
|
|
179
|
-
return;
|
|
180
|
-
if (stopAgents && this.#ownsEndpoint && !await this.#drainInstances("update", this.shutdownDeadlineMs)) {
|
|
181
|
-
throw new Error("active launch instances did not release ownership within the shutdown deadline");
|
|
182
|
-
}
|
|
183
|
-
this.#closing = true;
|
|
184
|
-
if (this.#supersededPoll)
|
|
185
|
-
clearInterval(this.#supersededPoll);
|
|
186
|
-
this.#supersededPoll = null;
|
|
187
|
-
for (const client of this.#clients)
|
|
188
|
-
client.destroy();
|
|
189
|
-
// Concurrency: disconnect reconciliation can still commit a terminal outcome after its
|
|
190
|
-
// bounded process wait. Settle it before retiring the endpoint and closing shared storage.
|
|
191
|
-
await Promise.allSettled(this.#reconciliations.values());
|
|
192
|
-
await withEndpointLock(this.paths.endpointMetadataPath, async () => {
|
|
193
|
-
try {
|
|
194
|
-
await this.#metadataWrites.catch(() => undefined);
|
|
195
|
-
if (this.#ownsEndpoint) {
|
|
196
|
-
// Concurrency: remove only our publication, before releasing the listening endpoint.
|
|
197
|
-
// A contender that failed to bind must never erase the successful owner's discovery file.
|
|
198
|
-
const metadata = await readFile(this.paths.endpointMetadataPath, "utf8").then(source => JSON.parse(source)).catch(() => null);
|
|
199
|
-
if (metadata?.supervisorId === this.id && metadata.bootNonce === this.bootNonce) {
|
|
200
|
-
await rm(this.paths.endpointMetadataPath, { force: true });
|
|
201
|
-
}
|
|
202
|
-
// Platform: Node unlinks its Unix socket when the server closes; unlinking it early would
|
|
203
|
-
// let a replacement bind before the old server finishes releasing that path.
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
finally {
|
|
207
|
-
// Platform: a metadata sharing error must not leave a bound but undiscoverable listener.
|
|
208
|
-
if (this.#server)
|
|
209
|
-
await new Promise(resolve => this.#server?.close(() => resolve()));
|
|
210
|
-
this.#server = null;
|
|
211
|
-
this.#ownsEndpoint = false;
|
|
212
|
-
this.store.close();
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
async closeForReleaseReplacement(stopAgents) {
|
|
217
|
-
await this.close(stopAgents);
|
|
218
|
-
this.terminateProcess(0);
|
|
219
|
-
}
|
|
220
|
-
#attach(socket) {
|
|
221
|
-
socket.setNoDelay(true);
|
|
222
|
-
const decoder = new LineFrameDecoder();
|
|
223
|
-
let welcomed = false;
|
|
224
|
-
socket.on("data", chunk => {
|
|
225
|
-
try {
|
|
226
|
-
for (const value of decoder.push(chunk)) {
|
|
227
|
-
if (!welcomed) {
|
|
228
|
-
if (isMessageType(value, "identity-probe")) {
|
|
229
|
-
this.#send(socket, { type: "identity", supervisorId: this.id, bootNonce: this.bootNonce, pidStartIdentity: this.pidStartIdentity, releaseId: this.release.releaseId });
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
if (isMessageType(value, "release-idle-ownership")) {
|
|
233
|
-
const request = value;
|
|
234
|
-
const identityMatches = request.bootNonce === this.bootNonce && typeof request.candidateReleaseId === "string";
|
|
235
|
-
const released = identityMatches && this.#instances.size === 0;
|
|
236
|
-
this.#send(socket, {
|
|
237
|
-
type: "release-ownership-result",
|
|
238
|
-
released,
|
|
239
|
-
reason: released ? "idle cohort released ownership"
|
|
240
|
-
: identityMatches ? "launch instances are still active" : "boot nonce or candidate release mismatch",
|
|
241
|
-
liveInstanceIds: this.#liveInstanceIds(),
|
|
242
|
-
});
|
|
243
|
-
if (released)
|
|
244
|
-
setTimeout(() => void this.closeForReleaseReplacement(false), 25);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
if (isMessageType(value, "release-update-ownership")) {
|
|
248
|
-
const request = value;
|
|
249
|
-
void this.#handleUpdateRelease(socket, request);
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
if (!isControlHello(value)) {
|
|
253
|
-
this.#send(socket, { type: "protocol-error", code: "invalid-control-handshake", message: `the first message must be a valid ${PRODUCT_TEXT.displayName} control feature handshake`, diagnostics: { received: value } });
|
|
254
|
-
socket.destroy();
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
const serverHello = localControlHello();
|
|
258
|
-
const negotiation = negotiateControlFeatures(value, serverHello);
|
|
259
|
-
if (!negotiation.ok) {
|
|
260
|
-
this.#send(socket, { type: "protocol-error", code: "incompatible-control-features", message: negotiation.diagnostic, diagnostics: negotiation });
|
|
261
|
-
socket.destroy();
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
welcomed = true;
|
|
265
|
-
this.#clients.add(socket);
|
|
266
|
-
this.#clientIds.set(socket, value.clientId);
|
|
267
|
-
this.#clientInstances.set(socket, new Set());
|
|
268
|
-
this.#send(socket, { type: "server-hello", ...serverHello, releaseId: this.release.releaseId, supervisorId: this.id, bootNonce: this.bootNonce, pidStartIdentity: this.pidStartIdentity, negotiatedFeatures: negotiation.negotiatedFeatures, snapshot: this.snapshot() });
|
|
269
|
-
}
|
|
270
|
-
else if (isCommandMessage(value)) {
|
|
271
|
-
void this.#execute(value.command, socket);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
this.#send(socket, { type: "protocol-error", code: "framing-error", message: error instanceof Error ? error.message : String(error) });
|
|
277
|
-
socket.destroy();
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
socket.on("close", () => this.#onSocketClosed(socket));
|
|
281
|
-
socket.on("error", () => this.#onSocketClosed(socket));
|
|
282
|
-
}
|
|
283
|
-
async #execute(command, socket) {
|
|
284
|
-
const clientId = this.#clientIds.get(socket);
|
|
285
|
-
if (!clientId) {
|
|
286
|
-
this.#send(socket, { type: "protocol-error", code: "unauthenticated-command", message: "launch-instance commands require an authenticated client" });
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const resultKey = `${clientId}:${command.requestId}`;
|
|
290
|
-
const recorded = this.#results.get(resultKey);
|
|
291
|
-
if (recorded) {
|
|
292
|
-
this.#send(socket, { type: "command-result", result: recorded });
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
let result;
|
|
296
|
-
try {
|
|
297
|
-
if (command.type === "create-launch-instance")
|
|
298
|
-
await this.#createLaunchInstance(command, socket, clientId);
|
|
299
|
-
if (command.type === "activate-launch-instance")
|
|
300
|
-
this.#activateLaunchInstance(command, socket, clientId);
|
|
301
|
-
if (command.type === "begin-launch-instance-stop")
|
|
302
|
-
this.#beginLaunchInstanceStop(command, socket, clientId);
|
|
303
|
-
if (command.type === "complete-launch-instance")
|
|
304
|
-
this.#completeLaunchInstance(command, socket, clientId);
|
|
305
|
-
if (command.type === "reconcile-launch-instance") {
|
|
306
|
-
this.#ownedInstance(command.instanceId, socket, clientId);
|
|
307
|
-
await this.#reconcileLaunchInstance(command.instanceId);
|
|
308
|
-
}
|
|
309
|
-
if (command.type === "resynchronize")
|
|
310
|
-
this.#send(socket, { type: "snapshot", snapshot: this.snapshot() });
|
|
311
|
-
await this.#metadataWrites;
|
|
312
|
-
result = { requestId: command.requestId, ok: true, revision: this.#revision };
|
|
313
|
-
}
|
|
314
|
-
catch (error) {
|
|
315
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
316
|
-
const explicitCode = error instanceof Error && "code" in error ? error.code : undefined;
|
|
317
|
-
const code = explicitCode === "release-superseded"
|
|
318
|
-
? "release-superseded"
|
|
319
|
-
: /not found/i.test(message) ? "not-found"
|
|
320
|
-
: /owner|ownership|authenticated/i.test(message) ? "ownership-error" : "driver-error";
|
|
321
|
-
result = { requestId: command.requestId, ok: false, revision: this.#revision, error: { code, message } };
|
|
322
|
-
}
|
|
323
|
-
this.#results.set(resultKey, result);
|
|
324
|
-
this.#send(socket, { type: "command-result", result });
|
|
325
|
-
}
|
|
326
|
-
async #createLaunchInstance(command, socket, clientId) {
|
|
327
|
-
assertNativeProcessIdentity(command.guardianIdentity);
|
|
328
|
-
const existing = this.store.loadLaunchInstance(command.instanceId);
|
|
329
|
-
if (!existing && this.readActiveReleaseId) {
|
|
330
|
-
const active = await this.readActiveReleaseId().catch(() => null);
|
|
331
|
-
if (active !== null)
|
|
332
|
-
this.#superseded = active !== this.release.releaseId;
|
|
333
|
-
}
|
|
334
|
-
if (this.#superseded && !existing) {
|
|
335
|
-
throw Object.assign(new Error(PRODUCT_TEXT.diagnostic(`release ${this.release.releaseId} is no longer active for new sessions`)), {
|
|
336
|
-
code: "release-superseded",
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
if (existing) {
|
|
340
|
-
if (existing.ownerClientId !== clientId
|
|
341
|
-
|| existing.profileId !== command.profileId
|
|
342
|
-
|| existing.shutdownPolicy !== command.shutdownPolicy
|
|
343
|
-
|| !sameProcessIdentity(existing.guardianIdentity, command.guardianIdentity)) {
|
|
344
|
-
throw new Error("launch instance already exists with different authenticated ownership");
|
|
345
|
-
}
|
|
346
|
-
if (existing.state === "completed" || existing.state === "interrupted")
|
|
347
|
-
throw new Error("launch instance already has a terminal outcome");
|
|
348
|
-
this.#instances.set(existing.id, existing);
|
|
349
|
-
this.#bindOwner(existing.id, socket);
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
const instance = {
|
|
353
|
-
id: command.instanceId,
|
|
354
|
-
ownerClientId: clientId,
|
|
355
|
-
profileId: command.profileId,
|
|
356
|
-
state: "requested",
|
|
357
|
-
shutdownPolicy: command.shutdownPolicy,
|
|
358
|
-
guardianIdentity: command.guardianIdentity,
|
|
359
|
-
rootIdentity: null,
|
|
360
|
-
containmentIdentity: null,
|
|
361
|
-
createdAt: new Date().toISOString(),
|
|
362
|
-
activatedAt: null,
|
|
363
|
-
stoppingAt: null,
|
|
364
|
-
completedAt: null,
|
|
365
|
-
outcome: null,
|
|
366
|
-
};
|
|
367
|
-
this.store.createLaunchInstance(instance);
|
|
368
|
-
this.#instances.set(instance.id, instance);
|
|
369
|
-
this.#bindOwner(instance.id, socket);
|
|
370
|
-
this.#mutated();
|
|
371
|
-
}
|
|
372
|
-
#activateLaunchInstance(command, socket, clientId) {
|
|
373
|
-
assertNativeProcessIdentity(command.rootIdentity);
|
|
374
|
-
assertProcessContainmentIdentity(command.containmentIdentity);
|
|
375
|
-
const instance = this.#ownedInstance(command.instanceId, socket, clientId);
|
|
376
|
-
if (instance.state === "active"
|
|
377
|
-
&& sameProcessIdentity(instance.rootIdentity, command.rootIdentity)
|
|
378
|
-
&& sameContainmentIdentity(instance.containmentIdentity, command.containmentIdentity))
|
|
379
|
-
return;
|
|
380
|
-
if (instance.state !== "requested")
|
|
381
|
-
throw new Error("launch instance is not requested");
|
|
382
|
-
const activatedAt = new Date().toISOString();
|
|
383
|
-
if (!this.store.activateLaunchInstance(instance.id, clientId, command.rootIdentity, command.containmentIdentity, activatedAt)) {
|
|
384
|
-
throw new Error("launch instance activation ownership mismatch");
|
|
385
|
-
}
|
|
386
|
-
this.#instances.set(instance.id, { ...instance, state: "active", rootIdentity: command.rootIdentity, containmentIdentity: command.containmentIdentity, activatedAt });
|
|
387
|
-
this.#mutated();
|
|
388
|
-
}
|
|
389
|
-
#beginLaunchInstanceStop(command, socket, clientId) {
|
|
390
|
-
const instance = this.#ownedInstance(command.instanceId, socket, clientId);
|
|
391
|
-
if (instance.state === "stopping")
|
|
392
|
-
return;
|
|
393
|
-
if (instance.state !== "active")
|
|
394
|
-
throw new Error("active launch instance not found");
|
|
395
|
-
const stoppingAt = new Date().toISOString();
|
|
396
|
-
if (!this.store.beginLaunchInstanceStop(instance.id, clientId, stoppingAt))
|
|
397
|
-
throw new Error("launch instance stop ownership mismatch");
|
|
398
|
-
this.#instances.set(instance.id, { ...instance, state: "stopping", stoppingAt });
|
|
399
|
-
this.#mutated();
|
|
400
|
-
}
|
|
401
|
-
#completeLaunchInstance(command, socket, clientId) {
|
|
402
|
-
assertLaunchInstanceOutcome(command.outcome);
|
|
403
|
-
const stored = this.store.loadLaunchInstance(command.instanceId);
|
|
404
|
-
if (!stored)
|
|
405
|
-
throw new Error("launch instance not found");
|
|
406
|
-
if (stored.ownerClientId !== clientId || this.#instanceOwners.get(stored.id) !== socket)
|
|
407
|
-
throw new Error("launch instance ownership mismatch");
|
|
408
|
-
if (stored.state === "completed" || stored.state === "interrupted") {
|
|
409
|
-
if (stored.state === command.terminalState && JSON.stringify(stored.outcome) === JSON.stringify(command.outcome))
|
|
410
|
-
return;
|
|
411
|
-
throw new Error("launch instance already has a different terminal outcome");
|
|
412
|
-
}
|
|
413
|
-
const completedAt = new Date().toISOString();
|
|
414
|
-
if (!this.store.completeLaunchInstance(stored.id, clientId, command.terminalState, command.outcome, completedAt)) {
|
|
415
|
-
throw new Error("launch instance completion ownership mismatch");
|
|
416
|
-
}
|
|
417
|
-
this.#instances.delete(stored.id);
|
|
418
|
-
this.#uncertainInstances.delete(stored.id);
|
|
419
|
-
this.#unbindOwner(stored.id, socket);
|
|
420
|
-
this.#mutated();
|
|
421
|
-
// Invariant: the last session on a superseded cohort has left; there is nothing here to keep.
|
|
422
|
-
if (this.#superseded && this.#instances.size === 0)
|
|
423
|
-
void this.retire();
|
|
424
|
-
}
|
|
425
|
-
#ownedInstance(instanceId, socket, clientId) {
|
|
426
|
-
const instance = this.#instances.get(instanceId) ?? this.store.loadLaunchInstance(instanceId);
|
|
427
|
-
if (!instance || instance.state === "completed" || instance.state === "interrupted")
|
|
428
|
-
throw new Error("active launch instance not found");
|
|
429
|
-
if (instance.ownerClientId !== clientId || this.#instanceOwners.get(instanceId) !== socket)
|
|
430
|
-
throw new Error("launch instance ownership mismatch");
|
|
431
|
-
return instance;
|
|
432
|
-
}
|
|
433
|
-
#bindOwner(instanceId, socket) {
|
|
434
|
-
const current = this.#instanceOwners.get(instanceId);
|
|
435
|
-
if (current && current !== socket)
|
|
436
|
-
throw new Error("launch instance already belongs to another authenticated connection");
|
|
437
|
-
this.#instanceOwners.set(instanceId, socket);
|
|
438
|
-
this.#clientInstances.get(socket)?.add(instanceId);
|
|
439
|
-
}
|
|
440
|
-
#unbindOwner(instanceId, socket) {
|
|
441
|
-
this.#instanceOwners.delete(instanceId);
|
|
442
|
-
this.#clientInstances.get(socket)?.delete(instanceId);
|
|
443
|
-
}
|
|
444
|
-
#onSocketClosed(socket) {
|
|
445
|
-
if (!this.#clients.delete(socket) && !this.#clientIds.has(socket))
|
|
446
|
-
return;
|
|
447
|
-
const instanceIds = [...(this.#clientInstances.get(socket) ?? [])];
|
|
448
|
-
this.#clientInstances.delete(socket);
|
|
449
|
-
this.#clientIds.delete(socket);
|
|
450
|
-
for (const instanceId of instanceIds) {
|
|
451
|
-
if (this.#instanceOwners.get(instanceId) === socket)
|
|
452
|
-
this.#instanceOwners.delete(instanceId);
|
|
453
|
-
if (!this.#closing)
|
|
454
|
-
void this.#reconcileLaunchInstance(instanceId);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
#reconcileLaunchInstance(instanceId) {
|
|
458
|
-
const existing = this.#reconciliations.get(instanceId);
|
|
459
|
-
if (existing)
|
|
460
|
-
return existing;
|
|
461
|
-
if (this.#closing)
|
|
462
|
-
return Promise.resolve();
|
|
463
|
-
const reconciliation = this.#performReconciliation(instanceId).finally(() => this.#reconciliations.delete(instanceId));
|
|
464
|
-
this.#reconciliations.set(instanceId, reconciliation);
|
|
465
|
-
return reconciliation;
|
|
466
|
-
}
|
|
467
|
-
async #performReconciliation(instanceId) {
|
|
468
|
-
const instance = this.#instances.get(instanceId);
|
|
469
|
-
if (!instance)
|
|
470
|
-
return;
|
|
471
|
-
const deadline = Date.now() + this.reconciliationDeadlineMs;
|
|
472
|
-
while (instance.rootIdentity && processIsAlive(instance.rootIdentity.pid) && Date.now() < deadline) {
|
|
473
|
-
await new Promise(resolvePromise => setTimeout(resolvePromise, 25));
|
|
474
|
-
}
|
|
475
|
-
if (instance.state === "requested" || (instance.rootIdentity && !processIsAlive(instance.rootIdentity.pid))) {
|
|
476
|
-
const outcome = { kind: "interrupted", reason: "owner-disconnect", message: "launch instance owner disconnected before reporting a terminal outcome" };
|
|
477
|
-
if (this.store.completeLaunchInstance(instance.id, instance.ownerClientId, "interrupted", outcome, new Date().toISOString())) {
|
|
478
|
-
this.#instances.delete(instance.id);
|
|
479
|
-
this.#uncertainInstances.delete(instance.id);
|
|
480
|
-
this.#mutated();
|
|
481
|
-
}
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
this.#uncertainInstances.add(instance.id);
|
|
485
|
-
await this.#writeEndpointMetadata();
|
|
486
|
-
}
|
|
487
|
-
async #handleUpdateRelease(socket, request) {
|
|
488
|
-
const identityMatches = request.bootNonce === this.bootNonce && typeof request.targetVersion === "string";
|
|
489
|
-
if (!identityMatches) {
|
|
490
|
-
this.#send(socket, {
|
|
491
|
-
type: "release-update-result",
|
|
492
|
-
accepted: false,
|
|
493
|
-
reason: "boot nonce or target version mismatch",
|
|
494
|
-
liveInstanceIds: this.#liveInstanceIds(),
|
|
495
|
-
});
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
const released = await this.#drainInstances("update", this.shutdownDeadlineMs);
|
|
499
|
-
this.#send(socket, {
|
|
500
|
-
type: "release-update-result",
|
|
501
|
-
accepted: released,
|
|
502
|
-
reason: released
|
|
503
|
-
? `verified ${PRODUCT_TEXT.displayName} owner drained all launch instances for immediate update shutdown`
|
|
504
|
-
: "one or more launch instances did not release verified ownership within the update deadline",
|
|
505
|
-
liveInstanceIds: this.#liveInstanceIds(),
|
|
506
|
-
});
|
|
507
|
-
if (released)
|
|
508
|
-
setTimeout(() => void this.closeForReleaseReplacement(false), 25);
|
|
509
|
-
}
|
|
510
|
-
async #drainInstances(reason, timeoutMs) {
|
|
511
|
-
if (this.#instances.size === 0)
|
|
512
|
-
return true;
|
|
513
|
-
this.#requestStopAll(reason);
|
|
514
|
-
const deadline = Date.now() + timeoutMs;
|
|
515
|
-
while (Date.now() < deadline) {
|
|
516
|
-
if (this.#instances.size === 0) {
|
|
517
|
-
// Concurrency: allow the terminal command result to flush before closing owner sockets.
|
|
518
|
-
await new Promise(resolvePromise => setTimeout(resolvePromise, 25));
|
|
519
|
-
return this.#instances.size === 0;
|
|
520
|
-
}
|
|
521
|
-
await new Promise(resolvePromise => setTimeout(resolvePromise, 25));
|
|
522
|
-
}
|
|
523
|
-
return this.#instances.size === 0;
|
|
524
|
-
}
|
|
525
|
-
#requestStopAll(reason) {
|
|
526
|
-
for (const [instanceId, socket] of this.#instanceOwners) {
|
|
527
|
-
this.#send(socket, { type: "stop-launch-instance", requestId: randomUUID(), instanceId, reason });
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
#mutated() {
|
|
531
|
-
this.#revision += 1;
|
|
532
|
-
void this.#writeEndpointMetadata();
|
|
533
|
-
}
|
|
534
|
-
#liveInstanceIds() {
|
|
535
|
-
return [...this.#instances.keys()];
|
|
536
|
-
}
|
|
537
|
-
#writeEndpointMetadata() {
|
|
538
|
-
if (this.#closing)
|
|
539
|
-
return Promise.resolve();
|
|
540
|
-
const liveInstanceIds = this.#liveInstanceIds();
|
|
541
|
-
const metadata = {
|
|
542
|
-
schema: PRODUCT_IDENTITY.protocol.supervisorSchema,
|
|
543
|
-
...localControlHello(this.release.releaseId),
|
|
544
|
-
supervisorId: this.id,
|
|
545
|
-
pid: process.pid,
|
|
546
|
-
pidStartIdentity: this.pidStartIdentity,
|
|
547
|
-
nativeStartIdentity: this.pidStartIdentity,
|
|
548
|
-
bootNonce: this.bootNonce,
|
|
549
|
-
endpoint: this.paths.endpoint,
|
|
550
|
-
databasePath: this.paths.databasePath,
|
|
551
|
-
startedAt: this.startedAt,
|
|
552
|
-
releaseId: this.release.releaseId,
|
|
553
|
-
releaseRoot: this.release.releaseRoot,
|
|
554
|
-
contentDigest: this.release.contentDigest,
|
|
555
|
-
ownership: {
|
|
556
|
-
state: this.#uncertainInstances.size > 0 ? "blocked" : liveInstanceIds.length > 0 ? "busy" : "idle",
|
|
557
|
-
liveInstanceIds,
|
|
558
|
-
nonResumableInstanceIds: liveInstanceIds,
|
|
559
|
-
uncertainInstanceIds: [...this.#uncertainInstances],
|
|
560
|
-
},
|
|
561
|
-
};
|
|
562
|
-
const commit = () => commitEndpointMetadata(this.paths.endpointMetadataPath, JSON.stringify(metadata, null, 2));
|
|
563
|
-
// Platform: one exhausted filesystem replacement must fail its command, but it must not
|
|
564
|
-
// poison every later ownership revision after the sharing condition has cleared.
|
|
565
|
-
this.#metadataWrites = this.#metadataWrites.then(commit, commit);
|
|
566
|
-
return this.#metadataWrites;
|
|
567
|
-
}
|
|
568
|
-
#send(socket, message) {
|
|
569
|
-
if (socket.destroyed)
|
|
570
|
-
return;
|
|
571
|
-
const frame = encodeFrame(message);
|
|
572
|
-
const bytes = Buffer.byteLength(frame, "utf8");
|
|
573
|
-
if (bytes > MAX_CONTROL_FRAME_BYTES || socket.writableLength + bytes > MAX_CONTROL_FRAME_BYTES * 2) {
|
|
574
|
-
socket.destroy(new Error("slow client exceeded the bounded control/output queue"));
|
|
575
|
-
return;
|
|
576
|
-
}
|
|
577
|
-
socket.write(frame);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
function sameProcessIdentity(left, right) {
|
|
581
|
-
return left !== null && left.pid === right.pid && left.startIdentity === right.startIdentity;
|
|
582
|
-
}
|
|
583
|
-
function sameContainmentIdentity(left, right) {
|
|
584
|
-
return left !== null && left.provider === right.provider && left.token === right.token;
|
|
585
|
-
}
|
|
586
|
-
function isMessageType(value, type) {
|
|
587
|
-
return typeof value === "object" && value !== null && "type" in value && value.type === type;
|
|
588
|
-
}
|
|
589
|
-
function isWindowsSharingViolation(error) {
|
|
590
|
-
return error instanceof Error && "code" in error
|
|
591
|
-
&& (error.code === "EPERM" || error.code === "EACCES" || error.code === "EBUSY");
|
|
592
|
-
}
|
|
593
|
-
async function ensureManagedEndpointDirectory(path) {
|
|
594
|
-
await mkdir(path, { recursive: true, mode: 0o700 });
|
|
595
|
-
const metadata = await lstat(path);
|
|
596
|
-
if (!metadata.isDirectory() || metadata.isSymbolicLink())
|
|
597
|
-
throw new Error(`managed endpoint path is not a directory: ${path}`);
|
|
598
|
-
const currentUser = process.getuid?.();
|
|
599
|
-
if (currentUser !== undefined && metadata.uid !== currentUser)
|
|
600
|
-
throw new Error(`managed endpoint directory has another owner: ${path}`);
|
|
601
|
-
await chmod(path, 0o700);
|
|
602
|
-
}
|
|
603
|
-
async function endpointIsLive(endpoint) {
|
|
604
|
-
return await new Promise(resolve => {
|
|
605
|
-
const socket = createConnection(endpoint);
|
|
606
|
-
const done = (live) => { socket.destroy(); resolve(live); };
|
|
607
|
-
socket.once("connect", () => done(true));
|
|
608
|
-
socket.once("error", () => done(false));
|
|
609
|
-
setTimeout(() => done(false), 250).unref();
|
|
610
|
-
});
|
|
611
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
|
|
2
|
-
export declare function adaptPiUserMessage(block: OwnedUiTranscriptBlock, width: number): readonly string[];
|
|
3
|
-
export declare function adaptPiAssistantMessage(block: OwnedUiTranscriptBlock, width: number): readonly string[];
|
|
4
|
-
export declare function adaptPiToolExecution(block: OwnedUiTranscriptBlock, width: number, cwd: string): readonly string[];
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { AssistantMessageComponent, ToolExecutionComponent, UserMessageComponent, } from "../startup-public.js";
|
|
2
|
-
import { createTuiFacade, validatedAssistantMessage } from "./shell-components.js";
|
|
3
|
-
import { ensurePiTheme, getPiMarkdownTheme } from "./theme.js";
|
|
4
|
-
export function adaptPiUserMessage(block, width) {
|
|
5
|
-
requireBlock(block, "user");
|
|
6
|
-
ensurePiTheme();
|
|
7
|
-
return new UserMessageComponent(block.text).render(width);
|
|
8
|
-
}
|
|
9
|
-
export function adaptPiAssistantMessage(block, width) {
|
|
10
|
-
requireBlock(block, "assistant");
|
|
11
|
-
ensurePiTheme();
|
|
12
|
-
return new AssistantMessageComponent(validatedAssistantMessage(block), false, getPiMarkdownTheme()).render(width);
|
|
13
|
-
}
|
|
14
|
-
export function adaptPiToolExecution(block, width, cwd) {
|
|
15
|
-
if (block.kind !== "tool-call" && block.kind !== "tool-result") {
|
|
16
|
-
throw new TypeError("Pi tool execution adaptation requires a tool block");
|
|
17
|
-
}
|
|
18
|
-
ensurePiTheme();
|
|
19
|
-
const payload = blockPayload(block);
|
|
20
|
-
const toolCallId = stringPayload(payload, "toolCallId") ?? block.id;
|
|
21
|
-
const toolName = stringPayload(payload, "toolName") ?? block.title ?? "tool";
|
|
22
|
-
const args = isRecord(payload.arguments) && "json" in payload.arguments ? payload.arguments.json : {};
|
|
23
|
-
const component = new ToolExecutionComponent(toolName, toolCallId, args, undefined, undefined, createTuiFacade({ getColumns: () => width, getRows: () => 24, requestRender() { } }), cwd);
|
|
24
|
-
if (block.status === "live")
|
|
25
|
-
component.markExecutionStarted();
|
|
26
|
-
component.setArgsComplete();
|
|
27
|
-
if (block.kind === "tool-result") {
|
|
28
|
-
component.updateResult({
|
|
29
|
-
content: [{ type: "text", text: block.text }],
|
|
30
|
-
isError: payload.isError === true,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
return component.render(width);
|
|
34
|
-
}
|
|
35
|
-
function requireBlock(block, kind) {
|
|
36
|
-
if (block.kind !== kind)
|
|
37
|
-
throw new TypeError(`Pi component adaptation requires ${kind}, received ${block.kind}`);
|
|
38
|
-
}
|
|
39
|
-
function blockPayload(block) {
|
|
40
|
-
return isRecord(block.payload) ? block.payload : {};
|
|
41
|
-
}
|
|
42
|
-
function stringPayload(payload, key) {
|
|
43
|
-
const value = payload[key];
|
|
44
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
45
|
-
}
|
|
46
|
-
function isRecord(value) {
|
|
47
|
-
return typeof value === "object" && value !== null;
|
|
48
|
-
}
|