@persistmemory/cli 0.3.1 → 0.3.2
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 +44 -162
- package/dist/bin.js.map +4 -4
- package/dist/index.js +44 -162
- 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.2" : 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);
|