@cydm/pie 1.0.29 → 1.0.30

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
@@ -5,6 +5,7 @@ import {
5
5
  cleanupBashOutputArtifacts,
6
6
  createCliHostCapabilities,
7
7
  createCliWebResearchHealthStore,
8
+ formatSize,
8
9
  getAgentDir,
9
10
  getBuiltinDir,
10
11
  getConfigDir,
@@ -16,8 +17,9 @@ import {
16
17
  getSessionsDir,
17
18
  getSettingsPath,
18
19
  getThemesDir,
19
- migrateConfigFromAgentDir
20
- } from "./chunks/chunk-BDDSZSHX.js";
20
+ migrateConfigFromAgentDir,
21
+ truncateHeadTail
22
+ } from "./chunks/chunk-PLJQYVFC.js";
21
23
  import {
22
24
  AGENTS_CONTEXT_FILE_NAME,
23
25
  AgentSessionController,
@@ -67,7 +69,7 @@ import {
67
69
  setExtensionEnabledInSettings,
68
70
  shouldPreserveExecutionStateForUserText,
69
71
  supersedeExecutionState
70
- } from "./chunks/chunk-L63BJMTT.js";
72
+ } from "./chunks/chunk-BOFCKEV5.js";
71
73
  import "./chunks/chunk-4B42ZU4B.js";
72
74
  import {
73
75
  Deref,
@@ -46263,7 +46265,7 @@ Default mode:
46263
46265
  - File tools read and write inside the current workspace.
46264
46266
  - ~/.pie is allowlisted for Pie configuration and session support.
46265
46267
  - Shell commands run from the workspace and return structured output, timeout, and truncation details.
46266
- - web_search is read-only and uses provider-native search; it does not grant bash/curl web scraping permission.
46268
+ - web_research is read-only, uses provider-native web/search/fetch capabilities, and does not grant bash/curl web scraping permission.
46267
46269
  - Protected paths from extensions can block reads/writes even when tools are present.
46268
46270
 
46269
46271
  Plan mode:
@@ -46969,6 +46971,7 @@ var CommandTree = class {
46969
46971
  if (isLast) {
46970
46972
  node.description = info.description;
46971
46973
  node.handler = info.handler;
46974
+ node.hidden = info.hidden === true;
46972
46975
  if (!node.children || node.children.length === 0) {
46973
46976
  node.isCategory = false;
46974
46977
  }
@@ -46993,7 +46996,7 @@ var CommandTree = class {
46993
46996
  */
46994
46997
  getChildren(path30) {
46995
46998
  const node = this.find(path30);
46996
- return node?.children || [];
46999
+ return (node?.children || []).filter((child) => !child.hidden);
46997
47000
  }
46998
47001
  /**
46999
47002
  * Check if a path exists (as category or command)
@@ -47014,6 +47017,7 @@ var CommandTree = class {
47014
47017
  search(prefix) {
47015
47018
  const results = [];
47016
47019
  const traverse = (node, currentPath) => {
47020
+ if (node.hidden) return;
47017
47021
  const newPath = node.name ? [...currentPath, node.name] : currentPath;
47018
47022
  const pathStr = newPath.join("/");
47019
47023
  if (node.name && pathStr.startsWith(prefix)) {
@@ -47038,6 +47042,7 @@ var CommandTree = class {
47038
47042
  searchByName(namePrefix) {
47039
47043
  const results = [];
47040
47044
  const traverse = (node, currentPath) => {
47045
+ if (node.hidden) return;
47041
47046
  const newPath = node.name ? [...currentPath, node.name] : currentPath;
47042
47047
  const pathStr = newPath.join("/");
47043
47048
  if (node.name && node.name.toLowerCase().startsWith(namePrefix.toLowerCase())) {
@@ -47061,6 +47066,7 @@ var CommandTree = class {
47061
47066
  getAllPaths() {
47062
47067
  const paths = [];
47063
47068
  const traverse = (node, currentPath) => {
47069
+ if (node.hidden) return;
47064
47070
  const newPath = node.name ? [...currentPath, node.name] : currentPath;
47065
47071
  if (node.name) {
47066
47072
  paths.push(newPath.join("/"));
@@ -47131,12 +47137,14 @@ function createExtensionContext(extension, cwd, uiContext, abortFn, isIdleFn, ha
47131
47137
  name: finalName,
47132
47138
  description: command.description,
47133
47139
  handler: command.handler,
47134
- path: cmdPath
47140
+ path: cmdPath,
47141
+ hidden: command.hidden === true
47135
47142
  };
47136
47143
  extension.commands.set(finalName, registeredCmd);
47137
47144
  commandTree.register(cmdPath, {
47138
47145
  description: command.description,
47139
- handler: command.handler
47146
+ handler: command.handler,
47147
+ hidden: command.hidden === true
47140
47148
  });
47141
47149
  },
47142
47150
  registerShortcut(key, shortcut) {
@@ -50138,6 +50146,18 @@ var SelectList = class {
50138
50146
  this.filteredItems = this.items.filter((item) => item.value.toLowerCase().startsWith(filter.toLowerCase()));
50139
50147
  this.selectedIndex = 0;
50140
50148
  }
50149
+ getVisibleRange() {
50150
+ const startIndex = Math.max(
50151
+ 0,
50152
+ Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible)
50153
+ );
50154
+ const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);
50155
+ return { startIndex, endIndex };
50156
+ }
50157
+ getVisibleItems() {
50158
+ const { startIndex, endIndex } = this.getVisibleRange();
50159
+ return this.filteredItems.slice(startIndex, endIndex);
50160
+ }
50141
50161
  setSelectedIndex(index) {
50142
50162
  this.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));
50143
50163
  }
@@ -50149,11 +50169,7 @@ var SelectList = class {
50149
50169
  lines.push(this.theme.noMatch(" No matching commands"));
50150
50170
  return lines;
50151
50171
  }
50152
- const startIndex = Math.max(
50153
- 0,
50154
- Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible)
50155
- );
50156
- const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);
50172
+ const { startIndex, endIndex } = this.getVisibleRange();
50157
50173
  for (let i = startIndex; i < endIndex; i++) {
50158
50174
  const item = this.filteredItems[i];
50159
50175
  if (!item) continue;
@@ -50166,19 +50182,20 @@ var SelectList = class {
50166
50182
  if (descriptionSingleLine && width > 40) {
50167
50183
  const maxValueWidth = Math.min(30, width - prefixWidth - 4);
50168
50184
  const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "");
50169
- const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
50170
- const descriptionStart = prefixWidth + truncatedValue.length + spacing.length;
50185
+ const valueWidth = visibleWidth(truncatedValue);
50186
+ const spacing = " ".repeat(Math.max(1, 32 - valueWidth));
50187
+ const descriptionStart = prefixWidth + valueWidth + spacing.length;
50171
50188
  const remainingWidth = width - descriptionStart - 2;
50172
50189
  if (remainingWidth > 10) {
50173
50190
  const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
50174
- line = this.theme.selectedText(`\u2192 ${truncatedValue}${spacing}${truncatedDesc}`);
50191
+ line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncatedValue}${spacing}${truncatedDesc}`), width, "");
50175
50192
  } else {
50176
50193
  const maxWidth = width - prefixWidth - 2;
50177
- line = this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`);
50194
+ line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`), width, "");
50178
50195
  }
50179
50196
  } else {
50180
50197
  const maxWidth = width - prefixWidth - 2;
50181
- line = this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`);
50198
+ line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`), width, "");
50182
50199
  }
50183
50200
  } else {
50184
50201
  const displayValue = item.label || item.value;
@@ -50186,23 +50203,24 @@ var SelectList = class {
50186
50203
  if (descriptionSingleLine && width > 40) {
50187
50204
  const maxValueWidth = Math.min(30, width - prefix.length - 4);
50188
50205
  const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "");
50189
- const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
50190
- const descriptionStart = prefix.length + truncatedValue.length + spacing.length;
50206
+ const valueWidth = visibleWidth(truncatedValue);
50207
+ const spacing = " ".repeat(Math.max(1, 32 - valueWidth));
50208
+ const descriptionStart = prefix.length + valueWidth + spacing.length;
50191
50209
  const remainingWidth = width - descriptionStart - 2;
50192
50210
  if (remainingWidth > 10) {
50193
50211
  const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
50194
50212
  const descText = this.theme.description(spacing + truncatedDesc);
50195
- line = prefix + truncatedValue + descText;
50213
+ line = truncateToWidth(prefix + truncatedValue + descText, width, "");
50196
50214
  } else {
50197
50215
  const maxWidth = width - prefix.length - 2;
50198
- line = prefix + truncateToWidth(displayValue, maxWidth, "");
50216
+ line = truncateToWidth(prefix + truncateToWidth(displayValue, maxWidth, ""), width, "");
50199
50217
  }
50200
50218
  } else {
50201
50219
  const maxWidth = width - prefix.length - 2;
50202
- line = prefix + truncateToWidth(displayValue, maxWidth, "");
50220
+ line = truncateToWidth(prefix + truncateToWidth(displayValue, maxWidth, ""), width, "");
50203
50221
  }
50204
50222
  }
50205
- lines.push(line);
50223
+ lines.push(truncateToWidth(line, width, ""));
50206
50224
  }
50207
50225
  if (startIndex > 0 || endIndex < this.filteredItems.length) {
50208
50226
  const scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;
@@ -56634,7 +56652,7 @@ var FileManagerError = class extends Error {
56634
56652
  code;
56635
56653
  details;
56636
56654
  locale;
56637
- constructor(code, details, locale = "zh") {
56655
+ constructor(code, details, locale = "en") {
56638
56656
  const messages = FileErrorMessages[code];
56639
56657
  super(messages[locale]);
56640
56658
  this.name = "FileManagerError";
@@ -61199,7 +61217,8 @@ var SessionSelectorComponent = class extends Container {
61199
61217
  items;
61200
61218
  refreshAttempted = /* @__PURE__ */ new Set();
61201
61219
  refreshInFlight = false;
61202
- pendingRefreshId;
61220
+ refreshQueue = [];
61221
+ refreshQueued = /* @__PURE__ */ new Set();
61203
61222
  refreshTimer;
61204
61223
  destroyed = false;
61205
61224
  constructor(sessions, callbacks, options = {}) {
@@ -61233,16 +61252,15 @@ var SessionSelectorComponent = class extends Container {
61233
61252
  this.clearRefreshTimer();
61234
61253
  this.callbacks.onCancel();
61235
61254
  };
61236
- this.selectList.onSelectionChange = (item) => {
61237
- this.scheduleRefresh(item.value);
61255
+ this.selectList.onSelectionChange = () => {
61256
+ this.scheduleVisibleRefreshes();
61238
61257
  };
61239
61258
  this.addChild(this.selectList);
61240
61259
  this.addChild(new Spacer(1));
61241
61260
  this.addChild(
61242
61261
  new Text(theme.fg("dim", " \u2191\u2193 to navigate \xB7 \u2190\u2192 to page \xB7 Enter to select \xB7 Esc to cancel"), 0, 0)
61243
61262
  );
61244
- const selected = this.selectList.getSelectedItem();
61245
- if (selected) this.scheduleRefresh(selected.value);
61263
+ this.scheduleVisibleRefreshes();
61246
61264
  }
61247
61265
  handleInput(data) {
61248
61266
  this.selectList.handleInput(data);
@@ -61264,9 +61282,14 @@ var SessionSelectorComponent = class extends Container {
61264
61282
  this.refreshTimer = void 0;
61265
61283
  }
61266
61284
  }
61267
- scheduleRefresh(sessionId) {
61268
- if (!this.options.refreshMetadata || this.destroyed || this.refreshAttempted.has(sessionId)) return;
61269
- this.pendingRefreshId = sessionId;
61285
+ scheduleVisibleRefreshes() {
61286
+ if (!this.options.refreshMetadata || this.destroyed) return;
61287
+ for (const item of this.selectList.getVisibleItems()) {
61288
+ if (this.refreshAttempted.has(item.value) || this.refreshQueued.has(item.value)) continue;
61289
+ this.refreshQueue.push(item.value);
61290
+ this.refreshQueued.add(item.value);
61291
+ }
61292
+ if (this.refreshQueue.length === 0) return;
61270
61293
  this.clearRefreshTimer();
61271
61294
  this.refreshTimer = setTimeout(() => {
61272
61295
  this.refreshTimer = void 0;
@@ -61276,9 +61299,9 @@ var SessionSelectorComponent = class extends Container {
61276
61299
  async runPendingRefresh() {
61277
61300
  if (this.destroyed || !this.options.refreshMetadata) return;
61278
61301
  if (this.refreshInFlight) return;
61279
- const sessionId = this.pendingRefreshId;
61280
- this.pendingRefreshId = void 0;
61302
+ const sessionId = this.refreshQueue.shift();
61281
61303
  if (!sessionId || this.refreshAttempted.has(sessionId)) return;
61304
+ this.refreshQueued.delete(sessionId);
61282
61305
  this.refreshAttempted.add(sessionId);
61283
61306
  this.refreshInFlight = true;
61284
61307
  try {
@@ -61289,7 +61312,7 @@ var SessionSelectorComponent = class extends Container {
61289
61312
  } catch {
61290
61313
  } finally {
61291
61314
  this.refreshInFlight = false;
61292
- if (this.pendingRefreshId && !this.destroyed) {
61315
+ if (this.refreshQueue.length > 0 && !this.destroyed) {
61293
61316
  void this.runPendingRefresh();
61294
61317
  }
61295
61318
  }
@@ -62383,7 +62406,7 @@ function renderExecutionWidgetLines(steps, activeTheme = theme) {
62383
62406
  }
62384
62407
 
62385
62408
  // src/components/tool-execution.ts
62386
- function formatSize(bytes) {
62409
+ function formatSize2(bytes) {
62387
62410
  if (bytes < 1024) return `${bytes}B`;
62388
62411
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
62389
62412
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
@@ -62513,7 +62536,7 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
62513
62536
  if (truncation.firstLineExceedsLimit) {
62514
62537
  text += "\n" + theme.fg(
62515
62538
  "warning",
62516
- `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`
62539
+ `[First line exceeds ${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`
62517
62540
  );
62518
62541
  } else if (truncation.truncatedBy === "lines") {
62519
62542
  text += "\n" + theme.fg(
@@ -62523,7 +62546,7 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
62523
62546
  } else {
62524
62547
  text += "\n" + theme.fg(
62525
62548
  "warning",
62526
- `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`
62549
+ `[Truncated: ${truncation.outputLines} lines shown (${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`
62527
62550
  );
62528
62551
  }
62529
62552
  }
@@ -62671,7 +62694,7 @@ ${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
62671
62694
  warnings.push(`${entryLimit} entries limit`);
62672
62695
  }
62673
62696
  if (truncation?.truncated) {
62674
- warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62697
+ warnings.push(`${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62675
62698
  }
62676
62699
  text += `
62677
62700
  ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
@@ -62709,7 +62732,7 @@ ${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
62709
62732
  warnings.push(`${resultLimit} results limit`);
62710
62733
  }
62711
62734
  if (truncation?.truncated) {
62712
- warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62735
+ warnings.push(`${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62713
62736
  }
62714
62737
  text += `
62715
62738
  ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
@@ -62752,7 +62775,7 @@ ${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
62752
62775
  warnings.push(`${matchLimit} matches limit`);
62753
62776
  }
62754
62777
  if (truncation?.truncated) {
62755
- warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62778
+ warnings.push(`${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
62756
62779
  }
62757
62780
  if (linesTruncated) {
62758
62781
  warnings.push("some lines truncated");
@@ -62792,7 +62815,7 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
62792
62815
  warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
62793
62816
  } else {
62794
62817
  warnings.push(
62795
- `Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`
62818
+ `Truncated: ${truncation.outputLines} lines shown (${formatSize2(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`
62796
62819
  );
62797
62820
  }
62798
62821
  }
@@ -64725,7 +64748,7 @@ function setupInteractiveEditorSubmitHandler(host) {
64725
64748
  const expanded = host.expandSkillCommand(skillText);
64726
64749
  if (expanded !== skillText) {
64727
64750
  if (host.submitLock) {
64728
- host.queueMessage(expanded, "steer");
64751
+ host.queueMessage(expanded, "followUp", { deliverWhileStreaming: false });
64729
64752
  return;
64730
64753
  }
64731
64754
  host.setSubmitLock(true);
@@ -64756,7 +64779,7 @@ function setupInteractiveEditorSubmitHandler(host) {
64756
64779
  if (text.startsWith("/tools/subagent")) {
64757
64780
  const args = text.slice("/tools/subagent".length).trim();
64758
64781
  if (host.submitLock) {
64759
- host.queueMessage(text, "steer");
64782
+ host.queueMessage(text, "followUp", { deliverWhileStreaming: false });
64760
64783
  return;
64761
64784
  }
64762
64785
  host.editor.setText("");
@@ -64775,7 +64798,7 @@ function setupInteractiveEditorSubmitHandler(host) {
64775
64798
  host.showStatus("Wait for the current response to finish before compacting");
64776
64799
  return;
64777
64800
  }
64778
- host.queueMessage(text, "steer");
64801
+ host.queueMessage(text, "followUp", { deliverWhileStreaming: false });
64779
64802
  return;
64780
64803
  }
64781
64804
  host.editor.setText("");
@@ -64805,6 +64828,11 @@ function setupInteractiveEditorSubmitHandler(host) {
64805
64828
  }
64806
64829
  return;
64807
64830
  }
64831
+ if (exactMatch?.isCategory && !exactMatch.handler) {
64832
+ host.showHierarchicalMenu(firstPartSegments);
64833
+ host.editor.setText("");
64834
+ return;
64835
+ }
64808
64836
  const pathStr = text.slice(1);
64809
64837
  const segments = pathStr.split("/").filter(Boolean);
64810
64838
  let node = null;
@@ -64826,7 +64854,7 @@ function setupInteractiveEditorSubmitHandler(host) {
64826
64854
  host.showStatus("Wait for the current response to finish before compacting");
64827
64855
  return;
64828
64856
  }
64829
- host.queueMessage(text, "steer");
64857
+ host.queueMessage(text, "followUp", { deliverWhileStreaming: false });
64830
64858
  return;
64831
64859
  }
64832
64860
  host.editor.setText("");
@@ -64867,7 +64895,7 @@ function setupInteractiveEditorSubmitHandler(host) {
64867
64895
  for (const [name, command] of ext.commands) {
64868
64896
  if (command.path?.join("/") === fullPath) {
64869
64897
  if (host.submitLock) {
64870
- host.queueMessage(text, "steer");
64898
+ host.queueMessage(text, "followUp", { deliverWhileStreaming: false });
64871
64899
  return;
64872
64900
  }
64873
64901
  host.editor.setText("");
@@ -64913,15 +64941,16 @@ function setupInteractiveEditorSubmitHandler(host) {
64913
64941
  }
64914
64942
  }
64915
64943
  if (host.mentionHandler?.hasPendingMentionWork()) {
64916
- host.queueMessage(text, "steer", {
64944
+ host.queueMessage(text, "followUp", {
64917
64945
  clearEditor: false,
64918
- statusMessage: "\u6587\u4EF6\u5904\u7406\u4E2D\uFF0C\u6D88\u606F\u5DF2\u6392\u961F\uFF0C\u6DFB\u52A0\u5B8C\u6210\u540E\u81EA\u52A8\u53D1\u9001"
64946
+ statusMessage: "Files are still processing. Message queued and will send when attachments are ready.",
64947
+ deliverWhileStreaming: false
64919
64948
  });
64920
64949
  host.agentSessionController?.requestQueueDispatch();
64921
64950
  return;
64922
64951
  }
64923
64952
  if (host.submitLock) {
64924
- host.queueMessage(text, "steer");
64953
+ host.queueMessage(text, "followUp", { deliverWhileStreaming: false });
64925
64954
  return;
64926
64955
  }
64927
64956
  host.setSubmitLock(true);
@@ -64951,9 +64980,10 @@ function setupInteractiveEditorSubmitHandler(host) {
64951
64980
  host.setSubmitLock(false);
64952
64981
  host.isProcessing = false;
64953
64982
  host.footer.setState({ status: "ready" });
64954
- host.queueMessage(text, "steer", {
64983
+ host.queueMessage(text, "followUp", {
64955
64984
  clearEditor: false,
64956
- statusMessage: `\u6587\u4EF6\u5904\u7406\u4E2D: ${processingFiles.join(", ")}\uFF0C\u5DF2\u6392\u961F\uFF0C\u5904\u7406\u5B8C\u6210\u540E\u81EA\u52A8\u53D1\u9001`
64985
+ statusMessage: `Files still processing: ${processingFiles.join(", ")}. Message queued and will send when attachments are ready.`,
64986
+ deliverWhileStreaming: false
64957
64987
  });
64958
64988
  host.agentSessionController?.requestQueueDispatch();
64959
64989
  return;
@@ -65193,7 +65223,7 @@ var FilePickerComponent = class extends Container {
65193
65223
  if (this.query) {
65194
65224
  this.addChild(new Text(theme.fg("dim", `@ ${this.query}`), 1, 0));
65195
65225
  } else {
65196
- this.addChild(new Text(theme.fg("dim", "@ \u9009\u62E9\u6587\u4EF6..."), 1, 0));
65226
+ this.addChild(new Text(theme.fg("dim", "@ Select a file..."), 1, 0));
65197
65227
  }
65198
65228
  this.addChild(new Text(theme.fg("border", "\u2500".repeat(40)), 1, 0));
65199
65229
  const maxOptions = 8;
@@ -65218,16 +65248,16 @@ var FilePickerComponent = class extends Container {
65218
65248
  new Text(
65219
65249
  theme.fg(
65220
65250
  "dim",
65221
- ` ${this.selectedIndex + 1}/${this.options.length} \xB7 \u663E\u793A ${this.scrollOffset + 1}-${visibleEnd}`
65251
+ ` ${this.selectedIndex + 1}/${this.options.length} \xB7 showing ${this.scrollOffset + 1}-${visibleEnd}`
65222
65252
  ),
65223
65253
  1,
65224
65254
  0
65225
65255
  )
65226
65256
  );
65227
65257
  }
65228
- this.addChild(new Text(theme.fg("dim", "\u2191\u2193 \u9009\u62E9 \xB7 \u2190 \u8FD4\u56DE / \u2192 \u8FDB\u5165 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88"), 1, 0));
65258
+ this.addChild(new Text(theme.fg("dim", "\u2191\u2193 Select \xB7 \u2190 Back / \u2192 Open \xB7 Enter Confirm \xB7 Esc Cancel"), 1, 0));
65229
65259
  } else {
65230
- this.addChild(new Text(theme.fg("dim", " \u65E0\u5339\u914D\u6587\u4EF6"), 1, 0));
65260
+ this.addChild(new Text(theme.fg("dim", " No matching files"), 1, 0));
65231
65261
  }
65232
65262
  }
65233
65263
  };
@@ -65260,11 +65290,11 @@ var FileCommands = class {
65260
65290
  purpose: parsed.purpose,
65261
65291
  onProgress: (progress, stage) => {
65262
65292
  const stageNames = {
65263
- analyzing: "\u5206\u6790\u4E2D",
65264
- preprocessing: "\u9884\u5904\u7406",
65265
- uploading: "\u4E0A\u4F20\u4E2D",
65266
- processing: "\u5904\u7406\u4E2D",
65267
- complete: "\u5B8C\u6210"
65293
+ analyzing: "Analyzing",
65294
+ preprocessing: "Preprocessing",
65295
+ uploading: "Uploading",
65296
+ processing: "Processing",
65297
+ complete: "Complete"
65268
65298
  };
65269
65299
  this.context.showStatus(`${stageNames[stage] || stage}... ${progress}%`);
65270
65300
  }
@@ -65331,11 +65361,11 @@ var FileCommands = class {
65331
65361
  optimize: parsed.options,
65332
65362
  onProgress: (progress, stage) => {
65333
65363
  const stageNames = {
65334
- analyzing: "\u5206\u6790\u89C6\u9891",
65335
- preprocessing: "\u9884\u5904\u7406",
65336
- uploading: "\u4E0A\u4F20\u4E2D",
65337
- processing: "\u5E73\u53F0\u5904\u7406\u4E2D",
65338
- complete: "\u5B8C\u6210"
65364
+ analyzing: "Analyzing video",
65365
+ preprocessing: "Preprocessing",
65366
+ uploading: "Uploading",
65367
+ processing: "Processing",
65368
+ complete: "Complete"
65339
65369
  };
65340
65370
  this.context.showStatus(`${stageNames[stage] || stage}... ${progress}%`);
65341
65371
  }
@@ -65890,7 +65920,7 @@ var MentionHandler = class {
65890
65920
  this.fileManager.ensureSessionTracking(option.fileId);
65891
65921
  const mention = this.formatMention(option.name, option.fileId);
65892
65922
  this.onInsertMention(mention, queryToken);
65893
- this.onStatus?.(`\u5DF2\u6DFB\u52A0\u6587\u4EF6 ${option.name}\uFF08\u5DF2\u4E0A\u4F20\u5230 ${this.fileManager.getPlatformDisplayName()}\uFF09`);
65923
+ this.onStatus?.(`Added ${option.name} (already uploaded to ${this.fileManager.getPlatformDisplayName()})`);
65894
65924
  } else if (option.type === "upload" && option.path) {
65895
65925
  this.pendingUploadCount += 1;
65896
65926
  const pendingMention = this.formatPendingMention(option.name);
@@ -65900,15 +65930,15 @@ var MentionHandler = class {
65900
65930
  if (option.cacheStatus === "uploaded") {
65901
65931
  this.pushPendingStatus(
65902
65932
  pendingStatusKey,
65903
- `\u51C6\u5907\u6DFB\u52A0 ${option.name}\uFF08\u5C06\u590D\u7528 ${this.fileManager.getPlatformDisplayName()} \u5DF2\u4E0A\u4F20\u6587\u4EF6\uFF09...`
65933
+ `Preparing ${option.name} (reusing upload from ${this.fileManager.getPlatformDisplayName()})...`
65904
65934
  );
65905
65935
  } else if (option.cacheStatus === "cached") {
65906
65936
  this.pushPendingStatus(
65907
65937
  pendingStatusKey,
65908
- `\u51C6\u5907\u6DFB\u52A0 ${option.name}\uFF08\u5C06\u590D\u7528\u672C\u5730\u7F13\u5B58\uFF09...`
65938
+ `Preparing ${option.name} (reusing local cache)...`
65909
65939
  );
65910
65940
  } else {
65911
- this.pushPendingStatus(pendingStatusKey, `\u51C6\u5907\u6DFB\u52A0 ${option.name}...`);
65941
+ this.pushPendingStatus(pendingStatusKey, `Preparing ${option.name}...`);
65912
65942
  }
65913
65943
  const mimeType = FileCache.getMimeType(option.path);
65914
65944
  const shouldStageLocally = !mimeType.startsWith("image/") && !mimeType.startsWith("video/");
@@ -65932,33 +65962,33 @@ var MentionHandler = class {
65932
65962
  const mention = this.formatMention(result.name, result.fileId);
65933
65963
  this.onInsertMention(mention, pendingMention);
65934
65964
  this.clearPendingStatus(pendingStatusKey);
65935
- this.onStatus?.(shouldStageLocally ? `\u5DF2\u6DFB\u52A0\u672C\u5730\u6587\u4EF6 ${result.name}` : `\u5DF2\u6DFB\u52A0\u6587\u4EF6 ${result.name}`);
65965
+ this.onStatus?.(shouldStageLocally ? `Added local file ${result.name}` : `Added ${result.name}`);
65936
65966
  } else {
65937
65967
  this.onInsertMention("", pendingMention);
65938
65968
  this.clearPendingStatus(pendingStatusKey);
65939
- this.onError?.("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5");
65969
+ this.onError?.("File upload failed. Please try again.");
65940
65970
  }
65941
65971
  } catch (err) {
65942
65972
  this.onInsertMention("", pendingMention);
65943
65973
  this.clearPendingStatus(pendingStatusKey);
65944
65974
  const errorMessage3 = err instanceof Error ? err.message : String(err);
65945
65975
  if (errorMessage3.includes("PLATFORM_NOT_SUPPORTED")) {
65946
- this.onError?.("\u5F53\u524D AI \u6A21\u578B\u4E0D\u652F\u6301\u6587\u4EF6\u4E0A\u4F20");
65976
+ this.onError?.("The current AI model does not support file uploads.");
65947
65977
  } else if (errorMessage3.includes("ENOENT")) {
65948
- this.onError?.("\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE");
65978
+ this.onError?.("File does not exist or cannot be accessed.");
65949
65979
  } else if (errorMessage3.includes("EACCES") || errorMessage3.includes("PERMISSION")) {
65950
- this.onError?.("\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u8BE5\u6587\u4EF6");
65980
+ this.onError?.("Permission denied while accessing the file.");
65951
65981
  } else if (errorMessage3.includes("network") || errorMessage3.includes("ETIMEDOUT") || errorMessage3.includes("ECONNREFUSED")) {
65952
- this.onError?.("\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5\u540E\u91CD\u8BD5");
65982
+ this.onError?.("Network error. Check the connection and try again.");
65953
65983
  } else {
65954
- this.onError?.(`\u4E0A\u4F20\u5931\u8D25: ${errorMessage3}`);
65984
+ this.onError?.(`Upload failed: ${errorMessage3}`);
65955
65985
  }
65956
65986
  } finally {
65957
65987
  this.clearPendingStatus(pendingStatusKey);
65958
65988
  this.pendingUploadCount = Math.max(0, this.pendingUploadCount - 1);
65959
65989
  }
65960
65990
  } else {
65961
- this.onError?.("\u65E0\u6548\u7684\u6587\u4EF6\u9009\u9879");
65991
+ this.onError?.("Invalid file option.");
65962
65992
  }
65963
65993
  this.browsingDirectory = void 0;
65964
65994
  this.onHidePicker();
@@ -66100,10 +66130,10 @@ var MentionHandler = class {
66100
66130
  const seenNames = /* @__PURE__ */ new Set();
66101
66131
  options.push({
66102
66132
  type: "browse",
66103
- name: "\u6D4F\u89C8\u6587\u4EF6\u7CFB\u7EDF...",
66133
+ name: "Browse filesystem...",
66104
66134
  path: process.cwd(),
66105
66135
  icon: "\u{1F4C2}",
66106
- meta: "\u8DF3\u51FA\u5F53\u524D\u76EE\u5F55\u9009\u62E9\u6587\u4EF6"
66136
+ meta: "Choose a file outside the current directory"
66107
66137
  });
66108
66138
  try {
66109
66139
  const sessionFiles = this.fileManager.getSessionFiles();
@@ -66111,7 +66141,7 @@ var MentionHandler = class {
66111
66141
  if (!query || file.name.toLowerCase().includes(query.toLowerCase())) {
66112
66142
  if (seenNames.has(file.name.toLowerCase())) continue;
66113
66143
  seenNames.add(file.name.toLowerCase());
66114
- const statusText = file.status === "ready" ? "\u5DF2\u4E0A\u4F20" : file.status === "uploading" ? "\u4E0A\u4F20\u4E2D" : file.status === "expired" ? "\u5DF2\u8FC7\u671F" : file.status;
66144
+ const statusText = file.status === "ready" ? "uploaded" : file.status === "uploading" ? "uploading" : file.status === "expired" ? "expired" : file.status;
66115
66145
  options.push({
66116
66146
  type: "cached",
66117
66147
  name: file.name,
@@ -66135,7 +66165,7 @@ var MentionHandler = class {
66135
66165
  path: file.path,
66136
66166
  icon: getFileTypeIcon(file.type),
66137
66167
  cacheStatus: file.cacheStatus,
66138
- meta: `${this.formatCacheMeta(file.cacheStatus)}\u5F53\u524D\u76EE\u5F55 \u2022 ${formatBytes(file.size)}`
66168
+ meta: `${this.formatCacheMeta(file.cacheStatus)}current directory \u2022 ${formatBytes(file.size)}`
66139
66169
  });
66140
66170
  }
66141
66171
  } catch (err) {
@@ -66158,7 +66188,7 @@ var MentionHandler = class {
66158
66188
  hash: file.hash,
66159
66189
  fileId,
66160
66190
  icon: getFileTypeIcon(file.type),
66161
- meta: `\u7F13\u5B58 \u2022 ${formatBytes(file.size)}`
66191
+ meta: `cache \u2022 ${formatBytes(file.size)}`
66162
66192
  });
66163
66193
  if (options.length >= 10) break;
66164
66194
  }
@@ -66179,7 +66209,7 @@ var MentionHandler = class {
66179
66209
  name,
66180
66210
  path: resolvedPath,
66181
66211
  icon: "\u2B06\uFE0F",
66182
- meta: `${formatBytes(stats.size)} \u2022 \u70B9\u51FB\u4E0A\u4F20`
66212
+ meta: `${formatBytes(stats.size)} \u2022 click to upload`
66183
66213
  });
66184
66214
  }
66185
66215
  }
@@ -66204,7 +66234,7 @@ var MentionHandler = class {
66204
66234
  name: "..",
66205
66235
  path: path26.dirname(currentDir),
66206
66236
  icon: "\u21A9",
66207
- meta: "\u8FD4\u56DE\u4E0A\u7EA7\u76EE\u5F55"
66237
+ meta: "Parent directory"
66208
66238
  });
66209
66239
  }
66210
66240
  for (const directory of entries.directories) {
@@ -66213,7 +66243,7 @@ var MentionHandler = class {
66213
66243
  name: directory.name,
66214
66244
  path: directory.path,
66215
66245
  icon: "\u{1F4C1}",
66216
- meta: "\u76EE\u5F55"
66246
+ meta: "Directory"
66217
66247
  });
66218
66248
  }
66219
66249
  for (const file of entries.files) {
@@ -66228,7 +66258,7 @@ var MentionHandler = class {
66228
66258
  }
66229
66259
  return {
66230
66260
  options,
66231
- queryLabel: `\u6D4F\u89C8 ${displayDir}${filter ? ` \xB7 ${filter}` : ""}`
66261
+ queryLabel: `Browse ${displayDir}${filter ? ` \xB7 ${filter}` : ""}`
66232
66262
  };
66233
66263
  }
66234
66264
  getBrowserDirectory(query = this.currentQuery) {
@@ -66245,24 +66275,24 @@ var MentionHandler = class {
66245
66275
  const normalizedPlatform = normalizeFileManagerPlatform(platform2);
66246
66276
  const fileInfo = this.findFileByFileId(fileId);
66247
66277
  if (!fileInfo) {
66248
- return { reason: "\u6587\u4EF6\u4E0D\u53EF\u7528" };
66278
+ return { reason: "File unavailable" };
66249
66279
  }
66250
66280
  if (fileInfo.platform === "local") {
66251
- return { fileInfo, reason: "\u4EC5\u672C\u5730\u53EF\u590D\u7528" };
66281
+ return { fileInfo, reason: "Reusable locally only" };
66252
66282
  }
66253
66283
  if (fileInfo.platform !== normalizedPlatform) {
66254
- return { fileInfo, reason: "\u5F53\u524D\u5E73\u53F0\u4E0D\u53EF\u590D\u7528" };
66284
+ return { fileInfo, reason: "Not reusable on the current platform" };
66255
66285
  }
66256
66286
  const fileStatus = await this.fileManager.getFileStatus(fileId);
66257
66287
  if (!fileStatus) {
66258
- return { fileInfo, reason: "\u6587\u4EF6\u4E0D\u53EF\u7528" };
66288
+ return { fileInfo, reason: "File unavailable" };
66259
66289
  }
66260
66290
  if (fileStatus.status === "active" || fileStatus.status === "ready") {
66261
66291
  return { fileInfo, fileId, status: "ready", reason: "ok" };
66262
66292
  }
66263
66293
  if (fileStatus.status === "processing" || fileStatus.status === "uploading") {
66264
66294
  if (fileInfo.mimeType.startsWith("video/")) {
66265
- return { fileInfo, fileId, status: "uploading", reason: "\u89C6\u9891\u5904\u7406\u4E2D" };
66295
+ return { fileInfo, fileId, status: "uploading", reason: "Video is still processing" };
66266
66296
  }
66267
66297
  return { fileInfo, fileId, status: "ready", reason: "ok" };
66268
66298
  }
@@ -66271,12 +66301,12 @@ var MentionHandler = class {
66271
66301
  if (refreshed.success && refreshed.fileId) {
66272
66302
  return { fileInfo, fileId: refreshed.fileId, status: "ready", reason: "ok" };
66273
66303
  }
66274
- return { fileInfo, reason: "\u6587\u4EF6\u5DF2\u8FC7\u671F" };
66304
+ return { fileInfo, reason: "File expired" };
66275
66305
  }
66276
66306
  if (fileStatus.unsupportedPlatform) {
66277
- return { fileInfo, reason: "\u5F53\u524D\u5E73\u53F0\u4E0D\u53EF\u590D\u7528" };
66307
+ return { fileInfo, reason: "Not reusable on the current platform" };
66278
66308
  }
66279
- return { fileInfo, reason: "\u6587\u4EF6\u4E0D\u53EF\u7528" };
66309
+ return { fileInfo, reason: "File unavailable" };
66280
66310
  }
66281
66311
  formatMention(name, fileId) {
66282
66312
  return `@[${name}](file:${fileId}) `;
@@ -66286,20 +66316,20 @@ var MentionHandler = class {
66286
66316
  }
66287
66317
  formatUploadProgress(name, progress, stage) {
66288
66318
  const stageNames = {
66289
- analyzing: "\u5206\u6790\u4E2D",
66290
- preprocessing: "\u9884\u5904\u7406\u4E2D",
66291
- uploading: "\u4E0A\u4F20\u4E2D",
66292
- processing: "\u5E73\u53F0\u5904\u7406\u4E2D",
66293
- complete: "\u5B8C\u6210"
66319
+ analyzing: "Analyzing",
66320
+ preprocessing: "Preprocessing",
66321
+ uploading: "Uploading",
66322
+ processing: "Processing",
66323
+ complete: "Complete"
66294
66324
  };
66295
66325
  return `${stageNames[stage]} ${name}... ${Math.max(0, Math.min(100, Math.round(progress)))}%`;
66296
66326
  }
66297
66327
  formatCacheMeta(cacheStatus) {
66298
66328
  if (cacheStatus === "uploaded") {
66299
- return `\u66FE\u4E0A\u4F20\u5230${this.fileManager.getPlatformDisplayName()} \u2022 `;
66329
+ return `uploaded to ${this.fileManager.getPlatformDisplayName()} \u2022 `;
66300
66330
  }
66301
66331
  if (cacheStatus === "cached") {
66302
- return "\u4EC5\u672C\u5730\u53EF\u590D\u7528 \u2022 ";
66332
+ return "local cache only \u2022 ";
66303
66333
  }
66304
66334
  return "";
66305
66335
  }
@@ -66763,7 +66793,8 @@ function queueMessage(host, text, mode, options = {}) {
66763
66793
  streamingBehavior: mode,
66764
66794
  displayText: text,
66765
66795
  dedupeKey: options.dedupeKey,
66766
- clearEditor
66796
+ clearEditor,
66797
+ deliverWhileStreaming: options.deliverWhileStreaming ?? mode === "steer"
66767
66798
  }
66768
66799
  ).catch((error) => {
66769
66800
  host.showError(`Queue error: ${error instanceof Error ? error.message : String(error)}`);
@@ -67408,7 +67439,7 @@ function recoverFromInvalidFileReferenceError(host, errorMessage3) {
67408
67439
  const fileId = url.slice("ms://".length);
67409
67440
  if (!invalidFileIds.has(fileId)) return [block];
67410
67441
  messageChanged = true;
67411
- return [{ type: "text", text: " [\u6587\u4EF6\u5F15\u7528\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u6587\u4EF6] " }];
67442
+ return [{ type: "text", text: " [File reference expired. Please attach the file again.] " }];
67412
67443
  });
67413
67444
  if (!messageChanged) return message;
67414
67445
  changed = true;
@@ -67416,7 +67447,7 @@ function recoverFromInvalidFileReferenceError(host, errorMessage3) {
67416
67447
  });
67417
67448
  if (!changed) return;
67418
67449
  host.replaceAgentMessagesAndMarkSynced(sanitizedMessages, { updateSession: true });
67419
- host.showStatus("\u68C0\u6D4B\u5230\u5931\u6548\u6587\u4EF6\u5F15\u7528\uFF0C\u5DF2\u4ECE\u5F53\u524D\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u79FB\u9664\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u6587\u4EF6");
67450
+ host.showStatus("Removed expired file references from this session context. Please attach the file again.");
67420
67451
  }
67421
67452
 
67422
67453
  // src/components/hierarchical-selector.ts
@@ -68198,6 +68229,80 @@ function buildDirectShellCommand(command) {
68198
68229
  }
68199
68230
  return { file: "bash", args: ["-lc", command], prompt: "$" };
68200
68231
  }
68232
+ var DIRECT_OUTPUT_MAX_LINES = 400;
68233
+ var DIRECT_OUTPUT_MAX_BYTES = 16 * 1024;
68234
+ var DIRECT_CAPTURE_PREFIX_BYTES = 512 * 1024;
68235
+ var DIRECT_CAPTURE_TAIL_BYTES = 512 * 1024;
68236
+ function takeUtf8Prefix(text, maxBytes) {
68237
+ const bytes = Buffer.from(text, "utf8");
68238
+ if (bytes.length <= maxBytes) return text;
68239
+ return bytes.subarray(0, maxBytes).toString("utf8").replace(/\uFFFD+$/g, "");
68240
+ }
68241
+ function takeUtf8Suffix(text, maxBytes) {
68242
+ const bytes = Buffer.from(text, "utf8");
68243
+ if (bytes.length <= maxBytes) return text;
68244
+ return bytes.subarray(Math.max(0, bytes.length - maxBytes)).toString("utf8").replace(/^\uFFFD+/g, "");
68245
+ }
68246
+ var DirectBashOutputCollector = class {
68247
+ prefix = "";
68248
+ tail = "";
68249
+ totalBytes = 0;
68250
+ overflowed = false;
68251
+ append(text) {
68252
+ if (!text) return;
68253
+ const bytes = Buffer.byteLength(text, "utf8");
68254
+ this.totalBytes += bytes;
68255
+ if (!this.overflowed) {
68256
+ const next = this.prefix + text;
68257
+ if (Buffer.byteLength(next, "utf8") <= DIRECT_CAPTURE_PREFIX_BYTES + DIRECT_CAPTURE_TAIL_BYTES) {
68258
+ this.prefix = next;
68259
+ return;
68260
+ }
68261
+ this.overflowed = true;
68262
+ this.prefix = takeUtf8Prefix(next, DIRECT_CAPTURE_PREFIX_BYTES);
68263
+ this.tail = takeUtf8Suffix(next, DIRECT_CAPTURE_TAIL_BYTES);
68264
+ return;
68265
+ }
68266
+ this.tail = takeUtf8Suffix(this.tail + text, DIRECT_CAPTURE_TAIL_BYTES);
68267
+ }
68268
+ format() {
68269
+ if (this.totalBytes === 0) {
68270
+ return {
68271
+ text: "[command completed with no output]",
68272
+ empty: true,
68273
+ truncated: false,
68274
+ totalBytes: 0,
68275
+ totalLines: 0
68276
+ };
68277
+ }
68278
+ const materialized = this.overflowed ? `${this.prefix}
68279
+ ... [direct bash capture omitted ${formatSize(Math.max(0, this.totalBytes - Buffer.byteLength(this.prefix, "utf8") - Buffer.byteLength(this.tail, "utf8")))} from the middle] ...
68280
+ ${this.tail}` : this.prefix;
68281
+ const truncated = truncateHeadTail(materialized, {
68282
+ maxLines: DIRECT_OUTPUT_MAX_LINES,
68283
+ maxBytes: DIRECT_OUTPUT_MAX_BYTES
68284
+ });
68285
+ const suffix = truncated.truncated ? `
68286
+
68287
+ [direct bash output truncated: showing ${truncated.outputLines}/${truncated.totalLines} lines, ${formatSize(truncated.outputBytes)}/${formatSize(this.totalBytes)}]` : "";
68288
+ return {
68289
+ text: `${truncated.content}${suffix}`,
68290
+ empty: false,
68291
+ truncated: truncated.truncated || this.overflowed,
68292
+ totalBytes: this.totalBytes,
68293
+ totalLines: truncated.totalLines
68294
+ };
68295
+ }
68296
+ };
68297
+ function renderOutputText(outputContainer, text, color = "dim") {
68298
+ const lines = text.split("\n");
68299
+ for (let i = 0; i < lines.length; i += 1) {
68300
+ const line = lines[i];
68301
+ if (line || i < lines.length - 1) {
68302
+ outputContainer.addChild(new Text(theme.fg(color, line), 1, 0));
68303
+ }
68304
+ }
68305
+ }
68201
68306
  async function handleDirectBash(host, command) {
68202
68307
  host.chatContainer.addChild(new Spacer(1));
68203
68308
  const shellCommand = buildDirectShellCommand(command);
@@ -68212,31 +68317,20 @@ async function handleDirectBash(host, command) {
68212
68317
  cwd: process.cwd(),
68213
68318
  env: process.env
68214
68319
  });
68320
+ const output = new DirectBashOutputCollector();
68215
68321
  child.stdout.on("data", (data) => {
68216
- const text = data.toString();
68217
- const lines = text.split("\n");
68218
- for (const line of lines) {
68219
- if (line || lines.indexOf(line) < lines.length - 1) {
68220
- outputContainer.addChild(new Text(theme.fg("dim", line), 1, 0));
68221
- }
68222
- }
68223
- host.ui.requestRender();
68322
+ output.append(data.toString());
68224
68323
  });
68225
68324
  child.stderr.on("data", (data) => {
68226
- const text = data.toString();
68227
- const lines = text.split("\n");
68228
- for (const line of lines) {
68229
- if (line || lines.indexOf(line) < lines.length - 1) {
68230
- outputContainer.addChild(new Text(theme.fg("error", line), 1, 0));
68231
- }
68232
- }
68233
- host.ui.requestRender();
68325
+ output.append(data.toString());
68234
68326
  });
68235
68327
  return new Promise((resolve5) => {
68236
68328
  let settled = false;
68237
68329
  const finish = (code) => {
68238
68330
  if (settled) return;
68239
68331
  settled = true;
68332
+ const formatted = output.format();
68333
+ renderOutputText(outputContainer, formatted.text, code === 0 ? "dim" : "error");
68240
68334
  if (code !== 0) {
68241
68335
  outputContainer.addChild(new Spacer(1));
68242
68336
  outputContainer.addChild(new Text(theme.fg("error", `[exit ${code ?? "spawn error"}]`), 1, 0));
@@ -68246,7 +68340,7 @@ async function handleDirectBash(host, command) {
68246
68340
  resolve5();
68247
68341
  };
68248
68342
  child.on("error", (error) => {
68249
- outputContainer.addChild(new Text(theme.fg("error", error.message), 1, 0));
68343
+ output.append(error.message);
68250
68344
  finish(null);
68251
68345
  });
68252
68346
  child.on("close", (code) => {
@@ -69094,6 +69188,7 @@ var InteractiveMode = class {
69094
69188
  },
69095
69189
  apiKey: this.options.apiKey,
69096
69190
  sessionId: activeSession?.id,
69191
+ streamFn: this.options.streamFn,
69097
69192
  transformContext: createRuntimeModeTransformContext({
69098
69193
  getState: () => this.getRuntimeModeState(),
69099
69194
  consumeTransition: () => this.consumeRuntimeModeTransition(),
@@ -71075,11 +71170,8 @@ async function runWithJsonEventsConsoleIsolation(fn) {
71075
71170
  }
71076
71171
  }
71077
71172
  async function createCliTestStreamFnFromEnv() {
71078
- if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) {
71079
- return void 0;
71080
- }
71081
- const { createTestStreamFnFromSequenceEnv } = await import("./chunks/test-stream-ZNGAUUVH.js");
71082
- return createTestStreamFnFromSequenceEnv();
71173
+ if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
71174
+ return (await import("./chunks/test-stream-A7JSM2UM.js")).createTestStreamFnFromSequenceEnv();
71083
71175
  }
71084
71176
  async function startChat(initialPrompt, testCommand) {
71085
71177
  const rawOutput = process.argv.includes("--raw-output");
@@ -71150,7 +71242,9 @@ async function startChat(initialPrompt, testCommand) {
71150
71242
  process.env.PIE_TUI_ACTIVE = "1";
71151
71243
  const runtimeLogger = initializeCliRuntimeLogger(runtime.sessionId, { mode: "interactive_tui" });
71152
71244
  const restoreConsoleInterception = installInteractiveConsoleInterception(runtimeLogger);
71153
- const interactive = new InteractiveMode(runtime.createInteractiveOptions());
71245
+ const interactiveOptions = runtime.createInteractiveOptions();
71246
+ interactiveOptions.streamFn = await createCliTestStreamFnFromEnv();
71247
+ const interactive = new InteractiveMode(interactiveOptions);
71154
71248
  try {
71155
71249
  await interactive.init();
71156
71250
  if (runtime.initialModel.unconfigured && runtime.initialModel.warning) {