@bike4mind/cli 0.2.25-feat-cli-multi-agentic-workflow.18573 → 0.2.25-fix-anthropic-overloaded-fallback.18535

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/index.js CHANGED
@@ -10,9 +10,8 @@ import {
10
10
  ConfigStore
11
11
  } from "./chunk-23T2XGSZ.js";
12
12
  import {
13
- selectActiveBackgroundAgents,
14
13
  useCliStore
15
- } from "./chunk-TVW4ZESU.js";
14
+ } from "./chunk-EIDW3VBS.js";
16
15
  import "./chunk-RAI6IM62.js";
17
16
  import "./chunk-NJW6ZADK.js";
18
17
  import {
@@ -88,15 +87,14 @@ import {
88
87
  } from "./chunk-OCYRD7D6.js";
89
88
 
90
89
  // src/index.tsx
91
- import React21, { useState as useState9, useEffect as useEffect6, useCallback as useCallback2, useRef as useRef3 } from "react";
92
- import { render, Box as Box20, Text as Text20, useApp, useInput as useInput9 } from "ink";
90
+ import React19, { useState as useState8, useEffect as useEffect4, useCallback, useRef as useRef3 } from "react";
91
+ import { render, Box as Box18, Text as Text18, useApp, useInput as useInput8 } from "ink";
93
92
  import { execSync } from "child_process";
94
- import { randomBytes as randomBytes5 } from "crypto";
95
93
  import { v4 as uuidv411 } from "uuid";
96
94
 
97
95
  // src/components/App.tsx
98
- import React15, { useState as useState5, useEffect as useEffect4 } from "react";
99
- import { Box as Box14, Text as Text14, Static, useInput as useInput6 } from "ink";
96
+ import React13, { useState as useState4 } from "react";
97
+ import { Box as Box12, Text as Text12, Static, useInput as useInput5 } from "ink";
100
98
 
101
99
  // src/components/StatusBar.tsx
102
100
  import React from "react";
@@ -1151,101 +1149,23 @@ var AgentThinking = React7.memo(function AgentThinking2() {
1151
1149
  return /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(ThoughtStream, { isThinking }));
1152
1150
  });
1153
1151
 
1154
- // src/components/BackgroundAgentStatus.tsx
1155
- import React8, { useMemo as useMemo2 } from "react";
1156
- import { Box as Box7, Text as Text7 } from "ink";
1157
- import Spinner2 from "ink-spinner";
1158
- var JobItem = React8.memo(function JobItem2({
1159
- job,
1160
- indented = false
1161
- }) {
1162
- const elapsed = Math.round((Date.now() - job.startTime) / 1e3);
1163
- const maxTaskLength = indented ? 50 : 60;
1164
- const taskPreview = job.task.length > maxTaskLength ? job.task.slice(0, maxTaskLength - 3) + "..." : job.task;
1165
- const isQueued = job.status === "queued";
1166
- return /* @__PURE__ */ React8.createElement(Box7, null, indented && /* @__PURE__ */ React8.createElement(Text7, null, " "), isQueued ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u23F3") : /* @__PURE__ */ React8.createElement(Text7, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text7, { color: isQueued ? "yellow" : "blue" }, " ", job.agentName), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " ", "[", job.id, "] ", taskPreview, " ", isQueued ? "(queued)" : `(${elapsed}s)`));
1167
- });
1168
- function formatStatusCounts(jobs) {
1169
- let running = 0;
1170
- let queued = 0;
1171
- for (const job of jobs) {
1172
- if (job.status === "running") running++;
1173
- else if (job.status === "queued") queued++;
1174
- }
1175
- const parts = [];
1176
- if (running > 0) parts.push(`${running} running`);
1177
- if (queued > 0) parts.push(`${queued} queued`);
1178
- return parts.join(", ");
1179
- }
1180
- function groupJobsByTurn(jobs) {
1181
- const groups = /* @__PURE__ */ new Map();
1182
- const ungrouped = [];
1183
- for (const job of jobs) {
1184
- if (job.turnId) {
1185
- const existing = groups.get(job.turnId);
1186
- if (existing) {
1187
- existing.jobs.push(job);
1188
- if (!existing.description && job.groupDescription) {
1189
- existing.description = job.groupDescription;
1190
- }
1191
- } else {
1192
- groups.set(job.turnId, {
1193
- description: job.groupDescription,
1194
- jobs: [job]
1195
- });
1196
- }
1197
- } else {
1198
- ungrouped.push(job);
1199
- }
1200
- }
1201
- return { groups, ungrouped };
1202
- }
1203
- function BackgroundAgentStatus() {
1204
- const activeJobs = useCliStore(selectActiveBackgroundAgents);
1205
- const permissionPrompt = useCliStore((state) => state.permissionPrompt);
1206
- const { groups, ungrouped } = useMemo2(() => groupJobsByTurn(activeJobs), [activeJobs]);
1207
- if (activeJobs.length === 0) return null;
1208
- if (permissionPrompt) {
1209
- return /* @__PURE__ */ React8.createElement(Box7, { paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Background agents: ", formatStatusCounts(activeJobs)));
1210
- }
1211
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", paddingX: 1, marginBottom: 0 }, Array.from(groups.entries()).map(([turnId, group]) => /* @__PURE__ */ React8.createElement(Box7, { key: turnId, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text7, { color: "magenta" }, "\u25B8 "), /* @__PURE__ */ React8.createElement(Text7, { color: "magenta", bold: true }, group.description || "Background Tasks"), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " (", formatStatusCounts(group.jobs), ")")), group.jobs.map((job) => /* @__PURE__ */ React8.createElement(JobItem, { key: job.id, job, indented: true })))), ungrouped.map((job) => /* @__PURE__ */ React8.createElement(JobItem, { key: job.id, job })));
1212
- }
1213
-
1214
- // src/components/CompletedGroupNotification.tsx
1215
- import React9, { useEffect as useEffect3 } from "react";
1216
- import { Box as Box8, Text as Text8 } from "ink";
1217
- var NOTIFICATION_DISPLAY_DURATION_MS = 3e3;
1218
- function CompletedGroupNotification() {
1219
- const notifications = useCliStore((state) => state.completedGroupNotifications);
1220
- const clearNotifications = useCliStore((state) => state.clearCompletedGroupNotifications);
1221
- useEffect3(() => {
1222
- if (notifications.length > 0) {
1223
- const timer = setTimeout(() => {
1224
- clearNotifications();
1225
- }, NOTIFICATION_DISPLAY_DURATION_MS);
1226
- return () => clearTimeout(timer);
1227
- }
1228
- }, [notifications.length, clearNotifications]);
1229
- if (notifications.length === 0) return null;
1230
- return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", paddingX: 1, marginBottom: 1 }, notifications.map((item, index) => /* @__PURE__ */ React9.createElement(Box8, { key: `${item.timestamp}-${index}`, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text8, { color: "green", bold: true }, "\u2714", " "), /* @__PURE__ */ React9.createElement(Text8, { color: "green", bold: true }, item.groupDescription ? `Background tasks completed: "${item.groupDescription}"` : "Background tasks completed")), /* @__PURE__ */ React9.createElement(Box8, { paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true, italic: true }, "Results will be incorporated in the next response.")))));
1231
- }
1232
-
1233
1152
  // src/components/PermissionPrompt.tsx
1234
- import React10, { useState as useState3, useCallback } from "react";
1235
- import { Box as Box9, Text as Text9, useInput as useInput3 } from "ink";
1153
+ import React8 from "react";
1154
+ import { Box as Box7, Text as Text7 } from "ink";
1155
+ import SelectInput from "ink-select-input";
1236
1156
  function renderDiffPreview(preview) {
1237
1157
  const lines = preview.split("\n");
1238
1158
  return lines.map((line, index) => {
1239
1159
  if (line.startsWith("+")) {
1240
- return /* @__PURE__ */ React10.createElement(Text9, { key: index, color: "green" }, line);
1160
+ return /* @__PURE__ */ React8.createElement(Text7, { key: index, color: "green" }, line);
1241
1161
  }
1242
1162
  if (line.startsWith("-")) {
1243
- return /* @__PURE__ */ React10.createElement(Text9, { key: index, color: "red" }, line);
1163
+ return /* @__PURE__ */ React8.createElement(Text7, { key: index, color: "red" }, line);
1244
1164
  }
1245
1165
  if (line.startsWith("@@")) {
1246
- return /* @__PURE__ */ React10.createElement(Text9, { key: index, color: "cyan" }, line);
1166
+ return /* @__PURE__ */ React8.createElement(Text7, { key: index, color: "cyan" }, line);
1247
1167
  }
1248
- return /* @__PURE__ */ React10.createElement(Text9, { key: index, dimColor: true }, line);
1168
+ return /* @__PURE__ */ React8.createElement(Text7, { key: index, dimColor: true }, line);
1249
1169
  });
1250
1170
  }
1251
1171
  function PermissionPrompt({
@@ -1264,36 +1184,16 @@ function PermissionPrompt({
1264
1184
  { label: "\u2713 Allow once", value: "allow-once" },
1265
1185
  { label: "\u2717 Deny", value: "deny" }
1266
1186
  ];
1267
- const [selectedIndex, setSelectedIndex] = useState3(0);
1268
- const [responded, setResponded] = useState3(false);
1269
- const handleSelect = useCallback(() => {
1270
- if (responded) return;
1271
- setResponded(true);
1272
- onResponse(items[selectedIndex].value);
1273
- }, [responded, onResponse, items, selectedIndex]);
1274
- useInput3(
1275
- (_input, key) => {
1276
- if (responded) return;
1277
- if (key.upArrow) {
1278
- setSelectedIndex((i) => i > 0 ? i - 1 : items.length - 1);
1279
- } else if (key.downArrow) {
1280
- setSelectedIndex((i) => i < items.length - 1 ? i + 1 : 0);
1281
- } else if (key.return) {
1282
- handleSelect();
1283
- }
1284
- },
1285
- { isActive: !responded }
1286
- );
1287
1187
  const MAX_ARGS_LENGTH = 500;
1288
1188
  const rawArgsString = typeof args === "string" ? args : JSON.stringify(args, null, 2);
1289
1189
  const argsString = rawArgsString.length > MAX_ARGS_LENGTH ? rawArgsString.slice(0, MAX_ARGS_LENGTH) + `
1290
1190
  ... (${rawArgsString.length - MAX_ARGS_LENGTH} more chars)` : rawArgsString;
1291
- return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Tool: "), /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Action: "), /* @__PURE__ */ React10.createElement(Text9, null, toolDescription)), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { bold: true }, "Arguments:"), /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { bold: true }, "Preview:"), /* @__PURE__ */ React10.createElement(Box9, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, items.map((item, index) => /* @__PURE__ */ React10.createElement(Box9, { key: item.value }, /* @__PURE__ */ React10.createElement(Text9, { color: index === selectedIndex ? "cyan" : void 0, bold: index === selectedIndex }, index === selectedIndex ? "\u276F " : " ", item.label)))));
1191
+ return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Tool: "), /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Action: "), /* @__PURE__ */ React8.createElement(Text7, null, toolDescription)), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { bold: true }, "Arguments:"), /* @__PURE__ */ React8.createElement(Box7, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { bold: true }, "Preview:"), /* @__PURE__ */ React8.createElement(Box7, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(SelectInput, { items, onSelect: (item) => onResponse(item.value) })));
1292
1192
  }
1293
1193
 
1294
1194
  // src/components/ConfigEditor.tsx
1295
- import React11, { useState as useState4, useMemo as useMemo3 } from "react";
1296
- import { Box as Box10, Text as Text10, useInput as useInput4 } from "ink";
1195
+ import React9, { useState as useState3, useMemo as useMemo2 } from "react";
1196
+ import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
1297
1197
  var MAX_ITERATIONS_OPTIONS = [
1298
1198
  { label: "10", value: 10 },
1299
1199
  { label: "20", value: 20 },
@@ -1437,12 +1337,12 @@ function buildConfigItems(availableModels) {
1437
1337
  return items;
1438
1338
  }
1439
1339
  function ConfigEditor({ config, availableModels, onSave, onClose }) {
1440
- const [selectedIndex, setSelectedIndex] = useState4(0);
1441
- const [editedConfig, setEditedConfig] = useState4(config);
1442
- const [saveError, setSaveError] = useState4(null);
1443
- const [isSaving, setIsSaving] = useState4(false);
1444
- const configItems = useMemo3(() => buildConfigItems(availableModels), [availableModels]);
1445
- const hasChanges = useMemo3(() => {
1340
+ const [selectedIndex, setSelectedIndex] = useState3(0);
1341
+ const [editedConfig, setEditedConfig] = useState3(config);
1342
+ const [saveError, setSaveError] = useState3(null);
1343
+ const [isSaving, setIsSaving] = useState3(false);
1344
+ const configItems = useMemo2(() => buildConfigItems(availableModels), [availableModels]);
1345
+ const hasChanges = useMemo2(() => {
1446
1346
  return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences) || config.defaultModel !== editedConfig.defaultModel;
1447
1347
  }, [config.preferences, editedConfig.preferences, config.defaultModel, editedConfig.defaultModel]);
1448
1348
  const handleSaveAndClose = async () => {
@@ -1460,7 +1360,7 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
1460
1360
  }
1461
1361
  onClose();
1462
1362
  };
1463
- useInput4((input, key) => {
1363
+ useInput3((input, key) => {
1464
1364
  const currentItem = configItems[selectedIndex];
1465
1365
  if (key.upArrow) {
1466
1366
  setSelectedIndex((prev) => prev > 0 ? prev - 1 : configItems.length - 1);
@@ -1525,33 +1425,33 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
1525
1425
  }
1526
1426
  return String(value);
1527
1427
  };
1528
- return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React11.createElement(Box10, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React11.createElement(Text10, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React11.createElement(Text10, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React11.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", marginBottom: 1 }, configItems.map((item, index) => {
1428
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React9.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React9.createElement(Text8, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React9.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, configItems.map((item, index) => {
1529
1429
  const isSelected = index === selectedIndex;
1530
1430
  const value = item.getValue(editedConfig);
1531
1431
  const displayValue = formatValue(item, value);
1532
1432
  const hasOptions = item.type === "select" || item.type === "boolean" || item.type === "number";
1533
- return /* @__PURE__ */ React11.createElement(Box10, { key: item.key }, /* @__PURE__ */ React11.createElement(Text10, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " "), /* @__PURE__ */ React11.createElement(Box10, { width: 18 }, /* @__PURE__ */ React11.createElement(Text10, { bold: isSelected, color: isSelected ? "white" : "gray" }, item.label, ":")), /* @__PURE__ */ React11.createElement(Box10, null, hasOptions && isSelected && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "< "), /* @__PURE__ */ React11.createElement(Text10, { bold: isSelected, color: isSelected ? "green" : void 0 }, displayValue), hasOptions && isSelected && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " >")));
1534
- })), /* @__PURE__ */ React11.createElement(Box10, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "\u2191/\u2193: Navigate | Space/\u2190/\u2192: Change | q/Esc: Save & Exit")));
1433
+ return /* @__PURE__ */ React9.createElement(Box8, { key: item.key }, /* @__PURE__ */ React9.createElement(Text8, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " "), /* @__PURE__ */ React9.createElement(Box8, { width: 18 }, /* @__PURE__ */ React9.createElement(Text8, { bold: isSelected, color: isSelected ? "white" : "gray" }, item.label, ":")), /* @__PURE__ */ React9.createElement(Box8, null, hasOptions && isSelected && /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "< "), /* @__PURE__ */ React9.createElement(Text8, { bold: isSelected, color: isSelected ? "green" : void 0 }, displayValue), hasOptions && isSelected && /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, " >")));
1434
+ })), /* @__PURE__ */ React9.createElement(Box8, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "\u2191/\u2193: Navigate | Space/\u2190/\u2192: Change | q/Esc: Save & Exit")));
1535
1435
  }
1536
1436
 
1537
1437
  // src/components/McpViewer.tsx
1538
- import React12 from "react";
1539
- import { Box as Box11, Text as Text11, useInput as useInput5 } from "ink";
1438
+ import React10 from "react";
1439
+ import { Box as Box9, Text as Text9, useInput as useInput4 } from "ink";
1540
1440
  function McpViewer({ config, mcpManager, onClose }) {
1541
- useInput5((input, key) => {
1441
+ useInput4((input, key) => {
1542
1442
  if (key.escape || input === "q") {
1543
1443
  onClose();
1544
1444
  }
1545
1445
  });
1546
1446
  if (config.mcpServers.length === 0) {
1547
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React12.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "No MCP servers configured."), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "To add MCP servers, edit your config file:")), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " Global: ~/.bike4mind/config.json"), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " Project: .bike4mind/config.json"), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 2 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true, italic: true }, "Press Esc or q to close")));
1447
+ return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "No MCP servers configured."), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "To add MCP servers, edit your config file:")), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " Global: ~/.bike4mind/config.json"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " Project: .bike4mind/config.json"), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, italic: true }, "Press Esc or q to close")));
1548
1448
  }
1549
1449
  const enabledServers = config.mcpServers.filter((s) => s.enabled);
1550
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React12.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true, dimColor: true }, "Configured Servers:"), config.mcpServers.map((server) => {
1450
+ return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React10.createElement(Text9, { bold: true, dimColor: true }, "Configured Servers:"), config.mcpServers.map((server) => {
1551
1451
  const status = server.enabled ? "\u2705 Enabled" : "\u23F8\uFE0F Disabled";
1552
1452
  const commandInfo = server.command ? `${server.command} ${(server.args || []).join(" ")}` : "(internal)";
1553
- return /* @__PURE__ */ React12.createElement(Box11, { key: server.name, flexDirection: "column", marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, null, "\u2022 ", /* @__PURE__ */ React12.createElement(Text11, { bold: true }, server.name), " - ", /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, status)), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " Command: ", commandInfo), Object.keys(server.env).length > 0 && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " Env vars: ", Object.keys(server.env).join(", ")));
1554
- })), enabledServers.length > 0 && mcpManager && /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true, dimColor: true }, "Connection Status:"), enabledServers.map((server) => {
1453
+ return /* @__PURE__ */ React10.createElement(Box9, { key: server.name, flexDirection: "column", marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, null, "\u2022 ", /* @__PURE__ */ React10.createElement(Text9, { bold: true }, server.name), " - ", /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, status)), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " Command: ", commandInfo), Object.keys(server.env).length > 0 && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " Env vars: ", Object.keys(server.env).join(", ")));
1454
+ })), enabledServers.length > 0 && mcpManager && /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React10.createElement(Text9, { bold: true, dimColor: true }, "Connection Status:"), enabledServers.map((server) => {
1555
1455
  const state = mcpManager.getConnectionState(server.name);
1556
1456
  let icon;
1557
1457
  let statusText;
@@ -1581,30 +1481,30 @@ function McpViewer({ config, mcpManager, onClose }) {
1581
1481
  const serverTools = toolCounts.find((t) => t.serverName === server.name);
1582
1482
  const toolCount = serverTools?.count || 0;
1583
1483
  const toolInfo = state === "connected" && toolCount > 0 ? ` (${toolCount} tool${toolCount === 1 ? "" : "s"})` : "";
1584
- return /* @__PURE__ */ React12.createElement(Box11, { key: server.name, marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, null, "\u2022 ", /* @__PURE__ */ React12.createElement(Text11, { bold: true }, server.name), " \xB7 ", /* @__PURE__ */ React12.createElement(Text11, { color }, icon), " ", /* @__PURE__ */ React12.createElement(Text11, { color }, statusText), toolInfo && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, toolInfo)));
1585
- }), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1, marginLeft: 2 }, (() => {
1484
+ return /* @__PURE__ */ React10.createElement(Box9, { key: server.name, marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, null, "\u2022 ", /* @__PURE__ */ React10.createElement(Text9, { bold: true }, server.name), " \xB7 ", /* @__PURE__ */ React10.createElement(Text9, { color }, icon), " ", /* @__PURE__ */ React10.createElement(Text9, { color }, statusText), toolInfo && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, toolInfo)));
1485
+ }), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, marginLeft: 2 }, (() => {
1586
1486
  const toolCounts = mcpManager.getToolCount();
1587
1487
  const totalTools = toolCounts.reduce((sum2, s) => sum2 + s.count, 0);
1588
1488
  if (totalTools > 0) {
1589
- return /* @__PURE__ */ React12.createElement(Text11, { bold: true, color: "green" }, "Total: ", totalTools, " MCP tool", totalTools === 1 ? "" : "s", " available");
1489
+ return /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "green" }, "Total: ", totalTools, " MCP tool", totalTools === 1 ? "" : "s", " available");
1590
1490
  } else {
1591
- return /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "No MCP tools available yet (servers still connecting)");
1491
+ return /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "No MCP tools available yet (servers still connecting)");
1592
1492
  }
1593
- })())), enabledServers.length === 0 && /* @__PURE__ */ React12.createElement(Box11, { marginBottom: 2 }, /* @__PURE__ */ React12.createElement(Text11, { color: "yellow" }, "\u26A0\uFE0F No MCP servers enabled"), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " Use `b4m mcp enable ", "<name>", "` to enable a server")), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true, italic: true }, "Press Esc or q to close")));
1493
+ })())), enabledServers.length === 0 && /* @__PURE__ */ React10.createElement(Box9, { marginBottom: 2 }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u26A0\uFE0F No MCP servers enabled"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " Use `b4m mcp enable ", "<name>", "` to enable a server")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, italic: true }, "Press Esc or q to close")));
1594
1494
  }
1595
1495
 
1596
1496
  // src/components/MessageItem.tsx
1597
- import React14 from "react";
1598
- import { Box as Box13, Text as Text13 } from "ink";
1497
+ import React12 from "react";
1498
+ import { Box as Box11, Text as Text11 } from "ink";
1599
1499
 
1600
1500
  // src/components/MarkdownRenderer.tsx
1601
- import React13 from "react";
1602
- import { Box as Box12, Text as Text12 } from "ink";
1501
+ import React11 from "react";
1502
+ import { Box as Box10, Text as Text10 } from "ink";
1603
1503
  import { marked } from "marked";
1604
1504
  import { highlight } from "cli-highlight";
1605
1505
  function MarkdownRenderer({ content }) {
1606
1506
  const tokens = marked.lexer(content);
1607
- return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, tokens.map((token, idx) => renderToken(token, idx)));
1507
+ return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, tokens.map((token, idx) => renderToken(token, idx)));
1608
1508
  }
1609
1509
  function renderToken(token, idx) {
1610
1510
  switch (token.type) {
@@ -1619,12 +1519,12 @@ function renderToken(token, idx) {
1619
1519
  case "blockquote":
1620
1520
  return renderBlockquote(token, idx);
1621
1521
  case "hr":
1622
- return /* @__PURE__ */ React13.createElement(Text12, { key: idx, dimColor: true }, "\u2500".repeat(50));
1522
+ return /* @__PURE__ */ React11.createElement(Text10, { key: idx, dimColor: true }, "\u2500".repeat(50));
1623
1523
  case "space":
1624
1524
  return null;
1625
1525
  default:
1626
1526
  if ("text" in token) {
1627
- return /* @__PURE__ */ React13.createElement(Text12, { key: idx }, token.text);
1527
+ return /* @__PURE__ */ React11.createElement(Text10, { key: idx }, token.text);
1628
1528
  }
1629
1529
  return null;
1630
1530
  }
@@ -1639,7 +1539,7 @@ function renderHeading(token, idx) {
1639
1539
  6: "white"
1640
1540
  };
1641
1541
  const color = colors[token.depth] || "white";
1642
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx, marginTop: idx > 0 ? 1 : 0 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true, color }, parseInlineText(token.text)));
1542
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx, marginTop: idx > 0 ? 1 : 0 }, /* @__PURE__ */ React11.createElement(Text10, { bold: true, color }, parseInlineText(token.text)));
1643
1543
  }
1644
1544
  function renderCodeBlock(token, idx) {
1645
1545
  let highlightedCode;
@@ -1651,20 +1551,20 @@ function renderCodeBlock(token, idx) {
1651
1551
  } catch (error) {
1652
1552
  highlightedCode = token.text;
1653
1553
  }
1654
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx, flexDirection: "column", paddingLeft: 2 }, token.lang && /* @__PURE__ */ React13.createElement(Text12, { dimColor: true, color: "gray" }, token.lang), /* @__PURE__ */ React13.createElement(Text12, null, highlightedCode));
1554
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx, flexDirection: "column", paddingLeft: 2 }, token.lang && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true, color: "gray" }, token.lang), /* @__PURE__ */ React11.createElement(Text10, null, highlightedCode));
1655
1555
  }
1656
1556
  function renderParagraph(token, idx) {
1657
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx }, /* @__PURE__ */ React13.createElement(Text12, null, parseInlineText(token.text)));
1557
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx }, /* @__PURE__ */ React11.createElement(Text10, null, parseInlineText(token.text)));
1658
1558
  }
1659
1559
  function renderList(token, idx) {
1660
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx, flexDirection: "column" }, token.items.map((item, itemIdx) => renderListItem(item, itemIdx, token.ordered, itemIdx + 1)));
1560
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx, flexDirection: "column" }, token.items.map((item, itemIdx) => renderListItem(item, itemIdx, token.ordered, itemIdx + 1)));
1661
1561
  }
1662
1562
  function renderListItem(item, idx, ordered, number) {
1663
1563
  const bullet = ordered ? `${number}.` : "\u2022";
1664
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx, paddingLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, null, bullet, " ", parseInlineText(item.text)));
1564
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx, paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text10, null, bullet, " ", parseInlineText(item.text)));
1665
1565
  }
1666
1566
  function renderBlockquote(token, idx) {
1667
- return /* @__PURE__ */ React13.createElement(Box12, { key: idx, paddingLeft: 2, borderStyle: "single", borderLeft: true, borderColor: "gray" }, token.tokens.map((t, i) => renderToken(t, i)));
1567
+ return /* @__PURE__ */ React11.createElement(Box10, { key: idx, paddingLeft: 2, borderStyle: "single", borderLeft: true, borderColor: "gray" }, token.tokens.map((t, i) => renderToken(t, i)));
1668
1568
  }
1669
1569
  function parseInlineText(text) {
1670
1570
  const parts = [];
@@ -1677,15 +1577,15 @@ function parseInlineText(text) {
1677
1577
  }
1678
1578
  if (match[1]) {
1679
1579
  parts.push(
1680
- /* @__PURE__ */ React13.createElement(Text12, { key: match.index, bold: true }, match[2])
1580
+ /* @__PURE__ */ React11.createElement(Text10, { key: match.index, bold: true }, match[2])
1681
1581
  );
1682
1582
  } else if (match[3]) {
1683
1583
  parts.push(
1684
- /* @__PURE__ */ React13.createElement(Text12, { key: match.index, italic: true }, match[4])
1584
+ /* @__PURE__ */ React11.createElement(Text10, { key: match.index, italic: true }, match[4])
1685
1585
  );
1686
1586
  } else if (match[5]) {
1687
1587
  parts.push(
1688
- /* @__PURE__ */ React13.createElement(Text12, { key: match.index, color: "cyan" }, match[6])
1588
+ /* @__PURE__ */ React11.createElement(Text10, { key: match.index, color: "cyan" }, match[6])
1689
1589
  );
1690
1590
  }
1691
1591
  lastIndex = regex.lastIndex;
@@ -1696,45 +1596,27 @@ function parseInlineText(text) {
1696
1596
  if (parts.length === 0) {
1697
1597
  return text;
1698
1598
  }
1699
- return /* @__PURE__ */ React13.createElement(React13.Fragment, null, parts);
1599
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, parts);
1700
1600
  }
1701
1601
 
1702
1602
  // src/components/MessageItem.tsx
1703
- function truncateValue(value, maxLength) {
1704
- const str = typeof value === "string" ? value : JSON.stringify(value);
1705
- if (str.length <= maxLength) {
1706
- return str;
1707
- }
1708
- return str.slice(0, maxLength) + "...";
1709
- }
1710
- function getRoleDisplay(role) {
1711
- switch (role) {
1712
- case "user":
1713
- return { color: "cyan", label: "\u{1F464} You" };
1714
- case "system":
1715
- return { color: "gray", label: "\u2139\uFE0F System" };
1716
- default:
1717
- return { color: "green", label: "\u{1F916} Assistant" };
1718
- }
1719
- }
1720
- var MessageItem = React14.memo(function MessageItem2({ message }) {
1603
+ function MessageItem({ message }) {
1721
1604
  const isUser = message.role === "user";
1722
- const isContinuation = message.metadata?.isContinuation === true;
1723
- const roleDisplay = getRoleDisplay(message.role);
1724
- return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", marginBottom: 1 }, !isContinuation && /* @__PURE__ */ React14.createElement(Box13, null, /* @__PURE__ */ React14.createElement(Text13, { bold: true, color: roleDisplay.color }, roleDisplay.label), isUser && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
1605
+ const isSystem = message.role === "system";
1606
+ return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Box11, null, /* @__PURE__ */ React12.createElement(Text11, { bold: true, color: isUser ? "cyan" : isSystem ? "gray" : "green" }, isUser ? "\u{1F464} You" : isSystem ? "\u2139\uFE0F System" : "\u{1F916} Assistant"), isUser && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React12.createElement(Box11, { paddingLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React12.createElement(Box11, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
1725
1607
  if (step.type === "thought") {
1726
- return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` ${step.content}`));
1608
+ return /* @__PURE__ */ React12.createElement(Box11, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text11, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, ` ${step.content}`));
1727
1609
  }
1728
1610
  if (step.type === "action") {
1729
1611
  const toolName = step.metadata?.toolName || "unknown";
1730
1612
  const toolInput = step.metadata?.toolInput;
1731
- const observationStep = message.metadata?.steps?.[idx + 1];
1613
+ const observationStep = message.metadata.steps[idx + 1];
1732
1614
  const result = observationStep?.type === "observation" ? observationStep.content : null;
1733
- return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Input: ${truncateValue(toolInput, 100)}`), result && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Result: ${truncateValue(result, 200)}`));
1615
+ return /* @__PURE__ */ React12.createElement(Box11, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text11, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
1734
1616
  }
1735
1617
  return null;
1736
- }).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, marginTop: message.metadata?.steps?.length ? 1 : 0 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React14.createElement(MarkdownRenderer, { content: message.content })), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
1737
- });
1618
+ }).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React12.createElement(Box11, { paddingLeft: 2, marginTop: message.metadata?.steps?.length ? 1 : 0 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React12.createElement(Text11, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React12.createElement(MarkdownRenderer, { content: message.content })), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React12.createElement(Box11, { paddingLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
1619
+ }
1738
1620
 
1739
1621
  // src/utils/processFileReferences.ts
1740
1622
  import * as fs2 from "fs";
@@ -1853,7 +1735,6 @@ function hasFileReferences(message) {
1853
1735
  // src/components/App.tsx
1854
1736
  function App({
1855
1737
  onMessage,
1856
- onBackgroundCompletion,
1857
1738
  onCommand,
1858
1739
  onBashCommand,
1859
1740
  onPermissionResponse,
@@ -1880,22 +1761,14 @@ function App({
1880
1761
  const setShowMcpViewer = useCliStore((state) => state.setShowMcpViewer);
1881
1762
  const exitRequested = useCliStore((state) => state.exitRequested);
1882
1763
  const setIsThinking = useCliStore((state) => state.setIsThinking);
1883
- const pendingBackgroundTrigger = useCliStore((state) => state.pendingBackgroundTrigger);
1884
- const setPendingBackgroundTrigger = useCliStore((state) => state.setPendingBackgroundTrigger);
1885
- useEffect4(() => {
1886
- if (pendingBackgroundTrigger && !isThinking && onBackgroundCompletion) {
1887
- setPendingBackgroundTrigger(false);
1888
- onBackgroundCompletion();
1889
- }
1890
- }, [pendingBackgroundTrigger, isThinking, setPendingBackgroundTrigger, onBackgroundCompletion]);
1891
1764
  const toggleAutoAcceptEdits = useCliStore((state) => state.toggleAutoAcceptEdits);
1892
- useInput6((_input, key) => {
1765
+ useInput5((_input, key) => {
1893
1766
  if (key.tab && key.shift) {
1894
1767
  toggleAutoAcceptEdits();
1895
1768
  }
1896
1769
  });
1897
- const [isBashMode, setIsBashMode] = useState5(false);
1898
- const handleSubmit = React15.useCallback(
1770
+ const [isBashMode, setIsBashMode] = useState4(false);
1771
+ const handleSubmit = React13.useCallback(
1899
1772
  async (input) => {
1900
1773
  const trimmed = input.trim();
1901
1774
  if (!trimmed) return;
@@ -1924,7 +1797,7 @@ ${errorBlock}`;
1924
1797
  },
1925
1798
  [onMessage, onCommand, setIsThinking]
1926
1799
  );
1927
- return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column" }, showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(
1800
+ return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React13.createElement(
1928
1801
  ConfigEditor,
1929
1802
  {
1930
1803
  config,
@@ -1934,8 +1807,8 @@ ${errorBlock}`;
1934
1807
  }
1935
1808
  )) : showMcpViewer && config ? (
1936
1809
  /* MCP Viewer - full screen takeover */
1937
- /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(McpViewer, { config, mcpManager, onClose: () => setShowMcpViewer(false) }))
1938
- ) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Static, { items: messages }, (message) => /* @__PURE__ */ React15.createElement(Box14, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(MessageItem, { message }))), /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column" }, pendingMessages.map((message) => /* @__PURE__ */ React15.createElement(Box14, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(MessageItem, { message })))), permissionPrompt && /* @__PURE__ */ React15.createElement(Box14, { key: permissionPrompt.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(
1810
+ /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React13.createElement(McpViewer, { config, mcpManager, onClose: () => setShowMcpViewer(false) }))
1811
+ ) : /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(Static, { items: messages }, (message) => /* @__PURE__ */ React13.createElement(Box12, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React13.createElement(MessageItem, { message }))), /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, pendingMessages.map((message) => /* @__PURE__ */ React13.createElement(Box12, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React13.createElement(MessageItem, { message })))), permissionPrompt && /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React13.createElement(
1939
1812
  PermissionPrompt,
1940
1813
  {
1941
1814
  toolName: permissionPrompt.toolName,
@@ -1944,7 +1817,7 @@ ${errorBlock}`;
1944
1817
  canBeTrusted: permissionPrompt.canBeTrusted,
1945
1818
  onResponse: onPermissionResponse
1946
1819
  }
1947
- )), !permissionPrompt && /* @__PURE__ */ React15.createElement(AgentThinking, null), /* @__PURE__ */ React15.createElement(BackgroundAgentStatus, null), /* @__PURE__ */ React15.createElement(CompletedGroupNotification, null), exitRequested && /* @__PURE__ */ React15.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React15.createElement(Box14, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React15.createElement(
1820
+ )), !permissionPrompt && /* @__PURE__ */ React13.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React13.createElement(Box12, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text12, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React13.createElement(Box12, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React13.createElement(
1948
1821
  InputPrompt,
1949
1822
  {
1950
1823
  onSubmit: handleSubmit,
@@ -1957,24 +1830,24 @@ ${errorBlock}`;
1957
1830
  onPrefillConsumed,
1958
1831
  onBashModeChange: setIsBashMode
1959
1832
  }
1960
- )), /* @__PURE__ */ React15.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens })));
1833
+ )), /* @__PURE__ */ React13.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens })));
1961
1834
  }
1962
1835
 
1963
1836
  // src/components/MessageList.tsx
1964
- import React16 from "react";
1965
- import { Box as Box15, Text as Text15 } from "ink";
1837
+ import React14 from "react";
1838
+ import { Box as Box13, Text as Text13 } from "ink";
1966
1839
  function stripThinkingTags(content) {
1967
1840
  return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
1968
1841
  }
1969
- var MessageList = React16.memo(
1842
+ var MessageList = React14.memo(
1970
1843
  function MessageList2({ messages }) {
1971
1844
  if (messages.length === 0) {
1972
- return /* @__PURE__ */ React16.createElement(Box15, { paddingY: 1 }, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "No messages yet. Type a message to start!"));
1845
+ return /* @__PURE__ */ React14.createElement(Box13, { paddingY: 1 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "No messages yet. Type a message to start!"));
1973
1846
  }
1974
- return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React16.createElement(Box15, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React16.createElement(Box15, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React16.createElement(Text15, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React16.createElement(Text15, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React16.createElement(Box15, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " tools used,", " ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
1847
+ return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React14.createElement(Box13, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Box13, null, /* @__PURE__ */ React14.createElement(Text13, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React14.createElement(Text13, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " tools used,", " ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
1975
1848
  if (step.type === "thought") {
1976
- return /* @__PURE__ */ React16.createElement(Box15, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text15, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React16.createElement(
1977
- Text15,
1849
+ return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React14.createElement(
1850
+ Text13,
1978
1851
  {
1979
1852
  dimColor: true
1980
1853
  },
@@ -1986,10 +1859,10 @@ var MessageList = React16.memo(
1986
1859
  const toolInput = step.metadata?.toolInput;
1987
1860
  const observationStep = message.metadata.steps[idx + 1];
1988
1861
  const result = observationStep?.type === "observation" ? observationStep.content : null;
1989
- return /* @__PURE__ */ React16.createElement(Box15, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text15, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
1862
+ return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
1990
1863
  }
1991
1864
  return null;
1992
- }).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React16.createElement(Box15, { paddingLeft: 2 }, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
1865
+ }).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
1993
1866
  },
1994
1867
  (prevProps, nextProps) => {
1995
1868
  if (prevProps.messages.length !== nextProps.messages.length) {
@@ -2000,9 +1873,9 @@ var MessageList = React16.memo(
2000
1873
  );
2001
1874
 
2002
1875
  // src/components/TrustLocationSelector.tsx
2003
- import React17 from "react";
2004
- import { Box as Box16, Text as Text16 } from "ink";
2005
- import SelectInput from "ink-select-input";
1876
+ import React15 from "react";
1877
+ import { Box as Box14, Text as Text14 } from "ink";
1878
+ import SelectInput2 from "ink-select-input";
2006
1879
  function TrustLocationSelector({ inProject, onSelect, onCancel }) {
2007
1880
  const items = [];
2008
1881
  if (inProject) {
@@ -2022,24 +1895,24 @@ function TrustLocationSelector({ inProject, onSelect, onCancel }) {
2022
1895
  const handleSelect = (item) => {
2023
1896
  onSelect(item.value);
2024
1897
  };
2025
- return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React17.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React17.createElement(
2026
- SelectInput,
1898
+ return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React15.createElement(
1899
+ SelectInput2,
2027
1900
  {
2028
1901
  items,
2029
1902
  onSelect: handleSelect,
2030
- itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React17.createElement(Box16, null, /* @__PURE__ */ React17.createElement(Text16, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
1903
+ itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2031
1904
  }
2032
- ), /* @__PURE__ */ React17.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
1905
+ ), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
2033
1906
  }
2034
1907
 
2035
1908
  // src/components/RewindSelector.tsx
2036
- import React18, { useState as useState6 } from "react";
2037
- import { Box as Box17, Text as Text17, useInput as useInput7 } from "ink";
2038
- import SelectInput2 from "ink-select-input";
1909
+ import React16, { useState as useState5 } from "react";
1910
+ import { Box as Box15, Text as Text15, useInput as useInput6 } from "ink";
1911
+ import SelectInput3 from "ink-select-input";
2039
1912
  function RewindSelector({ messages, onSelect, onCancel }) {
2040
- const [step, setStep] = useState6("selection");
2041
- const [selectedMessageIndex, setSelectedMessageIndex] = useState6(null);
2042
- useInput7((input, key) => {
1913
+ const [step, setStep] = useState5("selection");
1914
+ const [selectedMessageIndex, setSelectedMessageIndex] = useState5(null);
1915
+ useInput6((input, key) => {
2043
1916
  if (key.escape) {
2044
1917
  if (step === "confirmation") {
2045
1918
  setStep("selection");
@@ -2076,14 +1949,14 @@ function RewindSelector({ messages, onSelect, onCancel }) {
2076
1949
  return sum2 + (msg.metadata?.tokenUsage?.total || 0);
2077
1950
  }, 0);
2078
1951
  if (step === "selection") {
2079
- return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, { bold: true }, "Select a point to rewind to:")), /* @__PURE__ */ React18.createElement(
2080
- SelectInput2,
1952
+ return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React16.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text15, { bold: true }, "Select a point to rewind to:")), /* @__PURE__ */ React16.createElement(
1953
+ SelectInput3,
2081
1954
  {
2082
1955
  items,
2083
1956
  onSelect: handleSelectionSelect,
2084
- itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
1957
+ itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2085
1958
  }
2086
- ), /* @__PURE__ */ React18.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
1959
+ ), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
2087
1960
  }
2088
1961
  const confirmationItems = [
2089
1962
  { label: "Yes, rewind to this point", value: "confirm" },
@@ -2091,24 +1964,24 @@ function RewindSelector({ messages, onSelect, onCancel }) {
2091
1964
  ];
2092
1965
  const selectedMessage = selectedMessageIndex !== null && selectedMessageIndex >= 0 && selectedMessageIndex < messages.length ? messages[selectedMessageIndex] : null;
2093
1966
  const selectedPreview = selectedMessage ? selectedMessage.content.length > 50 ? selectedMessage.content.substring(0, 50) + "..." : selectedMessage.content : "";
2094
- return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React18.createElement(Text17, { bold: true }, "Confirm rewind operation:"), /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "Message: ", selectedPreview), /* @__PURE__ */ React18.createElement(Text17, { color: "yellow" }, "This will remove ", messagesToRemove.length, " message(s) (", tokensToRemove.toLocaleString(), " tokens)"), /* @__PURE__ */ React18.createElement(Text17, { color: "cyan" }, "The selected message will be placed in your input for editing.")), /* @__PURE__ */ React18.createElement(
2095
- SelectInput2,
1967
+ return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React16.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text15, { bold: true }, "Confirm rewind operation:"), /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "Message: ", selectedPreview), /* @__PURE__ */ React16.createElement(Text15, { color: "yellow" }, "This will remove ", messagesToRemove.length, " message(s) (", tokensToRemove.toLocaleString(), " tokens)"), /* @__PURE__ */ React16.createElement(Text15, { color: "cyan" }, "The selected message will be placed in your input for editing.")), /* @__PURE__ */ React16.createElement(
1968
+ SelectInput3,
2096
1969
  {
2097
1970
  items: confirmationItems,
2098
1971
  onSelect: handleConfirmationSelect,
2099
- itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
1972
+ itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2100
1973
  }
2101
- ), /* @__PURE__ */ React18.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
1974
+ ), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
2102
1975
  }
2103
1976
 
2104
1977
  // src/components/SessionSelector.tsx
2105
- import React19, { useState as useState7 } from "react";
2106
- import { Box as Box18, Text as Text18, useInput as useInput8 } from "ink";
2107
- import SelectInput3 from "ink-select-input";
1978
+ import React17, { useState as useState6 } from "react";
1979
+ import { Box as Box16, Text as Text16, useInput as useInput7 } from "ink";
1980
+ import SelectInput4 from "ink-select-input";
2108
1981
  function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
2109
- const [step, setStep] = useState7("selection");
2110
- const [selectedSession, setSelectedSession] = useState7(null);
2111
- useInput8((_input, key) => {
1982
+ const [step, setStep] = useState6("selection");
1983
+ const [selectedSession, setSelectedSession] = useState6(null);
1984
+ useInput7((_input, key) => {
2112
1985
  if (key.escape) {
2113
1986
  if (step === "confirmation") {
2114
1987
  setStep("selection");
@@ -2158,33 +2031,33 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
2158
2031
  }
2159
2032
  };
2160
2033
  if (step === "selection") {
2161
- return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React19.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text18, { bold: true }, "Select a session to resume:")), /* @__PURE__ */ React19.createElement(
2162
- SelectInput3,
2034
+ return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React17.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "Select a session to resume:")), /* @__PURE__ */ React17.createElement(
2035
+ SelectInput4,
2163
2036
  {
2164
2037
  items,
2165
2038
  onSelect: handleSelectionSelect,
2166
- itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2039
+ itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React17.createElement(Box16, null, /* @__PURE__ */ React17.createElement(Text16, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2167
2040
  }
2168
- ), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
2041
+ ), /* @__PURE__ */ React17.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
2169
2042
  }
2170
2043
  const confirmationItems = [
2171
2044
  { label: "Yes, resume this session", value: "confirm" },
2172
2045
  { label: "No, go back to selection", value: "cancel" }
2173
2046
  ];
2174
- return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React19.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Text18, { bold: true }, 'Resume session: "', selectedSession?.name, '"'), /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, selectedSession?.messages.length, " messages | ", selectedSession?.model, " |", " ", selectedSession?.metadata?.totalTokens?.toLocaleString() ?? 0, " tokens"), hasUnsavedWork && /* @__PURE__ */ React19.createElement(Text18, { color: "yellow" }, "Warning: Your current session has unsaved messages. Use /save first if needed.")), /* @__PURE__ */ React19.createElement(
2175
- SelectInput3,
2047
+ return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React17.createElement(Box16, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text16, { bold: true }, 'Resume session: "', selectedSession?.name, '"'), /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, selectedSession?.messages.length, " messages | ", selectedSession?.model, " |", " ", selectedSession?.metadata?.totalTokens?.toLocaleString() ?? 0, " tokens"), hasUnsavedWork && /* @__PURE__ */ React17.createElement(Text16, { color: "yellow" }, "Warning: Your current session has unsaved messages. Use /save first if needed.")), /* @__PURE__ */ React17.createElement(
2048
+ SelectInput4,
2176
2049
  {
2177
2050
  items: confirmationItems,
2178
2051
  onSelect: handleConfirmationSelect,
2179
- itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2052
+ itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React17.createElement(Box16, null, /* @__PURE__ */ React17.createElement(Text16, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
2180
2053
  }
2181
- ), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
2054
+ ), /* @__PURE__ */ React17.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
2182
2055
  }
2183
2056
 
2184
2057
  // src/components/LoginFlow.tsx
2185
- import React20, { useState as useState8, useEffect as useEffect5 } from "react";
2186
- import { Box as Box19, Text as Text19 } from "ink";
2187
- import Spinner3 from "ink-spinner";
2058
+ import React18, { useState as useState7, useEffect as useEffect3 } from "react";
2059
+ import { Box as Box17, Text as Text17 } from "ink";
2060
+ import Spinner2 from "ink-spinner";
2188
2061
  import jwt from "jsonwebtoken";
2189
2062
  import open from "open";
2190
2063
 
@@ -2299,11 +2172,11 @@ var OAuthClient = class {
2299
2172
 
2300
2173
  // src/components/LoginFlow.tsx
2301
2174
  function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
2302
- const [status, setStatus] = useState8("initiating");
2303
- const [deviceFlow, setDeviceFlow] = useState8(null);
2304
- const [statusMessage, setStatusMessage] = useState8("Initiating device authorization...");
2305
- const [error, setError] = useState8(null);
2306
- useEffect5(() => {
2175
+ const [status, setStatus] = useState7("initiating");
2176
+ const [deviceFlow, setDeviceFlow] = useState7(null);
2177
+ const [statusMessage, setStatusMessage] = useState7("Initiating device authorization...");
2178
+ const [error, setError] = useState7(null);
2179
+ useEffect3(() => {
2307
2180
  const runLoginFlow = async () => {
2308
2181
  const oauth = new OAuthClient(apiUrl);
2309
2182
  try {
@@ -2338,7 +2211,7 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
2338
2211
  };
2339
2212
  runLoginFlow();
2340
2213
  }, [apiUrl, configStore, onSuccess, onError]);
2341
- useEffect5(() => {
2214
+ useEffect3(() => {
2342
2215
  if (deviceFlow && status === "waiting") {
2343
2216
  open(deviceFlow.verification_uri_complete).catch((err) => {
2344
2217
  console.error("Failed to auto-open browser:", err);
@@ -2346,15 +2219,15 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
2346
2219
  }
2347
2220
  }, [deviceFlow, status]);
2348
2221
  if (status === "initiating") {
2349
- return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Box19, null, /* @__PURE__ */ React20.createElement(Text19, { color: "cyan" }, /* @__PURE__ */ React20.createElement(Spinner3, { type: "dots" }), " Initiating device authorization...")));
2222
+ return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { color: "cyan" }, /* @__PURE__ */ React18.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
2350
2223
  }
2351
2224
  if (status === "error") {
2352
- return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React20.createElement(Box19, null, /* @__PURE__ */ React20.createElement(Text19, { color: "red" }, error)));
2225
+ return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { color: "red" }, error)));
2353
2226
  }
2354
2227
  if (status === "success") {
2355
- return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React20.createElement(Box19, null, /* @__PURE__ */ React20.createElement(Text19, { dimColor: true }, "You can now use B4M CLI with your account.")));
2228
+ return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "You can now use B4M CLI with your account.")));
2356
2229
  }
2357
- return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React20.createElement(Text19, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, null, "And enter this code when prompted:")), /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React20.createElement(Text19, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React20.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text19, { color: "cyan" }, /* @__PURE__ */ React20.createElement(Spinner3, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React20.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text19, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
2230
+ return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React18.createElement(Text17, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, null, "And enter this code when prompted:")), /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React18.createElement(Text17, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React18.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "cyan" }, /* @__PURE__ */ React18.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React18.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
2358
2231
  }
2359
2232
 
2360
2233
  // src/storage/SessionStore.ts
@@ -3847,16 +3720,8 @@ CORE BEHAVIOR:
3847
3720
 
3848
3721
  FOR SOFTWARE ENGINEERING TASKS:
3849
3722
  When requested to perform tasks like fixing bugs, adding features, refactoring, or explaining code, follow this sequence:
3850
- 1. **Understand:** Think about the user's request and the relevant codebase context. Use '${TOOL_GREP_SEARCH}' and '${TOOL_GLOB_FILES}' search tools extensively (in parallel if independent) to understand file structures, existing code patterns, and conventions. Use '${TOOL_FILE_READ}' to understand context and validate any assumptions you may have.
3851
-
3852
- IMPORTANT FILE READING RULES:
3853
- - Read each file ONCE and refer to it in conversation history instead of re-reading
3854
- - Read files COMPLETELY by default (without offset/limit parameters)
3855
- - Only use offset/limit for files that are too large to fit in context (thousands of lines)
3856
- - If you need to read multiple DIFFERENT files, make multiple parallel calls to '${TOOL_FILE_READ}'
3857
- - NEVER make multiple calls to read the SAME file with different offsets unless it's truly too large
3858
-
3859
- When the task involves **complex refactoring, codebase exploration or system-wide analysis**, your **first and primary action** must be to delegate to the '${EXPLORE_SUBAGENT_TYPE}' agent using the '${TOOL_SUBAGENT_DELEGATE}' tool. Use it to build a comprehensive understanding of the code, its structure, and dependencies. For **simple, targeted searches** (like finding a specific function name, file path, or variable declaration), you should use '${TOOL_GREP_SEARCH}' or '${TOOL_GLOB_FILES}' directly.
3723
+ 1. **Understand:** Think about the user's request and the relevant codebase context. Use '${TOOL_GREP_SEARCH}' and '${TOOL_GLOB_FILES}' search tools extensively (in parallel if independent) to understand file structures, existing code patterns, and conventions. Use '${TOOL_FILE_READ}' to understand context and validate any assumptions you may have. If you need to read multiple files, you should make multiple parallel calls to '${TOOL_FILE_READ}'.
3724
+ When the task involves **complex refactoring, codebase exploration or system-wide analysis**, your **first and primary action** must be to delegate to the '${EXPLORE_SUBAGENT_TYPE}' agent using the '${TOOL_SUBAGENT_DELEGATE}' tool. Use it to build a comprehensive understanding of the code, its structure, and dependencies. For **simple, targeted searches** (like finding a specific function name, file path, or variable declaration), you should use '${TOOL_GREP_SEARCH}' or '${TOOL_GLOB_FILES}' directly.
3860
3725
  2. **Plan:** Build a coherent and grounded (based on the understanding in step 1) plan for how you intend to resolve the user's task. Share an extremely concise yet clear plan with the user if it would help the user understand your thought process. As part of the plan, you should use an iterative development process that includes writing unit tests to verify your changes. Use output logs or debug statements as part of this process to arrive at a solution.
3861
3726
  If '${EXPLORE_SUBAGENT_TYPE}' subagent was used, do not ignore the output of the agent, you must use it as the foundation of your plan. For complex tasks, break them down into smaller, manageable subtasks and use the \`${TOOL_WRITE_TODOS}\` tool to track your progress. Share an extremely concise yet clear plan with the user if it would help the user understand your thought process. As part of the plan, you should use an iterative development process that includes writing unit tests to verify your changes. Use output logs or debug statements as part of this process to arrive at a solution.
3862
3727
  3. **Implement:** Use the available tools (e.g., '${TOOL_EDIT_LOCAL_FILE}', '${TOOL_CREATE_FILE}', '${TOOL_BASH_EXECUTE}' ...) to act on the plan, strictly adhering to the project's established conventions.
@@ -9216,7 +9081,7 @@ import { existsSync as existsSync3, statSync as statSync4 } from "fs";
9216
9081
  import path7 from "path";
9217
9082
  var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
9218
9083
  async function readFileContent(params) {
9219
- const { path: filePath, encoding = "utf-8", offset = 0, limit } = params;
9084
+ const { path: filePath, encoding = "utf-8", maxLines } = params;
9220
9085
  const normalizedPath = path7.normalize(filePath);
9221
9086
  const resolvedPath = path7.resolve(process.cwd(), normalizedPath);
9222
9087
  const cwd = path7.resolve(process.cwd());
@@ -9238,39 +9103,16 @@ async function readFileContent(params) {
9238
9103
  throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
9239
9104
  }
9240
9105
  const content = await fs8.readFile(resolvedPath, encoding);
9241
- if (typeof content === "string") {
9106
+ if (maxLines && typeof content === "string") {
9242
9107
  const lines = content.split("\n");
9243
- const totalLines = lines.length;
9244
- if (offset < 0) {
9245
- throw new Error(`Invalid offset: ${offset}. Offset must be 0 or greater.`);
9246
- }
9247
- if (offset >= totalLines) {
9248
- return `No content to show. File has ${totalLines} lines, but offset is ${offset}.
9249
- (offset is 0-based, so valid range is 0-${Math.max(0, totalLines - 1)})`;
9250
- }
9251
- if (limit !== void 0 && limit > 0) {
9252
- const endLine = Math.min(offset + limit, totalLines);
9253
- const paginatedContent = lines.slice(offset, endLine).join("\n");
9254
- if (endLine < totalLines) {
9255
- const nextOffset = endLine;
9256
- return `${paginatedContent}
9108
+ if (lines.length > maxLines) {
9109
+ const truncatedContent = lines.slice(0, maxLines).join("\n");
9110
+ return `${truncatedContent}
9257
9111
 
9258
- ... Showing lines ${offset + 1}-${endLine} of ${totalLines} total lines (${stats.size} bytes total).
9259
- To read more, use offset: ${nextOffset}`;
9260
- }
9261
- return `${paginatedContent}
9262
-
9263
- ... Showing lines ${offset + 1}-${endLine} of ${totalLines} total lines (${stats.size} bytes total). End of file reached.`;
9112
+ ... (truncated: ${lines.length - maxLines} more lines, ${stats.size} bytes total)`;
9264
9113
  }
9265
- if (offset > 0) {
9266
- const paginatedContent = lines.slice(offset).join("\n");
9267
- return `${paginatedContent}
9268
-
9269
- ... Showing lines ${offset + 1}-${totalLines} of ${totalLines} total lines (${stats.size} bytes total).`;
9270
- }
9271
- return content;
9272
9114
  }
9273
- return `[Binary content, ${stats.size} bytes, base64 encoded]
9115
+ return typeof content === "string" ? content : `[Binary content, ${stats.size} bytes, base64 encoded]
9274
9116
  ${content}`;
9275
9117
  }
9276
9118
  async function checkIfBinary(filePath) {
@@ -9307,7 +9149,7 @@ var fileReadTool = {
9307
9149
  },
9308
9150
  toolSchema: {
9309
9151
  name: "file_read",
9310
- description: "Read the contents of a file from the local filesystem. Supports text files with various encodings. Files are restricted to the current working directory and subdirectories for security. IMPORTANT: Read files completely by default (without offset/limit). Only use offset/limit for extremely large files (thousands of lines) that exceed context limits. Never re-read the same file multiple times - refer to previous reads in conversation history instead.",
9152
+ description: "Read the contents of a file from the local filesystem. Supports text files with various encodings. Files are restricted to the current working directory and subdirectories for security.",
9311
9153
  parameters: {
9312
9154
  type: "object",
9313
9155
  properties: {
@@ -9320,13 +9162,9 @@ var fileReadTool = {
9320
9162
  description: "File encoding (default: utf-8). Use base64 for binary files.",
9321
9163
  enum: ["utf-8", "ascii", "base64"]
9322
9164
  },
9323
- offset: {
9165
+ maxLines: {
9324
9166
  type: "number",
9325
- description: "OPTIONAL: For text files, the 0-based line number to start reading from. Only use for extremely large files (thousands of lines) that cannot fit in context. Default behavior is to read the entire file, which is preferred for most cases."
9326
- },
9327
- limit: {
9328
- type: "number",
9329
- description: "OPTIONAL: Maximum number of lines to read from offset. Only use for extremely large files (thousands of lines) that cannot fit in context. Default behavior is to read the entire file, which is preferred for most cases."
9167
+ description: "Maximum number of lines to return (optional). Useful for previewing large files. Returns full file by default."
9330
9168
  }
9331
9169
  },
9332
9170
  required: ["path"]
@@ -11361,7 +11199,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
11361
11199
  agentContext.observationQueue.push({ toolName, result: result2 });
11362
11200
  return result2;
11363
11201
  }
11364
- const { useCliStore: useCliStore2 } = await import("./store-FU6NDC2W.js");
11202
+ const { useCliStore: useCliStore2 } = await import("./store-JNTO6SRG.js");
11365
11203
  if (useCliStore2.getState().autoAcceptEdits) {
11366
11204
  const result2 = await executeTool(toolName, args, apiClient, originalFn);
11367
11205
  agentContext.observationQueue.push({ toolName, result: result2 });
@@ -13036,40 +12874,6 @@ var ServerLlmBackend = class {
13036
12874
  }
13037
12875
  };
13038
12876
 
13039
- // src/llm/NotifyingLlmBackend.ts
13040
- var NotifyingLlmBackend = class {
13041
- constructor(inner, backgroundManager) {
13042
- this.inner = inner;
13043
- this.backgroundManager = backgroundManager;
13044
- }
13045
- get currentModel() {
13046
- return this.inner.currentModel;
13047
- }
13048
- set currentModel(model) {
13049
- this.inner.currentModel = model;
13050
- }
13051
- async complete(model, messages, options, callback) {
13052
- const notifications = this.backgroundManager.drainNotifications();
13053
- let effectiveMessages = messages;
13054
- if (notifications.length > 0) {
13055
- const notificationText = notifications.join("\n\n---\n\n");
13056
- const notificationMessage = {
13057
- role: "user",
13058
- content: `[System Notification]
13059
-
13060
- ${notificationText}
13061
-
13062
- Please acknowledge these background agent results and incorporate them into your current work.`
13063
- };
13064
- effectiveMessages = [...messages, notificationMessage];
13065
- }
13066
- return this.inner.complete(model, effectiveMessages, options, callback);
13067
- }
13068
- async getModelInfo() {
13069
- return this.inner.getModelInfo();
13070
- }
13071
- };
13072
-
13073
12877
  // src/auth/ApiClient.ts
13074
12878
  import axios11 from "axios";
13075
12879
  var ApiClient = class {
@@ -13207,7 +13011,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
13207
13011
  // package.json
13208
13012
  var package_default = {
13209
13013
  name: "@bike4mind/cli",
13210
- version: "0.2.25-feat-cli-multi-agentic-workflow.18573+8959c583b",
13014
+ version: "0.2.25-fix-anthropic-overloaded-fallback.18535+44e7b5760",
13211
13015
  type: "module",
13212
13016
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
13213
13017
  license: "UNLICENSED",
@@ -13315,10 +13119,10 @@ var package_default = {
13315
13119
  },
13316
13120
  devDependencies: {
13317
13121
  "@bike4mind/agents": "0.1.0",
13318
- "@bike4mind/common": "2.47.2-feat-cli-multi-agentic-workflow.18573+8959c583b",
13319
- "@bike4mind/mcp": "1.28.1-feat-cli-multi-agentic-workflow.18573+8959c583b",
13320
- "@bike4mind/services": "2.45.2-feat-cli-multi-agentic-workflow.18573+8959c583b",
13321
- "@bike4mind/utils": "2.3.4-feat-cli-multi-agentic-workflow.18573+8959c583b",
13122
+ "@bike4mind/common": "2.47.2-fix-anthropic-overloaded-fallback.18535+44e7b5760",
13123
+ "@bike4mind/mcp": "1.28.1-fix-anthropic-overloaded-fallback.18535+44e7b5760",
13124
+ "@bike4mind/services": "2.45.2-fix-anthropic-overloaded-fallback.18535+44e7b5760",
13125
+ "@bike4mind/utils": "2.3.4-fix-anthropic-overloaded-fallback.18535+44e7b5760",
13322
13126
  "@types/better-sqlite3": "^7.6.13",
13323
13127
  "@types/diff": "^5.0.9",
13324
13128
  "@types/jsonwebtoken": "^9.0.4",
@@ -13335,7 +13139,7 @@ var package_default = {
13335
13139
  optionalDependencies: {
13336
13140
  "@vscode/ripgrep": "^1.17.0"
13337
13141
  },
13338
- gitHead: "8959c583b664ae1081979a1b42a778bdf3be2729"
13142
+ gitHead: "44e7b5760cfc839f3777b505abfbac911e341c26"
13339
13143
  };
13340
13144
 
13341
13145
  // src/config/constants.ts
@@ -13933,7 +13737,7 @@ Describe the expected output format here.
13933
13737
  };
13934
13738
 
13935
13739
  // src/agents/delegateTool.ts
13936
- function createAgentDelegateTool(orchestrator, agentStore, parentSessionId, backgroundManager) {
13740
+ function createAgentDelegateTool(orchestrator, agentStore, parentSessionId) {
13937
13741
  const agents = agentStore.getAllAgents();
13938
13742
  const agentDescriptions = agents.map((a) => `- **${a.name}**: ${a.description}`).join("\n");
13939
13743
  const agentNames = agentStore.getAgentNames();
@@ -13950,21 +13754,13 @@ function createAgentDelegateTool(orchestrator, agentStore, parentSessionId, back
13950
13754
  const available = agentNames.join(", ");
13951
13755
  throw new Error(`agent_delegate: unknown agent "${params.agent}". Available agents: ${available}`);
13952
13756
  }
13953
- const spawnOptions = {
13757
+ const result = await orchestrator.delegateToAgent({
13954
13758
  task: params.task,
13955
13759
  agentName: params.agent,
13956
13760
  thoroughness: params.thoroughness,
13957
13761
  variables: params.variables,
13958
13762
  parentSessionId
13959
- };
13960
- if (params.run_in_background && backgroundManager) {
13961
- const jobId = backgroundManager.spawn({
13962
- ...spawnOptions,
13963
- groupDescription: params.group_description
13964
- });
13965
- return `Background agent started. Job ID: ${jobId}. Use check_agent_status tool with this job ID to retrieve results when ready.`;
13966
- }
13967
- const result = await orchestrator.delegateToAgent(spawnOptions);
13763
+ });
13968
13764
  return result.summary;
13969
13765
  },
13970
13766
  toolSchema: {
@@ -14015,14 +13811,6 @@ ${agentDescriptions}
14015
13811
  type: "object",
14016
13812
  additionalProperties: { type: "string" },
14017
13813
  description: 'Custom variables to substitute in agent system prompt. For example: { "DOMAIN": "authentication", "STRICTNESS": "high" }'
14018
- },
14019
- run_in_background: {
14020
- type: "boolean",
14021
- description: "Run the agent in the background (non-blocking). Returns a job ID immediately. Use check_agent_status to poll for results. Useful for parallel work or long-running tasks."
14022
- },
14023
- group_description: {
14024
- type: "string",
14025
- description: 'Short description of what this group of background agents is working on (e.g., "Implementing user authentication"). Only needed for the first background agent in a group. All background agents spawned in the same turn are automatically grouped.'
14026
13814
  }
14027
13815
  },
14028
13816
  required: ["task", "agent"]
@@ -14031,399 +13819,6 @@ ${agentDescriptions}
14031
13819
  };
14032
13820
  }
14033
13821
 
14034
- // src/agents/BackgroundAgentManager.ts
14035
- import { randomBytes as randomBytes4 } from "crypto";
14036
- var DEFAULT_MAX_CONCURRENT = 4;
14037
- var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
14038
- function isTerminalStatus(status) {
14039
- return TERMINAL_STATUSES.has(status);
14040
- }
14041
- var DEFAULT_MAX_JOB_AGE_MS = 60 * 60 * 1e3;
14042
- var MAX_JOBS_BEFORE_CLEANUP = 100;
14043
- function pluralize(count) {
14044
- return count === 1 ? "" : "s";
14045
- }
14046
- var BackgroundAgentManager = class {
14047
- constructor(orchestrator, maxConcurrent = DEFAULT_MAX_CONCURRENT) {
14048
- this.jobs = /* @__PURE__ */ new Map();
14049
- this.queue = [];
14050
- // Job IDs waiting to start
14051
- this.runningCount = 0;
14052
- this.onStatusChange = null;
14053
- this.onGroupCompletion = null;
14054
- this.pendingNotifications = [];
14055
- this.turnGroups = /* @__PURE__ */ new Map();
14056
- this.currentTurnId = null;
14057
- this.orchestrator = orchestrator;
14058
- this.maxConcurrent = maxConcurrent;
14059
- }
14060
- /**
14061
- * Set the current turn ID. Jobs spawned while this is set will be grouped.
14062
- * Call with null to clear (after agent.run() completes).
14063
- */
14064
- setCurrentTurn(turnId) {
14065
- this.currentTurnId = turnId;
14066
- }
14067
- /**
14068
- * Get the current turn ID (for testing/debugging)
14069
- */
14070
- getCurrentTurnId() {
14071
- return this.currentTurnId;
14072
- }
14073
- /**
14074
- * Set a callback that fires whenever a job changes status.
14075
- * Used to update the Zustand store / UI.
14076
- */
14077
- setOnStatusChange(callback) {
14078
- this.onStatusChange = callback;
14079
- }
14080
- /**
14081
- * Set a callback that fires when all jobs in a turn group complete.
14082
- * Used to notify the user that background work is done.
14083
- */
14084
- setOnGroupCompletion(callback) {
14085
- this.onGroupCompletion = callback;
14086
- }
14087
- /**
14088
- * Spawn an agent in the background. Returns the job ID immediately.
14089
- * If concurrency limit is reached, the job is queued and starts when a slot opens.
14090
- */
14091
- spawn(options) {
14092
- const id = `bg-${randomBytes4(4).toString("hex")}`;
14093
- const abortController = new AbortController();
14094
- const isQueued = this.runningCount >= this.maxConcurrent;
14095
- const job = {
14096
- id,
14097
- agentName: options.agentName,
14098
- task: options.task,
14099
- status: isQueued ? "queued" : "running",
14100
- startTime: Date.now(),
14101
- turnId: this.currentTurnId ?? void 0,
14102
- groupDescription: options.groupDescription
14103
- };
14104
- const internal = { job, options, abortController };
14105
- this.jobs.set(id, internal);
14106
- this.notifyStatusChange(job);
14107
- if (this.currentTurnId) {
14108
- let group = this.turnGroups.get(this.currentTurnId);
14109
- if (!group) {
14110
- group = {
14111
- turnId: this.currentTurnId,
14112
- description: options.groupDescription,
14113
- jobIds: [],
14114
- notifications: []
14115
- };
14116
- this.turnGroups.set(this.currentTurnId, group);
14117
- } else if (options.groupDescription && !group.description) {
14118
- group.description = options.groupDescription;
14119
- }
14120
- group.jobIds.push(id);
14121
- }
14122
- if (isQueued) {
14123
- this.queue.push(id);
14124
- } else {
14125
- this.startJob(internal);
14126
- }
14127
- return id;
14128
- }
14129
- /**
14130
- * Get a job by ID (public-facing snapshot without internals)
14131
- */
14132
- getJob(id) {
14133
- return this.jobs.get(id)?.job;
14134
- }
14135
- /**
14136
- * Get the full result of a completed job
14137
- */
14138
- getResult(id) {
14139
- return this.jobs.get(id)?.result;
14140
- }
14141
- /**
14142
- * List all jobs (public-facing snapshots)
14143
- */
14144
- listJobs() {
14145
- return Array.from(this.jobs.values()).map((j) => j.job);
14146
- }
14147
- /**
14148
- * Cancel a running or queued job
14149
- */
14150
- cancelJob(id) {
14151
- const internal = this.jobs.get(id);
14152
- if (!internal) return false;
14153
- if (internal.job.status === "queued") {
14154
- this.queue = this.queue.filter((qid) => qid !== id);
14155
- this.updateJob(id, { status: "cancelled", endTime: Date.now() });
14156
- return true;
14157
- }
14158
- if (internal.job.status === "running") {
14159
- internal.abortController.abort();
14160
- this.updateJob(id, { status: "cancelled", endTime: Date.now() });
14161
- this.runningCount--;
14162
- this.processQueue();
14163
- return true;
14164
- }
14165
- return false;
14166
- }
14167
- /**
14168
- * Drain all pending notifications (called by the LLM wrapper before each completion).
14169
- * Returns notification strings and clears the queue.
14170
- */
14171
- drainNotifications() {
14172
- return this.pendingNotifications.splice(0);
14173
- }
14174
- /**
14175
- * Handle job completion - routes to grouped or immediate notification
14176
- */
14177
- handleJobCompletion(job, status, content) {
14178
- if (job.turnId) {
14179
- const group = this.turnGroups.get(job.turnId);
14180
- if (group) {
14181
- group.notifications.push({
14182
- jobId: job.id,
14183
- agentName: job.agentName,
14184
- task: job.task,
14185
- status,
14186
- content
14187
- });
14188
- this.checkTurnGroupCompletion(job.turnId);
14189
- return;
14190
- }
14191
- }
14192
- this.pendingNotifications.push(content);
14193
- }
14194
- /**
14195
- * Check if all jobs in a turn group have completed
14196
- */
14197
- checkTurnGroupCompletion(turnId) {
14198
- const group = this.turnGroups.get(turnId);
14199
- if (!group) return;
14200
- const allComplete = group.jobIds.every((jobId) => {
14201
- const internal = this.jobs.get(jobId);
14202
- return internal && isTerminalStatus(internal.job.status);
14203
- });
14204
- if (allComplete) {
14205
- const notification = this.createConsolidatedNotification(group);
14206
- this.pendingNotifications.push(notification);
14207
- if (this.onGroupCompletion) {
14208
- this.onGroupCompletion(notification, group.description);
14209
- }
14210
- this.turnGroups.delete(turnId);
14211
- this.cleanupOldJobs();
14212
- }
14213
- }
14214
- /**
14215
- * Create a consolidated notification for a completed turn group
14216
- */
14217
- createConsolidatedNotification(group) {
14218
- const statusCounts = { completed: 0, failed: 0, cancelled: 0 };
14219
- for (const notification of group.notifications) {
14220
- statusCounts[notification.status]++;
14221
- }
14222
- const total = group.notifications.length;
14223
- const statsSummary = Object.entries(statusCounts).filter(([, count]) => count > 0).map(([status, count]) => `${count} ${status}`).join(", ");
14224
- const agentCount = `${total} agent${pluralize(total)} finished`;
14225
- const header = group.description ? `[Background Agents Completed] "${group.description}" - ${agentCount} (${statsSummary})` : `[Background Agents Completed] ${agentCount} (${statsSummary})`;
14226
- const details = group.notifications.map((n) => {
14227
- const statusLabel = n.status.toUpperCase();
14228
- return `=== Agent "${n.agentName}" (job ${n.jobId}) - ${statusLabel} ===
14229
- Task: ${n.task}
14230
- ${n.status === "completed" ? "Result" : "Error"}:
14231
- ${n.content}`;
14232
- }).join("\n\n");
14233
- return `${header}
14234
-
14235
- ${details}`;
14236
- }
14237
- startJob(internal) {
14238
- this.runningCount++;
14239
- this.updateJob(internal.job.id, { status: "running" });
14240
- const { job, options } = internal;
14241
- internal.promise = this.orchestrator.delegateToAgent(options).then((result) => {
14242
- this.updateJob(job.id, {
14243
- status: "completed",
14244
- endTime: Date.now(),
14245
- resultSummary: result.summary
14246
- });
14247
- internal.result = result;
14248
- this.handleJobCompletion(job, "completed", result.summary);
14249
- return result;
14250
- }).catch((error) => {
14251
- const isCancelled = internal.abortController.signal.aborted;
14252
- const errorMsg = error instanceof Error ? error.message : String(error);
14253
- const status = isCancelled ? "cancelled" : "failed";
14254
- this.updateJob(job.id, {
14255
- status,
14256
- endTime: Date.now(),
14257
- error: errorMsg
14258
- });
14259
- this.handleJobCompletion(job, status, errorMsg);
14260
- }).finally(() => {
14261
- this.runningCount--;
14262
- this.processQueue();
14263
- });
14264
- }
14265
- /** Start the next queued job if there's capacity */
14266
- processQueue() {
14267
- while (this.queue.length > 0 && this.runningCount < this.maxConcurrent) {
14268
- const nextId = this.queue.shift();
14269
- const internal = this.jobs.get(nextId);
14270
- if (internal && internal.job.status === "queued") {
14271
- this.startJob(internal);
14272
- }
14273
- }
14274
- }
14275
- updateJob(id, updates) {
14276
- const internal = this.jobs.get(id);
14277
- if (!internal) return;
14278
- Object.assign(internal.job, updates);
14279
- this.notifyStatusChange(internal.job);
14280
- }
14281
- notifyStatusChange(job) {
14282
- if (this.onStatusChange) {
14283
- this.onStatusChange({ ...job });
14284
- }
14285
- }
14286
- /**
14287
- * Clean up old completed jobs to prevent memory leaks.
14288
- * Removes jobs that have been in a terminal state for longer than maxAgeMs.
14289
- * Also removes jobs when total count exceeds MAX_JOBS_BEFORE_CLEANUP.
14290
- */
14291
- cleanupOldJobs(maxAgeMs = DEFAULT_MAX_JOB_AGE_MS) {
14292
- const now = Date.now();
14293
- let cleanedCount = 0;
14294
- for (const [id, internal] of this.jobs.entries()) {
14295
- if (isTerminalStatus(internal.job.status) && internal.job.endTime && now - internal.job.endTime > maxAgeMs) {
14296
- this.jobs.delete(id);
14297
- cleanedCount++;
14298
- }
14299
- }
14300
- if (this.jobs.size > MAX_JOBS_BEFORE_CLEANUP) {
14301
- const completedJobs = Array.from(this.jobs.entries()).filter(([, j]) => isTerminalStatus(j.job.status)).sort((a, b) => (a[1].job.endTime || 0) - (b[1].job.endTime || 0));
14302
- const toRemove = completedJobs.slice(0, this.jobs.size - MAX_JOBS_BEFORE_CLEANUP + 10);
14303
- for (const [id] of toRemove) {
14304
- this.jobs.delete(id);
14305
- cleanedCount++;
14306
- }
14307
- }
14308
- return cleanedCount;
14309
- }
14310
- /**
14311
- * Get the current number of jobs (for monitoring)
14312
- */
14313
- getJobCount() {
14314
- let running = 0;
14315
- let queued = 0;
14316
- let completed = 0;
14317
- for (const internal of this.jobs.values()) {
14318
- switch (internal.job.status) {
14319
- case "running":
14320
- running++;
14321
- break;
14322
- case "queued":
14323
- queued++;
14324
- break;
14325
- default:
14326
- completed++;
14327
- }
14328
- }
14329
- return { total: this.jobs.size, running, queued, completed };
14330
- }
14331
- };
14332
-
14333
- // src/agents/backgroundTools.ts
14334
- function createBackgroundAgentTools(manager) {
14335
- const checkAgentStatus = {
14336
- toolFn: async (args) => {
14337
- const { job_id } = args;
14338
- if (!job_id) throw new Error("check_agent_status: job_id is required");
14339
- const job = manager.getJob(job_id);
14340
- if (!job) return `No background agent found with ID: ${job_id}`;
14341
- switch (job.status) {
14342
- case "queued":
14343
- return `Agent "${job.agentName}" is queued (waiting for a concurrency slot). Task: ${job.task}`;
14344
- case "running": {
14345
- const elapsed = Math.round((Date.now() - job.startTime) / 1e3);
14346
- return `Agent "${job.agentName}" is still running (${elapsed}s elapsed). Task: ${job.task}`;
14347
- }
14348
- case "completed": {
14349
- const result = manager.getResult(job_id);
14350
- return result?.summary || `Agent "${job.agentName}" completed but no summary available.`;
14351
- }
14352
- case "failed":
14353
- return `Agent "${job.agentName}" failed: ${job.error || "Unknown error"}`;
14354
- case "cancelled":
14355
- return `Agent "${job.agentName}" was cancelled.`;
14356
- }
14357
- },
14358
- toolSchema: {
14359
- name: "check_agent_status",
14360
- description: "Check the status and retrieve results of a background agent job. Use after spawning an agent with run_in_background: true.",
14361
- parameters: {
14362
- type: "object",
14363
- properties: {
14364
- job_id: {
14365
- type: "string",
14366
- description: "The job ID returned by agent_delegate when run_in_background was true"
14367
- }
14368
- },
14369
- required: ["job_id"]
14370
- }
14371
- }
14372
- };
14373
- const listBackgroundAgents = {
14374
- toolFn: async () => {
14375
- const jobs = manager.listJobs();
14376
- if (jobs.length === 0) return "No background agents.";
14377
- return jobs.map((job) => {
14378
- const elapsed = Math.round(((job.endTime || Date.now()) - job.startTime) / 1e3);
14379
- const statusIcons = {
14380
- queued: "\u{1F550}",
14381
- running: "\u23F3",
14382
- completed: "\u2705",
14383
- failed: "\u274C",
14384
- cancelled: "\u{1F6AB}"
14385
- };
14386
- const statusIcon = statusIcons[job.status] || "\u2753";
14387
- return `${statusIcon} [${job.id}] ${job.agentName} (${job.status}, ${elapsed}s) - ${job.task.slice(0, 80)}`;
14388
- }).join("\n");
14389
- },
14390
- toolSchema: {
14391
- name: "list_background_agents",
14392
- description: "List all background agent jobs with their current status.",
14393
- parameters: {
14394
- type: "object",
14395
- properties: {}
14396
- }
14397
- }
14398
- };
14399
- const cancelBackgroundAgent = {
14400
- toolFn: async (args) => {
14401
- const { job_id } = args;
14402
- if (!job_id) throw new Error("cancel_background_agent: job_id is required");
14403
- const cancelled = manager.cancelJob(job_id);
14404
- if (cancelled) return `Background agent ${job_id} has been cancelled.`;
14405
- const job = manager.getJob(job_id);
14406
- if (!job) return `No background agent found with ID: ${job_id}`;
14407
- return `Cannot cancel agent ${job_id} - status is already "${job.status}".`;
14408
- },
14409
- toolSchema: {
14410
- name: "cancel_background_agent",
14411
- description: "Cancel a running background agent job.",
14412
- parameters: {
14413
- type: "object",
14414
- properties: {
14415
- job_id: {
14416
- type: "string",
14417
- description: "The job ID of the background agent to cancel"
14418
- }
14419
- },
14420
- required: ["job_id"]
14421
- }
14422
- }
14423
- };
14424
- return [checkAgentStatus, listBackgroundAgents, cancelBackgroundAgent];
14425
- }
14426
-
14427
13822
  // src/tools/skillTool.ts
14428
13823
  async function executeHook(script, context) {
14429
13824
  const result = await runShellCommand({
@@ -14798,7 +14193,7 @@ var usageCache = null;
14798
14193
  function CliApp() {
14799
14194
  const { exit } = useApp();
14800
14195
  const imageRenderer = new ImageRenderer();
14801
- const [state, setState] = useState9({
14196
+ const [state, setState] = useState8({
14802
14197
  session: null,
14803
14198
  sessionStore: new SessionStore(),
14804
14199
  configStore: new ConfigStore(),
@@ -14818,20 +14213,18 @@ function CliApp() {
14818
14213
  orchestrator: null,
14819
14214
  agentStore: null,
14820
14215
  abortController: null,
14821
- contextContent: "",
14822
- backgroundManager: null
14216
+ contextContent: ""
14823
14217
  });
14824
- const [isInitialized, setIsInitialized] = useState9(false);
14825
- const [initError, setInitError] = useState9(null);
14826
- const [commandHistory, setCommandHistory] = useState9([]);
14218
+ const [isInitialized, setIsInitialized] = useState8(false);
14219
+ const [initError, setInitError] = useState8(null);
14220
+ const [commandHistory, setCommandHistory] = useState8([]);
14827
14221
  const imageStoreInitPromise = useRef3(null);
14828
14222
  const setStoreSession = useCliStore((state2) => state2.setSession);
14829
- const enqueuePermissionPrompt = useCliStore((state2) => state2.enqueuePermissionPrompt);
14830
- const dequeuePermissionPrompt = useCliStore((state2) => state2.dequeuePermissionPrompt);
14223
+ const setPermissionPrompt = useCliStore((state2) => state2.setPermissionPrompt);
14831
14224
  const setShowConfigEditor = useCliStore((state2) => state2.setShowConfigEditor);
14832
14225
  const setShowMcpViewer = useCliStore((state2) => state2.setShowMcpViewer);
14833
14226
  const setExitRequested = useCliStore((state2) => state2.setExitRequested);
14834
- const performCleanup = useCallback2(async () => {
14227
+ const performCleanup = useCallback(async () => {
14835
14228
  const cleanupTasks = [];
14836
14229
  if (state.session) {
14837
14230
  cleanupTasks.push(
@@ -14866,7 +14259,7 @@ function CliApp() {
14866
14259
  process.exit(0);
14867
14260
  }, 100);
14868
14261
  }, [state.session, state.sessionStore, state.mcpManager, state.agent, state.imageStore]);
14869
- useInput9((input, key) => {
14262
+ useInput8((input, key) => {
14870
14263
  if (key.escape) {
14871
14264
  if (state.abortController) {
14872
14265
  logger.debug("[ABORT] ESC pressed - aborting current operation...");
@@ -14898,7 +14291,7 @@ function CliApp() {
14898
14291
  }
14899
14292
  }
14900
14293
  });
14901
- const init = useCallback2(async () => {
14294
+ const init = useCallback(async () => {
14902
14295
  try {
14903
14296
  const config = await state.configStore.load();
14904
14297
  const history = await state.commandHistoryStore.load();
@@ -15015,17 +14408,16 @@ function CliApp() {
15015
14408
  config.tools.disabled || []
15016
14409
  // denied tools from project config
15017
14410
  );
15018
- let permissionPromptCounter = 0;
15019
14411
  const promptFn = (toolName, args, preview) => {
15020
14412
  return new Promise((resolve3) => {
15021
14413
  const canBeTrusted = permissionManager.canBeTrusted(toolName);
15022
- const id = `perm-${++permissionPromptCounter}`;
15023
- const prompt = { id, toolName, args, preview, canBeTrusted, resolve: resolve3 };
14414
+ const prompt = { toolName, args, preview, canBeTrusted, resolve: resolve3 };
15024
14415
  setState((prev) => ({
15025
14416
  ...prev,
15026
- permissionManager
14417
+ permissionManager,
14418
+ permissionPrompt: prompt
15027
14419
  }));
15028
- enqueuePermissionPrompt(prompt);
14420
+ setPermissionPrompt(prompt);
15029
14421
  });
15030
14422
  };
15031
14423
  const agentContext = {
@@ -15071,17 +14463,7 @@ function CliApp() {
15071
14463
  agentStore,
15072
14464
  enableParallelToolExecution: config.preferences.enableParallelToolExecution === true
15073
14465
  });
15074
- const backgroundManager = new BackgroundAgentManager(orchestrator);
15075
- backgroundManager.setOnStatusChange((job) => {
15076
- useCliStore.getState().upsertBackgroundAgent(job);
15077
- });
15078
- backgroundManager.setOnGroupCompletion((notification, groupDescription) => {
15079
- useCliStore.getState().addCompletedGroupNotification(notification, groupDescription);
15080
- useCliStore.getState().setPendingBackgroundTrigger(true);
15081
- });
15082
- const agentDelegateTool = createAgentDelegateTool(orchestrator, agentStore, newSession.id, backgroundManager);
15083
- const backgroundTools = createBackgroundAgentTools(backgroundManager);
15084
- const notifyingLlm = new NotifyingLlmBackend(llm, backgroundManager);
14466
+ const agentDelegateTool = createAgentDelegateTool(orchestrator, agentStore, newSession.id);
15085
14467
  const todoStore = createTodoStore();
15086
14468
  const writeTodosTool = createWriteTodosTool(todoStore);
15087
14469
  const enableSkillTool = config.preferences.enableSkillTool !== false;
@@ -15090,14 +14472,13 @@ function CliApp() {
15090
14472
  subagentOrchestrator: orchestrator,
15091
14473
  sessionId: newSession.id
15092
14474
  }) : null;
15093
- const cliTools = [agentDelegateTool, ...backgroundTools, writeTodosTool];
14475
+ const cliTools = [agentDelegateTool, writeTodosTool];
15094
14476
  if (skillTool) {
15095
14477
  cliTools.push(skillTool);
15096
14478
  }
15097
14479
  const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
15098
14480
  console.log(`\u{1F4C2} Working directory: ${process.cwd()}`);
15099
- const agentNamesList = agentStore.getAgentNames().join(", ");
15100
- console.log(`\u{1F916} Subagent delegation enabled (${agentNamesList}) + background execution`);
14481
+ console.log(`\u{1F916} Subagent delegation enabled (explore, plan, review)`);
15101
14482
  if (skillTool) {
15102
14483
  const skillCount = state.customCommandStore.getCommandCount();
15103
14484
  if (skillCount > 0) {
@@ -15134,7 +14515,7 @@ ${contextResult.mergedContent}` : "";
15134
14515
  const agent = new ReActAgent({
15135
14516
  userId: config.userId,
15136
14517
  logger: silentLogger,
15137
- llm: notifyingLlm,
14518
+ llm,
15138
14519
  model: modelInfo.id,
15139
14520
  tools: allTools,
15140
14521
  maxIterations,
@@ -15186,10 +14567,8 @@ ${contextResult.mergedContent}` : "";
15186
14567
  // Store orchestrator for step handler updates
15187
14568
  agentStore,
15188
14569
  // Store agent store for agent management commands
15189
- contextContent: contextResult.mergedContent,
14570
+ contextContent: contextResult.mergedContent
15190
14571
  // Store raw context for compact instructions
15191
- backgroundManager
15192
- // Store for grouped notification turn tracking
15193
14572
  }));
15194
14573
  setStoreSession(newSession);
15195
14574
  setIsInitialized(true);
@@ -15203,11 +14582,11 @@ ${contextResult.mergedContent}` : "";
15203
14582
  setCommandHistory,
15204
14583
  setIsInitialized,
15205
14584
  setInitError,
15206
- enqueuePermissionPrompt,
14585
+ setPermissionPrompt,
15207
14586
  setStoreSession,
15208
14587
  setState
15209
14588
  ]);
15210
- useEffect6(() => {
14589
+ useEffect4(() => {
15211
14590
  init();
15212
14591
  }, [init]);
15213
14592
  const handleCustomCommandMessage = async (fullTemplate, displayMessage) => {
@@ -15283,19 +14662,12 @@ ${contextResult.mergedContent}` : "";
15283
14662
  content: msg.content
15284
14663
  }));
15285
14664
  const cliConfig = await state.configStore.get();
15286
- const turnId = `turn-${randomBytes5(4).toString("hex")}`;
15287
- state.backgroundManager?.setCurrentTurn(turnId);
15288
- let result;
15289
- try {
15290
- result = await state.agent.run(messageContent, {
15291
- previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
15292
- signal: abortController.signal,
15293
- parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
15294
- isReadOnlyTool
15295
- });
15296
- } finally {
15297
- state.backgroundManager?.setCurrentTurn(null);
15298
- }
14665
+ const result = await state.agent.run(messageContent, {
14666
+ previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
14667
+ signal: abortController.signal,
14668
+ parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
14669
+ isReadOnlyTool
14670
+ });
15299
14671
  const permissionDenied = result.finalAnswer.startsWith("Permission denied for tool");
15300
14672
  if (permissionDenied) {
15301
14673
  console.log("\n\u26A0\uFE0F Action denied by user\n");
@@ -15496,19 +14868,12 @@ ${contextResult.mergedContent}` : "";
15496
14868
  content: msg.content
15497
14869
  }));
15498
14870
  const cliConfig = await state.configStore.get();
15499
- const turnId = `turn-${randomBytes5(4).toString("hex")}`;
15500
- state.backgroundManager?.setCurrentTurn(turnId);
15501
- let result;
15502
- try {
15503
- result = await state.agent.run(messageContent, {
15504
- previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
15505
- signal: abortController.signal,
15506
- parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
15507
- isReadOnlyTool
15508
- });
15509
- } finally {
15510
- state.backgroundManager?.setCurrentTurn(null);
15511
- }
14871
+ const result = await state.agent.run(messageContent, {
14872
+ previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
14873
+ signal: abortController.signal,
14874
+ parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
14875
+ isReadOnlyTool
14876
+ });
15512
14877
  const permissionDenied = result.finalAnswer.startsWith("Permission denied for tool");
15513
14878
  if (permissionDenied) {
15514
14879
  console.log("\n\u26A0\uFE0F Action denied by user\n");
@@ -15584,88 +14949,7 @@ ${contextResult.mergedContent}` : "";
15584
14949
  useCliStore.getState().setIsThinking(false);
15585
14950
  }
15586
14951
  };
15587
- const handleBackgroundCompletion = async () => {
15588
- if (!state.agent || !state.session) {
15589
- return;
15590
- }
15591
- const authTokens = await state.configStore.getAuthTokens();
15592
- if (!authTokens || new Date(authTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
15593
- return;
15594
- }
15595
- useCliStore.getState().setIsThinking(true);
15596
- const abortController = new AbortController();
15597
- setState((prev) => ({ ...prev, abortController }));
15598
- try {
15599
- const pendingAssistantMessage = {
15600
- id: uuidv411(),
15601
- role: "assistant",
15602
- content: "...",
15603
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15604
- metadata: {
15605
- steps: []
15606
- }
15607
- };
15608
- useCliStore.getState().addPendingMessage(pendingAssistantMessage);
15609
- const recentMessages = state.session.messages.slice(-20);
15610
- const previousMessages = recentMessages.filter((msg) => msg.role === "user" || msg.role === "assistant").map((msg) => ({
15611
- role: msg.role,
15612
- content: msg.content
15613
- }));
15614
- const cliConfig = await state.configStore.get();
15615
- const result = await state.agent.run(
15616
- "[System: Background agents have completed. Review and summarize the results.]",
15617
- {
15618
- previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
15619
- signal: abortController.signal,
15620
- parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
15621
- isReadOnlyTool
15622
- }
15623
- );
15624
- const successfulToolCalls = result.steps.filter((s) => s.type === "observation").length;
15625
- const currentSession = useCliStore.getState().session;
15626
- if (!currentSession) return;
15627
- const continuationMessage = {
15628
- id: uuidv411(),
15629
- role: "assistant",
15630
- content: "---\n\n**Background Agent Results:**\n\n" + result.finalAnswer,
15631
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15632
- metadata: {
15633
- isContinuation: true,
15634
- // Flag to skip "Assistant" header in MessageItem
15635
- steps: result.steps.map(formatStep),
15636
- tokenUsage: {
15637
- prompt: 0,
15638
- completion: 0,
15639
- total: result.completionInfo.totalTokens
15640
- }
15641
- }
15642
- };
15643
- const updatedSession = {
15644
- ...currentSession,
15645
- messages: [...currentSession.messages, continuationMessage],
15646
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
15647
- metadata: {
15648
- ...currentSession.metadata,
15649
- totalTokens: currentSession.metadata.totalTokens + result.completionInfo.totalTokens,
15650
- toolCallCount: currentSession.metadata.toolCallCount + successfulToolCalls
15651
- }
15652
- };
15653
- useCliStore.getState().clearPendingMessages();
15654
- setState((prev) => ({ ...prev, session: updatedSession }));
15655
- setStoreSession(updatedSession);
15656
- await state.sessionStore.save(updatedSession);
15657
- } catch (error) {
15658
- useCliStore.getState().clearPendingMessages();
15659
- if (error instanceof Error && error.name === "AbortError") {
15660
- return;
15661
- }
15662
- console.error("Error processing background results:", error);
15663
- } finally {
15664
- setState((prev) => ({ ...prev, abortController: null }));
15665
- useCliStore.getState().setIsThinking(false);
15666
- }
15667
- };
15668
- const handleBashCommand = useCallback2(
14952
+ const handleBashCommand = useCallback(
15669
14953
  (command) => {
15670
14954
  if (!state.session) return;
15671
14955
  let output;
@@ -16640,12 +15924,12 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16640
15924
  }
16641
15925
  };
16642
15926
  if (initError) {
16643
- return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text20, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React21.createElement(Text20, null, initError), /* @__PURE__ */ React21.createElement(Text20, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
15927
+ return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React19.createElement(Text18, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React19.createElement(Text18, null, initError), /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
16644
15928
  }
16645
15929
  if (state.trustLocationSelector) {
16646
15930
  const projectDir = state.configStore.getProjectConfigDir();
16647
15931
  const inProject = projectDir !== null;
16648
- return /* @__PURE__ */ React21.createElement(
15932
+ return /* @__PURE__ */ React19.createElement(
16649
15933
  TrustLocationSelector,
16650
15934
  {
16651
15935
  inProject,
@@ -16663,7 +15947,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16663
15947
  );
16664
15948
  }
16665
15949
  if (state.rewindSelector && state.session) {
16666
- return /* @__PURE__ */ React21.createElement(
15950
+ return /* @__PURE__ */ React19.createElement(
16667
15951
  RewindSelector,
16668
15952
  {
16669
15953
  messages: state.session.messages,
@@ -16681,7 +15965,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16681
15965
  );
16682
15966
  }
16683
15967
  if (state.sessionSelector) {
16684
- return /* @__PURE__ */ React21.createElement(
15968
+ return /* @__PURE__ */ React19.createElement(
16685
15969
  SessionSelector,
16686
15970
  {
16687
15971
  sessions: state.sessionSelector.sessions,
@@ -16701,7 +15985,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16701
15985
  }
16702
15986
  if (state.showLoginFlow) {
16703
15987
  const loginApiUrl = getApiUrl(state.config?.apiConfig);
16704
- return /* @__PURE__ */ React21.createElement(
15988
+ return /* @__PURE__ */ React19.createElement(
16705
15989
  LoginFlow,
16706
15990
  {
16707
15991
  apiUrl: loginApiUrl,
@@ -16724,14 +16008,13 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16724
16008
  );
16725
16009
  }
16726
16010
  if (!isInitialized) {
16727
- return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text20, null, "\u{1F680} Initializing..."));
16011
+ return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React19.createElement(Text18, null, "\u{1F680} Initializing..."));
16728
16012
  }
16729
16013
  const allCommands = mergeCommands(state.customCommandStore.getAllCommands());
16730
- return /* @__PURE__ */ React21.createElement(
16014
+ return /* @__PURE__ */ React19.createElement(
16731
16015
  App,
16732
16016
  {
16733
16017
  onMessage: handleMessage,
16734
- onBackgroundCompletion: handleBackgroundCompletion,
16735
16018
  onCommand: handleCommand,
16736
16019
  onBashCommand: handleBashCommand,
16737
16020
  onImageDetected: handleImageDetected,
@@ -16746,10 +16029,10 @@ No usage data available for the last ${USAGE_DAYS} days.`);
16746
16029
  },
16747
16030
  mcpManager: state.mcpManager ?? void 0,
16748
16031
  onPermissionResponse: (response) => {
16749
- const currentPrompt = useCliStore.getState().permissionPrompt;
16750
- if (currentPrompt) {
16751
- currentPrompt.resolve({ action: response });
16752
- dequeuePermissionPrompt();
16032
+ if (state.permissionPrompt) {
16033
+ state.permissionPrompt.resolve({ action: response });
16034
+ setState((prev) => ({ ...prev, permissionPrompt: null }));
16035
+ setPermissionPrompt(null);
16753
16036
  }
16754
16037
  }
16755
16038
  }
@@ -16770,6 +16053,6 @@ var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "d
16770
16053
  if (isDevMode) {
16771
16054
  logger.debug("\u{1F527} Running in development mode (using TypeScript source)\n");
16772
16055
  }
16773
- render(/* @__PURE__ */ React21.createElement(CliApp, null), {
16056
+ render(/* @__PURE__ */ React19.createElement(CliApp, null), {
16774
16057
  exitOnCtrlC: false
16775
16058
  });