@bunny-agent/runner-cli 0.9.49 → 0.9.50-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 +135 -132
- package/package.json +5 -5
package/dist/bundle.mjs
CHANGED
|
@@ -210,39 +210,15 @@ 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
|
-
|
|
237
213
|
// ../../packages/runner-claude/dist/ai-sdk-stream.js
|
|
238
|
-
import { appendFileSync, existsSync as
|
|
239
|
-
import { join as
|
|
214
|
+
import { appendFileSync, existsSync as existsSync2, unlinkSync } from "node:fs";
|
|
215
|
+
import { join as join2 } from "node:path";
|
|
240
216
|
function trace(data, reset = false) {
|
|
241
217
|
if (process.env.DEBUG !== "true")
|
|
242
218
|
return;
|
|
243
219
|
try {
|
|
244
|
-
const file =
|
|
245
|
-
if (reset &&
|
|
220
|
+
const file = join2(process.cwd(), "claude-message-stream-debug.json");
|
|
221
|
+
if (reset && existsSync2(file))
|
|
246
222
|
unlinkSync(file);
|
|
247
223
|
const entry = {
|
|
248
224
|
_t: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1300,14 +1276,107 @@ function createOpenCodeRunner(options = {}) {
|
|
|
1300
1276
|
};
|
|
1301
1277
|
}
|
|
1302
1278
|
|
|
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
|
+
|
|
1303
1372
|
// ../../packages/runner-pi/dist/pi-runner.js
|
|
1304
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
1305
|
-
import { join as
|
|
1373
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync4, unlinkSync as unlinkSync3 } from "node:fs";
|
|
1374
|
+
import { join as join7 } from "node:path";
|
|
1306
1375
|
import { getModel } from "@earendil-works/pi-ai";
|
|
1307
|
-
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager as
|
|
1376
|
+
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager as SessionManager3 } from "@earendil-works/pi-coding-agent";
|
|
1308
1377
|
|
|
1309
1378
|
// ../../packages/runner-pi/dist/bunny-agent-resource-loader.js
|
|
1310
|
-
import { existsSync as
|
|
1379
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
1311
1380
|
import { homedir } from "node:os";
|
|
1312
1381
|
import { isAbsolute, join as join5, resolve as resolve2 } from "node:path";
|
|
1313
1382
|
import { DefaultResourceLoader, loadSkills } from "@earendil-works/pi-coding-agent";
|
|
@@ -1321,7 +1390,7 @@ function logSkillLoad(cwd, agentDir, skillPaths, result) {
|
|
|
1321
1390
|
];
|
|
1322
1391
|
for (const raw of skillPaths) {
|
|
1323
1392
|
const abs = isAbsolute(raw) ? raw : resolve2(cwd, raw);
|
|
1324
|
-
lines.push(` ${raw} -> ${abs} (exists: ${
|
|
1393
|
+
lines.push(` ${raw} -> ${abs} (exists: ${existsSync3(abs) ? "yes" : "no"})`);
|
|
1325
1394
|
}
|
|
1326
1395
|
lines.push(` loaded skills: ${result.skills.length}`);
|
|
1327
1396
|
if (result.skills.length > 0) {
|
|
@@ -1397,7 +1466,7 @@ var BunnyAgentResourceLoader = class {
|
|
|
1397
1466
|
|
|
1398
1467
|
// ../../packages/runner-pi/dist/image-tools.js
|
|
1399
1468
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1400
|
-
import { dirname as
|
|
1469
|
+
import { dirname as dirname2, extname, join as join6 } from "node:path";
|
|
1401
1470
|
var generateImageSchema = {
|
|
1402
1471
|
type: "object",
|
|
1403
1472
|
properties: {
|
|
@@ -1630,7 +1699,7 @@ async function saveImageItem(item, filePath, apiKey) {
|
|
|
1630
1699
|
const b64 = await resolveB64(item, apiKey);
|
|
1631
1700
|
if (!b64)
|
|
1632
1701
|
return void 0;
|
|
1633
|
-
mkdirSync2(
|
|
1702
|
+
mkdirSync2(dirname2(filePath), { recursive: true });
|
|
1634
1703
|
writeFileSync3(filePath, Buffer.from(b64, "base64"));
|
|
1635
1704
|
return filePath;
|
|
1636
1705
|
}
|
|
@@ -1928,96 +1997,6 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1928
1997
|
};
|
|
1929
1998
|
}
|
|
1930
1999
|
|
|
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
|
-
|
|
2021
2000
|
// ../../packages/runner-pi/dist/usage-metadata.js
|
|
2022
2001
|
function usageToMessageMetadata(usage) {
|
|
2023
2002
|
return {
|
|
@@ -5409,8 +5388,8 @@ function traceRawMessage(debugCwd, data, reset = false, optionsEnv) {
|
|
|
5409
5388
|
if (!enabled)
|
|
5410
5389
|
return;
|
|
5411
5390
|
try {
|
|
5412
|
-
const file =
|
|
5413
|
-
if (reset &&
|
|
5391
|
+
const file = join7(debugCwd, "pi-message-stream-debug.json");
|
|
5392
|
+
if (reset && existsSync4(file))
|
|
5414
5393
|
unlinkSync3(file);
|
|
5415
5394
|
const type = data !== null && typeof data === "object" ? data.type : void 0;
|
|
5416
5395
|
let payload = data;
|
|
@@ -5482,7 +5461,7 @@ function createPiRunner(options = {}) {
|
|
|
5482
5461
|
if (!sourcePath) {
|
|
5483
5462
|
throw new Error(`Pi runner: forkFrom source session not found: ${forkFrom}`);
|
|
5484
5463
|
}
|
|
5485
|
-
return
|
|
5464
|
+
return SessionManager3.forkFrom(sourcePath, cwd);
|
|
5486
5465
|
}
|
|
5487
5466
|
if (resume) {
|
|
5488
5467
|
const sessionPath2 = resolveSessionPathById(cwd, resume);
|
|
@@ -5491,18 +5470,18 @@ function createPiRunner(options = {}) {
|
|
|
5491
5470
|
if (isSessionFileTooLarge(sessionPath2)) {
|
|
5492
5471
|
const context = extractSessionContext(sessionPath2);
|
|
5493
5472
|
console.error(`${LOG_PREFIX2} session file too large, starting fresh${context ? " (with context)" : ""}`);
|
|
5494
|
-
const newMgr =
|
|
5473
|
+
const newMgr = SessionManager3.create(cwd);
|
|
5495
5474
|
if (context) {
|
|
5496
5475
|
const firstId = newMgr.getEntries()[0]?.id ?? "";
|
|
5497
5476
|
newMgr.appendCompaction(context, firstId, 0);
|
|
5498
5477
|
}
|
|
5499
5478
|
return newMgr;
|
|
5500
5479
|
}
|
|
5501
|
-
return
|
|
5480
|
+
return SessionManager3.open(sessionPath2);
|
|
5502
5481
|
}
|
|
5503
|
-
return
|
|
5482
|
+
return SessionManager3.create(cwd);
|
|
5504
5483
|
}
|
|
5505
|
-
return
|
|
5484
|
+
return SessionManager3.create(cwd);
|
|
5506
5485
|
})();
|
|
5507
5486
|
const resourceLoader = options.skillPaths ? new BunnyAgentResourceLoader({
|
|
5508
5487
|
cwd,
|
|
@@ -5631,6 +5610,30 @@ function createPiRunner(options = {}) {
|
|
|
5631
5610
|
};
|
|
5632
5611
|
}
|
|
5633
5612
|
|
|
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
|
+
|
|
5634
5637
|
// ../../packages/runner-harness/dist/session.js
|
|
5635
5638
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5636
5639
|
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.
|
|
3
|
+
"version": "0.9.50-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": {
|
|
@@ -53,12 +53,12 @@
|
|
|
53
53
|
"esbuild": "^0.27.2",
|
|
54
54
|
"typescript": "^5.3.0",
|
|
55
55
|
"vitest": "^1.6.1",
|
|
56
|
-
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
57
|
-
"@bunny-agent/runner-claude": "0.6.2",
|
|
58
56
|
"@bunny-agent/runner-codex": "0.6.2",
|
|
57
|
+
"@bunny-agent/runner-claude": "0.6.2",
|
|
58
|
+
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
59
59
|
"@bunny-agent/runner-gemini": "0.6.2",
|
|
60
|
-
"@bunny-agent/runner-
|
|
61
|
-
"@bunny-agent/runner-
|
|
60
|
+
"@bunny-agent/runner-opencode": "0.6.2",
|
|
61
|
+
"@bunny-agent/runner-pi": "0.6.4-beta.0"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "tsc && pnpm bundle",
|