@timurproko/a1 0.1.8-dev.527 → 0.1.8-dev.536

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 (100) hide show
  1. package/dist/app/session-shell/session-shell-root.d.ts +1 -0
  2. package/dist/app/session-shell/session-shell-root.js +3 -1
  3. package/dist/app/session-shell/session-shell.d.ts +1 -1
  4. package/dist/app/session-shell/session-shell.js +10 -4
  5. package/dist/composition/owned-ui.js +4 -3
  6. package/dist/composition/settings-route-host.d.ts +5 -9
  7. package/dist/composition/settings-route-host.js +2 -2
  8. package/dist/contracts/owned-ui/model.d.ts +4 -0
  9. package/dist/contracts/owned-ui/validation.js +25 -0
  10. package/dist/features/owned-ui/index.d.ts +1 -1
  11. package/dist/features/owned-ui/reference-screen-app.d.ts +9 -3
  12. package/dist/features/owned-ui/reference-screen-app.js +68 -20
  13. package/dist/features/owned-ui/settings-app.js +69 -24
  14. package/dist/foundation/startup/startup-descriptor.js +2 -2
  15. package/dist/integrations/pi/components/index.d.ts +3 -1
  16. package/dist/integrations/pi/components/index.js +2 -1
  17. package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +9 -1
  18. package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -9
  19. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  20. package/dist/integrations/pi/components/shell-footer-status.js +2 -2
  21. package/dist/integrations/pi/components/shell-hotkey-sections.d.ts +7 -0
  22. package/dist/integrations/pi/components/shell-hotkey-sections.js +29 -0
  23. package/dist/integrations/pi/components/shell-presenters-info.d.ts +1 -0
  24. package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
  25. package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +0 -1
  26. package/dist/integrations/pi/components/shell-selectors-dialogs.js +1 -7
  27. package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +8 -0
  28. package/dist/integrations/pi/components/thinking-selector-dialog.js +22 -0
  29. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  30. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
  31. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  32. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  33. package/dist/integrations/pi/components/upstream/components/daxnuts.d.ts +1 -1
  34. package/dist/integrations/pi/components/upstream/components/daxnuts.js +1 -1
  35. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  36. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  37. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  38. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  39. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
  40. package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
  41. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
  42. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
  43. package/dist/integrations/pi/components/upstream/components/session-footer.js +22 -11
  44. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  45. package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
  46. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  47. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  48. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
  49. package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
  50. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +33 -0
  51. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +140 -0
  52. package/dist/integrations/pi/components/upstream/components/tool-execution.js +1 -1
  53. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
  54. package/dist/integrations/pi/components/upstream/components/tree-selector.js +8 -1
  55. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  56. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  57. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +1 -1
  58. package/dist/integrations/pi/components/upstream/history/editor-core.js +1 -1
  59. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  60. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  61. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  62. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  63. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  64. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  65. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  66. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  67. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  68. package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
  69. package/dist/integrations/pi/engine/adapter.js +1 -0
  70. package/dist/integrations/pi/engine/repository-pr.d.ts +8 -0
  71. package/dist/integrations/pi/engine/repository-pr.js +62 -0
  72. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  73. package/dist/integrations/pi/engine/session-runtime.d.ts +5 -0
  74. package/dist/integrations/pi/engine/session-runtime.js +60 -1
  75. package/dist/integrations/pi/engine/workflows.d.ts +1 -1
  76. package/dist/integrations/pi/engine/workflows.js +4 -2
  77. package/dist/integrations/pi/startup-public.js +43 -37
  78. package/dist/integrations/pi/startup-public.manifest.json +143 -142
  79. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
  80. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
  81. package/dist/native/darwin-arm64/manifest.json +1 -1
  82. package/dist/native/linux-x64/manifest.json +1 -1
  83. package/dist/native/win32-x64/manifest.json +2 -2
  84. package/dist/native/win32-x64/process-guardian.exe +0 -0
  85. package/dist/product-identity.d.ts +1 -1
  86. package/dist/product-identity.js +1 -1
  87. package/dist/product-identity.json +1 -0
  88. package/dist/runtime-payload-inventory.json +2782 -2662
  89. package/dist/ui/components/index.d.ts +1 -1
  90. package/dist/ui/components/list-block.d.ts +10 -6
  91. package/dist/ui/components/list-block.js +28 -15
  92. package/dist/ui/components/list-view.d.ts +1 -1
  93. package/dist/ui/components/list-view.js +4 -2
  94. package/dist/ui/components/mouse.js +4 -2
  95. package/dist/ui/components/theme.d.ts +1 -5
  96. package/dist/ui/components/theme.js +0 -4
  97. package/dist/ui/components/value-menu.d.ts +3 -1
  98. package/dist/ui/components/value-menu.js +13 -5
  99. package/docs/local-worktree-cleanup.md +1 -1
  100. package/package.json +3 -3
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
+ * packages/coding-agent/src/modes/interactive/components/thinking-selector.ts.
4
+ * Modifications: Preserve the searchable thinking-level selector, current/default semantics,
5
+ * selection, save, cancellation, and focus while accepting the active bare-A1 cycle-key label from the
6
+ * shell, styling the title with the established bold semantic accent treatment, placing its muted hint
7
+ * directly below it, deduplicating levels, and rendering aligned muted descriptions after an adjacent
8
+ * success-colored active marker. All list and border colors use the owned theme and its explicit color
9
+ * mode. The comparison profile retains the public pinned component.
10
+ * Deviations: owned-level-cycle-shortcut, owned-thinking-selector-heading.
11
+ */
12
+ import { Container, fuzzyFilter, getKeybindings, Input, SelectList, Spacer, Text, } from "@earendil-works/pi-tui";
13
+ import { DynamicBorder } from "../../../startup-public.js";
14
+ import { piTheme } from "../theme/theme.js";
15
+ const THINKING_SELECT_LIST_LAYOUT = {
16
+ minPrimaryColumnWidth: 12,
17
+ maxPrimaryColumnWidth: 32,
18
+ };
19
+ const LEVEL_DESCRIPTIONS = {
20
+ off: "No reasoning",
21
+ minimal: "Very brief reasoning (~1k tokens)",
22
+ low: "Light reasoning (~2k tokens)",
23
+ medium: "Moderate reasoning (~8k tokens)",
24
+ high: "Deep reasoning (~16k tokens)",
25
+ xhigh: "Extra-high reasoning (~32k tokens)",
26
+ max: "Maximum reasoning",
27
+ };
28
+ /** Bare-A1 thinking-level selector with profile-resolved shortcut presentation. */
29
+ export class OwnedThinkingSelectorComponent extends Container {
30
+ searchInput;
31
+ selectList;
32
+ selectListChildIndex;
33
+ allItems;
34
+ onSelect;
35
+ onCancel;
36
+ onSelectAsDefault;
37
+ currentLevel;
38
+ _focused = false;
39
+ get focused() {
40
+ return this._focused;
41
+ }
42
+ set focused(value) {
43
+ this._focused = value;
44
+ this.searchInput.focused = value;
45
+ }
46
+ constructor(currentLevel, availableLevels, onSelect, onCancel, cycleKeyDisplay, onSelectAsDefault, defaultThinkingLevel) {
47
+ super();
48
+ this.onSelect = onSelect;
49
+ this.onCancel = onCancel;
50
+ this.onSelectAsDefault = onSelectAsDefault;
51
+ this.currentLevel = currentLevel;
52
+ this.allItems = [...new Set(availableLevels)].map((level) => ({
53
+ value: level,
54
+ label: level,
55
+ description: level === defaultThinkingLevel ? `${LEVEL_DESCRIPTIONS[level]} · default` : LEVEL_DESCRIPTIONS[level],
56
+ }));
57
+ this.addChild(new DynamicBorder((text) => piTheme().fg("border", text)));
58
+ this.addChild(new Spacer(1));
59
+ this.addChild(new Text(piTheme().fg("accent", piTheme().bold("Thinking Level")), 0, 0));
60
+ this.addChild(new Text(piTheme().fg("muted", `${cycleKeyDisplay} cycles thinking levels in-session`), 0, 0));
61
+ this.addChild(new Spacer(1));
62
+ this.searchInput = new Input();
63
+ this.searchInput.onSubmit = () => this.selectList.handleInput("\r");
64
+ this.addChild(this.searchInput);
65
+ this.addChild(new Spacer(1));
66
+ this.selectList = this.buildSelectList(this.allItems, currentLevel);
67
+ this.selectListChildIndex = this.children.length;
68
+ this.addChild(this.selectList);
69
+ this.addChild(new Spacer(1));
70
+ this.addChild(new Text(piTheme().fg("dim", ` ${this.keyDisplayText("tui.select.confirm")} to select · ${this.keyDisplayText("app.thinking.save")} to set as default · ${this.keyDisplayText("tui.select.cancel")} to cancel`), 0, 0));
71
+ this.addChild(new DynamicBorder((text) => piTheme().fg("border", text)));
72
+ }
73
+ keyDisplayText(keybinding) {
74
+ return getKeybindings().getKeys(keybinding)
75
+ .map((key) => key.split("+").map((part) => {
76
+ const display = process.platform === "darwin" && part.toLowerCase() === "alt" ? "option" : part;
77
+ return display.charAt(0).toUpperCase() + display.slice(1);
78
+ }).join("+"))
79
+ .join("/");
80
+ }
81
+ buildSelectList(items, preselect) {
82
+ const primaryWidth = this.allItems.reduce((widest, item) => {
83
+ const level = item.label ?? item.value;
84
+ return Math.max(widest, level.length + (item.value === this.currentLevel ? 2 : 0));
85
+ }, 0);
86
+ const themedItems = items.map((item) => {
87
+ const level = item.label ?? item.value;
88
+ const current = item.value === this.currentLevel;
89
+ const currentMarker = current ? ` ${piTheme().fg("success", "✓")}` : "";
90
+ const separator = " ".repeat(Math.max(1, primaryWidth - level.length - (current ? 2 : 0) + 1));
91
+ const description = item.description ? piTheme().fg("muted", item.description) : "";
92
+ return { value: item.value, label: `${level}${currentMarker}${separator}${description}` };
93
+ });
94
+ // Invariant: the bare selector uses the owned theme's explicit color mode, not upstream's host detection.
95
+ const list = new SelectList(themedItems, Math.max(1, themedItems.length), {
96
+ selectedPrefix: text => piTheme().fg("accent", text),
97
+ selectedText: text => piTheme().fg("accent", text),
98
+ description: text => piTheme().fg("muted", text),
99
+ scrollInfo: text => piTheme().fg("muted", text),
100
+ noMatch: text => piTheme().fg("muted", text),
101
+ }, THINKING_SELECT_LIST_LAYOUT);
102
+ const currentIndex = themedItems.findIndex((item) => item.value === preselect);
103
+ if (currentIndex !== -1)
104
+ list.setSelectedIndex(currentIndex);
105
+ list.onSelect = (item) => this.onSelect(item.value);
106
+ list.onCancel = () => this.onCancel();
107
+ return list;
108
+ }
109
+ applyFilter(query) {
110
+ const filtered = query
111
+ ? fuzzyFilter(this.allItems, query, (item) => `${item.value} ${item.description ?? ""}`)
112
+ : this.allItems;
113
+ const selectedValue = this.selectList.getSelectedItem()?.value;
114
+ const newList = this.buildSelectList(filtered, selectedValue);
115
+ this.children[this.selectListChildIndex] = newList;
116
+ this.selectList = newList;
117
+ }
118
+ handleInput(keyData) {
119
+ const kb = getKeybindings();
120
+ if (kb.matches(keyData, "app.thinking.save") && this.onSelectAsDefault) {
121
+ const item = this.selectList.getSelectedItem();
122
+ if (item)
123
+ this.onSelectAsDefault(item.value);
124
+ return;
125
+ }
126
+ const isNav = kb.matches(keyData, "tui.select.up") ||
127
+ kb.matches(keyData, "tui.select.down") ||
128
+ kb.matches(keyData, "tui.select.confirm") ||
129
+ kb.matches(keyData, "tui.select.cancel");
130
+ if (isNav) {
131
+ this.selectList.handleInput(keyData);
132
+ return;
133
+ }
134
+ this.searchInput.handleInput(keyData);
135
+ this.applyFilter(this.searchInput.getValue());
136
+ }
137
+ getSelectList() {
138
+ return this.selectList;
139
+ }
140
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/components/tool-execution.ts.
4
4
  * Modifications: Retain pinned shell and actual public tool-definition renderers. Replace private
5
5
  * index-keyed image conversion with current-source ownership, serial conversion, visible fallback, and
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/components/tree-selector.ts.
4
4
  * Modifications: Source-synchronized tree selector port: preserve filtering, folding, labels, copying,
5
5
  * tree navigation, key hints, focus, and viewport behavior while remapping public types/components
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/components/tree-selector.ts.
4
4
  * Modifications: Source-synchronized tree selector port: preserve filtering, folding, labels, copying,
5
5
  * tree navigation, key hints, focus, and viewport behavior while remapping public types/components
@@ -282,6 +282,7 @@ class TreeList {
282
282
  let passesFilter = true;
283
283
  // Entry types hidden in default view (settings/bookkeeping)
284
284
  const isSettingsEntry = entry.type === "label" ||
285
+ entry.type === "context_edit" ||
285
286
  entry.type === "custom" ||
286
287
  entry.type === "model_change" ||
287
288
  entry.type === "thinking_level_change" ||
@@ -507,6 +508,9 @@ class TreeList {
507
508
  case "custom":
508
509
  parts.push("custom", entry.customType);
509
510
  break;
511
+ case "context_edit":
512
+ parts.push("context edit", entry.replacement === null ? "omit" : "replace", entry.targetId);
513
+ break;
510
514
  case "label":
511
515
  parts.push("label", entry.label ?? "");
512
516
  break;
@@ -718,6 +722,9 @@ class TreeList {
718
722
  case "custom":
719
723
  result = theme.fg("dim", `[custom: ${entry.customType}]`);
720
724
  break;
725
+ case "context_edit":
726
+ result = theme.fg("dim", `[context ${entry.replacement === null ? "omit" : "replace"}: ${entry.targetId}]`);
727
+ break;
721
728
  case "label":
722
729
  result = theme.fg("dim", `[label: ${entry.label ?? "(cleared)"}]`);
723
730
  break;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/components/trust-selector.ts.
4
4
  * Modifications: Mechanical source-synchronized trust selector port with injected public
5
5
  * ProjectTrustStore-derived options and remapped owned theme imports.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/external-editor.ts.
4
4
  * Modifications: Mechanical port: retain temporary prompt file, asynchronous inherited-stdio editor
5
5
  * process, completion readback, and best-effort cleanup behind the owned extension-editor component.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/components/editor.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state with the user-approved numeric-only
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/components/editor.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state with the user-approved numeric-only
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/kill-ring.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/kill-ring.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/keys.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/utils.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/undo-stack.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/undo-stack.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-tui 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-tui 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/tui/src/word-navigation.ts.
4
4
  * Modifications: Owned editor core or minimal editor-local helper subset; public imports, strict
5
5
  * types, typed persistent-history hooks, and semantic border state. Public terminal runtime/exports
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/model-search.ts.
4
4
  * Modifications: Mechanical source-synchronized port preserving pinned model search terms for stateful
5
5
  * scoped-model filtering.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/theme/theme-controller.ts.
4
4
  * Modifications: Source-synchronized controller port: renamed owner class, injected dependency-free
5
5
  * settings/runtime ports, remapped private theme helpers to the public-backed A1 theme adapter, and
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance: @earendil-works/pi-coding-agent 0.86.1 (MIT), commit 13cbf77df2396303013a41646bcfa77b4271ae56,
2
+ * Provenance: @earendil-works/pi-coding-agent 0.87.0 (MIT), commit 16787ad5b2dc748047f314ca1bfe7708f30f54f3,
3
3
  * packages/coding-agent/src/modes/interactive/theme/theme.ts.
4
4
  * Modifications: Source-synchronized theme port: retain pinned theme schema, variable/color
5
5
  * resolution, built-in and custom loading, terminal detection, and layout defaults while constructing
@@ -428,6 +428,7 @@ export class PiEngineAdapter {
428
428
  usage: this.#usageCache ??= readUsageView(this.#engine.session, this.#engine.runtime, this.#activeModel),
429
429
  footer: {
430
430
  branch: this.#engine.gitBranch,
431
+ pullRequest: this.#engine.pullRequest,
431
432
  sessionName: this.#engine.session?.sessionManager?.getSessionName() ?? null,
432
433
  availableProviderCount: new Set(this.#engine.runtime?.services.modelRuntime.getAvailableSnapshot?.().map(model => model.provider).filter(provider => provider !== undefined) ?? []).size,
433
434
  extensionStatuses: [],
@@ -0,0 +1,8 @@
1
+ export interface PiPullRequestIdentity {
2
+ readonly number: number;
3
+ readonly url: string;
4
+ }
5
+ export type PiPullRequestProbe = (cwd: string, branch: string, signal: AbortSignal) => Promise<PiPullRequestIdentity | null>;
6
+ /** Read the open GitHub pull request associated with one exact local branch. */
7
+ export declare function readOpenPullRequest(cwd: string, branch: string, signal: AbortSignal, environment?: NodeJS.ProcessEnv): Promise<PiPullRequestIdentity | null>;
8
+ export declare function parseOpenPullRequest(stdout: string, branch: string): PiPullRequestIdentity | null;
@@ -0,0 +1,62 @@
1
+ import { execFile } from "node:child_process";
2
+ import { PRODUCT_IDENTITY } from "../../../product-identity.js";
3
+ const GH_TIMEOUT_MS = 5_000;
4
+ const GH_MAX_BUFFER_BYTES = 64 * 1024;
5
+ /** Read the open GitHub pull request associated with one exact local branch. */
6
+ export async function readOpenPullRequest(cwd, branch, signal, environment = process.env) {
7
+ if (branch.length === 0 || signal.aborted)
8
+ return null;
9
+ const preview = environment[PRODUCT_IDENTITY.environment.prFooterPreview];
10
+ if (preview !== undefined)
11
+ return parseOpenPullRequest(preview, branch);
12
+ const stdout = await executeGh(cwd, signal);
13
+ if (stdout === null)
14
+ return null;
15
+ return parseOpenPullRequest(stdout, branch);
16
+ }
17
+ export function parseOpenPullRequest(stdout, branch) {
18
+ let value;
19
+ try {
20
+ value = JSON.parse(stdout);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ if (!isRecord(value)
26
+ || !Number.isSafeInteger(value.number)
27
+ || value.number <= 0
28
+ || value.state !== "OPEN"
29
+ || value.headRefName !== branch
30
+ || typeof value.url !== "string")
31
+ return null;
32
+ const number = value.number;
33
+ try {
34
+ const url = new URL(value.url);
35
+ if (url.protocol !== "https:"
36
+ || url.hostname.toLowerCase() !== "github.com"
37
+ || url.username !== ""
38
+ || url.password !== ""
39
+ || url.port !== ""
40
+ || url.search !== ""
41
+ || url.hash !== ""
42
+ || !new RegExp(`^/[^/]+/[^/]+/pull/${number}/?$`, "u").test(url.pathname))
43
+ return null;
44
+ return { number, url: url.href.replace(/\/$/u, "") };
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ function executeGh(cwd, signal) {
51
+ return new Promise(resolve => {
52
+ try {
53
+ execFile("gh", ["pr", "view", "--json", "number,url,state,headRefName"], { cwd, windowsHide: true, timeout: GH_TIMEOUT_MS, maxBuffer: GH_MAX_BUFFER_BYTES, signal, encoding: "utf8" }, (error, stdout) => { resolve(error === null && typeof stdout === "string" ? stdout : null); });
54
+ }
55
+ catch {
56
+ resolve(null);
57
+ }
58
+ });
59
+ }
60
+ function isRecord(value) {
61
+ return typeof value === "object" && value !== null && !Array.isArray(value);
62
+ }