@persistmemory/cli 0.3.2 → 0.4.0

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
@@ -1404,7 +1404,7 @@ function shortDate(iso) {
1404
1404
  }
1405
1405
 
1406
1406
  // src/help.ts
1407
- var VERSION = true ? "0.3.2" : versionFromManifest();
1407
+ var VERSION = true ? "0.4.0" : versionFromManifest();
1408
1408
  var PACKAGE = "@persistmemory/cli";
1409
1409
  var HELP = `
1410
1410
  pm \u2014 PersistMemory from your terminal
@@ -1446,12 +1446,14 @@ var HELP = `
1446
1446
  remember - capture whatever is piped in
1447
1447
  remember --file <path> capture a file's contents
1448
1448
 
1449
- agent --root <dir> [--root ...] answer file requests from this machine \u2014
1450
- nothing outside those folders is read.
1451
- It stays in the foreground. Background it,
1452
- and stop it later, with:
1453
- nohup pm agent --root ~/Desktop &
1449
+ agent answer file requests from this machine.
1450
+ Reads ~/Desktop, ~/Documents and
1451
+ ~/Downloads by default, and nothing
1452
+ outside them. It stays in the foreground.
1453
+ Background it, and stop it later, with:
1454
+ nohup pm agent > ~/agent.log 2>&1 &
1454
1455
  pkill -f "pm agent"
1456
+ agent --root <dir> [--root ...] choose the folders yourself instead
1455
1457
 
1456
1458
  search <query> search your memory
1457
1459
  list memories the most recent memories
@@ -2320,6 +2322,15 @@ async function upload(apiUrl, token, filename, bytes) {
2320
2322
  if (!stored.attachToken) return { ok: false, error: "the upload returned no reference" };
2321
2323
  return { ok: true, attachToken: stored.attachToken, bytes: bytes.length };
2322
2324
  }
2325
+ function defaultRoots(home = homedir2(), isDirectory = (path) => {
2326
+ try {
2327
+ return statSync2(path).isDirectory();
2328
+ } catch {
2329
+ return false;
2330
+ }
2331
+ }) {
2332
+ return ["Desktop", "Documents", "Downloads"].map((name) => join4(home, name)).filter(isDirectory);
2333
+ }
2323
2334
  var MAX_LISTED = 200;
2324
2335
  function sizeOf(path) {
2325
2336
  const size = statSync2(path).size;
@@ -2337,18 +2348,19 @@ async function agentCommand(context) {
2337
2348
  (one) => resolve3(one.startsWith("~") ? resolve3(homedir2(), one.slice(1).replace(/^[/\\]/, "")) : one)
2338
2349
  );
2339
2350
  if (roots.length === 0) {
2340
- context.error(
2341
- "Say which folders this machine may read from, and nothing outside them will be:"
2351
+ const usual = defaultRoots();
2352
+ if (usual.length === 0) {
2353
+ context.error(
2354
+ "This machine has no Desktop, Documents or Downloads folder, so there is nothing to offer by default. Say which folders it may read from:"
2355
+ );
2356
+ context.error("");
2357
+ context.error(" pm agent --root ~/projects");
2358
+ return 1;
2359
+ }
2360
+ roots.push(...usual);
2361
+ context.print(
2362
+ `Reading from ${usual.map((path) => path.replace(homedir2(), "~")).join(", ")} \u2014 nothing outside them. Use --root to choose your own.`
2342
2363
  );
2343
- context.error("");
2344
- context.error(" pm agent --root ~/Desktop --root ~/Documents");
2345
- context.error("");
2346
- context.error("It stays in the foreground. To leave it running:");
2347
- context.error("");
2348
- context.error(" nohup pm agent --root ~/Desktop > ~/agent.log 2>&1 &");
2349
- context.error("");
2350
- context.error('And to stop it later: pkill -f "pm agent"');
2351
- return 1;
2352
2364
  }
2353
2365
  for (const root of roots) {
2354
2366
  try {
@@ -2993,6 +3005,9 @@ import { existsSync as existsSync7, rmSync } from "node:fs";
2993
3005
  import { spawnSync } from "node:child_process";
2994
3006
  import { dirname as dirname4, resolve as resolve7 } from "node:path";
2995
3007
  import { fileURLToPath } from "node:url";
3008
+ function installArgs(pkg = PACKAGE) {
3009
+ return ["install", "-g", "--prefer-online", `${pkg}@latest`];
3010
+ }
2996
3011
  async function updateCommand(context) {
2997
3012
  const manager = installer();
2998
3013
  if (!manager) {
@@ -3001,19 +3016,38 @@ async function updateCommand(context) {
3001
3016
  );
3002
3017
  return 1;
3003
3018
  }
3019
+ const before = versionOf(manager);
3004
3020
  context.print(`Installing the newest ${PACKAGE}\u2026`);
3005
- const result = spawnSync(manager, ["install", "-g", `${PACKAGE}@latest`], {
3006
- stdio: "inherit"
3007
- });
3021
+ const result = spawnSync(manager, installArgs(), { stdio: "inherit" });
3008
3022
  if (result.status !== 0) {
3009
3023
  context.error(
3010
- "That did not work. If it failed on permissions, do NOT re-run it with sudo \u2014\npoint npm at a directory you own instead:\n npm config set prefix ~/.npm-global\n export PATH=$HOME/.npm-global/bin:$PATH"
3024
+ 'That did not work.\n\nIf npm said ETARGET or "no matching version", its cached list of versions is\nstale. Clear it and try again:\n npm cache clean --force\n\nIf it failed on permissions, do NOT re-run it with sudo \u2014 point npm at a\ndirectory you own instead:\n npm config set prefix ~/.npm-global\n export PATH=$HOME/.npm-global/bin:$PATH'
3011
3025
  );
3012
3026
  return result.status ?? 1;
3013
3027
  }
3014
- context.print("Done. `pm --version` will show the new one.");
3028
+ const after = versionOf(manager);
3029
+ if (after && before && after === before) {
3030
+ context.print(
3031
+ `npm finished, but ${PACKAGE} is still ${after}. That is usually a second copy
3032
+ earlier on your PATH \u2014 check with: which -a pm`
3033
+ );
3034
+ return 1;
3035
+ }
3036
+ context.print(after ? `Done \u2014 now on ${after}.` : "Done.");
3015
3037
  return 0;
3016
3038
  }
3039
+ function versionOf(manager) {
3040
+ const result = spawnSync(manager, ["ls", "-g", "--depth", "0", "--json", PACKAGE], {
3041
+ encoding: "utf8"
3042
+ });
3043
+ if (result.status !== 0 || !result.stdout) return void 0;
3044
+ try {
3045
+ const parsed = JSON.parse(result.stdout);
3046
+ return parsed.dependencies?.[PACKAGE]?.version;
3047
+ } catch {
3048
+ return void 0;
3049
+ }
3050
+ }
3017
3051
  async function uninstallCommand(context) {
3018
3052
  const manager = installer();
3019
3053
  if (!manager) {