snow-ai 0.6.19 → 0.6.20

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/bundle/cli.mjs CHANGED
@@ -46862,14 +46862,18 @@ __export(vulnerabilityHuntingModeSystemPrompt_exports, {
46862
46862
  });
46863
46863
  function getAnalysisToolsSection(hasCodebase) {
46864
46864
  if (hasCodebase) {
46865
- return `- \`codebase-search\` - PRIMARY tool for semantic search (find security-related patterns)
46865
+ return `**CRITICAL: Use code search tools to find code. Only use terminal-execute to run build/test commands, NEVER for searching code.**
46866
+
46867
+ - \`codebase-search\` - PRIMARY tool for semantic search (find security-related patterns)
46866
46868
  - \`filesystem-read\` - Read code to analyze security controls
46867
46869
  - \`ace-find_definition\` - Locate function definitions
46868
46870
  - \`ace-find_references\` - Track data flow and usage patterns
46869
46871
  - \`ace-file_outline\` - Understand file structure
46870
46872
  - \`ace-text_search\` - Find security keywords (TODO, FIXME, password, secret, etc.)`;
46871
46873
  } else {
46872
- return `- \`ace-semantic_search\` - Find relevant code by security-related patterns
46874
+ return `**CRITICAL: Use code search tools to find code. Only use terminal-execute to run build/test commands, NEVER for searching code.**
46875
+
46876
+ - \`ace-semantic_search\` - Find relevant code by security-related patterns
46873
46877
  - \`ace-find_definition\` - Locate where symbols are defined
46874
46878
  - \`ace-find_references\` - Track data flow and usage patterns
46875
46879
  - \`ace-file_outline\` - Understand file structure
@@ -47466,14 +47470,18 @@ __export(planModeSystemPrompt_exports, {
47466
47470
  });
47467
47471
  function getAnalysisToolsSection2(hasCodebase) {
47468
47472
  if (hasCodebase) {
47469
- return `- \`codebase-search\` - PRIMARY tool for code exploration (semantic search across entire codebase)
47473
+ return `**CRITICAL: Use code search tools to find code. Only use terminal-execute to run build/test commands, NEVER for searching code.**
47474
+
47475
+ - \`codebase-search\` - PRIMARY tool for code exploration (semantic search across entire codebase)
47470
47476
  - \`filesystem-read\` - Read current code to understand implementation
47471
47477
  - \`ace-find_definition\` - Locate exact symbol definitions (when you know the symbol name)
47472
47478
  - \`ace-find_references\` - See where code is used throughout the project
47473
47479
  - \`ace-file_outline\` - Get structure overview of specific files
47474
47480
  - \`ide-get_diagnostics\` - Check for existing errors/warnings that might affect the plan`;
47475
47481
  } else {
47476
- return `- \`ace-semantic_search\` - Find relevant code by semantic meaning
47482
+ return `**CRITICAL: Use code search tools to find code. Only use terminal-execute to run build/test commands, NEVER for searching code.**
47483
+
47484
+ - \`ace-semantic_search\` - Find relevant code by semantic meaning
47477
47485
  - \`ace-find_definition\` - Locate where symbols are defined
47478
47486
  - \`ace-find_references\` - See where code is used throughout the project
47479
47487
  - \`ace-file_outline\` - Get structure overview of specific files
@@ -47971,6 +47979,8 @@ function getCodeSearchSection(hasCodebase) {
47971
47979
  if (hasCodebase) {
47972
47980
  return `**Code Search Strategy:**
47973
47981
 
47982
+ **CRITICAL: Use code search tools to find code. Only use terminal-execute to run build/test commands, NEVER for searching code.**
47983
+
47974
47984
  **PRIMARY TOOL - \`codebase-search\` (Semantic Search):**
47975
47985
  - **USE THIS FIRST for 90% of code exploration tasks**
47976
47986
  - Query by MEANING and intent: "authentication logic", "error handling patterns", "validation flow"
@@ -48061,6 +48071,10 @@ PLACEHOLDER_FOR_WORKFLOW_SECTION
48061
48071
  - Reduces cognitive load - AI doesn't need to remember everything
48062
48072
  - Enables recovery if conversation is interrupted
48063
48073
 
48074
+ **Formatting rule:**
48075
+ - TODO item content SHOULD start with a numeric prefix to explicitly mark execution order, e.g. "1. ...", "2. ...", "3. ..."
48076
+ - In continuous conversations, BEFORE calling todo-add, run todo-get (paired with an action tool) to inspect existing items and choose the next available sequence number (typically max(existingPrefix)+1). This prevents duplicate numbering across multiple turns.
48077
+
48064
48078
  **WHEN TO USE (Default for most work):**
48065
48079
  - ANY task touching 2+ files
48066
48080
  - Features, refactoring, bug fixes
@@ -48073,28 +48087,29 @@ PLACEHOLDER_FOR_WORKFLOW_SECTION
48073
48087
  - Simple queries that don't change code
48074
48088
 
48075
48089
  **STANDARD WORKFLOW - Always Plan First:**
48076
- 1. **Receive task** \u2192 Immediately create TODO with todo-add (batch add all steps at once)
48077
- 2. **Execute** \u2192 Update progress with todo-update as you complete each step
48078
- 3. **Complete** \u2192 Clean up with todo-delete for obsolete items
48090
+ 1. **Receive task** \u2192 Run todo-get (paired with an action tool) to see current list and determine the next sequence number
48091
+ 2. **Plan** \u2192 Create TODO with todo-add (batch add all steps at once, using the next available sequence number)
48092
+ 3. **Execute** \u2192 Update progress with todo-update as each step is completed
48093
+ 4. **Complete** \u2192 Clean up obsolete, incorrect, or superseded items with todo-delete
48079
48094
 
48080
48095
  **PARALLEL CALLS RULE:**
48081
48096
  ALWAYS pair TODO tools with action tools in same call:
48082
- - CORRECT: todo-get + filesystem-read | todo-update + filesystem-edit | todo-add + filesystem-read
48097
+ - CORRECT: todo-get + filesystem-read | todo-get + filesystem-edit | todo-update + filesystem-edit
48083
48098
  - WRONG: Call todo-get alone, wait for result, then act
48084
48099
 
48085
48100
  **Available tools:**
48086
48101
  - **todo-add**: Create task list (supports batch: pass string array to add multiple at once)
48087
- - **todo-get**: Check current progress (always pair with other tools)
48088
- - **todo-update**: Mark tasks completed as you go
48102
+ - **todo-get**: Get the current TODO list (always pair with other tools)
48103
+ - **todo-update**: Update TODO status/content
48089
48104
  - **todo-delete**: Remove obsolete/redundant items
48090
48105
 
48091
48106
  **Examples:**
48092
48107
  \`\`\`
48093
48108
  User: "Fix authentication bug and add logging"
48094
- AI: todo-add(content=["Fix auth bug in auth.ts", "Add logging to login flow", "Test login with new logs"]) + filesystem-read("auth.ts")
48109
+ AI: todo-add(content=["1. Fix auth bug in auth.ts", "2. Add logging to login flow", "3. Test login with new logs"]) + filesystem-read("auth.ts")
48095
48110
 
48096
48111
  User: "Refactor utils module"
48097
- AI: todo-add(content=["Read utils module structure", "Identify refactor targets", "Extract common functions", "Update imports", "Run tests"]) + filesystem-read("utils/")
48112
+ AI: todo-add(content=["1. Read utils module structure", "2. Identify refactor targets", "3. Extract common functions", "4. Update imports", "5. Run tests"]) + filesystem-read("utils/")
48098
48113
  \`\`\`
48099
48114
 
48100
48115
 
@@ -81712,6 +81727,10 @@ var init_en = __esm({
81712
81727
  // Pending
81713
81728
  pendingMessageWaiting: "Pending message waiting...",
81714
81729
  pendingToolConfirmation: "Tool confirmation required",
81730
+ pendingMessagesTitle: "Pending Messages",
81731
+ pendingMessagesFooter: "Will be sent after tool execution completes",
81732
+ pendingMessagesEscHint: "Press ESC to restore to input (does not interrupt the current process)",
81733
+ pendingMessagesImagesAttached: "{count} images attached",
81715
81734
  // Press keys hints
81716
81735
  pressEscToClose: "Press ESC to close",
81717
81736
  pressEnterToToggle: "Press Enter to toggle",
@@ -82927,6 +82946,10 @@ var init_zh = __esm({
82927
82946
  // Pending
82928
82947
  pendingMessageWaiting: "\u5F85\u5904\u7406\u6D88\u606F\u7B49\u5F85\u4E2D...",
82929
82948
  pendingToolConfirmation: "\u9700\u8981\u5DE5\u5177\u786E\u8BA4",
82949
+ pendingMessagesTitle: "\u5F85\u5904\u7406\u6D88\u606F",
82950
+ pendingMessagesFooter: "\u5DE5\u5177\u6267\u884C\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u53D1\u9001",
82951
+ pendingMessagesEscHint: "\u6309 ESC \u53EF\u64A4\u56DE\u5230\u8F93\u5165\u6846\uFF0C\u4E0D\u4F1A\u6253\u65AD\u5F53\u524D\u6D41\u7A0B",
82952
+ pendingMessagesImagesAttached: "\u5DF2\u9644\u5E26 {count} \u5F20\u56FE\u7247",
82930
82953
  // Press keys hints
82931
82954
  pressEscToClose: "\u6309 ESC \u5173\u95ED",
82932
82955
  pressEnterToToggle: "\u6309 Enter \u5207\u6362",
@@ -84142,6 +84165,10 @@ var init_zh_TW = __esm({
84142
84165
  // Pending
84143
84166
  pendingMessageWaiting: "\u5F85\u8655\u7406\u8A0A\u606F\u7B49\u5F85\u4E2D...",
84144
84167
  pendingToolConfirmation: "\u9700\u8981\u5DE5\u5177\u78BA\u8A8D",
84168
+ pendingMessagesTitle: "\u5F85\u8655\u7406\u8A0A\u606F",
84169
+ pendingMessagesFooter: "\u5DE5\u5177\u57F7\u884C\u5B8C\u6210\u5F8C\u5C07\u81EA\u52D5\u50B3\u9001",
84170
+ pendingMessagesEscHint: "\u6309 ESC \u53EF\u64A4\u56DE\u5230\u8F38\u5165\u6846\uFF0C\u4E0D\u6703\u4E2D\u65B7\u76EE\u524D\u6D41\u7A0B",
84171
+ pendingMessagesImagesAttached: "\u5DF2\u9644\u5E36 {count} \u5F35\u5716\u7247",
84145
84172
  // Press keys hints
84146
84173
  pressEscToClose: "\u6309 ESC \u95DC\u9589",
84147
84174
  pressEnterToToggle: "\u6309 Enter \u5207\u63DB",
@@ -365697,7 +365724,7 @@ var init_aceCodeSearch = __esm({
365697
365724
  /**
365698
365725
  * Strategy 1: Use git grep for fast searching in Git repositories
365699
365726
  */
365700
- async gitGrepSearch(pattern, fileGlob, maxResults = 100, isRegex = false) {
365727
+ async gitGrepSearch(pattern, fileGlob, maxResults = 100, isRegex = true) {
365701
365728
  return new Promise((resolve12, reject2) => {
365702
365729
  const args2 = ["grep", "--untracked", "-n", "--ignore-case"];
365703
365730
  if (isRegex) {
@@ -365819,7 +365846,7 @@ var init_aceCodeSearch = __esm({
365819
365846
  /**
365820
365847
  * Strategy 3: Pure JavaScript fallback search
365821
365848
  */
365822
- async jsTextSearch(pattern, fileGlob, isRegex = false, maxResults = 100) {
365849
+ async jsTextSearch(pattern, fileGlob, isRegex = true, maxResults = 100) {
365823
365850
  const results = [];
365824
365851
  await this.loadExclusionPatterns();
365825
365852
  let searchRegex;
@@ -365929,7 +365956,7 @@ var init_aceCodeSearch = __esm({
365929
365956
  * Strategy 3: JavaScript fallback (slower, but always works)
365930
365957
  * Searches for text patterns across files with glob filtering
365931
365958
  */
365932
- async textSearch(pattern, fileGlob, isRegex = false, maxResults = 100) {
365959
+ async textSearch(pattern, fileGlob, isRegex = true, maxResults = 100) {
365933
365960
  const [isGitRepo, gitAvailable, rgAvailable, grepAvailable] = await Promise.all([
365934
365961
  this.isGitRepository(),
365935
365962
  this.isCommandAvailableCached("git"),
@@ -366243,7 +366270,7 @@ var init_aceCodeSearch = __esm({
366243
366270
  properties: {
366244
366271
  pattern: {
366245
366272
  type: "string",
366246
- description: 'Text pattern or regex to search for (e.g., "TODO:", "import.*from", "throw new Error")'
366273
+ description: 'Text pattern or regex to search for. Examples: "TODO:" (literal), "import.*from" (regex), "tool_call|toolCall" (regex with OR). By default, pattern is treated as regex. Set isRegex to false for literal string search.'
366247
366274
  },
366248
366275
  fileGlob: {
366249
366276
  type: "string",
@@ -366251,8 +366278,8 @@ var init_aceCodeSearch = __esm({
366251
366278
  },
366252
366279
  isRegex: {
366253
366280
  type: "boolean",
366254
- description: "Whether the pattern is a regular expression (default: false for literal text search)",
366255
- default: false
366281
+ description: "Whether to force regex mode. If not specified, the tool defaults to regex mode. Set to false to use literal string search.",
366282
+ default: true
366256
366283
  },
366257
366284
  maxResults: {
366258
366285
  type: "number",
@@ -453400,7 +453427,7 @@ var init_HybridCodeSearchService = __esm({
453400
453427
  };
453401
453428
  return languageMap[ext] || "unknown";
453402
453429
  }
453403
- async textSearch(pattern, fileGlob, isRegex = false, maxResults = 100) {
453430
+ async textSearch(pattern, fileGlob, isRegex = true, maxResults = 100) {
453404
453431
  return this.regexSearch.textSearch(pattern, fileGlob, isRegex, maxResults);
453405
453432
  }
453406
453433
  async semanticSearch(query, searchType = "all", language, symbolType2, maxResults = 50) {
@@ -547842,7 +547869,7 @@ function MarkdownRenderer({ content }) {
547842
547869
  return renderFallback(content);
547843
547870
  }
547844
547871
  }
547845
- var import_react75, import_markdown_it_terminal, import_cli_highlight2, md, HEADING_STYLE, FIRST_HEADING_STYLE, originalBulletListOpen, originalBulletListClose, originalOrderedListOpen, originalOrderedListClose, originalListItemClose, originalFenceRule, ANSI_PATTERN;
547872
+ var import_react75, import_markdown_it_terminal, import_cli_highlight2, md, HEADING_STYLE, FIRST_HEADING_STYLE, originalParagraphClose, originalBulletListOpen, originalBulletListClose, originalOrderedListOpen, originalOrderedListClose, originalListItemClose, originalFenceRule, ANSI_PATTERN;
547846
547873
  var init_MarkdownRenderer = __esm({
547847
547874
  async "dist/ui/components/common/MarkdownRenderer.js"() {
547848
547875
  "use strict";
@@ -547872,16 +547899,18 @@ var init_MarkdownRenderer = __esm({
547872
547899
  open: "\x1B[35m\x1B[4m\x1B[1m",
547873
547900
  close: "\x1B[22m\x1B[24m\x1B[39m"
547874
547901
  };
547902
+ originalParagraphClose = md.renderer.rules["paragraph_close"];
547875
547903
  md.renderer.rules["paragraph_open"] = (tokens2, idx2) => {
547876
547904
  var _a21;
547877
547905
  return ((_a21 = tokens2[idx2]) == null ? void 0 : _a21.hidden) ? "" : "";
547878
547906
  };
547879
- md.renderer.rules["paragraph_close"] = (tokens2, idx2) => {
547907
+ md.renderer.rules["paragraph_close"] = (tokens2, idx2, options3, env5, self2) => {
547880
547908
  var _a21, _b14, _c6;
547881
547909
  if ((_a21 = tokens2[idx2]) == null ? void 0 : _a21.hidden) {
547882
547910
  return ((_c6 = (_b14 = tokens2[idx2 + 1]) == null ? void 0 : _b14.type) == null ? void 0 : _c6.endsWith("close")) ? "" : "\n";
547883
547911
  }
547884
- return "\n";
547912
+ const original = (originalParagraphClose == null ? void 0 : originalParagraphClose(tokens2, idx2, options3, env5, self2)) || "\n";
547913
+ return original.replace(/\n\n$/, "\n");
547885
547914
  };
547886
547915
  md.renderer.rules["heading_open"] = (tokens2, idx2) => {
547887
547916
  var _a21, _b14;
@@ -547992,13 +548021,16 @@ ${simpleLatexToUnicode(latex)}
547992
548021
  });
547993
548022
 
547994
548023
  // dist/ui/components/tools/ToolResultPreview.js
548024
+ function removeAnsiCodes(text3) {
548025
+ return text3.replace(/\x1b\[[0-9;]*m/g, "");
548026
+ }
547995
548027
  function ToolResultPreview({ toolName, result: result2, maxLines = 5, isSubAgentInternal = false }) {
547996
548028
  try {
547997
548029
  const data = JSON.parse(result2);
547998
548030
  if (toolName.startsWith("subagent-")) {
547999
548031
  return renderSubAgentPreview(data, maxLines);
548000
548032
  } else if (toolName === "terminal-execute") {
548001
- return renderTerminalExecutePreview(data, isSubAgentInternal);
548033
+ return renderTerminalExecutePreview(data, maxLines, isSubAgentInternal);
548002
548034
  } else if (toolName === "filesystem-read") {
548003
548035
  return renderReadPreview(data, isSubAgentInternal);
548004
548036
  } else if (toolName === "filesystem-create") {
@@ -548013,6 +548045,8 @@ function ToolResultPreview({ toolName, result: result2, maxLines = 5, isSubAgent
548013
548045
  return renderACEPreview(toolName, data, maxLines);
548014
548046
  } else if (toolName.startsWith("todo-")) {
548015
548047
  return renderTodoPreview(toolName, data, maxLines);
548048
+ } else if (toolName === "ide-get_diagnostics") {
548049
+ return renderIdeDiagnosticsPreview(data);
548016
548050
  } else if (toolName === "skill-execute") {
548017
548051
  return null;
548018
548052
  } else {
@@ -548040,21 +548074,61 @@ function renderSubAgentPreview(data, _maxLines) {
548040
548074
  )
548041
548075
  );
548042
548076
  }
548043
- function renderTerminalExecutePreview(data, isSubAgentInternal) {
548077
+ function renderTerminalExecutePreview(data, maxLines, isSubAgentInternal) {
548044
548078
  const hasError = data.exitCode !== 0;
548045
548079
  const hasStdout = data.stdout && data.stdout.trim();
548046
548080
  const hasStderr = data.stderr && data.stderr.trim();
548081
+ const sliceLines = (text3, limit) => {
548082
+ if (!text3)
548083
+ return { lines: [], truncated: false };
548084
+ const lines = text3.split("\n");
548085
+ if (lines.length <= limit)
548086
+ return { lines, truncated: false };
548087
+ return { lines: lines.slice(0, limit), truncated: true };
548088
+ };
548047
548089
  if (isSubAgentInternal) {
548090
+ const stdoutPreview = sliceLines(data.stdout, maxLines);
548091
+ const stderrPreview = sliceLines(data.stderr, maxLines);
548048
548092
  return import_react76.default.createElement(
548049
548093
  Box_default,
548050
- { marginLeft: 2 },
548094
+ { flexDirection: "column", marginLeft: 2 },
548095
+ data.command && import_react76.default.createElement(
548096
+ Box_default,
548097
+ { flexDirection: "column" },
548098
+ import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u251C\u2500 command:"),
548099
+ import_react76.default.createElement(
548100
+ Box_default,
548101
+ { marginLeft: 2 },
548102
+ import_react76.default.createElement(Text, { color: "gray" }, data.command)
548103
+ )
548104
+ ),
548051
548105
  import_react76.default.createElement(
548052
548106
  Text,
548053
548107
  { color: hasError ? "red" : "gray", dimColor: true },
548054
- "\u2514\u2500 Exit code: ",
548055
- data.exitCode,
548056
- hasStdout && ` (${data.stdout.trim().split("\n").length} lines output)`,
548057
- hasStderr && ` (${data.stderr.trim().split("\n").length} lines stderr)`
548108
+ "\u251C\u2500 exitCode: ",
548109
+ data.exitCode
548110
+ ),
548111
+ hasStdout && import_react76.default.createElement(
548112
+ Box_default,
548113
+ { flexDirection: "column" },
548114
+ import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u251C\u2500 stdout:"),
548115
+ import_react76.default.createElement(
548116
+ Box_default,
548117
+ { marginLeft: 2, flexDirection: "column" },
548118
+ stdoutPreview.lines.map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "white" }, removeAnsiCodes(line))),
548119
+ stdoutPreview.truncated && import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u2026")
548120
+ )
548121
+ ),
548122
+ hasStderr && import_react76.default.createElement(
548123
+ Box_default,
548124
+ { flexDirection: "column" },
548125
+ import_react76.default.createElement(Text, { color: hasError ? "red" : "gray", dimColor: true }, "\u2514\u2500 stderr:"),
548126
+ import_react76.default.createElement(
548127
+ Box_default,
548128
+ { marginLeft: 2, flexDirection: "column" },
548129
+ stderrPreview.lines.map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: hasError ? "red" : "gray" }, removeAnsiCodes(line))),
548130
+ stderrPreview.truncated && import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u2026")
548131
+ )
548058
548132
  )
548059
548133
  );
548060
548134
  }
@@ -548096,7 +548170,7 @@ function renderTerminalExecutePreview(data, isSubAgentInternal) {
548096
548170
  Box_default,
548097
548171
  { flexDirection: "column" },
548098
548172
  import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u251C\u2500 stdout:"),
548099
- import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stdout.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "white" }, line)))
548173
+ import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stdout.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "white" }, removeAnsiCodes(line))))
548100
548174
  ),
548101
548175
  import_react76.default.createElement(
548102
548176
  Text,
@@ -548130,13 +548204,13 @@ function renderTerminalExecutePreview(data, isSubAgentInternal) {
548130
548204
  Box_default,
548131
548205
  { flexDirection: "column" },
548132
548206
  import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u251C\u2500 stdout:"),
548133
- import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stdout.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "yellow" }, line)))
548207
+ import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stdout.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "yellow" }, removeAnsiCodes(line))))
548134
548208
  ),
548135
548209
  hasStderr && import_react76.default.createElement(
548136
548210
  Box_default,
548137
548211
  { flexDirection: "column" },
548138
548212
  import_react76.default.createElement(Text, { color: "red", dimColor: true }, "\u251C\u2500 stderr:"),
548139
- import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stderr.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "red" }, line)))
548213
+ import_react76.default.createElement(Box_default, { marginLeft: 2, flexDirection: "column" }, data.stderr.split("\n").map((line, idx2) => import_react76.default.createElement(Text, { key: idx2, color: "red" }, removeAnsiCodes(line))))
548140
548214
  ),
548141
548215
  data.executedAt && import_react76.default.createElement(
548142
548216
  Text,
@@ -548494,6 +548568,42 @@ function renderTodoPreview(_toolName, data, _maxLines) {
548494
548568
  )
548495
548569
  );
548496
548570
  }
548571
+ function renderIdeDiagnosticsPreview(data) {
548572
+ if (!data.diagnostics || !Array.isArray(data.diagnostics)) {
548573
+ return import_react76.default.createElement(
548574
+ Box_default,
548575
+ { marginLeft: 2 },
548576
+ import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u2514\u2500 No diagnostics data")
548577
+ );
548578
+ }
548579
+ const diagnosticsCount = data.diagnostics.length;
548580
+ if (diagnosticsCount === 0) {
548581
+ return import_react76.default.createElement(
548582
+ Box_default,
548583
+ { marginLeft: 2 },
548584
+ import_react76.default.createElement(Text, { color: "gray", dimColor: true }, "\u2514\u2500 No diagnostics found")
548585
+ );
548586
+ }
548587
+ const errorCount = data.diagnostics.filter((d) => d.severity === "error").length;
548588
+ const warningCount = data.diagnostics.filter((d) => d.severity === "warning").length;
548589
+ const infoCount = data.diagnostics.filter((d) => d.severity === "info").length;
548590
+ const hintCount = data.diagnostics.filter((d) => d.severity === "hint").length;
548591
+ return import_react76.default.createElement(
548592
+ Box_default,
548593
+ { marginLeft: 2 },
548594
+ import_react76.default.createElement(
548595
+ Text,
548596
+ { color: "gray", dimColor: true },
548597
+ "\u2514\u2500 Found ",
548598
+ diagnosticsCount,
548599
+ " diagnostic(s)",
548600
+ errorCount > 0 && ` (${errorCount} error${errorCount > 1 ? "s" : ""})`,
548601
+ warningCount > 0 && ` (${warningCount} warning${warningCount > 1 ? "s" : ""})`,
548602
+ infoCount > 0 && ` (${infoCount} info)`,
548603
+ hintCount > 0 && ` (${hintCount} hint${hintCount > 1 ? "s" : ""})`
548604
+ )
548605
+ );
548606
+ }
548497
548607
  var import_react76;
548498
548608
  var init_ToolResultPreview = __esm({
548499
548609
  async "dist/ui/components/tools/ToolResultPreview.js"() {
@@ -548614,11 +548724,11 @@ function MessageRenderer({ message, index, filteredMessages, terminalWidth, show
548614
548724
  if (!showThinking && message.thinking && !message.content && !message.toolCall && !message.toolResult && !message.terminalResult && !message.discontinued && !message.hookError) {
548615
548725
  return null;
548616
548726
  }
548617
- const removeAnsiCodes = (text3) => {
548727
+ const removeAnsiCodes2 = (text3) => {
548618
548728
  return text3.replace(/\x1b\[[0-9;]*m/g, "");
548619
548729
  };
548620
548730
  const getDisplayContent = (content) => {
548621
- return maskSkillInjectedText(removeAnsiCodes(content || "")).displayText;
548731
+ return maskSkillInjectedText(removeAnsiCodes2(content || "")).displayText;
548622
548732
  };
548623
548733
  const formatUserBubbleText = (text3) => {
548624
548734
  const normalized2 = text3.length > 0 ? text3 : " ";
@@ -548641,7 +548751,11 @@ function MessageRenderer({ message, index, filteredMessages, terminalWidth, show
548641
548751
  } else if (message.messageStatus === "error") {
548642
548752
  toolStatusColor = "red";
548643
548753
  } else {
548644
- toolStatusColor = message.role === "subagent" ? "magenta" : "blue";
548754
+ if (message.role === "subagent" && message.subAgentInternal === true) {
548755
+ toolStatusColor = "cyan";
548756
+ } else {
548757
+ toolStatusColor = message.role === "subagent" ? "magenta" : "blue";
548758
+ }
548645
548759
  }
548646
548760
  }
548647
548761
  return import_react78.default.createElement(Box_default, { key: `msg-${index}`, marginTop: 0, marginBottom: 1, paddingX: 1, flexDirection: "column", width: terminalWidth }, message.plainOutput ? import_react78.default.createElement(Text, { color: message.role === "user" ? "white" : toolStatusColor }, getDisplayContent(message.content)) : import_react78.default.createElement(
@@ -548674,7 +548788,7 @@ function MessageRenderer({ message, index, filteredMessages, terminalWidth, show
548674
548788
  ) : import_react78.default.createElement(
548675
548789
  import_react78.default.Fragment,
548676
548790
  null,
548677
- message.plainOutput ? import_react78.default.createElement(Text, { color: message.role === "user" ? "white" : toolStatusColor, backgroundColor: message.role === "user" ? theme14.colors.border : void 0 }, removeAnsiCodes(message.content || " ")) : (() => {
548791
+ message.plainOutput ? import_react78.default.createElement(Text, { color: message.role === "user" ? "white" : toolStatusColor, backgroundColor: message.role === "user" ? theme14.colors.border : void 0 }, removeAnsiCodes2(message.content || " ")) : (() => {
548678
548792
  if (message.hookError) {
548679
548793
  return import_react78.default.createElement(HookErrorDisplay, { details: message.hookError });
548680
548794
  }
@@ -548692,8 +548806,18 @@ function MessageRenderer({ message, index, filteredMessages, terminalWidth, show
548692
548806
  } catch {
548693
548807
  }
548694
548808
  const hasToolStatus = message.messageStatus !== void 0;
548695
- if (hasToolStatus && (message.role === "assistant" || message.role === "subagent")) {
548696
- return import_react78.default.createElement(Text, { color: toolStatusColor }, removeAnsiCodes(message.content || " "));
548809
+ const isSubAgentInternal = message.subAgentInternal === true;
548810
+ if ((hasToolStatus || isSubAgentInternal) && (message.role === "assistant" || message.role === "subagent")) {
548811
+ const content = message.content || " ";
548812
+ const lines = content.split("\n");
548813
+ const titleLine = lines[0] || "";
548814
+ const treeLines = lines.slice(1);
548815
+ return import_react78.default.createElement(
548816
+ import_react78.default.Fragment,
548817
+ null,
548818
+ import_react78.default.createElement(Text, { color: toolStatusColor }, removeAnsiCodes2(titleLine)),
548819
+ treeLines.length > 0 && import_react78.default.createElement(Text, { color: theme14.colors.menuSecondary }, treeLines.map((line) => removeAnsiCodes2(line || "")).join("\n"))
548820
+ );
548697
548821
  }
548698
548822
  return import_react78.default.createElement(
548699
548823
  import_react78.default.Fragment,
@@ -555312,7 +555436,7 @@ function calculateContextPercentage(contextUsage) {
555312
555436
  const totalInputTokens = isAnthropic ? contextUsage.inputTokens + (contextUsage.cacheCreationTokens || 0) + (contextUsage.cacheReadTokens || 0) : contextUsage.inputTokens;
555313
555437
  return Math.min(100, totalInputTokens / contextUsage.maxContextTokens * 100);
555314
555438
  }
555315
- function ChatInput({ onSubmit, onCommand, placeholder = "Type your message...", disabled = false, isProcessing = false, chatHistory = [], onHistorySelect, yoloMode = false, setYoloMode, planMode = false, setPlanMode, vulnerabilityHuntingMode = false, setVulnerabilityHuntingMode, contextUsage, initialContent = null, onContextPercentageChange, showProfilePicker = false, setShowProfilePicker, profileSelectedIndex = 0, setProfileSelectedIndex, getFilteredProfiles, handleProfileSelect, profileSearchQuery = "", setProfileSearchQuery, onSwitchProfile, disableKeyboardNavigation = false }) {
555439
+ function ChatInput({ onSubmit, onCommand, placeholder = "Type your message...", disabled = false, isProcessing = false, chatHistory = [], onHistorySelect, yoloMode = false, setYoloMode, planMode = false, setPlanMode, vulnerabilityHuntingMode = false, setVulnerabilityHuntingMode, contextUsage, initialContent = null, draftContent = null, onDraftChange, onContextPercentageChange, showProfilePicker = false, setShowProfilePicker, profileSelectedIndex = 0, setProfileSelectedIndex, getFilteredProfiles, handleProfileSelect, profileSearchQuery = "", setProfileSearchQuery, onSwitchProfile, disableKeyboardNavigation = false }) {
555316
555440
  const { t } = useI18n();
555317
555441
  const { theme: theme14 } = useTheme();
555318
555442
  const { parseBashCommands, parsePureBashCommands } = useBashMode();
@@ -555476,6 +555600,65 @@ function ChatInput({ onSubmit, onCommand, placeholder = "Type your message...",
555476
555600
  triggerUpdate();
555477
555601
  }
555478
555602
  }, [initialContent]);
555603
+ (0, import_react101.useEffect)(() => {
555604
+ if (!draftContent)
555605
+ return;
555606
+ if (initialContent)
555607
+ return;
555608
+ if (buffer.text.length > 0)
555609
+ return;
555610
+ buffer.setText("");
555611
+ const text3 = draftContent.text;
555612
+ const images = draftContent.images || [];
555613
+ if (images.length === 0) {
555614
+ if (text3) {
555615
+ restoreTextWithSkillPlaceholders(buffer, text3);
555616
+ }
555617
+ } else {
555618
+ const imagePlaceholderPattern = /\[image #\d+\]/g;
555619
+ const parts = text3.split(imagePlaceholderPattern);
555620
+ for (let i = 0; i < parts.length; i++) {
555621
+ const part = parts[i];
555622
+ if (part) {
555623
+ restoreTextWithSkillPlaceholders(buffer, part);
555624
+ }
555625
+ if (i < images.length) {
555626
+ const img = images[i];
555627
+ if (img) {
555628
+ let base64Data = img.data;
555629
+ if (base64Data.startsWith("data:")) {
555630
+ const base64Index = base64Data.indexOf("base64,");
555631
+ if (base64Index !== -1) {
555632
+ base64Data = base64Data.substring(base64Index + 7);
555633
+ }
555634
+ }
555635
+ buffer.insertImage(base64Data, img.mimeType);
555636
+ }
555637
+ }
555638
+ }
555639
+ }
555640
+ triggerUpdate();
555641
+ }, [draftContent, initialContent, buffer, triggerUpdate]);
555642
+ (0, import_react101.useEffect)(() => {
555643
+ if (!onDraftChange)
555644
+ return;
555645
+ const text3 = buffer.getFullText();
555646
+ const currentText = buffer.text;
555647
+ const allImages = buffer.getImages();
555648
+ const images = allImages.filter((img) => currentText.includes(img.placeholder)).map((img) => ({
555649
+ type: "image",
555650
+ data: img.data,
555651
+ mimeType: img.mimeType
555652
+ }));
555653
+ if (!text3 && images.length === 0) {
555654
+ onDraftChange(null);
555655
+ return;
555656
+ }
555657
+ onDraftChange({
555658
+ text: text3,
555659
+ images: images.length > 0 ? images : void 0
555660
+ });
555661
+ }, [buffer.text, buffer, onDraftChange]);
555479
555662
  (0, import_react101.useEffect)(() => {
555480
555663
  const timer2 = setTimeout(() => {
555481
555664
  forceUpdate();
@@ -556789,7 +556972,7 @@ function ChatFooter(props) {
556789
556972
  !props.showReviewCommitPanel && import_react106.default.createElement(
556790
556973
  import_react106.default.Fragment,
556791
556974
  null,
556792
- import_react106.default.createElement(ChatInput, { onSubmit: props.onSubmit, onCommand: props.onCommand, placeholder: t.chatScreen.inputPlaceholder, disabled: props.disabled, disableKeyboardNavigation: props.showBackgroundPanel, isProcessing: props.isProcessing, chatHistory: props.chatHistory, onHistorySelect: props.handleHistorySelect, yoloMode: props.yoloMode, setYoloMode: props.setYoloMode, planMode: props.planMode, setPlanMode: props.setPlanMode, vulnerabilityHuntingMode: props.vulnerabilityHuntingMode, setVulnerabilityHuntingMode: props.setVulnerabilityHuntingMode, contextUsage: props.contextUsage, initialContent: props.initialContent, onContextPercentageChange: props.onContextPercentageChange, showProfilePicker: props.showProfilePicker, setShowProfilePicker: props.setShowProfilePicker, profileSelectedIndex: props.profileSelectedIndex, setProfileSelectedIndex: props.setProfileSelectedIndex, getFilteredProfiles: props.getFilteredProfiles, handleProfileSelect: props.handleProfileSelect, profileSearchQuery: props.profileSearchQuery, setProfileSearchQuery: props.setProfileSearchQuery, onSwitchProfile: props.onSwitchProfile }),
556975
+ import_react106.default.createElement(ChatInput, { onSubmit: props.onSubmit, onCommand: props.onCommand, placeholder: t.chatScreen.inputPlaceholder, disabled: props.disabled, disableKeyboardNavigation: props.showBackgroundPanel, isProcessing: props.isProcessing, chatHistory: props.chatHistory, onHistorySelect: props.handleHistorySelect, yoloMode: props.yoloMode, setYoloMode: props.setYoloMode, planMode: props.planMode, setPlanMode: props.setPlanMode, vulnerabilityHuntingMode: props.vulnerabilityHuntingMode, setVulnerabilityHuntingMode: props.setVulnerabilityHuntingMode, contextUsage: props.contextUsage, initialContent: props.initialContent, draftContent: props.draftContent, onDraftChange: props.onDraftChange, onContextPercentageChange: props.onContextPercentageChange, showProfilePicker: props.showProfilePicker, setShowProfilePicker: props.setShowProfilePicker, profileSelectedIndex: props.profileSelectedIndex, setProfileSelectedIndex: props.setProfileSelectedIndex, getFilteredProfiles: props.getFilteredProfiles, handleProfileSelect: props.handleProfileSelect, profileSearchQuery: props.profileSearchQuery, setProfileSearchQuery: props.setProfileSearchQuery, onSwitchProfile: props.onSwitchProfile }),
556793
556976
  showTodos && todos.length > 0 && import_react106.default.createElement(
556794
556977
  Box_default,
556795
556978
  { marginTop: 1 },
@@ -556855,6 +557038,7 @@ var init_ChatFooter = __esm({
556855
557038
  // dist/ui/components/chat/PendingMessages.js
556856
557039
  function PendingMessages({ pendingMessages }) {
556857
557040
  const { theme: theme14 } = useTheme();
557041
+ const { t } = useI18n();
556858
557042
  if (pendingMessages.length === 0) {
556859
557043
  return null;
556860
557044
  }
@@ -556864,7 +557048,8 @@ function PendingMessages({ pendingMessages }) {
556864
557048
  import_react107.default.createElement(
556865
557049
  Text,
556866
557050
  { color: theme14.colors.warning, bold: true },
556867
- "\u2B11 Pending Messages (",
557051
+ t.chatScreen.pendingMessagesTitle,
557052
+ " (",
556868
557053
  pendingMessages.length,
556869
557054
  ")"
556870
557055
  ),
@@ -556892,15 +557077,14 @@ function PendingMessages({ pendingMessages }) {
556892
557077
  import_react107.default.createElement(
556893
557078
  Text,
556894
557079
  { color: theme14.colors.menuSecondary, dimColor: true },
556895
- "\u2514\u2500 ",
556896
- message.images.length,
556897
- " image",
556898
- message.images.length > 1 ? "s" : "",
556899
- " attached"
557080
+ "\u2514\u2500",
557081
+ " ",
557082
+ t.chatScreen.pendingMessagesImagesAttached.replace("{count}", String(message.images.length))
556900
557083
  )
556901
557084
  )
556902
557085
  )),
556903
- import_react107.default.createElement(Text, { color: theme14.colors.warning, dimColor: true }, "Will be sent after tool execution completes")
557086
+ import_react107.default.createElement(Text, { color: theme14.colors.warning, dimColor: true }, t.chatScreen.pendingMessagesFooter),
557087
+ import_react107.default.createElement(Text, { color: theme14.colors.warning, dimColor: true }, t.chatScreen.pendingMessagesEscHint)
556904
557088
  );
556905
557089
  }
556906
557090
  var import_react107;
@@ -556910,6 +557094,7 @@ var init_PendingMessages = __esm({
556910
557094
  import_react107 = __toESM(require_react(), 1);
556911
557095
  await init_build2();
556912
557096
  init_ThemeContext();
557097
+ init_i18n();
556913
557098
  }
556914
557099
  });
556915
557100
 
@@ -565122,7 +565307,7 @@ async function handleConversationWithTools(options3) {
565122
565307
  });
565123
565308
  const uiMsg = {
565124
565309
  role: "subagent",
565125
- content: `\x1B[38;2;184;122;206m\u2687 ${subAgentMessage.agentName}${toolLines.join("")}\x1B[0m`,
565310
+ content: `\x1B[36m\u2687 ${subAgentMessage.agentName}\x1B[0m${toolLines.join("")}`,
565126
565311
  streaming: false,
565127
565312
  subAgent: {
565128
565313
  agentId: subAgentMessage.agentId,
@@ -565218,6 +565403,7 @@ async function handleConversationWithTools(options3) {
565218
565403
  role: "subagent",
565219
565404
  content: `\x1B[38;2;0;186;255m\u2687${statusIcon} ${msg.tool_name}\x1B[0m${statusText}`,
565220
565405
  streaming: false,
565406
+ messageStatus: isError2 ? "error" : "success",
565221
565407
  toolResult: !isError2 ? msg.content : void 0,
565222
565408
  terminalResult: terminalResultData,
565223
565409
  toolCall: terminalResultData ? {
@@ -565238,6 +565424,7 @@ async function handleConversationWithTools(options3) {
565238
565424
  role: "subagent",
565239
565425
  content: `\x1B[38;2;255;100;100m\u2687\u2717 ${msg.tool_name}\x1B[0m`,
565240
565426
  streaming: false,
565427
+ messageStatus: "error",
565241
565428
  subAgent: {
565242
565429
  agentId: subAgentMessage.agentId,
565243
565430
  agentName: subAgentMessage.agentName,
@@ -569921,9 +570108,11 @@ ${errorMsg}`,
569921
570108
  await codebaseAgentRef.current.stop();
569922
570109
  codebaseAgentRef.current.stopWatching();
569923
570110
  codebaseAgentRef.current = null;
569924
- setCodebaseIndexing(false);
569925
- setWatcherEnabled(false);
569926
570111
  }
570112
+ setCodebaseIndexing(false);
570113
+ setWatcherEnabled(false);
570114
+ setCodebaseProgress(null);
570115
+ setFileUpdateNotification(null);
569927
570116
  }
569928
570117
  };
569929
570118
  const handleReviewCommitConfirm = async (selection, notes) => {
@@ -570839,6 +571028,7 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
570839
571028
  const [compressionError, setCompressionError] = (0, import_react139.useState)(null);
570840
571029
  const [showPermissionsPanel, setShowPermissionsPanel] = (0, import_react139.useState)(false);
570841
571030
  const [restoreInputContent, setRestoreInputContent] = (0, import_react139.useState)(null);
571031
+ const [inputDraftContent, setInputDraftContent] = (0, import_react139.useState)(null);
570842
571032
  const [bashSensitiveCommand, setBashSensitiveCommand] = (0, import_react139.useState)(null);
570843
571033
  const [suppressLoadingIndicator, setSuppressLoadingIndicator] = (0, import_react139.useState)(false);
570844
571034
  const hadBashSensitiveCommandRef = (0, import_react139.useRef)(false);
@@ -571080,7 +571270,10 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
571080
571270
  global.__stopCodebaseIndexing = async () => {
571081
571271
  if (codebaseAgentRef.current) {
571082
571272
  await codebaseAgentRef.current.stop();
571273
+ codebaseAgentRef.current.stopWatching();
571083
571274
  setCodebaseIndexing(false);
571275
+ setWatcherEnabled(false);
571276
+ setCodebaseProgress(null);
571084
571277
  }
571085
571278
  };
571086
571279
  return () => {
@@ -571347,7 +571540,6 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
571347
571540
  };
571348
571541
  }, [streamingState]);
571349
571542
  use_input_default((input2, key) => {
571350
- var _a21;
571351
571543
  if (backgroundProcesses.showPanel) {
571352
571544
  if (key.escape) {
571353
571545
  backgroundProcesses.hidePanel();
@@ -571416,25 +571608,26 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
571416
571608
  return;
571417
571609
  }
571418
571610
  if (key.escape && streamingState.isStreaming && streamingState.abortController && hasFocus) {
571611
+ if (pendingMessages.length > 0) {
571612
+ const mergedText = pendingMessages.map((m) => (m.text || "").trim()).filter(Boolean).join("\n\n");
571613
+ const mergedImages = pendingMessages.flatMap((m) => m.images ?? []);
571614
+ setRestoreInputContent({
571615
+ text: mergedText,
571616
+ images: mergedImages.length > 0 ? mergedImages.map((img) => ({
571617
+ type: "image",
571618
+ data: img.data,
571619
+ mimeType: img.mimeType
571620
+ })) : void 0
571621
+ });
571622
+ setPendingMessages([]);
571623
+ return;
571624
+ }
571419
571625
  userInterruptedRef.current = true;
571420
571626
  streamingState.setIsStopping(true);
571421
571627
  streamingState.setRetryStatus(null);
571422
571628
  streamingState.setCodebaseSearchStatus(null);
571423
571629
  streamingState.abortController.abort();
571424
571630
  setMessages((prev) => prev.filter((msg) => !msg.toolPending));
571425
- if (pendingMessages.length > 0) {
571426
- const firstPending = pendingMessages[0];
571427
- if (firstPending) {
571428
- setRestoreInputContent({
571429
- text: firstPending.text,
571430
- images: (_a21 = firstPending.images) == null ? void 0 : _a21.map((img) => ({
571431
- type: "image",
571432
- data: img.data,
571433
- mimeType: img.mimeType
571434
- }))
571435
- });
571436
- }
571437
- }
571438
571631
  setPendingMessages([]);
571439
571632
  }
571440
571633
  });
@@ -571620,7 +571813,7 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
571620
571813
  cacheCreationTokens: streamingState.contextUsage.cache_creation_input_tokens,
571621
571814
  cacheReadTokens: streamingState.contextUsage.cache_read_input_tokens,
571622
571815
  cachedTokens: streamingState.contextUsage.cached_tokens
571623
- } : void 0, initialContent: restoreInputContent, onContextPercentageChange: setCurrentContextPercentage, showProfilePicker: panelState.showProfilePanel, setShowProfilePicker: panelState.setShowProfilePanel, profileSelectedIndex: panelState.profileSelectedIndex, setProfileSelectedIndex: panelState.setProfileSelectedIndex, getFilteredProfiles: () => {
571816
+ } : void 0, initialContent: restoreInputContent, draftContent: inputDraftContent, onDraftChange: setInputDraftContent, onContextPercentageChange: setCurrentContextPercentage, showProfilePicker: panelState.showProfilePanel, setShowProfilePicker: panelState.setShowProfilePanel, profileSelectedIndex: panelState.profileSelectedIndex, setProfileSelectedIndex: panelState.setProfileSelectedIndex, getFilteredProfiles: () => {
571624
571817
  const allProfiles = getAllProfiles();
571625
571818
  const query = panelState.profileSearchQuery.toLowerCase();
571626
571819
  const currentName = panelState.currentProfileName;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.6.19",
3
+ "version": "0.6.20",
4
4
  "description": "Agentic coding in your terminal",
5
5
  "license": "MIT",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.6.19",
3
+ "version": "0.6.20",
4
4
  "description": "Agentic coding in your terminal",
5
5
  "license": "MIT",
6
6
  "bin": {