@timurproko/a1 0.1.8-dev.290 → 0.1.8-dev.322

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 (112) hide show
  1. package/README.md +21 -0
  2. package/bin/guardian.js +4 -3
  3. package/bin/ui.js +4 -2
  4. package/bin/update-recovery.js +3 -1
  5. package/dist/composition/owned-ui.js +13 -1
  6. package/dist/contracts/owned-ui/index.d.ts +1 -0
  7. package/dist/contracts/owned-ui/index.js +1 -0
  8. package/dist/contracts/owned-ui/prompt-history.d.ts +37 -0
  9. package/dist/contracts/owned-ui/prompt-history.js +23 -0
  10. package/dist/features/launch/profile-paths.d.ts +2 -0
  11. package/dist/features/launch/profile-paths.js +11 -0
  12. package/dist/features/prompt-history/index.d.ts +2 -0
  13. package/dist/features/prompt-history/index.js +2 -0
  14. package/dist/features/prompt-history/paths.d.ts +4 -0
  15. package/dist/features/prompt-history/paths.js +16 -0
  16. package/dist/features/prompt-history/service.d.ts +24 -0
  17. package/dist/features/prompt-history/service.js +260 -0
  18. package/dist/features/prompt-history/store.d.ts +15 -0
  19. package/dist/features/prompt-history/store.js +166 -0
  20. package/dist/features/prompt-history/worker.d.ts +9 -0
  21. package/dist/features/prompt-history/worker.js +42 -0
  22. package/dist/foundation/launch-context/index.d.ts +29 -0
  23. package/dist/foundation/launch-context/index.js +83 -0
  24. package/dist/foundation/launch-guardian/main.js +4 -3
  25. package/dist/foundation/release/bootstrap.d.ts +1 -1
  26. package/dist/foundation/release/bootstrap.js +18 -12
  27. package/dist/foundation/release/cohort-state.d.ts +1 -0
  28. package/dist/foundation/release/cohort-state.js +4 -0
  29. package/dist/foundation/release/release-gc.js +2 -2
  30. package/dist/foundation/release/release-store.js +10 -3
  31. package/dist/foundation/release/release.d.ts +3 -1
  32. package/dist/foundation/release/release.js +7 -3
  33. package/dist/foundation/release/restart-certification.d.ts +1 -0
  34. package/dist/foundation/release/restart-certification.js +5 -0
  35. package/dist/foundation/release/update-recovery.d.ts +2 -0
  36. package/dist/foundation/release/update-recovery.js +4 -0
  37. package/dist/foundation/release/update.js +5 -0
  38. package/dist/foundation/release/warmup.d.ts +1 -1
  39. package/dist/foundation/release/warmup.js +5 -4
  40. package/dist/foundation/startup/startup-runtime.js +13 -11
  41. package/dist/foundation/supervision/main.js +8 -7
  42. package/dist/integrations/pi/components/editor-interaction.d.ts +38 -0
  43. package/dist/integrations/pi/components/editor-interaction.js +1 -0
  44. package/dist/integrations/pi/components/history-editor-loader.d.ts +5 -0
  45. package/dist/integrations/pi/components/history-editor-loader.js +5 -0
  46. package/dist/integrations/pi/components/index.d.ts +1 -0
  47. package/dist/integrations/pi/components/index.js +1 -0
  48. package/dist/integrations/pi/components/owned-editor-ux.d.ts +2 -1
  49. package/dist/integrations/pi/components/owned-editor-ux.js +95 -22
  50. package/dist/integrations/pi/components/shell-editor-autocomplete.js +12 -1
  51. package/dist/integrations/pi/components/shell-presenters-info.d.ts +9 -2
  52. package/dist/integrations/pi/components/shell-presenters-info.js +35 -4
  53. package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +3 -2
  54. package/dist/integrations/pi/components/shell-selectors-dialogs.js +8 -5
  55. package/dist/integrations/pi/components/shell-shared-facade.d.ts +15 -2
  56. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +12 -0
  57. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +25 -2
  58. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +13 -9
  59. package/dist/integrations/pi/components/upstream/components/owned-editor.js +137 -133
  60. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +280 -0
  61. package/dist/integrations/pi/components/upstream/history/editor-core.js +2062 -0
  62. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +32 -0
  63. package/dist/integrations/pi/components/upstream/history/kill-ring.js +48 -0
  64. package/dist/integrations/pi/components/upstream/history/printable-key.d.ts +1 -0
  65. package/dist/integrations/pi/components/upstream/history/printable-key.js +40 -0
  66. package/dist/integrations/pi/components/upstream/history/text-helpers.d.ts +14 -0
  67. package/dist/integrations/pi/components/upstream/history/text-helpers.js +28 -0
  68. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +22 -0
  69. package/dist/integrations/pi/components/upstream/history/undo-stack.js +36 -0
  70. package/dist/integrations/pi/components/upstream/history/word-navigation.d.ts +24 -0
  71. package/dist/integrations/pi/components/upstream/history/word-navigation.js +100 -0
  72. package/dist/integrations/pi/engine/adapter.d.ts +13 -1
  73. package/dist/integrations/pi/engine/adapter.js +86 -25
  74. package/dist/integrations/pi/engine/changelog.d.ts +2 -0
  75. package/dist/integrations/pi/engine/changelog.js +63 -0
  76. package/dist/integrations/pi/engine/resources/changelog.json +12 -0
  77. package/dist/integrations/pi/engine/workflow-controllers.d.ts +1 -1
  78. package/dist/integrations/pi/engine/workflows.d.ts +1 -1
  79. package/dist/integrations/pi/session-ui/prompt-chips.d.ts +4 -1
  80. package/dist/integrations/pi/session-ui/prompt-chips.js +40 -13
  81. package/dist/integrations/pi/session-ui/prompt-history-controller.d.ts +30 -0
  82. package/dist/integrations/pi/session-ui/prompt-history-controller.js +147 -0
  83. package/dist/integrations/pi/session-ui/session-shell-root.d.ts +33 -0
  84. package/dist/integrations/pi/session-ui/session-shell-root.js +68 -74
  85. package/dist/integrations/pi/session-ui/session-shell.d.ts +1 -1
  86. package/dist/integrations/pi/session-ui/session-shell.js +98 -12
  87. package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +5 -0
  88. package/dist/integrations/pi/session-ui/session-viewport-controller.js +21 -15
  89. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +7 -0
  90. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +7 -6
  91. package/dist/native/darwin-arm64/manifest.json +1 -1
  92. package/dist/native/linux-x64/manifest.json +1 -1
  93. package/dist/native/win32-x64/manifest.json +2 -2
  94. package/dist/native/win32-x64/process-guardian.exe +0 -0
  95. package/dist/product-identity.d.ts +2 -2
  96. package/dist/product-identity.js +3 -36
  97. package/dist/product-identity.json +1 -22
  98. package/dist/ui/components/transcript-viewport.d.ts +8 -0
  99. package/dist/ui/components/transcript-viewport.js +23 -2
  100. package/dist/ui/components/visible-hyperlinks.d.ts +7 -0
  101. package/dist/ui/components/visible-hyperlinks.js +1 -0
  102. package/dist/ui/settings/declarations.js +19 -0
  103. package/dist/ui/settings/sections.js +11 -1
  104. package/dist/ui/settings/session.js +13 -4
  105. package/docs/architecture/boundaries.md +2 -0
  106. package/docs/architecture/history-editor-provenance.md +96 -0
  107. package/docs/architecture/internal-naming.md +89 -0
  108. package/docs/architecture/project-structure.md +1 -0
  109. package/docs/architecture/resource-and-data-policy.md +27 -1
  110. package/docs/architecture/toolchain.md +15 -1
  111. package/docs/features/prompt-history.md +149 -0
  112. package/package.json +8 -3
@@ -7,6 +7,22 @@ export function renderPiShellStatusText(message, width, outputPad = PINNED_PI_LA
7
7
  ensureTheme();
8
8
  return new Text(piTheme().fg("dim", message), outputPad, 0).render(width);
9
9
  }
10
+ export function renderPiShellCommandMessage(presentation, width, outputPad = PINNED_PI_LAYOUT.outputPad) {
11
+ ensureTheme();
12
+ const { kind, message, detail } = presentation;
13
+ const prefix = kind === "error" ? "Error: " : kind === "warning" ? "Warning: " : "";
14
+ const color = kind === "name" ? "dim" : kind === "error" || kind === "warning" ? kind : "accent";
15
+ const content = piTheme().fg(color, `${prefix}${message}`)
16
+ + (kind === "debug" && detail ? `\n${piTheme().fg("muted", detail)}` : "");
17
+ // Compatibility: pinned errors honor outputPad; warnings and command notices retain
18
+ // one-cell padding. New-session/debug notices also own one vertical padding row.
19
+ const text = new Text(content, kind === "error" ? outputPad : 1, kind === "new" || kind === "debug" ? 1 : 0);
20
+ return [
21
+ ...(kind === "name" && detail ? renderPiShellCommandMessage({ kind: "warning", message: detail }, width) : []),
22
+ ...new Spacer(1).render(width),
23
+ ...text.render(width),
24
+ ];
25
+ }
10
26
  export function createPiShellSessionInfo(presentation) {
11
27
  ensureTheme();
12
28
  const { stats, sessionName, cacheWaste, usageBreakdown } = presentation;
@@ -61,12 +77,27 @@ export function createPiShellChangelog(markdown) {
61
77
  container.addChild(new DynamicBorder());
62
78
  return componentPort(container);
63
79
  }
64
- export function createPiShellHotkeys() {
80
+ function shortcutDisplay(key) {
81
+ // Platform: pinned Pi labels Alt as Option on macOS, including extension shortcuts.
82
+ return key.split("/").map(binding => binding.split("+").map(part => {
83
+ const label = process.platform === "darwin" && part.toLowerCase() === "alt" ? "option" : part;
84
+ return label.charAt(0).toUpperCase() + label.slice(1);
85
+ }).join("+")).join("/");
86
+ }
87
+ export function createPiShellHotkeys(bindings, getShortcuts = () => [], profile = "pi") {
65
88
  ensureTheme();
66
- const keys = new KeybindingsManager();
67
- const display = (action) => keys.getKeys(action).map(key => key.split("+").map(part => part.charAt(0).toUpperCase() + part.slice(1)).join("+")).join("/");
89
+ const keys = new KeybindingsManager(bindings);
90
+ // Compatibility: the owned viewport consumes these physical chords before editor actions.
91
+ const display = (action) => keys.getKeys(action)
92
+ .filter(key => profile !== "a1" || (key !== "ctrl+home" && key !== "ctrl+end"))
93
+ .map(shortcutDisplay).join("/");
68
94
  const row = (actions, description) => `| ${actions.map(action => `\`${display(action)}\``).join(" / ")} | ${description} |`;
69
- const markdown = ["**Navigation**", "| Key | Action |", "|-----|--------|", row(["tui.editor.cursorUp", "tui.editor.cursorDown", "tui.editor.cursorLeft", "tui.editor.cursorRight"], "Move cursor / browse history"), row(["tui.editor.cursorWordLeft", "tui.editor.cursorWordRight"], "Move by word"), row(["tui.editor.cursorLineStart"], "Start of line"), row(["tui.editor.cursorLineEnd"], "End of line"), row(["tui.editor.jumpForward"], "Jump forward to character"), row(["tui.editor.jumpBackward"], "Jump backward to character"), row(["tui.editor.pageUp", "tui.editor.pageDown"], "Scroll by page"), "", "**Editing**", "| Key | Action |", "|-----|--------|", row(["tui.input.submit"], "Send message"), row(["tui.input.newLine"], `New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""}`), row(["tui.editor.deleteWordBackward"], "Delete word backwards"), row(["tui.editor.deleteWordForward"], "Delete word forwards"), row(["tui.editor.deleteToLineStart"], "Delete to start of line"), row(["tui.editor.deleteToLineEnd"], "Delete to end of line"), row(["tui.editor.yank"], "Paste the most-recently-deleted text"), row(["tui.editor.yankPop"], "Cycle through the deleted text after pasting"), row(["tui.editor.undo"], "Undo"), "", "**Other**", "| Key | Action |", "|-----|--------|", row(["tui.input.tab"], "Path completion / accept autocomplete"), row(["app.interrupt"], "Cancel autocomplete / abort streaming"), row(["app.clear"], "Clear editor (first) / exit (second)"), row(["app.exit"], "Exit (when editor is empty)"), row(["app.suspend"], "Suspend to background"), row(["app.thinking.cycle"], "Cycle thinking level"), row(["app.model.cycleForward", "app.model.cycleBackward"], "Cycle models"), row(["app.model.select"], "Open model selector"), row(["app.tools.expand"], "Toggle tool output expansion"), row(["app.thinking.toggle"], "Toggle thinking block visibility"), row(["app.editor.external"], "Edit message in external editor"), row(["app.message.copy"], "Copy last assistant message"), row(["app.message.followUp"], "Queue follow-up message"), row(["app.message.dequeue"], "Restore queued messages"), row(["app.clipboard.pasteImage"], "Paste image or text from clipboard"), "| `/` | Slash commands |", "| `!` | Run bash command |", "| `!!` | Run bash command (excluded from context) |"].join("\n");
95
+ let markdown = ["**Navigation**", "| Key | Action |", "|-----|--------|", row(["tui.editor.cursorUp", "tui.editor.cursorDown", "tui.editor.cursorLeft", "tui.editor.cursorRight"], "Move cursor / browse history"), row(["tui.editor.cursorWordLeft", "tui.editor.cursorWordRight"], "Move by word"), row(["tui.editor.cursorLineStart"], profile === "a1" ? "Start of prompt line" : "Start of line"), row(["tui.editor.cursorLineEnd"], profile === "a1" ? "End of prompt line" : "End of line"), ...(profile === "a1" ? ["| `Ctrl+Home` | Start of content |", "| `Ctrl+End` | End of content / follow output |"] : []), row(["tui.editor.jumpForward"], "Jump forward to character"), row(["tui.editor.jumpBackward"], "Jump backward to character"), row(["tui.editor.pageUp", "tui.editor.pageDown"], "Scroll by page"), "", "**Editing**", "| Key | Action |", "|-----|--------|", row(["tui.input.submit"], "Send message"), row(["tui.input.newLine"], `New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""}`), row(["tui.editor.deleteWordBackward"], "Delete word backwards"), row(["tui.editor.deleteWordForward"], "Delete word forwards"), row(["tui.editor.deleteToLineStart"], "Delete to start of line"), row(["tui.editor.deleteToLineEnd"], "Delete to end of line"), row(["tui.editor.yank"], "Paste the most-recently-deleted text"), row(["tui.editor.yankPop"], "Cycle through the deleted text after pasting"), row(["tui.editor.undo"], "Undo"), "", "**Other**", "| Key | Action |", "|-----|--------|", row(["tui.input.tab"], "Path completion / accept autocomplete"), row(["app.interrupt"], "Cancel autocomplete / abort streaming"), row(["app.clear"], "Clear editor (first) / exit (second)"), row(["app.exit"], "Exit (when editor is empty)"), row(["app.suspend"], "Suspend to background"), row(["app.thinking.cycle"], "Cycle thinking level"), row(["app.model.cycleForward", "app.model.cycleBackward"], "Cycle models"), row(["app.model.select"], "Open model selector"), row(["app.tools.expand"], "Toggle tool output expansion"), row(["app.thinking.toggle"], "Toggle thinking block visibility"), row(["app.editor.external"], "Edit message in external editor"), row(["app.message.copy"], "Copy last assistant message"), row(["app.message.followUp"], "Queue follow-up message"), row(["app.message.dequeue"], "Restore queued messages"), row(["app.clipboard.pasteImage"], "Paste image or text from clipboard"), "| `/` | Slash commands |", "| `!` | Run bash command |", "| `!!` | Run bash command (excluded from context) |"].join("\n");
96
+ const shortcuts = getShortcuts(bindings ?? keys.getEffectiveConfig());
97
+ if (shortcuts.length > 0) {
98
+ markdown += "\n\n**Extensions**\n| Key | Action |\n|-----|--------|\n";
99
+ markdown += shortcuts.map(shortcut => `| \`${shortcutDisplay(shortcut.key)}\` | ${shortcut.description} |`).join("\n");
100
+ }
70
101
  const container = new Container();
71
102
  container.addChild(new Spacer(1));
72
103
  container.addChild(new DynamicBorder());
@@ -67,6 +67,7 @@ export declare function createPiShellTreeSelector(options: {
67
67
  readonly onSelect: (id: string) => void;
68
68
  readonly onCancel: () => void;
69
69
  readonly onLabelChange: (entryId: string, label: string | undefined) => void;
70
+ readonly onCopy?: (text: string | undefined) => void;
70
71
  readonly initialSelectedId?: string;
71
72
  readonly initialFilterMode?: "default" | "no-tools" | "user-only" | "labeled-only" | "all";
72
73
  }): PiShellComponentPort;
@@ -87,7 +88,7 @@ export interface PiShellLoginDialogPort extends PiShellComponentPort {
87
88
  showWaiting(message: string): void;
88
89
  showProgress(message: string): void;
89
90
  }
90
- export declare function createPiShellLoginDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, providerId: string, onComplete: (success: boolean, message?: string) => void, providerName?: string): PiShellLoginDialogPort;
91
+ export declare function createPiShellLoginDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, providerId: string, onComplete: (success: boolean, message?: string) => void, providerName?: string, title?: string): PiShellLoginDialogPort;
91
92
  export declare function createPiShellArmin(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellComponentPort;
92
93
  export declare function createPiShellDaxnuts(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellComponentPort;
93
94
  export declare function createPiShellEarendilAnnouncement(): PiShellComponentPort;
@@ -104,7 +105,7 @@ export interface PiShellAuthProviderOption extends PiShellSelectorOption {
104
105
  readonly source?: string;
105
106
  };
106
107
  }
107
- export declare function createPiShellAuthProviderSelector(mode: "login" | "logout", providers: readonly PiShellAuthProviderOption[], onSelect: (id: string) => void, onCancel: () => void): PiShellComponentPort;
108
+ export declare function createPiShellAuthProviderSelector(mode: "login" | "logout", providers: readonly PiShellAuthProviderOption[], onSelect: (id: string) => void, onCancel: () => void, initialSearchInput?: string): PiShellComponentPort;
108
109
  export declare function createPiShellExtensionSelector(title: string, options: readonly string[], onSelect: (value: string) => void, onCancel: () => void): PiShellComponentPort;
109
110
  export declare function createPiShellThinkingSelector(currentLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", availableLevels: readonly ("off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max")[], onSelect: (level: string) => void, onCancel: () => void): PiShellComponentPort;
110
111
  export declare function createPiShellThemeSelector(currentTheme: string, onSelect: (theme: string) => void, onCancel: () => void, onPreview: (theme: string) => void): PiShellComponentPort;
@@ -111,7 +111,10 @@ export function createPiShellSessionSelector(options) {
111
111
  }
112
112
  export function createPiShellTreeSelector(options) {
113
113
  ensureTheme();
114
- return componentPort(new TreeSelectorComponent([...options.tree], options.currentLeafId, options.terminalHeight, options.onSelect, options.onCancel, options.onLabelChange, options.initialSelectedId, options.initialFilterMode));
114
+ const selector = new TreeSelectorComponent([...options.tree], options.currentLeafId, options.terminalHeight, options.onSelect, options.onCancel, options.onLabelChange, options.initialSelectedId, options.initialFilterMode);
115
+ if (options.onCopy)
116
+ selector.onCopy = options.onCopy;
117
+ return componentPort(selector);
115
118
  }
116
119
  export function createPiShellUserMessageSelector(messages, onSelect, onCancel, initialSelectedId) {
117
120
  ensureTheme();
@@ -119,9 +122,9 @@ export function createPiShellUserMessageSelector(messages, onSelect, onCancel, i
119
122
  const list = selector.getMessageList();
120
123
  return componentPort(selector, data => list.handleInput(data));
121
124
  }
122
- export function createPiShellLoginDialog(runtime, providerId, onComplete, providerName) {
125
+ export function createPiShellLoginDialog(runtime, providerId, onComplete, providerName, title) {
123
126
  ensureTheme();
124
- const dialog = new LoginDialogComponent(createTuiFacade(runtime), providerId, onComplete, providerName);
127
+ const dialog = new LoginDialogComponent(createTuiFacade(runtime), providerId, onComplete, providerName, title);
125
128
  return {
126
129
  ...componentPort(dialog),
127
130
  showAuth: (url, instructions) => dialog.showAuth(url, instructions),
@@ -162,7 +165,7 @@ export function createPiShellReloadBox() {
162
165
  container.addChild(new DynamicBorder(borderColor));
163
166
  return componentPort(container);
164
167
  }
165
- export function createPiShellAuthProviderSelector(mode, providers, onSelect, onCancel) {
168
+ export function createPiShellAuthProviderSelector(mode, providers, onSelect, onCancel, initialSearchInput) {
166
169
  ensureTheme();
167
170
  const selector = new OAuthSelectorComponent(mode, providers.map(provider => ({
168
171
  id: provider.providerId,
@@ -173,7 +176,7 @@ export function createPiShellAuthProviderSelector(mode, providers, onSelect, onC
173
176
  const selected = providers.find(provider => provider.providerId === providerId && provider.authType === authType);
174
177
  if (selected)
175
178
  onSelect(selected.id);
176
- }, onCancel);
179
+ }, onCancel, initialSearchInput);
177
180
  return componentPort(selector);
178
181
  }
179
182
  export function createPiShellExtensionSelector(title, options, onSelect, onCancel) {
@@ -1,5 +1,7 @@
1
- import { visibleWidth, type AutocompleteProvider, type Component, type TUI } from "#pi-tui";
1
+ import { visibleWidth, type AutocompleteProvider, type Component, type KeybindingsConfig, type TUI } from "#pi-tui";
2
2
  import type { OwnedUiImageAttachment, OwnedUiSessionViewModel, OwnedUiThinkingLevel, OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
3
+ import type { HistoryEditorConstructor } from "./history-editor-loader.js";
4
+ import type { EditorRecallPort } from "./editor-interaction.js";
3
5
  import type { PresentationComponentPort } from "../../../contracts/presentation/index.js";
4
6
  /** Terminal-cell width authority used by Pi-rendered component rows. */
5
7
  export declare const piShellVisibleWidth: typeof visibleWidth;
@@ -25,10 +27,14 @@ export interface PiShellEditorPointerEvent {
25
27
  readonly row: number;
26
28
  }
27
29
  export interface PiShellEditorPort extends PiShellComponentPort {
30
+ readonly recall?: EditorRecallPort;
31
+ readonly historyReplacement?: typeof import("../../../contracts/owned-ui/index.js").PROMPT_HISTORY_EDITOR_REPLACEMENT;
28
32
  /** Restores this editor's profile after another Pi component changed the global manager. */
29
33
  activateKeybindings(): void;
34
+ keybindingConfig(): KeybindingsConfig;
35
+ reloadKeybindings(): void;
30
36
  /** Uses Pi's terminal decoder rather than assuming one terminal escape spelling. */
31
- matchesTerminalKey(data: string, key: "home" | "end" | "ctrl+v"): boolean;
37
+ matchesTerminalKey(data: string, key: "home" | "end" | "ctrl+home" | "ctrl+end" | "ctrl+v"): boolean;
32
38
  getText(): string;
33
39
  setText(text: string): void;
34
40
  insertText(text: string): void;
@@ -90,6 +96,10 @@ export interface PiShellImageAssetResolver {
90
96
  export interface PiShellExtensionRendererResolver {
91
97
  getMessageRenderer(customType: string): unknown;
92
98
  getToolDefinition(toolName: string): unknown;
99
+ getShortcuts?(bindings: KeybindingsConfig): readonly {
100
+ readonly key: string;
101
+ readonly description: string;
102
+ }[];
93
103
  }
94
104
  export interface PiShellTranscriptComponentPort extends PiShellComponentPort {
95
105
  readonly id: string;
@@ -112,6 +122,8 @@ export interface PiShellHeaderOptions {
112
122
  readonly resources?: readonly PiShellResourceEntry[];
113
123
  }
114
124
  export interface PiShellEditorOptions {
125
+ readonly persistentHistory?: boolean;
126
+ readonly historyEditor?: HistoryEditorConstructor;
115
127
  /** Bare A1 adds ergonomic aliases while comparison profiles retain Pi defaults. */
116
128
  readonly keybindingProfile?: "pi" | "a1";
117
129
  readonly getColumns: () => number;
@@ -141,6 +153,7 @@ export interface PiShellEditorOptions {
141
153
  readonly marker: string;
142
154
  readonly result: Promise<string>;
143
155
  };
156
+ readonly editorHiddenRanges?: (line: string) => readonly PiShellEditorTextRange[];
144
157
  readonly transformPastedContent?: (content: PiShellClipboardContent) => string;
145
158
  readonly editorAtomicRanges?: (line: string) => readonly PiShellEditorTextRange[];
146
159
  readonly expandCopiedEditorText?: (text: string) => string;