@persistmemory/cli 0.3.1 → 0.3.3
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 +71 -167
- package/dist/bin.js.map +4 -4
- package/dist/index.js +71 -167
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// node_modules/@persistmemory/sdk/dist/index.js
|
|
2
2
|
function encodeQuery(params) {
|
|
3
3
|
if (!params) return "";
|
|
4
4
|
const search = new URLSearchParams();
|
|
@@ -232,27 +232,6 @@ var HttpClient = class {
|
|
|
232
232
|
...options ? { options } : {}
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
|
-
/** POST with a file as the body. The type describes the bytes, not JSON. */
|
|
236
|
-
async postBytes(path, bytes, contentType, query, options) {
|
|
237
|
-
return this.#request({
|
|
238
|
-
method: "POST",
|
|
239
|
-
path,
|
|
240
|
-
rawBody: bytes,
|
|
241
|
-
contentType,
|
|
242
|
-
...query ? { query } : {},
|
|
243
|
-
...options ? { options } : {}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
/** GET that returns bytes rather than JSON, for downloading a file. */
|
|
247
|
-
async getBytes(path, query, options) {
|
|
248
|
-
return this.#request({
|
|
249
|
-
method: "GET",
|
|
250
|
-
path,
|
|
251
|
-
rawResponse: true,
|
|
252
|
-
...query ? { query } : {},
|
|
253
|
-
...options ? { options } : {}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
235
|
async patch(path, body, options) {
|
|
257
236
|
return this.#request({
|
|
258
237
|
method: "PATCH",
|
|
@@ -305,20 +284,11 @@ var HttpClient = class {
|
|
|
305
284
|
this.#fetch(url, {
|
|
306
285
|
method: request.method,
|
|
307
286
|
headers: this.#headers(request),
|
|
308
|
-
...request.
|
|
287
|
+
...request.body !== void 0 ? { body: JSON.stringify(request.body) } : {},
|
|
309
288
|
signal: deadline.signal
|
|
310
289
|
}),
|
|
311
290
|
deadline.signal
|
|
312
291
|
);
|
|
313
|
-
if (request.rawResponse && response.ok) {
|
|
314
|
-
const disposition = response.headers.get("content-disposition") ?? "";
|
|
315
|
-
const named = /filename="([^"]+)"/.exec(disposition)?.[1];
|
|
316
|
-
return {
|
|
317
|
-
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
318
|
-
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
319
|
-
...named ? { filename: named } : {}
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
292
|
const payload = await readBody(response);
|
|
323
293
|
if (!response.ok) throw errorFromResponse(response.status, payload, response.headers);
|
|
324
294
|
return payload;
|
|
@@ -339,11 +309,9 @@ var HttpClient = class {
|
|
|
339
309
|
return {
|
|
340
310
|
// The only place the key is ever read.
|
|
341
311
|
authorization: `Bearer ${this.#apiKey}`,
|
|
342
|
-
|
|
343
|
-
// than a promise to accept only JSON that the server would have to break.
|
|
344
|
-
accept: request.rawResponse ? "*/*" : "application/json",
|
|
312
|
+
accept: "application/json",
|
|
345
313
|
"user-agent": this.#userAgent,
|
|
346
|
-
...request.
|
|
314
|
+
...request.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
347
315
|
...request.options?.idempotencyKey ? { "idempotency-key": request.options.idempotencyKey } : {}
|
|
348
316
|
};
|
|
349
317
|
}
|
|
@@ -920,119 +888,6 @@ var Conversations = class {
|
|
|
920
888
|
);
|
|
921
889
|
}
|
|
922
890
|
};
|
|
923
|
-
var Google = class {
|
|
924
|
-
#http;
|
|
925
|
-
constructor(http) {
|
|
926
|
-
this.#http = http;
|
|
927
|
-
}
|
|
928
|
-
/** Files by name, newest first. Omit the query for recently changed ones. */
|
|
929
|
-
async searchDrive(params = {}, options) {
|
|
930
|
-
return this.#http.get(
|
|
931
|
-
"/api/v1/google/drive/files",
|
|
932
|
-
{
|
|
933
|
-
...params.query !== void 0 ? { query: params.query } : {},
|
|
934
|
-
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
935
|
-
},
|
|
936
|
-
options
|
|
937
|
-
);
|
|
938
|
-
}
|
|
939
|
-
async getDriveFile(fileId, options) {
|
|
940
|
-
return this.#http.get(
|
|
941
|
-
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}`,
|
|
942
|
-
void 0,
|
|
943
|
-
options
|
|
944
|
-
);
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* The bytes of a Drive file.
|
|
948
|
-
*
|
|
949
|
-
* A Google Doc, Sheet or Slide holds no bytes of its own and is exported on
|
|
950
|
-
* the way - a document as PDF, a spreadsheet as CSV - so `filename` comes
|
|
951
|
-
* back describing what it BECAME. Writing it under the id instead produces a
|
|
952
|
-
* file nothing will open.
|
|
953
|
-
*/
|
|
954
|
-
async downloadDriveFile(fileId, options) {
|
|
955
|
-
return this.#http.getBytes(
|
|
956
|
-
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}/content`,
|
|
957
|
-
void 0,
|
|
958
|
-
options
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
/**
|
|
962
|
-
* Writes a file into the user's Drive.
|
|
963
|
-
*
|
|
964
|
-
* Needs one of the Drive write permissions on their connection. A read-only
|
|
965
|
-
* grant is refused by Google, and the error names the missing permission
|
|
966
|
-
* rather than reporting a failed upload - one is fixed with a checkbox and
|
|
967
|
-
* the other sends somebody looking for a bug.
|
|
968
|
-
*/
|
|
969
|
-
async saveToDrive(params, options) {
|
|
970
|
-
return this.#http.postBytes(
|
|
971
|
-
"/api/v1/google/drive/files",
|
|
972
|
-
params.bytes,
|
|
973
|
-
params.contentType ?? "application/octet-stream",
|
|
974
|
-
{
|
|
975
|
-
name: params.name,
|
|
976
|
-
...params.folderId !== void 0 ? { folderId: params.folderId } : {}
|
|
977
|
-
},
|
|
978
|
-
options
|
|
979
|
-
);
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Recent messages - senders, subjects and a one-line preview, never bodies.
|
|
983
|
-
*
|
|
984
|
-
* `query` is Gmail's own syntax passed through as written: `from:priya`,
|
|
985
|
-
* `has:attachment`, `newer_than:7d`. It selects within the connected mailbox
|
|
986
|
-
* and cannot reach another one.
|
|
987
|
-
*/
|
|
988
|
-
async searchMail(params = {}, options) {
|
|
989
|
-
return this.#http.get(
|
|
990
|
-
"/api/v1/google/mail",
|
|
991
|
-
{
|
|
992
|
-
...params.query !== void 0 ? { query: params.query } : {},
|
|
993
|
-
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
994
|
-
},
|
|
995
|
-
options
|
|
996
|
-
);
|
|
997
|
-
}
|
|
998
|
-
/** One message, with its body and the names of what is attached. */
|
|
999
|
-
async readMail(messageId, options) {
|
|
1000
|
-
return this.#http.get(
|
|
1001
|
-
`/api/v1/google/mail/${encodeURIComponent(messageId)}`,
|
|
1002
|
-
void 0,
|
|
1003
|
-
options
|
|
1004
|
-
);
|
|
1005
|
-
}
|
|
1006
|
-
/**
|
|
1007
|
-
* The bytes of one attachment.
|
|
1008
|
-
*
|
|
1009
|
-
* Separate from `readMail` so listing a mailbox never drags attachments
|
|
1010
|
-
* across the network: a message with a 40 MB deck should not cost 40 MB to
|
|
1011
|
-
* summarise.
|
|
1012
|
-
*/
|
|
1013
|
-
async downloadAttachment(messageId, attachmentId, options) {
|
|
1014
|
-
return this.#http.getBytes(
|
|
1015
|
-
`/api/v1/google/mail/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`,
|
|
1016
|
-
void 0,
|
|
1017
|
-
options
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
/** Sends as the connected account. Needs the send permission. */
|
|
1021
|
-
async sendMail(params, options) {
|
|
1022
|
-
return this.#http.post("/api/v1/google/mail/send", params, options);
|
|
1023
|
-
}
|
|
1024
|
-
/** People in the user's contacts. Omit the query to list them. */
|
|
1025
|
-
async contacts(params = {}, options) {
|
|
1026
|
-
return this.#http.get(
|
|
1027
|
-
"/api/v1/google/contacts",
|
|
1028
|
-
{
|
|
1029
|
-
...params.query !== void 0 ? { query: params.query } : {},
|
|
1030
|
-
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
1031
|
-
},
|
|
1032
|
-
options
|
|
1033
|
-
);
|
|
1034
|
-
}
|
|
1035
|
-
};
|
|
1036
891
|
var Integrations = class {
|
|
1037
892
|
#http;
|
|
1038
893
|
constructor(http) {
|
|
@@ -1163,8 +1018,6 @@ var PersistMemory = class {
|
|
|
1163
1018
|
conflicts;
|
|
1164
1019
|
conversations;
|
|
1165
1020
|
integrations;
|
|
1166
|
-
/** Drive, mail and contacts on the user's connected Google account. */
|
|
1167
|
-
google;
|
|
1168
1021
|
health;
|
|
1169
1022
|
agent;
|
|
1170
1023
|
#http;
|
|
@@ -1181,7 +1034,6 @@ var PersistMemory = class {
|
|
|
1181
1034
|
this.conflicts = new Conflicts(this.#http);
|
|
1182
1035
|
this.conversations = new Conversations(this.#http);
|
|
1183
1036
|
this.integrations = new Integrations(this.#http);
|
|
1184
|
-
this.google = new Google(this.#http);
|
|
1185
1037
|
this.health = new Health(this.#http);
|
|
1186
1038
|
this.agent = new Agent(this.#http);
|
|
1187
1039
|
}
|
|
@@ -1212,6 +1064,14 @@ function parseArgs(argv) {
|
|
|
1212
1064
|
const words = [];
|
|
1213
1065
|
const flags = {};
|
|
1214
1066
|
const rest = [];
|
|
1067
|
+
const set = (name, value) => {
|
|
1068
|
+
const held = flags[name];
|
|
1069
|
+
if (typeof value === "boolean" || held === void 0 || typeof held === "boolean") {
|
|
1070
|
+
flags[name] = value;
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
flags[name] = typeof held === "string" ? [held, value] : [...held, value];
|
|
1074
|
+
};
|
|
1215
1075
|
let index = 0;
|
|
1216
1076
|
while (index < argv.length) {
|
|
1217
1077
|
const token = argv[index];
|
|
@@ -1223,22 +1083,22 @@ function parseArgs(argv) {
|
|
|
1223
1083
|
const body = token.slice(2);
|
|
1224
1084
|
const equals = body.indexOf("=");
|
|
1225
1085
|
if (equals !== -1) {
|
|
1226
|
-
|
|
1086
|
+
set(body.slice(0, equals), body.slice(equals + 1));
|
|
1227
1087
|
index += 1;
|
|
1228
1088
|
continue;
|
|
1229
1089
|
}
|
|
1230
1090
|
if (body.startsWith("no-")) {
|
|
1231
|
-
|
|
1091
|
+
set(body.slice(3), false);
|
|
1232
1092
|
index += 1;
|
|
1233
1093
|
continue;
|
|
1234
1094
|
}
|
|
1235
1095
|
const next = argv[index + 1];
|
|
1236
1096
|
if (next !== void 0 && !next.startsWith("-")) {
|
|
1237
|
-
|
|
1097
|
+
set(body, next);
|
|
1238
1098
|
index += 2;
|
|
1239
1099
|
continue;
|
|
1240
1100
|
}
|
|
1241
|
-
|
|
1101
|
+
set(body, true);
|
|
1242
1102
|
index += 1;
|
|
1243
1103
|
continue;
|
|
1244
1104
|
}
|
|
@@ -1246,11 +1106,11 @@ function parseArgs(argv) {
|
|
|
1246
1106
|
const body = token.slice(1);
|
|
1247
1107
|
const next = argv[index + 1];
|
|
1248
1108
|
if (next !== void 0 && !next.startsWith("-")) {
|
|
1249
|
-
|
|
1109
|
+
set(body, next);
|
|
1250
1110
|
index += 2;
|
|
1251
1111
|
continue;
|
|
1252
1112
|
}
|
|
1253
|
-
|
|
1113
|
+
set(body, true);
|
|
1254
1114
|
index += 1;
|
|
1255
1115
|
continue;
|
|
1256
1116
|
}
|
|
@@ -1263,12 +1123,14 @@ function stringFlag(args, ...names) {
|
|
|
1263
1123
|
for (const name of names) {
|
|
1264
1124
|
const value = args.flags[name];
|
|
1265
1125
|
if (typeof value === "string") return value;
|
|
1126
|
+
if (Array.isArray(value) && value.length > 0) return value[value.length - 1];
|
|
1266
1127
|
}
|
|
1267
1128
|
return void 0;
|
|
1268
1129
|
}
|
|
1269
1130
|
function boolFlag(args, ...names) {
|
|
1270
1131
|
for (const name of names) {
|
|
1271
1132
|
const value = args.flags[name];
|
|
1133
|
+
if (Array.isArray(value)) continue;
|
|
1272
1134
|
if (typeof value === "boolean") return value;
|
|
1273
1135
|
if (value === "true") return true;
|
|
1274
1136
|
if (value === "false") return false;
|
|
@@ -1279,6 +1141,13 @@ function numberFlag(args, ...names) {
|
|
|
1279
1141
|
for (const name of names) {
|
|
1280
1142
|
const value = args.flags[name];
|
|
1281
1143
|
if (value === void 0 || typeof value === "boolean") continue;
|
|
1144
|
+
if (Array.isArray(value)) {
|
|
1145
|
+
const last = value[value.length - 1];
|
|
1146
|
+
if (last === void 0) continue;
|
|
1147
|
+
const parsed2 = Number(last);
|
|
1148
|
+
if (!Number.isFinite(parsed2)) return "invalid";
|
|
1149
|
+
return parsed2;
|
|
1150
|
+
}
|
|
1282
1151
|
const parsed = Number(value);
|
|
1283
1152
|
if (!Number.isFinite(parsed)) return "invalid";
|
|
1284
1153
|
return parsed;
|
|
@@ -1286,9 +1155,17 @@ function numberFlag(args, ...names) {
|
|
|
1286
1155
|
return void 0;
|
|
1287
1156
|
}
|
|
1288
1157
|
function listFlag(args, ...names) {
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1291
|
-
|
|
1158
|
+
const items = [];
|
|
1159
|
+
for (const name of names) {
|
|
1160
|
+
const value = args.flags[name];
|
|
1161
|
+
if (value === void 0 || typeof value === "boolean") continue;
|
|
1162
|
+
for (const one of Array.isArray(value) ? value : [value]) {
|
|
1163
|
+
for (const part of one.split(",")) {
|
|
1164
|
+
const trimmed = part.trim();
|
|
1165
|
+
if (trimmed.length > 0) items.push(trimmed);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1292
1169
|
return items.length > 0 ? items : void 0;
|
|
1293
1170
|
}
|
|
1294
1171
|
|
|
@@ -1525,7 +1402,7 @@ function shortDate(iso) {
|
|
|
1525
1402
|
}
|
|
1526
1403
|
|
|
1527
1404
|
// src/help.ts
|
|
1528
|
-
var VERSION = true ? "0.3.
|
|
1405
|
+
var VERSION = true ? "0.3.3" : versionFromManifest();
|
|
1529
1406
|
var PACKAGE = "@persistmemory/cli";
|
|
1530
1407
|
var HELP = `
|
|
1531
1408
|
pm \u2014 PersistMemory from your terminal
|
|
@@ -2303,6 +2180,11 @@ async function said(response, fallback) {
|
|
|
2303
2180
|
}
|
|
2304
2181
|
function locate(roots, requested) {
|
|
2305
2182
|
const expanded = requested.startsWith("~") ? resolve3(homedir2(), requested.slice(1).replace(/^[/\\]/, "")) : requested;
|
|
2183
|
+
if (!expanded.includes("/") && !expanded.includes("\\")) {
|
|
2184
|
+
const wanted2 = expanded.trim().toLowerCase();
|
|
2185
|
+
const named = roots.find((root) => basename(root).toLowerCase() === wanted2);
|
|
2186
|
+
if (named) return within(named, named);
|
|
2187
|
+
}
|
|
2306
2188
|
for (const root of roots) {
|
|
2307
2189
|
try {
|
|
2308
2190
|
return within(root, expanded);
|
|
@@ -3109,6 +2991,9 @@ import { existsSync as existsSync7, rmSync } from "node:fs";
|
|
|
3109
2991
|
import { spawnSync } from "node:child_process";
|
|
3110
2992
|
import { dirname as dirname4, resolve as resolve7 } from "node:path";
|
|
3111
2993
|
import { fileURLToPath } from "node:url";
|
|
2994
|
+
function installArgs(pkg = PACKAGE) {
|
|
2995
|
+
return ["install", "-g", "--prefer-online", `${pkg}@latest`];
|
|
2996
|
+
}
|
|
3112
2997
|
async function updateCommand(context) {
|
|
3113
2998
|
const manager = installer();
|
|
3114
2999
|
if (!manager) {
|
|
@@ -3117,19 +3002,38 @@ async function updateCommand(context) {
|
|
|
3117
3002
|
);
|
|
3118
3003
|
return 1;
|
|
3119
3004
|
}
|
|
3005
|
+
const before = versionOf(manager);
|
|
3120
3006
|
context.print(`Installing the newest ${PACKAGE}\u2026`);
|
|
3121
|
-
const result = spawnSync(manager,
|
|
3122
|
-
stdio: "inherit"
|
|
3123
|
-
});
|
|
3007
|
+
const result = spawnSync(manager, installArgs(), { stdio: "inherit" });
|
|
3124
3008
|
if (result.status !== 0) {
|
|
3125
3009
|
context.error(
|
|
3126
|
-
|
|
3010
|
+
'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'
|
|
3127
3011
|
);
|
|
3128
3012
|
return result.status ?? 1;
|
|
3129
3013
|
}
|
|
3130
|
-
|
|
3014
|
+
const after = versionOf(manager);
|
|
3015
|
+
if (after && before && after === before) {
|
|
3016
|
+
context.print(
|
|
3017
|
+
`npm finished, but ${PACKAGE} is still ${after}. That is usually a second copy
|
|
3018
|
+
earlier on your PATH \u2014 check with: which -a pm`
|
|
3019
|
+
);
|
|
3020
|
+
return 1;
|
|
3021
|
+
}
|
|
3022
|
+
context.print(after ? `Done \u2014 now on ${after}.` : "Done.");
|
|
3131
3023
|
return 0;
|
|
3132
3024
|
}
|
|
3025
|
+
function versionOf(manager) {
|
|
3026
|
+
const result = spawnSync(manager, ["ls", "-g", "--depth", "0", "--json", PACKAGE], {
|
|
3027
|
+
encoding: "utf8"
|
|
3028
|
+
});
|
|
3029
|
+
if (result.status !== 0 || !result.stdout) return void 0;
|
|
3030
|
+
try {
|
|
3031
|
+
const parsed = JSON.parse(result.stdout);
|
|
3032
|
+
return parsed.dependencies?.[PACKAGE]?.version;
|
|
3033
|
+
} catch {
|
|
3034
|
+
return void 0;
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3133
3037
|
async function uninstallCommand(context) {
|
|
3134
3038
|
const manager = installer();
|
|
3135
3039
|
if (!manager) {
|