@timurproko/a1 0.1.8-dev.137 → 0.1.8-dev.139

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 (82) hide show
  1. package/README.md +2 -4
  2. package/dist/cli/capabilities.d.ts +2 -11
  3. package/dist/cli/capabilities.js +1 -1
  4. package/dist/cli/dispatch.js +3 -6
  5. package/dist/composition/owned-ui.js +19 -1
  6. package/dist/contracts/owned-ui/model.d.ts +21 -0
  7. package/dist/contracts/owned-ui/validation.js +3 -0
  8. package/dist/features/launch/development-launch.js +11 -3
  9. package/dist/features/launch/index.d.ts +0 -1
  10. package/dist/features/launch/index.js +0 -1
  11. package/dist/features/launch/intent.d.ts +3 -2
  12. package/dist/features/launch/intent.js +1 -2
  13. package/dist/features/launch/prepare-launch.d.ts +0 -2
  14. package/dist/features/launch/prepare-launch.js +2 -9
  15. package/dist/features/launch/profile-paths.d.ts +1 -2
  16. package/dist/features/launch/profile-paths.js +2 -8
  17. package/dist/features/launch/runtime-selection.d.ts +2 -5
  18. package/dist/features/owned-ui/settings-app.js +36 -13
  19. package/dist/foundation/lifecycle/model.d.ts +1 -1
  20. package/dist/foundation/lifecycle/model.js +1 -1
  21. package/dist/foundation/release/bootstrap.d.ts +1 -3
  22. package/dist/foundation/release/bootstrap.js +1 -1
  23. package/dist/foundation/storage/control-store.js +37 -3
  24. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  25. package/dist/integrations/pi/components/shell-footer-status.js +14 -5
  26. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +3 -2
  27. package/dist/integrations/pi/components/shell-presenters-transcript.js +9 -8
  28. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +13 -0
  29. package/dist/integrations/pi/components/submitted-prompt-adapter.js +27 -0
  30. package/dist/integrations/pi/engine/adapter.js +16 -2
  31. package/dist/integrations/pi/engine/session-integration.js +5 -2
  32. package/dist/integrations/pi/owned-ui/session-shell-root.d.ts +17 -2
  33. package/dist/integrations/pi/owned-ui/session-shell-root.js +451 -42
  34. package/dist/integrations/pi/owned-ui/session-shell.js +116 -13
  35. package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -1
  36. package/dist/integrations/pi/tui-runtime/adapter.js +51 -2
  37. package/dist/integrations/pi/tui-runtime/contracts.d.ts +2 -0
  38. package/dist/native/darwin-arm64/manifest.json +1 -1
  39. package/dist/native/linux-x64/manifest.json +3 -3
  40. package/dist/native/linux-x64/process-guardian +0 -0
  41. package/dist/native/win32-x64/manifest.json +2 -2
  42. package/dist/native/win32-x64/process-guardian.exe +0 -0
  43. package/dist/product-identity.d.ts +2 -2
  44. package/dist/product-identity.js +3 -4
  45. package/dist/product-identity.json +3 -5
  46. package/dist/ui/components/index.d.ts +3 -0
  47. package/dist/ui/components/index.js +3 -0
  48. package/dist/ui/components/mouse.d.ts +10 -0
  49. package/dist/ui/components/mouse.js +23 -0
  50. package/dist/ui/components/prompt-row.d.ts +14 -0
  51. package/dist/ui/components/prompt-row.js +20 -0
  52. package/dist/ui/components/scrollbar.d.ts +26 -0
  53. package/dist/ui/components/scrollbar.js +35 -0
  54. package/dist/ui/components/spans.d.ts +6 -0
  55. package/dist/ui/components/spans.js +36 -0
  56. package/dist/ui/components/submitted-prompt.d.ts +23 -0
  57. package/dist/ui/components/submitted-prompt.js +50 -0
  58. package/dist/ui/components/text-selection.d.ts +53 -0
  59. package/dist/ui/components/text-selection.js +168 -0
  60. package/dist/ui/components/text.d.ts +14 -0
  61. package/dist/ui/components/text.js +40 -0
  62. package/dist/ui/components/transcript-viewport.d.ts +98 -0
  63. package/dist/ui/components/transcript-viewport.js +353 -0
  64. package/dist/ui/settings/declarations.d.ts +8 -1
  65. package/dist/ui/settings/declarations.js +33 -5
  66. package/dist/ui/settings/migrations.d.ts +1 -1
  67. package/dist/ui/settings/migrations.js +12 -2
  68. package/dist/ui/settings/sections.js +15 -8
  69. package/dist/ui/settings/session.d.ts +2 -0
  70. package/dist/ui/settings/session.js +7 -5
  71. package/docs/architecture/boundaries.md +2 -2
  72. package/docs/architecture/project-structure.md +1 -1
  73. package/docs/architecture/resource-and-data-policy.md +1 -1
  74. package/docs/architecture/toolchain.md +5 -5
  75. package/docs/architecture/ui-reference-provenance.md +11 -2
  76. package/docs/features/launch-profiles.md +7 -14
  77. package/docs/manual-launch-instance-acceptance.md +12 -35
  78. package/docs/manual-owned-ui-checkpoint.md +2 -3
  79. package/docs/manual-pi-boundary-candidate.md +4 -5
  80. package/package.json +1 -2
  81. package/dist/features/launch/profiles.d.ts +0 -12
  82. package/dist/features/launch/profiles.js +0 -26
@@ -1,8 +1,9 @@
1
1
  import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder, getMarkdownTheme, parseSkillBlock, ToolExecutionComponent, UserMessageComponent, } from "@earendil-works/pi-coding-agent";
2
- import { SkillInvocationMessageComponent, } from "./upstream/components/skill-invocation-message.js";
2
+ import { SkillInvocationMessageComponent } from "./upstream/components/skill-invocation-message.js";
3
3
  import { Container, Markdown, Spacer, Text, } from "#pi-tui";
4
4
  import { PRODUCT_TEXT } from "../../../product-identity.js";
5
- import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
5
+ import { createPiSubmittedPromptComponent, } from "./submitted-prompt-adapter.js";
6
+ import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
6
7
  import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
7
8
  import { componentPort, createTuiFacade, ensureTheme, formatSessionTokens, isRecord, } from "./shell-shared-facade.js";
8
9
  export function renderPiShellStatusText(message, width) {
@@ -106,11 +107,11 @@ export function createPiShellHotkeys() {
106
107
  container.addChild(new DynamicBorder());
107
108
  return componentPort(container);
108
109
  }
109
- export function createPiShellTranscriptComponent(initial, cwd, extensions) {
110
+ export function createPiShellTranscriptComponent(initial, cwd, extensions, submittedPrompt) {
110
111
  ensureTheme();
111
112
  let block = initial;
112
113
  let expanded = false;
113
- let component = transcriptComponent(block, cwd, expanded, extensions);
114
+ let component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
114
115
  return {
115
116
  get id() { return block.id; },
116
117
  get revision() { return block.revision; },
@@ -122,7 +123,7 @@ export function createPiShellTranscriptComponent(initial, cwd, extensions) {
122
123
  const previous = block;
123
124
  block = next;
124
125
  if (!updateTranscriptComponent(component, previous, next, expanded)) {
125
- component = transcriptComponent(block, cwd, expanded, extensions);
126
+ component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
126
127
  }
127
128
  },
128
129
  setExpanded(next) {
@@ -133,7 +134,7 @@ export function createPiShellTranscriptComponent(initial, cwd, extensions) {
133
134
  component.setExpanded(expanded);
134
135
  }
135
136
  else {
136
- component = transcriptComponent(block, cwd, expanded, extensions);
137
+ component = transcriptComponent(block, cwd, expanded, extensions, submittedPrompt);
137
138
  }
138
139
  },
139
140
  };
@@ -175,12 +176,12 @@ export function renderPiShellPackageUpdateNotice(packages, width) {
175
176
  container.addChild(new DynamicBorder(text => theme.fg("warning", text)));
176
177
  return container.render(width);
177
178
  }
178
- function transcriptComponent(block, cwd, expanded, extensions) {
179
+ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt) {
179
180
  switch (block.kind) {
180
181
  case "user": {
181
182
  const skill = parseSkillBlock(block.text);
182
183
  if (!skill)
183
- return new UserMessageComponent(block.text);
184
+ return submittedPrompt ? createPiSubmittedPromptComponent(block, submittedPrompt) : new UserMessageComponent(block.text);
184
185
  const invocation = new SkillInvocationMessageComponent(skill, getMarkdownTheme());
185
186
  invocation.setExpanded(expanded);
186
187
  if (!skill.userMessage)
@@ -0,0 +1,13 @@
1
+ import { type Component } from "#pi-tui";
2
+ import type { OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
3
+ export interface PiShellSubmittedPromptComposer {
4
+ readonly layout: (width: number, source?: Date | number | null) => {
5
+ readonly contentWidth: number;
6
+ };
7
+ readonly compose: (contentRows: readonly string[], width: number, source?: Date | number | null, style?: {
8
+ readonly prefix?: (text: string) => string;
9
+ readonly timestamp?: (text: string) => string;
10
+ }) => readonly string[];
11
+ }
12
+ /** Pi owns Markdown and theme adaptation; the injected composer owns neutral row geometry. */
13
+ export declare function createPiSubmittedPromptComponent(block: OwnedUiTranscriptBlock, composer: PiShellSubmittedPromptComposer): Component;
@@ -0,0 +1,27 @@
1
+ import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
2
+ import { Box, Markdown } from "#pi-tui";
3
+ import { piTheme } from "./theme.js";
4
+ /** Pi owns Markdown and theme adaptation; the injected composer owns neutral row geometry. */
5
+ export function createPiSubmittedPromptComponent(block, composer) {
6
+ const timestamp = numericTimestamp(block);
7
+ const markdown = new Markdown(block.text, 0, 0, getMarkdownTheme(), { color: content => piTheme().fg("userMessageText", content) }, { preserveOrderedListMarkers: true, preserveBackslashEscapes: true });
8
+ const content = {
9
+ render(width) {
10
+ const layout = composer.layout(width, timestamp);
11
+ return [...composer.compose(markdown.render(layout.contentWidth), width, timestamp, {
12
+ prefix: text => piTheme().fg("muted", text),
13
+ timestamp: text => piTheme().fg("dim", text),
14
+ })];
15
+ },
16
+ invalidate: () => markdown.invalidate(),
17
+ };
18
+ const box = new Box(0, 0, line => piTheme().bg("userMessageBg", line));
19
+ box.addChild(content);
20
+ return box;
21
+ }
22
+ function numericTimestamp(block) {
23
+ if (typeof block.payload !== "object" || block.payload === null)
24
+ return null;
25
+ const value = block.payload.timestamp;
26
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
27
+ }
@@ -16,7 +16,10 @@ const execFileAsync = promisify(execFile);
16
16
  * that a streaming burst never holds input, large enough that an ordinary turn is one
17
17
  * batch.
18
18
  */
19
- const EVENT_DELIVERY_BATCH = 16;
19
+ // Deliver at most one engine event per event-loop turn. Transcript updates can
20
+ // be expensive in long sessions; a larger synchronous batch starves terminal
21
+ // input and makes an in-progress mouse selection appear frozen.
22
+ const EVENT_DELIVERY_BATCH = 1;
20
23
  const TOOL_UPDATE_COALESCE_MS = 50;
21
24
  const DEFAULT_SURFACE = {
22
25
  columns: 100,
@@ -1484,6 +1487,7 @@ export class PiEngineAdapter {
1484
1487
  switch (event.type) {
1485
1488
  case "agent_start":
1486
1489
  this.#agentRunActive = true;
1490
+ this.#emitEvent({ type: "agent-run-started" });
1487
1491
  this.#enterWorkState("working", "Working...");
1488
1492
  return;
1489
1493
  case "message_start":
@@ -1505,6 +1509,12 @@ export class PiEngineAdapter {
1505
1509
  }
1506
1510
  case "message_end":
1507
1511
  this.#upsertMessageBlock(event.message, "finalized");
1512
+ // Preserve the same semantic boundary v2 counted. Transcript block
1513
+ // finalization is intentionally not a substitute: rebuilds, retries,
1514
+ // thinking parts, and tool rows can all finalize independently.
1515
+ if (isRecord(event.message) && event.message.role === "assistant") {
1516
+ this.#emitEvent({ type: "assistant-message-completed" });
1517
+ }
1508
1518
  return;
1509
1519
  case "turn_end":
1510
1520
  this.#upsertMessageBlock(event.message, "finalized");
@@ -1688,7 +1698,11 @@ export class PiEngineAdapter {
1688
1698
  revision: this.#nextBlockRevision(baseId),
1689
1699
  title: "User",
1690
1700
  text: textFromContent(message.content),
1691
- payload: { role: "user", imageCount: contentImageCount(message.content) },
1701
+ payload: {
1702
+ role: "user",
1703
+ imageCount: contentImageCount(message.content),
1704
+ timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : null,
1705
+ },
1692
1706
  }];
1693
1707
  }
1694
1708
  if (message.role === "bashExecution") {
@@ -13,11 +13,14 @@ export class PiSessionCommandIntegration {
13
13
  return { outcome: "completed" };
14
14
  case "steer":
15
15
  this.#lastPrompt = command.text;
16
- await this.session.steer(command.text);
16
+ // Match interactive Pi: prompt() owns template/extension expansion and
17
+ // turns the accepted steering message into the visible user row while
18
+ // later messages remain in the pending queue.
19
+ await this.session.prompt(command.text, { streamingBehavior: "steer" });
17
20
  return { outcome: "completed" };
18
21
  case "follow-up":
19
22
  this.#lastPrompt = command.text;
20
- await this.session.followUp(command.text);
23
+ await this.session.prompt(command.text, { streamingBehavior: "followUp" });
21
24
  return { outcome: "completed" };
22
25
  case "abort":
23
26
  if (this.session.isRetrying)
@@ -1,4 +1,4 @@
1
- import type { OwnedUiSessionViewModel } from "../../../contracts/owned-ui/index.js";
1
+ import type { OwnedUiSessionViewModel, OwnedUiViewportSettings, OwnedUiViewportSettingsPort } from "../../../contracts/owned-ui/index.js";
2
2
  import type { UiRouteHost } from "./route-host.js";
3
3
  import { type PiEngineAdapter, type PiWorkflowResult } from "../engine/index.js";
4
4
  import { type PiShellComponentPort, type PiShellEditorPort, type PiShellExtensionRendererResolver, type PiShellHeaderOptions, type PiShellHeaderPort, type PiShellLoadedResourcesPort, type PiShellResourceEntry, type PiShellTranscriptComponentPort } from "../components/index.js";
@@ -16,6 +16,10 @@ export interface OwnedUiSessionShellOptions {
16
16
  * every other route continues to the pinned workflow table unchanged.
17
17
  */
18
18
  readonly routeHost?: UiRouteHost;
19
+ /** Bare A1 selects the owned bounded viewport; comparison profiles stay pinned. */
20
+ readonly sessionLayout?: "pinned" | "custom-viewport";
21
+ /** Live profile-local settings, supplied only to the bare-A1 composition. */
22
+ readonly viewportSettings?: OwnedUiViewportSettingsPort;
19
23
  }
20
24
  export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
21
25
  #private;
@@ -37,7 +41,7 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
37
41
  readonly onMessageCopy?: () => void;
38
42
  readonly onFollowUp?: () => void;
39
43
  readonly onDequeue?: () => void;
40
- }, startup?: PiShellHeaderOptions, agentDir?: string, extensionRenderers?: PiShellExtensionRendererResolver);
44
+ }, startup?: PiShellHeaderOptions, agentDir?: string, extensionRenderers?: PiShellExtensionRendererResolver, sessionLayout?: "pinned" | "custom-viewport");
41
45
  update(view: OwnedUiSessionViewModel): void;
42
46
  /**
43
47
  * Applies one block: its component is created or updated in place and the order grows
@@ -46,6 +50,16 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
46
50
  */
47
51
  applyTranscriptBlock(block: OwnedUiSessionViewModel["transcript"][number]): void;
48
52
  render(width: number): readonly string[];
53
+ setViewportConfig(config: OwnedUiViewportSettings): void;
54
+ resumeViewportFollowing(): void;
55
+ noteCompletedAssistantMessage(): void;
56
+ resetViewport(): void;
57
+ clearViewportPointerState(): void;
58
+ handleViewportPreInput(data: string, allowWheel?: boolean, now?: number): {
59
+ readonly data: string;
60
+ readonly consumed: boolean;
61
+ readonly copyText?: string;
62
+ };
49
63
  layoutRoot(): PiTuiLayoutNode;
50
64
  transcriptComponent(id: string): PiShellTranscriptComponentPort | undefined;
51
65
  appendWorkflowStatus(message: string): void;
@@ -63,6 +77,7 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
63
77
  resetExtensionUi(): void;
64
78
  addExtensionNotification(message: string, type: "info" | "warning" | "error"): void;
65
79
  extensionFooterData(): unknown;
80
+ usesDefaultInputSurface(): boolean;
66
81
  setInputSurface(component: PiShellComponentPort | null, disposePrevious?: boolean): void;
67
82
  handleInput(data: string): void;
68
83
  invalidate(): void;