@bunny-agent/runner-cli 0.9.50-beta.4 → 0.9.50
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 +132 -135
- package/package.json +2 -2
package/dist/bundle.mjs
CHANGED
|
@@ -210,15 +210,39 @@ var BUNNY_AGENT_SYSTEM_PROMPT = [
|
|
|
210
210
|
"If the answer is a number, give only the number. If it's a name, give the exact name as it appears in the source."
|
|
211
211
|
].join("\n");
|
|
212
212
|
|
|
213
|
+
// ../../packages/runner-harness/dist/prompt.js
|
|
214
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
215
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
216
|
+
var PROMPT_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
217
|
+
function loadSystemPrompt(cwd) {
|
|
218
|
+
let dir = cwd;
|
|
219
|
+
for (let i = 0; i < 5; i++) {
|
|
220
|
+
for (const name of PROMPT_FILES) {
|
|
221
|
+
const p = join2(dir, name);
|
|
222
|
+
if (existsSync2(p)) {
|
|
223
|
+
try {
|
|
224
|
+
return readFileSync2(p, "utf8").trim() || void 0;
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const parent = dirname2(dir);
|
|
230
|
+
if (parent === dir)
|
|
231
|
+
break;
|
|
232
|
+
dir = parent;
|
|
233
|
+
}
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
213
237
|
// ../../packages/runner-claude/dist/ai-sdk-stream.js
|
|
214
|
-
import { appendFileSync, existsSync as
|
|
215
|
-
import { join as
|
|
238
|
+
import { appendFileSync, existsSync as existsSync3, unlinkSync } from "node:fs";
|
|
239
|
+
import { join as join3 } from "node:path";
|
|
216
240
|
function trace(data, reset = false) {
|
|
217
241
|
if (process.env.DEBUG !== "true")
|
|
218
242
|
return;
|
|
219
243
|
try {
|
|
220
|
-
const file =
|
|
221
|
-
if (reset &&
|
|
244
|
+
const file = join3(process.cwd(), "claude-message-stream-debug.json");
|
|
245
|
+
if (reset && existsSync3(file))
|
|
222
246
|
unlinkSync(file);
|
|
223
247
|
const entry = {
|
|
224
248
|
_t: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1276,107 +1300,14 @@ function createOpenCodeRunner(options = {}) {
|
|
|
1276
1300
|
};
|
|
1277
1301
|
}
|
|
1278
1302
|
|
|
1279
|
-
// ../../packages/runner-pi/dist/fork.js
|
|
1280
|
-
import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
|
|
1281
|
-
|
|
1282
|
-
// ../../packages/runner-pi/dist/session-utils.js
|
|
1283
|
-
import { closeSync, fstatSync, openSync, readdirSync as readdirSync2, readSync, statSync as statSync2 } from "node:fs";
|
|
1284
|
-
import { join as join4 } from "node:path";
|
|
1285
|
-
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
1286
|
-
var MAX_SESSION_FILE_BYTES = Number(process.env.SANDAGENT_MAX_SESSION_BYTES) || 10 * 1024 * 1024;
|
|
1287
|
-
function resolveSessionPathById(cwd, sessionIdOrPath) {
|
|
1288
|
-
if (sessionIdOrPath.includes("/"))
|
|
1289
|
-
return sessionIdOrPath;
|
|
1290
|
-
const tempMgr = SessionManager.create(cwd);
|
|
1291
|
-
const sessionsDir = tempMgr.getSessionDir();
|
|
1292
|
-
try {
|
|
1293
|
-
const suffix = `_${sessionIdOrPath}.jsonl`;
|
|
1294
|
-
const match = readdirSync2(sessionsDir).find((f) => f.endsWith(suffix));
|
|
1295
|
-
return match ? join4(sessionsDir, match) : void 0;
|
|
1296
|
-
} catch {
|
|
1297
|
-
return void 0;
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
function isSessionFileTooLarge(sessionPath2) {
|
|
1301
|
-
try {
|
|
1302
|
-
return statSync2(sessionPath2).size > MAX_SESSION_FILE_BYTES;
|
|
1303
|
-
} catch {
|
|
1304
|
-
return false;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
function readTailEntries(sessionPath2, tailBytes = 1024 * 1024) {
|
|
1308
|
-
let fd;
|
|
1309
|
-
try {
|
|
1310
|
-
fd = openSync(sessionPath2, "r");
|
|
1311
|
-
} catch {
|
|
1312
|
-
return [];
|
|
1313
|
-
}
|
|
1314
|
-
try {
|
|
1315
|
-
const fileSize = fstatSync(fd).size;
|
|
1316
|
-
const readStart = Math.max(0, fileSize - tailBytes);
|
|
1317
|
-
const readLen = fileSize - readStart;
|
|
1318
|
-
const buf = Buffer.alloc(readLen);
|
|
1319
|
-
readSync(fd, buf, 0, readLen, readStart);
|
|
1320
|
-
const tail = buf.toString("utf8");
|
|
1321
|
-
const entries = [];
|
|
1322
|
-
for (const line of tail.split("\n")) {
|
|
1323
|
-
const trimmed = line.trim();
|
|
1324
|
-
if (!trimmed)
|
|
1325
|
-
continue;
|
|
1326
|
-
try {
|
|
1327
|
-
entries.push(JSON.parse(trimmed));
|
|
1328
|
-
} catch {
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
return entries;
|
|
1332
|
-
} finally {
|
|
1333
|
-
closeSync(fd);
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
function extractSessionContext(sessionPath2) {
|
|
1337
|
-
const entries = readTailEntries(sessionPath2);
|
|
1338
|
-
if (entries.length === 0)
|
|
1339
|
-
return void 0;
|
|
1340
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1341
|
-
const e = entries[i];
|
|
1342
|
-
if (e.type === "compaction" && typeof e.summary === "string") {
|
|
1343
|
-
return e.summary;
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
const recentMessages = [];
|
|
1347
|
-
const MAX_MESSAGES = 6;
|
|
1348
|
-
for (let i = entries.length - 1; i >= 0 && recentMessages.length < MAX_MESSAGES; i--) {
|
|
1349
|
-
const e = entries[i];
|
|
1350
|
-
if (e.type !== "message")
|
|
1351
|
-
continue;
|
|
1352
|
-
const msg = e.message;
|
|
1353
|
-
if (!msg)
|
|
1354
|
-
continue;
|
|
1355
|
-
if (msg.role !== "user" && msg.role !== "assistant")
|
|
1356
|
-
continue;
|
|
1357
|
-
let text = "";
|
|
1358
|
-
if (typeof msg.content === "string") {
|
|
1359
|
-
text = msg.content;
|
|
1360
|
-
} else if (Array.isArray(msg.content)) {
|
|
1361
|
-
text = msg.content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n");
|
|
1362
|
-
}
|
|
1363
|
-
if (text) {
|
|
1364
|
-
recentMessages.unshift(`[${msg.role}]: ${text}`);
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
if (recentMessages.length === 0)
|
|
1368
|
-
return void 0;
|
|
1369
|
-
return "## Previous Session Context (auto-extracted)\n\nThe following is the tail of the previous conversation:\n\n" + recentMessages.join("\n\n");
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
1303
|
// ../../packages/runner-pi/dist/pi-runner.js
|
|
1373
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
1374
|
-
import { join as
|
|
1304
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync5, unlinkSync as unlinkSync3 } from "node:fs";
|
|
1305
|
+
import { join as join8 } from "node:path";
|
|
1375
1306
|
import { getModel } from "@earendil-works/pi-ai";
|
|
1376
|
-
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager as
|
|
1307
|
+
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
|
|
1377
1308
|
|
|
1378
1309
|
// ../../packages/runner-pi/dist/bunny-agent-resource-loader.js
|
|
1379
|
-
import { existsSync as
|
|
1310
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
1380
1311
|
import { homedir } from "node:os";
|
|
1381
1312
|
import { isAbsolute, join as join5, resolve as resolve2 } from "node:path";
|
|
1382
1313
|
import { DefaultResourceLoader, loadSkills } from "@earendil-works/pi-coding-agent";
|
|
@@ -1390,7 +1321,7 @@ function logSkillLoad(cwd, agentDir, skillPaths, result) {
|
|
|
1390
1321
|
];
|
|
1391
1322
|
for (const raw of skillPaths) {
|
|
1392
1323
|
const abs = isAbsolute(raw) ? raw : resolve2(cwd, raw);
|
|
1393
|
-
lines.push(` ${raw} -> ${abs} (exists: ${
|
|
1324
|
+
lines.push(` ${raw} -> ${abs} (exists: ${existsSync4(abs) ? "yes" : "no"})`);
|
|
1394
1325
|
}
|
|
1395
1326
|
lines.push(` loaded skills: ${result.skills.length}`);
|
|
1396
1327
|
if (result.skills.length > 0) {
|
|
@@ -1466,7 +1397,7 @@ var BunnyAgentResourceLoader = class {
|
|
|
1466
1397
|
|
|
1467
1398
|
// ../../packages/runner-pi/dist/image-tools.js
|
|
1468
1399
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1469
|
-
import { dirname as
|
|
1400
|
+
import { dirname as dirname3, extname, join as join6 } from "node:path";
|
|
1470
1401
|
var generateImageSchema = {
|
|
1471
1402
|
type: "object",
|
|
1472
1403
|
properties: {
|
|
@@ -1699,7 +1630,7 @@ async function saveImageItem(item, filePath, apiKey) {
|
|
|
1699
1630
|
const b64 = await resolveB64(item, apiKey);
|
|
1700
1631
|
if (!b64)
|
|
1701
1632
|
return void 0;
|
|
1702
|
-
mkdirSync2(
|
|
1633
|
+
mkdirSync2(dirname3(filePath), { recursive: true });
|
|
1703
1634
|
writeFileSync3(filePath, Buffer.from(b64, "base64"));
|
|
1704
1635
|
return filePath;
|
|
1705
1636
|
}
|
|
@@ -1997,6 +1928,96 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1997
1928
|
};
|
|
1998
1929
|
}
|
|
1999
1930
|
|
|
1931
|
+
// ../../packages/runner-pi/dist/session-utils.js
|
|
1932
|
+
import { closeSync, fstatSync, openSync, readdirSync as readdirSync2, readSync, statSync as statSync2 } from "node:fs";
|
|
1933
|
+
import { join as join7 } from "node:path";
|
|
1934
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
1935
|
+
var MAX_SESSION_FILE_BYTES = Number(process.env.SANDAGENT_MAX_SESSION_BYTES) || 10 * 1024 * 1024;
|
|
1936
|
+
function resolveSessionPathById(cwd, sessionIdOrPath) {
|
|
1937
|
+
if (sessionIdOrPath.includes("/"))
|
|
1938
|
+
return sessionIdOrPath;
|
|
1939
|
+
const tempMgr = SessionManager.create(cwd);
|
|
1940
|
+
const sessionsDir = tempMgr.getSessionDir();
|
|
1941
|
+
try {
|
|
1942
|
+
const suffix = `_${sessionIdOrPath}.jsonl`;
|
|
1943
|
+
const match = readdirSync2(sessionsDir).find((f) => f.endsWith(suffix));
|
|
1944
|
+
return match ? join7(sessionsDir, match) : void 0;
|
|
1945
|
+
} catch {
|
|
1946
|
+
return void 0;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
function isSessionFileTooLarge(sessionPath2) {
|
|
1950
|
+
try {
|
|
1951
|
+
return statSync2(sessionPath2).size > MAX_SESSION_FILE_BYTES;
|
|
1952
|
+
} catch {
|
|
1953
|
+
return false;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
function readTailEntries(sessionPath2, tailBytes = 1024 * 1024) {
|
|
1957
|
+
let fd;
|
|
1958
|
+
try {
|
|
1959
|
+
fd = openSync(sessionPath2, "r");
|
|
1960
|
+
} catch {
|
|
1961
|
+
return [];
|
|
1962
|
+
}
|
|
1963
|
+
try {
|
|
1964
|
+
const fileSize = fstatSync(fd).size;
|
|
1965
|
+
const readStart = Math.max(0, fileSize - tailBytes);
|
|
1966
|
+
const readLen = fileSize - readStart;
|
|
1967
|
+
const buf = Buffer.alloc(readLen);
|
|
1968
|
+
readSync(fd, buf, 0, readLen, readStart);
|
|
1969
|
+
const tail = buf.toString("utf8");
|
|
1970
|
+
const entries = [];
|
|
1971
|
+
for (const line of tail.split("\n")) {
|
|
1972
|
+
const trimmed = line.trim();
|
|
1973
|
+
if (!trimmed)
|
|
1974
|
+
continue;
|
|
1975
|
+
try {
|
|
1976
|
+
entries.push(JSON.parse(trimmed));
|
|
1977
|
+
} catch {
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
return entries;
|
|
1981
|
+
} finally {
|
|
1982
|
+
closeSync(fd);
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
function extractSessionContext(sessionPath2) {
|
|
1986
|
+
const entries = readTailEntries(sessionPath2);
|
|
1987
|
+
if (entries.length === 0)
|
|
1988
|
+
return void 0;
|
|
1989
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1990
|
+
const e = entries[i];
|
|
1991
|
+
if (e.type === "compaction" && typeof e.summary === "string") {
|
|
1992
|
+
return e.summary;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
const recentMessages = [];
|
|
1996
|
+
const MAX_MESSAGES = 6;
|
|
1997
|
+
for (let i = entries.length - 1; i >= 0 && recentMessages.length < MAX_MESSAGES; i--) {
|
|
1998
|
+
const e = entries[i];
|
|
1999
|
+
if (e.type !== "message")
|
|
2000
|
+
continue;
|
|
2001
|
+
const msg = e.message;
|
|
2002
|
+
if (!msg)
|
|
2003
|
+
continue;
|
|
2004
|
+
if (msg.role !== "user" && msg.role !== "assistant")
|
|
2005
|
+
continue;
|
|
2006
|
+
let text = "";
|
|
2007
|
+
if (typeof msg.content === "string") {
|
|
2008
|
+
text = msg.content;
|
|
2009
|
+
} else if (Array.isArray(msg.content)) {
|
|
2010
|
+
text = msg.content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n");
|
|
2011
|
+
}
|
|
2012
|
+
if (text) {
|
|
2013
|
+
recentMessages.unshift(`[${msg.role}]: ${text}`);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
if (recentMessages.length === 0)
|
|
2017
|
+
return void 0;
|
|
2018
|
+
return "## Previous Session Context (auto-extracted)\n\nThe following is the tail of the previous conversation:\n\n" + recentMessages.join("\n\n");
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2000
2021
|
// ../../packages/runner-pi/dist/usage-metadata.js
|
|
2001
2022
|
function usageToMessageMetadata(usage) {
|
|
2002
2023
|
return {
|
|
@@ -5388,8 +5409,8 @@ function traceRawMessage(debugCwd, data, reset = false, optionsEnv) {
|
|
|
5388
5409
|
if (!enabled)
|
|
5389
5410
|
return;
|
|
5390
5411
|
try {
|
|
5391
|
-
const file =
|
|
5392
|
-
if (reset &&
|
|
5412
|
+
const file = join8(debugCwd, "pi-message-stream-debug.json");
|
|
5413
|
+
if (reset && existsSync5(file))
|
|
5393
5414
|
unlinkSync3(file);
|
|
5394
5415
|
const type = data !== null && typeof data === "object" ? data.type : void 0;
|
|
5395
5416
|
let payload = data;
|
|
@@ -5461,7 +5482,7 @@ function createPiRunner(options = {}) {
|
|
|
5461
5482
|
if (!sourcePath) {
|
|
5462
5483
|
throw new Error(`Pi runner: forkFrom source session not found: ${forkFrom}`);
|
|
5463
5484
|
}
|
|
5464
|
-
return
|
|
5485
|
+
return SessionManager2.forkFrom(sourcePath, cwd);
|
|
5465
5486
|
}
|
|
5466
5487
|
if (resume) {
|
|
5467
5488
|
const sessionPath2 = resolveSessionPathById(cwd, resume);
|
|
@@ -5470,18 +5491,18 @@ function createPiRunner(options = {}) {
|
|
|
5470
5491
|
if (isSessionFileTooLarge(sessionPath2)) {
|
|
5471
5492
|
const context = extractSessionContext(sessionPath2);
|
|
5472
5493
|
console.error(`${LOG_PREFIX2} session file too large, starting fresh${context ? " (with context)" : ""}`);
|
|
5473
|
-
const newMgr =
|
|
5494
|
+
const newMgr = SessionManager2.create(cwd);
|
|
5474
5495
|
if (context) {
|
|
5475
5496
|
const firstId = newMgr.getEntries()[0]?.id ?? "";
|
|
5476
5497
|
newMgr.appendCompaction(context, firstId, 0);
|
|
5477
5498
|
}
|
|
5478
5499
|
return newMgr;
|
|
5479
5500
|
}
|
|
5480
|
-
return
|
|
5501
|
+
return SessionManager2.open(sessionPath2);
|
|
5481
5502
|
}
|
|
5482
|
-
return
|
|
5503
|
+
return SessionManager2.create(cwd);
|
|
5483
5504
|
}
|
|
5484
|
-
return
|
|
5505
|
+
return SessionManager2.create(cwd);
|
|
5485
5506
|
})();
|
|
5486
5507
|
const resourceLoader = options.skillPaths ? new BunnyAgentResourceLoader({
|
|
5487
5508
|
cwd,
|
|
@@ -5610,30 +5631,6 @@ function createPiRunner(options = {}) {
|
|
|
5610
5631
|
};
|
|
5611
5632
|
}
|
|
5612
5633
|
|
|
5613
|
-
// ../../packages/runner-harness/dist/prompt.js
|
|
5614
|
-
import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
|
|
5615
|
-
import { dirname as dirname3, join as join8 } from "node:path";
|
|
5616
|
-
var PROMPT_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
5617
|
-
function loadSystemPrompt(cwd) {
|
|
5618
|
-
let dir = cwd;
|
|
5619
|
-
for (let i = 0; i < 5; i++) {
|
|
5620
|
-
for (const name of PROMPT_FILES) {
|
|
5621
|
-
const p = join8(dir, name);
|
|
5622
|
-
if (existsSync5(p)) {
|
|
5623
|
-
try {
|
|
5624
|
-
return readFileSync2(p, "utf8").trim() || void 0;
|
|
5625
|
-
} catch {
|
|
5626
|
-
}
|
|
5627
|
-
}
|
|
5628
|
-
}
|
|
5629
|
-
const parent = dirname3(dir);
|
|
5630
|
-
if (parent === dir)
|
|
5631
|
-
break;
|
|
5632
|
-
dir = parent;
|
|
5633
|
-
}
|
|
5634
|
-
return void 0;
|
|
5635
|
-
}
|
|
5636
|
-
|
|
5637
5634
|
// ../../packages/runner-harness/dist/session.js
|
|
5638
5635
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5639
5636
|
import { join as join9 } from "node:path";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunny-agent/runner-cli",
|
|
3
|
-
"version": "0.9.50
|
|
3
|
+
"version": "0.9.50",
|
|
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": {
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"esbuild": "^0.27.2",
|
|
54
54
|
"typescript": "^5.3.0",
|
|
55
55
|
"vitest": "^1.6.1",
|
|
56
|
-
"@bunny-agent/runner-claude": "0.6.2",
|
|
57
56
|
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
58
57
|
"@bunny-agent/runner-gemini": "0.6.2",
|
|
58
|
+
"@bunny-agent/runner-claude": "0.6.2",
|
|
59
59
|
"@bunny-agent/runner-opencode": "0.6.2",
|
|
60
60
|
"@bunny-agent/runner-codex": "0.6.2",
|
|
61
61
|
"@bunny-agent/runner-pi": "0.6.4-beta.0"
|