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