@ringko-ai/rkh 0.1.0 → 0.2.1-rc

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.
@@ -893,7 +893,8 @@ var init_paths = __esm(() => {
893
893
  });
894
894
 
895
895
  // packages/config/src/config.ts
896
- import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "fs";
896
+ import { randomUUID as randomUUID2 } from "crypto";
897
+ import { chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "fs";
897
898
  import { dirname as dirname2 } from "path";
898
899
  function isRecord(value) {
899
900
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -945,6 +946,26 @@ function writeJson(path, value) {
945
946
  } catch {}
946
947
  return path;
947
948
  }
949
+ function saveConfigFile(config, path) {
950
+ const data = `${JSON.stringify(config, null, 2)}
951
+ `;
952
+ const target = existsSync(path) ? realpathSync(path) : path;
953
+ const temporary = `${target}.${randomUUID2()}.tmp`;
954
+ mkdirSync(dirname2(target), { recursive: true });
955
+ const descriptor = openSync(temporary, "wx", 384);
956
+ try {
957
+ try {
958
+ writeFileSync(descriptor, data, "utf8");
959
+ fsyncSync(descriptor);
960
+ } finally {
961
+ closeSync(descriptor);
962
+ }
963
+ renameSync(temporary, target);
964
+ } finally {
965
+ rmSync(temporary, { force: true });
966
+ }
967
+ return path;
968
+ }
948
969
  function saveConfig(config, env = process.env) {
949
970
  const { providers, model, small_model, mode, ...rest } = config;
950
971
  const settings = { ...rest };
@@ -1084,8 +1105,8 @@ var init_config = __esm(() => {
1084
1105
  });
1085
1106
 
1086
1107
  // packages/config/src/auth.ts
1087
- import { randomUUID as randomUUID2 } from "crypto";
1088
- import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync, rmSync } from "fs";
1108
+ import { randomUUID as randomUUID3 } from "crypto";
1109
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync as renameSync2, rmSync as rmSync2 } from "fs";
1089
1110
  import { dirname as dirname3 } from "path";
1090
1111
  function isRecord2(value) {
1091
1112
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1193,13 +1214,13 @@ function loadAuth(env = process.env) {
1193
1214
  function writeState(state, env) {
1194
1215
  const path = authPath(env);
1195
1216
  mkdirSync2(dirname3(path), { recursive: true, mode: 448 });
1196
- const temporary = `${path}.${randomUUID2()}.tmp`;
1217
+ const temporary = `${path}.${randomUUID3()}.tmp`;
1197
1218
  try {
1198
1219
  writeFileSync2(temporary, `${JSON.stringify(state, null, 2)}
1199
1220
  `, { flag: "wx", mode: 384 });
1200
- renameSync(temporary, path);
1221
+ renameSync2(temporary, path);
1201
1222
  } finally {
1202
- rmSync(temporary, { force: true });
1223
+ rmSync2(temporary, { force: true });
1203
1224
  }
1204
1225
  try {
1205
1226
  chmodSync2(path, 384);
@@ -1231,9 +1252,9 @@ function setOAuthAccount(domain, account, env = process.env) {
1231
1252
  const domainState = state.oauth[domain] ??= { accounts: [] };
1232
1253
  const index = domainState.accounts.findIndex((entry) => entry.id === account.id);
1233
1254
  if (index === -1)
1234
- domainState.accounts.push({ ...account, uuid: account.uuid ?? randomUUID2() });
1255
+ domainState.accounts.push({ ...account, uuid: account.uuid ?? randomUUID3() });
1235
1256
  else
1236
- domainState.accounts[index] = { ...account, uuid: domainState.accounts[index].uuid ?? account.uuid ?? randomUUID2() };
1257
+ domainState.accounts[index] = { ...account, uuid: domainState.accounts[index].uuid ?? account.uuid ?? randomUUID3() };
1237
1258
  domainState.defaultAccountId ??= account.id;
1238
1259
  writeState(state, env);
1239
1260
  }
@@ -2195,7 +2216,7 @@ var init_proxy = __esm(() => {
2195
2216
  });
2196
2217
 
2197
2218
  // packages/config/src/skills.ts
2198
- import { closeSync, openSync, readSync, mkdirSync as mkdirSync6, readdirSync, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
2219
+ import { closeSync as closeSync2, openSync as openSync2, readSync, mkdirSync as mkdirSync6, readdirSync, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
2199
2220
  import { isAbsolute, join as join2, relative, resolve as resolve2 } from "path";
2200
2221
  function parseSkillFrontmatter(text) {
2201
2222
  const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
@@ -2247,13 +2268,13 @@ function discoverSkills(options = {}) {
2247
2268
  }
2248
2269
  let text;
2249
2270
  try {
2250
- const descriptor = openSync(skillFile, "r");
2271
+ const descriptor = openSync2(skillFile, "r");
2251
2272
  try {
2252
2273
  const buffer = Buffer.alloc(SKILL_METADATA_BYTES);
2253
2274
  const bytes = readSync(descriptor, buffer, 0, buffer.length, 0);
2254
2275
  text = buffer.subarray(0, bytes).toString("utf8");
2255
2276
  } finally {
2256
- closeSync(descriptor);
2277
+ closeSync2(descriptor);
2257
2278
  }
2258
2279
  } catch {
2259
2280
  continue;
@@ -2299,7 +2320,7 @@ function removeSkill(dir, env = process.env, cwd = process.cwd()) {
2299
2320
  } catch {
2300
2321
  return false;
2301
2322
  }
2302
- rmSync2(target, { recursive: true, force: true });
2323
+ rmSync3(target, { recursive: true, force: true });
2303
2324
  return true;
2304
2325
  }
2305
2326
  var SKILL_FILE_NAME = "SKILL.md", SKILL_METADATA_BYTES, SINGLE_SEGMENT;
@@ -2310,7 +2331,7 @@ var init_skills = __esm(() => {
2310
2331
  });
2311
2332
 
2312
2333
  // packages/config/src/mcp.ts
2313
- import { chmodSync as chmodSync6, existsSync, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
2334
+ import { chmodSync as chmodSync6, existsSync as existsSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
2314
2335
  import { dirname as dirname7, join as join3 } from "path";
2315
2336
  function isRecord6(value) {
2316
2337
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2404,7 +2425,7 @@ function saveProjectMcpServers(cwd, servers, env = process.env) {
2404
2425
  throw new Error("No project root found; cannot save project MCP configuration.");
2405
2426
  const dotMcp = join3(root, ".mcp.json");
2406
2427
  const ringkoJson = join3(root, "ringko.json");
2407
- const useRingkoJson = !existsSync(dotMcp);
2428
+ const useRingkoJson = !existsSync2(dotMcp);
2408
2429
  const target = useRingkoJson ? ringkoJson : dotMcp;
2409
2430
  let existing = {};
2410
2431
  if (useRingkoJson) {
@@ -2496,7 +2517,7 @@ function configuredModelIds(config) {
2496
2517
  }
2497
2518
 
2498
2519
  // packages/config/src/diagnostics.ts
2499
- import { appendFileSync, mkdirSync as mkdirSync8, renameSync as renameSync2, statSync as statSync4 } from "fs";
2520
+ import { appendFileSync, mkdirSync as mkdirSync8, renameSync as renameSync3, statSync as statSync4 } from "fs";
2500
2521
  import { join as join5 } from "path";
2501
2522
  function diagnosticLogPath() {
2502
2523
  return join5(ringkoRoot(), "logs", "diagnostics.jsonl");
@@ -2514,7 +2535,7 @@ function writeDiagnostic(source, message) {
2514
2535
  throw error;
2515
2536
  }
2516
2537
  if (size >= MAX_LOG_BYTES)
2517
- renameSync2(path, `${path}.previous`);
2538
+ renameSync3(path, `${path}.previous`);
2518
2539
  const text = message.slice(0, MAX_MESSAGE_LENGTH).replace(/(Bearer\s+)[^\s"']+/gi, "$1[redacted]").replace(/((?:api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\s*["']?\s*[:=]\s*["']?)[^\s,"'}]+/gi, "$1[redacted]");
2519
2540
  appendFileSync(path, `${JSON.stringify({ timestamp: new Date().toISOString(), source: source.slice(0, 256), message: text, truncated: message.length > MAX_MESSAGE_LENGTH })}
2520
2541
  `, { mode: 384 });
@@ -2712,7 +2733,7 @@ function parseHeaderOnly(text) {
2712
2733
  var init_format = () => {};
2713
2734
 
2714
2735
  // packages/session/src/lock.ts
2715
- import { closeSync as closeSync2, openSync as openSync2, readFileSync as readFileSync9, unlinkSync, writeSync } from "fs";
2736
+ import { closeSync as closeSync3, openSync as openSync3, readFileSync as readFileSync9, unlinkSync, writeSync } from "fs";
2716
2737
  function readOwnerPid(path) {
2717
2738
  try {
2718
2739
  const parsed = JSON.parse(readFileSync9(path, "utf8"));
@@ -2735,9 +2756,9 @@ function isAlive(pid) {
2735
2756
  function acquireLock(path) {
2736
2757
  for (let attempt = 0;attempt < 2; attempt += 1) {
2737
2758
  try {
2738
- const fd = openSync2(path, "wx");
2759
+ const fd = openSync3(path, "wx");
2739
2760
  writeSync(fd, JSON.stringify({ pid: process.pid, time: Date.now() }));
2740
- closeSync2(fd);
2761
+ closeSync3(fd);
2741
2762
  return {
2742
2763
  release() {
2743
2764
  try {
@@ -2764,13 +2785,13 @@ var init_lock = () => {};
2764
2785
 
2765
2786
  // packages/session/src/store.ts
2766
2787
  import {
2767
- closeSync as closeSync3,
2768
- fsyncSync,
2788
+ closeSync as closeSync4,
2789
+ fsyncSync as fsyncSync2,
2769
2790
  mkdirSync as mkdirSync9,
2770
- openSync as openSync3,
2791
+ openSync as openSync4,
2771
2792
  readdirSync as readdirSync2,
2772
2793
  readFileSync as readFileSync10,
2773
- rmSync as rmSync3,
2794
+ rmSync as rmSync4,
2774
2795
  statSync as statSync5,
2775
2796
  writeSync as writeSync2
2776
2797
  } from "fs";
@@ -2831,7 +2852,7 @@ class SessionStore {
2831
2852
  return false;
2832
2853
  const lock = acquireLock(sessionLockPath(dir));
2833
2854
  try {
2834
- rmSync3(dir, { recursive: true, force: true });
2855
+ rmSync4(dir, { recursive: true, force: true });
2835
2856
  } finally {
2836
2857
  lock.release();
2837
2858
  }
@@ -2929,15 +2950,15 @@ class SessionHandle {
2929
2950
  mkdirSync9(this.dir, { recursive: true, mode: 448 });
2930
2951
  this.lock = acquireLock(sessionLockPath(this.dir));
2931
2952
  try {
2932
- this.fd = openSync3(this.path, "a");
2953
+ this.fd = openSync4(this.path, "a");
2933
2954
  if (!fileExists(this.path) || statSync5(this.path).size === 0) {
2934
2955
  writeSync2(this.fd, serializeHeader(this.header));
2935
- fsyncSync(this.fd);
2956
+ fsyncSync2(this.fd);
2936
2957
  }
2937
2958
  } catch (error) {
2938
2959
  try {
2939
2960
  if (this.fd !== undefined)
2940
- closeSync3(this.fd);
2961
+ closeSync4(this.fd);
2941
2962
  } finally {
2942
2963
  this.fd = undefined;
2943
2964
  this.lock.release();
@@ -2984,16 +3005,16 @@ class SessionHandle {
2984
3005
  if (!this.materialized) {
2985
3006
  mkdirSync9(this.dir, { recursive: true, mode: 448 });
2986
3007
  this.lock = acquireLock(sessionLockPath(this.dir));
2987
- this.fd = openSync3(this.path, "a");
3008
+ this.fd = openSync4(this.path, "a");
2988
3009
  writeSync2(this.fd, serializeHeader(this.header));
2989
3010
  this.materialized = true;
2990
3011
  }
2991
3012
  if (this.fd === undefined)
2992
- this.fd = openSync3(this.path, "a");
3013
+ this.fd = openSync4(this.path, "a");
2993
3014
  for (const line of this.buffer)
2994
3015
  writeSync2(this.fd, line);
2995
3016
  this.buffer.length = 0;
2996
- fsyncSync(this.fd);
3017
+ fsyncSync2(this.fd);
2997
3018
  } catch (error) {
2998
3019
  this.writeFailure = error;
2999
3020
  throw error;
@@ -3014,7 +3035,7 @@ class SessionHandle {
3014
3035
  }
3015
3036
  try {
3016
3037
  if (this.fd !== undefined)
3017
- closeSync3(this.fd);
3038
+ closeSync4(this.fd);
3018
3039
  } catch (error) {
3019
3040
  errors.push(error);
3020
3041
  }
@@ -4009,7 +4030,7 @@ var init_src4 = __esm(() => {
4009
4030
  });
4010
4031
 
4011
4032
  // packages/sdk/src/task.ts
4012
- import { randomUUID as randomUUID3 } from "crypto";
4033
+ import { randomUUID as randomUUID4 } from "crypto";
4013
4034
  function parseTask(value) {
4014
4035
  if (!value || typeof value !== "object" || Array.isArray(value))
4015
4036
  throw new TypeError("Expected a task object.");
@@ -4075,7 +4096,7 @@ class TaskManager {
4075
4096
  throw new Error("Task budget exhausted for this run.");
4076
4097
  this.active++;
4077
4098
  this.launched++;
4078
- const taskId = id ?? randomUUID3();
4099
+ const taskId = id ?? randomUUID4();
4079
4100
  const controller = new AbortController;
4080
4101
  const parentAbort = () => controller.abort(context.signal?.reason);
4081
4102
  context.signal?.addEventListener("abort", parentAbort, { once: true });
@@ -5237,7 +5258,7 @@ var init_src6 = __esm(() => {
5237
5258
  });
5238
5259
 
5239
5260
  // packages/tools/src/ask.ts
5240
- import { randomUUID as randomUUID4 } from "crypto";
5261
+ import { randomUUID as randomUUID5 } from "crypto";
5241
5262
  function parseOption(value, where) {
5242
5263
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
5243
5264
  throw new TypeError(`${where} must be an object.`);
@@ -5371,7 +5392,7 @@ class AskManager {
5371
5392
  context?.signal?.throwIfAborted();
5372
5393
  if (this.queue.length >= ASK_LIMITS.questions)
5373
5394
  throw new Error("Too many pending questions.");
5374
- const id = randomUUID4();
5395
+ const id = randomUUID5();
5375
5396
  const cancel = () => this.finish(id);
5376
5397
  const timer = setTimeout(cancel, 300000);
5377
5398
  const pending = { id, input, resolve, reject, cleanup: () => {
@@ -6191,6 +6212,219 @@ var init_todo = __esm(() => {
6191
6212
  TODO_LIMITS = Object.freeze({ items: 100, characters: 2048 });
6192
6213
  });
6193
6214
 
6215
+ // packages/tools/src/tree.ts
6216
+ import { lstat, opendir, realpath as realpath2 } from "fs/promises";
6217
+ import { isAbsolute as isAbsolute3, join as join9, relative as relative3, sep as sep2 } from "path";
6218
+ function parseTree(value) {
6219
+ if (!value || typeof value !== "object" || Array.isArray(value))
6220
+ throw new TypeError("Expected a tree input object.");
6221
+ const data = value;
6222
+ if (Object.keys(data).some((key) => !["path", "max_depth", "max_entries", "directories_only", "include_hidden", "exclude"].includes(key)))
6223
+ throw new TypeError("Unexpected tree input field.");
6224
+ const input = {};
6225
+ if (data.path !== undefined) {
6226
+ if (typeof data.path !== "string" || !data.path.trim() || data.path.includes("\x00") || data.path.length > TREE_LIMITS.pathCharacters)
6227
+ throw new TypeError("Invalid tree path.");
6228
+ input.path = data.path;
6229
+ }
6230
+ for (const [key, minimum, maximum] of [["max_depth", 0, TREE_LIMITS.maxDepth], ["max_entries", 1, TREE_LIMITS.maxEntries]]) {
6231
+ const value = data[key];
6232
+ if (value !== undefined) {
6233
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < minimum || value > maximum)
6234
+ throw new TypeError(`${key} must be an integer from ${minimum} to ${maximum}.`);
6235
+ input[key] = value;
6236
+ }
6237
+ }
6238
+ for (const key of ["directories_only", "include_hidden"]) {
6239
+ if (data[key] !== undefined) {
6240
+ if (typeof data[key] !== "boolean")
6241
+ throw new TypeError(`${key} must be boolean.`);
6242
+ input[key] = data[key];
6243
+ }
6244
+ }
6245
+ if (data.exclude !== undefined) {
6246
+ if (!Array.isArray(data.exclude) || data.exclude.length > TREE_LIMITS.excludeNames || data.exclude.some((name) => typeof name !== "string" || !name || name.length > TREE_LIMITS.nameCharacters || name === "." || name === ".." || /[\\/\0]/.test(name)))
6247
+ throw new TypeError(`exclude must contain at most ${TREE_LIMITS.excludeNames} nonempty entry names without path separators.`);
6248
+ input.exclude = data.exclude;
6249
+ }
6250
+ return input;
6251
+ }
6252
+ function contained(root, path) {
6253
+ const child = relative3(root, path);
6254
+ return child === "" || child !== ".." && !child.startsWith(`..${sep2}`) && !isAbsolute3(child);
6255
+ }
6256
+ function label(value) {
6257
+ return JSON.stringify(value).slice(1, -1);
6258
+ }
6259
+ function errorCode(error) {
6260
+ const code = error?.code;
6261
+ return typeof code === "string" && /^[A-Z0-9_]+$/.test(code) ? code : "DIRECTORY_CHANGED";
6262
+ }
6263
+ function compareNames(a, b) {
6264
+ return Number(b.directory) - Number(a.directory) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
6265
+ }
6266
+ function createTreeTool(workspace) {
6267
+ return defineTool({
6268
+ name: "tree",
6269
+ taskAccess: "read",
6270
+ description: "Show a directory tree using native filesystem APIs, not a shell or system tree command. Use this tool for directory structure instead of shell. Defaults: workspace root, depth 3, 500 entries; skips hidden entries and common dependency/build directories. Symlinks are shown but not traversed. Outside-workspace targets require approval. exclude replaces the default list with exact entry names.",
6271
+ inputSchema: {
6272
+ type: "object",
6273
+ properties: {
6274
+ path: { type: "string" },
6275
+ max_depth: { type: "integer", minimum: 0, maximum: TREE_LIMITS.maxDepth },
6276
+ max_entries: { type: "integer", minimum: 1, maximum: TREE_LIMITS.maxEntries },
6277
+ directories_only: { type: "boolean" },
6278
+ include_hidden: { type: "boolean" },
6279
+ exclude: { type: "array", maxItems: TREE_LIMITS.excludeNames, items: { type: "string", minLength: 1, maxLength: TREE_LIMITS.nameCharacters } }
6280
+ },
6281
+ additionalProperties: false
6282
+ },
6283
+ parseInput: parseTree,
6284
+ async assessRisk(input) {
6285
+ const target = await resolveWriteTarget(workspace, input.path ?? ".");
6286
+ return { kind: target.insideWorkspace ? "workspace_file" : "external_file", reason: `List directory tree ${target.insideWorkspace ? target.relative || "." : target.absolute}.`, target: target.absolute };
6287
+ },
6288
+ async execute(input, context) {
6289
+ context?.signal?.throwIfAborted();
6290
+ const target = await resolveWriteTarget(workspace, input.path ?? ".");
6291
+ if (context?.approvedTarget && context.approvedTarget !== target.absolute)
6292
+ throw new Error("Tree target changed after approval; retry the call.");
6293
+ const rootInfo = await lstat(target.absolute);
6294
+ if (!rootInfo.isDirectory() || rootInfo.isSymbolicLink())
6295
+ throw new TypeError("tree path must resolve to a directory.");
6296
+ const shown = target.insideWorkspace ? target.relative || "." : target.absolute.split(sep2).join("/");
6297
+ const lines = [label(shown)];
6298
+ const entries = [];
6299
+ const reasons = new Set;
6300
+ const depthLimit = input.max_depth ?? TREE_LIMITS.defaultDepth;
6301
+ const entryLimit = input.max_entries ?? TREE_LIMITS.defaultEntries;
6302
+ const exclusions = new Set((input.exclude ?? TREE_DEFAULT_EXCLUDES).map((name) => process.platform === "win32" ? name.toLowerCase() : name));
6303
+ let scanned = 0;
6304
+ let characters = JSON.stringify(shown).length * 2;
6305
+ let stopped = false;
6306
+ const list = async (path) => {
6307
+ context?.signal?.throwIfAborted();
6308
+ const before = await lstat(path, { bigint: true });
6309
+ const canonical = await realpath2(path);
6310
+ if (!before.isDirectory() || before.isSymbolicLink() || !contained(target.absolute, canonical) || relative3(path, canonical) !== "")
6311
+ throw new Error("Tree directory changed before traversal.");
6312
+ const directory = await opendir(path);
6313
+ const children = [];
6314
+ try {
6315
+ for (;; ) {
6316
+ context?.signal?.throwIfAborted();
6317
+ if (scanned >= TREE_LIMITS.scannedEntries) {
6318
+ reasons.add("scan_limit");
6319
+ break;
6320
+ }
6321
+ const child = await directory.read();
6322
+ if (!child)
6323
+ break;
6324
+ scanned++;
6325
+ if (!input.include_hidden && child.name.startsWith(".") || exclusions.has(process.platform === "win32" ? child.name.toLowerCase() : child.name))
6326
+ continue;
6327
+ children.push({ name: child.name, directory: child.isDirectory() && !child.isSymbolicLink(), symlink: child.isSymbolicLink() });
6328
+ }
6329
+ } finally {
6330
+ await directory.close();
6331
+ }
6332
+ const after = await lstat(path, { bigint: true });
6333
+ if (after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino || relative3(canonical, await realpath2(path)) !== "")
6334
+ throw new Error("Tree directory changed during traversal.");
6335
+ return children.sort(compareNames);
6336
+ };
6337
+ const walk = async (path, display, prefix, depth) => {
6338
+ if (depth >= depthLimit) {
6339
+ reasons.add("max_depth");
6340
+ return;
6341
+ }
6342
+ const candidates = await list(path);
6343
+ const children = input.directories_only ? candidates.filter((child) => child.directory || child.symlink) : candidates;
6344
+ for (let index = 0;index < children.length; index++) {
6345
+ context?.signal?.throwIfAborted();
6346
+ if (entries.length >= entryLimit) {
6347
+ reasons.add("max_entries");
6348
+ stopped = true;
6349
+ return;
6350
+ }
6351
+ const child = children[index];
6352
+ const absolute = join9(path, child.name);
6353
+ const childPath = display ? `${display}/${child.name}` : child.name;
6354
+ const entry = { path: childPath, type: "other", depth: depth + 1 };
6355
+ try {
6356
+ const info = await lstat(absolute);
6357
+ entry.type = info.isSymbolicLink() ? "symlink" : info.isDirectory() ? "directory" : info.isFile() ? "file" : "other";
6358
+ } catch (error) {
6359
+ entry.error = errorCode(error);
6360
+ reasons.add("io_error");
6361
+ }
6362
+ if (input.directories_only && entry.type !== "directory" && entry.type !== "symlink" && !entry.error)
6363
+ continue;
6364
+ const last = index === children.length - 1;
6365
+ const suffix = entry.type === "directory" ? "/" : entry.type === "symlink" ? " [symlink; not followed]" : "";
6366
+ const line = `${prefix}${last ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${label(child.name)}${suffix}${entry.error ? ` [${entry.error}]` : ""}`;
6367
+ const cost = JSON.stringify(line).length + JSON.stringify(entry).length + TREE_LIMITS.entryOverhead;
6368
+ if (characters + cost > TREE_LIMITS.outputCharacters - TREE_LIMITS.footerCharacters) {
6369
+ reasons.add("output_limit");
6370
+ stopped = true;
6371
+ return;
6372
+ }
6373
+ characters += cost;
6374
+ entries.push(entry);
6375
+ lines.push(line);
6376
+ const lineIndex = lines.length - 1;
6377
+ if (entry.type === "directory") {
6378
+ if (depth + 1 >= depthLimit) {
6379
+ entry.children_truncated = true;
6380
+ reasons.add("max_depth");
6381
+ lines[lineIndex] += " [depth limit]";
6382
+ } else if (scanned < TREE_LIMITS.scannedEntries) {
6383
+ try {
6384
+ await walk(absolute, childPath, `${prefix}${last ? " " : "\u2502 "}`, depth + 1);
6385
+ } catch (error) {
6386
+ context?.signal?.throwIfAborted();
6387
+ entry.error = errorCode(error);
6388
+ entry.children_truncated = true;
6389
+ reasons.add("io_error");
6390
+ lines[lineIndex] += ` [${entry.error}]`;
6391
+ }
6392
+ if (stopped)
6393
+ entry.children_truncated = true;
6394
+ } else
6395
+ entry.children_truncated = true;
6396
+ }
6397
+ if (stopped)
6398
+ return;
6399
+ }
6400
+ };
6401
+ await walk(target.absolute, "", "", 0);
6402
+ context?.signal?.throwIfAborted();
6403
+ if (reasons.size)
6404
+ lines.push(`\u2026 [truncated: ${[...reasons].join(", ")}]`);
6405
+ return {
6406
+ path: shown,
6407
+ tree: lines.join(`
6408
+ `),
6409
+ entries,
6410
+ directories: entries.filter((entry) => entry.type === "directory").length,
6411
+ files: entries.filter((entry) => entry.type === "file").length,
6412
+ symlinks: entries.filter((entry) => entry.type === "symlink").length,
6413
+ other: entries.filter((entry) => entry.type === "other").length,
6414
+ truncated: reasons.size > 0,
6415
+ ...reasons.size ? { truncation_reasons: [...reasons] } : {}
6416
+ };
6417
+ }
6418
+ });
6419
+ }
6420
+ var TREE_LIMITS, TREE_DEFAULT_EXCLUDES;
6421
+ var init_tree = __esm(() => {
6422
+ init_src();
6423
+ init_workspace();
6424
+ TREE_LIMITS = Object.freeze({ defaultDepth: 3, maxDepth: 16, defaultEntries: 500, maxEntries: 2000, scannedEntries: 20000, outputCharacters: 131072, footerCharacters: 160, entryOverhead: 160, excludeNames: 64, nameCharacters: 255, pathCharacters: 32768 });
6425
+ TREE_DEFAULT_EXCLUDES = [".git", "node_modules", "dist", "build", "coverage", "target", ".next", ".cache", ".venv", "venv", "__pycache__"];
6426
+ });
6427
+
6194
6428
  // node_modules/.pnpm/entities@7.0.1/node_modules/entities/dist/esm/decode-codepoint.js
6195
6429
  function replaceCodePoint(codePoint) {
6196
6430
  var _a;
@@ -23856,14 +24090,14 @@ function process2(parentNode) {
23856
24090
  } else if (node.nodeType === 1) {
23857
24091
  replacement = replacementForNode.call(self2, node);
23858
24092
  }
23859
- return join9(output, replacement);
24093
+ return join10(output, replacement);
23860
24094
  }, "");
23861
24095
  }
23862
24096
  function postProcess(output) {
23863
24097
  var self2 = this;
23864
24098
  this.rules.forEach(function(rule) {
23865
24099
  if (typeof rule.append === "function") {
23866
- output = join9(output, rule.append(self2.options));
24100
+ output = join10(output, rule.append(self2.options));
23867
24101
  }
23868
24102
  });
23869
24103
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -23876,7 +24110,7 @@ function replacementForNode(node) {
23876
24110
  content = content.trim();
23877
24111
  return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
23878
24112
  }
23879
- function join9(output, replacement) {
24113
+ function join10(output, replacement) {
23880
24114
  var s1 = trimTrailingNewlines(output);
23881
24115
  var s2 = trimLeadingNewlines(replacement);
23882
24116
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -24596,6 +24830,314 @@ var init_write = __esm(() => {
24596
24830
  init_workspace();
24597
24831
  });
24598
24832
 
24833
+ // packages/tools/src/session-query.ts
24834
+ import { resolve as resolve5 } from "path";
24835
+ function asRecord3(value) {
24836
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
24837
+ throw new TypeError("Expected an object input.");
24838
+ }
24839
+ return value;
24840
+ }
24841
+ function integerField(record, key, min, max) {
24842
+ const value = record[key];
24843
+ if (value === undefined)
24844
+ return;
24845
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
24846
+ throw new TypeError(`Invalid '${key}'; expected an integer between ${min} and ${max}.`);
24847
+ }
24848
+ return value;
24849
+ }
24850
+ function stringField(record, key, max) {
24851
+ const value = record[key];
24852
+ if (value === undefined)
24853
+ return;
24854
+ if (typeof value !== "string" || value.trim().length === 0 || value.length > max) {
24855
+ throw new TypeError(`Invalid '${key}'; expected a non-empty string of at most ${max} characters.`);
24856
+ }
24857
+ return value;
24858
+ }
24859
+ function normalizePath(path) {
24860
+ const resolved = resolve5(path);
24861
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
24862
+ }
24863
+ function inWorkspace(cwd, workspace) {
24864
+ return typeof cwd === "string" && cwd.length > 0 && normalizePath(cwd) === normalizePath(workspace);
24865
+ }
24866
+ function serialize2(value) {
24867
+ if (value === undefined)
24868
+ return "";
24869
+ try {
24870
+ return typeof value === "string" ? value : JSON.stringify(value) ?? "";
24871
+ } catch {
24872
+ return String(value);
24873
+ }
24874
+ }
24875
+ function collapse(text) {
24876
+ return text.replace(/\s+/g, " ").trim();
24877
+ }
24878
+ function snippetOf(text, needle, limit) {
24879
+ const folded = text.toLowerCase();
24880
+ const at = folded.indexOf(needle);
24881
+ if (at < 0)
24882
+ return collapse(text).slice(0, limit);
24883
+ const start = Math.max(0, at - Math.floor((limit - needle.length) / 2));
24884
+ const window2 = collapse(text.slice(start, start + limit * 2));
24885
+ return window2.length > limit ? `${window2.slice(0, limit)}\u2026` : window2;
24886
+ }
24887
+ function titleFor(handle) {
24888
+ try {
24889
+ return sessionTitle(handle.all());
24890
+ } catch {
24891
+ return;
24892
+ }
24893
+ }
24894
+ function openScoped(store, workspace, id, limits) {
24895
+ const meta = store.list().find((candidate) => candidate.id === id);
24896
+ if (!meta)
24897
+ throw new Error(`No session "${id}" in this workspace.`);
24898
+ if (meta.sizeBytes > limits.sessionBytes) {
24899
+ throw new Error(`Session "${id}" is too large to read (${meta.sizeBytes} bytes; limit ${limits.sessionBytes}).`);
24900
+ }
24901
+ const handle = store.open(meta.id, "read");
24902
+ try {
24903
+ if (!inWorkspace(handle.header.cwd, workspace)) {
24904
+ throw new Error(`Session "${id}" belongs to another workspace.`);
24905
+ }
24906
+ const title = titleFor(handle);
24907
+ return {
24908
+ summary: {
24909
+ id: handle.header.id,
24910
+ ...title ? { title } : {},
24911
+ createdAt: handle.header.createdAt,
24912
+ sizeBytes: meta.sizeBytes,
24913
+ ...handle.header.parentSession ? { parentSession: handle.header.parentSession } : {}
24914
+ },
24915
+ events: handle.all()
24916
+ };
24917
+ } finally {
24918
+ handle.close();
24919
+ }
24920
+ }
24921
+ function summaryFor(meta, store, limits) {
24922
+ const base = {
24923
+ id: meta.id,
24924
+ createdAt: meta.header.createdAt,
24925
+ sizeBytes: meta.sizeBytes,
24926
+ ...meta.header.parentSession ? { parentSession: meta.header.parentSession } : {}
24927
+ };
24928
+ if (meta.sizeBytes > limits.titleBytes)
24929
+ return base;
24930
+ try {
24931
+ const handle = store.open(meta.id, "read");
24932
+ try {
24933
+ const title = titleFor(handle);
24934
+ return title ? { ...base, title } : base;
24935
+ } finally {
24936
+ handle.close();
24937
+ }
24938
+ } catch {
24939
+ return base;
24940
+ }
24941
+ }
24942
+ function createSessionListTool(store, workspace, limits = SESSION_QUERY_LIMITS) {
24943
+ return defineTool({
24944
+ name: "session_list",
24945
+ taskAccess: "read",
24946
+ description: "List the recorded sessions of the current workspace, newest first, with id, title, creation time and size. Use the id with session_read or session_search.",
24947
+ inputSchema: {
24948
+ type: "object",
24949
+ properties: { limit: { type: "integer", minimum: 1, maximum: limits.sessions } },
24950
+ additionalProperties: false
24951
+ },
24952
+ parseInput(value) {
24953
+ if (value === undefined || value === null)
24954
+ return {};
24955
+ const record = asRecord3(value);
24956
+ const limit = integerField(record, "limit", 1, limits.sessions);
24957
+ return limit === undefined ? {} : { limit };
24958
+ },
24959
+ assessRisk() {
24960
+ return { kind: "workspace_file", reason: "List recorded sessions for this workspace.", target: "session:list" };
24961
+ },
24962
+ execute({ limit }) {
24963
+ const all = store.list().filter((meta) => inWorkspace(meta.header.cwd, workspace));
24964
+ const selected = all.slice(0, limit ?? limits.sessions);
24965
+ return {
24966
+ workspace,
24967
+ sessions: selected.map((meta) => summaryFor(meta, store, limits)),
24968
+ truncated: all.length > selected.length
24969
+ };
24970
+ }
24971
+ });
24972
+ }
24973
+ function createSessionSearchTool(store, workspace, limits = SESSION_QUERY_LIMITS) {
24974
+ return defineTool({
24975
+ name: "session_search",
24976
+ taskAccess: "read",
24977
+ description: "Search recorded session events in this workspace for a case-insensitive substring. Returns the session id, sequence number, event type and a short snippet for each match; follow up with session_read.",
24978
+ inputSchema: {
24979
+ type: "object",
24980
+ properties: {
24981
+ query: { type: "string", minLength: 1, maxLength: limits.queryCharacters },
24982
+ session: { type: "string" }
24983
+ },
24984
+ required: ["query"],
24985
+ additionalProperties: false
24986
+ },
24987
+ parseInput(value) {
24988
+ const record = asRecord3(value);
24989
+ const query = stringField(record, "query", limits.queryCharacters);
24990
+ if (query === undefined)
24991
+ throw new TypeError("Expected a non-empty string 'query'.");
24992
+ const session = stringField(record, "session", 256);
24993
+ return session === undefined ? { query } : { query, session };
24994
+ },
24995
+ assessRisk(input) {
24996
+ const target = input.session ? `session:${input.session}` : "session:search";
24997
+ return { kind: "workspace_file", reason: "Search recorded session events for this workspace.", target };
24998
+ },
24999
+ execute({ query, session }) {
25000
+ const needle = query.toLowerCase();
25001
+ const all = store.list().filter((meta) => inWorkspace(meta.header.cwd, workspace));
25002
+ const targets = session ? all.filter((meta) => meta.id === session) : all.slice(0, limits.sessions);
25003
+ if (session !== undefined && targets.length === 0)
25004
+ throw new Error(`No session "${session}" in this workspace.`);
25005
+ const matches = [];
25006
+ const scanned = { sessions: 0, events: 0 };
25007
+ let characters = 0;
25008
+ let bytes = 0;
25009
+ let truncated = false;
25010
+ for (const meta of targets) {
25011
+ if (matches.length >= limits.events || characters >= limits.responseCharacters) {
25012
+ truncated = true;
25013
+ break;
25014
+ }
25015
+ if (bytes + meta.sizeBytes > limits.scanBytes) {
25016
+ truncated = true;
25017
+ break;
25018
+ }
25019
+ let scoped;
25020
+ try {
25021
+ scoped = openScoped(store, workspace, meta.id, limits);
25022
+ } catch {
25023
+ continue;
25024
+ }
25025
+ bytes += meta.sizeBytes;
25026
+ scanned.sessions += 1;
25027
+ for (const event of scoped.events.slice(0, limits.scanEventsPerSession)) {
25028
+ if (matches.length >= limits.events || characters >= limits.responseCharacters) {
25029
+ truncated = true;
25030
+ break;
25031
+ }
25032
+ scanned.events += 1;
25033
+ const haystack = `${event.type} ${serialize2(event.data)}`;
25034
+ if (!haystack.toLowerCase().includes(needle))
25035
+ continue;
25036
+ const snippet = snippetOf(haystack, needle, limits.snippetCharacters);
25037
+ matches.push({ session: meta.id, seq: event.seq, time: event.time, type: event.type, snippet });
25038
+ characters += snippet.length + 64;
25039
+ }
25040
+ }
25041
+ return { query, matches, scanned, truncated };
25042
+ }
25043
+ });
25044
+ }
25045
+ function createSessionReadTool(store, workspace, limits = SESSION_QUERY_LIMITS) {
25046
+ return defineTool({
25047
+ name: "session_read",
25048
+ taskAccess: "read",
25049
+ description: "Read recorded events from one session of this workspace by sequence cursor. Returns seq, time, type and data; oversized data is returned as bounded text.",
25050
+ inputSchema: {
25051
+ type: "object",
25052
+ properties: {
25053
+ session: { type: "string" },
25054
+ before: { type: "integer", minimum: 0 },
25055
+ after: { type: "integer", minimum: 0 },
25056
+ limit: { type: "integer", minimum: 1, maximum: limits.events }
25057
+ },
25058
+ required: ["session"],
25059
+ additionalProperties: false
25060
+ },
25061
+ parseInput(value) {
25062
+ const record = asRecord3(value);
25063
+ const session = stringField(record, "session", 256);
25064
+ if (session === undefined)
25065
+ throw new TypeError("Expected a non-empty string 'session'.");
25066
+ const before = integerField(record, "before", 0, Number.MAX_SAFE_INTEGER);
25067
+ const after = integerField(record, "after", 0, Number.MAX_SAFE_INTEGER);
25068
+ if (before !== undefined && after !== undefined)
25069
+ throw new TypeError("Pass either 'before' or 'after', not both.");
25070
+ const limit = integerField(record, "limit", 1, limits.events);
25071
+ return { session, ...before !== undefined ? { before } : {}, ...after !== undefined ? { after } : {}, ...limit !== undefined ? { limit } : {} };
25072
+ },
25073
+ assessRisk(input) {
25074
+ return { kind: "workspace_file", reason: "Read recorded events from a session of this workspace.", target: `session:${input.session}` };
25075
+ },
25076
+ execute({ session, before, after, limit }) {
25077
+ const scoped = openScoped(store, workspace, session, limits);
25078
+ const candidates = scoped.events.filter((event) => before !== undefined ? event.seq < before : after !== undefined ? event.seq > after : true);
25079
+ const selected = after !== undefined ? candidates.slice(0, limit ?? limits.events) : candidates.slice(-(limit ?? limits.events));
25080
+ const records = [];
25081
+ let characters = 0;
25082
+ let truncated = false;
25083
+ for (const event of selected) {
25084
+ const text = serialize2(event.data);
25085
+ const tooLarge = text.length > limits.eventCharacters;
25086
+ if (characters + Math.min(text.length, limits.eventCharacters) > limits.responseCharacters) {
25087
+ truncated = true;
25088
+ break;
25089
+ }
25090
+ characters += Math.min(text.length, limits.eventCharacters) + 64;
25091
+ records.push({
25092
+ seq: event.seq,
25093
+ time: event.time,
25094
+ type: event.type,
25095
+ ...tooLarge ? { dataText: `${text.slice(0, limits.eventCharacters)}\u2026` } : event.data !== undefined ? { data: event.data } : {},
25096
+ dataTruncated: tooLarge
25097
+ });
25098
+ }
25099
+ const first = selected[0];
25100
+ const last = selected[selected.length - 1];
25101
+ return {
25102
+ session: scoped.summary,
25103
+ events: records,
25104
+ hasOlder: first !== undefined && candidates.some((event) => event.seq < first.seq),
25105
+ hasNewer: last !== undefined && candidates.some((event) => event.seq > last.seq),
25106
+ truncated: truncated || records.length < selected.length
25107
+ };
25108
+ }
25109
+ });
25110
+ }
25111
+ function registerSessionQueryTools(registry, options) {
25112
+ if (typeof options.workspace !== "string" || options.workspace.trim().length === 0) {
25113
+ throw new TypeError("Session query tools require a workspace.");
25114
+ }
25115
+ const limits = { ...SESSION_QUERY_LIMITS, ...options.limits };
25116
+ const store = options.store ?? new SessionStore({ cwd: options.workspace });
25117
+ registry.registerAll([
25118
+ createSessionListTool(store, options.workspace, limits),
25119
+ createSessionSearchTool(store, options.workspace, limits),
25120
+ createSessionReadTool(store, options.workspace, limits)
25121
+ ]);
25122
+ }
25123
+ var SESSION_QUERY_LIMITS;
25124
+ var init_session_query = __esm(() => {
25125
+ init_src();
25126
+ init_src3();
25127
+ SESSION_QUERY_LIMITS = Object.freeze({
25128
+ sessions: 50,
25129
+ events: 100,
25130
+ sessionBytes: 4 * 1024 * 1024,
25131
+ titleBytes: 256 * 1024,
25132
+ scanBytes: 32 * 1024 * 1024,
25133
+ eventCharacters: 4096,
25134
+ snippetCharacters: 240,
25135
+ queryCharacters: 200,
25136
+ responseCharacters: 60000,
25137
+ scanEventsPerSession: 20000
25138
+ });
25139
+ });
25140
+
24599
25141
  // packages/tools/src/index.ts
24600
25142
  function registerWorkspaceTools(registry, options) {
24601
25143
  const workspace = createWorkspace(options.workspace);
@@ -24605,6 +25147,7 @@ function registerWorkspaceTools(registry, options) {
24605
25147
  registry.register(createEditTool(workspace, tracker));
24606
25148
  registry.register(createGlobTool(workspace));
24607
25149
  registry.register(createGrepTool(workspace));
25150
+ registry.register(createTreeTool(workspace));
24608
25151
  return workspace;
24609
25152
  }
24610
25153
  function registerNetworkTools(registry, options = {}) {
@@ -24630,11 +25173,13 @@ var init_src7 = __esm(() => {
24630
25173
  init_read();
24631
25174
  init_shell();
24632
25175
  init_todo();
25176
+ init_tree();
24633
25177
  init_webfetch();
24634
25178
  init_websearch();
24635
25179
  init_write();
24636
25180
  init_workspace();
24637
25181
  init_ask();
25182
+ init_session_query();
24638
25183
  });
24639
25184
 
24640
25185
  // packages/workflow/src/index.ts
@@ -24725,7 +25270,7 @@ var init_src8 = __esm(() => {
24725
25270
 
24726
25271
  // packages/sdk/src/skills.ts
24727
25272
  import { open } from "fs/promises";
24728
- import { join as join10 } from "path";
25273
+ import { join as join11 } from "path";
24729
25274
  function registerRuntimeSkills(registry, workspace) {
24730
25275
  const skills = discoverSkills({ cwd: workspace }).slice(0, MAX_SKILLS);
24731
25276
  if (skills.length === 0)
@@ -24747,7 +25292,7 @@ function registerRuntimeSkills(registry, workspace) {
24747
25292
  const skill = skills.find((skill) => skill.name === input.name);
24748
25293
  if (!skill)
24749
25294
  throw new Error("Skill is no longer available.");
24750
- const file = await open(join10(skill.dir, SKILL_FILE_NAME), "r");
25295
+ const file = await open(join11(skill.dir, SKILL_FILE_NAME), "r");
24751
25296
  try {
24752
25297
  const stat = await file.stat();
24753
25298
  if (!stat.isFile() || stat.size > MAX_SKILL_BYTES)
@@ -24762,7 +25307,7 @@ function registerRuntimeSkills(registry, workspace) {
24762
25307
  }
24763
25308
  if (total > MAX_SKILL_BYTES)
24764
25309
  throw new Error("Skill exceeds 64 KiB.");
24765
- return `Instructions from: ${join10(skill.dir, SKILL_FILE_NAME)}
25310
+ return `Instructions from: ${join11(skill.dir, SKILL_FILE_NAME)}
24766
25311
  ${buffer.subarray(0, total).toString("utf8")}`;
24767
25312
  } finally {
24768
25313
  await file.close();
@@ -24778,9 +25323,9 @@ var init_skills2 = __esm(() => {
24778
25323
  });
24779
25324
 
24780
25325
  // packages/sdk/src/permissions.ts
24781
- import { createHash as createHash2, randomUUID as randomUUID5 } from "crypto";
24782
- import { closeSync as closeSync4, existsSync as existsSync2, fstatSync, mkdirSync as mkdirSync11, openSync as openSync4, readSync as readSync2, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
24783
- import { join as join11, resolve as resolve5 } from "path";
25326
+ import { createHash as createHash2, randomUUID as randomUUID6 } from "crypto";
25327
+ import { closeSync as closeSync5, existsSync as existsSync3, fstatSync, mkdirSync as mkdirSync11, openSync as openSync5, readSync as readSync2, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
25328
+ import { join as join12, resolve as resolve6 } from "path";
24784
25329
  function validateRules(value) {
24785
25330
  if (!Array.isArray(value) || value.length > MAX_RULES)
24786
25331
  throw new TypeError("Invalid permission rules.");
@@ -24795,13 +25340,13 @@ class PermissionManager {
24795
25340
  path;
24796
25341
  sessions = new Map;
24797
25342
  constructor(workspace) {
24798
- const key = createHash2("sha256").update(resolve5(workspace)).digest("hex");
24799
- this.path = join11(ringkoRoot(), "permissions", `${key}.json`);
25343
+ const key = createHash2("sha256").update(resolve6(workspace)).digest("hex");
25344
+ this.path = join12(ringkoRoot(), "permissions", `${key}.json`);
24800
25345
  }
24801
25346
  saved() {
24802
- if (!existsSync2(this.path))
25347
+ if (!existsSync3(this.path))
24803
25348
  return [];
24804
- const descriptor = openSync4(this.path, "r");
25349
+ const descriptor = openSync5(this.path, "r");
24805
25350
  const buffer = Buffer.alloc(MAX_FILE_BYTES2 + 1);
24806
25351
  let size = 0;
24807
25352
  try {
@@ -24814,7 +25359,7 @@ class PermissionManager {
24814
25359
  size += count;
24815
25360
  }
24816
25361
  } finally {
24817
- closeSync4(descriptor);
25362
+ closeSync5(descriptor);
24818
25363
  }
24819
25364
  if (size > MAX_FILE_BYTES2)
24820
25365
  throw new Error("Permission file exceeds 256 KiB.");
@@ -24843,10 +25388,10 @@ class PermissionManager {
24843
25388
  this.sessions.clear();
24844
25389
  }
24845
25390
  updateSaved(change) {
24846
- mkdirSync11(join11(ringkoRoot(), "permissions"), { recursive: true, mode: 448 });
25391
+ mkdirSync11(join12(ringkoRoot(), "permissions"), { recursive: true, mode: 448 });
24847
25392
  let lock;
24848
25393
  try {
24849
- lock = openSync4(`${this.path}.lock`, "wx", 384);
25394
+ lock = openSync5(`${this.path}.lock`, "wx", 384);
24850
25395
  } catch {
24851
25396
  throw new Error(`Permission rules are locked; retry or remove the stale lock after confirming no writer is active: ${this.path}.lock`);
24852
25397
  }
@@ -24858,17 +25403,17 @@ class PermissionManager {
24858
25403
  const data = JSON.stringify({ version: 1, rules: next });
24859
25404
  if (Buffer.byteLength(data) > MAX_FILE_BYTES2)
24860
25405
  throw new Error("Permission rules exceed 256 KiB.");
24861
- const temporary = `${this.path}.${randomUUID5()}.tmp`;
25406
+ const temporary = `${this.path}.${randomUUID6()}.tmp`;
24862
25407
  try {
24863
25408
  writeFileSync9(temporary, data, { flag: "wx", mode: 384 });
24864
- renameSync3(temporary, this.path);
25409
+ renameSync4(temporary, this.path);
24865
25410
  } finally {
24866
- if (existsSync2(temporary))
25411
+ if (existsSync3(temporary))
24867
25412
  unlinkSync2(temporary);
24868
25413
  }
24869
25414
  return true;
24870
25415
  } finally {
24871
- closeSync4(lock);
25416
+ closeSync5(lock);
24872
25417
  unlinkSync2(`${this.path}.lock`);
24873
25418
  }
24874
25419
  }
@@ -25049,7 +25594,7 @@ var init_mcp_manager = __esm(() => {
25049
25594
  });
25050
25595
 
25051
25596
  // packages/sdk/src/runtime.ts
25052
- import { resolve as resolve6 } from "path";
25597
+ import { resolve as resolve7 } from "path";
25053
25598
  function applyToolPolicy(agent, workflow) {
25054
25599
  for (const tool of agent.tools.list())
25055
25600
  if (!workflowAllowsTool(workflow, tool.name))
@@ -25068,6 +25613,7 @@ function registerRuntimeTools(agent, config, workspace, host = {}, session) {
25068
25613
  registerSessionTools(agent.tools, { todos, ask: host.ask ?? (async () => {
25069
25614
  throw new Error("Questions require an interactive host.");
25070
25615
  }) });
25616
+ registerSessionQueryTools(agent.tools, { workspace });
25071
25617
  if (config.capabilities?.network)
25072
25618
  registerNetworkTools(agent.tools, {
25073
25619
  allowPrivateHosts: config.capabilities.privateNetwork === true,
@@ -25093,7 +25639,7 @@ class RuntimeManager {
25093
25639
  constructor(workspace, log) {
25094
25640
  if (typeof workspace !== "string" || !workspace.trim())
25095
25641
  throw new TypeError("Runtime requires a workspace.");
25096
- this.workspace = resolve6(workspace);
25642
+ this.workspace = resolve7(workspace);
25097
25643
  this.permissions = new PermissionManager(this.workspace);
25098
25644
  this.mcp = new McpManager(this.workspace);
25099
25645
  this.log = log ?? new EventLog;
@@ -35698,7 +36244,7 @@ function createProviderExecutedToolFactory({
35698
36244
  supportsDeferredResults
35699
36245
  });
35700
36246
  }
35701
- async function resolve9(value) {
36247
+ async function resolve10(value) {
35702
36248
  if (typeof value === "function") {
35703
36249
  value = value();
35704
36250
  }
@@ -41844,7 +42390,7 @@ var anthropicErrorDataSchema, anthropicFailedResponseHandler, anthropicUploadFil
41844
42390
  });
41845
42391
  }
41846
42392
  async getBatchHeaders(headers) {
41847
- return combineHeaders(this.options.config.headers ? await resolve9(this.options.config.headers) : undefined, headers);
42393
+ return combineHeaders(this.options.config.headers ? await resolve10(this.options.config.headers) : undefined, headers);
41848
42394
  }
41849
42395
  }, bash_20241022InputSchema, bash_20241022_internal, bash_20250124InputSchema, bash_20250124_internal, computer_20241022InputSchema, computer_20241022, computer_20250124InputSchema, computer_20250124, computer_20251124InputSchema, computer_20251124, memory_20250818InputSchema, memory_20250818, textEditor_20241022InputSchema, textEditor_20241022, textEditor_20250124InputSchema, textEditor_20250124, textEditor_20250429InputSchema, textEditor_20250429, toolSearchBm25_20251119OutputSchema, toolSearchBm25_20251119InputSchema, factory13, toolSearchBm25_20251119 = (args = {}) => {
41850
42396
  return factory13(args);
@@ -41857,7 +42403,7 @@ var anthropicErrorDataSchema, anthropicFailedResponseHandler, anthropicUploadFil
41857
42403
  return this.config.provider;
41858
42404
  }
41859
42405
  async getHeaders() {
41860
- return combineHeaders(await resolve9(this.config.headers), {
42406
+ return combineHeaders(await resolve10(this.config.headers), {
41861
42407
  "anthropic-beta": "skills-2025-10-02"
41862
42408
  });
41863
42409
  }
@@ -44022,10 +44568,10 @@ var init_dist5 = __esm(() => {
44022
44568
  betas,
44023
44569
  headers
44024
44570
  }) {
44025
- return combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
44571
+ return combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
44026
44572
  }
44027
44573
  async getBetasFromHeaders(requestHeaders) {
44028
- const configHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
44574
+ const configHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
44029
44575
  const configBetaHeader = configHeaders?.["anthropic-beta"] ?? "";
44030
44576
  const requestBetaHeader = requestHeaders?.["anthropic-beta"] ?? "";
44031
44577
  return new Set([
@@ -50614,7 +51160,7 @@ var VERSION3 = "4.0.82", googleErrorDataSchema, googleFailedResponseHandler, goo
50614
51160
  return { ...prepared, warnings: [...warnings, ...prepared.warnings] };
50615
51161
  }
50616
51162
  async getHeaders(headers) {
50617
- return combineHeaders(this.batchConfig.headers ? await resolve9(this.batchConfig.headers) : undefined, headers);
51163
+ return combineHeaders(this.batchConfig.headers ? await resolve10(this.batchConfig.headers) : undefined, headers);
50618
51164
  }
50619
51165
  getBaseOrigin() {
50620
51166
  return this.batchConfig.baseURL.replace(/\/v1beta$/, "");
@@ -50852,7 +51398,7 @@ var VERSION3 = "4.0.82", googleErrorDataSchema, googleFailedResponseHandler, goo
50852
51398
  }
50853
51399
  const videos = [];
50854
51400
  const videoMetadata = [];
50855
- const resolvedHeaders = await resolve9(this.config.headers);
51401
+ const resolvedHeaders = await resolve10(this.config.headers);
50856
51402
  const apiKey = resolvedHeaders?.["x-goog-api-key"];
50857
51403
  for (const generatedSample of response.generateVideoResponse.generatedSamples) {
50858
51404
  if (generatedSample.video?.uri) {
@@ -50894,7 +51440,7 @@ var VERSION3 = "4.0.82", googleErrorDataSchema, googleFailedResponseHandler, goo
50894
51440
  const { instances, parameters, warnings } = await this.buildRequest(options);
50895
51441
  const { value: operation, responseHeaders } = await postJsonToApi({
50896
51442
  url: `${this.config.baseURL}/models/${this.modelId}:predictLongRunning`,
50897
- headers: combineHeaders(await resolve9(this.config.headers), options.headers),
51443
+ headers: combineHeaders(await resolve10(this.config.headers), options.headers),
50898
51444
  body: {
50899
51445
  instances,
50900
51446
  parameters
@@ -50927,7 +51473,7 @@ var VERSION3 = "4.0.82", googleErrorDataSchema, googleFailedResponseHandler, goo
50927
51473
  const { value: statusOperation, responseHeaders } = await getFromApi({
50928
51474
  url: `${this.config.baseURL}/${operationName}`,
50929
51475
  validateUrl: false,
50930
- headers: combineHeaders(await resolve9(this.config.headers), options.headers),
51476
+ headers: combineHeaders(await resolve10(this.config.headers), options.headers),
50931
51477
  successfulResponseHandler: createJsonResponseHandler(googleOperationSchema),
50932
51478
  failedResponseHandler: googleFailedResponseHandler,
50933
51479
  abortSignal: options.abortSignal,
@@ -51577,7 +52123,7 @@ var init_dist6 = __esm(() => {
51577
52123
  values
51578
52124
  });
51579
52125
  }
51580
- const mergedHeaders = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, headers);
52126
+ const mergedHeaders = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, headers);
51581
52127
  const multimodalContent = googleOptions?.content;
51582
52128
  validateMultimodalContentLength({ multimodalContent, values });
51583
52129
  if (values.length === 1) {
@@ -52161,7 +52707,7 @@ var init_dist6 = __esm(() => {
52161
52707
  extraHeaders,
52162
52708
  toolNameMapping
52163
52709
  } = await this.getArgs(options);
52164
- const mergedHeaders = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers, extraHeaders);
52710
+ const mergedHeaders = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers, extraHeaders);
52165
52711
  const {
52166
52712
  responseHeaders,
52167
52713
  value: response,
@@ -52201,7 +52747,7 @@ var init_dist6 = __esm(() => {
52201
52747
  toolNameMapping
52202
52748
  } = await this.getArgs(options, { isStreaming: true });
52203
52749
  const wrapProviderMetadata = (payload) => Object.fromEntries(providerOptionsNames.map((name) => [name, payload]));
52204
- const headers = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers, extraHeaders);
52750
+ const headers = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers, extraHeaders);
52205
52751
  const { responseHeaders, value: response } = await postJsonToApi({
52206
52752
  url: `${this.config.baseURL}/${getModelPath(this.modelId)}:streamGenerateContent?alt=sse`,
52207
52753
  headers,
@@ -53203,7 +53749,7 @@ var init_dist6 = __esm(() => {
53203
53749
  rawValue: rawResponse
53204
53750
  } = await postJsonToApi({
53205
53751
  url: `${this.config.baseURL}/models/${this.modelId}:generateContent`,
53206
- headers: combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers),
53752
+ headers: combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers),
53207
53753
  body: requestBody,
53208
53754
  failedResponseHandler: googleFailedResponseHandler,
53209
53755
  successfulResponseHandler: createJsonResponseHandler(googleSpeechResponseSchema),
@@ -53885,7 +54431,7 @@ var init_dist6 = __esm(() => {
53885
54431
  async doGenerate(options) {
53886
54432
  const { args, warnings, isAgent, pollingTimeoutMs } = await this.getArgs(options);
53887
54433
  const url = `${this.config.baseURL}/interactions`;
53888
- const mergedHeaders = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers);
54434
+ const mergedHeaders = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers);
53889
54435
  const postResult = await postJsonToApi({
53890
54436
  url,
53891
54437
  headers: mergedHeaders,
@@ -53961,7 +54507,7 @@ var init_dist6 = __esm(() => {
53961
54507
  async doStream(options) {
53962
54508
  const { args, warnings, isBackground, pollingTimeoutMs } = await this.getArgs(options);
53963
54509
  const url = `${this.config.baseURL}/interactions`;
53964
- const mergedHeaders = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers);
54510
+ const mergedHeaders = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers);
53965
54511
  if (isBackground) {
53966
54512
  return this.doStreamBackground({
53967
54513
  args,
@@ -54112,7 +54658,7 @@ var init_dist6 = __esm(() => {
54112
54658
  rawValue: rawResponse
54113
54659
  } = await postJsonToApi({
54114
54660
  url: `${this.config.baseURL}/interactions`,
54115
- headers: combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers),
54661
+ headers: combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers),
54116
54662
  body: requestBody,
54117
54663
  failedResponseHandler: googleFailedResponseHandler,
54118
54664
  successfulResponseHandler: createJsonResponseHandler(googleInteractionsTranscriptionResponseSchema),
@@ -54168,7 +54714,7 @@ var init_dist6 = __esm(() => {
54168
54714
  const warnings = [];
54169
54715
  const googleOptions = await this.parseOptions(options.providerOptions);
54170
54716
  validateLiveInputAudioFormat(options.inputAudioFormat);
54171
- const headers = combineHeaders(this.config.headers ? await resolve9(this.config.headers) : undefined, options.headers);
54717
+ const headers = combineHeaders(this.config.headers ? await resolve10(this.config.headers) : undefined, options.headers);
54172
54718
  let apiKey;
54173
54719
  for (const [key, value] of Object.entries(headers)) {
54174
54720
  if (key.toLowerCase() === "x-goog-api-key" && value != null) {
@@ -54496,21 +55042,21 @@ function createOpenAIStreamError({
54496
55042
  });
54497
55043
  }
54498
55044
  function parseStreamError(frame) {
54499
- const value = asRecord3(frame);
55045
+ const value = asRecord4(frame);
54500
55046
  if (value == null) {
54501
55047
  return;
54502
55048
  }
54503
55049
  if (value.type === "response.failed") {
54504
- const response = asRecord3(value.response);
54505
- const responseError = asRecord3(response?.error);
55050
+ const response = asRecord4(value.response);
55051
+ const responseError = asRecord4(response?.error);
54506
55052
  return typeof responseError?.message === "string" ? {
54507
55053
  message: responseError.message,
54508
55054
  code: getStringOrNumber(responseError.code),
54509
55055
  type: "response.failed"
54510
55056
  } : undefined;
54511
55057
  }
54512
- const error = asRecord3(value.error) ?? value;
54513
- return typeof error.message === "string" && (asRecord3(value.error) != null || typeof error.type === "string" || ("code" in error) || ("param" in error)) ? {
55058
+ const error = asRecord4(value.error) ?? value;
55059
+ return typeof error.message === "string" && (asRecord4(value.error) != null || typeof error.type === "string" || ("code" in error) || ("param" in error)) ? {
54514
55060
  message: error.message,
54515
55061
  code: getStringOrNumber(error.code),
54516
55062
  type: typeof error.type === "string" ? error.type : undefined
@@ -54540,7 +55086,7 @@ function getStatusCode(error) {
54540
55086
  return 504;
54541
55087
  return 500;
54542
55088
  }
54543
- function asRecord3(value) {
55089
+ function asRecord4(value) {
54544
55090
  return typeof value === "object" && value != null ? value : undefined;
54545
55091
  }
54546
55092
  function getStringOrNumber(value) {
@@ -67980,7 +68526,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
67980
68526
  const { value } = await getFromApi({
67981
68527
  url: `${this.config.baseURL}/config`,
67982
68528
  validateUrl: false,
67983
- headers: this.config.headers ? await resolve9(this.config.headers) : undefined,
68529
+ headers: this.config.headers ? await resolve10(this.config.headers) : undefined,
67984
68530
  successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema),
67985
68531
  failedResponseHandler: createJsonErrorResponseHandler({
67986
68532
  errorSchema: z.any(),
@@ -67999,7 +68545,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
67999
68545
  const { value } = await getFromApi({
68000
68546
  url: `${baseUrl.origin}/v1/credits`,
68001
68547
  validateUrl: false,
68002
- headers: this.config.headers ? await resolve9(this.config.headers) : undefined,
68548
+ headers: this.config.headers ? await resolve10(this.config.headers) : undefined,
68003
68549
  successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema),
68004
68550
  failedResponseHandler: createJsonErrorResponseHandler({
68005
68551
  errorSchema: z.any(),
@@ -68046,7 +68592,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68046
68592
  const { value } = await getFromApi({
68047
68593
  url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
68048
68594
  validateUrl: false,
68049
- headers: this.config.headers ? await resolve9(this.config.headers) : undefined,
68595
+ headers: this.config.headers ? await resolve10(this.config.headers) : undefined,
68050
68596
  successfulResponseHandler: createJsonResponseHandler(gatewaySpendReportResponseSchema),
68051
68597
  failedResponseHandler: createJsonErrorResponseHandler({
68052
68598
  errorSchema: z.any(),
@@ -68069,7 +68615,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68069
68615
  const { value } = await getFromApi({
68070
68616
  url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
68071
68617
  validateUrl: false,
68072
- headers: this.config.headers ? await resolve9(this.config.headers) : undefined,
68618
+ headers: this.config.headers ? await resolve10(this.config.headers) : undefined,
68073
68619
  successfulResponseHandler: createJsonResponseHandler(gatewayGenerationInfoResponseSchema),
68074
68620
  failedResponseHandler: createJsonErrorResponseHandler({
68075
68621
  errorSchema: z.any(),
@@ -68098,13 +68644,13 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68098
68644
  }) {
68099
68645
  assertTextBatchRequests3(requests);
68100
68646
  const modelId = validateSingleModel2(requests);
68101
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68647
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68102
68648
  const idempotencyKey = getGatewayBatchIdempotencyKey(providerOptions);
68103
68649
  const forwardedProviderOptions = omitGatewayIdempotencyKey(providerOptions);
68104
68650
  try {
68105
68651
  const { value: responseBody } = await postJsonToApi({
68106
68652
  url: this.getBatchUrl("start"),
68107
- headers: combineHeaders(resolvedHeaders, headers, { "ai-model-id": modelId }, await resolve9(this.config.o11yHeaders), idempotencyKey != null ? { "idempotency-key": idempotencyKey } : undefined),
68653
+ headers: combineHeaders(resolvedHeaders, headers, { "ai-model-id": modelId }, await resolve10(this.config.o11yHeaders), idempotencyKey != null ? { "idempotency-key": idempotencyKey } : undefined),
68108
68654
  body: {
68109
68655
  ...webhookUrl != null && { callbackUrl: webhookUrl },
68110
68656
  requests: requests.map((request) => ({
@@ -68142,11 +68688,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68142
68688
  headers,
68143
68689
  abortSignal
68144
68690
  }) {
68145
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68691
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68146
68692
  try {
68147
68693
  const { value: responseBody } = await postJsonToApi({
68148
68694
  url: this.getBatchUrl("status"),
68149
- headers: combineHeaders(resolvedHeaders, headers, await resolve9(this.config.o11yHeaders)),
68695
+ headers: combineHeaders(resolvedHeaders, headers, await resolve10(this.config.o11yHeaders)),
68150
68696
  body: { batchId },
68151
68697
  successfulResponseHandler: createJsonResponseHandler(gatewayBatchStatusResponseSchema),
68152
68698
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -68169,11 +68715,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68169
68715
  headers,
68170
68716
  abortSignal
68171
68717
  }) {
68172
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68718
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68173
68719
  try {
68174
68720
  const { value: lines } = await postJsonToApi({
68175
68721
  url: this.getBatchUrl("results"),
68176
- headers: combineHeaders(resolvedHeaders, headers, await resolve9(this.config.o11yHeaders)),
68722
+ headers: combineHeaders(resolvedHeaders, headers, await resolve10(this.config.o11yHeaders)),
68177
68723
  body: { batchId },
68178
68724
  successfulResponseHandler: createJsonLinesResponseHandler(gatewayBatchItemResultLineSchema),
68179
68725
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -68196,11 +68742,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68196
68742
  headers,
68197
68743
  abortSignal
68198
68744
  }) {
68199
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68745
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68200
68746
  try {
68201
68747
  const { value: responseBody } = await postJsonToApi({
68202
68748
  url: this.getBatchUrl("cancel"),
68203
- headers: combineHeaders(resolvedHeaders, headers, await resolve9(this.config.o11yHeaders)),
68749
+ headers: combineHeaders(resolvedHeaders, headers, await resolve10(this.config.o11yHeaders)),
68204
68750
  body: { batchId },
68205
68751
  successfulResponseHandler: createJsonResponseHandler(gatewayBatchStatusResponseSchema),
68206
68752
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -68237,11 +68783,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68237
68783
  }
68238
68784
  async doGenerate(options) {
68239
68785
  const { headers, abortSignal } = options;
68240
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68786
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68241
68787
  try {
68242
68788
  const { responseHeaders, value: responseBody } = await postJsonToApi({
68243
68789
  url: this.getUrl(),
68244
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders), { accept: "text/event-stream" }),
68790
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders), { accept: "text/event-stream" }),
68245
68791
  body: this.buildRequestBody(options),
68246
68792
  successfulResponseHandler: async ({
68247
68793
  response,
@@ -68336,11 +68882,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68336
68882
  }
68337
68883
  async doStart(options) {
68338
68884
  const { headers, abortSignal, webhookUrl } = options;
68339
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68885
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68340
68886
  try {
68341
68887
  const { responseHeaders, value: responseBody } = await postJsonToApi({
68342
68888
  url: this.getStartUrl(),
68343
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
68889
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68344
68890
  body: {
68345
68891
  ...this.buildRequestBody(options),
68346
68892
  ...webhookUrl && { callbackUrl: webhookUrl }
@@ -68372,11 +68918,11 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68372
68918
  abortSignal,
68373
68919
  headers
68374
68920
  }) {
68375
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
68921
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68376
68922
  try {
68377
68923
  const { responseHeaders, value: responseBody } = await postJsonToApi({
68378
68924
  url: this.getStatusUrl(),
68379
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
68925
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68380
68926
  body: { operation },
68381
68927
  successfulResponseHandler: createJsonResponseHandler(gatewayVideoStatusResponseSchema),
68382
68928
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -68500,7 +69046,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68500
69046
  schema: gatewayEvaluationProviderOptionsSchema
68501
69047
  });
68502
69048
  const validatedProviderOptions = gatewayOptions == null ? providerOptions : { ...providerOptions, gateway: gatewayOptions };
68503
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69049
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68504
69050
  try {
68505
69051
  const {
68506
69052
  responseHeaders,
@@ -68508,7 +69054,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68508
69054
  rawValue
68509
69055
  } = await postJsonToApi({
68510
69056
  url: this.getUrl(),
68511
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
69057
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68512
69058
  body: {
68513
69059
  state,
68514
69060
  questions,
@@ -68564,7 +69110,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68564
69110
  abortSignal,
68565
69111
  providerOptions
68566
69112
  }) {
68567
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69113
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68568
69114
  try {
68569
69115
  const {
68570
69116
  responseHeaders,
@@ -68572,7 +69118,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68572
69118
  rawValue
68573
69119
  } = await postJsonToApi({
68574
69120
  url: this.getUrl(),
68575
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
69121
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68576
69122
  body: {
68577
69123
  documents,
68578
69124
  query,
@@ -68626,7 +69172,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68626
69172
  headers,
68627
69173
  abortSignal
68628
69174
  }) {
68629
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69175
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68630
69176
  try {
68631
69177
  const {
68632
69178
  responseHeaders,
@@ -68634,7 +69180,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68634
69180
  rawValue
68635
69181
  } = await postJsonToApi({
68636
69182
  url: this.getUrl(),
68637
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
69183
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68638
69184
  body: {
68639
69185
  text,
68640
69186
  ...voice && { voice },
@@ -68692,7 +69238,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68692
69238
  headers,
68693
69239
  abortSignal
68694
69240
  }) {
68695
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69241
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
68696
69242
  try {
68697
69243
  const {
68698
69244
  responseHeaders,
@@ -68700,7 +69246,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68700
69246
  rawValue
68701
69247
  } = await postJsonToApi({
68702
69248
  url: this.getUrl(),
68703
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
69249
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
68704
69250
  body: {
68705
69251
  audio: audio instanceof Uint8Array ? convertUint8ArrayToBase64(audio) : audio,
68706
69252
  mediaType,
@@ -68734,7 +69280,7 @@ var import_oidc, import_oidc2, GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realti
68734
69280
  }
68735
69281
  async doStream(options) {
68736
69282
  const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date;
68737
- const headers = combineHeaders(await resolve9(this.config.headers ?? {}), options.headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders));
69283
+ const headers = combineHeaders(await resolve10(this.config.headers ?? {}), options.headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders));
68738
69284
  const authMethod = await parseAuthMethod(headers);
68739
69285
  const startFrame = {
68740
69286
  type: TRANSCRIPTION_STREAM_START_FRAME_TYPE,
@@ -69339,7 +69885,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69339
69885
  async doGenerate(options) {
69340
69886
  const { args, warnings } = await this.getArgs(options);
69341
69887
  const { abortSignal } = options;
69342
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69888
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
69343
69889
  try {
69344
69890
  const {
69345
69891
  responseHeaders,
@@ -69347,7 +69893,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69347
69893
  rawValue: rawResponse
69348
69894
  } = await postJsonToApi({
69349
69895
  url: this.getUrl(),
69350
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve9(this.config.o11yHeaders)),
69896
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve10(this.config.o11yHeaders)),
69351
69897
  body: args,
69352
69898
  successfulResponseHandler: createJsonResponseHandler(z.any()),
69353
69899
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -69370,11 +69916,11 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69370
69916
  async doStream(options) {
69371
69917
  const { args, warnings } = await this.getArgs(options);
69372
69918
  const { abortSignal } = options;
69373
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
69919
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
69374
69920
  try {
69375
69921
  const { value: response, responseHeaders } = await postJsonToApi({
69376
69922
  url: this.getUrl(),
69377
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve9(this.config.o11yHeaders)),
69923
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve10(this.config.o11yHeaders)),
69378
69924
  body: args,
69379
69925
  successfulResponseHandler: createEventSourceResponseHandler(z.any()),
69380
69926
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -69469,7 +70015,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69469
70015
  abortSignal,
69470
70016
  providerOptions
69471
70017
  }) {
69472
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
70018
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
69473
70019
  try {
69474
70020
  const {
69475
70021
  responseHeaders,
@@ -69477,7 +70023,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69477
70023
  rawValue
69478
70024
  } = await postJsonToApi({
69479
70025
  url: this.getUrl(),
69480
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
70026
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
69481
70027
  body: {
69482
70028
  values,
69483
70029
  ...providerOptions ? { providerOptions } : {}
@@ -69569,11 +70115,11 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
69569
70115
  headers,
69570
70116
  abortSignal
69571
70117
  }) {
69572
- const resolvedHeaders = this.config.headers ? await resolve9(this.config.headers) : undefined;
70118
+ const resolvedHeaders = this.config.headers ? await resolve10(this.config.headers) : undefined;
69573
70119
  try {
69574
70120
  const { responseHeaders, value: responseBody } = await postJsonToApi({
69575
70121
  url: this.getUrl(),
69576
- headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve9(this.config.o11yHeaders)),
70122
+ headers: combineHeaders(resolvedHeaders, headers ?? {}, this.getModelConfigHeaders(), await resolve10(this.config.o11yHeaders)),
69577
70123
  body: {
69578
70124
  prompt,
69579
70125
  n,
@@ -76759,12 +77305,12 @@ function normalizeStreamProviderError(error) {
76759
77305
  if (isError(error) || AISDKError.isInstance(error) || StreamProviderError.isInstance(error)) {
76760
77306
  return error;
76761
77307
  }
76762
- const outer = asRecord4(error);
77308
+ const outer = asRecord5(error);
76763
77309
  if (outer == null) {
76764
77310
  return error;
76765
77311
  }
76766
77312
  const providerStreamError = isProviderStreamError(error);
76767
- const details = providerStreamError ? outer : asRecord4(asRecord4(outer.response)?.error) ?? asRecord4(outer.error) ?? outer;
77313
+ const details = providerStreamError ? outer : asRecord5(asRecord5(outer.response)?.error) ?? asRecord5(outer.error) ?? outer;
76768
77314
  if (typeof details.message !== "string") {
76769
77315
  return error;
76770
77316
  }
@@ -76800,7 +77346,7 @@ function inferExactMessageMetadata(message) {
76800
77346
  function isRetryableStatusCode22(statusCode) {
76801
77347
  return statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500);
76802
77348
  }
76803
- function asRecord4(value) {
77349
+ function asRecord5(value) {
76804
77350
  return typeof value === "object" && value != null ? value : undefined;
76805
77351
  }
76806
77352
  function isError(value) {
@@ -77808,7 +78354,7 @@ var __defProp2, __export2 = (target, all) => {
77808
78354
  const schema = asSchema(inputSchema);
77809
78355
  return {
77810
78356
  name: "object",
77811
- responseFormat: resolve9(schema.jsonSchema).then((jsonSchema3) => ({
78357
+ responseFormat: resolve10(schema.jsonSchema).then((jsonSchema3) => ({
77812
78358
  type: "json",
77813
78359
  schema: jsonSchema3,
77814
78360
  ...name25 != null && { name: name25 },
@@ -77880,7 +78426,7 @@ var __defProp2, __export2 = (target, all) => {
77880
78426
  const elementSchema = asSchema(inputElementSchema);
77881
78427
  return {
77882
78428
  name: "array",
77883
- responseFormat: resolve9(elementSchema.jsonSchema).then((jsonSchema3) => {
78429
+ responseFormat: resolve10(elementSchema.jsonSchema).then((jsonSchema3) => {
77884
78430
  const {
77885
78431
  $schema: _$schema,
77886
78432
  definitions,
@@ -81358,7 +81904,7 @@ function tokenCount(value) {
81358
81904
  }
81359
81905
  return;
81360
81906
  }
81361
- function asRecord5(value) {
81907
+ function asRecord6(value) {
81362
81908
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
81363
81909
  }
81364
81910
  function providerErrorFields(body) {
@@ -81369,8 +81915,8 @@ function providerErrorFields(body) {
81369
81915
  } catch {
81370
81916
  return fields;
81371
81917
  }
81372
- const outer = asRecord5(parsed);
81373
- const error = asRecord5(outer?.error) ?? outer;
81918
+ const outer = asRecord6(parsed);
81919
+ const error = asRecord6(outer?.error) ?? outer;
81374
81920
  if (!error)
81375
81921
  return fields;
81376
81922
  for (const key of ["code", "param", "type"]) {
@@ -81381,7 +81927,7 @@ function providerErrorFields(body) {
81381
81927
  return fields;
81382
81928
  }
81383
81929
  function describeModelError(error) {
81384
- const record = asRecord5(error);
81930
+ const record = asRecord6(error);
81385
81931
  if (record) {
81386
81932
  const parts = [];
81387
81933
  if (typeof record.message === "string" && record.message.length > 0)
@@ -81677,7 +82223,7 @@ var init_github_copilot = __esm(() => {
81677
82223
  });
81678
82224
 
81679
82225
  // packages/providers/src/openai/oauth.ts
81680
- import { randomUUID as randomUUID6 } from "crypto";
82226
+ import { randomUUID as randomUUID7 } from "crypto";
81681
82227
  function describeError(error) {
81682
82228
  return error instanceof Error ? error : new Error(String(error));
81683
82229
  }
@@ -81717,7 +82263,7 @@ function withCodexStore(body) {
81717
82263
  }
81718
82264
  function createOpenAiOauthFetch(accountId) {
81719
82265
  let pending = null;
81720
- const sessionId = randomUUID6();
82266
+ const sessionId = randomUUID7();
81721
82267
  const send = async (input, init) => {
81722
82268
  applyProxyEnv();
81723
82269
  const account = getOAuthAccount(OPENAI_OAUTH_DOMAIN, accountId);
@@ -81832,13 +82378,13 @@ function codexModelsRequest(access, accountId) {
81832
82378
  }
81833
82379
  };
81834
82380
  }
81835
- function asRecord6(value) {
82381
+ function asRecord7(value) {
81836
82382
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
81837
82383
  }
81838
82384
  function toModel(value) {
81839
82385
  if (typeof value === "string" && value.length > 0)
81840
82386
  return { id: value };
81841
- const record = asRecord6(value);
82387
+ const record = asRecord7(value);
81842
82388
  if (!record)
81843
82389
  return;
81844
82390
  const id = record.id ?? record.slug ?? record.name ?? record.model;
@@ -81848,7 +82394,7 @@ function toModel(value) {
81848
82394
  return { id, ...typeof name === "string" && name.length > 0 ? { name } : {} };
81849
82395
  }
81850
82396
  function normalizeModels(payload) {
81851
- const record = asRecord6(payload);
82397
+ const record = asRecord7(payload);
81852
82398
  const candidates = Array.isArray(payload) ? payload : Array.isArray(record?.data) ? record.data : Array.isArray(record?.models) ? record.models : [];
81853
82399
  const seen = new Set;
81854
82400
  const models = [];
@@ -86060,7 +86606,7 @@ var defaultColumns = 80, defaultRows = 24, exec2 = (command, arguments_, { shell
86060
86606
  };
86061
86607
  var init_terminal_size = () => {};
86062
86608
 
86063
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/utils.js
86609
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/utils.js
86064
86610
  var getWindowSize = (stdout) => {
86065
86611
  const { columns, rows } = stdout;
86066
86612
  if (columns && rows) {
@@ -96810,7 +97356,7 @@ var init_widest_line = __esm(() => {
96810
97356
  init_string_width();
96811
97357
  });
96812
97358
 
96813
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/measure-text.js
97359
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/measure-text.js
96814
97360
  var cache, measureText = (text) => {
96815
97361
  if (text.length === 0) {
96816
97362
  return {
@@ -97784,7 +98330,7 @@ var init_cli_truncate = __esm(() => {
97784
98330
  validPositions = new Set(["start", "middle", "end"]);
97785
98331
  });
97786
98332
 
97787
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/wrap-text.js
98333
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/wrap-text.js
97788
98334
  var cache2, wrapText = (text, maxWidth, wrapType) => {
97789
98335
  const cacheKey = text + String(maxWidth) + String(wrapType);
97790
98336
  const cachedText = cache2[cacheKey];
@@ -97825,7 +98371,7 @@ var init_wrap_text = __esm(() => {
97825
98371
  wrap_text_default = wrapText;
97826
98372
  });
97827
98373
 
97828
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/ansi-tokenizer.js
98374
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/ansi-tokenizer.js
97829
98375
  var bellCharacter = "\x07", escapeCharacter = "\x1B", stringTerminatorCharacter = "\x9C", csiCharacter = "\x9B", oscCharacter = "\x9D", dcsCharacter = "\x90", pmCharacter = "\x9E", apcCharacter = "\x9F", sosCharacter = "\x98", isCsiParameterCharacter2 = (character) => {
97830
98376
  const codePoint = character.codePointAt(0);
97831
98377
  return codePoint !== undefined && codePoint >= 48 && codePoint <= 63;
@@ -98110,7 +98656,7 @@ var bellCharacter = "\x07", escapeCharacter = "\x1B", stringTerminatorCharacter
98110
98656
  return tokens;
98111
98657
  };
98112
98658
 
98113
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/sanitize-ansi.js
98659
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/sanitize-ansi.js
98114
98660
  var sgrParametersRegex, sanitizeAnsi = (text) => {
98115
98661
  if (!hasAnsiControlCharacters(text)) {
98116
98662
  return text;
@@ -98132,7 +98678,7 @@ var init_sanitize_ansi = __esm(() => {
98132
98678
  sanitize_ansi_default = sanitizeAnsi;
98133
98679
  });
98134
98680
 
98135
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/squash-text-nodes.js
98681
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/squash-text-nodes.js
98136
98682
  var squashTextNodes = (node) => {
98137
98683
  let text = "";
98138
98684
  for (let index = 0;index < node.childNodes.length; index++) {
@@ -98160,7 +98706,7 @@ var init_squash_text_nodes = __esm(() => {
98160
98706
  squash_text_nodes_default = squashTextNodes;
98161
98707
  });
98162
98708
 
98163
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/dom.js
98709
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/dom.js
98164
98710
  var createNode = (nodeName) => {
98165
98711
  const node = {
98166
98712
  nodeName,
@@ -98287,7 +98833,7 @@ var init_dom = __esm(async () => {
98287
98833
  await init_src13();
98288
98834
  });
98289
98835
 
98290
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/styles.js
98836
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/styles.js
98291
98837
  var positionEdges, applyPositionStyles = (node, style) => {
98292
98838
  if ("position" in style) {
98293
98839
  let positionType = src_default.POSITION_TYPE_RELATIVE;
@@ -98569,7 +99115,7 @@ var init_styles = __esm(async () => {
98569
99115
  styles_default = styles2;
98570
99116
  });
98571
99117
 
98572
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/devtools-window-polyfill.js
99118
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/devtools-window-polyfill.js
98573
99119
  import ws from "ws";
98574
99120
  var customGlobal;
98575
99121
  var init_devtools_window_polyfill = __esm(() => {
@@ -114722,7 +115268,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
114722
115268
  });
114723
115269
  });
114724
115270
 
114725
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/devtools.js
115271
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/devtools.js
114726
115272
  import WebSocket2 from "ws";
114727
115273
  var import_react_devtools_core, isDevToolsReachable = async () => new Promise((resolve) => {
114728
115274
  const socket = new WebSocket2("ws://localhost:8097");
@@ -114756,7 +115302,7 @@ $ npx react-devtools
114756
115302
  }
114757
115303
  });
114758
115304
 
114759
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/reconciler.js
115305
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/reconciler.js
114760
115306
  import process5 from "process";
114761
115307
  async function loadPackageJson() {
114762
115308
  const fs = await import("fs");
@@ -115061,7 +115607,7 @@ function indentString(string, count = 1, options = {}) {
115061
115607
  return string.replace(regex, indent.repeat(count));
115062
115608
  }
115063
115609
 
115064
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/get-max-width.js
115610
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/get-max-width.js
115065
115611
  var getMaxWidth = (yogaNode) => {
115066
115612
  return yogaNode.getComputedWidth() - yogaNode.getComputedPadding(src_default.EDGE_LEFT) - yogaNode.getComputedPadding(src_default.EDGE_RIGHT) - yogaNode.getComputedBorder(src_default.EDGE_LEFT) - yogaNode.getComputedBorder(src_default.EDGE_RIGHT);
115067
115613
  }, get_max_width_default;
@@ -115653,7 +116199,7 @@ var init_source = __esm(() => {
115653
116199
  source_default = chalk;
115654
116200
  });
115655
116201
 
115656
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/colorize.js
116202
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/colorize.js
115657
116203
  var rgbRegex, ansiRegex2, isNamedColor = (color) => {
115658
116204
  return color in source_default;
115659
116205
  }, colorize = (str, color, type) => {
@@ -115697,7 +116243,7 @@ var init_colorize = __esm(() => {
115697
116243
  colorize_default = colorize;
115698
116244
  });
115699
116245
 
115700
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/render-border.js
116246
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/render-border.js
115701
116247
  var stylePiece = (segment, fg, bg, dim) => {
115702
116248
  let styled = colorize_default(segment, fg, "foreground");
115703
116249
  styled = colorize_default(styled, bg, "background");
@@ -115774,7 +116320,7 @@ var init_render_border = __esm(() => {
115774
116320
  render_border_default = renderBorder;
115775
116321
  });
115776
116322
 
115777
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/render-background.js
116323
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/render-background.js
115778
116324
  var renderBackground = (x, y, node, output) => {
115779
116325
  if (!node.style.backgroundColor) {
115780
116326
  return;
@@ -115800,7 +116346,7 @@ var init_render_background = __esm(() => {
115800
116346
  render_background_default = renderBackground;
115801
116347
  });
115802
116348
 
115803
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/render-node-to-output.js
116349
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/render-node-to-output.js
115804
116350
  var applyPaddingToText = (node, text) => {
115805
116351
  const yogaNode = node.childNodes[0]?.yogaNode;
115806
116352
  if (yogaNode) {
@@ -116247,7 +116793,7 @@ var init_build = __esm(() => {
116247
116793
  init_tokenize();
116248
116794
  });
116249
116795
 
116250
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/output.js
116796
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/output.js
116251
116797
  class OutputCaches {
116252
116798
  widths = new Map;
116253
116799
  blockWidths = new Map;
@@ -116444,7 +116990,7 @@ var init_output = __esm(() => {
116444
116990
  init_build();
116445
116991
  });
116446
116992
 
116447
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/renderer.js
116993
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/renderer.js
116448
116994
  var renderer = (node, isScreenReaderEnabled) => {
116449
116995
  if (node.yogaNode) {
116450
116996
  if (isScreenReaderEnabled) {
@@ -116503,7 +117049,7 @@ var init_renderer = __esm(async () => {
116503
117049
  renderer_default = renderer;
116504
117050
  });
116505
117051
 
116506
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/cursor-helpers.js
117052
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/cursor-helpers.js
116507
117053
  var showCursorEscape = "\x1B[?25h", hideCursorEscape = "\x1B[?25l", cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y, buildCursorSuffix = (visibleLineCount, cursorPosition) => {
116508
117054
  if (!cursorPosition) {
116509
117055
  return "";
@@ -116626,7 +117172,7 @@ var init_cli_cursor = __esm(() => {
116626
117172
  cli_cursor_default = cliCursor;
116627
117173
  });
116628
117174
 
116629
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/log-update.js
117175
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/log-update.js
116630
117176
  var visibleLineCount = (lines, str) => str.endsWith(`
116631
117177
  `) ? lines.length - 1 : lines.length, createStandard = (stream, { showCursor = false } = {}) => {
116632
117178
  let previousLineCount = 0;
@@ -116865,7 +117411,7 @@ var init_log_update = __esm(() => {
116865
117411
  log_update_default = logUpdate;
116866
117412
  });
116867
117413
 
116868
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/write-synchronized.js
117414
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/write-synchronized.js
116869
117415
  function shouldSynchronize(stream, interactive) {
116870
117416
  return "isTTY" in stream && stream.isTTY && (interactive ?? !is_in_ci_default);
116871
117417
  }
@@ -116874,14 +117420,14 @@ var init_write_synchronized = __esm(() => {
116874
117420
  init_is_in_ci();
116875
117421
  });
116876
117422
 
116877
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/instances.js
117423
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/instances.js
116878
117424
  var instances, instances_default;
116879
117425
  var init_instances = __esm(() => {
116880
117426
  instances = new WeakMap;
116881
117427
  instances_default = instances;
116882
117428
  });
116883
117429
 
116884
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/input-parser.js
117430
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/input-parser.js
116885
117431
  var escape2 = "\x1B", pasteStart = "\x1B[200~", pasteEnd = "\x1B[201~", isCsiParameterByte = (byte) => {
116886
117432
  return byte >= 48 && byte <= 63;
116887
117433
  }, isCsiIntermediateByte = (byte) => {
@@ -117053,7 +117599,7 @@ var escape2 = "\x1B", pasteStart = "\x1B[200~", pasteEnd = "\x1B[201~", isCsiPar
117053
117599
  };
117054
117600
  };
117055
117601
 
117056
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/AppContext.js
117602
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/AppContext.js
117057
117603
  var import_react2, noopSuspension, defaultValue, AppContext, AppContext_default;
117058
117604
  var init_AppContext = __esm(() => {
117059
117605
  import_react2 = __toESM(require_react(), 1);
@@ -117077,7 +117623,7 @@ var init_AppContext = __esm(() => {
117077
117623
  AppContext_default = AppContext;
117078
117624
  });
117079
117625
 
117080
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/StdinContext.js
117626
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/StdinContext.js
117081
117627
  import { EventEmitter } from "events";
117082
117628
  import process9 from "process";
117083
117629
  var import_react3, StdinContext, StdinContext_default;
@@ -117095,7 +117641,7 @@ var init_StdinContext = __esm(() => {
117095
117641
  StdinContext_default = StdinContext;
117096
117642
  });
117097
117643
 
117098
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/StdoutContext.js
117644
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/StdoutContext.js
117099
117645
  import process10 from "process";
117100
117646
  var import_react4, StdoutContext, StdoutContext_default;
117101
117647
  var init_StdoutContext = __esm(() => {
@@ -117108,7 +117654,7 @@ var init_StdoutContext = __esm(() => {
117108
117654
  StdoutContext_default = StdoutContext;
117109
117655
  });
117110
117656
 
117111
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/StderrContext.js
117657
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/StderrContext.js
117112
117658
  import process11 from "process";
117113
117659
  var import_react5, StderrContext, StderrContext_default;
117114
117660
  var init_StderrContext = __esm(() => {
@@ -117121,7 +117667,7 @@ var init_StderrContext = __esm(() => {
117121
117667
  StderrContext_default = StderrContext;
117122
117668
  });
117123
117669
 
117124
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/FocusContext.js
117670
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/FocusContext.js
117125
117671
  var import_react6, FocusContext, FocusContext_default;
117126
117672
  var init_FocusContext = __esm(() => {
117127
117673
  import_react6 = __toESM(require_react(), 1);
@@ -117141,7 +117687,7 @@ var init_FocusContext = __esm(() => {
117141
117687
  FocusContext_default = FocusContext;
117142
117688
  });
117143
117689
 
117144
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/AnimationContext.js
117690
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/AnimationContext.js
117145
117691
  var import_react7, animationContext, AnimationContext_default;
117146
117692
  var init_AnimationContext = __esm(() => {
117147
117693
  import_react7 = __toESM(require_react(), 1);
@@ -117158,7 +117704,7 @@ var init_AnimationContext = __esm(() => {
117158
117704
  AnimationContext_default = animationContext;
117159
117705
  });
117160
117706
 
117161
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/CursorContext.js
117707
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/CursorContext.js
117162
117708
  var import_react8, CursorContext, CursorContext_default;
117163
117709
  var init_CursorContext = __esm(() => {
117164
117710
  import_react8 = __toESM(require_react(), 1);
@@ -117454,7 +118000,7 @@ var init_dist13 = __esm(() => {
117454
118000
  dist_default3 = codeExcerpt;
117455
118001
  });
117456
118002
 
117457
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/AccessibilityContext.js
118003
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/AccessibilityContext.js
117458
118004
  var import_react9, accessibilityContext;
117459
118005
  var init_AccessibilityContext = __esm(() => {
117460
118006
  import_react9 = __toESM(require_react(), 1);
@@ -117463,14 +118009,14 @@ var init_AccessibilityContext = __esm(() => {
117463
118009
  });
117464
118010
  });
117465
118011
 
117466
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/BackgroundContext.js
118012
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/BackgroundContext.js
117467
118013
  var import_react10, backgroundContext;
117468
118014
  var init_BackgroundContext = __esm(() => {
117469
118015
  import_react10 = __toESM(require_react(), 1);
117470
118016
  backgroundContext = import_react10.createContext(undefined);
117471
118017
  });
117472
118018
 
117473
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Box.js
118019
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Box.js
117474
118020
  var import_react11, Box, Box_default;
117475
118021
  var init_Box = __esm(() => {
117476
118022
  init_AccessibilityContext();
@@ -117504,7 +118050,7 @@ var init_Box = __esm(() => {
117504
118050
  Box_default = Box;
117505
118051
  });
117506
118052
 
117507
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Text.js
118053
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Text.js
117508
118054
  function Text2({ color, backgroundColor, dimColor = false, bold = false, italic = false, underline = false, strikethrough = false, inverse = false, wrap = "wrap", children, "aria-label": ariaLabel, "aria-hidden": ariaHidden = false }) {
117509
118055
  const { isScreenReaderEnabled } = import_react12.useContext(accessibilityContext);
117510
118056
  const inheritedBackgroundColor = import_react12.useContext(backgroundContext);
@@ -117554,7 +118100,7 @@ var init_Text = __esm(() => {
117554
118100
  import_react12 = __toESM(require_react(), 1);
117555
118101
  });
117556
118102
 
117557
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/ErrorOverview.js
118103
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/ErrorOverview.js
117558
118104
  import * as fs2 from "fs";
117559
118105
  import { cwd } from "process";
117560
118106
  function ErrorOverview({ error }) {
@@ -117601,7 +118147,7 @@ var init_ErrorOverview = __esm(() => {
117601
118147
  });
117602
118148
  });
117603
118149
 
117604
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/ErrorBoundary.js
118150
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/ErrorBoundary.js
117605
118151
  var import_react14, ErrorBoundary;
117606
118152
  var init_ErrorBoundary = __esm(() => {
117607
118153
  init_ErrorOverview();
@@ -117626,7 +118172,7 @@ var init_ErrorBoundary = __esm(() => {
117626
118172
  };
117627
118173
  });
117628
118174
 
117629
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/App.js
118175
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/App.js
117630
118176
  import { EventEmitter as EventEmitter2 } from "events";
117631
118177
  import process12 from "process";
117632
118178
  function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, exitOnCtrlC, onExit, onWaitUntilRenderFlush, onSuspendTerminal, onRegisterInputControl, setCursorPosition, interactive, renderThrottleMs }) {
@@ -118120,7 +118666,7 @@ var init_App = __esm(() => {
118120
118666
  App_default = App;
118121
118667
  });
118122
118668
 
118123
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/kitty-keyboard.js
118669
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/kitty-keyboard.js
118124
118670
  function resolveFlags(flags) {
118125
118671
  let result = 0;
118126
118672
  for (const flag of flags) {
@@ -118149,7 +118695,7 @@ var init_kitty_keyboard = __esm(() => {
118149
118695
  };
118150
118696
  });
118151
118697
 
118152
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/ink.js
118698
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/ink.js
118153
118699
  import process13 from "process";
118154
118700
 
118155
118701
  class Ink {
@@ -118928,7 +119474,7 @@ var init_ink = __esm(async () => {
118928
119474
  isWindowsConsole = process13.platform === "win32";
118929
119475
  });
118930
119476
 
118931
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/render.js
119477
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/render.js
118932
119478
  import { Stream } from "stream";
118933
119479
  import process14 from "process";
118934
119480
  var render = (node, options) => {
@@ -118984,7 +119530,7 @@ var init_render = __esm(async () => {
118984
119530
  render_default = render;
118985
119531
  });
118986
119532
 
118987
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/render-to-string.js
119533
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/render-to-string.js
118988
119534
  var import_constants3;
118989
119535
  var init_render_to_string = __esm(async () => {
118990
119536
  await __promiseAll([
@@ -118996,33 +119542,33 @@ var init_render_to_string = __esm(async () => {
118996
119542
  import_constants3 = __toESM(require_constants(), 1);
118997
119543
  });
118998
119544
 
118999
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Static.js
119545
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Static.js
119000
119546
  var import_react17;
119001
119547
  var init_Static = __esm(() => {
119002
119548
  import_react17 = __toESM(require_react(), 1);
119003
119549
  });
119004
119550
 
119005
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Transform.js
119551
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Transform.js
119006
119552
  var import_react18;
119007
119553
  var init_Transform = __esm(() => {
119008
119554
  init_AccessibilityContext();
119009
119555
  import_react18 = __toESM(require_react(), 1);
119010
119556
  });
119011
119557
 
119012
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Newline.js
119558
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Newline.js
119013
119559
  var import_react19;
119014
119560
  var init_Newline = __esm(() => {
119015
119561
  import_react19 = __toESM(require_react(), 1);
119016
119562
  });
119017
119563
 
119018
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/components/Spacer.js
119564
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/components/Spacer.js
119019
119565
  var import_react20;
119020
119566
  var init_Spacer = __esm(() => {
119021
119567
  init_Box();
119022
119568
  import_react20 = __toESM(require_react(), 1);
119023
119569
  });
119024
119570
 
119025
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/parse-keypress.js
119571
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/parse-keypress.js
119026
119572
  function resolveEventType(value) {
119027
119573
  if (value === 3)
119028
119574
  return "release";
@@ -119438,14 +119984,14 @@ var init_parse_keypress = __esm(() => {
119438
119984
  parse_keypress_default = parseKeypress;
119439
119985
  });
119440
119986
 
119441
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-stdin.js
119987
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-stdin.js
119442
119988
  var import_react21, useStdinContext = () => import_react21.useContext(StdinContext_default);
119443
119989
  var init_use_stdin = __esm(() => {
119444
119990
  init_StdinContext();
119445
119991
  import_react21 = __toESM(require_react(), 1);
119446
119992
  });
119447
119993
 
119448
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-input.js
119994
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-input.js
119449
119995
  var import_react22, useInput = (inputHandler, options = {}) => {
119450
119996
  const { setRawMode, internal_exitOnCtrlC, internal_eventEmitter } = useStdinContext();
119451
119997
  import_react22.useEffect(() => {
@@ -119530,7 +120076,7 @@ var init_use_input = __esm(async () => {
119530
120076
  use_input_default = useInput;
119531
120077
  });
119532
120078
 
119533
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-paste.js
120079
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-paste.js
119534
120080
  var import_react23, usePaste = (handler, options = {}) => {
119535
120081
  const { setRawMode, setBracketedPasteMode, internal_eventEmitter } = useStdinContext();
119536
120082
  import_react23.useEffect(() => {
@@ -119566,7 +120112,7 @@ var init_use_paste = __esm(async () => {
119566
120112
  use_paste_default = usePaste;
119567
120113
  });
119568
120114
 
119569
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-app.js
120115
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-app.js
119570
120116
  var import_react24, useApp = () => import_react24.useContext(AppContext_default), use_app_default;
119571
120117
  var init_use_app = __esm(() => {
119572
120118
  init_AppContext();
@@ -119574,7 +120120,7 @@ var init_use_app = __esm(() => {
119574
120120
  use_app_default = useApp;
119575
120121
  });
119576
120122
 
119577
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-stdout.js
120123
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-stdout.js
119578
120124
  var import_react25, useStdout = () => import_react25.useContext(StdoutContext_default), use_stdout_default;
119579
120125
  var init_use_stdout = __esm(() => {
119580
120126
  init_StdoutContext();
@@ -119582,14 +120128,14 @@ var init_use_stdout = __esm(() => {
119582
120128
  use_stdout_default = useStdout;
119583
120129
  });
119584
120130
 
119585
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-stderr.js
120131
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-stderr.js
119586
120132
  var import_react26;
119587
120133
  var init_use_stderr = __esm(() => {
119588
120134
  init_StderrContext();
119589
120135
  import_react26 = __toESM(require_react(), 1);
119590
120136
  });
119591
120137
 
119592
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-focus.js
120138
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-focus.js
119593
120139
  var import_react27;
119594
120140
  var init_use_focus = __esm(() => {
119595
120141
  init_FocusContext();
@@ -119597,35 +120143,35 @@ var init_use_focus = __esm(() => {
119597
120143
  import_react27 = __toESM(require_react(), 1);
119598
120144
  });
119599
120145
 
119600
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-focus-manager.js
120146
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-focus-manager.js
119601
120147
  var import_react28;
119602
120148
  var init_use_focus_manager = __esm(() => {
119603
120149
  init_FocusContext();
119604
120150
  import_react28 = __toESM(require_react(), 1);
119605
120151
  });
119606
120152
 
119607
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-is-screen-reader-enabled.js
120153
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-is-screen-reader-enabled.js
119608
120154
  var import_react29;
119609
120155
  var init_use_is_screen_reader_enabled = __esm(() => {
119610
120156
  init_AccessibilityContext();
119611
120157
  import_react29 = __toESM(require_react(), 1);
119612
120158
  });
119613
120159
 
119614
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-cursor.js
120160
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-cursor.js
119615
120161
  var import_react30;
119616
120162
  var init_use_cursor = __esm(() => {
119617
120163
  init_CursorContext();
119618
120164
  import_react30 = __toESM(require_react(), 1);
119619
120165
  });
119620
120166
 
119621
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-animation.js
120167
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-animation.js
119622
120168
  var import_react31;
119623
120169
  var init_use_animation = __esm(() => {
119624
120170
  init_AnimationContext();
119625
120171
  import_react31 = __toESM(require_react(), 1);
119626
120172
  });
119627
120173
 
119628
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-window-size.js
120174
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-window-size.js
119629
120175
  var import_react32;
119630
120176
  var init_use_window_size = __esm(() => {
119631
120177
  init_utils();
@@ -119633,7 +120179,7 @@ var init_use_window_size = __esm(() => {
119633
120179
  import_react32 = __toESM(require_react(), 1);
119634
120180
  });
119635
120181
 
119636
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/hooks/use-box-metrics.js
120182
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/hooks/use-box-metrics.js
119637
120183
  var import_react33, emptyMetrics, findRootNode = (node) => {
119638
120184
  if (!node) {
119639
120185
  return;
@@ -119678,10 +120224,10 @@ var init_use_box_metrics = __esm(async () => {
119678
120224
  use_box_metrics_default = useBoxMetrics;
119679
120225
  });
119680
120226
 
119681
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/measure-element.js
120227
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/measure-element.js
119682
120228
  var init_measure_element = () => {};
119683
120229
 
119684
- // node_modules/.pnpm/ink@7.1.1_@types+react@19.3_70993b4e971952190401d8ef62a09bf2/node_modules/ink/build/index.js
120230
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.3.0_react-devtools-core@8.0.0_react@19.3.0/node_modules/ink/build/index.js
119685
120231
  var init_build2 = __esm(async () => {
119686
120232
  init_Box();
119687
120233
  init_Text();
@@ -119858,6 +120404,9 @@ function edit(state, action) {
119858
120404
  return { text: chars.join(""), cursor: start };
119859
120405
  }
119860
120406
  function editorLines(state, columns, maxRows) {
120407
+ return editorViewport(state, columns, maxRows).lines;
120408
+ }
120409
+ function editorViewport(state, columns, maxRows) {
119861
120410
  const width = Math.max(2, columns);
119862
120411
  const rows = [{ before: "", after: "" }];
119863
120412
  let row = 0;
@@ -119892,7 +120441,8 @@ function editorLines(state, columns, maxRows) {
119892
120441
  used += cells;
119893
120442
  }
119894
120443
  const start = Math.max(0, cursorRow - Math.max(1, maxRows) + 1);
119895
- return rows.slice(start, start + Math.max(1, maxRows));
120444
+ const lines = rows.slice(start, start + Math.max(1, maxRows));
120445
+ return { lines, above: start, below: Math.max(0, rows.length - start - lines.length) };
119896
120446
  }
119897
120447
  var INPUT_LIMIT = 65536, HISTORY_LIMIT = 100, segmenter5;
119898
120448
  var init_editor = __esm(() => {
@@ -119922,9 +120472,12 @@ var init_glyphs = __esm(() => {
119922
120472
  var theme, SPINNER_FRAMES;
119923
120473
  var init_theme = __esm(() => {
119924
120474
  theme = {
119925
- brand: "#ff7a1a",
120475
+ brand: "#e58c54",
119926
120476
  userBackground: "#303030",
119927
- tool: "cyan",
120477
+ userText: "#eeeeee",
120478
+ tool: "#b8b8b8",
120479
+ selected: "#383838",
120480
+ shell: "magenta",
119928
120481
  error: "red",
119929
120482
  success: "green",
119930
120483
  dim: "gray",
@@ -119935,6 +120488,22 @@ var init_theme = __esm(() => {
119935
120488
  SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
119936
120489
  });
119937
120490
 
120491
+ // packages/repl/src/terminal-layout.ts
120492
+ function terminalColumns(columns, windows = process.platform === "win32") {
120493
+ return Math.max(1, Math.floor(columns) - (windows ? 1 : 0));
120494
+ }
120495
+ function terminalLayout(rows, modal) {
120496
+ const height = Math.max(6, Math.floor(rows) - 1);
120497
+ const compact = height < 20;
120498
+ return {
120499
+ height,
120500
+ compact,
120501
+ todoRows: modal || height < 16 ? 0 : Math.min(5, Math.floor(height / 5)),
120502
+ jobRows: modal || height < 16 ? 0 : 2,
120503
+ inputRows: Math.max(1, Math.min(5, Math.floor(height / 5)))
120504
+ };
120505
+ }
120506
+
119938
120507
  // node_modules/.pnpm/react@19.3.0/node_modules/react/cjs/react-jsx-dev-runtime.development.js
119939
120508
  var require_react_jsx_dev_runtime_development = __commonJS(function(exports) {
119940
120509
  var React = __toESM(require_react());
@@ -120172,7 +120741,7 @@ function TodoPanel({ todos, maxRows = 5 }) {
120172
120741
  const { stdout } = use_stdout_default();
120173
120742
  if (todos.length === 0 || maxRows <= 0)
120174
120743
  return null;
120175
- const columns = stdout.columns ?? 80;
120744
+ const columns = terminalColumns(stdout.columns ?? 80);
120176
120745
  const padding = columns > 6 ? 1 : 0;
120177
120746
  const width = Math.max(1, columns - padding * 2);
120178
120747
  const completed = todos.filter((todo) => todo.status === "completed").length;
@@ -120243,7 +120812,7 @@ function formatElapsed(ms) {
120243
120812
  const hours = Math.floor(minutes / 60);
120244
120813
  return minutes % 60 === 0 ? `${hours}h` : `${hours}h ${minutes % 60}m`;
120245
120814
  }
120246
- function TaskTree({ tasks, selectedId, columns }) {
120815
+ function TaskTree({ tasks, selectedId, columns, maxRows = MAX_VISIBLE + 2 }) {
120247
120816
  const anyRunning = tasks.some((task) => task.status === "running");
120248
120817
  const [now, setNow] = import_react34.useState(() => Date.now());
120249
120818
  import_react34.useEffect(() => {
@@ -120255,8 +120824,14 @@ function TaskTree({ tasks, selectedId, columns }) {
120255
120824
  if (!tasks.length)
120256
120825
  return null;
120257
120826
  const selected = tasks.find((task) => task.id === selectedId);
120258
- const recent = tasks.slice(-MAX_VISIBLE);
120259
- const visible = selected && !recent.includes(selected) ? [selected, ...tasks.slice(-(MAX_VISIBLE - 1))] : recent;
120827
+ if (maxRows < 3)
120828
+ return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text2, {
120829
+ color: theme.dim,
120830
+ children: fitTerminalLine(`${tasks.length} subagent${tasks.length === 1 ? "" : "s"} \xB7 ${selected ? selected.description : "main"} \xB7 Ctrl+G views`, columns)
120831
+ }, undefined, false, undefined, this);
120832
+ const count = Math.max(1, Math.min(MAX_VISIBLE, maxRows - 2));
120833
+ const recent = tasks.slice(-count);
120834
+ const visible = selected && !recent.includes(selected) ? [selected, ...count > 1 ? tasks.slice(-(count - 1)) : []] : recent;
120260
120835
  const width = Math.max(1, columns - 2);
120261
120836
  const mainViewed = selectedId === undefined;
120262
120837
  return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
@@ -120307,7 +120882,7 @@ function Banner({ modelLabel, workspace }) {
120307
120882
  children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text2, {
120308
120883
  color: theme.brand,
120309
120884
  bold: true,
120310
- children: fitTerminalLine(`RingKo \xB7 ${modelLabel} \xB7 ${workspace}`, stdout.columns ?? 80)
120885
+ children: fitTerminalLine(`RingKo \xB7 ${modelLabel} \xB7 ${workspace}`, terminalColumns(stdout.columns ?? 80))
120311
120886
  }, undefined, false, undefined, this)
120312
120887
  }, undefined, false, undefined, this);
120313
120888
  }
@@ -121940,6 +122515,8 @@ function toolResultSummary(item) {
121940
122515
  const parsed = JSON.parse(item.text);
121941
122516
  if (typeof parsed === "object" && parsed !== null) {
121942
122517
  const record = parsed;
122518
+ if (!item.failed && item.toolName === "tree" && typeof record.directories === "number" && typeof record.files === "number")
122519
+ return `${record.directories} ${record.directories === 1 ? "directory" : "directories"} \xB7 ${record.files} file${record.files === 1 ? "" : "s"}${record.truncated === true ? " (truncated)" : ""}`;
121943
122520
  if (typeof record.exitCode === "number" || record.exitCode === null)
121944
122521
  return `Exit ${record.exitCode ?? "unknown"}${record.timedOut === true ? " (timed out)" : ""}${record.truncated === true ? " (truncated)" : ""}`;
121945
122522
  if (item.failed)
@@ -121949,7 +122526,7 @@ function toolResultSummary(item) {
121949
122526
  if (Array.isArray(record.matches)) {
121950
122527
  const count = record.matches.length;
121951
122528
  const unit = item.toolName === "glob" ? "file" : "match";
121952
- return `${count} ${unit}${count === 1 ? "" : "s"}${truncated}`;
122529
+ return `${count} ${unit}${count === 1 ? "" : unit === "match" ? "es" : "s"}${truncated}`;
121953
122530
  }
121954
122531
  if (Array.isArray(record.files)) {
121955
122532
  const count = record.files.length;
@@ -121987,6 +122564,13 @@ function toolInputText(item) {
121987
122564
  }
121988
122565
  }
121989
122566
  function toolOutputText(item) {
122567
+ if (!item.failed && item.toolName === "tree") {
122568
+ try {
122569
+ const value = JSON.parse(item.text);
122570
+ if (value && typeof value === "object" && typeof value.tree === "string")
122571
+ return value.tree;
122572
+ } catch {}
122573
+ }
121990
122574
  if (item.toolName === "shell") {
121991
122575
  try {
121992
122576
  const value = JSON.parse(item.text);
@@ -122023,103 +122607,236 @@ var init_state = __esm(() => {
122023
122607
  QUIET_TOOLS = new Set(["glob", "grep"]);
122024
122608
  });
122025
122609
 
122610
+ // packages/repl/src/transcript-groups.ts
122611
+ function transcriptGroups(items) {
122612
+ const groups = [];
122613
+ for (const item of items) {
122614
+ const exploration = item.kind === "tool" && !item.failed && !item.incomplete && EXPLORATION_TOOLS.has(item.toolName ?? "");
122615
+ const previous = groups.at(-1);
122616
+ if (exploration && previous?.exploration)
122617
+ previous.items.push(item);
122618
+ else
122619
+ groups.push({ items: [item], exploration });
122620
+ }
122621
+ return groups;
122622
+ }
122623
+ function explorationLabel(items) {
122624
+ const reads = items.filter((item) => item.toolName === "read").length;
122625
+ const searches = items.filter((item) => item.toolName === "grep" || item.toolName === "glob").length;
122626
+ const lists = items.length - reads - searches;
122627
+ const counts = [[reads, "read"], [searches, "search"], [lists, "listing"]];
122628
+ const detail = counts.filter(([count]) => count > 0).map(([count, name]) => `${count} ${name}${count === 1 ? "" : name === "search" ? "es" : "s"}`).join(" \xB7 ");
122629
+ return `${items.some((item) => item.running) ? "Exploring" : "Explored"} \xB7 ${detail}`;
122630
+ }
122631
+ var EXPLORATION_TOOLS;
122632
+ var init_transcript_groups = __esm(() => {
122633
+ EXPLORATION_TOOLS = new Set(["read", "glob", "grep", "list", "tree"]);
122634
+ });
122635
+
122026
122636
  // packages/repl/src/transcript-layout.ts
122027
- function transcriptLines(items, columns, expandThinking, expandTools) {
122637
+ function wrapped(item, text, columns, options = {}) {
122638
+ const prefix = options.prefix ?? "";
122639
+ const continuation = options.continuation ?? prefix;
122640
+ const width = Math.max(1, columns - prefix.length);
122641
+ const source = options.markdown ? markdownToAnsi(text) : cleanTerminalText(text);
122642
+ let position = (options.section ?? 0) * (MARKDOWN_LIMITS.characters + 1);
122643
+ return wrapAnsi2(source, width, { hard: true, trim: false }).split(`
122644
+ `).map((line, index) => {
122645
+ const result = { text: `${index === 0 ? prefix : continuation}${line}`, kind: item.kind, failed: item.failed, heading: options.heading, running: item.running, itemId: item.id, position };
122646
+ position += Math.max(1, cleanTerminalText(line).length);
122647
+ return result;
122648
+ });
122649
+ }
122650
+ function renderBlock(item, columns, thinking, tools) {
122651
+ if (item.kind === "user")
122652
+ return wrapped(item, item.text.slice(0, MARKDOWN_LIMITS.characters) + (item.text.length > MARKDOWN_LIMITS.characters ? `
122653
+ [Prompt display truncated; full text retained in session]` : ""), columns, { prefix: "> ", continuation: " " });
122654
+ if (item.kind === "assistant")
122655
+ return wrapped(item, item.text, columns, { markdown: true, prefix: "\u25CF ", continuation: " " });
122656
+ if (item.kind === "notice")
122657
+ return wrapped(item, item.text, columns, { prefix: " " });
122658
+ if (item.kind === "thinking") {
122659
+ const title = wrapped(item, thinking ? "Thinking" : "Thinking \xB7 Ctrl+T to expand", columns, { prefix: " ", heading: true });
122660
+ return thinking ? [...title, ...wrapped(item, item.text.slice(0, MARKDOWN_LIMITS.characters), columns, { prefix: " ", section: 1 })] : title;
122661
+ }
122662
+ const target = toolCallSummary(item);
122663
+ const status = item.failed ? " \xB7 Failed" : item.incomplete ? " \xB7 Outcome unknown" : item.running ? " \xB7 Running" : "";
122664
+ const lines = wrapped(item, `${item.toolName ?? "tool"}${target ? ` (${target})` : ""}${status}`, columns, { prefix: "\u25CF ", continuation: " ", heading: true });
122665
+ lines.push(...wrapped(item, toolResultSummary(item) ?? "Done", columns, { prefix: " \u2514 ", continuation: " ", section: 1 }));
122666
+ if (tools) {
122667
+ const input = toolInputText(item);
122668
+ if (input !== undefined)
122669
+ lines.push(...wrapped(item, `Input:
122670
+ ${input}`, columns, { prefix: " ", section: 2 }));
122671
+ if (!item.running) {
122672
+ const output = toolOutputText(item);
122673
+ const preview = output.slice(0, TRANSCRIPT_LIMITS.toolPreview);
122674
+ lines.push(...wrapped(item, `Output:
122675
+ ${preview}${output.length > preview.length ? `
122676
+ [Display preview truncated; full output retained in session]` : ""}`, columns, { prefix: " ", section: 3 }));
122677
+ }
122678
+ }
122679
+ return lines;
122680
+ }
122681
+ function layout(items, columns, thinking, tools, render) {
122028
122682
  const lines = [];
122029
- const width = Math.max(1, columns);
122030
- const append = (item, text, heading = false) => {
122031
- for (const line of wrapAnsi2(cleanTerminalText(text), width, { hard: true, trim: false }).split(`
122032
- `))
122033
- lines.push({ text: line, kind: item.kind, failed: item.failed, heading });
122034
- };
122035
- const appendMarkdown = (item, text) => {
122036
- const rendered = markdownToAnsi(text);
122037
- for (const line of wrapAnsi2(rendered, width, { hard: true, trim: false }).split(`
122038
- `))
122039
- lines.push({ text: line, kind: item.kind, failed: item.failed });
122040
- };
122041
- for (const item of items) {
122042
- if (item.kind === "user") {
122043
- append(item, "");
122044
- append(item, `> ${item.text}`);
122045
- } else if (item.kind === "assistant")
122046
- appendMarkdown(item, item.text);
122047
- else if (item.kind === "notice")
122048
- append(item, item.text);
122049
- else if (item.kind === "thinking") {
122050
- append(item, expandThinking ? "Thinking" : "Thinking (Ctrl+T to expand)", true);
122051
- if (expandThinking)
122052
- append(item, item.text);
122683
+ const width = Math.max(1, Math.floor(columns));
122684
+ for (const group of transcriptGroups(items)) {
122685
+ const first = group.items[0];
122686
+ if (!first)
122687
+ continue;
122688
+ if (lines.length && (first.kind === "user" || first.kind === "tool" || first.kind === "assistant")) {
122689
+ lines.push({ text: "", kind: "notice", itemId: first.id, position: -1 });
122690
+ }
122691
+ if (group.exploration && group.items.length > 1 && !tools) {
122692
+ const active = group.items.find((item) => item.running);
122693
+ const last = active ?? group.items.at(-1);
122694
+ lines.push(...wrapped({ ...first, running: Boolean(active) }, explorationLabel(group.items), width, { prefix: "\u25CF ", heading: true }));
122695
+ lines.push(...wrapped(first, `${last.toolName}${toolCallSummary(last) ? ` (${toolCallSummary(last)})` : ""} \xB7 ${toolResultSummary(last) ?? "Done"}`, width, { prefix: " \u2514 ", continuation: " ", section: 1 }));
122053
122696
  } else {
122054
- append(item, "");
122055
- const target = toolCallSummary(item);
122056
- append(item, `${item.running ? "Running" : item.incomplete ? "Unknown" : item.failed ? "Failed" : "Completed"}: ${item.toolName ?? "tool"}${target ? ` (${target})` : ""}`, true);
122057
- append(item, ` ${toolResultSummary(item) ?? "Done"} \xB7 Ctrl+O ${expandTools ? "collapse" : "expand"}`);
122058
- if (expandTools) {
122059
- const detailWidth = Math.max(1, width - 2);
122060
- const input = toolInputText(item);
122061
- if (input !== undefined) {
122062
- append(item, " Input:");
122063
- for (const line of wrapAnsi2(cleanTerminalText(input), detailWidth, { hard: true, trim: false }).split(`
122064
- `))
122065
- append(item, ` ${line}`);
122066
- }
122067
- if (!item.running) {
122068
- append(item, " Output:");
122069
- for (const line of wrapAnsi2(cleanTerminalText(toolOutputText(item)), detailWidth, { hard: true, trim: false }).split(`
122070
- `))
122071
- append(item, ` ${line}`);
122072
- }
122073
- }
122074
- append(item, "");
122697
+ for (const item of group.items)
122698
+ lines.push(...render(item, width, thinking, tools));
122075
122699
  }
122076
122700
  }
122077
122701
  return lines;
122078
122702
  }
122703
+ function createTranscriptRenderer() {
122704
+ const cache = new Map;
122705
+ let characters = 0;
122706
+ const render = (item, columns, thinking, tools) => {
122707
+ const signature = [item.kind, item.text, item.toolName, item.running, item.incomplete, item.failed, toolCallSummary(item), tools ? toolInputText(item) : undefined, columns, thinking, tools];
122708
+ const previous = cache.get(item.id);
122709
+ if (previous && previous.signature.every((part, index) => part === signature[index])) {
122710
+ cache.delete(item.id);
122711
+ cache.set(item.id, previous);
122712
+ return previous.lines;
122713
+ }
122714
+ if (previous) {
122715
+ characters -= previous.size;
122716
+ cache.delete(item.id);
122717
+ }
122718
+ const lines = renderBlock(item, columns, thinking, tools);
122719
+ const size = signature.reduce((sum, part) => sum + (typeof part === "string" ? part.length : 0), 0) + lines.reduce((sum, line) => sum + line.text.length, 0);
122720
+ if (size <= TRANSCRIPT_LIMITS.cacheCharacters) {
122721
+ cache.set(item.id, { signature, lines, size });
122722
+ characters += size;
122723
+ while (cache.size > TRANSCRIPT_LIMITS.cacheEntries || characters > TRANSCRIPT_LIMITS.cacheCharacters) {
122724
+ const oldest = cache.keys().next().value;
122725
+ if (oldest === undefined)
122726
+ break;
122727
+ characters -= cache.get(oldest).size;
122728
+ cache.delete(oldest);
122729
+ }
122730
+ }
122731
+ return lines;
122732
+ };
122733
+ return (items, columns, thinking, tools) => layout(items, columns, thinking, tools, render);
122734
+ }
122735
+ var TRANSCRIPT_LIMITS;
122079
122736
  var init_transcript_layout = __esm(() => {
122080
122737
  init_wrap_ansi2();
122081
122738
  init_editor();
122082
122739
  init_markdown();
122083
122740
  init_state();
122741
+ init_transcript_groups();
122742
+ TRANSCRIPT_LIMITS = Object.freeze({ cacheEntries: 256, cacheCharacters: 2097152, toolPreview: 65536 });
122743
+ });
122744
+
122745
+ // packages/repl/src/transcript-viewport.ts
122746
+ function transcriptViewport(lines, rows, columns, offset, viewKey, previous) {
122747
+ const height = Math.max(0, Math.floor(rows));
122748
+ const sameView = previous?.viewKey === viewKey;
122749
+ const continuing = sameView && previous.offset === offset && offset > 0;
122750
+ const history = offset > 0 && lines.length > height;
122751
+ const available = Math.max(0, height - (history ? 1 : 0));
122752
+ const tailLine = lines.at(-1);
122753
+ const tail = tailLine ? `${tailLine.itemId}:${tailLine.position}:${tailLine.text}` : undefined;
122754
+ let end = Math.max(available, lines.length - Math.max(0, offset));
122755
+ if (continuing && previous.anchor) {
122756
+ let match = -1;
122757
+ for (let index = 0;index < lines.length; index++) {
122758
+ const line = lines[index];
122759
+ if (line.itemId === previous.anchor.itemId && line.position <= previous.anchor.position && line.position >= 0)
122760
+ match = index;
122761
+ }
122762
+ if (match >= 0)
122763
+ end = Math.max(0, match - previous.anchor.leading) + available;
122764
+ }
122765
+ end = Math.min(lines.length, Math.max(0, end));
122766
+ const actual = history ? Math.max(0, lines.length - end) : 0;
122767
+ if (!actual)
122768
+ end = lines.length;
122769
+ const count = actual ? available : height;
122770
+ const page = height ? lines.slice(Math.max(0, end - count), end) : [];
122771
+ const firstIndex = page.findIndex((line) => line.position >= 0);
122772
+ const first = page[firstIndex];
122773
+ return {
122774
+ offset: actual,
122775
+ page,
122776
+ anchor: actual && first ? { itemId: first.itemId, position: first.position, leading: firstIndex } : actual && sameView ? previous.anchor : undefined,
122777
+ pending: Boolean(actual && sameView && (previous.pending || previous.columns === columns && previous.tail !== tail)),
122778
+ tail,
122779
+ columns,
122780
+ viewKey
122781
+ };
122782
+ }
122783
+
122784
+ // packages/repl/src/chrome.ts
122785
+ function hintLine(hints, columns) {
122786
+ let line = "";
122787
+ for (const hint of hints) {
122788
+ const label = cleanTerminalText(hint).replace(/\s+/g, " ").trim();
122789
+ const next = line ? `${line} \xB7 ${label}` : label;
122790
+ if (stringWidth2(next) <= columns)
122791
+ line = next;
122792
+ }
122793
+ return line;
122794
+ }
122795
+ var init_chrome = __esm(() => {
122796
+ init_string_width2();
122797
+ init_editor();
122084
122798
  });
122085
122799
 
122086
122800
  // packages/repl/src/components/Transcript.tsx
122087
- function Transcript({ items, limit, expandThinking = false, expandTools = false, columns = 80, rows = 20, offset = 0, onOffset }) {
122088
- const lines = import_react35.useMemo(() => transcriptLines(limit === undefined ? items : items.slice(-limit), columns, expandThinking, expandTools), [items, limit, expandThinking, expandTools, columns]);
122089
- const height = Math.max(0, rows);
122090
- const contentHeight = Math.max(0, height - (offset > 0 ? 1 : 0));
122091
- const maximum = Math.max(0, lines.length - contentHeight);
122092
- const active = Math.min(offset, maximum);
122093
- import_react35.useEffect(() => {
122094
- if (offset !== active)
122095
- onOffset?.(active);
122096
- }, [offset, active, onOffset]);
122097
- const end = Math.max(0, lines.length - active);
122098
- const page = lines.slice(Math.max(0, end - contentHeight), end);
122801
+ function Transcript({ items, limit, expandThinking = false, expandTools = false, columns = 80, rows = 20, offset = 0, onOffset, viewKey = "main" }) {
122802
+ const render = import_react35.useMemo(() => createTranscriptRenderer(), [viewKey]);
122803
+ const lines = import_react35.useMemo(() => render(limit === undefined ? items : items.slice(-limit), columns, expandThinking, expandTools), [items, limit, expandThinking, expandTools, columns, render]);
122804
+ const tools = items.some((item) => item.kind === "tool");
122805
+ const previous = import_react35.useRef(undefined);
122806
+ const height = Math.max(0, rows - (tools && rows > 2 ? 1 : 0));
122807
+ const viewport = transcriptViewport(lines, height, columns, offset, viewKey, previous.current);
122808
+ import_react35.useLayoutEffect(() => {
122809
+ previous.current = viewport;
122810
+ if (offset !== viewport.offset)
122811
+ onOffset?.(viewport.offset);
122812
+ });
122099
122813
  return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
122100
122814
  flexDirection: "column",
122101
122815
  flexShrink: 0,
122102
122816
  children: [
122103
- active > 0 && height > 0 ? /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text2, {
122104
- color: theme.dim,
122105
- children: [
122106
- "History \xB7 ",
122107
- active,
122108
- " rows above latest \xB7 PgDn to return"
122109
- ]
122110
- }, undefined, true, undefined, this) : null,
122111
- page.map((line, index) => /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text2, {
122817
+ viewport.offset > 0 && height > 0 ? /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text2, {
122818
+ color: viewport.pending ? theme.brand : theme.dim,
122819
+ children: fitTerminalLine(`${viewport.pending ? "New output \xB7 " : ""}History \xB7 PgDn to latest`, columns)
122820
+ }, undefined, false, undefined, this) : null,
122821
+ viewport.page.map((line, index) => /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text2, {
122112
122822
  bold: line.heading,
122113
122823
  backgroundColor: line.kind === "user" ? theme.userBackground : undefined,
122114
- color: line.failed ? theme.error : line.kind === "thinking" || line.kind === "notice" ? theme.dim : line.kind === "tool" && line.heading ? theme.tool : undefined,
122115
- children: line.text || " "
122116
- }, index, false, undefined, this))
122824
+ color: line.failed ? theme.error : line.kind === "user" ? theme.userText : line.kind === "thinking" || line.kind === "notice" ? theme.dim : line.running && line.heading ? theme.brand : line.kind === "tool" && line.heading ? theme.tool : undefined,
122825
+ children: line.kind === "user" ? line.text + " ".repeat(Math.max(0, columns - stringWidth2(line.text))) : line.text || " "
122826
+ }, index, false, undefined, this)),
122827
+ tools && rows > 2 ? /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text2, {
122828
+ color: theme.dim,
122829
+ children: hintLine([`Ctrl+O ${expandTools ? "collapse" : "expand"} tool details`, "Ctrl+T thinking"], columns)
122830
+ }, undefined, false, undefined, this) : null
122117
122831
  ]
122118
122832
  }, undefined, true, undefined, this);
122119
122833
  }
122120
122834
  var import_react35, jsx_dev_runtime4;
122121
122835
  var init_Transcript = __esm(async () => {
122836
+ init_string_width2();
122122
122837
  init_transcript_layout();
122838
+ init_editor();
122839
+ init_chrome();
122123
122840
  init_theme();
122124
122841
  await init_build2();
122125
122842
  import_react35 = __toESM(require_react(), 1);
@@ -122345,15 +123062,18 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122345
123062
  const [historyIndex, setHistoryIndex] = import_react37.useState(null);
122346
123063
  const [draft, setDraft] = import_react37.useState("");
122347
123064
  const [exitArmed, setExitArmed] = import_react37.useState(false);
123065
+ const [dismissed, setDismissed] = import_react37.useState();
122348
123066
  const lastInterrupt = import_react37.useRef(0);
122349
123067
  const value = editor.text;
122350
123068
  const maxSuggestions = Math.max(1, Math.min(MAX_SUGGESTIONS, Math.floor(((stdout.rows ?? 24) - 14) / 2)));
122351
- const width = Math.max(10, (stdout.columns ?? 80) - 6);
122352
- const suggestions = value.startsWith("/") && !/\s/.test(value) ? filterCommands(value.slice(1)).slice(0, maxSuggestions) : [];
123069
+ const columns = terminalColumns(stdout.columns ?? 80);
123070
+ const width = Math.max(1, columns - 2);
123071
+ const suggestions = value !== dismissed && value.startsWith("/") && !/\s/.test(value) ? filterCommands(value.slice(1)).slice(0, maxSuggestions) : [];
122353
123072
  const active = Math.min(selected, Math.max(0, suggestions.length - 1));
122354
123073
  const recent = history.slice(-HISTORY_LIMIT);
122355
123074
  function change(action) {
122356
123075
  onEdit(edit(editor, action));
123076
+ setDismissed(undefined);
122357
123077
  setSelected(0);
122358
123078
  }
122359
123079
  use_paste_default((text) => {
@@ -122400,7 +123120,9 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122400
123120
  return;
122401
123121
  }
122402
123122
  if (key.escape) {
122403
- if (running)
123123
+ if (suggestions.length)
123124
+ setDismissed(value);
123125
+ else if (running)
122404
123126
  onInterrupt();
122405
123127
  return;
122406
123128
  }
@@ -122477,7 +123199,13 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122477
123199
  else if (!key.meta && input)
122478
123200
  change({ type: "insert", text: input });
122479
123201
  });
122480
- const lines = editorLines(editor, Math.max(1, (stdout.columns ?? 80) - 4), Math.max(1, maxEditorLines));
123202
+ const viewport = editorViewport(editor, Math.max(1, columns - 4), Math.max(1, maxEditorLines));
123203
+ const shell = value.startsWith("!");
123204
+ const overflow = [viewport.above ? `\u2191 ${viewport.above} more` : "", viewport.below ? `\u2193 ${viewport.below} more` : ""].filter(Boolean).join(" \xB7 ");
123205
+ const border = shell ? theme.shell : theme.border;
123206
+ const borderLabel = [shell ? "Shell" : "", overflow].filter(Boolean).join(" \xB7 ");
123207
+ const caption = borderLabel ? fitTerminalLine(`\u2500\u2500 ${borderLabel}`, columns) : "";
123208
+ const hints = suggestions.length ? ["\u2191/\u2193 select", "Tab complete", "Enter run", "Esc close"] : running ? ["Esc interrupt", "Draft kept until idle", "Alt+Enter newline"] : shell ? ["Enter run shell", "Alt+Enter newline", "Ctrl+C clear"] : ["Enter send", "Alt+Enter newline", "/ commands", "Ctrl+L models", "Ctrl+C twice exits"];
122481
123209
  return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
122482
123210
  flexDirection: "column",
122483
123211
  flexShrink: 0,
@@ -122485,50 +123213,47 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122485
123213
  suggestions.length ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
122486
123214
  flexDirection: "column",
122487
123215
  paddingX: 1,
123216
+ children: suggestions.map((command, index) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(import_react37.Fragment, {
123217
+ children: [
123218
+ index === 0 || commandGroup(suggestions[index - 1]?.name ?? "") !== commandGroup(command.name) ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123219
+ color: theme.dim,
123220
+ bold: true,
123221
+ children: commandGroup(command.name)
123222
+ }, undefined, false, undefined, this) : null,
123223
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
123224
+ children: [
123225
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123226
+ color: index === active ? theme.brand : undefined,
123227
+ bold: index === active,
123228
+ children: [
123229
+ "/",
123230
+ command.name
123231
+ ]
123232
+ }, undefined, true, undefined, this),
123233
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123234
+ color: theme.dim,
123235
+ children: [
123236
+ " ",
123237
+ truncate2(command.description, Math.max(1, width - command.name.length - 3))
123238
+ ]
123239
+ }, undefined, true, undefined, this)
123240
+ ]
123241
+ }, undefined, true, undefined, this)
123242
+ ]
123243
+ }, command.name, true, undefined, this))
123244
+ }, undefined, false, undefined, this) : null,
123245
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123246
+ color: border,
122488
123247
  children: [
122489
- suggestions.map((command, index) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(import_react37.Fragment, {
122490
- children: [
122491
- index === 0 || commandGroup(suggestions[index - 1]?.name ?? "") !== commandGroup(command.name) ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122492
- color: theme.dim,
122493
- bold: true,
122494
- children: commandGroup(command.name)
122495
- }, undefined, false, undefined, this) : null,
122496
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
122497
- children: [
122498
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122499
- color: index === active ? theme.brand : undefined,
122500
- bold: index === active,
122501
- children: [
122502
- "/",
122503
- command.name
122504
- ]
122505
- }, undefined, true, undefined, this),
122506
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122507
- color: theme.dim,
122508
- children: [
122509
- " ",
122510
- truncate2(command.description, Math.max(1, width - command.name.length - 3))
122511
- ]
122512
- }, undefined, true, undefined, this)
122513
- ]
122514
- }, undefined, true, undefined, this)
122515
- ]
122516
- }, command.name, true, undefined, this)),
122517
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122518
- color: theme.dim,
122519
- children: truncate2("Up/Down select \xB7 Tab complete \xB7 Enter run", width)
122520
- }, undefined, false, undefined, this)
123248
+ caption,
123249
+ "\u2500".repeat(Math.max(0, columns - stringWidth2(caption)))
122521
123250
  ]
122522
- }, undefined, true, undefined, this) : null,
123251
+ }, undefined, true, undefined, this),
122523
123252
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
122524
- borderStyle: "single",
122525
- borderLeft: false,
122526
- borderRight: false,
122527
- borderColor: running ? theme.permission : theme.brand,
122528
123253
  paddingX: 1,
122529
123254
  children: [
122530
123255
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122531
- color: theme.brand,
123256
+ color: shell ? theme.shell : theme.brand,
122532
123257
  children: "> "
122533
123258
  }, undefined, false, undefined, this),
122534
123259
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
@@ -122542,10 +123267,10 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122542
123267
  }, undefined, false, undefined, this),
122543
123268
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122544
123269
  color: theme.dim,
122545
- children: fitTerminalLine(running ? "Working \xB7 Esc interrupts" : "Message, /command or !shell command", Math.max(1, (stdout.columns ?? 80) - 5))
123270
+ children: fitTerminalLine(running ? "Working \xB7 Esc interrupts" : "Message, /command or !shell command", Math.max(1, columns - 5))
122546
123271
  }, undefined, false, undefined, this)
122547
123272
  ]
122548
- }, undefined, true, undefined, this) : lines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123273
+ }, undefined, true, undefined, this) : viewport.lines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122549
123274
  children: [
122550
123275
  line.before,
122551
123276
  line.cursor !== undefined ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
@@ -122558,20 +123283,26 @@ function PromptInput({ running, editor, onEdit, history, onSubmit, onShortcut, o
122558
123283
  }, undefined, false, undefined, this)
122559
123284
  ]
122560
123285
  }, undefined, true, undefined, this),
123286
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
123287
+ color: border,
123288
+ children: "\u2500".repeat(columns)
123289
+ }, undefined, false, undefined, this),
122561
123290
  exitArmed ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122562
123291
  color: theme.permission,
122563
123292
  children: truncate2("Press Ctrl+C again to exit", width)
122564
123293
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text2, {
122565
123294
  color: theme.dim,
122566
- children: truncate2(`${running ? "Esc interrupt" : "Enter send"} \xB7 Alt+Enter newline \xB7 Up/Down history \xB7 Ctrl+C twice exits`, width)
123295
+ children: hintLine(hints, columns)
122567
123296
  }, undefined, false, undefined, this)
122568
123297
  ]
122569
123298
  }, undefined, true, undefined, this);
122570
123299
  }
122571
123300
  var import_react37, jsx_dev_runtime6, MAX_SUGGESTIONS = 6, MAX_EDITOR_LINES = 5, EXIT_CTRL_C_WINDOW_MS = 800;
122572
123301
  var init_PromptInput = __esm(async () => {
123302
+ init_string_width2();
122573
123303
  init_commands();
122574
123304
  init_editor();
123305
+ init_chrome();
122575
123306
  init_theme();
122576
123307
  init_state();
122577
123308
  await init_build2();
@@ -122581,16 +123312,19 @@ var init_PromptInput = __esm(async () => {
122581
123312
 
122582
123313
  // packages/repl/src/components/StatusBar.tsx
122583
123314
  import { homedir as homedir2 } from "os";
122584
- import { relative as relative3, isAbsolute as isAbsolute3 } from "path";
123315
+ import { relative as relative4, isAbsolute as isAbsolute4 } from "path";
122585
123316
  function formatCwd(path) {
122586
123317
  const home = homedir2();
122587
- const child = relative3(home, path);
122588
- if (home.length > 0 && !isAbsolute3(child) && child !== ".." && !child.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`))
123318
+ const child = relative4(home, path);
123319
+ if (home.length > 0 && !isAbsolute4(child) && child !== ".." && !child.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`))
122589
123320
  return child ? `~/${child}` : "~";
122590
123321
  return path;
122591
123322
  }
122592
123323
  function StatusBar({ modelLabel, workspace, title, columns = 80, compact = false, loop }) {
122593
123324
  const line1 = title ? `${formatCwd(workspace)} \u2022 ${title}` : formatCwd(workspace);
123325
+ const model = fitTerminalLine(modelLabel, Math.max(1, Math.floor(columns / 2)));
123326
+ const left = fitTerminalLine(line1, Math.max(1, columns - stringWidth2(model) - 2));
123327
+ const inline = !compact && columns >= 70;
122594
123328
  return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
122595
123329
  flexDirection: "column",
122596
123330
  flexShrink: 0,
@@ -122599,30 +123333,70 @@ function StatusBar({ modelLabel, workspace, title, columns = 80, compact = false
122599
123333
  color: theme.permission,
122600
123334
  children: fitTerminalLine(loop, columns)
122601
123335
  }, undefined, false, undefined, this) : null,
122602
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text2, {
123336
+ inline ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text2, {
122603
123337
  color: theme.dim,
122604
- children: fitTerminalLine(`${modelLabel} \xB7 ${line1}`, columns)
122605
- }, undefined, false, undefined, this),
122606
- !compact && columns >= 60 ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text2, {
123338
+ children: [
123339
+ left,
123340
+ " ".repeat(Math.max(1, columns - stringWidth2(left) - stringWidth2(model))),
123341
+ model
123342
+ ]
123343
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text2, {
122607
123344
  color: theme.dim,
122608
- children: fitTerminalLine(HINTS, columns)
122609
- }, undefined, false, undefined, this) : null
123345
+ children: fitTerminalLine(`${modelLabel} \xB7 ${line1}`, columns)
123346
+ }, undefined, false, undefined, this)
122610
123347
  ]
122611
123348
  }, undefined, true, undefined, this);
122612
123349
  }
122613
- var jsx_dev_runtime7, HINTS = "Ctrl+L models \xB7 Ctrl+O tools \xB7 Ctrl+G agents \xB7 /shortcuts";
123350
+ var jsx_dev_runtime7;
122614
123351
  var init_StatusBar = __esm(async () => {
123352
+ init_string_width2();
122615
123353
  init_editor();
122616
123354
  init_theme();
122617
123355
  await init_build2();
122618
123356
  jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
122619
123357
  });
122620
123358
 
123359
+ // packages/repl/src/components/Panel.tsx
123360
+ function Panel({ title, children, color = theme.brand }) {
123361
+ const { stdout } = use_stdout_default();
123362
+ const columns = terminalColumns(stdout.columns ?? 80);
123363
+ const width = Math.max(1, columns - 2);
123364
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
123365
+ flexDirection: "column",
123366
+ flexShrink: 0,
123367
+ children: [
123368
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123369
+ color,
123370
+ children: "\u2500".repeat(columns)
123371
+ }, undefined, false, undefined, this),
123372
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
123373
+ flexDirection: "column",
123374
+ paddingX: columns > 2 ? 1 : 0,
123375
+ children: [
123376
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123377
+ bold: true,
123378
+ color,
123379
+ children: fitTerminalLine(title, width)
123380
+ }, undefined, false, undefined, this),
123381
+ children
123382
+ ]
123383
+ }, undefined, true, undefined, this)
123384
+ ]
123385
+ }, undefined, true, undefined, this);
123386
+ }
123387
+ var jsx_dev_runtime8;
123388
+ var init_Panel = __esm(async () => {
123389
+ init_editor();
123390
+ init_theme();
123391
+ await init_build2();
123392
+ jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
123393
+ });
123394
+
122621
123395
  // packages/repl/src/components/ApprovalDialog.tsx
122622
123396
  function ApprovalDialog({ request, onAnswer }) {
122623
123397
  const { stdout } = use_stdout_default();
122624
123398
  const [offset, setOffset] = import_react38.useState(0);
122625
- const width = Math.max(1, (stdout.columns ?? 80) - 4);
123399
+ const width = Math.max(1, terminalColumns(stdout.columns ?? 80) - 4);
122626
123400
  const count = Math.max(1, Math.min(4, (stdout.rows ?? 24) - 10));
122627
123401
  const details = wrapAnsi2(cleanTerminalText(`${request.reason}${request.target ? `
122628
123402
  target: ${request.target}` : ""}`), width, { hard: true, trim: false }).split(`
@@ -122646,49 +123420,45 @@ target: ${request.target}` : ""}`), width, { hard: true, trim: false }).split(`
122646
123420
  else if (input === "n" || input === "N" || key.escape)
122647
123421
  onAnswer(false);
122648
123422
  });
122649
- return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
122650
- flexDirection: "column",
122651
- borderStyle: "round",
122652
- borderColor: theme.permission,
122653
- paddingX: 1,
123423
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Panel, {
123424
+ title: `Approve ${request.toolName}?`,
123425
+ color: theme.permission,
122654
123426
  children: [
122655
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
122656
- color: theme.permission,
122657
- bold: true,
122658
- children: fitTerminalLine(`Approve ${request.toolName}?`, width)
122659
- }, undefined, false, undefined, this),
122660
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123427
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122661
123428
  color: theme.dim,
122662
123429
  children: fitTerminalLine(`${request.riskKind} \xB7 ${request.riskLevel}`, width)
122663
123430
  }, undefined, false, undefined, this),
122664
- details.slice(start, start + count).map((line, index) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123431
+ details.slice(start, start + count).map((line, index) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122665
123432
  children: line
122666
123433
  }, index, false, undefined, this)),
122667
- request.remember ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123434
+ request.remember ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122668
123435
  color: theme.dim,
122669
123436
  children: fitTerminalLine("s allow for session \xB7 a save rule (same tool and target)", width)
122670
123437
  }, undefined, false, undefined, this) : null,
122671
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text2, {
123438
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122672
123439
  color: theme.dim,
122673
- children: fitTerminalLine(`y allow once \xB7 n reject${details.length > count ? " \xB7 PgUp/PgDn details" : ""}`, width)
123440
+ children: fitTerminalLine(`Enter/y allow once \xB7 n/Esc reject${details.length > count ? " \xB7 PgUp/PgDn details" : ""}`, width)
122674
123441
  }, undefined, false, undefined, this)
122675
123442
  ]
122676
123443
  }, undefined, true, undefined, this);
122677
123444
  }
122678
- var import_react38, jsx_dev_runtime8;
123445
+ var import_react38, jsx_dev_runtime9;
122679
123446
  var init_ApprovalDialog = __esm(async () => {
122680
123447
  init_wrap_ansi2();
122681
123448
  init_theme();
122682
123449
  init_editor();
122683
- await init_build2();
123450
+ await __promiseAll([
123451
+ init_build2(),
123452
+ init_Panel()
123453
+ ]);
122684
123454
  import_react38 = __toESM(require_react(), 1);
122685
- jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
123455
+ jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
122686
123456
  });
122687
123457
 
122688
123458
  // packages/repl/src/components/AskDialog.tsx
122689
123459
  function AskDialog({ input, onAnswer, onCancel }) {
122690
123460
  const { stdout } = use_stdout_default();
122691
- const width = Math.max(1, (stdout.columns ?? 80) - 4);
123461
+ const width = Math.max(1, terminalColumns(stdout.columns ?? 80) - 4);
122692
123462
  const optionCount = Math.max(1, Math.min(6, (stdout.rows ?? 24) - 12));
122693
123463
  const [index, setIndex] = import_react39.useState(0);
122694
123464
  const [cursor, setCursor] = import_react39.useState(0);
@@ -122817,71 +123587,59 @@ function AskDialog({ input, onAnswer, onCancel }) {
122817
123587
  advance();
122818
123588
  });
122819
123589
  if (reviewing)
122820
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
122821
- flexDirection: "column",
122822
- borderStyle: "round",
122823
- borderColor: theme.brand,
122824
- paddingX: 1,
123590
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Panel, {
123591
+ title: "Review answers",
122825
123592
  children: [
122826
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122827
- bold: true,
122828
- color: theme.brand,
122829
- children: "Review answers"
122830
- }, undefined, false, undefined, this),
122831
- detailLines.slice(detailStart, detailStart + visibleCount).map((line, row) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123593
+ detailLines.slice(detailStart, detailStart + visibleCount).map((line, row) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122832
123594
  children: line
122833
123595
  }, row, false, undefined, this)),
122834
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123596
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122835
123597
  color: theme.dim,
122836
- children: fitTerminalLine("Enter submit \xB7 Left edit \xB7 PgUp/PgDn details \xB7 Esc cancel", width)
123598
+ children: hintLine(["Enter submit", "Esc cancel", "Left edit", "PgUp/PgDn details"], width)
122837
123599
  }, undefined, false, undefined, this)
122838
123600
  ]
122839
123601
  }, undefined, true, undefined, this);
122840
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
122841
- flexDirection: "column",
122842
- borderStyle: "round",
122843
- borderColor: theme.brand,
122844
- paddingX: 1,
123602
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Panel, {
123603
+ title: `Question ${index + 1}/${input.questions.length}${question.header ? ` \xB7 ${question.header}` : ""}`,
122845
123604
  children: [
122846
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
122847
- bold: true,
122848
- color: theme.brand,
122849
- children: fitTerminalLine(`Question ${index + 1}/${input.questions.length}${question.header ? ` \xB7 ${question.header}` : ""}`, width)
122850
- }, undefined, false, undefined, this),
122851
- detailLines.slice(detailStart, detailStart + visibleCount).map((line, row) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123605
+ detailLines.slice(detailStart, detailStart + visibleCount).map((line, row) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122852
123606
  children: line
122853
123607
  }, row, false, undefined, this)),
122854
123608
  options.slice(optionStart, optionStart + optionCount).map((option, row) => {
122855
123609
  const optionIndex = optionStart + row;
122856
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123610
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122857
123611
  color: !editing && optionIndex === cursor ? theme.brand : undefined,
122858
123612
  children: fitTerminalLine(`${optionIndex === cursor && !editing ? ">" : " "} ${draft.selected.includes(option.label) ? "[x]" : "[ ]"} ${option.label}${option.description ? ` \u2014 ${option.description}` : ""}`, width)
122859
123613
  }, option.label, false, undefined, this);
122860
123614
  }),
122861
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123615
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122862
123616
  color: editing || cursor === options.length ? theme.brand : theme.dim,
122863
123617
  children: fitTerminalLine(`${!editing && cursor === options.length ? ">" : " "} Custom: ${draft.custom || (editing ? "Type your answer" : "Enter/Tab to type")}`, width)
122864
123618
  }, undefined, false, undefined, this),
122865
- feedback ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123619
+ feedback ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122866
123620
  color: theme.brand,
122867
123621
  children: fitTerminalLine(feedback, width)
122868
123622
  }, undefined, false, undefined, this) : null,
122869
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text2, {
123623
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122870
123624
  color: theme.dim,
122871
- children: fitTerminalLine("Up/Down \xB7 Space select \xB7 Enter next \xB7 Tab custom \xB7 PgUp/PgDn details \xB7 Esc", width)
123625
+ children: hintLine([...question.multiSelect ? ["Space toggle"] : [], "Enter next", "Esc cancel", "\u2191/\u2193 select", "Tab custom", "PgUp/PgDn details"], width)
122872
123626
  }, undefined, false, undefined, this)
122873
123627
  ]
122874
123628
  }, undefined, true, undefined, this);
122875
123629
  }
122876
- var import_react39, jsx_dev_runtime9, emptyDraft = () => ({ selected: [], custom: "" });
123630
+ var import_react39, jsx_dev_runtime10, emptyDraft = () => ({ selected: [], custom: "" });
122877
123631
  var init_AskDialog = __esm(async () => {
122878
123632
  init_wrap_ansi2();
122879
123633
  init_src7();
122880
123634
  init_editor();
122881
123635
  init_theme();
122882
- await init_build2();
123636
+ init_chrome();
123637
+ await __promiseAll([
123638
+ init_build2(),
123639
+ init_Panel()
123640
+ ]);
122883
123641
  import_react39 = __toESM(require_react(), 1);
122884
- jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
123642
+ jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
122885
123643
  });
122886
123644
 
122887
123645
  // packages/repl/src/clipboard.ts
@@ -122919,9 +123677,9 @@ var init_clipboard = () => {};
122919
123677
  // packages/repl/src/components/AuthDialog.tsx
122920
123678
  function AuthDialog({ auth, onCopied, onClose }) {
122921
123679
  const { stdout } = use_stdout_default();
122922
- const width = Math.max(1, (stdout.columns ?? 80) - 4);
123680
+ const width = Math.max(1, terminalColumns(stdout.columns ?? 80) - 4);
122923
123681
  use_input_default((input, key) => {
122924
- if (key.escape) {
123682
+ if (key.escape || key.ctrl && input === "c") {
122925
123683
  onClose();
122926
123684
  return;
122927
123685
  }
@@ -122936,37 +123694,31 @@ function AuthDialog({ auth, onCopied, onClose }) {
122936
123694
  }
122937
123695
  }
122938
123696
  });
122939
- return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
122940
- flexDirection: "column",
122941
- borderStyle: "round",
122942
- borderColor: theme.permission,
122943
- paddingX: 1,
123697
+ return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Panel, {
123698
+ title: auth.title,
123699
+ color: theme.permission,
122944
123700
  children: [
122945
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
122946
- bold: true,
122947
- children: fitTerminalLine(auth.title, width)
122948
- }, undefined, false, undefined, this),
122949
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123701
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122950
123702
  color: theme.brand,
122951
123703
  children: fitTerminalLine(auth.url, width)
122952
123704
  }, undefined, false, undefined, this),
122953
- auth.instructions ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123705
+ auth.instructions ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122954
123706
  color: theme.dim,
122955
123707
  children: fitTerminalLine(auth.instructions, width)
122956
123708
  }, undefined, false, undefined, this) : null,
122957
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123709
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122958
123710
  color: theme.dim,
122959
123711
  children: "waiting for authorization\u2026"
122960
123712
  }, undefined, false, undefined, this),
122961
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123713
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122962
123714
  children: [
122963
123715
  "c ",
122964
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123716
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122965
123717
  color: theme.dim,
122966
123718
  children: "copy"
122967
123719
  }, undefined, false, undefined, this),
122968
123720
  " \xB7 esc ",
122969
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text2, {
123721
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
122970
123722
  color: theme.dim,
122971
123723
  children: "hide"
122972
123724
  }, undefined, false, undefined, this)
@@ -122975,23 +123727,27 @@ function AuthDialog({ auth, onCopied, onClose }) {
122975
123727
  ]
122976
123728
  }, undefined, true, undefined, this);
122977
123729
  }
122978
- var jsx_dev_runtime10, CODE_PATTERN;
123730
+ var jsx_dev_runtime11, CODE_PATTERN;
122979
123731
  var init_AuthDialog = __esm(async () => {
122980
123732
  init_clipboard();
122981
123733
  init_theme();
122982
123734
  init_editor();
122983
- await init_build2();
122984
- jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
123735
+ await __promiseAll([
123736
+ init_build2(),
123737
+ init_Panel()
123738
+ ]);
123739
+ jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
122985
123740
  CODE_PATTERN = /[A-Z0-9]{4}-[A-Z0-9]{4,5}/;
122986
123741
  });
122987
123742
 
122988
123743
  // packages/repl/src/components/RenameInput.tsx
122989
123744
  function RenameInput({ initial, onSubmit, onCancel }) {
122990
123745
  const { stdout } = use_stdout_default();
122991
- const width = Math.max(1, (stdout.columns ?? 80) - 4);
123746
+ const width = Math.max(1, terminalColumns(stdout.columns ?? 80) - 4);
122992
123747
  const [editor, setEditor] = import_react40.useState({ text: initial, cursor: graphemes(initial).length });
123748
+ use_paste_default((text) => setEditor((previous) => edit(previous, { type: "insert", text: text.replace(/[\r\n]+/g, " ") })));
122993
123749
  use_input_default((input, key) => {
122994
- if (key.escape) {
123750
+ if (key.escape || key.ctrl && input === "c") {
122995
123751
  onCancel();
122996
123752
  return;
122997
123753
  }
@@ -123035,45 +123791,40 @@ function RenameInput({ initial, onSubmit, onCancel }) {
123035
123791
  setEditor(edit(editor, { type: "insert", text: input }));
123036
123792
  });
123037
123793
  const lines = editorLines(editor, width, 1);
123038
- return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
123039
- flexDirection: "column",
123040
- borderStyle: "round",
123041
- borderColor: theme.brand,
123042
- paddingX: 1,
123794
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Panel, {
123795
+ title: "Rename session",
123043
123796
  children: [
123044
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
123045
- bold: true,
123046
- color: theme.brand,
123047
- children: fitTerminalLine("Rename session", width)
123048
- }, undefined, false, undefined, this),
123049
- lines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
123797
+ lines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123050
123798
  children: [
123051
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
123799
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123052
123800
  color: theme.brand,
123053
123801
  children: "> "
123054
123802
  }, undefined, false, undefined, this),
123055
123803
  line.before,
123056
- line.cursor !== undefined ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
123804
+ line.cursor !== undefined ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123057
123805
  inverse: true,
123058
123806
  children: line.cursor
123059
123807
  }, undefined, false, undefined, this) : null,
123060
123808
  line.after
123061
123809
  ]
123062
123810
  }, index, true, undefined, this)),
123063
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text2, {
123811
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123064
123812
  color: theme.dim,
123065
123813
  children: fitTerminalLine("Enter save \xB7 Esc cancel", width)
123066
123814
  }, undefined, false, undefined, this)
123067
123815
  ]
123068
123816
  }, undefined, true, undefined, this);
123069
123817
  }
123070
- var import_react40, jsx_dev_runtime11;
123818
+ var import_react40, jsx_dev_runtime12;
123071
123819
  var init_RenameInput = __esm(async () => {
123072
123820
  init_editor();
123073
123821
  init_theme();
123074
- await init_build2();
123822
+ await __promiseAll([
123823
+ init_build2(),
123824
+ init_Panel()
123825
+ ]);
123075
123826
  import_react40 = __toESM(require_react(), 1);
123076
- jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
123827
+ jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
123077
123828
  });
123078
123829
 
123079
123830
  // packages/repl/src/selection.ts
@@ -123108,7 +123859,7 @@ function Selector({ title, items, onSelect, onCancel, actions }) {
123108
123859
  const count = Math.max(1, Math.min(8, Math.floor(((stdout.rows ?? 24) - 14) / 2)));
123109
123860
  const start = Math.max(0, Math.min(active - Math.floor(count / 2), filtered.length - count));
123110
123861
  const visible = filtered.slice(start, start + count);
123111
- const width = Math.max(10, (stdout.columns ?? 80) - 10);
123862
+ const width = Math.max(1, terminalColumns(stdout.columns ?? 80) - 2);
123112
123863
  function search(input) {
123113
123864
  setQuery((value) => (value + cleanTerminalText(input.slice(0, 1024)).replace(/\n/g, " ")).slice(0, 256));
123114
123865
  setIndex(0);
@@ -123151,49 +123902,29 @@ function Selector({ title, items, onSelect, onCancel, actions }) {
123151
123902
  search(input);
123152
123903
  }
123153
123904
  });
123154
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
123155
- flexDirection: "column",
123156
- borderStyle: "round",
123157
- borderColor: theme.brand,
123158
- paddingX: 1,
123159
- flexShrink: 0,
123905
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Panel, {
123906
+ title: `${title} \xB7 ${filtered.length} options`,
123160
123907
  children: [
123161
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
123162
- justifyContent: "space-between",
123163
- children: [
123164
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123165
- bold: true,
123166
- children: title
123167
- }, undefined, false, undefined, this),
123168
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123169
- color: theme.dim,
123170
- children: [
123171
- filtered.length,
123172
- " options"
123173
- ]
123174
- }, undefined, true, undefined, this)
123175
- ]
123176
- }, undefined, true, undefined, this),
123177
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123908
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123178
123909
  color: query ? undefined : theme.dim,
123179
123910
  children: fitTerminalLine(`Search: ${query || "type to filter"}`, width)
123180
123911
  }, undefined, false, undefined, this),
123181
- visible.length === 0 ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123912
+ visible.length === 0 ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123182
123913
  color: theme.dim,
123183
123914
  children: "No matches. Backspace to edit; Esc to return."
123184
123915
  }, undefined, false, undefined, this) : null,
123185
123916
  visible.map((item, row) => {
123186
123917
  const selected = start + row === active;
123187
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(import_react41.Fragment, {
123918
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(import_react41.Fragment, {
123188
123919
  children: [
123189
- item.group && (row === 0 || visible[row - 1]?.group !== item.group) ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123920
+ item.group && (row === 0 || visible[row - 1]?.group !== item.group) ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123190
123921
  bold: true,
123191
123922
  color: theme.dim,
123192
123923
  children: fitTerminalLine(cleanTerminalText(item.group), width)
123193
123924
  }, undefined, false, undefined, this) : null,
123194
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123925
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123195
123926
  color: selected ? theme.brand : undefined,
123196
- backgroundColor: selected ? theme.userBackground : undefined,
123927
+ backgroundColor: selected ? theme.selected : undefined,
123197
123928
  bold: selected,
123198
123929
  children: [
123199
123930
  selected ? "> " : " ",
@@ -123204,24 +123935,28 @@ function Selector({ title, items, onSelect, onCancel, actions }) {
123204
123935
  ]
123205
123936
  }, item.value, true, undefined, this);
123206
123937
  }),
123207
- filtered[active]?.description ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123938
+ filtered[active]?.description ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123208
123939
  color: theme.dim,
123209
123940
  children: fitTerminalLine(cleanTerminalText(filtered[active].description ?? ""), width)
123210
123941
  }, undefined, false, undefined, this) : null,
123211
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
123942
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
123212
123943
  color: theme.dim,
123213
- children: fitTerminalLine(`${filtered.length ? `${active + 1}/${filtered.length} \xB7 ` : ""}Up/Down \xB7 Enter select${actions?.length ? ` \xB7 ${actions.map((action) => action.label).join(" \xB7 ")}` : ""} \xB7 Esc back`, width)
123944
+ children: hintLine(["Enter select", "Esc back", "\u2191/\u2193", ...(actions ?? []).map((action) => action.label), ...filtered.length ? [`${active + 1}/${filtered.length}`] : []], width)
123214
123945
  }, undefined, false, undefined, this)
123215
123946
  ]
123216
123947
  }, undefined, true, undefined, this);
123217
123948
  }
123218
- var import_react41, jsx_dev_runtime12;
123949
+ var import_react41, jsx_dev_runtime13;
123219
123950
  var init_Selector = __esm(async () => {
123220
123951
  init_editor();
123221
123952
  init_theme();
123222
- await init_build2();
123953
+ init_chrome();
123954
+ await __promiseAll([
123955
+ init_build2(),
123956
+ init_Panel()
123957
+ ]);
123223
123958
  import_react41 = __toESM(require_react(), 1);
123224
- jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
123959
+ jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
123225
123960
  });
123226
123961
 
123227
123962
  // packages/repl/src/local-shell.ts
@@ -123237,19 +123972,6 @@ var init_local_shell = __esm(() => {
123237
123972
  init_src7();
123238
123973
  });
123239
123974
 
123240
- // packages/repl/src/terminal-layout.ts
123241
- function terminalLayout(rows, modal) {
123242
- const height = Math.max(6, Math.floor(rows) - 1);
123243
- const compact = height < 20;
123244
- return {
123245
- height,
123246
- compact,
123247
- todoRows: modal || height < 16 ? 0 : Math.min(5, Math.floor(height / 5)),
123248
- jobRows: modal || height < 16 ? 0 : 2,
123249
- inputRows: Math.max(1, Math.min(5, Math.floor(height / 5)))
123250
- };
123251
- }
123252
-
123253
123975
  // packages/repl/src/subagent-view.ts
123254
123976
  function bounded2(text) {
123255
123977
  return text.length > MAX_EVENT_CHARACTERS ? `${text.slice(0, MAX_EVENT_CHARACTERS)}
@@ -123305,6 +124027,9 @@ var init_subagent_view = __esm(() => {
123305
124027
  });
123306
124028
 
123307
124029
  // packages/repl/src/backend-state.ts
124030
+ function stableItems(items) {
124031
+ return items.map((item, index) => ({ ...item, id: -(index + 1) }));
124032
+ }
123308
124033
  function snapshotItems(snapshot) {
123309
124034
  const pending = new Set(toolLogEntries(snapshot.events).filter((call) => call.status === "pending").map((call) => call.callId));
123310
124035
  const items = messagesToItems(snapshot.messages, snapshot.events).map((item) => snapshot.busy && item.toolCallId && pending.has(item.toolCallId) ? { ...item, running: true, incomplete: false, text: "" } : item);
@@ -123312,12 +124037,15 @@ function snapshotItems(snapshot) {
123312
124037
  items.push({ id: nextId(), kind: "thinking", text: snapshot.partial.reasoning });
123313
124038
  if (snapshot.partial?.content)
123314
124039
  items.push({ id: nextId(), kind: "assistant", text: snapshot.partial.content, running: true });
123315
- return items;
124040
+ if (snapshot.error)
124041
+ items.push({ id: nextId(), kind: "assistant", text: `Request failed: ${snapshot.error.split(" | ")[0]}`, failed: true });
124042
+ return stableItems(items);
123316
124043
  }
123317
124044
  function snapshotTasks(snapshot) {
123318
124045
  return restoreTaskViews(snapshot.events).map((view) => {
123319
124046
  const task = snapshot.tasks.find((task) => task.taskId === view.id);
123320
- return !snapshot.busy && view.status === "running" ? { ...view, status: "cancelled", reason: task?.reason ?? "No active backend run." } : view;
124047
+ const stable = { ...view, items: stableItems(view.items) };
124048
+ return !snapshot.busy && view.status === "running" ? { ...stable, status: "cancelled", reason: task?.reason ?? "No active backend run." } : stable;
123321
124049
  });
123322
124050
  }
123323
124051
  var init_backend_state = __esm(() => {
@@ -123349,9 +124077,9 @@ function Repl(props) {
123349
124077
  const { exit } = use_app_default();
123350
124078
  const { createModel, workspace, onSession, backend } = props;
123351
124079
  const { stdout } = use_stdout_default();
123352
- const [size, setSize] = import_react42.useState({ columns: stdout.columns ?? 80, rows: stdout.rows ?? 24 });
124080
+ const [size, setSize] = import_react42.useState({ columns: terminalColumns(stdout.columns ?? 80), rows: stdout.rows ?? 24 });
123353
124081
  import_react42.useEffect(() => {
123354
- const update = () => setSize({ columns: stdout.columns ?? 80, rows: stdout.rows ?? 24 });
124082
+ const update = () => setSize({ columns: terminalColumns(stdout.columns ?? 80), rows: stdout.rows ?? 24 });
123355
124083
  stdout.on("resize", update);
123356
124084
  return () => {
123357
124085
  stdout.off("resize", update);
@@ -124670,21 +125398,22 @@ function Repl(props) {
124670
125398
  const layout = terminalLayout(size.rows, modal);
124671
125399
  const selectedTask = taskViews.find((task) => task.id === viewedTaskId);
124672
125400
  const visibleItems = selectedTask?.items ?? items;
124673
- return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
125401
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
124674
125402
  flexDirection: "column",
124675
125403
  width: size.columns,
124676
125404
  height: layout.height,
124677
125405
  children: [
124678
- !sessionStarted ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Banner, {
125406
+ !sessionStarted ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Banner, {
124679
125407
  modelLabel: modelLabelText,
124680
125408
  workspace
124681
125409
  }, undefined, false, undefined, this) : null,
124682
- !modal && taskViews.length > 0 ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(TaskTree, {
125410
+ !modal && taskViews.length > 0 ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(TaskTree, {
124683
125411
  tasks: taskViews,
124684
125412
  selectedId: selectedTask?.id,
124685
- columns: size.columns
125413
+ columns: size.columns,
125414
+ maxRows: layout.compact ? 1 : Math.min(6, Math.floor(layout.height / 6) + 1)
124686
125415
  }, undefined, false, undefined, this) : null,
124687
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
125416
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
124688
125417
  ref: transcriptBox,
124689
125418
  flexDirection: "column",
124690
125419
  flexGrow: 1,
@@ -124693,7 +125422,8 @@ function Repl(props) {
124693
125422
  justifyContent: !sessionStarted ? "flex-start" : "flex-end",
124694
125423
  overflowY: "hidden",
124695
125424
  children: [
124696
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Transcript, {
125425
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Transcript, {
125426
+ viewKey: `${sessionId ?? "new"}:${viewedTaskId ?? "main"}`,
124697
125427
  items: visibleItems,
124698
125428
  expandThinking,
124699
125429
  expandTools,
@@ -124702,22 +125432,22 @@ function Repl(props) {
124702
125432
  offset: scrollOffset,
124703
125433
  onOffset: setScrollOffset
124704
125434
  }, undefined, false, undefined, this),
124705
- !sessionStarted ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
125435
+ !sessionStarted ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
124706
125436
  flexDirection: "column",
124707
125437
  paddingX: 2,
124708
125438
  marginTop: 1,
124709
125439
  marginBottom: 1,
124710
125440
  children: [
124711
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
125441
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text2, {
124712
125442
  bold: true,
124713
125443
  color: theme.brand,
124714
125444
  children: "What would you like to work on?"
124715
125445
  }, undefined, false, undefined, this),
124716
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
125446
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text2, {
124717
125447
  color: theme.dim,
124718
125448
  children: "/connect providers \xB7 /model models \xB7 /resume sessions"
124719
125449
  }, undefined, false, undefined, this),
124720
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
125450
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text2, {
124721
125451
  color: theme.dim,
124722
125452
  children: "Ctrl+L models \xB7 Shift+Tab effort \xB7 /shortcuts keyboard help"
124723
125453
  }, undefined, false, undefined, this)
@@ -124725,52 +125455,52 @@ function Repl(props) {
124725
125455
  }, undefined, true, undefined, this) : null
124726
125456
  ]
124727
125457
  }, undefined, true, undefined, this),
124728
- running ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Spinner, {}, undefined, false, undefined, this) : null,
124729
- switching ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Spinner, {
125458
+ running ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Spinner, {}, undefined, false, undefined, this) : null,
125459
+ switching ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Spinner, {
124730
125460
  label: "Applying changes"
124731
125461
  }, undefined, false, undefined, this) : null,
124732
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(TodoPanel, {
125462
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(TodoPanel, {
124733
125463
  todos,
124734
125464
  maxRows: layout.todoRows
124735
125465
  }, undefined, false, undefined, this),
124736
- layout.jobRows > 0 && jobs.some((job) => job.status === "running") ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
125466
+ layout.jobRows > 0 && jobs.some((job) => job.status === "running") ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
124737
125467
  flexDirection: "column",
124738
125468
  paddingX: 1,
124739
125469
  flexShrink: 0,
124740
125470
  children: [
124741
- jobs.filter((job) => job.status === "running").slice(-1).map((job) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
125471
+ jobs.filter((job) => job.status === "running").slice(-1).map((job) => /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text2, {
124742
125472
  color: theme.dim,
124743
125473
  children: fitTerminalLine(`${job.kind} ${job.jobId.slice(0, 8)} \xB7 ${job.background ? "background" : "foreground"} \xB7 ${job.description}`, size.columns - 2)
124744
125474
  }, job.jobId, false, undefined, this)),
124745
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text2, {
125475
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text2, {
124746
125476
  color: theme.dim,
124747
125477
  children: fitTerminalLine("Ctrl+B move foreground job to background", size.columns - 2)
124748
125478
  }, undefined, false, undefined, this)
124749
125479
  ]
124750
125480
  }, undefined, true, undefined, this) : null,
124751
- pending ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ApprovalDialog, {
125481
+ pending ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ApprovalDialog, {
124752
125482
  request: pending.request,
124753
125483
  onAnswer: answer
124754
125484
  }, undefined, false, undefined, this) : null,
124755
- pending ? null : question?.input ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(AskDialog, {
125485
+ pending ? null : question?.input ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(AskDialog, {
124756
125486
  input: question.input,
124757
125487
  onAnswer: (output) => backend ? void backend.request("/api/ask", { id: question.id, output }).catch(reportRemote) : askRef.current?.respond(question.id, output),
124758
125488
  onCancel: () => backend ? void backend.request("/api/ask", { id: question.id, cancel: true }).catch(reportRemote) : askRef.current?.respond(question.id)
124759
- }, question.id, false, undefined, this) : authBox ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(AuthDialog, {
125489
+ }, question.id, false, undefined, this) : authBox ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(AuthDialog, {
124760
125490
  auth: authBox,
124761
125491
  onCopied: (label) => print(`${label} copied to clipboard.`),
124762
125492
  onClose: () => setAuthBox(null)
124763
- }, undefined, false, undefined, this) : renameTarget ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(RenameInput, {
125493
+ }, undefined, false, undefined, this) : renameTarget ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(RenameInput, {
124764
125494
  initial: renameTarget.title,
124765
125495
  onSubmit: applyRename,
124766
125496
  onCancel: () => setRenameTarget(null)
124767
- }, undefined, false, undefined, this) : picker ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Selector, {
125497
+ }, undefined, false, undefined, this) : picker ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Selector, {
124768
125498
  title: picker.title,
124769
125499
  items: picker.items,
124770
125500
  onSelect: picker.onSelect,
124771
125501
  onCancel: () => setPicker(null),
124772
125502
  actions: picker.actions
124773
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(PromptInput, {
125503
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(PromptInput, {
124774
125504
  maxEditorLines: layout.inputRows,
124775
125505
  running: running || switching,
124776
125506
  editor,
@@ -124780,7 +125510,7 @@ function Repl(props) {
124780
125510
  onShortcut: handleShortcut,
124781
125511
  onInterrupt: interrupt
124782
125512
  }, undefined, false, undefined, this),
124783
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(StatusBar, {
125513
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(StatusBar, {
124784
125514
  modelLabel: thinking === "off" ? `${modelLabelText} \u2022 thinking off` : `${modelLabelText} \u2022 ${thinking}`,
124785
125515
  workspace,
124786
125516
  title: selectedTask ? `Subagent: ${selectedTask.description}` : title,
@@ -124791,7 +125521,7 @@ function Repl(props) {
124791
125521
  ]
124792
125522
  }, undefined, true, undefined, this);
124793
125523
  }
124794
- var import_react42, jsx_dev_runtime13;
125524
+ var import_react42, jsx_dev_runtime14;
124795
125525
  var init_app = __esm(async () => {
124796
125526
  init_src5();
124797
125527
  init_src7();
@@ -124827,7 +125557,7 @@ var init_app = __esm(async () => {
124827
125557
  init_Selector()
124828
125558
  ]);
124829
125559
  import_react42 = __toESM(require_react(), 1);
124830
- jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
125560
+ jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
124831
125561
  });
124832
125562
 
124833
125563
  // packages/repl/src/diagnostics.ts
@@ -124939,8 +125669,8 @@ var init_model = __esm(() => {
124939
125669
  // packages/app/src/workspace-review.ts
124940
125670
  import { execFile } from "child_process";
124941
125671
  import { constants as constants2 } from "fs";
124942
- import { lstat, open as open3, opendir, realpath as realpath2 } from "fs/promises";
124943
- import { isAbsolute as isAbsolute4, join as join13, relative as relative4, resolve as resolve10, sep as sep2 } from "path";
125672
+ import { lstat as lstat2, open as open3, opendir as opendir2, realpath as realpath3 } from "fs/promises";
125673
+ import { isAbsolute as isAbsolute5, join as join14, relative as relative5, resolve as resolve11, sep as sep3 } from "path";
124944
125674
  import { promisify } from "util";
124945
125675
 
124946
125676
  class WorkspaceReview {
@@ -124949,29 +125679,29 @@ class WorkspaceReview {
124949
125679
  this.root = root;
124950
125680
  }
124951
125681
  async target(path) {
124952
- if (typeof path !== "string" || path.length > REVIEW_LIMITS.path || path.includes("\x00") || isAbsolute4(path) || path.split(/[\\/]/).some((part) => part === ".." || part.includes(":")))
125682
+ if (typeof path !== "string" || path.length > REVIEW_LIMITS.path || path.includes("\x00") || isAbsolute5(path) || path.split(/[\\/]/).some((part) => part === ".." || part.includes(":")))
124953
125683
  throw new Error("Invalid workspace-relative path.");
124954
- const root = await realpath2(this.root);
124955
- const candidate = resolve10(root, path || ".");
124956
- const rel = relative4(root, candidate);
124957
- if (isAbsolute4(rel) || rel === ".." || rel.startsWith(`..${sep2}`))
125684
+ const root = await realpath3(this.root);
125685
+ const candidate = resolve11(root, path || ".");
125686
+ const rel = relative5(root, candidate);
125687
+ if (isAbsolute5(rel) || rel === ".." || rel.startsWith(`..${sep3}`))
124958
125688
  throw new Error("Path is outside the workspace.");
124959
125689
  let current = root;
124960
- for (const part of rel.split(sep2).filter(Boolean)) {
124961
- current = join13(current, part);
124962
- if ((await lstat(current)).isSymbolicLink())
125690
+ for (const part of rel.split(sep3).filter(Boolean)) {
125691
+ current = join14(current, part);
125692
+ if ((await lstat2(current)).isSymbolicLink())
124963
125693
  throw new Error("Links cannot be opened in the workspace viewer.");
124964
125694
  }
124965
- const target = await realpath2(candidate);
124966
- const canonical = relative4(root, target);
124967
- if (isAbsolute4(canonical) || canonical === ".." || canonical.startsWith(`..${sep2}`))
125695
+ const target = await realpath3(candidate);
125696
+ const canonical = relative5(root, target);
125697
+ if (isAbsolute5(canonical) || canonical === ".." || canonical.startsWith(`..${sep3}`))
124968
125698
  throw new Error("Path is outside the workspace.");
124969
125699
  return { root, target };
124970
125700
  }
124971
125701
  async list(path = "") {
124972
125702
  const { target } = await this.target(path);
124973
125703
  const entries = [];
124974
- for await (const item of await opendir(target)) {
125704
+ for await (const item of await opendir2(target)) {
124975
125705
  if (!item.isSymbolicLink() && item.name !== ".git" && (item.isFile() || item.isDirectory()))
124976
125706
  entries.push(item);
124977
125707
  if (entries.length > REVIEW_LIMITS.entries)
@@ -125009,10 +125739,10 @@ var init_workspace_review = __esm(() => {
125009
125739
  });
125010
125740
 
125011
125741
  // packages/app/src/services/sync.ts
125012
- import { randomUUID as randomUUID7 } from "crypto";
125742
+ import { randomUUID as randomUUID8 } from "crypto";
125013
125743
 
125014
125744
  class SyncManager {
125015
- instance = randomUUID7();
125745
+ instance = randomUUID8();
125016
125746
  revision = 0;
125017
125747
  subscribers = new Set;
125018
125748
  publish(kind, sessionId) {
@@ -125141,11 +125871,11 @@ var init_runs = __esm(() => {
125141
125871
  });
125142
125872
 
125143
125873
  // packages/app/src/server.ts
125144
- import { randomUUID as randomUUID8 } from "crypto";
125145
- import { existsSync as existsSync4, mkdirSync as mkdirSync12, readdirSync as readdirSync3, statSync as statSync6 } from "fs";
125874
+ import { randomUUID as randomUUID9 } from "crypto";
125875
+ import { existsSync as existsSync5, mkdirSync as mkdirSync12, readdirSync as readdirSync3, statSync as statSync6 } from "fs";
125146
125876
  import { readFile as readFile4 } from "fs/promises";
125147
125877
  import { homedir as homedir3 } from "os";
125148
- import { basename as basename3, dirname as dirname11, extname, join as join14, relative as relative5, resolve as resolve11, sep as sep3 } from "path";
125878
+ import { basename as basename3, dirname as dirname11, extname, join as join15, relative as relative6, resolve as resolve12, sep as sep4 } from "path";
125149
125879
  function json3(data, status = 200) {
125150
125880
  return new Response(JSON.stringify(data), {
125151
125881
  status,
@@ -125193,9 +125923,9 @@ function startServer(options = {}) {
125193
125923
  throw new Error("Shared backends only support loopback hosts. Unset RINGKO_HOST or use 127.0.0.1.");
125194
125924
  const configuredPort = Number(process.env.RINGKO_PORT);
125195
125925
  const port = options.port ?? (Number.isInteger(configuredPort) && configuredPort > 0 ? configuredPort : DEFAULT_PORT);
125196
- let workspace = resolve11(options.workspace ?? process.cwd());
125197
- const bundledWebuiDir = resolve11(import.meta.dir, "../webui");
125198
- const webuiDir = resolve11(options.webuiDir ?? process.env.RINGKO_WEBUI_DIR ?? (existsSync4(join14(DEFAULT_WEBUI_DIR, "index.html")) ? DEFAULT_WEBUI_DIR : existsSync4(join14(bundledWebuiDir, "index.html")) ? bundledWebuiDir : join14(dirname11(process.execPath), "webui")));
125926
+ let workspace = resolve12(options.workspace ?? process.cwd());
125927
+ const bundledWebuiDir = resolve12(import.meta.dir, "../webui");
125928
+ const webuiDir = resolve12(options.webuiDir ?? process.env.RINGKO_WEBUI_DIR ?? (existsSync5(join15(DEFAULT_WEBUI_DIR, "index.html")) ? DEFAULT_WEBUI_DIR : existsSync5(join15(bundledWebuiDir, "index.html")) ? bundledWebuiDir : join15(dirname11(process.execPath), "webui")));
125199
125929
  let store = new SessionStore({ cwd: workspace });
125200
125930
  const approvals = new Map;
125201
125931
  const questions = new Map;
@@ -125237,7 +125967,7 @@ function startServer(options = {}) {
125237
125967
  if (activeProject && !options.shared && !options.workspace) {
125238
125968
  try {
125239
125969
  if (statSync6(activeProject.path).isDirectory())
125240
- workspace = resolve11(activeProject.path);
125970
+ workspace = resolve12(activeProject.path);
125241
125971
  } catch {}
125242
125972
  }
125243
125973
  store = new SessionStore({ cwd: workspace });
@@ -125249,14 +125979,14 @@ function startServer(options = {}) {
125249
125979
  projects = id ? { projects: projects.projects, current: id } : { projects: projects.projects };
125250
125980
  saveProjects(projects);
125251
125981
  const active = id ? projects.projects.find((entry) => entry.id === id) : undefined;
125252
- workspace = active ? resolve11(active.path) : baseWorkspace;
125982
+ workspace = active ? resolve12(active.path) : baseWorkspace;
125253
125983
  store = new SessionStore({ cwd: workspace });
125254
125984
  resetMcp();
125255
125985
  sync.publish("workspace");
125256
125986
  }
125257
125987
  const runtimes = new Map;
125258
125988
  function runtimeFor(cwd) {
125259
- const path = resolve11(cwd);
125989
+ const path = resolve12(cwd);
125260
125990
  let runtime = runtimes.get(path);
125261
125991
  if (!runtime) {
125262
125992
  runtime = new RuntimeManager(path, eventLog);
@@ -125338,16 +126068,16 @@ function startServer(options = {}) {
125338
126068
  const raw = typeof body?.path === "string" ? body.path.trim() : "";
125339
126069
  if (raw.length === 0)
125340
126070
  return json3({ error: "path is required." }, 400);
125341
- const target = resolve11(raw);
126071
+ const target = resolve12(raw);
125342
126072
  try {
125343
126073
  if (!statSync6(target).isDirectory())
125344
126074
  return json3({ error: "path is not a directory." }, 400);
125345
126075
  } catch {
125346
126076
  return json3({ error: "path does not exist." }, 400);
125347
126077
  }
125348
- const existing = projects.projects.find((entry) => resolve11(entry.path) === target);
126078
+ const existing = projects.projects.find((entry) => resolve12(entry.path) === target);
125349
126079
  if (!existing) {
125350
- const id = `proj-${randomUUID8().slice(0, 8)}`;
126080
+ const id = `proj-${randomUUID9().slice(0, 8)}`;
125351
126081
  const name = typeof body?.name === "string" && body.name.trim().length > 0 ? body.name.trim() : basename3(target);
125352
126082
  projects = { projects: [...projects.projects, { id, name, path: target }], ...projects.current ? { current: projects.current } : {} };
125353
126083
  if (!projects.current) {
@@ -125361,7 +126091,7 @@ function startServer(options = {}) {
125361
126091
  const LIST_LIMIT = 2000;
125362
126092
  function crumbsFor(target) {
125363
126093
  const crumbs = [];
125364
- let current = resolve11(target);
126094
+ let current = resolve12(target);
125365
126095
  for (;; ) {
125366
126096
  const parent = dirname11(current);
125367
126097
  crumbs.unshift({ name: basename3(current) || current, path: current });
@@ -125374,7 +126104,7 @@ function startServer(options = {}) {
125374
126104
  function handleListDirectory(url) {
125375
126105
  const home = homedir3();
125376
126106
  const requested = url.searchParams.get("path");
125377
- const target = requested && requested.trim().length > 0 ? resolve11(requested) : home;
126107
+ const target = requested && requested.trim().length > 0 ? resolve12(requested) : home;
125378
126108
  let dirents;
125379
126109
  try {
125380
126110
  dirents = readdirSync3(target, { withFileTypes: true });
@@ -125382,11 +126112,11 @@ function startServer(options = {}) {
125382
126112
  const code = error.code;
125383
126113
  return json3({ error: code === "ENOENT" ? "Directory not found." : "Cannot read this directory." }, 400);
125384
126114
  }
125385
- const entries = dirents.filter((entry) => entry.isDirectory()).map((entry) => ({ name: entry.name, path: join14(target, entry.name), hidden: entry.name.startsWith(".") })).sort((a, b) => a.name.localeCompare(b.name));
126115
+ const entries = dirents.filter((entry) => entry.isDirectory()).map((entry) => ({ name: entry.name, path: join15(target, entry.name), hidden: entry.name.startsWith(".") })).sort((a, b) => a.name.localeCompare(b.name));
125386
126116
  return json3({
125387
126117
  path: target,
125388
126118
  home,
125389
- separator: sep3,
126119
+ separator: sep4,
125390
126120
  crumbs: crumbsFor(target),
125391
126121
  entries: entries.slice(0, LIST_LIMIT),
125392
126122
  truncated: entries.length > LIST_LIMIT
@@ -125401,7 +126131,7 @@ function startServer(options = {}) {
125401
126131
  if (name.trim().length === 0 || name.includes("/") || name.includes("\\")) {
125402
126132
  return json3({ error: "name must be a single folder name." }, 400);
125403
126133
  }
125404
- const target = join14(resolve11(parent), name);
126134
+ const target = join15(resolve12(parent), name);
125405
126135
  try {
125406
126136
  mkdirSync12(target, { recursive: false });
125407
126137
  } catch (error) {
@@ -125508,7 +126238,7 @@ function startServer(options = {}) {
125508
126238
  const url = typeof body?.url === "string" ? body.url.trim() : "";
125509
126239
  if (name.length === 0 || url.length === 0)
125510
126240
  return json3({ error: "name and url are required." }, 400);
125511
- const id = randomUUID8();
126241
+ const id = randomUUID9();
125512
126242
  oauthFlows.set(id, { status: "pending", createdAt: now });
125513
126243
  let resolveIssued;
125514
126244
  const issued = new Promise((resolve) => {
@@ -125691,13 +126421,13 @@ function startServer(options = {}) {
125691
126421
  return json3({ error: `Unsupported OAuth domain "${domain}".` }, 400);
125692
126422
  if ([...oauthFlows.values()].filter((flow) => flow.status === "pending").length >= 4 || oauthFlows.size >= 64)
125693
126423
  return json3({ error: "Too many sign-in attempts. Finish an existing attempt or retry later." }, 429);
125694
- const id = randomUUID8();
126424
+ const id = randomUUID9();
125695
126425
  oauthFlows.set(id, { status: "pending", createdAt: now });
125696
126426
  let resolveIssued;
125697
126427
  const onCode = (url, code) => resolveIssued?.({ url, code });
125698
126428
  const login = kind === "openai" ? loginOpenAiDevice(onCode) : kind === "copilot" ? loginGitHubCopilot(onCode) : kind === "anthropic" ? loginAnthropic((url) => onCode(url, "")) : loginXaiDevice(onCode);
125699
126429
  const outcome = login.then((credential) => {
125700
- const accountId = credential.accountId ?? credential.login ?? randomUUID8();
126430
+ const accountId = credential.accountId ?? credential.login ?? randomUUID9();
125701
126431
  setOAuthAccount(domain, { id: accountId, credential, authenticatedAt: Date.now() });
125702
126432
  oauthFlows.set(id, { status: "success", createdAt: now });
125703
126433
  return;
@@ -125798,6 +126528,12 @@ function startServer(options = {}) {
125798
126528
  return json3({ error: "Could not fork session." }, 500);
125799
126529
  }
125800
126530
  }
126531
+ function persistSettings(config) {
126532
+ if (options.configPath)
126533
+ saveConfigFile(config, options.configPath);
126534
+ else
126535
+ saveSettings(config);
126536
+ }
125801
126537
  async function handleSetAccess(request) {
125802
126538
  const body = await readJson(request);
125803
126539
  const permission = body?.permission ?? body?.mode;
@@ -125807,7 +126543,7 @@ function startServer(options = {}) {
125807
126543
  const config = readConfig();
125808
126544
  if (typeof config === "string")
125809
126545
  return json3({ error: config }, 500);
125810
- saveSettings({ ...config, permission, mode: permission });
126546
+ persistSettings({ ...config, permission, mode: permission });
125811
126547
  return await handleInfo();
125812
126548
  }
125813
126549
  async function handleSetMode(request) {
@@ -125818,7 +126554,7 @@ function startServer(options = {}) {
125818
126554
  const config = readConfig();
125819
126555
  if (typeof config === "string")
125820
126556
  return json3({ error: config }, 500);
125821
- saveSettings({ ...config, workflow });
126557
+ persistSettings({ ...config, workflow });
125822
126558
  return await handleInfo();
125823
126559
  }
125824
126560
  async function handleUpload(request) {
@@ -125831,13 +126567,13 @@ function startServer(options = {}) {
125831
126567
  const files = form.getAll("file").filter((value) => value instanceof File);
125832
126568
  if (files.length === 0)
125833
126569
  return json3({ error: "no files." }, 400);
125834
- const dir = join14(workspace, ".ringko", "uploads");
126570
+ const dir = join15(workspace, ".ringko", "uploads");
125835
126571
  mkdirSync12(dir, { recursive: true });
125836
126572
  const saved = [];
125837
126573
  for (const file of files) {
125838
126574
  const safe = file.name.replace(/[^A-Za-z0-9._-]/g, "_");
125839
126575
  const stored = `${Date.now()}-${safe}`;
125840
- await Bun.write(join14(dir, stored), file);
126576
+ await Bun.write(join15(dir, stored), file);
125841
126577
  saved.push({ name: file.name, path: `.ringko/uploads/${stored}` });
125842
126578
  }
125843
126579
  return json3({ files: saved });
@@ -125851,7 +126587,7 @@ function startServer(options = {}) {
125851
126587
  const config = readConfig();
125852
126588
  if (typeof config === "string")
125853
126589
  return json3({ error: config }, 500);
125854
- saveSettings({ ...config, thinking: level });
126590
+ persistSettings({ ...config, thinking: level });
125855
126591
  return await handleInfo();
125856
126592
  }
125857
126593
  async function handleSetUi(request) {
@@ -125864,7 +126600,7 @@ function startServer(options = {}) {
125864
126600
  next.expandThinking = body.expandThinking;
125865
126601
  if (typeof body?.expandTools === "boolean")
125866
126602
  next.expandTools = body.expandTools;
125867
- saveSettings(next);
126603
+ persistSettings(next);
125868
126604
  return await handleInfo();
125869
126605
  }
125870
126606
  async function handleCompact(request) {
@@ -125928,7 +126664,10 @@ function startServer(options = {}) {
125928
126664
  if (!(provider.models ?? []).some((entry) => entry.id === modelId)) {
125929
126665
  return json3({ error: `unknown model "${modelId}" for provider "${providerName}".` }, 400);
125930
126666
  }
125931
- saveProviders({ ...loadProviders(), model: target });
126667
+ if (options.configPath)
126668
+ saveConfigFile({ ...config, model: target }, options.configPath);
126669
+ else
126670
+ saveProviders({ ...loadProviders(), model: target });
125932
126671
  return await handleInfo();
125933
126672
  }
125934
126673
  function sessionTitleView(events) {
@@ -126174,7 +126913,7 @@ function startServer(options = {}) {
126174
126913
  } catch {
126175
126914
  return json3({ error: "Unknown or locked session." }, 404);
126176
126915
  }
126177
- const call = { id: randomUUID8(), name: "shell", arguments: { command: body.command } };
126916
+ const call = { id: randomUUID9(), name: "shell", arguments: { command: body.command } };
126178
126917
  const abort = beginRun(session, () => {
126179
126918
  session.appendEvent("run/started", { kind: "shell" });
126180
126919
  recordUserMessage(session, `!${body.command}`);
@@ -126246,7 +126985,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126246
126985
  if (activeRuns.has(body.sessionId))
126247
126986
  return json3({ error: "This session already has an active run. Queue the message until it finishes." }, 409);
126248
126987
  const existing = runStore.open(body.sessionId, "read");
126249
- if (existing.header.cwd && resolve11(existing.header.cwd) !== runWorkspace)
126988
+ if (existing.header.cwd && resolve12(existing.header.cwd) !== runWorkspace)
126250
126989
  return json3({ error: "Session belongs to a different workspace." }, 409);
126251
126990
  history = toChatMessages(existing.all());
126252
126991
  session = runStore.open(body.sessionId, "write");
@@ -126320,7 +127059,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126320
127059
  ...config.compaction ? { compaction: config.compaction } : {},
126321
127060
  ...isAccessMode(config.permission) ? { accessMode: config.permission } : isAccessMode(config.mode) ? { accessMode: config.mode } : {},
126322
127061
  requestApproval: async (approval) => {
126323
- const id = randomUUID8();
127062
+ const id = randomUUID9();
126324
127063
  send("approval", { id, toolName: approval.toolName, riskLevel: approval.riskLevel, riskKind: approval.riskKind, reason: approval.reason, target: approval.target ?? null });
126325
127064
  return await new Promise((resolveApproval) => {
126326
127065
  const approvalSignal = approval.signal ?? abort.signal;
@@ -126486,16 +127225,16 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126486
127225
  }
126487
127226
  async function serveStatic(pathname) {
126488
127227
  const rel = pathname === "/" ? "index.html" : pathname.replace(/^\/+/, "");
126489
- const target = resolve11(join14(webuiDir, rel));
126490
- const withinRoot = relative5(webuiDir, target);
127228
+ const target = resolve12(join15(webuiDir, rel));
127229
+ const withinRoot = relative6(webuiDir, target);
126491
127230
  if (withinRoot.startsWith("..") || withinRoot.includes(".."))
126492
127231
  return json3({ error: "not found" }, 404);
126493
127232
  let file = target;
126494
127233
  try {
126495
127234
  if (statSync6(file).isDirectory())
126496
- file = join14(file, "index.html");
127235
+ file = join15(file, "index.html");
126497
127236
  } catch {
126498
- file = join14(webuiDir, "index.html");
127237
+ file = join15(webuiDir, "index.html");
126499
127238
  }
126500
127239
  try {
126501
127240
  const bytes = await readFile4(file);
@@ -126538,7 +127277,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126538
127277
  const nodePath = Bun.which("node");
126539
127278
  if (!nodePath)
126540
127279
  throw new Error("Interactive terminals require Node.js in PATH.");
126541
- const bridgePath = join14(import.meta.dir, "terminal-bridge.mjs");
127280
+ const bridgePath = join15(import.meta.dir, "terminal-bridge.mjs");
126542
127281
  const child = Bun.spawn([nodePath, bridgePath], {
126543
127282
  cwd,
126544
127283
  env: { ...process.env },
@@ -126658,7 +127397,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126658
127397
  } catch (cause) {
126659
127398
  return json3({ error: cause instanceof Error ? cause.message : "Could not start a terminal." }, 500);
126660
127399
  }
126661
- const id = randomUUID8();
127400
+ const id = randomUUID9();
126662
127401
  const session = { terminal, exited: false, pendingOutput: "" };
126663
127402
  terminalSessions.set(id, session);
126664
127403
  terminal.onData((data) => {
@@ -126756,7 +127495,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126756
127495
  const expectedWorkspace = request.headers.get("x-ringko-workspace");
126757
127496
  if (expectedWorkspace) {
126758
127497
  try {
126759
- if (resolve11(decodeURIComponent(expectedWorkspace)) !== workspace)
127498
+ if (resolve12(decodeURIComponent(expectedWorkspace)) !== workspace)
126760
127499
  return json3({ error: "Backend workspace changed. Reconnect to the correct workspace." }, 409);
126761
127500
  } catch {
126762
127501
  return json3({ error: "Invalid workspace header." }, 400);
@@ -126771,7 +127510,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126771
127510
  }
126772
127511
  }
126773
127512
  if (url.pathname === "/api/backend" && request.method === "GET")
126774
- return json3({ protocol: PROTOCOL_VERSION2, instance: sync.instance, workspace, configPath: options.configPath ? resolve11(options.configPath) : null });
127513
+ return json3({ protocol: PROTOCOL_VERSION2, instance: sync.instance, workspace, configPath: options.configPath ? resolve12(options.configPath) : null });
126775
127514
  if (url.pathname === "/api/backend/stop" && request.method === "POST") {
126776
127515
  if (activeRuns.size)
126777
127516
  return json3({ error: "Stop active sessions before stopping the backend." }, 409);
@@ -126914,7 +127653,7 @@ Attached files (read them if relevant): ${attachments.join(", ")}` : raw;
126914
127653
  if (options.shared) {
126915
127654
  try {
126916
127655
  const existing = store.open(id, "read");
126917
- if (existing.header.cwd && resolve11(existing.header.cwd) !== workspace)
127656
+ if (existing.header.cwd && resolve12(existing.header.cwd) !== workspace)
126918
127657
  return json3({ error: "Session belongs to a different workspace." }, 409);
126919
127658
  } catch {
126920
127659
  return json3({ error: "Unknown session." }, 404);
@@ -127074,7 +127813,7 @@ var init_server = __esm(() => {
127074
127813
  init_src9();
127075
127814
  init_sync();
127076
127815
  init_runs();
127077
- DEFAULT_WEBUI_DIR = resolve11(import.meta.dir, "../../webui/dist");
127816
+ DEFAULT_WEBUI_DIR = resolve12(import.meta.dir, "../../webui/dist");
127078
127817
  APPROVAL_TIMEOUT_MS = 5 * 60 * 1000;
127079
127818
  TERMINAL_SESSION_TTL_MS = 30 * 60 * 1000;
127080
127819
  MIME = {
@@ -127102,10 +127841,9 @@ var init_src15 = __esm(() => {
127102
127841
  init_src5();
127103
127842
 
127104
127843
  // packages/tui/src/cli-identity.ts
127105
- var NPM_CLI_COMMAND = "rkh";
127106
- function cliCommand(entry = process.argv[1]) {
127107
- const name = (entry ?? "").replace(/\\/g, "/").split("/").pop()?.replace(/\.(mjs|cmd|exe)$/, "");
127108
- return name === NPM_CLI_COMMAND ? NPM_CLI_COMMAND : "ringko";
127844
+ var CLI_COMMAND = "ringko";
127845
+ function cliCommand(_entry = process.argv[1]) {
127846
+ return CLI_COMMAND;
127109
127847
  }
127110
127848
 
127111
127849
  // packages/tui/src/resume-hint.ts
@@ -127121,36 +127859,37 @@ ${source} tui --session ${quote(sessionId, windows)} --workspace ${quote(workspa
127121
127859
 
127122
127860
  // packages/tui/src/cli.ts
127123
127861
  init_runtime();
127124
- import { resolve as resolve12 } from "path";
127862
+ import { resolve as resolve13 } from "path";
127125
127863
 
127126
127864
  // packages/tui/src/backend.ts
127127
127865
  init_src10();
127128
127866
  import { spawn as spawn2 } from "child_process";
127129
- import { resolve as resolve8 } from "path";
127867
+ import { resolve as resolve9 } from "path";
127130
127868
 
127131
127869
  // packages/client/src/local.ts
127132
127870
  import { createHash as createHash3 } from "crypto";
127133
- import { realpathSync } from "fs";
127134
- import { resolve as resolve7 } from "path";
127871
+ import { realpathSync as realpathSync2 } from "fs";
127872
+ import { resolve as resolve8 } from "path";
127135
127873
  var SERVICE_PORT_BASE = 22000;
127136
127874
  var SERVICE_PORT_RANGE = 20000;
127137
127875
  function canonicalWorkspace(workspace) {
127138
- return realpathSync(resolve7(workspace));
127876
+ return realpathSync2(resolve8(workspace));
127139
127877
  }
127140
127878
  function sharedPort(workspace, configPath) {
127141
127879
  const path = canonicalWorkspace(workspace);
127142
127880
  const normalized = process.platform === "win32" ? path.toLowerCase() : path;
127143
- const config = configPath ? resolve7(configPath) : "";
127881
+ const config = configPath ? resolve8(configPath) : "";
127144
127882
  const key = `${normalized}\x00${process.platform === "win32" ? config.toLowerCase() : config}`;
127145
127883
  return SERVICE_PORT_BASE + createHash3("sha256").update(key).digest().readUInt32BE(0) % SERVICE_PORT_RANGE;
127146
127884
  }
127885
+
127147
127886
  // packages/tui/src/backend.ts
127148
127887
  var START_TIMEOUT_MS = 15000;
127149
127888
  var PROBE_TIMEOUT_MS = 1000;
127150
127889
  var RETRY_MS = 200;
127151
127890
  async function connectBackend(options) {
127152
127891
  const workspace = canonicalWorkspace(options.workspace);
127153
- const configPath = options.configPath ? resolve8(options.configPath) : undefined;
127892
+ const configPath = options.configPath ? resolve9(options.configPath) : undefined;
127154
127893
  const token = process.env.RINGKO_WEB_TOKEN?.trim();
127155
127894
  const explicit = options.url ?? process.env.RINGKO_SERVER;
127156
127895
  const port = sharedPort(workspace, configPath);
@@ -127170,7 +127909,7 @@ async function connectBackend(options) {
127170
127909
  throw error;
127171
127910
  return false;
127172
127911
  }
127173
- if (identity.protocol !== PROTOCOL_VERSION2 || resolve8(identity.workspace) !== workspace || (identity.configPath ?? undefined) !== configPath) {
127912
+ if (identity.protocol !== PROTOCOL_VERSION2 || resolve9(identity.workspace) !== workspace || (identity.configPath ?? undefined) !== configPath) {
127174
127913
  throw new Error("This port belongs to a different backend/workspace/configuration. Use --server with the correct local backend address.");
127175
127914
  }
127176
127915
  return true;
@@ -127187,7 +127926,7 @@ async function connectBackend(options) {
127187
127926
  const executable = process.execPath;
127188
127927
  const script = process.argv[1];
127189
127928
  const compiled = script?.includes("$bunfs") || script?.includes("~BUN") || script === executable;
127190
- const args = [...!compiled && script ? [resolve8(script)] : [], "serve", "--shared", "--port", String(port), "--workspace", workspace, ...configPath ? ["--config", configPath] : []];
127929
+ const args = [...!compiled && script ? [resolve9(script)] : [], "serve", "--shared", "--port", String(port), "--workspace", workspace, ...configPath ? ["--config", configPath] : []];
127191
127930
  const child = spawn2(executable, args, { cwd: workspace, env: process.env, detached: true, stdio: "ignore", windowsHide: true });
127192
127931
  const spawned = new Promise((ready, reject) => {
127193
127932
  child.once("spawn", ready);
@@ -127213,7 +127952,7 @@ init_src3();
127213
127952
  // packages/tui/src/provider.ts
127214
127953
  init_loader();
127215
127954
  // packages/tui/package.json
127216
- var version2 = "0.1.0";
127955
+ var version2 = "0.2.1-rc";
127217
127956
 
127218
127957
  // packages/tui/src/cli.ts
127219
127958
  var VERSION8 = version2;
@@ -127263,7 +128002,7 @@ Options:
127263
128002
  --completion-promise <text> (loop) Stop when a reply contains <promise>text</promise>
127264
128003
 
127265
128004
  Providers are introduced through configuration; the config names a provider
127266
- module that is imported at run time. See docs/PROVIDERS.md.
128005
+ module that is imported at run time.
127267
128006
  `;
127268
128007
  function denyApprovals(io) {
127269
128008
  return async (request) => {
@@ -127522,7 +128261,7 @@ async function tuiCommand(parsed, io) {
127522
128261
  ...info.modelId ? { modelId: info.modelId } : {}
127523
128262
  });
127524
128263
  if (sessionId && (await backend.sessions()).some((session) => session.id === sessionId)) {
127525
- io.out(resumeHint(sessionId, resolve12(workspace), process.argv[1]));
128264
+ io.out(resumeHint(sessionId, resolve13(workspace), process.argv[1]));
127526
128265
  }
127527
128266
  return 0;
127528
128267
  }
@@ -127530,7 +128269,7 @@ async function serveCommand(parsed, io) {
127530
128269
  await Promise.resolve().then(() => init_src15());
127531
128270
  let server;
127532
128271
  try {
127533
- server = startServer({ workspace: resolve12(parsed.workspace ?? process.cwd()), port: parsed.port, configPath: parsed.config, shared: parsed.shared, authToken: process.env.RINGKO_WEB_TOKEN?.trim() });
128272
+ server = startServer({ workspace: resolve13(parsed.workspace ?? process.cwd()), port: parsed.port, configPath: parsed.config, shared: parsed.shared, authToken: process.env.RINGKO_WEB_TOKEN?.trim() });
127534
128273
  } catch (error) {
127535
128274
  io.err(error instanceof Error ? error.message : "Backend startup failed.");
127536
128275
  return 1;