@timurproko/a1 0.2.7-dev.1275 → 0.2.7-dev.1285

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 (220) hide show
  1. package/README.md +5 -1
  2. package/dist/app/session-shell/apps-dialog.d.ts +1 -1
  3. package/dist/app/session-shell/apps-dialog.js +2 -1
  4. package/dist/app/session-shell/dialog-coordinator.d.ts +4 -5
  5. package/dist/app/session-shell/dialog-coordinator.js +41 -12
  6. package/dist/app/session-shell/input-route.d.ts +23 -0
  7. package/dist/app/session-shell/input-route.js +59 -0
  8. package/dist/app/session-shell/session-selectors.d.ts +3 -3
  9. package/dist/app/session-shell/session-selectors.js +7 -2
  10. package/dist/app/session-shell/session-shell-root.d.ts +4 -68
  11. package/dist/app/session-shell/session-shell-root.js +6 -2
  12. package/dist/app/session-shell/session-shell.js +9 -13
  13. package/dist/app/session-shell/shell-host.js +2 -2
  14. package/dist/app/session-shell/shell-options.d.ts +65 -0
  15. package/dist/app/session-shell/shell-options.js +1 -0
  16. package/dist/app/session-shell/viewport-pointer.js +5 -1
  17. package/dist/app/session-shell/workflow-router.d.ts +4 -2
  18. package/dist/app/session-shell/workflow-router.js +12 -0
  19. package/dist/cli/dispatch.js +27 -1
  20. package/dist/cli/packages.js +18 -2
  21. package/dist/cli/session-context.js +6 -2
  22. package/dist/composition/owned-ui.js +20 -8
  23. package/dist/composition/session-naming.js +1 -1
  24. package/dist/composition/session-runtime-registry.d.ts +2 -0
  25. package/dist/composition/session-runtime-registry.js +49 -9
  26. package/dist/composition/settings-route-host.js +1 -0
  27. package/dist/contracts/agent-engine/package-ports.d.ts +10 -14
  28. package/dist/contracts/agent-engine/package-ports.js +5 -9
  29. package/dist/contracts/owned-ui/session-workflows.d.ts +6 -0
  30. package/dist/contracts/owned-ui/shell-components.d.ts +10 -0
  31. package/dist/contracts/presentation/component.d.ts +7 -0
  32. package/dist/contracts/presentation/index.d.ts +3 -0
  33. package/dist/contracts/presentation/index.js +4 -0
  34. package/dist/contracts/presentation/progress-palette.generated.d.ts +25 -1
  35. package/dist/contracts/presentation/progress-palette.generated.js +2 -135
  36. package/dist/contracts/presentation/progress-spinner.d.ts +7 -0
  37. package/dist/contracts/presentation/progress-spinner.js +1 -0
  38. package/dist/features/launch/session-context.d.ts +8 -0
  39. package/dist/features/launch/session-context.js +19 -10
  40. package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
  41. package/dist/features/owned-ui/project-trust-dialog.js +5 -5
  42. package/dist/features/owned-ui/project-trust-prompt.js +2 -2
  43. package/dist/features/owned-ui/reference-screen-app.d.ts +2 -0
  44. package/dist/features/owned-ui/reference-screen-app.js +12 -5
  45. package/dist/features/owned-ui/session-fork-prompt.d.ts +2 -1
  46. package/dist/features/owned-ui/session-fork-prompt.js +11 -5
  47. package/dist/features/owned-ui/settings-app.d.ts +1 -1
  48. package/dist/features/owned-ui/settings-app.js +20 -13
  49. package/dist/features/owned-ui/settings-model-dialog.js +3 -3
  50. package/dist/features/owned-ui/settings-spinner-preview.d.ts +9 -0
  51. package/dist/features/owned-ui/settings-spinner-preview.js +29 -0
  52. package/dist/features/session-naming/context.d.ts +17 -0
  53. package/dist/features/session-naming/context.js +39 -0
  54. package/dist/features/session-naming/controller.d.ts +1 -5
  55. package/dist/features/session-naming/controller.js +7 -4
  56. package/dist/features/session-naming/generate.d.ts +2 -1
  57. package/dist/features/session-naming/generate.js +14 -10
  58. package/dist/features/session-naming/index.d.ts +1 -1
  59. package/dist/foundation/lifecycle/index.d.ts +3 -1
  60. package/dist/foundation/lifecycle/index.js +3 -1
  61. package/dist/foundation/lifecycle/session-claim-lock.d.ts +2 -2
  62. package/dist/foundation/lifecycle/session-claim-lock.js +36 -10
  63. package/dist/foundation/lifecycle/session-context-retry.d.ts +2 -0
  64. package/dist/foundation/lifecycle/session-context-retry.js +17 -0
  65. package/dist/foundation/lifecycle/session-repository-context.d.ts +7 -1
  66. package/dist/foundation/lifecycle/session-repository-context.js +105 -39
  67. package/dist/foundation/lifecycle/session-worktree-entry.d.ts +3 -0
  68. package/dist/foundation/lifecycle/session-worktree-entry.js +87 -0
  69. package/dist/foundation/release/automatic-update.js +2 -2
  70. package/dist/foundation/release/bootstrap.js +19 -3
  71. package/dist/foundation/release/release-gc.js +20 -5
  72. package/dist/foundation/release/release-state.d.ts +12 -3
  73. package/dist/foundation/release/release-state.js +55 -24
  74. package/dist/foundation/release/release-use.d.ts +10 -0
  75. package/dist/foundation/release/release-use.js +70 -0
  76. package/dist/foundation/release/update-activation.js +2 -2
  77. package/dist/foundation/release/update-recovery.js +2 -2
  78. package/dist/foundation/release/update.js +1 -1
  79. package/dist/foundation/release/warmup.js +8 -9
  80. package/dist/foundation/session-writer-lock/index.d.ts +2 -2
  81. package/dist/foundation/session-writer-lock/index.js +82 -12
  82. package/dist/foundation/startup/startup-descriptor.js +2 -2
  83. package/dist/foundation/terminal-cleanup/fatal-diagnostic.d.ts +2 -0
  84. package/dist/foundation/terminal-cleanup/fatal-diagnostic.js +59 -0
  85. package/dist/foundation/terminal-cleanup/fatal-exit.js +1 -29
  86. package/dist/integrations/pi/components/deferred-selector.d.ts +6 -0
  87. package/dist/integrations/pi/components/deferred-selector.js +40 -0
  88. package/dist/integrations/pi/components/login-dialog-loader.d.ts +3 -0
  89. package/dist/integrations/pi/components/login-dialog-loader.js +57 -0
  90. package/dist/integrations/pi/components/login-links.d.ts +6 -0
  91. package/dist/integrations/pi/components/login-links.js +31 -0
  92. package/dist/integrations/pi/components/login-text.d.ts +7 -0
  93. package/dist/integrations/pi/components/login-text.js +17 -0
  94. package/dist/integrations/pi/components/modal-frame.d.ts +5 -0
  95. package/dist/integrations/pi/components/modal-frame.js +30 -2
  96. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
  97. package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
  98. package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -1
  99. package/dist/integrations/pi/components/share-operation-dialog.js +13 -5
  100. package/dist/integrations/pi/components/shell-footer-status.d.ts +2 -1
  101. package/dist/integrations/pi/components/shell-footer-status.js +15 -8
  102. package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +11 -8
  103. package/dist/integrations/pi/components/shell-selectors-dialogs.js +36 -35
  104. package/dist/integrations/pi/components/shell-session-info-reference.d.ts +1 -1
  105. package/dist/integrations/pi/components/shell-session-info-reference.js +55 -49
  106. package/dist/integrations/pi/components/theme.d.ts +2 -0
  107. package/dist/integrations/pi/components/theme.js +4 -0
  108. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  109. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
  110. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  111. package/dist/integrations/pi/components/upstream/components/auth-url.d.ts +16 -0
  112. package/dist/integrations/pi/components/upstream/components/auth-url.js +49 -0
  113. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  114. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  115. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  116. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  117. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  118. package/dist/integrations/pi/components/upstream/components/extension-selector.d.ts +1 -0
  119. package/dist/integrations/pi/components/upstream/components/extension-selector.js +22 -11
  120. package/dist/integrations/pi/components/upstream/components/login-dialog.d.ts +3 -0
  121. package/dist/integrations/pi/components/upstream/components/login-dialog.js +216 -0
  122. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  123. package/dist/integrations/pi/components/upstream/components/oauth-selector.d.ts +19 -0
  124. package/dist/integrations/pi/components/upstream/components/oauth-selector.js +123 -0
  125. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
  126. package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
  127. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  128. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
  129. package/dist/integrations/pi/components/upstream/components/session-footer.js +22 -13
  130. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  131. package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
  132. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  133. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  134. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
  135. package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
  136. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  137. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  138. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
  139. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +1 -1
  140. package/dist/integrations/pi/components/upstream/components/tool-execution.js +1 -1
  141. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
  142. package/dist/integrations/pi/components/upstream/components/tree-selector.js +1 -1
  143. package/dist/integrations/pi/components/upstream/components/trust-selector.d.ts +2 -0
  144. package/dist/integrations/pi/components/upstream/components/trust-selector.js +30 -13
  145. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  146. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +1 -1
  147. package/dist/integrations/pi/components/upstream/history/editor-core.js +1 -1
  148. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  149. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  150. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  151. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  152. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  153. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  154. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  155. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  156. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  157. package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
  158. package/dist/integrations/pi/engine/adapter.d.ts +3 -1
  159. package/dist/integrations/pi/engine/adapter.js +24 -6
  160. package/dist/integrations/pi/engine/changelog.js +5 -2
  161. package/dist/integrations/pi/engine/delivery-retention.d.ts +7 -0
  162. package/dist/integrations/pi/engine/delivery-retention.js +66 -0
  163. package/dist/integrations/pi/engine/event-delivery.d.ts +17 -1
  164. package/dist/integrations/pi/engine/event-delivery.js +25 -3
  165. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -1
  166. package/dist/integrations/pi/engine/extension-ui-binding.js +45 -0
  167. package/dist/integrations/pi/engine/host-ports.d.ts +2 -0
  168. package/dist/integrations/pi/engine/host.d.ts +3 -0
  169. package/dist/integrations/pi/engine/host.js +2 -0
  170. package/dist/integrations/pi/engine/package-integration.js +19 -4
  171. package/dist/integrations/pi/engine/pending-delivery.d.ts +4 -1
  172. package/dist/integrations/pi/engine/pending-delivery.js +51 -18
  173. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  174. package/dist/integrations/pi/engine/runtime-integration.d.ts +8 -0
  175. package/dist/integrations/pi/engine/runtime-integration.js +58 -9
  176. package/dist/integrations/pi/engine/session-cwd-recovery.d.ts +11 -0
  177. package/dist/integrations/pi/engine/session-cwd-recovery.js +18 -0
  178. package/dist/integrations/pi/engine/session-runtime.d.ts +3 -0
  179. package/dist/integrations/pi/engine/session-runtime.js +2 -0
  180. package/dist/integrations/pi/engine/session-selection.d.ts +3 -2
  181. package/dist/integrations/pi/engine/session-selection.js +25 -5
  182. package/dist/integrations/pi/engine/transcript-image-assets.d.ts +3 -0
  183. package/dist/integrations/pi/engine/transcript-image-assets.js +65 -14
  184. package/dist/integrations/pi/engine/view-state.d.ts +14 -0
  185. package/dist/integrations/pi/engine/view-state.js +17 -0
  186. package/dist/integrations/pi/engine/workflow-runner.d.ts +2 -0
  187. package/dist/integrations/pi/engine/workflow-runner.js +47 -26
  188. package/dist/integrations/pi/engine/worktree-tools.d.ts +4 -0
  189. package/dist/integrations/pi/engine/worktree-tools.js +26 -0
  190. package/dist/integrations/pi/session-presenters/components.d.ts +2 -1
  191. package/dist/integrations/pi/session-presenters/components.js +12 -10
  192. package/dist/integrations/pi/session-presenters/presenters.d.ts +3 -1
  193. package/dist/integrations/pi/session-presenters/presenters.js +2 -2
  194. package/dist/integrations/pi/startup-public.d.ts +1 -1
  195. package/dist/integrations/pi/startup-public.js +16 -20
  196. package/dist/integrations/pi/startup-public.manifest.json +29 -29
  197. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
  198. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
  199. package/dist/product-identity.json +1 -1
  200. package/dist/runtime-payload-inventory.json +5027 -5027
  201. package/dist/ui/components/index.d.ts +1 -1
  202. package/dist/ui/components/index.js +1 -1
  203. package/dist/ui/components/list-block.d.ts +2 -2
  204. package/dist/ui/components/list-block.js +4 -3
  205. package/dist/ui/components/progress-status.d.ts +7 -0
  206. package/dist/ui/components/progress-status.js +21 -0
  207. package/dist/ui/components/value-menu.d.ts +1 -1
  208. package/dist/ui/components/value-menu.js +4 -2
  209. package/dist/ui/settings/declarations.d.ts +16 -4
  210. package/dist/ui/settings/declarations.js +13 -4
  211. package/dist/ui/settings/early-accent.d.ts +24 -0
  212. package/docs/architecture/internal-naming.md +1 -1
  213. package/docs/architecture/project-structure.md +7 -11
  214. package/docs/features/session-exports.md +1 -1
  215. package/docs/features/session-naming.md +8 -6
  216. package/docs/features/worktrees.md +38 -0
  217. package/docs/local-worktree-cleanup.md +27 -4
  218. package/docs/openspec-archive-automation.md +30 -4
  219. package/docs/worktree-link-recovery.md +2 -2
  220. package/package.json +5 -5
@@ -0,0 +1,59 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdir, readdir, unlink, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ /** Loaded only on a failure; persistence must never impede terminal restoration. */
5
+ export async function writeFatalDiagnostic(directory, origin, error, releaseId) {
6
+ try {
7
+ // Security: only known classifications and code locations are retained, never private messages or objects.
8
+ const cleanupFailed = error instanceof AggregateError && error.cause instanceof Error;
9
+ const primary = cleanupFailed ? error.cause : error;
10
+ const classification = primary instanceof TypeError ? "TypeError" : primary instanceof RangeError ? "RangeError" : "Error";
11
+ const stack = primary instanceof Error && typeof primary.stack === "string" ? primary.stack.slice(0, 32768) : "";
12
+ const locations = stack.split("\n").slice(1).flatMap(line => {
13
+ const match = /\/(?:dist|src)\/([a-zA-Z0-9_./-]+\.[cm]?[jt]s):(\d+):(\d+)\)?$/.exec(line.replaceAll("\\", "/"));
14
+ return match ? [{ file: match[1].slice(0, 160), line: Number(match[2]), column: Number(match[3]) }] : [];
15
+ }).slice(0, 16);
16
+ const delivery = deliveryFailure(primary);
17
+ const record = {
18
+ timestamp: new Date().toISOString(),
19
+ origin: ["uncaughtException", "unhandledRejection", "entry", "delivery"].includes(origin) ? origin : "entry",
20
+ ...(delivery === null ? {} : { deliveryFailure: delivery }),
21
+ classification, cleanupFailed, locations, node: process.version, platform: process.platform,
22
+ releaseId: releaseId && /^[a-zA-Z0-9._-]{1,128}$/.test(releaseId) ? releaseId : "unknown",
23
+ };
24
+ await mkdir(directory, { recursive: true, mode: 0o700 });
25
+ const name = `${origin === "delivery" ? "delivery" : "fatal"}-${Date.now()}-${randomUUID()}.json`;
26
+ const path = join(directory, name);
27
+ const text = JSON.stringify(record, null, 2);
28
+ if (Buffer.byteLength(text) > 16 * 1024)
29
+ return null;
30
+ await writeFile(path, text, { flag: "wx", mode: 0o600 });
31
+ const names = (await readdir(directory)).filter(file => /^(?:fatal|delivery)-\d+-[a-f0-9-]+\.json$/.test(file))
32
+ .sort((a, b) => Number(b.split("-")[1]) - Number(a.split("-")[1]));
33
+ await Promise.all(names.slice(10).map(file => unlink(join(directory, file)).catch(() => undefined)));
34
+ return path;
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ function deliveryFailure(error) {
41
+ if (!(error instanceof Error) || !("deliveryFailure" in error))
42
+ return null;
43
+ const value = error.deliveryFailure;
44
+ if (!value || typeof value !== "object")
45
+ return null;
46
+ const record = value;
47
+ if (!["event-count", "retained-bytes", "listener"].includes(String(record.reason))
48
+ || !["snapshot", "session-view", "transcript-block", "session-lifecycle", "status", "editor-state", "terminal-surface",
49
+ "agent-run-started", "agent-run-settled", "assistant-message-completed", "command-outcome", "diagnostic"].includes(String(record.event)))
50
+ return null;
51
+ const result = { reason: String(record.reason), event: String(record.event) };
52
+ for (const key of ["generation", "pending", "bytes"]) {
53
+ const number = record[key];
54
+ if (typeof number !== "number" || !Number.isSafeInteger(number) || number < 0)
55
+ return null;
56
+ result[key] = number;
57
+ }
58
+ return result;
59
+ }
@@ -1,36 +1,8 @@
1
- import { randomUUID } from "node:crypto";
2
- import { mkdir, readdir, unlink, writeFile } from "node:fs/promises";
3
1
  import { writeSync } from "node:fs";
4
- import { join } from "node:path";
5
2
  import { boundedCleanup, restoreProcessTerminal } from "./terminal-reset.js";
6
3
  export async function writeFatalDiagnostic(directory, origin, error, releaseId) {
7
4
  try {
8
- // Security: only known classifications and code locations are retained. Error messages,
9
- // function names, arbitrary paths, and request objects are never persisted.
10
- const cleanupFailed = error instanceof AggregateError && error.cause instanceof Error;
11
- const primary = cleanupFailed ? error.cause : error;
12
- const classification = primary instanceof TypeError ? "TypeError" : primary instanceof RangeError ? "RangeError" : "Error";
13
- const stack = primary instanceof Error && typeof primary.stack === "string" ? primary.stack.slice(0, 32768) : "";
14
- const locations = stack.split("\n").slice(1).flatMap(line => {
15
- const match = /\/(?:dist|src)\/([a-zA-Z0-9_./-]+\.[cm]?[jt]s):(\d+):(\d+)\)?$/.exec(line.replaceAll("\\", "/"));
16
- return match ? [{ file: match[1].slice(0, 160), line: Number(match[2]), column: Number(match[3]) }] : [];
17
- }).slice(0, 16);
18
- const record = {
19
- timestamp: new Date().toISOString(),
20
- origin: ["uncaughtException", "unhandledRejection", "entry"].includes(origin) ? origin : "entry",
21
- classification, cleanupFailed, locations, node: process.version, platform: process.platform,
22
- releaseId: releaseId && /^[a-zA-Z0-9._-]{1,128}$/.test(releaseId) ? releaseId : "unknown",
23
- };
24
- await mkdir(directory, { recursive: true, mode: 0o700 });
25
- const name = `fatal-${Date.now()}-${randomUUID()}.json`;
26
- const path = join(directory, name);
27
- const text = JSON.stringify(record, null, 2);
28
- if (Buffer.byteLength(text) > 16 * 1024)
29
- return null;
30
- await writeFile(path, text, { flag: "wx", mode: 0o600 });
31
- const names = (await readdir(directory)).filter(file => /^fatal-\d+-[a-f0-9-]+\.json$/.test(file)).sort().reverse();
32
- await Promise.all(names.slice(10).map(file => unlink(join(directory, file)).catch(() => undefined)));
33
- return path;
5
+ return await (await import("./fatal-diagnostic.js")).writeFatalDiagnostic(directory, origin, error, releaseId);
34
6
  }
35
7
  catch {
36
8
  return null;
@@ -0,0 +1,6 @@
1
+ import type { PiShellSkillsSelectorOptions } from "./skills-dialog.js";
2
+ import type { OwnedUiShellComponentPort } from "../../../contracts/owned-ui/index.js";
3
+ /** Defers optional selector code while retaining focus, early input and cancellation. */
4
+ export declare function deferredSelector(load: () => Promise<OwnedUiShellComponentPort>, cancel: () => void): OwnedUiShellComponentPort;
5
+ /** Keeps Skills outside first-prompt loading. */
6
+ export declare function createPiShellSkillsSelector(options: PiShellSkillsSelectorOptions): OwnedUiShellComponentPort;
@@ -0,0 +1,40 @@
1
+ /** Defers optional selector code while retaining focus, early input and cancellation. */
2
+ export function deferredSelector(load, cancel) {
3
+ let delegate;
4
+ let closed = false;
5
+ let focused = false;
6
+ let failure;
7
+ const pending = [];
8
+ const ready = load().then(component => {
9
+ if (closed) {
10
+ component.dispose?.();
11
+ return;
12
+ }
13
+ delegate = component;
14
+ delegate.setFocused?.(focused);
15
+ for (const key of pending.splice(0)) {
16
+ if (!closed)
17
+ delegate.handleInput?.(key);
18
+ }
19
+ }).catch(() => { if (!closed)
20
+ failure = "Selector unavailable — Esc close"; });
21
+ return {
22
+ ready,
23
+ render: width => delegate?.render(width) ?? (failure === undefined ? [] : [failure.slice(0, width)]),
24
+ invalidate: () => delegate?.invalidate(),
25
+ handleInput: data => {
26
+ if (delegate !== undefined)
27
+ delegate.handleInput?.(data);
28
+ else if (data === "\u001b" || data === "\u0003")
29
+ cancel();
30
+ else if (pending.length < 32)
31
+ pending.push(data);
32
+ },
33
+ setFocused: value => { focused = value; delegate?.setFocused?.(value); },
34
+ dispose: () => { closed = true; pending.length = 0; delegate?.dispose?.(); },
35
+ };
36
+ }
37
+ /** Keeps Skills outside first-prompt loading. */
38
+ export function createPiShellSkillsSelector(options) {
39
+ return deferredSelector(() => import("./skills-dialog.js").then(module => module.createPiShellSkillsSelector(options)), options.onCancel);
40
+ }
@@ -0,0 +1,3 @@
1
+ import type { OwnedUiShellLoginDialogPort as Login } from "../../../contracts/owned-ui/index.js";
2
+ /** Queues optional login calls. */
3
+ export declare function deferredLoginDialog(...args: Parameters<typeof import("./upstream/components/login-dialog.js").createThemedLoginDialog>): Login;
@@ -0,0 +1,57 @@
1
+ /** Queues optional login calls. */
2
+ export function deferredLoginDialog(...args) {
3
+ const [runtime, , complete] = args;
4
+ let dialog, closed = false, focused = false, failed = false;
5
+ const pending = [];
6
+ const rejects = new Set();
7
+ const rejectAll = (message) => { for (const reject of rejects)
8
+ reject(new Error(message)); rejects.clear(); pending.length = 0; };
9
+ const ready = import("./upstream/components/login-dialog.js").then(module => {
10
+ if (closed)
11
+ return;
12
+ dialog = module.createThemedLoginDialog(...args);
13
+ dialog.setFocused?.(focused);
14
+ for (const action of pending.splice(0)) {
15
+ if (!closed)
16
+ action(dialog);
17
+ }
18
+ }).catch(() => { failed = true; rejectAll("Login unavailable"); }).finally(() => { if (!closed)
19
+ runtime.requestRender(); });
20
+ const call = (action) => { if (!closed && !failed) {
21
+ if (dialog)
22
+ action(dialog);
23
+ else
24
+ pending.push(action);
25
+ } };
26
+ const dispose = () => { closed = true; dialog?.dispose?.(); rejectAll("Login cancelled"); };
27
+ const answer = (action) => new Promise((resolve, reject) => {
28
+ if (closed || failed) {
29
+ reject(new Error("Login unavailable"));
30
+ return;
31
+ }
32
+ rejects.add(reject);
33
+ call(target => { rejects.delete(reject); void action(target).then(resolve, reject); });
34
+ });
35
+ return {
36
+ ready, dispose,
37
+ render: width => dialog?.render(width) ?? (failed ? ["Login unavailable — Esc close".slice(0, width)] : []),
38
+ invalidate: () => dialog?.invalidate(),
39
+ setFocused: value => { focused = value; dialog?.setFocused?.(value); },
40
+ handleInput: data => {
41
+ if (!dialog && (data === "\u001b" || data === "\u0003")) {
42
+ dispose();
43
+ complete(false, "Login cancelled");
44
+ }
45
+ else
46
+ call(target => target.handleInput?.(data));
47
+ },
48
+ showAuth: (url, instructions) => call(target => target.showAuth(url, instructions)),
49
+ showDeviceCode: info => call(target => target.showDeviceCode(info)),
50
+ showManualInput: message => answer(target => target.showManualInput(message)),
51
+ showPrompt: (message, placeholder) => answer(target => target.showPrompt(message, placeholder)),
52
+ showDetails: lines => call(target => target.showDetails(lines)),
53
+ showInfo: (message, links) => call(target => target.showInfo(message, links)),
54
+ showWaiting: message => call(target => target.showWaiting(message)),
55
+ showProgress: message => call(target => target.showProgress(message)),
56
+ };
57
+ }
@@ -0,0 +1,6 @@
1
+ /** Login effects accept web URLs only; controls are encoded before any hyperlink or launcher sees them. */
2
+ export declare function loginWebUrl(value: string): string | undefined;
3
+ /** Keeps untrusted non-web instructions printable without granting them a hyperlink target. */
4
+ export declare function loginLink(value: string, label?: string): string;
5
+ /** Best-effort browser request with argv boundaries, no shell, and no dependency on the project cwd. */
6
+ export declare function openLoginBrowser(value: string): void;
@@ -0,0 +1,31 @@
1
+ import { spawn } from "node:child_process";
2
+ import { hyperlink, replaceControlCharacters } from "@earendil-works/pi-tui";
3
+ /** Login effects accept web URLs only; controls are encoded before any hyperlink or launcher sees them. */
4
+ export function loginWebUrl(value) {
5
+ try {
6
+ const url = new URL(value);
7
+ return ["http:", "https:"].includes(url.protocol) ? url.href : undefined;
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ /** Keeps untrusted non-web instructions printable without granting them a hyperlink target. */
14
+ export function loginLink(value, label) {
15
+ const url = loginWebUrl(value);
16
+ const text = replaceControlCharacters(label ?? url ?? value);
17
+ return url === undefined ? text : hyperlink(text, url);
18
+ }
19
+ /** Best-effort browser request with argv boundaries, no shell, and no dependency on the project cwd. */
20
+ export function openLoginBrowser(value) {
21
+ const url = loginWebUrl(value);
22
+ if (url === undefined)
23
+ return;
24
+ const platform = process.platform;
25
+ const executable = platform === "win32" ? "rundll32" : platform === "darwin" ? "open" : "xdg-open";
26
+ const args = platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
27
+ try {
28
+ spawn(executable, args, { stdio: "ignore", detached: true, cwd: "/" }).on("error", () => { }).unref();
29
+ }
30
+ catch { /* Compatibility: a failed browser launch never interrupts provider authentication. */ }
31
+ }
@@ -0,0 +1,7 @@
1
+ import { type Component } from "@earendil-works/pi-tui";
2
+ type LoginTextRole = "accent" | "muted" | "warning" | "success" | "error" | "dim" | "text";
3
+ /** Preserves authored line breaks without replaying control payloads. */
4
+ export declare function loginPlainText(value: string): string;
5
+ /** A zero-inset login row that resolves its semantic role against the live theme on every frame. */
6
+ export declare function loginText(text: string | (() => string), role?: LoginTextRole, bold?: boolean): Component;
7
+ export {};
@@ -0,0 +1,17 @@
1
+ import { Text, replaceControlCharacters } from "@earendil-works/pi-tui";
2
+ import { piTheme } from "./theme.js";
3
+ /** Preserves authored line breaks without replaying control payloads. */
4
+ export function loginPlainText(value) {
5
+ return value.split("\n").map(line => replaceControlCharacters(line)).join("\n");
6
+ }
7
+ /** A zero-inset login row that resolves its semantic role against the live theme on every frame. */
8
+ export function loginText(text, role = "muted", bold = false) {
9
+ return {
10
+ render(width) {
11
+ const theme = piTheme();
12
+ const value = typeof text === "string" ? loginPlainText(text) : text();
13
+ return new Text(theme.fg(role, bold ? theme.bold(value) : value), 0, 0).render(width);
14
+ },
15
+ invalidate() { },
16
+ };
17
+ }
@@ -1,5 +1,10 @@
1
1
  import { Container, Input, type Component, type Focusable } from "@earendil-works/pi-tui";
2
+ import type { OwnedUiShellComponentPort } from "../../../contracts/owned-ui/index.js";
2
3
  export declare const PI_MODAL_CONTENT_PADDING_X = 1;
4
+ /** Applies standard primary/metadata roles without changing a pinned row's text or clipping. */
5
+ export declare function renderPiModalSelectedPrimary(row: string, width: number, labels: readonly string[]): string;
6
+ /** Standardizes internal legacy model/message choices without changing their controller or metadata. */
7
+ export declare function standardInternalChoicePort(port: OwnedUiShellComponentPort, metadata?: boolean): OwnedUiShellComponentPort;
3
8
  /** Paints the standard Pi Input prompt as a live-themed dialog-search marker. */
4
9
  export declare function renderPiModalSearchInput(input: Input, width: number): string[];
5
10
  /** Replaces one explicitly identified direct Input child with the standard search presentation. */
@@ -1,7 +1,35 @@
1
- import { Container, Input, Spacer, Text, } from "@earendil-works/pi-tui";
1
+ import { Container, Input, Spacer, Text, sliceByColumn, stripTerminalSequences, visibleWidth, } from "@earendil-works/pi-tui";
2
2
  import { DIALOG_CONTENT_PADDING_X, dialogFrameGeometry, insetDialogContent } from "../../../contracts/presentation/index.js";
3
- import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints } from "./theme.js";
3
+ import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints, renderPiModalListRow } from "./theme.js";
4
4
  export const PI_MODAL_CONTENT_PADDING_X = DIALOG_CONTENT_PADDING_X;
5
+ /** Applies standard primary/metadata roles without changing a pinned row's text or clipping. */
6
+ export function renderPiModalSelectedPrimary(row, width, labels) {
7
+ const plain = stripTerminalSequences(row).trimEnd();
8
+ if (!plain.startsWith(" → "))
9
+ return row;
10
+ const primary = labels.filter(label => plain.slice(3).startsWith(label))
11
+ .sort((left, right) => visibleWidth(right) - visibleWidth(left))[0];
12
+ const length = primary === undefined ? Math.max(0, visibleWidth(plain) - 3) : visibleWidth(primary);
13
+ const label = stripTerminalSequences(sliceByColumn(row, 3, length));
14
+ const suffix = sliceByColumn(row, 3 + length, Math.max(0, visibleWidth(plain) - 3 - length));
15
+ const theme = piTheme();
16
+ return ` ${renderPiModalListRow(`${theme.fg("accent", "→ ")}${theme.fg("text", label)}${theme.fg("muted", stripTerminalSequences(suffix))}`, Math.max(0, width - 1), true)}`;
17
+ }
18
+ /** Standardizes internal legacy model/message choices without changing their controller or metadata. */
19
+ export function standardInternalChoicePort(port, metadata = false) {
20
+ return { ...port, render: width => port.render(width).map(row => {
21
+ const match = /^(\s*)[→›] (.*)$/u.exec(stripTerminalSequences(row).trimEnd());
22
+ if (match === null)
23
+ return row;
24
+ const indent = visibleWidth(match[1]);
25
+ const marker = metadata ? sliceByColumn(row, indent + 2, 2) : "";
26
+ const label = metadata ? match[2].slice(2).split(/ \[| \(/u, 1)[0] : match[2];
27
+ const suffixStart = indent + 2 + (metadata ? 2 : 0) + visibleWidth(label);
28
+ const suffix = metadata ? sliceByColumn(row, suffixStart, Math.max(0, visibleWidth(row) - suffixStart)).trimEnd() : "";
29
+ const theme = piTheme();
30
+ return `${match[1]}${renderPiModalListRow(`${theme.fg("accent", "→ ")}${marker}${theme.fg("text", label)}${suffix}`, Math.max(0, width - indent), true)}`;
31
+ }) };
32
+ }
5
33
  /** Paints the standard Pi Input prompt as a live-themed dialog-search marker. */
6
34
  export function renderPiModalSearchInput(input, width) {
7
35
  return input.render(width).map(row => {
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.5.1 (MIT),
3
- * commit dd30101cfc5b0609411dd80b6f93adbc14db14cf.
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.5.2 (MIT),
3
+ * commit b4afdddf44e059c67ccf5097e5317d913521b470.
4
4
  * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
5
  * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.5.1 (MIT),
3
- * commit dd30101cfc5b0609411dd80b6f93adbc14db14cf.
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.5.2 (MIT),
3
+ * commit b4afdddf44e059c67ccf5097e5317d913521b470.
4
4
  * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
5
  * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
@@ -1,8 +1,9 @@
1
+ import type { ProgressSpinnerSource } from "../../../contracts/presentation/index.js";
1
2
  import { type PiShellComponentPort, type PiShellEditorOptions } from "./shell-shared-facade.js";
2
3
  export interface PiShellOperationLoaderPort extends PiShellComponentPort {
3
4
  readonly signal: AbortSignal;
4
5
  /** Relabels the running operation; the pinned comparison loader keeps its first label. */
5
6
  readonly setMessage?: (message: string) => void;
6
7
  }
7
- export declare function createPiShellShareOperationDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, message: string): PiShellOperationLoaderPort;
8
+ export declare function createPiShellShareOperationDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, message: string, spinner?: ProgressSpinnerSource): PiShellOperationLoaderPort;
8
9
  export declare function createPiShellOperationLoader(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, message: string): PiShellOperationLoaderPort;
@@ -1,5 +1,6 @@
1
1
  import { CancellableLoader, Spacer, Text, } from "@earendil-works/pi-tui";
2
2
  import { BorderedLoader, DynamicBorder } from "../startup-public.js";
3
+ import { progressSpinnerFrame } from "../../../ui/components/index.js";
3
4
  import { adoptPiModalFrame, PiModalFrame } from "./modal-frame.js";
4
5
  import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "./theme.js";
5
6
  import { componentPort, createTuiFacade, ensureTheme, } from "./shell-shared-facade.js";
@@ -7,26 +8,33 @@ import { componentPort, createTuiFacade, ensureTheme, } from "./shell-shared-fac
7
8
  class ShareOperationDialog {
8
9
  #loader;
9
10
  #frame;
10
- constructor(runtime, message) {
11
+ #releaseSpinner;
12
+ constructor(runtime, message, spinner) {
11
13
  const theme = piTheme();
12
- this.#loader = new CancellableLoader(createTuiFacade(runtime), text => theme.fg("accent", text), text => theme.fg("muted", text), message);
14
+ let phase = -1;
15
+ this.#loader = new CancellableLoader(createTuiFacade(runtime), currentFrame => {
16
+ phase += 1;
17
+ const glyph = progressSpinnerFrame(spinner?.snapshot() ?? "current", phase, currentFrame);
18
+ return glyph === "" ? "" : piTheme().fg("accent", glyph);
19
+ }, text => piTheme().fg("muted", text), message);
13
20
  this.#frame = new PiModalFrame(new DynamicBorder(paintPiBorder), [
14
21
  new Text(theme.fg("accent", theme.bold("Share")), 0, 0),
15
22
  this.#loader,
16
23
  new Spacer(1),
17
24
  new Text(renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]), 0, 0),
18
25
  ], new DynamicBorder(paintPiBorder));
26
+ this.#releaseSpinner = spinner?.onChange(() => this.#loader.invalidate());
19
27
  }
20
28
  get signal() { return this.#loader.signal; }
21
29
  setMessage(message) { this.#loader.setMessage(message); }
22
30
  invalidate() { this.#frame.invalidate(); }
23
31
  render(width) { return this.#frame.render(width); }
24
32
  handleInput(data) { this.#loader.handleInput(data); }
25
- dispose() { this.#loader.dispose(); }
33
+ dispose() { this.#releaseSpinner?.(); this.#loader.dispose(); }
26
34
  }
27
- export function createPiShellShareOperationDialog(runtime, message) {
35
+ export function createPiShellShareOperationDialog(runtime, message, spinner) {
28
36
  ensureTheme();
29
- const dialog = new ShareOperationDialog(runtime, message);
37
+ const dialog = new ShareOperationDialog(runtime, message, spinner);
30
38
  return { ...componentPort(dialog), signal: dialog.signal, setMessage: message => dialog.setMessage(message) };
31
39
  }
32
40
  export function createPiShellOperationLoader(runtime, message) {
@@ -1,8 +1,9 @@
1
1
  import type { OwnedUiShellKeybindings } from "../../../contracts/owned-ui/index.js";
2
+ import type { ProgressSpinnerSource } from "../../../contracts/presentation/index.js";
2
3
  import type { OwnedUiSessionViewModel } from "../../../contracts/owned-ui/index.js";
3
4
  import { type PiShellViewComponentPort, type PiShellStatusPort, type PiShellProgressStatusPresentation, type PiShellQueuedInputPort, type PiShellHeaderPort, type PiShellResourceEntry, type PiShellLoadedResourcesPort, type PiShellHeaderOptions, type PiShellEditorOptions } from "./shell-shared-facade.js";
4
5
  export declare function createPiShellHeader(options?: PiShellHeaderOptions): PiShellHeaderPort;
5
6
  export declare function createPiShellLoadedResources(resources: readonly PiShellResourceEntry[], initialExpanded?: boolean): PiShellLoadedResourcesPort;
6
- export declare function createPiShellStatus(view: OwnedUiSessionViewModel, progressStatus: PiShellProgressStatusPresentation, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellStatusPort;
7
+ export declare function createPiShellStatus(view: OwnedUiSessionViewModel, progressStatus: PiShellProgressStatusPresentation, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, spinner?: ProgressSpinnerSource): PiShellStatusPort;
7
8
  export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", showLevel?: () => boolean): PiShellViewComponentPort;
8
9
  export declare function createPiQueuedInputStatus(submissions: readonly string[], presentation?: "pinned" | "custom-viewport", getKeybindings?: () => OwnedUiShellKeybindings): PiShellQueuedInputPort;
@@ -1,3 +1,4 @@
1
+ import { progressSpinnerFrame } from "../../../ui/components/progress-status.js";
1
2
  import { piKeybindings } from "./shell-shared-facade.js";
2
3
  import { rawKeyHint, VERSION } from "../startup-public.js";
3
4
  import { Spacer, Text, } from "@earendil-works/pi-tui";
@@ -74,7 +75,7 @@ export function createPiShellLoadedResources(resources, initialExpanded = false)
74
75
  invalidate() { },
75
76
  };
76
77
  }
77
- export function createPiShellStatus(view, progressStatus, runtime) {
78
+ export function createPiShellStatus(view, progressStatus, runtime, spinner) {
78
79
  ensureTheme();
79
80
  const statusUi = createTuiFacade(runtime ?? { getColumns: () => 80, getRows: () => 24, requestRender() { } });
80
81
  let workingOverride;
@@ -83,7 +84,7 @@ export function createPiShellStatus(view, progressStatus, runtime) {
83
84
  let progressPresentation = "pinned";
84
85
  let placement = statusPlacement(view, workingOverride, workingOverrideActive);
85
86
  const liveStatusText = () => progressStatus.text(liveWorkingText(view, workingOverride, progressPresentation), progressPresentation);
86
- let component = statusComponent(view, statusUi, outputPad, liveStatusText, placement, progressPresentation, progressStatus);
87
+ let component = statusComponent(view, statusUi, outputPad, liveStatusText, placement, progressPresentation, progressStatus, spinner);
87
88
  let signature = statusSignature(view, workingOverride, outputPad, placement, progressPresentation);
88
89
  const rebuild = () => {
89
90
  const nextPlacement = statusPlacement(view, workingOverride, workingOverrideActive);
@@ -105,8 +106,12 @@ export function createPiShellStatus(view, progressStatus, runtime) {
105
106
  component.dispose();
106
107
  placement = nextPlacement;
107
108
  signature = nextSignature;
108
- component = statusComponent(view, statusUi, outputPad, liveStatusText, placement, progressPresentation, progressStatus);
109
+ component = statusComponent(view, statusUi, outputPad, liveStatusText, placement, progressPresentation, progressStatus, spinner);
109
110
  };
111
+ const releaseSpinner = spinner?.onChange(() => {
112
+ if (progressPresentation === "custom-viewport")
113
+ component?.invalidate();
114
+ });
110
115
  return {
111
116
  render: width => appendInstalledUpdateStatus(component?.render(width) ?? [], width, view, progressPresentation),
112
117
  renderDock: width => placement === "dock" ? component?.render(width) ?? [] : [],
@@ -131,6 +136,7 @@ export function createPiShellStatus(view, progressStatus, runtime) {
131
136
  rebuild();
132
137
  },
133
138
  dispose() {
139
+ releaseSpinner?.();
134
140
  if (component !== undefined && "dispose" in component && typeof component.dispose === "function")
135
141
  component.dispose();
136
142
  component = undefined;
@@ -201,21 +207,22 @@ function liveWorkingText(view, workingOverride, progressPresentation) {
201
207
  : message;
202
208
  }
203
209
  class OwnedWorkingStatusIndicator extends StatusIndicator {
204
- constructor(ui, message, frame) {
210
+ constructor(ui, message, frame, spinner) {
205
211
  let phase = -1;
206
- super("working", ui, spinner => {
212
+ super("working", ui, defaultFrame => {
207
213
  phase += 1;
208
- return piTheme().fg("accent", spinner);
214
+ const glyph = progressSpinnerFrame(spinner?.snapshot() ?? "current", phase, defaultFrame);
215
+ return glyph === "" ? "" : piTheme().fg("accent", glyph);
209
216
  }, text => frame(text, phase, {
210
217
  muted: value => piTheme().fg("muted", value),
211
218
  highlight: value => piTheme().fg("text", value),
212
219
  }), message);
213
220
  }
214
221
  }
215
- function statusComponent(view, ui, outputPad, liveStatusText, placement, progressPresentation, progressStatus) {
222
+ function statusComponent(view, ui, outputPad, liveStatusText, placement, progressPresentation, progressStatus, spinner) {
216
223
  if (placement === "live") {
217
224
  return progressPresentation === "custom-viewport"
218
- ? new OwnedWorkingStatusIndicator(ui, liveStatusText(), progressStatus.frame)
225
+ ? new OwnedWorkingStatusIndicator(ui, liveStatusText(), progressStatus.frame, spinner)
219
226
  : new WorkingStatusIndicator(ui, liveStatusText());
220
227
  }
221
228
  if (placement === "dock") {
@@ -1,10 +1,11 @@
1
1
  import { ModelSelectorComponent, type SessionInfo, type SettingsCallbacks, type SettingsConfig } from "../startup-public.js";
2
2
  import type { OwnedUiDialog } from "../../../contracts/owned-ui/index.js";
3
3
  import type { ModelsDialogCallbacks, ModelsDialogConfig } from "./models-dialog.js";
4
- import { type TrustDecision, type TrustOption, type TrustUpdate } from "./upstream/components/trust-selector.js";
4
+ import type { TrustDecision, TrustOption, TrustUpdate } from "./upstream/components/trust-selector.js";
5
5
  import { type PiShellComponentPort, type PiShellEditorOptions, type PiShellSelectorOption, type PiShellSelectorOptions } from "./shell-shared-facade.js";
6
- export { createPiShellSkillsSelector, type PiShellSkillsSelectorOptions } from "./skills-dialog.js";
7
- export declare function createPiShellSelector(options: PiShellSelectorOptions): PiShellComponentPort;
6
+ export { createPiShellSkillsSelector } from "./deferred-selector.js";
7
+ export type { PiShellSkillsSelectorOptions } from "./skills-dialog.js";
8
+ export declare function createPiShellSelector(options: PiShellSelectorOptions, standard?: boolean): PiShellComponentPort;
8
9
  export interface PiShellSettingsSelectorOptions {
9
10
  readonly config: SettingsConfig;
10
11
  readonly onChange: (callback: keyof SettingsCallbacks, value: unknown) => void;
@@ -13,6 +14,7 @@ export interface PiShellSettingsSelectorOptions {
13
14
  export declare function createPiShellSettingsSelector(options: PiShellSettingsSelectorOptions): PiShellComponentPort;
14
15
  type PiModelSelectorArguments = ConstructorParameters<typeof ModelSelectorComponent>;
15
16
  export interface PiShellModelSelectorOptions {
17
+ readonly standardStyle?: boolean;
16
18
  readonly currentModel: unknown;
17
19
  readonly modelRuntime: unknown;
18
20
  readonly scopedModels: readonly unknown[];
@@ -58,6 +60,7 @@ export interface PiShellModelsDialogPort extends PiShellComponentPort {
58
60
  /** The bare-A1 unified Models dialog behind the owned component boundary; the pinned selectors above stay for `a1 pi`. */
59
61
  export declare function createPiShellModelsDialog(options: PiShellModelsDialogOptions): PiShellModelsDialogPort;
60
62
  export declare function createPiShellTrustSelector(options: {
63
+ readonly standardStyle?: boolean;
61
64
  readonly cwd: string;
62
65
  readonly savedDecision: TrustDecision | null;
63
66
  readonly projectTrusted: boolean;
@@ -91,7 +94,7 @@ export declare function createPiShellTreeSelector(options: {
91
94
  readonly initialSelectedId?: string;
92
95
  readonly initialFilterMode?: "default" | "no-tools" | "user-only" | "labeled-only" | "all";
93
96
  }): Promise<PiShellComponentPort>;
94
- export declare function createPiShellUserMessageSelector(messages: readonly PiShellSelectorOption[], onSelect: (id: string) => void, onCancel: () => void, initialSelectedId?: string): PiShellComponentPort;
97
+ export declare function createPiShellUserMessageSelector(messages: readonly PiShellSelectorOption[], onSelect: (id: string) => void, onCancel: () => void, initialSelectedId?: string, standard?: boolean): PiShellComponentPort;
95
98
  export interface PiShellLoginDialogPort extends PiShellComponentPort {
96
99
  showAuth(url: string, instructions?: string): void;
97
100
  showDeviceCode(info: {
@@ -108,7 +111,7 @@ export interface PiShellLoginDialogPort extends PiShellComponentPort {
108
111
  showWaiting(message: string): void;
109
112
  showProgress(message: string): void;
110
113
  }
111
- export declare function createPiShellLoginDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, providerId: string, onComplete: (success: boolean, message?: string) => void, providerName?: string, title?: string): PiShellLoginDialogPort;
114
+ export declare function createPiShellLoginDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, providerId: string, onComplete: (success: boolean, message?: string) => void, providerName?: string, title?: string, standard?: boolean): PiShellLoginDialogPort;
112
115
  export declare function createPiShellArmin(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellComponentPort;
113
116
  export declare function createPiShellEarendilAnnouncement(): PiShellComponentPort;
114
117
  export declare function createPiShellReloadBox(): PiShellComponentPort;
@@ -120,11 +123,11 @@ export interface PiShellAuthProviderOption extends PiShellSelectorOption {
120
123
  readonly source?: string;
121
124
  };
122
125
  }
123
- export declare function createPiShellAuthProviderSelector(mode: "login" | "logout", providers: readonly PiShellAuthProviderOption[], onSelect: (id: string) => void, onCancel: () => void, initialSearchInput?: string): PiShellComponentPort;
124
- export declare function createPiShellExtensionSelector(title: string, options: readonly string[], onSelect: (value: string) => void, onCancel: () => void): PiShellComponentPort;
126
+ export declare function createPiShellAuthProviderSelector(mode: "login" | "logout", providers: readonly PiShellAuthProviderOption[], onSelect: (id: string) => void, onCancel: () => void, initialSearchInput?: string, standardStyle?: boolean): PiShellComponentPort;
127
+ export declare function createPiShellExtensionSelector(title: string, options: readonly string[], onSelect: (value: string) => void, onCancel: () => void, standardSelection?: boolean): PiShellComponentPort;
125
128
  export declare function createPiShellThemeSelector(currentTheme: string, onSelect: (theme: string) => void, onCancel: () => void, onPreview: (theme: string) => void): PiShellComponentPort;
126
129
  export declare function createPiShellShowImagesSelector(currentValue: boolean, onSelect: (show: boolean) => void, onCancel: () => void): PiShellComponentPort;
127
130
  export declare function createPiShellDialog(dialog: OwnedUiDialog, handlers?: {
128
131
  readonly onSelect?: (id: string) => void;
129
132
  readonly onCancel?: () => void;
130
- }): PiShellComponentPort;
133
+ }, standard?: boolean): PiShellComponentPort;