@timurproko/a1 0.1.8-dev.157 → 0.1.8-dev.214

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 (171) hide show
  1. package/README.md +32 -0
  2. package/bin/cli.js +2 -2
  3. package/bin/sync-pi-tui-proxy.js +1 -1
  4. package/bin/ui.js +18 -3
  5. package/dist/cli/dispatch.js +3 -3
  6. package/dist/cli/packages.js +1 -1
  7. package/dist/cli/version-stats.js +3 -3
  8. package/dist/composition/owned-ui.d.ts +4 -1
  9. package/dist/composition/owned-ui.js +9 -6
  10. package/dist/composition/settings-route-host.js +6 -4
  11. package/dist/contracts/agent-engine/capability-ports.d.ts +2 -2
  12. package/dist/contracts/agent-engine/domain-validation.js +22 -4
  13. package/dist/contracts/agent-engine/domain.d.ts +17 -0
  14. package/dist/contracts/owned-ui/model.d.ts +8 -0
  15. package/dist/contracts/owned-ui/validation.js +11 -0
  16. package/dist/features/launch/development-launch.js +1 -1
  17. package/dist/features/owned-ui/customization.d.ts +2 -0
  18. package/dist/features/owned-ui/customization.js +2 -0
  19. package/dist/features/owned-ui/diagnostics.d.ts +1 -0
  20. package/dist/features/owned-ui/diagnostics.js +1 -0
  21. package/dist/features/owned-ui/index.d.ts +1 -0
  22. package/dist/features/owned-ui/index.js +1 -0
  23. package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
  24. package/dist/features/owned-ui/project-trust-prompt.js +149 -0
  25. package/dist/features/owned-ui/settings-app.js +69 -44
  26. package/dist/features/workspace/reducer.d.ts +1 -0
  27. package/dist/features/workspace/reducer.js +1 -0
  28. package/dist/features/workspace/router.d.ts +1 -0
  29. package/dist/features/workspace/router.js +1 -0
  30. package/dist/features/workspace/store.d.ts +1 -0
  31. package/dist/features/workspace/store.js +1 -0
  32. package/dist/foundation/launch-guardian/main.js +1 -1
  33. package/dist/foundation/native-host-protocol/codec.d.ts +2 -0
  34. package/dist/foundation/native-host-protocol/codec.js +2 -0
  35. package/dist/foundation/process-containment/linux-process-inspector.d.ts +1 -0
  36. package/dist/foundation/process-containment/linux-process-inspector.js +1 -0
  37. package/dist/foundation/process-containment/native-guardian-containment.d.ts +1 -0
  38. package/dist/foundation/process-containment/native-guardian-containment.js +1 -0
  39. package/dist/foundation/process-containment/windows-process-inspector.d.ts +1 -0
  40. package/dist/foundation/process-containment/windows-process-inspector.js +1 -0
  41. package/dist/foundation/protocol/client.d.ts +1 -0
  42. package/dist/foundation/protocol/client.js +1 -0
  43. package/dist/foundation/protocol/messages.d.ts +1 -0
  44. package/dist/foundation/protocol/messages.js +1 -0
  45. package/dist/foundation/release/bootstrap.js +6 -6
  46. package/dist/foundation/release/cohort-state.d.ts +1 -0
  47. package/dist/foundation/release/cohort-state.js +1 -0
  48. package/dist/foundation/release/release-gc.js +1 -1
  49. package/dist/foundation/release/release.js +1 -1
  50. package/dist/foundation/release/update-transaction.d.ts +1 -0
  51. package/dist/foundation/release/update-transaction.js +1 -0
  52. package/dist/foundation/release/update.js +12 -12
  53. package/dist/foundation/storage/control-store.d.ts +1 -0
  54. package/dist/foundation/storage/control-store.js +1 -0
  55. package/dist/foundation/structured-agent-runtime/backpressure.d.ts +1 -0
  56. package/dist/foundation/structured-agent-runtime/backpressure.js +1 -0
  57. package/dist/foundation/structured-agent-runtime/commands.d.ts +1 -0
  58. package/dist/foundation/structured-agent-runtime/commands.js +1 -0
  59. package/dist/foundation/structured-agent-runtime/reconnection.d.ts +1 -0
  60. package/dist/foundation/structured-agent-runtime/reconnection.js +1 -0
  61. package/dist/foundation/structured-agent-runtime/state.d.ts +1 -0
  62. package/dist/foundation/structured-agent-runtime/state.js +1 -0
  63. package/dist/foundation/supervision/main.js +1 -1
  64. package/dist/foundation/supervision/server.d.ts +1 -0
  65. package/dist/foundation/supervision/server.js +4 -6
  66. package/dist/integrations/pi/components/conformance.d.ts +1 -0
  67. package/dist/integrations/pi/components/conformance.js +1 -0
  68. package/dist/integrations/pi/components/shell-components.d.ts +1 -0
  69. package/dist/integrations/pi/components/shell-components.js +1 -0
  70. package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -0
  71. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  72. package/dist/integrations/pi/components/shell-footer-status.js +19 -13
  73. package/dist/integrations/pi/components/shell-presenters-info.d.ts +36 -0
  74. package/dist/integrations/pi/components/shell-presenters-info.js +78 -0
  75. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +3 -36
  76. package/dist/integrations/pi/components/shell-presenters-transcript.js +88 -128
  77. package/dist/integrations/pi/components/shell-shared-facade.d.ts +11 -1
  78. package/dist/integrations/pi/components/shell-shared-facade.js +1 -1
  79. package/dist/integrations/pi/engine/adapter.d.ts +22 -4
  80. package/dist/integrations/pi/engine/adapter.js +220 -70
  81. package/dist/integrations/pi/engine/conformance.d.ts +2 -0
  82. package/dist/integrations/pi/engine/conformance.js +2 -0
  83. package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
  84. package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
  85. package/dist/integrations/pi/engine/index.d.ts +3 -0
  86. package/dist/integrations/pi/engine/index.js +3 -0
  87. package/dist/integrations/pi/engine/model-auth-integration.d.ts +1 -0
  88. package/dist/integrations/pi/engine/model-auth-integration.js +1 -0
  89. package/dist/integrations/pi/engine/package-integration.js +1 -1
  90. package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
  91. package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
  92. package/dist/integrations/pi/engine/resource-extension-integration.d.ts +1 -0
  93. package/dist/integrations/pi/engine/resource-extension-integration.js +1 -0
  94. package/dist/integrations/pi/engine/runtime-integration.d.ts +16 -1
  95. package/dist/integrations/pi/engine/runtime-integration.js +34 -4
  96. package/dist/integrations/pi/engine/session-integration.d.ts +1 -0
  97. package/dist/integrations/pi/engine/session-integration.js +2 -1
  98. package/dist/integrations/pi/engine/settings-effects.d.ts +66 -0
  99. package/dist/integrations/pi/engine/settings-effects.js +249 -0
  100. package/dist/integrations/pi/engine/settings-integration.d.ts +14 -26
  101. package/dist/integrations/pi/engine/settings-integration.js +102 -108
  102. package/dist/integrations/pi/engine/workflow-controllers.d.ts +2 -1
  103. package/dist/integrations/pi/engine/workflow-controllers.js +1 -0
  104. package/dist/integrations/pi/session-ui/clipboard-image.d.ts +11 -0
  105. package/dist/integrations/pi/session-ui/clipboard-image.js +29 -0
  106. package/dist/integrations/pi/session-ui/index.d.ts +1 -0
  107. package/dist/integrations/pi/session-ui/index.js +1 -0
  108. package/dist/integrations/pi/session-ui/prompt-chips.js +6 -2
  109. package/dist/integrations/pi/session-ui/session-shell-root.d.ts +39 -4
  110. package/dist/integrations/pi/session-ui/session-shell-root.js +215 -80
  111. package/dist/integrations/pi/session-ui/session-shell.d.ts +10 -1
  112. package/dist/integrations/pi/session-ui/session-shell.js +256 -45
  113. package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +5 -0
  114. package/dist/integrations/pi/session-ui/session-viewport-controller.js +76 -11
  115. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.d.ts +29 -0
  116. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.js +79 -0
  117. package/dist/integrations/pi/session-ui/system-clipboard.d.ts +9 -0
  118. package/dist/integrations/pi/session-ui/system-clipboard.js +38 -9
  119. package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
  120. package/dist/integrations/pi/tui-runtime/adapter.js +166 -8
  121. package/dist/integrations/pi/tui-runtime/contracts.d.ts +25 -0
  122. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +63 -0
  123. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +240 -0
  124. package/dist/integrations/pi/tui-runtime/index.d.ts +2 -0
  125. package/dist/integrations/pi/tui-runtime/index.js +2 -0
  126. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
  127. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
  128. package/dist/native/darwin-arm64/manifest.json +1 -1
  129. package/dist/native/linux-x64/manifest.json +1 -1
  130. package/dist/native/win32-x64/manifest.json +2 -2
  131. package/dist/native/win32-x64/process-guardian.exe +0 -0
  132. package/dist/ui/apps/host.js +5 -9
  133. package/dist/ui/apps/registry.d.ts +1 -0
  134. package/dist/ui/apps/registry.js +1 -0
  135. package/dist/ui/components/dialog-panel.js +5 -3
  136. package/dist/ui/components/frame.d.ts +1 -0
  137. package/dist/ui/components/frame.js +1 -0
  138. package/dist/ui/components/index.d.ts +1 -0
  139. package/dist/ui/components/index.js +1 -0
  140. package/dist/ui/components/line-input.d.ts +1 -6
  141. package/dist/ui/components/line-input.js +4 -9
  142. package/dist/ui/components/list-view.d.ts +0 -6
  143. package/dist/ui/components/list-view.js +14 -7
  144. package/dist/ui/components/progress-status.d.ts +2 -0
  145. package/dist/ui/components/progress-status.js +4 -0
  146. package/dist/ui/components/scrollbar.js +1 -1
  147. package/dist/ui/components/shortcuts.d.ts +1 -0
  148. package/dist/ui/components/shortcuts.js +1 -0
  149. package/dist/ui/components/spans.d.ts +2 -5
  150. package/dist/ui/components/spans.js +28 -8
  151. package/dist/ui/components/surface.d.ts +0 -5
  152. package/dist/ui/components/surface.js +1 -5
  153. package/dist/ui/components/text-selection.d.ts +10 -1
  154. package/dist/ui/components/text-selection.js +96 -29
  155. package/dist/ui/components/text.js +3 -3
  156. package/dist/ui/components/transcript-viewport.d.ts +42 -0
  157. package/dist/ui/components/transcript-viewport.js +287 -39
  158. package/dist/ui/settings/sections.d.ts +6 -19
  159. package/dist/ui/settings/sections.js +17 -15
  160. package/dist/ui/settings/session.d.ts +8 -18
  161. package/dist/ui/settings/session.js +60 -52
  162. package/dist/ui/settings/store.d.ts +1 -0
  163. package/dist/ui/settings/store.js +2 -1
  164. package/docs/architecture/code-documentation.md +77 -0
  165. package/docs/architecture/project-structure.md +15 -1
  166. package/docs/architecture/ui-reference-provenance.md +23 -3
  167. package/docs/ci-release-runbook.md +98 -7
  168. package/docs/manual-owned-ui-checkpoint.md +28 -1
  169. package/docs/manual-terminal-colour-check.md +4 -3
  170. package/docs/repository-governance-live-acceptance.md +77 -0
  171. package/package.json +11 -3
@@ -1,147 +1,106 @@
1
1
  import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder, getMarkdownTheme, parseSkillBlock, ToolExecutionComponent, UserMessageComponent, } from "@earendil-works/pi-coding-agent";
2
2
  import { SkillInvocationMessageComponent } from "./upstream/components/skill-invocation-message.js";
3
- import { Container, Markdown, Spacer, Text, } from "#pi-tui";
3
+ import { createMermaidMarkdownTransformer } from "./upstream/components/mermaid.js";
4
+ import { Container, Image, Spacer, Text, } from "#pi-tui";
4
5
  import { PRODUCT_TEXT } from "../../../product-identity.js";
5
6
  import { createPiSubmittedPromptComponent, } from "./submitted-prompt-adapter.js";
6
- import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
7
7
  import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
8
- import { componentPort, createTuiFacade, ensureTheme, formatSessionTokens, isRecord, } from "./shell-shared-facade.js";
9
- export function renderPiShellStatusText(message, width) {
10
- ensureTheme();
11
- return new Text(piTheme().fg("dim", message), PINNED_PI_LAYOUT.outputPad, 0).render(width);
12
- }
13
- export function createPiShellSessionInfo(presentation) {
14
- ensureTheme();
15
- const { stats, sessionName, cacheWaste, usageBreakdown } = presentation;
16
- let info = `${piTheme().bold("Session Info")}\n\n`;
17
- if (sessionName)
18
- info += `${piTheme().fg("dim", "Name:")} ${sessionName}\n`;
19
- info += `${piTheme().fg("dim", "File:")} ${stats.sessionFile ?? "In-memory"}\n`;
20
- info += `${piTheme().fg("dim", "ID:")} ${stats.sessionId}\n\n`;
21
- info += `${piTheme().bold("Messages")}\n`;
22
- info += `${piTheme().fg("dim", "Total:")} ${stats.totalMessages}\n`;
23
- info += `${piTheme().fg("dim", "User:")} ${stats.userMessages}\n`;
24
- info += `${piTheme().fg("dim", "Assistant:")} ${stats.assistantMessages}\n`;
25
- info += `${piTheme().fg("dim", "Tools:")} ${stats.toolCalls} calls, ${stats.toolResults} results\n\n`;
26
- info += `${piTheme().bold("Tokens")}\n`;
27
- const { input, cacheRead, cacheWrite } = stats.tokens;
28
- const promptTokens = input + cacheRead + cacheWrite;
29
- info += `${piTheme().fg("dim", "Input:")} ${promptTokens.toLocaleString()}\n`;
30
- if (promptTokens > 0 && (cacheRead > 0 || cacheWrite > 0)) {
31
- const hitRate = piTheme().fg("dim", `(${((cacheRead / promptTokens) * 100).toFixed(1)}%)`);
32
- info += ` ${piTheme().fg("dim", "Cached:")} ${cacheRead.toLocaleString()} ${hitRate}\n`;
33
- const written = cacheWrite > 0 ? ` ${piTheme().fg("dim", `(${cacheWrite.toLocaleString()} written to cache)`)}` : "";
34
- info += ` ${piTheme().fg("dim", "Uncached:")} ${(input + cacheWrite).toLocaleString()}${written}\n`;
35
- }
36
- info += `${piTheme().fg("dim", "Output:")} ${stats.tokens.output.toLocaleString()}\n`;
37
- info += `${piTheme().fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
38
- if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
39
- info += `\n${piTheme().bold("Cost")}\n`;
40
- info += `${piTheme().fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
41
- if (usageBreakdown.length > 1) {
42
- for (const entry of usageBreakdown) {
43
- info += `\n ${piTheme().fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${piTheme().fg("dim", `(${formatSessionTokens(entry.tokens)} tokens)`)}`;
44
- }
45
- }
46
- if (cacheWaste.missedTokens > 0) {
47
- const missLabel = cacheWaste.missCount === 1 ? "1 miss" : `${cacheWaste.missCount} misses`;
48
- const detail = `${cacheWaste.missedTokens.toLocaleString()} tokens, ${missLabel}`;
49
- info += cacheWaste.missedCost >= 0.0001
50
- ? `\n${piTheme().fg("dim", "Cache Re-billed:")} $${cacheWaste.missedCost.toFixed(3)} ${piTheme().fg("dim", `(${detail})`)}`
51
- : `\n${piTheme().fg("dim", "Cache Re-billed:")} ${detail}`;
52
- }
53
- }
54
- const container = new Container();
55
- container.addChild(new Spacer(1));
56
- container.addChild(new Text(info, 1, 0));
57
- return componentPort(container);
58
- }
59
- export function createPiShellChangelog(markdown) {
60
- ensureTheme();
61
- const container = new Container();
62
- container.addChild(new Spacer(1));
63
- container.addChild(new DynamicBorder());
64
- container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "What's New")), 1, 0));
65
- container.addChild(new Spacer(1));
66
- container.addChild(new Markdown(markdown.trim() || "No changelog entries found.", 1, 1, getMarkdownTheme()));
67
- container.addChild(new DynamicBorder());
68
- return componentPort(container);
69
- }
70
- export function createPiShellHotkeys() {
71
- ensureTheme();
72
- const keys = new KeybindingsManager();
73
- const display = (action) => keys.getKeys(action)
74
- .map(key => key.split("+").map(part => part.charAt(0).toUpperCase() + part.slice(1)).join("+"))
75
- .join("/");
76
- const row = (actions, description) => `| ${actions.map(action => `\`${display(action)}\``).join(" / ")} | ${description} |`;
77
- const markdown = [
78
- "**Navigation**", "| Key | Action |", "|-----|--------|",
79
- row(["tui.editor.cursorUp", "tui.editor.cursorDown", "tui.editor.cursorLeft", "tui.editor.cursorRight"], "Move cursor / browse history"),
80
- row(["tui.editor.cursorWordLeft", "tui.editor.cursorWordRight"], "Move by word"),
81
- row(["tui.editor.cursorLineStart"], "Start of line"), row(["tui.editor.cursorLineEnd"], "End of line"),
82
- row(["tui.editor.jumpForward"], "Jump forward to character"), row(["tui.editor.jumpBackward"], "Jump backward to character"),
83
- row(["tui.editor.pageUp", "tui.editor.pageDown"], "Scroll by page"), "",
84
- "**Editing**", "| Key | Action |", "|-----|--------|",
85
- row(["tui.input.submit"], "Send message"),
86
- row(["tui.input.newLine"], `New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""}`),
87
- row(["tui.editor.deleteWordBackward"], "Delete word backwards"), row(["tui.editor.deleteWordForward"], "Delete word forwards"),
88
- row(["tui.editor.deleteToLineStart"], "Delete to start of line"), row(["tui.editor.deleteToLineEnd"], "Delete to end of line"),
89
- row(["tui.editor.yank"], "Paste the most-recently-deleted text"), row(["tui.editor.yankPop"], "Cycle through the deleted text after pasting"),
90
- row(["tui.editor.undo"], "Undo"), "", "**Other**", "| Key | Action |", "|-----|--------|",
91
- row(["tui.input.tab"], "Path completion / accept autocomplete"), row(["app.interrupt"], "Cancel autocomplete / abort streaming"),
92
- row(["app.clear"], "Clear editor (first) / exit (second)"), row(["app.exit"], "Exit (when editor is empty)"),
93
- row(["app.suspend"], "Suspend to background"), row(["app.thinking.cycle"], "Cycle thinking level"),
94
- row(["app.model.cycleForward", "app.model.cycleBackward"], "Cycle models"), row(["app.model.select"], "Open model selector"),
95
- row(["app.tools.expand"], "Toggle tool output expansion"), row(["app.thinking.toggle"], "Toggle thinking block visibility"),
96
- row(["app.editor.external"], "Edit message in external editor"), row(["app.message.copy"], "Copy last assistant message"),
97
- row(["app.message.followUp"], "Queue follow-up message"), row(["app.message.dequeue"], "Restore queued messages"),
98
- row(["app.clipboard.pasteImage"], "Paste image or text from clipboard"),
99
- "| `/` | Slash commands |", "| `!` | Run bash command |", "| `!!` | Run bash command (excluded from context) |",
100
- ].join("\n");
101
- const container = new Container();
102
- container.addChild(new Spacer(1));
103
- container.addChild(new DynamicBorder());
104
- container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "Keyboard Shortcuts")), 1, 0));
105
- container.addChild(new Spacer(1));
106
- container.addChild(new Markdown(markdown, 1, 1, getMarkdownTheme()));
107
- container.addChild(new DynamicBorder());
108
- return componentPort(container);
109
- }
110
- export function createPiShellTranscriptComponent(initial, cwd, extensions, submittedPrompt) {
8
+ import { componentPort, createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
9
+ export function createPiShellTranscriptComponent(initial, cwd, extensions, submittedPrompt, initialOutputPad = PINNED_PI_LAYOUT.outputPad, initialHideThinkingBlock = false, initialMermaidRenderingMode = "off", initialShowImages = true, initialImageWidthCells = 80, imageAssets) {
111
10
  ensureTheme();
112
11
  let block = initial;
113
12
  let expanded = false;
114
- let component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
13
+ let outputPad = initialOutputPad;
14
+ let hideThinkingBlock = initialHideThinkingBlock;
15
+ let mermaidRenderingMode = initialMermaidRenderingMode;
16
+ let showImages = initialShowImages;
17
+ let imageWidthCells = initialImageWidthCells;
18
+ const rebuild = () => withTranscriptImages(transcriptComponent(block, cwd, expanded, extensions, submittedPrompt, outputPad, hideThinkingBlock, mermaidRenderingMode, showImages, imageWidthCells), block, imageAssets, showImages, imageWidthCells);
19
+ let component = rebuild();
115
20
  return {
116
21
  get id() { return block.id; },
117
22
  get revision() { return block.revision; },
118
- render: width => component.render(width),
23
+ render: width => renderWithOutputPad(component, block.kind, width, outputPad),
119
24
  invalidate: () => component.invalidate(),
120
25
  update(next) {
121
26
  if (next.id !== block.id)
122
27
  throw new TypeError("Pi transcript component identity cannot change");
123
28
  const previous = block;
124
29
  block = next;
125
- if (!updateTranscriptComponent(component, previous, next, expanded)) {
126
- component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
127
- }
30
+ if (!updateTranscriptComponent(component, previous, next, expanded))
31
+ component = rebuild();
128
32
  },
129
33
  setExpanded(next) {
130
34
  if (expanded === next)
131
35
  return;
132
36
  expanded = next;
133
- if ("setExpanded" in component && typeof component.setExpanded === "function") {
37
+ if ("setExpanded" in component && typeof component.setExpanded === "function")
134
38
  component.setExpanded(expanded);
39
+ else
40
+ component = rebuild();
41
+ },
42
+ setOutputPad(padding) {
43
+ if (outputPad === padding)
44
+ return;
45
+ outputPad = padding;
46
+ component = rebuild();
47
+ },
48
+ setHideThinkingBlock(hidden) {
49
+ if (hideThinkingBlock === hidden)
50
+ return;
51
+ hideThinkingBlock = hidden;
52
+ component = rebuild();
53
+ },
54
+ setMermaidRenderingMode(mode) {
55
+ if (mermaidRenderingMode === mode)
56
+ return;
57
+ mermaidRenderingMode = mode;
58
+ component = rebuild();
59
+ },
60
+ setImagePresentation(show, width) {
61
+ showImages = show;
62
+ imageWidthCells = width;
63
+ if (component instanceof ToolExecutionComponent) {
64
+ component.setShowImages(show);
65
+ component.setImageWidthCells(width);
135
66
  }
136
- else {
137
- component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
138
- }
67
+ else
68
+ component = rebuild();
139
69
  },
140
70
  };
141
71
  }
72
+ function withTranscriptImages(component, block, assets, showImages, imageWidthCells) {
73
+ const references = block.imageReferences ?? [];
74
+ if (references.length === 0)
75
+ return component;
76
+ const container = new Container();
77
+ container.addChild(component);
78
+ for (const reference of references) {
79
+ container.addChild(new Spacer(1));
80
+ const asset = assets?.resolve(reference.assetId) ?? null;
81
+ if (!showImages) {
82
+ container.addChild(new Text(piTheme().fg("muted", `[Image hidden: ${reference.mimeType}, ${reference.byteLength} bytes]`), 1, 0));
83
+ }
84
+ else if (asset === null) {
85
+ container.addChild(new Text(piTheme().fg("warning", `[Image unavailable: ${reference.mimeType}]`), 1, 0));
86
+ }
87
+ else {
88
+ container.addChild(new Image(asset.data, asset.mimeType, {
89
+ fallbackColor: text => piTheme().fg("muted", text),
90
+ }, { maxWidthCells: imageWidthCells, filename: reference.assetId }));
91
+ }
92
+ }
93
+ return container;
94
+ }
95
+ function renderWithOutputPad(component, kind, width, outputPad) {
96
+ const rows = component.render(width);
97
+ if (outputPad !== 0 || (kind !== "tool-call" && kind !== "tool-result" && kind !== "bash"))
98
+ return rows;
99
+ return rows.map(row => row.startsWith(" ") ? row.slice(1) : row);
100
+ }
142
101
  export function renderPiShellTranscriptBlock(block, width, cwd) {
143
102
  ensureTheme();
144
- return transcriptComponent(block, cwd, true).render(width);
103
+ return transcriptComponent(block, cwd, true, undefined, undefined, PINNED_PI_LAYOUT.outputPad, false, "off", true, 80).render(width);
145
104
  }
146
105
  /**
147
106
  * Pinned Pi's CLI prints startup diagnostics with `reportDiagnostics` before
@@ -176,7 +135,7 @@ export function renderPiShellPackageUpdateNotice(packages, width) {
176
135
  container.addChild(new DynamicBorder(text => theme.fg("warning", text)));
177
136
  return container.render(width);
178
137
  }
179
- function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt) {
138
+ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt, outputPad, hideThinkingBlock, mermaidRenderingMode, showImages, imageWidthCells) {
180
139
  switch (block.kind) {
181
140
  case "user": {
182
141
  const skill = parseSkillBlock(block.text);
@@ -194,10 +153,10 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt)
194
153
  }
195
154
  case "assistant":
196
155
  case "thinking":
197
- return assistantComponent(block);
156
+ return assistantComponent(block, outputPad, hideThinkingBlock, mermaidRenderingMode);
198
157
  case "tool-call":
199
158
  case "tool-result": {
200
- const component = toolComponent(block, cwd, extensions);
159
+ const component = toolComponent(block, cwd, extensions, showImages, imageWidthCells);
201
160
  component.setExpanded(expanded);
202
161
  return component;
203
162
  }
@@ -212,13 +171,13 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt)
212
171
  return component;
213
172
  }
214
173
  case "retry":
215
- return new Text(piTheme().fg("warning", `Retry: ${block.text}`), PINNED_PI_LAYOUT.outputPad, 0);
174
+ return new Text(piTheme().fg("warning", `Retry: ${block.text}`), outputPad, 0);
216
175
  case "error":
217
- return new Text(piTheme().fg("error", `Error: ${block.text}`), PINNED_PI_LAYOUT.outputPad, 0);
176
+ return new Text(piTheme().fg("error", `Error: ${block.text}`), outputPad, 0);
218
177
  case "system":
219
- return new Text(piTheme().fg("dim", block.text), PINNED_PI_LAYOUT.outputPad, 0);
178
+ return new Text(piTheme().fg("dim", block.text), outputPad, 0);
220
179
  case "custom":
221
- return customMessageComponent(block, expanded, extensions);
180
+ return customMessageComponent(block, expanded, extensions, outputPad);
222
181
  case "bash":
223
182
  return bashExecutionComponent(block, cwd, expanded);
224
183
  }
@@ -267,8 +226,9 @@ function updateTranscriptComponent(component, previous, next, expanded) {
267
226
  }
268
227
  return false;
269
228
  }
270
- function assistantComponent(block) {
271
- const component = new AssistantMessageComponent(undefined, false, getMarkdownTheme(), undefined, PINNED_PI_LAYOUT.outputPad);
229
+ function assistantComponent(block, outputPad, hideThinkingBlock, mermaidRenderingMode) {
230
+ const transformer = createMermaidMarkdownTransformer({ getMode: () => mermaidRenderingMode, theme: piTheme() });
231
+ const component = new AssistantMessageComponent(undefined, hideThinkingBlock, getMarkdownTheme(), undefined, outputPad, [transformer]);
272
232
  component.updateContent(validatedAssistantMessage(block), block.status === "live");
273
233
  return component;
274
234
  }
@@ -336,12 +296,12 @@ function validatedMessageRenderer(value) {
336
296
  function isPiMessageRenderer(value) {
337
297
  return typeof value === "function";
338
298
  }
339
- function toolComponent(block, cwd, extensions) {
299
+ function toolComponent(block, cwd, extensions, showImages, imageWidthCells) {
340
300
  const payload = blockPayload(block);
341
301
  const toolCallId = stringPayload(payload, "toolCallId") ?? block.id;
342
302
  const toolName = stringPayload(payload, "toolName") ?? block.title ?? "tool";
343
303
  const argumentsPayload = toolArguments(payload);
344
- const component = new ToolExecutionComponent(toolName, toolCallId, argumentsPayload, undefined, validatedToolDefinition(extensions?.getToolDefinition(toolName)), createTuiFacade({ getColumns: () => 80, getRows: () => 24, requestRender() { }, onSubmit() { } }), cwd);
304
+ const component = new ToolExecutionComponent(toolName, toolCallId, argumentsPayload, { showImages, imageWidthCells }, validatedToolDefinition(extensions?.getToolDefinition(toolName)), createTuiFacade({ getColumns: () => 80, getRows: () => 24, requestRender() { }, onSubmit() { } }), cwd);
345
305
  if (block.status === "live")
346
306
  component.markExecutionStarted();
347
307
  if (block.status === "finalized" || payload.argsComplete === true)
@@ -357,7 +317,7 @@ function toolComponent(block, cwd, extensions) {
357
317
  }
358
318
  return component;
359
319
  }
360
- function customMessageComponent(block, expanded, extensions) {
320
+ function customMessageComponent(block, expanded, extensions, outputPad) {
361
321
  const payload = blockPayload(block);
362
322
  const message = {
363
323
  role: "custom",
@@ -368,7 +328,7 @@ function customMessageComponent(block, expanded, extensions) {
368
328
  timestamp: numericPayload(block, "timestamp") || 0,
369
329
  };
370
330
  const renderer = validatedMessageRenderer(extensions?.getMessageRenderer(message.customType));
371
- const component = new CustomMessageComponent(message, renderer, getMarkdownTheme(), PINNED_PI_LAYOUT.outputPad);
331
+ const component = new CustomMessageComponent(message, renderer, getMarkdownTheme(), outputPad);
372
332
  component.setExpanded(expanded);
373
333
  return component;
374
334
  }
@@ -1,5 +1,5 @@
1
1
  import { visibleWidth, type AutocompleteProvider, type Component, type TUI } from "#pi-tui";
2
- import type { OwnedUiSessionViewModel, OwnedUiThinkingLevel, OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
2
+ import type { OwnedUiImageAttachment, OwnedUiSessionViewModel, OwnedUiThinkingLevel, OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
3
3
  import type { PresentationComponentPort } from "../../../contracts/presentation/index.js";
4
4
  /** Terminal-cell width authority used by Pi-rendered component rows. */
5
5
  export declare const piShellVisibleWidth: typeof visibleWidth;
@@ -37,6 +37,8 @@ export interface PiShellEditorPort extends PiShellComponentPort {
37
37
  setSubmitHandler(handler: (text: string) => void): void;
38
38
  setInterruptHandler(handler: () => void): void;
39
39
  setAutocompleteCommands(commands: readonly PiShellAutocompleteCommand[]): void;
40
+ setPaddingX(padding: number): void;
41
+ setAutocompleteMaxVisible(maxVisible: number): void;
40
42
  addAutocompleteProvider(factory: unknown): void;
41
43
  setThinkingLevel(level: OwnedUiThinkingLevel): void;
42
44
  hasSelection(): boolean;
@@ -55,6 +57,7 @@ export interface PiShellViewComponentPort extends PiShellComponentPort {
55
57
  }
56
58
  export interface PiShellStatusPort extends PiShellViewComponentPort {
57
59
  setWorkingOverride(message: string | undefined): void;
60
+ setOutputPad(padding: 0 | 1): void;
58
61
  }
59
62
  export interface PiShellQueuedInputPort extends PiShellComponentPort {
60
63
  update(submissions: readonly string[]): void;
@@ -73,6 +76,9 @@ export interface PiShellResourceEntry {
73
76
  export interface PiShellLoadedResourcesPort extends PiShellComponentPort {
74
77
  setExpanded(expanded: boolean): void;
75
78
  }
79
+ export interface PiShellImageAssetResolver {
80
+ resolve(assetId: string): OwnedUiImageAttachment | null;
81
+ }
76
82
  export interface PiShellExtensionRendererResolver {
77
83
  getMessageRenderer(customType: string): unknown;
78
84
  getToolDefinition(toolName: string): unknown;
@@ -82,6 +88,10 @@ export interface PiShellTranscriptComponentPort extends PiShellComponentPort {
82
88
  readonly revision: number;
83
89
  update(block: OwnedUiTranscriptBlock): void;
84
90
  setExpanded(expanded: boolean): void;
91
+ setOutputPad(padding: 0 | 1): void;
92
+ setHideThinkingBlock(hidden: boolean): void;
93
+ setMermaidRenderingMode(mode: "off" | "final" | "streaming"): void;
94
+ setImagePresentation(showImages: boolean, imageWidthCells: number): void;
85
95
  }
86
96
  export interface PiShellStartupNotice {
87
97
  readonly kind: "info" | "warning" | "error";
@@ -3,7 +3,7 @@ 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. */
5
5
  export const piShellVisibleWidth = visibleWidth;
6
- // Pinned from packages/coding-agent/src/core/slash-commands.ts at 914cf14.
6
+ // Provenance: pinned from packages/coding-agent/src/core/slash-commands.ts at 914cf14.
7
7
  export function createTuiFacade(options) {
8
8
  const children = [];
9
9
  const terminal = {
@@ -1,11 +1,16 @@
1
1
  import { type AgentSessionRuntime, type AgentSessionServices, type SessionInfo } from "@earendil-works/pi-coding-agent";
2
- import { OWNED_UI_EXTENSION_CONTRACT_VERSION, OWNED_UI_EXTENSION_RENDER_CALLBACKS, OWNED_UI_EXTENSION_UI_CALLBACKS, OWNED_UI_EXTENSION_UI_PROPERTIES, type OwnedUiCommand, type OwnedUiCommandOutcome, type OwnedUiEvent, type OwnedUiSessionViewModel, type OwnedUiSnapshot } from "../../../contracts/owned-ui/index.js";
2
+ import { OWNED_UI_EXTENSION_CONTRACT_VERSION, OWNED_UI_EXTENSION_RENDER_CALLBACKS, OWNED_UI_EXTENSION_UI_CALLBACKS, OWNED_UI_EXTENSION_UI_PROPERTIES, type OwnedUiCommand, type OwnedUiCommandOutcome, type OwnedUiImageAttachment, type OwnedUiEvent, type OwnedUiSessionViewModel, type OwnedUiSnapshot } from "../../../contracts/owned-ui/index.js";
3
3
  import { type PiAuthenticationProviderOption, type PiBashWorkflowResult, type PiPinnedSettingsCallback, type PiPinnedSettingsSnapshot, type PiWorkflowAutocompleteCommand, type PiWorkflowHost, type PiWorkflowInteractionHost, type PiWorkflowOption, type PiWorkflowRequest, type PiWorkflowResult } from "./workflows.js";
4
- import type { AgentSettingsPort } from "../../../contracts/agent-engine/index.js";
4
+ import { PiSettingsIntegration } from "./settings-integration.js";
5
+ import type { PiSettingOwnerHandlers } from "./settings-effects.js";
6
+ import type { PiProjectTrustPreflightPrompt } from "./project-trust-preflight.js";
7
+ import type { AgentSettingOwner } from "../../../contracts/agent-engine/index.js";
5
8
  export interface PiEngineRuntimeFactoryInput {
6
9
  readonly cwd: string;
7
10
  readonly agentDir: string;
8
11
  readonly sessionId: string;
12
+ readonly sessionPath?: string;
13
+ readonly projectTrustPrompt?: PiProjectTrustPreflightPrompt;
9
14
  }
10
15
  export interface PiScopedModelDescriptor {
11
16
  readonly provider: string;
@@ -41,6 +46,11 @@ export interface PiTreeSelectorContext {
41
46
  readonly skipSummaryPrompt: boolean;
42
47
  readonly appendLabelChange: (entryId: string, label: string | undefined) => void;
43
48
  }
49
+ export interface PiSessionResumeMetadata {
50
+ readonly sessionId: string;
51
+ readonly sessionDir: string;
52
+ readonly usesDefaultSessionDir: boolean;
53
+ }
44
54
  export interface PiSessionSelectorContext {
45
55
  readonly currentSessionFilePath: string | undefined;
46
56
  readonly loadCurrentSessions: (onProgress?: (loaded: number, total: number) => void) => Promise<SessionInfo[]>;
@@ -90,6 +100,7 @@ export interface PiEngineAdapterOptions {
90
100
  readonly cwd?: string;
91
101
  readonly agentDir?: string;
92
102
  readonly sessionId?: string;
103
+ readonly sessionPath?: string;
93
104
  readonly createRuntime?: PiEngineRuntimeFactory;
94
105
  readonly workflowHost?: PiWorkflowHost;
95
106
  /**
@@ -98,6 +109,8 @@ export interface PiEngineAdapterOptions {
98
109
  * offering stay here.
99
110
  */
100
111
  readonly availableThemes?: () => readonly string[];
112
+ readonly settingsProductMode?: "bare" | "comparison";
113
+ readonly projectTrustPrompt?: PiProjectTrustPreflightPrompt;
101
114
  /**
102
115
  * Startup extension-package update probe, mirroring pinned Pi's interactive
103
116
  * mode. Returns display names of packages with updates available.
@@ -108,6 +121,7 @@ export interface AdapterCommandResult {
108
121
  readonly outcome: OwnedUiCommandOutcome;
109
122
  readonly diagnostic: string | null;
110
123
  }
124
+ /** Owns the pinned Pi session lifecycle and translates its events into the neutral agent-engine contract. */
111
125
  export declare class PiEngineAdapter {
112
126
  #private;
113
127
  constructor(options?: PiEngineAdapterOptions);
@@ -115,6 +129,9 @@ export declare class PiEngineAdapter {
115
129
  get sessionId(): string;
116
130
  get sessionGeneration(): number;
117
131
  get agentDir(): string;
132
+ resolveTranscriptImage(assetId: string): OwnedUiImageAttachment | null;
133
+ currentSessionFile(): string | null;
134
+ currentSessionResumeMetadata(): PiSessionResumeMetadata | null;
118
135
  get disposed(): boolean;
119
136
  start(): Promise<OwnedUiSessionViewModel>;
120
137
  onEvent(listener: (event: OwnedUiEvent) => void): () => void;
@@ -132,7 +149,8 @@ export declare class PiEngineAdapter {
132
149
  */
133
150
  configuredTheme(): string | undefined;
134
151
  /** Settings port for the live runtime, or null before the runtime is available. */
135
- settingsPort(): AgentSettingsPort | null;
152
+ settingsPort(): PiSettingsIntegration | null;
153
+ bindSettingsOwner(owner: AgentSettingOwner, handlers: PiSettingOwnerHandlers): () => void;
136
154
  pinnedModelSelectorContext(): {
137
155
  readonly currentModel: unknown;
138
156
  readonly settingsManager: unknown;
@@ -160,7 +178,7 @@ export declare class PiEngineAdapter {
160
178
  clearQueuedWorkflows(): readonly string[];
161
179
  abortBashWorkflow(): void;
162
180
  executeBashWorkflow(command: string, excludeFromContext: boolean): Promise<PiBashWorkflowResult>;
163
- applyPinnedSettingValue(callback: PiPinnedSettingsCallback, value: unknown): PiWorkflowResult;
181
+ applyPinnedSettingValue(callback: PiPinnedSettingsCallback, value: unknown): Promise<PiWorkflowResult>;
164
182
  executeWorkflow(request: PiWorkflowRequest): Promise<PiWorkflowResult>;
165
183
  view(): OwnedUiSessionViewModel;
166
184
  snapshot(): OwnedUiSnapshot;