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

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 (51) hide show
  1. package/dist/composition/owned-ui.js +10 -7
  2. package/dist/composition/settings-route-host.d.ts +1 -1
  3. package/dist/composition/settings-route-host.js +1 -1
  4. package/dist/contracts/owned-ui/model.d.ts +8 -1
  5. package/dist/contracts/owned-ui/validation.js +11 -0
  6. package/dist/features/owned-ui/settings-app.js +2 -1
  7. package/dist/integrations/pi/components/owned-editor-ux.d.ts +55 -0
  8. package/dist/integrations/pi/components/owned-editor-ux.js +778 -0
  9. package/dist/integrations/pi/components/shell-editor-autocomplete.js +44 -6
  10. package/dist/integrations/pi/components/shell-shared-facade.d.ts +41 -7
  11. package/dist/integrations/pi/components/shell-shared-facade.js +3 -1
  12. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +10 -2
  13. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +36 -3
  14. package/dist/integrations/pi/engine/adapter.js +5 -1
  15. package/dist/integrations/pi/engine/session-integration.d.ts +2 -1
  16. package/dist/integrations/pi/engine/session-integration.js +14 -3
  17. package/dist/integrations/pi/session-ui/prompt-chips.d.ts +23 -0
  18. package/dist/integrations/pi/session-ui/prompt-chips.js +242 -0
  19. package/dist/integrations/pi/session-ui/route-host.d.ts +5 -0
  20. package/dist/integrations/pi/{owned-ui → session-ui}/session-shell-root.d.ts +17 -3
  21. package/dist/integrations/pi/{owned-ui → session-ui}/session-shell-root.js +100 -260
  22. package/dist/integrations/pi/{owned-ui → session-ui}/session-shell.d.ts +1 -1
  23. package/dist/integrations/pi/{owned-ui → session-ui}/session-shell.js +52 -12
  24. package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +39 -0
  25. package/dist/integrations/pi/session-ui/session-viewport-controller.js +369 -0
  26. package/dist/integrations/pi/session-ui/system-clipboard.d.ts +11 -0
  27. package/dist/integrations/pi/session-ui/system-clipboard.js +101 -0
  28. package/dist/integrations/pi/tui-runtime/contracts.d.ts +2 -6
  29. package/dist/native/darwin-arm64/manifest.json +1 -1
  30. package/dist/native/linux-x64/manifest.json +3 -3
  31. package/dist/native/linux-x64/process-guardian +0 -0
  32. package/dist/native/win32-x64/manifest.json +3 -3
  33. package/dist/native/win32-x64/process-guardian.exe +0 -0
  34. package/dist/ui/apps/contracts.d.ts +23 -1
  35. package/dist/ui/apps/host.js +9 -1
  36. package/dist/ui/components/scrollbar.d.ts +2 -2
  37. package/dist/ui/components/scrollbar.js +3 -3
  38. package/dist/ui/components/spans.d.ts +16 -1
  39. package/dist/ui/components/spans.js +144 -2
  40. package/dist/ui/components/transcript-viewport.d.ts +6 -0
  41. package/dist/ui/components/transcript-viewport.js +36 -8
  42. package/dist/ui/settings/declarations.d.ts +1 -1
  43. package/dist/ui/settings/declarations.js +3 -3
  44. package/dist/ui/settings/migrations.js +9 -0
  45. package/docs/architecture/boundaries.md +1 -1
  46. package/docs/architecture/project-structure.md +1 -1
  47. package/package.json +4 -1
  48. package/dist/integrations/pi/owned-ui/route-host.d.ts +0 -29
  49. /package/dist/integrations/pi/{owned-ui → session-ui}/index.d.ts +0 -0
  50. /package/dist/integrations/pi/{owned-ui → session-ui}/index.js +0 -0
  51. /package/dist/integrations/pi/{owned-ui → session-ui}/route-host.js +0 -0
@@ -1,7 +1,7 @@
1
1
  import { resolveProductPaths } from "../foundation/lifecycle/index.js";
2
2
  import { applyConfiguredPiTheme, getAvailablePiThemes } from "../integrations/pi/components/index.js";
3
3
  import { createPiEngineAdapter } from "../integrations/pi/engine/index.js";
4
- import { OwnedUiSessionShell } from "../integrations/pi/owned-ui/index.js";
4
+ import { OwnedUiSessionShell } from "../integrations/pi/session-ui/index.js";
5
5
  import { OwnedUiSettingsSession, OwnedUiSettingsStore } from "../ui/settings/index.js";
6
6
  import { createPiTerminalBridge } from "../integrations/pi/tui-runtime/index.js";
7
7
  import { createOwnedRouteHost } from "./settings-route-host.js";
@@ -13,17 +13,20 @@ export async function composeOwnedUi(options = {}) {
13
13
  const adapter = options.createPiAdapter
14
14
  ? await options.createPiAdapter()
15
15
  : await createPiEngineAdapter({ cwd, availableThemes: () => getAvailablePiThemes().map(theme => theme.name) });
16
+ const ownedSurfaces = options.ownedSurfaces !== "off";
16
17
  const settings = options.profileId === undefined
17
18
  ? null
18
19
  : new OwnedUiSettingsSession({
19
20
  store: new OwnedUiSettingsStore({ configDir: resolveProductPaths().configDir, profileId: options.profileId }),
20
21
  agentProvider: () => adapter.settingsPort(),
21
- ...(options.ownedSurfaces === "off" ? {} : { hiddenAgentSettingIds: ["tuiMode"] }),
22
+ ...(ownedSurfaces ? {
23
+ hiddenAgentSettingIds: ["tuiMode", "theme", "fullscreenScrollbar", "quietStartup"],
24
+ } : {}),
22
25
  });
23
- // Before anything is drawn, so every surface uses the configured theme rather
24
- // than the one guessed from the terminal's background.
25
- applyConfiguredPiTheme(adapter.configuredTheme());
26
- const ownedSurfaces = options.ownedSurfaces !== "off";
26
+ // Bare A1 intentionally ships one visual target while its UI is being completed:
27
+ // dark, regardless of terminal detection or a previously stored Pi theme. The
28
+ // comparison profile keeps Pi's configured theme behavior and settings surface.
29
+ applyConfiguredPiTheme(ownedSurfaces ? "dark" : adapter.configuredTheme());
27
30
  const routeHost = settings === null || !ownedSurfaces ? null : createOwnedRouteHost(settings);
28
31
  const viewportSettings = settings === null || !ownedSurfaces ? null : {
29
32
  snapshot: () => viewportSettingsSnapshot(settings),
@@ -51,7 +54,7 @@ function viewportSettingsSnapshot(settings) {
51
54
  const style = settings.value("scrollbarStyle");
52
55
  const speed = settings.value("scrollbarSpeed");
53
56
  return {
54
- scrollbarAppearance: appearance === "always" || appearance === "hidden" ? appearance : "hover",
57
+ scrollbarAppearance: appearance === "always" || appearance === "hidden" ? appearance : "auto",
55
58
  scrollbarStyle: style === "thick" ? "thick" : "thin",
56
59
  scrollbarSpeed: speed === "high" ? "high" : speed === "fast" ? "fast" : "normal",
57
60
  };
@@ -1,5 +1,5 @@
1
- import type { UiRouteHost } from "../integrations/pi/owned-ui/index.js";
2
1
  import type { OwnedUiSettingsSession } from "../ui/settings/index.js";
2
+ import { type UiRouteHost } from "../ui/apps/index.js";
3
3
  /**
4
4
  * Registers the A1-owned screens and adapts the app host to the shell's route
5
5
  * seam. The shell mounts whatever surface it is handed and forwards keys; it
@@ -1,6 +1,6 @@
1
1
  import { SETTINGS_APP_ID, SETTINGS_ROUTE, SettingsApp } from "../features/owned-ui/index.js";
2
2
  import { piTheme } from "../integrations/pi/components/index.js";
3
- import { UiAppHost, UiAppRegistry } from "../ui/apps/index.js";
3
+ import { UiAppHost, UiAppRegistry, } from "../ui/apps/index.js";
4
4
  import { faint } from "../ui/components/index.js";
5
5
  /**
6
6
  * Registers the A1-owned screens and adapts the app host to the shell's route
@@ -13,7 +13,7 @@ export interface OwnedUiModelInfo {
13
13
  }
14
14
  export type OwnedUiThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
15
15
  export interface OwnedUiViewportSettings {
16
- readonly scrollbarAppearance: "always" | "hover" | "hidden";
16
+ readonly scrollbarAppearance: "auto" | "always" | "hidden";
17
17
  readonly scrollbarStyle: "thin" | "thick";
18
18
  /** normal is baseline; fast is 2x normal; high is normal plus fast. */
19
19
  readonly scrollbarSpeed: "normal" | "fast" | "high";
@@ -29,6 +29,11 @@ export interface OwnedUiTerminalSurface {
29
29
  readonly focusedRegion: "transcript" | "editor" | "dialog" | "overlay" | "status";
30
30
  readonly hardwareCursor: boolean;
31
31
  }
32
+ export interface OwnedUiImageAttachment {
33
+ readonly type: "image";
34
+ readonly data: string;
35
+ readonly mimeType: string;
36
+ }
32
37
  export interface OwnedUiEditorState {
33
38
  readonly text: string;
34
39
  readonly queuedSubmissions: readonly string[];
@@ -133,11 +138,13 @@ export type OwnedUiCommand = {
133
138
  readonly correlationId: OwnedUiCorrelationId;
134
139
  readonly sessionId: OwnedUiSessionId;
135
140
  readonly text: string;
141
+ readonly images?: readonly OwnedUiImageAttachment[];
136
142
  } | {
137
143
  readonly type: "steer" | "follow-up";
138
144
  readonly correlationId: OwnedUiCorrelationId;
139
145
  readonly sessionId: OwnedUiSessionId;
140
146
  readonly text: string;
147
+ readonly images?: readonly OwnedUiImageAttachment[];
141
148
  } | {
142
149
  readonly type: "abort" | "retry" | "compact" | "shutdown";
143
150
  readonly correlationId: OwnedUiCorrelationId;
@@ -5,6 +5,8 @@ const MAX_MESSAGE_LENGTH = 4_096;
5
5
  const MAX_TEXT_BYTES = 256 * 1024;
6
6
  const MAX_PAYLOAD_BYTES = 64 * 1024;
7
7
  const MAX_SESSION_VIEW_BYTES = 1024 * 1024;
8
+ const MAX_IMAGE_DATA_BYTES = 8 * 1024 * 1024;
9
+ const MAX_PROMPT_IMAGES = 8;
8
10
  const MAX_BLOCKS = 10_000;
9
11
  const MAX_CUSTOMIZATIONS = 1_000;
10
12
  const MAX_DIAGNOSTICS = 1_000;
@@ -53,6 +55,15 @@ export function assertOwnedUiCommand(command) {
53
55
  case "steer":
54
56
  case "follow-up":
55
57
  assertBoundedText(command.text, "owned-UI prompt text", MAX_TEXT_BYTES);
58
+ if (command.images !== undefined) {
59
+ assertCollection(command.images, "owned-UI prompt images", MAX_PROMPT_IMAGES);
60
+ for (const image of command.images) {
61
+ if (image.type !== "image")
62
+ throw new TypeError("owned-UI prompt image type is invalid");
63
+ assertBoundedText(image.data, "owned-UI prompt image data", MAX_IMAGE_DATA_BYTES);
64
+ assertBoundedText(image.mimeType, "owned-UI prompt image MIME type", MAX_LABEL_LENGTH);
65
+ }
66
+ }
56
67
  return;
57
68
  case "abort":
58
69
  case "retry":
@@ -1,4 +1,4 @@
1
- import { GLOBAL_SCOPE, LineInput, PLAIN_THEME, ShortcutRegistry, PROMPT_GLYPH, blockJumpTarget, dialogValueColumn, numericValues, RAIL_COLUMNS, renderDialogPanel, renderEmptyState, renderGroupHeader, renderInputRow, renderStatusLine, renderListRow, renderNote, dialogRowAt, menuRowAt, regionAt, renderValueMenu, withScrollbarRail, stepperEnds, steppedValue, valueColumnFor, valueMenuFrame, promptRule, caretCell, blockRowSpan, displayWidth, faint, handleLineInputKey, humanizeLabel, humanizeTitle, indexOfKey, isThumbRow, layoutList, moveSelection, rowKey, scrollForSelection, scrollbarGeometry, selectableIndexes, } from "../../ui/components/index.js";
1
+ import { GLOBAL_SCOPE, LineInput, PLAIN_THEME, ShortcutRegistry, assertNoShortcutConflicts, PROMPT_GLYPH, blockJumpTarget, dialogValueColumn, numericValues, RAIL_COLUMNS, renderDialogPanel, renderEmptyState, renderGroupHeader, renderInputRow, renderStatusLine, renderListRow, renderNote, dialogRowAt, menuRowAt, regionAt, renderValueMenu, withScrollbarRail, stepperEnds, steppedValue, valueColumnFor, valueMenuFrame, promptRule, caretCell, blockRowSpan, displayWidth, faint, handleLineInputKey, humanizeLabel, humanizeTitle, indexOfKey, isThumbRow, layoutList, moveSelection, rowKey, scrollForSelection, scrollbarGeometry, selectableIndexes, } from "../../ui/components/index.js";
2
2
  export const SETTINGS_APP_ID = "settings";
3
3
  export const SETTINGS_ROUTE = "settings";
4
4
  const SCOPE = SETTINGS_APP_ID;
@@ -29,6 +29,7 @@ SETTINGS_SHORTCUTS.declare({ key: "left", scope: DIALOG_SCOPE, description: "Cha
29
29
  SETTINGS_SHORTCUTS.declare({ key: "right", scope: DIALOG_SCOPE, description: "Change this part", section: "Parts" }, "part-change");
30
30
  SETTINGS_SHORTCUTS.declare({ key: "up", scope: DIALOG_SCOPE, description: "Previous part", section: "Parts" }, "part-previous");
31
31
  SETTINGS_SHORTCUTS.declare({ key: "down", scope: DIALOG_SCOPE, description: "Next part", section: "Parts" }, "part-next");
32
+ assertNoShortcutConflicts(SETTINGS_SHORTCUTS.assemble());
32
33
  const KEYS = {
33
34
  "\u001b[A": "up",
34
35
  "\u001b[B": "down",
@@ -0,0 +1,55 @@
1
+ import { type Editor } from "#pi-tui";
2
+ import type { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
3
+ import type { PiShellClipboardContent, PiShellEditorTextRange } from "./shell-shared-facade.js";
4
+ /**
5
+ * Middleware boundary around Pi's editor. Interceptors may claim an input or
6
+ * delegate to the next interceptor/vanilla editor, and may decorate the rows
7
+ * vanilla Pi renders. This keeps owned UX additions out of the synchronized
8
+ * Pi editor port and gives future interactions one registration point.
9
+ */
10
+ export interface OwnedEditorUxInterceptor {
11
+ handleInput(data: string, next: () => void): void;
12
+ render(width: number, next: () => string[]): string[];
13
+ reset(): void;
14
+ handlePointer?(event: OwnedEditorPointerEvent): boolean;
15
+ hasSelection?(): boolean;
16
+ ownsPointer?(): boolean;
17
+ pasteClipboard?(): boolean;
18
+ }
19
+ export interface OwnedEditorPointerEvent {
20
+ readonly kind: "press" | "motion" | "release";
21
+ readonly button: number;
22
+ readonly column: number;
23
+ /** One-based row relative to the top of the editor component. */
24
+ readonly row: number;
25
+ }
26
+ export declare class OwnedEditorUxInterception {
27
+ readonly interceptors: readonly OwnedEditorUxInterceptor[];
28
+ readonly fallback: {
29
+ handleInput(data: string): void;
30
+ render(width: number): string[];
31
+ };
32
+ constructor(interceptors: readonly OwnedEditorUxInterceptor[], fallback: {
33
+ handleInput(data: string): void;
34
+ render(width: number): string[];
35
+ });
36
+ handleInput(data: string): void;
37
+ render(width: number): string[];
38
+ reset(): void;
39
+ handlePointer(event: OwnedEditorPointerEvent): boolean;
40
+ hasSelection(): boolean;
41
+ ownsPointer(): boolean;
42
+ pasteClipboard(): boolean;
43
+ }
44
+ export interface PromptSelectionUxOptions {
45
+ readonly copyText: (text: string) => void;
46
+ readonly readClipboardContent: () => Promise<PiShellClipboardContent | null>;
47
+ readonly transformPastedContent: (content: PiShellClipboardContent) => string;
48
+ readonly atomicRanges: (line: string) => readonly PiShellEditorTextRange[];
49
+ readonly expandCopiedText: (text: string) => string;
50
+ readonly paintSelection: (line: string, from: number, to: number, atomic: boolean) => string;
51
+ readonly decorateRow: (row: string, width: number) => string;
52
+ readonly requestRender: () => void;
53
+ readonly getRows: () => number;
54
+ }
55
+ export declare function createPromptSelectionInterceptor(editor: Editor, keybindings: KeybindingsManager, options: PromptSelectionUxOptions): OwnedEditorUxInterceptor;