fluxflow-cli 1.9.18 → 1.9.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fluxflow.js +73 -146
- package/package.json +1 -3
package/dist/fluxflow.js
CHANGED
|
@@ -154,7 +154,6 @@ var init_ChatLayout = __esm({
|
|
|
154
154
|
"web_scrape": "ReadSite",
|
|
155
155
|
"search_keyword": "FindFiles",
|
|
156
156
|
"write_pdf": "CreatePDF",
|
|
157
|
-
"write_pptx": "CreatePresentation",
|
|
158
157
|
"write_docx": "CreateDocument"
|
|
159
158
|
};
|
|
160
159
|
cleanSignals = (text) => {
|
|
@@ -211,7 +210,7 @@ var init_ChatLayout = __esm({
|
|
|
211
210
|
}
|
|
212
211
|
}
|
|
213
212
|
}
|
|
214
|
-
return result.replace(/^\[TOOL_RESULT\]:\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|
|
|
213
|
+
return result.replace(/^\[TOOL_RESULT\]:\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx)\b/gi, (match) => TOOL_LABELS[match.toLowerCase()] || match).trim();
|
|
215
214
|
};
|
|
216
215
|
formatThinkText = (cleaned, columns = 80) => {
|
|
217
216
|
if (!cleaned) return null;
|
|
@@ -875,32 +874,29 @@ Access to internal tools. To call a tool, MUST use the exact syntax on a new lin
|
|
|
875
874
|
[tool:functions.tool_name(arguments)]
|
|
876
875
|
|
|
877
876
|
- COMMUNICATION TOOLS -
|
|
878
|
-
1. Ask User: [tool:functions.ask(question="...", optionA="
|
|
877
|
+
1. Ask User: [tool:functions.ask(question="...", optionA="<option>::<description>", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
|
|
879
878
|
Suggest best options; don't ask for preferences. System handles the rest
|
|
880
879
|
|
|
881
880
|
- WEB TOOLS -
|
|
882
881
|
1. Web Search: [tool:functions.web_search(query="...", limit=number)]. Find info (limit 3-10). Proactive use for unknown topics${mode === "Flux" ? " or docs" : ""}
|
|
883
|
-
2. Web Scrape: [tool:functions.web_scrape(url="
|
|
882
|
+
2. Web Scrape: [tool:functions.web_scrape(url="...")]. Visit URL
|
|
884
883
|
|
|
885
884
|
${mode === "Flux" ? `- DEV TOOLS (path = relative to CWD) -
|
|
886
885
|
1. View File: [tool:functions.view_file(path="...", start_line=N, end_line=N)]. Reads contents. Supports images/docs. User gives image/doc: VIEW FIRST
|
|
887
886
|
2. Read Folder: [tool:functions.read_folder(path="...")]. Detailed DIR stats
|
|
888
|
-
3. Write File: [tool:functions.write_file(path="...", content="
|
|
889
|
-
4. Update File: [tool:functions.update_file(path="...", content_to_replace="old
|
|
890
|
-
5. Write PDF: [tool:functions.write_pdf(path="...", content="
|
|
891
|
-
6. Write DOCX: [tool:functions.write_docx(path="...", content="
|
|
892
|
-
7.
|
|
893
|
-
|
|
894
|
-
CSS: background-color,color,font-family,font-size(pt),font-style,font-weight,margin,text-align,text-shadow
|
|
895
|
-
8. Execution: [tool:functions.exec_command(command="command")]. Runs a shell command. Destructive/Irreversible ops -> ask user
|
|
896
|
-
9. Search: [tool:functions.search_keyword(keyword="...")]. Global search. Finds definitions/logic without reading every file
|
|
887
|
+
3. Write File: [tool:functions.write_file(path="...", content="...")]. Creates/Overwrites. File Exist? -> update_file > write_file
|
|
888
|
+
4. Update File: [tool:functions.update_file(path="...", content_to_replace="old content", content_to_add="new content")]. Surgical patching. Unsure content_to_replace? -> view_file >> guessing.
|
|
889
|
+
5. Write PDF: [tool:functions.write_pdf(path="...", content="...", orientation="...")]. A4 PDF. Use CSS for layout (100vh/vw). Handle page breaks; no manual footers
|
|
890
|
+
6. Write DOCX: [tool:functions.write_docx(path="...", content="...")]. A4 Word doc. Proper margins and page breaks
|
|
891
|
+
7. Execution: [tool:functions.exec_command(command="...")]. Runs a shell command. Destructive/Irreversible ops -> ask user
|
|
892
|
+
8. Search: [tool:functions.search_keyword(keyword="...")]. Global search. Finds definitions/logic without reading every file
|
|
897
893
|
|
|
898
|
-
- VERIFY
|
|
894
|
+
- VERIFY RESULT CONTENTS. Fix errors. No hallucinations
|
|
899
895
|
- File tools > code chat
|
|
900
896
|
|
|
901
897
|
- Escape quotes: Use \\" inside code strings
|
|
902
898
|
- Literal escapes: Double-escape sequences (e.g., \\\\n, \\\\t)
|
|
903
|
-
- File structure:
|
|
899
|
+
- File structure: Real newlines for code formatting`.trim() : `
|
|
904
900
|
- DEV TOOLS ARE NOT AVAILABLE IN FLOW MODE. If you need to access files, tell the user to switch to FLUX`.trim()}
|
|
905
901
|
|
|
906
902
|
- Results: Passed as [TOOL_RESULT] SYSTEM
|
|
@@ -949,7 +945,9 @@ Refinement: Iterate on the chosen path until it is bulletproof.
|
|
|
949
945
|
RULES:
|
|
950
946
|
- NO HEADINGS. Just a solid, stable analytical monologue.
|
|
951
947
|
- Be thorough and exhaustive. Explore the 'why' behind every decision, depth and nuances.
|
|
952
|
-
|
|
948
|
+
Question your own logic as you go,
|
|
949
|
+
|
|
950
|
+
DO NOT GET STUCK IN RE-VERIFICATION LOOP.
|
|
953
951
|
- MANDATORY THINKING: You MUST engage in full reasoning regardless of perceived simplicity.`,
|
|
954
952
|
High: "EFFORT_LEVEL: HIGH\nThink in a stable, analytical monologue within the <think>...</think> block. Avoid headings or structured formatting. Your thinking should be a continuous stream of logical deduction:\nAnalyze the immediate task and its dependencies.\nMentally simulate the execution to identify potential failure points.\nStructure a precise plan that addresses both primary goals and secondary constraints.\nRULES:\n- NO HEADINGS. Maintain a fluid monologue style.\n- Be detailed and rigorous in your self-questioning.\n- Focus on accuracy, technical correctness, depth and nuances.\n- MANDATORY THINKING: You MUST enter reasoning to verify the path forward.",
|
|
955
953
|
Medium: "EFFORT_LEVEL: MEDIUM\nThink in a concise, stable monologue within the <think>...</think> block. No headings needed. Focus on the core logic required to solve the task efficiently:\nIdentify the most direct path to the solution.\nBriefly consider and discard obvious alternatives.\nConfirm the plan meets the user's immediate requirements.\nRULES:\n- NO HEADINGS. Keep it as a simple, logical stream.\n- Be efficient. Spend energy only on what matters for the task.\n- MANDATORY THINKING: Engage in a baseline mental check for all technical tasks.",
|
|
@@ -1027,10 +1025,10 @@ Protocol: [SYSTEM] and [STEERING HINT] are high-priority
|
|
|
1027
1025
|
|
|
1028
1026
|
-- THINKING INSTRUCTIONS --
|
|
1029
1027
|
${thinkingConfig}
|
|
1030
|
-
***
|
|
1031
|
-
- Always use <think> ... </think> before
|
|
1028
|
+
***THINKING POLICY***
|
|
1029
|
+
- Always use <think> ... </think> before responding
|
|
1032
1030
|
- Never skip thinking, even for simple tasks, code, or greetings
|
|
1033
|
-
- Never jump to responses directly, regardless of task complexity
|
|
1031
|
+
- Never jump to responses directly, regardless of task complexity
|
|
1034
1032
|
|
|
1035
1033
|
${TOOL_PROTOCOL(mode)}
|
|
1036
1034
|
${projectContextBlock}
|
|
@@ -1051,10 +1049,10 @@ ${projectContextBlock}
|
|
|
1051
1049
|
-- RESPONSE PROTOCOL --
|
|
1052
1050
|
- End with [turn: continue] for more steps or [turn: finish] when done
|
|
1053
1051
|
- Multi-tool: Stack tools if needed, but always end with [turn: continue] if called any tools
|
|
1054
|
-
TO END THE LOOP
|
|
1052
|
+
TO END THE LOOP, **MUST** WRITE [turn: finish] AT END OF RESPONSE
|
|
1055
1053
|
|
|
1056
|
-
[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v1.9.
|
|
1057
|
-
===
|
|
1054
|
+
[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v1.9.20 | Turn Progress: ${currentLoop}/${maxLoops} steps (Prompt user if reached)
|
|
1055
|
+
=== SYSTEM PROMPT ===`.trim();
|
|
1058
1056
|
};
|
|
1059
1057
|
getJanitorInstruction = (originalText, agentRaws, userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
1060
1058
|
let agentRes = `${agentRaws.replace(/tool:functions\..*\n/g, "").replace(/<think>.*<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[turn: continue\]/g, "").replace(/\[turn: finish\]/g, "").replace(/\[TOOL_RESULTS\]/g, "").replace(/\[tool_results\]/g, "").substring(0, 3500)}`;
|
|
@@ -2416,72 +2414,6 @@ var init_write_docx = __esm({
|
|
|
2416
2414
|
}
|
|
2417
2415
|
});
|
|
2418
2416
|
|
|
2419
|
-
// src/tools/write_pptx.js
|
|
2420
|
-
import fs16 from "fs-extra";
|
|
2421
|
-
import path15 from "path";
|
|
2422
|
-
import pptxgen from "pptxgenjs";
|
|
2423
|
-
import html2pptxgenjs from "html2pptxgenjs";
|
|
2424
|
-
var write_pptx;
|
|
2425
|
-
var init_write_pptx = __esm({
|
|
2426
|
-
"src/tools/write_pptx.js"() {
|
|
2427
|
-
init_arg_parser();
|
|
2428
|
-
write_pptx = async (args) => {
|
|
2429
|
-
let {
|
|
2430
|
-
path: targetPath,
|
|
2431
|
-
content = "",
|
|
2432
|
-
title = "Autonomous Agent Report"
|
|
2433
|
-
} = parseArgs(args);
|
|
2434
|
-
if (!targetPath) return 'ERROR: Missing "path" argument for write_pptx.';
|
|
2435
|
-
if (!content) return 'ERROR: No "content" (HTML) provided for write_pptx.';
|
|
2436
|
-
const absolutePath = path15.resolve(process.cwd(), targetPath);
|
|
2437
|
-
try {
|
|
2438
|
-
await fs16.ensureDir(path15.dirname(absolutePath));
|
|
2439
|
-
const PptxConstructor = typeof pptxgen === "function" ? pptxgen : pptxgen.default;
|
|
2440
|
-
if (!PptxConstructor) throw new Error("Could not find PptxGenJS constructor in module");
|
|
2441
|
-
const pres = new PptxConstructor();
|
|
2442
|
-
pres.layout = "LAYOUT_4x3";
|
|
2443
|
-
pres.title = title;
|
|
2444
|
-
pres.author = "FluxFlow CLI";
|
|
2445
|
-
pres.company = "Generated with Agentic AI System";
|
|
2446
|
-
const slideBlocks = content.split(/---/).filter((s) => s.trim().length > 0);
|
|
2447
|
-
if (slideBlocks.length === 0) {
|
|
2448
|
-
slideBlocks.push(content);
|
|
2449
|
-
}
|
|
2450
|
-
for (let i = 0; i < slideBlocks.length; i++) {
|
|
2451
|
-
const slide = pres.addSlide();
|
|
2452
|
-
const htmlSnippet = slideBlocks[i].trim();
|
|
2453
|
-
try {
|
|
2454
|
-
const items = html2pptxgenjs.htmlToPptxText(htmlSnippet);
|
|
2455
|
-
slide.addText(items, {
|
|
2456
|
-
x: 0.5,
|
|
2457
|
-
y: 0.5,
|
|
2458
|
-
w: "90%",
|
|
2459
|
-
h: "90%",
|
|
2460
|
-
valign: "top",
|
|
2461
|
-
fontSize: 18,
|
|
2462
|
-
color: "363636"
|
|
2463
|
-
});
|
|
2464
|
-
} catch (err) {
|
|
2465
|
-
slide.addText(htmlSnippet.replace(/<[^>]*>/g, ""), {
|
|
2466
|
-
x: 0.5,
|
|
2467
|
-
y: 0.5,
|
|
2468
|
-
w: "90%",
|
|
2469
|
-
h: "90%",
|
|
2470
|
-
fontSize: 14
|
|
2471
|
-
});
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
const buffer = await pres.write({ outputType: "nodebuffer" });
|
|
2475
|
-
await fs16.writeFile(absolutePath, buffer);
|
|
2476
|
-
return `SUCCESS: Native HTML-to-PPTX [${targetPath}] generated with ${slideBlocks.length} slides.
|
|
2477
|
-
- Size: ${(buffer.length / 1024).toFixed(1)} KB`;
|
|
2478
|
-
} catch (err) {
|
|
2479
|
-
return `ERROR: Failed to generate native HTML-to-PPTX [${targetPath}]: ${err.message}`;
|
|
2480
|
-
}
|
|
2481
|
-
};
|
|
2482
|
-
}
|
|
2483
|
-
});
|
|
2484
|
-
|
|
2485
2417
|
// src/tools/search_keyword.js
|
|
2486
2418
|
import { exec } from "child_process";
|
|
2487
2419
|
var search_keyword;
|
|
@@ -2555,7 +2487,6 @@ var init_tools = __esm({
|
|
|
2555
2487
|
init_ask_user();
|
|
2556
2488
|
init_write_pdf();
|
|
2557
2489
|
init_write_docx();
|
|
2558
|
-
init_write_pptx();
|
|
2559
2490
|
init_search_keyword();
|
|
2560
2491
|
TOOL_MAP = {
|
|
2561
2492
|
web_search,
|
|
@@ -2570,7 +2501,6 @@ var init_tools = __esm({
|
|
|
2570
2501
|
read_folder,
|
|
2571
2502
|
write_pdf,
|
|
2572
2503
|
write_docx,
|
|
2573
|
-
write_pptx,
|
|
2574
2504
|
search_keyword,
|
|
2575
2505
|
ask: ask_user
|
|
2576
2506
|
};
|
|
@@ -2590,8 +2520,8 @@ var init_tools = __esm({
|
|
|
2590
2520
|
|
|
2591
2521
|
// src/utils/ai.js
|
|
2592
2522
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
2593
|
-
import
|
|
2594
|
-
import
|
|
2523
|
+
import path15 from "path";
|
|
2524
|
+
import fs16 from "fs";
|
|
2595
2525
|
var client, TERMINATION_SIGNAL, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, detectToolCalls, initAI, getAIStream;
|
|
2596
2526
|
var init_ai = __esm({
|
|
2597
2527
|
"src/utils/ai.js"() {
|
|
@@ -2620,14 +2550,13 @@ var init_ai = __esm({
|
|
|
2620
2550
|
"search_keyword": "Finding Files",
|
|
2621
2551
|
"ask": "Asking User",
|
|
2622
2552
|
"write_pdf": "Creating PDF",
|
|
2623
|
-
"write_pptx": "Creating Presentation",
|
|
2624
2553
|
"write_docx": "Creating Document"
|
|
2625
2554
|
};
|
|
2626
2555
|
getToolDetail = (toolName, argsStr) => {
|
|
2627
2556
|
try {
|
|
2628
2557
|
const pArgs = parseArgs(argsStr);
|
|
2629
2558
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
2630
|
-
return filePath ?
|
|
2559
|
+
return filePath ? path15.basename(filePath.replace(/[\\"]/g, "")) : null;
|
|
2631
2560
|
} catch (e) {
|
|
2632
2561
|
return null;
|
|
2633
2562
|
}
|
|
@@ -2708,9 +2637,9 @@ var init_ai = __esm({
|
|
|
2708
2637
|
finalSynthesis = fullContent;
|
|
2709
2638
|
if (lastUsage) await addToUsage("tokens", lastUsage.totalTokenCount || 0);
|
|
2710
2639
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2711
|
-
const janitorLogDir =
|
|
2712
|
-
if (!
|
|
2713
|
-
|
|
2640
|
+
const janitorLogDir = path15.join(LOGS_DIR, "janitor");
|
|
2641
|
+
if (!fs16.existsSync(janitorLogDir)) fs16.mkdirSync(janitorLogDir, { recursive: true });
|
|
2642
|
+
fs16.appendFileSync(path15.join(janitorLogDir, "debug.log"), `
|
|
2714
2643
|
|
|
2715
2644
|
---------------------------------------------------
|
|
2716
2645
|
|
|
@@ -2730,8 +2659,8 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2730
2659
|
const toolContext = { chatId, sessionId: chatId, history };
|
|
2731
2660
|
const result = await dispatchTool(janitorToolCall.toolName, janitorToolCall.args, toolContext);
|
|
2732
2661
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2733
|
-
const janitorLogDir =
|
|
2734
|
-
|
|
2662
|
+
const janitorLogDir = path15.join(LOGS_DIR, "janitor");
|
|
2663
|
+
fs16.appendFileSync(path15.join(janitorLogDir, "debug.log"), `DEBUG [${date}]: RESULT [${janitorToolCall.toolName}]: ${result}
|
|
2735
2664
|
`);
|
|
2736
2665
|
if (janitorToolCall.toolName === "memory" && !janitorToolCall.args.includes("action='temp'")) {
|
|
2737
2666
|
if (onMemoryUpdated) onMemoryUpdated();
|
|
@@ -2741,9 +2670,9 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2741
2670
|
} catch (janitorErr) {
|
|
2742
2671
|
attempts++;
|
|
2743
2672
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2744
|
-
const janitorErrDir =
|
|
2745
|
-
if (!
|
|
2746
|
-
|
|
2673
|
+
const janitorErrDir = path15.join(LOGS_DIR, "janitor");
|
|
2674
|
+
if (!fs16.existsSync(janitorErrDir)) fs16.mkdirSync(janitorErrDir, { recursive: true });
|
|
2675
|
+
fs16.appendFileSync(path15.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${String(janitorErr)}
|
|
2747
2676
|
|
|
2748
2677
|
`);
|
|
2749
2678
|
if (attempts > MAX_JANITOR_RETRIES) break;
|
|
@@ -2752,8 +2681,8 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2752
2681
|
}
|
|
2753
2682
|
}
|
|
2754
2683
|
if (attempts) {
|
|
2755
|
-
const janitorErrDir =
|
|
2756
|
-
|
|
2684
|
+
const janitorErrDir = path15.join(LOGS_DIR, "janitor");
|
|
2685
|
+
fs16.appendFileSync(path15.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
|
|
2757
2686
|
|
|
2758
2687
|
|
|
2759
2688
|
`);
|
|
@@ -3144,19 +3073,19 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
3144
3073
|
const potentialTool = toolContext.toolName;
|
|
3145
3074
|
const partialArgs = toolContext.args || "";
|
|
3146
3075
|
let detail = null;
|
|
3147
|
-
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "
|
|
3076
|
+
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "write_docx", "search_keyword"].includes(potentialTool)) {
|
|
3148
3077
|
const pArgs = parseArgs(partialArgs);
|
|
3149
3078
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
3150
3079
|
const keyword = pArgs.keyword;
|
|
3151
3080
|
if (keyword) {
|
|
3152
3081
|
detail = keyword.replace(/[\\"]/g, "");
|
|
3153
3082
|
} else if (filePath) {
|
|
3154
|
-
detail =
|
|
3083
|
+
detail = path15.basename(filePath.replace(/[\\"]/g, ""));
|
|
3155
3084
|
} else {
|
|
3156
3085
|
const m = partialArgs.match(/(?:path|targetFile|TargetFile|directory|keyword)\s*=\s*\\?["']?([^\\"' \),]+)/);
|
|
3157
3086
|
if (m) {
|
|
3158
3087
|
const val = m[1].replace(/[\\"]/g, "");
|
|
3159
|
-
detail = potentialTool === "search_keyword" ? val :
|
|
3088
|
+
detail = potentialTool === "search_keyword" ? val : path15.basename(val);
|
|
3160
3089
|
}
|
|
3161
3090
|
}
|
|
3162
3091
|
}
|
|
@@ -3243,9 +3172,9 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
3243
3172
|
let totalLines = "...";
|
|
3244
3173
|
let actualEndLine = eLine;
|
|
3245
3174
|
try {
|
|
3246
|
-
const absPath =
|
|
3247
|
-
if (
|
|
3248
|
-
const content =
|
|
3175
|
+
const absPath = path15.resolve(process.cwd(), targetPath2);
|
|
3176
|
+
if (fs16.existsSync(absPath)) {
|
|
3177
|
+
const content = fs16.readFileSync(absPath, "utf8");
|
|
3249
3178
|
const lines = content.split("\n").length;
|
|
3250
3179
|
totalLines = lines;
|
|
3251
3180
|
actualEndLine = Math.min(eLine, lines);
|
|
@@ -3272,8 +3201,6 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
3272
3201
|
label = `\u{1F4D1} PDF CREATED: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
|
|
3273
3202
|
} else if (toolCall.toolName === "write_docx") {
|
|
3274
3203
|
label = `\u{1F4DD} DOCX CREATED: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
|
|
3275
|
-
} else if (toolCall.toolName === "write_pptx") {
|
|
3276
|
-
label = `\u{1F4CA} PPTX CREATED: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
|
|
3277
3204
|
} else if (toolCall.toolName === "search_keyword") {
|
|
3278
3205
|
const { keyword } = parseArgs(toolCall.args);
|
|
3279
3206
|
label = `\u{1F50E} KEYWORD SEARCHED: "${keyword}"`.toUpperCase();
|
|
@@ -3295,7 +3222,7 @@ ${boxBottom}` };
|
|
|
3295
3222
|
const { command } = parseArgs(toolCall.args);
|
|
3296
3223
|
if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
|
|
3297
3224
|
const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
|
|
3298
|
-
const currentDrive =
|
|
3225
|
+
const currentDrive = path15.resolve(process.cwd()).substring(0, 3).toLowerCase();
|
|
3299
3226
|
const isViolating = riskyPatterns.some((pattern) => {
|
|
3300
3227
|
if (pattern.source === "[a-zA-Z]:[\\\\\\/]") {
|
|
3301
3228
|
const driveMatch = command.match(/[a-zA-Z]:[\\\/]/i);
|
|
@@ -3318,8 +3245,8 @@ ${boxBottom}` };
|
|
|
3318
3245
|
const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
|
|
3319
3246
|
if (targetPath) {
|
|
3320
3247
|
const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
|
|
3321
|
-
const absoluteTarget =
|
|
3322
|
-
const absoluteCwd =
|
|
3248
|
+
const absoluteTarget = path15.resolve(targetPath);
|
|
3249
|
+
const absoluteCwd = path15.resolve(process.cwd());
|
|
3323
3250
|
if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
|
|
3324
3251
|
const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace. To enable this, ask the user to turn on "External Workspace Access" in /settings.`;
|
|
3325
3252
|
toolResults.push({ role: "user", text: `[TOOL_RESULT]: ERROR: ${denyMsg}
|
|
@@ -3422,9 +3349,9 @@ ${boxBottom}` };
|
|
|
3422
3349
|
const errMsg = err.status || err.error && err.error.message || String(err);
|
|
3423
3350
|
const errLog = String(err);
|
|
3424
3351
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
3425
|
-
const agentErrDir =
|
|
3426
|
-
if (!
|
|
3427
|
-
|
|
3352
|
+
const agentErrDir = path15.join(LOGS_DIR, "agent");
|
|
3353
|
+
if (!fs16.existsSync(agentErrDir)) fs16.mkdirSync(agentErrDir, { recursive: true });
|
|
3354
|
+
fs16.appendFileSync(path15.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
|
|
3428
3355
|
|
|
3429
3356
|
----------------------------------------------------------------------
|
|
3430
3357
|
|
|
@@ -3447,7 +3374,7 @@ ${boxBottom}` };
|
|
|
3447
3374
|
yield { type: "status", content: `Error Occured. Recovering Stream...` };
|
|
3448
3375
|
} else {
|
|
3449
3376
|
throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
|
|
3450
|
-
Error Log can be found in ${
|
|
3377
|
+
Error Log can be found in ${path15.join(LOGS_DIR, "agent", "error.log")}`);
|
|
3451
3378
|
}
|
|
3452
3379
|
} else {
|
|
3453
3380
|
if (retryCount <= MAX_RETRIES) {
|
|
@@ -3462,7 +3389,7 @@ Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
3462
3389
|
yield { type: "status", content: `Retrying Connection...` };
|
|
3463
3390
|
} else {
|
|
3464
3391
|
throw new Error(`Model cannot be reached. (Failed ${MAX_RETRIES} times)
|
|
3465
|
-
Error Log can be found in ${
|
|
3392
|
+
Error Log can be found in ${path15.join(LOGS_DIR, "agent", "error.log")}`);
|
|
3466
3393
|
}
|
|
3467
3394
|
}
|
|
3468
3395
|
}
|
|
@@ -3523,8 +3450,8 @@ ${timestamp}`;
|
|
|
3523
3450
|
});
|
|
3524
3451
|
|
|
3525
3452
|
// src/utils/settings.js
|
|
3526
|
-
import
|
|
3527
|
-
import
|
|
3453
|
+
import fs17 from "fs-extra";
|
|
3454
|
+
import path16 from "path";
|
|
3528
3455
|
var DEFAULT_SETTINGS, loadSettings, migrateToExternal, saveSettings;
|
|
3529
3456
|
var init_settings = __esm({
|
|
3530
3457
|
"src/utils/settings.js"() {
|
|
@@ -3559,8 +3486,8 @@ var init_settings = __esm({
|
|
|
3559
3486
|
};
|
|
3560
3487
|
loadSettings = async () => {
|
|
3561
3488
|
try {
|
|
3562
|
-
if (await
|
|
3563
|
-
const saved = await
|
|
3489
|
+
if (await fs17.exists(SETTINGS_FILE)) {
|
|
3490
|
+
const saved = await fs17.readJson(SETTINGS_FILE);
|
|
3564
3491
|
const merged = {
|
|
3565
3492
|
...DEFAULT_SETTINGS,
|
|
3566
3493
|
...saved,
|
|
@@ -3570,7 +3497,7 @@ var init_settings = __esm({
|
|
|
3570
3497
|
};
|
|
3571
3498
|
if (merged.showFullThinking === false) {
|
|
3572
3499
|
merged.showFullThinking = true;
|
|
3573
|
-
await
|
|
3500
|
+
await fs17.writeJson(SETTINGS_FILE, merged, { spaces: 2 });
|
|
3574
3501
|
}
|
|
3575
3502
|
return merged;
|
|
3576
3503
|
}
|
|
@@ -3583,12 +3510,12 @@ var init_settings = __esm({
|
|
|
3583
3510
|
const { FLUXFLOW_DIR: FLUXFLOW_DIR2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
3584
3511
|
const folders = ["logs", "secret"];
|
|
3585
3512
|
for (const folder of folders) {
|
|
3586
|
-
const src =
|
|
3587
|
-
const dest =
|
|
3513
|
+
const src = path16.join(FLUXFLOW_DIR2, folder);
|
|
3514
|
+
const dest = path16.join(newPath, folder);
|
|
3588
3515
|
try {
|
|
3589
|
-
if (await
|
|
3590
|
-
await
|
|
3591
|
-
await
|
|
3516
|
+
if (await fs17.exists(src)) {
|
|
3517
|
+
await fs17.ensureDir(dest);
|
|
3518
|
+
await fs17.copy(src, dest, { overwrite: true });
|
|
3592
3519
|
}
|
|
3593
3520
|
} catch (err) {
|
|
3594
3521
|
console.error(`Migration failed for ${folder}:`, err);
|
|
@@ -3602,8 +3529,8 @@ var init_settings = __esm({
|
|
|
3602
3529
|
await migrateToExternal(settings.systemSettings.externalDataPath);
|
|
3603
3530
|
}
|
|
3604
3531
|
const updated = { ...current, ...settings };
|
|
3605
|
-
await
|
|
3606
|
-
await
|
|
3532
|
+
await fs17.ensureDir(path16.dirname(SETTINGS_FILE));
|
|
3533
|
+
await fs17.writeJson(SETTINGS_FILE, updated, { spaces: 2 });
|
|
3607
3534
|
return true;
|
|
3608
3535
|
} catch (err) {
|
|
3609
3536
|
console.error("Failed to save settings:", err);
|
|
@@ -3816,7 +3743,7 @@ var init_UpdateProcessor = __esm({
|
|
|
3816
3743
|
import puppeteer4 from "puppeteer";
|
|
3817
3744
|
import { exec as exec3 } from "child_process";
|
|
3818
3745
|
import { promisify } from "util";
|
|
3819
|
-
import
|
|
3746
|
+
import fs18 from "fs";
|
|
3820
3747
|
var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
|
|
3821
3748
|
var init_setup = __esm({
|
|
3822
3749
|
"src/utils/setup.js"() {
|
|
@@ -3824,7 +3751,7 @@ var init_setup = __esm({
|
|
|
3824
3751
|
checkPuppeteerReady = () => {
|
|
3825
3752
|
try {
|
|
3826
3753
|
const exePath = puppeteer4.executablePath();
|
|
3827
|
-
const exists = exePath &&
|
|
3754
|
+
const exists = exePath && fs18.existsSync(exePath);
|
|
3828
3755
|
if (exists) return true;
|
|
3829
3756
|
} catch (e) {
|
|
3830
3757
|
return false;
|
|
@@ -3858,8 +3785,8 @@ import os3 from "os";
|
|
|
3858
3785
|
import React10, { useState as useState7, useEffect as useEffect5, useRef as useRef2, useMemo } from "react";
|
|
3859
3786
|
import { Box as Box10, Text as Text10, useInput as useInput4, useStdout } from "ink";
|
|
3860
3787
|
import Spinner2 from "ink-spinner";
|
|
3861
|
-
import
|
|
3862
|
-
import
|
|
3788
|
+
import fs19 from "fs-extra";
|
|
3789
|
+
import path17 from "path";
|
|
3863
3790
|
import { exec as exec4 } from "child_process";
|
|
3864
3791
|
import { MultilineInput } from "ink-multiline-input";
|
|
3865
3792
|
import TextInput3 from "ink-text-input";
|
|
@@ -4581,12 +4508,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
4581
4508
|
setCompletedIndex(prev.length + 1);
|
|
4582
4509
|
return [...prev, { id: Date.now(), role: "system", text: "\u2622\uFE0F [NUCLEAR] Initiating reset...", isMeta: true }];
|
|
4583
4510
|
});
|
|
4584
|
-
if (
|
|
4585
|
-
if (
|
|
4586
|
-
if (
|
|
4511
|
+
if (fs19.existsSync(LOGS_DIR)) fs19.removeSync(LOGS_DIR);
|
|
4512
|
+
if (fs19.existsSync(SECRET_DIR)) fs19.removeSync(SECRET_DIR);
|
|
4513
|
+
if (fs19.existsSync(SETTINGS_FILE)) fs19.removeSync(SETTINGS_FILE);
|
|
4587
4514
|
try {
|
|
4588
|
-
const items =
|
|
4589
|
-
if (items.length === 0)
|
|
4515
|
+
const items = fs19.readdirSync(FLUXFLOW_DIR);
|
|
4516
|
+
if (items.length === 0) fs19.removeSync(FLUXFLOW_DIR);
|
|
4590
4517
|
} catch (e) {
|
|
4591
4518
|
}
|
|
4592
4519
|
setTimeout(() => {
|
|
@@ -4643,14 +4570,14 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
4643
4570
|
# SKILLS & WORKFLOWS
|
|
4644
4571
|
- [Define custom step-by-step recipes for this project here]
|
|
4645
4572
|
`;
|
|
4646
|
-
const filePath =
|
|
4647
|
-
if (
|
|
4573
|
+
const filePath = path17.join(process.cwd(), "FluxFlow.md");
|
|
4574
|
+
if (fs19.pathExistsSync(filePath)) {
|
|
4648
4575
|
setMessages((prev) => {
|
|
4649
4576
|
setCompletedIndex(prev.length + 1);
|
|
4650
4577
|
return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "\u274C ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
|
|
4651
4578
|
});
|
|
4652
4579
|
} else {
|
|
4653
|
-
|
|
4580
|
+
fs19.writeFileSync(filePath, template);
|
|
4654
4581
|
setMessages((prev) => {
|
|
4655
4582
|
setCompletedIndex(prev.length + 1);
|
|
4656
4583
|
return [...prev, { id: "init-ok-" + Date.now(), role: "system", text: "\u2705 [SUCCESS] FluxFlow.md has been initialized. You can now customize it for this project.", isMeta: true }];
|
|
@@ -5624,8 +5551,8 @@ var init_app = __esm({
|
|
|
5624
5551
|
init_text();
|
|
5625
5552
|
SESSION_START_TIME = Date.now();
|
|
5626
5553
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
5627
|
-
versionFluxflow = "1.9.
|
|
5628
|
-
updatedOn = "2026-05-
|
|
5554
|
+
versionFluxflow = "1.9.20";
|
|
5555
|
+
updatedOn = "2026-05-17";
|
|
5629
5556
|
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION")), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, null, "The agent already finished the task before your hint was consumed.")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 0 }, /* @__PURE__ */ React10.createElement(
|
|
5630
5557
|
CommandMenu,
|
|
5631
5558
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxflow-cli",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.20",
|
|
4
4
|
"description": "A high-fidelity agentic terminal assistant for the Flux Era.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
"fs-extra": "^11.3.4",
|
|
43
43
|
"gradient-string": "^3.0.0",
|
|
44
44
|
"html-to-docx": "^1.8.0",
|
|
45
|
-
"html2pptxgenjs": "^0.0.3",
|
|
46
45
|
"ink": "^7.0.1",
|
|
47
46
|
"ink-multiline-input": "^0.1.0",
|
|
48
47
|
"ink-select-input": "^6.2.0",
|
|
@@ -50,7 +49,6 @@
|
|
|
50
49
|
"ink-text-input": "^6.0.0",
|
|
51
50
|
"nanoid": "^5.1.9",
|
|
52
51
|
"pdf-lib": "^1.17.1",
|
|
53
|
-
"pptxgenjs": "^4.0.1",
|
|
54
52
|
"puppeteer": "24.43.1",
|
|
55
53
|
"react": "^19.2.5",
|
|
56
54
|
"zod": "^4.3.6"
|