@timurproko/a1 0.2.6-dev.717 → 0.2.6-dev.734

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 (213) hide show
  1. package/bin/cli.js +13 -2
  2. package/bin/ui.js +13 -0
  3. package/dist/app/session-shell/clipboard-services.d.ts +19 -0
  4. package/dist/app/session-shell/clipboard-services.js +7 -0
  5. package/dist/app/session-shell/exit-notice.d.ts +9 -5
  6. package/dist/app/session-shell/exit-notice.js +5 -5
  7. package/dist/app/session-shell/index.d.ts +3 -1
  8. package/dist/app/session-shell/index.js +1 -0
  9. package/dist/app/session-shell/paste-preparation-client.d.ts +3 -0
  10. package/dist/app/session-shell/paste-preparation-client.js +5 -2
  11. package/dist/app/session-shell/path-chip-presentation.d.ts +10 -3
  12. package/dist/app/session-shell/path-chip-presentation.js +48 -6
  13. package/dist/app/session-shell/prompt-chips.js +30 -4
  14. package/dist/app/session-shell/prompt-suggestion-controller.d.ts +5 -4
  15. package/dist/app/session-shell/prompt-suggestion-controller.js +148 -58
  16. package/dist/app/session-shell/quit-outro.d.ts +3 -1
  17. package/dist/app/session-shell/quit-outro.js +23 -8
  18. package/dist/app/session-shell/response-copy-transport.d.ts +6 -1
  19. package/dist/app/session-shell/response-copy-transport.js +8 -2
  20. package/dist/app/session-shell/session-shell-root.d.ts +22 -11
  21. package/dist/app/session-shell/session-shell-root.js +19 -12
  22. package/dist/app/session-shell/session-shell.d.ts +19 -21
  23. package/dist/app/session-shell/session-shell.js +678 -840
  24. package/dist/app/session-shell/session-viewport-controller.js +33 -21
  25. package/dist/cli/dispatch.js +5 -3
  26. package/dist/cli/session-context.d.ts +5 -1
  27. package/dist/cli/session-context.js +25 -8
  28. package/dist/composition/owned-ui.d.ts +23 -2
  29. package/dist/composition/owned-ui.js +124 -33
  30. package/dist/composition/session-info-reference.d.ts +2 -2
  31. package/dist/composition/session-info-reference.js +2 -2
  32. package/dist/composition/settings-route-host.js +2 -1
  33. package/dist/contracts/agent-engine/capability-ports.d.ts +1 -85
  34. package/dist/contracts/agent-engine/capability-ports.js +1 -35
  35. package/dist/contracts/agent-engine/index.d.ts +1 -7
  36. package/dist/contracts/agent-engine/index.js +0 -4
  37. package/dist/contracts/owned-ui/index.d.ts +9 -3
  38. package/dist/contracts/owned-ui/index.js +2 -1
  39. package/dist/contracts/owned-ui/model.d.ts +10 -0
  40. package/dist/contracts/owned-ui/session-backend.d.ts +119 -0
  41. package/dist/contracts/owned-ui/session-presenters.d.ts +55 -0
  42. package/dist/contracts/owned-ui/session-presenters.js +1 -0
  43. package/dist/contracts/owned-ui/session-workflows.d.ts +342 -0
  44. package/dist/contracts/owned-ui/session-workflows.js +30 -0
  45. package/dist/contracts/owned-ui/suggestion-diagnostics.d.ts +5 -1
  46. package/dist/contracts/owned-ui/suggestion-diagnostics.js +3 -1
  47. package/dist/contracts/owned-ui/validation.js +7 -0
  48. package/dist/features/launch/index.d.ts +1 -1
  49. package/dist/features/launch/session-context.d.ts +17 -2
  50. package/dist/features/launch/session-context.js +9 -5
  51. package/dist/features/owned-ui/settings-app.js +56 -54
  52. package/dist/features/prompt-suggestions/diagnostics.js +4 -1
  53. package/dist/foundation/lifecycle/index.d.ts +2 -2
  54. package/dist/foundation/lifecycle/index.js +1 -1
  55. package/dist/foundation/lifecycle/session-repository-context.d.ts +19 -2
  56. package/dist/foundation/lifecycle/session-repository-context.js +434 -66
  57. package/dist/foundation/process-containment/index.d.ts +1 -0
  58. package/dist/foundation/process-containment/index.js +1 -0
  59. package/dist/foundation/process-containment/native-process-inspector.d.ts +3 -0
  60. package/dist/foundation/process-containment/native-process-inspector.js +21 -0
  61. package/dist/foundation/release/bootstrap.js +1 -2
  62. package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
  63. package/dist/foundation/release/progress-palette.generated.js +2 -2
  64. package/dist/foundation/release/release-gc.js +1 -1
  65. package/dist/foundation/release/update.js +0 -4
  66. package/dist/foundation/startup/startup-descriptor.js +2 -2
  67. package/dist/foundation/storage/control-store.js +0 -12
  68. package/dist/integrations/pi/components/components.js +2 -18
  69. package/dist/integrations/pi/components/index.d.ts +4 -4
  70. package/dist/integrations/pi/components/index.js +2 -2
  71. package/dist/integrations/pi/components/modal-frame.js +3 -4
  72. package/dist/integrations/pi/components/models-dialog.js +6 -35
  73. package/dist/integrations/pi/components/prompt-input-port.d.ts +1 -0
  74. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
  75. package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
  76. package/dist/integrations/pi/components/share-operation-dialog.js +3 -3
  77. package/dist/integrations/pi/components/shell-editor-autocomplete.js +19 -16
  78. package/dist/integrations/pi/components/shell-extension-ui.d.ts +5 -3
  79. package/dist/integrations/pi/components/shell-extension-ui.js +26 -12
  80. package/dist/integrations/pi/components/shell-hotkey-sections.js +2 -2
  81. package/dist/integrations/pi/components/shell-presenters-info.js +10 -10
  82. package/dist/integrations/pi/components/shell-presenters-transcript.js +13 -13
  83. package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -6
  84. package/dist/integrations/pi/components/shell-shared-facade.d.ts +21 -1
  85. package/dist/integrations/pi/components/shell-shared-facade.js +19 -3
  86. package/dist/integrations/pi/components/skills-dialog.js +3 -3
  87. package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -3
  88. package/dist/integrations/pi/components/theme.d.ts +9 -0
  89. package/dist/integrations/pi/components/theme.js +30 -0
  90. package/dist/integrations/pi/components/tool-result-adapter.js +6 -1
  91. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  92. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
  93. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  94. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  95. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  96. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  97. package/dist/integrations/pi/components/upstream/components/extension-editor.js +6 -6
  98. package/dist/integrations/pi/components/upstream/components/extension-input.js +4 -4
  99. package/dist/integrations/pi/components/upstream/components/extension-selector.js +4 -4
  100. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  101. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +5 -5
  102. package/dist/integrations/pi/components/upstream/components/owned-editor.js +8 -5
  103. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  104. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
  105. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +3 -3
  106. package/dist/integrations/pi/components/upstream/components/session-footer.js +1 -1
  107. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  108. package/dist/integrations/pi/components/upstream/components/session-selector.js +9 -9
  109. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +3 -2
  110. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +6 -3
  111. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
  112. package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
  113. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  114. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  115. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
  116. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +2 -2
  117. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +4 -0
  118. package/dist/integrations/pi/components/upstream/components/tool-execution.js +11 -1
  119. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +2 -2
  120. package/dist/integrations/pi/components/upstream/components/tree-selector.js +27 -18
  121. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  122. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  123. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +4 -4
  124. package/dist/integrations/pi/components/upstream/history/editor-core.js +11 -7
  125. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  126. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  127. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  128. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  129. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  130. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  131. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  132. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  133. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +31 -0
  134. package/dist/integrations/pi/components/upstream/program-status-reporter.js +89 -0
  135. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  136. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +22 -1
  137. package/dist/integrations/pi/components/upstream/theme/theme.js +225 -10
  138. package/dist/integrations/pi/engine/adapter.d.ts +44 -24
  139. package/dist/integrations/pi/engine/adapter.js +130 -22
  140. package/dist/integrations/pi/engine/command-dispatch.d.ts +2 -5
  141. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -11
  142. package/dist/integrations/pi/engine/host-ports.d.ts +20 -0
  143. package/dist/integrations/pi/engine/host-ports.js +13 -0
  144. package/dist/integrations/pi/engine/host.d.ts +70 -0
  145. package/dist/integrations/pi/engine/host.js +147 -0
  146. package/dist/integrations/pi/engine/index.d.ts +8 -4
  147. package/dist/integrations/pi/engine/index.js +3 -1
  148. package/dist/integrations/pi/engine/pi-settings-metadata.json +1 -1
  149. package/dist/integrations/pi/engine/resource-catalog.d.ts +4 -23
  150. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  151. package/dist/integrations/pi/engine/runtime-integration.d.ts +8 -2
  152. package/dist/integrations/pi/engine/runtime-integration.js +12 -7
  153. package/dist/integrations/pi/engine/session-events.js +10 -2
  154. package/dist/integrations/pi/engine/session-integration.d.ts +3 -8
  155. package/dist/integrations/pi/engine/session-integration.js +0 -49
  156. package/dist/integrations/pi/engine/session-runtime.d.ts +18 -3
  157. package/dist/integrations/pi/engine/session-runtime.js +18 -7
  158. package/dist/integrations/pi/engine/settings-bridge.d.ts +2 -2
  159. package/dist/integrations/pi/engine/settings-bridge.js +0 -2
  160. package/dist/integrations/pi/engine/settings-port.d.ts +2 -0
  161. package/dist/integrations/pi/engine/settings-port.js +3 -5
  162. package/dist/integrations/pi/engine/transcript-projection.js +2 -1
  163. package/dist/integrations/pi/engine/workflows.d.ts +33 -260
  164. package/dist/integrations/pi/engine/workflows.js +6 -28
  165. package/dist/integrations/pi/session-presenters/index.d.ts +2 -0
  166. package/dist/integrations/pi/session-presenters/index.js +1 -0
  167. package/dist/integrations/pi/session-presenters/presenters.d.ts +16 -0
  168. package/dist/integrations/pi/session-presenters/presenters.js +341 -0
  169. package/dist/integrations/pi/startup-public.js +306 -290
  170. package/dist/integrations/pi/startup-public.manifest.json +289 -265
  171. package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -1
  172. package/dist/integrations/pi/tui-runtime/adapter.js +7 -2
  173. package/dist/integrations/pi/tui-runtime/contracts.d.ts +3 -1
  174. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +8 -1
  175. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +67 -2
  176. package/dist/integrations/pi/tui-runtime/index.d.ts +1 -1
  177. package/dist/integrations/pi/tui-runtime/index.js +1 -1
  178. package/dist/native/darwin-arm64/manifest.json +1 -1
  179. package/dist/native/linux-x64/manifest.json +1 -1
  180. package/dist/native/win32-x64/manifest.json +2 -2
  181. package/dist/native/win32-x64/process-guardian.exe +0 -0
  182. package/dist/product-identity.d.ts +2 -2
  183. package/dist/product-identity.js +2 -2
  184. package/dist/product-identity.json +3 -1
  185. package/dist/runtime-payload-inventory.json +3092 -2878
  186. package/dist/ui/components/prompt-input.d.ts +2 -0
  187. package/dist/ui/components/prompt-input.js +5 -1
  188. package/dist/ui/components/text-selection.d.ts +1 -1
  189. package/dist/ui/components/text-selection.js +3 -1
  190. package/dist/ui/components/theme.d.ts +2 -0
  191. package/dist/ui/components/transcript-viewport.d.ts +6 -4
  192. package/dist/ui/components/transcript-viewport.js +94 -16
  193. package/dist/ui/components/value-menu.d.ts +2 -0
  194. package/dist/ui/components/value-menu.js +13 -8
  195. package/dist/ui/settings/declarations.d.ts +38 -14
  196. package/dist/ui/settings/declarations.js +35 -11
  197. package/dist/ui/settings/migrations.js +23 -0
  198. package/docs/architecture/boundaries.md +9 -1
  199. package/docs/architecture/project-structure.md +7 -5
  200. package/docs/architecture/prompt-suggestions.md +14 -10
  201. package/docs/local-worktree-cleanup.md +11 -5
  202. package/docs/openspec-archive-automation.md +6 -5
  203. package/package.json +3 -3
  204. package/dist/contracts/agent-engine/model.d.ts +0 -78
  205. package/dist/contracts/agent-engine/model.js +0 -1
  206. package/dist/contracts/agent-engine/ports.d.ts +0 -18
  207. package/dist/contracts/agent-engine/serialization.d.ts +0 -7
  208. package/dist/contracts/agent-engine/serialization.js +0 -58
  209. package/dist/contracts/agent-engine/validation.d.ts +0 -5
  210. package/dist/contracts/agent-engine/validation.js +0 -128
  211. package/dist/integrations/pi/components/upstream/theme/system-theme.d.ts +0 -61
  212. package/dist/integrations/pi/components/upstream/theme/system-theme.js +0 -709
  213. /package/dist/contracts/{agent-engine/ports.js → owned-ui/session-backend.js} +0 -0
@@ -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); }
@@ -10,7 +10,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
10
10
  ],
11
11
  "generatedArtifact": {
12
12
  "path": "dist/integrations/pi/startup-public.js",
13
- "sha256": "2adac500d8cebd5f7805c18a549ec0c6b23f13bd10ee5f3f463a6758f489e410"
13
+ "sha256": "62906f5056fabed7a83b97843e3a407c955103ab2bb7849e6713026fe7c760a9"
14
14
  },
15
15
  "dependencyLayerIdentity": {
16
16
  "source": "A1_RELEASE_LAYERS",
@@ -19,7 +19,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
19
19
  "compileCacheNamespace": {
20
20
  "strategy": "node-abi-version-and-ordered-layer-sha256-v1"
21
21
  },
22
- "identity": "b010b97970c6c40fe160224121793bf0b26d7c77e7860d8e787aaeb912333100"
22
+ "identity": "089bcfdc784e7d61cd028ede3b5546864ab49e6329e1296ed55afacb16bcb077"
23
23
  });
24
24
 
25
25
  export function loadDeclaredStartupGraph() {
@@ -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 = {
@@ -1,6 +1,6 @@
1
1
  import { AssistantMessageComponent, ToolExecutionComponent, UserMessageComponent, } from "../startup-public.js";
2
2
  import { createTuiFacade, validatedAssistantMessage } from "./shell-components.js";
3
- import { ensurePiTheme } from "./theme.js";
3
+ import { ensurePiTheme, getPiMarkdownTheme } from "./theme.js";
4
4
  export function adaptPiUserMessage(block, width) {
5
5
  requireBlock(block, "user");
6
6
  ensurePiTheme();
@@ -9,7 +9,7 @@ export function adaptPiUserMessage(block, width) {
9
9
  export function adaptPiAssistantMessage(block, width) {
10
10
  requireBlock(block, "assistant");
11
11
  ensurePiTheme();
12
- return new AssistantMessageComponent(validatedAssistantMessage(block), false).render(width);
12
+ return new AssistantMessageComponent(validatedAssistantMessage(block), false, getPiMarkdownTheme()).render(width);
13
13
  }
14
14
  export function adaptPiToolExecution(block, width, cwd) {
15
15
  if (block.kind !== "tool-call" && block.kind !== "tool-result") {
@@ -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,12 +3,12 @@ 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, currentPiThemeName, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, stopPiThemeWatcher, } from "./theme.js";
11
- export type { PiColorMode, PiTerminalTheme, PiTerminalThemeDetection, PiTerminalThemeDetector, PiThemeBackground, PiThemeResult } 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
+ 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";
14
14
  export { PI_MODAL_CONTENT_PADDING_X, PiModalFrame, PiModalHeader, addPiModalHeader, adoptPiModalFrame, adoptPiModalHeader, } from "./modal-frame.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, currentPiThemeName, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, 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";
@@ -1,6 +1,6 @@
1
1
  import { CancellableLoader, Container, Spacer, Text } from "@earendil-works/pi-tui";
2
2
  import { DynamicBorder } from "../startup-public.js";
3
- import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints } from "./theme.js";
3
+ import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "./theme.js";
4
4
  export const PI_MODAL_CONTENT_PADDING_X = 1;
5
5
  /** Adds the standard navigation/select/close footer before a dependency component's bottom rule. */
6
6
  export function addPiModalSelectFooter(container) {
@@ -14,14 +14,13 @@ export class PiCancellableOperationFrame extends Container {
14
14
  constructor(tui, message) {
15
15
  super();
16
16
  const theme = piTheme();
17
- const border = (text) => theme.fg("border", text);
18
17
  this.#loader = new CancellableLoader(tui, text => theme.fg("accent", text), text => theme.fg("muted", text), message);
19
- this.addChild(new DynamicBorder(border));
18
+ this.addChild(new DynamicBorder(paintPiBorder));
20
19
  this.addChild(this.#loader);
21
20
  this.addChild(new Spacer(1));
22
21
  this.addChild(new Text(renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]), 0, 0));
23
22
  this.addChild(new Spacer(1));
24
- this.addChild(new DynamicBorder(border));
23
+ this.addChild(new DynamicBorder(paintPiBorder));
25
24
  adoptPiModalFrame(this, { topIndex: 0, bottomIndex: this.children.length - 1 });
26
25
  }
27
26
  get signal() { return this.#loader.signal; }
@@ -1,7 +1,7 @@
1
1
  import { Input, getKeybindings, matchesKey, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
2
2
  import { DynamicBorder } from "../startup-public.js";
3
3
  import { PiModalFrame } from "./modal-frame.js";
4
- import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
4
+ import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
5
5
  function renderHintsWithClose(entries, width) {
6
6
  const body = renderPiModalShortcutHints(entries.slice(0, -1));
7
7
  const close = renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]);
@@ -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; }
@@ -51,7 +50,7 @@ export class ModelsDialogComponent {
51
50
  invalidate: () => this.#input.invalidate(),
52
51
  render: width => this.#renderBody(width),
53
52
  };
54
- #frame = new PiModalFrame(new DynamicBorder(), [this.#title, this.#body], new DynamicBorder());
53
+ #frame = new PiModalFrame(new DynamicBorder(paintPiBorder), [this.#title, this.#body], new DynamicBorder(paintPiBorder));
55
54
  #callbacks;
56
55
  #models = [];
57
56
  #activeModelId;
@@ -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 = [];
@@ -286,9 +257,9 @@ export class ModelsDialogComponent {
286
257
  const rows = this.#rows();
287
258
  this.#clampSelection(rows);
288
259
  push(theme.fg("dim", "Filter: ")
289
- + theme.fg(this.#filter === "all" ? "accent" : "dim", "all")
260
+ + theme.fg(this.#filter === "all" ? "mdHeading" : "dim", "all")
290
261
  + theme.fg("dim", " | ")
291
- + theme.fg(this.#filter === "scoped" ? "accent" : "dim", "scoped"));
262
+ + theme.fg(this.#filter === "scoped" ? "mdHeading" : "dim", "scoped"));
292
263
  push();
293
264
  for (const line of this.#input.render(width))
294
265
  push(line);
@@ -305,7 +276,7 @@ export class ModelsDialogComponent {
305
276
  const scoped = this.#scopeIds.includes(row.fullId);
306
277
  // Invariant: arrow, scope marker, model id, [provider], then the active checkmark.
307
278
  const prefix = selected ? theme.fg("accent", "→ ") : " ";
308
- const marker = scoped ? theme.fg("accent", "●") : theme.fg("dim", "○");
279
+ const marker = scoped ? theme.fg("text", "●") : theme.fg("dim", "○");
309
280
  const label = selected ? theme.fg("text", row.model.id) : row.model.id;
310
281
  const provider = theme.fg("muted", `[${row.model.provider}]`);
311
282
  const active = row.fullId === this.#activeModelId ? ` ${theme.fg("success", "✓")}` : "";
@@ -10,6 +10,7 @@ export interface PiShellPromptInputBody {
10
10
  readonly topRule?: string | undefined;
11
11
  readonly bottomRule?: string | undefined;
12
12
  readonly after?: readonly string[];
13
+ readonly afterIndent?: number;
13
14
  }
14
15
  export interface PiShellPromptInputPresentation {
15
16
  geometry(width: number, padding?: number): PiShellPromptInputGeometry;
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.0.4 (MIT),
3
- * commit 7c10bd4337495ee613f2224843ecdf349b80d1df.
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
+ * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
4
  * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
5
  * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.0.4 (MIT),
3
- * commit 7c10bd4337495ee613f2224843ecdf349b80d1df.
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
+ * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
4
  * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
5
  * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
@@ -1,7 +1,7 @@
1
1
  import { CancellableLoader, Spacer, Text, } from "@earendil-works/pi-tui";
2
2
  import { BorderedLoader, DynamicBorder } from "../startup-public.js";
3
3
  import { adoptPiModalFrame, PiModalFrame } from "./modal-frame.js";
4
- import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints } from "./theme.js";
4
+ import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "./theme.js";
5
5
  import { componentPort, createTuiFacade, ensureTheme, } from "./shell-shared-facade.js";
6
6
  /** Bare A1's titled share progress surface; the pinned comparison keeps its bordered loader. */
7
7
  class ShareOperationDialog {
@@ -10,12 +10,12 @@ class ShareOperationDialog {
10
10
  constructor(runtime, message) {
11
11
  const theme = piTheme();
12
12
  this.#loader = new CancellableLoader(createTuiFacade(runtime), text => theme.fg("accent", text), text => theme.fg("muted", text), message);
13
- this.#frame = new PiModalFrame(new DynamicBorder(text => theme.fg("border", text)), [
13
+ this.#frame = new PiModalFrame(new DynamicBorder(paintPiBorder), [
14
14
  new Text(theme.fg("accent", theme.bold("Share")), 0, 0),
15
15
  this.#loader,
16
16
  new Spacer(1),
17
17
  new Text(renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]), 0, 0),
18
- ], new DynamicBorder(text => theme.fg("border", text)));
18
+ ], new DynamicBorder(paintPiBorder));
19
19
  }
20
20
  get signal() { return this.#loader.signal; }
21
21
  invalidate() { this.#frame.invalidate(); }
@@ -1,14 +1,14 @@
1
- import { getSelectListTheme } from "../startup-public.js";
2
- import { CombinedAutocompleteProvider, matchesKey, setKeybindings, visibleWidth, } from "@earendil-works/pi-tui";
1
+ import { CombinedAutocompleteProvider, matchesKey, visibleWidth, } from "@earendil-works/pi-tui";
3
2
  import { PROMPT_HISTORY_EDITOR_REPLACEMENT } from "../../../contracts/owned-ui/index.js";
4
- import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
5
3
  import { OwnedEditor } from "./upstream/components/owned-editor.js";
6
4
  import { OwnedEditorUxInterception, createPromptSelectionInterceptor, editorVisualLineCount, } from "./owned-editor-ux.js";
7
- import { PINNED_PI_LAYOUT, piTheme, renderPiListSelection, } from "./theme.js";
8
- import { createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
5
+ import { PINNED_PI_LAYOUT, getPiSelectListTheme, piTheme, renderPiListSelection, } from "./theme.js";
6
+ import { createPiKeybindingsHost, createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
9
7
  import { SKILLS_COMMAND_NAME, collapseSkillCommands, createSkillsTunnelProvider, } from "./skills-command.js";
10
8
  /** A selected autocomplete row: its arrow/primary column, then the aligned description. */
11
9
  const SELECTED_DESCRIBED_ROW = /^(→ .*?\S)(\s{2,}.*)$/u;
10
+ const INPUT_COUNTER_INSET = 3;
11
+ const INPUT_COUNTER_PREFIX = "── ";
12
12
  function renderOwnedAutocompleteSelection(text) {
13
13
  const theme = piTheme();
14
14
  const row = SELECTED_DESCRIBED_ROW.exec(text);
@@ -62,15 +62,18 @@ export function createPiShellEditor(options) {
62
62
  ensureTheme();
63
63
  const tui = createTuiFacade(options);
64
64
  const inputPresentation = options.keybindingProfile === "a1" ? options.promptPresentation?.input : undefined;
65
- const keybindings = options.keybindingProfile === "a1"
66
- ? KeybindingsManager.createForOwnedInput(options.agentDir)
67
- : KeybindingsManager.create(options.agentDir);
68
- 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;
69
72
  if (options.persistentHistory === true && options.keybindingProfile === "a1" && options.historyEditor === undefined) {
70
73
  throw new Error("Persistent history requires the loaded owned editor");
71
74
  }
72
75
  const scrollInfo = { emitted: false, counter: undefined };
73
- const selectListTheme = getSelectListTheme();
76
+ const selectListTheme = getPiSelectListTheme();
74
77
  let tunnelSkills = [];
75
78
  const EditorClass = options.keybindingProfile === "a1" && options.persistentHistory === true ? options.historyEditor : OwnedEditor;
76
79
  const editor = new EditorClass(tui, {
@@ -234,10 +237,10 @@ export function createPiShellEditor(options) {
234
237
  const rowCount = editor.getRenderedBodyRowCount();
235
238
  const menu = rows.slice(rowCount, scrollInfo.emitted ? -1 : undefined);
236
239
  const label = scrollInfo.counter === undefined ? "" : `${scrollInfo.counter} `;
237
- // Compatibility: match the history border's four-cell inset and dim label style.
238
- const counterBorder = label.length > 0 && 4 + visibleWidth(label) <= width
239
- ? editor.borderColor("─── ") + piTheme().fg("dim", label)
240
- + editor.borderColor("─".repeat(width - 4 - visibleWidth(label)))
240
+ // Compatibility: share the history counter's three-cell inset and dim label style.
241
+ const counterBorder = label.length > 0 && INPUT_COUNTER_INSET + visibleWidth(label) <= width
242
+ ? editor.borderColor(INPUT_COUNTER_PREFIX) + piTheme().fg("dim", label)
243
+ + editor.borderColor("─".repeat(width - INPUT_COUNTER_INSET - visibleWidth(label)))
241
244
  : editor.borderColor("─".repeat(width));
242
245
  // Rationale: when the menu is open, drop the plain top border above the
243
246
  // menu and instead show the counter on the border directly above the input
@@ -250,9 +253,9 @@ export function createPiShellEditor(options) {
250
253
  // Completion state, sizing, styles, and pagination still belong to the editor.
251
254
  return [...menu, ...bodyRows];
252
255
  },
253
- activateKeybindings: () => setKeybindings(keybindings),
256
+ activateKeybindings: () => host.ensureActive(),
254
257
  keybindingConfig: () => keybindings.getEffectiveConfig(),
255
- reloadKeybindings: () => { keybindings.reload(); setKeybindings(keybindings); },
258
+ reloadKeybindings: () => host.reload(),
256
259
  matchesTerminalKey: (data, key) => matchesKey(data, key),
257
260
  handleInput: data => {
258
261
  // Compatibility: an unassigned reverse Tab must not clear selection or reach autocomplete fallback.
@@ -1,10 +1,11 @@
1
- import { type ExtensionUIContext } from "../startup-public.js";
2
- import type { OwnedUiExtensionOverlayHandle, OwnedUiExtensionOverlayOptions } from "../../../contracts/owned-ui/index.js";
1
+ import type { ProgramStatusBlocked } from "./upstream/program-status-reporter.js";
2
+ import { type OwnedUiExtensionOverlayHandle, type OwnedUiExtensionOverlayOptions, type OwnedUiExtensionUiPort } from "../../../contracts/owned-ui/index.js";
3
3
  import { type PiShellComponentPort, type PiShellEditorOptions } from "./shell-shared-facade.js";
4
4
  export interface PiExtensionUiBridgeHost {
5
5
  readonly runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">;
6
6
  readonly agentDir?: string;
7
7
  setInputSurface(component: PiShellComponentPort | null): void;
8
+ setProgramStatusBlocked(status: ProgramStatusBlocked | undefined): void;
8
9
  showOverlay(component: PiShellComponentPort, options?: OwnedUiExtensionOverlayOptions): OwnedUiExtensionOverlayHandle;
9
10
  listenInput(handler: (data: string) => {
10
11
  readonly consume?: boolean;
@@ -27,7 +28,8 @@ export interface PiExtensionUiBridgeHost {
27
28
  setToolsExpanded(expanded: boolean): void;
28
29
  }
29
30
  export interface PiExtensionUiBridge {
30
- 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;
31
33
  input(title: string, placeholder: string, options?: {
32
34
  readonly retainSurfaceOnSettle?: boolean;
33
35
  }): Promise<string | undefined>;
@@ -1,17 +1,18 @@
1
- import { getSelectListTheme, } from "../startup-public.js";
1
+ 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
- import { PINNED_PI_LAYOUT, applyPiTheme, applyPiThemeInstance, getAvailablePiThemes, loadPiTheme, piTheme, } from "./theme.js";
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";
9
10
  /** Public ExtensionUIContext ported from pinned InteractiveMode without constructing it. */
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;
@@ -45,7 +46,7 @@ export function createPiExtensionUiBridge(host) {
45
46
  disposers.delete(dispose);
46
47
  };
47
48
  };
48
- const showInput = (create, options, retainSurfaceOnSettle = false) => new Promise(resolve => {
49
+ const showInput = (create, options, retainSurfaceOnSettle = false, blocked) => new Promise(resolve => {
49
50
  let settled = false;
50
51
  let surface;
51
52
  let untrack = () => { };
@@ -56,10 +57,13 @@ export function createPiExtensionUiBridge(host) {
56
57
  if (activeCancel === cancel)
57
58
  activeCancel = undefined;
58
59
  untrack();
59
- if (retainSurfaceOnSettle && activeSurface === surface)
60
+ const ownedSurface = activeSurface === surface;
61
+ if (retainSurfaceOnSettle && ownedSurface)
60
62
  activeSurface = undefined;
61
63
  else
62
64
  closeSurface(surface);
65
+ if (ownedSurface)
66
+ host.setProgramStatusBlocked(undefined);
63
67
  resolve(value);
64
68
  };
65
69
  const cancel = () => finish(undefined);
@@ -68,6 +72,7 @@ export function createPiExtensionUiBridge(host) {
68
72
  if (!settled) {
69
73
  activeCancel = cancel;
70
74
  mountSurface(surface);
75
+ host.setProgramStatusBlocked(blocked);
71
76
  }
72
77
  });
73
78
  const createFactoryComponent = (factory, ...arguments_) => {
@@ -85,14 +90,19 @@ export function createPiExtensionUiBridge(host) {
85
90
  tui,
86
91
  ...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
87
92
  onToggleToolsExpanded: () => host.setToolsExpanded(!host.getToolsExpanded()),
88
- })), opts),
93
+ })), opts, false, { kind: "question", message: title }),
89
94
  async confirm(title, message, opts) {
90
- return (await context.select(`${title}\n${message}`, ["Yes", "No"], opts)) === "Yes";
95
+ const selected = await showInput((resolve, cancel) => componentPort(new ExtensionSelectorComponent(`${title}\n${message}`, ["Yes", "No"], resolve, cancel, {
96
+ tui,
97
+ ...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
98
+ onToggleToolsExpanded: () => host.setToolsExpanded(!host.getToolsExpanded()),
99
+ })), opts, false, { kind: "permission", message: title });
100
+ return selected === "Yes";
91
101
  },
92
102
  input: (title, placeholder, opts) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, {
93
103
  tui,
94
104
  ...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
95
- })), opts),
105
+ })), opts, false, { kind: "question", message: title }),
96
106
  notify: (message, type = "info") => host.notify(message, type),
97
107
  onTerminalInput: handler => host.listenInput(handler),
98
108
  setStatus: (key, text) => host.setStatus(key, text),
@@ -196,7 +206,7 @@ export function createPiExtensionUiBridge(host) {
196
206
  pasteToEditor: text => host.pasteToEditor(text),
197
207
  setEditorText: text => host.setEditorText(text),
198
208
  getEditorText: () => host.getEditorText(),
199
- editor: (title, prefill) => showInput((resolve, cancel) => componentPort(new ExtensionEditorComponent(tui, keybindings, title, prefill, resolve, cancel))),
209
+ editor: (title, prefill) => showInput((resolve, cancel) => componentPort(new ExtensionEditorComponent(tui, keybindings, title, prefill, resolve, cancel)), undefined, false, { kind: "question", message: title }),
200
210
  addAutocompleteProvider: factory => host.addAutocompleteProvider(factory),
201
211
  setEditorComponent(factory) {
202
212
  customEditorFactory = factory;
@@ -207,7 +217,7 @@ export function createPiExtensionUiBridge(host) {
207
217
  try {
208
218
  const editor = Reflect.apply(factory, undefined, [tui, {
209
219
  borderColor: (text) => piTheme().fg("borderMuted", text),
210
- selectList: getSelectListTheme(),
220
+ selectList: getPiSelectListTheme(),
211
221
  }, keybindings]);
212
222
  if (!isComponent(editor))
213
223
  throw new TypeError("extension editor factory returned a malformed editor");
@@ -247,10 +257,14 @@ export function createPiExtensionUiBridge(host) {
247
257
  activeSurface?.dispose?.();
248
258
  activeSurface = undefined;
249
259
  host.setInputSurface(null);
260
+ host.setProgramStatusBlocked(undefined);
250
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);
251
265
  return {
252
266
  context,
253
- input: (title, placeholder, options) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, { tui })), undefined, options?.retainSurfaceOnSettle === true),
267
+ input: (title, placeholder, options) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, { tui })), undefined, options?.retainSurfaceOnSettle === true, { kind: "question", message: title }),
254
268
  reset,
255
269
  dispose() {
256
270
  reset();
@@ -1,4 +1,4 @@
1
- import { getMarkdownTheme } from "../startup-public.js";
1
+ import { getPiHotkeysMarkdownTheme } from "./theme.js";
2
2
  import { Markdown } from "@earendil-works/pi-tui";
3
3
  import { ensureTheme } from "./shell-shared-facade.js";
4
4
  import { hotkeysMarkdown } from "./shell-presenters-info.js";
@@ -19,7 +19,7 @@ export function renderPiShellHotkeySections(presentation, width) {
19
19
  while (section.lines.at(-1) === "")
20
20
  section.lines.pop();
21
21
  return sections.map(section => {
22
- const rows = [...new Markdown(section.lines.join("\n"), 1, 1, getMarkdownTheme()).render(width)];
22
+ const rows = [...new Markdown(section.lines.join("\n"), 1, 1, getPiHotkeysMarkdownTheme()).render(width)];
23
23
  while (rows[0]?.trim().length === 0)
24
24
  rows.shift();
25
25
  while (rows.at(-1)?.trim().length === 0)