@bike4mind/cli 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{BubblewrapRuntime-BHbtqvLx.mjs → BubblewrapRuntime-CUD3bsgG.mjs} +1 -1
  2. package/dist/{ConfigStore-CAKSUXCi.mjs → ConfigStore-BauEpjvT.mjs} +1892 -1182
  3. package/dist/ProxyManager-DIAAw902.mjs +3 -0
  4. package/dist/{SandboxOrchestrator-CHZgSR3P.mjs → SandboxOrchestrator-C4oDqltp.mjs} +1 -1
  5. package/dist/{SandboxRuntimeAdapter-C1B4t20N.mjs → SandboxRuntimeAdapter-D1RUReNL.mjs} +2 -2
  6. package/dist/{SandboxRuntimeAdapter-D7UAG13n.mjs → SandboxRuntimeAdapter-DXa3nFOw.mjs} +1 -1
  7. package/dist/{SeatbeltRuntime-D4m0VOcD.mjs → SeatbeltRuntime-CTElMR9Q.mjs} +1 -1
  8. package/dist/commands/doctorCommand.mjs +13 -1
  9. package/dist/commands/headlessCommand.mjs +5 -5
  10. package/dist/commands/mcpCommand.mjs +1 -1
  11. package/dist/commands/updateCommand.mjs +33 -15
  12. package/dist/{grepSearch-DMuEcUSq-D3RsGLCg.mjs → grepSearch-BxucZWO8-lPRv6R6F.mjs} +15 -26
  13. package/dist/index.mjs +74 -66
  14. package/dist/ripgrepCheck-DIu4apVE.mjs +39 -0
  15. package/dist/store-5PXzE9DM.mjs +3 -0
  16. package/dist/{tools-ICW0xW8W.mjs → tools-CpWE3Qif.mjs} +12961 -1962
  17. package/dist/{updateChecker-Dproz7j-.mjs → updateChecker-DhWcEKAu.mjs} +1 -1
  18. package/package.json +15 -15
  19. package/dist/ProxyManager-kiOD1X8-.mjs +0 -3
  20. package/dist/store-YhSkjsW4.mjs +0 -3
  21. /package/dist/{ImageStore-DaKT_Ew8.mjs → ImageStore-BFp_d12J.mjs} +0 -0
  22. /package/dist/{ProxyManager-Dl2nFk-A.mjs → ProxyManager-BsCoxpns.mjs} +0 -0
  23. /package/dist/{SandboxOrchestrator-BEW3rqYi.mjs → SandboxOrchestrator-B4GcZdBc.mjs} +0 -0
  24. /package/dist/{StderrViolationParser-D0afQ3-1.mjs → StderrViolationParser-BFP4bo7I.mjs} +0 -0
  25. /package/dist/{ViolationLogStore-CZl35HcA.mjs → ViolationLogStore-Dp6HF0nz.mjs} +0 -0
  26. /package/dist/{bashExecute-pYljpfPn-Bsh-jb3S.mjs → bashExecute-pYljpfPn-BZXHMQEl.mjs} +0 -0
  27. /package/dist/{createFile-C1JoeuYh-LvIRJtxM.mjs → createFile-C1JoeuYh-metInFKd.mjs} +0 -0
  28. /package/dist/{deleteFile-BTberNGj-BpBvrcoC.mjs → deleteFile-BTberNGj-CW922hRM.mjs} +0 -0
  29. /package/dist/{globFiles-Bez8QCbS-DyZsKEJB.mjs → globFiles-Bez8QCbS-DZb6McbJ.mjs} +0 -0
  30. /package/dist/{store-DLduYYGR.mjs → store-BonrwrMi.mjs} +0 -0
  31. /package/dist/{terminalSetup-rmr1P8KF.mjs → terminalSetup-DxloCowq.mjs} +0 -0
  32. /package/dist/{treeSitterEngine-BFTHnDwH.mjs → treeSitterEngine-Cw2LbVZT.mjs} +0 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { t as ProxyManager } from "./ProxyManager-BsCoxpns.mjs";
3
+ export { ProxyManager };
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { t as SandboxOrchestrator } from "./SandboxOrchestrator-BEW3rqYi.mjs";
2
+ import { t as SandboxOrchestrator } from "./SandboxOrchestrator-B4GcZdBc.mjs";
3
3
  export { SandboxOrchestrator };
@@ -42,12 +42,12 @@ async function createSandboxRuntime() {
42
42
  const platform = detectPlatform();
43
43
  if (!platform) return null;
44
44
  if (platform === "darwin") {
45
- const { SeatbeltRuntime } = await import("./SeatbeltRuntime-D4m0VOcD.mjs");
45
+ const { SeatbeltRuntime } = await import("./SeatbeltRuntime-CTElMR9Q.mjs");
46
46
  const runtime = new SeatbeltRuntime();
47
47
  return runtime.isAvailable() ? runtime : null;
48
48
  }
49
49
  if (platform === "linux") {
50
- const { BubblewrapRuntime } = await import("./BubblewrapRuntime-BHbtqvLx.mjs");
50
+ const { BubblewrapRuntime } = await import("./BubblewrapRuntime-CUD3bsgG.mjs");
51
51
  const runtime = new BubblewrapRuntime();
52
52
  return runtime.isAvailable() ? runtime : null;
53
53
  }
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-C1B4t20N.mjs";
2
+ import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-D1RUReNL.mjs";
3
3
  export { createSandboxRuntime, detectPlatform, expandPath, isBinaryAvailable };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-C1B4t20N.mjs";
2
+ import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-D1RUReNL.mjs";
3
3
  import { mkdtempSync, writeFileSync } from "fs";
4
4
  import os from "os";
5
5
  import path from "path";
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-Dproz7j-.mjs";
2
+ import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-DhWcEKAu.mjs";
3
+ import { t as checkRipgrep } from "../ripgrepCheck-DIu4apVE.mjs";
3
4
  import { execSync } from "child_process";
4
5
  import { constants, existsSync, promises } from "fs";
5
6
  import { homedir } from "os";
@@ -74,6 +75,17 @@ async function handleDoctorCommand() {
74
75
  message: "Could not determine npm prefix"
75
76
  });
76
77
  }
78
+ const rg = await checkRipgrep();
79
+ if (rg.available) results.push({
80
+ name: "ripgrep (grep_search)",
81
+ status: "pass",
82
+ message: rg.path
83
+ });
84
+ else results.push({
85
+ name: "ripgrep (grep_search)",
86
+ status: "warn",
87
+ message: `${rg.error ?? "not found"} — run: b4m update`
88
+ });
77
89
  const configFile = path.join(homedir(), ".bike4mind", "config.json");
78
90
  if (existsSync(configFile)) results.push({
79
91
  name: "Config file",
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, I as generateCliTools, M as loadContextFiles, N as getApiUrl, O as McpManager, Q as CheckpointStore, S as ApiClient, T as FallbackLlmBackend, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, b as createSkillTool, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, m as createCoordinateTaskTool, p as createWriteTodosTool, q as buildSystemPrompt, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, y as SubagentOrchestrator } from "../tools-ICW0xW8W.mjs";
3
- import { n as logger, t as ConfigStore } from "../ConfigStore-CAKSUXCi.mjs";
2
+ import { C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, I as generateCliTools, M as loadContextFiles, N as getApiUrl, O as McpManager, Q as CheckpointStore, S as ApiClient, T as FallbackLlmBackend, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, b as createSkillTool, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, m as createCoordinateTaskTool, p as createWriteTodosTool, q as buildSystemPrompt, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, y as SubagentOrchestrator } from "../tools-CpWE3Qif.mjs";
3
+ import { n as logger, t as ConfigStore } from "../ConfigStore-BauEpjvT.mjs";
4
4
  import { t as DEFAULT_SANDBOX_CONFIG } from "../types-DBEjF9YS.mjs";
5
- import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-C1B4t20N.mjs";
6
- import { t as SandboxOrchestrator } from "../SandboxOrchestrator-BEW3rqYi.mjs";
7
- import { t as ProxyManager } from "../ProxyManager-Dl2nFk-A.mjs";
5
+ import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-D1RUReNL.mjs";
6
+ import { t as SandboxOrchestrator } from "../SandboxOrchestrator-B4GcZdBc.mjs";
7
+ import { t as ProxyManager } from "../ProxyManager-BsCoxpns.mjs";
8
8
  import { randomBytes } from "crypto";
9
9
  import { v4 } from "uuid";
10
10
  //#region src/commands/headlessCommand.ts
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-CAKSUXCi.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-BauEpjvT.mjs";
3
3
  //#region src/commands/mcpCommand.ts
4
4
  /**
5
5
  * External MCP commands (b4m mcp list, b4m mcp add, etc.)
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as version, i as forceCheckForUpdate } from "../updateChecker-Dproz7j-.mjs";
2
+ import { a as version, i as forceCheckForUpdate } from "../updateChecker-DhWcEKAu.mjs";
3
+ import { t as checkRipgrep } from "../ripgrepCheck-DIu4apVE.mjs";
3
4
  import { execSync } from "child_process";
4
5
  //#region src/commands/updateCommand.ts
5
6
  /**
@@ -7,6 +8,22 @@ import { execSync } from "child_process";
7
8
  * Checks for and installs CLI updates.
8
9
  * Runs outside the interactive CLI session.
9
10
  */
11
+ const INSTALL_CMD = "npm install -g @bike4mind/cli@latest";
12
+ function runGlobalInstall() {
13
+ try {
14
+ execSync(INSTALL_CMD, {
15
+ stdio: "inherit",
16
+ timeout: 12e4
17
+ });
18
+ return true;
19
+ } catch {
20
+ console.error("\nInstall failed. Try running manually:");
21
+ console.error(` ${INSTALL_CMD}`);
22
+ console.error("\nIf you get permission errors, try:");
23
+ console.error(` sudo ${INSTALL_CMD}`);
24
+ return false;
25
+ }
26
+ }
10
27
  async function handleUpdateCommand() {
11
28
  const currentVersion = version;
12
29
  console.log(`Current version: v${currentVersion}`);
@@ -16,25 +33,26 @@ async function handleUpdateCommand() {
16
33
  console.error("Failed to check for updates. Check your internet connection.");
17
34
  process.exit(1);
18
35
  }
19
- if (!result.updateAvailable) {
36
+ const rgBefore = await checkRipgrep();
37
+ const needsRepair = !rgBefore.available;
38
+ if (!result.updateAvailable && !needsRepair) {
20
39
  console.log(`Already on the latest version (v${currentVersion}).`);
21
40
  return;
22
41
  }
23
- console.log(`Update available: v${currentVersion} → v${result.latestVersion}\n`);
24
- console.log("Installing update...\n");
25
- try {
26
- execSync("npm install -g @bike4mind/cli@latest", {
27
- stdio: "inherit",
28
- timeout: 12e4
29
- });
30
- console.log(`\nSuccessfully updated to v${result.latestVersion}.`);
31
- } catch {
32
- console.error("\nUpdate failed. Try running manually:");
33
- console.error(" npm install -g @bike4mind/cli@latest");
34
- console.error("\nIf you get permission errors, try:");
35
- console.error(" sudo npm install -g @bike4mind/cli@latest");
42
+ if (result.updateAvailable) console.log(`Update available: v${currentVersion} → v${result.latestVersion}`);
43
+ if (needsRepair) console.log(`Repairing missing ripgrep binary (${rgBefore.error ?? "unknown reason"})`);
44
+ console.log("\nInstalling...\n");
45
+ if (!runGlobalInstall()) process.exit(1);
46
+ const rgAfter = await checkRipgrep();
47
+ if (!rgAfter.available) {
48
+ console.error("\nWarning: ripgrep is still unavailable after install.");
49
+ console.error(` ${rgAfter.error ?? "unknown reason"}`);
50
+ console.error("The grep_search tool will not work. Try a forced reinstall:");
51
+ console.error(` ${INSTALL_CMD} --force`);
36
52
  process.exit(1);
37
53
  }
54
+ if (result.updateAvailable) console.log(`\nSuccessfully updated to v${result.latestVersion}.`);
55
+ else console.log("\nRipgrep restored.");
38
56
  }
39
57
  //#endregion
40
58
  export { handleUpdateCommand };
@@ -1,42 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as isPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
3
- import { execFile, execFileSync } from "child_process";
3
+ import { execFile } from "child_process";
4
4
  import { existsSync } from "fs";
5
5
  import path from "path";
6
6
  import { stat } from "fs/promises";
7
7
  import { promisify } from "util";
8
- import { createRequire } from "module";
9
- //#region ../../b4m-core/services/dist/grepSearch-DMuEcUSq.mjs
8
+ //#region ../../b4m-core/services/dist/grepSearch-BxucZWO8.mjs
10
9
  const execFileAsync = promisify(execFile);
11
- const require = createRequire(import.meta.url);
12
10
  /** Cached ripgrep binary path after first resolution */
13
11
  let cachedRgPath = null;
14
12
  /**
15
- * Get ripgrep binary path
16
- * This is an optional dependency (CLI-only), so we load it lazily.
17
- * If the binary is missing (postinstall was skipped), auto-downloads it.
13
+ * Resolve ripgrep binary path via the package's exported `rgPath`.
14
+ * `@vscode/ripgrep` is an optional dependency, so we load it lazily; in 1.18+
15
+ * the binary lives in a platform-specific sibling package and is resolved by
16
+ * the package itself — we just have to ask for it.
18
17
  */
19
- function getRipgrepPath() {
18
+ async function getRipgrepPath() {
20
19
  if (cachedRgPath) return cachedRgPath;
20
+ let rgPath;
21
21
  try {
22
- const ripgrepPath = require.resolve("@vscode/ripgrep");
23
- const ripgrepDir = path.dirname(ripgrepPath);
24
- const rgBinary = path.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
25
- if (!existsSync(rgBinary)) {
26
- const postinstallScript = path.join(ripgrepDir, "..", "lib", "postinstall.js");
27
- if (existsSync(postinstallScript)) execFileSync(process.execPath, [postinstallScript], {
28
- cwd: path.join(ripgrepDir, ".."),
29
- stdio: "pipe",
30
- timeout: 3e4
31
- });
32
- if (!existsSync(rgBinary)) throw new Error(`ripgrep binary not found at ${rgBinary}. The postinstall download may have failed. Try running: cd ${path.join(ripgrepDir, "..")} && node lib/postinstall.js`);
33
- }
34
- cachedRgPath = rgBinary;
35
- return rgBinary;
36
- } catch (error) {
37
- if (error instanceof Error && error.message.includes("ripgrep binary not found")) throw error;
38
- throw new Error("ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services");
22
+ ({rgPath} = await import("@vscode/ripgrep"));
23
+ } catch {
24
+ throw new Error("ripgrep is not available. Install the optional dependency: pnpm add @vscode/ripgrep --filter @bike4mind/services");
39
25
  }
26
+ if (!rgPath || !existsSync(rgPath)) throw new Error(`ripgrep binary not found at ${rgPath ?? "<unresolved>"}. Ensure @vscode/ripgrep platform optional dependencies are installed for ${process.platform}-${process.arch}.`);
27
+ cachedRgPath = rgPath;
28
+ return rgPath;
40
29
  }
41
30
  /**
42
31
  * Converts a glob pattern to ripgrep glob patterns
@@ -62,7 +51,7 @@ async function searchFiles(params, allowedDirectories) {
62
51
  if (error.code === "ENOENT") throw new Error(`Path does not exist: ${dir_path}`);
63
52
  throw error;
64
53
  }
65
- const rgPath = getRipgrepPath();
54
+ const rgPath = await getRipgrepPath();
66
55
  const rgArgs = [
67
56
  "--json",
68
57
  "--max-count",
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-DLduYYGR.mjs";
3
- import { $ as CommandHistoryStore, A as formatStep, B as DEFAULT_RETRY_CONFIG, C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, G as OllamaBackend, H as clearFeatureModuleTools, I as generateCliTools, J as buildSkillsPromptSection, K as getPlanModeFilePath, L as ALWAYS_DENIED_FOR_AGENTS, M as loadContextFiles, N as getApiUrl, O as McpManager, P as getEnvironmentName, Q as CheckpointStore, R as DEFAULT_AGENT_MODEL, S as ApiClient, T as FallbackLlmBackend, U as registerFeatureModuleTools, V as DEFAULT_THOROUGHNESS, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, a as createBlockerTools, at as mergeCommands, b as createSkillTool, c as createDecisionStore, ct as warmFileCache, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, i as createBlockerStore, it as searchCommands, j as extractCompactInstructions, k as substituteArguments, l as formatDecisionsOutput, m as createCoordinateTaskTool, n as createReviewGateTool, nt as hasFileReferences, o as formatBlockersOutput, ot as formatFileSize, p as createWriteTodosTool, q as buildSystemPrompt, r as formatReviewGatesOutput, rt as processFileReferences, s as createDecisionLogTool, st as searchFiles, t as createReviewGateStore, tt as OAuthClient, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, x as parseAgentConfig, y as SubagentOrchestrator, z as DEFAULT_MAX_ITERATIONS } from "./tools-ICW0xW8W.mjs";
4
- import { Nt as validateJupyterKernelName, Pt as validateNotebookPath$1, g as ChatModels, m as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore } from "./ConfigStore-CAKSUXCi.mjs";
5
- import { a as version, t as checkForUpdate } from "./updateChecker-Dproz7j-.mjs";
2
+ import { $ as CommandHistoryStore, A as formatStep, B as DEFAULT_RETRY_CONFIG, C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, G as OllamaBackend, H as clearFeatureModuleTools, I as generateCliTools, J as buildSkillsPromptSection, K as getPlanModeFilePath, L as ALWAYS_DENIED_FOR_AGENTS, M as loadContextFiles, N as getApiUrl, O as McpManager, P as getEnvironmentName, Q as CheckpointStore, R as DEFAULT_AGENT_MODEL, S as ApiClient, T as FallbackLlmBackend, U as registerFeatureModuleTools, V as DEFAULT_THOROUGHNESS, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, a as createBlockerTools, at as mergeCommands, b as createSkillTool, c as createDecisionStore, ct as warmFileCache, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, i as createBlockerStore, it as searchCommands, j as extractCompactInstructions, k as substituteArguments, l as formatDecisionsOutput, m as createCoordinateTaskTool, n as createReviewGateTool, nt as hasFileReferences, o as formatBlockersOutput, ot as formatFileSize, p as createWriteTodosTool, q as buildSystemPrompt, r as formatReviewGatesOutput, rt as processFileReferences, s as createDecisionLogTool, st as searchFiles, t as createReviewGateStore, tt as OAuthClient, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, x as parseAgentConfig, y as SubagentOrchestrator, z as DEFAULT_MAX_ITERATIONS } from "./tools-CpWE3Qif.mjs";
3
+ import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-BonrwrMi.mjs";
4
+ import { Xt as validateNotebookPath$1, Yt as validateJupyterKernelName, g as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore, v as ChatModels } from "./ConfigStore-BauEpjvT.mjs";
5
+ import { a as version, t as checkForUpdate } from "./updateChecker-DhWcEKAu.mjs";
6
6
  import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
7
7
  import { Box, Static, Text, render, useApp, useInput, usePaste, useStdout } from "ink";
8
8
  import { execSync } from "child_process";
@@ -2078,8 +2078,7 @@ const MessageItem = React.memo(function MessageItem({ message, showThoughts = tr
2078
2078
  const paddedUserPromptText = userPromptText.length >= terminalCols ? userPromptText : userPromptText.padEnd(terminalCols);
2079
2079
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, isUser && message.content && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, {
2080
2080
  backgroundColor: "whiteBright",
2081
- color: "black",
2082
- wrap: "truncate-end"
2081
+ color: "black"
2083
2082
  }, paddedUserPromptText)), !isUser && message.metadata?.steps && message.metadata.steps.filter((s) => showThoughts && s.type === "thought" || s.type === "action").length > 0 && /* @__PURE__ */ React.createElement(Box, {
2084
2083
  paddingLeft: 2,
2085
2084
  flexDirection: "column",
@@ -5442,6 +5441,67 @@ function summarizeUserQuestion(payload) {
5442
5441
  const first = payload.questions?.[0]?.question;
5443
5442
  return first ? first.slice(0, 240) : void 0;
5444
5443
  }
5444
+ /**
5445
+ * Render the B4M ASCII banner with an optional startup log column to the right.
5446
+ * Used on startup and after /clear so the user always sees the banner at the
5447
+ * top of a fresh session.
5448
+ */
5449
+ function renderBanner(startupLog = []) {
5450
+ const bannerLines = [
5451
+ {
5452
+ text: "██████╗ ██╗ ██╗███╗ ███╗",
5453
+ ansi: "\x1B[36m\x1B[1m"
5454
+ },
5455
+ {
5456
+ text: "██╔══██╗██║ ██║████╗ ████║",
5457
+ ansi: "\x1B[36m\x1B[1m"
5458
+ },
5459
+ {
5460
+ text: "██████╔╝███████║██╔████╔██║",
5461
+ ansi: "\x1B[36m\x1B[1m"
5462
+ },
5463
+ {
5464
+ text: "██╔══██╗╚════██║██║╚██╔╝██║",
5465
+ ansi: "\x1B[36m\x1B[1m"
5466
+ },
5467
+ {
5468
+ text: "██████╔╝ ██║██║ ╚═╝ ██║",
5469
+ ansi: "\x1B[36m\x1B[1m"
5470
+ },
5471
+ {
5472
+ text: "╚═════╝ ╚═╝╚═╝ ╚═╝",
5473
+ ansi: "\x1B[36m\x1B[1m"
5474
+ },
5475
+ {
5476
+ text: "",
5477
+ ansi: ""
5478
+ },
5479
+ {
5480
+ text: `v${version} - AI-Powered CLI`,
5481
+ ansi: "\x1B[2m"
5482
+ },
5483
+ {
5484
+ text: "/help for more information",
5485
+ ansi: "\x1B[2m"
5486
+ }
5487
+ ];
5488
+ const bannerWidth = 30;
5489
+ const rightColWidth = (process.stdout.columns || 80) - bannerWidth - 2;
5490
+ const truncate = (str, max) => {
5491
+ if (str.length > max) return str.slice(0, max - 1) + "…";
5492
+ return str;
5493
+ };
5494
+ const totalLines = Math.max(bannerLines.length, startupLog.length);
5495
+ for (let i = 0; i < totalLines; i++) {
5496
+ const banner = bannerLines[i];
5497
+ const leftText = banner?.text || "";
5498
+ const leftAnsi = banner?.ansi || "";
5499
+ const right = startupLog[i] || "";
5500
+ const coloredLeft = leftText ? `${leftAnsi}${leftText}\x1b[0m` : "";
5501
+ const gap = " ".repeat(bannerWidth - leftText.length + 2);
5502
+ console.log(coloredLeft + gap + truncate(right, rightColWidth));
5503
+ }
5504
+ }
5445
5505
  let exitTimestamp = null;
5446
5506
  let exitInProgress = false;
5447
5507
  const EXIT_TIMEOUT_MS = 2e3;
@@ -5794,11 +5854,11 @@ function CliApp() {
5794
5854
  };
5795
5855
  const permissionManager = new PermissionManager(config.trustedTools || [], void 0, config.tools.disabled || []);
5796
5856
  const [{ createSandboxRuntime }, { SandboxOrchestrator }, { DEFAULT_SANDBOX_CONFIG }, { ProxyManager }, { ViolationLogStore }] = await Promise.all([
5797
- import("./SandboxRuntimeAdapter-D7UAG13n.mjs"),
5798
- import("./SandboxOrchestrator-CHZgSR3P.mjs"),
5857
+ import("./SandboxRuntimeAdapter-DXa3nFOw.mjs"),
5858
+ import("./SandboxOrchestrator-C4oDqltp.mjs"),
5799
5859
  import("./types-DK3P88Px.mjs"),
5800
- import("./ProxyManager-kiOD1X8-.mjs"),
5801
- import("./ViolationLogStore-CZl35HcA.mjs")
5860
+ import("./ProxyManager-DIAAw902.mjs"),
5861
+ import("./ViolationLogStore-Dp6HF0nz.mjs")
5802
5862
  ]);
5803
5863
  const sandboxConfig = config.sandbox ?? DEFAULT_SANDBOX_CONFIG;
5804
5864
  const checkpointStore = new CheckpointStore(state.configStore.getProjectConfigDir() || process.cwd());
@@ -6170,60 +6230,7 @@ function CliApp() {
6170
6230
  featureRegistry
6171
6231
  }));
6172
6232
  setStoreSession(newSession);
6173
- const bannerLines = [
6174
- {
6175
- text: "██████╗ ██╗ ██╗███╗ ███╗",
6176
- ansi: "\x1B[36m\x1B[1m"
6177
- },
6178
- {
6179
- text: "██╔══██╗██║ ██║████╗ ████║",
6180
- ansi: "\x1B[36m\x1B[1m"
6181
- },
6182
- {
6183
- text: "██████╔╝███████║██╔████╔██║",
6184
- ansi: "\x1B[36m\x1B[1m"
6185
- },
6186
- {
6187
- text: "██╔══██╗╚════██║██║╚██╔╝██║",
6188
- ansi: "\x1B[36m\x1B[1m"
6189
- },
6190
- {
6191
- text: "██████╔╝ ██║██║ ╚═╝ ██║",
6192
- ansi: "\x1B[36m\x1B[1m"
6193
- },
6194
- {
6195
- text: "╚═════╝ ╚═╝╚═╝ ╚═╝",
6196
- ansi: "\x1B[36m\x1B[1m"
6197
- },
6198
- {
6199
- text: "",
6200
- ansi: ""
6201
- },
6202
- {
6203
- text: `v${version} - AI-Powered CLI`,
6204
- ansi: "\x1B[2m"
6205
- },
6206
- {
6207
- text: "/help for more information",
6208
- ansi: "\x1B[2m"
6209
- }
6210
- ];
6211
- const bannerWidth = 30;
6212
- const rightColWidth = (process.stdout.columns || 80) - bannerWidth - 2;
6213
- const truncate = (str, max) => {
6214
- if (str.length > max) return str.slice(0, max - 1) + "…";
6215
- return str;
6216
- };
6217
- const totalLines = Math.max(bannerLines.length, startupLog.length);
6218
- for (let i = 0; i < totalLines; i++) {
6219
- const banner = bannerLines[i];
6220
- const leftText = banner?.text || "";
6221
- const leftAnsi = banner?.ansi || "";
6222
- const right = startupLog[i] || "";
6223
- const coloredLeft = leftText ? `${leftAnsi}${leftText}\x1b[0m` : "";
6224
- const gap = " ".repeat(bannerWidth - leftText.length + 2);
6225
- console.log(coloredLeft + gap + truncate(right, rightColWidth));
6226
- }
6233
+ renderBanner(startupLog);
6227
6234
  setIsInitialized(true);
6228
6235
  console.log("");
6229
6236
  } catch (error) {
@@ -6868,7 +6875,7 @@ function CliApp() {
6868
6875
  let imageStore = state.imageStore;
6869
6876
  if (!imageStore) {
6870
6877
  if (!imageStoreInitPromise.current) imageStoreInitPromise.current = (async () => {
6871
- const { ImageStore: ImageStoreClass } = await import("./ImageStore-DaKT_Ew8.mjs");
6878
+ const { ImageStore: ImageStoreClass } = await import("./ImageStore-BFp_d12J.mjs");
6872
6879
  const newImageStore = new ImageStoreClass();
6873
6880
  setState((prev) => ({
6874
6881
  ...prev,
@@ -7475,6 +7482,7 @@ Multi-line Input:
7475
7482
  case "clear":
7476
7483
  case "new": {
7477
7484
  console.clear();
7485
+ renderBanner();
7478
7486
  const model = state.session?.model || state.config?.defaultModel || ChatModels.CLAUDE_4_5_SONNET;
7479
7487
  const newSession = {
7480
7488
  id: v4(),
@@ -8146,7 +8154,7 @@ Multi-line Input:
8146
8154
  break;
8147
8155
  }
8148
8156
  case "terminal-setup": {
8149
- const { runTerminalSetup } = await import("./terminalSetup-rmr1P8KF.mjs");
8157
+ const { runTerminalSetup } = await import("./terminalSetup-DxloCowq.mjs");
8150
8158
  await runTerminalSetup();
8151
8159
  break;
8152
8160
  }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { access, constants } from "fs/promises";
3
+ //#region src/utils/ripgrepCheck.ts
4
+ /**
5
+ * Probe `@vscode/ripgrep` the same way `grep_search` does: dynamic-import the
6
+ * package, take its exported `rgPath`, and verify it's executable on disk.
7
+ * The package is an optional dependency, so any failure mode (missing package,
8
+ * missing platform sibling, missing binary) is reported as `available: false`.
9
+ */
10
+ async function checkRipgrep() {
11
+ let rgPath;
12
+ try {
13
+ ({rgPath} = await import("@vscode/ripgrep"));
14
+ } catch (err) {
15
+ return {
16
+ available: false,
17
+ error: err instanceof Error ? err.message : String(err)
18
+ };
19
+ }
20
+ if (!rgPath) return {
21
+ available: false,
22
+ error: "@vscode/ripgrep did not export rgPath"
23
+ };
24
+ try {
25
+ await access(rgPath, constants.X_OK);
26
+ return {
27
+ available: true,
28
+ path: rgPath
29
+ };
30
+ } catch {
31
+ return {
32
+ available: false,
33
+ path: rgPath,
34
+ error: `binary not executable at ${rgPath}`
35
+ };
36
+ }
37
+ }
38
+ //#endregion
39
+ export { checkRipgrep as t };
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { n as useCliStore } from "./store-BonrwrMi.mjs";
3
+ export { useCliStore };