@bike4mind/cli 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AgentHistoryStore-O2gKB5YG.mjs → AgentHistoryStore-BWko6txx.mjs} +6041 -5674
- package/dist/{ConfigStore-RHqyXcSS.mjs → ConfigStore-v0wgf0_j.mjs} +594 -306
- package/dist/{WorkItemsClient-cmw7WYBy.mjs → WorkItemsClient-BZL44N12.mjs} +1 -1
- package/dist/{buildAgent-C0jmyDL4.mjs → buildAgent-BZnmDQIr.mjs} +14 -206
- package/dist/commands/acpCommand.mjs +13 -9
- package/dist/commands/apiCommand.mjs +1 -1
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +16 -15
- package/dist/commands/mcpCommand.mjs +3 -3
- package/dist/commands/pluginCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/{dist-B1bGf-yn.mjs → dist-5DDaX8tB.mjs} +2 -2
- package/dist/index.mjs +21 -15
- package/dist/{package-DsG8Tgvs.mjs → package-COr17yKT.mjs} +1 -1
- package/dist/{serve-CAfCQose.mjs → serve-D6Eu3oXv.mjs} +2 -2
- package/package.json +10 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { Mt as tokenEstimateMultiplier } from "./ConfigStore-v0wgf0_j.mjs";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
4
|
import { get_encoding } from "tiktoken";
|
|
5
5
|
//#region ../../b4m-core/utils/dist/calibratedTokenizer.mjs
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { F as generateCliTools, G as setWebSocketToolExecutor, J as DeferredToolRegistry, U as wrapTools, V as buildSystemPrompt, Y as ReActAgent, a as loadProjectContext, c as createSseBackend, i as buildProjectAgentStore, l as ServerLlmBackend, n as BackgroundAgentManager, o as McpManager, q as getPlanModeFilePath, r as SubagentOrchestrator, t as AgentHistoryStore, ut as Logger } from "./AgentHistoryStore-BWko6txx.mjs";
|
|
3
|
+
import { $ as PermissionDeniedError, At as stripToolArtifactMarkup, F as CONTEXT_WINDOW_SAFETY_BUFFER_TOKENS, J as ModelBackend, K as MODEL_INFO_FIELD_GROUP_OF, L as ChatModels, O as ARTIFACT_DELIVERED_PLACEHOLDER, R as CompletionReasoningEffortSchema, _t as hasDeliverablePinnedArtifact, dt as escapeThinkMarkers, ft as filterToolArtifactMarkup, ht as getQuestErrorCode, k as ARTIFACT_REMOVED_PLACEHOLDER, kt as stripDeliveredArtifactBlocks, ut as createThinkMarkerEscaper, xt as isUserInitiatedAbort, y as logger } from "./ConfigStore-v0wgf0_j.mjs";
|
|
4
4
|
import "crypto";
|
|
5
5
|
import { v4 } from "uuid";
|
|
6
|
-
import { z as z$1 } from "zod";
|
|
7
6
|
import "axios";
|
|
8
7
|
import "@aws-sdk/client-bedrock-runtime";
|
|
9
8
|
import "openai";
|
|
@@ -394,12 +393,17 @@ var AnthropicCachingAdapter = class {
|
|
|
394
393
|
}
|
|
395
394
|
}
|
|
396
395
|
const tools = modifiedParams.tools;
|
|
397
|
-
|
|
396
|
+
const markIndex = Array.isArray(tools) ? tools.findLastIndex((t) => {
|
|
397
|
+
const tool = t;
|
|
398
|
+
const isServerTool = typeof tool.type === "string" && !("input_schema" in tool);
|
|
399
|
+
return tool.defer_loading !== true && !isServerTool;
|
|
400
|
+
}) : -1;
|
|
401
|
+
if (strategy.cacheTools && Array.isArray(tools) && markIndex >= 0) {
|
|
398
402
|
const toolsCopy = [...tools];
|
|
399
|
-
const
|
|
400
|
-
if (claim("tools", hasMarker(
|
|
401
|
-
toolsCopy[
|
|
402
|
-
...
|
|
403
|
+
const markTool = toolsCopy[markIndex];
|
|
404
|
+
if (claim("tools", hasMarker(markTool))) {
|
|
405
|
+
toolsCopy[markIndex] = {
|
|
406
|
+
...markTool,
|
|
403
407
|
cache_control: cacheControl
|
|
404
408
|
};
|
|
405
409
|
modifiedParams.tools = toolsCopy;
|
|
@@ -1430,203 +1434,7 @@ var NotifyingLlmBackend = class {
|
|
|
1430
1434
|
};
|
|
1431
1435
|
//#endregion
|
|
1432
1436
|
//#region src/tools/deferredToolRegistry.ts
|
|
1433
|
-
|
|
1434
|
-
* Registry of tool schemas that are NOT loaded into the model's initial tool
|
|
1435
|
-
* list. The model sees only the names (via the system prompt directory) and
|
|
1436
|
-
* must call the `tool_search` meta-tool to load schemas on demand.
|
|
1437
|
-
*
|
|
1438
|
-
* This mirrors Claude Code's deferred-tool pattern. The win is large for
|
|
1439
|
-
* heavy MCP integrations (e.g. 41 GitHub MCP tools at ~250-350 tokens of
|
|
1440
|
-
* JSONSchema each = ~10-15k tokens per turn that's now ~1-1.5k of names).
|
|
1441
|
-
*/
|
|
1442
|
-
var DeferredToolRegistry = class {
|
|
1443
|
-
constructor() {
|
|
1444
|
-
this.byName = /* @__PURE__ */ new Map();
|
|
1445
|
-
this.directoryNames = [];
|
|
1446
|
-
}
|
|
1447
|
-
/** Replace registry contents with the supplied tools. Idempotent. */
|
|
1448
|
-
register(tools) {
|
|
1449
|
-
this.byName.clear();
|
|
1450
|
-
for (const tool of tools) this.byName.set(tool.toolSchema.name, tool);
|
|
1451
|
-
this.directoryNames = Object.freeze([...this.byName.keys()].sort());
|
|
1452
|
-
logger.debug(`[DeferredToolRegistry] Registered ${tools.length} deferred tool(s)`);
|
|
1453
|
-
}
|
|
1454
|
-
clear() {
|
|
1455
|
-
this.byName.clear();
|
|
1456
|
-
this.directoryNames = Object.freeze([]);
|
|
1457
|
-
}
|
|
1458
|
-
size() {
|
|
1459
|
-
return this.byName.size;
|
|
1460
|
-
}
|
|
1461
|
-
has(name) {
|
|
1462
|
-
return this.byName.has(name);
|
|
1463
|
-
}
|
|
1464
|
-
get(name) {
|
|
1465
|
-
return this.byName.get(name);
|
|
1466
|
-
}
|
|
1467
|
-
getAll() {
|
|
1468
|
-
return Array.from(this.byName.values());
|
|
1469
|
-
}
|
|
1470
|
-
/** Return tools whose names appear in the supplied list, in input order. */
|
|
1471
|
-
getByNames(names) {
|
|
1472
|
-
const found = [];
|
|
1473
|
-
for (const name of names) {
|
|
1474
|
-
const tool = this.byName.get(name);
|
|
1475
|
-
if (tool) found.push(tool);
|
|
1476
|
-
}
|
|
1477
|
-
return found;
|
|
1478
|
-
}
|
|
1479
|
-
/**
|
|
1480
|
-
* Rank-search deferred tools by query terms. Name matches outrank
|
|
1481
|
-
* description matches; exact substring on name wins ties.
|
|
1482
|
-
*/
|
|
1483
|
-
searchByKeywords(query, maxResults) {
|
|
1484
|
-
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
1485
|
-
if (terms.length === 0) return [];
|
|
1486
|
-
const scored = [];
|
|
1487
|
-
for (const tool of this.byName.values()) {
|
|
1488
|
-
const name = tool.toolSchema.name.toLowerCase();
|
|
1489
|
-
const desc = (tool.toolSchema.description || "").toLowerCase();
|
|
1490
|
-
let score = 0;
|
|
1491
|
-
for (const term of terms) {
|
|
1492
|
-
if (name.includes(term)) score += 10;
|
|
1493
|
-
if (desc.includes(term)) score += 1;
|
|
1494
|
-
}
|
|
1495
|
-
if (score > 0) scored.push({
|
|
1496
|
-
tool,
|
|
1497
|
-
score
|
|
1498
|
-
});
|
|
1499
|
-
}
|
|
1500
|
-
scored.sort((a, b) => b.score - a.score);
|
|
1501
|
-
return scored.slice(0, maxResults).map((s) => s.tool);
|
|
1502
|
-
}
|
|
1503
|
-
/**
|
|
1504
|
-
* Directory entries rendered into the cache-stamped system-prompt reminder.
|
|
1505
|
-
* Returns the frozen snapshot captured at `register()`, NOT live `byName`
|
|
1506
|
-
* keys, so loading a tool mid-session can never change a byte of the cached
|
|
1507
|
-
* system block (issue #213). A loaded tool remaining listed here is
|
|
1508
|
-
* harmless: re-selecting it via `tool_search` is an idempotent no-op.
|
|
1509
|
-
*/
|
|
1510
|
-
getDirectoryNames() {
|
|
1511
|
-
return [...this.directoryNames];
|
|
1512
|
-
}
|
|
1513
|
-
};
|
|
1514
|
-
const deferredToolRegistry = new DeferredToolRegistry();
|
|
1515
|
-
//#endregion
|
|
1516
|
-
//#region src/tools/toolSearchTool.ts
|
|
1517
|
-
/**
|
|
1518
|
-
* Default number of tools returned for a keyword search. Matches Claude
|
|
1519
|
-
* Code's ToolSearch convention. 5 keeps the response payload small while
|
|
1520
|
-
* surfacing enough alternatives for the model to refine its query.
|
|
1521
|
-
*/
|
|
1522
|
-
const DEFAULT_MAX_RESULTS = 5;
|
|
1523
|
-
/**
|
|
1524
|
-
* Runtime validation for tool_search params. The LLM produces these
|
|
1525
|
-
* values, so we validate at this boundary rather than trusting the
|
|
1526
|
-
* shape. Coerces `max_results` from string->number for models that emit
|
|
1527
|
-
* numeric-looking strings.
|
|
1528
|
-
*/
|
|
1529
|
-
const ToolSearchParamsSchema = z$1.object({
|
|
1530
|
-
query: z$1.string().min(1, "query must be a non-empty string"),
|
|
1531
|
-
max_results: z$1.coerce.number().int().min(1).max(20).optional()
|
|
1532
|
-
});
|
|
1533
|
-
/**
|
|
1534
|
-
* Parse the query string. Two forms:
|
|
1535
|
-
* - `select:name1,name2,...` - exact-name selection
|
|
1536
|
-
* - free text - keyword search across name + description
|
|
1537
|
-
*/
|
|
1538
|
-
function parseQuery(query) {
|
|
1539
|
-
const trimmed = query.trim();
|
|
1540
|
-
const selectMatch = trimmed.match(/^select:(.+)$/i);
|
|
1541
|
-
if (selectMatch) return {
|
|
1542
|
-
mode: "select",
|
|
1543
|
-
names: selectMatch[1].split(",").map((n) => n.trim()).filter((n) => n.length > 0)
|
|
1544
|
-
};
|
|
1545
|
-
return {
|
|
1546
|
-
mode: "search",
|
|
1547
|
-
text: trimmed
|
|
1548
|
-
};
|
|
1549
|
-
}
|
|
1550
|
-
/**
|
|
1551
|
-
* Format the loaded-tools response. Mirrors Claude Code's convention:
|
|
1552
|
-
* one <function>{...}</function> line per matched tool. The model has
|
|
1553
|
-
* already seen this format in its tool-registration system messages, so
|
|
1554
|
-
* it parses without additional explanation.
|
|
1555
|
-
*
|
|
1556
|
-
* Note: the schemas are *also* injected into context.tools by the caller,
|
|
1557
|
-
* so on the next iteration the model gets them as native tool definitions.
|
|
1558
|
-
* The text response here is for in-turn awareness and audit trail.
|
|
1559
|
-
*/
|
|
1560
|
-
function renderToolsBlock(tools) {
|
|
1561
|
-
if (tools.length === 0) return "";
|
|
1562
|
-
return `<functions>\n${tools.map((tool) => {
|
|
1563
|
-
const schema = {
|
|
1564
|
-
description: tool.toolSchema.description,
|
|
1565
|
-
name: tool.toolSchema.name,
|
|
1566
|
-
parameters: tool.toolSchema.parameters
|
|
1567
|
-
};
|
|
1568
|
-
return `<function>${JSON.stringify(schema)}</function>`;
|
|
1569
|
-
}).join("\n")}\n</functions>`;
|
|
1570
|
-
}
|
|
1571
|
-
/**
|
|
1572
|
-
* Build the tool_search meta-tool. The returned tool has a closure over
|
|
1573
|
-
* the supplied `toolListAccessor`, which it uses to push newly-resolved
|
|
1574
|
-
* tool schemas into the live agent context.
|
|
1575
|
-
*
|
|
1576
|
-
* Idempotent: re-loading a tool that's already in the context is a no-op.
|
|
1577
|
-
*/
|
|
1578
|
-
function createToolSearchTool(toolListAccessor) {
|
|
1579
|
-
return {
|
|
1580
|
-
toolSchema: {
|
|
1581
|
-
name: "tool_search",
|
|
1582
|
-
description: "Fetches full schema definitions for deferred tools so they can be called. Deferred tools appear by name only in a system reminder; their parameter schemas are NOT loaded by default. Use this tool to load schemas on demand. Query forms: 'select:name1,name2' for exact selection, or free-text keywords to search by name and description. Once a tool's schema is returned, it becomes callable in subsequent turns.",
|
|
1583
|
-
parameters: {
|
|
1584
|
-
type: "object",
|
|
1585
|
-
properties: {
|
|
1586
|
-
query: {
|
|
1587
|
-
type: "string",
|
|
1588
|
-
description: "Either 'select:<comma-separated names>' to fetch specific tools, or free-text keywords (e.g. 'github pull request') to rank-search deferred tools."
|
|
1589
|
-
},
|
|
1590
|
-
max_results: {
|
|
1591
|
-
type: "number",
|
|
1592
|
-
description: `Maximum number of tools to return for keyword search. Defaults to ${DEFAULT_MAX_RESULTS}. Ignored for 'select:' queries.`
|
|
1593
|
-
}
|
|
1594
|
-
},
|
|
1595
|
-
required: ["query"]
|
|
1596
|
-
}
|
|
1597
|
-
},
|
|
1598
|
-
toolFn: async (params) => {
|
|
1599
|
-
const parsedParams = ToolSearchParamsSchema.safeParse(params ?? {});
|
|
1600
|
-
if (!parsedParams.success) {
|
|
1601
|
-
const issue = parsedParams.error.issues[0];
|
|
1602
|
-
return `tool_search: invalid parameters — ${issue.path.join(".") || "params"}: ${issue.message}`;
|
|
1603
|
-
}
|
|
1604
|
-
const { query, max_results } = parsedParams.data;
|
|
1605
|
-
const parsed = parseQuery(query);
|
|
1606
|
-
let matched;
|
|
1607
|
-
let unmatched = [];
|
|
1608
|
-
if (parsed.mode === "select") {
|
|
1609
|
-
matched = deferredToolRegistry.getByNames(parsed.names);
|
|
1610
|
-
const foundNames = new Set(matched.map((t) => t.toolSchema.name));
|
|
1611
|
-
unmatched = parsed.names.filter((n) => !foundNames.has(n));
|
|
1612
|
-
} else {
|
|
1613
|
-
const max = max_results ?? DEFAULT_MAX_RESULTS;
|
|
1614
|
-
matched = deferredToolRegistry.searchByKeywords(parsed.text, max);
|
|
1615
|
-
}
|
|
1616
|
-
if (matched.length === 0) return parsed.mode === "select" ? `tool_search: no deferred tools matched ${parsed.names.join(", ")}. Use a free-text query to search.` : `tool_search: no deferred tools matched query "${parsed.text}".`;
|
|
1617
|
-
const liveTools = toolListAccessor();
|
|
1618
|
-
const liveNames = new Set(liveTools.map((t) => t.toolSchema.name));
|
|
1619
|
-
let added = 0;
|
|
1620
|
-
for (const tool of matched) if (!liveNames.has(tool.toolSchema.name)) {
|
|
1621
|
-
liveTools.push(tool);
|
|
1622
|
-
added++;
|
|
1623
|
-
}
|
|
1624
|
-
logger.debug(`[tool_search] query="${query}" matched=${matched.length} added=${added} alreadyLoaded=${matched.length - added}`);
|
|
1625
|
-
const block = renderToolsBlock(matched);
|
|
1626
|
-
return `${`Loaded ${added} new tool schema(s)${added < matched.length ? ` (${matched.length - added} already loaded)` : ""}. These are now callable in your next message.${unmatched.length > 0 ? `\n\nNot found: ${unmatched.join(", ")}` : ""}`}\n\n${block}`;
|
|
1627
|
-
}
|
|
1628
|
-
};
|
|
1629
|
-
}
|
|
1437
|
+
const deferredToolRegistry = new DeferredToolRegistry({ logger });
|
|
1630
1438
|
//#endregion
|
|
1631
1439
|
//#region src/llm/MultiLlmBackend.ts
|
|
1632
1440
|
/**
|
|
@@ -2166,4 +1974,4 @@ function buildAgent(input) {
|
|
|
2166
1974
|
};
|
|
2167
1975
|
}
|
|
2168
1976
|
//#endregion
|
|
2169
|
-
export {
|
|
1977
|
+
export { NotifyingLlmBackend as a, deferredToolRegistry as i, buildSupportingStores as n, buildLlmBackend as r, buildAgent as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as createAgentDelegateTool, C as createTodoStore, D as createCoordinateTaskTool,
|
|
3
|
-
import {
|
|
4
|
-
import { a as
|
|
5
|
-
import { a as ApiClient } from "../dist-
|
|
2
|
+
import { $ as CustomCommandStore, A as createAgentDelegateTool, C as createTodoStore, D as createCoordinateTaskTool, G as setWebSocketToolExecutor, N as PermissionManager, O as createResumeAgentTool, P as buildCliToolList, Q as RemoteSkillSource, S as createFindDefinitionTool, T as createSkillTool, X as createToolSearchTool, b as createGetFileStructureTool, j as FallbackLlmBackend, k as createBackgroundAgentTools, nt as CheckpointStore, rt as SessionStore, s as buildSandbox, w as createWriteTodosTool } from "../AgentHistoryStore-BWko6txx.mjs";
|
|
3
|
+
import { f as requireApiUrl, i as ToolCatalog, t as ConfigStore, y as logger } from "../ConfigStore-v0wgf0_j.mjs";
|
|
4
|
+
import { a as NotifyingLlmBackend, i as deferredToolRegistry, n as buildSupportingStores, r as buildLlmBackend, t as buildAgent } from "../buildAgent-BZnmDQIr.mjs";
|
|
5
|
+
import { a as ApiClient } from "../dist-5DDaX8tB.mjs";
|
|
6
6
|
import { randomUUID } from "crypto";
|
|
7
7
|
import { existsSync, realpathSync, statSync } from "fs";
|
|
8
8
|
import { isAbsolute } from "path";
|
|
@@ -424,7 +424,7 @@ var AcpServer = class {
|
|
|
424
424
|
result = await stack.agent.run(userText, {
|
|
425
425
|
signal: abortController.signal,
|
|
426
426
|
previousMessages: session.history,
|
|
427
|
-
isReadOnlyTool,
|
|
427
|
+
isReadOnlyTool: (toolName) => stack.permissionManager.catalog.isReadOnly(toolName),
|
|
428
428
|
maxHistoryIterations: 4
|
|
429
429
|
});
|
|
430
430
|
} catch (error) {
|
|
@@ -594,7 +594,7 @@ var AcpServer = class {
|
|
|
594
594
|
tokenGetter,
|
|
595
595
|
startupLog
|
|
596
596
|
});
|
|
597
|
-
const permissionManager = new PermissionManager(config.trustedTools ?? [],
|
|
597
|
+
const permissionManager = new PermissionManager(new ToolCatalog(), config.trustedTools ?? [], config.tools.disabled ?? []);
|
|
598
598
|
const checkpointStore = new CheckpointStore(this.configStore.getProjectConfigDir() ?? process.cwd());
|
|
599
599
|
const stackSessionId = randomUUID();
|
|
600
600
|
const { sandboxOrchestrator } = await buildSandbox({
|
|
@@ -627,9 +627,13 @@ var AcpServer = class {
|
|
|
627
627
|
const llmWithFallback = config.fallbackModels && config.fallbackModels.length > 0 ? new FallbackLlmBackend(llm, config.fallbackModels, (from, to, error) => logger.debug(`[acp] Model "${from}" failed (${error.message}); falling back to "${to}"`)) : llm;
|
|
628
628
|
const notifyingLlm = new NotifyingLlmBackend(llmWithFallback, backgroundManager);
|
|
629
629
|
const agentToolsRef = { current: null };
|
|
630
|
-
const toolSearchTool = deferredToolRegistry.size() > 0 ? createToolSearchTool(
|
|
631
|
-
|
|
632
|
-
|
|
630
|
+
const toolSearchTool = deferredToolRegistry.size() > 0 ? createToolSearchTool({
|
|
631
|
+
registry: deferredToolRegistry,
|
|
632
|
+
logger,
|
|
633
|
+
toolListAccessor: () => {
|
|
634
|
+
if (!agentToolsRef.current) throw new Error("tool_search invoked before agent context was wired");
|
|
635
|
+
return agentToolsRef.current;
|
|
636
|
+
}
|
|
633
637
|
}) : null;
|
|
634
638
|
const cliTools = this.buildCliTools({
|
|
635
639
|
config,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { p as resolveApiEndpoint, t as ConfigStore, v as parseApiUrl } from "../ConfigStore-v0wgf0_j.mjs";
|
|
3
3
|
//#region src/commands/apiCommand.ts
|
|
4
4
|
/**
|
|
5
5
|
* External API config command (--api-url / --reset-api)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as version } from "../package-
|
|
2
|
+
import { t as version } from "../package-COr17yKT.mjs";
|
|
3
3
|
import { c as isNpmPrefixWritable, i as fetchLatestVersion, r as compareSemver } from "../updateChecker-CCLVVdH0.mjs";
|
|
4
4
|
import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
|
|
5
5
|
import { existsSync } from "fs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { r as reconstructTurnBlocks, t as WorkItemsClient } from "../WorkItemsClient-
|
|
5
|
-
import { a as ApiClient } from "../dist-
|
|
2
|
+
import { $ as CustomCommandStore, A as createAgentDelegateTool, C as createTodoStore, D as createCoordinateTaskTool, F as generateCliTools, G as setWebSocketToolExecutor, K as classifyCommandRisk, N as PermissionManager, O as createResumeAgentTool, P as buildCliToolList, Q as RemoteSkillSource, S as createFindDefinitionTool, T as createSkillTool, U as wrapTools, V as buildSystemPrompt, Y as ReActAgent, a as loadProjectContext, b as createGetFileStructureTool, c as createSseBackend, i as buildProjectAgentStore, j as FallbackLlmBackend, k as createBackgroundAgentTools, n as BackgroundAgentManager, nt as CheckpointStore, o as McpManager, r as SubagentOrchestrator, rt as SessionStore, s as buildSandbox, t as AgentHistoryStore, w as createWriteTodosTool, x as createWorkItemTools } from "../AgentHistoryStore-BWko6txx.mjs";
|
|
3
|
+
import { a as commandTextOf, f as requireApiUrl, i as ToolCatalog, s as toolCategory, t as ConfigStore, y as logger } from "../ConfigStore-v0wgf0_j.mjs";
|
|
4
|
+
import { r as reconstructTurnBlocks, t as WorkItemsClient } from "../WorkItemsClient-BZL44N12.mjs";
|
|
5
|
+
import { a as ApiClient } from "../dist-5DDaX8tB.mjs";
|
|
6
6
|
import { randomBytes } from "crypto";
|
|
7
7
|
import { v4 } from "uuid";
|
|
8
8
|
import { readFile } from "fs/promises";
|
|
@@ -87,15 +87,15 @@ function parseStringArray(raw, inputType) {
|
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
89
|
* Classify the risk of a single tool invocation for the permission protocol.
|
|
90
|
-
* Shell-like tools are classified from their actual
|
|
91
|
-
* shared command-risk tokenizer
|
|
92
|
-
*
|
|
93
|
-
*
|
|
90
|
+
* Shell-like tools (a descriptor commandArg) are classified from their actual
|
|
91
|
+
* command text, reusing the shared command-risk tokenizer, exactly as the
|
|
92
|
+
* gateway's command-risk stage does; every other tool falls back to a level
|
|
93
|
+
* derived from its permission category (auto_approve -> low, prompt_always ->
|
|
94
|
+
* high, else medium). Never throws: a classifier failure fails closed at `high`.
|
|
94
95
|
*/
|
|
95
|
-
function classifyToolRisk(
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
if (typeof command === "string") try {
|
|
96
|
+
function classifyToolRisk(descriptor, args) {
|
|
97
|
+
const command = commandTextOf(descriptor, args);
|
|
98
|
+
if (command !== void 0) try {
|
|
99
99
|
return classifyCommandRisk(command);
|
|
100
100
|
} catch {
|
|
101
101
|
return {
|
|
@@ -103,6 +103,7 @@ function classifyToolRisk(toolName, args, category) {
|
|
|
103
103
|
reasons: ["command risk analysis failed (fail closed)"]
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
+
const category = toolCategory(descriptor);
|
|
106
107
|
return {
|
|
107
108
|
level: category === "auto_approve" ? "low" : category === "prompt_always" ? "high" : "medium",
|
|
108
109
|
reasons: []
|
|
@@ -319,11 +320,11 @@ async function handleHeadlessCommand(options) {
|
|
|
319
320
|
}
|
|
320
321
|
};
|
|
321
322
|
await logger.initialize(session.id);
|
|
322
|
-
const permissionManager = new PermissionManager(config.trustedTools ?? [],
|
|
323
|
+
const permissionManager = new PermissionManager(new ToolCatalog(), config.trustedTools ?? [], config.tools.disabled);
|
|
323
324
|
const emit = createHeadlessEmitter(runId, (line) => process.stdout.write(line));
|
|
324
325
|
const streaming = outputFormat === "stream-json";
|
|
325
326
|
const promptFn = (toolName, args, _preview, kind) => {
|
|
326
|
-
const risk = classifyToolRisk(
|
|
327
|
+
const risk = classifyToolRisk(permissionManager.catalog.resolve(toolName), args);
|
|
327
328
|
if (streaming) emit({
|
|
328
329
|
type: "permission_request",
|
|
329
330
|
toolName,
|
|
@@ -482,7 +483,7 @@ async function handleHeadlessCommand(options) {
|
|
|
482
483
|
try {
|
|
483
484
|
result = await agent.run(fullPrompt, {
|
|
484
485
|
parallelExecution: config.preferences.enableParallelToolExecution === true,
|
|
485
|
-
isReadOnlyTool,
|
|
486
|
+
isReadOnlyTool: (toolName) => permissionManager.catalog.isReadOnly(toolName),
|
|
486
487
|
maxHistoryIterations: 4
|
|
487
488
|
});
|
|
488
489
|
} finally {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as ConfigStore } from "../ConfigStore-
|
|
3
|
-
import { t as version } from "../package-
|
|
2
|
+
import { t as ConfigStore } from "../ConfigStore-v0wgf0_j.mjs";
|
|
3
|
+
import { t as version } from "../package-COr17yKT.mjs";
|
|
4
4
|
//#region src/commands/mcpCommand.ts
|
|
5
5
|
/**
|
|
6
6
|
* External MCP commands (b4m mcp list, b4m mcp add, etc.)
|
|
@@ -70,7 +70,7 @@ async function handleMcpCommand(subcommand, argv) {
|
|
|
70
70
|
await handleDisable(config, argv.name, configStore);
|
|
71
71
|
break;
|
|
72
72
|
case "serve": {
|
|
73
|
-
const { handleMcpServeCommand } = await import("../serve-
|
|
73
|
+
const { handleMcpServeCommand } = await import("../serve-D6Eu3oXv.mjs");
|
|
74
74
|
await handleMcpServeCommand({
|
|
75
75
|
http: Boolean(argv.http),
|
|
76
76
|
port: typeof argv.port === "number" ? argv.port : void 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as ConfigStore } from "../ConfigStore-
|
|
2
|
+
import { t as ConfigStore } from "../ConfigStore-v0wgf0_j.mjs";
|
|
3
3
|
import { n as getDefaultPluginsDir, r as isFeatureEnabled, t as PluginStore } from "../PluginStore-DwvOJ-G3.mjs";
|
|
4
4
|
import { promises } from "fs";
|
|
5
5
|
import path from "path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as version } from "../package-
|
|
2
|
+
import { t as version } from "../package-COr17yKT.mjs";
|
|
3
3
|
import { a as forceCheckForUpdate, c as isNpmPrefixWritable, d as shouldAttemptAutoUpdate, l as readCachedUpdate, n as REEXEC_GUARD_ENV, o as getAutoUpdatePreference, t as INSTALL_CMD, u as setAutoUpdatePreference } from "../updateChecker-CCLVVdH0.mjs";
|
|
4
4
|
import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
|
|
5
5
|
import { execSync, spawnSync } from "child_process";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t as version } from "./package-
|
|
2
|
+
import { h as DeviceFlowClient, m as AuthenticatedApiClient, t as ConfigStore, y as logger } from "./ConfigStore-v0wgf0_j.mjs";
|
|
3
|
+
import { t as version } from "./package-COr17yKT.mjs";
|
|
4
4
|
import { isAxiosError } from "axios";
|
|
5
5
|
import { Readable } from "node:stream";
|
|
6
6
|
import { createParser } from "eventsource-parser";
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as CustomCommandStore, A as createAgentDelegateTool, B as DEFAULT_THOROUGHNESS, C as createTodoStore, D as createCoordinateTaskTool, E as parseAgentConfig, G as setWebSocketToolExecutor, H as buildSkillsPromptSection, I as ALWAYS_DENIED_FOR_AGENTS, L as DEFAULT_AGENT_MODEL, M as substituteArguments, N as PermissionManager, O as createResumeAgentTool, P as buildCliToolList, Q as RemoteSkillSource, R as DEFAULT_MAX_ITERATIONS, S as createFindDefinitionTool, T as createSkillTool, V as buildSystemPrompt, W as getProcessHooks, X as createToolSearchTool, Z as findIterationBoundary, _ as createDecisionLogTool, at as mergeCommands, b as createGetFileStructureTool, ct as searchFiles, d as createReviewGateStore, dt as COMPACTION_SUMMARY_MARKER, et as processFileReferences, f as createReviewGateTool, g as formatBlockersOutput, h as createBlockerTools, it as searchCommands, j as FallbackLlmBackend, k as createBackgroundAgentTools, lt as warmFileCache, m as createBlockerStore, nt as CheckpointStore, ot as rewireReservedNames, p as formatReviewGatesOutput, pt as MAX_PASTE_SIZE, q as getPlanModeFilePath, rt as SessionStore, s as buildSandbox, st as formatFileSize, tt as hasFileReferences, u as isConnectionDrop, v as createDecisionStore, w as createWriteTodosTool, x as createWorkItemTools, y as formatDecisionsOutput, z as DEFAULT_RETRY_CONFIG } from "./AgentHistoryStore-BWko6txx.mjs";
|
|
3
3
|
import { a as selectLiveSubagentTokens, i as selectLiveSubagentCredits, n as selectActiveBackgroundShells, o as useCliStore, r as selectCompletedBackgroundShells, t as selectActiveBackgroundAgents } from "./store-BxmPEI3v.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { Bt as actorKindMarker, Ht as delegationPayloadSchema, I as CREDIT_DEDUCT_TRANSACTION_TYPES, L as ChatModels, Lt as ACTOR_COLOR_SLOTS, Mt as tokenEstimateMultiplier, Rt as DELEGATION_PAYLOAD_SCHEMA_NAME, Ut as selfClaimedActorKindSchema, Vt as actorKindSchema, b as SESSION_ID_PATTERN, d as getEnvironmentName, et as REVIEW_GATE_STATUS_VALUES, f as requireApiUrl, g as LOCAL_DEV_URL, i as ToolCatalog, l as ApiEndpointUnconfiguredError, n as extractCompactInstructions, p as resolveApiEndpoint, rt as SUBQUEST_STATUS_VALUES, t as ConfigStore, u as getCreditsUrl, v as parseApiUrl, vt as isEarlyStop, x as isValidSessionId, y as logger, zt as actorColorIndex } from "./ConfigStore-v0wgf0_j.mjs";
|
|
5
5
|
import { r as isFeatureEnabled, t as PluginStore } from "./PluginStore-DwvOJ-G3.mjs";
|
|
6
|
-
import { i as getTokenCounter, n as ConversationContext, r as reconstructTurnBlocks, t as WorkItemsClient } from "./WorkItemsClient-
|
|
7
|
-
import { a as
|
|
6
|
+
import { i as getTokenCounter, n as ConversationContext, r as reconstructTurnBlocks, t as WorkItemsClient } from "./WorkItemsClient-BZL44N12.mjs";
|
|
7
|
+
import { a as NotifyingLlmBackend, i as deferredToolRegistry, n as buildSupportingStores, r as buildLlmBackend, t as buildAgent } from "./buildAgent-BZnmDQIr.mjs";
|
|
8
8
|
import { t as getShellSessionManager } from "./ShellSessionManager-6o8KZzl1-vrbPAUTq.mjs";
|
|
9
|
-
import { a as ApiClient, s as OAuthClient } from "./dist-
|
|
10
|
-
import { t as version } from "./package-
|
|
9
|
+
import { a as ApiClient, s as OAuthClient } from "./dist-5DDaX8tB.mjs";
|
|
10
|
+
import { t as version } from "./package-COr17yKT.mjs";
|
|
11
11
|
import { s as getStartupUpdateStatus } from "./updateChecker-CCLVVdH0.mjs";
|
|
12
12
|
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
13
13
|
import { Box, Static, Text, measureElement, render, useApp, useInput, usePaste, useStdout } from "ink";
|
|
@@ -5768,7 +5768,7 @@ const HandoffSchema = z$1.object({
|
|
|
5768
5768
|
updatedAt: z$1.string()
|
|
5769
5769
|
});
|
|
5770
5770
|
z$1.object({
|
|
5771
|
-
|
|
5771
|
+
id: z$1.string(),
|
|
5772
5772
|
notebookId: z$1.string(),
|
|
5773
5773
|
goal: z$1.string(),
|
|
5774
5774
|
quests: z$1.array(QuestDataSchema),
|
|
@@ -8405,7 +8405,7 @@ async function runTurn(message, ctx) {
|
|
|
8405
8405
|
}
|
|
8406
8406
|
}
|
|
8407
8407
|
async function runHeldTurn(message, ctx) {
|
|
8408
|
-
const { agent, sessionStore, configStore, commandHistoryStore, customCommandStore, messageBuilder, config, availableModels, agentStore, contextContent, additionalDirectories, featureRegistry, backgroundManager, todoStore, decisionStore, blockerStore, postEditDiagnostics, workflowStores, setCommandHistory, setAbortController } = ctx;
|
|
8408
|
+
const { agent, sessionStore, configStore, commandHistoryStore, customCommandStore, messageBuilder, config, availableModels, agentStore, contextContent, additionalDirectories, featureRegistry, backgroundManager, toolCatalog, todoStore, decisionStore, blockerStore, postEditDiagnostics, workflowStores, setCommandHistory, setAbortController } = ctx;
|
|
8409
8409
|
const storeSession = useCliStore.getState().session;
|
|
8410
8410
|
if (!agent || !storeSession) {
|
|
8411
8411
|
console.error("❌ CLI failed to initialize. Try restarting b4m.\n");
|
|
@@ -8523,7 +8523,7 @@ async function runHeldTurn(message, ctx) {
|
|
|
8523
8523
|
previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
|
|
8524
8524
|
signal: abortController.signal,
|
|
8525
8525
|
parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
|
|
8526
|
-
isReadOnlyTool,
|
|
8526
|
+
isReadOnlyTool: (toolName) => toolCatalog.isReadOnly(toolName),
|
|
8527
8527
|
workflowReminder,
|
|
8528
8528
|
drainFeedback: diagnostics ? (phase) => diagnostics.drain(DRAIN_BUDGET_MS[phase], abortController.signal) : void 0,
|
|
8529
8529
|
onContextLimit: createReactiveCompactionHandler(agent, activeSession)
|
|
@@ -8957,6 +8957,7 @@ function CliApp() {
|
|
|
8957
8957
|
agent: null,
|
|
8958
8958
|
mcpManager: null,
|
|
8959
8959
|
permissionManager: null,
|
|
8960
|
+
toolCatalog: new ToolCatalog(),
|
|
8960
8961
|
permissionPrompt: null,
|
|
8961
8962
|
trustLocationSelector: null,
|
|
8962
8963
|
folderTrustPrompt: null,
|
|
@@ -9214,7 +9215,7 @@ function CliApp() {
|
|
|
9214
9215
|
error: () => {},
|
|
9215
9216
|
debug: () => {}
|
|
9216
9217
|
};
|
|
9217
|
-
const permissionManager = new PermissionManager(config.trustedTools || [],
|
|
9218
|
+
const permissionManager = new PermissionManager(state.toolCatalog, config.trustedTools || [], config.tools.disabled || []);
|
|
9218
9219
|
const checkpointProjectDir = state.configStore.getProjectConfigDir() || process.cwd();
|
|
9219
9220
|
const checkpointStore = new CheckpointStore(checkpointProjectDir);
|
|
9220
9221
|
const { sandboxOrchestrator } = await buildSandbox({
|
|
@@ -9374,9 +9375,13 @@ function CliApp() {
|
|
|
9374
9375
|
}) : null;
|
|
9375
9376
|
const workItemTools = config.preferences.enableWorkItemTools ? createWorkItemTools(new WorkItemsClient(apiClient)) : [];
|
|
9376
9377
|
const agentToolsRef = { current: null };
|
|
9377
|
-
const toolSearchTool = deferredToolRegistry.size() > 0 ? createToolSearchTool(
|
|
9378
|
-
|
|
9379
|
-
|
|
9378
|
+
const toolSearchTool = deferredToolRegistry.size() > 0 ? createToolSearchTool({
|
|
9379
|
+
registry: deferredToolRegistry,
|
|
9380
|
+
logger,
|
|
9381
|
+
toolListAccessor: () => {
|
|
9382
|
+
if (!agentToolsRef.current) throw new Error("tool_search invoked before agent context was wired");
|
|
9383
|
+
return agentToolsRef.current;
|
|
9384
|
+
}
|
|
9380
9385
|
}) : null;
|
|
9381
9386
|
const cliTools = buildCliToolList({
|
|
9382
9387
|
toolSearchTool,
|
|
@@ -9662,7 +9667,7 @@ function CliApp() {
|
|
|
9662
9667
|
previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
|
|
9663
9668
|
signal: abortController.signal,
|
|
9664
9669
|
parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
|
|
9665
|
-
isReadOnlyTool,
|
|
9670
|
+
isReadOnlyTool: (toolName) => state.toolCatalog.isReadOnly(toolName),
|
|
9666
9671
|
onContextLimit: createReactiveCompactionHandler(state.agent, session)
|
|
9667
9672
|
});
|
|
9668
9673
|
} finally {
|
|
@@ -9797,6 +9802,7 @@ function CliApp() {
|
|
|
9797
9802
|
additionalDirectories: state.additionalDirectories,
|
|
9798
9803
|
featureRegistry: state.featureRegistry,
|
|
9799
9804
|
backgroundManager: state.backgroundManager,
|
|
9805
|
+
toolCatalog: state.toolCatalog,
|
|
9800
9806
|
todoStore: todoStoreRef.current,
|
|
9801
9807
|
decisionStore: decisionStoreRef.current,
|
|
9802
9808
|
blockerStore: blockerStoreRef.current,
|
|
@@ -9864,7 +9870,7 @@ function CliApp() {
|
|
|
9864
9870
|
previousMessages: previousMessages.length > 0 ? previousMessages : void 0,
|
|
9865
9871
|
signal: abortController.signal,
|
|
9866
9872
|
parallelExecution: cliConfig.preferences.enableParallelToolExecution === true,
|
|
9867
|
-
isReadOnlyTool
|
|
9873
|
+
isReadOnlyTool: (toolName) => state.toolCatalog.isReadOnly(toolName)
|
|
9868
9874
|
});
|
|
9869
9875
|
const successfulToolCalls = result.steps.filter((s) => s.type === "observation").length;
|
|
9870
9876
|
const currentSession = useCliStore.getState().session;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { a as ApiClient, i as parseRetryAfterSeconds, o as isProviderKeyFailure, r as createClient, t as B4mApiError } from "./dist-
|
|
2
|
+
import { B as DEFAULT_TTS_PROVIDER, D as AGENT_QUEST_MCP_URI, E as AGENT_QUEST_MANIFEST, Ft as ttsResponseTooLargeSchema, H as GENERATED_IMAGE_EXTENSION_RE, M as BRIEFCASE_CATALOG_QUERIES, Nt as ttsBase64ResponseSchema, P as BriefcasePromptIdSchema, Pt as ttsRequestSchema, Q as PROMPT_TEXT_MAX, St as joinReplySlots, T as AGENT_QUEST_ID, Tt as replacePromptVariables, U as ImageModels, W as ImagePromptResolutionSchema, _ as NotAuthenticatedError, at as VisibilitySchema, f as requireApiUrl, j as ArtifactTypeSchema, jt as supportedVoiceGenerationVendor, lt as buildPromptContext, pt as generatedAudioResponseSchema, t as ConfigStore, v as parseApiUrl, wt as questReplyText, y as logger, z as CreateArtifactRequestSchema } from "./ConfigStore-v0wgf0_j.mjs";
|
|
3
|
+
import { a as ApiClient, i as parseRetryAfterSeconds, o as isProviderKeyFailure, r as createClient, t as B4mApiError } from "./dist-5DDaX8tB.mjs";
|
|
4
4
|
import { z as z$1 } from "zod";
|
|
5
5
|
import { isAxiosError } from "axios";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"mcpName": "io.github.
|
|
3
|
+
"version": "3.2.0",
|
|
4
|
+
"mcpName": "io.github.Bike4Mind/bike4mind",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
7
7
|
"license": "BUSL-1.1",
|
|
@@ -124,17 +124,17 @@
|
|
|
124
124
|
"tsx": "^4.23.0",
|
|
125
125
|
"typescript": "^5.9.3",
|
|
126
126
|
"vitest": "^4.1.11",
|
|
127
|
-
"@bike4mind/agents": "
|
|
127
|
+
"@bike4mind/agents": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
128
|
+
"@bike4mind/common": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
128
129
|
"@bike4mind/client-auth": "0.2.0",
|
|
129
|
-
"@bike4mind/
|
|
130
|
-
"@bike4mind/fab-pipeline": "2.1.1",
|
|
131
|
-
"@bike4mind/llm-adapters": "1.1.1",
|
|
130
|
+
"@bike4mind/fab-pipeline": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
132
131
|
"@bike4mind/hearth": "0.3.1",
|
|
133
|
-
"@bike4mind/mcp": "
|
|
132
|
+
"@bike4mind/mcp": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
134
133
|
"@bike4mind/observability": "0.2.3",
|
|
135
|
-
"@bike4mind/sdk": "1.0
|
|
136
|
-
"@bike4mind/
|
|
137
|
-
"@bike4mind/utils": "
|
|
134
|
+
"@bike4mind/sdk": "1.1.0",
|
|
135
|
+
"@bike4mind/llm-adapters": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
136
|
+
"@bike4mind/utils": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015",
|
|
137
|
+
"@bike4mind/services": "0.0.0-snapshot-gh-readonly-queue-main-pr-5009-e421f9aab9-20261019120015"
|
|
138
138
|
},
|
|
139
139
|
"optionalDependencies": {
|
|
140
140
|
"@vscode/ripgrep": "^1.18.0"
|