fluxflow-cli 3.19.0 → 3.19.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 +94 -15
  2. package/package.json +2 -2
package/dist/fluxflow.js CHANGED
@@ -2662,7 +2662,7 @@ var init_text = __esm({
2662
2662
  const indices = /* @__PURE__ */ new Set();
2663
2663
  const allowMultiple = args.allowMultiple === true || String(args.allowMultiple).toLowerCase() === "true";
2664
2664
  Object.keys(args).forEach((key) => {
2665
- const m = key.match(/^(replaceContent|newContent|content_to_replace|content_to_add)(\d+)?$/);
2665
+ const m = key.match(/^(searchContent|replaceContent|newContent|content_to_replace|content_to_add)(\d+)?$/);
2666
2666
  if (m) {
2667
2667
  const index2 = m[2] ? parseInt(m[2]) : 1;
2668
2668
  indices.add(index2);
@@ -2672,10 +2672,10 @@ var init_text = __esm({
2672
2672
  for (const i of sortedIndices) {
2673
2673
  let r, n;
2674
2674
  if (i === 1) {
2675
- r = args.replaceContent1 ?? (args.content_to_replace ?? args.replaceContent);
2675
+ r = args.searchContent1 ?? args.searchContent ?? args.replaceContent1 ?? (args.content_to_replace ?? args.replaceContent);
2676
2676
  n = args.newContent1 ?? (args.content_to_add ?? args.newContent);
2677
2677
  } else {
2678
- r = args[`replaceContent${i}`] ?? args[`content_to_replace${i}`];
2678
+ r = args[`searchContent${i}`] ?? args[`replaceContent${i}`] ?? args[`content_to_replace${i}`];
2679
2679
  n = args[`newContent${i}`] ?? args[`content_to_add${i}`];
2680
2680
  }
2681
2681
  if (r !== void 0 && n !== void 0) {
@@ -6989,7 +6989,7 @@ ${mode === "Flux" ? `- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENT
6989
6989
  ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
6990
6990
  - [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
6991
6991
  - [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
6992
- - [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. replaceContent accepts exact string OR "^LINE:start..end$" for large selection or escape sequences. Verify diffs
6992
+ - [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", searchContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. "^LINE:start..end$" line ranges MUST for multi-line selection or escape sequences. Verify diffs
6993
6993
  - [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
6994
6994
  - [tool:functions.SearchKeyword(keyword="...", path="optional, dir/file/glob/regex", fuzzy="bool optional, default: false", regex="bool optional, default: auto")]. path scopes search. Find definitions, logic, relevant code
6995
6995
  - [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
@@ -7007,6 +7007,7 @@ Invocations:
7007
7007
  - [tool:functions.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
7008
7008
  - [tool:functions.Await(id="...", timeout="integer seconds, default: 120")]. Event-driven wait
7009
7009
  - [tool:functions.GetProgress(id="...")]. Poll \`getProgress\` sparingly; NO initial poll. Work or await. Never end while subagent runs
7010
+ - [tool:functions.Steer(id="...", message="...")]. Inject additional instruction or redirection into active async subagent
7010
7011
  - [tool:functions.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: '/') -
7011
7012
  - [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
7012
7013
  - [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
@@ -11934,7 +11935,7 @@ var init_update_file = __esm({
11934
11935
  const { patchPairs, allowMultiple: parsedAllowMultiple, error: parseError } = parsePatchPairs(parsed);
11935
11936
  if (parseError) return `ERROR: ${parseError}`;
11936
11937
  if (patchPairs.length === 0) {
11937
- return "ERROR: No valid replacement pairs found. Use replaceContent1, newContent1, etc.";
11938
+ return "ERROR: No valid replacement pairs found. Use searchContent1, newContent1, etc.";
11938
11939
  }
11939
11940
  const allowMultiple = parsed.allowMultiple !== void 0 ? parsed.allowMultiple === true || String(parsed.allowMultiple).toLowerCase() === "true" : parsedAllowMultiple;
11940
11941
  const absolutePath = path14.resolve(process.cwd(), targetPath);
@@ -13863,6 +13864,12 @@ var init_invoke = __esm({
13863
13864
  lastChunkTime: Date.now(),
13864
13865
  wps: 0,
13865
13866
  questions: [],
13867
+ pendingSteerMessages: [],
13868
+ steer: (msg) => {
13869
+ if (msg) {
13870
+ taskEntry.pendingSteerMessages.push(msg);
13871
+ }
13872
+ },
13866
13873
  completionPromise,
13867
13874
  _resolveCompletion,
13868
13875
  _rejectCompletion,
@@ -14649,6 +14656,45 @@ var init_answerSubagent = __esm({
14649
14656
  }
14650
14657
  });
14651
14658
 
14659
+ // src/tools/steerSubagent.js
14660
+ var steerSubagent;
14661
+ var init_steerSubagent = __esm({
14662
+ "src/tools/steerSubagent.js"() {
14663
+ init_subagent_state();
14664
+ init_arg_parser();
14665
+ steerSubagent = async (args, context = {}) => {
14666
+ const parsed = parseArgs(args);
14667
+ const id = parsed.id;
14668
+ const message = parsed.message || parsed.instruction || parsed.text || parsed.prompt;
14669
+ if (!id) {
14670
+ return 'ERROR: Missing "id" argument for Steer.';
14671
+ }
14672
+ if (!message) {
14673
+ return 'ERROR: Missing "message" argument for Steer.';
14674
+ }
14675
+ const task = subagentProgress.find((t) => t.id === id);
14676
+ if (!task) {
14677
+ return `ERROR: Subagent task with ID [${id}] not found.`;
14678
+ }
14679
+ if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
14680
+ return `ERROR: Cannot steer subagent task [${id}] because it has already finished with status [${task.status.toUpperCase()}].`;
14681
+ }
14682
+ if (typeof task.steer === "function") {
14683
+ task.steer(message);
14684
+ } else {
14685
+ if (!task.pendingSteerMessages) {
14686
+ task.pendingSteerMessages = [];
14687
+ }
14688
+ task.pendingSteerMessages.push(message);
14689
+ }
14690
+ if (context.onSubagentUpdate) {
14691
+ context.onSubagentUpdate();
14692
+ }
14693
+ return `SUCCESS: Steering instruction injected into subagent task [${id}]. It will be processed on the subagent's turn.`;
14694
+ };
14695
+ }
14696
+ });
14697
+
14652
14698
  // src/utils/tools.js
14653
14699
  var TOOL_MAP, dispatchTool;
14654
14700
  var init_tools = __esm({
@@ -14679,6 +14725,7 @@ var init_tools = __esm({
14679
14725
  init_emergency_rollback();
14680
14726
  init_awaitSubagent();
14681
14727
  init_answerSubagent();
14728
+ init_steerSubagent();
14682
14729
  TOOL_MAP = {
14683
14730
  web_search,
14684
14731
  web_scrape,
@@ -14703,10 +14750,14 @@ var init_tools = __esm({
14703
14750
  cancel,
14704
14751
  awaitSubagent,
14705
14752
  answerSubagent,
14753
+ steerSubagent,
14706
14754
  invoke_sync: invokeSync,
14707
14755
  get_progress: getProgress,
14708
14756
  await_subagent: awaitSubagent,
14709
14757
  answer_subagent: answerSubagent,
14758
+ steer_subagent: steerSubagent,
14759
+ steer: steerSubagent,
14760
+ Steer: steerSubagent,
14710
14761
  ask: ask_user,
14711
14762
  // PascalCase Normalizations for Token Efficiency
14712
14763
  Ask: ask_user,
@@ -15069,7 +15120,7 @@ var init_ai = __esm({
15069
15120
  systemInstructionCache = { key: null, value: null };
15070
15121
  colorMainWords = (label) => {
15071
15122
  if (!label) return label;
15072
- 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|Resolved Sub-Agent Query|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) => {
15123
+ 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|Resolved Sub-Agent Query|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Steered|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) => {
15073
15124
  return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
15074
15125
  });
15075
15126
  };
@@ -16098,7 +16149,9 @@ var init_ai = __esm({
16098
16149
  "await": "Waiting",
16099
16150
  "EmergencyRollback": "Don't Panic. Lookin' into it",
16100
16151
  "answer": "Answering Sub-Agent",
16101
- "Answer": "Answering Sub-Agent"
16152
+ "Answer": "Answering Sub-Agent",
16153
+ "steer": "Steering Sub-Agent",
16154
+ "Steer": "Steering Sub-Agent"
16102
16155
  };
16103
16156
  getToolDetail = (toolName, argsStr) => {
16104
16157
  try {
@@ -16107,7 +16160,7 @@ var init_ai = __esm({
16107
16160
  if (normToolName === "invokesync" || normToolName === "invoke") {
16108
16161
  return pArgs.title || (pArgs.task ? pArgs.task.substring(0, 30) : null);
16109
16162
  }
16110
- if (normToolName === "getprogress" || normToolName === "cancel") {
16163
+ if (normToolName === "getprogress" || normToolName === "cancel" || normToolName === "steer" || normToolName === "steersubagent") {
16111
16164
  return pArgs.id || pArgs.taskId;
16112
16165
  }
16113
16166
  const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
@@ -18369,7 +18422,9 @@ ${ideErr} [/ERROR]`;
18369
18422
  "GetProgress": "get_progress",
18370
18423
  "Cancel": "cancel",
18371
18424
  "Await": "await",
18372
- "Answer": "answer"
18425
+ "Answer": "answer",
18426
+ "Steer": "steer",
18427
+ "steer": "steer"
18373
18428
  };
18374
18429
  const potentialTool = NORMALIZE_MAP[toolContext.toolName] || toolContext.toolName;
18375
18430
  const partialArgs = toolContext.args || "";
@@ -18459,7 +18514,9 @@ ${ideErr} [/ERROR]`;
18459
18514
  "await": "Waiting",
18460
18515
  "EmergencyRollback": "Rolling the Ball",
18461
18516
  "Answer": "Answering Sub-Agent",
18462
- "answer": "Answering Sub-Agent"
18517
+ "answer": "Answering Sub-Agent",
18518
+ "Steer": "Steering Sub-Agent",
18519
+ "steer": "Steering Sub-Agent"
18463
18520
  };
18464
18521
  const toolTitle = TOOL_TITLES[potentialTool] || "Working";
18465
18522
  process.stdout.write(`\x1B]0;${toolTitle}...\x07`);
@@ -18603,6 +18660,10 @@ ${ideErr} [/ERROR]`;
18603
18660
  "answer": "answer",
18604
18661
  "AnswerSubagent": "answer",
18605
18662
  "answerSubagent": "answer",
18663
+ "Steer": "steer",
18664
+ "steer": "steer",
18665
+ "SteerSubagent": "steer",
18666
+ "steerSubagent": "steer",
18606
18667
  "Cancel": "cancel",
18607
18668
  "cancel": "cancel",
18608
18669
  "EmergencyRollback": "EmergencyRollback"
@@ -18686,6 +18747,9 @@ ${ideErr} [/ERROR]`;
18686
18747
  } else if (normToolName === "cancel") {
18687
18748
  const detail2 = getToolDetail(normToolName, toolCall.args);
18688
18749
  label = `\u{1F6C7} Cancelled${detail2 ? `: ${detail2}` : ""}`;
18750
+ } else if (normToolName === "steer" || normToolName === "Steer") {
18751
+ const detail2 = getToolDetail(normToolName, toolCall.args);
18752
+ label = `\u2714 Steered${detail2 ? `: ${detail2}` : ""}`;
18689
18753
  } else if (normToolName === "EmergencyRollback") {
18690
18754
  const { method } = parseArgs(toolCall.args);
18691
18755
  label = method === "forceRevert" ? "" : "\u2714 Rollback Point Checked";
@@ -19949,7 +20013,7 @@ ${isAsync ? `- [tool:functions.AskMain(question="...")]. Communicate with PARENT
19949
20013
  - [tool:functions.SearchKeyword(keyword="...", path="optional, dir/file/glob/regex", fuzzy="bool optional, default: false", regex="bool optional, default: auto")]. path scopes search. Find definitions, logic, relevant code
19950
20014
  - [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
19951
20015
  - [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. View files
19952
- - [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. replaceContent: select string OR "^LINE:start..end$" for large selection or escape sequences. Verify diffs
20016
+ - [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", searchContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. "^LINE:start..end$" line ranges MUST for multi-line selection or escape sequences. Verify diffs
19953
20017
  - [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. VERIFY IMPORTS
19954
20018
  - [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user`.trim();
19955
20019
  const systemInstructionSubAgent = `=== START SYSTEM PROMPT ===
@@ -20197,7 +20261,22 @@ ${result}
20197
20261
  await incrementUsage("toolFailure");
20198
20262
  }
20199
20263
  }
20200
- subagentHistory.push({ role: "user", text: toolResultsStr.trim() });
20264
+ let steerAppendText = "";
20265
+ if (settings?.taskId && typeof subagentProgress !== "undefined") {
20266
+ const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
20267
+ if (taskObj && taskObj.pendingSteerMessages && taskObj.pendingSteerMessages.length > 0) {
20268
+ const steerMsgs = [...taskObj.pendingSteerMessages];
20269
+ taskObj.pendingSteerMessages = [];
20270
+ for (const steerMsg of steerMsgs) {
20271
+ steerAppendText += `
20272
+
20273
+ [STEERING INSTRUCTION FROM MAIN AGENT]: ${steerMsg}`;
20274
+ if (logCallback) logCallback(`[Subagent Steered] ${steerMsg}`);
20275
+ }
20276
+ }
20277
+ }
20278
+ const combinedUserText = (toolResultsStr.trim() + steerAppendText).trim();
20279
+ subagentHistory.push({ role: "user", text: combinedUserText });
20201
20280
  turn++;
20202
20281
  }
20203
20282
  return finalAnswer;
@@ -25597,7 +25676,7 @@ Selection: ${val}`,
25597
25676
  const patchPairs = [];
25598
25677
  const indices = /* @__PURE__ */ new Set();
25599
25678
  Object.keys(args2).forEach((key) => {
25600
- const m = key.match(/^(replaceContent|newContent|content_to_replace|content_to_add|TargetContent|ReplacementContent|replacementContent)(\d+)?$/);
25679
+ const m = key.match(/^(searchContent|replaceContent|newContent|content_to_replace|content_to_add|TargetContent|ReplacementContent|replacementContent)(\d+)?$/);
25601
25680
  if (m) {
25602
25681
  const index2 = m[2] ? parseInt(m[2]) : 1;
25603
25682
  indices.add(index2);
@@ -25607,10 +25686,10 @@ Selection: ${val}`,
25607
25686
  sortedIndices.forEach((i) => {
25608
25687
  let r, n;
25609
25688
  if (i === 1) {
25610
- r = args2.replaceContent1 ?? args2.content_to_replace1 ?? args2.replaceContent ?? args2.content_to_replace ?? args2.TargetContent ?? null;
25689
+ r = args2.searchContent1 ?? args2.searchContent ?? args2.replaceContent1 ?? args2.content_to_replace1 ?? args2.replaceContent ?? args2.content_to_replace ?? args2.TargetContent ?? null;
25611
25690
  n = args2.newContent1 ?? args2.content_to_add1 ?? args2.newContent ?? args2.content_to_add ?? args2.ReplacementContent ?? args2.replacementContent ?? null;
25612
25691
  } else {
25613
- r = args2[`replaceContent${i}`] ?? args2[`content_to_replace${i}`] ?? null;
25692
+ r = args2[`searchContent${i}`] ?? args2[`replaceContent${i}`] ?? args2[`content_to_replace${i}`] ?? null;
25614
25693
  n = args2[`newContent${i}`] ?? args2[`content_to_add${i}`] ?? null;
25615
25694
  }
25616
25695
  if (r !== null || n !== null) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.19.0",
4
- "date": "2026-08-05",
3
+ "version": "3.19.1",
4
+ "date": "2026-08-06",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",