@bunny-agent/runner-cli 0.9.62 → 0.9.63-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.mjs +279 -249
- package/package.json +10 -10
package/dist/bundle.mjs
CHANGED
|
@@ -23504,14 +23504,73 @@ function approvalFileName(toolCallId) {
|
|
|
23504
23504
|
return `${stem}.json`;
|
|
23505
23505
|
}
|
|
23506
23506
|
|
|
23507
|
+
// ../../packages/manager/dist/tool-output.js
|
|
23508
|
+
import { randomBytes } from "node:crypto";
|
|
23509
|
+
import { writeFile } from "node:fs/promises";
|
|
23510
|
+
import { tmpdir } from "node:os";
|
|
23511
|
+
import { join as join2 } from "node:path";
|
|
23512
|
+
var TOOL_OUTPUT_MAX_BYTES = 50 * 1024;
|
|
23513
|
+
var TOOL_OUTPUT_MAX_LINES = 2e3;
|
|
23514
|
+
function countLines(text) {
|
|
23515
|
+
let lines = 1;
|
|
23516
|
+
for (let index = 0; index < text.length; index++) {
|
|
23517
|
+
if (text[index] === "\n")
|
|
23518
|
+
lines++;
|
|
23519
|
+
}
|
|
23520
|
+
return lines;
|
|
23521
|
+
}
|
|
23522
|
+
function previewText(text, maxBytes, maxLines) {
|
|
23523
|
+
const buffer = Buffer.from(text.slice(0, maxBytes), "utf8");
|
|
23524
|
+
let end = Math.min(buffer.length, maxBytes);
|
|
23525
|
+
while (end > 0 && end < buffer.length && (buffer[end] & 192) === 128) {
|
|
23526
|
+
end--;
|
|
23527
|
+
}
|
|
23528
|
+
const prefix = buffer.subarray(0, end).toString("utf8");
|
|
23529
|
+
let lines = 1;
|
|
23530
|
+
for (let index = 0; index < prefix.length; index++) {
|
|
23531
|
+
if (prefix[index] === "\n" && ++lines > maxLines) {
|
|
23532
|
+
return prefix.slice(0, index);
|
|
23533
|
+
}
|
|
23534
|
+
}
|
|
23535
|
+
return prefix;
|
|
23536
|
+
}
|
|
23537
|
+
async function guardToolOutput(text) {
|
|
23538
|
+
const originalBytes = Buffer.byteLength(text, "utf8");
|
|
23539
|
+
const originalLines = countLines(text);
|
|
23540
|
+
if (originalBytes <= TOOL_OUTPUT_MAX_BYTES && originalLines <= TOOL_OUTPUT_MAX_LINES) {
|
|
23541
|
+
return { text };
|
|
23542
|
+
}
|
|
23543
|
+
let fullOutputPath;
|
|
23544
|
+
try {
|
|
23545
|
+
const path3 = join2(tmpdir(), `bunny-tool-output-${randomBytes(8).toString("hex")}.txt`);
|
|
23546
|
+
await writeFile(path3, text, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
23547
|
+
fullOutputPath = path3;
|
|
23548
|
+
} catch {
|
|
23549
|
+
}
|
|
23550
|
+
const retrieval = fullOutputPath ? `Full output saved to: ${JSON.stringify(fullOutputPath)}. Use read with offset/limit or bash to extract a bounded fragment.` : "Full output could not be saved. Retry with a narrower query or fewer fields.";
|
|
23551
|
+
const notice = `
|
|
23552
|
+
|
|
23553
|
+
[Tool output truncated: original ${originalBytes} bytes / ${originalLines} lines; preview limit ${TOOL_OUTPUT_MAX_BYTES} bytes / ${TOOL_OUTPUT_MAX_LINES} lines. ${retrieval}]`;
|
|
23554
|
+
const preview = previewText(text, TOOL_OUTPUT_MAX_BYTES - Buffer.byteLength(notice, "utf8"), TOOL_OUTPUT_MAX_LINES - countLines(notice) + 1);
|
|
23555
|
+
return {
|
|
23556
|
+
text: `${preview}${notice}`,
|
|
23557
|
+
outputGuard: {
|
|
23558
|
+
truncated: true,
|
|
23559
|
+
originalBytes,
|
|
23560
|
+
originalLines,
|
|
23561
|
+
...fullOutputPath ? { fullOutputPath } : {}
|
|
23562
|
+
}
|
|
23563
|
+
};
|
|
23564
|
+
}
|
|
23565
|
+
|
|
23507
23566
|
// ../../packages/runner-claude/dist/ai-sdk-stream.js
|
|
23508
23567
|
import { appendFileSync, existsSync as existsSync2, unlinkSync } from "node:fs";
|
|
23509
|
-
import { join as
|
|
23568
|
+
import { join as join3 } from "node:path";
|
|
23510
23569
|
function trace(data, reset = false) {
|
|
23511
23570
|
if (process.env.DEBUG !== "true")
|
|
23512
23571
|
return;
|
|
23513
23572
|
try {
|
|
23514
|
-
const file3 =
|
|
23573
|
+
const file3 = join3(process.cwd(), "claude-message-stream-debug.json");
|
|
23515
23574
|
if (reset && existsSync2(file3))
|
|
23516
23575
|
unlinkSync(file3);
|
|
23517
23576
|
const entry = {
|
|
@@ -23861,22 +23920,22 @@ function streamSDKMessagesToAISDKUI(messageIterator) {
|
|
|
23861
23920
|
|
|
23862
23921
|
// ../../packages/runner-claude/dist/skill-plugin.js
|
|
23863
23922
|
import { cpSync, mkdirSync, mkdtempSync, symlinkSync, writeFileSync } from "node:fs";
|
|
23864
|
-
import { tmpdir } from "node:os";
|
|
23865
|
-
import { basename, join as
|
|
23923
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
23924
|
+
import { basename, join as join4 } from "node:path";
|
|
23866
23925
|
var PLUGIN_NAME = "bunny-agent-skills";
|
|
23867
23926
|
function createSkillPlugin(skillPaths) {
|
|
23868
23927
|
if (skillPaths.length === 0)
|
|
23869
23928
|
return void 0;
|
|
23870
23929
|
try {
|
|
23871
|
-
const pluginDir = mkdtempSync(
|
|
23872
|
-
const manifestDir =
|
|
23930
|
+
const pluginDir = mkdtempSync(join4(tmpdir2(), "bunny-claude-skills-"));
|
|
23931
|
+
const manifestDir = join4(pluginDir, ".claude-plugin");
|
|
23873
23932
|
mkdirSync(manifestDir, { recursive: true });
|
|
23874
|
-
writeFileSync(
|
|
23933
|
+
writeFileSync(join4(manifestDir, "plugin.json"), JSON.stringify({
|
|
23875
23934
|
name: PLUGIN_NAME,
|
|
23876
23935
|
version: "0.0.0",
|
|
23877
23936
|
description: "Bunny Agent skills exposed to the Claude runner"
|
|
23878
23937
|
}, null, 2));
|
|
23879
|
-
const skillsDir =
|
|
23938
|
+
const skillsDir = join4(pluginDir, "skills");
|
|
23880
23939
|
mkdirSync(skillsDir, { recursive: true });
|
|
23881
23940
|
const usedNames = /* @__PURE__ */ new Set();
|
|
23882
23941
|
for (const skillPath of skillPaths) {
|
|
@@ -23886,7 +23945,7 @@ function createSkillPlugin(skillPaths) {
|
|
|
23886
23945
|
name = `${basename(skillPath)}-${suffix++}`;
|
|
23887
23946
|
}
|
|
23888
23947
|
usedNames.add(name);
|
|
23889
|
-
const target =
|
|
23948
|
+
const target = join4(skillsDir, name);
|
|
23890
23949
|
try {
|
|
23891
23950
|
symlinkSync(skillPath, target, "dir");
|
|
23892
23951
|
} catch {
|
|
@@ -37687,13 +37746,15 @@ function buildOne(ref) {
|
|
|
37687
37746
|
response = await executeToolRef(ref, args, void 0);
|
|
37688
37747
|
} catch (error109) {
|
|
37689
37748
|
const message = error109 instanceof Error ? error109.message : String(error109);
|
|
37690
|
-
|
|
37749
|
+
const output3 = await guardToolOutput(`Tool "${ref.name}" transport error: ${message}`);
|
|
37750
|
+
return errorResult(output3.text);
|
|
37691
37751
|
}
|
|
37752
|
+
const output2 = await guardToolOutput(response.body);
|
|
37692
37753
|
if (response.status < 200 || response.status >= 300) {
|
|
37693
|
-
const body =
|
|
37754
|
+
const body = output2.text.trim();
|
|
37694
37755
|
return errorResult(body.length > 0 ? body : `Tool execution failed with status ${response.status}`);
|
|
37695
37756
|
}
|
|
37696
|
-
return { content: [{ type: "text", text:
|
|
37757
|
+
return { content: [{ type: "text", text: output2.text }] };
|
|
37697
37758
|
}
|
|
37698
37759
|
};
|
|
37699
37760
|
}
|
|
@@ -38447,7 +38508,7 @@ ${inputToCodex}`;
|
|
|
38447
38508
|
|
|
38448
38509
|
// ../../packages/runner-copilot/dist/copilot-runner.js
|
|
38449
38510
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
38450
|
-
import { join as
|
|
38511
|
+
import { join as join6 } from "node:path";
|
|
38451
38512
|
import { approveAll, CopilotClient } from "@github/copilot-sdk";
|
|
38452
38513
|
var AsyncEventQueue = class {
|
|
38453
38514
|
values = [];
|
|
@@ -38539,8 +38600,8 @@ function createFilePermissionHandler(cwd) {
|
|
|
38539
38600
|
return async (request) => {
|
|
38540
38601
|
const rawId = request.toolCallId ?? `copilot-${Date.now()}`;
|
|
38541
38602
|
const approvalId = rawId.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
38542
|
-
const approvalDir =
|
|
38543
|
-
const approvalFile =
|
|
38603
|
+
const approvalDir = join6(cwd, ".bunny-agent", "approvals");
|
|
38604
|
+
const approvalFile = join6(approvalDir, `${approvalId}.json`);
|
|
38544
38605
|
mkdirSync2(approvalDir, { recursive: true });
|
|
38545
38606
|
if (!existsSync3(approvalFile)) {
|
|
38546
38607
|
writeFileSync3(approvalFile, JSON.stringify({
|
|
@@ -38818,7 +38879,7 @@ function createCopilotRunner(options) {
|
|
|
38818
38879
|
// ../../packages/runner-acp/dist/process-runner.js
|
|
38819
38880
|
import { spawn } from "node:child_process";
|
|
38820
38881
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
38821
|
-
import { join as
|
|
38882
|
+
import { join as join7 } from "node:path";
|
|
38822
38883
|
import { Readable, Writable } from "node:stream";
|
|
38823
38884
|
var AsyncQueue2 = class {
|
|
38824
38885
|
values = [];
|
|
@@ -38902,8 +38963,8 @@ function usageMetadata(usage) {
|
|
|
38902
38963
|
async function waitForFileApproval(cwd, request) {
|
|
38903
38964
|
const rawId = request.toolCall.toolCallId ?? `acp-${Date.now()}`;
|
|
38904
38965
|
const approvalId = rawId.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
38905
|
-
const approvalDir =
|
|
38906
|
-
const approvalFile =
|
|
38966
|
+
const approvalDir = join7(cwd, ".bunny-agent", "approvals");
|
|
38967
|
+
const approvalFile = join7(approvalDir, `${approvalId}.json`);
|
|
38907
38968
|
mkdirSync3(approvalDir, { recursive: true });
|
|
38908
38969
|
if (!existsSync4(approvalFile)) {
|
|
38909
38970
|
writeFileSync4(approvalFile, JSON.stringify({
|
|
@@ -39206,7 +39267,7 @@ var mcpAdapterModule;
|
|
|
39206
39267
|
function getMcpAdapterModule() {
|
|
39207
39268
|
if (!mcpAdapterModule) {
|
|
39208
39269
|
const jiti = createJiti(import.meta.url, {
|
|
39209
|
-
fsCache:
|
|
39270
|
+
fsCache: true,
|
|
39210
39271
|
moduleCache: true
|
|
39211
39272
|
});
|
|
39212
39273
|
mcpAdapterModule = jiti("pi-mcp-adapter");
|
|
@@ -39490,15 +39551,15 @@ function createMcpExtension(config4) {
|
|
|
39490
39551
|
}
|
|
39491
39552
|
|
|
39492
39553
|
// ../../packages/runner-pi/dist/pi-runner.js
|
|
39493
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
39494
|
-
import { join as join12 } from "node:path";
|
|
39554
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync8, unlinkSync as unlinkSync7 } from "node:fs";
|
|
39555
|
+
import { isAbsolute, join as join12, resolve as resolve2 } from "node:path";
|
|
39495
39556
|
import { getBuiltinModel } from "@earendil-works/pi-ai/providers/all";
|
|
39496
|
-
import { createAgentSession,
|
|
39557
|
+
import { CONFIG_DIR_NAME, createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager as SessionManager2, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
39497
39558
|
|
|
39498
39559
|
// ../../packages/runner-pi/dist/apply-patch-shim.js
|
|
39499
39560
|
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync4, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
39500
|
-
import { tmpdir as
|
|
39501
|
-
import { join as
|
|
39561
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
39562
|
+
import { join as join8 } from "node:path";
|
|
39502
39563
|
import { fileURLToPath } from "node:url";
|
|
39503
39564
|
var SHIM_FILE = "apply_patch";
|
|
39504
39565
|
function resolveApplyPatchBin() {
|
|
@@ -39514,15 +39575,15 @@ function ensureApplyPatchShim(binPath = resolveApplyPatchBin()) {
|
|
|
39514
39575
|
}
|
|
39515
39576
|
try {
|
|
39516
39577
|
const uid = process.getuid?.() ?? 0;
|
|
39517
|
-
const shimDir =
|
|
39578
|
+
const shimDir = join8(tmpdir4(), `bunny-agent-apply-patch-${uid}`);
|
|
39518
39579
|
mkdirSync4(shimDir, { recursive: true });
|
|
39519
39580
|
const script = `#!/bin/sh
|
|
39520
39581
|
exec "${process.execPath}" "${binPath}" "$@"
|
|
39521
39582
|
`;
|
|
39522
|
-
const staging =
|
|
39583
|
+
const staging = join8(shimDir, `.${SHIM_FILE}.${process.pid}.tmp`);
|
|
39523
39584
|
writeFileSync5(staging, script);
|
|
39524
39585
|
chmodSync(staging, 493);
|
|
39525
|
-
renameSync(staging,
|
|
39586
|
+
renameSync(staging, join8(shimDir, SHIM_FILE));
|
|
39526
39587
|
return shimDir;
|
|
39527
39588
|
} catch {
|
|
39528
39589
|
return void 0;
|
|
@@ -39787,102 +39848,6 @@ function buildApplyPatchTool(cwd) {
|
|
|
39787
39848
|
};
|
|
39788
39849
|
}
|
|
39789
39850
|
|
|
39790
|
-
// ../../packages/runner-pi/dist/bunny-agent-resource-loader.js
|
|
39791
|
-
import { existsSync as existsSync7 } from "node:fs";
|
|
39792
|
-
import { homedir } from "node:os";
|
|
39793
|
-
import { isAbsolute, join as join8, resolve as resolve2 } from "node:path";
|
|
39794
|
-
import { DefaultResourceLoader, loadSkills } from "@earendil-works/pi-coding-agent";
|
|
39795
|
-
var LOG_PREFIX = "[bunny-agent:pi]";
|
|
39796
|
-
function logSkillLoad(cwd, agentDir, skillPaths, result) {
|
|
39797
|
-
const lines = [
|
|
39798
|
-
`${LOG_PREFIX} loadSkills`,
|
|
39799
|
-
` cwd: ${cwd}`,
|
|
39800
|
-
` agentDir: ${agentDir}`,
|
|
39801
|
-
` extra skillPaths (${skillPaths.length}):`
|
|
39802
|
-
];
|
|
39803
|
-
for (const raw of skillPaths) {
|
|
39804
|
-
const abs = isAbsolute(raw) ? raw : resolve2(cwd, raw);
|
|
39805
|
-
lines.push(` ${raw} -> ${abs} (exists: ${existsSync7(abs) ? "yes" : "no"})`);
|
|
39806
|
-
}
|
|
39807
|
-
lines.push(` loaded skills: ${result.skills.length}`);
|
|
39808
|
-
if (result.skills.length > 0) {
|
|
39809
|
-
lines.push(` skill names: ${result.skills.map((s) => s.name).join(", ")}`);
|
|
39810
|
-
}
|
|
39811
|
-
if (result.diagnostics.length > 0) {
|
|
39812
|
-
lines.push(` diagnostics (${result.diagnostics.length}):`);
|
|
39813
|
-
for (const d of result.diagnostics) {
|
|
39814
|
-
const pathPart = d.path !== void 0 ? ` path=${d.path}` : "";
|
|
39815
|
-
lines.push(` [${d.type}] ${d.message}${pathPart}`);
|
|
39816
|
-
}
|
|
39817
|
-
}
|
|
39818
|
-
console.error(lines.join("\n"));
|
|
39819
|
-
}
|
|
39820
|
-
var BunnyAgentResourceLoader = class {
|
|
39821
|
-
constructor(options = {}) {
|
|
39822
|
-
this.cwd = options.cwd ?? process.cwd();
|
|
39823
|
-
this.agentDir = options.agentDir ?? join8(homedir(), ".bunny", "agent");
|
|
39824
|
-
this.skillPaths = options.skillPaths ?? [];
|
|
39825
|
-
this.extraAppendPrompt = options.appendSystemPrompt;
|
|
39826
|
-
this.delegate = new DefaultResourceLoader({
|
|
39827
|
-
cwd: this.cwd,
|
|
39828
|
-
agentDir: this.agentDir,
|
|
39829
|
-
settingsManager: options.settingsManager,
|
|
39830
|
-
extensionFactories: options.extensionFactories
|
|
39831
|
-
});
|
|
39832
|
-
}
|
|
39833
|
-
async reload() {
|
|
39834
|
-
await this.delegate.reload();
|
|
39835
|
-
this.cachedSkills = void 0;
|
|
39836
|
-
}
|
|
39837
|
-
getSkills() {
|
|
39838
|
-
if (!this.cachedSkills) {
|
|
39839
|
-
this.cachedSkills = loadSkills({
|
|
39840
|
-
cwd: this.cwd,
|
|
39841
|
-
agentDir: this.agentDir,
|
|
39842
|
-
skillPaths: this.skillPaths,
|
|
39843
|
-
includeDefaults: true
|
|
39844
|
-
});
|
|
39845
|
-
if (this.skillPaths.length > 0) {
|
|
39846
|
-
logSkillLoad(this.cwd, this.agentDir, this.skillPaths, this.cachedSkills);
|
|
39847
|
-
}
|
|
39848
|
-
}
|
|
39849
|
-
return this.cachedSkills;
|
|
39850
|
-
}
|
|
39851
|
-
// Delegate all other methods
|
|
39852
|
-
getExtensions() {
|
|
39853
|
-
return this.delegate.getExtensions();
|
|
39854
|
-
}
|
|
39855
|
-
getPrompts() {
|
|
39856
|
-
return this.delegate.getPrompts();
|
|
39857
|
-
}
|
|
39858
|
-
getThemes() {
|
|
39859
|
-
return this.delegate.getThemes();
|
|
39860
|
-
}
|
|
39861
|
-
getAgentsFiles() {
|
|
39862
|
-
return this.delegate.getAgentsFiles();
|
|
39863
|
-
}
|
|
39864
|
-
getSystemPrompt() {
|
|
39865
|
-
return this.delegate.getSystemPrompt();
|
|
39866
|
-
}
|
|
39867
|
-
getSystemPromptSource() {
|
|
39868
|
-
return this.delegate.getSystemPromptSource();
|
|
39869
|
-
}
|
|
39870
|
-
getAppendSystemPromptSources() {
|
|
39871
|
-
return this.delegate.getAppendSystemPromptSources();
|
|
39872
|
-
}
|
|
39873
|
-
getAppendSystemPrompt() {
|
|
39874
|
-
const base = this.delegate.getAppendSystemPrompt();
|
|
39875
|
-
if (this.extraAppendPrompt) {
|
|
39876
|
-
console.error(`${LOG_PREFIX} getAppendSystemPrompt: appending extra prompt (${this.extraAppendPrompt.length} chars)`);
|
|
39877
|
-
return [...base, this.extraAppendPrompt];
|
|
39878
|
-
}
|
|
39879
|
-
return base;
|
|
39880
|
-
}
|
|
39881
|
-
extendResources(paths) {
|
|
39882
|
-
this.delegate.extendResources(paths);
|
|
39883
|
-
}
|
|
39884
|
-
};
|
|
39885
|
-
|
|
39886
39851
|
// ../../packages/runner-pi/dist/image-tools.js
|
|
39887
39852
|
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "node:fs";
|
|
39888
39853
|
import { dirname as dirname3, extname, join as join9 } from "node:path";
|
|
@@ -40294,7 +40259,7 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
40294
40259
|
// biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
|
|
40295
40260
|
parameters: editImageSchema,
|
|
40296
40261
|
async execute(_toolCallId, params, signal, _onUpdate) {
|
|
40297
|
-
const { readFileSync: readFileSync8, existsSync:
|
|
40262
|
+
const { readFileSync: readFileSync8, existsSync: existsSync12 } = await import("node:fs");
|
|
40298
40263
|
const { resolve: resolve5, basename: basename3 } = await import("node:path");
|
|
40299
40264
|
const p = params;
|
|
40300
40265
|
const imagePath = p.image;
|
|
@@ -40307,7 +40272,7 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
40307
40272
|
const rawFilename = p.filename;
|
|
40308
40273
|
const safePrompt = buildPolicySafeEditPrompt(prompt);
|
|
40309
40274
|
const resolvedImage = resolve5(cwd, imagePath);
|
|
40310
|
-
if (!
|
|
40275
|
+
if (!existsSync12(resolvedImage)) {
|
|
40311
40276
|
return {
|
|
40312
40277
|
content: [
|
|
40313
40278
|
{
|
|
@@ -40351,7 +40316,7 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
40351
40316
|
];
|
|
40352
40317
|
if (maskPath) {
|
|
40353
40318
|
const resolvedMask = resolve5(cwd, maskPath);
|
|
40354
|
-
if (
|
|
40319
|
+
if (existsSync12(resolvedMask)) {
|
|
40355
40320
|
files.push({
|
|
40356
40321
|
name: "mask",
|
|
40357
40322
|
filename: basename3(resolvedMask),
|
|
@@ -43568,37 +43533,37 @@ function buildAskUserQuestionTool(options) {
|
|
|
43568
43533
|
}
|
|
43569
43534
|
};
|
|
43570
43535
|
}
|
|
43571
|
-
function
|
|
43536
|
+
function createToolApprovalExtension(options) {
|
|
43572
43537
|
return {
|
|
43573
|
-
name: tool
|
|
43574
|
-
|
|
43575
|
-
|
|
43576
|
-
|
|
43577
|
-
|
|
43578
|
-
|
|
43579
|
-
|
|
43580
|
-
|
|
43581
|
-
|
|
43582
|
-
|
|
43583
|
-
|
|
43584
|
-
|
|
43585
|
-
|
|
43538
|
+
name: "bunny-agent-tool-approval",
|
|
43539
|
+
factory: (pi) => {
|
|
43540
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
43541
|
+
if (isAskUserQuestionToolName(event.toolName) || event.parentToolCallId !== void 0) {
|
|
43542
|
+
return void 0;
|
|
43543
|
+
}
|
|
43544
|
+
const decision = await waitForApproval({
|
|
43545
|
+
cwd: options.cwd,
|
|
43546
|
+
toolCallId: event.toolCallId,
|
|
43547
|
+
toolName: event.toolName,
|
|
43548
|
+
input: event.input,
|
|
43549
|
+
signal: ctx.signal ?? options.fallbackSignal,
|
|
43550
|
+
pollIntervalMs: options.pollIntervalMs,
|
|
43551
|
+
timeoutMs: options.timeoutMs
|
|
43552
|
+
});
|
|
43553
|
+
if (decision.behavior === "deny") {
|
|
43554
|
+
return {
|
|
43555
|
+
block: true,
|
|
43556
|
+
reason: `Tool "${event.toolName}" was not approved: ${decision.message}`
|
|
43557
|
+
};
|
|
43558
|
+
}
|
|
43559
|
+
return void 0;
|
|
43586
43560
|
});
|
|
43587
|
-
if (decision.behavior === "deny") {
|
|
43588
|
-
throw new Error(`Tool "${tool.name}" was not approved: ${decision.message}`);
|
|
43589
|
-
}
|
|
43590
|
-
return tool.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
43591
43561
|
}
|
|
43592
43562
|
};
|
|
43593
43563
|
}
|
|
43594
|
-
function gateToolsForApproval(tools, bypass, options) {
|
|
43595
|
-
if (bypass)
|
|
43596
|
-
return tools;
|
|
43597
|
-
return tools.map((tool) => wrapToolWithApproval(tool, options));
|
|
43598
|
-
}
|
|
43599
43564
|
|
|
43600
43565
|
// ../../packages/runner-pi/dist/tool-overrides.js
|
|
43601
|
-
import {
|
|
43566
|
+
import { createBashToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
43602
43567
|
|
|
43603
43568
|
// ../../packages/runner-pi/dist/web-tools.js
|
|
43604
43569
|
var braveProvider = {
|
|
@@ -44020,11 +43985,11 @@ function buildWebFetchTool() {
|
|
|
44020
43985
|
|
|
44021
43986
|
// ../../packages/runner-pi/dist/tool-overrides.js
|
|
44022
43987
|
function redactSecrets(text, secrets) {
|
|
44023
|
-
|
|
43988
|
+
const values = secretValues(secrets).filter((v) => text.includes(v));
|
|
43989
|
+
if (values.length === 0)
|
|
44024
43990
|
return text;
|
|
44025
43991
|
let result = text;
|
|
44026
43992
|
const escapeRegex3 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
44027
|
-
const values = Object.values(secrets).filter((v) => v.length >= 8).filter((v) => !/^\//.test(v) && !/^[A-Za-z]:[/\\]/.test(v)).sort((a, b) => b.length - a.length);
|
|
44028
43993
|
for (const v of values) {
|
|
44029
43994
|
const ev = escapeRegex3(v);
|
|
44030
43995
|
result = result.replace(new RegExp(`^\\S+=.*${ev}.*$\\n?`, "gm"), "");
|
|
@@ -44034,19 +43999,61 @@ function redactSecrets(text, secrets) {
|
|
|
44034
43999
|
result = result.replace(/\n{3,}/g, "\n\n");
|
|
44035
44000
|
return result.trim();
|
|
44036
44001
|
}
|
|
44037
|
-
function
|
|
44038
|
-
|
|
44039
|
-
|
|
44002
|
+
function secretValues(secrets) {
|
|
44003
|
+
return Object.values(secrets).filter((v) => v.length >= 8).filter((v) => !/^\//.test(v) && !/^[A-Za-z]:[/\\]/.test(v)).sort((a, b) => b.length - a.length);
|
|
44004
|
+
}
|
|
44005
|
+
function maskSecrets(value, values) {
|
|
44006
|
+
if (typeof value === "string") {
|
|
44007
|
+
let masked = value;
|
|
44008
|
+
for (const v of values)
|
|
44009
|
+
masked = masked.split(v).join("***");
|
|
44010
|
+
return masked;
|
|
44011
|
+
}
|
|
44012
|
+
if (Array.isArray(value)) {
|
|
44013
|
+
const next = value.map((item) => maskSecrets(item, values));
|
|
44014
|
+
return next.some((item, i) => item !== value[i]) ? next : value;
|
|
44015
|
+
}
|
|
44016
|
+
if (value !== null && typeof value === "object") {
|
|
44017
|
+
let changed = false;
|
|
44018
|
+
const next = {};
|
|
44019
|
+
for (const [key, item] of Object.entries(value)) {
|
|
44020
|
+
next[key] = maskSecrets(item, values);
|
|
44021
|
+
if (next[key] !== item)
|
|
44022
|
+
changed = true;
|
|
44023
|
+
}
|
|
44024
|
+
return changed ? next : value;
|
|
44040
44025
|
}
|
|
44026
|
+
return value;
|
|
44041
44027
|
}
|
|
44028
|
+
var ENV_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
44029
|
+
"-u",
|
|
44030
|
+
"--unset",
|
|
44031
|
+
"-C",
|
|
44032
|
+
"--chdir",
|
|
44033
|
+
"-S",
|
|
44034
|
+
"--split-string"
|
|
44035
|
+
]);
|
|
44042
44036
|
function isEnvDumpCommand(command) {
|
|
44043
44037
|
const cmd = command.replace(/\s+/g, " ").trim();
|
|
44044
|
-
|
|
44038
|
+
if (/(?:^|[|;&])\s*(?:printenv|export\s+-p|declare\s+-x)\b/.test(cmd)) {
|
|
44039
|
+
return true;
|
|
44040
|
+
}
|
|
44041
|
+
for (const match of cmd.matchAll(/(?:^|[|;&])\s*env(?=$|[\s|;&>])([^|;&>]*)/g)) {
|
|
44042
|
+
const words = match[1].trim().split(" ").filter(Boolean);
|
|
44043
|
+
let i = 0;
|
|
44044
|
+
while (i < words.length && (words[i].startsWith("-") || /^[A-Za-z_]\w*=/.test(words[i]))) {
|
|
44045
|
+
i += ENV_OPTIONS_WITH_VALUE.has(words[i]) ? 2 : 1;
|
|
44046
|
+
}
|
|
44047
|
+
if (i >= words.length || isEnvDumpCommand(words.slice(i).join(" "))) {
|
|
44048
|
+
return true;
|
|
44049
|
+
}
|
|
44050
|
+
}
|
|
44051
|
+
return false;
|
|
44045
44052
|
}
|
|
44046
|
-
function buildEnvInjectedBashTool(cwd,
|
|
44053
|
+
function buildEnvInjectedBashTool(cwd, opts = {}) {
|
|
44047
44054
|
const safeEnv = opts.systemEnv ?? {};
|
|
44048
44055
|
const pathPrepend = opts.pathPrepend;
|
|
44049
|
-
|
|
44056
|
+
return createBashToolDefinition(cwd, {
|
|
44050
44057
|
spawnHook: (ctx) => {
|
|
44051
44058
|
const env = {
|
|
44052
44059
|
...ctx.env,
|
|
@@ -44059,50 +44066,45 @@ function buildEnvInjectedBashTool(cwd, extraEnv, opts = {}) {
|
|
|
44059
44066
|
return { ...ctx, env };
|
|
44060
44067
|
}
|
|
44061
44068
|
});
|
|
44062
|
-
return {
|
|
44063
|
-
name: bashAgentTool.name,
|
|
44064
|
-
label: bashAgentTool.label ?? "bash",
|
|
44065
|
-
description: bashAgentTool.description,
|
|
44066
|
-
// biome-ignore lint/suspicious/noExplicitAny: TypeBox schema from pi internals
|
|
44067
|
-
parameters: bashAgentTool.parameters,
|
|
44068
|
-
async execute(toolCallId, params, signal, onUpdate) {
|
|
44069
|
-
const command = params.command ?? "";
|
|
44070
|
-
if (isEnvDumpCommand(command)) {
|
|
44071
|
-
return {
|
|
44072
|
-
content: [
|
|
44073
|
-
{
|
|
44074
|
-
type: "text",
|
|
44075
|
-
text: "Command blocked: printing or redirecting environment variables is not allowed."
|
|
44076
|
-
}
|
|
44077
|
-
],
|
|
44078
|
-
details: void 0
|
|
44079
|
-
};
|
|
44080
|
-
}
|
|
44081
|
-
const result = await bashAgentTool.execute(toolCallId, params, signal, onUpdate);
|
|
44082
|
-
redactResultContent(result, extraEnv);
|
|
44083
|
-
return result;
|
|
44084
|
-
}
|
|
44085
|
-
};
|
|
44086
44069
|
}
|
|
44087
|
-
|
|
44088
|
-
|
|
44070
|
+
var ENV_DUMP_BLOCKED_MESSAGE = "Command blocked: printing or redirecting environment variables is not allowed.";
|
|
44071
|
+
function createSecretGuardExtension(secrets) {
|
|
44089
44072
|
return {
|
|
44090
|
-
name:
|
|
44091
|
-
|
|
44092
|
-
|
|
44093
|
-
|
|
44094
|
-
|
|
44095
|
-
|
|
44096
|
-
|
|
44097
|
-
|
|
44098
|
-
|
|
44073
|
+
name: "bunny-agent-secret-guard",
|
|
44074
|
+
factory: (pi) => {
|
|
44075
|
+
pi.on("tool_call", (event) => {
|
|
44076
|
+
if (event.toolName === "bash" && typeof event.input.command === "string" && isEnvDumpCommand(event.input.command)) {
|
|
44077
|
+
return { block: true, reason: ENV_DUMP_BLOCKED_MESSAGE };
|
|
44078
|
+
}
|
|
44079
|
+
return void 0;
|
|
44080
|
+
});
|
|
44081
|
+
const values = secretValues(secrets);
|
|
44082
|
+
pi.on("tool_result", (event) => {
|
|
44083
|
+
if (values.length === 0)
|
|
44084
|
+
return void 0;
|
|
44085
|
+
let contentChanged = false;
|
|
44086
|
+
const content = event.content.map((part) => {
|
|
44087
|
+
if (part.type !== "text")
|
|
44088
|
+
return part;
|
|
44089
|
+
const text = redactSecrets(part.text, secrets);
|
|
44090
|
+
if (text === part.text)
|
|
44091
|
+
return part;
|
|
44092
|
+
contentChanged = true;
|
|
44093
|
+
return { ...part, text };
|
|
44094
|
+
});
|
|
44095
|
+
const details = maskSecrets(event.details, values);
|
|
44096
|
+
const structuredContent = maskSecrets(event.structuredContent, values);
|
|
44097
|
+
if (!contentChanged && details === event.details && structuredContent === event.structuredContent) {
|
|
44098
|
+
return void 0;
|
|
44099
|
+
}
|
|
44100
|
+
return { content, details, structuredContent };
|
|
44101
|
+
});
|
|
44099
44102
|
}
|
|
44100
44103
|
};
|
|
44101
44104
|
}
|
|
44102
44105
|
function buildSecretAwareTools(cwd, secrets, opts = {}) {
|
|
44103
44106
|
const tools = [
|
|
44104
|
-
buildEnvInjectedBashTool(cwd,
|
|
44105
|
-
buildSecretRedactingReadTool(cwd, secrets),
|
|
44107
|
+
buildEnvInjectedBashTool(cwd, opts),
|
|
44106
44108
|
buildWebFetchTool()
|
|
44107
44109
|
];
|
|
44108
44110
|
if (resolveSearchProvider(secrets)) {
|
|
@@ -44136,17 +44138,21 @@ function buildOne2(spec) {
|
|
|
44136
44138
|
try {
|
|
44137
44139
|
response = await executeToolRef2(spec, params, signal);
|
|
44138
44140
|
} catch (error109) {
|
|
44139
|
-
const message = formatTransportError(error109);
|
|
44140
|
-
throw new PiToolRefError(
|
|
44141
|
+
const { text: message } = await guardToolOutput(`Tool "${spec.name}" transport error: ${formatTransportError(error109)}`);
|
|
44142
|
+
throw new PiToolRefError(message, { toolName: spec.name });
|
|
44141
44143
|
}
|
|
44144
|
+
const output2 = await guardToolOutput(response.body);
|
|
44142
44145
|
if (response.status < 200 || response.status >= 300) {
|
|
44143
|
-
throw new PiToolRefError(formatToolRuntimeErrorMessage(response), {
|
|
44146
|
+
throw new PiToolRefError(formatToolRuntimeErrorMessage({ ...response, body: output2.text }), {
|
|
44144
44147
|
toolName: spec.name,
|
|
44145
44148
|
status: response.status,
|
|
44146
|
-
body:
|
|
44149
|
+
body: output2.text
|
|
44147
44150
|
});
|
|
44148
44151
|
}
|
|
44149
|
-
return
|
|
44152
|
+
return {
|
|
44153
|
+
content: [{ type: "text", text: output2.text }],
|
|
44154
|
+
details: output2.outputGuard ? { outputGuard: output2.outputGuard } : void 0
|
|
44155
|
+
};
|
|
44150
44156
|
}
|
|
44151
44157
|
};
|
|
44152
44158
|
}
|
|
@@ -44203,12 +44209,6 @@ async function executeModuleTool2(runtime, params, signal) {
|
|
|
44203
44209
|
const result = await fn(params, { signal });
|
|
44204
44210
|
return { status: 200, body: serializeResult2(result) };
|
|
44205
44211
|
}
|
|
44206
|
-
function okResult(text) {
|
|
44207
|
-
return {
|
|
44208
|
-
content: [{ type: "text", text }],
|
|
44209
|
-
details: void 0
|
|
44210
|
-
};
|
|
44211
|
-
}
|
|
44212
44212
|
function serializeResult2(result) {
|
|
44213
44213
|
if (typeof result === "string")
|
|
44214
44214
|
return result;
|
|
@@ -44216,7 +44216,7 @@ function serializeResult2(result) {
|
|
|
44216
44216
|
}
|
|
44217
44217
|
|
|
44218
44218
|
// ../../packages/runner-pi/dist/pi-runner.js
|
|
44219
|
-
var
|
|
44219
|
+
var LOG_PREFIX = "[bunny-agent:pi]";
|
|
44220
44220
|
var DEFAULT_DYNAMIC_MODEL_PROFILE = {
|
|
44221
44221
|
contextWindow: 128e3,
|
|
44222
44222
|
maxTokens: 16384,
|
|
@@ -44345,7 +44345,7 @@ function traceRawMessage(debugCwd, data, reset = false, optionsEnv) {
|
|
|
44345
44345
|
return;
|
|
44346
44346
|
try {
|
|
44347
44347
|
const file3 = join12(debugCwd, "pi-message-stream-debug.json");
|
|
44348
|
-
if (reset &&
|
|
44348
|
+
if (reset && existsSync8(file3))
|
|
44349
44349
|
unlinkSync7(file3);
|
|
44350
44350
|
const type = data !== null && typeof data === "object" ? data.type : void 0;
|
|
44351
44351
|
let payload = data;
|
|
@@ -44359,6 +44359,39 @@ function traceRawMessage(debugCwd, data, reset = false, optionsEnv) {
|
|
|
44359
44359
|
} catch {
|
|
44360
44360
|
}
|
|
44361
44361
|
}
|
|
44362
|
+
async function createPiResourceLoader(options) {
|
|
44363
|
+
const { systemPrompt } = options;
|
|
44364
|
+
const defaultSkillDirs = [
|
|
44365
|
+
join12(options.agentDir, "skills"),
|
|
44366
|
+
join12(options.cwd, CONFIG_DIR_NAME, "skills")
|
|
44367
|
+
].filter((dir) => existsSync8(dir));
|
|
44368
|
+
const loader = new DefaultResourceLoader({
|
|
44369
|
+
cwd: options.cwd,
|
|
44370
|
+
agentDir: options.agentDir,
|
|
44371
|
+
settingsManager: options.settingsManager,
|
|
44372
|
+
noSkills: true,
|
|
44373
|
+
additionalSkillPaths: [...defaultSkillDirs, ...options.skillPaths ?? []],
|
|
44374
|
+
appendSystemPromptOverride: systemPrompt ? (base) => [...base, systemPrompt] : void 0,
|
|
44375
|
+
extensionFactories: options.extensionFactories
|
|
44376
|
+
});
|
|
44377
|
+
await loader.reload();
|
|
44378
|
+
if (options.skillPaths && options.skillPaths.length > 0) {
|
|
44379
|
+
logSkillLoad(options.cwd, options.skillPaths, loader.getSkills());
|
|
44380
|
+
}
|
|
44381
|
+
return loader;
|
|
44382
|
+
}
|
|
44383
|
+
function logSkillLoad(cwd, skillPaths, result) {
|
|
44384
|
+
const lines = [`${LOG_PREFIX} loadSkills cwd=${cwd}`];
|
|
44385
|
+
for (const raw of skillPaths) {
|
|
44386
|
+
const abs = isAbsolute(raw) ? raw : resolve2(cwd, raw);
|
|
44387
|
+
lines.push(` ${raw} -> ${abs} (exists: ${existsSync8(abs) ? "yes" : "no"})`);
|
|
44388
|
+
}
|
|
44389
|
+
lines.push(` loaded skills (${result.skills.length}): ${result.skills.map((s) => s.name).join(", ")}`);
|
|
44390
|
+
for (const d of result.diagnostics) {
|
|
44391
|
+
lines.push(` [${d.type}] ${d.message}${d.path !== void 0 ? ` path=${d.path}` : ""}`);
|
|
44392
|
+
}
|
|
44393
|
+
console.error(lines.join("\n"));
|
|
44394
|
+
}
|
|
44362
44395
|
function createPiRunner(options = {}) {
|
|
44363
44396
|
const modelSpec = options.model;
|
|
44364
44397
|
if (modelSpec == null || modelSpec.trim() === "") {
|
|
@@ -44372,6 +44405,8 @@ function createPiRunner(options = {}) {
|
|
|
44372
44405
|
const mcpExtension = shouldEnableMcp(options.mcpConfig, options.allowedTools) ? createMcpExtension(options.mcpConfig) : void 0;
|
|
44373
44406
|
return {
|
|
44374
44407
|
async *run(userInput) {
|
|
44408
|
+
const agentDir = getAgentDir();
|
|
44409
|
+
const settingsManager = SettingsManager.create(cwd, agentDir);
|
|
44375
44410
|
const modelRuntime = await ModelRuntime.create({
|
|
44376
44411
|
modelsPath: null,
|
|
44377
44412
|
allowModelNetwork: false
|
|
@@ -44418,7 +44453,7 @@ function createPiRunner(options = {}) {
|
|
|
44418
44453
|
const sessionManager = await (async () => {
|
|
44419
44454
|
if (forkFrom) {
|
|
44420
44455
|
const sourcePath = resolveSessionPathById(cwd, forkFrom);
|
|
44421
|
-
console.error(`${
|
|
44456
|
+
console.error(`${LOG_PREFIX} fork: sourceId=${forkFrom} sourcePath=${sourcePath ?? "(not found)"}`);
|
|
44422
44457
|
if (!sourcePath) {
|
|
44423
44458
|
throw new Error(`Pi runner: forkFrom source session not found: ${forkFrom}`);
|
|
44424
44459
|
}
|
|
@@ -44426,11 +44461,11 @@ function createPiRunner(options = {}) {
|
|
|
44426
44461
|
}
|
|
44427
44462
|
if (resume) {
|
|
44428
44463
|
const sessionPath2 = resolveSessionPathById(cwd, resume);
|
|
44429
|
-
console.error(`${
|
|
44464
|
+
console.error(`${LOG_PREFIX} resume: id=${resume} path=${sessionPath2 ?? "(not found)"}`);
|
|
44430
44465
|
if (sessionPath2) {
|
|
44431
44466
|
if (isSessionFileTooLarge(sessionPath2)) {
|
|
44432
44467
|
const context = extractSessionContext(sessionPath2);
|
|
44433
|
-
console.error(`${
|
|
44468
|
+
console.error(`${LOG_PREFIX} session file too large, starting fresh${context ? " (with context)" : ""}`);
|
|
44434
44469
|
const newMgr = SessionManager2.create(cwd);
|
|
44435
44470
|
if (context) {
|
|
44436
44471
|
const firstId = newMgr.getEntries()[0]?.id ?? "";
|
|
@@ -44444,24 +44479,14 @@ function createPiRunner(options = {}) {
|
|
|
44444
44479
|
}
|
|
44445
44480
|
return SessionManager2.create(cwd);
|
|
44446
44481
|
})();
|
|
44447
|
-
const resourceLoader = options.skillPaths || options.systemPrompt || mcpExtension ? new BunnyAgentResourceLoader({
|
|
44448
|
-
cwd,
|
|
44449
|
-
skillPaths: options.skillPaths,
|
|
44450
|
-
appendSystemPrompt: options.systemPrompt,
|
|
44451
|
-
extensionFactories: mcpExtension ? [mcpExtension] : void 0
|
|
44452
|
-
}) : void 0;
|
|
44453
|
-
if (options.skillPaths && options.skillPaths.length > 0) {
|
|
44454
|
-
console.error(`${LOG_PREFIX2} runner: cwd=${cwd} skillPaths=${JSON.stringify(options.skillPaths)}`);
|
|
44455
|
-
}
|
|
44456
|
-
if (resourceLoader) {
|
|
44457
|
-
await resourceLoader.reload();
|
|
44458
|
-
}
|
|
44459
44482
|
const applyPatchShimDir = ensureApplyPatchShim();
|
|
44460
44483
|
const customTools = options.env && Object.keys(options.env).length > 0 ? buildSecretAwareTools(cwd, options.env, {
|
|
44461
44484
|
systemEnv: options.systemEnv,
|
|
44462
44485
|
pathPrepend: applyPatchShimDir
|
|
44463
44486
|
}) : applyPatchShimDir ? [
|
|
44464
|
-
buildEnvInjectedBashTool(cwd, {
|
|
44487
|
+
buildEnvInjectedBashTool(cwd, {
|
|
44488
|
+
pathPrepend: applyPatchShimDir
|
|
44489
|
+
})
|
|
44465
44490
|
] : [];
|
|
44466
44491
|
if (provider === "openai") {
|
|
44467
44492
|
customTools.push(buildApplyPatchTool(cwd));
|
|
@@ -44482,29 +44507,34 @@ function createPiRunner(options = {}) {
|
|
|
44482
44507
|
cwd,
|
|
44483
44508
|
fallbackSignal: options.abortController?.signal
|
|
44484
44509
|
};
|
|
44485
|
-
let regularTools = [
|
|
44486
|
-
...applyAllowedTools(customTools, allowedTools),
|
|
44487
|
-
...toolRefDefinitions
|
|
44488
|
-
];
|
|
44489
|
-
if (!bypassApproval) {
|
|
44490
|
-
const overriddenNames = new Set(regularTools.map((tool) => tool.name));
|
|
44491
|
-
const builtinTools = applyAllowedTools(createCodingTools(cwd), allowedTools).filter((tool) => !overriddenNames.has(tool.name));
|
|
44492
|
-
regularTools = [...regularTools, ...builtinTools];
|
|
44493
|
-
}
|
|
44494
|
-
const gatedTools = gateToolsForApproval(regularTools, bypassApproval, approvalGate);
|
|
44495
44510
|
const askUserQuestionEnabled = allowedTools === void 0 || allowedTools.includes(ASK_USER_QUESTION_TOOL_NAME);
|
|
44496
44511
|
const previousModel = sessionManager.buildSessionContext?.().model;
|
|
44497
44512
|
const thinkingLevel = resolveInitialThinkingLevel(options.effort, previousModel, model);
|
|
44513
|
+
const resourceLoader = await createPiResourceLoader({
|
|
44514
|
+
cwd,
|
|
44515
|
+
agentDir,
|
|
44516
|
+
settingsManager,
|
|
44517
|
+
skillPaths: options.skillPaths,
|
|
44518
|
+
systemPrompt: options.systemPrompt,
|
|
44519
|
+
extensionFactories: [
|
|
44520
|
+
createSecretGuardExtension(options.env ?? {}),
|
|
44521
|
+
...bypassApproval ? [] : [createToolApprovalExtension(approvalGate)],
|
|
44522
|
+
...mcpExtension ? [mcpExtension] : []
|
|
44523
|
+
]
|
|
44524
|
+
});
|
|
44498
44525
|
const { session } = await createAgentSession({
|
|
44499
44526
|
cwd,
|
|
44527
|
+
agentDir,
|
|
44500
44528
|
model,
|
|
44501
44529
|
sessionManager,
|
|
44530
|
+
settingsManager,
|
|
44502
44531
|
modelRuntime,
|
|
44503
44532
|
resourceLoader,
|
|
44504
44533
|
thinkingLevel,
|
|
44505
44534
|
tools: allowedTools,
|
|
44506
44535
|
customTools: [
|
|
44507
|
-
...
|
|
44536
|
+
...applyAllowedTools(customTools, allowedTools),
|
|
44537
|
+
...toolRefDefinitions,
|
|
44508
44538
|
...askUserQuestionEnabled ? [
|
|
44509
44539
|
buildAskUserQuestionTool({
|
|
44510
44540
|
...approvalGate,
|
|
@@ -44637,7 +44667,7 @@ function createPiRunner(options = {}) {
|
|
|
44637
44667
|
}
|
|
44638
44668
|
|
|
44639
44669
|
// ../../packages/runner-harness/dist/session.js
|
|
44640
|
-
import { existsSync as
|
|
44670
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
44641
44671
|
import { join as join13 } from "node:path";
|
|
44642
44672
|
var DIR = ".bunny-agent";
|
|
44643
44673
|
var FILE = "session-id";
|
|
@@ -44647,7 +44677,7 @@ function sessionPath(cwd) {
|
|
|
44647
44677
|
function readSessionId(cwd) {
|
|
44648
44678
|
try {
|
|
44649
44679
|
const p = sessionPath(cwd);
|
|
44650
|
-
if (!
|
|
44680
|
+
if (!existsSync9(p))
|
|
44651
44681
|
return void 0;
|
|
44652
44682
|
return readFileSync6(p, "utf8").trim() || void 0;
|
|
44653
44683
|
} catch {
|
|
@@ -44663,21 +44693,21 @@ function writeSessionId(cwd, id) {
|
|
|
44663
44693
|
}
|
|
44664
44694
|
|
|
44665
44695
|
// ../../packages/runner-harness/dist/skills.js
|
|
44666
|
-
import { existsSync as
|
|
44667
|
-
import { homedir
|
|
44696
|
+
import { existsSync as existsSync10, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
44697
|
+
import { homedir } from "node:os";
|
|
44668
44698
|
import { join as join14 } from "node:path";
|
|
44669
44699
|
function discoverSkillPaths(cwd) {
|
|
44670
44700
|
const paths = [];
|
|
44671
44701
|
for (const base of [
|
|
44672
44702
|
join14(cwd, "skills"),
|
|
44673
|
-
join14(
|
|
44703
|
+
join14(homedir(), ".bunny-agent", "skills")
|
|
44674
44704
|
]) {
|
|
44675
|
-
if (!
|
|
44705
|
+
if (!existsSync10(base))
|
|
44676
44706
|
continue;
|
|
44677
44707
|
try {
|
|
44678
44708
|
for (const entry of readdirSync2(base)) {
|
|
44679
44709
|
const full = join14(base, entry);
|
|
44680
|
-
if (statSync2(full).isDirectory() &&
|
|
44710
|
+
if (statSync2(full).isDirectory() && existsSync10(join14(full, "SKILL.md"))) {
|
|
44681
44711
|
paths.push(full);
|
|
44682
44712
|
}
|
|
44683
44713
|
}
|
|
@@ -45211,7 +45241,7 @@ async function runAcpAgent(options) {
|
|
|
45211
45241
|
import { execSync } from "node:child_process";
|
|
45212
45242
|
import {
|
|
45213
45243
|
copyFileSync,
|
|
45214
|
-
existsSync as
|
|
45244
|
+
existsSync as existsSync11,
|
|
45215
45245
|
mkdirSync as mkdirSync9,
|
|
45216
45246
|
readdirSync as readdirSync3,
|
|
45217
45247
|
readFileSync as readFileSync7,
|
|
@@ -45239,7 +45269,7 @@ function getShippedDockerfile() {
|
|
|
45239
45269
|
resolve3(process.cwd(), "docker", "bunny-agent-claude", "Dockerfile")
|
|
45240
45270
|
];
|
|
45241
45271
|
for (const p of candidates) {
|
|
45242
|
-
if (
|
|
45272
|
+
if (existsSync11(p)) return p;
|
|
45243
45273
|
}
|
|
45244
45274
|
console.error(
|
|
45245
45275
|
`\u274C Dockerfile not found. Searched:
|
|
@@ -45260,7 +45290,7 @@ function ensureDocker() {
|
|
|
45260
45290
|
}
|
|
45261
45291
|
function resolveTemplatePath(template) {
|
|
45262
45292
|
const abs = resolve3(process.cwd(), template);
|
|
45263
|
-
if (!
|
|
45293
|
+
if (!existsSync11(abs)) {
|
|
45264
45294
|
console.error(`\u274C Template directory not found: ${abs}`);
|
|
45265
45295
|
process.exit(1);
|
|
45266
45296
|
}
|
|
@@ -45297,16 +45327,16 @@ async function buildImage(opts) {
|
|
|
45297
45327
|
const destDir = join15(buildContext, "templates", templateName);
|
|
45298
45328
|
mkdirSync9(destDir, { recursive: true });
|
|
45299
45329
|
const claudeMd = join15(templatePath, "CLAUDE.md");
|
|
45300
|
-
if (
|
|
45330
|
+
if (existsSync11(claudeMd))
|
|
45301
45331
|
copyFileSync(claudeMd, join15(destDir, "CLAUDE.md"));
|
|
45302
45332
|
const claudeDir = join15(templatePath, ".claude");
|
|
45303
|
-
if (
|
|
45333
|
+
if (existsSync11(claudeDir)) copyDirSync(claudeDir, join15(destDir, ".claude"));
|
|
45304
45334
|
let copyLines = "\n# Template files\nRUN mkdir -p /opt/bunny-agent/templates";
|
|
45305
|
-
if (
|
|
45335
|
+
if (existsSync11(join15(destDir, "CLAUDE.md"))) {
|
|
45306
45336
|
copyLines += `
|
|
45307
45337
|
COPY templates/${templateName}/CLAUDE.md /opt/bunny-agent/templates/CLAUDE.md`;
|
|
45308
45338
|
}
|
|
45309
|
-
if (
|
|
45339
|
+
if (existsSync11(join15(destDir, ".claude"))) {
|
|
45310
45340
|
copyLines += `
|
|
45311
45341
|
COPY templates/${templateName}/.claude /opt/bunny-agent/templates/.claude`;
|
|
45312
45342
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunny-agent/runner-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.63-beta.2",
|
|
4
4
|
"description": "BunnyAgent Runner CLI - Like gemini-cli or claude-code, runs in your local terminal with AI SDK UI streaming",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,15 +42,15 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@anthropic-ai/claude-agent-sdk": "0.3.215",
|
|
44
44
|
"@anthropic-ai/sdk": "0.112.3",
|
|
45
|
-
"@earendil-works/pi-agent-core": "1.
|
|
46
|
-
"@earendil-works/pi-ai": "1.
|
|
47
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
48
|
-
"@earendil-works/pi-tui": "1.
|
|
45
|
+
"@earendil-works/pi-agent-core": "1.3.0",
|
|
46
|
+
"@earendil-works/pi-ai": "1.3.0",
|
|
47
|
+
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
48
|
+
"@earendil-works/pi-tui": "1.3.0",
|
|
49
49
|
"@github/copilot-sdk": "1.0.7",
|
|
50
50
|
"@openai/codex-sdk": "^0.144.6",
|
|
51
51
|
"dotenv": "^17.3.1",
|
|
52
52
|
"jiti": "2.7.0",
|
|
53
|
-
"pi-mcp-adapter": "5.3.
|
|
53
|
+
"pi-mcp-adapter": "5.3.1",
|
|
54
54
|
"typebox": "1.1.38",
|
|
55
55
|
"zod": "^4.0.0"
|
|
56
56
|
},
|
|
@@ -60,15 +60,15 @@
|
|
|
60
60
|
"typescript": "^5.3.0",
|
|
61
61
|
"vitest": "^1.6.1",
|
|
62
62
|
"@bunny-agent/apply-patch": "0.1.0",
|
|
63
|
-
"@bunny-agent/runner-claude": "0.6.2",
|
|
64
|
-
"@bunny-agent/manager": "0.9.62",
|
|
65
63
|
"@bunny-agent/runner-codex": "0.6.2",
|
|
64
|
+
"@bunny-agent/runner-claude": "0.6.2",
|
|
66
65
|
"@bunny-agent/runner-gemini": "0.6.2",
|
|
67
66
|
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
68
67
|
"@bunny-agent/runner-copilot": "0.1.0",
|
|
69
|
-
"@bunny-agent/
|
|
68
|
+
"@bunny-agent/runner-opencode": "0.6.2",
|
|
70
69
|
"@bunny-agent/runner-pi": "0.6.4-beta.0",
|
|
71
|
-
"@bunny-agent/
|
|
70
|
+
"@bunny-agent/manager": "0.9.63-beta.2",
|
|
71
|
+
"@bunny-agent/server-acp": "0.1.0"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "tsc && pnpm bundle",
|