@bunny-agent/runner-cli 0.9.50-beta.3 → 0.9.50-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bundle.mjs +135 -132
  2. 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 existsSync3, unlinkSync } from "node:fs";
239
- import { join as join3 } from "node:path";
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 = join3(process.cwd(), "claude-message-stream-debug.json");
245
- if (reset && existsSync3(file))
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 existsSync5, unlinkSync as unlinkSync3 } from "node:fs";
1305
- import { join as join8 } from "node:path";
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 SessionManager2 } from "@earendil-works/pi-coding-agent";
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 existsSync4 } from "node:fs";
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: ${existsSync4(abs) ? "yes" : "no"})`);
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 dirname3, extname, join as join6 } from "node:path";
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(dirname3(filePath), { recursive: true });
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 = join8(debugCwd, "pi-message-stream-debug.json");
5413
- if (reset && existsSync5(file))
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 SessionManager2.forkFrom(sourcePath, cwd);
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 = SessionManager2.create(cwd);
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 SessionManager2.open(sessionPath2);
5480
+ return SessionManager3.open(sessionPath2);
5502
5481
  }
5503
- return SessionManager2.create(cwd);
5482
+ return SessionManager3.create(cwd);
5504
5483
  }
5505
- return SessionManager2.create(cwd);
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.50-beta.3",
3
+ "version": "0.9.50-beta.4",
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
56
  "@bunny-agent/runner-claude": "0.6.2",
58
- "@bunny-agent/runner-opencode": "0.6.2",
57
+ "@bunny-agent/runner-harness": "0.1.1-beta.0",
59
58
  "@bunny-agent/runner-gemini": "0.6.2",
60
- "@bunny-agent/runner-pi": "0.6.4-beta.0",
61
- "@bunny-agent/runner-codex": "0.6.2"
59
+ "@bunny-agent/runner-opencode": "0.6.2",
60
+ "@bunny-agent/runner-codex": "0.6.2",
61
+ "@bunny-agent/runner-pi": "0.6.4-beta.0"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "tsc && pnpm bundle",