@persistmemory/cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -342,7 +342,7 @@ var SignalFired = class extends Error {
342
342
  };
343
343
  function untilAborted(work, signal) {
344
344
  work.catch(() => void 0);
345
- return new Promise((resolve6, reject) => {
345
+ return new Promise((resolve7, reject) => {
346
346
  if (signal.aborted) {
347
347
  reject(new SignalFired());
348
348
  return;
@@ -352,7 +352,7 @@ function untilAborted(work, signal) {
352
352
  work.then(
353
353
  (value) => {
354
354
  signal.removeEventListener("abort", onAbort);
355
- resolve6(value);
355
+ resolve7(value);
356
356
  },
357
357
  (error) => {
358
358
  signal.removeEventListener("abort", onAbort);
@@ -362,14 +362,14 @@ function untilAborted(work, signal) {
362
362
  });
363
363
  }
364
364
  function defaultSleep(ms, signal) {
365
- return new Promise((resolve6, reject) => {
365
+ return new Promise((resolve7, reject) => {
366
366
  if (signal?.aborted) {
367
367
  reject(new AbortError());
368
368
  return;
369
369
  }
370
370
  const timer = setTimeout(() => {
371
371
  signal?.removeEventListener("abort", onAbort);
372
- resolve6();
372
+ resolve7();
373
373
  }, ms);
374
374
  function onAbort() {
375
375
  clearTimeout(timer);
@@ -556,6 +556,58 @@ var Spaces = class {
556
556
  async create(params, options) {
557
557
  return this.#http.post("/api/v1/spaces", params, options);
558
558
  }
559
+ /**
560
+ * Deletes a Space. You must say what happens to what is in it.
561
+ *
562
+ * There is no default, here or in the API, and that is deliberate: "delete
563
+ * this Space" means the label to some people and everything inside it to
564
+ * others, and a client that guessed would destroy or keep somebody's
565
+ * material without being asked.
566
+ *
567
+ * `delete` never destroys a memory that is filed in another Space as well —
568
+ * that one is detached and left alone. `deleted` and `kept` come back so you
569
+ * can say what actually happened.
570
+ */
571
+ async delete(id, params, options) {
572
+ return this.#http.delete(
573
+ `/api/v1/spaces/${encodeURIComponent(id)}`,
574
+ params,
575
+ options
576
+ );
577
+ }
578
+ /**
579
+ * Merges Spaces into a NEW one, leaving every source exactly as it was.
580
+ *
581
+ * Additive, not destructive: a memory ends up in the sources AND the result,
582
+ * every existing search over a source returns what it did before, and
583
+ * undoing it is deleting the Space this returns. A memory in two sources is
584
+ * filed once.
585
+ */
586
+ async merge(params, options) {
587
+ return this.#http.post(
588
+ "/api/v1/spaces/merge",
589
+ params,
590
+ options
591
+ );
592
+ }
593
+ /**
594
+ * The Space this account files into when a capture names none.
595
+ *
596
+ * `{}` — an object with no `space` — means there is no default, which is the
597
+ * normal state rather than a gap. It is also what comes back after the Space
598
+ * somebody chose has been deleted.
599
+ */
600
+ async getDefault(options) {
601
+ return this.#http.get("/api/v1/spaces/default", void 0, options);
602
+ }
603
+ /** `null` clears it. Not the same as omitting it, which is why the type says so. */
604
+ async setDefault(spaceId, options) {
605
+ return this.#http.patch(
606
+ "/api/v1/spaces/default",
607
+ { spaceId },
608
+ options
609
+ );
610
+ }
559
611
  /** Renaming, retention, and archiving - `archived` is a field, not a verb. */
560
612
  async update(id, params, options) {
561
613
  return this.#http.patch(`/api/v1/spaces/${encodeURIComponent(id)}`, params, options);
@@ -918,6 +970,42 @@ var Health = class {
918
970
  return this.#http.get("/health/ready", void 0, options);
919
971
  }
920
972
  };
973
+ var Agent = class {
974
+ #http;
975
+ constructor(http) {
976
+ this.#http = http;
977
+ }
978
+ /** The row, including whether it finished and how large the result is. */
979
+ async request(id, options) {
980
+ return this.#http.get(
981
+ `/api/v1/agent/request/${encodeURIComponent(id)}`,
982
+ void 0,
983
+ options
984
+ );
985
+ }
986
+ /**
987
+ * A short-lived link to the bytes of a finished request.
988
+ *
989
+ * Returns the URL rather than the file, and that is a deliberate limit of
990
+ * this package rather than an oversight. The transport under every other
991
+ * method parses JSON, retries, and attaches the API key; none of those is
992
+ * right for a hundred-megabyte binary body, and building a second request
993
+ * path inside the SDK to serve one method is how a client ends up with two
994
+ * retry policies that differ only during an outage. Fetch the URL with
995
+ * whatever already streams in your runtime - it needs no credential, which
996
+ * is the whole reason it is signed.
997
+ *
998
+ * Treat the URL as the file. It is a bearer credential for exactly one
999
+ * object, it expires in minutes, and it should not be logged or stored.
1000
+ */
1001
+ async downloadLink(id, options) {
1002
+ return this.#http.get(
1003
+ `/api/v1/agent/request/${encodeURIComponent(id)}/download`,
1004
+ void 0,
1005
+ options
1006
+ );
1007
+ }
1008
+ };
921
1009
  var PersistMemory = class {
922
1010
  memories;
923
1011
  search;
@@ -931,6 +1019,7 @@ var PersistMemory = class {
931
1019
  conversations;
932
1020
  integrations;
933
1021
  health;
1022
+ agent;
934
1023
  #http;
935
1024
  constructor(options) {
936
1025
  this.#http = new HttpClient(options);
@@ -946,6 +1035,7 @@ var PersistMemory = class {
946
1035
  this.conversations = new Conversations(this.#http);
947
1036
  this.integrations = new Integrations(this.#http);
948
1037
  this.health = new Health(this.#http);
1038
+ this.agent = new Agent(this.#http);
949
1039
  }
950
1040
  /**
951
1041
  * An escape hatch for an endpoint this package has not caught up with.
@@ -1287,7 +1377,7 @@ function shortDate(iso) {
1287
1377
  }
1288
1378
 
1289
1379
  // src/help.ts
1290
- var VERSION = "0.1.1";
1380
+ var VERSION = "0.1.2";
1291
1381
  var PACKAGE = "@persistmemory/cli";
1292
1382
  var HELP = `
1293
1383
  pm \u2014 PersistMemory from your terminal
@@ -1334,6 +1424,7 @@ var HELP = `
1334
1424
 
1335
1425
  status is the service healthy
1336
1426
  requests file requests waiting for you to approve
1427
+ requests get <id> write a finished one to a file here
1337
1428
 
1338
1429
  update install the newest version
1339
1430
  uninstall remove pm from this machine
@@ -1477,8 +1568,8 @@ async function startLoopback(options = {}) {
1477
1568
  const timeoutMs = options.timeoutMs ?? 5 * 60 * 1e3;
1478
1569
  let resolveCallback;
1479
1570
  let rejectCallback;
1480
- const received = new Promise((resolve6, reject) => {
1481
- resolveCallback = resolve6;
1571
+ const received = new Promise((resolve7, reject) => {
1572
+ resolveCallback = resolve7;
1482
1573
  rejectCallback = reject;
1483
1574
  });
1484
1575
  const server = createServer((request, response) => {
@@ -1504,9 +1595,9 @@ async function startLoopback(options = {}) {
1504
1595
  response.end(donePage(callback));
1505
1596
  resolveCallback?.(callback);
1506
1597
  });
1507
- await new Promise((resolve6, reject) => {
1598
+ await new Promise((resolve7, reject) => {
1508
1599
  server.once("error", reject);
1509
- server.listen(0, "127.0.0.1", resolve6);
1600
+ server.listen(0, "127.0.0.1", resolve7);
1510
1601
  });
1511
1602
  const address = server.address();
1512
1603
  if (address === null || typeof address === "string") {
@@ -1768,7 +1859,7 @@ function safeEqual(a, b) {
1768
1859
  }
1769
1860
  async function openBrowser(url) {
1770
1861
  const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
1771
- await new Promise((resolve6, reject) => {
1862
+ await new Promise((resolve7, reject) => {
1772
1863
  const child = spawn(command, args, {
1773
1864
  stdio: "ignore",
1774
1865
  // Detached so closing the terminal does not close the browser, and so
@@ -1777,7 +1868,7 @@ async function openBrowser(url) {
1777
1868
  });
1778
1869
  child.once("error", reject);
1779
1870
  child.unref();
1780
- resolve6();
1871
+ resolve7();
1781
1872
  });
1782
1873
  }
1783
1874
  async function describe(response) {
@@ -1839,13 +1930,13 @@ async function currentCredential(resolved, deps) {
1839
1930
  // src/context.ts
1840
1931
  import { createInterface } from "node:readline";
1841
1932
  async function askOnTty(prompt) {
1842
- return new Promise((resolve6) => {
1933
+ return new Promise((resolve7) => {
1843
1934
  const readline = createInterface({ input: process.stdin, output: process.stdout });
1844
1935
  readline.question(prompt, (answer3) => {
1845
1936
  readline.close();
1846
- resolve6(answer3.trim());
1937
+ resolve7(answer3.trim());
1847
1938
  });
1848
- readline.once("close", () => resolve6(""));
1939
+ readline.once("close", () => resolve7(""));
1849
1940
  });
1850
1941
  }
1851
1942
  var ETX = "";
@@ -1854,13 +1945,13 @@ var BACKSPACE = "\b";
1854
1945
  async function readSecretFromTty(prompt) {
1855
1946
  const input = process.stdin;
1856
1947
  if (!input.isTTY) {
1857
- return new Promise((resolve6) => {
1948
+ return new Promise((resolve7) => {
1858
1949
  const readline = createInterface({ input });
1859
1950
  readline.once("line", (line) => {
1860
1951
  readline.close();
1861
- resolve6(line.trim());
1952
+ resolve7(line.trim());
1862
1953
  });
1863
- readline.once("close", () => resolve6(""));
1954
+ readline.once("close", () => resolve7(""));
1864
1955
  });
1865
1956
  }
1866
1957
  process.stdout.write(prompt);
@@ -1868,14 +1959,14 @@ async function readSecretFromTty(prompt) {
1868
1959
  input.setRawMode?.(true);
1869
1960
  input.resume();
1870
1961
  input.setEncoding("utf8");
1871
- return new Promise((resolve6) => {
1962
+ return new Promise((resolve7) => {
1872
1963
  let value = "";
1873
1964
  const finish2 = () => {
1874
1965
  input.removeListener("data", onData);
1875
1966
  input.setRawMode?.(previouslyRaw);
1876
1967
  input.pause();
1877
1968
  process.stdout.write("\n");
1878
- resolve6(value.trim());
1969
+ resolve7(value.trim());
1879
1970
  };
1880
1971
  const onData = (chunk) => {
1881
1972
  for (const character of chunk) {
@@ -1912,8 +2003,8 @@ async function readStdin() {
1912
2003
  // src/commands/agent.ts
1913
2004
  import { hostname } from "node:os";
1914
2005
  import { homedir as homedir2 } from "node:os";
1915
- import { resolve as resolve3 } from "node:path";
1916
- import { readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
2006
+ import { join as join4, resolve as resolve3 } from "node:path";
2007
+ import { readFileSync as readFileSync4, readdirSync, statSync as statSync2 } from "node:fs";
1917
2008
 
1918
2009
  // src/files.ts
1919
2010
  import { existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
@@ -1926,11 +2017,13 @@ var OutsideWorkspace = class extends Error {
1926
2017
  };
1927
2018
  var TooLarge = class extends Error {
1928
2019
  constructor(path, bytes, limit) {
1929
- super(`${path} is ${Math.round(bytes / 1024)} KB, over the ${Math.round(limit / 1024)} KB limit.`);
2020
+ const say = (value) => value >= 1024 * 1024 ? `${(value / (1024 * 1024)).toFixed(1)} MB` : `${Math.round(value / 1024)} KB`;
2021
+ super(`${path} is ${say(bytes)}, over the ${say(limit)} limit.`);
1930
2022
  this.name = "TooLarge";
1931
2023
  }
1932
2024
  };
1933
2025
  var MAX_READ_BYTES = 512 * 1024;
2026
+ var MAX_TRANSFER_BYTES = 100 * 1024 * 1024;
1934
2027
  function realLocation(absolute) {
1935
2028
  let existing = absolute;
1936
2029
  const trailing = [];
@@ -2044,19 +2137,41 @@ async function answer(context, apiUrl, token, roots, request) {
2044
2137
  return { ok: false, error: error instanceof Error ? error.message : "refused" };
2045
2138
  }
2046
2139
  let bytes;
2140
+ let filename = request.path.split("/").pop() ?? "file";
2141
+ if (request.kind === "list_dir") {
2142
+ try {
2143
+ const stats = statSync2(located);
2144
+ if (!stats.isDirectory()) return { ok: false, error: `${request.path} is not a folder.` };
2145
+ const entries = readdirSync(located, { withFileTypes: true }).filter((entry) => !entry.name.startsWith(".")).slice(0, MAX_LISTED).map((entry) => {
2146
+ if (entry.isDirectory()) return `${entry.name}/`;
2147
+ try {
2148
+ return `${entry.name} ${sizeOf(join4(located, entry.name))}`;
2149
+ } catch {
2150
+ return entry.name;
2151
+ }
2152
+ }).sort();
2153
+ const listing = entries.length > 0 ? entries.join("\n") : "(empty)";
2154
+ bytes = Buffer.from(`${request.path}
2155
+
2156
+ ${listing}
2157
+ `, "utf8");
2158
+ filename = `${request.path.split("/").filter(Boolean).pop() ?? "listing"}.txt`;
2159
+ const grant = await upload(apiUrl, token, filename, bytes);
2160
+ return grant;
2161
+ } catch (error) {
2162
+ return { ok: false, error: error instanceof Error ? error.message : "could not list it" };
2163
+ }
2164
+ }
2047
2165
  try {
2048
2166
  const stats = statSync2(located);
2049
2167
  if (!stats.isFile()) return { ok: false, error: `${request.path} is not a file.` };
2050
- if (stats.size > MAX_READ_BYTES) {
2051
- return {
2052
- ok: false,
2053
- error: new TooLarge(request.path, stats.size, MAX_READ_BYTES).message
2054
- };
2055
- }
2056
2168
  bytes = readFileSync4(located);
2057
2169
  } catch (error) {
2058
2170
  return { ok: false, error: error instanceof Error ? error.message : "could not read it" };
2059
2171
  }
2172
+ return upload(apiUrl, token, filename, bytes);
2173
+ }
2174
+ async function upload(apiUrl, token, filename, bytes) {
2060
2175
  const grant = await fetch(`${apiUrl}/api/v1/agent/upload-url`, {
2061
2176
  method: "POST",
2062
2177
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
@@ -2068,13 +2183,17 @@ async function answer(context, apiUrl, token, roots, request) {
2068
2183
  // No content type is sent: this machine has a path, not a declaration.
2069
2184
  // The server resolves it from the name against the one table that knows
2070
2185
  // which types it can read, and tells us below what it decided.
2071
- filename: request.path.split("/").pop() ?? "file"
2186
+ filename
2072
2187
  })
2073
2188
  });
2074
2189
  if (!grant.ok) {
2075
2190
  return { ok: false, error: await said(grant, "could not get an upload url") };
2076
2191
  }
2077
- const { uploadUrl, contentType } = await grant.json();
2192
+ const { uploadUrl, contentType, maxBytes } = await grant.json();
2193
+ const limit = maxBytes ?? MAX_TRANSFER_BYTES;
2194
+ if (bytes.length > limit) {
2195
+ return { ok: false, error: new TooLarge(filename, bytes.length, limit).message };
2196
+ }
2078
2197
  const put = await fetch(uploadUrl, {
2079
2198
  method: "PUT",
2080
2199
  // The type the grant was signed for. Anything else is refused.
@@ -2086,6 +2205,13 @@ async function answer(context, apiUrl, token, roots, request) {
2086
2205
  if (!stored.attachToken) return { ok: false, error: "the upload returned no reference" };
2087
2206
  return { ok: true, attachToken: stored.attachToken, bytes: bytes.length };
2088
2207
  }
2208
+ var MAX_LISTED = 200;
2209
+ function sizeOf(path) {
2210
+ const size = statSync2(path).size;
2211
+ if (size < 1024) return `${size} B`;
2212
+ if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`;
2213
+ return `${(size / (1024 * 1024)).toFixed(1)} MB`;
2214
+ }
2089
2215
  async function agentCommand(context) {
2090
2216
  const credential = context.resolved.credential;
2091
2217
  if (!credential) {
@@ -2195,7 +2321,10 @@ async function agentCommand(context) {
2195
2321
  }
2196
2322
 
2197
2323
  // src/commands/requests.ts
2324
+ import { existsSync as existsSync4, writeFileSync as writeFileSync4 } from "node:fs";
2325
+ import { resolve as resolve4 } from "node:path";
2198
2326
  async function requestsCommand(context) {
2327
+ if (context.args.words[1] === "get") return collectCommand(context);
2199
2328
  const credential = context.resolved.credential;
2200
2329
  if (!credential) {
2201
2330
  context.error("Sign in first: pm auth login");
@@ -2233,16 +2362,53 @@ async function requestsCommand(context) {
2233
2362
  context.print("They cannot be approved from here \u2014 see `pm help requests`.");
2234
2363
  return 0;
2235
2364
  }
2365
+ async function collectCommand(context) {
2366
+ const credential = context.resolved.credential;
2367
+ if (!credential) {
2368
+ context.error("Sign in first: pm auth login");
2369
+ return 1;
2370
+ }
2371
+ const id = context.args.words[2];
2372
+ if (!id) {
2373
+ context.error("Which request? `pm requests` lists them with their ids.");
2374
+ return 2;
2375
+ }
2376
+ const apiUrl = context.resolved.apiUrl.replace(/\/+$/, "");
2377
+ const link = await fetch(
2378
+ `${apiUrl}/api/v1/agent/request/${encodeURIComponent(id)}/download`,
2379
+ { headers: { authorization: `Bearer ${credential.token}` } }
2380
+ );
2381
+ if (!link.ok) {
2382
+ const body = await link.json().catch(() => void 0);
2383
+ context.error(body?.error?.message ?? `Could not prepare that file (${link.status}).`);
2384
+ return 1;
2385
+ }
2386
+ const { downloadUrl, filename } = await link.json();
2387
+ const file = await fetch(downloadUrl);
2388
+ if (!file.ok) {
2389
+ context.error(`The download refused it (${file.status}). Links expire in minutes \u2014 try again.`);
2390
+ return 1;
2391
+ }
2392
+ const name = stringFlag(context.args, "output", "o") ?? filename;
2393
+ const target = resolve4(name);
2394
+ if (existsSync4(target)) {
2395
+ context.error(`${target} already exists. Pass --output to write somewhere else.`);
2396
+ return 1;
2397
+ }
2398
+ writeFileSync4(target, new Uint8Array(await file.arrayBuffer()));
2399
+ context.print(`Wrote ${target}`);
2400
+ return 0;
2401
+ }
2236
2402
 
2237
2403
  // src/workspace.ts
2238
- import { existsSync as existsSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
2239
- import { dirname as dirname3, join as join4, resolve as resolvePath } from "node:path";
2404
+ import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
2405
+ import { dirname as dirname3, join as join5, resolve as resolvePath } from "node:path";
2240
2406
  var WORKSPACE_FILE = ".persistmemory.json";
2241
2407
  function findWorkspace(from = process.cwd()) {
2242
2408
  let dir = resolvePath(from);
2243
2409
  for (; ; ) {
2244
- const file = join4(dir, WORKSPACE_FILE);
2245
- if (existsSync4(file)) {
2410
+ const file = join5(dir, WORKSPACE_FILE);
2411
+ if (existsSync5(file)) {
2246
2412
  const config = readWorkspace(file);
2247
2413
  if (config) return { file, dir, config };
2248
2414
  }
@@ -2264,8 +2430,8 @@ function readWorkspace(file) {
2264
2430
  }
2265
2431
  }
2266
2432
  function writeWorkspace(dir, config) {
2267
- const file = join4(dir, WORKSPACE_FILE);
2268
- writeFileSync4(file, `${JSON.stringify(config, null, 2)}
2433
+ const file = join5(dir, WORKSPACE_FILE);
2434
+ writeFileSync5(file, `${JSON.stringify(config, null, 2)}
2269
2435
  `, "utf8");
2270
2436
  return file;
2271
2437
  }
@@ -2534,9 +2700,9 @@ function message(error) {
2534
2700
  }
2535
2701
 
2536
2702
  // src/commands/maintain.ts
2537
- import { existsSync as existsSync5, rmSync } from "node:fs";
2703
+ import { existsSync as existsSync6, rmSync } from "node:fs";
2538
2704
  import { spawnSync } from "node:child_process";
2539
- import { dirname as dirname4, resolve as resolve5 } from "node:path";
2705
+ import { dirname as dirname4, resolve as resolve6 } from "node:path";
2540
2706
  import { fileURLToPath } from "node:url";
2541
2707
  async function updateCommand(context) {
2542
2708
  const manager = installer();
@@ -2578,7 +2744,7 @@ Delete the file it runs from: ${processPath()}`
2578
2744
  return 0;
2579
2745
  }
2580
2746
  async function deleteCommand(context) {
2581
- if (!existsSync5(context.paths.dir)) {
2747
+ if (!existsSync6(context.paths.dir)) {
2582
2748
  context.print(`Nothing to delete: ${context.paths.dir} does not exist.`);
2583
2749
  return 0;
2584
2750
  }
@@ -2607,7 +2773,7 @@ async function deleteCommand(context) {
2607
2773
  return 0;
2608
2774
  }
2609
2775
  function removeEverything(context) {
2610
- const dir = resolve5(context.paths.dir);
2776
+ const dir = resolve6(context.paths.dir);
2611
2777
  if (dir === "/" || dir.split("/").filter(Boolean).length < 2) {
2612
2778
  context.error(`Refusing to delete ${dir}: that does not look like a data directory.`);
2613
2779
  return;
@@ -2619,7 +2785,7 @@ function installer() {
2619
2785
  }
2620
2786
  function processPath() {
2621
2787
  try {
2622
- return resolve5(dirname4(fileURLToPath(import.meta.url)));
2788
+ return resolve6(dirname4(fileURLToPath(import.meta.url)));
2623
2789
  } catch {
2624
2790
  return process.argv[1] ?? "";
2625
2791
  }
@@ -2631,12 +2797,12 @@ import { randomUUID } from "node:crypto";
2631
2797
  import { relative as relative2 } from "node:path";
2632
2798
 
2633
2799
  // src/events.ts
2634
- import { appendFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync6 } from "node:fs";
2635
- import { join as join5 } from "node:path";
2800
+ import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync6 } from "node:fs";
2801
+ import { join as join6 } from "node:path";
2636
2802
  function openSessionLog(paths, id) {
2637
- const directory = join5(paths.dir, "sessions");
2803
+ const directory = join6(paths.dir, "sessions");
2638
2804
  mkdirSync3(directory, { recursive: true, mode: 448 });
2639
- const path = join5(directory, `${id}.jsonl`);
2805
+ const path = join6(directory, `${id}.jsonl`);
2640
2806
  return {
2641
2807
  id,
2642
2808
  path,
@@ -2648,7 +2814,7 @@ function openSessionLog(paths, id) {
2648
2814
  }
2649
2815
  },
2650
2816
  read() {
2651
- if (!existsSync6(path)) return [];
2817
+ if (!existsSync7(path)) return [];
2652
2818
  return readFileSync6(path, "utf8").split("\n").filter((line) => line.trim() !== "").flatMap((line) => {
2653
2819
  try {
2654
2820
  return [JSON.parse(line)];
@@ -2726,9 +2892,9 @@ async function sessionCommand(context) {
2726
2892
  context.print(` Ask anything. /help for commands, /exit to leave.
2727
2893
  `);
2728
2894
  const readline = createInterface2({ input: process.stdin, output: process.stdout });
2729
- const ask = (prompt) => new Promise((resolve6) => {
2730
- readline.question(prompt, resolve6);
2731
- readline.once("close", () => resolve6(void 0));
2895
+ const ask = (prompt) => new Promise((resolve7) => {
2896
+ readline.question(prompt, resolve7);
2897
+ readline.once("close", () => resolve7(void 0));
2732
2898
  });
2733
2899
  const root = process.cwd();
2734
2900
  let running = true;