fluxflow-cli 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fluxflow.js +141 -91
- package/package.json +2 -3
package/dist/fluxflow.js
CHANGED
|
@@ -754,28 +754,35 @@ Current date and Time is: ${dateTimeStr}
|
|
|
754
754
|
--- END SYSTEM INSTRUCTION ---`.trim();
|
|
755
755
|
};
|
|
756
756
|
getJanitorInstruction = (originalText, agentRaws, userMemories = "", isMemoryEnabled = true, needTitle = false) => {
|
|
757
|
-
|
|
757
|
+
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)}`;
|
|
758
|
+
if (agentRes.length > 3500) {
|
|
759
|
+
agentRes += "\n... (truncated) ...";
|
|
760
|
+
}
|
|
761
|
+
let originalTextProcessed = originalText.replace(/\[Prompted on:.*?\]/g, "");
|
|
762
|
+
return `USER PROMPT: ${originalTextProcessed.substring(0, 600)}${originalTextProcessed.length > 600 ? "\n... (truncated) ..." : ""}
|
|
758
763
|
AGENT RAWS (responses from this turn):
|
|
759
|
-
${
|
|
764
|
+
${agentRes}
|
|
765
|
+
${userMemories ? `
|
|
766
|
+
|
|
767
|
+
-- CURRENT PERSISTENT USER MEMORIES --
|
|
768
|
+
${userMemories}
|
|
769
|
+
-------------------------------------------------
|
|
770
|
+
` : ""}
|
|
760
771
|
|
|
761
772
|
--- START SYSTEM INSTRUCTION (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY) ---
|
|
762
|
-
YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT MEDIUM IS VALID TOOL
|
|
773
|
+
YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT MEDIUM IS VALID TOOL CALLS.
|
|
763
774
|
[CRITICAL RULES]
|
|
764
775
|
1. OUTPUT ONLY 'tool:functions.xxx' CALLS.
|
|
765
|
-
2. DO NOT EXPLAIN. DO NOT
|
|
776
|
+
2. DO NOT EXPLAIN. DO NOT TALK TO THE USER.
|
|
766
777
|
3. NON-TOOL TEXT WILL BREAK THE SYSTEM.
|
|
767
|
-
4. DO NOT REPEAT AGENT RAWS IN YOUR RESPONSE.
|
|
768
|
-
5. IF YOU GET ONLY USER
|
|
778
|
+
4. DO NOT REPEAT AGENT RAWS AND TOOL RESULTS IN YOUR RESPONSE.
|
|
779
|
+
5. IF YOU GET ONLY USER QUERY AND NO AGENT RAWS, THEN JUST USE TEMP MEMORY TO LOG THE SUMMARY OF USER QUERY.
|
|
769
780
|
|
|
770
781
|
YOUR JOB: Analyze the 'User prompt' and 'Agent Raws' to extract facts for long-term memory or handle system tasks.
|
|
771
782
|
${isMemoryEnabled ? `If user tell something that is important (like, hobbies, preferences, facts about user, hates, likes, etc) to know user better over time, use long term memory tools.` : ""}
|
|
772
783
|
|
|
773
784
|
${JANITOR_TOOLS_PROTOCOL(isMemoryEnabled, needTitle)}
|
|
774
785
|
|
|
775
|
-
${userMemories ? `-- CURRENT PERSISTENT USER MEMORIES --
|
|
776
|
-
${userMemories}
|
|
777
|
-
-------------------------------------------------
|
|
778
|
-
` : ""}
|
|
779
786
|
Current date and Time: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
780
787
|
|
|
781
788
|
--- END SYSTEM INSTRUCTION ---`.trim();
|
|
@@ -973,7 +980,7 @@ var init_arg_parser = __esm({
|
|
|
973
980
|
});
|
|
974
981
|
|
|
975
982
|
// src/tools/web_search.js
|
|
976
|
-
import
|
|
983
|
+
import puppeteer from "puppeteer";
|
|
977
984
|
import fs6 from "fs";
|
|
978
985
|
import path6 from "path";
|
|
979
986
|
var web_search;
|
|
@@ -984,67 +991,83 @@ var init_web_search = __esm({
|
|
|
984
991
|
web_search = async (argsString) => {
|
|
985
992
|
const { query, limit = 10 } = parseArgs(argsString);
|
|
986
993
|
if (!query) return 'ERROR: Missing "query" argument for web_search.';
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
}
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
994
|
+
const maxRetries = 3;
|
|
995
|
+
let lastError = null;
|
|
996
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
997
|
+
let browser = null;
|
|
998
|
+
try {
|
|
999
|
+
browser = await puppeteer.launch({
|
|
1000
|
+
headless: true,
|
|
1001
|
+
args: [
|
|
1002
|
+
"--no-sandbox",
|
|
1003
|
+
"--disable-setuid-sandbox",
|
|
1004
|
+
"--disable-gpu",
|
|
1005
|
+
"--disable-dev-shm-usage"
|
|
1006
|
+
]
|
|
1007
|
+
});
|
|
1008
|
+
const page = await browser.newPage();
|
|
1009
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
|
|
1010
|
+
await page.setViewport({ width: 1280, height: 800 });
|
|
1011
|
+
const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
|
|
1012
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
1013
|
+
const searchUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
1014
|
+
await page.goto(searchUrl, { waitUntil: "networkidle2" });
|
|
1015
|
+
const results = await page.$$eval(".result", (elements, maxLimit) => {
|
|
1016
|
+
return elements.slice(0, maxLimit).map((el, i) => {
|
|
1017
|
+
const titleEl = el.querySelector(".result__a");
|
|
1018
|
+
const snippetEl = el.querySelector(".result__snippet");
|
|
1019
|
+
let url = titleEl ? titleEl.href : "";
|
|
1020
|
+
if (url.includes("uddg=")) {
|
|
1021
|
+
url = decodeURIComponent(url.split("uddg=")[1].split("&")[0]);
|
|
1022
|
+
}
|
|
1023
|
+
const title = titleEl ? titleEl.innerText.trim() : "No Title";
|
|
1024
|
+
const snippet = snippetEl ? snippetEl.innerText.trim() : "No Snippet";
|
|
1025
|
+
return `${i + 1}. ${title}
|
|
1007
1026
|
Source: ${url}
|
|
1008
|
-
Snippet: ${snippet}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1027
|
+
Snippet: ${snippet}`;
|
|
1028
|
+
});
|
|
1029
|
+
}, limit);
|
|
1030
|
+
if (results.length === 0) {
|
|
1031
|
+
const bodyText = await page.evaluate(() => document.body.innerText);
|
|
1032
|
+
if (bodyText.includes("anomaly")) {
|
|
1033
|
+
throw new Error("ANOMALY_DETECTED");
|
|
1034
|
+
}
|
|
1035
|
+
await browser.close();
|
|
1036
|
+
return `No results found for query: [${query}].`;
|
|
1037
|
+
}
|
|
1038
|
+
const finalResults = results.join("\n\n");
|
|
1039
|
+
const toolLogDir = path6.join(LOGS_DIR, "tools");
|
|
1040
|
+
if (!fs6.existsSync(toolLogDir)) fs6.mkdirSync(toolLogDir, { recursive: true });
|
|
1041
|
+
fs6.appendFileSync(path6.join(toolLogDir, "search-results.log"), `SEARCH ${(/* @__PURE__ */ new Date()).toISOString()} - Query: [${query}]. Count: ${results.length}.
|
|
1042
|
+
Content:
|
|
1043
|
+
${finalResults}
|
|
1044
|
+
|
|
1045
|
+
--------------------------------------------------------
|
|
1018
1046
|
|
|
1019
1047
|
|
|
1020
1048
|
`);
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
const toolErrDir = path6.join(LOGS_DIR, "tools");
|
|
1024
|
-
if (!fs6.existsSync(toolErrDir)) {
|
|
1025
|
-
fs6.mkdirSync(toolErrDir, { recursive: true });
|
|
1026
|
-
}
|
|
1027
|
-
fs6.appendFileSync(path6.join(toolErrDir, "error.log"), `ERROR ${(/* @__PURE__ */ new Date()).toISOString()} - DDG detected unusual activity. Cuimp impersonation might need adjustment.
|
|
1028
|
-
`);
|
|
1029
|
-
throw new Error("DDG detected unusual activity. Cuimp impersonation might need adjustment.");
|
|
1030
|
-
}
|
|
1031
|
-
return `No results found for query: [${query}].`;
|
|
1032
|
-
}
|
|
1033
|
-
const finalResults = results.join("\n\n");
|
|
1034
|
-
return `Search results for [${query}]:
|
|
1049
|
+
await browser.close();
|
|
1050
|
+
return `Search results for [${query}]:
|
|
1035
1051
|
|
|
1036
1052
|
${finalResults}`;
|
|
1037
|
-
|
|
1038
|
-
|
|
1053
|
+
} catch (err) {
|
|
1054
|
+
lastError = err;
|
|
1055
|
+
if (browser) await browser.close();
|
|
1056
|
+
if (attempt < maxRetries) {
|
|
1057
|
+
const backoff = Math.pow(2, attempt) * 1e3;
|
|
1058
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1039
1061
|
}
|
|
1062
|
+
return `ERROR: Search failed after ${maxRetries + 1} attempts. Last error: ${lastError.message}`;
|
|
1040
1063
|
};
|
|
1041
1064
|
}
|
|
1042
1065
|
});
|
|
1043
1066
|
|
|
1044
1067
|
// src/tools/web_scrape.js
|
|
1068
|
+
import puppeteer2 from "puppeteer";
|
|
1045
1069
|
import fs7 from "fs";
|
|
1046
1070
|
import path7 from "path";
|
|
1047
|
-
import * as cuimp2 from "cuimp";
|
|
1048
1071
|
var web_scrape;
|
|
1049
1072
|
var init_web_scrape = __esm({
|
|
1050
1073
|
"src/tools/web_scrape.js"() {
|
|
@@ -1052,39 +1075,66 @@ var init_web_scrape = __esm({
|
|
|
1052
1075
|
web_scrape = async (args) => {
|
|
1053
1076
|
const urlMatch = args.match(/url\s*=\s*["'](.*)["']/);
|
|
1054
1077
|
const url = urlMatch ? urlMatch[1] : args;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1078
|
+
const maxRetries = 3;
|
|
1079
|
+
let lastError = null;
|
|
1080
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1081
|
+
let browser = null;
|
|
1082
|
+
try {
|
|
1083
|
+
browser = await puppeteer2.launch({
|
|
1084
|
+
headless: true,
|
|
1085
|
+
args: [
|
|
1086
|
+
"--no-sandbox",
|
|
1087
|
+
"--disable-setuid-sandbox",
|
|
1088
|
+
"--disable-gpu",
|
|
1089
|
+
"--disable-dev-shm-usage"
|
|
1090
|
+
]
|
|
1091
|
+
});
|
|
1092
|
+
const page = await browser.newPage();
|
|
1093
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
|
|
1094
|
+
await page.setViewport({ width: 1280, height: 1600 });
|
|
1095
|
+
const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
|
|
1096
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
1097
|
+
await page.goto(url, { waitUntil: "networkidle2", timeout: 45e3 });
|
|
1098
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
1099
|
+
let text = await page.evaluate(() => {
|
|
1100
|
+
const junk = document.querySelectorAll("script, style, nav, footer, header, noscript");
|
|
1101
|
+
junk.forEach((el) => el.remove());
|
|
1102
|
+
const links = document.querySelectorAll("a");
|
|
1103
|
+
links.forEach((a) => {
|
|
1104
|
+
const href = a.href;
|
|
1105
|
+
const content = a.innerText.trim();
|
|
1106
|
+
if (href && content && !href.startsWith("javascript:") && !href.startsWith("#")) {
|
|
1107
|
+
a.innerText = ` [${content}](${href}) `;
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
return document.body.innerText;
|
|
1111
|
+
});
|
|
1112
|
+
if (!text) throw new Error("EMPTY_RENDER_RESULT");
|
|
1113
|
+
const cleanedText = text.replace(/\s+/g, " ").trim().substring(0, 25e3);
|
|
1114
|
+
const toolLogDir = path7.join(LOGS_DIR, "tools");
|
|
1115
|
+
if (!fs7.existsSync(toolLogDir)) fs7.mkdirSync(toolLogDir, { recursive: true });
|
|
1116
|
+
fs7.appendFileSync(path7.join(toolLogDir, "search-scraped.log"), `PUPPETEER ${(/* @__PURE__ */ new Date()).toISOString()} - URL: [${url}]. Length: ${cleanedText.length}.
|
|
1117
|
+
Content:
|
|
1118
|
+
${cleanedText}
|
|
1119
|
+
|
|
1120
|
+
--------------------------------------------------------
|
|
1079
1121
|
|
|
1080
1122
|
|
|
1081
1123
|
`);
|
|
1082
|
-
|
|
1124
|
+
await browser.close();
|
|
1125
|
+
return `CONTENT FROM [${url}]:
|
|
1083
1126
|
|
|
1084
|
-
${
|
|
1085
|
-
|
|
1086
|
-
|
|
1127
|
+
${cleanedText}${text.length > 25e3 ? "\n\n[TRUNCATED AT 25K CHARS]" : ""}`;
|
|
1128
|
+
} catch (err) {
|
|
1129
|
+
lastError = err;
|
|
1130
|
+
if (browser) await browser.close();
|
|
1131
|
+
if (attempt < maxRetries) {
|
|
1132
|
+
const backoff = Math.pow(2, attempt) * 1e3;
|
|
1133
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1087
1136
|
}
|
|
1137
|
+
return `ERROR: Scrape failed after ${maxRetries + 1} attempts. Last error: ${lastError.message}`;
|
|
1088
1138
|
};
|
|
1089
1139
|
}
|
|
1090
1140
|
});
|
|
@@ -1633,7 +1683,7 @@ var init_ask_user = __esm({
|
|
|
1633
1683
|
});
|
|
1634
1684
|
|
|
1635
1685
|
// src/tools/write_pdf.js
|
|
1636
|
-
import
|
|
1686
|
+
import puppeteer3 from "puppeteer";
|
|
1637
1687
|
import path13 from "path";
|
|
1638
1688
|
import fs13 from "fs-extra";
|
|
1639
1689
|
var write_pdf;
|
|
@@ -1648,7 +1698,7 @@ var init_write_pdf = __esm({
|
|
|
1648
1698
|
let browser = null;
|
|
1649
1699
|
try {
|
|
1650
1700
|
await fs13.ensureDir(path13.dirname(absolutePath));
|
|
1651
|
-
browser = await
|
|
1701
|
+
browser = await puppeteer3.launch({
|
|
1652
1702
|
headless: true,
|
|
1653
1703
|
args: [
|
|
1654
1704
|
"--no-sandbox",
|
|
@@ -2461,7 +2511,7 @@ var init_UpdateProcessor = __esm({
|
|
|
2461
2511
|
});
|
|
2462
2512
|
|
|
2463
2513
|
// src/utils/setup.js
|
|
2464
|
-
import
|
|
2514
|
+
import puppeteer4 from "puppeteer";
|
|
2465
2515
|
import { exec as exec2 } from "child_process";
|
|
2466
2516
|
import { promisify } from "util";
|
|
2467
2517
|
import fs16 from "fs";
|
|
@@ -2471,7 +2521,7 @@ var init_setup = __esm({
|
|
|
2471
2521
|
execAsync = promisify(exec2);
|
|
2472
2522
|
checkPuppeteerReady = () => {
|
|
2473
2523
|
try {
|
|
2474
|
-
const exePath =
|
|
2524
|
+
const exePath = puppeteer4.executablePath();
|
|
2475
2525
|
const exists = exePath && fs16.existsSync(exePath);
|
|
2476
2526
|
if (exists) return true;
|
|
2477
2527
|
} catch (e) {
|
|
@@ -4039,7 +4089,7 @@ var init_app = __esm({
|
|
|
4039
4089
|
init_setup();
|
|
4040
4090
|
SESSION_START_TIME = Date.now();
|
|
4041
4091
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
4042
|
-
versionFluxflow = "1.5.
|
|
4092
|
+
versionFluxflow = "1.5.2";
|
|
4043
4093
|
updatedOn = "2026-05-01";
|
|
4044
4094
|
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION"), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1 }, "The agent already finished the task (turn: finish) before your hint was consumed."), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, backgroundColor: "#222", paddingX: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(
|
|
4045
4095
|
CommandMenu,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxflow-cli",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "A high-fidelity agentic terminal assistant for the Flux Era.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -34,12 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"start": "tsx ./src/cli.jsx",
|
|
37
|
-
"build": "esbuild ./src/cli.jsx --bundle --platform=node --format=esm --outfile=./dist/fluxflow.js --external:react --external:ink --external:chalk --external:fs-extra --external:gradient-string --external:ink-text-input --external:ink-select-input --external:ink-spinner --external:ink-multiline-input --external:@google/genai --external:zod --external:
|
|
37
|
+
"build": "esbuild ./src/cli.jsx --bundle --platform=node --format=esm --outfile=./dist/fluxflow.js --external:react --external:ink --external:chalk --external:fs-extra --external:gradient-string --external:ink-text-input --external:ink-select-input --external:ink-spinner --external:ink-multiline-input --external:@google/genai --external:zod --external:nanoid --external:puppeteer --external:typescript"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@google/genai": "^1.50.1",
|
|
41
41
|
"chalk": "^5.6.2",
|
|
42
|
-
"cuimp": "^1.10.0",
|
|
43
42
|
"fs-extra": "^11.3.4",
|
|
44
43
|
"gradient-string": "^3.0.0",
|
|
45
44
|
"ink": "^7.0.1",
|