fluxflow-cli 3.14.2 → 3.15.1

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 +404 -242
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -779,7 +779,9 @@ var init_settings = __esm({
779
779
  loadingPhrases: true,
780
780
  progressiveRendering: true,
781
781
  showTPMEstimate: false,
782
- subAgents: true
782
+ subAgents: true,
783
+ dynamicDirAwareness: false,
784
+ indentationTree: true
783
785
  },
784
786
  profileData: {
785
787
  name: null,
@@ -6706,25 +6708,25 @@ Tool calls: ONLY use [tool:functions.ToolName(args)]
6706
6708
  - MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
6707
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' : ""}
6708
6710
  - COMMUNICATION TOOLS -
6709
- 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
6710
6712
 
6711
6713
  - WEB TOOLS -
6712
- 1. [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
6713
- 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
6714
6716
 
6715
6717
  ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
6716
- 1. [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
6717
- 2. [tool:functions.ReadFolder(path="...", recurse="integer 0-4 optional, default: 0")]. Detailed DIR stats including File Sizes
6718
- 3. [tool:functions.FileMap(path="file")]. Shows file structure
6719
- 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
6720
- 5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
6721
- 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
6722
- 7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
6723
- 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' : ""}
6724
6726
  ${_cachedAdvanceRollback ? `
6725
6727
  - EMERGENCY SAFETY TOOLS -
6726
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
6727
- 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.
6728
6730
  Use ONLY for catastrophic/codebase corruption. Before ending loop, verify no catastrophe. \`id\` not required with \`getCheckPoint\`.
6729
6731
  ` : ""}${enableSubAgents ? `
6730
6732
  - SUB AGENT TOOLS -
@@ -6732,11 +6734,11 @@ Use ONLY for catastrophic/codebase corruption. Before ending loop, verify no cat
6732
6734
  Invocations:
6733
6735
  - Invoke (async/background, \u22647 parallel). Parallelize long tasks. NEVER repeat while active
6734
6736
  - InvokeSync (sync/blocking). Sequential, repetitive or delegated tasks. Saves tokens/cost
6735
- 1. [agent:generalist.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
6736
- 2. [agent:generalist.GetProgress(id="...")]. Check async task progress. If still running, continue your work. Wait exponentially longer between checks
6737
- 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: '/') -
6738
- 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
6739
- 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
6740
6742
  - WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}`.trim();
6741
6743
  };
6742
6744
  }
@@ -7511,6 +7513,8 @@ function SettingsMenu({
7511
7513
  return [
7512
7514
  { label: "Sub-Agents", value: "subAgents", status: systemSettings.subAgents !== false ? "ON" : "OFF" },
7513
7515
  { label: "Preserve Thinking", value: "preserveThinking", status: systemSettings.preserveThinking !== false ? "ON" : "OFF" },
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)" },
7514
7518
  { label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
7515
7519
  ];
7516
7520
  default:
@@ -7565,6 +7569,11 @@ function SettingsMenu({
7565
7569
  setActiveView("chat");
7566
7570
  }
7567
7571
  } else if (activeColumn === "items") {
7572
+ const currentItem = currentItems[selectedItemIndex];
7573
+ if (input === "?" && currentItem?.value === "dynamicDirAwareness") {
7574
+ setActiveView("dynamicDirHelp");
7575
+ return;
7576
+ }
7568
7577
  if (key.upArrow) {
7569
7578
  setSelectedItemIndex((prev) => (prev - 1 + currentItems.length) % currentItems.length);
7570
7579
  } else if (key.downArrow) {
@@ -7690,6 +7699,12 @@ function SettingsMenu({
7690
7699
  setActiveView("updateManager");
7691
7700
  } else if (item.value === "parserDownload") {
7692
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
+ });
7693
7708
  } else if (item.value === "subAgents") {
7694
7709
  setSystemSettings((s) => {
7695
7710
  const newSysSettings = { ...s, subAgents: s.subAgents === false ? true : false };
@@ -7702,6 +7717,16 @@ function SettingsMenu({
7702
7717
  saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
7703
7718
  return newSysSettings;
7704
7719
  });
7720
+ } else if (item.value === "dynamicDirAwareness") {
7721
+ if (!systemSettings.dynamicDirAwareness) {
7722
+ setActiveView("dynamicDirDanger");
7723
+ } else {
7724
+ setSystemSettings((s) => {
7725
+ const newSysSettings = { ...s, dynamicDirAwareness: false };
7726
+ saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
7727
+ return newSysSettings;
7728
+ });
7729
+ }
7705
7730
  } else if (item.value === "loadingPhrases") {
7706
7731
  setSystemSettings((s) => {
7707
7732
  const newSysSettings = { ...s, loadingPhrases: s.loadingPhrases === false ? true : false };
@@ -7825,7 +7850,7 @@ function SettingsMenu({
7825
7850
  );
7826
7851
  }
7827
7852
  return elements;
7828
- })() : /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, flexDirection: "column", width: "100%" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, CATEGORIES[selectedCategoryIndex].desc), currentCatId === "exit" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop: 19, paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: colors.text }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited")), /* @__PURE__ */ React7.createElement(Box6, { key: "memory-load-2026", paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Memory Load: ", currentMemory, "/", maxMemory, " ", memoryUnit)))))), /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginTop: 0, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, activeColumn === "categories" ? "\u25B2\u25BC Select Category \u2022 Enter/\u25BA to configure" : "\u25B2\u25BC Select Option \u2022 Enter to Toggle \u2022 \u25C4/ESC to go back"), activeColumn === "categories" && /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, CATEGORIES[selectedCategoryIndex].desc)));
7853
+ })() : /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, flexDirection: "column", width: "100%" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, CATEGORIES[selectedCategoryIndex].desc), currentCatId === "exit" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop: 19, paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: colors.text }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited")), /* @__PURE__ */ React7.createElement(Box6, { key: "memory-load-2026", paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Memory Load: ", currentMemory, "/", maxMemory, " ", memoryUnit)))))), /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginTop: 0, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, activeColumn === "categories" ? "\u25B2\u25BC Select Category \u2022 Enter/\u25BA to configure" : currentItems[selectedItemIndex]?.value === "dynamicDirAwareness" ? "\u25B2\u25BC Select Option \u2022 Enter to Toggle \u2022 ? HELP \u2022 \u25C4/ESC to go back" : "\u25B2\u25BC Select Option \u2022 Enter to Toggle \u2022 \u25C4/ESC to go back"), activeColumn === "categories" && /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, CATEGORIES[selectedCategoryIndex].desc)));
7829
7854
  }
7830
7855
  var themeOptions, CATEGORIES, getActivePreset, truncateCSV;
7831
7856
  var init_SettingsMenu = __esm({
@@ -8056,16 +8081,16 @@ var init_janitor_tools = __esm({
8056
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
8057
8082
 
8058
8083
  -- CHAT MANAGEMENT TOOLS (MUST CALL THESE 2 TOOLS IN THIS TURN) --
8059
- 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
8060
- 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
8061
8086
 
8062
8087
  ${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
8063
- 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)
8064
- 2. Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
8065
- 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>")]
8066
8091
 
8067
8092
  -- Memory Relevance Decay Tool --
8068
- 1. Score Adjustment: [tool:functions.addMemScore(id="<memory id>")]
8093
+ - Score Adjustment: [tool:functions.addMemScore(id="<memory id>")]
8069
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
8070
8095
 
8071
8096
  Explicit Triggers for permanent memory:
@@ -8142,8 +8167,7 @@ var init_prompts = __esm({
8142
8167
  if (!isMemoryEnabled) return "";
8143
8168
  const tempMemoriesStr = tempMemories?.length > 0 && !isContext32k ? `-- RECENT CONTEXT FROM OTHER CHATS (PRIORITY: DYNAMIC-LOW, FOCUS: Chat Context > Recent) --
8144
8169
  ${tempMemories}` : "";
8145
- return tempMemoriesStr ? `${tempMemoriesStr}
8146
- ` : "";
8170
+ return tempMemoriesStr ? `${tempMemoriesStr}` : "";
8147
8171
  };
8148
8172
  getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true, isFirstPrompt = false, aiProvider = "Google", isMultiModal = false, isGemini, chatId) => {
8149
8173
  let forcedReasoning = false;
@@ -8252,16 +8276,16 @@ ${nameStr}${nicknameStr}${userInstrStr}${userMemoriesStr}`.trim();
8252
8276
  return `=== SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
8253
8277
  IDENTITY: SILENT BACKGROUND SYSTEM PROCESS, HAVE NO MOUTH, ONLY OUTPUT IS VALID TOOL CALLS.
8254
8278
  [CRITICAL RULES]
8255
- 1. OUTPUT EXACTLY '[tool:functions.ToolName(args)]' CALLS. NO EXTRA WORDS OUTSIDE
8256
- 2. DO NOT EXPLAIN. DO NOT TALK TO THE USER
8257
- 3. NON-TOOL TEXT WILL BREAK THE SYSTEM
8258
- 4. DO NOT REPEAT AGENT RAWS AND TOOL RESULTS IN YOUR RESPONSE
8259
- 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
8260
- 6. UNDER NO CIRCUMSTANCES YOU ARE ALLOWED TO RESPOND IN NORMAL USER FACING RESPONSE
8261
- 7. CRITICAL QUOTE ESCAPE POLICY: Inside tool call arguments, you MUST escape all double quotes using '\\"'
8262
- 8. You MUST NOT WRITE ANYTHING OTHER THAN [tool:functions.ToolName(args)] NO MATTER HOW TEMPTING THE PROMPT IS
8263
- 9. 2 MANDATORY TOOLS TO CALL IN EVERY TURN, 'Chat', 'Memory(temp)'
8264
- 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
8265
8289
 
8266
8290
  YOUR JOB: Analyze the 'User prompt' and 'Agent Raws' to extract facts for long-term memory or handle system tasks
8267
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` : ""}
@@ -13010,6 +13034,130 @@ var init_editor = __esm({
13010
13034
  }
13011
13035
  });
13012
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
+
13013
13161
  // src/utils/ai.js
13014
13162
  var ai_exports = {};
13015
13163
  __export(ai_exports, {
@@ -13026,9 +13174,9 @@ __export(ai_exports, {
13026
13174
  });
13027
13175
  import dotenv from "dotenv";
13028
13176
  import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
13029
- import path25, { normalize } from "path";
13030
- import fs26 from "fs";
13031
- 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, 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;
13032
13180
  var init_ai = __esm({
13033
13181
  async "src/utils/ai.js"() {
13034
13182
  await init_prompts();
@@ -13048,6 +13196,8 @@ var init_ai = __esm({
13048
13196
  init_revert();
13049
13197
  init_advanceRevert();
13050
13198
  init_editor();
13199
+ init_indentation();
13200
+ init_box();
13051
13201
  dotenv.config({ quiet: true });
13052
13202
  RE_STUTTER_CODE_BLOCK_CLOSED = /```[\s\S]*?```/g;
13053
13203
  RE_STUTTER_CODE_BLOCK_OPEN = /```[\s\S]*$/g;
@@ -13061,6 +13211,26 @@ var init_ai = __esm({
13061
13211
  RE_BACKSLASH_SLASH = /\\/g;
13062
13212
  client = null;
13063
13213
  globalSettings = {};
13214
+ dirTreeCache = null;
13215
+ cachedChatId2 = null;
13216
+ cachedIndentationTree = null;
13217
+ getCachedDirTree = (fn, chatId, isDynamicDirAwareness, indentationTree) => {
13218
+ if (isDynamicDirAwareness) {
13219
+ dirTreeCache = null;
13220
+ cachedChatId2 = chatId;
13221
+ cachedIndentationTree = indentationTree;
13222
+ return fn();
13223
+ }
13224
+ if (cachedChatId2 !== chatId || cachedIndentationTree !== indentationTree) {
13225
+ dirTreeCache = null;
13226
+ cachedChatId2 = chatId;
13227
+ cachedIndentationTree = indentationTree;
13228
+ }
13229
+ if (dirTreeCache === null) {
13230
+ dirTreeCache = fn();
13231
+ }
13232
+ return dirTreeCache;
13233
+ };
13064
13234
  colorMainWords = (label) => {
13065
13235
  if (!label) return label;
13066
13236
  return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
@@ -14006,7 +14176,7 @@ var init_ai = __esm({
14006
14176
  return pArgs.id || pArgs.taskId;
14007
14177
  }
14008
14178
  const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
14009
- return filePath ? path25.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
14179
+ return filePath ? path27.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
14010
14180
  } catch (e) {
14011
14181
  return null;
14012
14182
  }
@@ -14271,9 +14441,9 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14271
14441
  }
14272
14442
  })() : String(err);
14273
14443
  await new Promise((resolve) => setTimeout(resolve, 1e3));
14274
- const janitorErrDir = path25.join(LOGS_DIR, "janitor");
14275
- if (!fs26.existsSync(janitorErrDir)) fs26.mkdirSync(janitorErrDir, { recursive: true });
14276
- 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}
14277
14447
 
14278
14448
  `);
14279
14449
  if (attempts > MAX_JANITOR_RETRIES) break;
@@ -14282,8 +14452,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14282
14452
  }
14283
14453
  }
14284
14454
  if (attempts) {
14285
- const janitorErrDir = path25.join(LOGS_DIR, "janitor");
14286
- fs26.appendFileSync(path25.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
14455
+ const janitorErrDir = path27.join(LOGS_DIR, "janitor");
14456
+ fs28.appendFileSync(path27.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
14287
14457
 
14288
14458
  `);
14289
14459
  }
@@ -14302,16 +14472,17 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14302
14472
  }
14303
14473
  };
14304
14474
  getActiveToolContext = (text) => {
14475
+ const cleanText = text.replace(/(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])/gi, "").replace(/(?:<(think|thought)>|\[(think|thought)\])[\s\S]*$/gi, "");
14305
14476
  RE_TOOL_CALL_FUNC.lastIndex = 0;
14306
14477
  let match;
14307
- while ((match = RE_TOOL_CALL_FUNC.exec(text)) !== null) {
14478
+ while ((match = RE_TOOL_CALL_FUNC.exec(cleanText)) !== null) {
14308
14479
  const startIdx = match.index + match[0].length - 1;
14309
14480
  let balance = 0;
14310
14481
  let inString = null;
14311
14482
  let isEscaped = false;
14312
14483
  let closed = false;
14313
- for (let i = startIdx; i < text.length; i++) {
14314
- const char = text[i];
14484
+ for (let i = startIdx; i < cleanText.length; i++) {
14485
+ const char = cleanText[i];
14315
14486
  if (!inString && (char === '"' || char === "'" || char === "`")) {
14316
14487
  inString = char;
14317
14488
  isEscaped = false;
@@ -14323,8 +14494,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14323
14494
  else if (char === ")") balance--;
14324
14495
  if (balance === 0) {
14325
14496
  let j = i + 1;
14326
- while (j < text.length && /\s/.test(text[j])) j++;
14327
- if (j < text.length && text[j] === "]") {
14497
+ while (j < cleanText.length && /\s/.test(cleanText[j])) j++;
14498
+ if (j < cleanText.length && cleanText[j] === "]") {
14328
14499
  closed = true;
14329
14500
  RE_TOOL_CALL_FUNC.lastIndex = j + 1;
14330
14501
  break;
@@ -14335,7 +14506,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
14335
14506
  else isEscaped = false;
14336
14507
  }
14337
14508
  if (!closed) {
14338
- return { inside: true, toolName: match[1], startIndex: match.index, args: text.substring(match.index + match[0].length) };
14509
+ return { inside: true, toolName: match[1], startIndex: match.index, args: cleanText.substring(match.index + match[0].length) };
14339
14510
  }
14340
14511
  }
14341
14512
  return { inside: false };
@@ -14816,10 +14987,10 @@ ${newMemoryListStr}
14816
14987
  }
14817
14988
  })() : String(err);
14818
14989
  ;
14819
- const janitorLogDir = path25.join(LOGS_DIR, "janitor");
14820
- if (!fs26.existsSync(janitorLogDir)) fs26.mkdirSync(janitorLogDir, { recursive: true });
14821
- fs26.appendFileSync(
14822
- 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"),
14823
14994
  `[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${errLog}
14824
14995
  `
14825
14996
  );
@@ -14827,7 +14998,7 @@ ${newMemoryListStr}
14827
14998
  };
14828
14999
  compressHistory = async (settings, history, isAuto = false) => {
14829
15000
  const { chatId, aiProvider = "Google" } = settings;
14830
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
15001
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
14831
15002
  const flattenContext = (hist) => {
14832
15003
  return hist.filter(
14833
15004
  (m) => (m.role === "user" || m.role === "agent" || m.role === "system") && m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !String(m.id).startsWith("welcome")
@@ -14902,8 +15073,8 @@ Provide a consolidated summary of the entire session.`;
14902
15073
  };
14903
15074
  deleteChatSummary = (chatId) => {
14904
15075
  try {
14905
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
14906
- if (fs26.existsSync(summariesFile)) {
15076
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
15077
+ if (fs28.existsSync(summariesFile)) {
14907
15078
  const summaries = readEncryptedJson(summariesFile, {});
14908
15079
  if (summaries[chatId]) {
14909
15080
  delete summaries[chatId];
@@ -14919,7 +15090,7 @@ Provide a consolidated summary of the entire session.`;
14919
15090
  if (!client && aiProvider === "Google") throw new Error("AI not initialized");
14920
15091
  const isMemoryEnabled = systemSettings?.memory !== false;
14921
15092
  const originalText = history[history.length - 1].text;
14922
- const summariesFile = path25.join(SECRET_DIR, "chat-summaries.json");
15093
+ const summariesFile = path27.join(SECRET_DIR, "chat-summaries.json");
14923
15094
  let wasCompressedInStream = false;
14924
15095
  const isFirstPrompt = history.filter((m) => m.role === "user").length === 1;
14925
15096
  const hasTitleSignal = originalText.includes("[TITLE-UPDATE]");
@@ -15006,7 +15177,7 @@ Provide a consolidated summary of the entire session.`;
15006
15177
  const otherMemories = [...cachedSummaries, ...otherRawMemories].map((mem) => `- ${mem}`).join("\n");
15007
15178
  const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
15008
15179
  const mainUserMemories = persistentStorage.map((m) => `- ${m.memory}`).join("\n");
15009
- const isContext32k = (sessionStats?.tokens || 0) >= 12e3;
15180
+ const isContext32k = (sessionStats?.tokens || 0) >= 1e4;
15010
15181
  const memoryPrompt = getMemoryPrompt(otherMemories, mainUserMemories, isMemoryEnabled, isContext32k);
15011
15182
  const dateTimeStr = (/* @__PURE__ */ new Date()).toLocaleString([], { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit", hour12: true });
15012
15183
  const COLLAPSED_DIRS_GLOBAL = [
@@ -15166,7 +15337,7 @@ Provide a consolidated summary of the entire session.`;
15166
15337
  ];
15167
15338
  const safeReaddirWithTypes = (dir) => {
15168
15339
  try {
15169
- return fs26.readdirSync(dir, { withFileTypes: true });
15340
+ return fs28.readdirSync(dir, { withFileTypes: true });
15170
15341
  } catch (e) {
15171
15342
  return [];
15172
15343
  }
@@ -15179,62 +15350,14 @@ Provide a consolidated summary of the entire session.`;
15179
15350
  if (COLLAPSED_DIRS_GLOBAL.includes(entry.name) || entry.name.startsWith(".")) continue;
15180
15351
  if (entry.isDirectory()) {
15181
15352
  currentCount.value++;
15182
- countFolders(path25.join(dir, entry.name), currentCount, depth + 1);
15353
+ countFolders(path27.join(dir, entry.name), currentCount, depth + 1);
15183
15354
  }
15184
15355
  }
15185
15356
  return currentCount.value;
15186
15357
  };
15187
- const getDirTree = (dir, maxDepth, prefix = "", depth = 1) => {
15188
- const entries = safeReaddirWithTypes(dir);
15189
- const sep = path25.sep;
15190
- if (entries.length > 100) {
15191
- return `${prefix}\u2514\u2500\u2500 ${path25.basename(dir)}${sep} ...100+ files...
15192
- `;
15193
- }
15194
- let result = "";
15195
- const COLLAPSED_DIRS = COLLAPSED_DIRS_GLOBAL;
15196
- const filtered = entries.filter((e) => !COLLAPSED_DIRS.includes(e.name) && !e.name.startsWith("."));
15197
- const collapsedInDir = entries.filter((e) => COLLAPSED_DIRS.includes(e.name) || e.name.startsWith(".")).map((e) => e.name).sort();
15198
- filtered.sort((a, b) => {
15199
- if (a.isDirectory() && !b.isDirectory()) return -1;
15200
- if (!a.isDirectory() && b.isDirectory()) return 1;
15201
- return a.name.localeCompare(b.name);
15202
- });
15203
- const finalItems = [
15204
- ...filtered.map((e) => ({ name: e.name, isDir: e.isDirectory() })),
15205
- ...collapsedInDir.map((name) => ({ name, isDir: true, isCollapsed: true }))
15206
- ];
15207
- finalItems.forEach((item, index) => {
15208
- const isLast = index === finalItems.length - 1;
15209
- const filePath = path25.join(dir, item.name);
15210
- const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
15211
- const childPrefix = prefix + (isLast ? " " : "\u2502 ");
15212
- if (item.isCollapsed) {
15213
- result += `${prefix}${connector}${item.name}${sep}...
15214
- `;
15215
- return;
15216
- }
15217
- if (item.isDir) {
15218
- if (depth > maxDepth) {
15219
- result += `${prefix}${connector}${item.name}${sep} ...depth exceeded...
15220
- `;
15221
- } else {
15222
- const subEntries = safeReaddirWithTypes(filePath);
15223
- if (subEntries.length > 80) {
15224
- result += `${prefix}${connector}${item.name}${sep} ...80+ files...
15225
- `;
15226
- } else {
15227
- result += `${prefix}${connector}${item.name}${sep}
15228
- `;
15229
- result += getDirTree(filePath, maxDepth, childPrefix, depth + 1);
15230
- }
15231
- }
15232
- } else {
15233
- result += `${prefix}${connector}${item.name}
15234
- `;
15235
- }
15236
- });
15237
- 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);
15238
15361
  };
15239
15362
  const totalFolders = countFolders(process.cwd());
15240
15363
  let dynamicMaxDepth = 12;
@@ -15283,17 +15406,17 @@ ${currentSummary}
15283
15406
  **CONTEXT SUMMARY OF PREVIOUS TURNS**
15284
15407
  ${currentSummary}
15285
15408
  ` : "";
15286
- let dirStructure = "CWD: " + process.cwd() + `${isPlayground ? " [PLAYGROUND MODE]" : ""}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
15287
- ` + getDirTree(process.cwd(), dynamicMaxDepth);
15409
+ let dirStructure = "\n**DIRECTORY STRUCTURE**\nCWD: " + process.cwd() + `${isPlayground ? " [PLAYGROUND MODE]" : ""}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
15410
+ ` + getCachedDirTree(() => getDirTree(process.cwd(), dynamicMaxDepth), chatId, systemSettings?.dynamicDirAwareness, systemSettings?.indentationTree);
15288
15411
  const ideCtx = await getIDEContext();
15289
15412
  let ideBlock = "";
15290
15413
  if (isBridgeConnected()) {
15291
- ideBlock = "[ADDITIONAL IDE CONTEXT]\n";
15414
+ ideBlock = "\n[ADDITIONAL IDE CONTEXT]\n";
15292
15415
  if (ideCtx.file_focused !== "none") {
15293
- const relFocused = path25.relative(process.cwd(), ideCtx.file_focused);
15416
+ const relFocused = path27.relative(process.cwd(), ideCtx.file_focused);
15294
15417
  const relOpened = (ideCtx.opened_editors || []).map((p) => {
15295
- const rel = path25.relative(process.cwd(), p);
15296
- 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;
15297
15420
  });
15298
15421
  ideBlock += `Focused File: ${relFocused}
15299
15422
  Cursor Line: ${ideCtx.cursor_line}
@@ -15335,7 +15458,7 @@ Cursor Line: ${ideCtx.cursor_line}
15335
15458
  }
15336
15459
  const getSumForLimit = (limit, activeFiles2) => {
15337
15460
  return activeFiles2.reduce((sum, f) => {
15338
- 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));
15339
15462
  const fileLimit = isFocused ? Math.ceil(limit * 1.2) : limit;
15340
15463
  return sum + Math.min(f.edits.length, fileLimit);
15341
15464
  }, 0);
@@ -15369,7 +15492,7 @@ Cursor Line: ${ideCtx.cursor_line}
15369
15492
  }
15370
15493
  }
15371
15494
  for (const file of activeFiles) {
15372
- 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));
15373
15496
  const fileLimit = isFocused ? Math.ceil(chosenLimit * 1.2) : chosenLimit;
15374
15497
  if (file.edits.length > fileLimit) {
15375
15498
  file.edits = file.edits.slice(-fileLimit);
@@ -15456,9 +15579,9 @@ ${ideCtx.warnings}
15456
15579
  endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
15457
15580
  filePath = tagClean.slice(0, matchRange.index);
15458
15581
  }
15459
- const absPath = path25.resolve(process.cwd(), filePath);
15460
- if (fs26.existsSync(absPath)) {
15461
- const stats = fs26.statSync(absPath);
15582
+ const absPath = path27.resolve(process.cwd(), filePath);
15583
+ if (fs28.existsSync(absPath)) {
15584
+ const stats = fs28.statSync(absPath);
15462
15585
  if (stats.isFile()) {
15463
15586
  const pathLower = filePath.toLowerCase();
15464
15587
  const isPdf = pathLower.endsWith(".pdf");
@@ -15467,7 +15590,7 @@ ${ideCtx.warnings}
15467
15590
  const isMultimodalFile = isImage || isPdf || isOfficeFile;
15468
15591
  const isSupported = aiProvider === "Google" || isModelMultimodal(modelName);
15469
15592
  if (isMultimodalFile && !isSupported) {
15470
- const label = `\u2718 Unsupported Modality: ${path25.basename(filePath)}`;
15593
+ const label = `\u2718 Unsupported Modality: ${path27.basename(filePath)}`;
15471
15594
  let terminalWidth = 115;
15472
15595
  if (process.stdout.isTTY) {
15473
15596
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -15483,11 +15606,11 @@ ${ideCtx.warnings}
15483
15606
  if (startLine === null && !isMultimodalFile) {
15484
15607
  let lineCount = 0;
15485
15608
  try {
15486
- lineCount = fs26.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
15609
+ lineCount = fs28.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
15487
15610
  } catch (e) {
15488
15611
  }
15489
15612
  if (lineCount > 300) {
15490
- const label = `\u21B7 Skipped (Too Large): ${path25.basename(filePath)}`;
15613
+ const label = `\u21B7 Skipped (Too Large): ${path27.basename(filePath)}`;
15491
15614
  let terminalWidth = 115;
15492
15615
  if (process.stdout.isTTY) {
15493
15616
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -15528,13 +15651,13 @@ ${ideCtx.warnings}
15528
15651
  if (!isError) {
15529
15652
  let label = "";
15530
15653
  if (isImage) {
15531
- label = `\u2714 Processed: ${path25.basename(filePath)}`;
15654
+ label = `\u2714 Processed: ${path27.basename(filePath)}`;
15532
15655
  attachedBinaryPart = binPart;
15533
15656
  } else if (isPdf || isOfficeFile) {
15534
- label = `\u2714 Auto-Analysed: ${path25.basename(filePath)}`;
15657
+ label = `\u2714 Auto-Analysed: ${path27.basename(filePath)}`;
15535
15658
  attachedBinaryPart = binPart;
15536
15659
  } else {
15537
- label = `\u2714 Auto-Read: ${path25.basename(filePath)}`;
15660
+ label = `\u2714 Auto-Read: ${path27.basename(filePath)}`;
15538
15661
  taggedContextBlocks.push(textResult);
15539
15662
  }
15540
15663
  if (label) {
@@ -15561,13 +15684,14 @@ ${ideCtx.warnings}
15561
15684
  }
15562
15685
  const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
15563
15686
  const cleanPromptForModel = cleanAgentText.replace(/\\(@\[[^\]]+\])/g, "$1");
15564
- const firstUserMsg = `[SYSTEM METADATA, Chat Context > Metadata]
15687
+ const firstUserMsg = `[METADATA, Chat Context > Metadata]
15565
15688
  Time: ${dateTimeStr}
15566
- OS: ${osDetected}
15567
- **DIRECTORY STRUCTURE**
15568
- ${dirStructure}${memoryPrompt}${ideBlock}
15689
+ OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${memoryPrompt}${ideBlock}
15690
+ [/METADATA]
15569
15691
  ${activeSummaryBlock}${thinkingLevel !== "Fast" && (aiProvider === "Mistral" || thinkingLevel !== "xHigh" && aiProvider === "Google") ? `${aiProvider === "Mistral" || modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[SYSTEM Priority: HIGH] ONLY use the system prompt tool schema. eg: [tool:functions.ReadFolder(path=".")] [/SYSTEM]
15570
- ${taggedContextStr}[USER PROMPT] ${cleanPromptForModel.trim()} [/USER PROMPT]`.trim();
15692
+ ${taggedContextStr}[USER PROMPT]
15693
+ ${cleanPromptForModel.trim()}
15694
+ [/USER PROMPT]`.trim();
15571
15695
  const userMsgObj = { role: "user", text: firstUserMsg };
15572
15696
  if (attachedBinaryPart) {
15573
15697
  userMsgObj.binaryPart = attachedBinaryPart;
@@ -15736,6 +15860,10 @@ ${taggedContextStr}[USER PROMPT] ${cleanPromptForModel.trim()} [/USER PROMPT]`.t
15736
15860
  }
15737
15861
  targetModel = modelName;
15738
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);
15863
+ if (!systemSettings?.dynamicDirAwareness) {
15864
+ currentSystemInstruction += `
15865
+ ${dirStructure.replace("\n**DIRECTORY STRUCTURE**", "\n**DIRECTORY STRUCTURE AT CONVERSATION START**")}`;
15866
+ }
15739
15867
  const lastUserMsg = contents[contents.length - 1];
15740
15868
  if (isBridgeConnected() & loop > 0) {
15741
15869
  await new Promise((resolve) => setTimeout(resolve, 2500));
@@ -15789,7 +15917,7 @@ ${ideErr} [/ERROR]`;
15789
15917
  const currentStep = loop + 1;
15790
15918
  if (currentStep >= stepThreshold && lastUserMsg && lastUserMsg.parts?.[0]) {
15791
15919
  lastUserMsg.parts[0].text += `
15792
- [SYSTEM] WARNING, Turn Limit Impending: Step ${currentStep}/${MAX_LOOPS}. Wrap up quickly/prompt user to continue & use [[END]] quickly. [/SYSTEM]`;
15920
+ [SYSTEM] WARNING, Turn Limit Impending: Step ${currentStep}/${MAX_LOOPS}. Wrap up quickly/prompt user to continue. [/SYSTEM]`;
15793
15921
  }
15794
15922
  const abortPromise = new Promise((_, reject) => {
15795
15923
  if (abortController.signal.aborted) {
@@ -16209,7 +16337,7 @@ ${ideErr} [/ERROR]`;
16209
16337
  if (keyword !== void 0 && keyword !== null) {
16210
16338
  detail = String(keyword).replace(RE_STRIP_QUOTES, "");
16211
16339
  } else if (filePath) {
16212
- 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, "/"));
16213
16341
  } else if (title && (potentialTool === "invoke" || potentialTool === "invoke_sync")) {
16214
16342
  detail = String(title).replace(RE_STRIP_QUOTES, "").substring(0, 30);
16215
16343
  } else if (id && potentialTool === "get_progress") {
@@ -16238,7 +16366,7 @@ ${ideErr} [/ERROR]`;
16238
16366
  if (potentialTool === "invoke" || potentialTool === "invoke_sync" || potentialTool === "get_progress") {
16239
16367
  detail = val.substring(0, 30);
16240
16368
  } else {
16241
- 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, "/"));
16242
16370
  }
16243
16371
  }
16244
16372
  }
@@ -16444,9 +16572,9 @@ ${ideErr} [/ERROR]`;
16444
16572
  let totalLines = "...";
16445
16573
  let actualEndLine = eLine;
16446
16574
  try {
16447
- const absPath = path25.resolve(process.cwd(), targetPath2);
16448
- if (fs26.existsSync(absPath)) {
16449
- 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");
16450
16578
  const lines = content.split("\n").length;
16451
16579
  totalLines = lines;
16452
16580
  if (!rawStart && !rawEnd && lines > 800) {
@@ -16462,30 +16590,30 @@ ${ideErr} [/ERROR]`;
16462
16590
  const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
16463
16591
  const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
16464
16592
  if (isPdf || isOfficeFile) {
16465
- 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"}`;
16466
16594
  } else if (isImage) {
16467
- 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"}`;
16468
16596
  } else {
16469
- 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"}`;
16470
16598
  }
16471
16599
  } else if (normToolName === "list_files" || normToolName === "read_folder") {
16472
16600
  const action = normToolName === "list_files" ? "List" : "Browsed";
16473
- const path27 = parseArgs(toolCall.args).path || null;
16601
+ const path29 = parseArgs(toolCall.args).path || null;
16474
16602
  const recurse = parseArgs(toolCall.args).recurse || 0;
16475
- 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}${recurse > 0 ? `${path29.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path29.endsWith("/") ? "" : "/"}`}`}` : "No Folder Selected"}`;
16476
16604
  } else if (normToolName === "write_file" || normToolName === "update_file") {
16477
16605
  const action = normToolName === "write_file" ? "Created" : "Edited";
16478
- const path27 = parseArgs(toolCall.args).path || null;
16479
- label = `${path27 ? "\u2714" : "\u2718"} ${action}: ${path27 || "No File Changes"}`;
16606
+ const path29 = parseArgs(toolCall.args).path || null;
16607
+ label = `${path29 ? "\u2714" : "\u2718"} ${action}: ${path29 || "No File Changes"}`;
16480
16608
  } else if (normToolName === "write_pdf") {
16481
- const path27 = parseArgs(toolCall.args).path || null;
16482
- label = `${path27 ? "\u2714" : "\u2718"} Generated: ${path27 || "No PDF Generated"}`;
16609
+ const path29 = parseArgs(toolCall.args).path || null;
16610
+ label = `${path29 ? "\u2714" : "\u2718"} Generated: ${path29 || "No PDF Generated"}`;
16483
16611
  } else if (normToolName === "write_docx") {
16484
- const path27 = parseArgs(toolCall.args).path || null;
16485
- label = `${path27 ? "\u2714" : "\u2718"} Generated: ${path27 || "No Docx Generated"}`;
16612
+ const path29 = parseArgs(toolCall.args).path || null;
16613
+ label = `${path29 ? "\u2714" : "\u2718"} Generated: ${path29 || "No Docx Generated"}`;
16486
16614
  } else if (normToolName === "file_map") {
16487
- const path27 = parseArgs(toolCall.args).path;
16488
- label = `${path27 ? "\u2714" : "\u2718"} Indexed: ${path27 ? "" + path27 : "File Not Found"}`;
16615
+ const path29 = parseArgs(toolCall.args).path;
16616
+ label = `${path29 ? "\u2714" : "\u2718"} Indexed: ${path29 ? "" + path29 : "File Not Found"}`;
16489
16617
  } else if (normToolName.toLowerCase() === "search_keyword" || normToolName.toLowerCase() === "todo") {
16490
16618
  label = "";
16491
16619
  } else if (normToolName.toLowerCase() === "generate_image") {
@@ -16560,7 +16688,7 @@ ${ideErr} [/ERROR]`;
16560
16688
  const { command } = parseArgs(toolCall.args);
16561
16689
  if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
16562
16690
  const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
16563
- const currentDrive = path25.resolve(process.cwd()).substring(0, 3).toLowerCase();
16691
+ const currentDrive = path27.resolve(process.cwd()).substring(0, 3).toLowerCase();
16564
16692
  const splitCommands = (cmdString) => {
16565
16693
  const commands = [];
16566
16694
  let current = "";
@@ -16689,8 +16817,8 @@ ${ideErr} [/ERROR]`;
16689
16817
  const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
16690
16818
  if (targetPath) {
16691
16819
  const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
16692
- const absoluteTarget = path25.resolve(targetPath);
16693
- const absoluteCwd = path25.resolve(process.cwd());
16820
+ const absoluteTarget = path27.resolve(targetPath);
16821
+ const absoluteCwd = path27.resolve(process.cwd());
16694
16822
  if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
16695
16823
  const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
16696
16824
  if (normToolName === "write_file" || normToolName === "update_file") {
@@ -16879,7 +17007,7 @@ ${ideErr} [/ERROR]`;
16879
17007
  const toolArgs = parseArgs(toolCall.args);
16880
17008
  const { path: filePath } = toolArgs;
16881
17009
  if (filePath) {
16882
- const absPath = path25.resolve(process.cwd(), filePath);
17010
+ const absPath = path27.resolve(process.cwd(), filePath);
16883
17011
  const normalize2 = (p) => p ? p.toLowerCase().replace(/\\/g, "/").replace(/^[a-z]:/, (m) => m.toUpperCase()) : "";
16884
17012
  const normAbsPath = normalize2(absPath);
16885
17013
  let originalContent = "";
@@ -16889,8 +17017,8 @@ ${ideErr} [/ERROR]`;
16889
17017
  if (currentIDE && normFocused === normAbsPath && currentIDE.full_content) {
16890
17018
  originalContent = currentIDE.full_content;
16891
17019
  hasOriginal = true;
16892
- } else if (fs26.existsSync(absPath)) {
16893
- originalContent = fs26.readFileSync(absPath, "utf8");
17020
+ } else if (fs28.existsSync(absPath)) {
17021
+ originalContent = fs28.readFileSync(absPath, "utf8");
16894
17022
  hasOriginal = true;
16895
17023
  }
16896
17024
  originalContentForReporting = originalContent;
@@ -16918,9 +17046,9 @@ ${ideErr} [/ERROR]`;
16918
17046
  const successes = patchResults.filter((r) => r.success);
16919
17047
  const failures = patchResults.filter((r) => !r.success);
16920
17048
  if (successes.length === 0) {
16921
- 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)}].
16922
17050
  ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
16923
- const errorLabel = `\u2714 Edited: ${path25.basename(absPath)}`;
17051
+ const errorLabel = `\u2714 Edited: ${path27.basename(absPath)}`;
16924
17052
  let terminalWidth = 115;
16925
17053
  if (process.stdout.isTTY) {
16926
17054
  terminalWidth = process.stdout.columns - 5 || 120;
@@ -16937,19 +17065,19 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
16937
17065
  continue;
16938
17066
  }
16939
17067
  }
16940
- yield { type: "status", content: `Opening Diff in IDE: ${path25.basename(absPath)}` };
17068
+ yield { type: "status", content: `Opening Diff in IDE: ${path27.basename(absPath)}` };
16941
17069
  showDiffInIDE(absPath, originalContent, modifiedContent);
16942
17070
  diffOpened = true;
16943
17071
  await new Promise((r) => setTimeout(r, 50));
16944
17072
  } else if (normToolName === "write_file") {
16945
17073
  const rawContent = toolArgs.content || toolArgs.newContent || "";
16946
17074
  const modifiedContent = rawContent.endsWith("\n") ? rawContent : rawContent + "\n";
16947
- if (!fs26.existsSync(absPath)) {
17075
+ if (!fs28.existsSync(absPath)) {
16948
17076
  isNewFileCreated = true;
16949
- fs26.mkdirSync(path25.dirname(absPath), { recursive: true });
16950
- fs26.writeFileSync(absPath, "", "utf8");
17077
+ fs28.mkdirSync(path27.dirname(absPath), { recursive: true });
17078
+ fs28.writeFileSync(absPath, "", "utf8");
16951
17079
  }
16952
- 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)}` };
16953
17081
  showDiffInIDE(absPath, "", modifiedContent);
16954
17082
  diffOpened = true;
16955
17083
  await new Promise((r) => setTimeout(r, 50));
@@ -16985,11 +17113,11 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
16985
17113
  if (normToolName === "write_file" || normToolName === "update_file") {
16986
17114
  const { path: filePath } = parseArgs(toolCall.args);
16987
17115
  if (filePath) {
16988
- const absPath = path25.resolve(process.cwd(), filePath);
17116
+ const absPath = path27.resolve(process.cwd(), filePath);
16989
17117
  closeDiffInIDE(absPath, approval);
16990
- if (approval === "deny" && isNewFileCreated && fs26.existsSync(absPath)) {
17118
+ if (approval === "deny" && isNewFileCreated && fs28.existsSync(absPath)) {
16991
17119
  try {
16992
- fs26.unlinkSync(absPath);
17120
+ fs28.unlinkSync(absPath);
16993
17121
  } catch (e) {
16994
17122
  }
16995
17123
  }
@@ -17001,18 +17129,18 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
17001
17129
  }
17002
17130
  if (approval === "allow" && diffOpened && isBridgeConnected()) {
17003
17131
  const { path: filePath } = parseArgs(toolCall.args);
17004
- const absPath = path25.resolve(process.cwd(), filePath);
17005
- 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() : "";
17006
17134
  const finalIDE = await getIDEContext();
17007
17135
  let finalContent = "";
17008
17136
  if (finalIDE && finalIDE.file_focused && normPath(finalIDE.file_focused) === normPath(absPath) && finalIDE.full_content) {
17009
17137
  finalContent = finalIDE.full_content;
17010
17138
  }
17011
- if (!finalContent && fs26.existsSync(absPath)) {
17012
- finalContent = fs26.readFileSync(absPath, "utf8");
17139
+ if (!finalContent && fs28.existsSync(absPath)) {
17140
+ finalContent = fs28.readFileSync(absPath, "utf8");
17013
17141
  if (!finalContent) {
17014
17142
  await new Promise((r) => setTimeout(r, 100));
17015
- finalContent = fs26.readFileSync(absPath, "utf8");
17143
+ finalContent = fs28.readFileSync(absPath, "utf8");
17016
17144
  }
17017
17145
  }
17018
17146
  const verifiedLines = finalContent.split(/\r?\n/);
@@ -17173,7 +17301,7 @@ ${snippet2}`;
17173
17301
  try {
17174
17302
  const { path: filePath } = parseArgs(toolCall.args);
17175
17303
  if (filePath) {
17176
- const absPath = path25.resolve(process.cwd(), filePath);
17304
+ const absPath = path27.resolve(process.cwd(), filePath);
17177
17305
  const currentIDE = await getIDEContext();
17178
17306
  if (currentIDE && currentIDE.file_focused === absPath && currentIDE.full_content) {
17179
17307
  execToolContext.forcedContent = currentIDE.full_content;
@@ -17187,7 +17315,7 @@ ${snippet2}`;
17187
17315
  if ((normToolName === "write_file" || normToolName === "update_file") && result.startsWith("SUCCESS")) {
17188
17316
  const { path: filePath } = parseArgs(toolCall.args);
17189
17317
  if (filePath) {
17190
- const absPath = path25.resolve(process.cwd(), filePath);
17318
+ const absPath = path27.resolve(process.cwd(), filePath);
17191
17319
  openFileInEditor(absPath);
17192
17320
  }
17193
17321
  }
@@ -17204,7 +17332,7 @@ ${snippet2}`;
17204
17332
  result = result.text;
17205
17333
  }
17206
17334
  if (normToolName === "search_keyword") {
17207
- const { keyword, path: path27 } = parseArgs(toolCall.args);
17335
+ const { keyword, path: path29 } = parseArgs(toolCall.args);
17208
17336
  const _isDir = typeof result === "string" && result.startsWith("[DIR]");
17209
17337
  if (_isDir) result = result.slice(5);
17210
17338
  let matchCount = 0;
@@ -17214,7 +17342,7 @@ ${snippet2}`;
17214
17342
  matchCount = parseInt(m[1]);
17215
17343
  }
17216
17344
  }
17217
- const _sp = path27 ? path27.replace(/[\/\\]+$/, "") : null;
17345
+ const _sp = path29 ? path29.replace(/[\/\\]+$/, "") : null;
17218
17346
  const displayPath = _sp && _sp !== "." ? `"${_isDir ? `${_sp}/*` : _sp}"` : "./";
17219
17347
  const postLabel = `${keyword ? "\u2714" : "\u2718"} Searched: "${keyword ? keyword : ""}" in ${displayPath} \u2192 ${matchCount} Match${matchCount === 1 ? "" : "es"}`;
17220
17348
  let terminalWidth = 115;
@@ -17454,9 +17582,9 @@ ${snippet2}`;
17454
17582
  })() : String(err);
17455
17583
  ;
17456
17584
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
17457
- const agentErrDir = path25.join(LOGS_DIR, "agent");
17458
- if (!fs26.existsSync(agentErrDir)) fs26.mkdirSync(agentErrDir, { recursive: true });
17459
- 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}
17460
17588
 
17461
17589
  ----------------------------------------------------------------------
17462
17590
 
@@ -17503,7 +17631,7 @@ ${recoveryText}`
17503
17631
  yield { type: "status", content: `Error Occured. Recovering Stream...` };
17504
17632
  } else {
17505
17633
  throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
17506
- 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")}`);
17507
17635
  }
17508
17636
  } else {
17509
17637
  if (retryCount <= MAX_RETRIES) {
@@ -17521,7 +17649,7 @@ Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17521
17649
  yield { type: "status", content: `Trying to reach ${modelName}` };
17522
17650
  } else {
17523
17651
  throw new Error(`Model ${modelName} cannot be reached. (Failed ${MAX_RETRIES} times)
17524
- 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")}`);
17525
17653
  }
17526
17654
  }
17527
17655
  }
@@ -17620,7 +17748,7 @@ Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17620
17748
  if (wasToolCalledInLastLoop || detectedAnyToolCalls) {
17621
17749
  modifiedHistory.push({ role: "user", text: `[SYSTEM] Failed to execute some tools. Verify proper schema compliance & try again [/SYSTEM]` });
17622
17750
  } else {
17623
- modifiedHistory.push({ role: "user", text: `[SYSTEM] ${isStutteringLoop && !isThinkingLoop ? `STUTTERING DETECTED by Internal System. Re-calibrate your response & proceed.` : `${isThinkingLoop ? " OVER THINKING" : " LOOP"} DETECTED by Internal System${isThinkingLoop ? " for current EFFORT_LEVEL" : ""}. ${isThinkingLoop ? "If you have planned the task, prioritize execution/output" : "If you have finished your task use [[END]]"}`} [/SYSTEM]` });
17751
+ modifiedHistory.push({ role: "user", text: `[SYSTEM] ${isStutteringLoop && !isThinkingLoop ? `STUTTERING DETECTED by Internal System. Re-calibrate your response & proceed.` : `${isThinkingLoop ? " OVER THINKING" : " LOOP"} DETECTED by Internal System${isThinkingLoop ? " for current EFFORT_LEVEL" : ""}. ${isThinkingLoop ? "If you have planned the task, prioritize execution/output" : "If you have finished your task provide a simple summary and end"}`} [/SYSTEM]` });
17624
17752
  }
17625
17753
  isThinkingLoop = false;
17626
17754
  isStutteringLoop = false;
@@ -17640,10 +17768,10 @@ Error Log can be found in ${path25.join(LOGS_DIR, "agent", "error.log")}`);
17640
17768
  }
17641
17769
  })() : String(err);
17642
17770
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
17643
- const agentErrDir = path25.join(LOGS_DIR, "agent");
17771
+ const agentErrDir = path27.join(LOGS_DIR, "agent");
17644
17772
  yield { type: "text", content: `\u274C CRITICAL ERROR: ${errLog.includes("fetch failed") ? "Failed to Connect. Check your Internet Connection or Wait a moment" : errLog}` };
17645
- if (!fs26.existsSync(agentErrDir)) fs26.mkdirSync(agentErrDir, { recursive: true });
17646
- 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}
17647
17775
 
17648
17776
  ----------------------------------------------------------------------
17649
17777
 
@@ -17792,22 +17920,22 @@ ${cleanResponse}
17792
17920
  const keywordPath = pArgs.path || "";
17793
17921
  label = `${keyword ? "\u2714" : "\u2718"} \x1B[95mSearched\x1B[0m: ${keyword || "No Query"}${keywordPath ? ` \u2192 ${keywordPath}` : ""}`;
17794
17922
  } else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
17795
- const path27 = parseArgs(toolCall.args).path || "";
17796
- label = `\u2714 \x1B[95mRead\x1B[0m: ${path27}`;
17923
+ const path29 = parseArgs(toolCall.args).path || "";
17924
+ label = `\u2714 \x1B[95mRead\x1B[0m: ${path29}`;
17797
17925
  } else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
17798
- const path27 = parseArgs(toolCall.args).path || null;
17926
+ const path29 = parseArgs(toolCall.args).path || null;
17799
17927
  const recurse = parseArgs(toolCall.args).recurse || 0;
17800
- 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}${recurse > 0 ? `${path29.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path29.endsWith("/") ? "" : "/"}`}` : ""}`;
17801
17929
  } else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
17802
- const path27 = parseArgs(toolCall.args).path || null;
17803
- 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}` : "No File Changes"}`;
17804
17932
  } else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
17805
- const path27 = parseArgs(toolCall.args).path || null;
17933
+ const path29 = parseArgs(toolCall.args).path || null;
17806
17934
  const content = parseArgs(toolCall.args).content || null;
17807
- label = `${path27 ? "\u2714" : "\u2718"} \x1B[95mEdited\x1B[0m: ${path27 ? `${path27}` : "No File Changes"}`;
17935
+ label = `${path29 ? "\u2714" : "\u2718"} \x1B[95mEdited\x1B[0m: ${path29 ? `${path29}` : "No File Changes"}`;
17808
17936
  } else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
17809
- const path27 = parseArgs(toolCall.args).path || "";
17810
- 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}` : "File Not Found"}`;
17811
17939
  } else if (normalizedToolName === "await") {
17812
17940
  const { time } = parseArgs(toolCall.args);
17813
17941
  let sec = parseFloat(time) || 0;
@@ -18803,7 +18931,7 @@ var init_RevertModal = __esm({
18803
18931
  import puppeteer4 from "puppeteer";
18804
18932
  import { exec } from "child_process";
18805
18933
  import { promisify } from "util";
18806
- import fs27 from "fs";
18934
+ import fs29 from "fs";
18807
18935
  var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
18808
18936
  var init_setup = __esm({
18809
18937
  "src/utils/setup.js"() {
@@ -18812,11 +18940,11 @@ var init_setup = __esm({
18812
18940
  checkPuppeteerReady = () => {
18813
18941
  try {
18814
18942
  const pptrConfig = getPuppeteerConfig();
18815
- if (pptrConfig.executablePath && fs27.existsSync(pptrConfig.executablePath)) {
18943
+ if (pptrConfig.executablePath && fs29.existsSync(pptrConfig.executablePath)) {
18816
18944
  return true;
18817
18945
  }
18818
18946
  const exePath = puppeteer4.executablePath();
18819
- const exists = exePath && fs27.existsSync(exePath);
18947
+ const exists = exePath && fs29.existsSync(exePath);
18820
18948
  if (exists) return true;
18821
18949
  } catch (e) {
18822
18950
  return false;
@@ -18903,8 +19031,8 @@ __export(app_exports, {
18903
19031
  import os5 from "os";
18904
19032
  import React16, { useState as useState15, useEffect as useEffect12, useRef as useRef4, useMemo as useMemo2 } from "react";
18905
19033
  import { Box as Box14, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
18906
- import fs28 from "fs-extra";
18907
- import path26 from "path";
19034
+ import fs30 from "fs-extra";
19035
+ import path28 from "path";
18908
19036
  import { exec as exec2 } from "child_process";
18909
19037
  import { fileURLToPath as fileURLToPath3 } from "url";
18910
19038
  import TextInput4 from "ink-text-input";
@@ -19231,10 +19359,10 @@ function App({ args = [] }) {
19231
19359
  const kbPath = getKeybindingsPath(ideName);
19232
19360
  if (!kbPath) return;
19233
19361
  try {
19234
- await fs28.ensureDir(path26.dirname(kbPath));
19362
+ await fs30.ensureDir(path28.dirname(kbPath));
19235
19363
  let bindings = [];
19236
- if (fs28.existsSync(kbPath)) {
19237
- const content = fs28.readFileSync(kbPath, "utf8").trim();
19364
+ if (fs30.existsSync(kbPath)) {
19365
+ const content = fs30.readFileSync(kbPath, "utf8").trim();
19238
19366
  if (content) {
19239
19367
  try {
19240
19368
  bindings = parseJsonc(content);
@@ -19254,7 +19382,7 @@ function App({ args = [] }) {
19254
19382
  },
19255
19383
  "when": "terminalFocus"
19256
19384
  });
19257
- fs28.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
19385
+ fs30.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
19258
19386
  cachedShortcut = "Shift + Enter";
19259
19387
  setMessages((prev) => {
19260
19388
  setCompletedIndex(prev.length + 1);
@@ -19978,7 +20106,7 @@ function App({ args = [] }) {
19978
20106
  useEffect12(() => {
19979
20107
  async function init() {
19980
20108
  try {
19981
- 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"));
19982
20110
  initBridge(versionFluxflow || pkg.version || "2.0.0");
19983
20111
  } catch (e) {
19984
20112
  initBridge("2.0.0");
@@ -20092,7 +20220,7 @@ function App({ args = [] }) {
20092
20220
  if (!parsedArgs.playground) {
20093
20221
  deleteChat(PLAYGROUND_CHAT_ID).catch(() => {
20094
20222
  });
20095
- fs28.remove(path26.join(DATA_DIR, "playground")).catch(() => {
20223
+ fs30.remove(path28.join(DATA_DIR, "playground")).catch(() => {
20096
20224
  });
20097
20225
  }
20098
20226
  performVersionCheck(false, freshSettings);
@@ -20126,9 +20254,9 @@ function App({ args = [] }) {
20126
20254
  }
20127
20255
  }
20128
20256
  if (parsedArgs.playground) {
20129
- const playgroundDir = path26.join(DATA_DIR, "playground");
20257
+ const playgroundDir = path28.join(DATA_DIR, "playground");
20130
20258
  try {
20131
- fs28.ensureDirSync(playgroundDir);
20259
+ fs30.ensureDirSync(playgroundDir);
20132
20260
  process.chdir(playgroundDir);
20133
20261
  } catch (e) {
20134
20262
  }
@@ -20169,8 +20297,8 @@ function App({ args = [] }) {
20169
20297
  if (kbPath) {
20170
20298
  try {
20171
20299
  let bindings = [];
20172
- if (fs28.existsSync(kbPath)) {
20173
- const content = fs28.readFileSync(kbPath, "utf8").trim();
20300
+ if (fs30.existsSync(kbPath)) {
20301
+ const content = fs30.readFileSync(kbPath, "utf8").trim();
20174
20302
  if (content) {
20175
20303
  bindings = parseJsonc(content);
20176
20304
  }
@@ -20548,22 +20676,22 @@ ${cleanText}`, color: "magenta" }];
20548
20676
  });
20549
20677
  break;
20550
20678
  }
20551
- const src = path26.join(DATA_DIR, "playground");
20552
- 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");
20553
20681
  const moveFiles = async () => {
20554
20682
  try {
20555
20683
  setMessages((prev) => {
20556
20684
  setCompletedIndex(prev.length + 1);
20557
20685
  return [...prev, { id: Date.now(), role: "system", text: `[PLAYGROUND] Exporting playground content to ${dest}`, isMeta: true }];
20558
20686
  });
20559
- await fs28.ensureDir(dest);
20687
+ await fs30.ensureDir(dest);
20560
20688
  const excludeDirs = ["node_modules", ".git", ".venv", "venv", "env", ".next", "dist", "build", ".cache"];
20561
- await fs28.copy(src, dest, {
20689
+ await fs30.copy(src, dest, {
20562
20690
  overwrite: true,
20563
20691
  filter: (srcPath) => {
20564
- const relative = path26.relative(src, srcPath);
20692
+ const relative = path28.relative(src, srcPath);
20565
20693
  if (!relative) return true;
20566
- const parts2 = relative.split(path26.sep);
20694
+ const parts2 = relative.split(path28.sep);
20567
20695
  return !parts2.some((part) => excludeDirs.includes(part));
20568
20696
  }
20569
20697
  });
@@ -20625,7 +20753,7 @@ ${cleanText}`, color: "magenta" }];
20625
20753
  }
20626
20754
  }
20627
20755
  setTimeout(() => {
20628
- fs28.emptyDir(path26.join(DATA_DIR, "playground")).catch((err) => {
20756
+ fs30.emptyDir(path28.join(DATA_DIR, "playground")).catch((err) => {
20629
20757
  setMessages((prev) => {
20630
20758
  const newMsgs = [...prev, {
20631
20759
  id: "playground-" + Date.now(),
@@ -21015,12 +21143,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
21015
21143
  setCompletedIndex(prev.length + 1);
21016
21144
  return [...prev, { id: Date.now(), role: "system", text: "[NUCLEAR] Initiating reset...", isMeta: true }];
21017
21145
  });
21018
- if (fs28.existsSync(LOGS_DIR)) fs28.removeSync(LOGS_DIR);
21019
- if (fs28.existsSync(SECRET_DIR)) fs28.removeSync(SECRET_DIR);
21020
- 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);
21021
21149
  try {
21022
- const items = fs28.readdirSync(FLUXFLOW_DIR);
21023
- if (items.length === 0) fs28.removeSync(FLUXFLOW_DIR);
21150
+ const items = fs30.readdirSync(FLUXFLOW_DIR);
21151
+ if (items.length === 0) fs30.removeSync(FLUXFLOW_DIR);
21024
21152
  } catch (e) {
21025
21153
  }
21026
21154
  setTimeout(() => {
@@ -21142,15 +21270,15 @@ ${list || "No saved chats found."}`, isMeta: true }];
21142
21270
  # SKILLS & WORKFLOWS
21143
21271
  - [Define custom step-by-step recipes for this project here]
21144
21272
  `;
21145
- const filePath = path26.join(process.cwd(), "FluxFlow.md");
21146
- if (fs28.pathExistsSync(filePath)) {
21273
+ const filePath = path28.join(process.cwd(), "FluxFlow.md");
21274
+ if (fs30.pathExistsSync(filePath)) {
21147
21275
  setMessages((prev) => {
21148
21276
  setCompletedIndex(prev.length + 1);
21149
21277
  return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
21150
21278
  });
21151
21279
  } else {
21152
21280
  try {
21153
- fs28.writeFileSync(filePath, template);
21281
+ fs30.writeFileSync(filePath, template);
21154
21282
  setMessages((prev) => {
21155
21283
  setCompletedIndex(prev.length + 1);
21156
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 }];
@@ -22634,6 +22762,40 @@ Selection: ${val}`,
22634
22762
  return /* @__PURE__ */ React16.createElement(Box14, { key: provider, flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 40 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.primary, bold: true }, provider, ":")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true }, formatTokens(providerTotalTokens))), Object.entries(models).map(([modelName, stats]) => /* @__PURE__ */ React16.createElement(Box14, { key: modelName, flexDirection: "column", marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 36 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "\xBB ", modelName, ":")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(stats.tokens || 0))), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 32 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens((stats.tokens || 0) - (stats.candidateTokens || 0)))), (stats.cachedTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 5 }, /* @__PURE__ */ React16.createElement(Box14, { width: 31 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(stats.cachedTokens))), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 32 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(stats.candidateTokens || 0))))));
22635
22763
  })) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Session Duration:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionAgentCalls)), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB API Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Tool Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionBackgroundCalls)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tokens Consumed:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Active Context:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionStats.tokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Images Made:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionImageCount)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Image Credits:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Code Changes (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", runtimeSession.linesAdded), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", runtimeSession.linesRemoved))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tool Calls (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, runtimeSession.toolSuccess + runtimeSession.toolFailure + runtimeSession.toolDenied, " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", runtimeSession.toolSuccess), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", runtimeSession.toolDenied), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", runtimeSession.toolFailure), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )"))), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, trackerTitle), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, timeLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatDuration(u?.duration || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.agent || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.background || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, tokensLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u?.tokens || 0))), (u?.tokens || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens((u?.tokens || 0) - (u?.candidateTokens || 0)))), (u?.cachedTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.cachedTokens))), (u?.candidateTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.candidateTokens)))), (u?.imageCalls?.length || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imagesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u.imageCalls.length)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imageCreditsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((u.imageCalls.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, codeChangesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", u?.linesAdded || 0), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", u?.linesRemoved || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, toolCallsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, (u?.toolSuccess || 0) + (u?.toolFailure || 0) + (u?.toolDenied || 0), " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", u?.toolSuccess || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", u?.toolDenied || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", u?.toolFailure || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )")))), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, dimColor: true, marginTop: 1, italic: true }, "(Press TAB to toggle Daily/Monthly views, SPACE for Model Breakdown, ESC to return)"));
22636
22764
  }
22765
+ case "dynamicDirDanger":
22766
+ return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow", bold: true, underline: true }, "DYNAMIC DIRECTORY AWARENESS"), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1, color: colors.text }, "Enabling this keeps the agent aware of filesystem state in real time, but may reduce prompt cache efficiency."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, "\n", "RECOMMENDED SCENARIOS TO TURN ON:"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Repo is small."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 The task benefits from real-time filesystem awareness."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Files are often created, renamed, or deleted."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You know exactly what you're signing up for."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You don't have conflicting decisions regarding token bills."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You want to see your wallet crying at 3am."), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
22767
+ CommandMenu,
22768
+ {
22769
+ title: "Confirm Intent",
22770
+ theme: systemSettings.theme,
22771
+ items: [
22772
+ { label: "Turn On Dynamic Directory Awareness", value: "on" },
22773
+ { label: "Keep Off (Recommended)", value: "off" }
22774
+ ],
22775
+ onSelect: (item) => {
22776
+ if (item.value === "on") {
22777
+ setSystemSettings((s) => {
22778
+ const updated = { ...s, dynamicDirAwareness: true };
22779
+ saveSettings({ systemSettings: updated, apiTier, quotas });
22780
+ return updated;
22781
+ });
22782
+ }
22783
+ setActiveView("settings");
22784
+ }
22785
+ }
22786
+ )));
22787
+ case "dynamicDirHelp":
22788
+ return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "DYNAMIC DIRECTORY AWARENESS \u2014 HELP & EXPLANATION"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true }, "\n", "OFF (Default):"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Takes a static directory snapshot at conversation/session start and places it in System Context."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Prompt cache remains stable across user turns, saving tokens and money."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true }, "\n", "ON:"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Rescans and updates the directory's state dynamically on every single user turn."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Provides real-time filesystem awareness if files are continuously created, renamed, or removed."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Changes Prompt Context on each turn, invalidating part of prompt caches and increasing token usage."), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
22789
+ CommandMenu,
22790
+ {
22791
+ title: "Actions",
22792
+ theme: systemSettings.theme,
22793
+ items: [
22794
+ { label: "Back to Settings", value: "back" }
22795
+ ],
22796
+ onSelect: () => setActiveView("settings")
22797
+ }
22798
+ )));
22637
22799
  case "autoExecDanger":
22638
22800
  return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow", bold: true, underline: true }, "SECURITY WARNING: YOLO MODE"), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1, color: colors.text }, "Turning this ON allows the agent to execute terminal commands automatically without requiring your approval for each step."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1, color: colors.text, bold: true }, "RISKS INVOLVED:"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 The agent may execute destructive commands (rm -rf, etc.) by mistake unless specified in sandbox rules."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Unintended system changes if the agent hallucinates a path or command."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Reduced control over the agent's step-by-step decision making."), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
22639
22801
  CommandMenu,
@@ -23407,11 +23569,11 @@ var init_app = __esm({
23407
23569
  if (process.platform === "win32") {
23408
23570
  const appData = process.env.APPDATA;
23409
23571
  if (!appData) return null;
23410
- return path26.join(appData, dirName, "User", "keybindings.json");
23572
+ return path28.join(appData, dirName, "User", "keybindings.json");
23411
23573
  } else if (process.platform === "darwin") {
23412
- return path26.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
23574
+ return path28.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
23413
23575
  } else {
23414
- return path26.join(home, ".config", dirName, "User", "keybindings.json");
23576
+ return path28.join(home, ".config", dirName, "User", "keybindings.json");
23415
23577
  }
23416
23578
  };
23417
23579
  parseJsonc = (content) => {
@@ -23455,8 +23617,8 @@ var init_app = __esm({
23455
23617
  SESSION_START_TIME = Date.now();
23456
23618
  CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog";
23457
23619
  DOCS_URL = "https://fluxflow-cli.onrender.com/";
23458
- packageJsonPath = path26.join(path26.dirname(fileURLToPath3(import.meta.url)), "../package.json");
23459
- 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"));
23460
23622
  versionFluxflow = packageJson.version;
23461
23623
  updatedOn = packageJson.date || "2026-05-20";
23462
23624
  ResolutionModal = ({ data, onResolve, onEdit, theme = "Dark" }) => {
@@ -23490,20 +23652,20 @@ var init_app = __esm({
23490
23652
  const scan = (currentDir) => {
23491
23653
  if (fileList.length >= 2e3) return;
23492
23654
  try {
23493
- const files = fs28.readdirSync(currentDir);
23655
+ const files = fs30.readdirSync(currentDir);
23494
23656
  for (const file of files) {
23495
23657
  if (fileList.length >= 2e3) return;
23496
23658
  if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
23497
23659
  continue;
23498
23660
  }
23499
- const filePath = path26.join(currentDir, file);
23500
- const stat = fs28.statSync(filePath);
23661
+ const filePath = path28.join(currentDir, file);
23662
+ const stat = fs30.statSync(filePath);
23501
23663
  if (stat.isDirectory()) {
23502
23664
  scan(filePath);
23503
23665
  } else {
23504
23666
  fileList.push({
23505
23667
  name: flattenString(file),
23506
- relativePath: flattenString(path26.relative(process.cwd(), filePath))
23668
+ relativePath: flattenString(path28.relative(process.cwd(), filePath))
23507
23669
  });
23508
23670
  }
23509
23671
  }
@@ -23703,11 +23865,11 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
23703
23865
  const isUpdate = args[0] === "--update";
23704
23866
  const isExport = args[0] === "--export";
23705
23867
  if (isVersion || isHelp || isHelpCommands || isUpdate || isExport) {
23706
- const fs29 = await import("fs");
23707
- const path27 = await import("path");
23868
+ const fs31 = await import("fs");
23869
+ const path29 = await import("path");
23708
23870
  const { fileURLToPath: fileURLToPath5 } = await import("url");
23709
- const packageJsonPath2 = path27.join(path27.dirname(fileURLToPath5(import.meta.url)), "../package.json");
23710
- 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"));
23711
23873
  const versionFluxflow2 = packageJson2.version;
23712
23874
  if (isExport) {
23713
23875
  const subArg = (args[1] || "").toLowerCase();