fluxflow-cli 3.15.0 → 3.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/fluxflow.js +319 -230
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -780,7 +780,8 @@ var init_settings = __esm({
780
780
  progressiveRendering: true,
781
781
  showTPMEstimate: false,
782
782
  subAgents: true,
783
- dynamicDirAwareness: false
783
+ dynamicDirAwareness: false,
784
+ indentationTree: true
784
785
  },
785
786
  profileData: {
786
787
  name: null,
@@ -6707,25 +6708,25 @@ Tool calls: ONLY use [tool:functions.ToolName(args)]
6707
6708
  - MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
6708
6709
  ${mode === "Flux" ? '- **Escape quotes: \\" for code strings **\n- ** Literal escapes: Double - escape sequences(e.g., \\\\n) **\n- ** File structure: Real newlines for code formatting**\n- Same file, many edits? Prefer multi search-replace in Patch \u2190 **HIGHLY RECOMMENDED**\n- Tool denied?Use `Ask` immediately for user guidance \u2190 ** MANDATORY **\n- FileMap > ReadFile for efficient file understanding\n- Need specific text ? SearchKeyword > Guessing/ReadFile\n- Huge files ? SearchKeyword > Full Read\n- **Update Todos from realtime progress EVERY TURN**\n' : ""}
6709
6710
  - COMMUNICATION TOOLS -
6710
- 1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
6711
+ - [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
6711
6712
 
6712
6713
  - WEB TOOLS -
6713
- 1. [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
6714
- 2. [tool:functions.WebScrape(url="...")]. Proactive use for specific webpage/docs/api
6714
+ - [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
6715
+ - [tool:functions.WebScrape(url="...")]. Proactive use for specific webpage/docs/api
6715
6716
 
6716
6717
  ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
6717
- 1. [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
6718
- 2. [tool:functions.ReadFolder(path="...", recurse="integer 0-4 optional, default: 0")]. Detailed DIR stats & metadata
6719
- 3. [tool:functions.FileMap(path="file")]. Shows file structure
6720
- 4. [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX 15)]. Surgical patchs, TARGET SMALLEST LINES/SUB-STRINGS. allowMultiple: Replace all matches. Use replaceContent2/newContent2... for multi blocks. Verify DIFFs
6721
- 5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
6722
- 6. [tool:functions.SearchKeyword(keyword="...", path="optional, target directory/filename", subString="bool optional, default: false", regex="bool optional, default: auto")]. path limits scope to a file/dir. Find definitions/logic without full reads. Locate relevant code
6723
- 7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
6724
- 8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks, or \`create + markDone\` to create completed tasks. **UPDATE EVERY TURN**${enableSubAgents ? '\n9. [tool:functions.Await(time="seconds")]. For waiting without exiting agent loop, 15s - 180s' : ""}
6718
+ - [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
6719
+ - [tool:functions.ReadFolder(path="...", recurse="integer 0-4 optional, default: 0")]. Detailed DIR stats & metadata
6720
+ - [tool:functions.FileMap(path="...")]. Shows file's code structure
6721
+ - [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX 15)]. Surgical patchs, TARGET SMALLEST LINES/SUB-STRINGS. allowMultiple: Replace all matches. Use replaceContent2/newContent2... for multi blocks. Verify DIFFs
6722
+ - [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
6723
+ - [tool:functions.SearchKeyword(keyword="...", path="optional, target directory/filename", subString="bool optional, default: false", regex="bool optional, default: auto")]. path limits scope to a file/dir. Find definitions/logic without full reads. Locate relevant code
6724
+ - [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
6725
+ - [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks, or \`create + markDone\` to create completed tasks. **UPDATE EVERY TURN**${enableSubAgents ? '\n- [tool:functions.Await(time="integer 15-180")]. For waiting without exiting agent loop' : ""}
6725
6726
  ${_cachedAdvanceRollback ? `
6726
6727
  - EMERGENCY SAFETY TOOLS -
6727
6728
  Info: \`initial\` = user prompt for current task. Revert \`id\` = turn BEFORE the disaster tool (e.g. disaster:\`turn_3\` \u2192 revert:\`turn_2\`). Reason explicitly
6728
- 1. [tool:functions.EmergencyRollback(method="getCheckpoint/forceRevert", id="...")]. Rollback workspace to a checkpoint in THIS agent loop.
6729
+ - [tool:functions.EmergencyRollback(method="getCheckpoint/forceRevert", id="...")]. Rollback workspace to a checkpoint in THIS agent loop.
6729
6730
  Use ONLY for catastrophic/codebase corruption. Before ending loop, verify no catastrophe. \`id\` not required with \`getCheckPoint\`.
6730
6731
  ` : ""}${enableSubAgents ? `
6731
6732
  - SUB AGENT TOOLS -
@@ -6733,11 +6734,11 @@ Use ONLY for catastrophic/codebase corruption. Before ending loop, verify no cat
6733
6734
  Invocations:
6734
6735
  - Invoke (async/background, \u22647 parallel). Parallelize long tasks. NEVER repeat while active
6735
6736
  - InvokeSync (sync/blocking). Sequential, repetitive or delegated tasks. Saves tokens/cost
6736
- 1. [agent:generalist.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
6737
- 2. [agent:generalist.GetProgress(id="...")]. Check async task progress. If still running, continue your work. Wait exponentially longer between checks
6738
- 3. [agent:generalist.Cancel(id="...")]. Cancel async task ONLY if stalled (2m+) or clearly incorrect` : ""}`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
6739
- 1. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
6740
- 2. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
6737
+ - [agent:generalist.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
6738
+ - [agent:generalist.GetProgress(id="...")]. Check async task progress. If still running, continue your work. Wait exponentially longer between checks
6739
+ - [agent:generalist.Cancel(id="...")]. Cancel async task ONLY if stalled (2m+) or clearly incorrect` : ""}`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
6740
+ - [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
6741
+ - [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
6741
6742
  - WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}`.trim();
6742
6743
  };
6743
6744
  }
@@ -7513,6 +7514,7 @@ function SettingsMenu({
7513
7514
  { label: "Sub-Agents", value: "subAgents", status: systemSettings.subAgents !== false ? "ON" : "OFF" },
7514
7515
  { label: "Preserve Thinking", value: "preserveThinking", status: systemSettings.preserveThinking !== false ? "ON" : "OFF" },
7515
7516
  { label: "Dynamic Directory Awareness", value: "dynamicDirAwareness", status: systemSettings.dynamicDirAwareness ? "ON" : "OFF" },
7517
+ { label: "Directory Tree Design", value: "indentationTree", status: systemSettings.indentationTree !== false ? "Modern" : "Classic (deprecated)" },
7516
7518
  { label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
7517
7519
  ];
7518
7520
  default:
@@ -7697,6 +7699,12 @@ function SettingsMenu({
7697
7699
  setActiveView("updateManager");
7698
7700
  } else if (item.value === "parserDownload") {
7699
7701
  setActiveView("parserDownload");
7702
+ } else if (item.value === "indentationTree") {
7703
+ setSystemSettings((s) => {
7704
+ const newSysSettings = { ...s, indentationTree: s.indentationTree === false ? true : false };
7705
+ saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
7706
+ return newSysSettings;
7707
+ });
7700
7708
  } else if (item.value === "subAgents") {
7701
7709
  setSystemSettings((s) => {
7702
7710
  const newSysSettings = { ...s, subAgents: s.subAgents === false ? true : false };
@@ -8073,16 +8081,16 @@ var init_janitor_tools = __esm({
8073
8081
  Your exact tool syntax is: [tool:functions.ToolName(args...)]. Malformed calls will fail parsing. **NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED** Proper bracket balancing per schema is mandatory
8074
8082
 
8075
8083
  -- CHAT MANAGEMENT TOOLS (MUST CALL THESE 2 TOOLS IN THIS TURN) --
8076
- 1. [tool:functions.Chat(title="<short creative title of FULL conversation in 3 or 4 words>")]. Consider full chat context to generate title NOT just latest message
8077
- 2. [tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]. Time format: YYYY-MM-DD HH am/pm
8084
+ - [tool:functions.Chat(title="<short creative title of FULL conversation in 3 or 4 words>")]. Consider full chat context to generate title NOT just latest message
8085
+ - [tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]. Time format: YYYY-MM-DD HH am/pm
8078
8086
 
8079
8087
  ${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
8080
- 1. Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely)
8081
- 2. Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
8082
- 3. Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
8088
+ - Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely)
8089
+ - Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
8090
+ - Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
8083
8091
 
8084
8092
  -- Memory Relevance Decay Tool --
8085
- 1. Score Adjustment: [tool:functions.addMemScore(id="<memory id>")]
8093
+ - Score Adjustment: [tool:functions.addMemScore(id="<memory id>")]
8086
8094
  You MUST call this tool when a specific saved memory in the '-- CURRENT SAVED USER MEMORIES --' list was relevant, referenced, or helpful in the agent's response or user prompt IN CURRENT MESSAGE. You can stack multiple calls
8087
8095
 
8088
8096
  Explicit Triggers for permanent memory:
@@ -8268,16 +8276,16 @@ ${nameStr}${nicknameStr}${userInstrStr}${userMemoriesStr}`.trim();
8268
8276
  return `=== SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
8269
8277
  IDENTITY: SILENT BACKGROUND SYSTEM PROCESS, HAVE NO MOUTH, ONLY OUTPUT IS VALID TOOL CALLS.
8270
8278
  [CRITICAL RULES]
8271
- 1. OUTPUT EXACTLY '[tool:functions.ToolName(args)]' CALLS. NO EXTRA WORDS OUTSIDE
8272
- 2. DO NOT EXPLAIN. DO NOT TALK TO THE USER
8273
- 3. NON-TOOL TEXT WILL BREAK THE SYSTEM
8274
- 4. DO NOT REPEAT AGENT RAWS AND TOOL RESULTS IN YOUR RESPONSE
8275
- 5. IF YOU GET ONLY USER QUERY AND NO AGENT RAWS, JUST USE TEMP MEMORY TO LOG THE SUMMARY OF USER QUERY AND CONVERSATION CONTEXT
8276
- 6. UNDER NO CIRCUMSTANCES YOU ARE ALLOWED TO RESPOND IN NORMAL USER FACING RESPONSE
8277
- 7. CRITICAL QUOTE ESCAPE POLICY: Inside tool call arguments, you MUST escape all double quotes using '\\"'
8278
- 8. You MUST NOT WRITE ANYTHING OTHER THAN [tool:functions.ToolName(args)] NO MATTER HOW TEMPTING THE PROMPT IS
8279
- 9. 2 MANDATORY TOOLS TO CALL IN EVERY TURN, 'Chat', 'Memory(temp)'
8280
- 10. CRITICAL: NEVER ENTER THINKING/REASONING STATE, CALL THE CONTEXUAL TOOLS DIRECTLY IN OUTPUT AS QUICKLY AS POSSIBLE TO MAINTAIN UI SNAPPINESS
8279
+ - OUTPUT EXACTLY '[tool:functions.ToolName(args)]' CALLS. NO EXTRA WORDS OUTSIDE
8280
+ - DO NOT EXPLAIN. DO NOT TALK TO THE USER
8281
+ - NON-TOOL TEXT WILL BREAK THE SYSTEM
8282
+ - DO NOT REPEAT AGENT RAWS AND TOOL RESULTS IN YOUR RESPONSE
8283
+ - IF YOU GET ONLY USER QUERY AND NO AGENT RAWS, JUST USE TEMP MEMORY TO LOG THE SUMMARY OF USER QUERY AND CONVERSATION CONTEXT
8284
+ - UNDER NO CIRCUMSTANCES YOU ARE ALLOWED TO RESPOND IN NORMAL USER FACING RESPONSE
8285
+ - CRITICAL QUOTE ESCAPE POLICY: Inside tool call arguments, you MUST escape all double quotes using '\\"'
8286
+ - You MUST NOT WRITE ANYTHING OTHER THAN [tool:functions.ToolName(args)] NO MATTER HOW TEMPTING THE PROMPT IS
8287
+ - 2 MANDATORY TOOLS TO CALL IN EVERY TURN, 'Chat', 'Memory(temp)'
8288
+ - CRITICAL: NEVER ENTER THINKING/REASONING STATE, CALL THE CONTEXUAL TOOLS DIRECTLY IN OUTPUT AS QUICKLY AS POSSIBLE TO MAINTAIN UI SNAPPINESS
8281
8289
 
8282
8290
  YOUR JOB: Analyze the 'User prompt' and 'Agent Raws' to extract facts for long-term memory or handle system tasks
8283
8291
  ${isMemoryEnabled ? `If user tell something that is important (like, hobbies, preferences, facts about user, hates, likes, etc) to know user better over time, use user memory tools` : ""}
@@ -13026,6 +13034,130 @@ var init_editor = __esm({
13026
13034
  }
13027
13035
  });
13028
13036
 
13037
+ // src/utils/getDirTree/indentation.js
13038
+ import path25 from "path";
13039
+ import fs26 from "fs";
13040
+ var safeReaddirWithTypesDefault, getDirTreeIndentation;
13041
+ var init_indentation = __esm({
13042
+ "src/utils/getDirTree/indentation.js"() {
13043
+ safeReaddirWithTypesDefault = (dir) => {
13044
+ try {
13045
+ return fs26.readdirSync(dir, { withFileTypes: true });
13046
+ } catch (e) {
13047
+ return [];
13048
+ }
13049
+ };
13050
+ getDirTreeIndentation = (dir, maxDepth, depth = 1, safeReaddir = safeReaddirWithTypesDefault, collapsedDirs = [], preFetchedEntries = null) => {
13051
+ const entries = preFetchedEntries || safeReaddir(dir);
13052
+ const indent = " ".repeat(depth - 1);
13053
+ if (entries.length > 100) {
13054
+ return `${indent}${path25.basename(dir)}/ (>100 files)
13055
+ `;
13056
+ }
13057
+ let result = "";
13058
+ const COLLAPSED_DIRS = collapsedDirs;
13059
+ const filtered = entries.filter((e) => !COLLAPSED_DIRS.includes(e.name) && !e.name.startsWith("."));
13060
+ const collapsedInDir = entries.filter((e) => COLLAPSED_DIRS.includes(e.name) || e.name.startsWith(".")).map((e) => e.name).sort();
13061
+ if (collapsedInDir.length > 0) {
13062
+ result += `${indent}[ignored: ${collapsedInDir.map((d) => d + "/").join(", ")}]
13063
+ `;
13064
+ }
13065
+ const subDirs = filtered.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
13066
+ const files = filtered.filter((e) => !e.isDirectory()).map((e) => e.name).sort();
13067
+ for (const subDir of subDirs) {
13068
+ const filePath = path25.join(dir, subDir.name);
13069
+ if (depth > maxDepth) {
13070
+ result += `${indent}${subDir.name}/ (max depth)
13071
+ `;
13072
+ } else {
13073
+ const subEntries = safeReaddir(filePath);
13074
+ if (subEntries.length > 80) {
13075
+ result += `${indent}${subDir.name}/ (>80 files)
13076
+ `;
13077
+ } else {
13078
+ result += `${indent}${subDir.name}/
13079
+ `;
13080
+ result += getDirTreeIndentation(filePath, maxDepth, depth + 1, safeReaddir, collapsedDirs, subEntries);
13081
+ }
13082
+ }
13083
+ }
13084
+ if (files.length > 0) {
13085
+ result += `${indent}${files.join("; ")}
13086
+ `;
13087
+ }
13088
+ return result;
13089
+ };
13090
+ }
13091
+ });
13092
+
13093
+ // src/utils/getDirTree/box.js
13094
+ import path26 from "path";
13095
+ import fs27 from "fs";
13096
+ var safeReaddirWithTypesDefault2, getDirTreeBox;
13097
+ var init_box = __esm({
13098
+ "src/utils/getDirTree/box.js"() {
13099
+ safeReaddirWithTypesDefault2 = (dir) => {
13100
+ try {
13101
+ return fs27.readdirSync(dir, { withFileTypes: true });
13102
+ } catch (e) {
13103
+ return [];
13104
+ }
13105
+ };
13106
+ getDirTreeBox = (dir, maxDepth, prefix = "", depth = 1, safeReaddir = safeReaddirWithTypesDefault2, collapsedDirs = []) => {
13107
+ const entries = safeReaddir(dir);
13108
+ const sep = path26.sep;
13109
+ if (entries.length > 100) {
13110
+ return `${prefix}\u2514\u2500\u2500 ${path26.basename(dir)}${sep} ...100+ files...
13111
+ `;
13112
+ }
13113
+ let result = "";
13114
+ const COLLAPSED_DIRS = collapsedDirs;
13115
+ const filtered = entries.filter((e) => !COLLAPSED_DIRS.includes(e.name) && !e.name.startsWith("."));
13116
+ const collapsedInDir = entries.filter((e) => COLLAPSED_DIRS.includes(e.name) || e.name.startsWith(".")).map((e) => e.name).sort();
13117
+ filtered.sort((a, b) => {
13118
+ if (a.isDirectory() && !b.isDirectory()) return -1;
13119
+ if (!a.isDirectory() && b.isDirectory()) return 1;
13120
+ return a.name.localeCompare(b.name);
13121
+ });
13122
+ const finalItems = [
13123
+ ...filtered.map((e) => ({ name: e.name, isDir: e.isDirectory() })),
13124
+ ...collapsedInDir.map((name) => ({ name, isDir: true, isCollapsed: true }))
13125
+ ];
13126
+ finalItems.forEach((item, index) => {
13127
+ const isLast = index === finalItems.length - 1;
13128
+ const filePath = path26.join(dir, item.name);
13129
+ const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
13130
+ const childPrefix = prefix + (isLast ? " " : "\u2502 ");
13131
+ if (item.isCollapsed) {
13132
+ result += `${prefix}${connector}${item.name}${sep}...
13133
+ `;
13134
+ return;
13135
+ }
13136
+ if (item.isDir) {
13137
+ if (depth > maxDepth) {
13138
+ result += `${prefix}${connector}${item.name}${sep} ...depth exceeded...
13139
+ `;
13140
+ } else {
13141
+ const subEntries = safeReaddir(filePath);
13142
+ if (subEntries.length > 80) {
13143
+ result += `${prefix}${connector}${item.name}${sep} ...80+ files...
13144
+ `;
13145
+ } else {
13146
+ result += `${prefix}${connector}${item.name}${sep}
13147
+ `;
13148
+ result += getDirTreeBox(filePath, maxDepth, childPrefix, depth + 1, safeReaddir, collapsedDirs);
13149
+ }
13150
+ }
13151
+ } else {
13152
+ result += `${prefix}${connector}${item.name}
13153
+ `;
13154
+ }
13155
+ });
13156
+ return result;
13157
+ };
13158
+ }
13159
+ });
13160
+
13029
13161
  // src/utils/ai.js
13030
13162
  var ai_exports = {};
13031
13163
  __export(ai_exports, {
@@ -13042,9 +13174,9 @@ __export(ai_exports, {
13042
13174
  });
13043
13175
  import dotenv from "dotenv";
13044
13176
  import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
13045
- import path25, { normalize } from "path";
13046
- import fs26 from "fs";
13047
- var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, client, globalSettings, dirTreeCache, cachedChatId2, getCachedDirTree, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
13177
+ import path27, { normalize } from "path";
13178
+ import fs28 from "fs";
13179
+ var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, client, globalSettings, dirTreeCache, cachedChatId2, cachedIndentationTree, getCachedDirTree, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
13048
13180
  var init_ai = __esm({
13049
13181
  async "src/utils/ai.js"() {
13050
13182
  await init_prompts();
@@ -13064,6 +13196,8 @@ var init_ai = __esm({
13064
13196
  init_revert();
13065
13197
  init_advanceRevert();
13066
13198
  init_editor();
13199
+ init_indentation();
13200
+ init_box();
13067
13201
  dotenv.config({ quiet: true });
13068
13202
  RE_STUTTER_CODE_BLOCK_CLOSED = /```[\s\S]*?```/g;
13069
13203
  RE_STUTTER_CODE_BLOCK_OPEN = /```[\s\S]*$/g;
@@ -13079,15 +13213,18 @@ var init_ai = __esm({
13079
13213
  globalSettings = {};
13080
13214
  dirTreeCache = null;
13081
13215
  cachedChatId2 = null;
13082
- getCachedDirTree = (fn, chatId, isDynamicDirAwareness) => {
13216
+ cachedIndentationTree = null;
13217
+ getCachedDirTree = (fn, chatId, isDynamicDirAwareness, indentationTree) => {
13083
13218
  if (isDynamicDirAwareness) {
13084
13219
  dirTreeCache = null;
13085
13220
  cachedChatId2 = chatId;
13221
+ cachedIndentationTree = indentationTree;
13086
13222
  return fn();
13087
13223
  }
13088
- if (cachedChatId2 !== chatId) {
13224
+ if (cachedChatId2 !== chatId || cachedIndentationTree !== indentationTree) {
13089
13225
  dirTreeCache = null;
13090
13226
  cachedChatId2 = chatId;
13227
+ cachedIndentationTree = indentationTree;
13091
13228
  }
13092
13229
  if (dirTreeCache === null) {
13093
13230
  dirTreeCache = fn();
@@ -14039,7 +14176,7 @@ var init_ai = __esm({
14039
14176
  return pArgs.id || pArgs.taskId;
14040
14177
  }
14041
14178
  const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
14042
- return filePath ? path25.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
14179
+ return filePath ? path27.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
14043
14180
  } catch (e) {
14044
14181
  return null;
14045
14182
  }
@@ -14304,9 +14441,9 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14304
14441
  }
14305
14442
  })() : String(err);
14306
14443
  await new Promise((resolve) => setTimeout(resolve, 1e3));
14307
- const janitorErrDir = path25.join(LOGS_DIR, "janitor");
14308
- if (!fs26.existsSync(janitorErrDir)) fs26.mkdirSync(janitorErrDir, { recursive: true });
14309
- fs26.appendFileSync(path25.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${errLog}
14444
+ const janitorErrDir = path27.join(LOGS_DIR, "janitor");
14445
+ if (!fs28.existsSync(janitorErrDir)) fs28.mkdirSync(janitorErrDir, { recursive: true });
14446
+ fs28.appendFileSync(path27.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${errLog}
14310
14447
 
14311
14448
  `);
14312
14449
  if (attempts > MAX_JANITOR_RETRIES) break;
@@ -14315,8 +14452,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14315
14452
  }
14316
14453
  }
14317
14454
  if (attempts) {
14318
- const janitorErrDir = path25.join(LOGS_DIR, "janitor");
14319
- fs26.appendFileSync(path25.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
14455
+ const janitorErrDir = path27.join(LOGS_DIR, "janitor");
14456
+ fs28.appendFileSync(path27.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
14320
14457
 
14321
14458
  `);
14322
14459
  }
@@ -14850,10 +14987,10 @@ ${newMemoryListStr}
14850
14987
  }
14851
14988
  })() : String(err);
14852
14989
  ;
14853
- const janitorLogDir = path25.join(LOGS_DIR, "janitor");
14854
- if (!fs26.existsSync(janitorLogDir)) fs26.mkdirSync(janitorLogDir, { recursive: true });
14855
- fs26.appendFileSync(
14856
- path25.join(janitorLogDir, "error.log"),
14990
+ const janitorLogDir = path27.join(LOGS_DIR, "janitor");
14991
+ if (!fs28.existsSync(janitorLogDir)) fs28.mkdirSync(janitorLogDir, { recursive: true });
14992
+ fs28.appendFileSync(
14993
+ path27.join(janitorLogDir, "error.log"),
14857
14994
  `[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${errLog}
14858
14995
  `
14859
14996
  );
@@ -14861,7 +14998,7 @@ ${newMemoryListStr}
14861
14998
  };
14862
14999
  compressHistory = async (settings, history, isAuto = false) => {
14863
15000
  const { chatId, aiProvider = "Google" } = settings;
14864
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
15001
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
14865
15002
  const flattenContext = (hist) => {
14866
15003
  return hist.filter(
14867
15004
  (m) => (m.role === "user" || m.role === "agent" || m.role === "system") && m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !String(m.id).startsWith("welcome")
@@ -14936,8 +15073,8 @@ Provide a consolidated summary of the entire session.`;
14936
15073
  };
14937
15074
  deleteChatSummary = (chatId) => {
14938
15075
  try {
14939
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
14940
- if (fs26.existsSync(summariesFile)) {
15076
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
15077
+ if (fs28.existsSync(summariesFile)) {
14941
15078
  const summaries = readEncryptedJson(summariesFile, {});
14942
15079
  if (summaries[chatId]) {
14943
15080
  delete summaries[chatId];
@@ -14953,7 +15090,7 @@ Provide a consolidated summary of the entire session.`;
14953
15090
  if (!client && aiProvider === "Google") throw new Error("AI not initialized");
14954
15091
  const isMemoryEnabled = systemSettings?.memory !== false;
14955
15092
  const originalText = history[history.length - 1].text;
14956
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
15093
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
14957
15094
  let wasCompressedInStream = false;
14958
15095
  const isFirstPrompt = history.filter((m) => m.role === "user").length === 1;
14959
15096
  const hasTitleSignal = originalText.includes("[TITLE-UPDATE]");
@@ -15200,7 +15337,7 @@ Provide a consolidated summary of the entire session.`;
15200
15337
  ];
15201
15338
  const safeReaddirWithTypes = (dir) => {
15202
15339
  try {
15203
- return fs26.readdirSync(dir, { withFileTypes: true });
15340
+ return fs28.readdirSync(dir, { withFileTypes: true });
15204
15341
  } catch (e) {
15205
15342
  return [];
15206
15343
  }
@@ -15213,62 +15350,14 @@ Provide a consolidated summary of the entire session.`;
15213
15350
  if (COLLAPSED_DIRS_GLOBAL.includes(entry.name) || entry.name.startsWith(".")) continue;
15214
15351
  if (entry.isDirectory()) {
15215
15352
  currentCount.value++;
15216
- countFolders(path25.join(dir, entry.name), currentCount, depth + 1);
15353
+ countFolders(path27.join(dir, entry.name), currentCount, depth + 1);
15217
15354
  }
15218
15355
  }
15219
15356
  return currentCount.value;
15220
15357
  };
15221
- const getDirTree = (dir, maxDepth, prefix = "", depth = 1) => {
15222
- const entries = safeReaddirWithTypes(dir);
15223
- const sep = path25.sep;
15224
- if (entries.length > 100) {
15225
- return `${prefix}\u2514\u2500\u2500 ${path25.basename(dir)}${sep} ...100+ files...
15226
- `;
15227
- }
15228
- let result = "";
15229
- const COLLAPSED_DIRS = COLLAPSED_DIRS_GLOBAL;
15230
- const filtered = entries.filter((e) => !COLLAPSED_DIRS.includes(e.name) && !e.name.startsWith("."));
15231
- const collapsedInDir = entries.filter((e) => COLLAPSED_DIRS.includes(e.name) || e.name.startsWith(".")).map((e) => e.name).sort();
15232
- filtered.sort((a, b) => {
15233
- if (a.isDirectory() && !b.isDirectory()) return -1;
15234
- if (!a.isDirectory() && b.isDirectory()) return 1;
15235
- return a.name.localeCompare(b.name);
15236
- });
15237
- const finalItems = [
15238
- ...filtered.map((e) => ({ name: e.name, isDir: e.isDirectory() })),
15239
- ...collapsedInDir.map((name) => ({ name, isDir: true, isCollapsed: true }))
15240
- ];
15241
- finalItems.forEach((item, index) => {
15242
- const isLast = index === finalItems.length - 1;
15243
- const filePath = path25.join(dir, item.name);
15244
- const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
15245
- const childPrefix = prefix + (isLast ? " " : "\u2502 ");
15246
- if (item.isCollapsed) {
15247
- result += `${prefix}${connector}${item.name}${sep}...
15248
- `;
15249
- return;
15250
- }
15251
- if (item.isDir) {
15252
- if (depth > maxDepth) {
15253
- result += `${prefix}${connector}${item.name}${sep} ...depth exceeded...
15254
- `;
15255
- } else {
15256
- const subEntries = safeReaddirWithTypes(filePath);
15257
- if (subEntries.length > 80) {
15258
- result += `${prefix}${connector}${item.name}${sep} ...80+ files...
15259
- `;
15260
- } else {
15261
- result += `${prefix}${connector}${item.name}${sep}
15262
- `;
15263
- result += getDirTree(filePath, maxDepth, childPrefix, depth + 1);
15264
- }
15265
- }
15266
- } else {
15267
- result += `${prefix}${connector}${item.name}
15268
- `;
15269
- }
15270
- });
15271
- return result;
15358
+ const getDirTree = (dir, maxDepth) => {
15359
+ const useModern = systemSettings?.indentationTree !== false;
15360
+ return useModern ? getDirTreeIndentation(dir, maxDepth, 1, safeReaddirWithTypes, COLLAPSED_DIRS_GLOBAL) : getDirTreeBox(dir, maxDepth, "", 1, safeReaddirWithTypes, COLLAPSED_DIRS_GLOBAL);
15272
15361
  };
15273
15362
  const totalFolders = countFolders(process.cwd());
15274
15363
  let dynamicMaxDepth = 12;
@@ -15318,16 +15407,16 @@ ${currentSummary}
15318
15407
  ${currentSummary}
15319
15408
  ` : "";
15320
15409
  let dirStructure = "\n**DIRECTORY STRUCTURE**\nCWD: " + process.cwd() + `${isPlayground ? " [PLAYGROUND MODE]" : ""}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
15321
- ` + getCachedDirTree(() => getDirTree(process.cwd(), dynamicMaxDepth), chatId, systemSettings?.dynamicDirAwareness);
15410
+ ` + getCachedDirTree(() => getDirTree(process.cwd(), dynamicMaxDepth), chatId, systemSettings?.dynamicDirAwareness, systemSettings?.indentationTree);
15322
15411
  const ideCtx = await getIDEContext();
15323
15412
  let ideBlock = "";
15324
15413
  if (isBridgeConnected()) {
15325
15414
  ideBlock = "\n[ADDITIONAL IDE CONTEXT]\n";
15326
15415
  if (ideCtx.file_focused !== "none") {
15327
- const relFocused = path25.relative(process.cwd(), ideCtx.file_focused);
15416
+ const relFocused = path27.relative(process.cwd(), ideCtx.file_focused);
15328
15417
  const relOpened = (ideCtx.opened_editors || []).map((p) => {
15329
- const rel = path25.relative(process.cwd(), p);
15330
- return rel.startsWith("..") ? `[External] ${path25.basename(p)}` : rel;
15418
+ const rel = path27.relative(process.cwd(), p);
15419
+ return rel.startsWith("..") ? `[External] ${path27.basename(p)}` : rel;
15331
15420
  });
15332
15421
  ideBlock += `Focused File: ${relFocused}
15333
15422
  Cursor Line: ${ideCtx.cursor_line}
@@ -15369,7 +15458,7 @@ Cursor Line: ${ideCtx.cursor_line}
15369
15458
  }
15370
15459
  const getSumForLimit = (limit, activeFiles2) => {
15371
15460
  return activeFiles2.reduce((sum, f) => {
15372
- const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused || path25.resolve(process.cwd(), f.path) === path25.resolve(ideCtx.file_focused));
15461
+ const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused || path27.resolve(process.cwd(), f.path) === path27.resolve(ideCtx.file_focused));
15373
15462
  const fileLimit = isFocused ? Math.ceil(limit * 1.2) : limit;
15374
15463
  return sum + Math.min(f.edits.length, fileLimit);
15375
15464
  }, 0);
@@ -15403,7 +15492,7 @@ Cursor Line: ${ideCtx.cursor_line}
15403
15492
  }
15404
15493
  }
15405
15494
  for (const file of activeFiles) {
15406
- const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused || path25.resolve(process.cwd(), file.path) === path25.resolve(ideCtx.file_focused));
15495
+ const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused || path27.resolve(process.cwd(), file.path) === path27.resolve(ideCtx.file_focused));
15407
15496
  const fileLimit = isFocused ? Math.ceil(chosenLimit * 1.2) : chosenLimit;
15408
15497
  if (file.edits.length > fileLimit) {
15409
15498
  file.edits = file.edits.slice(-fileLimit);
@@ -15490,9 +15579,9 @@ ${ideCtx.warnings}
15490
15579
  endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
15491
15580
  filePath = tagClean.slice(0, matchRange.index);
15492
15581
  }
15493
- const absPath = path25.resolve(process.cwd(), filePath);
15494
- if (fs26.existsSync(absPath)) {
15495
- const stats = fs26.statSync(absPath);
15582
+ const absPath = path27.resolve(process.cwd(), filePath);
15583
+ if (fs28.existsSync(absPath)) {
15584
+ const stats = fs28.statSync(absPath);
15496
15585
  if (stats.isFile()) {
15497
15586
  const pathLower = filePath.toLowerCase();
15498
15587
  const isPdf = pathLower.endsWith(".pdf");
@@ -15501,7 +15590,7 @@ ${ideCtx.warnings}
15501
15590
  const isMultimodalFile = isImage || isPdf || isOfficeFile;
15502
15591
  const isSupported = aiProvider === "Google" || isModelMultimodal(modelName);
15503
15592
  if (isMultimodalFile && !isSupported) {
15504
- const label = `\u2718 Unsupported Modality: ${path25.basename(filePath)}`;
15593
+ const label = `\u2718 Unsupported Modality: ${path27.basename(filePath)}`;
15505
15594
  let terminalWidth = 115;
15506
15595
  if (process.stdout.isTTY) {
15507
15596
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -15517,11 +15606,11 @@ ${ideCtx.warnings}
15517
15606
  if (startLine === null && !isMultimodalFile) {
15518
15607
  let lineCount = 0;
15519
15608
  try {
15520
- lineCount = fs26.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
15609
+ lineCount = fs28.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
15521
15610
  } catch (e) {
15522
15611
  }
15523
15612
  if (lineCount > 300) {
15524
- const label = `\u21B7 Skipped (Too Large): ${path25.basename(filePath)}`;
15613
+ const label = `\u21B7 Skipped (Too Large): ${path27.basename(filePath)}`;
15525
15614
  let terminalWidth = 115;
15526
15615
  if (process.stdout.isTTY) {
15527
15616
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -15562,13 +15651,13 @@ ${ideCtx.warnings}
15562
15651
  if (!isError) {
15563
15652
  let label = "";
15564
15653
  if (isImage) {
15565
- label = `\u2714 Processed: ${path25.basename(filePath)}`;
15654
+ label = `\u2714 Processed: ${path27.basename(filePath)}`;
15566
15655
  attachedBinaryPart = binPart;
15567
15656
  } else if (isPdf || isOfficeFile) {
15568
- label = `\u2714 Auto-Analysed: ${path25.basename(filePath)}`;
15657
+ label = `\u2714 Auto-Analysed: ${path27.basename(filePath)}`;
15569
15658
  attachedBinaryPart = binPart;
15570
15659
  } else {
15571
- label = `\u2714 Auto-Read: ${path25.basename(filePath)}`;
15660
+ label = `\u2714 Auto-Read: ${path27.basename(filePath)}`;
15572
15661
  taggedContextBlocks.push(textResult);
15573
15662
  }
15574
15663
  if (label) {
@@ -15773,7 +15862,7 @@ ${cleanPromptForModel.trim()}
15773
15862
  currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? thinkingLevel : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt, aiProvider, aiProvider === "Google" ? true : isMultiModal, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? true : false, chatId);
15774
15863
  if (!systemSettings?.dynamicDirAwareness) {
15775
15864
  currentSystemInstruction += `
15776
- ${dirStructure.replace("\n**DIRECTORY STRUCTURE**", "\n**DIRECTORY STRUCTURE AT CONVERSATION START**")}`;
15865
+ ${dirStructure.replace("\n**DIRECTORY STRUCTURE**", "\n**DIRECTORY STRUCTURE**")}`;
15777
15866
  }
15778
15867
  const lastUserMsg = contents[contents.length - 1];
15779
15868
  if (isBridgeConnected() & loop > 0) {
@@ -16248,7 +16337,7 @@ ${ideErr} [/ERROR]`;
16248
16337
  if (keyword !== void 0 && keyword !== null) {
16249
16338
  detail = String(keyword).replace(RE_STRIP_QUOTES, "");
16250
16339
  } else if (filePath) {
16251
- detail = path25.basename(String(filePath).replace(RE_STRIP_QUOTES, "").replace(RE_BACKSLASH_SLASH, "/"));
16340
+ detail = path27.basename(String(filePath).replace(RE_STRIP_QUOTES, "").replace(RE_BACKSLASH_SLASH, "/"));
16252
16341
  } else if (title && (potentialTool === "invoke" || potentialTool === "invoke_sync")) {
16253
16342
  detail = String(title).replace(RE_STRIP_QUOTES, "").substring(0, 30);
16254
16343
  } else if (id && potentialTool === "get_progress") {
@@ -16277,7 +16366,7 @@ ${ideErr} [/ERROR]`;
16277
16366
  if (potentialTool === "invoke" || potentialTool === "invoke_sync" || potentialTool === "get_progress") {
16278
16367
  detail = val.substring(0, 30);
16279
16368
  } else {
16280
- detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val : path25.basename(val.replace(RE_BACKSLASH_SLASH, "/"));
16369
+ detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val : path27.basename(val.replace(RE_BACKSLASH_SLASH, "/"));
16281
16370
  }
16282
16371
  }
16283
16372
  }
@@ -16483,9 +16572,9 @@ ${ideErr} [/ERROR]`;
16483
16572
  let totalLines = "...";
16484
16573
  let actualEndLine = eLine;
16485
16574
  try {
16486
- const absPath = path25.resolve(process.cwd(), targetPath2);
16487
- if (fs26.existsSync(absPath)) {
16488
- const content = fs26.readFileSync(absPath, "utf8");
16575
+ const absPath = path27.resolve(process.cwd(), targetPath2);
16576
+ if (fs28.existsSync(absPath)) {
16577
+ const content = fs28.readFileSync(absPath, "utf8");
16489
16578
  const lines = content.split("\n").length;
16490
16579
  totalLines = lines;
16491
16580
  if (!rawStart && !rawEnd && lines > 800) {
@@ -16501,30 +16590,30 @@ ${ideErr} [/ERROR]`;
16501
16590
  const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
16502
16591
  const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
16503
16592
  if (isPdf || isOfficeFile) {
16504
- label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Analyzed: ${path25.basename(targetPath2)}` : "Analyzed: File Not Found"}`;
16593
+ label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Analyzed: ${path27.basename(targetPath2)}` : "Analyzed: File Not Found"}`;
16505
16594
  } else if (isImage) {
16506
- label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Processed: ${path25.basename(targetPath2)}` : "Processed: File Not Found"}`;
16595
+ label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Processed: ${path27.basename(targetPath2)}` : "Processed: File Not Found"}`;
16507
16596
  } else {
16508
- label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${targetPath2 ? `${path25.basename(targetPath2)} \u2192 ${totalLines !== "..." ? `Lines ${sLine} - ${actualEndLine} of ${totalLines}` : "File Not Found"}` : "File Not Found"}`;
16597
+ label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${targetPath2 ? `${path27.basename(targetPath2)} \u2192 ${totalLines !== "..." ? `Lines ${sLine} - ${actualEndLine} of ${totalLines}` : "File Not Found"}` : "File Not Found"}`;
16509
16598
  }
16510
16599
  } else if (normToolName === "list_files" || normToolName === "read_folder") {
16511
16600
  const action = normToolName === "list_files" ? "List" : "Browsed";
16512
- const path27 = parseArgs(toolCall.args).path || null;
16601
+ const path29 = parseArgs(toolCall.args).path || null;
16513
16602
  const recurse = parseArgs(toolCall.args).recurse || 0;
16514
- label = `${path27 ? "\u2714" : "\u2718"} ${action}: ${path27 ? `${path27 === "." ? "./" : `${path27}${recurse > 0 ? `${path27.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path27.endsWith("/") ? "" : "/"}`}`}` : "No Folder Selected"}`;
16603
+ label = `${path29 ? "\u2714" : "\u2718"} ${action}: ${path29 ? `${path29 === "." ? "./" : `${path29.replaceAll("\\", "/")}${recurse > 0 ? `${path29.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path29.endsWith("/") ? "" : "/"}`}`}` : "No Folder Selected"}`;
16515
16604
  } else if (normToolName === "write_file" || normToolName === "update_file") {
16516
16605
  const action = normToolName === "write_file" ? "Created" : "Edited";
16517
- const path27 = parseArgs(toolCall.args).path || null;
16518
- label = `${path27 ? "\u2714" : "\u2718"} ${action}: ${path27 || "No File Changes"}`;
16606
+ const path29 = parseArgs(toolCall.args).path || null;
16607
+ label = `${path29 ? "\u2714" : "\u2718"} ${action}: ${path29.replaceAll("\\", "/") || "No File Changes"}`;
16519
16608
  } else if (normToolName === "write_pdf") {
16520
- const path27 = parseArgs(toolCall.args).path || null;
16521
- label = `${path27 ? "\u2714" : "\u2718"} Generated: ${path27 || "No PDF Generated"}`;
16609
+ const path29 = parseArgs(toolCall.args).path || null;
16610
+ label = `${path29 ? "\u2714" : "\u2718"} Generated: ${path29.replaceAll("\\", "/") || "No PDF Generated"}`;
16522
16611
  } else if (normToolName === "write_docx") {
16523
- const path27 = parseArgs(toolCall.args).path || null;
16524
- label = `${path27 ? "\u2714" : "\u2718"} Generated: ${path27 || "No Docx Generated"}`;
16612
+ const path29 = parseArgs(toolCall.args).path || null;
16613
+ label = `${path29 ? "\u2714" : "\u2718"} Generated: ${path29.replaceAll("\\", "/") || "No Docx Generated"}`;
16525
16614
  } else if (normToolName === "file_map") {
16526
- const path27 = parseArgs(toolCall.args).path;
16527
- label = `${path27 ? "\u2714" : "\u2718"} Indexed: ${path27 ? "" + path27 : "File Not Found"}`;
16615
+ const path29 = parseArgs(toolCall.args).path;
16616
+ label = `${path29 ? "\u2714" : "\u2718"} Indexed: ${path29.replaceAll("\\", "/") ? "" + path29 : "File Not Found"}`;
16528
16617
  } else if (normToolName.toLowerCase() === "search_keyword" || normToolName.toLowerCase() === "todo") {
16529
16618
  label = "";
16530
16619
  } else if (normToolName.toLowerCase() === "generate_image") {
@@ -16599,7 +16688,7 @@ ${ideErr} [/ERROR]`;
16599
16688
  const { command } = parseArgs(toolCall.args);
16600
16689
  if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
16601
16690
  const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
16602
- const currentDrive = path25.resolve(process.cwd()).substring(0, 3).toLowerCase();
16691
+ const currentDrive = path27.resolve(process.cwd()).substring(0, 3).toLowerCase();
16603
16692
  const splitCommands = (cmdString) => {
16604
16693
  const commands = [];
16605
16694
  let current = "";
@@ -16728,8 +16817,8 @@ ${ideErr} [/ERROR]`;
16728
16817
  const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
16729
16818
  if (targetPath) {
16730
16819
  const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
16731
- const absoluteTarget = path25.resolve(targetPath);
16732
- const absoluteCwd = path25.resolve(process.cwd());
16820
+ const absoluteTarget = path27.resolve(targetPath);
16821
+ const absoluteCwd = path27.resolve(process.cwd());
16733
16822
  if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
16734
16823
  const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
16735
16824
  if (normToolName === "write_file" || normToolName === "update_file") {
@@ -16918,7 +17007,7 @@ ${ideErr} [/ERROR]`;
16918
17007
  const toolArgs = parseArgs(toolCall.args);
16919
17008
  const { path: filePath } = toolArgs;
16920
17009
  if (filePath) {
16921
- const absPath = path25.resolve(process.cwd(), filePath);
17010
+ const absPath = path27.resolve(process.cwd(), filePath);
16922
17011
  const normalize2 = (p) => p ? p.toLowerCase().replace(/\\/g, "/").replace(/^[a-z]:/, (m) => m.toUpperCase()) : "";
16923
17012
  const normAbsPath = normalize2(absPath);
16924
17013
  let originalContent = "";
@@ -16928,8 +17017,8 @@ ${ideErr} [/ERROR]`;
16928
17017
  if (currentIDE && normFocused === normAbsPath && currentIDE.full_content) {
16929
17018
  originalContent = currentIDE.full_content;
16930
17019
  hasOriginal = true;
16931
- } else if (fs26.existsSync(absPath)) {
16932
- originalContent = fs26.readFileSync(absPath, "utf8");
17020
+ } else if (fs28.existsSync(absPath)) {
17021
+ originalContent = fs28.readFileSync(absPath, "utf8");
16933
17022
  hasOriginal = true;
16934
17023
  }
16935
17024
  originalContentForReporting = originalContent;
@@ -16957,9 +17046,9 @@ ${ideErr} [/ERROR]`;
16957
17046
  const successes = patchResults.filter((r) => r.success);
16958
17047
  const failures = patchResults.filter((r) => !r.success);
16959
17048
  if (successes.length === 0) {
16960
- const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${path25.basename(absPath)}].
17049
+ const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${path27.basename(absPath)}].
16961
17050
  ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
16962
- const errorLabel = `\u2714 Edited: ${path25.basename(absPath)}`;
17051
+ const errorLabel = `\u2714 Edited: ${path27.basename(absPath.replaceAll("\\", "/"))}`;
16963
17052
  let terminalWidth = 115;
16964
17053
  if (process.stdout.isTTY) {
16965
17054
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -16976,19 +17065,19 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
16976
17065
  continue;
16977
17066
  }
16978
17067
  }
16979
- yield { type: "status", content: `Opening Diff in IDE: ${path25.basename(absPath)}` };
17068
+ yield { type: "status", content: `Opening Diff in IDE: ${path27.basename(absPath)}` };
16980
17069
  showDiffInIDE(absPath, originalContent, modifiedContent);
16981
17070
  diffOpened = true;
16982
17071
  await new Promise((r) => setTimeout(r, 50));
16983
17072
  } else if (normToolName === "write_file") {
16984
17073
  const rawContent = toolArgs.content || toolArgs.newContent || "";
16985
17074
  const modifiedContent = rawContent.endsWith("\n") ? rawContent : rawContent + "\n";
16986
- if (!fs26.existsSync(absPath)) {
17075
+ if (!fs28.existsSync(absPath)) {
16987
17076
  isNewFileCreated = true;
16988
- fs26.mkdirSync(path25.dirname(absPath), { recursive: true });
16989
- fs26.writeFileSync(absPath, "", "utf8");
17077
+ fs28.mkdirSync(path27.dirname(absPath), { recursive: true });
17078
+ fs28.writeFileSync(absPath, "", "utf8");
16990
17079
  }
16991
- yield { type: "status", content: `Opening New File Diff in IDE: ${path25.basename(absPath)}` };
17080
+ yield { type: "status", content: `Opening New File Diff in IDE: ${path27.basename(absPath)}` };
16992
17081
  showDiffInIDE(absPath, "", modifiedContent);
16993
17082
  diffOpened = true;
16994
17083
  await new Promise((r) => setTimeout(r, 50));
@@ -17024,11 +17113,11 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
17024
17113
  if (normToolName === "write_file" || normToolName === "update_file") {
17025
17114
  const { path: filePath } = parseArgs(toolCall.args);
17026
17115
  if (filePath) {
17027
- const absPath = path25.resolve(process.cwd(), filePath);
17116
+ const absPath = path27.resolve(process.cwd(), filePath);
17028
17117
  closeDiffInIDE(absPath, approval);
17029
- if (approval === "deny" && isNewFileCreated && fs26.existsSync(absPath)) {
17118
+ if (approval === "deny" && isNewFileCreated && fs28.existsSync(absPath)) {
17030
17119
  try {
17031
- fs26.unlinkSync(absPath);
17120
+ fs28.unlinkSync(absPath);
17032
17121
  } catch (e) {
17033
17122
  }
17034
17123
  }
@@ -17040,18 +17129,18 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
17040
17129
  }
17041
17130
  if (approval === "allow" && diffOpened && isBridgeConnected()) {
17042
17131
  const { path: filePath } = parseArgs(toolCall.args);
17043
- const absPath = path25.resolve(process.cwd(), filePath);
17044
- const normPath = (p) => p ? path25.resolve(p).replace(/\\/g, "/").toLowerCase() : "";
17132
+ const absPath = path27.resolve(process.cwd(), filePath);
17133
+ const normPath = (p) => p ? path27.resolve(p).replace(/\\/g, "/").toLowerCase() : "";
17045
17134
  const finalIDE = await getIDEContext();
17046
17135
  let finalContent = "";
17047
17136
  if (finalIDE && finalIDE.file_focused && normPath(finalIDE.file_focused) === normPath(absPath) && finalIDE.full_content) {
17048
17137
  finalContent = finalIDE.full_content;
17049
17138
  }
17050
- if (!finalContent && fs26.existsSync(absPath)) {
17051
- finalContent = fs26.readFileSync(absPath, "utf8");
17139
+ if (!finalContent && fs28.existsSync(absPath)) {
17140
+ finalContent = fs28.readFileSync(absPath, "utf8");
17052
17141
  if (!finalContent) {
17053
17142
  await new Promise((r) => setTimeout(r, 100));
17054
- finalContent = fs26.readFileSync(absPath, "utf8");
17143
+ finalContent = fs28.readFileSync(absPath, "utf8");
17055
17144
  }
17056
17145
  }
17057
17146
  const verifiedLines = finalContent.split(/\r?\n/);
@@ -17114,7 +17203,7 @@ ${ancestry2}- Content Preview:
17114
17203
  ${snippet2}`;
17115
17204
  }
17116
17205
  const action = normToolName === "write_file" ? "Created" : "Edited";
17117
- const feedbackLabel = `${filePath ? "\u2714" : "\u2718"} ${action}: ${filePath || "No File Changes"}`;
17206
+ const feedbackLabel = `${filePath ? "\u2714" : "\u2718"} ${action}: ${filePath.replaceAll("\\", "/") || "No File Changes"}`;
17118
17207
  let terminalWidth = 115;
17119
17208
  if (process.stdout.isTTY) {
17120
17209
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -17148,7 +17237,7 @@ ${snippet2}`;
17148
17237
  }
17149
17238
  if (normToolName === "write_file" || normToolName === "update_file") {
17150
17239
  const action = normToolName === "write_file" ? "Write Cancelled" : "Edit Denied";
17151
- const deniedLabel = `\u2718 ${action}: ${parseArgs(toolCall.args).path || "..."}`;
17240
+ const deniedLabel = `\u2718 ${action}: ${parseArgs(toolCall.args).path.replaceAll("\\", "/") || "..."}`;
17152
17241
  let terminalWidth = 115;
17153
17242
  if (process.stdout.isTTY) {
17154
17243
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -17212,7 +17301,7 @@ ${snippet2}`;
17212
17301
  try {
17213
17302
  const { path: filePath } = parseArgs(toolCall.args);
17214
17303
  if (filePath) {
17215
- const absPath = path25.resolve(process.cwd(), filePath);
17304
+ const absPath = path27.resolve(process.cwd(), filePath);
17216
17305
  const currentIDE = await getIDEContext();
17217
17306
  if (currentIDE && currentIDE.file_focused === absPath && currentIDE.full_content) {
17218
17307
  execToolContext.forcedContent = currentIDE.full_content;
@@ -17226,7 +17315,7 @@ ${snippet2}`;
17226
17315
  if ((normToolName === "write_file" || normToolName === "update_file") && result.startsWith("SUCCESS")) {
17227
17316
  const { path: filePath } = parseArgs(toolCall.args);
17228
17317
  if (filePath) {
17229
- const absPath = path25.resolve(process.cwd(), filePath);
17318
+ const absPath = path27.resolve(process.cwd(), filePath);
17230
17319
  openFileInEditor(absPath);
17231
17320
  }
17232
17321
  }
@@ -17243,7 +17332,7 @@ ${snippet2}`;
17243
17332
  result = result.text;
17244
17333
  }
17245
17334
  if (normToolName === "search_keyword") {
17246
- const { keyword, path: path27 } = parseArgs(toolCall.args);
17335
+ const { keyword, path: path29 } = parseArgs(toolCall.args);
17247
17336
  const _isDir = typeof result === "string" && result.startsWith("[DIR]");
17248
17337
  if (_isDir) result = result.slice(5);
17249
17338
  let matchCount = 0;
@@ -17253,9 +17342,9 @@ ${snippet2}`;
17253
17342
  matchCount = parseInt(m[1]);
17254
17343
  }
17255
17344
  }
17256
- const _sp = path27 ? path27.replace(/[\/\\]+$/, "") : null;
17345
+ const _sp = path29 ? path29.replace(/[\/\\]+$/, "") : null;
17257
17346
  const displayPath = _sp && _sp !== "." ? `"${_isDir ? `${_sp}/*` : _sp}"` : "./";
17258
- const postLabel = `${keyword ? "\u2714" : "\u2718"} Searched: "${keyword ? keyword : ""}" in ${displayPath} \u2192 ${matchCount} Match${matchCount === 1 ? "" : "es"}`;
17347
+ const postLabel = `${keyword ? "\u2714" : "\u2718"} Searched: "${keyword ? keyword : ""}" in ${displayPath.replaceAll("\\", "/")} \u2192 ${matchCount} Match${matchCount === 1 ? "" : "es"}`;
17259
17348
  let terminalWidth = 115;
17260
17349
  if (process.stdout.isTTY) {
17261
17350
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -17493,9 +17582,9 @@ ${snippet2}`;
17493
17582
  })() : String(err);
17494
17583
  ;
17495
17584
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
17496
- const agentErrDir = path25.join(LOGS_DIR, "agent");
17497
- if (!fs26.existsSync(agentErrDir)) fs26.mkdirSync(agentErrDir, { recursive: true });
17498
- fs26.appendFileSync(path25.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
17585
+ const agentErrDir = path27.join(LOGS_DIR, "agent");
17586
+ if (!fs28.existsSync(agentErrDir)) fs28.mkdirSync(agentErrDir, { recursive: true });
17587
+ fs28.appendFileSync(path27.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
17499
17588
 
17500
17589
  ----------------------------------------------------------------------
17501
17590
 
@@ -17542,7 +17631,7 @@ ${recoveryText}`
17542
17631
  yield { type: "status", content: `Error Occured. Recovering Stream...` };
17543
17632
  } else {
17544
17633
  throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
17545
- Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17634
+ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
17546
17635
  }
17547
17636
  } else {
17548
17637
  if (retryCount <= MAX_RETRIES) {
@@ -17560,7 +17649,7 @@ Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17560
17649
  yield { type: "status", content: `Trying to reach ${modelName}` };
17561
17650
  } else {
17562
17651
  throw new Error(`Model ${modelName} cannot be reached. (Failed ${MAX_RETRIES} times)
17563
- Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17652
+ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
17564
17653
  }
17565
17654
  }
17566
17655
  }
@@ -17679,10 +17768,10 @@ Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17679
17768
  }
17680
17769
  })() : String(err);
17681
17770
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
17682
- const agentErrDir = path25.join(LOGS_DIR, "agent");
17771
+ const agentErrDir = path27.join(LOGS_DIR, "agent");
17683
17772
  yield { type: "text", content: `\u274C CRITICAL ERROR: ${errLog.includes("fetch failed") ? "Failed to Connect. Check your Internet Connection or Wait a moment" : errLog}` };
17684
- if (!fs26.existsSync(agentErrDir)) fs26.mkdirSync(agentErrDir, { recursive: true });
17685
- fs26.appendFileSync(path25.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${err}
17773
+ if (!fs28.existsSync(agentErrDir)) fs28.mkdirSync(agentErrDir, { recursive: true });
17774
+ fs28.appendFileSync(path27.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${err}
17686
17775
 
17687
17776
  ----------------------------------------------------------------------
17688
17777
 
@@ -17829,24 +17918,24 @@ ${cleanResponse}
17829
17918
  const pArgs = parseArgs(toolCall.args);
17830
17919
  const keyword = pArgs.keyword || "";
17831
17920
  const keywordPath = pArgs.path || "";
17832
- label = `${keyword ? "\u2714" : "\u2718"} \x1B[95mSearched\x1B[0m: ${keyword || "No Query"}${keywordPath ? ` \u2192 ${keywordPath}` : ""}`;
17921
+ label = `${keyword ? "\u2714" : "\u2718"} \x1B[95mSearched\x1B[0m: ${keyword || "No Query"}${keywordPath ? ` \u2192 ${keywordPath.replaceAll("\\", "/")}` : ""}`;
17833
17922
  } else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
17834
- const path27 = parseArgs(toolCall.args).path || "";
17835
- label = `\u2714 \x1B[95mRead\x1B[0m: ${path27}`;
17923
+ const path29 = parseArgs(toolCall.args).path || "";
17924
+ label = `\u2714 \x1B[95mRead\x1B[0m: ${path29.replaceAll("\\", "/")}`;
17836
17925
  } else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
17837
- const path27 = parseArgs(toolCall.args).path || null;
17926
+ const path29 = parseArgs(toolCall.args).path || null;
17838
17927
  const recurse = parseArgs(toolCall.args).recurse || 0;
17839
- label = `${path27 ? "\u2714" : "\u2718"} \x1B[95mBrowsed\x1B[0m: ${path27 ? `${path27}${recurse > 0 ? `${path27.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path27.endsWith("/") ? "" : "/"}`}` : ""}`;
17928
+ label = `${path29 ? "\u2714" : "\u2718"} \x1B[95mBrowsed\x1B[0m: ${path29 ? `${path29.replaceAll("\\", "/")}${recurse > 0 ? `${path29.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path29.endsWith("/") ? "" : "/"}`}` : ""}`;
17840
17929
  } else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
17841
- const path27 = parseArgs(toolCall.args).path || null;
17842
- label = `${path27 ? "\u2714" : "\u2718"} \x1B[95mCreated\x1B[0m: ${path27 ? `${path27}` : "No File Changes"}`;
17930
+ const path29 = parseArgs(toolCall.args).path || null;
17931
+ label = `${path29 ? "\u2714" : "\u2718"} \x1B[95mCreated\x1B[0m: ${path29 ? `${path29.replaceAll("\\", "/")}` : "No File Changes"}`;
17843
17932
  } else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
17844
- const path27 = parseArgs(toolCall.args).path || null;
17933
+ const path29 = parseArgs(toolCall.args).path || null;
17845
17934
  const content = parseArgs(toolCall.args).content || null;
17846
- label = `${path27 ? "\u2714" : "\u2718"} \x1B[95mEdited\x1B[0m: ${path27 ? `${path27}` : "No File Changes"}`;
17935
+ label = `${path29 ? "\u2714" : "\u2718"} \x1B[95mEdited\x1B[0m: ${path29 ? `${path29.replaceAll("\\", "/")}` : "No File Changes"}`;
17847
17936
  } else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
17848
- const path27 = parseArgs(toolCall.args).path || "";
17849
- label = `${path27 ? "\u2714" : "\u2718"} \x1B[95mIndexed\x1B[0m: ${path27 ? `${path27}` : "File Not Found"}`;
17937
+ const path29 = parseArgs(toolCall.args).path || "";
17938
+ label = `${path29 ? "\u2714" : "\u2718"} \x1B[95mIndexed\x1B[0m: ${path29 ? `${path29.replaceAll("\\", "/")}` : "File Not Found"}`;
17850
17939
  } else if (normalizedToolName === "await") {
17851
17940
  const { time } = parseArgs(toolCall.args);
17852
17941
  let sec = parseFloat(time) || 0;
@@ -18842,7 +18931,7 @@ var init_RevertModal = __esm({
18842
18931
  import puppeteer4 from "puppeteer";
18843
18932
  import { exec } from "child_process";
18844
18933
  import { promisify } from "util";
18845
- import fs27 from "fs";
18934
+ import fs29 from "fs";
18846
18935
  var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
18847
18936
  var init_setup = __esm({
18848
18937
  "src/utils/setup.js"() {
@@ -18851,11 +18940,11 @@ var init_setup = __esm({
18851
18940
  checkPuppeteerReady = () => {
18852
18941
  try {
18853
18942
  const pptrConfig = getPuppeteerConfig();
18854
- if (pptrConfig.executablePath && fs27.existsSync(pptrConfig.executablePath)) {
18943
+ if (pptrConfig.executablePath && fs29.existsSync(pptrConfig.executablePath)) {
18855
18944
  return true;
18856
18945
  }
18857
18946
  const exePath = puppeteer4.executablePath();
18858
- const exists = exePath && fs27.existsSync(exePath);
18947
+ const exists = exePath && fs29.existsSync(exePath);
18859
18948
  if (exists) return true;
18860
18949
  } catch (e) {
18861
18950
  return false;
@@ -18942,8 +19031,8 @@ __export(app_exports, {
18942
19031
  import os5 from "os";
18943
19032
  import React16, { useState as useState15, useEffect as useEffect12, useRef as useRef4, useMemo as useMemo2 } from "react";
18944
19033
  import { Box as Box14, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
18945
- import fs28 from "fs-extra";
18946
- import path26 from "path";
19034
+ import fs30 from "fs-extra";
19035
+ import path28 from "path";
18947
19036
  import { exec as exec2 } from "child_process";
18948
19037
  import { fileURLToPath as fileURLToPath3 } from "url";
18949
19038
  import TextInput4 from "ink-text-input";
@@ -19270,10 +19359,10 @@ function App({ args = [] }) {
19270
19359
  const kbPath = getKeybindingsPath(ideName);
19271
19360
  if (!kbPath) return;
19272
19361
  try {
19273
- await fs28.ensureDir(path26.dirname(kbPath));
19362
+ await fs30.ensureDir(path28.dirname(kbPath));
19274
19363
  let bindings = [];
19275
- if (fs28.existsSync(kbPath)) {
19276
- const content = fs28.readFileSync(kbPath, "utf8").trim();
19364
+ if (fs30.existsSync(kbPath)) {
19365
+ const content = fs30.readFileSync(kbPath, "utf8").trim();
19277
19366
  if (content) {
19278
19367
  try {
19279
19368
  bindings = parseJsonc(content);
@@ -19293,7 +19382,7 @@ function App({ args = [] }) {
19293
19382
  },
19294
19383
  "when": "terminalFocus"
19295
19384
  });
19296
- fs28.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
19385
+ fs30.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
19297
19386
  cachedShortcut = "Shift + Enter";
19298
19387
  setMessages((prev) => {
19299
19388
  setCompletedIndex(prev.length + 1);
@@ -20017,7 +20106,7 @@ function App({ args = [] }) {
20017
20106
  useEffect12(() => {
20018
20107
  async function init() {
20019
20108
  try {
20020
- const pkg = JSON.parse(fs28.readFileSync(path26.join(process.cwd(), "package.json"), "utf8"));
20109
+ const pkg = JSON.parse(fs30.readFileSync(path28.join(process.cwd(), "package.json"), "utf8"));
20021
20110
  initBridge(versionFluxflow || pkg.version || "2.0.0");
20022
20111
  } catch (e) {
20023
20112
  initBridge("2.0.0");
@@ -20131,7 +20220,7 @@ function App({ args = [] }) {
20131
20220
  if (!parsedArgs.playground) {
20132
20221
  deleteChat(PLAYGROUND_CHAT_ID).catch(() => {
20133
20222
  });
20134
- fs28.remove(path26.join(DATA_DIR, "playground")).catch(() => {
20223
+ fs30.remove(path28.join(DATA_DIR, "playground")).catch(() => {
20135
20224
  });
20136
20225
  }
20137
20226
  performVersionCheck(false, freshSettings);
@@ -20165,9 +20254,9 @@ function App({ args = [] }) {
20165
20254
  }
20166
20255
  }
20167
20256
  if (parsedArgs.playground) {
20168
- const playgroundDir = path26.join(DATA_DIR, "playground");
20257
+ const playgroundDir = path28.join(DATA_DIR, "playground");
20169
20258
  try {
20170
- fs28.ensureDirSync(playgroundDir);
20259
+ fs30.ensureDirSync(playgroundDir);
20171
20260
  process.chdir(playgroundDir);
20172
20261
  } catch (e) {
20173
20262
  }
@@ -20208,8 +20297,8 @@ function App({ args = [] }) {
20208
20297
  if (kbPath) {
20209
20298
  try {
20210
20299
  let bindings = [];
20211
- if (fs28.existsSync(kbPath)) {
20212
- const content = fs28.readFileSync(kbPath, "utf8").trim();
20300
+ if (fs30.existsSync(kbPath)) {
20301
+ const content = fs30.readFileSync(kbPath, "utf8").trim();
20213
20302
  if (content) {
20214
20303
  bindings = parseJsonc(content);
20215
20304
  }
@@ -20587,22 +20676,22 @@ ${cleanText}`, color: "magenta" }];
20587
20676
  });
20588
20677
  break;
20589
20678
  }
20590
- const src = path26.join(DATA_DIR, "playground");
20591
- const dest = path26.join(parsedArgs.originalCwd, "playground-export");
20679
+ const src = path28.join(DATA_DIR, "playground");
20680
+ const dest = path28.join(parsedArgs.originalCwd, "playground-export");
20592
20681
  const moveFiles = async () => {
20593
20682
  try {
20594
20683
  setMessages((prev) => {
20595
20684
  setCompletedIndex(prev.length + 1);
20596
20685
  return [...prev, { id: Date.now(), role: "system", text: `[PLAYGROUND] Exporting playground content to ${dest}`, isMeta: true }];
20597
20686
  });
20598
- await fs28.ensureDir(dest);
20687
+ await fs30.ensureDir(dest);
20599
20688
  const excludeDirs = ["node_modules", ".git", ".venv", "venv", "env", ".next", "dist", "build", ".cache"];
20600
- await fs28.copy(src, dest, {
20689
+ await fs30.copy(src, dest, {
20601
20690
  overwrite: true,
20602
20691
  filter: (srcPath) => {
20603
- const relative = path26.relative(src, srcPath);
20692
+ const relative = path28.relative(src, srcPath);
20604
20693
  if (!relative) return true;
20605
- const parts2 = relative.split(path26.sep);
20694
+ const parts2 = relative.split(path28.sep);
20606
20695
  return !parts2.some((part) => excludeDirs.includes(part));
20607
20696
  }
20608
20697
  });
@@ -20664,7 +20753,7 @@ ${cleanText}`, color: "magenta" }];
20664
20753
  }
20665
20754
  }
20666
20755
  setTimeout(() => {
20667
- fs28.emptyDir(path26.join(DATA_DIR, "playground")).catch((err) => {
20756
+ fs30.emptyDir(path28.join(DATA_DIR, "playground")).catch((err) => {
20668
20757
  setMessages((prev) => {
20669
20758
  const newMsgs = [...prev, {
20670
20759
  id: "playground-" + Date.now(),
@@ -21054,12 +21143,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
21054
21143
  setCompletedIndex(prev.length + 1);
21055
21144
  return [...prev, { id: Date.now(), role: "system", text: "[NUCLEAR] Initiating reset...", isMeta: true }];
21056
21145
  });
21057
- if (fs28.existsSync(LOGS_DIR)) fs28.removeSync(LOGS_DIR);
21058
- if (fs28.existsSync(SECRET_DIR)) fs28.removeSync(SECRET_DIR);
21059
- if (fs28.existsSync(SETTINGS_FILE)) fs28.removeSync(SETTINGS_FILE);
21146
+ if (fs30.existsSync(LOGS_DIR)) fs30.removeSync(LOGS_DIR);
21147
+ if (fs30.existsSync(SECRET_DIR)) fs30.removeSync(SECRET_DIR);
21148
+ if (fs30.existsSync(SETTINGS_FILE)) fs30.removeSync(SETTINGS_FILE);
21060
21149
  try {
21061
- const items = fs28.readdirSync(FLUXFLOW_DIR);
21062
- if (items.length === 0) fs28.removeSync(FLUXFLOW_DIR);
21150
+ const items = fs30.readdirSync(FLUXFLOW_DIR);
21151
+ if (items.length === 0) fs30.removeSync(FLUXFLOW_DIR);
21063
21152
  } catch (e) {
21064
21153
  }
21065
21154
  setTimeout(() => {
@@ -21181,15 +21270,15 @@ ${list || "No saved chats found."}`, isMeta: true }];
21181
21270
  # SKILLS & WORKFLOWS
21182
21271
  - [Define custom step-by-step recipes for this project here]
21183
21272
  `;
21184
- const filePath = path26.join(process.cwd(), "FluxFlow.md");
21185
- if (fs28.pathExistsSync(filePath)) {
21273
+ const filePath = path28.join(process.cwd(), "FluxFlow.md");
21274
+ if (fs30.pathExistsSync(filePath)) {
21186
21275
  setMessages((prev) => {
21187
21276
  setCompletedIndex(prev.length + 1);
21188
21277
  return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
21189
21278
  });
21190
21279
  } else {
21191
21280
  try {
21192
- fs28.writeFileSync(filePath, template);
21281
+ fs30.writeFileSync(filePath, template);
21193
21282
  setMessages((prev) => {
21194
21283
  setCompletedIndex(prev.length + 1);
21195
21284
  return [...prev, { id: "init-ok-" + Date.now(), role: "system", text: "[SUCCESS] FluxFlow.md has been initialized. You can now customize it for this project.", isMeta: true }];
@@ -23480,11 +23569,11 @@ var init_app = __esm({
23480
23569
  if (process.platform === "win32") {
23481
23570
  const appData = process.env.APPDATA;
23482
23571
  if (!appData) return null;
23483
- return path26.join(appData, dirName, "User", "keybindings.json");
23572
+ return path28.join(appData, dirName, "User", "keybindings.json");
23484
23573
  } else if (process.platform === "darwin") {
23485
- return path26.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
23574
+ return path28.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
23486
23575
  } else {
23487
- return path26.join(home, ".config", dirName, "User", "keybindings.json");
23576
+ return path28.join(home, ".config", dirName, "User", "keybindings.json");
23488
23577
  }
23489
23578
  };
23490
23579
  parseJsonc = (content) => {
@@ -23528,8 +23617,8 @@ var init_app = __esm({
23528
23617
  SESSION_START_TIME = Date.now();
23529
23618
  CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog";
23530
23619
  DOCS_URL = "https://fluxflow-cli.onrender.com/";
23531
- packageJsonPath = path26.join(path26.dirname(fileURLToPath3(import.meta.url)), "../package.json");
23532
- packageJson = JSON.parse(fs28.readFileSync(packageJsonPath, "utf8"));
23620
+ packageJsonPath = path28.join(path28.dirname(fileURLToPath3(import.meta.url)), "../package.json");
23621
+ packageJson = JSON.parse(fs30.readFileSync(packageJsonPath, "utf8"));
23533
23622
  versionFluxflow = packageJson.version;
23534
23623
  updatedOn = packageJson.date || "2026-05-20";
23535
23624
  ResolutionModal = ({ data, onResolve, onEdit, theme = "Dark" }) => {
@@ -23563,20 +23652,20 @@ var init_app = __esm({
23563
23652
  const scan = (currentDir) => {
23564
23653
  if (fileList.length >= 2e3) return;
23565
23654
  try {
23566
- const files = fs28.readdirSync(currentDir);
23655
+ const files = fs30.readdirSync(currentDir);
23567
23656
  for (const file of files) {
23568
23657
  if (fileList.length >= 2e3) return;
23569
23658
  if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
23570
23659
  continue;
23571
23660
  }
23572
- const filePath = path26.join(currentDir, file);
23573
- const stat = fs28.statSync(filePath);
23661
+ const filePath = path28.join(currentDir, file);
23662
+ const stat = fs30.statSync(filePath);
23574
23663
  if (stat.isDirectory()) {
23575
23664
  scan(filePath);
23576
23665
  } else {
23577
23666
  fileList.push({
23578
23667
  name: flattenString(file),
23579
- relativePath: flattenString(path26.relative(process.cwd(), filePath))
23668
+ relativePath: flattenString(path28.relative(process.cwd(), filePath))
23580
23669
  });
23581
23670
  }
23582
23671
  }
@@ -23776,11 +23865,11 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
23776
23865
  const isUpdate = args[0] === "--update";
23777
23866
  const isExport = args[0] === "--export";
23778
23867
  if (isVersion || isHelp || isHelpCommands || isUpdate || isExport) {
23779
- const fs29 = await import("fs");
23780
- const path27 = await import("path");
23868
+ const fs31 = await import("fs");
23869
+ const path29 = await import("path");
23781
23870
  const { fileURLToPath: fileURLToPath5 } = await import("url");
23782
- const packageJsonPath2 = path27.join(path27.dirname(fileURLToPath5(import.meta.url)), "../package.json");
23783
- const packageJson2 = JSON.parse(fs29.readFileSync(packageJsonPath2, "utf8"));
23871
+ const packageJsonPath2 = path29.join(path29.dirname(fileURLToPath5(import.meta.url)), "../package.json");
23872
+ const packageJson2 = JSON.parse(fs31.readFileSync(packageJsonPath2, "utf8"));
23784
23873
  const versionFluxflow2 = packageJson2.version;
23785
23874
  if (isExport) {
23786
23875
  const subArg = (args[1] || "").toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.15.0",
3
+ "version": "3.15.2",
4
4
  "date": "2026-07-31",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [