@ours.network/cli 1.0.1 → 2.0.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/README.md +16 -4
- package/dist/{boot-35BOHNSZ.js → boot-LJ2V4NSS.js} +1 -1
- package/dist/{chunk-ZFE47KH3.js → chunk-FKSRG5UJ.js} +3 -3
- package/dist/{chunk-MHVYJY3H.js → chunk-LJ35FDQH.js} +1500 -1023
- package/dist/{chunk-QRNZFPNJ.js → chunk-MS4TDUZY.js} +41 -42
- package/dist/{chunk-QZIL3IT7.js → chunk-NRPPG3WH.js} +1 -1
- package/dist/{chunk-SDNTPCKW.js → chunk-NWRXKQBD.js} +10 -12
- package/dist/commands.d.ts +10 -12
- package/dist/commands.js +1 -1
- package/dist/{daemon-UUG6P6GK.js → daemon-YCC24SVU.js} +2 -2
- package/dist/help.js +3 -3
- package/dist/lifecycle.js +1 -1
- package/dist/main.js +5 -5
- package/dist/mufl_code/{7962BB01B1D3E782A1F80B083A900AEC30BAC8F8CE79282B31821802B94A39B6.muflo → 351F16D444E6DAA252D4A8D829D17204360D9015FEF670ACE68FB4747BB3B14E.muflo} +0 -0
- package/dist/operations.d.ts +32 -57
- package/dist/operations.js +1 -1
- package/dist/{server-TDJBEWTU.js → server-2RIEOKDA.js} +198 -145
- package/package.json +3 -2
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
appendNotifyLog,
|
|
12
12
|
bindSession,
|
|
13
13
|
bootWrapper,
|
|
14
|
-
buildMessagesPayload,
|
|
15
14
|
capabilityReconcileSweep,
|
|
16
15
|
clearNotifyHook,
|
|
17
16
|
closeTemporaryIdentity,
|
|
18
17
|
clusterSweep,
|
|
18
|
+
consumeOutboundHistoryFailure,
|
|
19
19
|
contactRestoreSweep,
|
|
20
20
|
decodeWireBin,
|
|
21
21
|
delegateRole,
|
|
@@ -27,13 +27,18 @@ import {
|
|
|
27
27
|
establishRoot,
|
|
28
28
|
exportAdBlob,
|
|
29
29
|
findIdentityFile,
|
|
30
|
+
getFileHistoryItem,
|
|
31
|
+
getMessageHistoryItem,
|
|
30
32
|
hashLeaseToken,
|
|
31
33
|
identities,
|
|
32
34
|
isSelectableWireId,
|
|
33
35
|
leaseByToken,
|
|
34
36
|
leases,
|
|
37
|
+
listFileHistory,
|
|
38
|
+
listIncomingFiles,
|
|
39
|
+
listIncomingMessages,
|
|
40
|
+
listMessageHistory,
|
|
35
41
|
log,
|
|
36
|
-
mimeFromExt,
|
|
37
42
|
mutatingTx,
|
|
38
43
|
outboundRemovalInFlight,
|
|
39
44
|
persistBindings,
|
|
@@ -41,16 +46,13 @@ import {
|
|
|
41
46
|
provisionIdentity,
|
|
42
47
|
publishToBook,
|
|
43
48
|
readBook,
|
|
44
|
-
readE2eWireIds,
|
|
45
49
|
readonlyTx,
|
|
46
50
|
refreshUnread,
|
|
47
51
|
registrar,
|
|
48
52
|
renderContactRoots,
|
|
49
53
|
renderContacts,
|
|
50
54
|
renderDegraded,
|
|
51
|
-
renderFileMetadata,
|
|
52
55
|
renderImportRenames,
|
|
53
|
-
renderInbox,
|
|
54
56
|
renderPending,
|
|
55
57
|
requireAuth,
|
|
56
58
|
reservedNames,
|
|
@@ -62,16 +64,21 @@ import {
|
|
|
62
64
|
sessionHeaders,
|
|
63
65
|
setNotifyHook,
|
|
64
66
|
startupProgress,
|
|
67
|
+
structuredVoiceOutcome,
|
|
68
|
+
sttStatus,
|
|
65
69
|
sweepStaleTempIdentities,
|
|
70
|
+
takeUnreadFiles,
|
|
71
|
+
takeUnreadMessages,
|
|
66
72
|
tombstones,
|
|
73
|
+
transcribeVoice,
|
|
67
74
|
unpublishFromBook,
|
|
68
75
|
unreadSummary,
|
|
69
76
|
validateName,
|
|
77
|
+
voiceDeliveryLine,
|
|
70
78
|
withScope,
|
|
71
79
|
withScopeAsync,
|
|
72
|
-
writeIncomingFiles,
|
|
73
80
|
writeTempMetaFile
|
|
74
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-LJ35FDQH.js";
|
|
75
82
|
import {
|
|
76
83
|
buildIdentityFile,
|
|
77
84
|
writeIdentityFile
|
|
@@ -96,13 +103,6 @@ function startGcTimer() {
|
|
|
96
103
|
void (async () => {
|
|
97
104
|
try {
|
|
98
105
|
for (const id of identities.values()) {
|
|
99
|
-
try {
|
|
100
|
-
await withScopeAsync(async (lt) => {
|
|
101
|
-
await mutatingTx(id, "::actor::gc", {}, lt);
|
|
102
|
-
});
|
|
103
|
-
} catch (e) {
|
|
104
|
-
log(`gc(${id.name}) failed:`, String(e));
|
|
105
|
-
}
|
|
106
106
|
await contactRestoreSweep(id);
|
|
107
107
|
await capabilityReconcileSweep(id);
|
|
108
108
|
await e2eRecoverySweep(id);
|
|
@@ -113,7 +113,7 @@ function startGcTimer() {
|
|
|
113
113
|
})();
|
|
114
114
|
}, GC_INTERVAL_MS);
|
|
115
115
|
gcTimer.unref?.();
|
|
116
|
-
log(`
|
|
116
|
+
log(`protocol maintenance timer armed (every ${GC_INTERVAL_MS}ms)`);
|
|
117
117
|
}
|
|
118
118
|
function stopGcTimer() {
|
|
119
119
|
if (gcTimer) {
|
|
@@ -989,7 +989,37 @@ async function respondToIntroduction(ctx, a) {
|
|
|
989
989
|
|
|
990
990
|
// ../../src/api/messaging.ts
|
|
991
991
|
import { readFile } from "node:fs/promises";
|
|
992
|
-
import { basename as
|
|
992
|
+
import { basename as basename3 } from "node:path";
|
|
993
|
+
|
|
994
|
+
// ../../src/files.ts
|
|
995
|
+
import { basename as basename2, extname } from "node:path";
|
|
996
|
+
var FILE_MIME = {
|
|
997
|
+
".png": "image/png",
|
|
998
|
+
".jpg": "image/jpeg",
|
|
999
|
+
".jpeg": "image/jpeg",
|
|
1000
|
+
".gif": "image/gif",
|
|
1001
|
+
".webp": "image/webp",
|
|
1002
|
+
".svg": "image/svg+xml",
|
|
1003
|
+
".bmp": "image/bmp",
|
|
1004
|
+
".ico": "image/x-icon",
|
|
1005
|
+
".pdf": "application/pdf",
|
|
1006
|
+
".txt": "text/plain",
|
|
1007
|
+
".md": "text/markdown",
|
|
1008
|
+
".json": "application/json",
|
|
1009
|
+
".csv": "text/csv",
|
|
1010
|
+
".html": "text/html",
|
|
1011
|
+
".xml": "application/xml",
|
|
1012
|
+
".zip": "application/zip",
|
|
1013
|
+
".gz": "application/gzip",
|
|
1014
|
+
".tar": "application/x-tar",
|
|
1015
|
+
".mp3": "audio/mpeg",
|
|
1016
|
+
".wav": "audio/wav",
|
|
1017
|
+
".mp4": "video/mp4",
|
|
1018
|
+
".mov": "video/quicktime"
|
|
1019
|
+
};
|
|
1020
|
+
function mimeFromExt(p) {
|
|
1021
|
+
return FILE_MIME[extname(p).toLowerCase()] ?? "application/octet-stream";
|
|
1022
|
+
}
|
|
993
1023
|
|
|
994
1024
|
// ../../src/messaging/send.ts
|
|
995
1025
|
function findSibling(id, contact) {
|
|
@@ -1001,15 +1031,19 @@ function findSibling(id, contact) {
|
|
|
1001
1031
|
}
|
|
1002
1032
|
async function sendViaSibling(id, target, text) {
|
|
1003
1033
|
const targetAd = exportAdBlob(target);
|
|
1004
|
-
await withScopeAsync(async (lt) => {
|
|
1005
|
-
await mutatingTx(id, "::actor::connect_sibling", {
|
|
1034
|
+
const wireId = await withScopeAsync(async (lt) => {
|
|
1035
|
+
const result = await mutatingTx(id, "::actor::connect_sibling", {
|
|
1006
1036
|
name: target.name,
|
|
1007
1037
|
target_ad: id.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt),
|
|
1008
1038
|
text
|
|
1009
1039
|
}, lt);
|
|
1040
|
+
return result.Reduce("wire_id").Visualize();
|
|
1010
1041
|
});
|
|
1011
1042
|
scheduleCapabilityReconcile(id);
|
|
1012
|
-
return
|
|
1043
|
+
return {
|
|
1044
|
+
text: `"${target.name}" was not a contact yet \u2014 connected as an intra-root sibling (delegation-cert auto-accept) and delivered the message.`,
|
|
1045
|
+
wireId
|
|
1046
|
+
};
|
|
1013
1047
|
}
|
|
1014
1048
|
async function sendViaLocalBook(id, contact, text) {
|
|
1015
1049
|
if (!registrar) {
|
|
@@ -1028,22 +1062,26 @@ async function sendViaLocalBook(id, contact, text) {
|
|
|
1028
1062
|
const targetAd = Buffer.from(entry.address_document, "base64url");
|
|
1029
1063
|
const entrySig = Buffer.from(entry.registrar_sig, "base64url");
|
|
1030
1064
|
const joinerAd = exportAdBlob(id);
|
|
1031
|
-
await withScopeAsync(async (lt) => {
|
|
1065
|
+
const wireId = await withScopeAsync(async (lt) => {
|
|
1032
1066
|
const minted = await mutatingTx(registrar, "::actor::mint_introduction", {
|
|
1033
1067
|
joiner_ad: registrar.pw.packet.NewBinaryFromBuffer(joinerAd).Attach(lt),
|
|
1034
1068
|
target_ad: registrar.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt)
|
|
1035
1069
|
}, lt);
|
|
1036
1070
|
const introBlob = Buffer.from(minted.Reduce("intro").GetBinary());
|
|
1037
|
-
await mutatingTx(id, "::actor::connect_local", {
|
|
1071
|
+
const result = await mutatingTx(id, "::actor::connect_local", {
|
|
1038
1072
|
name: entry.name,
|
|
1039
1073
|
target_ad: id.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt),
|
|
1040
1074
|
intro: id.pw.packet.NewBinaryFromBuffer(introBlob).Attach(lt),
|
|
1041
1075
|
entry_sig: id.pw.packet.NewBinaryFromBuffer(entrySig).Attach(lt),
|
|
1042
1076
|
text
|
|
1043
1077
|
}, lt);
|
|
1078
|
+
return result.Reduce("wire_id").Visualize();
|
|
1044
1079
|
});
|
|
1045
1080
|
scheduleCapabilityReconcile(id);
|
|
1046
|
-
return
|
|
1081
|
+
return {
|
|
1082
|
+
text: `"${entry.name}" was not a contact yet \u2014 connected via the local contact book and sent the message with the introduction. If "${entry.name}" requires approval for local introductions, delivery completes once they approve.`,
|
|
1083
|
+
wireId
|
|
1084
|
+
};
|
|
1047
1085
|
}
|
|
1048
1086
|
var parseSendVerdict = (sent) => {
|
|
1049
1087
|
const has = (f) => !sent.Reduce(f).IsNil();
|
|
@@ -1090,6 +1128,14 @@ async function sendMessage(ctx, a) {
|
|
|
1090
1128
|
default:
|
|
1091
1129
|
break;
|
|
1092
1130
|
}
|
|
1131
|
+
if (v.kind === "sent" || v.kind === "e2e") {
|
|
1132
|
+
return {
|
|
1133
|
+
...v,
|
|
1134
|
+
sent: true,
|
|
1135
|
+
wire_id: v.wireId,
|
|
1136
|
+
history_stored: !consumeOutboundHistoryFailure(id, v.wireId)
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1093
1139
|
return v;
|
|
1094
1140
|
} catch (e) {
|
|
1095
1141
|
if (!/Unknown contact/.test(String(e))) {
|
|
@@ -1098,7 +1144,14 @@ async function sendMessage(ctx, a) {
|
|
|
1098
1144
|
try {
|
|
1099
1145
|
const sibling = findSibling(id, contact);
|
|
1100
1146
|
const sent = sibling ? await sendViaSibling(id, sibling, text) : await sendViaLocalBook(id, contact, text);
|
|
1101
|
-
return {
|
|
1147
|
+
return {
|
|
1148
|
+
kind: "introduced",
|
|
1149
|
+
text: sent.text,
|
|
1150
|
+
wireId: sent.wireId,
|
|
1151
|
+
wire_id: sent.wireId,
|
|
1152
|
+
sent: true,
|
|
1153
|
+
history_stored: !consumeOutboundHistoryFailure(id, sent.wireId)
|
|
1154
|
+
};
|
|
1102
1155
|
} catch (e2) {
|
|
1103
1156
|
throw errTool("send_message", String(e2), "FALLBACK_FAILED");
|
|
1104
1157
|
}
|
|
@@ -1116,7 +1169,7 @@ async function sendFile(ctx, a) {
|
|
|
1116
1169
|
try {
|
|
1117
1170
|
if (path) {
|
|
1118
1171
|
buf = await readFile(path);
|
|
1119
|
-
fname = filename ??
|
|
1172
|
+
fname = filename ?? basename3(path);
|
|
1120
1173
|
} else if (upload_id) {
|
|
1121
1174
|
const got = consumeStagedUpload(id, upload_id);
|
|
1122
1175
|
if (!got) throw errUploadNotFound(upload_id);
|
|
@@ -1195,53 +1248,68 @@ async function sendFile(ctx, a) {
|
|
|
1195
1248
|
default:
|
|
1196
1249
|
break;
|
|
1197
1250
|
}
|
|
1251
|
+
if (v.kind === "sent" || v.kind === "e2e") {
|
|
1252
|
+
return {
|
|
1253
|
+
...v,
|
|
1254
|
+
filename: fname,
|
|
1255
|
+
bytes: buf.length,
|
|
1256
|
+
mime: mt,
|
|
1257
|
+
sent: true,
|
|
1258
|
+
wire_id: v.wireId,
|
|
1259
|
+
history_stored: !consumeOutboundHistoryFailure(id, v.wireId)
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1198
1262
|
return { ...v, filename: fname, bytes: buf.length, mime: mt };
|
|
1199
1263
|
} catch (e) {
|
|
1200
1264
|
throw errTool("send_file", String(e));
|
|
1201
1265
|
}
|
|
1202
1266
|
}
|
|
1203
|
-
async function
|
|
1267
|
+
async function listIncomingMessages2(ctx) {
|
|
1204
1268
|
const id = requireBound(ctx);
|
|
1205
1269
|
try {
|
|
1206
|
-
return
|
|
1270
|
+
return listIncomingMessages(id);
|
|
1207
1271
|
} catch (e) {
|
|
1208
1272
|
throw errTool("list_incoming_messages", String(e));
|
|
1209
1273
|
}
|
|
1210
1274
|
}
|
|
1211
|
-
async function getMessages(ctx) {
|
|
1275
|
+
async function getMessages(ctx, input = {}) {
|
|
1212
1276
|
const id = requireBound(ctx);
|
|
1213
1277
|
try {
|
|
1214
|
-
const fresh =
|
|
1215
|
-
const data = await mutatingTx(id, "::actor::get_messages", {}, lt);
|
|
1216
|
-
return renderInbox(data.Reduce("messages"));
|
|
1217
|
-
});
|
|
1278
|
+
const fresh = takeUnreadMessages(id, input);
|
|
1218
1279
|
refreshUnread(id);
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1280
|
+
const bySender = /* @__PURE__ */ new Map();
|
|
1281
|
+
for (const message of fresh.messages) {
|
|
1282
|
+
let wireIds = bySender.get(message.from.id);
|
|
1283
|
+
if (!wireIds) {
|
|
1284
|
+
wireIds = [];
|
|
1285
|
+
bySender.set(message.from.id, wireIds);
|
|
1286
|
+
}
|
|
1287
|
+
wireIds.push(message.wire_id);
|
|
1288
|
+
}
|
|
1289
|
+
for (const [senderId, wireIds] of bySender) {
|
|
1290
|
+
try {
|
|
1291
|
+
await withScopeAsync(async (lt) => {
|
|
1292
|
+
await mutatingTx(id, "::actor::send_read_receipts", {
|
|
1293
|
+
sender_id: senderId,
|
|
1294
|
+
wire_ids: wireIds
|
|
1295
|
+
}, lt);
|
|
1296
|
+
});
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
log(`[${id.name}] read-receipt attempt failed sender_id=${senderId} count=${wireIds.length}:`, String(error));
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
return fresh;
|
|
1221
1302
|
} catch (e) {
|
|
1222
1303
|
throw errTool("get_messages", String(e));
|
|
1223
1304
|
}
|
|
1224
1305
|
}
|
|
1225
|
-
async function deferMessages(ctx, a) {
|
|
1226
|
-
const id = requireBound(ctx);
|
|
1227
|
-
const { msg_ids } = a;
|
|
1228
|
-
try {
|
|
1229
|
-
const n = await withScopeAsync(async (lt) => {
|
|
1230
|
-
const data = await mutatingTx(id, "::actor::defer_messages", { msg_ids }, lt);
|
|
1231
|
-
return data.Reduce("deferred").Visualize();
|
|
1232
|
-
});
|
|
1233
|
-
refreshUnread(id);
|
|
1234
|
-
return { deferred: n };
|
|
1235
|
-
} catch (e) {
|
|
1236
|
-
throw errTool("defer_messages", String(e));
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
1306
|
|
|
1240
1307
|
// ../../src/api/files.ts
|
|
1241
|
-
|
|
1308
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
1309
|
+
async function listIncomingFiles2(ctx) {
|
|
1242
1310
|
const id = requireBound(ctx);
|
|
1243
1311
|
try {
|
|
1244
|
-
return
|
|
1312
|
+
return listIncomingFiles(id);
|
|
1245
1313
|
} catch (e) {
|
|
1246
1314
|
throw errTool("list_incoming_files", String(e));
|
|
1247
1315
|
}
|
|
@@ -1257,18 +1325,66 @@ async function getFiles(ctx, a = {}) {
|
|
|
1257
1325
|
if (new Set(wire_ids).size !== wire_ids.length) throw errDuplicateId();
|
|
1258
1326
|
}
|
|
1259
1327
|
try {
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1328
|
+
const selected = takeUnreadFiles(id, { wire_ids, limit: a.limit });
|
|
1329
|
+
const files = [];
|
|
1330
|
+
const lines = [];
|
|
1331
|
+
for (const file of selected.files) {
|
|
1332
|
+
const base = {
|
|
1333
|
+
file_id: file.file_id,
|
|
1334
|
+
wire_id: file.wire_id,
|
|
1335
|
+
from: file.from,
|
|
1336
|
+
filename: file.filename,
|
|
1337
|
+
path: file.blob_path,
|
|
1338
|
+
mime: file.mime,
|
|
1339
|
+
size: file.byte_length,
|
|
1340
|
+
sha256: file.sha256,
|
|
1341
|
+
status: "processed",
|
|
1342
|
+
date: file.date,
|
|
1343
|
+
kind: file.kind,
|
|
1344
|
+
sender: file.from.name
|
|
1345
|
+
};
|
|
1346
|
+
if (file.kind === "voice_message") {
|
|
1347
|
+
const st = sttStatus(CONFIG.stt);
|
|
1348
|
+
let outcome;
|
|
1349
|
+
if (!st.ready) outcome = { kind: "unconfigured", reason: st.reason };
|
|
1350
|
+
else {
|
|
1351
|
+
try {
|
|
1352
|
+
const result = await transcribeVoice(
|
|
1353
|
+
await readFile2(file.blob_path),
|
|
1354
|
+
file.filename,
|
|
1355
|
+
file.mime,
|
|
1356
|
+
CONFIG.stt
|
|
1357
|
+
);
|
|
1358
|
+
outcome = result.ok ? { kind: "transcript", text: result.text } : { kind: "failed", error: result.error };
|
|
1359
|
+
} catch (error) {
|
|
1360
|
+
outcome = { kind: "failed", error: error instanceof Error ? error.message : String(error) };
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
base.transcription = structuredVoiceOutcome(st, outcome, {
|
|
1364
|
+
audioPath: file.blob_path,
|
|
1365
|
+
wireId: file.wire_id
|
|
1366
|
+
});
|
|
1367
|
+
lines.push(voiceDeliveryLine({
|
|
1368
|
+
sender: file.from.name,
|
|
1369
|
+
wire: file.wire_id,
|
|
1370
|
+
savedPath: file.blob_path,
|
|
1371
|
+
sizeBytes: file.byte_length
|
|
1372
|
+
}, outcome));
|
|
1373
|
+
} else {
|
|
1374
|
+
lines.push(
|
|
1375
|
+
` \u2022 ${file.filename} (${file.mime}, ${file.byte_length} B, sha256 ${file.sha256}) from ${file.from.name} \u2192 ${file.blob_path} {${file.wire_id}}`
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
files.push(base);
|
|
1379
|
+
}
|
|
1264
1380
|
refreshUnread(id);
|
|
1265
1381
|
return {
|
|
1266
|
-
files
|
|
1267
|
-
|
|
1268
|
-
|
|
1382
|
+
files,
|
|
1383
|
+
text: lines.length === 0 ? "No new files." : `${lines.length} new file(s) available from immutable identity blob storage (bytes stay on disk, never in this result):
|
|
1384
|
+
${lines.join("\n")}`,
|
|
1269
1385
|
mode: wire_ids === void 0 ? "all_unread" : "selected",
|
|
1270
|
-
|
|
1271
|
-
|
|
1386
|
+
requested: wire_ids ?? null,
|
|
1387
|
+
remaining: selected.remaining
|
|
1272
1388
|
};
|
|
1273
1389
|
} catch (e) {
|
|
1274
1390
|
const message = String(e);
|
|
@@ -1282,20 +1398,6 @@ function saveFileFallbackNotice(ctx, a) {
|
|
|
1282
1398
|
const id = requireBound(ctx);
|
|
1283
1399
|
return { existsOnDisk: findIdentityFile(id, a.wire_id) !== null };
|
|
1284
1400
|
}
|
|
1285
|
-
async function deferFiles(ctx, a) {
|
|
1286
|
-
const id = requireBound(ctx);
|
|
1287
|
-
const { file_ids } = a;
|
|
1288
|
-
try {
|
|
1289
|
-
const n = await withScopeAsync(async (lt) => {
|
|
1290
|
-
const data = await mutatingTx(id, "::actor::defer_files", { file_ids }, lt);
|
|
1291
|
-
return data.Reduce("deferred").Visualize();
|
|
1292
|
-
});
|
|
1293
|
-
refreshUnread(id);
|
|
1294
|
-
return { deferred: n };
|
|
1295
|
-
} catch (e) {
|
|
1296
|
-
throw errTool("defer_files", String(e));
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
1401
|
|
|
1300
1402
|
// ../../src/api/profile.ts
|
|
1301
1403
|
async function setBio2(ctx, a) {
|
|
@@ -1363,82 +1465,37 @@ async function readvertiseOnUpgrade(ctx) {
|
|
|
1363
1465
|
}
|
|
1364
1466
|
}
|
|
1365
1467
|
|
|
1366
|
-
// ../../src/api/
|
|
1367
|
-
function
|
|
1368
|
-
const out = [];
|
|
1369
|
-
const msgs = av.Reduce("messages");
|
|
1370
|
-
if (msgs.IsNil()) return out;
|
|
1371
|
-
for (let i = 0; ; i++) {
|
|
1372
|
-
const m = msgs.Reduce(i);
|
|
1373
|
-
if (m.IsNil()) break;
|
|
1374
|
-
const wire = m.Reduce("wire_id");
|
|
1375
|
-
const receipt = m.Reduce("receipt");
|
|
1376
|
-
out.push({
|
|
1377
|
-
dir: m.Reduce("dir").Visualize() === "out" ? "out" : "in",
|
|
1378
|
-
text: m.Reduce("text").Visualize(),
|
|
1379
|
-
date: m.Reduce("date").Visualize(),
|
|
1380
|
-
// GetBoolean, never Visualize: a MUFL boolean visualizes as '%%TRUE',
|
|
1381
|
-
// never 'TRUE' — the G4 trap from wire-handlers, one layer up.
|
|
1382
|
-
read: m.Reduce("read").GetBoolean(),
|
|
1383
|
-
wire_id: wire.IsNil() ? "" : wire.Visualize(),
|
|
1384
|
-
receipt: receipt.IsNil() ? null : receipt.Visualize()
|
|
1385
|
-
});
|
|
1386
|
-
}
|
|
1387
|
-
return out;
|
|
1388
|
-
}
|
|
1389
|
-
async function getConversation(ctx, a) {
|
|
1468
|
+
// ../../src/api/history.ts
|
|
1469
|
+
function listHistory(ctx, query = {}) {
|
|
1390
1470
|
const id = requireBound(ctx);
|
|
1391
1471
|
try {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
);
|
|
1395
|
-
return { contact: a.contact, messages };
|
|
1396
|
-
} catch (e) {
|
|
1397
|
-
throw errTool("get_conversation", String(e));
|
|
1472
|
+
return listMessageHistory(id, query);
|
|
1473
|
+
} catch (error) {
|
|
1474
|
+
throw errTool("list_history", String(error));
|
|
1398
1475
|
}
|
|
1399
1476
|
}
|
|
1400
|
-
|
|
1477
|
+
function getHistoryItem(ctx, input) {
|
|
1401
1478
|
const id = requireBound(ctx);
|
|
1402
1479
|
try {
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
if (av.IsNil()) return out;
|
|
1407
|
-
for (const key of av.GetKeys()) {
|
|
1408
|
-
const wid = key.Visualize();
|
|
1409
|
-
out[wid] = av.Reduce(wid).Visualize();
|
|
1410
|
-
}
|
|
1411
|
-
return out;
|
|
1412
|
-
});
|
|
1413
|
-
return { contact: a.contact, receipts };
|
|
1414
|
-
} catch (e) {
|
|
1415
|
-
throw errTool("get_receipts", String(e));
|
|
1480
|
+
return getMessageHistoryItem(id, input.wire_id);
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
throw errTool("get_history_item", String(error));
|
|
1416
1483
|
}
|
|
1417
1484
|
}
|
|
1418
|
-
|
|
1485
|
+
function listFiles(ctx, query = {}) {
|
|
1419
1486
|
const id = requireBound(ctx);
|
|
1420
1487
|
try {
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
});
|
|
1425
|
-
return { contact: a.contact, marked };
|
|
1426
|
-
} catch (e) {
|
|
1427
|
-
throw errTool("mark_read", String(e));
|
|
1488
|
+
return listFileHistory(id, query);
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
throw errTool("list_files", String(error));
|
|
1428
1491
|
}
|
|
1429
1492
|
}
|
|
1430
|
-
|
|
1493
|
+
function getFileInfo(ctx, input) {
|
|
1431
1494
|
const id = requireBound(ctx);
|
|
1432
1495
|
try {
|
|
1433
|
-
return
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
keepHistory: data.Reduce("keep_history").GetBoolean(),
|
|
1437
|
-
autoAccept: data.Reduce("auto_accept").GetBoolean()
|
|
1438
|
-
};
|
|
1439
|
-
});
|
|
1440
|
-
} catch (e) {
|
|
1441
|
-
throw errTool("set_local_policy", String(e));
|
|
1496
|
+
return getFileHistoryItem(id, input.wire_id);
|
|
1497
|
+
} catch (error) {
|
|
1498
|
+
throw errTool("get_file_info", String(error));
|
|
1442
1499
|
}
|
|
1443
1500
|
}
|
|
1444
1501
|
|
|
@@ -1478,18 +1535,14 @@ var API_OPERATIONS = {
|
|
|
1478
1535
|
// ----- messaging (Task 12) -------------------------------------------------
|
|
1479
1536
|
sendMessage: op(sendMessage),
|
|
1480
1537
|
sendFile: op(sendFile),
|
|
1481
|
-
listIncomingMessages: op0(
|
|
1482
|
-
getMessages:
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
getConversation: op(getConversation),
|
|
1488
|
-
getReceipts: op(getReceipts),
|
|
1489
|
-
markRead: op(markRead),
|
|
1490
|
-
setConversationPolicy: op(setConversationPolicy),
|
|
1538
|
+
listIncomingMessages: op0(listIncomingMessages2),
|
|
1539
|
+
getMessages: op(getMessages),
|
|
1540
|
+
listHistory: op(listHistory),
|
|
1541
|
+
getHistoryItem: op(getHistoryItem),
|
|
1542
|
+
listFiles: op(listFiles),
|
|
1543
|
+
getFileInfo: op(getFileInfo),
|
|
1491
1544
|
// ----- files (Task 12) -----------------------------------------------------
|
|
1492
|
-
listIncomingFiles: op0(
|
|
1545
|
+
listIncomingFiles: op0(listIncomingFiles2),
|
|
1493
1546
|
getFiles: op(getFiles),
|
|
1494
1547
|
saveFileFallbackNotice: op(saveFileFallbackNotice)
|
|
1495
1548
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Transport-neutral operator CLI for the ours shared daemon",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@adapt-toolkit/sdk": "0.10.12",
|
|
27
27
|
"@adapt-toolkit/sdk-native": "0.10.12",
|
|
28
|
-
"@ours.network/sdk": "^
|
|
28
|
+
"@ours.network/sdk": "^3.0.0",
|
|
29
|
+
"better-sqlite3": "^11.10.0"
|
|
29
30
|
}
|
|
30
31
|
}
|