@timurproko/a1 0.2.7-dev.1233 → 0.2.7-dev.1235

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 (98) hide show
  1. package/dist/app/session-shell/dock-chrome.js +8 -4
  2. package/dist/app/session-shell/transcript-document.js +1 -0
  3. package/dist/composition/release-update-observation.js +15 -7
  4. package/dist/contracts/owned-ui/session-workflows.d.ts +1 -1
  5. package/dist/foundation/release/automatic-update.d.ts +3 -1
  6. package/dist/foundation/release/automatic-update.js +29 -4
  7. package/dist/foundation/release/index.d.ts +2 -2
  8. package/dist/foundation/release/index.js +2 -2
  9. package/dist/foundation/release/prepared-update-activation.d.ts +3 -0
  10. package/dist/foundation/release/prepared-update-activation.js +27 -0
  11. package/dist/foundation/release/progress-palette.generated.d.ts +1 -1
  12. package/dist/foundation/release/progress-palette.generated.js +1 -1
  13. package/dist/foundation/release/update-activation.d.ts +7 -0
  14. package/dist/foundation/release/update-activation.js +29 -10
  15. package/dist/foundation/release/update-transaction.d.ts +1 -0
  16. package/dist/foundation/release/update-transaction.js +5 -0
  17. package/dist/foundation/release/update.d.ts +3 -0
  18. package/dist/foundation/release/update.js +30 -12
  19. package/dist/foundation/startup/startup-descriptor.js +2 -2
  20. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
  21. package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
  22. package/dist/integrations/pi/components/shell-footer-status.js +9 -4
  23. package/dist/integrations/pi/components/shell-shared-facade.d.ts +3 -0
  24. package/dist/integrations/pi/components/shell-shared-facade.js +8 -0
  25. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  26. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
  27. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  28. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  29. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  30. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +3 -3
  31. package/dist/integrations/pi/components/upstream/components/extension-editor.js +4 -1
  32. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  33. package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
  34. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  35. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
  36. package/dist/integrations/pi/components/upstream/components/owned-editor.js +8 -1
  37. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  38. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +2 -1
  39. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +14 -3
  40. package/dist/integrations/pi/components/upstream/components/session-footer.js +1 -1
  41. package/dist/integrations/pi/components/upstream/components/session-selector-search.d.ts +4 -0
  42. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +87 -23
  43. package/dist/integrations/pi/components/upstream/components/session-selector.d.ts +3 -2
  44. package/dist/integrations/pi/components/upstream/components/session-selector.js +18 -13
  45. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  46. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  47. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
  48. package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
  49. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  50. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  51. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
  52. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +1 -1
  53. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +6 -0
  54. package/dist/integrations/pi/components/upstream/components/tool-execution.js +14 -2
  55. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +2 -1
  56. package/dist/integrations/pi/components/upstream/components/tree-selector.js +5 -4
  57. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  58. package/dist/integrations/pi/components/upstream/external-editor.d.ts +1 -0
  59. package/dist/integrations/pi/components/upstream/external-editor.js +13 -6
  60. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +3 -1
  61. package/dist/integrations/pi/components/upstream/history/editor-core.js +9 -2
  62. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  63. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  64. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  65. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  66. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  67. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  68. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  69. package/dist/integrations/pi/components/upstream/model-search.d.ts +11 -1
  70. package/dist/integrations/pi/components/upstream/model-search.js +21 -0
  71. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  72. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  73. package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
  74. package/dist/integrations/pi/engine/adapter.js +9 -1
  75. package/dist/integrations/pi/engine/diagnostics-state.d.ts +1 -0
  76. package/dist/integrations/pi/engine/diagnostics-state.js +15 -2
  77. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  78. package/dist/integrations/pi/startup-public.js +324 -309
  79. package/dist/integrations/pi/startup-public.manifest.json +1156 -846
  80. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
  81. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
  82. package/dist/native/darwin-arm64/manifest.json +1 -1
  83. package/dist/native/darwin-arm64/terminal-host.manifest.json +3 -3
  84. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  85. package/dist/native/darwin-x64/manifest.json +1 -1
  86. package/dist/native/darwin-x64/terminal-host.manifest.json +3 -3
  87. package/dist/native/darwin-x64/terminal-host.node +0 -0
  88. package/dist/native/linux-x64/manifest.json +1 -1
  89. package/dist/native/linux-x64/terminal-host.manifest.json +3 -3
  90. package/dist/native/linux-x64/terminal-host.node +0 -0
  91. package/dist/native/win32-x64/manifest.json +2 -2
  92. package/dist/native/win32-x64/process-guardian.node +0 -0
  93. package/dist/native/win32-x64/terminal-host.manifest.json +3 -3
  94. package/dist/native/win32-x64/terminal-host.node +0 -0
  95. package/dist/runtime-payload-inventory.json +8178 -5237
  96. package/dist/ui/settings/progress-palette.generated.d.ts +1 -1
  97. package/dist/ui/settings/progress-palette.generated.js +1 -1
  98. package/package.json +5 -5
@@ -5,6 +5,7 @@ import { ensurePiTheme, piTheme, } from "./theme.js";
5
5
  export const piShellVisibleWidth = visibleWidth;
6
6
  export const piShellTruncateToWidth = (text, width) => truncateToWidth(text, width, "");
7
7
  export const INSTALLED_UPDATE_STATUS_TEXT = "Update installed, restart to update";
8
+ export const BLOCKED_UPDATE_STATUS_TEXT = "Update prepared; activation blocked";
8
9
  /** Shared green restart notice for the pinned status and bare-A1 prompt overlay. */
9
10
  export function renderPiShellInstalledUpdateStatus(width) {
10
11
  if (width <= 0)
@@ -12,6 +13,13 @@ export function renderPiShellInstalledUpdateStatus(width) {
12
13
  ensurePiTheme();
13
14
  return piShellTruncateToWidth(piTheme().fg("success", INSTALLED_UPDATE_STATUS_TEXT), width);
14
15
  }
16
+ /** Sanitized warning for a certified candidate that cannot yet preserve resident continuity. */
17
+ export function renderPiShellBlockedUpdateStatus(width) {
18
+ if (width <= 0)
19
+ return "";
20
+ ensurePiTheme();
21
+ return piShellTruncateToWidth(piTheme().fg("warning", BLOCKED_UPDATE_STATUS_TEXT), width);
22
+ }
15
23
  /** A clickable URL in pinned Pi's grammar: an OSC 8 link where the terminal supports one, the plain URL otherwise. */
16
24
  export const piShellHyperlink = (url, text = url) => hyperlink(url, text);
17
25
  // Provenance: pinned from packages/coding-agent/src/core/slash-commands.ts at 914cf14.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/core/keybindings.ts.
4
4
  * Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
5
5
  * resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/core/keybindings.ts.
4
4
  * Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
5
5
  * resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "sourcePackage": "@earendil-works/pi-coding-agent",
3
- "sourceVersion": "1.4.0",
3
+ "sourceVersion": "1.5.0",
4
4
  "upstreamRepository": "https://github.com/earendil-works/pi.git",
5
- "upstreamCommit": "4a080252f06caf63a525d7873c5d94d3c23887e0",
5
+ "upstreamCommit": "f9a26365568127461c47a07a37dcb42c140a3ac5",
6
6
  "sourcePath": "dist/modes/interactive/assets/clankolas.png",
7
7
  "sourceSha256": "169acd0dfe6fbb8d8742ed24a3fc654fd0b2e2d4223c733249c5493723f1b72d",
8
8
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/countdown-timer.ts.
4
4
  * Modifications: Mechanical source port with ECMAScript private fields; imports remain on the public
5
5
  * Pi TUI package root.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/earendil-announcement.ts.
4
4
  * Modifications: Mechanical pinned source port with private imports remapped to public package-root
5
5
  * types/APIs and A1-owned theme boundaries. The unchanged image is loaded lazily from its attributed,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-editor.ts.
4
4
  * Modifications: Mechanical port: remap pi-tui to the root public singleton, use owned
5
5
  * keybindings/theme and external-editor seams, preserve editor layout, hints, focus, submission,
@@ -7,9 +7,9 @@
7
7
  * compact padded modal frame.
8
8
  * Deviations: owned-modal-shortcut-hints.
9
9
  */
10
- import { Container, type TUI } from "@earendil-works/pi-tui";
10
+ import { Container, type Focusable, type TUI } from "@earendil-works/pi-tui";
11
11
  import type { KeybindingsManager } from "../adjacent/core/keybindings.js";
12
- export declare class ExtensionEditorComponent extends Container {
12
+ export declare class ExtensionEditorComponent extends Container implements Focusable {
13
13
  #private;
14
14
  get focused(): boolean;
15
15
  set focused(value: boolean);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-editor.ts.
4
4
  * Modifications: Mechanical port: remap pi-tui to the root public singleton, use owned
5
5
  * keybindings/theme and external-editor seams, preserve editor layout, hints, focus, submission,
@@ -18,6 +18,7 @@ export class ExtensionEditorComponent extends Container {
18
18
  #keybindings;
19
19
  #externalEditorCommand;
20
20
  #onCancel;
21
+ #externalEditorStatus = new Text("", 0, 0);
21
22
  #focused = false;
22
23
  get focused() {
23
24
  return this.#focused;
@@ -50,6 +51,7 @@ export class ExtensionEditorComponent extends Container {
50
51
  this.#editor.setText(prefill);
51
52
  this.#editor.onSubmit = onSubmit;
52
53
  this.addChild(this.#editor);
54
+ this.addChild(this.#externalEditorStatus);
53
55
  this.addChild(new Spacer(1));
54
56
  const hint = renderPiModalShortcutHints([
55
57
  { key: this.#keybindings.getKeys("tui.select.confirm").join("/"), action: "submit" },
@@ -78,6 +80,7 @@ export class ExtensionEditorComponent extends Container {
78
80
  this.#tui.stop();
79
81
  try {
80
82
  const result = await editInExternalEditor({ command: this.#externalEditorCommand, content });
83
+ this.#externalEditorStatus.setText(result.status === "failed" ? piTheme().fg("warning", result.message) : "");
81
84
  if (result.status === "complete")
82
85
  this.#editor.setText(result.content);
83
86
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-input.ts.
4
4
  * Modifications: Mechanical port: remap public imports, use ECMAScript private fields, and route the
5
5
  * bare-A1 instruction row and chrome through the shared semantic shortcut and compact padded
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/extension-selector.ts.
4
4
  * Modifications: Mechanical port: remap public imports, use ECMAScript private fields, and route the
5
5
  * bare-A1 instruction row and chrome through the shared semantic shortcut and compact padded
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/mermaid.ts.
4
4
  * Modifications: Mechanical pinned source port with private imports remapped to public package-root
5
5
  * types/APIs and A1-owned theme boundaries; behavior remains acceptance-tested.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/custom-editor.ts.
4
4
  * Modifications: A1-owned class name and synchronized A1 keybinding contract replace the nominal
5
5
  * private upstream keybinding constructor dependency; bare A1 injects the shared Settings/agent input
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/custom-editor.ts.
4
4
  * Modifications: A1-owned class name and synchronized A1 keybinding contract replace the nominal
5
5
  * private upstream keybinding constructor dependency; bare A1 injects the shared Settings/agent input
@@ -108,6 +108,13 @@ export function createOwnedEditorClass(Base) {
108
108
  this.onPromptSuggestionAccepted?.(accepted);
109
109
  return;
110
110
  }
111
+ // Selection page keys move an open autocomplete menu before app actions run.
112
+ // This lets users bind Ctrl+V even though it pastes images by default.
113
+ if (this.isShowingAutocomplete()
114
+ && (this.keybindings.matches(data, "tui.select.pageUp") || this.keybindings.matches(data, "tui.select.pageDown"))) {
115
+ super.handleInput(data);
116
+ return;
117
+ }
111
118
  if (this.keybindings.matches(data, "app.clipboard.pasteImage")) {
112
119
  this.onPasteImage?.();
113
120
  return;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/pi-logo.ts.
4
4
  * Modifications: Remapped the private theme import to A1's public-backed adapter and composed the
5
5
  * fixed-color logo into the owned startup header.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/scoped-models-selector.ts.
4
4
  * Modifications: Source-synchronized scoped-model selector port: preserve session-only toggles,
5
5
  * search, bulk/provider/reorder actions, dirty state, Ctrl+S persistence, refresh status,
@@ -32,6 +32,7 @@ export interface ModelsCallbacks {
32
32
  * Changes are session-only until explicitly persisted with Ctrl+S.
33
33
  */
34
34
  export declare class ScopedModelsSelectorComponent extends Container implements Focusable {
35
+ readonly capturesViewportInput: boolean;
35
36
  private modelsById;
36
37
  private allIds;
37
38
  private enabledIds;
@@ -1,6 +1,6 @@
1
- import { Container, fuzzyFilter, getKeybindings, Input, Spacer, Text, } from "@earendil-works/pi-tui";
1
+ import { Container, fuzzyFilter, getKeybindings, getSelectPageIndex, Input, Spacer, Text, } from "@earendil-works/pi-tui";
2
2
  import { DynamicBorder } from "../../../startup-public.js";
3
- import { getModelSearchText } from "../model-search.js";
3
+ import { getDistinctModelName, getModelSearchText } from "../model-search.js";
4
4
  import { addPiModalHeader, addPiModalSearchInput, adoptPiModalFrame } from "../../modal-frame.js";
5
5
  import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "../../theme.js";
6
6
  // Rationale: upstream's capitalized hint formatter is private to the package; the same mapping lives here.
@@ -79,6 +79,7 @@ function getSortedIds(enabledIds, allIds) {
79
79
  * Changes are session-only until explicitly persisted with Ctrl+S.
80
80
  */
81
81
  export class ScopedModelsSelectorComponent extends Container {
82
+ capturesViewportInput = true;
82
83
  modelsById = new Map();
83
84
  allIds = [];
84
85
  enabledIds = null;
@@ -217,9 +218,11 @@ export class ScopedModelsSelectorComponent extends Container {
217
218
  const id = item.model?.id ?? item.fullId;
218
219
  const styledId = item.model ? id : theme.strikethrough(id);
219
220
  const modelText = isSelected ? theme.fg("accent", styledId) : styledId;
221
+ const name = item.model ? getDistinctModelName(item.model) : undefined;
222
+ const nameText = name ? theme.fg("muted", ` (${name})`) : "";
220
223
  const providerBadge = theme.fg("muted", item.model ? ` [${item.model.provider}]` : " [unavailable]");
221
224
  const status = item.model && item.enabled ? theme.fg("accent", "✓ ") : " ";
222
- this.listContainer.addChild(new Text(`${prefix}${status}${modelText}${providerBadge}`, 0, 0));
225
+ this.listContainer.addChild(new Text(`${prefix}${status}${modelText}${nameText}${providerBadge}`, 0, 0));
223
226
  }
224
227
  // Add scroll indicator if needed
225
228
  if (startIndex > 0 || endIndex < this.filteredItems.length) {
@@ -248,6 +251,14 @@ export class ScopedModelsSelectorComponent extends Container {
248
251
  this.updateList();
249
252
  return;
250
253
  }
254
+ const pageIndex = getSelectPageIndex(kb, data, this.selectedIndex, this.filteredItems.length, this.maxVisible);
255
+ if (pageIndex !== undefined) {
256
+ if (this.filteredItems.length === 0)
257
+ return;
258
+ this.selectedIndex = pageIndex;
259
+ this.updateList();
260
+ return;
261
+ }
251
262
  // Reorder enabled models
252
263
  const reorderUp = kb.matches(data, "app.models.reorderUp");
253
264
  const reorderDown = kb.matches(data, "app.models.reorderDown");
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/footer.ts.
4
4
  * Modifications: Owned UI/routing; A1 level color, linked PRs, resident names, dim ellipsis and model
5
5
  * priority; Pi unchanged.
@@ -18,5 +18,9 @@ export interface MatchResult {
18
18
  }
19
19
  export declare function hasSessionName(session: SessionInfo): boolean;
20
20
  export declare function parseSearchQuery(query: string): ParsedSearchQuery;
21
+ /**
22
+ * Each field is matched separately, so a token never matches across field boundaries.
23
+ * Different tokens may match different fields.
24
+ */
21
25
  export declare function matchSession(session: SessionInfo, parsed: ParsedSearchQuery): MatchResult;
22
26
  export declare function filterAndSortSessions(sessions: SessionInfo[], query: string, sortMode: SortMode, nameFilter?: NameFilter): SessionInfo[];
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/session-selector-search.ts.
4
4
  * Modifications: Source-synchronized session search port with only the public SessionInfo type import
5
5
  * remapped.
@@ -9,8 +9,79 @@ import { fuzzyMatch } from "@earendil-works/pi-tui";
9
9
  function normalizeWhitespaceLower(text) {
10
10
  return text.toLowerCase().replace(/\s+/g, " ").trim();
11
11
  }
12
- function getSessionSearchText(session) {
13
- return `${session.id} ${session.name ?? ""} ${session.allMessagesText} ${session.cwd}`;
12
+ /**
13
+ * Match tiers, best first. Each token is scored by the best field it matches; tiers dominate
14
+ * fuzzy scores so an exact hit anywhere beats a scattered subsequence in a short field.
15
+ */
16
+ const TIER_NAME = 0; // query text appears in the session name
17
+ const TIER_TEXT = 1; // query text appears in the session id, messages, or cwd
18
+ const TIER_FUZZY = 2; // query characters appear scattered in the session name or cwd
19
+ const TIER_WEIGHT = 1_000_000;
20
+ /**
21
+ * Lowercased message text per session. allMessagesText holds every user/assistant message and
22
+ * can be megabytes, so lowercase it once instead of on every keystroke.
23
+ */
24
+ const messageTextCache = new WeakMap();
25
+ function getMessageText(session) {
26
+ let cached = messageTextCache.get(session);
27
+ if (!cached || cached.source !== session.allMessagesText) {
28
+ cached = { source: session.allMessagesText, lower: session.allMessagesText.toLowerCase() };
29
+ messageTextCache.set(session, cached);
30
+ }
31
+ return cached;
32
+ }
33
+ function getNormalizedMessageText(session) {
34
+ const cached = getMessageText(session);
35
+ cached.normalized ??= cached.lower.replace(/\s+/g, " ").trim();
36
+ return cached.normalized;
37
+ }
38
+ function tierScore(tier, score = 0) {
39
+ return tier * TIER_WEIGHT + score;
40
+ }
41
+ /** Exact (case-insensitive) text match. Messages and ids are only matched exactly: scattered matches in them are noise. */
42
+ function matchLiteralToken(session, value) {
43
+ const name = session.name?.toLowerCase() ?? "";
44
+ if (name.includes(value))
45
+ return tierScore(TIER_NAME, fuzzyMatch(value, name).score);
46
+ if (session.id.toLowerCase().includes(value))
47
+ return tierScore(TIER_TEXT);
48
+ if (getMessageText(session).lower.includes(value))
49
+ return tierScore(TIER_TEXT);
50
+ if (session.cwd.toLowerCase().includes(value))
51
+ return tierScore(TIER_TEXT);
52
+ return undefined;
53
+ }
54
+ function matchFuzzyToken(session, value) {
55
+ const literal = matchLiteralToken(session, value.toLowerCase());
56
+ if (literal !== undefined)
57
+ return literal;
58
+ let best;
59
+ for (const field of [session.name ?? "", session.cwd]) {
60
+ const m = fuzzyMatch(value, field);
61
+ if (m.matches && (best === undefined || m.score < best))
62
+ best = m.score;
63
+ }
64
+ return best === undefined ? undefined : tierScore(TIER_FUZZY, best);
65
+ }
66
+ function matchPhraseToken(session, phrase) {
67
+ const name = normalizeWhitespaceLower(session.name ?? "");
68
+ if (name.includes(phrase))
69
+ return tierScore(TIER_NAME, fuzzyMatch(phrase, name).score);
70
+ if (session.id.toLowerCase().includes(phrase))
71
+ return tierScore(TIER_TEXT);
72
+ if (getNormalizedMessageText(session).includes(phrase))
73
+ return tierScore(TIER_TEXT);
74
+ if (normalizeWhitespaceLower(session.cwd).includes(phrase))
75
+ return tierScore(TIER_TEXT);
76
+ return undefined;
77
+ }
78
+ function matchRegex(session, regex) {
79
+ if (session.name && regex.test(session.name))
80
+ return tierScore(TIER_NAME);
81
+ if (regex.test(session.id) || regex.test(session.allMessagesText) || regex.test(session.cwd)) {
82
+ return tierScore(TIER_TEXT);
83
+ }
84
+ return undefined;
14
85
  }
15
86
  export function hasSessionName(session) {
16
87
  return Boolean(session.name?.trim());
@@ -89,40 +160,33 @@ export function parseSearchQuery(query) {
89
160
  flush(inQuote ? "phrase" : "fuzzy");
90
161
  return { mode: "tokens", tokens, regex: null };
91
162
  }
163
+ /**
164
+ * Each field is matched separately, so a token never matches across field boundaries.
165
+ * Different tokens may match different fields.
166
+ */
92
167
  export function matchSession(session, parsed) {
93
- const text = getSessionSearchText(session);
94
168
  if (parsed.mode === "regex") {
95
169
  if (!parsed.regex) {
96
170
  return { matches: false, score: 0 };
97
171
  }
98
- const idx = text.search(parsed.regex);
99
- if (idx < 0)
100
- return { matches: false, score: 0 };
101
- return { matches: true, score: idx * 0.1 };
102
- }
103
- if (parsed.tokens.length === 0) {
104
- return { matches: true, score: 0 };
172
+ const score = matchRegex(session, parsed.regex);
173
+ return score === undefined ? { matches: false, score: 0 } : { matches: true, score };
105
174
  }
106
175
  let totalScore = 0;
107
- let normalizedText = null;
108
176
  for (const token of parsed.tokens) {
177
+ let score;
109
178
  if (token.kind === "phrase") {
110
- if (normalizedText === null) {
111
- normalizedText = normalizeWhitespaceLower(text);
112
- }
113
179
  const phrase = normalizeWhitespaceLower(token.value);
114
180
  if (!phrase)
115
181
  continue;
116
- const idx = normalizedText.indexOf(phrase);
117
- if (idx < 0)
118
- return { matches: false, score: 0 };
119
- totalScore += idx * 0.1;
120
- continue;
182
+ score = matchPhraseToken(session, phrase);
183
+ }
184
+ else {
185
+ score = matchFuzzyToken(session, token.value);
121
186
  }
122
- const m = fuzzyMatch(token.value, text);
123
- if (!m.matches)
187
+ if (score === undefined)
124
188
  return { matches: false, score: 0 };
125
- totalScore += m.score;
189
+ totalScore += score;
126
190
  }
127
191
  return { matches: true, score: totalScore };
128
192
  }
@@ -1,10 +1,10 @@
1
1
  import { type Component, Container, type Focusable } from "@earendil-works/pi-tui";
2
2
  import { KeybindingsManager } from "../adjacent/core/keybindings.js";
3
3
  import { type SessionInfo } from "@earendil-works/pi-coding-agent";
4
+ import { type NameFilter, type SortMode } from "./session-selector-search.js";
4
5
  type SessionListProgress = (loaded: number, total: number,
5
6
  /** Sessions loaded so far, sorted by activity. Present on periodic updates. */
6
7
  partialSessions?: readonly SessionInfo[]) => void;
7
- import { type NameFilter, type SortMode } from "./session-selector-search.js";
8
8
  /**
9
9
  * Custom session list component with multi-line items and search
10
10
  */
@@ -21,7 +21,7 @@ declare class SessionList implements Component, Focusable {
21
21
  private keybindings;
22
22
  private showPath;
23
23
  private confirmingDeletePath;
24
- private currentSessionCanonicalPath;
24
+ private currentSessionPathKey;
25
25
  onSelect?: (sessionPath: string) => void;
26
26
  onCancel?: () => void;
27
27
  onExit: () => void;
@@ -56,6 +56,7 @@ type SessionsLoader = (onProgress?: SessionListProgress, signal?: AbortSignal) =
56
56
  * Component that renders a session selector
57
57
  */
58
58
  export declare class SessionSelectorComponent extends Container implements Focusable {
59
+ get capturesViewportInput(): boolean;
59
60
  handleInput(data: string): void;
60
61
  private canRename;
61
62
  private sessionList;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/session-selector.ts.
4
4
  * Modifications: Source-synchronized session selector port: preserve threaded/current/all scope,
5
5
  * search, sort, named/path filters, rename, delete confirmation, active-session protection,
@@ -23,6 +23,7 @@ import { KeybindingsManager } from "../adjacent/core/keybindings.js";
23
23
  import { DynamicBorder } from "../../../startup-public.js";
24
24
  import { addPiModalHeader, adoptPiModalFrame, renderPiModalSearchInput } from "../../modal-frame.js";
25
25
  import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "../../theme.js";
26
+ import { filterAndSortSessions, hasSessionName } from "./session-selector-search.js";
26
27
  const theme = new Proxy({}, {
27
28
  get(_target, property) {
28
29
  const active = piTheme();
@@ -46,15 +47,11 @@ function withCloseHint(content, width) {
46
47
  const body = truncateToWidth(content, bodyWidth, "…");
47
48
  return body.length === 0 ? close : `${body} ${close}`;
48
49
  }
49
- import { filterAndSortSessions, hasSessionName } from "./session-selector-search.js";
50
50
  function shortenPath(path) {
51
51
  const home = os.homedir();
52
52
  if (!path)
53
53
  return path;
54
- if (path.startsWith(home)) {
55
- return `~${path.slice(home.length)}`;
56
- }
57
- return path;
54
+ return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
58
55
  }
59
56
  function formatSessionDate(date) {
60
57
  const now = new Date();
@@ -107,6 +104,11 @@ function canonicalizePath(path) {
107
104
  return path;
108
105
  }
109
106
  }
107
+ /** Comparison key for a session file path; follows symlinks and ignores case on Windows. */
108
+ function getSessionPathKey(path) {
109
+ const canonical = canonicalizePath(path) ?? path;
110
+ return process.platform === "win32" ? canonical.toLocaleLowerCase("en-US") : canonical;
111
+ }
110
112
  class SessionSelectorHeader {
111
113
  scope;
112
114
  sortMode;
@@ -219,14 +221,14 @@ class SessionSelectorFooter {
219
221
  function buildSessionTree(sessions) {
220
222
  const byPath = new Map();
221
223
  for (const session of sessions) {
222
- const sessionPath = canonicalizePath(session.path) ?? session.path;
224
+ const sessionPath = getSessionPathKey(session.path);
223
225
  byPath.set(sessionPath, { session, children: [], latestActivity: session.modified.getTime() });
224
226
  }
225
227
  const roots = [];
226
228
  for (const session of sessions) {
227
- const sessionPath = canonicalizePath(session.path) ?? session.path;
229
+ const sessionPath = getSessionPathKey(session.path);
228
230
  const node = byPath.get(sessionPath);
229
- const parentPath = canonicalizePath(session.parentSessionPath);
231
+ const parentPath = session.parentSessionPath ? getSessionPathKey(session.parentSessionPath) : undefined;
230
232
  if (parentPath && byPath.has(parentPath)) {
231
233
  byPath.get(parentPath).children.push(node);
232
234
  }
@@ -293,7 +295,7 @@ class SessionList {
293
295
  keybindings;
294
296
  showPath = false;
295
297
  confirmingDeletePath = null;
296
- currentSessionCanonicalPath;
298
+ currentSessionPathKey;
297
299
  onSelect;
298
300
  onCancel;
299
301
  onExit = () => { };
@@ -326,7 +328,7 @@ class SessionList {
326
328
  this.sortMode = sortMode;
327
329
  this.nameFilter = nameFilter;
328
330
  this.keybindings = keybindings;
329
- this.currentSessionCanonicalPath = canonicalizePath(currentSessionFilePath);
331
+ this.currentSessionPathKey = currentSessionFilePath ? getSessionPathKey(currentSessionFilePath) : undefined;
330
332
  this.filterSessions("");
331
333
  // Handle Enter in search input - select current item
332
334
  this.searchInput.onSubmit = () => {
@@ -396,9 +398,9 @@ class SessionList {
396
398
  this.setConfirmingDeletePath(selected.session.path);
397
399
  }
398
400
  isCurrentSessionPath(path) {
399
- if (!this.currentSessionCanonicalPath)
401
+ if (!this.currentSessionPathKey)
400
402
  return false;
401
- return (canonicalizePath(path) ?? path) === this.currentSessionCanonicalPath;
403
+ return getSessionPathKey(path) === this.currentSessionPathKey;
402
404
  }
403
405
  sessionPathText(session) {
404
406
  if (this.showPath)
@@ -644,6 +646,9 @@ async function deleteSessionFile(sessionPath) {
644
646
  * Component that renders a session selector
645
647
  */
646
648
  export class SessionSelectorComponent extends Container {
649
+ get capturesViewportInput() {
650
+ return this.mode !== "rename";
651
+ }
647
652
  handleInput(data) {
648
653
  if (this.mode === "rename") {
649
654
  const kb = getKeybindings();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/skill-invocation-message.ts.
4
4
  * Modifications: Mechanical port uses A1's public pi-tui instance, owned theme boundary, and
5
5
  * root-instance keybinding registry because the public coding-agent component closes over a second
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/skill-invocation-message.ts.
4
4
  * Modifications: Mechanical port uses A1's public pi-tui instance, owned theme boundary, and
5
5
  * root-instance keybinding registry because the public coding-agent component closes over a second
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/status-indicator.ts.
4
4
  * Modifications: Mechanical source port with public package-root keybinding, Loader, and owned
5
5
  * theme/countdown imports plus ECMAScript private fields.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/status-indicator.ts.
4
4
  * Modifications: Mechanical source port with public package-root keybinding, Loader, and owned
5
5
  * theme/countdown imports plus ECMAScript private fields.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/themed-text.ts.
4
4
  * Modifications: Integrated invalidation-aware text into A1's owned startup header and notices;
5
5
  * repository formatting only.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/themed-text.ts.
4
4
  * Modifications: Integrated invalidation-aware text into A1's owned startup header and notices;
5
5
  * repository formatting only.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/thinking-selector.ts.
4
4
  * Modifications: Preserve the searchable thinking-level selector, current/default semantics,
5
5
  * selection, and focus while accepting the active bare-A1 cycle-key label from the shell, styling the
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
2
+ * Provenance: @earendil-works/pi-coding-agent 1.5.0 (MIT), commit f9a26365568127461c47a07a37dcb42c140a3ac5,
3
3
  * packages/coding-agent/src/modes/interactive/components/thinking-selector.ts.
4
4
  * Modifications: Preserve the searchable thinking-level selector, current/default semantics,
5
5
  * selection, and focus while accepting the active bare-A1 cycle-key label from the shell, styling the
@@ -38,6 +38,8 @@ export declare class ToolExecutionComponent extends Container {
38
38
  private cwd;
39
39
  private executionStarted;
40
40
  private argsComplete;
41
+ /** `updateArgs()` ran since the last display update; the next render applies it. */
42
+ private argsPending;
41
43
  private result;
42
44
  private hideComponent;
43
45
  constructor(toolName: string, toolCallId: string, args: any, options: ToolExecutionOptions | undefined, toolDefinition: ToolRenderers | ToolDefinition<any, any, any> | undefined, ui: TUI, cwd: string);
@@ -46,6 +48,10 @@ export declare class ToolExecutionComponent extends Container {
46
48
  private createCallFallback;
47
49
  private createResultFallback;
48
50
  private createResultRegion;
51
+ /**
52
+ * Show new partial arguments. Applied at the next render, so a call streaming many argument deltas between two
53
+ * frames runs its renderer once per frame, not once per delta (#9265).
54
+ */
49
55
  updateArgs(args: any): void;
50
56
  markExecutionStarted(): void;
51
57
  setArgsComplete(): void;