@timurproko/a1 0.2.6-dev.736 → 0.2.7-dev.1221
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 +41 -3
- package/bin/automatic-update.js +7 -0
- package/bin/cli.js +4 -0
- package/bin/guardian.js +5 -0
- package/bin/tab-launch-context.d.ts +27 -0
- package/bin/tab-launch-context.js +94 -0
- package/bin/ui.js +107 -59
- package/dist/app/session-shell/clipboard-diagnostics.js +1 -1
- package/dist/app/session-shell/dialog-coordinator.d.ts +42 -0
- package/dist/app/session-shell/dialog-coordinator.js +133 -0
- package/dist/app/session-shell/dock-chrome.d.ts +34 -0
- package/dist/app/session-shell/dock-chrome.js +109 -0
- package/dist/app/session-shell/exit-notice.d.ts +1 -1
- package/dist/app/session-shell/exit-notice.js +1 -1
- package/dist/app/session-shell/extension-surface.d.ts +30 -0
- package/dist/app/session-shell/extension-surface.js +105 -0
- package/dist/app/session-shell/helper-pool.d.ts +3 -5
- package/dist/app/session-shell/helper-pool.js +3 -5
- package/dist/app/session-shell/input-surface-switch.d.ts +36 -0
- package/dist/app/session-shell/input-surface-switch.js +85 -0
- package/dist/app/session-shell/login-interaction.d.ts +27 -0
- package/dist/app/session-shell/login-interaction.js +91 -0
- package/dist/app/session-shell/prompt-submission.d.ts +48 -0
- package/dist/app/session-shell/prompt-submission.js +276 -0
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +38 -0
- package/dist/app/session-shell/resident-tab-coordinator.js +77 -0
- package/dist/app/session-shell/response-copy-helper.js +21 -6
- package/dist/app/session-shell/response-copy-protocol.d.ts +1 -1
- package/dist/app/session-shell/response-copy-transport.d.ts +16 -6
- package/dist/app/session-shell/response-copy-transport.js +69 -17
- package/dist/app/session-shell/session-concern.d.ts +22 -0
- package/dist/app/session-shell/session-concern.js +29 -0
- package/dist/app/session-shell/session-lifecycle.d.ts +29 -0
- package/dist/app/session-shell/session-lifecycle.js +49 -0
- package/dist/app/session-shell/session-shell-root.d.ts +42 -6
- package/dist/app/session-shell/session-shell-root.js +196 -908
- package/dist/app/session-shell/session-shell.d.ts +3 -8
- package/dist/app/session-shell/session-shell.js +324 -835
- package/dist/app/session-shell/session-viewport-controller.d.ts +2 -2
- package/dist/app/session-shell/session-viewport-controller.js +29 -15
- package/dist/app/session-shell/settings-bindings.d.ts +17 -0
- package/dist/app/session-shell/settings-bindings.js +91 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +27 -0
- package/dist/app/session-shell/shell-editor-factory.js +102 -0
- package/dist/app/session-shell/shell-host.d.ts +6 -0
- package/dist/app/session-shell/shell-host.js +34 -7
- package/dist/app/session-shell/shell-layout.d.ts +64 -0
- package/dist/app/session-shell/shell-layout.js +18 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +25 -0
- package/dist/app/session-shell/suggestion-surface.js +63 -0
- package/dist/app/session-shell/transcript-document.d.ts +78 -0
- package/dist/app/session-shell/transcript-document.js +365 -0
- package/dist/app/session-shell/viewport-layout.d.ts +31 -0
- package/dist/app/session-shell/viewport-layout.js +160 -0
- package/dist/app/session-shell/workflow-output.d.ts +33 -0
- package/dist/app/session-shell/workflow-output.js +174 -0
- package/dist/app/session-shell/workflow-router.d.ts +25 -0
- package/dist/app/session-shell/workflow-router.js +39 -0
- package/dist/cli/dispatch.d.ts +11 -1
- package/dist/cli/dispatch.js +79 -5
- package/dist/cli/tabs-request.d.ts +7 -0
- package/dist/cli/tabs-request.js +1 -0
- package/dist/cli/tabs.d.ts +14 -0
- package/dist/cli/tabs.js +151 -0
- package/dist/cli/version-stats.js +38 -3
- package/dist/composition/owned-settings.d.ts +12 -0
- package/dist/composition/owned-settings.js +36 -0
- package/dist/composition/owned-ui.d.ts +27 -28
- package/dist/composition/owned-ui.js +205 -153
- package/dist/composition/resident-tab-bridge.d.ts +25 -0
- package/dist/composition/resident-tab-bridge.js +180 -0
- package/dist/composition/session-backend.d.ts +19 -0
- package/dist/composition/session-backend.js +1 -0
- package/dist/composition/session-runtime-registry.d.ts +20 -0
- package/dist/composition/session-runtime-registry.js +85 -0
- package/dist/composition/settings-route-host.d.ts +16 -1
- package/dist/composition/settings-route-host.js +29 -10
- package/dist/composition/settings-search-input.d.ts +9 -0
- package/dist/composition/settings-search-input.js +58 -0
- package/dist/composition/startup-route.d.ts +32 -0
- package/dist/composition/startup-route.js +72 -0
- package/dist/composition/utility-tab.d.ts +28 -0
- package/dist/composition/utility-tab.js +242 -0
- package/dist/contracts/owned-ui/index.d.ts +1 -1
- package/dist/contracts/owned-ui/model.d.ts +3 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +3 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +11 -4
- package/dist/contracts/presentation/index.d.ts +11 -0
- package/dist/contracts/presentation/index.js +12 -0
- package/dist/features/launch/development-launch.js +6 -0
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/intent.d.ts +3 -1
- package/dist/features/launch/intent.js +7 -4
- package/dist/features/launch/profile-paths.js +4 -0
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
- package/dist/features/owned-ui/plus-menu-dialog.js +76 -0
- package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
- package/dist/features/owned-ui/project-trust-dialog.js +6 -8
- package/dist/features/owned-ui/project-trust-prompt.d.ts +1 -0
- package/dist/features/owned-ui/project-trust-prompt.js +7 -3
- package/dist/features/owned-ui/reference-screen-app.d.ts +2 -0
- package/dist/features/owned-ui/reference-screen-app.js +12 -2
- package/dist/features/owned-ui/resources/release-notes.json +4 -0
- package/dist/features/owned-ui/settings-app.d.ts +12 -2
- package/dist/features/owned-ui/settings-app.js +119 -84
- package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
- package/dist/features/owned-ui/settings-search-input.js +1 -0
- package/dist/features/prompt-history/index.d.ts +1 -1
- package/dist/features/prompt-history/paths.d.ts +2 -1
- package/dist/features/prompt-history/paths.js +10 -2
- package/dist/features/prompt-history/service.d.ts +5 -0
- package/dist/features/prompt-history/service.js +1 -1
- package/dist/features/resident-tab/auto-name.d.ts +11 -0
- package/dist/features/resident-tab/auto-name.js +44 -0
- package/dist/features/resident-tab/index.d.ts +5 -0
- package/dist/features/resident-tab/index.js +7 -0
- package/dist/features/resident-tab/shortcut-bindings-file.d.ts +8 -0
- package/dist/features/resident-tab/shortcut-bindings-file.js +40 -0
- package/dist/features/resident-tab/shortcut-declarations.d.ts +13 -0
- package/dist/features/resident-tab/shortcut-declarations.js +26 -0
- package/dist/features/resident-tab/shortcut-projection.d.ts +29 -0
- package/dist/features/resident-tab/shortcut-projection.js +64 -0
- package/dist/features/resident-tab/status-deriver.d.ts +10 -0
- package/dist/features/resident-tab/status-deriver.js +12 -0
- package/dist/foundation/launch-context/index.d.ts +12 -0
- package/dist/foundation/launch-context/index.js +26 -0
- package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
- package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
- package/dist/foundation/launch-guardian/main.d.ts +7 -1
- package/dist/foundation/launch-guardian/main.js +60 -7
- package/dist/foundation/lifecycle/session-repository-context.js +16 -2
- package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
- package/dist/foundation/process-containment/addon-containment.js +139 -0
- package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
- package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
- package/dist/foundation/process-containment/addon.d.ts +42 -0
- package/dist/foundation/process-containment/addon.js +57 -0
- package/dist/foundation/process-containment/artifact.d.ts +1 -1
- package/dist/foundation/process-containment/artifact.js +6 -5
- package/dist/foundation/process-containment/contracts.d.ts +2 -0
- package/dist/foundation/process-containment/index.d.ts +4 -4
- package/dist/foundation/process-containment/index.js +3 -3
- package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
- package/dist/foundation/process-containment/native-process-inspector.js +10 -10
- package/dist/foundation/release/automatic-update.d.ts +37 -0
- package/dist/foundation/release/automatic-update.js +265 -0
- package/dist/foundation/release/bootstrap.d.ts +7 -9
- package/dist/foundation/release/bootstrap.js +107 -24
- package/dist/foundation/release/cohort-state.d.ts +1 -1
- package/dist/foundation/release/cohort-state.js +6 -3
- package/dist/foundation/release/dependency-certification.js +54 -19
- package/dist/foundation/release/early-accent.d.ts +12 -0
- package/dist/foundation/release/early-accent.js +59 -0
- package/dist/foundation/release/index.d.ts +2 -2
- package/dist/foundation/release/index.js +2 -2
- package/dist/foundation/release/latest-release.d.ts +24 -2
- package/dist/foundation/release/latest-release.js +51 -1
- package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
- package/dist/foundation/release/progress-palette.generated.js +137 -3
- package/dist/foundation/release/release-gc.d.ts +3 -0
- package/dist/foundation/release/release-gc.js +59 -8
- package/dist/foundation/release/release-store.d.ts +12 -0
- package/dist/foundation/release/release-store.js +124 -2
- package/dist/foundation/release/update-execution-lease.d.ts +48 -0
- package/dist/foundation/release/update-execution-lease.js +161 -0
- package/dist/foundation/release/update.d.ts +12 -7
- package/dist/foundation/release/update.js +281 -196
- package/dist/foundation/resident-tabs/bounded-host-command.d.ts +18 -0
- package/dist/foundation/resident-tabs/bounded-host-command.js +39 -0
- package/dist/foundation/resident-tabs/bridge-client.d.ts +70 -0
- package/dist/foundation/resident-tabs/bridge-client.js +321 -0
- package/dist/foundation/resident-tabs/doctor.d.ts +28 -0
- package/dist/foundation/resident-tabs/doctor.js +166 -0
- package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
- package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
- package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +36 -0
- package/dist/foundation/resident-tabs/ensure-terminal-host.js +151 -0
- package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
- package/dist/foundation/resident-tabs/fault-injection.js +26 -0
- package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
- package/dist/foundation/resident-tabs/fixture-control.js +35 -0
- package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
- package/dist/foundation/resident-tabs/host-entry.js +17 -0
- package/dist/foundation/resident-tabs/index.d.ts +12 -0
- package/dist/foundation/resident-tabs/index.js +6 -0
- package/dist/foundation/resident-tabs/maintenance.d.ts +39 -0
- package/dist/foundation/resident-tabs/maintenance.js +75 -0
- package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
- package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
- package/dist/foundation/resident-tabs/progress-observation.d.ts +4 -0
- package/dist/foundation/resident-tabs/progress-observation.js +150 -0
- package/dist/foundation/resident-tabs/prompt-journal.d.ts +63 -0
- package/dist/foundation/resident-tabs/prompt-journal.js +213 -0
- package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
- package/dist/foundation/resident-tabs/protocol.js +195 -0
- package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
- package/dist/foundation/resident-tabs/recovery.js +205 -0
- package/dist/foundation/resident-tabs/release-holds.d.ts +28 -0
- package/dist/foundation/resident-tabs/release-holds.js +75 -0
- package/dist/foundation/resident-tabs/routes.d.ts +5 -0
- package/dist/foundation/resident-tabs/routes.js +5 -0
- package/dist/foundation/resident-tabs/routing.d.ts +11 -0
- package/dist/foundation/resident-tabs/routing.js +10 -0
- package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
- package/dist/foundation/resident-tabs/session-sync.js +37 -0
- package/dist/foundation/resident-tabs/settings.d.ts +12 -0
- package/dist/foundation/resident-tabs/settings.js +58 -0
- package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +14 -0
- package/dist/foundation/resident-tabs/terminal-host-artifact.js +78 -0
- package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
- package/dist/foundation/resident-tabs/zip-archive.js +56 -0
- package/dist/foundation/session-writer-lock/index.d.ts +30 -0
- package/dist/foundation/session-writer-lock/index.js +203 -0
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
- package/dist/foundation/terminal-cleanup/index.js +1 -1
- package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +6 -0
- package/dist/foundation/terminal-cleanup/terminal-reset.js +6 -0
- package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
- package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
- package/dist/integrations/pi/components/modal-frame.js +48 -9
- package/dist/integrations/pi/components/models-dialog.js +4 -52
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +6 -1
- package/dist/integrations/pi/components/owned-editor-ux.js +90 -6
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
- package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
- package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -0
- package/dist/integrations/pi/components/share-operation-dialog.js +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +58 -36
- package/dist/integrations/pi/components/shell-extension-ui.js +79 -60
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +21 -5
- package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +5 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +18 -4
- package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +12 -1
- package/dist/integrations/pi/components/skills-dialog.js +2 -2
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -6
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +16 -9
- package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +4 -4
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +31 -25
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -7
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
- package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +8 -7
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +10 -9
- package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +2 -6
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +103 -101
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +9 -9
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +13 -21
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/history/editor-core.js +7 -5
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -0
- package/dist/integrations/pi/components/upstream/theme/theme.js +29 -2
- package/dist/integrations/pi/engine/adapter.d.ts +5 -77
- package/dist/integrations/pi/engine/adapter.js +95 -394
- package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
- package/dist/integrations/pi/engine/command-dispatch.js +57 -0
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
- package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
- package/dist/integrations/pi/engine/pi-settings-metadata.json +14 -2
- package/dist/integrations/pi/engine/ports.d.ts +56 -0
- package/dist/integrations/pi/engine/ports.js +93 -0
- package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
- package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/runtime-integration.js +102 -29
- package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
- package/dist/integrations/pi/engine/session-runtime.js +13 -5
- package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
- package/dist/integrations/pi/engine/session-selection.js +45 -9
- package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
- package/dist/integrations/pi/engine/settings-bridge.js +15 -0
- package/dist/integrations/pi/engine/settings-port.js +11 -15
- package/dist/integrations/pi/engine/view-state.d.ts +42 -0
- package/dist/integrations/pi/engine/view-state.js +126 -0
- package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
- package/dist/integrations/pi/engine/workflow-runner.js +73 -4
- package/dist/integrations/pi/engine/workflow-support.d.ts +12 -0
- package/dist/integrations/pi/engine/workflow-support.js +36 -0
- package/dist/integrations/pi/engine/workflows.d.ts +3 -1
- package/dist/integrations/pi/engine/workflows.js +1 -0
- package/dist/integrations/pi/startup-public.js +257 -310
- package/dist/integrations/pi/startup-public.manifest.json +564 -440
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
- package/dist/integrations/pi/tui-runtime/adapter.js +32 -1
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +12 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +31 -2
- package/dist/native/darwin-arm64/manifest.json +10 -7
- package/dist/native/darwin-arm64/process-guardian.node +0 -0
- package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
- package/dist/native/darwin-arm64/terminal-host.manifest.json +46 -0
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +23 -0
- package/dist/native/darwin-x64/process-guardian.node +0 -0
- package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
- package/dist/native/darwin-x64/terminal-host.manifest.json +46 -0
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +10 -7
- package/dist/native/linux-x64/process-guardian.node +0 -0
- package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
- package/dist/native/linux-x64/terminal-host.manifest.json +46 -0
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +10 -7
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +46 -0
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/product-identity.d.ts +3 -3
- package/dist/product-identity.js +4 -4
- package/dist/product-identity.json +16 -2
- package/dist/runtime-payload-inventory.json +6330 -6677
- package/dist/ui/apps/host.d.ts +2 -0
- package/dist/ui/apps/host.js +7 -1
- package/dist/ui/components/dialog-panel.js +35 -30
- package/dist/ui/components/index.d.ts +2 -2
- package/dist/ui/components/index.js +1 -1
- package/dist/ui/components/line-input.d.ts +4 -1
- package/dist/ui/components/line-input.js +3 -1
- package/dist/ui/components/prompt-input.d.ts +11 -8
- package/dist/ui/components/prompt-input.js +15 -13
- package/dist/ui/components/selection-copy.d.ts +2 -0
- package/dist/ui/components/selection-copy.js +13 -0
- package/dist/ui/components/spans.js +2 -2
- package/dist/ui/components/submitted-prompt.d.ts +9 -6
- package/dist/ui/components/submitted-prompt.js +20 -12
- package/dist/ui/components/surface.js +4 -2
- package/dist/ui/components/text.d.ts +3 -6
- package/dist/ui/components/text.js +6 -8
- package/dist/ui/components/transcript-viewport.d.ts +9 -2
- package/dist/ui/components/transcript-viewport.js +176 -55
- package/dist/ui/components/value-menu.d.ts +6 -3
- package/dist/ui/components/value-menu.js +6 -5
- package/dist/ui/settings/declarations.d.ts +90 -16
- package/dist/ui/settings/declarations.js +67 -14
- package/dist/ui/settings/early-accent.d.ts +81 -0
- package/dist/ui/settings/early-accent.js +50 -0
- package/dist/ui/settings/index.d.ts +4 -2
- package/dist/ui/settings/index.js +2 -1
- package/dist/ui/settings/manager.d.ts +16 -3
- package/dist/ui/settings/manager.js +122 -33
- package/dist/ui/settings/migrations.d.ts +6 -0
- package/dist/ui/settings/migrations.js +73 -0
- package/dist/ui/settings/profile-document.d.ts +26 -0
- package/dist/ui/settings/profile-document.js +164 -0
- package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
- package/dist/ui/settings/progress-palette.generated.js +139 -0
- package/dist/ui/settings/sections.d.ts +4 -0
- package/dist/ui/settings/sections.js +9 -3
- package/docs/architecture/boundaries.md +25 -10
- package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
- package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
- package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
- package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
- package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +70 -0
- package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +32 -0
- package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +115 -0
- package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +48 -0
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +125 -0
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +56 -0
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +174 -0
- package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +18 -0
- package/docs/architecture/internal-naming.md +3 -1
- package/docs/architecture/process-guardian-provenance.md +18 -10
- package/docs/architecture/project-structure.md +8 -0
- package/docs/architecture/resident-tabs-requirements.md +18 -0
- package/docs/architecture/resident-tabs.md +648 -0
- package/docs/architecture/response-copy-delivery.md +1 -1
- package/docs/architecture/terminal-host-proof-gate.md +3 -1
- package/docs/architecture/terminal-host-provenance.md +16 -4
- package/docs/architecture/terminal-host-spike-evidence.md +1 -1
- package/docs/architecture/tool-image-presentation.md +2 -1
- package/docs/architecture/toolchain.md +11 -9
- package/docs/ci-release-runbook.md +14 -7
- package/docs/features/launch-profiles.md +11 -8
- package/docs/features/prompt-history.md +41 -20
- package/docs/manual-resident-tabs-acceptance.md +51 -0
- package/docs/openspec-archive-automation.md +49 -22
- package/docs/releases/0.2.6.md +44 -0
- package/docs/validation.md +49 -9
- package/package.json +19 -6
- package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
- package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
- package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
- package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
- package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
- package/dist/native/darwin-arm64/process-guardian +0 -0
- package/dist/native/linux-x64/process-guardian +0 -0
- package/dist/native/win32-x64/process-guardian.exe +0 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
2
4
|
import { PRODUCT_TEXT } from "../../product-identity.js";
|
|
3
5
|
import { readLaunchContext } from "../launch-context/index.js";
|
|
4
6
|
import { resolve } from "node:path";
|
|
5
7
|
import { assertLaunchProfileId, resolveCohortEndpoint, resolveProductPaths, sessionSelectionArguments } from "../lifecycle/index.js";
|
|
6
|
-
import {
|
|
8
|
+
import { AddonContainment, AddonProcessInspector, closeVerifiedContainment, LinuxNativeProcessInspector, loadProcessGuardianAddon, resolveProcessGuardianPath, verifyProcessGuardianArtifact, } from "../process-containment/index.js";
|
|
7
9
|
import { SupervisorClient } from "../protocol/index.js";
|
|
8
10
|
import { markStartupPhase } from "../startup/index.js";
|
|
11
|
+
import { exitWatcherArguments } from "./exit-watcher.js";
|
|
9
12
|
export async function runLaunchGuardian(options) {
|
|
10
13
|
assertLaunchProfileId(options.profileId);
|
|
11
14
|
const sessionArgs = sessionSelectionArguments(options.sessionSelection);
|
|
@@ -15,8 +18,11 @@ export async function runLaunchGuardian(options) {
|
|
|
15
18
|
const paths = resolveProductPaths(environment);
|
|
16
19
|
const instanceId = randomUUID();
|
|
17
20
|
const helperPath = options.helperPath ?? resolveProcessGuardianPath(options.releaseRoot, environment);
|
|
18
|
-
const inspector = options.inspector ?? platformInspector(helperPath);
|
|
19
21
|
await (options.ensureHelper ?? verifyProcessGuardianArtifact)(helperPath);
|
|
22
|
+
// Rationale: tests that inject both process boundaries need no native module; every production
|
|
23
|
+
// path loads the exact artifact only after its manifest and digest have been verified.
|
|
24
|
+
const addon = options.addon ?? (options.containment && options.inspector ? null : loadProcessGuardianAddon(helperPath));
|
|
25
|
+
const inspector = options.inspector ?? platformInspector(requireAddon(addon));
|
|
20
26
|
const guardianIdentity = await inspector.observe(process.pid);
|
|
21
27
|
if (!guardianIdentity)
|
|
22
28
|
throw diagnosticError("launch guardian cannot verify its own native process identity", "PROCESS_IDENTITY_UNAVAILABLE");
|
|
@@ -30,7 +36,8 @@ export async function runLaunchGuardian(options) {
|
|
|
30
36
|
: paths.endpoint;
|
|
31
37
|
await client.connect(endpoint);
|
|
32
38
|
await markStartupPhase(environment, "guardian-connected");
|
|
33
|
-
const
|
|
39
|
+
const exitNoticePath = resolve(paths.runtimeDir, "launch-instances", `${instanceId}.exit-notice`);
|
|
40
|
+
const containment = options.containment ?? new AddonContainment(instanceId, helperPath, exitNoticePath, requireAddon(addon));
|
|
34
41
|
const stop = stopRequests(client, instanceId);
|
|
35
42
|
let rootIdentity = null;
|
|
36
43
|
try {
|
|
@@ -43,13 +50,26 @@ export async function runLaunchGuardian(options) {
|
|
|
43
50
|
guardianIdentity,
|
|
44
51
|
});
|
|
45
52
|
let handle;
|
|
53
|
+
let encodedModes = null;
|
|
46
54
|
try {
|
|
47
|
-
|
|
55
|
+
const rootCommand = options.rootCommand ?? { executable: process.execPath, arguments: [options.uiEntry, ...sessionArgs] };
|
|
56
|
+
encodedModes = addon?.captureTerminalModes() ?? null;
|
|
57
|
+
handle = await containment.spawn(rootCommand.executable, [...rootCommand.arguments], {
|
|
48
58
|
cwd: options.cwd ?? process.cwd(),
|
|
49
59
|
environment: environmentEntries(environment),
|
|
50
60
|
...(environment.TERM ? { terminalType: environment.TERM } : {}),
|
|
51
61
|
});
|
|
52
62
|
rootIdentity = handle.identity;
|
|
63
|
+
if (addon && encodedModes !== null) {
|
|
64
|
+
await startExitWatcher(addon, {
|
|
65
|
+
addonPath: helperPath,
|
|
66
|
+
noticePath: exitNoticePath,
|
|
67
|
+
encodedModes,
|
|
68
|
+
runtimePid: handle.identity.pid,
|
|
69
|
+
processGroup: handle.processGroup ?? null,
|
|
70
|
+
foregroundGroup: handle.foregroundGroup ?? null,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
53
73
|
await requireAccepted(client, {
|
|
54
74
|
type: "activate-launch-instance",
|
|
55
75
|
requestId: randomUUID(),
|
|
@@ -88,6 +108,10 @@ export async function runLaunchGuardian(options) {
|
|
|
88
108
|
return result.outcome;
|
|
89
109
|
}),
|
|
90
110
|
]);
|
|
111
|
+
// Invariant: the root removes a clean notice. If it left the notice armed, the guardian claims,
|
|
112
|
+
// restores, and prints it before closing the native containment handle.
|
|
113
|
+
if (addon && encodedModes !== null)
|
|
114
|
+
addon.deliverExitNotice(exitNoticePath, encodedModes);
|
|
91
115
|
await containment.close();
|
|
92
116
|
if (outcome.kind !== "interrupted" || outcome.reason !== "supervisor-disconnect") {
|
|
93
117
|
await completeBestEffort(client, instanceId, outcome.kind === "interrupted" || outcome.kind === "cleanup-error" ? "interrupted" : "completed", outcome);
|
|
@@ -103,15 +127,44 @@ export async function runLaunchGuardian(options) {
|
|
|
103
127
|
client.close();
|
|
104
128
|
}
|
|
105
129
|
}
|
|
106
|
-
function
|
|
130
|
+
async function startExitWatcher(addon, options) {
|
|
131
|
+
const entry = fileURLToPath(new URL("./exit-watcher.js", import.meta.url));
|
|
132
|
+
const arguments_ = [entry, ...exitWatcherArguments({
|
|
133
|
+
guardianPid: process.pid,
|
|
134
|
+
...options,
|
|
135
|
+
})];
|
|
136
|
+
if (process.platform === "win32") {
|
|
137
|
+
addon.spawnWatcher({ executable: process.execPath, arguments: arguments_ });
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
141
|
+
const watcher = spawn(process.execPath, arguments_, {
|
|
142
|
+
stdio: "inherit",
|
|
143
|
+
detached: false,
|
|
144
|
+
windowsHide: false,
|
|
145
|
+
});
|
|
146
|
+
watcher.once("error", rejectPromise);
|
|
147
|
+
watcher.once("spawn", () => {
|
|
148
|
+
watcher.off("error", rejectPromise);
|
|
149
|
+
watcher.unref();
|
|
150
|
+
resolvePromise();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function platformInspector(addon) {
|
|
107
155
|
if (process.platform === "win32")
|
|
108
|
-
return new
|
|
156
|
+
return new AddonProcessInspector(addon, "windows-filetime:");
|
|
109
157
|
if (process.platform === "linux")
|
|
110
158
|
return new LinuxNativeProcessInspector();
|
|
111
159
|
if (process.platform === "darwin")
|
|
112
|
-
return new
|
|
160
|
+
return new AddonProcessInspector(addon, "darwin-proc-start:");
|
|
113
161
|
throw diagnosticError(`launch-instance process containment is unsupported on ${process.platform}`, "CONTAINMENT_UNSUPPORTED");
|
|
114
162
|
}
|
|
163
|
+
function requireAddon(addon) {
|
|
164
|
+
if (!addon)
|
|
165
|
+
throw diagnosticError("process guardian addon is unavailable", "CONTAINMENT_ARTIFACT_MISSING");
|
|
166
|
+
return addon;
|
|
167
|
+
}
|
|
115
168
|
function stopRequests(client, instanceId) {
|
|
116
169
|
let resolveStop;
|
|
117
170
|
let settled = false;
|
|
@@ -143,6 +143,10 @@ export async function listSessionRepositoryWorktrees(identity, options = {}) {
|
|
|
143
143
|
const contended = await mutationLockExists(options);
|
|
144
144
|
const entries = [];
|
|
145
145
|
for (const selected of worktrees) {
|
|
146
|
+
if ("stale" in selected) {
|
|
147
|
+
entries.push({ cwd: selected.root, branch: selected.branch ?? "(detached)", status: "unverifiable", agentId: null });
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
146
150
|
if (selected.branch === null) {
|
|
147
151
|
entries.push({ cwd: selected.root, branch: "(detached)", status: "unverifiable", agentId: null });
|
|
148
152
|
continue;
|
|
@@ -407,9 +411,15 @@ async function listGitWorktrees(cwd, commonDir, signal) {
|
|
|
407
411
|
if (current !== null)
|
|
408
412
|
records.push(current);
|
|
409
413
|
return await Promise.all(records.map(async (record) => {
|
|
410
|
-
const root = await realpath(record.root)
|
|
414
|
+
const root = await realpath(record.root).catch(error => { if (isMissingPathError(error))
|
|
415
|
+
return null; throw error; });
|
|
416
|
+
if (root === null)
|
|
417
|
+
return { stale: true, root: resolve(record.root), branch: record.branch };
|
|
411
418
|
const dotGit = join(root, ".git");
|
|
412
|
-
const metadata = await lstat(dotGit)
|
|
419
|
+
const metadata = await lstat(dotGit).catch(error => { if (isMissingPathError(error))
|
|
420
|
+
return null; throw error; });
|
|
421
|
+
if (metadata === null)
|
|
422
|
+
return { stale: true, root, branch: record.branch };
|
|
413
423
|
let gitDir;
|
|
414
424
|
if (metadata.isDirectory() && !metadata.isSymbolicLink())
|
|
415
425
|
gitDir = await realpath(dotGit);
|
|
@@ -424,6 +434,10 @@ async function listGitWorktrees(cwd, commonDir, signal) {
|
|
|
424
434
|
return { root, commonDir, gitDir, branch: record.branch };
|
|
425
435
|
}));
|
|
426
436
|
}
|
|
437
|
+
/** True for the errors a deleted directory or file produces, which mark a registered worktree as stale rather than broken. */
|
|
438
|
+
function isMissingPathError(error) {
|
|
439
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
440
|
+
}
|
|
427
441
|
async function executeGit(arguments_, cwd, maxBuffer, signal) {
|
|
428
442
|
const { execFile } = await import("node:child_process");
|
|
429
443
|
const execute = promisify(execFile);
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { NativeProcessIdentity, ProcessContainmentIdentity } from "../lifecycle/index.js";
|
|
2
|
+
import { type ProcessGuardianAddon } from "./addon.js";
|
|
2
3
|
import type { ContainedProcessHandle, ContainedSpawnOptions, ProcessContainment } from "./contracts.js";
|
|
3
|
-
/**
|
|
4
|
-
export declare class
|
|
4
|
+
/** Owns one native containment object in the launch guardian's Node process. */
|
|
5
|
+
export declare class AddonContainment implements ProcessContainment {
|
|
5
6
|
#private;
|
|
6
7
|
readonly instanceId: string;
|
|
7
|
-
readonly
|
|
8
|
-
readonly statusPath: string;
|
|
8
|
+
readonly addonPath: string;
|
|
9
9
|
readonly exitNoticePath: string | null;
|
|
10
|
-
|
|
10
|
+
readonly addon: ProcessGuardianAddon;
|
|
11
|
+
private readonly platform;
|
|
12
|
+
constructor(instanceId: string, addonPath: string, exitNoticePath?: string | null, addon?: ProcessGuardianAddon, platform?: NodeJS.Platform);
|
|
11
13
|
get identity(): ProcessContainmentIdentity;
|
|
12
14
|
spawn(executable: string, arguments_: readonly string[], options: ContainedSpawnOptions): Promise<ContainedProcessHandle>;
|
|
13
15
|
contains(identity: NativeProcessIdentity): Promise<boolean>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { constants } from "node:os";
|
|
2
|
+
import { mkdir, rm } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { PRODUCT_IDENTITY } from "../../product-identity.js";
|
|
5
|
+
import { loadProcessGuardianAddon } from "./addon.js";
|
|
6
|
+
/** Owns one native containment object in the launch guardian's Node process. */
|
|
7
|
+
export class AddonContainment {
|
|
8
|
+
#identity;
|
|
9
|
+
#rootIdentity = null;
|
|
10
|
+
#runtime = null;
|
|
11
|
+
#outcome = null;
|
|
12
|
+
#settled = false;
|
|
13
|
+
instanceId;
|
|
14
|
+
addonPath;
|
|
15
|
+
exitNoticePath;
|
|
16
|
+
addon;
|
|
17
|
+
platform;
|
|
18
|
+
constructor(instanceId, addonPath, exitNoticePath = null, addon = loadProcessGuardianAddon(addonPath), platform = process.platform) {
|
|
19
|
+
this.instanceId = instanceId;
|
|
20
|
+
this.addonPath = addonPath;
|
|
21
|
+
this.exitNoticePath = exitNoticePath;
|
|
22
|
+
this.addon = addon;
|
|
23
|
+
this.platform = platform;
|
|
24
|
+
this.#identity = { provider: "native-addon-pending", token: instanceId };
|
|
25
|
+
}
|
|
26
|
+
get identity() {
|
|
27
|
+
return this.#identity;
|
|
28
|
+
}
|
|
29
|
+
async spawn(executable, arguments_, options) {
|
|
30
|
+
if (this.#runtime)
|
|
31
|
+
throw new Error("process containment already has a root runtime");
|
|
32
|
+
if (this.exitNoticePath) {
|
|
33
|
+
await mkdir(dirname(this.exitNoticePath), { recursive: true, mode: 0o700 });
|
|
34
|
+
await rm(this.exitNoticePath, { force: true });
|
|
35
|
+
}
|
|
36
|
+
const runtime = this.addon.spawnContained({
|
|
37
|
+
executable,
|
|
38
|
+
arguments: [...arguments_],
|
|
39
|
+
cwd: options.cwd,
|
|
40
|
+
environment: {
|
|
41
|
+
...options.environment,
|
|
42
|
+
...(options.terminalType ? { TERM: options.terminalType } : {}),
|
|
43
|
+
...(this.exitNoticePath ? { [PRODUCT_IDENTITY.environment.exitNoticePath]: this.exitNoticePath } : {}),
|
|
44
|
+
},
|
|
45
|
+
instanceId: this.instanceId,
|
|
46
|
+
});
|
|
47
|
+
assertRuntime(runtime);
|
|
48
|
+
this.#runtime = runtime;
|
|
49
|
+
this.#rootIdentity = { pid: runtime.pid, startIdentity: runtime.startIdentity };
|
|
50
|
+
this.#identity = { provider: runtime.containmentProvider, token: runtime.containmentToken };
|
|
51
|
+
const outcome = runtime.wait().then(exitCode => outcomeFromExitCode(exitCode, this.platform), error => ({
|
|
52
|
+
kind: "guardian-error",
|
|
53
|
+
message: errorMessage(error),
|
|
54
|
+
code: errorCode(error),
|
|
55
|
+
})).finally(() => { this.#settled = true; });
|
|
56
|
+
this.#outcome = outcome;
|
|
57
|
+
return {
|
|
58
|
+
identity: this.#rootIdentity,
|
|
59
|
+
outcome,
|
|
60
|
+
...(runtime.processGroup === null ? {} : { processGroup: runtime.processGroup }),
|
|
61
|
+
...(runtime.foregroundGroup === null ? {} : { foregroundGroup: runtime.foregroundGroup }),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async contains(identity) {
|
|
65
|
+
return this.#rootIdentity !== null
|
|
66
|
+
&& identity.pid === this.#rootIdentity.pid
|
|
67
|
+
&& identity.startIdentity === this.#rootIdentity.startIdentity;
|
|
68
|
+
}
|
|
69
|
+
async stop(force) {
|
|
70
|
+
const runtime = this.#runtime;
|
|
71
|
+
if (!runtime || this.#settled)
|
|
72
|
+
return;
|
|
73
|
+
try {
|
|
74
|
+
if (force)
|
|
75
|
+
runtime.terminate(137);
|
|
76
|
+
else if (this.platform === "win32")
|
|
77
|
+
process.kill(runtime.pid, "SIGTERM");
|
|
78
|
+
else
|
|
79
|
+
runtime.stop();
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (errorCode(error) !== "ESRCH")
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async waitForEmpty(timeoutMs) {
|
|
87
|
+
if (this.#settled || !this.#outcome)
|
|
88
|
+
return true;
|
|
89
|
+
return await Promise.race([
|
|
90
|
+
this.#outcome.then(() => true),
|
|
91
|
+
new Promise(resolvePromise => {
|
|
92
|
+
const timer = setTimeout(() => resolvePromise(false), timeoutMs);
|
|
93
|
+
timer.unref();
|
|
94
|
+
}),
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
97
|
+
async close() {
|
|
98
|
+
const runtime = this.#runtime;
|
|
99
|
+
if (!runtime)
|
|
100
|
+
return;
|
|
101
|
+
runtime.close();
|
|
102
|
+
await this.waitForEmpty(1_500);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function resolveProcessGuardianPath(releaseRoot, environment = process.env, platform = process.platform, architecture = process.arch) {
|
|
106
|
+
const override = environment[PRODUCT_IDENTITY.environment.processGuardianPath]?.trim();
|
|
107
|
+
if (override)
|
|
108
|
+
return resolve(override);
|
|
109
|
+
return resolve(releaseRoot, "dist", "native", `${platform}-${architecture}`, `${PRODUCT_IDENTITY.artifacts.processGuardianAddon}.node`);
|
|
110
|
+
}
|
|
111
|
+
function assertRuntime(runtime) {
|
|
112
|
+
if (!Number.isSafeInteger(runtime.pid) || runtime.pid <= 0
|
|
113
|
+
|| typeof runtime.startIdentity !== "string" || runtime.startIdentity.length === 0
|
|
114
|
+
|| typeof runtime.containmentProvider !== "string" || runtime.containmentProvider.length === 0
|
|
115
|
+
|| typeof runtime.containmentToken !== "string" || runtime.containmentToken.length === 0
|
|
116
|
+
|| (runtime.processGroup !== null && (!Number.isSafeInteger(runtime.processGroup) || runtime.processGroup <= 0))
|
|
117
|
+
|| (runtime.foregroundGroup !== null && (!Number.isSafeInteger(runtime.foregroundGroup) || runtime.foregroundGroup <= 0))) {
|
|
118
|
+
runtime.close();
|
|
119
|
+
throw Object.assign(new Error("process guardian addon returned invalid containment identity"), { code: "CONTAINMENT_ARTIFACT_INCOMPATIBLE" });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function outcomeFromExitCode(exitCode, platform) {
|
|
123
|
+
if (!Number.isSafeInteger(exitCode) || exitCode < 0 || exitCode > 255) {
|
|
124
|
+
return { kind: "guardian-error", message: "process guardian addon returned an invalid exit code", code: "CONTAINMENT_OUTCOME_INVALID" };
|
|
125
|
+
}
|
|
126
|
+
if (platform !== "win32" && exitCode >= 128) {
|
|
127
|
+
const signalNumber = exitCode - 128;
|
|
128
|
+
const signal = Object.entries(constants.signals).find(([, value]) => value === signalNumber)?.[0];
|
|
129
|
+
if (signal)
|
|
130
|
+
return { kind: "signaled", signal };
|
|
131
|
+
}
|
|
132
|
+
return { kind: "exited", exitCode };
|
|
133
|
+
}
|
|
134
|
+
function errorCode(error) {
|
|
135
|
+
return error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : null;
|
|
136
|
+
}
|
|
137
|
+
function errorMessage(error) {
|
|
138
|
+
return error instanceof Error ? error.message : String(error);
|
|
139
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NativeProcessIdentity } from "../lifecycle/index.js";
|
|
2
|
+
import type { ProcessGuardianAddon } from "./addon.js";
|
|
3
|
+
import type { NativeProcessInspector } from "./contracts.js";
|
|
4
|
+
/** Verifies native process identity through the process-guardian addon's bounded inspection call. */
|
|
5
|
+
export declare class AddonProcessInspector implements NativeProcessInspector {
|
|
6
|
+
readonly addon: Pick<ProcessGuardianAddon, "inspectProcessStart">;
|
|
7
|
+
readonly identityPrefix: string;
|
|
8
|
+
constructor(addon: Pick<ProcessGuardianAddon, "inspectProcessStart">, identityPrefix: string);
|
|
9
|
+
observe(pid: number): Promise<NativeProcessIdentity | null>;
|
|
10
|
+
matches(identity: NativeProcessIdentity): Promise<boolean>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Verifies native process identity through the process-guardian addon's bounded inspection call. */
|
|
2
|
+
export class AddonProcessInspector {
|
|
3
|
+
addon;
|
|
4
|
+
identityPrefix;
|
|
5
|
+
constructor(addon, identityPrefix) {
|
|
6
|
+
if (!identityPrefix || identityPrefix.includes("\0"))
|
|
7
|
+
throw new TypeError("process identity prefix is invalid");
|
|
8
|
+
this.addon = addon;
|
|
9
|
+
this.identityPrefix = identityPrefix;
|
|
10
|
+
}
|
|
11
|
+
async observe(pid) {
|
|
12
|
+
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
13
|
+
throw new TypeError("inspected PID must be a positive safe integer");
|
|
14
|
+
let startIdentity;
|
|
15
|
+
try {
|
|
16
|
+
startIdentity = this.addon.inspectProcessStart(pid);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw Object.assign(new Error(`cannot inspect native process identity: ${errorMessage(error)}`), { code: "PROCESS_INSPECTION_FAILED" });
|
|
20
|
+
}
|
|
21
|
+
if (startIdentity === null)
|
|
22
|
+
return null;
|
|
23
|
+
if (typeof startIdentity !== "string" || startIdentity.length === 0 || startIdentity.length > 512
|
|
24
|
+
|| startIdentity.includes("\0") || !startIdentity.startsWith(this.identityPrefix)) {
|
|
25
|
+
throw Object.assign(new Error("process guardian returned mismatched identity data"), { code: "PROCESS_INSPECTION_INVALID" });
|
|
26
|
+
}
|
|
27
|
+
return { pid, startIdentity };
|
|
28
|
+
}
|
|
29
|
+
async matches(identity) {
|
|
30
|
+
const observed = await this.observe(identity.pid);
|
|
31
|
+
return observed !== null && observed.startIdentity === identity.startIdentity;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function errorMessage(error) {
|
|
35
|
+
return error instanceof Error ? error.message : String(error);
|
|
36
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ProcessGuardianVersion {
|
|
2
|
+
readonly crateVersion: string;
|
|
3
|
+
readonly protocolVersion: 2;
|
|
4
|
+
readonly target: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ProcessGuardianRuntime {
|
|
7
|
+
readonly pid: number;
|
|
8
|
+
readonly startIdentity: string;
|
|
9
|
+
readonly containmentProvider: string;
|
|
10
|
+
readonly containmentToken: string;
|
|
11
|
+
readonly processGroup: number | null;
|
|
12
|
+
readonly foregroundGroup: number | null;
|
|
13
|
+
wait(): Promise<number>;
|
|
14
|
+
terminate(code: number): void;
|
|
15
|
+
stop(): void;
|
|
16
|
+
close(): void;
|
|
17
|
+
}
|
|
18
|
+
export interface SpawnContainedOptions {
|
|
19
|
+
readonly executable: string;
|
|
20
|
+
readonly arguments: readonly string[];
|
|
21
|
+
readonly cwd: string;
|
|
22
|
+
readonly environment: Readonly<Record<string, string>>;
|
|
23
|
+
readonly instanceId: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ProcessGuardianAddon {
|
|
26
|
+
version(): ProcessGuardianVersion;
|
|
27
|
+
inspectProcessStart(pid: number): string | null;
|
|
28
|
+
captureTerminalModes(): string;
|
|
29
|
+
restoreTerminalModes(encoded: string): void;
|
|
30
|
+
deliverExitNotice(path: string, encodedModes: string): void;
|
|
31
|
+
spawnContained(options: SpawnContainedOptions): ProcessGuardianRuntime;
|
|
32
|
+
spawnWatcher(options: {
|
|
33
|
+
readonly executable: string;
|
|
34
|
+
readonly arguments: readonly string[];
|
|
35
|
+
}): number;
|
|
36
|
+
waitForProcessExit(pid: number): Promise<void>;
|
|
37
|
+
stopProcessGroup(processGroup: number): void;
|
|
38
|
+
restoreForegroundGroup(processGroup: number): void;
|
|
39
|
+
ignoreConsoleControl(): void;
|
|
40
|
+
}
|
|
41
|
+
/** Loads one verified Node-API guardian instance per exact addon path. */
|
|
42
|
+
export declare function loadProcessGuardianAddon(path: string): ProcessGuardianAddon;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
const cache = new Map();
|
|
5
|
+
/** Loads one verified Node-API guardian instance per exact addon path. */
|
|
6
|
+
export function loadProcessGuardianAddon(path) {
|
|
7
|
+
if (!path || path.includes("\0"))
|
|
8
|
+
throw new TypeError("process guardian addon path is invalid");
|
|
9
|
+
const exactPath = resolve(path);
|
|
10
|
+
const cached = cache.get(exactPath);
|
|
11
|
+
if (cached)
|
|
12
|
+
return cached;
|
|
13
|
+
let value;
|
|
14
|
+
try {
|
|
15
|
+
value = require(exactPath);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
const code = errorCode(error) === "MODULE_NOT_FOUND" || errorCode(error) === "ENOENT"
|
|
19
|
+
? "CONTAINMENT_ARTIFACT_MISSING"
|
|
20
|
+
: "CONTAINMENT_ARTIFACT_INCOMPATIBLE";
|
|
21
|
+
throw diagnosticError(`process guardian addon could not be loaded: ${errorMessage(error)}`, code);
|
|
22
|
+
}
|
|
23
|
+
if (!isProcessGuardianAddon(value)) {
|
|
24
|
+
throw diagnosticError("process guardian addon exports are incompatible", "CONTAINMENT_ARTIFACT_INCOMPATIBLE");
|
|
25
|
+
}
|
|
26
|
+
let report;
|
|
27
|
+
try {
|
|
28
|
+
report = value.version();
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw diagnosticError(`process guardian addon identity failed: ${errorMessage(error)}`, "CONTAINMENT_ARTIFACT_INCOMPATIBLE");
|
|
32
|
+
}
|
|
33
|
+
if (report.protocolVersion !== 2 || typeof report.crateVersion !== "string" || report.crateVersion.length === 0 || typeof report.target !== "string") {
|
|
34
|
+
throw diagnosticError("process guardian addon protocol is incompatible", "CONTAINMENT_ARTIFACT_INCOMPATIBLE");
|
|
35
|
+
}
|
|
36
|
+
cache.set(exactPath, value);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
function isProcessGuardianAddon(value) {
|
|
40
|
+
if (typeof value !== "object" || value === null)
|
|
41
|
+
return false;
|
|
42
|
+
const candidate = value;
|
|
43
|
+
return [
|
|
44
|
+
"version", "inspectProcessStart", "captureTerminalModes", "restoreTerminalModes",
|
|
45
|
+
"deliverExitNotice", "spawnContained", "spawnWatcher", "waitForProcessExit",
|
|
46
|
+
"stopProcessGroup", "restoreForegroundGroup", "ignoreConsoleControl",
|
|
47
|
+
].every(name => typeof candidate[name] === "function");
|
|
48
|
+
}
|
|
49
|
+
function diagnosticError(message, code) {
|
|
50
|
+
return Object.assign(new Error(message), { code });
|
|
51
|
+
}
|
|
52
|
+
function errorCode(error) {
|
|
53
|
+
return error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : null;
|
|
54
|
+
}
|
|
55
|
+
function errorMessage(error) {
|
|
56
|
+
return error instanceof Error ? error.message : String(error);
|
|
57
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function verifyProcessGuardianArtifact(
|
|
1
|
+
export declare function verifyProcessGuardianArtifact(addonPath: string, platform?: NodeJS.Platform, architecture?: string): Promise<void>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFile, stat } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, resolve } from "node:path";
|
|
4
|
-
export async function verifyProcessGuardianArtifact(
|
|
5
|
-
const manifestPath = resolve(dirname(
|
|
4
|
+
export async function verifyProcessGuardianArtifact(addonPath, platform = process.platform, architecture = process.arch) {
|
|
5
|
+
const manifestPath = resolve(dirname(addonPath), "manifest.json");
|
|
6
6
|
let manifest;
|
|
7
7
|
try {
|
|
8
8
|
manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
@@ -10,15 +10,16 @@ export async function verifyProcessGuardianArtifact(helperPath, platform = proce
|
|
|
10
10
|
catch (error) {
|
|
11
11
|
throw artifactError(`process guardian manifest is missing or malformed: ${errorMessage(error)}`, "CONTAINMENT_ARTIFACT_MISSING");
|
|
12
12
|
}
|
|
13
|
-
if (manifest.schema !== "a1-process-guardian-artifact-
|
|
13
|
+
if (manifest.schema !== "a1-process-guardian-artifact-v2" || manifest.kind !== "node-addon"
|
|
14
|
+
|| manifest.nodeApi !== 9 || manifest.protocolVersion !== 2
|
|
14
15
|
|| manifest.platform !== platform || manifest.architecture !== architecture
|
|
15
|
-
|| manifest.artifact?.filename !== basename(
|
|
16
|
+
|| manifest.artifact?.filename !== basename(addonPath)) {
|
|
16
17
|
throw artifactError("process guardian manifest is incompatible with this platform or protocol", "CONTAINMENT_ARTIFACT_INCOMPATIBLE");
|
|
17
18
|
}
|
|
18
19
|
if (manifest.capability !== "supported") {
|
|
19
20
|
throw artifactError(`process containment is not certified for ${platform}-${architecture}`, "CONTAINMENT_UNSUPPORTED");
|
|
20
21
|
}
|
|
21
|
-
const [bytes, metadata] = await Promise.all([readFile(
|
|
22
|
+
const [bytes, metadata] = await Promise.all([readFile(addonPath), stat(addonPath)]).catch(error => {
|
|
22
23
|
throw artifactError(`process guardian artifact is unavailable: ${errorMessage(error)}`, "CONTAINMENT_ARTIFACT_MISSING");
|
|
23
24
|
});
|
|
24
25
|
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
@@ -7,6 +7,8 @@ export interface ContainedSpawnOptions {
|
|
|
7
7
|
export interface ContainedProcessHandle {
|
|
8
8
|
readonly identity: NativeProcessIdentity;
|
|
9
9
|
readonly outcome: Promise<LaunchInstanceOutcome>;
|
|
10
|
+
readonly processGroup?: number;
|
|
11
|
+
readonly foregroundGroup?: number;
|
|
10
12
|
}
|
|
11
13
|
export interface NativeProcessInspector {
|
|
12
14
|
observe(pid: number): Promise<NativeProcessIdentity | null>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
export { loadProcessGuardianAddon } from "./addon.js";
|
|
2
|
+
export type { ProcessGuardianAddon, ProcessGuardianRuntime, ProcessGuardianVersion } from "./addon.js";
|
|
3
|
+
export { AddonContainment, resolveProcessGuardianPath } from "./addon-containment.js";
|
|
4
|
+
export { AddonProcessInspector } from "./addon-process-inspector.js";
|
|
1
5
|
export { verifyProcessGuardianArtifact } from "./artifact.js";
|
|
2
6
|
export { closeVerifiedContainment } from "./contracts.js";
|
|
3
7
|
export type { ContainedProcessHandle, ContainedSpawnOptions, ContainmentCloseResult, NativeProcessInspector, ProcessContainment, ProcessContainmentFactory, } from "./contracts.js";
|
|
4
|
-
export { DarwinNativeProcessInspector } from "./darwin-process-inspector.js";
|
|
5
8
|
export { LinuxNativeProcessInspector } from "./linux-process-inspector.js";
|
|
6
|
-
export { NativeGuardianContainment, resolveProcessGuardianPath } from "./native-guardian-containment.js";
|
|
7
9
|
export { createNativeProcessInspector } from "./native-process-inspector.js";
|
|
8
|
-
export { WindowsNativeProcessInspector } from "./windows-process-inspector.js";
|
|
9
|
-
export type { InspectorCommandResult, InspectorCommandRunner } from "./windows-process-inspector.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export { loadProcessGuardianAddon } from "./addon.js";
|
|
2
|
+
export { AddonContainment, resolveProcessGuardianPath } from "./addon-containment.js";
|
|
3
|
+
export { AddonProcessInspector } from "./addon-process-inspector.js";
|
|
1
4
|
export { verifyProcessGuardianArtifact } from "./artifact.js";
|
|
2
5
|
export { closeVerifiedContainment } from "./contracts.js";
|
|
3
|
-
export { DarwinNativeProcessInspector } from "./darwin-process-inspector.js";
|
|
4
6
|
export { LinuxNativeProcessInspector } from "./linux-process-inspector.js";
|
|
5
|
-
export { NativeGuardianContainment, resolveProcessGuardianPath } from "./native-guardian-containment.js";
|
|
6
7
|
export { createNativeProcessInspector } from "./native-process-inspector.js";
|
|
7
|
-
export { WindowsNativeProcessInspector } from "./windows-process-inspector.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProcessGuardianAddon } from "./addon.js";
|
|
1
2
|
import type { NativeProcessInspector } from "./contracts.js";
|
|
2
3
|
/** Resolve only the platform's exact-process inspector used by cooperative session ownership. */
|
|
3
|
-
export declare function createNativeProcessInspector(environment?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, releaseRoot?: string): Promise<NativeProcessInspector>;
|
|
4
|
+
export declare function createNativeProcessInspector(environment?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, releaseRoot?: string, loadAddon?: (path: string) => ProcessGuardianAddon): Promise<NativeProcessInspector>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PRODUCT_IDENTITY } from "../../product-identity.js";
|
|
2
2
|
/** Resolve only the platform's exact-process inspector used by cooperative session ownership. */
|
|
3
|
-
export async function createNativeProcessInspector(environment = process.env, platform = process.platform, releaseRoot) {
|
|
3
|
+
export async function createNativeProcessInspector(environment = process.env, platform = process.platform, releaseRoot, loadAddon) {
|
|
4
4
|
if (platform === "linux") {
|
|
5
5
|
const { LinuxNativeProcessInspector } = await import("./linux-process-inspector.js");
|
|
6
6
|
return new LinuxNativeProcessInspector();
|
|
@@ -8,14 +8,14 @@ export async function createNativeProcessInspector(environment = process.env, pl
|
|
|
8
8
|
if (platform !== "win32" && platform !== "darwin")
|
|
9
9
|
throw new Error(`native process identity is unsupported on ${platform}`);
|
|
10
10
|
if (releaseRoot === undefined && !environment[PRODUCT_IDENTITY.environment.processGuardianPath]) {
|
|
11
|
-
throw new Error("native process identity
|
|
11
|
+
throw new Error("native process identity addon is unavailable");
|
|
12
12
|
}
|
|
13
|
-
const { resolveProcessGuardianPath } = await
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
return new
|
|
13
|
+
const [{ resolveProcessGuardianPath }, { loadProcessGuardianAddon }, { AddonProcessInspector }] = await Promise.all([
|
|
14
|
+
import("./addon-containment.js"),
|
|
15
|
+
import("./addon.js"),
|
|
16
|
+
import("./addon-process-inspector.js"),
|
|
17
|
+
]);
|
|
18
|
+
const addonPath = resolveProcessGuardianPath(releaseRoot ?? process.cwd(), environment, platform);
|
|
19
|
+
const addon = (loadAddon ?? loadProcessGuardianAddon)(addonPath);
|
|
20
|
+
return new AddonProcessInspector(addon, platform === "win32" ? "windows-filetime:" : "darwin-proc-start:");
|
|
21
21
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type AvailableRelease, type ReleaseChannel } from "./latest-release.js";
|
|
2
|
+
export declare const AUTOMATIC_UPDATE_STATE_SCHEMA = 1;
|
|
3
|
+
export declare const AUTOMATIC_UPDATE_RETRY_MS: number;
|
|
4
|
+
export interface AutomaticUpdateState {
|
|
5
|
+
readonly schema: typeof AUTOMATIC_UPDATE_STATE_SCHEMA;
|
|
6
|
+
readonly channel: ReleaseChannel;
|
|
7
|
+
readonly targetVersion: string;
|
|
8
|
+
readonly status: "running" | "installed" | "failed";
|
|
9
|
+
readonly attemptedAt: number;
|
|
10
|
+
readonly updatedAt: number;
|
|
11
|
+
readonly installedVersion: string | null;
|
|
12
|
+
readonly failure: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare class AutomaticUpdateStateStore {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
constructor(dataDir: string);
|
|
17
|
+
read(): Promise<AutomaticUpdateState | null>;
|
|
18
|
+
write(value: AutomaticUpdateState): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface AutomaticUpdateRequestOptions {
|
|
21
|
+
readonly release: AvailableRelease;
|
|
22
|
+
readonly runningVersion: string;
|
|
23
|
+
readonly environment?: NodeJS.ProcessEnv;
|
|
24
|
+
readonly signal?: AbortSignal;
|
|
25
|
+
readonly now?: () => number;
|
|
26
|
+
readonly spawnWorker?: (entry: string, arguments_: readonly string[], environment: NodeJS.ProcessEnv) => Promise<void>;
|
|
27
|
+
readonly sleep?: (durationMs: number) => Promise<void>;
|
|
28
|
+
/** Focused-test seams; production resolves both from the certified launch cohort. */
|
|
29
|
+
readonly worker?: {
|
|
30
|
+
readonly entry: string;
|
|
31
|
+
readonly packageRoot: string;
|
|
32
|
+
};
|
|
33
|
+
readonly activeVersion?: () => Promise<string | null>;
|
|
34
|
+
}
|
|
35
|
+
/** Start or observe one silent update and resolve with the active newer version once restart is useful. */
|
|
36
|
+
export declare function requestAutomaticUpdate(options: AutomaticUpdateRequestOptions): Promise<string | null>;
|
|
37
|
+
export declare function runAutomaticUpdateWorker(argv: readonly string[], environment?: NodeJS.ProcessEnv): Promise<number>;
|