@timurproko/a1 0.2.6-dev.727 → 0.2.6-dev.736

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.
Files changed (116) hide show
  1. package/dist/app/session-shell/clipboard-services.d.ts +19 -0
  2. package/dist/app/session-shell/clipboard-services.js +7 -0
  3. package/dist/app/session-shell/exit-notice.d.ts +9 -5
  4. package/dist/app/session-shell/exit-notice.js +5 -5
  5. package/dist/app/session-shell/index.d.ts +4 -2
  6. package/dist/app/session-shell/index.js +2 -1
  7. package/dist/app/session-shell/paste-preparation-client.d.ts +3 -0
  8. package/dist/app/session-shell/paste-preparation-client.js +5 -2
  9. package/dist/app/session-shell/path-chip-presentation.d.ts +10 -3
  10. package/dist/app/session-shell/path-chip-presentation.js +48 -6
  11. package/dist/app/session-shell/prompt-chips.js +30 -4
  12. package/dist/app/session-shell/quit-outro.d.ts +3 -1
  13. package/dist/app/session-shell/quit-outro.js +23 -8
  14. package/dist/app/session-shell/response-copy-transport.d.ts +6 -1
  15. package/dist/app/session-shell/response-copy-transport.js +8 -2
  16. package/dist/app/session-shell/session-shell-root.d.ts +29 -11
  17. package/dist/app/session-shell/session-shell-root.js +62 -53
  18. package/dist/app/session-shell/session-shell.d.ts +55 -29
  19. package/dist/app/session-shell/session-shell.js +748 -1132
  20. package/dist/app/session-shell/shell-host.d.ts +105 -0
  21. package/dist/app/session-shell/shell-host.js +523 -0
  22. package/dist/cli/session-context.js +6 -3
  23. package/dist/composition/owned-ui.d.ts +20 -2
  24. package/dist/composition/owned-ui.js +107 -56
  25. package/dist/composition/session-info-reference.d.ts +2 -2
  26. package/dist/composition/session-info-reference.js +2 -2
  27. package/dist/contracts/agent-engine/capability-ports.d.ts +1 -85
  28. package/dist/contracts/agent-engine/capability-ports.js +1 -35
  29. package/dist/contracts/agent-engine/index.d.ts +1 -7
  30. package/dist/contracts/agent-engine/index.js +0 -4
  31. package/dist/contracts/owned-ui/index.d.ts +5 -1
  32. package/dist/contracts/owned-ui/index.js +1 -0
  33. package/dist/contracts/owned-ui/model.d.ts +6 -0
  34. package/dist/contracts/owned-ui/session-backend.d.ts +119 -0
  35. package/dist/contracts/owned-ui/session-presenters.d.ts +82 -0
  36. package/dist/contracts/owned-ui/session-presenters.js +1 -0
  37. package/dist/contracts/owned-ui/session-workflows.d.ts +342 -0
  38. package/dist/contracts/owned-ui/session-workflows.js +30 -0
  39. package/dist/features/launch/index.d.ts +1 -1
  40. package/dist/features/launch/index.js +1 -1
  41. package/dist/features/launch/session-context.d.ts +1 -0
  42. package/dist/features/launch/session-context.js +1 -0
  43. package/dist/features/owned-ui/settings-app.js +35 -15
  44. package/dist/foundation/lifecycle/index.d.ts +1 -1
  45. package/dist/foundation/lifecycle/index.js +1 -1
  46. package/dist/foundation/lifecycle/session-repository-context.d.ts +8 -2
  47. package/dist/foundation/lifecycle/session-repository-context.js +200 -65
  48. package/dist/foundation/release/bootstrap.js +1 -2
  49. package/dist/foundation/release/release-gc.js +1 -1
  50. package/dist/foundation/release/update.js +0 -4
  51. package/dist/foundation/storage/control-store.js +0 -12
  52. package/dist/integrations/pi/components/components.js +0 -16
  53. package/dist/integrations/pi/components/index.d.ts +3 -3
  54. package/dist/integrations/pi/components/index.js +2 -2
  55. package/dist/integrations/pi/components/models-dialog.js +1 -30
  56. package/dist/integrations/pi/components/shell-editor-autocomplete.js +11 -9
  57. package/dist/integrations/pi/components/shell-extension-ui.d.ts +3 -3
  58. package/dist/integrations/pi/components/shell-extension-ui.js +6 -2
  59. package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -4
  60. package/dist/integrations/pi/components/shell-shared-facade.d.ts +21 -1
  61. package/dist/integrations/pi/components/shell-shared-facade.js +18 -2
  62. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -1
  63. package/dist/integrations/pi/components/upstream/theme/theme.js +20 -2
  64. package/dist/integrations/pi/engine/adapter.d.ts +44 -24
  65. package/dist/integrations/pi/engine/adapter.js +130 -22
  66. package/dist/integrations/pi/engine/command-dispatch.d.ts +2 -5
  67. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -11
  68. package/dist/integrations/pi/engine/host-ports.d.ts +20 -0
  69. package/dist/integrations/pi/engine/host-ports.js +13 -0
  70. package/dist/integrations/pi/engine/host.d.ts +70 -0
  71. package/dist/integrations/pi/engine/host.js +147 -0
  72. package/dist/integrations/pi/engine/index.d.ts +8 -4
  73. package/dist/integrations/pi/engine/index.js +3 -1
  74. package/dist/integrations/pi/engine/resource-catalog.d.ts +4 -23
  75. package/dist/integrations/pi/engine/runtime-integration.d.ts +8 -2
  76. package/dist/integrations/pi/engine/runtime-integration.js +12 -7
  77. package/dist/integrations/pi/engine/session-integration.d.ts +3 -8
  78. package/dist/integrations/pi/engine/session-integration.js +0 -49
  79. package/dist/integrations/pi/engine/session-runtime.d.ts +18 -3
  80. package/dist/integrations/pi/engine/session-runtime.js +18 -7
  81. package/dist/integrations/pi/engine/settings-bridge.d.ts +2 -2
  82. package/dist/integrations/pi/engine/settings-bridge.js +0 -2
  83. package/dist/integrations/pi/engine/settings-port.d.ts +2 -0
  84. package/dist/integrations/pi/engine/settings-port.js +3 -5
  85. package/dist/integrations/pi/engine/workflows.d.ts +33 -260
  86. package/dist/integrations/pi/engine/workflows.js +6 -28
  87. package/dist/integrations/pi/session-presenters/index.d.ts +2 -0
  88. package/dist/integrations/pi/session-presenters/index.js +1 -0
  89. package/dist/integrations/pi/session-presenters/presenters.d.ts +16 -0
  90. package/dist/integrations/pi/session-presenters/presenters.js +341 -0
  91. package/dist/integrations/pi/tui-runtime/adapter.js +0 -2
  92. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +18 -0
  93. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +84 -3
  94. package/dist/integrations/pi/tui-runtime/index.d.ts +1 -1
  95. package/dist/integrations/pi/tui-runtime/index.js +1 -1
  96. package/dist/native/darwin-arm64/manifest.json +1 -1
  97. package/dist/native/linux-x64/manifest.json +1 -1
  98. package/dist/native/win32-x64/manifest.json +2 -2
  99. package/dist/native/win32-x64/process-guardian.exe +0 -0
  100. package/dist/ui/settings/declarations.d.ts +13 -1
  101. package/dist/ui/settings/declarations.js +12 -1
  102. package/dist/ui/settings/migrations.js +7 -0
  103. package/docs/architecture/boundaries.md +9 -1
  104. package/docs/architecture/project-structure.md +3 -2
  105. package/docs/architecture/ui-reference-provenance.md +1 -1
  106. package/package.json +1 -1
  107. package/dist/contracts/agent-engine/model.d.ts +0 -78
  108. package/dist/contracts/agent-engine/model.js +0 -1
  109. package/dist/contracts/agent-engine/ports.d.ts +0 -18
  110. package/dist/contracts/agent-engine/serialization.d.ts +0 -7
  111. package/dist/contracts/agent-engine/serialization.js +0 -58
  112. package/dist/contracts/agent-engine/validation.d.ts +0 -5
  113. package/dist/contracts/agent-engine/validation.js +0 -128
  114. package/dist/integrations/pi/components/upstream/theme/system-theme.d.ts +0 -61
  115. package/dist/integrations/pi/components/upstream/theme/system-theme.js +0 -709
  116. /package/dist/contracts/{agent-engine/ports.js → owned-ui/session-backend.js} +0 -0
@@ -2,7 +2,6 @@ import { spawn } from "node:child_process";
2
2
  import { restoreAfterOwnedExit } from "../terminal-cleanup/index.js";
3
3
  import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { connect } from "node:net";
5
- import { platform } from "node:os";
6
5
  import { resolve } from "node:path";
7
6
  import { selectCohortLaunch } from "./cohort-selection.js";
8
7
  import { selectOrdinaryLaunchReleaseId } from "./ordinary-launch-selection.js";
@@ -16,7 +15,7 @@ import { selectUpdateLaunchRelease } from "./update-launch.js";
16
15
  import { consumeMaterializationProof, materializeRelease, readCertifiedReleaseManifest, readMaterializedRelease, resolveReleaseEntryPoint, verifyMaterializedRelease } from "./release-store.js";
17
16
  import { scheduleReleaseCleanup } from "./release-gc.js";
18
17
  import { createRestartSeal, readRestartCertifiedRelease, releaseCertificationDocument } from "./restart-certification.js";
19
- import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
18
+ import { PRODUCT_TEXT } from "../../product-identity.js";
20
19
  import { markStartupPhase } from "../startup/index.js";
21
20
  import { launchContractTarget, readLaunchContext, withLaunchContext } from "../launch-context/index.js";
22
21
  const RELEASE_RESELECTION_MESSAGE = "a1-release-reselection";
@@ -3,7 +3,7 @@ import { spawn } from "node:child_process";
3
3
  import { lstat, mkdir, open, readFile, readdir, realpath, rename, rm, stat } from "node:fs/promises";
4
4
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { CohortStateStore, planProtectedReleases, } from "./cohort-state.js";
6
+ import { CohortStateStore, } from "./cohort-state.js";
7
7
  import { liveReleaseIds } from "./endpoints.js";
8
8
  import { resolveProductPaths } from "../lifecycle/index.js";
9
9
  import { RELEASE_MANIFEST_FILENAME } from "./release-store.js";
@@ -790,10 +790,6 @@ async function canonicalImmutableRoot(dataDir, releaseRoot) {
790
790
  function samePath(left, right) {
791
791
  return process.platform === "win32" ? resolve(left).toLowerCase() === resolve(right).toLowerCase() : resolve(left) === resolve(right);
792
792
  }
793
- function isContainedBy(parent, child) {
794
- const pathFromParent = relative(parent, child);
795
- return pathFromParent.length > 0 && pathFromParent !== ".." && !pathFromParent.startsWith(`..${sep}`) && !isAbsolute(pathFromParent);
796
- }
797
793
  function unsuccessfulCode(code) { return code === null || code === 0 ? 1 : code; }
798
794
  function formatExitCode(code) { return code === null ? "unknown" : String(code); }
799
795
  function errorMessage(error) { return error instanceof Error ? error.message : String(error); }
@@ -308,18 +308,6 @@ export class ControlStore {
308
308
  close() {
309
309
  this.database.close();
310
310
  }
311
- #transaction(operation) {
312
- this.database.exec("BEGIN IMMEDIATE");
313
- try {
314
- const result = operation();
315
- this.database.exec("COMMIT");
316
- return result;
317
- }
318
- catch (error) {
319
- this.database.exec("ROLLBACK");
320
- throw error;
321
- }
322
- }
323
311
  }
324
312
  function launchInstanceFromRow(row) {
325
313
  const instance = {
@@ -39,26 +39,10 @@ function requireBlock(block, kind) {
39
39
  function blockPayload(block) {
40
40
  return isRecord(block.payload) ? block.payload : {};
41
41
  }
42
- function blockProvider(block) {
43
- return stringPayload(blockPayload(block), "provider") ?? "openai";
44
- }
45
- function blockModel(block) {
46
- return stringPayload(blockPayload(block), "model") ?? "gpt-5";
47
- }
48
42
  function stringPayload(payload, key) {
49
43
  const value = payload[key];
50
44
  return typeof value === "string" && value.length > 0 ? value : undefined;
51
45
  }
52
- function emptyUsage() {
53
- return {
54
- input: 0,
55
- output: 0,
56
- cacheRead: 0,
57
- cacheWrite: 0,
58
- totalTokens: 0,
59
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
60
- };
61
- }
62
46
  function isRecord(value) {
63
47
  return typeof value === "object" && value !== null;
64
48
  }
@@ -3,11 +3,11 @@ export { loadHistoryEditor, type HistoryEditorConstructor } from "./history-edit
3
3
  export { PiComponentConformanceError, runPiComponentConformance } from "./conformance.js";
4
4
  export type { PiComponentConformanceReport, PiComponentConformanceResult } from "./conformance.js";
5
5
  export { createPiShellOperationLoader, createPiShellShareOperationDialog, type PiShellOperationLoaderPort, } from "./share-operation-dialog.js";
6
- export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellReleaseUpdateBanner, renderPiShellReleaseUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
6
+ export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, createPiKeybindingsHost, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellReleaseUpdateBanner, renderPiShellReleaseUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
7
7
  export { renderPiShellHotkeySections } from "./shell-hotkey-sections.js";
8
8
  export type { PiShellHotkeySection } from "./shell-hotkey-sections.js";
9
- export type { PiExtensionUiBridge, PiExtensionUiBridgeHost, PiShellAuthProviderOption, PiShellAutocompleteCommand, PiShellClipboardContent, PiShellCommandMessagePresentation, PiShellComponentPort, PiShellEditorBodyGeometry, PiShellEditorOptions, PiShellEditorPointerEvent, PiShellEditorPort, PiShellEditorTextRange, PiShellExtensionRendererResolver, PiShellHeaderOptions, PiShellHeaderPort, PiShellHotkeysPresentation, PiShellImageAssetResolver, PiShellLoadedResourcesPort, PiShellLoginDialogPort, PiShellModelSelectorOptions, PiShellModelsDialogOptions, PiShellModelsDialogPort, PiShellPasteReservation, PiShellQueuedInputPort, PiShellResourceEntry, PiShellResourceSection, PiShellScopedModelDescriptor, PiShellScopedModelsSelectorOptions, PiShellScopedModelsSelectorPort, PiShellSelectorOption, PiShellSelectorOptions, PiShellSessionInfoPresentation, PiShellSettingsSelectorOptions, PiShellStartupNotice, PiShellStatusPlacement, PiShellStatusPort, PiShellSubmittedPromptComposer, PiShellTranscriptComponentPort, PiShellViewComponentPort, } from "./shell-components.js";
10
- export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
9
+ export type { PiExtensionUiBridge, PiExtensionUiBridgeHost, PiShellAuthProviderOption, PiShellAutocompleteCommand, PiShellClipboardContent, PiShellCommandMessagePresentation, PiShellComponentPort, PiShellEditorBodyGeometry, PiShellEditorOptions, PiShellEditorPointerEvent, PiKeybindingsHost, PiShellEditorPort, PiShellEditorTextRange, PiShellExtensionRendererResolver, PiShellHeaderOptions, PiShellHeaderPort, PiShellHotkeysPresentation, PiShellImageAssetResolver, PiShellLoadedResourcesPort, PiShellLoginDialogPort, PiShellModelSelectorOptions, PiShellModelsDialogOptions, PiShellModelsDialogPort, PiShellPasteReservation, PiShellQueuedInputPort, PiShellResourceEntry, PiShellResourceSection, PiShellScopedModelDescriptor, PiShellScopedModelsSelectorOptions, PiShellScopedModelsSelectorPort, PiShellSelectorOption, PiShellSelectorOptions, PiShellSessionInfoPresentation, PiShellSettingsSelectorOptions, PiShellStartupNotice, PiShellStatusPlacement, PiShellStatusPort, PiShellSubmittedPromptComposer, PiShellTranscriptComponentPort, PiShellViewComponentPort, } from "./shell-components.js";
10
+ export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, derivePiCanvasBackground, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piCanvasBackgroundAnsi, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
11
11
  export type { PiAccentProjection, PiColorMode, PiTerminalTheme, PiTerminalThemeDetection, PiTerminalThemeDetector, PiThemeBackground, PiThemeResult } from "./theme.js";
12
12
  export { OwnedPiThemeController } from "./upstream/theme/theme-controller.js";
13
13
  export type { PiThemeRuntimePort, PiThemeSettingsPort } from "./upstream/theme/theme-controller.js";
@@ -2,9 +2,9 @@ export { adaptPiAssistantMessage, adaptPiToolExecution, adaptPiUserMessage } fro
2
2
  export { loadHistoryEditor } from "./history-editor-loader.js";
3
3
  export { PiComponentConformanceError, runPiComponentConformance } from "./conformance.js";
4
4
  export { createPiShellOperationLoader, createPiShellShareOperationDialog, } from "./share-operation-dialog.js";
5
- export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellReleaseUpdateBanner, renderPiShellReleaseUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
5
+ export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, createPiKeybindingsHost, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellReleaseUpdateBanner, renderPiShellReleaseUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
6
6
  export { renderPiShellHotkeySections } from "./shell-hotkey-sections.js";
7
- export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
7
+ export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, derivePiCanvasBackground, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piCanvasBackgroundAnsi, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
8
8
  export { OwnedPiThemeController } from "./upstream/theme/theme-controller.js";
9
9
  export { PI_MODAL_CONTENT_PADDING_X, PiModalFrame, PiModalHeader, addPiModalHeader, adoptPiModalFrame, adoptPiModalHeader, } from "./modal-frame.js";
10
10
  export { ModelsDialogComponent } from "./models-dialog.js";
@@ -14,7 +14,6 @@ function renderHintsWithClose(entries, width) {
14
14
  const MAX_VISIBLE_ROWS = 10;
15
15
  const MODELS_TITLE = "Models";
16
16
  const REFRESHING_TITLE_MIN_DURATION_MS = 1_000;
17
- const REFRESHED_TITLE_DURATION_MS = 2_000;
18
17
  class ModalTitleLine {
19
18
  #text = "";
20
19
  setText(text) { this.#text = text; }
@@ -64,8 +63,6 @@ export class ModelsDialogComponent {
64
63
  #refreshing = false;
65
64
  #refreshStartedAt;
66
65
  #refreshOutcomeTimer;
67
- #refreshed = false;
68
- #refreshDismissalTimer;
69
66
  #disposed = false;
70
67
  #focused = false;
71
68
  constructor(config, callbacks) {
@@ -119,11 +116,9 @@ export class ModelsDialogComponent {
119
116
  return;
120
117
  if (kind === "muted") {
121
118
  this.#clearRefreshOutcome();
122
- this.#clearRefreshDismissal();
123
119
  this.#refreshStatus = undefined;
124
120
  this.#refreshing = true;
125
121
  this.#refreshStartedAt = Date.now();
126
- this.#refreshed = false;
127
122
  return;
128
123
  }
129
124
  const visibleMs = this.#refreshStartedAt === undefined ? REFRESHING_TITLE_MIN_DURATION_MS : Date.now() - this.#refreshStartedAt;
@@ -149,10 +144,8 @@ export class ModelsDialogComponent {
149
144
  dispose() {
150
145
  this.#disposed = true;
151
146
  this.#clearRefreshOutcome();
152
- this.#clearRefreshDismissal();
153
147
  this.#refreshing = false;
154
148
  this.#refreshStartedAt = undefined;
155
- this.#refreshed = false;
156
149
  }
157
150
  invalidate() {
158
151
  this.#input.invalidate();
@@ -243,29 +236,13 @@ export class ModelsDialogComponent {
243
236
  const theme = piTheme();
244
237
  this.#title.setText(theme.fg("accent", theme.bold(MODELS_TITLE))
245
238
  + (this.dirty ? theme.fg("warning", " (unsaved)") : "")
246
- + (this.#refreshing ? theme.fg("muted", " (refreshing)") : "")
247
- + (this.#refreshed ? theme.fg("success", " (refreshed)") : ""));
239
+ + (this.#refreshing ? theme.fg("muted", " (refreshing)") : ""));
248
240
  return this.#frame.render(width);
249
241
  }
250
242
  #applyRefreshOutcome(message, kind) {
251
- this.#clearRefreshDismissal();
252
243
  this.#refreshing = false;
253
244
  this.#refreshStartedAt = undefined;
254
- this.#refreshed = kind === "success";
255
245
  this.#refreshStatus = kind === "warning" ? { message, kind } : undefined;
256
- if (kind !== "success")
257
- return;
258
- const timer = setTimeout(() => {
259
- if (this.#refreshDismissalTimer !== timer)
260
- return;
261
- this.#refreshDismissalTimer = undefined;
262
- if (this.#disposed)
263
- return;
264
- this.#refreshed = false;
265
- this.#callbacks.requestRender();
266
- }, REFRESHED_TITLE_DURATION_MS);
267
- timer.unref?.();
268
- this.#refreshDismissalTimer = timer;
269
246
  }
270
247
  #clearRefreshOutcome() {
271
248
  if (this.#refreshOutcomeTimer === undefined)
@@ -273,12 +250,6 @@ export class ModelsDialogComponent {
273
250
  clearTimeout(this.#refreshOutcomeTimer);
274
251
  this.#refreshOutcomeTimer = undefined;
275
252
  }
276
- #clearRefreshDismissal() {
277
- if (this.#refreshDismissalTimer === undefined)
278
- return;
279
- clearTimeout(this.#refreshDismissalTimer);
280
- this.#refreshDismissalTimer = undefined;
281
- }
282
253
  #renderBody(width) {
283
254
  const theme = piTheme();
284
255
  const lines = [];
@@ -1,10 +1,9 @@
1
- import { CombinedAutocompleteProvider, matchesKey, setKeybindings, visibleWidth, } from "@earendil-works/pi-tui";
1
+ import { CombinedAutocompleteProvider, matchesKey, visibleWidth, } from "@earendil-works/pi-tui";
2
2
  import { PROMPT_HISTORY_EDITOR_REPLACEMENT } from "../../../contracts/owned-ui/index.js";
3
- import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
4
3
  import { OwnedEditor } from "./upstream/components/owned-editor.js";
5
4
  import { OwnedEditorUxInterception, createPromptSelectionInterceptor, editorVisualLineCount, } from "./owned-editor-ux.js";
6
5
  import { PINNED_PI_LAYOUT, getPiSelectListTheme, piTheme, renderPiListSelection, } from "./theme.js";
7
- import { createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
6
+ import { createPiKeybindingsHost, createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
8
7
  import { SKILLS_COMMAND_NAME, collapseSkillCommands, createSkillsTunnelProvider, } from "./skills-command.js";
9
8
  /** A selected autocomplete row: its arrow/primary column, then the aligned description. */
10
9
  const SELECTED_DESCRIBED_ROW = /^(→ .*?\S)(\s{2,}.*)$/u;
@@ -63,10 +62,13 @@ export function createPiShellEditor(options) {
63
62
  ensureTheme();
64
63
  const tui = createTuiFacade(options);
65
64
  const inputPresentation = options.keybindingProfile === "a1" ? options.promptPresentation?.input : undefined;
66
- const keybindings = options.keybindingProfile === "a1"
67
- ? KeybindingsManager.createForOwnedInput(options.agentDir)
68
- : KeybindingsManager.create(options.agentDir);
69
- setKeybindings(keybindings);
65
+ // Invariant: the process shares one manager; a standalone editor gets its own host for its profile.
66
+ const host = options.keybindings ?? createPiKeybindingsHost({
67
+ profile: options.keybindingProfile ?? "pi",
68
+ ...(options.agentDir === undefined ? {} : { agentDir: options.agentDir }),
69
+ });
70
+ host.ensureActive();
71
+ const keybindings = host.manager;
70
72
  if (options.persistentHistory === true && options.keybindingProfile === "a1" && options.historyEditor === undefined) {
71
73
  throw new Error("Persistent history requires the loaded owned editor");
72
74
  }
@@ -251,9 +253,9 @@ export function createPiShellEditor(options) {
251
253
  // Completion state, sizing, styles, and pagination still belong to the editor.
252
254
  return [...menu, ...bodyRows];
253
255
  },
254
- activateKeybindings: () => setKeybindings(keybindings),
256
+ activateKeybindings: () => host.ensureActive(),
255
257
  keybindingConfig: () => keybindings.getEffectiveConfig(),
256
- reloadKeybindings: () => { keybindings.reload(); setKeybindings(keybindings); },
258
+ reloadKeybindings: () => host.reload(),
257
259
  matchesTerminalKey: (data, key) => matchesKey(data, key),
258
260
  handleInput: data => {
259
261
  // Compatibility: an unassigned reverse Tab must not clear selection or reach autocomplete fallback.
@@ -1,6 +1,5 @@
1
- import { type ExtensionUIContext } from "../startup-public.js";
2
1
  import type { ProgramStatusBlocked } from "./upstream/program-status-reporter.js";
3
- import type { OwnedUiExtensionOverlayHandle, OwnedUiExtensionOverlayOptions } from "../../../contracts/owned-ui/index.js";
2
+ import { type OwnedUiExtensionOverlayHandle, type OwnedUiExtensionOverlayOptions, type OwnedUiExtensionUiPort } from "../../../contracts/owned-ui/index.js";
4
3
  import { type PiShellComponentPort, type PiShellEditorOptions } from "./shell-shared-facade.js";
5
4
  export interface PiExtensionUiBridgeHost {
6
5
  readonly runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">;
@@ -29,7 +28,8 @@ export interface PiExtensionUiBridgeHost {
29
28
  setToolsExpanded(expanded: boolean): void;
30
29
  }
31
30
  export interface PiExtensionUiBridge {
32
- readonly context: ExtensionUIContext;
31
+ /** The extension UI context the engine binds to a session, typed by the neutral contract it satisfies. */
32
+ readonly context: OwnedUiExtensionUiPort;
33
33
  input(title: string, placeholder: string, options?: {
34
34
  readonly retainSurfaceOnSettle?: boolean;
35
35
  }): Promise<string | undefined>;
@@ -2,7 +2,8 @@ import {} from "../startup-public.js";
2
2
  import { ExtensionEditorComponent } from "./upstream/components/extension-editor.js";
3
3
  import { ExtensionInputComponent } from "./upstream/components/extension-input.js";
4
4
  import { ExtensionSelectorComponent } from "./upstream/components/extension-selector.js";
5
- import { setKeybindings, Text, } from "@earendil-works/pi-tui";
5
+ import { Text, } from "@earendil-works/pi-tui";
6
+ import { assertOwnedUiExtensionUiPort, } from "../../../contracts/owned-ui/index.js";
6
7
  import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
7
8
  import { PINNED_PI_LAYOUT, applyPiTheme, applyPiThemeInstance, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, piTheme, } from "./theme.js";
8
9
  import { componentPort, createTuiFacade, ensureTheme, isRecord, withPiDialogCancel, } from "./shell-shared-facade.js";
@@ -10,8 +11,8 @@ import { componentPort, createTuiFacade, ensureTheme, isRecord, withPiDialogCanc
10
11
  export function createPiExtensionUiBridge(host) {
11
12
  ensureTheme();
12
13
  const tui = createTuiFacade(host.runtime);
14
+ // Invariant: extension components receive Pi's manager explicitly; the registry stays the process host's.
13
15
  const keybindings = KeybindingsManager.create(host.agentDir);
14
- setKeybindings(keybindings);
15
16
  const disposers = new Set();
16
17
  let customEditorFactory;
17
18
  let activeSurface;
@@ -258,6 +259,9 @@ export function createPiExtensionUiBridge(host) {
258
259
  host.setInputSurface(null);
259
260
  host.setProgramStatusBlocked(undefined);
260
261
  };
262
+ // Compatibility: Pi's context takes its own TUI and Theme in factory callbacks, so it is not statically the
263
+ // neutral port; the same runtime check the engine applies at bind time lets the shell see only that port.
264
+ assertOwnedUiExtensionUiPort(context);
261
265
  return {
262
266
  context,
263
267
  input: (title, placeholder, options) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, { tui })), undefined, options?.retainSurfaceOnSettle === true, { kind: "question", message: title }),
@@ -1,4 +1,4 @@
1
- import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder, parseSkillBlock, UserMessageComponent, } from "../startup-public.js";
1
+ import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, parseSkillBlock, UserMessageComponent, } from "../startup-public.js";
2
2
  import { ToolExecutionComponent } from "./upstream/components/tool-execution.js";
3
3
  import { SkillInvocationMessageComponent } from "./upstream/components/skill-invocation-message.js";
4
4
  import { piToolArguments as toolArguments, updatePiToolResult as updateToolResult } from "./tool-result-adapter.js";
@@ -8,7 +8,7 @@ import { Container, Image, Spacer, Text, } from "@earendil-works/pi-tui";
8
8
  import { createPiSubmittedPromptComponent, isPiPromptStyleCompaction, } from "./submitted-prompt-adapter.js";
9
9
  export { isPiPromptStyleCompaction, paintPiSubmittedPromptTimestamp } from "./submitted-prompt-adapter.js";
10
10
  import { getPiMarkdownTheme, PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
11
- import { componentPort, createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
11
+ import { createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
12
12
  export function createPiShellTranscriptComponent(initial, cwd, extensions, submittedPrompt, initialOutputPad = PINNED_PI_LAYOUT.outputPad, initialHideThinkingBlock = false, initialMermaidRenderingMode = "off", initialShowImages = true, initialImageWidthCells = 80, imageAssets, presentation) {
13
13
  ensureTheme();
14
14
  let block = initial;
@@ -219,7 +219,7 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt,
219
219
  case "custom":
220
220
  return customMessageComponent(block, expanded, extensions, outputPad);
221
221
  case "bash":
222
- return bashExecutionComponent(block, cwd, expanded, tui);
222
+ return bashExecutionComponent(block, expanded, tui);
223
223
  }
224
224
  }
225
225
  function updateTranscriptComponent(component, previous, next, expanded, imageAssets) {
@@ -364,7 +364,7 @@ function customMessageComponent(block, expanded, extensions, outputPad) {
364
364
  component.setExpanded(expanded);
365
365
  return component;
366
366
  }
367
- function bashExecutionComponent(block, cwd, expanded, tui) {
367
+ function bashExecutionComponent(block, expanded, tui) {
368
368
  const payload = blockPayload(block);
369
369
  const component = new BashExecutionComponent(stringPayload(payload, "command") ?? block.title ?? "", tui ?? createTuiFacade({ getColumns: () => 80, getRows: () => 24, requestRender() { } }), payload.excludeFromContext === true);
370
370
  if (block.text)
@@ -4,6 +4,7 @@ import type { HistoryEditorConstructor } from "./history-editor-loader.js";
4
4
  import type { PiShellPromptInputPresentation } from "./prompt-input-port.js";
5
5
  import type { EditorRecallPort } from "./editor-interaction.js";
6
6
  import type { PresentationComponentPort } from "../../../contracts/presentation/index.js";
7
+ import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
7
8
  /** Terminal-cell width authority used by Pi-rendered component rows. */
8
9
  export declare const piShellVisibleWidth: typeof visibleWidth;
9
10
  export declare const piShellTruncateToWidth: (text: string, width: number) => string;
@@ -41,7 +42,7 @@ export interface PiShellEditorPort extends PiShellComponentPort {
41
42
  bodyGeometry?(): PiShellEditorBodyGeometry;
42
43
  readonly recall?: EditorRecallPort;
43
44
  readonly historyReplacement?: typeof import("../../../contracts/owned-ui/index.js").PROMPT_HISTORY_EDITOR_REPLACEMENT;
44
- /** Restores this editor's profile after another Pi component changed the global manager. */
45
+ /** Restores the shared manager if anything replaced pi-tui's registry; a no-op when it is already active. */
45
46
  activateKeybindings(): void;
46
47
  keybindingConfig(): KeybindingsConfig;
47
48
  reloadKeybindings(): void;
@@ -161,6 +162,8 @@ export interface PiShellEditorOptions {
161
162
  readonly historyEditor?: HistoryEditorConstructor;
162
163
  /** Bare A1 adds ergonomic aliases while comparison profiles retain Pi defaults. */
163
164
  readonly keybindingProfile?: "pi" | "a1";
165
+ /** The process's shared keybindings; its profile must match `keybindingProfile`. */
166
+ readonly keybindings?: PiKeybindingsHost;
164
167
  readonly getColumns: () => number;
165
168
  readonly getRows: () => number;
166
169
  readonly requestRender: () => void;
@@ -233,4 +236,21 @@ export declare function componentFromPort(port: PiShellComponentPort): Component
233
236
  export declare function formatSessionTokens(count: number): string;
234
237
  export declare function isAutocompleteProvider(value: unknown): value is AutocompleteProvider;
235
238
  export declare function isRecord(value: unknown): value is Record<string, unknown>;
239
+ /**
240
+ * Applies theme state. The keybinding registry belongs to the process's `PiKeybindingsHost`; only when no
241
+ * A1 manager was ever applied (a presenter built outside composition) does this install Pi's defaults once.
242
+ */
236
243
  export declare function ensureTheme(): void;
244
+ /** The process's one keybinding manager and the only writer of pi-tui's global keybinding registry. */
245
+ export interface PiKeybindingsHost {
246
+ readonly manager: KeybindingsManager;
247
+ /** Installs the manager in the registry unless it is already the active one. */
248
+ ensureActive(): void;
249
+ /** Re-reads the user's keybindings file into the shared manager and keeps it active. */
250
+ reload(): void;
251
+ }
252
+ /** Composition creates one host per process; bare A1 uses the owned-input aliases, comparison profiles keep Pi's. */
253
+ export declare function createPiKeybindingsHost(options: {
254
+ readonly profile: "pi" | "a1";
255
+ readonly agentDir?: string;
256
+ }): PiKeybindingsHost;
@@ -1,4 +1,4 @@
1
- import { hyperlink, matchesKey, setKeybindings, visibleWidth, truncateToWidth, } from "@earendil-works/pi-tui";
1
+ import { getKeybindings, hyperlink, matchesKey, setKeybindings, visibleWidth, truncateToWidth, } from "@earendil-works/pi-tui";
2
2
  import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
3
3
  import { ensurePiTheme, } from "./theme.js";
4
4
  /** Terminal-cell width authority used by Pi-rendered component rows. */
@@ -97,7 +97,23 @@ export function isAutocompleteProvider(value) {
97
97
  export function isRecord(value) {
98
98
  return typeof value === "object" && value !== null;
99
99
  }
100
+ let fallbackKeybindings;
101
+ /**
102
+ * Applies theme state. The keybinding registry belongs to the process's `PiKeybindingsHost`; only when no
103
+ * A1 manager was ever applied (a presenter built outside composition) does this install Pi's defaults once.
104
+ */
100
105
  export function ensureTheme() {
101
106
  ensurePiTheme();
102
- setKeybindings(KeybindingsManager.create());
107
+ if (!(getKeybindings() instanceof KeybindingsManager))
108
+ setKeybindings(fallbackKeybindings ??= KeybindingsManager.create());
109
+ }
110
+ /** Composition creates one host per process; bare A1 uses the owned-input aliases, comparison profiles keep Pi's. */
111
+ export function createPiKeybindingsHost(options) {
112
+ const manager = options.profile === "a1"
113
+ ? KeybindingsManager.createForOwnedInput(options.agentDir)
114
+ : KeybindingsManager.create(options.agentDir);
115
+ const ensureActive = () => { if (getKeybindings() !== manager)
116
+ setKeybindings(manager); };
117
+ ensureActive();
118
+ return { manager, ensureActive, reload: () => { manager.reload(); setKeybindings(manager); } };
103
119
  }
@@ -1,7 +1,7 @@
1
1
  import { Theme, type ThemeColor } from "@earendil-works/pi-coding-agent";
2
2
  export type { ThemeColor } from "@earendil-works/pi-coding-agent";
3
3
  import { type Color, type RgbColor } from "@earendil-works/pi-tui";
4
- import type { UiAccentColor } from "../../../../../contracts/owned-ui/index.js";
4
+ import type { OwnedUiBackgroundStyle, UiAccentColor } from "../../../../../contracts/owned-ui/index.js";
5
5
  export declare const PINNED_PI_LAYOUT: Readonly<{
6
6
  readonly editorPaddingX: 0;
7
7
  readonly outputPad: 1;
@@ -51,6 +51,10 @@ export declare function currentPiThemeName(): string;
51
51
  export declare function currentPiAccentColor(): UiAccentColor;
52
52
  /** Paints one menu swatch from a named A1 palette entry. */
53
53
  export declare function renderPiAccentPreview(color: string, text: string): string | null;
54
+ /** Derives A1's fullscreen canvas without adding a token to Pi's theme grammar. */
55
+ export declare function derivePiCanvasBackground(style: OwnedUiBackgroundStyle, accent: Color): Color | null;
56
+ /** Resolves the selected canvas through the active accent and terminal color mode. */
57
+ export declare function piCanvasBackgroundAnsi(style: OwnedUiBackgroundStyle): string | null;
54
58
  /** Keeps the complete comparison theme unmodified while bare A1 projects its semantic accent family. */
55
59
  export declare function setPiPackageBorderProjectionEnabled(enabled: boolean): void;
56
60
  /** Reprojects the active base theme; repeated changes never derive from an earlier projection. */
@@ -3,7 +3,8 @@
3
3
  * packages/coding-agent/src/modes/interactive/theme/theme.ts.
4
4
  * Modifications: Source-synchronized theme port: retain pinned theme schema, variable/color
5
5
  * resolution, built-in and custom loading, terminal detection, and layout defaults while constructing
6
- * the public package-root Theme class and projecting A1's optional semantic accent.
6
+ * the public package-root Theme class, projecting A1's optional semantic accent, and deriving its
7
+ * owned fullscreen canvas.
7
8
  * Deviations: theme-public-api-boundary, theme-owned-watcher-boundary, semantic-accent-projection.
8
9
  */
9
10
  import { existsSync, readFileSync, readdirSync, watch } from "node:fs";
@@ -36,7 +37,7 @@ const ACCENT_PALETTE = Object.freeze({
36
37
  dark: Object.freeze({ kind: "rgb", r: 167, g: 152, b: 215 }),
37
38
  light: Object.freeze({ kind: "rgb", r: 116, g: 89, b: 180 }),
38
39
  }),
39
- blue: Object.freeze({ dark: okhslColor(232, 0.54, 0.67), light: okhslColor(231, 0.68, 0.47) }),
40
+ blue: Object.freeze({ dark: okhslColor(268, 0.80, 0.67), light: okhslColor(268, 0.90, 0.47) }),
40
41
  cyan: Object.freeze({ dark: okhslColor(202, 0.58, 0.67), light: okhslColor(203, 0.73, 0.46) }),
41
42
  green: Object.freeze({ dark: okhslColor(159, 0.59, 0.67), light: okhslColor(159, 0.75, 0.46) }),
42
43
  orange: Object.freeze({ dark: okhslColor(48, 0.75, 0.67), light: okhslColor(48, 0.90, 0.47) }),
@@ -104,6 +105,23 @@ export function renderPiAccentPreview(color, text) {
104
105
  const accent = ACCENT_PALETTE[color][base.appearance];
105
106
  return `${foregroundAnsi(accent, base.getColorMode())}${text}\u001b[39m`;
106
107
  }
108
+ /** Derives A1's fullscreen canvas without adding a token to Pi's theme grammar. */
109
+ export function derivePiCanvasBackground(style, accent) {
110
+ if (style === "transparent")
111
+ return null;
112
+ if (style === "dark")
113
+ return okhslColor(229, 0.03, 0.12);
114
+ const { h } = colorToOkhsl(accent);
115
+ return okhslColor(h, 0.12, 0.12);
116
+ }
117
+ /** Resolves the selected canvas through the active accent and terminal color mode. */
118
+ export function piCanvasBackgroundAnsi(style) {
119
+ ensurePiTheme();
120
+ const base = activeBaseTheme;
121
+ const accent = ACCENT_PALETTE[activeAccentColor][base.appearance];
122
+ const background = derivePiCanvasBackground(style, accent);
123
+ return background === null ? null : backgroundAnsi(background, base.getColorMode());
124
+ }
107
125
  /** Keeps the complete comparison theme unmodified while bare A1 projects its semantic accent family. */
108
126
  export function setPiPackageBorderProjectionEnabled(enabled) {
109
127
  if (packageBorderProjectionEnabled === enabled)
@@ -1,5 +1,5 @@
1
1
  import { type AgentSession } from "../startup-public.js";
2
- import { type OwnedUiCommand, type OwnedUiImageAttachment, type OwnedUiPromptSuggestionGeneratorPort, type OwnedUiPromptSuggestionReasoning, type OwnedUiPromptSuggestionRequest, type OwnedUiPromptSuggestionResult, type OwnedUiEvent, type OwnedUiSessionViewModel, type OwnedUiSnapshot } from "../../../contracts/owned-ui/index.js";
2
+ import { type OwnedUiCommand, type OwnedUiExtensionPort, type OwnedUiExtensionUiPort, type OwnedUiImageAttachment, type OwnedUiPromptSuggestionGeneratorPort, type OwnedUiPromptSuggestionReasoning, type OwnedUiPromptSuggestionRequest, type OwnedUiPromptSuggestionResult, type OwnedUiEvent, type OwnedUiReleaseUpdate, type OwnedUiSessionBackend, type OwnedUiSessionCatalogPort, type OwnedUiSessionIdentityPort, type OwnedUiSessionPort, type OwnedUiSessionSettingsPort, type OwnedUiSessionViewModel, type OwnedUiSnapshot, type OwnedUiWorkflowPort } from "../../../contracts/owned-ui/index.js";
3
3
  import type { PiAuthenticationProviderOption, PiBashWorkflowResult, PiModelsContext, PiModelsRefreshResult, PiPinnedSettingsCallback, PiPinnedSettingsSnapshot, PiProjectTrustContext, PiProjectTrustUpdate, PiScopedModelsContext, PiScopedModelsRefreshResult, PiSessionResumeMetadata, PiSessionSelectorContext, PiTreeSelectorContext, PiWorkflowAutocompleteCommand, PiWorkflowHost, PiWorkflowInteractionHost, PiWorkflowOption, PiWorkflowRequest, PiWorkflowResult } from "./workflows.js";
4
4
  import type { PiSettingsBridge } from "./settings-bridge.js";
5
5
  import type { PiSettingOwnerHandlers } from "./settings-bridge.js";
@@ -10,11 +10,29 @@ import { type AdapterCommandResult } from "./command-dispatch.js";
10
10
  import { type OwnedPiVisualExtensionSupport } from "./extension-ui-binding.js";
11
11
  import { type OwnedPiExtensionResourceSummary, type OwnedPiResourceSummary } from "./resource-catalog.js";
12
12
  import { type PiEnginePackageUpdateProbe, type PiEngineRuntimeFactory, type PiRepositoryContextReader } from "./session-runtime.js";
13
+ import { type PiEngineHostSessionPorts } from "./host-ports.js";
13
14
  import { PiWorkflowContexts } from "./workflow-contexts.js";
14
15
  export type { OwnedPiExtensionResourceSummary, OwnedPiExtensionSourceSummary, OwnedPiResourceSummary } from "./resource-catalog.js";
15
16
  export type { PiEngineRuntimeFactory, PiEngineRuntimeFactoryInput } from "./session-runtime.js";
16
17
  export type { AdapterCommandResult } from "./command-dispatch.js";
17
18
  export type { OwnedPiVisualExtensionSupport } from "./extension-ui-binding.js";
19
+ /**
20
+ * The Pi objects pinned selectors and transcript renderers are built from. They are not part of the
21
+ * session backend contract; only the session presenters owner reads them.
22
+ */
23
+ export interface PiSessionPresentationSource {
24
+ pinnedModelSelectorContext(): ReturnType<PiWorkflowContexts["pinnedModelSelectorContext"]>;
25
+ pinnedSessionSelectorContext(): PiSessionSelectorContext;
26
+ pinnedTreeSelectorContext(): PiTreeSelectorContext;
27
+ pinnedMessageRenderer(customType: string): unknown;
28
+ pinnedToolRenderers(toolName: string): unknown;
29
+ pinnedShortcutDescriptions(bindings: Parameters<AgentSession["extensionRunner"]["getShortcuts"]>[0]): readonly {
30
+ readonly key: string;
31
+ readonly description: string;
32
+ }[];
33
+ pinnedSettingsModels(): Pick<PiPinnedSettingsSnapshot, "currentModel" | "availableDefaultModels">;
34
+ applyPinnedSettingValue(callback: PiPinnedSettingsCallback, value: unknown): Promise<PiWorkflowResult>;
35
+ }
18
36
  /** Explicit flush failure when required delivery was interrupted rather than completed. */
19
37
  export declare class EngineDeliveryError extends Error {
20
38
  constructor();
@@ -22,7 +40,13 @@ export declare class EngineDeliveryError extends Error {
22
40
  export interface PiEngineAdapterOptions {
23
41
  readonly cwd?: string;
24
42
  readonly agentDir?: string;
25
- readonly sessionId?: string;
43
+ /** Unique within the process; the engine host assigns one when the caller has none. */
44
+ readonly sessionId: string;
45
+ /**
46
+ * The process-level host this session belongs to. Absent only for adapters built directly in
47
+ * tests and tools: then no process dispatcher is installed and nothing is announced.
48
+ */
49
+ readonly engineHost?: PiEngineHostSessionPorts;
26
50
  readonly sessionPath?: string;
27
51
  readonly sessionSelection?: PiSessionSelection;
28
52
  readonly sessionForkPrompt?: PiSessionForkPrompt;
@@ -41,14 +65,20 @@ export interface PiEngineAdapterOptions {
41
65
  * mode. Returns display names of packages with updates available.
42
66
  */
43
67
  readonly checkPackageUpdates?: PiEnginePackageUpdateProbe;
44
- /** Comparison profiles preserve Pi's startup changelog; bare A1 owns release-note startup. */
45
- readonly announceStartupChangelog?: boolean;
46
68
  readonly repositoryContextReader?: PiRepositoryContextReader;
47
69
  }
48
- /** Owns the pinned Pi session lifecycle and translates its events into the neutral agent-engine contract. */
49
- export declare class PiEngineAdapter implements OwnedUiPromptSuggestionGeneratorPort {
70
+ /** Owns the pinned Pi session lifecycle and serves it to the owned shell as the neutral session backend. */
71
+ export declare class PiEngineAdapter implements OwnedUiSessionBackend, OwnedUiPromptSuggestionGeneratorPort {
50
72
  #private;
51
- constructor(options?: PiEngineAdapterOptions);
73
+ constructor(options: PiEngineAdapterOptions);
74
+ get identity(): OwnedUiSessionIdentityPort;
75
+ get session(): OwnedUiSessionPort;
76
+ get workflows(): OwnedUiWorkflowPort;
77
+ get settings(): OwnedUiSessionSettingsPort;
78
+ get catalog(): OwnedUiSessionCatalogPort;
79
+ get extensions(): OwnedUiExtensionPort;
80
+ /** The Pi objects behind pinned selectors and renderers, for the session presenters owner only. */
81
+ presentationSource(): PiSessionPresentationSource;
52
82
  setWorkflowInteractionHost(interaction: PiWorkflowInteractionHost): void;
53
83
  get sessionId(): string;
54
84
  get sessionGeneration(): number;
@@ -65,14 +95,14 @@ export declare class PiEngineAdapter implements OwnedUiPromptSuggestionGenerator
65
95
  * pinned Pi's `Update Available` notice; it arrives whenever the check resolves, so a late
66
96
  * result is appended to the transcript like Pi's own fire-and-forget version check.
67
97
  */
68
- announceReleaseUpdate(release: {
69
- readonly version: string;
70
- readonly command: string;
71
- readonly changelogUrl: string | null;
72
- }): void;
98
+ announceReleaseUpdate(release: OwnedUiReleaseUpdate): void;
73
99
  suggestionReasoningPolicy(): OwnedUiPromptSuggestionReasoning;
74
100
  generate(request: OwnedUiPromptSuggestionRequest): Promise<OwnedUiPromptSuggestionResult>;
75
101
  start(): Promise<OwnedUiSessionViewModel>;
102
+ /** Announce pinned Pi's changelog since the profile's last seen version; the host calls this once per process. */
103
+ announceStartupChangelog(): Promise<void>;
104
+ /** Probe extension packages for updates and announce them; the host calls this once per process. */
105
+ announcePackageUpdates(): Promise<void>;
76
106
  onEvent(listener: (event: OwnedUiEvent) => void): () => void;
77
107
  /** Developer-only pressure evidence; never mirrored into visible diagnostic/status arrays. */
78
108
  deliveryDiagnostics(): {
@@ -93,13 +123,11 @@ export declare class PiEngineAdapter implements OwnedUiPromptSuggestionGenerator
93
123
  extensionResources(): readonly OwnedPiExtensionResourceSummary[];
94
124
  workflowAutocompleteCommands(): readonly PiWorkflowAutocompleteCommand[];
95
125
  visualExtensionSupport(): OwnedPiVisualExtensionSupport;
96
- bindExtensionUi(ui: unknown, shutdown?: () => void | Promise<void>): Promise<void>;
126
+ bindExtensionUi(ui: OwnedUiExtensionUiPort, shutdown?: () => void | Promise<void>): Promise<void>;
97
127
  unbindExtensionUi(): Promise<void>;
98
128
  cycleModelWorkflow(direction: "forward" | "backward"): Promise<PiWorkflowResult>;
99
- pinnedModelSelectorContext(): ReturnType<PiWorkflowContexts["pinnedModelSelectorContext"]>;
100
129
  pinnedProjectTrustContext(): PiProjectTrustContext;
101
130
  persistProjectTrust(updates: readonly PiProjectTrustUpdate[]): void;
102
- pinnedSessionSelectorContext(): PiSessionSelectorContext;
103
131
  pinnedScopedModelsContext(): PiScopedModelsContext;
104
132
  updateScopedModels(enabledModelIds: readonly string[] | null): void;
105
133
  persistScopedModels(enabledModelIds: readonly string[] | null): void;
@@ -116,7 +144,6 @@ export declare class PiEngineAdapter implements OwnedUiPromptSuggestionGenerator
116
144
  pinnedAmbientAuthentication(selection: string): ReturnType<PiWorkflowContexts["pinnedAmbientAuthentication"]>;
117
145
  pinnedLogoutOptions(): Promise<readonly PiAuthenticationProviderOption[]>;
118
146
  pinnedForkOptions(): readonly PiWorkflowOption[];
119
- pinnedTreeSelectorContext(): PiTreeSelectorContext;
120
147
  /** Bind the owned UI's clipboard lifecycle without changing the comparison host. True means acknowledged delivery. */
121
148
  bindClipboardWriter(writer: (text: string) => Promise<boolean>): () => void;
122
149
  /** Workflow and tree copying share the active owner's write fence and delivery acknowledgment. */
@@ -138,17 +165,10 @@ export declare class PiEngineAdapter implements OwnedUiPromptSuggestionGenerator
138
165
  get settingsProductMode(): "bare" | "comparison";
139
166
  bindSettingsOwner(owner: AgentSettingOwner, handlers: PiSettingOwnerHandlers): () => void;
140
167
  pinnedSettingsSnapshot(): PiPinnedSettingsSnapshot;
141
- applyPinnedSettingValue(callback: PiPinnedSettingsCallback, value: unknown): Promise<PiWorkflowResult>;
142
- pinnedMessageRenderer(customType: string): unknown;
143
- pinnedShortcutDescriptions(bindings: Parameters<AgentSession["extensionRunner"]["getShortcuts"]>[0]): readonly {
144
- readonly key: string;
145
- readonly description: string;
146
- }[];
147
- pinnedToolRenderers(toolName: string): unknown;
148
168
  clearQueuedWorkflows(): readonly string[];
149
169
  view(): OwnedUiSessionViewModel;
150
170
  snapshot(): OwnedUiSnapshot;
151
171
  execute(command: OwnedUiCommand): Promise<AdapterCommandResult>;
152
172
  dispose(): Promise<void>;
153
173
  }
154
- export declare function createPiEngineAdapter(options?: PiEngineAdapterOptions): Promise<PiEngineAdapter>;
174
+ export declare function createPiEngineAdapter(options: PiEngineAdapterOptions): Promise<PiEngineAdapter>;