@cydm/pie 2.6.4 → 2.6.5

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.
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createCliWebResearchHealthStore,
8
8
  formatSize,
9
9
  truncateHeadTail
10
- } from "./chunks/chunk-6QEDYZUR.js";
10
+ } from "./chunks/chunk-TFRQE7UQ.js";
11
11
  import {
12
12
  AGENTS_CONTEXT_FILE_NAME,
13
13
  AgentSessionController,
@@ -60,8 +60,8 @@ import {
60
60
  setExtensionEnabledInSettings,
61
61
  shouldPreserveExecutionStateForUserText,
62
62
  supersedeExecutionState
63
- } from "./chunks/chunk-3AOMWS2Z.js";
64
- import "./chunks/chunk-YEUBQBOB.js";
63
+ } from "./chunks/chunk-QKSK5K5N.js";
64
+ import "./chunks/chunk-AETQBDEG.js";
65
65
  import {
66
66
  Deref,
67
67
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -85,7 +85,7 @@ import {
85
85
  setLogger,
86
86
  sortToolModelCandidatesByCapability,
87
87
  type_exports
88
- } from "./chunks/chunk-OCEYHWVX.js";
88
+ } from "./chunks/chunk-5OXH6NUH.js";
89
89
  import {
90
90
  VERSION,
91
91
  getAgentDir,
@@ -53581,20 +53581,83 @@ function filterEnabledTools(tools, settingsManager) {
53581
53581
  const disabled = getDisabledToolNames(settingsManager);
53582
53582
  return disabled.size > 0 ? tools.filter((tool) => !disabled.has(tool.name)) : [...tools];
53583
53583
  }
53584
+ function isPlainObject(value) {
53585
+ return typeof value === "object" && value !== null && !Array.isArray(value);
53586
+ }
53584
53587
  function mergeSnapshotDelta(atLoad, current, onDisk) {
53585
- const merged = { ...onDisk };
53586
- const load = atLoad;
53587
- const cur = current;
53588
- const allKeys = /* @__PURE__ */ new Set([...Object.keys(load), ...Object.keys(cur)]);
53588
+ return mergeDeltaNode(atLoad, current, onDisk);
53589
+ }
53590
+ function mergeDeltaNode(load, cur, disk) {
53591
+ if (!isPlainObject(disk)) {
53592
+ return JSON.stringify(load) === JSON.stringify(cur) ? disk : cur;
53593
+ }
53594
+ const merged = { ...disk };
53595
+ const l = load === void 0 || load === null ? {} : isPlainObject(load) ? load : null;
53596
+ const c = cur === void 0 || cur === null ? {} : isPlainObject(cur) ? cur : null;
53597
+ if (l === null || c === null) {
53598
+ return JSON.stringify(load) === JSON.stringify(cur) ? disk : cur;
53599
+ }
53600
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(l), ...Object.keys(c)]);
53601
+ const own = (o, key) => Object.hasOwn(o, key) ? o[key] : void 0;
53589
53602
  for (const key of allKeys) {
53590
- const before = JSON.stringify(load[key]);
53591
- const after = JSON.stringify(cur[key]);
53592
- if (before === after) continue;
53593
- if (after === void 0) delete merged[key];
53594
- else merged[key] = cur[key];
53603
+ const before = own(l, key);
53604
+ const after = own(c, key);
53605
+ if (JSON.stringify(before) === JSON.stringify(after)) continue;
53606
+ const diskValue = own(merged, key);
53607
+ if (after === void 0) {
53608
+ if (isPlainObject(before) && isPlainObject(diskValue)) {
53609
+ const pruned = { ...diskValue };
53610
+ for (const nestedKey of Object.keys(before)) delete pruned[nestedKey];
53611
+ if (Object.keys(pruned).length === 0) delete merged[key];
53612
+ else setOwnDataProperty(merged, key, pruned);
53613
+ } else {
53614
+ delete merged[key];
53615
+ }
53616
+ continue;
53617
+ }
53618
+ if (isPlainObject(after) && (isPlainObject(diskValue) || diskValue === void 0 || diskValue === null)) {
53619
+ setOwnDataProperty(merged, key, mergeDeltaNode(before, after, diskValue ?? {}));
53620
+ } else {
53621
+ setOwnDataProperty(merged, key, after);
53622
+ }
53595
53623
  }
53596
53624
  return merged;
53597
53625
  }
53626
+ function setOwnDataProperty(target, key, value) {
53627
+ Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
53628
+ }
53629
+ function cloneJsonDocument(value) {
53630
+ return JSON.parse(JSON.stringify(value));
53631
+ }
53632
+ function writeJsonAtomic(filePath, value) {
53633
+ fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
53634
+ const tempPath = `${filePath}.${process.pid}.${Date.now().toString(36)}.tmp`;
53635
+ try {
53636
+ const fd = fs4.openSync(tempPath, "w");
53637
+ try {
53638
+ fs4.writeFileSync(fd, JSON.stringify(value, null, 2));
53639
+ fs4.fsyncSync(fd);
53640
+ } finally {
53641
+ fs4.closeSync(fd);
53642
+ }
53643
+ fs4.renameSync(tempPath, filePath);
53644
+ try {
53645
+ const dirFd = fs4.openSync(path4.dirname(filePath), "r");
53646
+ try {
53647
+ fs4.fsyncSync(dirFd);
53648
+ } finally {
53649
+ fs4.closeSync(dirFd);
53650
+ }
53651
+ } catch {
53652
+ }
53653
+ } catch (error) {
53654
+ try {
53655
+ fs4.unlinkSync(tempPath);
53656
+ } catch {
53657
+ }
53658
+ throw error;
53659
+ }
53660
+ }
53598
53661
  var SettingsManager = class {
53599
53662
  settingsPath;
53600
53663
  legacyConfigPath;
@@ -53612,9 +53675,9 @@ var SettingsManager = class {
53612
53675
  this.settingsPath = getSettingsPath();
53613
53676
  this.legacyConfigPath = `${configDir}/config.json`;
53614
53677
  this.settings = this.loadSettingsFile();
53615
- this.settingsLastWritten = structuredClone(this.settings);
53678
+ this.settingsLastWritten = cloneJsonDocument(this.settings);
53616
53679
  this.legacyConfig = this.loadLegacyConfigFile();
53617
- this.legacyConfigLastWritten = structuredClone(this.legacyConfig);
53680
+ this.legacyConfigLastWritten = cloneJsonDocument(this.legacyConfig);
53618
53681
  }
53619
53682
  readJson(filePath) {
53620
53683
  if (!fs4.existsSync(filePath)) return null;
@@ -53635,9 +53698,9 @@ var SettingsManager = class {
53635
53698
  }
53636
53699
  writeSettings() {
53637
53700
  this.ensureDir();
53638
- const written = this.writeMergedOrFull(() => this.settingsPath, () => this.settingsLastWritten, () => this.settings, (value) => this.writeSettingsValue(value));
53639
- this.settings = structuredClone(written);
53640
- this.settingsLastWritten = structuredClone(written);
53701
+ const { value } = this.mergeOntoDisk(this.settingsPath, this.settingsLastWritten, this.settings);
53702
+ this.settings = cloneJsonDocument(value);
53703
+ this.settingsLastWritten = cloneJsonDocument(value);
53641
53704
  }
53642
53705
  /** Merged write for an explicit candidate state (setters that build a
53643
53706
  * nextSettings object): writes FIRST (a failed write leaves this
@@ -53645,39 +53708,33 @@ var SettingsManager = class {
53645
53708
  * written — callers assign THAT (not their candidate, which lacks keys
53646
53709
  * preserved from disk) so state and lastWritten never diverge. */
53647
53710
  writeSettingsWith(next) {
53648
- const written = this.writeMergedOrFull(() => this.settingsPath, () => this.settingsLastWritten, () => next, (value) => this.writeSettingsValue(value));
53649
- this.settingsLastWritten = structuredClone(written);
53650
- return written;
53711
+ const { value } = this.mergeOntoDisk(this.settingsPath, this.settingsLastWritten, next);
53712
+ this.settingsLastWritten = cloneJsonDocument(value);
53713
+ return value;
53651
53714
  }
53652
- /** Shared write path: merge our delta onto the current on-disk object and
53653
- * return the value actually written. When the file EXISTS but does not
53654
- * parse (another process mid-write over a non-atomic writeFileSync),
53715
+ /** Shared write path: merge our delta onto the current on-disk object
53716
+ * (atomic temp+rename write) and return the value actually written. When
53717
+ * the file EXISTS but does not parse (a foreign non-atomic writer),
53655
53718
  * merging onto {} would silently delete every unrelated key — fall back
53656
53719
  * to the full candidate write instead. */
53657
- writeMergedOrFull(path34, lastWritten, current, write) {
53720
+ mergeOntoDisk(filePath, lastWritten, current) {
53658
53721
  let onDisk = null;
53659
53722
  let corrupt = false;
53660
- if (fs4.existsSync(path34())) {
53723
+ if (fs4.existsSync(filePath)) {
53661
53724
  try {
53662
- onDisk = JSON.parse(fs4.readFileSync(path34(), "utf-8"));
53725
+ onDisk = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
53663
53726
  } catch {
53664
53727
  corrupt = true;
53665
53728
  }
53666
53729
  }
53667
- const value = corrupt ? current() : mergeSnapshotDelta(lastWritten(), current(), onDisk ?? {});
53668
- write(value);
53669
- return value;
53670
- }
53671
- writeSettingsValue(settings) {
53672
- this.ensureDir();
53673
- fs4.writeFileSync(this.settingsPath, JSON.stringify(settings, null, 2));
53730
+ const value = corrupt ? current : mergeSnapshotDelta(lastWritten, current, onDisk ?? {});
53731
+ writeJsonAtomic(filePath, value);
53732
+ return { value };
53674
53733
  }
53675
53734
  writeLegacyConfig() {
53676
53735
  this.ensureDir();
53677
- this.writeMergedOrFull(() => this.legacyConfigPath, () => this.legacyConfigLastWritten, () => this.legacyConfig, (value) => {
53678
- fs4.writeFileSync(this.legacyConfigPath, JSON.stringify(value, null, 2));
53679
- this.legacyConfigLastWritten = structuredClone(value);
53680
- });
53736
+ const { value } = this.mergeOntoDisk(this.legacyConfigPath, this.legacyConfigLastWritten, this.legacyConfig);
53737
+ this.legacyConfigLastWritten = cloneJsonDocument(value);
53681
53738
  }
53682
53739
  getLegacyApiKey() {
53683
53740
  return this.legacyConfig.apiKey;
@@ -53760,11 +53817,9 @@ var SettingsManager = class {
53760
53817
  readProjectSettings(cwd) {
53761
53818
  return this.readJson(getProjectSettingsPath(cwd)) || {};
53762
53819
  }
53763
- writeProjectSettings(cwd, settings) {
53764
- const settingsPath = getProjectSettingsPath(cwd);
53765
- fs4.mkdirSync(path4.dirname(settingsPath), { recursive: true });
53766
- fs4.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
53767
- }
53820
+ /** Per-cwd last-written baselines so project-scope writes use the same
53821
+ * recursive delta merge as user settings instead of whole-file rewrites. */
53822
+ projectLastWritten = /* @__PURE__ */ new Map();
53768
53823
  /** Raw extension enablement map for one scope. */
53769
53824
  getExtensionSettings(scope = "user", cwd = process.cwd()) {
53770
53825
  const settings = scope === "project" ? this.readProjectSettings(cwd) : this.settings;
@@ -53788,9 +53843,12 @@ var SettingsManager = class {
53788
53843
  */
53789
53844
  setExtensionEnabled(identity, enabled, scope = "user", cwd = process.cwd()) {
53790
53845
  if (scope === "project") {
53791
- const projectSettings = this.readProjectSettings(cwd);
53792
- setExtensionEnabledInSettings(projectSettings, identity, enabled);
53793
- this.writeProjectSettings(cwd, projectSettings);
53846
+ const loaded = this.readProjectSettings(cwd);
53847
+ const next = cloneJsonDocument(loaded);
53848
+ setExtensionEnabledInSettings(next, identity, enabled);
53849
+ const settingsPath = getProjectSettingsPath(cwd);
53850
+ const { value } = this.mergeOntoDisk(settingsPath, this.projectLastWritten.get(cwd) ?? loaded, next);
53851
+ this.projectLastWritten.set(cwd, cloneJsonDocument(value));
53794
53852
  return;
53795
53853
  }
53796
53854
  const nextSettings = {
@@ -55644,7 +55702,7 @@ function recoverOnePublishJournal(params) {
55644
55702
  }
55645
55703
  const dirExists = (id) => {
55646
55704
  try {
55647
- return fs7.statSync(path7.join(params.sessionsDir, id)).isDirectory();
55705
+ return fs7.lstatSync(path7.join(params.sessionsDir, id)).isDirectory();
55648
55706
  } catch {
55649
55707
  return false;
55650
55708
  }
@@ -57748,14 +57806,21 @@ var Box = class {
57748
57806
  this.invalidateCache();
57749
57807
  }
57750
57808
  setBgFn(bgFn) {
57809
+ if (this.bgFn === bgFn) return;
57751
57810
  this.bgFn = bgFn;
57811
+ this.invalidateCache();
57752
57812
  }
57753
57813
  invalidateCache() {
57754
57814
  this.cache = void 0;
57755
57815
  }
57756
- matchCache(width, childLines, bgSample) {
57816
+ matchCache(width, childOutputs, bgSample) {
57757
57817
  const cache = this.cache;
57758
- return !!cache && cache.width === width && cache.bgSample === bgSample && cache.childLines.length === childLines.length && cache.childLines.every((line, i) => line === childLines[i]);
57818
+ if (!cache || cache.width !== width || cache.bgSample !== bgSample) return false;
57819
+ if (cache.childOutputs.length !== childOutputs.length) return false;
57820
+ for (let i = 0; i < childOutputs.length; i++) {
57821
+ if (cache.childOutputs[i] !== childOutputs[i]) return false;
57822
+ }
57823
+ return true;
57759
57824
  }
57760
57825
  invalidate() {
57761
57826
  this.invalidateCache();
@@ -57765,22 +57830,29 @@ var Box = class {
57765
57830
  }
57766
57831
  render(width) {
57767
57832
  if (this.children.length === 0) {
57768
- return [];
57833
+ if (!this.cache) this.cache = { childOutputs: [], width, bgSample: void 0, lines: [] };
57834
+ return this.cache.lines;
57769
57835
  }
57770
57836
  const contentWidth = Math.max(1, width - this.paddingX * 2);
57771
57837
  const leftPad = " ".repeat(this.paddingX);
57772
- const childLines = [];
57838
+ const childOutputs = [];
57773
57839
  for (const child of this.children) {
57774
- const lines = child.render(contentWidth);
57775
- for (const line of lines) {
57840
+ childOutputs.push(child.render(contentWidth));
57841
+ }
57842
+ const bgSample = this.bgFn ? this.bgFn("test") : void 0;
57843
+ if (this.matchCache(width, childOutputs, bgSample)) {
57844
+ return this.cache.lines;
57845
+ }
57846
+ const childLines = [];
57847
+ let anyContent = false;
57848
+ for (const output of childOutputs) {
57849
+ for (const line of output) {
57776
57850
  childLines.push(leftPad + line);
57851
+ anyContent = true;
57777
57852
  }
57778
57853
  }
57779
- if (childLines.length === 0) {
57780
- return [];
57781
- }
57782
- const bgSample = this.bgFn ? this.bgFn("test") : void 0;
57783
- if (this.matchCache(width, childLines, bgSample)) {
57854
+ if (!anyContent) {
57855
+ this.cache = { childOutputs, width, bgSample, lines: [] };
57784
57856
  return this.cache.lines;
57785
57857
  }
57786
57858
  const result = [];
@@ -57793,7 +57865,7 @@ var Box = class {
57793
57865
  for (let i = 0; i < this.paddingY; i++) {
57794
57866
  result.push(this.applyBg("", width));
57795
57867
  }
57796
- this.cache = { childLines, width, bgSample, lines: result };
57868
+ this.cache = { childOutputs, width, bgSample, lines: result };
57797
57869
  return result;
57798
57870
  }
57799
57871
  applyBg(line, width) {
@@ -58544,30 +58616,66 @@ function isImageLine(line) {
58544
58616
  // ../../packages/tui/src/component-tree.ts
58545
58617
  var Container = class {
58546
58618
  children = [];
58619
+ memoWidth = -1;
58620
+ memoChildOutputs = [];
58621
+ memoLines = null;
58547
58622
  addChild(component) {
58548
58623
  this.children.push(component);
58624
+ this.dropMemo();
58549
58625
  }
58550
58626
  removeChild(component) {
58551
58627
  const index = this.children.indexOf(component);
58552
58628
  if (index !== -1) {
58553
58629
  this.children.splice(index, 1);
58630
+ this.dropMemo();
58554
58631
  }
58555
58632
  }
58556
58633
  clear() {
58557
58634
  this.children = [];
58635
+ this.dropMemo();
58558
58636
  }
58559
58637
  invalidate() {
58638
+ this.dropMemo();
58560
58639
  for (const child of this.children) {
58561
58640
  child.invalidate?.();
58562
58641
  }
58563
58642
  }
58564
58643
  render(width) {
58644
+ const childCount = this.children.length;
58645
+ if (this.memoLines !== null && this.memoWidth === width && this.memoChildOutputs.length === childCount) {
58646
+ const outputs2 = new Array(childCount);
58647
+ let unchanged = true;
58648
+ for (let i = 0; i < childCount; i++) {
58649
+ const childLines = this.children[i].render(width);
58650
+ outputs2[i] = childLines;
58651
+ if (childLines !== this.memoChildOutputs[i]) unchanged = false;
58652
+ }
58653
+ if (unchanged) return this.memoLines;
58654
+ return this.rebuildMemo(width, outputs2);
58655
+ }
58656
+ const outputs = new Array(childCount);
58657
+ for (let i = 0; i < childCount; i++) {
58658
+ outputs[i] = this.children[i].render(width);
58659
+ }
58660
+ return this.rebuildMemo(width, outputs);
58661
+ }
58662
+ rebuildMemo(width, outputs) {
58565
58663
  const lines = [];
58566
- for (const child of this.children) {
58567
- lines.push(...child.render(width));
58664
+ for (const childLines of outputs) {
58665
+ for (let j2 = 0; j2 < childLines.length; j2++) {
58666
+ lines.push(childLines[j2]);
58667
+ }
58568
58668
  }
58669
+ this.memoWidth = width;
58670
+ this.memoChildOutputs = outputs;
58671
+ this.memoLines = lines;
58569
58672
  return lines;
58570
58673
  }
58674
+ dropMemo() {
58675
+ this.memoWidth = -1;
58676
+ this.memoChildOutputs = [];
58677
+ this.memoLines = null;
58678
+ }
58571
58679
  };
58572
58680
 
58573
58681
  // ../../packages/tui/src/tui-core.ts
@@ -58873,26 +58981,17 @@ function extractCursorPosition(lines, height) {
58873
58981
  const viewportTop = Math.max(0, lines.length - height);
58874
58982
  for (let row = lines.length - 1; row >= viewportTop; row--) {
58875
58983
  const line = lines[row];
58984
+ if (line === void 0) continue;
58876
58985
  const markerIndex = line.indexOf(CURSOR_MARKER);
58877
58986
  if (markerIndex !== -1) {
58878
58987
  const beforeMarker = line.slice(0, markerIndex);
58879
58988
  const col = visibleWidth(beforeMarker);
58880
- lines[row] = line.slice(0, markerIndex) + line.slice(markerIndex + CURSOR_MARKER.length);
58881
- return { row, col };
58989
+ const strippedLine = beforeMarker + line.slice(markerIndex + CURSOR_MARKER.length);
58990
+ return { row, col, strippedLine };
58882
58991
  }
58883
58992
  }
58884
58993
  return null;
58885
58994
  }
58886
- function applyLineResets(lines) {
58887
- const reset = "\x1B[0m\x1B]8;;\x07";
58888
- for (let i = 0; i < lines.length; i++) {
58889
- const line = lines[i];
58890
- if (!isImageLine(line)) {
58891
- lines[i] = line + reset;
58892
- }
58893
- }
58894
- return lines;
58895
- }
58896
58995
  function findChangedRange(previousLines, newLines) {
58897
58996
  let firstChanged = -1;
58898
58997
  let lastChanged = -1;
@@ -58971,6 +59070,10 @@ var TerminalProtocol = class {
58971
59070
  };
58972
59071
 
58973
59072
  // ../../packages/tui/src/tui.ts
59073
+ var LINE_RESET_SUFFIX = "\x1B[0m\x1B]8;;\x07";
59074
+ function lineForWrite(line) {
59075
+ return isImageLine(line) ? line : line + LINE_RESET_SUFFIX;
59076
+ }
58974
59077
  var TUI = class extends Container {
58975
59078
  terminal;
58976
59079
  previousLines = [];
@@ -59146,7 +59249,10 @@ var TUI = class extends Container {
59146
59249
  newLines = this.overlayManager.composite(newLines, width, height, this.maxLinesRendered);
59147
59250
  }
59148
59251
  const cursorPos = extractCursorPosition(newLines, height);
59149
- newLines = applyLineResets(newLines);
59252
+ if (cursorPos) {
59253
+ newLines = newLines.slice();
59254
+ newLines[cursorPos.row] = cursorPos.strippedLine;
59255
+ }
59150
59256
  const widthChanged = this.previousWidth !== 0 && this.previousWidth !== width;
59151
59257
  const fullRender = (clear) => {
59152
59258
  this.fullRedrawCount += 1;
@@ -59154,7 +59260,7 @@ var TUI = class extends Container {
59154
59260
  if (clear) buffer2 += "\x1B[3J\x1B[2J\x1B[H";
59155
59261
  for (let i = 0; i < newLines.length; i++) {
59156
59262
  if (i > 0) buffer2 += "\r\n";
59157
- buffer2 += newLines[i];
59263
+ buffer2 += lineForWrite(newLines[i]);
59158
59264
  }
59159
59265
  buffer2 += "\x1B[?2026l";
59160
59266
  this.terminal.write(buffer2);
@@ -59293,7 +59399,7 @@ var TUI = class extends Container {
59293
59399
  ].join("\n");
59294
59400
  throw new Error(errorMsg);
59295
59401
  }
59296
- buffer += line;
59402
+ buffer += lineForWrite(line);
59297
59403
  }
59298
59404
  let finalCursorRow = renderEnd;
59299
59405
  if (this.previousLines.length > newLines.length) {
@@ -62624,6 +62730,11 @@ var Xt = b.parse;
62624
62730
  var Jt = x.lex;
62625
62731
 
62626
62732
  // ../../packages/tui/src/components/markdown.ts
62733
+ function appendLines(target, source) {
62734
+ for (let i = 0; i < source.length; i++) {
62735
+ target.push(source[i]);
62736
+ }
62737
+ }
62627
62738
  var Markdown = class {
62628
62739
  text;
62629
62740
  paddingX;
@@ -62672,7 +62783,7 @@ var Markdown = class {
62672
62783
  const token = tokens[i];
62673
62784
  const nextToken = tokens[i + 1];
62674
62785
  const tokenLines = this.renderToken(token, contentWidth, nextToken?.type);
62675
- renderedLines.push(...tokenLines);
62786
+ appendLines(renderedLines, tokenLines);
62676
62787
  }
62677
62788
  const wrappedLines = [];
62678
62789
  for (const line of renderedLines) {
@@ -62836,12 +62947,12 @@ var Markdown = class {
62836
62947
  }
62837
62948
  case "list": {
62838
62949
  const listLines = this.renderList(token, 0);
62839
- lines.push(...listLines);
62950
+ appendLines(lines, listLines);
62840
62951
  break;
62841
62952
  }
62842
62953
  case "table": {
62843
62954
  const tableLines = this.renderTable(token, width);
62844
- lines.push(...tableLines);
62955
+ appendLines(lines, tableLines);
62845
62956
  break;
62846
62957
  }
62847
62958
  case "blockquote": {
@@ -62992,7 +63103,7 @@ var Markdown = class {
62992
63103
  for (const token of tokens) {
62993
63104
  if (token.type === "list") {
62994
63105
  const nestedLines = this.renderList(token, parentDepth + 1);
62995
- lines.push(...nestedLines);
63106
+ appendLines(lines, nestedLines);
62996
63107
  } else if (token.type === "text") {
62997
63108
  const text = token.tokens && token.tokens.length > 0 ? this.renderInlineTokens(token.tokens) : token.text || "";
62998
63109
  lines.push(text);
@@ -63367,19 +63478,25 @@ var SettingsList = class {
63367
63478
  // ../../packages/tui/src/components/spacer.ts
63368
63479
  var Spacer = class {
63369
63480
  lines;
63481
+ cache = [];
63370
63482
  constructor(lines = 1) {
63371
63483
  this.lines = lines;
63372
63484
  }
63373
63485
  setLines(lines) {
63486
+ if (lines === this.lines) return;
63374
63487
  this.lines = lines;
63488
+ this.cache = [];
63375
63489
  }
63376
63490
  invalidate() {
63491
+ this.cache = [];
63377
63492
  }
63378
63493
  render(_width) {
63494
+ if (this.cache.length === this.lines) return this.cache;
63379
63495
  const result = [];
63380
63496
  for (let i = 0; i < this.lines; i++) {
63381
63497
  result.push("");
63382
63498
  }
63499
+ this.cache = result;
63383
63500
  return result;
63384
63501
  }
63385
63502
  };
@@ -65915,6 +66032,9 @@ function setTheme(name, enableWatcher = false) {
65915
66032
  function getCurrentThemeName() {
65916
66033
  return currentThemeName ?? getDefaultTheme();
65917
66034
  }
66035
+ function onThemeChange(callback) {
66036
+ onThemeChangeCallback = callback;
66037
+ }
65918
66038
  function startThemeWatcher() {
65919
66039
  if (themeWatcher) {
65920
66040
  themeWatcher.close();
@@ -71838,9 +71958,14 @@ ${theme.fg("error", "Error: " + errorOutput)}`;
71838
71958
  };
71839
71959
 
71840
71960
  // src/runtime/footer-lifecycle.ts
71961
+ var FOOTER_LABEL_MAX_WIDTH = 60;
71962
+ var MIN_PROGRESS_WIDTH = 8;
71841
71963
  function messageRole(event) {
71842
71964
  return String(event.message.role);
71843
71965
  }
71966
+ function isCuratedProgressDetails(details) {
71967
+ return typeof details === "object" && details !== null && "increment" in details;
71968
+ }
71844
71969
  function formatFooterLifecycleEvent(event) {
71845
71970
  switch (event.type) {
71846
71971
  case "message_start":
@@ -71852,8 +71977,15 @@ function formatFooterLifecycleEvent(event) {
71852
71977
  case "tool_execution_start":
71853
71978
  return `\u25B6 ${event.toolName}`;
71854
71979
  case "tool_execution_update": {
71855
- const progress = latestProgressText(event.partialResult?.content);
71856
- return progress ? clipProgressText(progress) : `\u21BB ${event.toolName}`;
71980
+ const status = `\u21BB ${event.toolName}`;
71981
+ const progress = isCuratedProgressDetails(event.partialResult?.details) ? latestProgressText(event.partialResult?.content) : void 0;
71982
+ if (!progress) return clipProgressText(status, FOOTER_LABEL_MAX_WIDTH);
71983
+ const prefixWidth = visibleWidth(`${status} \xB7 `);
71984
+ const progressBudget = FOOTER_LABEL_MAX_WIDTH - prefixWidth;
71985
+ if (progressBudget < MIN_PROGRESS_WIDTH) {
71986
+ return clipProgressText(status, FOOTER_LABEL_MAX_WIDTH);
71987
+ }
71988
+ return `${status} \xB7 ${clipProgressText(progress, progressBudget)}`;
71857
71989
  }
71858
71990
  case "tool_execution_end":
71859
71991
  return event.isError ? `\u2715 ${event.toolName}` : `\u2713 ${event.toolName}`;
@@ -71919,6 +72051,24 @@ function sendDesktopNotification(reason, options = {}) {
71919
72051
  }
71920
72052
 
71921
72053
  // src/runtime/interactive-runtime-events.ts
72054
+ var STREAM_RENDER_MIN_INTERVAL_MS = 80;
72055
+ var lastStreamRenderAt = 0;
72056
+ var trailingStreamRenderTimer = null;
72057
+ function requestStreamingRender(host) {
72058
+ const now = Date.now();
72059
+ if (now - lastStreamRenderAt >= STREAM_RENDER_MIN_INTERVAL_MS) {
72060
+ lastStreamRenderAt = now;
72061
+ host.safeRequestRender();
72062
+ return;
72063
+ }
72064
+ if (trailingStreamRenderTimer === null) {
72065
+ trailingStreamRenderTimer = setTimeout(() => {
72066
+ trailingStreamRenderTimer = null;
72067
+ lastStreamRenderAt = Date.now();
72068
+ host.safeRequestRender();
72069
+ }, STREAM_RENDER_MIN_INTERVAL_MS - (now - lastStreamRenderAt));
72070
+ }
72071
+ }
71922
72072
  function bindInteractiveRuntimeEvents(host) {
71923
72073
  host.agent.subscribe((event) => {
71924
72074
  switch (event.type) {
@@ -72257,7 +72407,7 @@ function handleMessageUpdate(host, event) {
72257
72407
  role: "assistant",
72258
72408
  content
72259
72409
  });
72260
- host.safeRequestRender();
72410
+ requestStreamingRender(host);
72261
72411
  }
72262
72412
  function findToolRenderHint(host, toolName) {
72263
72413
  const tools = host.agent?.state?.tools ?? [];
@@ -77859,7 +78009,8 @@ function stripStaleUsageBeforeCompaction(messages, latestCompactionTimestamp) {
77859
78009
  }
77860
78010
 
77861
78011
  // src/runtime/retry-policy.ts
77862
- var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|client network socket disconnected before secure TLS connection was established|certificate (?:has )?expired|unable to verify (?:the first certificate|certificate)|self[- ]signed cert|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
78012
+ var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|client network socket disconnected before secure TLS connection was established|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
78013
+ var TLS_VALIDATION_ERROR_PATTERN = /certificate (?:has )?expired|certificate is not yet valid|unable to verify (?:the first certificate|certificate)|unable to get (?:local )?issuer certificate|self[-_ ]signed cert(?:ificate)?|CERT_HAS_EXPIRED|SELF_SIGNED_CERT|does not match certificate's altnames|ERR_TLS_CERT_ALTNAME_INVALID/i;
77863
78014
  var PROVIDER_TRANSIENT_ERROR_PATTERN = /overloaded|rate.?limit|too many requests|\b429\b|\b500\b|\b502\b|\b503\b|\b504\b|service.?unavailable|server error|internal error|retry delay|quota (?:has been |is )?exhausted/i;
77864
78015
  var USER_ABORT_PATTERN = /request was aborted|local abort signal|user abort|user_interrupt|interrupted by user|esc pressed|ctrl\+c/i;
77865
78016
  var AUTH_CONFIG_PATTERN = /missing api key|invalid api key|api key.*invalid|unauthorized|\b401\b|\b403\b|forbidden|authentication failed|no configured model|no models? are configured/i;
@@ -77869,6 +78020,7 @@ var INVALID_REQUEST_PATTERN = /bad request|\b400\b|invalid request|invalid schem
77869
78020
  var CLI_RETRY_MAX_RETRIES = 3;
77870
78021
  var CLI_RETRY_BASE_DELAY_MS = 2e3;
77871
78022
  var CLI_TRANSIENT_NETWORK_MAX_RETRIES = 10;
78023
+ var CLI_RETRY_TOTAL_MAX_RETRIES = 12;
77872
78024
  var CLI_RETRY_MAX_DELAY_MS = 6e4;
77873
78025
  function isCliContextOverflowError(errorMessage4) {
77874
78026
  return /context length exceeded|context_length_exceeded|maximum context length|maximum context size|too many tokens|input.*too long|prompt.*too long|context window|token limit exceeded|exceeds.{0,20}context/i.test(
@@ -77906,6 +78058,12 @@ function classifyCliFailure(context) {
77906
78058
  if (AUTH_CONFIG_PATTERN.test(errorMessage4) || QUOTA_EXHAUSTED_PATTERN.test(errorMessage4)) {
77907
78059
  return createClassification("auth_config", errorMessage4);
77908
78060
  }
78061
+ if (TLS_VALIDATION_ERROR_PATTERN.test(errorMessage4)) {
78062
+ return createClassification("tls_config", errorMessage4, {
78063
+ retryable: true,
78064
+ terminal: false
78065
+ });
78066
+ }
77909
78067
  if (TRANSIENT_NETWORK_ERROR_PATTERN.test(errorMessage4)) {
77910
78068
  return createClassification("transient_network", errorMessage4, {
77911
78069
  retryable: true,
@@ -77962,13 +78120,22 @@ function getCliRetryMaxDelayMs() {
77962
78120
  const parsed = Number(override);
77963
78121
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : CLI_RETRY_MAX_DELAY_MS;
77964
78122
  }
78123
+ function getCliRetryTotalMaxRetries() {
78124
+ const override = process.env.PIE_RETRY_TOTAL_MAX_RETRIES;
78125
+ if (!override) {
78126
+ return CLI_RETRY_TOTAL_MAX_RETRIES;
78127
+ }
78128
+ const parsed = Number(override);
78129
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : CLI_RETRY_TOTAL_MAX_RETRIES;
78130
+ }
77965
78131
  function createCliRetryPolicy(isRetryableErrorOverride) {
77966
78132
  return {
77967
78133
  isRetryableError: isRetryableErrorOverride ?? isCliRetryableError,
77968
78134
  maxRetries: CLI_RETRY_MAX_RETRIES,
77969
78135
  baseDelayMs: getCliRetryBaseDelayMs(),
77970
78136
  maxDelayMs: getCliRetryMaxDelayMs(),
77971
- maxRetriesForFailure: (failure) => failure.kind === "transient_network" ? getCliTransientNetworkMaxRetries() : CLI_RETRY_MAX_RETRIES
78137
+ maxRetriesForFailure: (failure) => failure.kind === "transient_network" ? getCliTransientNetworkMaxRetries() : CLI_RETRY_MAX_RETRIES,
78138
+ maxTotalRetries: getCliRetryTotalMaxRetries()
77972
78139
  };
77973
78140
  }
77974
78141
 
@@ -78028,6 +78195,10 @@ function setupUI(host) {
78028
78195
  thinkingLevel: host.thinkingLevel,
78029
78196
  contextWindow: host.options.model?.contextWindow ?? 0
78030
78197
  });
78198
+ onThemeChange(() => {
78199
+ host.ui.invalidate();
78200
+ host.ui.requestRender();
78201
+ });
78031
78202
  host.editorContainer = new Container();
78032
78203
  host.todoWidgetContainer = new Container();
78033
78204
  host.todoWidget = new TodoWidgetComponent(host.executionState);
@@ -80265,7 +80436,7 @@ var InteractiveMode = class {
80265
80436
  async init() {
80266
80437
  const activeSession = this.sessionManager.getActiveSession();
80267
80438
  this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
80268
- const { Agent } = await import("./chunks/src-XT5S6AUQ.js");
80439
+ const { Agent } = await import("./chunks/src-Z4KWMX6E.js");
80269
80440
  this.agent = new Agent({
80270
80441
  initialState: {
80271
80442
  systemPrompt: this.buildSystemPrompt(),
@@ -80960,7 +81131,7 @@ function createPrintModeRetryStatusReporter() {
80960
81131
  console.error(`Retry succeeded after ${event.attempts} attempt${event.attempts === 1 ? "" : "s"}.`);
80961
81132
  } else if (event.type === "retry_exhausted") {
80962
81133
  exhaustedRetryBudget = event.maxRetries;
80963
- } else if (event.type === "turn_failed_terminal" && (event.failure.kind === "transient_network" || event.failure.kind === "provider_transient")) {
81134
+ } else if (event.type === "turn_failed_terminal" && (event.failure.kind === "transient_network" || event.failure.kind === "provider_transient" || event.failure.kind === "tls_config")) {
80964
81135
  console.error(`Request failed after ${exhaustedRetryBudget ?? CLI_RETRY_MAX_RETRIES} retries: ${event.failure.message}`);
80965
81136
  }
80966
81137
  };
@@ -81097,7 +81268,7 @@ async function runPrintMode(params) {
81097
81268
  `);
81098
81269
  console.log("Assistant: ");
81099
81270
  }
81100
- const { Agent: AgentClass } = await import("./chunks/src-XT5S6AUQ.js");
81271
+ const { Agent: AgentClass } = await import("./chunks/src-Z4KWMX6E.js");
81101
81272
  let agent;
81102
81273
  const printModeExtensions = await loadPrintModeExtensions({
81103
81274
  cwd: runtime.cwd,
@@ -81958,7 +82129,7 @@ async function runJsonEventsMode(params) {
81958
82129
  return;
81959
82130
  }
81960
82131
  const parent = agent;
81961
- const { Agent: AgentClass } = await import("./chunks/src-XT5S6AUQ.js");
82132
+ const { Agent: AgentClass } = await import("./chunks/src-Z4KWMX6E.js");
81962
82133
  const sideAgent = new AgentClass({
81963
82134
  initialState: {
81964
82135
  systemPrompt: parent.state.systemPrompt,
@@ -82302,7 +82473,7 @@ async function runJsonEventsMode(params) {
82302
82473
  if (runtime.initialModel.unconfigured || controller) {
82303
82474
  return;
82304
82475
  }
82305
- const { Agent: AgentClass } = await import("./chunks/src-XT5S6AUQ.js");
82476
+ const { Agent: AgentClass } = await import("./chunks/src-Z4KWMX6E.js");
82306
82477
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
82307
82478
  extensionRunner = jsonModeExtensions.runner;
82308
82479
  const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
@@ -82896,7 +83067,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
82896
83067
  }
82897
83068
  async function createCliTestStreamFnFromEnv() {
82898
83069
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
82899
- return (await import("./chunks/test-stream-FNWDHRTM.js")).createTestStreamFnFromSequenceEnv();
83070
+ return (await import("./chunks/test-stream-3FG7FHHU.js")).createTestStreamFnFromSequenceEnv();
82900
83071
  }
82901
83072
  function resolveJsonEventsDetailFlag() {
82902
83073
  for (let index = 0; index < process.argv.length; index += 1) {