fluxflow-cli 1.0.1 → 1.0.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/TOOLS.md ADDED
@@ -0,0 +1,48 @@
1
+ # 🧰 Agent Tools & Capabilities
2
+
3
+ Flux Flow provides a robust set of tools that allow the AI to interact with the file system, execute code, and search the web. The availability of these tools depends on the active operating mode.
4
+
5
+ ## Tool Availability by Mode
6
+
7
+ | Tool | Flux Mode (Dev) | Flow Mode (Chat) |
8
+ | :--- | :---: | :---: |
9
+ | **Web Search** | ✅ | ✅ |
10
+ | **Web Scrape** | ✅ | ✅ |
11
+ | **View/Read Files** | ✅ | ❌ |
12
+ | **Write/Update Files** | ✅ | ❌ |
13
+ | **Execute Commands** | ✅ | ❌ |
14
+
15
+ ---
16
+
17
+ ## Core Tools
18
+
19
+ ### 🌐 Web & Research
20
+ - **`web_search`**: Uses DuckDuckGo to find up-to-date information on the internet. Crucial for answering questions about recent events or unlearned documentation.
21
+ - **`web_scrape`**: Extracts the detailed text content from a specific URL, allowing the agent to read documentation or articles.
22
+
23
+ ### 📁 File System Operations
24
+ - **`list_files`**: Lists the contents of a directory to help the agent understand the project structure.
25
+ - **`read_folder`**: Provides detailed statistics and metadata about a directory's contents.
26
+ - **`view_file`**: Reads the content of a file. Supports reading specific line ranges (`start_line`, `end_line`) to manage context size efficiently.
27
+
28
+ ### ✍️ Code Editing
29
+ - **`write_file`**: Creates a new file or completely overwrites an existing one with new content.
30
+ - **`update_file` (Smart Patching)**: Surgically replaces a specific block of text within a file.
31
+ - *Diff Generation*: It returns a high-fidelity visual diff (Red/Green changes with context lines) to the UI, allowing the user to see exactly what the agent modified.
32
+
33
+ ### 💻 Terminal Execution
34
+ - **`exec_command`**: Runs a shell command directly in the terminal using Node's `child_process.spawn`.
35
+ - *Context Aware*: Runs in the current working directory.
36
+ - *Cross-Platform*: Uses `shell: true` to handle Windows `.cmd`/`.bat` files natively.
37
+
38
+ ---
39
+
40
+ ## Memory Management
41
+
42
+ The memory tool (`memory.js`) is primarily used by the background **Janitor** model, but can be accessed by the main agent if necessary.
43
+
44
+ - **Temporary Context (`action='temp'`)**: Saves a rolling summary of the current session to maintain conversational context without bloating the main prompt history.
45
+ - **Persistent User Memory (`action='user'`)**:
46
+ - The Janitor analyzes conversations to detect user preferences, hobbies, or instructions.
47
+ - It uses `add`, `update`, or `delete` methods to manage facts in the encrypted `memories.json` vault.
48
+ - These memories are injected into the system prompt of *future* sessions, allowing Flux Flow to learn and adapt to the user over time.
package/UI_FEATURES.md ADDED
@@ -0,0 +1,66 @@
1
+ # 🎮 User Interface & Interaction Features
2
+
3
+ Flux Flow is designed to be a high-performance terminal application. Beyond basic chat, it includes a variety of advanced UI features and human-in-the-loop controls to keep you in command of the agent.
4
+
5
+ ## ⌨️ Command System
6
+
7
+ You can control the application using `/` commands directly in the chat input:
8
+
9
+ - **/mode [flux|flow]**: Quickly switch between **Flux** (Dev) and **Flow** (Chat) modes. Using it without arguments opens the selection menu.
10
+ - **/thinking [low|medium|high|max|show|hide]**: Adjust reasoning depth or toggle visibility of the thinking process. Using it without arguments opens the selection menu.
11
+ - **/model [name]**: Choose which AI model to use for the main interaction.
12
+ - **/key**: Open the API Key management view to update or remove your credentials.
13
+ - **/settings**: Access the system configuration menu.
14
+ - **/profile**: Update your name, nickname, and custom instructions.
15
+ - **/memory**: View and manage the persistent memories extracted by the Janitor.
16
+ - **/resume <chat-id>**: Switch back to a previous conversation.
17
+ - **/help**: List all available commands.
18
+
19
+ ### Command Shortcuts
20
+
21
+ For power users, several commands support direct arguments to skip the menus:
22
+ - ` /mode flux ` or ` /mode flow `
23
+ - ` /thinking low ` / ` /thinking medium ` / ` /thinking high ` / ` /thinking max `
24
+ - ` /thinking show ` / ` /thinking hide ` (Toggles thinking process visibility)
25
+ - ` /model gemini-3.1-pro-preview ` (Switches model directly)
26
+
27
+ ## 🧠 Thinking Levels & Visualization
28
+
29
+ Flux Flow separates the model's "internal monologue" (reasoning) from its final response using `<think>` tags.
30
+
31
+ - **Thinking Levels**: Depending on the mode, you can choose from **Low**, **Medium**, **High**, or **Max**. Higher levels allow the agent more "space" to reason through complex architecture or debugging problems.
32
+ - **Show/Hide Thinking**: You can toggle the visibility of the thinking process using `/thinking show/hide`.
33
+ - When **Hidden**, the agent doesn't just disappear; it provides a "minimalist" view showing only the core **Headings** and **Action Steps** (bolded lines) from its reasoning. This keeps you informed of its current "step" without cluttering the screen with detailed internal monologue.
34
+
35
+ ## 🛡️ Human-in-the-Loop (HITL) Verification
36
+
37
+ Security and safety are paramount when an AI has access to your file system and terminal. Flux Flow implements several layers of verification:
38
+
39
+ ### Tool Approval
40
+ By default, the agent **cannot** execute dangerous actions without your consent.
41
+ - **Terminal Approval**: If the agent attempts to run a shell command (`exec_command`), a dedicated approval screen appears showing the exact command. You can **Allow** or **Deny** the execution.
42
+ - **File Approval**: Similar to terminal commands, writing or updating files requires manual approval unless configured otherwise.
43
+ - **Safe Commands**: Basic read-only commands (like `ls`, `git status`, `pwd`) are automatically allowed to minimize friction.
44
+
45
+ ### Auto-Execution (Advanced)
46
+ For power users, **Auto-Exec** can be enabled in `/settings`.
47
+ - **⚠️ Warning**: This allows the agent to run any tool and execute any command autonomously.
48
+ - **External Access**: You can also toggle whether the agent is allowed to access files outside of its current working directory.
49
+
50
+ ## 🔄 Steering & Resolution
51
+
52
+ ### Real-time Steering
53
+ If you realize the agent is going down the wrong path *while* it is in an agentic loop, you can provide "Steering Hints." The system will inject your feedback into the next loop to course-correct the agent.
54
+
55
+ ### Resolution Modal
56
+ If the agent finishes its task just as you send a steering hint, a **Resolution Modal** appears. It asks if you want to:
57
+ - **Send Anyway**: Start a new loop with your feedback.
58
+ - **Edit Prompt**: Refine your feedback before sending.
59
+
60
+ ## 📊 Status Bar & Feedback
61
+ The bottom of the screen features a dynamic status bar showing:
62
+ - **Active Mode** (Flux/Flow)
63
+ - **Thinking Level**
64
+ - **Token Usage**: Real-time tracking of tokens used in the current session.
65
+ - **Agentic Loops**: Counters showing how many times the agent has "looped" to solve the current task.
66
+ - **API Status**: Visual feedback when the model is thinking or executing a tool.
@@ -194,7 +194,7 @@ function StatusBar({ mode, thinkingLevel, tokens = "0.0k", chatId = "NEW-SESSION
194
194
  },
195
195
  /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: modeColor, bold: true }, modeIcon, " ", mode.toUpperCase()), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "magenta" }, "\u{1F9E0} ", thinkingLevel)),
196
196
  /* @__PURE__ */ React3.createElement(Box3, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React3.createElement(Text3, { color: "gray", dimColor: true }, "\u{1F4C1} "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue", dimColor: true, italic: true }, process.cwd())),
197
- /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens / 128e3 * 100), "%)"), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "dim" }, "ID: ", chatId, " "))
197
+ /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens / 196e3 * 100), "%)"), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "dim" }, "ID: ", chatId, " "))
198
198
  );
199
199
  }
200
200
 
@@ -795,7 +795,7 @@ var memory = async (rawArgs, context = {}) => {
795
795
  if (!content) return "ERROR: Missing 'content' for temp memory.";
796
796
  const tempStorage = readEncryptedJson(TEMP_MEM_PATH, {});
797
797
  if (!tempStorage[chatId]) tempStorage[chatId] = [];
798
- const MAX_CHARS = 4e3 * 4;
798
+ const MAX_CHARS = 3e3 * 4;
799
799
  let currentTotalLength = tempStorage[chatId].reduce((acc, m) => acc + m.length, 0);
800
800
  while (tempStorage[chatId].length > 0 && currentTotalLength + content.length > MAX_CHARS) {
801
801
  const removed = tempStorage[chatId].shift();
@@ -809,7 +809,7 @@ var memory = async (rawArgs, context = {}) => {
809
809
  const memories = readEncryptedJson(MEMORIES_PATH, []);
810
810
  if (method === "add") {
811
811
  if (!content) return "ERROR: Missing 'content' for memory addition.";
812
- const MAX_CHARS = 3e3 * 4;
812
+ const MAX_CHARS = 2e3 * 4;
813
813
  let currentTotalLength = memories.reduce((acc, m) => acc + (m.memory?.length || 0), 0);
814
814
  while (memories.length > 0 && currentTotalLength + content.length > MAX_CHARS) {
815
815
  const removed = memories.shift();
@@ -1285,7 +1285,7 @@ var getAIStream = async function* (modelName, history, settings, steeringCallbac
1285
1285
  const needTitle = isFirstPrompt || hasTitleSignal;
1286
1286
  const agentText = originalText.replace(/\[TITLE-UPDATE\]/g, "").trim();
1287
1287
  let modifiedHistory = [...history.slice(0, -1)];
1288
- if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 128e3) {
1288
+ if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 196e3) {
1289
1289
  modifiedHistory = getTruncatedHistory(modifiedHistory, 4);
1290
1290
  }
1291
1291
  const tempStorage = readEncryptedJson(TEMP_MEM_PATH2, {});
@@ -1394,7 +1394,17 @@ USER_PROMPT: ${agentText}`.trim();
1394
1394
  const url = parseArgs(toolCall.args).url || "...";
1395
1395
  label = `\u{1F4D6} READING SITE: ${url}`.toUpperCase();
1396
1396
  } else if (toolCall.toolName === "view_file") {
1397
- label = `\u{1F4C4} READING FILE: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
1397
+ const { path: targetPath2, start_line = 1, end_line = 500 } = parseArgs(toolCall.args);
1398
+ let totalLines = "...";
1399
+ try {
1400
+ const absPath = path13.resolve(process.cwd(), targetPath2);
1401
+ if (fs12.existsSync(absPath)) {
1402
+ const content = fs12.readFileSync(absPath, "utf8");
1403
+ totalLines = content.split("\n").length;
1404
+ }
1405
+ } catch (e) {
1406
+ }
1407
+ label = `\u{1F4C4} READING FILE: ${targetPath2}. LINES ${start_line} - ${end_line} FROM ${totalLines}`.toUpperCase();
1398
1408
  } else if (toolCall.toolName === "list_files" || toolCall.toolName === "read_folder") {
1399
1409
  const action = toolCall.toolName === "list_files" ? "LISTING" : "DISCOVERING";
1400
1410
  label = `\u{1F4C2} ${action} DIRECTORY: ${parseArgs(toolCall.args).path || "."}`.toUpperCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
5
5
  "keywords": [
6
6
  "ai",
@@ -23,15 +23,18 @@
23
23
  "dist",
24
24
  "README.md",
25
25
  "package.json",
26
- "ARCHITECTURE.md"
26
+ "ARCHITECTURE.md",
27
+ "TOOLS.md",
28
+ "UI_FEATURES.md"
27
29
  ],
28
30
  "type": "module",
29
31
  "bin": {
30
- "fluxflow-cli": "dist/index.js"
32
+ "fluxflow-cli": "dist/fluxflow.js",
33
+ "fluxflow": "dist/fluxflow.js"
31
34
  },
32
35
  "scripts": {
33
36
  "start": "tsx ./src/cli.jsx",
34
- "build": "esbuild ./src/cli.jsx --bundle --platform=node --format=esm --outfile=./dist/index.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:duck-duck-scrape --external:nanoid --external:cuimp"
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:duck-duck-scrape --external:nanoid --external:cuimp"
35
38
  },
36
39
  "dependencies": {
37
40
  "@google/genai": "^1.50.1",