@mtreeai/msapling-cli 2.3.6-beta.23 → 2.3.6-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +678 -144
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -266,6 +266,125 @@ var init_src = __esm({
266
266
  body: JSON.stringify(symbol)
267
267
  });
268
268
  }
269
+ // CLI-MDRIVE-COMMANDS-01 (Iter 36): MDrive user-facing file CRUD. Per LAB
270
+ // routers/mdrive_files.py — all paths under /api/mdrive/ (assembled by
271
+ // mdrive_product.py).
272
+ async mdriveList(path2 = ".", limit = 1e3, offset = 0) {
273
+ const qs = new URLSearchParams({ path: path2, limit: String(limit), offset: String(offset) });
274
+ return await this.request(`/api/mdrive/list?${qs.toString()}`);
275
+ }
276
+ async mdriveRead(path2) {
277
+ return await this.request("/api/mdrive/read", {
278
+ method: "POST",
279
+ body: JSON.stringify({ path: path2 })
280
+ });
281
+ }
282
+ async mdriveWrite(path2, content) {
283
+ return await this.request("/api/mdrive/write", {
284
+ method: "POST",
285
+ body: JSON.stringify({ path: path2, content })
286
+ });
287
+ }
288
+ async mdriveDelete(path2) {
289
+ return await this.request("/api/mdrive/delete", {
290
+ method: "POST",
291
+ body: JSON.stringify({ path: path2 })
292
+ });
293
+ }
294
+ async mdriveRename(path2, newName) {
295
+ return await this.request("/api/mdrive/rename", {
296
+ method: "POST",
297
+ body: JSON.stringify({ path: path2, new_name: newName })
298
+ });
299
+ }
300
+ async mdriveMkdir(path2) {
301
+ return await this.request("/api/mdrive/mkdir", {
302
+ method: "POST",
303
+ body: JSON.stringify({ path: path2 })
304
+ });
305
+ }
306
+ // CLI-OLLAMA-COMMANDS-01 (Iter 35): Ollama BYOK helpers. Per LAB ollama.py
307
+ // routes are GET/POST/DELETE under /api/ollama. The CLI uses these to wire
308
+ // up the user's local Ollama instance as a free-tier model provider.
309
+ async getOllamaStatus() {
310
+ return await this.request("/api/ollama/status");
311
+ }
312
+ async configureOllama(opts) {
313
+ return await this.request("/api/ollama/configure", {
314
+ method: "POST",
315
+ body: JSON.stringify({
316
+ base_url: opts.baseUrl,
317
+ enabled: opts.enabled,
318
+ action: opts.action,
319
+ model: opts.model
320
+ })
321
+ });
322
+ }
323
+ async testOllama(baseUrl) {
324
+ return await this.request("/api/ollama/test", {
325
+ method: "POST",
326
+ body: JSON.stringify({ base_url: baseUrl })
327
+ });
328
+ }
329
+ async deleteOllamaModel(modelName) {
330
+ return await this.request(`/api/ollama/models/${encodeURIComponent(modelName)}`, {
331
+ method: "DELETE"
332
+ });
333
+ }
334
+ async disableOllama() {
335
+ return await this.request("/api/ollama/disable", { method: "POST" });
336
+ }
337
+ // CLI-KEYS-BYOK-01 (Iter 35): BYOK provider-key management. Per LAB
338
+ // routers/keys.py — /api/keys/{status,save,{provider}}.
339
+ async getProviderKeys() {
340
+ return await this.request("/api/keys/status");
341
+ }
342
+ async saveProviderKey(provider, apiKey) {
343
+ return await this.request("/api/keys/save", {
344
+ method: "POST",
345
+ body: JSON.stringify({ provider, api_key: apiKey })
346
+ });
347
+ }
348
+ async deleteProviderKey(provider) {
349
+ return await this.request(`/api/keys/${encodeURIComponent(provider)}`, { method: "DELETE" });
350
+ }
351
+ // CLI-CHAT-LIFECYCLE-01 (Iter 35): rename/delete/fork/pin. Per LAB
352
+ // projects.py:404 (PATCH), 879 (DELETE), 534 (POST fork), 726 (PATCH pin).
353
+ async renameChat(chatId, title) {
354
+ return await this.request(`/api/projects/chat/${encodeURIComponent(chatId)}`, {
355
+ method: "PATCH",
356
+ body: JSON.stringify({ title })
357
+ });
358
+ }
359
+ async deleteChat(chatId) {
360
+ return await this.request(`/api/projects/chat/${encodeURIComponent(chatId)}`, { method: "DELETE" });
361
+ }
362
+ async forkChat(chatId, body) {
363
+ return await this.request(`/api/projects/chat/${encodeURIComponent(chatId)}/fork`, {
364
+ method: "POST",
365
+ body: JSON.stringify(body ?? {})
366
+ });
367
+ }
368
+ async pinChat(chatId, pinned) {
369
+ return await this.request(`/api/projects/chat/${encodeURIComponent(chatId)}/pin`, {
370
+ method: "PATCH",
371
+ body: JSON.stringify({ pinned })
372
+ });
373
+ }
374
+ // CLI-MEMORIES-01 (Iter 35): backend-managed memories (vs the local notes
375
+ // /memory currently surfaces). Per LAB memories.py — list / create / delete.
376
+ async listMemories() {
377
+ return await this.request("/api/memories");
378
+ }
379
+ async createMemory(content) {
380
+ return await this.request("/api/memories", {
381
+ method: "POST",
382
+ body: JSON.stringify({ content })
383
+ });
384
+ }
385
+ async deleteMemory(memoryId) {
386
+ return await this.request(`/api/memories/${encodeURIComponent(memoryId)}`, { method: "DELETE" });
387
+ }
269
388
  // CLI-PROJECT-CREATE-01 (Iter 34): create a new project. Per LAB
270
389
  // projects.py:239 — POST /api/projects/ with {project_name}.
271
390
  async createProject(name) {
@@ -1213,7 +1332,7 @@ var init_RunCommandTool = __esm({
1213
1332
  this.activeCommands++;
1214
1333
  return;
1215
1334
  }
1216
- return new Promise((resolve18) => this.queue.push(resolve18));
1335
+ return new Promise((resolve19) => this.queue.push(resolve19));
1217
1336
  }
1218
1337
  static releaseLock() {
1219
1338
  if (this.queue.length > 0) {
@@ -1292,9 +1411,9 @@ var init_RunCommandTool = __esm({
1292
1411
  const chunks = { stdout: [], stderr: [] };
1293
1412
  proc.stdout?.on("data", (chunk) => chunks.stdout.push(chunk));
1294
1413
  proc.stderr?.on("data", (chunk) => chunks.stderr.push(chunk));
1295
- const exitCode = await new Promise((resolve18) => {
1296
- proc.on("exit", (code) => resolve18(code ?? 1));
1297
- proc.on("error", () => resolve18(1));
1414
+ const exitCode = await new Promise((resolve19) => {
1415
+ proc.on("exit", (code) => resolve19(code ?? 1));
1416
+ proc.on("error", () => resolve19(1));
1298
1417
  });
1299
1418
  const stdout = Buffer.concat(chunks.stdout).toString("utf-8");
1300
1419
  const stderr = Buffer.concat(chunks.stderr).toString("utf-8");
@@ -1405,9 +1524,9 @@ var init_src2 = __esm({
1405
1524
  const messages = this.parser.parse(value);
1406
1525
  for (const msg of messages) {
1407
1526
  if (msg.id !== void 0 && this.pendingRequests.has(Number(msg.id))) {
1408
- const resolve18 = this.pendingRequests.get(Number(msg.id));
1409
- if (resolve18) {
1410
- resolve18(msg.result || msg.error);
1527
+ const resolve19 = this.pendingRequests.get(Number(msg.id));
1528
+ if (resolve19) {
1529
+ resolve19(msg.result || msg.error);
1411
1530
  this.pendingRequests.delete(Number(msg.id));
1412
1531
  }
1413
1532
  }
@@ -1422,8 +1541,8 @@ var init_src2 = __esm({
1422
1541
  const message = `Content-Length: ${Buffer.byteLength(content, "utf8")}\r
1423
1542
  \r
1424
1543
  ${content}`;
1425
- return new Promise((resolve18) => {
1426
- this.pendingRequests.set(id, resolve18);
1544
+ return new Promise((resolve19) => {
1545
+ this.pendingRequests.set(id, resolve19);
1427
1546
  this.process.stdin.write(message);
1428
1547
  this.process.stdin.flush();
1429
1548
  });
@@ -1555,9 +1674,9 @@ var init_SubShellTool = __esm({
1555
1674
  }
1556
1675
  throw e;
1557
1676
  }
1558
- await new Promise((resolve18) => {
1559
- proc.on("exit", () => resolve18());
1560
- proc.on("error", () => resolve18());
1677
+ await new Promise((resolve19) => {
1678
+ proc.on("exit", () => resolve19());
1679
+ proc.on("error", () => resolve19());
1561
1680
  });
1562
1681
  return { content: `Successfully launched separate window for ${args2.worker_id}` };
1563
1682
  }
@@ -1640,13 +1759,13 @@ async function findRg() {
1640
1759
  const candidates = ["rg", "C:\\Program Files\\ripgrep\\rg.exe"];
1641
1760
  for (const bin of candidates) {
1642
1761
  try {
1643
- const exited = await new Promise((resolve18) => {
1762
+ const exited = await new Promise((resolve19) => {
1644
1763
  try {
1645
1764
  const p = spawn4(bin, ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
1646
- p.on("error", () => resolve18(null));
1647
- p.on("exit", (code) => resolve18(code));
1765
+ p.on("error", () => resolve19(null));
1766
+ p.on("exit", (code) => resolve19(code));
1648
1767
  } catch {
1649
- resolve18(null);
1768
+ resolve19(null);
1650
1769
  }
1651
1770
  });
1652
1771
  if (exited === 0) return bin;
@@ -1656,7 +1775,7 @@ async function findRg() {
1656
1775
  return null;
1657
1776
  }
1658
1777
  function runRg(bin, args2) {
1659
- return new Promise((resolve18) => {
1778
+ return new Promise((resolve19) => {
1660
1779
  const p = spawn4(bin, args2, { stdio: ["ignore", "pipe", "pipe"] });
1661
1780
  let stdout = "";
1662
1781
  let stderr = "";
@@ -1667,10 +1786,10 @@ function runRg(bin, args2) {
1667
1786
  stderr += d.toString("utf8");
1668
1787
  });
1669
1788
  p.on("error", (e) => {
1670
- resolve18({ stdout, stderr: stderr + (e?.message ?? ""), exitCode: -1 });
1789
+ resolve19({ stdout, stderr: stderr + (e?.message ?? ""), exitCode: -1 });
1671
1790
  });
1672
1791
  p.on("exit", (code) => {
1673
- resolve18({ stdout, stderr, exitCode: code });
1792
+ resolve19({ stdout, stderr, exitCode: code });
1674
1793
  });
1675
1794
  });
1676
1795
  }
@@ -2922,12 +3041,12 @@ Command: ${command}`,
2922
3041
  proc.stdout?.on("data", (chunk) => chunks.stdout.push(chunk));
2923
3042
  proc.stderr?.on("data", (chunk) => chunks.stderr.push(chunk));
2924
3043
  const timeoutPromise = new Promise(
2925
- (resolve18) => setTimeout(() => resolve18("timeout"), timeoutMs)
3044
+ (resolve19) => setTimeout(() => resolve19("timeout"), timeoutMs)
2926
3045
  );
2927
3046
  const processPromise = (async () => {
2928
- const exitCode2 = await new Promise((resolve18) => {
2929
- proc.on("exit", (code) => resolve18(code ?? 1));
2930
- proc.on("error", () => resolve18(1));
3047
+ const exitCode2 = await new Promise((resolve19) => {
3048
+ proc.on("exit", (code) => resolve19(code ?? 1));
3049
+ proc.on("error", () => resolve19(1));
2931
3050
  });
2932
3051
  const stdout2 = Buffer.concat(chunks.stdout).toString("utf-8");
2933
3052
  const stderr2 = Buffer.concat(chunks.stderr).toString("utf-8");
@@ -3674,7 +3793,7 @@ async function copyDir(src, dst) {
3674
3793
  }
3675
3794
  async function backupFile(absPath) {
3676
3795
  try {
3677
- const { readFile: readFile23, writeFile: writeFile12, mkdir: mkdir9 } = await import("fs/promises");
3796
+ const { readFile: readFile24, writeFile: writeFile13, mkdir: mkdir9 } = await import("fs/promises");
3678
3797
  const { homedir: homedir18 } = await import("os");
3679
3798
  const { join: join31 } = await import("path");
3680
3799
  const filename = absPath.split(/[\\/]/).pop() ?? "file";
@@ -3687,8 +3806,8 @@ async function backupFile(absPath) {
3687
3806
  `${filename}.backup-${stamp}-${suffix}.bak`
3688
3807
  );
3689
3808
  await mkdir9(join31(homedir18(), ".msapling", "backups"), { recursive: true });
3690
- const content = await readFile23(absPath, "utf8");
3691
- await writeFile12(backupPath, content, "utf8");
3809
+ const content = await readFile24(absPath, "utf8");
3810
+ await writeFile13(backupPath, content, "utf8");
3692
3811
  return backupPath;
3693
3812
  } catch {
3694
3813
  return null;
@@ -3913,15 +4032,15 @@ var init_DeleteFileTool = __esm({
3913
4032
  let backedUpTo = null;
3914
4033
  if (isFile) {
3915
4034
  try {
3916
- const { readFile: readFile23, writeFile: writeFile12, mkdir: mkdir9 } = await import("fs/promises");
4035
+ const { readFile: readFile24, writeFile: writeFile13, mkdir: mkdir9 } = await import("fs/promises");
3917
4036
  const { homedir: homedir18 } = await import("os");
3918
- const existingContent = await readFile23(abs, "utf8");
4037
+ const existingContent = await readFile24(abs, "utf8");
3919
4038
  const filename = abs.split(/[\\/]/).pop() ?? "file";
3920
4039
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3921
4040
  const suffix = randomBytes6(4).toString("hex");
3922
4041
  const backupPath = join11(homedir18(), ".msapling", "backups", `${filename}.backup-${stamp}-${suffix}.bak`);
3923
4042
  await mkdir9(join11(homedir18(), ".msapling", "backups"), { recursive: true });
3924
- await writeFile12(backupPath, existingContent, "utf8");
4043
+ await writeFile13(backupPath, existingContent, "utf8");
3925
4044
  backedUpTo = backupPath;
3926
4045
  } catch {
3927
4046
  }
@@ -4260,10 +4379,10 @@ var init_Voice = __esm({
4260
4379
  `;
4261
4380
  try {
4262
4381
  if (process.platform === "win32") {
4263
- await new Promise((resolve18, reject) => {
4382
+ await new Promise((resolve19, reject) => {
4264
4383
  try {
4265
4384
  const proc = spawn6("powershell", ["-Command", psCommand]);
4266
- proc.on("exit", () => resolve18());
4385
+ proc.on("exit", () => resolve19());
4267
4386
  proc.on("error", reject);
4268
4387
  } catch (e) {
4269
4388
  reject(e);
@@ -4377,7 +4496,7 @@ function matches(entry, ctx) {
4377
4496
  async function runOne(entry, ctx) {
4378
4497
  const timeoutMs = entry.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
4379
4498
  const command = entry.command;
4380
- return new Promise((resolve18) => {
4499
+ return new Promise((resolve19) => {
4381
4500
  const isWindows = process.platform === "win32";
4382
4501
  const child = spawn7(isWindows ? "cmd.exe" : "sh", isWindows ? ["/c", command] : ["-c", command], {
4383
4502
  cwd: ctx.cwd ?? process.cwd(),
@@ -4392,7 +4511,7 @@ async function runOne(entry, ctx) {
4392
4511
  settled = true;
4393
4512
  clearTimeout(killer);
4394
4513
  const blocked = !!entry.blocking && (exitCode === null || exitCode !== 0);
4395
- resolve18({ command, exitCode, stdout, stderr, timedOut, blocked });
4514
+ resolve19({ command, exitCode, stdout, stderr, timedOut, blocked });
4396
4515
  };
4397
4516
  const killer = setTimeout(() => {
4398
4517
  timedOut = true;
@@ -5257,8 +5376,8 @@ var init_Mutex = __esm({
5257
5376
  */
5258
5377
  acquire() {
5259
5378
  let release2;
5260
- const next = new Promise((resolve18) => {
5261
- release2 = resolve18;
5379
+ const next = new Promise((resolve19) => {
5380
+ release2 = resolve19;
5262
5381
  });
5263
5382
  const entry = this._queue.then(() => release2);
5264
5383
  this._queue = this._queue.then(() => next);
@@ -5898,8 +6017,8 @@ var require_graceful_fs = __commonJS({
5898
6017
  fs4.createReadStream = createReadStream;
5899
6018
  fs4.createWriteStream = createWriteStream;
5900
6019
  var fs$readFile = fs4.readFile;
5901
- fs4.readFile = readFile23;
5902
- function readFile23(path2, options, cb) {
6020
+ fs4.readFile = readFile24;
6021
+ function readFile24(path2, options, cb) {
5903
6022
  if (typeof options === "function")
5904
6023
  cb = options, options = null;
5905
6024
  return go$readFile(path2, options, cb);
@@ -5915,8 +6034,8 @@ var require_graceful_fs = __commonJS({
5915
6034
  }
5916
6035
  }
5917
6036
  var fs$writeFile = fs4.writeFile;
5918
- fs4.writeFile = writeFile12;
5919
- function writeFile12(path2, data, options, cb) {
6037
+ fs4.writeFile = writeFile13;
6038
+ function writeFile13(path2, data, options, cb) {
5920
6039
  if (typeof options === "function")
5921
6040
  cb = options, options = null;
5922
6041
  return go$writeFile(path2, data, options, cb);
@@ -6918,12 +7037,12 @@ var require_adapter = __commonJS({
6918
7037
  return newFs;
6919
7038
  }
6920
7039
  function toPromise(method) {
6921
- return (...args2) => new Promise((resolve18, reject) => {
7040
+ return (...args2) => new Promise((resolve19, reject) => {
6922
7041
  args2.push((err, result) => {
6923
7042
  if (err) {
6924
7043
  reject(err);
6925
7044
  } else {
6926
- resolve18(result);
7045
+ resolve19(result);
6927
7046
  }
6928
7047
  });
6929
7048
  method(...args2);
@@ -7851,7 +7970,7 @@ var init_client = __esm({
7851
7970
  if (!this.proc) throw new MCPClientError(`MCP server "${this.name}" not started`);
7852
7971
  const id = this.nextId++;
7853
7972
  const frame = { jsonrpc: "2.0", id, method, params };
7854
- return new Promise((resolve18, reject) => {
7973
+ return new Promise((resolve19, reject) => {
7855
7974
  const timer = setTimeout(() => {
7856
7975
  this.pending.delete(id);
7857
7976
  reject(new MCPClientError(`MCP request ${method} timed out after ${timeoutMs}ms`));
@@ -7859,7 +7978,7 @@ var init_client = __esm({
7859
7978
  this.pending.set(id, {
7860
7979
  resolve: (v) => {
7861
7980
  clearTimeout(timer);
7862
- resolve18(v);
7981
+ resolve19(v);
7863
7982
  },
7864
7983
  reject: (e) => {
7865
7984
  clearTimeout(timer);
@@ -7886,7 +8005,7 @@ var init_client = __esm({
7886
8005
  if (!this.proc?.stdout) return;
7887
8006
  const stdout = this.proc.stdout;
7888
8007
  const decoder = new TextDecoder();
7889
- return new Promise((resolve18) => {
8008
+ return new Promise((resolve19) => {
7890
8009
  stdout.on("data", (chunk) => {
7891
8010
  this.buffer += decoder.decode(chunk, { stream: true });
7892
8011
  let idx;
@@ -7897,8 +8016,8 @@ var init_client = __esm({
7897
8016
  this.handleFrame(line);
7898
8017
  }
7899
8018
  });
7900
- stdout.on("end", () => resolve18());
7901
- stdout.on("error", () => resolve18());
8019
+ stdout.on("end", () => resolve19());
8020
+ stdout.on("error", () => resolve19());
7902
8021
  });
7903
8022
  }
7904
8023
  handleFrame(line) {
@@ -8122,7 +8241,7 @@ function setRawModeGuarded(stdin, mode) {
8122
8241
  }
8123
8242
  }
8124
8243
  async function promptPassword(prompt4) {
8125
- return new Promise((resolve18) => {
8244
+ return new Promise((resolve19) => {
8126
8245
  const stdin = process.stdin;
8127
8246
  const stdout = process.stdout;
8128
8247
  stdout.write(prompt4);
@@ -8135,12 +8254,12 @@ async function promptPassword(prompt4) {
8135
8254
  setRawModeGuarded(stdin, wasRaw);
8136
8255
  stdin.removeListener("data", onData);
8137
8256
  stdout.write("\n");
8138
- resolve18(password);
8257
+ resolve19(password);
8139
8258
  } else if (char === "") {
8140
8259
  setRawModeGuarded(stdin, wasRaw);
8141
8260
  stdin.removeListener("data", onData);
8142
8261
  stdout.write("\n");
8143
- resolve18("");
8262
+ resolve19("");
8144
8263
  } else if (char === "\x7F" || char === "\b") {
8145
8264
  password = password.slice(0, -1);
8146
8265
  } else if (char >= " " && char <= "~") {
@@ -8219,7 +8338,7 @@ async function loginWithGithubDevice(context) {
8219
8338
  const deadline = Date.now() + expires_in * 1e3;
8220
8339
  let githubToken = null;
8221
8340
  while (Date.now() < deadline) {
8222
- await new Promise((resolve18) => setTimeout(resolve18, pollMs));
8341
+ await new Promise((resolve19) => setTimeout(resolve19, pollMs));
8223
8342
  let tokenResp;
8224
8343
  try {
8225
8344
  tokenResp = await fetch(GITHUB_TOKEN_URL, {
@@ -8243,7 +8362,7 @@ async function loginWithGithubDevice(context) {
8243
8362
  if (tokenData.error === "authorization_pending") continue;
8244
8363
  if (tokenData.error === "slow_down") {
8245
8364
  pollMs += 5e3;
8246
- await new Promise((resolve18) => setTimeout(resolve18, 5e3));
8365
+ await new Promise((resolve19) => setTimeout(resolve19, 5e3));
8247
8366
  continue;
8248
8367
  }
8249
8368
  context.addMessage("system", `GitHub auth error: ${tokenData.error_description || tokenData.error}`);
@@ -8656,10 +8775,79 @@ async function createChat(args2, context) {
8656
8775
  context.addMessage("error", `Failed to create chat: ${e.message}`);
8657
8776
  }
8658
8777
  }
8778
+ async function resolveChatId(rest, context) {
8779
+ const candidate = rest[0]?.trim();
8780
+ if (candidate && /^[0-9a-fA-F-]{32,}$/.test(candidate)) return candidate;
8781
+ return context.activeChatId ?? null;
8782
+ }
8783
+ async function lifecycleSub(args2, context) {
8784
+ const sub = args2[0]?.toLowerCase();
8785
+ const rest = args2.slice(1);
8786
+ try {
8787
+ if (sub === "rename") {
8788
+ const newTitle = rest.slice(1).join(" ").trim() || rest[0]?.trim();
8789
+ const chatId = await resolveChatId(rest, context);
8790
+ if (!chatId || !newTitle) {
8791
+ context.addMessage("system", "Usage: /chat rename [<chat_id>] <new title>");
8792
+ return;
8793
+ }
8794
+ const r = await context.client.renameChat(chatId, newTitle);
8795
+ context.addMessage("system", `Renamed to "${r.title}"`);
8796
+ return;
8797
+ }
8798
+ if (sub === "delete" || sub === "rm") {
8799
+ const chatId = await resolveChatId(rest, context);
8800
+ if (!chatId) {
8801
+ context.addMessage("system", "Usage: /chat delete [<chat_id>]");
8802
+ return;
8803
+ }
8804
+ await context.client.deleteChat(chatId);
8805
+ context.addMessage("system", `Deleted chat ${chatId}`);
8806
+ if (chatId === context.activeChatId) context.setActiveChatId(null);
8807
+ return;
8808
+ }
8809
+ if (sub === "fork") {
8810
+ const chatId = await resolveChatId(rest, context);
8811
+ if (!chatId) {
8812
+ context.addMessage("system", "Usage: /chat fork [<chat_id>]");
8813
+ return;
8814
+ }
8815
+ const r = await context.client.forkChat(chatId);
8816
+ context.addMessage("system", `Forked \u2192 ${r.chat_id ?? r.title ?? "(ok)"}`);
8817
+ if (r.chat_id) context.setActiveChatId(r.chat_id);
8818
+ return;
8819
+ }
8820
+ if (sub === "pin") {
8821
+ const chatId = await resolveChatId(rest, context);
8822
+ if (!chatId) {
8823
+ context.addMessage("system", "Usage: /chat pin [<chat_id>]");
8824
+ return;
8825
+ }
8826
+ await context.client.pinChat(chatId, true);
8827
+ context.addMessage("system", `Pinned ${chatId}`);
8828
+ return;
8829
+ }
8830
+ if (sub === "unpin") {
8831
+ const chatId = await resolveChatId(rest, context);
8832
+ if (!chatId) {
8833
+ context.addMessage("system", "Usage: /chat unpin [<chat_id>]");
8834
+ return;
8835
+ }
8836
+ await context.client.pinChat(chatId, false);
8837
+ context.addMessage("system", `Unpinned ${chatId}`);
8838
+ return;
8839
+ }
8840
+ } catch (e) {
8841
+ context.addMessage("error", `Chat ${sub}: ${e.message}`);
8842
+ }
8843
+ }
8659
8844
  async function listChats(args2, context) {
8660
8845
  if (args2[0] === "new" || args2[0] === "create") {
8661
8846
  return createChat(args2.slice(1), context);
8662
8847
  }
8848
+ if (["rename", "delete", "rm", "fork", "pin", "unpin"].includes(args2[0])) {
8849
+ return lifecycleSub(args2, context);
8850
+ }
8663
8851
  const arg = args2.join(" ").trim();
8664
8852
  const result = await fetchChatsForCurrentProject(context);
8665
8853
  if ("error" in result) {
@@ -8782,6 +8970,344 @@ var init_broadcast = __esm({
8782
8970
  }
8783
8971
  });
8784
8972
 
8973
+ // src/commands/ollama.ts
8974
+ function formatSize(bytes) {
8975
+ if (!bytes) return "?";
8976
+ const gb = bytes / 1e9;
8977
+ if (gb >= 1) return `${gb.toFixed(1)} GB`;
8978
+ const mb = bytes / 1e6;
8979
+ return `${mb.toFixed(0)} MB`;
8980
+ }
8981
+ var DEFAULT_BASE_URL, ollamaCommand;
8982
+ var init_ollama = __esm({
8983
+ "src/commands/ollama.ts"() {
8984
+ "use strict";
8985
+ init_esm_shims();
8986
+ DEFAULT_BASE_URL = "http://localhost:11434";
8987
+ ollamaCommand = {
8988
+ name: "ollama",
8989
+ args: "[status|configure|enable|disable|test|models|pull|delete] [...args]",
8990
+ description: "Configure local Ollama integration (BYOK free tier) and manage local models.",
8991
+ category: "config",
8992
+ handler: async (args2, context) => {
8993
+ const sub = (args2[0] ?? "status").toLowerCase();
8994
+ const rest = args2.slice(1);
8995
+ try {
8996
+ if (sub === "status" || sub === "models") {
8997
+ const s = await context.client.getOllamaStatus();
8998
+ context.addMessage("system", "=== Ollama Status ===");
8999
+ context.addMessage("system", ` Enabled: ${s.enabled ? "yes" : "no"}`);
9000
+ context.addMessage("system", ` Base URL: ${s.base_url}`);
9001
+ context.addMessage("system", ` Connected: ${s.connected ? "yes" : "no"}${s.connection_message ? " \u2014 " + s.connection_message : ""}`);
9002
+ if (s.models?.length) {
9003
+ context.addMessage("system", ` Models (${s.models.length}):`);
9004
+ for (const m of s.models) {
9005
+ context.addMessage("system", ` - ${m.id} (${formatSize(m.size)})`);
9006
+ }
9007
+ } else if (s.enabled) {
9008
+ context.addMessage("system", " Models: (none pulled \u2014 try /ollama pull <name>, e.g. llama3.2)");
9009
+ } else {
9010
+ context.addMessage("system", "");
9011
+ context.addMessage("system", " Run '/ollama configure' to enable.");
9012
+ }
9013
+ return;
9014
+ }
9015
+ if (sub === "configure" || sub === "enable") {
9016
+ const url = rest[0] || DEFAULT_BASE_URL;
9017
+ const res = await context.client.configureOllama({ baseUrl: url, enabled: true });
9018
+ context.addMessage("system", `Ollama enabled at ${url}: ${res.message ?? res.status}`);
9019
+ return;
9020
+ }
9021
+ if (sub === "disable") {
9022
+ const res = await context.client.disableOllama();
9023
+ context.addMessage("system", `Ollama disabled: ${res.message ?? res.status}`);
9024
+ return;
9025
+ }
9026
+ if (sub === "test") {
9027
+ const url = rest[0] || DEFAULT_BASE_URL;
9028
+ const res = await context.client.testOllama(url);
9029
+ context.addMessage("system", `Connection to ${url}: ${res.connected ? "OK" : "FAILED"} \u2014 ${res.message}`);
9030
+ if (res.models?.length) {
9031
+ context.addMessage("system", ` Found ${res.models.length} model(s):`);
9032
+ for (const m of res.models.slice(0, 12)) {
9033
+ context.addMessage("system", ` - ${m.id}`);
9034
+ }
9035
+ if (res.models.length > 12) context.addMessage("system", ` \u2026and ${res.models.length - 12} more.`);
9036
+ }
9037
+ return;
9038
+ }
9039
+ if (sub === "pull") {
9040
+ const model = rest[0];
9041
+ if (!model) {
9042
+ context.addMessage("system", "Usage: /ollama pull <model> (e.g. /ollama pull llama3.2)");
9043
+ return;
9044
+ }
9045
+ const status = await context.client.getOllamaStatus();
9046
+ const res = await context.client.configureOllama({
9047
+ baseUrl: status.base_url || DEFAULT_BASE_URL,
9048
+ enabled: status.enabled !== false,
9049
+ action: "pull",
9050
+ model
9051
+ });
9052
+ context.addMessage("system", res.message ?? res.status);
9053
+ return;
9054
+ }
9055
+ if (sub === "delete" || sub === "remove" || sub === "rm") {
9056
+ const model = rest[0];
9057
+ if (!model) {
9058
+ context.addMessage("system", "Usage: /ollama delete <model>");
9059
+ return;
9060
+ }
9061
+ const res = await context.client.deleteOllamaModel(model);
9062
+ context.addMessage("system", res.message ?? res.status);
9063
+ return;
9064
+ }
9065
+ context.addMessage("error", `Unknown /ollama subcommand '${sub}'. Try: status, configure, disable, test, pull, delete.`);
9066
+ } catch (e) {
9067
+ context.addMessage("error", `Ollama: ${e.message}`);
9068
+ }
9069
+ }
9070
+ };
9071
+ }
9072
+ });
9073
+
9074
+ // src/commands/keys.ts
9075
+ var keysCommand;
9076
+ var init_keys = __esm({
9077
+ "src/commands/keys.ts"() {
9078
+ "use strict";
9079
+ init_esm_shims();
9080
+ keysCommand = {
9081
+ name: "keys",
9082
+ args: "[list|add|delete] [...args]",
9083
+ description: "Manage BYOK provider API keys (openai, anthropic, google, openrouter, \u2026).",
9084
+ category: "config",
9085
+ handler: async (args2, context) => {
9086
+ const sub = (args2[0] ?? "list").toLowerCase();
9087
+ const rest = args2.slice(1);
9088
+ try {
9089
+ if (sub === "list" || sub === "status") {
9090
+ const s = await context.client.getProviderKeys();
9091
+ const providers = s.providers ?? [];
9092
+ context.addMessage("system", `Provider Keys (${providers.length}):`);
9093
+ for (const p of providers) {
9094
+ const tag = p.configured ? "\u2713" : " ";
9095
+ const prefix = p.key_prefix ? ` (${p.key_prefix}\u2026)` : "";
9096
+ context.addMessage("system", ` [${tag}] ${p.provider}${prefix}`);
9097
+ }
9098
+ if (providers.length === 0) {
9099
+ context.addMessage("system", " (none \u2014 add via /keys add <provider> <key>)");
9100
+ }
9101
+ return;
9102
+ }
9103
+ if (sub === "add" || sub === "save") {
9104
+ const provider = rest[0];
9105
+ const key = rest.slice(1).join(" ").trim();
9106
+ if (!provider || !key) {
9107
+ context.addMessage("system", "Usage: /keys add <provider> <key> (e.g. /keys add openai sk-...)");
9108
+ return;
9109
+ }
9110
+ const res = await context.client.saveProviderKey(provider, key);
9111
+ context.addMessage("system", `Saved key for ${provider}: ${res.message ?? res.status}`);
9112
+ return;
9113
+ }
9114
+ if (sub === "delete" || sub === "rm" || sub === "remove") {
9115
+ const provider = rest[0];
9116
+ if (!provider) {
9117
+ context.addMessage("system", "Usage: /keys delete <provider>");
9118
+ return;
9119
+ }
9120
+ const res = await context.client.deleteProviderKey(provider);
9121
+ context.addMessage("system", `Removed key for ${provider}: ${res.message ?? res.status}`);
9122
+ return;
9123
+ }
9124
+ context.addMessage("error", `Unknown /keys subcommand '${sub}'. Try: list, add, delete.`);
9125
+ } catch (e) {
9126
+ context.addMessage("error", `Keys: ${e.message}`);
9127
+ }
9128
+ }
9129
+ };
9130
+ }
9131
+ });
9132
+
9133
+ // src/commands/memories.ts
9134
+ var memoriesCommand;
9135
+ var init_memories = __esm({
9136
+ "src/commands/memories.ts"() {
9137
+ "use strict";
9138
+ init_esm_shims();
9139
+ memoriesCommand = {
9140
+ name: "memories",
9141
+ args: "[list|add|delete] [...args]",
9142
+ description: "Manage the user-scoped memory bank (used across all chats).",
9143
+ category: "project",
9144
+ handler: async (args2, context) => {
9145
+ const sub = (args2[0] ?? "list").toLowerCase();
9146
+ const rest = args2.slice(1);
9147
+ try {
9148
+ if (sub === "list" || sub === "show") {
9149
+ const items = await context.client.listMemories();
9150
+ if (!items || items.length === 0) {
9151
+ context.addMessage("system", "No memories yet. Add one via /memories add <text>.");
9152
+ return;
9153
+ }
9154
+ context.addMessage("system", `Memories (${items.length}):`);
9155
+ for (const m of items) {
9156
+ const when = m.created_at ? new Date(m.created_at).toISOString().slice(0, 10) : "";
9157
+ context.addMessage("system", ` ${m.id?.slice(0, 8)} \xB7 ${when} ${m.content}`);
9158
+ }
9159
+ return;
9160
+ }
9161
+ if (sub === "add" || sub === "save") {
9162
+ const content = rest.join(" ").trim();
9163
+ if (!content) {
9164
+ context.addMessage("system", "Usage: /memories add <content>");
9165
+ return;
9166
+ }
9167
+ const m = await context.client.createMemory(content);
9168
+ context.addMessage("system", `Saved (${m.id?.slice(0, 8)}).`);
9169
+ return;
9170
+ }
9171
+ if (sub === "delete" || sub === "rm" || sub === "remove") {
9172
+ const id = rest[0]?.trim();
9173
+ if (!id) {
9174
+ context.addMessage("system", "Usage: /memories delete <id>");
9175
+ return;
9176
+ }
9177
+ await context.client.deleteMemory(id);
9178
+ context.addMessage("system", `Deleted ${id.slice(0, 8)}.`);
9179
+ return;
9180
+ }
9181
+ context.addMessage("error", `Unknown /memories subcommand '${sub}'. Try: list, add, delete.`);
9182
+ } catch (e) {
9183
+ context.addMessage("error", `Memories: ${e.message}`);
9184
+ }
9185
+ }
9186
+ };
9187
+ }
9188
+ });
9189
+
9190
+ // src/commands/mdrive.ts
9191
+ import { readFile as readFile14, writeFile as writeFile7 } from "fs/promises";
9192
+ import { existsSync as existsSync15 } from "fs";
9193
+ import { basename, resolve as resolve14 } from "path";
9194
+ function formatBytes(b) {
9195
+ if (!b) return "0";
9196
+ if (b < 1024) return `${b}`;
9197
+ if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)}K`;
9198
+ return `${(b / 1024 / 1024).toFixed(1)}M`;
9199
+ }
9200
+ var mdriveCommand;
9201
+ var init_mdrive = __esm({
9202
+ "src/commands/mdrive.ts"() {
9203
+ "use strict";
9204
+ init_esm_shims();
9205
+ mdriveCommand = {
9206
+ name: "mdrive",
9207
+ args: "[ls|cat|put|get|rm|mv|mkdir] [...args]",
9208
+ description: "Browse and manage files on MSapling Drive (your AI-native context storage).",
9209
+ category: "project",
9210
+ handler: async (args2, context) => {
9211
+ const sub = (args2[0] ?? "ls").toLowerCase();
9212
+ const rest = args2.slice(1);
9213
+ try {
9214
+ if (sub === "ls" || sub === "list") {
9215
+ const path2 = rest[0] || ".";
9216
+ const res = await context.client.mdriveList(path2);
9217
+ const entries = res.entries ?? res.files ?? res.items ?? [];
9218
+ context.addMessage("system", `MDrive: ${path2} (${entries.length} entries)`);
9219
+ for (const e of entries) {
9220
+ const type = e.is_dir || e.type === "dir" ? "d" : "-";
9221
+ const size = e.size != null ? formatBytes(e.size).padStart(6) : " -";
9222
+ const name = e.name ?? e.path ?? "?";
9223
+ context.addMessage("system", ` ${type} ${size} ${name}`);
9224
+ }
9225
+ return;
9226
+ }
9227
+ if (sub === "cat" || sub === "read") {
9228
+ const p = rest[0];
9229
+ if (!p) {
9230
+ context.addMessage("system", "Usage: /mdrive cat <path>");
9231
+ return;
9232
+ }
9233
+ const res = await context.client.mdriveRead(p);
9234
+ context.addMessage("system", res.content ?? res.body ?? "(no content)");
9235
+ return;
9236
+ }
9237
+ if (sub === "put" || sub === "upload" || sub === "write") {
9238
+ const local = rest[0];
9239
+ const remote = rest[1] || (local ? basename(local) : "");
9240
+ if (!local || !remote) {
9241
+ context.addMessage("system", "Usage: /mdrive put <local> [<remote>]");
9242
+ return;
9243
+ }
9244
+ const absLocal = resolve14(local);
9245
+ if (!existsSync15(absLocal)) {
9246
+ context.addMessage("error", `Local file not found: ${absLocal}`);
9247
+ return;
9248
+ }
9249
+ const content = await readFile14(absLocal, "utf8");
9250
+ const res = await context.client.mdriveWrite(remote, content);
9251
+ context.addMessage("system", `Uploaded ${absLocal} \u2192 mdrive:${remote} (${formatBytes(content.length)}, hash=${res?.hash?.slice(0, 12) ?? "?"})`);
9252
+ return;
9253
+ }
9254
+ if (sub === "get" || sub === "download" || sub === "pull") {
9255
+ const remote = rest[0];
9256
+ const local = rest[1];
9257
+ if (!remote) {
9258
+ context.addMessage("system", "Usage: /mdrive get <remote> [<local>]");
9259
+ return;
9260
+ }
9261
+ const res = await context.client.mdriveRead(remote);
9262
+ const content = res.content ?? res.body ?? "";
9263
+ if (local) {
9264
+ await writeFile7(resolve14(local), content, "utf8");
9265
+ context.addMessage("system", `Wrote ${resolve14(local)} (${formatBytes(content.length)})`);
9266
+ } else {
9267
+ context.addMessage("system", content);
9268
+ }
9269
+ return;
9270
+ }
9271
+ if (sub === "rm" || sub === "delete" || sub === "del") {
9272
+ const p = rest[0];
9273
+ if (!p) {
9274
+ context.addMessage("system", "Usage: /mdrive rm <path>");
9275
+ return;
9276
+ }
9277
+ await context.client.mdriveDelete(p);
9278
+ context.addMessage("system", `Deleted mdrive:${p}`);
9279
+ return;
9280
+ }
9281
+ if (sub === "mv" || sub === "rename") {
9282
+ const p = rest[0];
9283
+ const newName = rest[1];
9284
+ if (!p || !newName) {
9285
+ context.addMessage("system", "Usage: /mdrive mv <path> <new-name>");
9286
+ return;
9287
+ }
9288
+ await context.client.mdriveRename(p, newName);
9289
+ context.addMessage("system", `Renamed mdrive:${p} \u2192 ${newName}`);
9290
+ return;
9291
+ }
9292
+ if (sub === "mkdir") {
9293
+ const p = rest[0];
9294
+ if (!p) {
9295
+ context.addMessage("system", "Usage: /mdrive mkdir <path>");
9296
+ return;
9297
+ }
9298
+ await context.client.mdriveMkdir(p);
9299
+ context.addMessage("system", `Created mdrive:${p}/`);
9300
+ return;
9301
+ }
9302
+ context.addMessage("error", `Unknown /mdrive subcommand '${sub}'. Try: ls, cat, put, get, rm, mv, mkdir.`);
9303
+ } catch (e) {
9304
+ context.addMessage("error", `MDrive: ${e.message}`);
9305
+ }
9306
+ }
9307
+ };
9308
+ }
9309
+ });
9310
+
8785
9311
  // src/commands/clear.ts
8786
9312
  var clearCommand;
8787
9313
  var init_clear = __esm({
@@ -8807,13 +9333,13 @@ var init_clear = __esm({
8807
9333
  // src/commands/mode.ts
8808
9334
  import { homedir as homedir10 } from "os";
8809
9335
  import { join as join17 } from "path";
8810
- import { existsSync as existsSync15 } from "fs";
8811
- import { readFile as readFile14, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
9336
+ import { existsSync as existsSync16 } from "fs";
9337
+ import { readFile as readFile15, writeFile as writeFile8, mkdir as mkdir7 } from "fs/promises";
8812
9338
  async function persistApprovalMode(mode, ttlMs) {
8813
9339
  try {
8814
9340
  let existing = {};
8815
- if (existsSync15(SETTINGS_PATH)) {
8816
- const text = await readFile14(SETTINGS_PATH, "utf8");
9341
+ if (existsSync16(SETTINGS_PATH)) {
9342
+ const text = await readFile15(SETTINGS_PATH, "utf8");
8817
9343
  if (text.trim()) {
8818
9344
  existing = JSON.parse(text);
8819
9345
  }
@@ -8825,10 +9351,10 @@ async function persistApprovalMode(mode, ttlMs) {
8825
9351
  };
8826
9352
  existing.approvalMode = entry;
8827
9353
  const settingsDir = join17(homedir10(), ".msapling");
8828
- if (!existsSync15(settingsDir)) {
9354
+ if (!existsSync16(settingsDir)) {
8829
9355
  await mkdir7(settingsDir, { recursive: true });
8830
9356
  }
8831
- await writeFile7(SETTINGS_PATH, JSON.stringify(existing, null, 2), "utf8");
9357
+ await writeFile8(SETTINGS_PATH, JSON.stringify(existing, null, 2), "utf8");
8832
9358
  } catch {
8833
9359
  }
8834
9360
  }
@@ -9213,8 +9739,8 @@ var init_compact = __esm({
9213
9739
 
9214
9740
  // src/commands/init.ts
9215
9741
  import { join as join18 } from "path";
9216
- import { existsSync as existsSync16 } from "fs";
9217
- import { writeFile as writeFile8 } from "fs/promises";
9742
+ import { existsSync as existsSync17 } from "fs";
9743
+ import { writeFile as writeFile9 } from "fs/promises";
9218
9744
  var initCommand;
9219
9745
  var init_init = __esm({
9220
9746
  "src/commands/init.ts"() {
@@ -9228,7 +9754,7 @@ var init_init = __esm({
9228
9754
  try {
9229
9755
  const cwd = process.cwd();
9230
9756
  const path2 = join18(cwd, "MSAPLING.md");
9231
- if (existsSync16(path2)) {
9757
+ if (existsSync17(path2)) {
9232
9758
  context.addMessage("error", "MSAPLING.md already exists in current directory.");
9233
9759
  return;
9234
9760
  }
@@ -9243,7 +9769,7 @@ var init_init = __esm({
9243
9769
  ## Guidelines
9244
9770
  - Follow existing code style.
9245
9771
  `;
9246
- await writeFile8(path2, content, "utf8");
9772
+ await writeFile9(path2, content, "utf8");
9247
9773
  context.addMessage("system", `Created MSAPLING.md at ${path2}`);
9248
9774
  } catch (e) {
9249
9775
  context.addMessage("error", `Failed to initialize project: ${e.message}`);
@@ -9254,8 +9780,8 @@ var init_init = __esm({
9254
9780
  });
9255
9781
 
9256
9782
  // src/commands/review.ts
9257
- import { existsSync as existsSync17 } from "fs";
9258
- import { readFile as readFile15 } from "fs/promises";
9783
+ import { existsSync as existsSync18 } from "fs";
9784
+ import { readFile as readFile16 } from "fs/promises";
9259
9785
  var reviewCommand;
9260
9786
  var init_review = __esm({
9261
9787
  "src/commands/review.ts"() {
@@ -9274,8 +9800,8 @@ var init_review = __esm({
9274
9800
  }
9275
9801
  let content = "";
9276
9802
  try {
9277
- if (existsSync17(target)) {
9278
- content = await readFile15(target, "utf8");
9803
+ if (existsSync18(target)) {
9804
+ content = await readFile16(target, "utf8");
9279
9805
  } else {
9280
9806
  content = `Review target: ${target}`;
9281
9807
  }
@@ -9368,15 +9894,15 @@ var init_swarm = __esm({
9368
9894
 
9369
9895
  // src/commands/recipe.ts
9370
9896
  import { parse as parseYaml } from "yaml";
9371
- import { existsSync as existsSync18 } from "fs";
9372
- import { readFile as readFile16 } from "fs/promises";
9897
+ import { existsSync as existsSync19 } from "fs";
9898
+ import { readFile as readFile17 } from "fs/promises";
9373
9899
  import { join as join19 } from "path";
9374
9900
  function findRecipe(name, cwd) {
9375
9901
  for (const dir of RECIPE_DIRS) {
9376
9902
  for (const suffix of NAME_SUFFIXES) {
9377
9903
  for (const ext of FILE_EXTS) {
9378
9904
  const p = join19(cwd, dir, `${name}${suffix}${ext}`);
9379
- if (existsSync18(p)) return p;
9905
+ if (existsSync19(p)) return p;
9380
9906
  }
9381
9907
  }
9382
9908
  }
@@ -9435,7 +9961,7 @@ var init_recipe = __esm({
9435
9961
  let text;
9436
9962
  let recipe;
9437
9963
  try {
9438
- text = await readFile16(path2, "utf8");
9964
+ text = await readFile17(path2, "utf8");
9439
9965
  recipe = parseYaml(text);
9440
9966
  } catch (e) {
9441
9967
  context.addMessage("error", `Failed to load ${path2}: ${e.message}`);
@@ -9489,13 +10015,13 @@ ${rendered}` : rendered;
9489
10015
  });
9490
10016
 
9491
10017
  // src/commands/skill.ts
9492
- import { existsSync as existsSync19, readdirSync as readdirSync2, statSync as statSync5 } from "fs";
9493
- import { readFile as readFile17 } from "fs/promises";
9494
- import { join as join20, resolve as resolve14 } from "path";
10018
+ import { existsSync as existsSync20, readdirSync as readdirSync2, statSync as statSync5 } from "fs";
10019
+ import { readFile as readFile18 } from "fs/promises";
10020
+ import { join as join20, resolve as resolve15 } from "path";
9495
10021
  function findSkillsRoot(cwd) {
9496
10022
  for (const candidate of SKILLS_DIRS) {
9497
- const full = resolve14(cwd, candidate);
9498
- if (existsSync19(full) && statSync5(full).isDirectory()) return full;
10023
+ const full = resolve15(cwd, candidate);
10024
+ if (existsSync20(full) && statSync5(full).isDirectory()) return full;
9499
10025
  }
9500
10026
  return null;
9501
10027
  }
@@ -9589,7 +10115,7 @@ var init_skill = __esm({
9589
10115
  }
9590
10116
  let body;
9591
10117
  try {
9592
- body = await readFile17(skill.path, "utf8");
10118
+ body = await readFile18(skill.path, "utf8");
9593
10119
  } catch (e) {
9594
10120
  context.addMessage("error", `Failed to load skill ${skill.path}: ${e.message}`);
9595
10121
  return;
@@ -9985,21 +10511,21 @@ var init_theme = __esm({
9985
10511
  // src/commands/theme.ts
9986
10512
  import { join as join22 } from "path";
9987
10513
  import { homedir as homedir12 } from "os";
9988
- import { existsSync as existsSync20 } from "fs";
9989
- import { readFile as readFile18, writeFile as writeFile9 } from "fs/promises";
10514
+ import { existsSync as existsSync21 } from "fs";
10515
+ import { readFile as readFile19, writeFile as writeFile10 } from "fs/promises";
9990
10516
  async function persistTheme(storage, themeName) {
9991
10517
  const settingsPath = join22(homedir12(), ".msapling", "settings.json");
9992
10518
  let existing = {};
9993
10519
  try {
9994
- if (existsSync20(settingsPath)) {
9995
- const text = await readFile18(settingsPath, "utf8");
10520
+ if (existsSync21(settingsPath)) {
10521
+ const text = await readFile19(settingsPath, "utf8");
9996
10522
  if (text.trim()) existing = JSON.parse(text);
9997
10523
  }
9998
10524
  } catch {
9999
10525
  }
10000
10526
  existing["theme"] = themeName;
10001
10527
  ensureConfigDir(join22(homedir12(), ".msapling"));
10002
- await writeFile9(settingsPath, JSON.stringify(existing, null, 2), "utf8");
10528
+ await writeFile10(settingsPath, JSON.stringify(existing, null, 2), "utf8");
10003
10529
  }
10004
10530
  var VALID_THEMES, themeCommand;
10005
10531
  var init_theme2 = __esm({
@@ -10070,7 +10596,7 @@ var init_version = __esm({
10070
10596
  description: "Show version information for CLI and core packages",
10071
10597
  category: "debug",
10072
10598
  handler: async (_args, context) => {
10073
- const cliVersion = true ? "2.3.6-beta.23" : "(dev)";
10599
+ const cliVersion = true ? "2.3.6-beta.25" : "(dev)";
10074
10600
  const coreVersion = true ? "2.3.2" : "(dev)";
10075
10601
  const runtime = process.version;
10076
10602
  context.addMessage("system", "MSapling Version Info");
@@ -10079,7 +10605,7 @@ var init_version = __esm({
10079
10605
  context.addMessage("system", row2("Core (@msapling/core)", coreVersion));
10080
10606
  context.addMessage("system", row2("Runtime (Node/Bun)", runtime));
10081
10607
  try {
10082
- const ts = "2026-05-28T19:20:38.494Z";
10608
+ const ts = "2026-05-28T19:45:02.204Z";
10083
10609
  if (ts && ts !== "__BUILD_TIMESTAMP__") {
10084
10610
  context.addMessage("system", row2("Build Timestamp", ts));
10085
10611
  }
@@ -10093,14 +10619,14 @@ var init_version = __esm({
10093
10619
 
10094
10620
  // src/commands/feedback.ts
10095
10621
  import { join as join23 } from "path";
10096
- import { existsSync as existsSync21 } from "fs";
10097
- import { readFile as readFile19 } from "fs/promises";
10622
+ import { existsSync as existsSync22 } from "fs";
10623
+ import { readFile as readFile20 } from "fs/promises";
10098
10624
  async function readCliVersion() {
10099
10625
  try {
10100
10626
  const baseDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
10101
10627
  const pkgPath = join23(baseDir, "..", "..", "package.json");
10102
- if (!existsSync21(pkgPath)) return "unknown";
10103
- const text = await readFile19(pkgPath, "utf8");
10628
+ if (!existsSync22(pkgPath)) return "unknown";
10629
+ const text = await readFile20(pkgPath, "utf8");
10104
10630
  const json = JSON.parse(text);
10105
10631
  return json.version ?? "unknown";
10106
10632
  } catch {
@@ -10142,7 +10668,7 @@ var init_feedback = __esm({
10142
10668
  // src/commands/export.ts
10143
10669
  import { homedir as homedir13 } from "os";
10144
10670
  import { join as join24 } from "path";
10145
- import { writeFile as writeFile10, mkdir as mkdir8 } from "fs/promises";
10671
+ import { writeFile as writeFile11, mkdir as mkdir8 } from "fs/promises";
10146
10672
  function formatTimestamp(date) {
10147
10673
  return date.toISOString().replace(/[:.]/g, "-").replace("T", "_").slice(0, 19);
10148
10674
  }
@@ -10208,7 +10734,7 @@ var init_export = __esm({
10208
10734
  try {
10209
10735
  const dir = join24(outputPath, "..");
10210
10736
  await mkdir8(dir, { recursive: true });
10211
- await writeFile10(outputPath, content, "utf8");
10737
+ await writeFile11(outputPath, content, "utf8");
10212
10738
  context.addMessage("system", `Exported to: ${outputPath}`);
10213
10739
  } catch (e) {
10214
10740
  context.addMessage("error", `Failed to export: ${e.message}`);
@@ -10403,15 +10929,15 @@ var init_plan = __esm({
10403
10929
  // src/commands/note.ts
10404
10930
  import { homedir as homedir14 } from "os";
10405
10931
  import { join as join25 } from "path";
10406
- import { existsSync as existsSync22 } from "fs";
10407
- import { readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
10932
+ import { existsSync as existsSync23 } from "fs";
10933
+ import { readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
10408
10934
  function getNotesFilePath() {
10409
10935
  return join25(homedir14(), ".msapling", "notes.json");
10410
10936
  }
10411
10937
  async function readNotes(filePath = getNotesFilePath()) {
10412
10938
  try {
10413
- if (!existsSync22(filePath)) return [];
10414
- const raw = await readFile20(filePath, "utf8");
10939
+ if (!existsSync23(filePath)) return [];
10940
+ const raw = await readFile21(filePath, "utf8");
10415
10941
  const parsed = JSON.parse(raw);
10416
10942
  if (!Array.isArray(parsed)) return [];
10417
10943
  return parsed;
@@ -10422,7 +10948,7 @@ async function readNotes(filePath = getNotesFilePath()) {
10422
10948
  async function writeNotes(notes, filePath = getNotesFilePath()) {
10423
10949
  const dir = join25(homedir14(), ".msapling");
10424
10950
  ensureConfigDir(dir);
10425
- await writeFile11(filePath, JSON.stringify(notes, null, 2), "utf8");
10951
+ await writeFile12(filePath, JSON.stringify(notes, null, 2), "utf8");
10426
10952
  }
10427
10953
  function formatTimestamp2(iso) {
10428
10954
  const d = new Date(iso);
@@ -10567,8 +11093,8 @@ var init_todo = __esm({
10567
11093
 
10568
11094
  // src/commands/outputStyle.ts
10569
11095
  import { homedir as homedir15 } from "os";
10570
- import { join as join26, basename, extname as extname3 } from "path";
10571
- import { existsSync as existsSync23, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync, writeFileSync as writeFileSync2 } from "fs";
11096
+ import { join as join26, basename as basename2, extname as extname3 } from "path";
11097
+ import { existsSync as existsSync24, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync, writeFileSync as writeFileSync2 } from "fs";
10572
11098
  function stylesDir() {
10573
11099
  return join26(homedir15(), ".msapling", "output-styles");
10574
11100
  }
@@ -10594,7 +11120,7 @@ function parseStyleFile(text) {
10594
11120
  }
10595
11121
  function listUserStyles() {
10596
11122
  const dir = stylesDir();
10597
- if (!existsSync23(dir)) return [];
11123
+ if (!existsSync24(dir)) return [];
10598
11124
  const out = [];
10599
11125
  for (const entry of readdirSync3(dir)) {
10600
11126
  if (extname3(entry).toLowerCase() !== ".md") continue;
@@ -10603,7 +11129,7 @@ function listUserStyles() {
10603
11129
  const text = readFileSync(full, "utf8");
10604
11130
  const { description, body } = parseStyleFile(text);
10605
11131
  out.push({
10606
- name: basename(entry, ".md"),
11132
+ name: basename2(entry, ".md"),
10607
11133
  description,
10608
11134
  body,
10609
11135
  source: "user",
@@ -10626,7 +11152,7 @@ function findStyle(name) {
10626
11152
  function getActiveStyleName() {
10627
11153
  try {
10628
11154
  const f = activeFile();
10629
- if (!existsSync23(f)) return "default";
11155
+ if (!existsSync24(f)) return "default";
10630
11156
  return readFileSync(f, "utf8").trim() || "default";
10631
11157
  } catch {
10632
11158
  return "default";
@@ -10634,7 +11160,7 @@ function getActiveStyleName() {
10634
11160
  }
10635
11161
  function setActiveStyleName(name) {
10636
11162
  const dir = stylesDir();
10637
- if (!existsSync23(dir)) mkdirSync5(dir, { recursive: true });
11163
+ if (!existsSync24(dir)) mkdirSync5(dir, { recursive: true });
10638
11164
  writeFileSync2(activeFile(), `${name}
10639
11165
  `, "utf8");
10640
11166
  }
@@ -10647,7 +11173,7 @@ function createUserStyle(name, description, body) {
10647
11173
  throw new Error(`Invalid style name "${name}" \u2014 use letters, digits, _ and - only.`);
10648
11174
  }
10649
11175
  const dir = stylesDir();
10650
- if (!existsSync23(dir)) mkdirSync5(dir, { recursive: true });
11176
+ if (!existsSync24(dir)) mkdirSync5(dir, { recursive: true });
10651
11177
  const target = join26(dir, `${name}.md`);
10652
11178
  const frontmatter = `---
10653
11179
  description: ${description.replace(/\n/g, " ")}
@@ -10819,6 +11345,10 @@ var init_commands = __esm({
10819
11345
  init_help();
10820
11346
  init_chat();
10821
11347
  init_broadcast();
11348
+ init_ollama();
11349
+ init_keys();
11350
+ init_memories();
11351
+ init_mdrive();
10822
11352
  init_clear();
10823
11353
  init_mode();
10824
11354
  init_model();
@@ -10855,6 +11385,10 @@ var init_commands = __esm({
10855
11385
  chatCommand,
10856
11386
  chatsCommand,
10857
11387
  broadcastCommand,
11388
+ ollamaCommand,
11389
+ keysCommand,
11390
+ memoriesCommand,
11391
+ mdriveCommand,
10858
11392
  clearCommand,
10859
11393
  modeCommand,
10860
11394
  modelCommand,
@@ -10951,16 +11485,16 @@ var exec_exports = {};
10951
11485
  __export(exec_exports, {
10952
11486
  runExec: () => runExec
10953
11487
  });
10954
- import { existsSync as existsSync25 } from "fs";
10955
- import { readFile as readFile22 } from "fs/promises";
11488
+ import { existsSync as existsSync26 } from "fs";
11489
+ import { readFile as readFile23 } from "fs/promises";
10956
11490
  import { homedir as homedir16 } from "os";
10957
11491
  import { join as join27 } from "path";
10958
11492
  async function loadPersistedSettings() {
10959
11493
  const out = { mode: "default", theme: null };
10960
11494
  try {
10961
11495
  const p = join27(homedir16(), ".msapling", "settings.json");
10962
- if (!existsSync25(p)) return out;
10963
- const raw = JSON.parse(await readFile22(p, "utf8"));
11496
+ if (!existsSync26(p)) return out;
11497
+ const raw = JSON.parse(await readFile23(p, "utf8"));
10964
11498
  const parsed = parseApprovalMode(raw, Date.now());
10965
11499
  if (parsed.kind === "ok") out.mode = parsed.mode;
10966
11500
  const themeRaw = raw?.theme;
@@ -11210,13 +11744,13 @@ async function openBrowser(url) {
11210
11744
  cmd = "xdg-open";
11211
11745
  args2 = [url];
11212
11746
  }
11213
- return new Promise((resolve18) => {
11747
+ return new Promise((resolve19) => {
11214
11748
  try {
11215
11749
  const child = spawn10(cmd, args2, { stdio: "ignore", detached: true });
11216
11750
  child.unref();
11217
11751
  } catch {
11218
11752
  }
11219
- resolve18();
11753
+ resolve19();
11220
11754
  });
11221
11755
  }
11222
11756
  var init_open_browser = __esm({
@@ -11306,7 +11840,7 @@ var init_checkout = __esm({
11306
11840
  // src/commands/billing/sub.ts
11307
11841
  import * as readline from "readline";
11308
11842
  function prompt(rl, question) {
11309
- return new Promise((resolve18) => rl.question(question, resolve18));
11843
+ return new Promise((resolve19) => rl.question(question, resolve19));
11310
11844
  }
11311
11845
  async function runSub(argv) {
11312
11846
  const subCmd = argv[0] ?? "";
@@ -11435,11 +11969,11 @@ var init_sub = __esm({
11435
11969
  // src/commands/billing/topup.ts
11436
11970
  import * as readline2 from "readline";
11437
11971
  function prompt2(rl, question) {
11438
- return new Promise((resolve18) => rl.question(question, resolve18));
11972
+ return new Promise((resolve19) => rl.question(question, resolve19));
11439
11973
  }
11440
11974
  function promptDefault(rl, question, defaultVal) {
11441
11975
  return new Promise(
11442
- (resolve18) => rl.question(`${question} [${defaultVal}]: `, (ans) => resolve18(ans.trim() || defaultVal))
11976
+ (resolve19) => rl.question(`${question} [${defaultVal}]: `, (ans) => resolve19(ans.trim() || defaultVal))
11443
11977
  );
11444
11978
  }
11445
11979
  async function runTopup(argv) {
@@ -11580,7 +12114,7 @@ var init_redeem = __esm({
11580
12114
  // src/commands/billing/gift.ts
11581
12115
  import * as readline3 from "readline";
11582
12116
  function prompt3(rl, question) {
11583
- return new Promise((resolve18) => rl.question(question, resolve18));
12117
+ return new Promise((resolve19) => rl.question(question, resolve19));
11584
12118
  }
11585
12119
  async function runGift(argv) {
11586
12120
  const subCmd = argv[0] ?? "";
@@ -11837,7 +12371,7 @@ __export(doctor_exports, {
11837
12371
  });
11838
12372
  import { homedir as homedir17, platform as platform3 } from "os";
11839
12373
  import { join as join28 } from "path";
11840
- import { existsSync as existsSync26, statSync as statSync6, accessSync } from "fs";
12374
+ import { existsSync as existsSync27, statSync as statSync6, accessSync } from "fs";
11841
12375
  import { readdir as readdir3 } from "fs/promises";
11842
12376
  import { exec } from "child_process";
11843
12377
  import { promisify } from "util";
@@ -11861,7 +12395,7 @@ async function checkNodeVersion() {
11861
12395
  }
11862
12396
  async function checkConfigDir() {
11863
12397
  const configDir = join28(homedir17(), ".msapling");
11864
- if (!existsSync26(configDir)) {
12398
+ if (!existsSync27(configDir)) {
11865
12399
  return {
11866
12400
  name: "Config directory",
11867
12401
  status: "WARN",
@@ -11927,7 +12461,7 @@ async function checkPathConflicts() {
11927
12461
  const paths = pathEnv.split(platform3() === "win32" ? ";" : ":");
11928
12462
  const conflicts = [];
11929
12463
  for (const dir of paths) {
11930
- if (!dir || !existsSync26(dir)) continue;
12464
+ if (!dir || !existsSync27(dir)) continue;
11931
12465
  try {
11932
12466
  const files = await readdir3(dir);
11933
12467
  for (const file of files) {
@@ -13349,16 +13883,16 @@ var init_registry_merger = __esm({
13349
13883
  // ../core/src/mcp/local_tools.ts
13350
13884
  import { spawn as spawn11 } from "child_process";
13351
13885
  import { readdir as readdir4, stat as stat4, realpath as realpath2 } from "fs/promises";
13352
- import { resolve as resolve16 } from "path";
13886
+ import { resolve as resolve17 } from "path";
13353
13887
  function asResult(text, isError = false) {
13354
13888
  return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
13355
13889
  }
13356
13890
  async function runCommand(command, cwd) {
13357
- return new Promise((resolve18) => {
13891
+ return new Promise((resolve19) => {
13358
13892
  let p;
13359
13893
  const timeout = setTimeout(() => {
13360
13894
  if (p) p.kill();
13361
- resolve18({ stdout: "", stderr: "Command timed out after 30s", exit_code: -1 });
13895
+ resolve19({ stdout: "", stderr: "Command timed out after 30s", exit_code: -1 });
13362
13896
  }, 3e4);
13363
13897
  try {
13364
13898
  p = spawn11("sh", ["-c", command], {
@@ -13376,15 +13910,15 @@ async function runCommand(command, cwd) {
13376
13910
  });
13377
13911
  p.on("error", (e) => {
13378
13912
  clearTimeout(timeout);
13379
- resolve18({ stdout, stderr: stderr + (e?.message ?? ""), exit_code: -1 });
13913
+ resolve19({ stdout, stderr: stderr + (e?.message ?? ""), exit_code: -1 });
13380
13914
  });
13381
13915
  p.on("exit", (code) => {
13382
13916
  clearTimeout(timeout);
13383
- resolve18({ stdout, stderr, exit_code: code });
13917
+ resolve19({ stdout, stderr, exit_code: code });
13384
13918
  });
13385
13919
  } catch (e) {
13386
13920
  clearTimeout(timeout);
13387
- resolve18({
13921
+ resolve19({
13388
13922
  stdout: "",
13389
13923
  stderr: e?.message ?? "Failed to spawn process",
13390
13924
  exit_code: -1
@@ -13451,7 +13985,7 @@ async function callLocalTool(name, args2, projectRoot) {
13451
13985
  const command = String(args2.command ?? "");
13452
13986
  let cwd = projectRoot;
13453
13987
  if (args2.cwd) {
13454
- cwd = resolve16(projectRoot, String(args2.cwd));
13988
+ cwd = resolve17(projectRoot, String(args2.cwd));
13455
13989
  try {
13456
13990
  const resolvedCwd = await realpath2(cwd);
13457
13991
  const resolvedRoot = await realpath2(projectRoot);
@@ -13488,7 +14022,7 @@ ${res.stderr}`
13488
14022
  return asResult("path is required", true);
13489
14023
  }
13490
14024
  try {
13491
- const resolvedPath = await realpath2(resolve16(projectRoot, pathArg));
14025
+ const resolvedPath = await realpath2(resolve17(projectRoot, pathArg));
13492
14026
  const resolvedRoot = await realpath2(projectRoot);
13493
14027
  if (!resolvedPath.startsWith(resolvedRoot)) {
13494
14028
  return asResult("Error: path attempts to escape project root", true);
@@ -13507,7 +14041,7 @@ ${res.stderr}`
13507
14041
  }
13508
14042
  case "local_glob": {
13509
14043
  const pattern = String(args2.pattern ?? "");
13510
- let cwd = args2.cwd ? resolve16(projectRoot, String(args2.cwd)) : projectRoot;
14044
+ let cwd = args2.cwd ? resolve17(projectRoot, String(args2.cwd)) : projectRoot;
13511
14045
  if (!pattern) {
13512
14046
  return asResult("pattern is required", true);
13513
14047
  }
@@ -13536,7 +14070,7 @@ ${res.stderr}`
13536
14070
  }
13537
14071
  if (path2) {
13538
14072
  try {
13539
- const resolvedPath = await realpath2(resolve16(projectRoot, path2));
14073
+ const resolvedPath = await realpath2(resolve17(projectRoot, path2));
13540
14074
  const resolvedRoot = await realpath2(projectRoot);
13541
14075
  if (!resolvedPath.startsWith(resolvedRoot)) {
13542
14076
  return asResult("Error: path attempts to escape project root", true);
@@ -13556,7 +14090,7 @@ ${res.stderr}`
13556
14090
  return asResult("cwd is required", true);
13557
14091
  }
13558
14092
  try {
13559
- const resolvedCwd = await realpath2(resolve16(projectRoot, cwdArg));
14093
+ const resolvedCwd = await realpath2(resolve17(projectRoot, cwdArg));
13560
14094
  const resolvedRoot = await realpath2(projectRoot);
13561
14095
  if (!resolvedCwd.startsWith(resolvedRoot)) {
13562
14096
  return asResult("Error: cwd attempts to escape project root", true);
@@ -13582,7 +14116,7 @@ ${status.porcelain || "(clean)"}`
13582
14116
  return asResult("cwd is required", true);
13583
14117
  }
13584
14118
  try {
13585
- const resolvedCwd = await realpath2(resolve16(projectRoot, cwdArg));
14119
+ const resolvedCwd = await realpath2(resolve17(projectRoot, cwdArg));
13586
14120
  const resolvedRoot = await realpath2(projectRoot);
13587
14121
  if (!resolvedCwd.startsWith(resolvedRoot)) {
13588
14122
  return asResult("Error: cwd attempts to escape project root", true);
@@ -13698,7 +14232,7 @@ __export(server_exports, {
13698
14232
  runStdioWithRegistry: () => runStdioWithRegistry
13699
14233
  });
13700
14234
  import { readdirSync as readdirSync4, readFileSync as readFileSync2, statSync as statSync7 } from "fs";
13701
- import { join as join29, relative as relative14, resolve as resolve17 } from "path";
14235
+ import { join as join29, relative as relative14, resolve as resolve18 } from "path";
13702
14236
  function asResult2(text, isError = false) {
13703
14237
  return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
13704
14238
  }
@@ -14056,13 +14590,13 @@ var init_server = __esm({
14056
14590
  if (inflight === 0) {
14057
14591
  return [];
14058
14592
  }
14059
- const forcedResponses = await new Promise((resolve18) => {
14060
- this._drainResolve = () => resolve18([]);
14593
+ const forcedResponses = await new Promise((resolve19) => {
14594
+ this._drainResolve = () => resolve19([]);
14061
14595
  setTimeout(() => {
14062
14596
  this._drainResolve = null;
14063
14597
  const remaining = Array.from(this._inflightCalls.values());
14064
14598
  if (remaining.length === 0) {
14065
- resolve18([]);
14599
+ resolve19([]);
14066
14600
  return;
14067
14601
  }
14068
14602
  process.stderr.write(
@@ -14078,7 +14612,7 @@ var init_server = __esm({
14078
14612
  }
14079
14613
  }));
14080
14614
  this._inflightCalls.clear();
14081
- resolve18(errorResponses);
14615
+ resolve19(errorResponses);
14082
14616
  }, DRAIN_TIMEOUT_MS);
14083
14617
  });
14084
14618
  return forcedResponses;
@@ -14356,7 +14890,7 @@ ${r.response ?? ""}`;
14356
14890
  return asResult2(JSON.stringify(result));
14357
14891
  }
14358
14892
  case "msapling_project_context": {
14359
- const root = resolve17(String(args2.path ?? "."));
14893
+ const root = resolve18(String(args2.path ?? "."));
14360
14894
  const maxFiles = Number.isFinite(args2.max_files) ? Number(args2.max_files) : 30;
14361
14895
  const maxKB = Number.isFinite(args2.max_file_size_kb) ? Number(args2.max_file_size_kb) : 50;
14362
14896
  const files = buildFileTree(root, maxFiles);
@@ -14484,7 +15018,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
14484
15018
  var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
14485
15019
  /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
14486
15020
  "\u25CF MSapling CLI v",
14487
- "2.3.6-beta.23"
15021
+ "2.3.6-beta.25"
14488
15022
  ] }),
14489
15023
  /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
14490
15024
  ] });
@@ -14978,9 +15512,9 @@ ${prompt4}` : prompt4;
14978
15512
  if (proc.stderr) proc.stderr.on("data", (chunk) => {
14979
15513
  stderr += chunk.toString();
14980
15514
  });
14981
- await new Promise((resolve18, reject) => {
15515
+ await new Promise((resolve19, reject) => {
14982
15516
  proc.on("close", (code) => {
14983
- if (code === 0 || code === null) resolve18();
15517
+ if (code === 0 || code === null) resolve19();
14984
15518
  else reject(new Error(`Process exited with code ${code}`));
14985
15519
  });
14986
15520
  proc.on("error", reject);
@@ -15007,10 +15541,10 @@ ${prompt4}` : prompt4;
15007
15541
  for (const mention of fileMentions) {
15008
15542
  const filePath = mention.slice(1);
15009
15543
  try {
15010
- const { existsSync: existsSync27 } = await import("fs");
15011
- const { readFile: readFile23 } = await import("fs/promises");
15012
- if (existsSync27(filePath)) {
15013
- const content = await readFile23(filePath, "utf8");
15544
+ const { existsSync: existsSync28 } = await import("fs");
15545
+ const { readFile: readFile24 } = await import("fs/promises");
15546
+ if (existsSync28(filePath)) {
15547
+ const content = await readFile24(filePath, "utf8");
15014
15548
  const MAX_LEN = 32768;
15015
15549
  const truncated = content.length > MAX_LEN ? content.slice(0, MAX_LEN) + "\n...[TRUNCATED]" : content;
15016
15550
  finalCmd += `
@@ -15062,8 +15596,8 @@ ${finalCmd}`;
15062
15596
  init_esm_shims();
15063
15597
  init_src3();
15064
15598
  init_parseApprovalMode();
15065
- import { readFile as readFile21 } from "fs/promises";
15066
- import { existsSync as existsSync24 } from "fs";
15599
+ import { readFile as readFile22 } from "fs/promises";
15600
+ import { existsSync as existsSync25 } from "fs";
15067
15601
  async function initSession(ctx) {
15068
15602
  try {
15069
15603
  const { settings } = await loadSettings(
@@ -15080,8 +15614,8 @@ async function initSession(ctx) {
15080
15614
  const { homedir: homedir18 } = await import("os");
15081
15615
  const { join: join31 } = await import("path");
15082
15616
  const userSettingsPath = join31(homedir18(), ".msapling", "settings.json");
15083
- if (existsSync24(userSettingsPath)) {
15084
- const userText = await readFile21(userSettingsPath, "utf8");
15617
+ if (existsSync25(userSettingsPath)) {
15618
+ const userText = await readFile22(userSettingsPath, "utf8");
15085
15619
  let parsed;
15086
15620
  try {
15087
15621
  parsed = JSON.parse(userText);
@@ -15181,8 +15715,8 @@ var App = ({ compact: compact2 = false }) => {
15181
15715
  const storage = useRef(new StorageManager()).current;
15182
15716
  const client = useRef(new MSaplingClient()).current;
15183
15717
  const requestApproval = useCallback((request) => {
15184
- return new Promise((resolve18) => {
15185
- setPendingApproval({ request, resolve: resolve18 });
15718
+ return new Promise((resolve19) => {
15719
+ setPendingApproval({ request, resolve: resolve19 });
15186
15720
  });
15187
15721
  }, []);
15188
15722
  const agent = useRef(new Agent(client, process.cwd(), requestApproval)).current;