fluxflow-cli 1.16.5 → 1.17.0
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 +171 -33
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -238,7 +238,7 @@ var init_ChatLayout = __esm({
|
|
|
238
238
|
};
|
|
239
239
|
InlineMarkdown = React2.memo(({ text, color }) => {
|
|
240
240
|
if (!text) return null;
|
|
241
|
-
const parts = text.split(/(```[\s\S]*?```|`[^`]
|
|
241
|
+
const parts = text.split(/(```[\s\S]*?```|`[^`]+`|@\[.*?\]|\*\*.*?\*\*|\*.*?\*|\$.*?\$|\[.*?\]\s*\(.*?\)|\[.*?\]\s*\[.*?\]|https?:\/\/[^\s]+)/g);
|
|
242
242
|
return /* @__PURE__ */ React2.createElement(Text2, { color, wrap: "anywhere" }, parts.map((part, j) => {
|
|
243
243
|
if (!part) return null;
|
|
244
244
|
if (part.startsWith("```") && part.endsWith("```")) {
|
|
@@ -253,6 +253,11 @@ var init_ChatLayout = __esm({
|
|
|
253
253
|
if (part.startsWith("`") && part.endsWith("`")) {
|
|
254
254
|
return /* @__PURE__ */ React2.createElement(Text2, { key: j, color: "cyan", backgroundColor: "#003333" }, " ", part.slice(1, -1), " ");
|
|
255
255
|
}
|
|
256
|
+
if (part.startsWith("@[") && part.endsWith("]")) {
|
|
257
|
+
const filePath = part.slice(2, -1);
|
|
258
|
+
const basename = filePath.split("/").pop().split("\\").pop();
|
|
259
|
+
return /* @__PURE__ */ React2.createElement(Text2, { key: j, color: "cyan", backgroundColor: "#1a1a2e" }, " ", basename, " ");
|
|
260
|
+
}
|
|
256
261
|
if (part.startsWith("$") && part.endsWith("$")) {
|
|
257
262
|
const content = part.slice(1, -1);
|
|
258
263
|
const latexParts = content.split(/(\\(?:mathbf|textbf|textit|underline|text|mathrm|textsf|texttt)\{.*?\})/g);
|
|
@@ -529,8 +534,8 @@ var init_ChatLayout = __esm({
|
|
|
529
534
|
wrapText(
|
|
530
535
|
finalContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\\\n/g, "\n").replace(/\\$/, ""),
|
|
531
536
|
columns - 6
|
|
532
|
-
).split("\n").map((line, lineIdx) => /* @__PURE__ */ React2.createElement(Box2, { key: lineIdx, flexDirection: "row", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 0, width: 2 }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, lineIdx === 0 ? "\u276F" : " ")), /* @__PURE__ */ React2.createElement(Box2, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React2.createElement(
|
|
533
|
-
) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, msg.isStreaming && !msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2727 Thinking...") : /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2726 Thought", msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { dimColor: true, color: "gray" }, " for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.duration))) : ""), /* @__PURE__ */ React2.createElement(Box2, { borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, flexDirection: "column", width: "100%" }, formatThinkText(finalContent, columns))) : /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginTop: 0, width: "100%" }, /* @__PURE__ */ React2.createElement(CodeRenderer, { text: finalContent.replace(/ \|\n\n/g, " |\n"), columns }), msg.memoryUpdated && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow", italic: true }, "\u2728 [Memory Updated]"))))
|
|
537
|
+
).split("\n").map((line, lineIdx) => /* @__PURE__ */ React2.createElement(Box2, { key: lineIdx, flexDirection: "row", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 0, width: 2 }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, lineIdx === 0 ? "\u276F" : " ")), /* @__PURE__ */ React2.createElement(Box2, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React2.createElement(InlineMarkdown, { text: line, color: msg.color || "white" }))))
|
|
538
|
+
) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, msg.isStreaming && !msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2727 Thinking...") : /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2726 Thought", msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { dimColor: true, color: "gray" }, " for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.duration))) : ""), /* @__PURE__ */ React2.createElement(Box2, { borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, flexDirection: "column", width: "100%" }, formatThinkText(finalContent, columns))) : /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginTop: 0, width: "100%" }, /* @__PURE__ */ React2.createElement(CodeRenderer, { text: finalContent.replace(/ \|\n\n/g, " |\n"), columns }), msg.memoryUpdated && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow", italic: true }, "\u2728 [Memory Updated]")), msg.role === "agent" && msg.workedDuration ? /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { dimColor: true, color: "gray" }, "[\u26A1 Worked for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.workedDuration)), " ]")) : null))
|
|
534
539
|
);
|
|
535
540
|
});
|
|
536
541
|
ChatLayout = React2.memo(({ messages, showFullThinking, columns = 80 }) => {
|
|
@@ -1275,7 +1280,7 @@ var init_main_tools = __esm({
|
|
|
1275
1280
|
TOOL_PROTOCOL = (mode, osDetected) => `
|
|
1276
1281
|
-- TOOL DEFINITIONS --
|
|
1277
1282
|
Access to internal tools. To call a tool, MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
|
|
1278
|
-
- **STRICT POLICY: MAX 3 TOOL CALLS PER TURN. Next Turn, verify results
|
|
1283
|
+
- **STRICT POLICY: MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**
|
|
1279
1284
|
|
|
1280
1285
|
- COMMUNICATION TOOLS -
|
|
1281
1286
|
1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
|
|
@@ -1366,7 +1371,7 @@ var init_prompts = __esm({
|
|
|
1366
1371
|
init_thinking_prompts();
|
|
1367
1372
|
getMemoryPrompt = (tempMemories = "", userMemories = "", isMemoryEnabled = true, isContext32k = false) => {
|
|
1368
1373
|
if (!isMemoryEnabled) return "";
|
|
1369
|
-
const tempMemoriesStr = tempMemories?.length > 0 && !isContext32k ? `-- RECENT CONTEXT FROM OTHER CHATS (PRIORITY: DYNAMIC-
|
|
1374
|
+
const tempMemoriesStr = tempMemories?.length > 0 && !isContext32k ? `-- RECENT CONTEXT FROM OTHER CHATS (PRIORITY: DYNAMIC-LOW, FOCUS: Chat Context > Recent) --
|
|
1370
1375
|
${tempMemories}` : "";
|
|
1371
1376
|
const userMemoriesStr = userMemories?.length > 0 ? `--- SAVED MEMORIES (PRIORITY: MEDIUM, USER PREFERENCES) ---
|
|
1372
1377
|
${userMemories}` : "";
|
|
@@ -1419,8 +1424,7 @@ Check these first; These Files > Training Data. Safety rules apply
|
|
|
1419
1424
|
return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM]
|
|
1420
1425
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy${mode === "Flux" ? ", No Flirting, Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
|
|
1421
1426
|
Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard latest coding practices/libraries, clean code, Double Check Imports, Client-Server Sync" : "Conversational, Concise"}
|
|
1422
|
-
|
|
1423
|
-
|
|
1427
|
+
${isSystemDir ? "[PROTECTED DIRECTORY: ASK BEFORE MODIFYING]\n" : ""}
|
|
1424
1428
|
-- THINKING RULES --
|
|
1425
1429
|
${thinkingConfig}
|
|
1426
1430
|
${thinkingLevel !== "Fast" ? `
|
|
@@ -4636,8 +4640,71 @@ ${newMemoryListStr}
|
|
|
4636
4640
|
const isContext32k = (sessionStats?.tokens || 0) >= 32e3;
|
|
4637
4641
|
const memoryPrompt = getMemoryPrompt(otherMemories, mainUserMemories, isMemoryEnabled, isContext32k);
|
|
4638
4642
|
const dateTimeStr = (/* @__PURE__ */ new Date()).toLocaleString([], { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit", hour12: true });
|
|
4639
|
-
const
|
|
4640
|
-
|
|
4643
|
+
const getDirTree = (dir, prefix = "") => {
|
|
4644
|
+
try {
|
|
4645
|
+
const files = fs16.readdirSync(dir);
|
|
4646
|
+
const sep = path15.sep;
|
|
4647
|
+
if (files.length > 70) {
|
|
4648
|
+
return `${prefix}\u2514\u2500\u2500 ${path15.basename(dir)}${sep}...
|
|
4649
|
+
`;
|
|
4650
|
+
}
|
|
4651
|
+
let result = "";
|
|
4652
|
+
const COLLAPSED_DIRS = [".git", "node_modules", ".gemini", "dist", "build", ".next", "out", ".cache", "bin", "obj", "vendor"];
|
|
4653
|
+
const filtered = files.filter((f) => !COLLAPSED_DIRS.includes(f));
|
|
4654
|
+
const collapsedInDir = files.filter((f) => COLLAPSED_DIRS.includes(f)).sort();
|
|
4655
|
+
const sorted = filtered.sort((a, b) => {
|
|
4656
|
+
try {
|
|
4657
|
+
const aStat = fs16.statSync(path15.join(dir, a));
|
|
4658
|
+
const bStat = fs16.statSync(path15.join(dir, b));
|
|
4659
|
+
if (aStat.isDirectory() && !bStat.isDirectory()) return -1;
|
|
4660
|
+
if (!aStat.isDirectory() && bStat.isDirectory()) return 1;
|
|
4661
|
+
} catch (e) {
|
|
4662
|
+
}
|
|
4663
|
+
return a.localeCompare(b);
|
|
4664
|
+
});
|
|
4665
|
+
sorted.push(...collapsedInDir);
|
|
4666
|
+
sorted.forEach((file, index) => {
|
|
4667
|
+
const isLast = index === sorted.length - 1;
|
|
4668
|
+
const filePath = path15.join(dir, file);
|
|
4669
|
+
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
4670
|
+
const childPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
4671
|
+
if (COLLAPSED_DIRS.includes(file)) {
|
|
4672
|
+
result += `${prefix}${connector}${file}${sep}...
|
|
4673
|
+
`;
|
|
4674
|
+
return;
|
|
4675
|
+
}
|
|
4676
|
+
try {
|
|
4677
|
+
const stat = fs16.statSync(filePath);
|
|
4678
|
+
if (stat.isDirectory()) {
|
|
4679
|
+
const subFiles = fs16.readdirSync(filePath);
|
|
4680
|
+
if (subFiles.length > 80) {
|
|
4681
|
+
result += `${prefix}${connector}${file}${sep}...
|
|
4682
|
+
`;
|
|
4683
|
+
} else {
|
|
4684
|
+
result += `${prefix}${connector}${file}${sep}
|
|
4685
|
+
`;
|
|
4686
|
+
result += getDirTree(filePath, childPrefix);
|
|
4687
|
+
}
|
|
4688
|
+
} else {
|
|
4689
|
+
result += `${prefix}${connector}${file}
|
|
4690
|
+
`;
|
|
4691
|
+
}
|
|
4692
|
+
} catch (e) {
|
|
4693
|
+
result += `${prefix}${connector}${file}
|
|
4694
|
+
`;
|
|
4695
|
+
}
|
|
4696
|
+
});
|
|
4697
|
+
return result;
|
|
4698
|
+
} catch (e) {
|
|
4699
|
+
return "";
|
|
4700
|
+
}
|
|
4701
|
+
};
|
|
4702
|
+
let dirStructure = process.cwd() + "\n" + getDirTree(process.cwd());
|
|
4703
|
+
const firstUserMsg = `[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v${versionFluxflow2}
|
|
4704
|
+
CWD: ${process.cwd()}
|
|
4705
|
+
**DIRECTORY STRUCTURE**
|
|
4706
|
+
${dirStructure}
|
|
4707
|
+
${memoryPrompt}
|
|
4641
4708
|
${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**\n" : ""}[USER] ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
4642
4709
|
modifiedHistory.push({ role: "user", text: firstUserMsg });
|
|
4643
4710
|
let lastUsage = null;
|
|
@@ -5222,7 +5289,7 @@ ${boxBottom}` };
|
|
|
5222
5289
|
await new Promise((resolve) => setTimeout(resolve, 1e3 - timeSinceLastTool));
|
|
5223
5290
|
}
|
|
5224
5291
|
}
|
|
5225
|
-
const
|
|
5292
|
+
const executionStart = Date.now();
|
|
5226
5293
|
yield { type: "spinner", content: false };
|
|
5227
5294
|
let result = await dispatchTool(normToolName, toolCall.args, {
|
|
5228
5295
|
chatId,
|
|
@@ -5237,7 +5304,7 @@ ${boxBottom}` };
|
|
|
5237
5304
|
}
|
|
5238
5305
|
const toolEnd = Date.now();
|
|
5239
5306
|
lastToolFinishedAt = toolEnd;
|
|
5240
|
-
yield { type: "tool_time", content: toolEnd -
|
|
5307
|
+
yield { type: "tool_time", content: toolEnd - executionStart };
|
|
5241
5308
|
lastToolEventTime = toolEnd;
|
|
5242
5309
|
let binaryPart = null;
|
|
5243
5310
|
if (typeof result === "object" && result.binaryPart) {
|
|
@@ -5858,6 +5925,7 @@ function App({ args = [] }) {
|
|
|
5858
5925
|
rows: stdout?.rows || 24
|
|
5859
5926
|
});
|
|
5860
5927
|
const [selectedIndex, setSelectedIndex] = useState9(0);
|
|
5928
|
+
const [isFilePickerDismissed, setIsFilePickerDismissed] = useState9(false);
|
|
5861
5929
|
const persistedModelRef = useRef2(null);
|
|
5862
5930
|
const parsedArgs = useMemo(() => {
|
|
5863
5931
|
const parsed = {};
|
|
@@ -6153,6 +6221,10 @@ function App({ args = [] }) {
|
|
|
6153
6221
|
}
|
|
6154
6222
|
}
|
|
6155
6223
|
if (key.escape) {
|
|
6224
|
+
if (suggestions.length > 0 && activeView === "chat") {
|
|
6225
|
+
setIsFilePickerDismissed(true);
|
|
6226
|
+
return;
|
|
6227
|
+
}
|
|
6156
6228
|
if (confirmExit) {
|
|
6157
6229
|
setConfirmExit(false);
|
|
6158
6230
|
return;
|
|
@@ -7454,7 +7526,16 @@ Selection: ${val}`,
|
|
|
7454
7526
|
setActiveView("resolution");
|
|
7455
7527
|
}
|
|
7456
7528
|
setMessages((prev) => {
|
|
7457
|
-
const
|
|
7529
|
+
const totalDuration = Date.now() - apiStart;
|
|
7530
|
+
let foundLastAgent = false;
|
|
7531
|
+
const newMsgs = [...prev].reverse().map((m) => {
|
|
7532
|
+
let updated = m.isStreaming ? { ...m, isStreaming: false } : m;
|
|
7533
|
+
if (!foundLastAgent && updated.role === "agent") {
|
|
7534
|
+
foundLastAgent = true;
|
|
7535
|
+
updated = { ...updated, workedDuration: totalDuration };
|
|
7536
|
+
}
|
|
7537
|
+
return updated;
|
|
7538
|
+
}).reverse();
|
|
7458
7539
|
const historyToSave = newMsgs.filter((m) => !String(m.id).startsWith("welcome") && !m.isMeta);
|
|
7459
7540
|
saveChat(chatId, null, historyToSave);
|
|
7460
7541
|
setCompletedIndex(newMsgs.length);
|
|
@@ -7468,28 +7549,48 @@ Selection: ${val}`,
|
|
|
7468
7549
|
setIsExpanded(false);
|
|
7469
7550
|
};
|
|
7470
7551
|
const suggestions = useMemo(() => {
|
|
7471
|
-
if (
|
|
7552
|
+
if (input.startsWith("/") && !isFilePickerDismissed) {
|
|
7553
|
+
const parts2 = input.split(" ");
|
|
7554
|
+
const query = parts2[parts2.length - 1].toLowerCase();
|
|
7555
|
+
if (parts2.length === 1) {
|
|
7556
|
+
const cleanQuery = query.startsWith("/") ? query.slice(1) : query;
|
|
7557
|
+
return COMMANDS.filter((c) => {
|
|
7558
|
+
const cleanCmd = c.cmd.startsWith("/") ? c.cmd.slice(1) : c.cmd;
|
|
7559
|
+
return cleanCmd.toLowerCase().includes(cleanQuery);
|
|
7560
|
+
});
|
|
7561
|
+
}
|
|
7562
|
+
let currentList = COMMANDS;
|
|
7563
|
+
for (let i = 0; i < parts2.length - 1; i++) {
|
|
7564
|
+
const part = parts2[i].toLowerCase();
|
|
7565
|
+
const found = currentList.find((c) => c.cmd.toLowerCase() === part);
|
|
7566
|
+
if (found && found.subs) {
|
|
7567
|
+
currentList = found.subs;
|
|
7568
|
+
} else {
|
|
7569
|
+
return [];
|
|
7570
|
+
}
|
|
7571
|
+
}
|
|
7572
|
+
return currentList.filter((s) => s.cmd.toLowerCase().includes(query));
|
|
7573
|
+
}
|
|
7472
7574
|
const parts = input.split(" ");
|
|
7473
|
-
const
|
|
7474
|
-
if (
|
|
7475
|
-
const
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7575
|
+
const lastPart = parts[parts.length - 1];
|
|
7576
|
+
if (lastPart && lastPart.startsWith("@") && !isFilePickerDismissed) {
|
|
7577
|
+
const hashIndex = lastPart.indexOf("#");
|
|
7578
|
+
const hasHash = hashIndex !== -1;
|
|
7579
|
+
const query = hasHash ? lastPart.substring(1, hashIndex).toLowerCase() : lastPart.slice(1).toLowerCase();
|
|
7580
|
+
const suffix = hasHash ? lastPart.substring(hashIndex) : "";
|
|
7581
|
+
const projectFiles = getProjectFiles(process.cwd());
|
|
7582
|
+
const matches = projectFiles.filter((f) => f.name.toLowerCase().includes(query));
|
|
7583
|
+
return matches.map((f) => {
|
|
7584
|
+
const relPath = f.relativePath.replace(/\\/g, "/");
|
|
7585
|
+
const formattedPath = relPath.startsWith(".") ? relPath : "./" + relPath;
|
|
7586
|
+
return {
|
|
7587
|
+
cmd: "@[" + formattedPath + suffix + "]",
|
|
7588
|
+
desc: f.relativePath
|
|
7589
|
+
};
|
|
7479
7590
|
});
|
|
7480
7591
|
}
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
const part = parts[i].toLowerCase();
|
|
7484
|
-
const found = currentList.find((c) => c.cmd.toLowerCase() === part);
|
|
7485
|
-
if (found && found.subs) {
|
|
7486
|
-
currentList = found.subs;
|
|
7487
|
-
} else {
|
|
7488
|
-
return [];
|
|
7489
|
-
}
|
|
7490
|
-
}
|
|
7491
|
-
return currentList.filter((s) => s.cmd.toLowerCase().includes(query));
|
|
7492
|
-
}, [input]);
|
|
7592
|
+
return [];
|
|
7593
|
+
}, [input, isFilePickerDismissed]);
|
|
7493
7594
|
useEffect6(() => {
|
|
7494
7595
|
setSelectedIndex(0);
|
|
7495
7596
|
}, [suggestions]);
|
|
@@ -7979,6 +8080,7 @@ Selection: ${val}`,
|
|
|
7979
8080
|
onChange: (val) => {
|
|
7980
8081
|
const cleanVal = val.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\\\s*\n/g, "\n");
|
|
7981
8082
|
setInput(cleanVal);
|
|
8083
|
+
setIsFilePickerDismissed(false);
|
|
7982
8084
|
},
|
|
7983
8085
|
onSubmit: handleSubmit,
|
|
7984
8086
|
maxRows: 3,
|
|
@@ -8039,7 +8141,7 @@ Selection: ${val}`,
|
|
|
8039
8141
|
paddingY: 0,
|
|
8040
8142
|
width: "100%"
|
|
8041
8143
|
},
|
|
8042
|
-
/* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 0 }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", bold: true, dimColor: true }, "\u{1F50D} COMMAND SUGGESTIONS")),
|
|
8144
|
+
/* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", bold: true, dimColor: true }, suggestions[0]?.cmd?.startsWith("@") ? "\u{1F4C1} FILE SUGGESTIONS" : "\u{1F50D} COMMAND SUGGESTIONS"), suggestions[0]?.cmd?.startsWith("@") && /* @__PURE__ */ React12.createElement(Text12, { color: "gray", dimColor: true, italic: true }, "(Use '#Lstart-Lend' to specify line numbers)")),
|
|
8043
8145
|
visible.map((s, i) => {
|
|
8044
8146
|
const actualIdx = startIdx + i;
|
|
8045
8147
|
const isActive = actualIdx === selectedIndex;
|
|
@@ -8069,7 +8171,7 @@ Selection: ${val}`,
|
|
|
8069
8171
|
);
|
|
8070
8172
|
})()));
|
|
8071
8173
|
}
|
|
8072
|
-
var SESSION_START_TIME, CHANGELOG_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO, parseAgentText;
|
|
8174
|
+
var SESSION_START_TIME, CHANGELOG_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO, parseAgentText, getProjectFiles;
|
|
8073
8175
|
var init_app = __esm({
|
|
8074
8176
|
"src/app.jsx"() {
|
|
8075
8177
|
init_ChatLayout();
|
|
@@ -8190,6 +8292,42 @@ var init_app = __esm({
|
|
|
8190
8292
|
}
|
|
8191
8293
|
return blocks;
|
|
8192
8294
|
};
|
|
8295
|
+
getProjectFiles = /* @__PURE__ */ (() => {
|
|
8296
|
+
let cachedFiles = null;
|
|
8297
|
+
let lastScanTime = 0;
|
|
8298
|
+
return (dir) => {
|
|
8299
|
+
const now = Date.now();
|
|
8300
|
+
if (cachedFiles && now - lastScanTime < 5e3) {
|
|
8301
|
+
return cachedFiles;
|
|
8302
|
+
}
|
|
8303
|
+
const fileList = [];
|
|
8304
|
+
const scan = (currentDir) => {
|
|
8305
|
+
try {
|
|
8306
|
+
const files = fs18.readdirSync(currentDir);
|
|
8307
|
+
for (const file of files) {
|
|
8308
|
+
if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
|
|
8309
|
+
continue;
|
|
8310
|
+
}
|
|
8311
|
+
const filePath = path16.join(currentDir, file);
|
|
8312
|
+
const stat = fs18.statSync(filePath);
|
|
8313
|
+
if (stat.isDirectory()) {
|
|
8314
|
+
scan(filePath);
|
|
8315
|
+
} else {
|
|
8316
|
+
fileList.push({
|
|
8317
|
+
name: file,
|
|
8318
|
+
relativePath: path16.relative(process.cwd(), filePath)
|
|
8319
|
+
});
|
|
8320
|
+
}
|
|
8321
|
+
}
|
|
8322
|
+
} catch (e) {
|
|
8323
|
+
}
|
|
8324
|
+
};
|
|
8325
|
+
scan(dir);
|
|
8326
|
+
cachedFiles = fileList;
|
|
8327
|
+
lastScanTime = now;
|
|
8328
|
+
return fileList;
|
|
8329
|
+
};
|
|
8330
|
+
})();
|
|
8193
8331
|
}
|
|
8194
8332
|
});
|
|
8195
8333
|
|