@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 +76 -18
- package/dist/bin.js.map +3 -3
- package/dist/index.js +76 -18
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
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
|
|
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
|
|
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 ??
|
|
2548
|
-
|
|
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") ??
|
|
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
|
|
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 (
|
|
2761
|
+
if (existsSync5(target)) {
|
|
2714
2762
|
context.error(`${target} already exists. Pass --output to write somewhere else.`);
|
|
2715
2763
|
return 1;
|
|
2716
2764
|
}
|
|
2717
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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);
|