@persistmemory/cli 0.2.0 → 0.2.1

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
@@ -1525,7 +1525,7 @@ function shortDate(iso) {
1525
1525
  }
1526
1526
 
1527
1527
  // src/help.ts
1528
- var VERSION = "0.1.2";
1528
+ var VERSION = true ? "0.2.1" : versionFromManifest();
1529
1529
  var PACKAGE = "@persistmemory/cli";
1530
1530
  var HELP = `
1531
1531
  pm \u2014 PersistMemory from your terminal
@@ -2157,8 +2157,8 @@ async function readStdin() {
2157
2157
  // src/commands/agent.ts
2158
2158
  import { hostname } from "node:os";
2159
2159
  import { homedir as homedir2 } from "node:os";
2160
- import { join as join4, resolve as resolve3 } from "node:path";
2161
- import { readFileSync as readFileSync4, readdirSync, statSync as statSync2 } from "node:fs";
2160
+ import { basename, join as join4, resolve as resolve3 } from "node:path";
2161
+ import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
2162
2162
 
2163
2163
  // src/files.ts
2164
2164
  import { existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
@@ -2283,6 +2283,17 @@ function locate(roots, requested) {
2283
2283
  }
2284
2284
  throw new Error(`${requested} is not inside any allowed folder (${roots.join(", ")})`);
2285
2285
  }
2286
+ function uncontested(target) {
2287
+ if (!existsSync4(target)) return target;
2288
+ const dot = target.lastIndexOf(".");
2289
+ const stem = dot > target.lastIndexOf("/") && dot !== -1 ? target.slice(0, dot) : target;
2290
+ const extension = stem === target ? "" : target.slice(dot);
2291
+ for (let n = 1; n < 1e3; n += 1) {
2292
+ const candidate = `${stem} (${n})${extension}`;
2293
+ if (!existsSync4(candidate)) return candidate;
2294
+ }
2295
+ throw new Error(`${target} and a thousand names beside it are taken.`);
2296
+ }
2286
2297
  async function answer(context, apiUrl, token, roots, request) {
2287
2298
  let located;
2288
2299
  try {
@@ -2290,6 +2301,43 @@ async function answer(context, apiUrl, token, roots, request) {
2290
2301
  } catch (error) {
2291
2302
  return { ok: false, error: error instanceof Error ? error.message : "refused" };
2292
2303
  }
2304
+ if (request.kind === "write_file") {
2305
+ if (!request.sourceUrl) return { ok: false, error: "There was nothing to write." };
2306
+ let downloaded;
2307
+ let fetched;
2308
+ try {
2309
+ fetched = await fetch(request.sourceUrl);
2310
+ if (!fetched.ok) {
2311
+ return { ok: false, error: await said(fetched, "The file could not be fetched") };
2312
+ }
2313
+ downloaded = Buffer.from(await fetched.arrayBuffer());
2314
+ } catch {
2315
+ return { ok: false, error: "The file could not be fetched from the service." };
2316
+ }
2317
+ try {
2318
+ let target = located;
2319
+ if (existsSync4(located) && statSync2(located).isDirectory()) {
2320
+ const disposition = fetched.headers.get("content-disposition") ?? "";
2321
+ const named = /filename="([^"]+)"/.exec(disposition)?.[1];
2322
+ target = join4(located, basename(named ?? "file"));
2323
+ }
2324
+ target = uncontested(target);
2325
+ writeFileSync4(target, downloaded, { flag: "wx" });
2326
+ return upload(
2327
+ apiUrl,
2328
+ token,
2329
+ "written.txt",
2330
+ Buffer.from(`Saved to ${target}
2331
+ ${downloaded.length} bytes
2332
+ `, "utf8")
2333
+ );
2334
+ } catch (error) {
2335
+ return {
2336
+ ok: false,
2337
+ error: error instanceof Error ? error.message : "could not write it"
2338
+ };
2339
+ }
2340
+ }
2293
2341
  let bytes;
2294
2342
  let filename = request.path.split("/").pop() ?? "file";
2295
2343
  if (request.kind === "list_dir") {
@@ -2475,8 +2523,8 @@ async function agentCommand(context) {
2475
2523
  }
2476
2524
 
2477
2525
  // src/commands/google.ts
2478
- import { writeFileSync as writeFileSync4 } from "node:fs";
2479
- import { basename, resolve as resolve4 } from "node:path";
2526
+ import { writeFileSync as writeFileSync5 } from "node:fs";
2527
+ import { basename as basename2, resolve as resolve4 } from "node:path";
2480
2528
  import { readFileSync as readFileSync5 } from "node:fs";
2481
2529
  async function callApi(context, path, init = {}) {
2482
2530
  const credential = context.resolved.credential;
@@ -2542,8 +2590,8 @@ async function driveGet(context, fileId) {
2542
2590
  const disposition = response.headers.get("content-disposition") ?? "";
2543
2591
  const named = /filename="([^"]+)"/.exec(disposition)?.[1];
2544
2592
  const out = stringFlag(context.args, "out");
2545
- const target = resolve4(out ?? basename(named ?? fileId));
2546
- writeFileSync4(target, Buffer.from(await response.arrayBuffer()));
2593
+ const target = resolve4(out ?? basename2(named ?? fileId));
2594
+ writeFileSync5(target, Buffer.from(await response.arrayBuffer()));
2547
2595
  context.print(target);
2548
2596
  return 0;
2549
2597
  }
@@ -2559,7 +2607,7 @@ async function drivePut(context, path) {
2559
2607
  context.error(`Cannot read ${path}.`);
2560
2608
  return 1;
2561
2609
  }
2562
- const name = stringFlag(context.args, "name") ?? basename(path);
2610
+ const name = stringFlag(context.args, "name") ?? basename2(path);
2563
2611
  const response = await callApi(
2564
2612
  context,
2565
2613
  `/api/v1/google/drive/files?name=${encodeURIComponent(name)}`,
@@ -2638,7 +2686,7 @@ async function mailCommand(context) {
2638
2686
  }
2639
2687
 
2640
2688
  // src/commands/requests.ts
2641
- import { existsSync as existsSync4, writeFileSync as writeFileSync5 } from "node:fs";
2689
+ import { existsSync as existsSync5, writeFileSync as writeFileSync6 } from "node:fs";
2642
2690
  import { resolve as resolve5 } from "node:path";
2643
2691
  async function requestsCommand(context) {
2644
2692
  if (context.args.words[1] === "get") return collectCommand(context);
@@ -2708,24 +2756,24 @@ async function collectCommand(context) {
2708
2756
  }
2709
2757
  const name = stringFlag(context.args, "output", "o") ?? filename;
2710
2758
  const target = resolve5(name);
2711
- if (existsSync4(target)) {
2759
+ if (existsSync5(target)) {
2712
2760
  context.error(`${target} already exists. Pass --output to write somewhere else.`);
2713
2761
  return 1;
2714
2762
  }
2715
- writeFileSync5(target, new Uint8Array(await file.arrayBuffer()));
2763
+ writeFileSync6(target, new Uint8Array(await file.arrayBuffer()));
2716
2764
  context.print(`Wrote ${target}`);
2717
2765
  return 0;
2718
2766
  }
2719
2767
 
2720
2768
  // src/workspace.ts
2721
- import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
2769
+ import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "node:fs";
2722
2770
  import { dirname as dirname3, join as join5, resolve as resolvePath } from "node:path";
2723
2771
  var WORKSPACE_FILE = ".persistmemory.json";
2724
2772
  function findWorkspace(from = process.cwd()) {
2725
2773
  let dir = resolvePath(from);
2726
2774
  for (; ; ) {
2727
2775
  const file = join5(dir, WORKSPACE_FILE);
2728
- if (existsSync5(file)) {
2776
+ if (existsSync6(file)) {
2729
2777
  const config = readWorkspace(file);
2730
2778
  if (config) return { file, dir, config };
2731
2779
  }
@@ -2748,7 +2796,7 @@ function readWorkspace(file) {
2748
2796
  }
2749
2797
  function writeWorkspace(dir, config) {
2750
2798
  const file = join5(dir, WORKSPACE_FILE);
2751
- writeFileSync6(file, `${JSON.stringify(config, null, 2)}
2799
+ writeFileSync7(file, `${JSON.stringify(config, null, 2)}
2752
2800
  `, "utf8");
2753
2801
  return file;
2754
2802
  }
@@ -3017,7 +3065,7 @@ function message(error) {
3017
3065
  }
3018
3066
 
3019
3067
  // src/commands/maintain.ts
3020
- import { existsSync as existsSync6, rmSync } from "node:fs";
3068
+ import { existsSync as existsSync7, rmSync } from "node:fs";
3021
3069
  import { spawnSync } from "node:child_process";
3022
3070
  import { dirname as dirname4, resolve as resolve7 } from "node:path";
3023
3071
  import { fileURLToPath } from "node:url";
@@ -3061,7 +3109,7 @@ Delete the file it runs from: ${processPath()}`
3061
3109
  return 0;
3062
3110
  }
3063
3111
  async function deleteCommand(context) {
3064
- if (!existsSync6(context.paths.dir)) {
3112
+ if (!existsSync7(context.paths.dir)) {
3065
3113
  context.print(`Nothing to delete: ${context.paths.dir} does not exist.`);
3066
3114
  return 0;
3067
3115
  }
@@ -3114,7 +3162,7 @@ import { randomUUID } from "node:crypto";
3114
3162
  import { relative as relative2 } from "node:path";
3115
3163
 
3116
3164
  // src/events.ts
3117
- import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "node:fs";
3165
+ import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "node:fs";
3118
3166
  import { join as join6 } from "node:path";
3119
3167
  function openSessionLog(paths, id) {
3120
3168
  const directory = join6(paths.dir, "sessions");
@@ -3131,7 +3179,7 @@ function openSessionLog(paths, id) {
3131
3179
  }
3132
3180
  },
3133
3181
  read() {
3134
- if (!existsSync7(path)) return [];
3182
+ if (!existsSync8(path)) return [];
3135
3183
  return readFileSync7(path, "utf8").split("\n").filter((line) => line.trim() !== "").flatMap((line) => {
3136
3184
  try {
3137
3185
  return [JSON.parse(line)];
@@ -3747,6 +3795,16 @@ async function dispatch(context) {
3747
3795
  case "setup":
3748
3796
  case "init":
3749
3797
  return setupCommand(context);
3798
+ /*
3799
+ `pm version` as well as `--version`.
3800
+
3801
+ It is what people type, and answering "Unknown command" to somebody
3802
+ asking which version they are running — while a flag two characters away
3803
+ answers it — is a needless dead end.
3804
+ */
3805
+ case "version":
3806
+ context.print(VERSION);
3807
+ return 0;
3750
3808
  case "update":
3751
3809
  case "upgrade":
3752
3810
  return updateCommand(context);