@timurproko/a1 0.2.6 → 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/settings-app.d.ts +12 -2
- package/dist/features/owned-ui/settings-app.js +116 -81
- 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 +1 -1
- 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/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 +24 -9
- 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/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 +2 -0
- package/docs/architecture/terminal-host-provenance.md +16 -4
- 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/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
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { createPiShellArmin, createPiShellEarendilAnnouncement, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
|
|
2
|
+
import { createPiShellChangelog, createPiShellHotkeys, createPiShellSessionInfo, renderPiShellCommandMessage, renderPiShellStatusText, } from "../../integrations/pi/components/shell-presenters-info.js";
|
|
3
|
+
import { piShellHyperlink } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
4
|
+
/**
|
|
5
|
+
* Presents workflow results: bare A1 answers in the dock notice, the pinned profile appends
|
|
6
|
+
* transcript-anchored output, and consecutive status lines at the same anchor replace each other.
|
|
7
|
+
*/
|
|
8
|
+
export class WorkflowOutput {
|
|
9
|
+
#ports;
|
|
10
|
+
#sequence = 0;
|
|
11
|
+
#statusMessages = new Map();
|
|
12
|
+
#lastStatusId;
|
|
13
|
+
constructor(ports) {
|
|
14
|
+
this.#ports = ports;
|
|
15
|
+
}
|
|
16
|
+
appendStatus(message) {
|
|
17
|
+
// Rationale: bare A1 acknowledges commands in one dock notice above the editor, where the
|
|
18
|
+
// reader's eye already is, instead of a transcript row that opens an empty session at the
|
|
19
|
+
// top-left or sinks into a long feed. The pinned route keeps Pi's chat placement.
|
|
20
|
+
if (this.#ports.customViewport) {
|
|
21
|
+
this.#ports.dock.setNotice({ kind: "status", message });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const { document } = this.#ports;
|
|
25
|
+
const previousId = this.#lastStatusId;
|
|
26
|
+
if (previousId !== undefined
|
|
27
|
+
&& document.lastId === previousId
|
|
28
|
+
&& document.anchorOf(previousId) === this.#ports.transcriptLength()) {
|
|
29
|
+
this.#statusMessages.set(previousId, message);
|
|
30
|
+
document.invalidate("workflow-status");
|
|
31
|
+
this.#ports.invalidate();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const id = this.#appendAnchored(width => [
|
|
35
|
+
"",
|
|
36
|
+
...renderPiShellStatusText(this.#statusMessages.get(id) ?? message, width),
|
|
37
|
+
]);
|
|
38
|
+
this.#statusMessages.set(id, message);
|
|
39
|
+
this.#lastStatusId = id;
|
|
40
|
+
}
|
|
41
|
+
appendMessage(message, errorCode) {
|
|
42
|
+
if (message.kind === "status") {
|
|
43
|
+
this.appendStatus(message.message);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (this.#ports.customViewport && (message.kind === "warning" || message.kind === "error")) {
|
|
47
|
+
this.#ports.dock.setNotice({
|
|
48
|
+
kind: errorCode === "image-count" ? "warning" : message.kind,
|
|
49
|
+
message: message.message,
|
|
50
|
+
...(errorCode === undefined ? {} : { errorCode }),
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.#lastStatusId = undefined;
|
|
55
|
+
const presentation = { kind: message.kind, message: message.message };
|
|
56
|
+
this.#appendAnchored(width => renderPiShellCommandMessage(presentation, width, this.#ports.outputPad()));
|
|
57
|
+
}
|
|
58
|
+
appendResult(result, errorCode) {
|
|
59
|
+
if (result.messages !== undefined) {
|
|
60
|
+
for (const message of result.messages)
|
|
61
|
+
this.appendMessage(message, errorCode);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (result.messageKind === "silent" || (result.outcome === "cancelled" && result.messageKind === undefined))
|
|
65
|
+
return;
|
|
66
|
+
if (result.command === "reload" && result.outcome === "completed") {
|
|
67
|
+
this.appendStatus(result.message);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (result.outcome === "completed" && this.#appendPresentation(result))
|
|
71
|
+
return;
|
|
72
|
+
if (result.outcome === "failed") {
|
|
73
|
+
this.appendMessage({
|
|
74
|
+
kind: result.messageKind === "warning" ? "warning" : "error",
|
|
75
|
+
message: result.message,
|
|
76
|
+
}, errorCode);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (result.outcome === "completed" && (result.command === "quit" || result.command === "compact"))
|
|
80
|
+
return;
|
|
81
|
+
if (result.outcome === "completed" && result.command === "new" && this.#ports.customViewport) {
|
|
82
|
+
// Rationale: bare A1 keeps the replacement session visually empty while preserving Pi's accent notice shape.
|
|
83
|
+
this.#ports.dock.setNotice({ kind: "new-session", message: result.message });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (result.outcome === "completed" && (result.command === "new" || result.command === "name" || result.command === "debug")) {
|
|
87
|
+
this.#lastStatusId = undefined;
|
|
88
|
+
const presentation = { kind: result.command, message: result.message, ...(result.detail === undefined ? {} : { detail: result.detail }) };
|
|
89
|
+
this.#appendAnchored(width => renderPiShellCommandMessage(presentation, width, this.#ports.outputPad()));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (result.outcome === "completed" && this.#appendAnnouncement(result.command))
|
|
93
|
+
return;
|
|
94
|
+
// Rationale: the pinned engine links both share URLs; the workflow result carries the plain URLs.
|
|
95
|
+
const message = result.command !== "share" ? result.message
|
|
96
|
+
: result.detail ? `${linkShareUrl(result.message)}\nGist: ${piShellHyperlink(result.detail)}`
|
|
97
|
+
// Protocol: Radius shares carry only the artifact URL.
|
|
98
|
+
: linkShareUrl(result.message);
|
|
99
|
+
this.appendStatus(message);
|
|
100
|
+
}
|
|
101
|
+
/** Drops every anchored output and the status-replacement chain. */
|
|
102
|
+
reset() {
|
|
103
|
+
this.#ports.document.removeAnchored();
|
|
104
|
+
this.#statusMessages.clear();
|
|
105
|
+
this.#lastStatusId = undefined;
|
|
106
|
+
}
|
|
107
|
+
// Invariant: session info, hotkeys, and changelog draw their own components; false for any other completed command.
|
|
108
|
+
#appendPresentation(result) {
|
|
109
|
+
if (result.command === "session" && result.presentation?.kind === "session-info") {
|
|
110
|
+
this.#lastStatusId = undefined;
|
|
111
|
+
const sessionInfo = createPiShellSessionInfo(result.presentation);
|
|
112
|
+
this.#appendAnchored(width => sessionInfo.render(width), () => sessionInfo.dispose?.());
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
if (result.command === "hotkeys") {
|
|
116
|
+
this.#lastStatusId = undefined;
|
|
117
|
+
const presentation = this.#ports.hotkeysPresentation();
|
|
118
|
+
const hotkeys = createPiShellHotkeys(presentation.bindings, presentation.getShortcuts, presentation.profile, presentation.residentTabs);
|
|
119
|
+
this.#appendAnchored(width => hotkeys.render(width), () => hotkeys.dispose?.());
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (result.command === "changelog") {
|
|
123
|
+
this.#lastStatusId = undefined;
|
|
124
|
+
const changelog = createPiShellChangelog(result.detail ?? "No changelog entries found.");
|
|
125
|
+
this.#appendAnchored(width => changelog.render(width), () => changelog.dispose?.());
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
// Invariant: the two easter-egg announcements; false for any other command.
|
|
131
|
+
#appendAnnouncement(command) {
|
|
132
|
+
if (command === "arminsayshi") {
|
|
133
|
+
this.#lastStatusId = undefined;
|
|
134
|
+
const armin = createPiShellArmin(this.#ports.componentRuntime);
|
|
135
|
+
this.#appendAnchored(width => ["", ...armin.render(width)], () => armin.dispose?.());
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
if (command === "dementedelves") {
|
|
139
|
+
this.#lastStatusId = undefined;
|
|
140
|
+
const announcement = createPiShellEarendilAnnouncement();
|
|
141
|
+
this.#appendAnchored(width => ["", ...announcement.render(width)], () => announcement.dispose?.());
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
#appendAnchored(render, dispose) {
|
|
147
|
+
// Invariant: transcript-bound workflow output supersedes a pending acknowledgement.
|
|
148
|
+
this.#ports.dock.dismissNotice();
|
|
149
|
+
this.#sequence += 1;
|
|
150
|
+
const id = `workflow-status-${this.#sequence}`;
|
|
151
|
+
const component = {
|
|
152
|
+
id,
|
|
153
|
+
revision: 1,
|
|
154
|
+
render,
|
|
155
|
+
handleInput() { },
|
|
156
|
+
invalidate() { },
|
|
157
|
+
update() { },
|
|
158
|
+
setExpanded() { },
|
|
159
|
+
setOutputPad() { },
|
|
160
|
+
setHideThinkingBlock() { },
|
|
161
|
+
setMermaidRenderingMode() { },
|
|
162
|
+
setImagePresentation() { },
|
|
163
|
+
...(dispose === undefined ? {} : { dispose }),
|
|
164
|
+
};
|
|
165
|
+
this.#ports.document.appendAnchored(id, component, this.#ports.transcriptLength());
|
|
166
|
+
this.#ports.invalidate();
|
|
167
|
+
return id;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** "Share URL: <url>" with the URL made clickable; other share wordings pass through unchanged. */
|
|
171
|
+
function linkShareUrl(message) {
|
|
172
|
+
const match = /^Share URL: (\S+)$/.exec(message);
|
|
173
|
+
return match === null ? message : `Share URL: ${piShellHyperlink(match[1])}`;
|
|
174
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OwnedUiCommandResult, OwnedUiWorkflowRequest } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
/** The owned selectors a workflow can open in place of asking the engine to choose. */
|
|
3
|
+
export interface WorkflowSelectors {
|
|
4
|
+
showScopedModelsSelector(): void;
|
|
5
|
+
showModelsDialog(initialQuery?: string): void;
|
|
6
|
+
showModelSelector(initialSearchInput?: string): void;
|
|
7
|
+
showForkSelector(): void;
|
|
8
|
+
showThinkingSelector(): Promise<void>;
|
|
9
|
+
showTrustSelector(): void;
|
|
10
|
+
showSettingsSelector(): void;
|
|
11
|
+
showSessionSelector(): Promise<void>;
|
|
12
|
+
showLoginAuthTypeSelector(): void;
|
|
13
|
+
showLoginMethodSelector(providerReference: string): void;
|
|
14
|
+
showLogoutSelector(): Promise<void>;
|
|
15
|
+
showTreeSelector(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Opens the owned selector a workflow request asks for when the user has not chosen yet. Returns
|
|
19
|
+
* the command result when a selector handled the request, settling once an asynchronous selector
|
|
20
|
+
* has opened, or undefined when the request goes to the engine. The decision itself is synchronous,
|
|
21
|
+
* so a request that goes to the engine reaches it in the same turn.
|
|
22
|
+
*/
|
|
23
|
+
export declare function openWorkflowSelector(request: OwnedUiWorkflowRequest, selectors: WorkflowSelectors, options: {
|
|
24
|
+
readonly residentTab: boolean;
|
|
25
|
+
}): OwnedUiCommandResult | Promise<OwnedUiCommandResult> | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const unchosen = (request) => request.selection === undefined && request.confirmed === undefined;
|
|
2
|
+
const unchosenBare = (request) => unchosen(request) && request.argument.trim().length === 0;
|
|
3
|
+
// Invariant: the routes are checked in this order, matching the order the workflows were introduced.
|
|
4
|
+
const SELECTOR_ROUTES = [
|
|
5
|
+
{ command: "scoped-models", pending: unchosen, open: selectors => selectors.showScopedModelsSelector() },
|
|
6
|
+
{ command: "models", pending: request => request.selection === undefined, open: (selectors, request) => selectors.showModelsDialog(request.argument.trim() || undefined) },
|
|
7
|
+
{ command: "model", pending: unchosenBare, open: selectors => selectors.showModelSelector() },
|
|
8
|
+
{ command: "fork", pending: unchosen, open: selectors => selectors.showForkSelector() },
|
|
9
|
+
{ command: "thinking", pending: request => request.selection === undefined && request.argument.trim().length === 0, open: selectors => selectors.showThinkingSelector() },
|
|
10
|
+
{ command: "trust", pending: unchosen, open: selectors => selectors.showTrustSelector() },
|
|
11
|
+
{ command: "settings", pending: unchosen, open: selectors => selectors.showSettingsSelector() },
|
|
12
|
+
{ command: "resume", pending: unchosenBare, open: selectors => selectors.showSessionSelector() },
|
|
13
|
+
{
|
|
14
|
+
command: "login",
|
|
15
|
+
pending: unchosen,
|
|
16
|
+
open: (selectors, request) => request.argument.trim().length === 0
|
|
17
|
+
? selectors.showLoginAuthTypeSelector()
|
|
18
|
+
: selectors.showLoginMethodSelector(request.argument),
|
|
19
|
+
},
|
|
20
|
+
{ command: "logout", pending: unchosen, open: selectors => selectors.showLogoutSelector() },
|
|
21
|
+
{ command: "tree", pending: unchosenBare, open: selectors => selectors.showTreeSelector() },
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Opens the owned selector a workflow request asks for when the user has not chosen yet. Returns
|
|
25
|
+
* the command result when a selector handled the request, settling once an asynchronous selector
|
|
26
|
+
* has opened, or undefined when the request goes to the engine. The decision itself is synchronous,
|
|
27
|
+
* so a request that goes to the engine reaches it in the same turn.
|
|
28
|
+
*/
|
|
29
|
+
export function openWorkflowSelector(request, selectors, options) {
|
|
30
|
+
const route = SELECTOR_ROUTES.find(candidate => candidate.command === request.command && candidate.pending(request));
|
|
31
|
+
if (route === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
if (route.command === "settings" && options.residentTab) {
|
|
34
|
+
return { outcome: "rejected", diagnostic: "Settings is available from the global Settings tab." };
|
|
35
|
+
}
|
|
36
|
+
const completed = { outcome: "completed", diagnostic: null };
|
|
37
|
+
const opened = route.open(selectors, request);
|
|
38
|
+
return opened instanceof Promise ? opened.then(() => completed) : completed;
|
|
39
|
+
}
|
package/dist/cli/dispatch.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type InteractiveLaunchIntent, type LaunchProfileId, type SessionSelection } from "../features/launch/index.js";
|
|
1
|
+
import { type InteractiveLaunchIntent, type InteractiveLaunchMode, type LaunchProfileId, type SessionSelection } from "../features/launch/index.js";
|
|
2
2
|
import type { CliCapabilities } from "./capabilities.js";
|
|
3
3
|
import type { PackageCommandRequest } from "./packages.js";
|
|
4
4
|
import type { SessionContextRequest } from "./session-context.js";
|
|
5
|
+
import type { TabsRequest } from "./tabs-request.js";
|
|
5
6
|
import { type PackageCliVerb, type PackageCommandNamespace, type PackageSyntaxDiagnostic } from "./package-messages.js";
|
|
6
7
|
export type UpdateChannel = "stable" | "next";
|
|
7
8
|
export interface CliHandlers {
|
|
@@ -10,6 +11,7 @@ export interface CliHandlers {
|
|
|
10
11
|
readonly update: (channel: UpdateChannel, target?: string) => Promise<number>;
|
|
11
12
|
readonly packages: (request: PackageCommandRequest) => Promise<number>;
|
|
12
13
|
readonly sessionContext: (request: SessionContextRequest) => Promise<number>;
|
|
14
|
+
readonly tabs: (request: TabsRequest) => Promise<number>;
|
|
13
15
|
}
|
|
14
16
|
export interface CliOutput {
|
|
15
17
|
readonly stdout: (message: string) => void;
|
|
@@ -17,6 +19,8 @@ export interface CliOutput {
|
|
|
17
19
|
}
|
|
18
20
|
export declare function cliUsage(capabilities: CliCapabilities): string;
|
|
19
21
|
export declare function cliHelp(capabilities: CliCapabilities): string;
|
|
22
|
+
/** Focused help for the resident-tab maintenance forms; printing it contacts no host. */
|
|
23
|
+
export declare function tabsHelp(): string;
|
|
20
24
|
export declare function dispatchCli(arguments_: readonly string[], handlers: CliHandlers, output: CliOutput, capabilities: CliCapabilities): Promise<number>;
|
|
21
25
|
export type CliCommand = {
|
|
22
26
|
readonly kind: "noop";
|
|
@@ -33,6 +37,7 @@ export type CliCommand = {
|
|
|
33
37
|
} | {
|
|
34
38
|
readonly kind: "launch";
|
|
35
39
|
readonly profileId: LaunchProfileId;
|
|
40
|
+
readonly launchMode: InteractiveLaunchMode;
|
|
36
41
|
readonly sessionSelection?: SessionSelection;
|
|
37
42
|
} | {
|
|
38
43
|
readonly kind: "version";
|
|
@@ -46,6 +51,11 @@ export type CliCommand = {
|
|
|
46
51
|
} | {
|
|
47
52
|
readonly kind: "session-context";
|
|
48
53
|
readonly request: SessionContextRequest;
|
|
54
|
+
} | {
|
|
55
|
+
readonly kind: "tabs";
|
|
56
|
+
readonly request: TabsRequest;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: "tabs-help";
|
|
49
59
|
} | {
|
|
50
60
|
readonly kind: "error";
|
|
51
61
|
readonly message: string;
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -6,6 +6,7 @@ export function cliUsage(capabilities) {
|
|
|
6
6
|
"",
|
|
7
7
|
"--session <path|id>",
|
|
8
8
|
"--session-dir <dir> --session <path|id>",
|
|
9
|
+
"solo",
|
|
9
10
|
...(capabilities.developmentComparison ? ["pi"] : []),
|
|
10
11
|
"help",
|
|
11
12
|
"version",
|
|
@@ -21,6 +22,10 @@ export function cliUsage(capabilities) {
|
|
|
21
22
|
"session worktrees",
|
|
22
23
|
"session link-worktree <path>",
|
|
23
24
|
"session unlink-worktree",
|
|
25
|
+
"tabs",
|
|
26
|
+
"tabs stop <id>|--all",
|
|
27
|
+
"tabs host status|stop",
|
|
28
|
+
"tabs doctor",
|
|
24
29
|
]);
|
|
25
30
|
}
|
|
26
31
|
export function cliHelp(capabilities) {
|
|
@@ -30,6 +35,7 @@ export function cliHelp(capabilities) {
|
|
|
30
35
|
` ${command}`,
|
|
31
36
|
` ${command} --session <path|id>`,
|
|
32
37
|
` ${command} --session-dir <dir> --session <path|id>`,
|
|
38
|
+
` ${command} solo`,
|
|
33
39
|
...(capabilities.developmentComparison ? [` ${command} pi`] : []),
|
|
34
40
|
` ${command} help`,
|
|
35
41
|
` ${command} version`,
|
|
@@ -52,9 +58,32 @@ export function cliHelp(capabilities) {
|
|
|
52
58
|
` ${command} session link-worktree <path>`,
|
|
53
59
|
` ${command} session unlink-worktree`,
|
|
54
60
|
"",
|
|
61
|
+
"Tabs:",
|
|
62
|
+
` ${command} tabs`,
|
|
63
|
+
` ${command} tabs stop <id>|--all`,
|
|
64
|
+
` ${command} tabs host status|stop`,
|
|
65
|
+
` ${command} tabs doctor`,
|
|
66
|
+
"",
|
|
67
|
+
].join("\n");
|
|
68
|
+
}
|
|
69
|
+
/** Focused help for the resident-tab maintenance forms; printing it contacts no host. */
|
|
70
|
+
export function tabsHelp() {
|
|
71
|
+
const command = PRODUCT_TEXT.commandName;
|
|
72
|
+
return [
|
|
73
|
+
"Resident tabs:",
|
|
74
|
+
` ${command} tabs List running tabs`,
|
|
75
|
+
` ${command} tabs stop <id> Stop one tab; its session stays resumable`,
|
|
76
|
+
` ${command} tabs stop --all Stop every tab and keep the host`,
|
|
77
|
+
` ${command} tabs host status Show host identity, limits, and health counters`,
|
|
78
|
+
` ${command} tabs host stop Stop every tab and the host`,
|
|
79
|
+
` ${command} tabs doctor Write a redacted diagnostic bundle`,
|
|
80
|
+
"",
|
|
81
|
+
"Options:",
|
|
82
|
+
" --json Print the versioned machine-readable report",
|
|
83
|
+
"",
|
|
55
84
|
].join("\n");
|
|
56
85
|
}
|
|
57
|
-
const PROFILE_WORDS = new Set(["pi"]);
|
|
86
|
+
const PROFILE_WORDS = new Set(["pi", "solo"]);
|
|
58
87
|
export async function dispatchCli(arguments_, handlers, output, capabilities) {
|
|
59
88
|
const command = parseCliCommand(arguments_, capabilities);
|
|
60
89
|
if (command.kind === "noop")
|
|
@@ -76,23 +105,29 @@ export async function dispatchCli(arguments_, handlers, output, capabilities) {
|
|
|
76
105
|
return 2;
|
|
77
106
|
}
|
|
78
107
|
if (command.kind === "launch")
|
|
79
|
-
return await handlers.launch(interactiveLaunchIntent(command.profileId, command.sessionSelection));
|
|
108
|
+
return await handlers.launch(interactiveLaunchIntent(command.profileId, command.sessionSelection, command.launchMode));
|
|
80
109
|
if (command.kind === "version")
|
|
81
110
|
return await handlers.version();
|
|
82
111
|
if (command.kind === "packages")
|
|
83
112
|
return await handlers.packages(command.request);
|
|
84
113
|
if (command.kind === "session-context")
|
|
85
114
|
return await handlers.sessionContext(command.request);
|
|
115
|
+
if (command.kind === "tabs-help") {
|
|
116
|
+
output.stdout(tabsHelp());
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
if (command.kind === "tabs")
|
|
120
|
+
return await handlers.tabs(command.request);
|
|
86
121
|
return await handlers.update(command.channel, command.target);
|
|
87
122
|
}
|
|
88
123
|
export function parseCliCommand(arguments_, capabilities) {
|
|
89
124
|
if (arguments_.length === 0)
|
|
90
|
-
return { kind: "launch", profileId: "a1" };
|
|
125
|
+
return { kind: "launch", profileId: "a1", launchMode: "tabs" };
|
|
91
126
|
const [command, ...rest] = arguments_;
|
|
92
127
|
if (command === "--session" || command === "--session-dir") {
|
|
93
128
|
try {
|
|
94
129
|
const sessionSelection = parseSessionSelection(arguments_);
|
|
95
|
-
return { kind: "launch", profileId: "a1", ...(sessionSelection === undefined ? {} : { sessionSelection }) };
|
|
130
|
+
return { kind: "launch", profileId: "a1", launchMode: "tabs", ...(sessionSelection === undefined ? {} : { sessionSelection }) };
|
|
96
131
|
}
|
|
97
132
|
catch (error) {
|
|
98
133
|
return { kind: "error", message: PRODUCT_TEXT.diagnostic(`could not parse session launch: ${error instanceof Error ? error.message : String(error)}`) };
|
|
@@ -108,18 +143,57 @@ export function parseCliCommand(arguments_, capabilities) {
|
|
|
108
143
|
if (command === "pi") {
|
|
109
144
|
if (rest.length > 0)
|
|
110
145
|
return parsePackageCommand(rest, "pi");
|
|
111
|
-
return capabilities.developmentComparison ? { kind: "launch", profileId: "pi" } : { kind: "noop" };
|
|
146
|
+
return capabilities.developmentComparison ? { kind: "launch", profileId: "pi", launchMode: "solo" } : { kind: "noop" };
|
|
112
147
|
}
|
|
148
|
+
if (command === "solo")
|
|
149
|
+
return withoutArguments(rest, { kind: "launch", profileId: "a1", launchMode: "solo" });
|
|
113
150
|
if (command === "update")
|
|
114
151
|
return parseUpdate(rest);
|
|
115
152
|
if (command === "session")
|
|
116
153
|
return parseSessionContext(rest);
|
|
154
|
+
if (command === "tabs")
|
|
155
|
+
return parseTabs(rest);
|
|
117
156
|
if (command?.startsWith("update:"))
|
|
118
157
|
return { kind: "noop" };
|
|
119
158
|
// Rationale: unsupported and reserved command spaces are deliberately quiet. Help is
|
|
120
159
|
// explicit, and a typo must never start an interactive or maintenance path.
|
|
121
160
|
return { kind: "noop" };
|
|
122
161
|
}
|
|
162
|
+
/** Parses `a1 tabs` before any I/O; a malformed form fails with one line and contacts no host. */
|
|
163
|
+
function parseTabs(rest) {
|
|
164
|
+
if (rest.some(value => value === "--help" || value === "-h"))
|
|
165
|
+
return { kind: "tabs-help" };
|
|
166
|
+
const json = rest.includes("--json");
|
|
167
|
+
const words = rest.filter(value => value !== "--json");
|
|
168
|
+
const fail = (detail) => ({ kind: "error", message: PRODUCT_TEXT.diagnostic(`could not parse tabs: ${detail}`) });
|
|
169
|
+
const [action, value, extra] = words;
|
|
170
|
+
if (action === undefined)
|
|
171
|
+
return { kind: "tabs", request: { action: "list", json } };
|
|
172
|
+
if (action === "stop") {
|
|
173
|
+
if (value === undefined)
|
|
174
|
+
return fail("stop requires a tab id or --all.");
|
|
175
|
+
if (extra !== undefined)
|
|
176
|
+
return fail("stop accepts one tab id or --all.");
|
|
177
|
+
if (value === "--all")
|
|
178
|
+
return { kind: "tabs", request: { action: "stop-all", json } };
|
|
179
|
+
if (value.startsWith("-"))
|
|
180
|
+
return fail(`unknown option ${value}.`);
|
|
181
|
+
return { kind: "tabs", request: { action: "stop", tabId: value, json } };
|
|
182
|
+
}
|
|
183
|
+
if (action === "host") {
|
|
184
|
+
if (extra !== undefined || (value !== "status" && value !== "stop"))
|
|
185
|
+
return fail("host accepts status or stop.");
|
|
186
|
+
return { kind: "tabs", request: { action: value === "status" ? "host-status" : "host-stop", json } };
|
|
187
|
+
}
|
|
188
|
+
if (action === "doctor") {
|
|
189
|
+
if (value !== undefined)
|
|
190
|
+
return fail("doctor does not accept arguments.");
|
|
191
|
+
return { kind: "tabs", request: { action: "doctor", json } };
|
|
192
|
+
}
|
|
193
|
+
if (action.startsWith("-"))
|
|
194
|
+
return fail(`unknown option ${action}.`);
|
|
195
|
+
return fail(`unknown subcommand ${action}; use list, stop, host, or doctor.`);
|
|
196
|
+
}
|
|
123
197
|
function parseSessionContext(rest) {
|
|
124
198
|
const [action, value, extra] = rest;
|
|
125
199
|
if (action === "link-worktree") {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type TabsAction = "list" | "stop" | "stop-all" | "host-status" | "host-stop" | "doctor";
|
|
2
|
+
/** One parsed `a1 tabs` form. Parsing finishes before any host is contacted. */
|
|
3
|
+
export interface TabsRequest {
|
|
4
|
+
readonly action: TabsAction;
|
|
5
|
+
readonly tabId?: string;
|
|
6
|
+
readonly json: boolean;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { runTerminalHostMaintenance, writeDoctorBundle } from "../foundation/resident-tabs/index.js";
|
|
2
|
+
import type { TabsRequest } from "./tabs-request.js";
|
|
3
|
+
export type { TabsRequest } from "./tabs-request.js";
|
|
4
|
+
export interface TabsCommandOptions {
|
|
5
|
+
/** The invoking package, never a different active or retained release. */
|
|
6
|
+
readonly packageRoot?: string;
|
|
7
|
+
readonly environment?: NodeJS.ProcessEnv;
|
|
8
|
+
readonly stdout?: (message: string) => void;
|
|
9
|
+
readonly stderr?: (message: string) => void;
|
|
10
|
+
readonly maintenance?: typeof runTerminalHostMaintenance;
|
|
11
|
+
readonly doctor?: typeof writeDoctorBundle;
|
|
12
|
+
}
|
|
13
|
+
/** `a1 tabs`: inspect or stop resident tabs without attaching, and never start a host to report state. */
|
|
14
|
+
export declare function runTabsCommand(request: TabsRequest, options?: TabsCommandOptions): Promise<number>;
|
package/dist/cli/tabs.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { resolveProductPaths } from "../foundation/lifecycle/index.js";
|
|
2
|
+
import { materializeRelease } from "../foundation/release/index.js";
|
|
3
|
+
import { readResidentTabLaunchSettings, runTerminalHostMaintenance, writeDoctorBundle, } from "../foundation/resident-tabs/index.js";
|
|
4
|
+
import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../product-identity.js";
|
|
5
|
+
/** `a1 tabs`: inspect or stop resident tabs without attaching, and never start a host to report state. */
|
|
6
|
+
export async function runTabsCommand(request, options = {}) {
|
|
7
|
+
const environment = options.environment ?? process.env;
|
|
8
|
+
const stdout = options.stdout ?? (message => process.stdout.write(message));
|
|
9
|
+
const stderr = options.stderr ?? (message => process.stderr.write(message));
|
|
10
|
+
const paths = resolveProductPaths(environment);
|
|
11
|
+
const profileRoot = environment[PRODUCT_IDENTITY.environment.profileHome] ?? paths.configDir;
|
|
12
|
+
const releaseRoots = await invokingReleaseRoots(paths.dataDir, options.packageRoot, environment);
|
|
13
|
+
const maintenance = options.maintenance ?? runTerminalHostMaintenance;
|
|
14
|
+
const report = await maintenance({
|
|
15
|
+
action: request.action === "doctor" ? "host-status" : request.action,
|
|
16
|
+
...(request.tabId === undefined ? {} : { tabId: request.tabId }),
|
|
17
|
+
profileRoot,
|
|
18
|
+
dataDir: paths.dataDir,
|
|
19
|
+
runtimeDir: paths.runtimeDir,
|
|
20
|
+
releaseRoots,
|
|
21
|
+
environment,
|
|
22
|
+
});
|
|
23
|
+
if (request.action === "doctor") {
|
|
24
|
+
if (!report.stateDir) {
|
|
25
|
+
stderr(`${PRODUCT_TEXT.diagnostic(`tabs doctor could not locate resident state: ${report.message ?? report.host}`)}\n`);
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
const settings = await readResidentTabLaunchSettings(environment.PI_CODING_AGENT_DIR ?? paths.configDir, PRODUCT_IDENTITY.commandName, paths.configDir, "a1");
|
|
29
|
+
const bundle = await (options.doctor ?? writeDoctorBundle)({
|
|
30
|
+
stateDir: report.stateDir,
|
|
31
|
+
hostStatus: report,
|
|
32
|
+
releaseRoots,
|
|
33
|
+
settings: { tabsAutoName: settings.tabsAutoName },
|
|
34
|
+
});
|
|
35
|
+
if (request.json)
|
|
36
|
+
stdout(`${JSON.stringify({ schema: "a1-tabs-doctor-v1", path: bundle.path, bytes: bundle.bytes, dropped: bundle.dropped })}\n`);
|
|
37
|
+
else
|
|
38
|
+
stdout(`Wrote ${bundle.path}\n`);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
if (request.json) {
|
|
42
|
+
const { exitCode: _exitCode, ...printed } = report;
|
|
43
|
+
stdout(`${JSON.stringify(printed)}\n`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const text = describe(request, report);
|
|
47
|
+
if (report.exitCode === 0)
|
|
48
|
+
stdout(text);
|
|
49
|
+
else
|
|
50
|
+
stderr(text);
|
|
51
|
+
}
|
|
52
|
+
return report.exitCode === 0 ? 0 : 1;
|
|
53
|
+
}
|
|
54
|
+
async function invokingReleaseRoots(dataDir, packageRoot, environment) {
|
|
55
|
+
if (!packageRoot)
|
|
56
|
+
return [];
|
|
57
|
+
if (environment[PRODUCT_IDENTITY.environment.developmentInstanceId])
|
|
58
|
+
return [packageRoot];
|
|
59
|
+
try {
|
|
60
|
+
// Invariant: immutable materialization selects exact payload bytes without activating or starting a host.
|
|
61
|
+
return [(await materializeRelease(packageRoot, dataDir)).releaseRoot];
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const NO_TABS = "No resident tabs are running.\n";
|
|
68
|
+
function describe(request, report) {
|
|
69
|
+
const command = PRODUCT_TEXT.commandName;
|
|
70
|
+
if (report.host === "none")
|
|
71
|
+
return NO_TABS;
|
|
72
|
+
if (report.host === "unavailable")
|
|
73
|
+
return `${PRODUCT_TEXT.diagnostic(`tabs could not run maintenance: ${report.message ?? "terminal host unavailable"}`)}\n`;
|
|
74
|
+
if (report.host === "unresponsive") {
|
|
75
|
+
return `The resident host (pid ${report.pid ?? "unknown"}) is not responding. Run \`${command} tabs host stop\` to stop it.\n`;
|
|
76
|
+
}
|
|
77
|
+
if (report.host === "incompatible") {
|
|
78
|
+
return `${PRODUCT_TEXT.diagnostic(report.message ?? "running tabs use another version")} Run \`${command} tabs host stop\` from that version.\n`;
|
|
79
|
+
}
|
|
80
|
+
if (report.host === "unverifiable" || report.host === "refused") {
|
|
81
|
+
return `${PRODUCT_TEXT.diagnostic(report.message ?? "the resident host could not be verified; nothing was changed")}\n`;
|
|
82
|
+
}
|
|
83
|
+
const result = report.result ?? {};
|
|
84
|
+
if (request.action === "list")
|
|
85
|
+
return listing(result);
|
|
86
|
+
if (request.action === "host-status")
|
|
87
|
+
return status(result);
|
|
88
|
+
if (request.action === "host-stop") {
|
|
89
|
+
if (report.host === "stopped")
|
|
90
|
+
return "Stopped every tab and the resident host.\n";
|
|
91
|
+
return `Could not stop every tab: ${remaining(result)}. The host is still running.\n`;
|
|
92
|
+
}
|
|
93
|
+
if (result.accepted === false && typeof result.message === "string") {
|
|
94
|
+
return `${PRODUCT_TEXT.diagnostic(`tabs stop: ${result.message === "unknown tab" ? `no tab ${request.tabId ?? ""}` : result.message}`)}\n`;
|
|
95
|
+
}
|
|
96
|
+
const stopped = Array.isArray(result.stopped) ? result.stopped.length : 0;
|
|
97
|
+
if (result.accepted === false)
|
|
98
|
+
return `Could not stop: ${remaining(result)}.\n`;
|
|
99
|
+
if (request.action === "stop")
|
|
100
|
+
return `Stopped tab ${request.tabId ?? ""}; its session can be resumed.\n`;
|
|
101
|
+
return stopped === 0 ? NO_TABS : `Stopped ${stopped} tab${stopped === 1 ? "" : "s"}; their sessions can be resumed.\n`;
|
|
102
|
+
}
|
|
103
|
+
function remaining(result) {
|
|
104
|
+
return Array.isArray(result.remaining) && result.remaining.length > 0 ? result.remaining.join(", ") : "unknown tabs";
|
|
105
|
+
}
|
|
106
|
+
function listing(result) {
|
|
107
|
+
const tabs = Array.isArray(result.tabs) ? result.tabs : [];
|
|
108
|
+
if (tabs.length === 0)
|
|
109
|
+
return NO_TABS;
|
|
110
|
+
const rows = [
|
|
111
|
+
["ID", "NAME", "STATUS", "CWD", "RELEASE", "HOLDER"],
|
|
112
|
+
...tabs.map(tab => [tab.tabId, tab.name, tab.status, tab.cwd, tab.release, tab.holderPid ?? "-"].map(value => String(value ?? "-"))),
|
|
113
|
+
];
|
|
114
|
+
const widths = rows[0].map((_, column) => Math.max(...rows.map(row => row[column].length)));
|
|
115
|
+
return `${rows.map(row => row.map((cell, column) => column === row.length - 1 ? cell : cell.padEnd(widths[column])).join(" ")).join("\n")}\n`;
|
|
116
|
+
}
|
|
117
|
+
function status(result) {
|
|
118
|
+
const limits = (result.limits ?? {});
|
|
119
|
+
const counters = (result.counters ?? {});
|
|
120
|
+
const byStatus = (result.tabsByStatus ?? {});
|
|
121
|
+
const lines = [
|
|
122
|
+
`pid: ${String(result.pid ?? "-")}`,
|
|
123
|
+
`build: ${String(result.build ?? "-")}`,
|
|
124
|
+
`release: ${String(result.release ?? "-")}`,
|
|
125
|
+
`generation: ${String(result.generation ?? "-")}`,
|
|
126
|
+
`epoch: ${String(result.epoch ?? "-")}`,
|
|
127
|
+
`uptime: ${String(result.uptimeSeconds ?? "-")}s`,
|
|
128
|
+
`detachment: ${String(result.detachmentMode ?? "unknown")}${result.detachmentVerified === false ? " (not verified)" : ""}`,
|
|
129
|
+
`tabs: ${String(result.tabs ?? 0)}${Object.keys(byStatus).length > 0 ? ` (${Object.entries(byStatus).map(([key, value]) => `${key} ${String(value)}`).join(", ")})` : ""}`,
|
|
130
|
+
`clients: ${String(result.clients ?? 0)}`,
|
|
131
|
+
...startsAndLifecycle(result),
|
|
132
|
+
`limits: ${Object.entries(limits).map(([key, value]) => `${key} ${String(value)}`).join(", ")}`,
|
|
133
|
+
`counters: ${Object.entries(counters).map(([key, value]) => `${key} ${String(value)}`).join(", ")}`,
|
|
134
|
+
...(Array.isArray(result.logs) ? result.logs.map(path => `log: ${String(path)}`) : []),
|
|
135
|
+
];
|
|
136
|
+
return `${lines.join("\n")}\n`;
|
|
137
|
+
}
|
|
138
|
+
/** Lifecycle work running this long means a terminal's tab requests are stuck. */
|
|
139
|
+
const LIFECYCLE_STALL_MS = 10_000;
|
|
140
|
+
function startsAndLifecycle(result) {
|
|
141
|
+
const lines = [];
|
|
142
|
+
const starts = result.starts;
|
|
143
|
+
if (starts)
|
|
144
|
+
lines.push(`starts: active ${String(starts.active ?? 0)}, waiting ${String(starts.interactiveWaiting ?? 0)}, recovering ${String(starts.recoverySlots ?? 0)}`);
|
|
145
|
+
const lifecycle = result.lifecycle;
|
|
146
|
+
if (lifecycle) {
|
|
147
|
+
const oldest = typeof lifecycle.oldestMs === "number" ? lifecycle.oldestMs : 0;
|
|
148
|
+
lines.push(`lifecycle: pending ${String(lifecycle.pending ?? 0)}, oldest ${oldest}ms${oldest > LIFECYCLE_STALL_MS ? " (stalled)" : ""}`);
|
|
149
|
+
}
|
|
150
|
+
return lines;
|
|
151
|
+
}
|