@persistmemory/cli 0.2.2 → 0.3.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/index.js CHANGED
@@ -1525,7 +1525,7 @@ function shortDate(iso) {
1525
1525
  }
1526
1526
 
1527
1527
  // src/help.ts
1528
- var VERSION = true ? "0.2.2" : versionFromManifest();
1528
+ var VERSION = true ? "0.3.0" : versionFromManifest();
1529
1529
  var PACKAGE = "@persistmemory/cli";
1530
1530
  var HELP = `
1531
1531
  pm \u2014 PersistMemory from your terminal
@@ -1546,8 +1546,6 @@ var HELP = `
1546
1546
  auth login sign in through the browser
1547
1547
  auth login --api-key sign in with a key, for CI and headless machines
1548
1548
 
1549
- agent --root <dir> answer file requests from your assistants,
1550
- reading only inside the folders you name
1551
1549
  auth status who am I, and does the server still accept it
1552
1550
  auth logout forget the stored credential
1553
1551
 
@@ -1559,12 +1557,23 @@ var HELP = `
1559
1557
  setup --new-space "Acme" create one and use it
1560
1558
 
1561
1559
  spaces list your Spaces
1562
- spaces create <name> make a new one
1560
+ spaces create "Acme" make a new one
1561
+ spaces delete "Acme" --memories keep|delete
1562
+ delete one \u2014 you must say what happens
1563
+ to what is in it
1564
+ spaces merge "A" "B" --name "C" a new Space holding both, originals kept
1563
1565
 
1564
1566
  remember <text> capture text
1565
1567
  remember - capture whatever is piped in
1566
1568
  remember --file <path> capture a file's contents
1567
1569
 
1570
+ agent --root <dir> [--root ...] answer file requests from this machine \u2014
1571
+ nothing outside those folders is read.
1572
+ It stays in the foreground. Background it,
1573
+ and stop it later, with:
1574
+ nohup pm agent --root ~/Desktop &
1575
+ pkill -f "pm agent"
1576
+
1568
1577
  search <query> search your memory
1569
1578
  list memories the most recent memories
1570
1579
  list spaces your Spaces
@@ -2095,14 +2104,18 @@ async function currentCredential(resolved, deps) {
2095
2104
 
2096
2105
  // src/context.ts
2097
2106
  import { createInterface } from "node:readline";
2098
- async function askOnTty(prompt) {
2107
+ async function askOnTty(prompt, input = process.stdin, output = process.stdout) {
2099
2108
  return new Promise((resolve8) => {
2100
- const readline = createInterface({ input: process.stdin, output: process.stdout });
2109
+ const readline = createInterface({ input, output });
2110
+ let answered = false;
2101
2111
  readline.question(prompt, (answer3) => {
2102
- readline.close();
2112
+ answered = true;
2103
2113
  resolve8(answer3.trim());
2114
+ readline.close();
2115
+ });
2116
+ readline.once("close", () => {
2117
+ if (!answered) resolve8("");
2104
2118
  });
2105
- readline.once("close", () => resolve8(""));
2106
2119
  });
2107
2120
  }
2108
2121
  var ETX = "";
@@ -2113,11 +2126,15 @@ async function readSecretFromTty(prompt) {
2113
2126
  if (!input.isTTY) {
2114
2127
  return new Promise((resolve8) => {
2115
2128
  const readline = createInterface({ input });
2129
+ let answered = false;
2116
2130
  readline.once("line", (line) => {
2117
- readline.close();
2131
+ answered = true;
2118
2132
  resolve8(line.trim());
2133
+ readline.close();
2134
+ });
2135
+ readline.once("close", () => {
2136
+ if (!answered) resolve8("");
2119
2137
  });
2120
- readline.once("close", () => resolve8(""));
2121
2138
  });
2122
2139
  }
2123
2140
  process.stdout.write(prompt);
@@ -2439,7 +2456,14 @@ async function agentCommand(context) {
2439
2456
  context.error(
2440
2457
  "Say which folders this machine may read from, and nothing outside them will be:"
2441
2458
  );
2442
- context.error(" pm agent --root ~/notes --root ~/projects");
2459
+ context.error("");
2460
+ context.error(" pm agent --root ~/Desktop --root ~/Documents");
2461
+ context.error("");
2462
+ context.error("It stays in the foreground. To leave it running:");
2463
+ context.error("");
2464
+ context.error(" nohup pm agent --root ~/Desktop > ~/agent.log 2>&1 &");
2465
+ context.error("");
2466
+ context.error('And to stop it later: pkill -f "pm agent"');
2443
2467
  return 1;
2444
2468
  }
2445
2469
  for (const root of roots) {
@@ -3705,6 +3729,67 @@ var spaceFields = [
3705
3729
  { header: "name", value: (s) => s.name },
3706
3730
  { header: "kind", value: (s) => s.kind }
3707
3731
  ];
3732
+ async function deleteSpaceCommand(context) {
3733
+ const named = context.args.words.slice(2).join(" ").trim();
3734
+ if (named === "") {
3735
+ context.error('Which Space? Try `pm spaces delete "Acme" --memories keep`.');
3736
+ return 2;
3737
+ }
3738
+ const memories = stringFlag(context.args, "memories");
3739
+ if (memories !== "keep" && memories !== "delete") {
3740
+ context.error("Say what happens to what is in it \u2014 there is no default:");
3741
+ context.error("");
3742
+ context.error(` pm spaces delete "${named}" --memories keep the memories survive`);
3743
+ context.error(` pm spaces delete "${named}" --memories delete they go with it`);
3744
+ return 2;
3745
+ }
3746
+ const client = await context.client();
3747
+ const { data } = await client.spaces.list({ limit: 200 }).first();
3748
+ const found = named.startsWith("space_") ? data.find((one) => one.id === named) : data.find((one) => one.name.toLowerCase() === named.toLowerCase());
3749
+ if (!found) {
3750
+ context.error(`No Space called "${named}". Run \`pm spaces list\` to see them.`);
3751
+ return 1;
3752
+ }
3753
+ const result = await client.spaces.delete(found.id, { memories });
3754
+ if (context.flags.output !== "table") {
3755
+ context.print(JSON.stringify({ id: found.id, ...result }, void 0, 2));
3756
+ return 0;
3757
+ }
3758
+ context.print(`Deleted "${found.name}".`);
3759
+ context.print(` ${result.deleted} memories deleted, ${result.kept} kept`);
3760
+ return 0;
3761
+ }
3762
+ async function mergeSpacesCommand(context) {
3763
+ const named = context.args.words.slice(2);
3764
+ const name = stringFlag(context.args, "name");
3765
+ if (named.length < 2 || !name) {
3766
+ context.error("Two or more Spaces, and a name for the one this makes:");
3767
+ context.error("");
3768
+ context.error(' pm spaces merge "Work" "Personal" --name "Everything"');
3769
+ return 2;
3770
+ }
3771
+ const client = await context.client();
3772
+ const { data } = await client.spaces.list({ limit: 200 }).first();
3773
+ const ids = [];
3774
+ for (const one of named) {
3775
+ const found = one.startsWith("space_") ? data.find((space2) => space2.id === one) : data.find((space2) => space2.name.toLowerCase() === one.toLowerCase());
3776
+ if (!found) {
3777
+ context.error(`No Space called "${one}". Run \`pm spaces list\` to see them.`);
3778
+ return 1;
3779
+ }
3780
+ ids.push(found.id);
3781
+ }
3782
+ const { space, added } = await client.spaces.merge({ sourceIds: ids, name });
3783
+ if (context.flags.output !== "table") {
3784
+ context.print(renderOne(space, spaceFields, { format: context.flags.output }));
3785
+ return 0;
3786
+ }
3787
+ context.print(`Created "${space.name}" from ${ids.length} Spaces, holding ${added} memories.`);
3788
+ context.print(` id ${space.id}`);
3789
+ context.print("");
3790
+ context.print("The Spaces it drew from are unchanged \u2014 nothing was moved or deleted.");
3791
+ return 0;
3792
+ }
3708
3793
 
3709
3794
  // src/index.ts
3710
3795
  async function run(deps) {
@@ -3860,8 +3945,10 @@ async function dispatch(context) {
3860
3945
  case "spaces":
3861
3946
  case "space":
3862
3947
  if (noun === "create" || noun === "new") return createSpaceCommand(context);
3948
+ if (noun === "delete" || noun === "remove") return deleteSpaceCommand(context);
3949
+ if (noun === "merge") return mergeSpacesCommand(context);
3863
3950
  if (noun === void 0 || noun === "list") return listSpacesCommand(context);
3864
- context.error(`Cannot "pm spaces ${noun}". Try list or create.`);
3951
+ context.error(`Cannot "pm spaces ${noun}". Try list, create, delete or merge.`);
3865
3952
  return 2;
3866
3953
  case "list":
3867
3954
  if (noun === "memories" || noun === "memory") return listMemoriesCommand(context);