@ours.network/cli 1.0.1 → 2.0.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/README.md +21 -8
- package/dist/{boot-35BOHNSZ.js → boot-Y3GXCN6X.js} +1 -1
- package/dist/{chunk-QZIL3IT7.js → chunk-DTN7MN44.js} +29 -12
- package/dist/{chunk-MHVYJY3H.js → chunk-IL724CY2.js} +1517 -1013
- package/dist/{chunk-QRNZFPNJ.js → chunk-MS4TDUZY.js} +41 -42
- package/dist/{chunk-TNNBVUKK.js → chunk-NBAZ2NEL.js} +2 -2
- package/dist/{chunk-SDNTPCKW.js → chunk-VA6UQKYN.js} +16 -18
- package/dist/{chunk-ZFE47KH3.js → chunk-VFAC74XR.js} +4 -4
- package/dist/commands.d.ts +16 -18
- package/dist/commands.js +1 -1
- package/dist/{daemon-UUG6P6GK.js → daemon-A2L6UMGZ.js} +2 -2
- package/dist/help.js +3 -3
- package/dist/lifecycle.d.ts +3 -0
- package/dist/lifecycle.js +5 -1
- package/dist/main.js +6 -6
- 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-6BZCHN6Q.js} +206 -143
- package/dist/service.js +1 -1
- 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,19 @@ import {
|
|
|
27
27
|
establishRoot,
|
|
28
28
|
exportAdBlob,
|
|
29
29
|
findIdentityFile,
|
|
30
|
+
getFileHistoryItem,
|
|
31
|
+
getMessageHistoryItem,
|
|
32
|
+
getMessageHistorySummary,
|
|
30
33
|
hashLeaseToken,
|
|
31
34
|
identities,
|
|
32
35
|
isSelectableWireId,
|
|
33
36
|
leaseByToken,
|
|
34
37
|
leases,
|
|
38
|
+
listFileHistory,
|
|
39
|
+
listIncomingFiles,
|
|
40
|
+
listIncomingMessages,
|
|
41
|
+
listMessageHistory,
|
|
35
42
|
log,
|
|
36
|
-
mimeFromExt,
|
|
37
43
|
mutatingTx,
|
|
38
44
|
outboundRemovalInFlight,
|
|
39
45
|
persistBindings,
|
|
@@ -41,16 +47,13 @@ import {
|
|
|
41
47
|
provisionIdentity,
|
|
42
48
|
publishToBook,
|
|
43
49
|
readBook,
|
|
44
|
-
readE2eWireIds,
|
|
45
50
|
readonlyTx,
|
|
46
51
|
refreshUnread,
|
|
47
52
|
registrar,
|
|
48
53
|
renderContactRoots,
|
|
49
54
|
renderContacts,
|
|
50
55
|
renderDegraded,
|
|
51
|
-
renderFileMetadata,
|
|
52
56
|
renderImportRenames,
|
|
53
|
-
renderInbox,
|
|
54
57
|
renderPending,
|
|
55
58
|
requireAuth,
|
|
56
59
|
reservedNames,
|
|
@@ -62,16 +65,21 @@ import {
|
|
|
62
65
|
sessionHeaders,
|
|
63
66
|
setNotifyHook,
|
|
64
67
|
startupProgress,
|
|
68
|
+
structuredVoiceOutcome,
|
|
69
|
+
sttStatus,
|
|
65
70
|
sweepStaleTempIdentities,
|
|
71
|
+
takeUnreadFiles,
|
|
72
|
+
takeUnreadMessages,
|
|
66
73
|
tombstones,
|
|
74
|
+
transcribeVoice,
|
|
67
75
|
unpublishFromBook,
|
|
68
76
|
unreadSummary,
|
|
69
77
|
validateName,
|
|
78
|
+
voiceDeliveryLine,
|
|
70
79
|
withScope,
|
|
71
80
|
withScopeAsync,
|
|
72
|
-
writeIncomingFiles,
|
|
73
81
|
writeTempMetaFile
|
|
74
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-IL724CY2.js";
|
|
75
83
|
import {
|
|
76
84
|
buildIdentityFile,
|
|
77
85
|
writeIdentityFile
|
|
@@ -96,13 +104,6 @@ function startGcTimer() {
|
|
|
96
104
|
void (async () => {
|
|
97
105
|
try {
|
|
98
106
|
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
107
|
await contactRestoreSweep(id);
|
|
107
108
|
await capabilityReconcileSweep(id);
|
|
108
109
|
await e2eRecoverySweep(id);
|
|
@@ -113,7 +114,7 @@ function startGcTimer() {
|
|
|
113
114
|
})();
|
|
114
115
|
}, GC_INTERVAL_MS);
|
|
115
116
|
gcTimer.unref?.();
|
|
116
|
-
log(`
|
|
117
|
+
log(`protocol maintenance timer armed (every ${GC_INTERVAL_MS}ms)`);
|
|
117
118
|
}
|
|
118
119
|
function stopGcTimer() {
|
|
119
120
|
if (gcTimer) {
|
|
@@ -989,7 +990,37 @@ async function respondToIntroduction(ctx, a) {
|
|
|
989
990
|
|
|
990
991
|
// ../../src/api/messaging.ts
|
|
991
992
|
import { readFile } from "node:fs/promises";
|
|
992
|
-
import { basename as
|
|
993
|
+
import { basename as basename3 } from "node:path";
|
|
994
|
+
|
|
995
|
+
// ../../src/files.ts
|
|
996
|
+
import { basename as basename2, extname } from "node:path";
|
|
997
|
+
var FILE_MIME = {
|
|
998
|
+
".png": "image/png",
|
|
999
|
+
".jpg": "image/jpeg",
|
|
1000
|
+
".jpeg": "image/jpeg",
|
|
1001
|
+
".gif": "image/gif",
|
|
1002
|
+
".webp": "image/webp",
|
|
1003
|
+
".svg": "image/svg+xml",
|
|
1004
|
+
".bmp": "image/bmp",
|
|
1005
|
+
".ico": "image/x-icon",
|
|
1006
|
+
".pdf": "application/pdf",
|
|
1007
|
+
".txt": "text/plain",
|
|
1008
|
+
".md": "text/markdown",
|
|
1009
|
+
".json": "application/json",
|
|
1010
|
+
".csv": "text/csv",
|
|
1011
|
+
".html": "text/html",
|
|
1012
|
+
".xml": "application/xml",
|
|
1013
|
+
".zip": "application/zip",
|
|
1014
|
+
".gz": "application/gzip",
|
|
1015
|
+
".tar": "application/x-tar",
|
|
1016
|
+
".mp3": "audio/mpeg",
|
|
1017
|
+
".wav": "audio/wav",
|
|
1018
|
+
".mp4": "video/mp4",
|
|
1019
|
+
".mov": "video/quicktime"
|
|
1020
|
+
};
|
|
1021
|
+
function mimeFromExt(p) {
|
|
1022
|
+
return FILE_MIME[extname(p).toLowerCase()] ?? "application/octet-stream";
|
|
1023
|
+
}
|
|
993
1024
|
|
|
994
1025
|
// ../../src/messaging/send.ts
|
|
995
1026
|
function findSibling(id, contact) {
|
|
@@ -1001,15 +1032,19 @@ function findSibling(id, contact) {
|
|
|
1001
1032
|
}
|
|
1002
1033
|
async function sendViaSibling(id, target, text) {
|
|
1003
1034
|
const targetAd = exportAdBlob(target);
|
|
1004
|
-
await withScopeAsync(async (lt) => {
|
|
1005
|
-
await mutatingTx(id, "::actor::connect_sibling", {
|
|
1035
|
+
const wireId = await withScopeAsync(async (lt) => {
|
|
1036
|
+
const result = await mutatingTx(id, "::actor::connect_sibling", {
|
|
1006
1037
|
name: target.name,
|
|
1007
1038
|
target_ad: id.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt),
|
|
1008
1039
|
text
|
|
1009
1040
|
}, lt);
|
|
1041
|
+
return result.Reduce("wire_id").Visualize();
|
|
1010
1042
|
});
|
|
1011
1043
|
scheduleCapabilityReconcile(id);
|
|
1012
|
-
return
|
|
1044
|
+
return {
|
|
1045
|
+
text: `"${target.name}" was not a contact yet \u2014 connected as an intra-root sibling (delegation-cert auto-accept) and delivered the message.`,
|
|
1046
|
+
wireId
|
|
1047
|
+
};
|
|
1013
1048
|
}
|
|
1014
1049
|
async function sendViaLocalBook(id, contact, text) {
|
|
1015
1050
|
if (!registrar) {
|
|
@@ -1028,22 +1063,26 @@ async function sendViaLocalBook(id, contact, text) {
|
|
|
1028
1063
|
const targetAd = Buffer.from(entry.address_document, "base64url");
|
|
1029
1064
|
const entrySig = Buffer.from(entry.registrar_sig, "base64url");
|
|
1030
1065
|
const joinerAd = exportAdBlob(id);
|
|
1031
|
-
await withScopeAsync(async (lt) => {
|
|
1066
|
+
const wireId = await withScopeAsync(async (lt) => {
|
|
1032
1067
|
const minted = await mutatingTx(registrar, "::actor::mint_introduction", {
|
|
1033
1068
|
joiner_ad: registrar.pw.packet.NewBinaryFromBuffer(joinerAd).Attach(lt),
|
|
1034
1069
|
target_ad: registrar.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt)
|
|
1035
1070
|
}, lt);
|
|
1036
1071
|
const introBlob = Buffer.from(minted.Reduce("intro").GetBinary());
|
|
1037
|
-
await mutatingTx(id, "::actor::connect_local", {
|
|
1072
|
+
const result = await mutatingTx(id, "::actor::connect_local", {
|
|
1038
1073
|
name: entry.name,
|
|
1039
1074
|
target_ad: id.pw.packet.NewBinaryFromBuffer(targetAd).Attach(lt),
|
|
1040
1075
|
intro: id.pw.packet.NewBinaryFromBuffer(introBlob).Attach(lt),
|
|
1041
1076
|
entry_sig: id.pw.packet.NewBinaryFromBuffer(entrySig).Attach(lt),
|
|
1042
1077
|
text
|
|
1043
1078
|
}, lt);
|
|
1079
|
+
return result.Reduce("wire_id").Visualize();
|
|
1044
1080
|
});
|
|
1045
1081
|
scheduleCapabilityReconcile(id);
|
|
1046
|
-
return
|
|
1082
|
+
return {
|
|
1083
|
+
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.`,
|
|
1084
|
+
wireId
|
|
1085
|
+
};
|
|
1047
1086
|
}
|
|
1048
1087
|
var parseSendVerdict = (sent) => {
|
|
1049
1088
|
const has = (f) => !sent.Reduce(f).IsNil();
|
|
@@ -1090,6 +1129,14 @@ async function sendMessage(ctx, a) {
|
|
|
1090
1129
|
default:
|
|
1091
1130
|
break;
|
|
1092
1131
|
}
|
|
1132
|
+
if (v.kind === "sent" || v.kind === "e2e") {
|
|
1133
|
+
return {
|
|
1134
|
+
...v,
|
|
1135
|
+
sent: true,
|
|
1136
|
+
wire_id: v.wireId,
|
|
1137
|
+
history_stored: !consumeOutboundHistoryFailure(id, v.wireId)
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1093
1140
|
return v;
|
|
1094
1141
|
} catch (e) {
|
|
1095
1142
|
if (!/Unknown contact/.test(String(e))) {
|
|
@@ -1098,7 +1145,14 @@ async function sendMessage(ctx, a) {
|
|
|
1098
1145
|
try {
|
|
1099
1146
|
const sibling = findSibling(id, contact);
|
|
1100
1147
|
const sent = sibling ? await sendViaSibling(id, sibling, text) : await sendViaLocalBook(id, contact, text);
|
|
1101
|
-
return {
|
|
1148
|
+
return {
|
|
1149
|
+
kind: "introduced",
|
|
1150
|
+
text: sent.text,
|
|
1151
|
+
wireId: sent.wireId,
|
|
1152
|
+
wire_id: sent.wireId,
|
|
1153
|
+
sent: true,
|
|
1154
|
+
history_stored: !consumeOutboundHistoryFailure(id, sent.wireId)
|
|
1155
|
+
};
|
|
1102
1156
|
} catch (e2) {
|
|
1103
1157
|
throw errTool("send_message", String(e2), "FALLBACK_FAILED");
|
|
1104
1158
|
}
|
|
@@ -1116,7 +1170,7 @@ async function sendFile(ctx, a) {
|
|
|
1116
1170
|
try {
|
|
1117
1171
|
if (path) {
|
|
1118
1172
|
buf = await readFile(path);
|
|
1119
|
-
fname = filename ??
|
|
1173
|
+
fname = filename ?? basename3(path);
|
|
1120
1174
|
} else if (upload_id) {
|
|
1121
1175
|
const got = consumeStagedUpload(id, upload_id);
|
|
1122
1176
|
if (!got) throw errUploadNotFound(upload_id);
|
|
@@ -1195,53 +1249,68 @@ async function sendFile(ctx, a) {
|
|
|
1195
1249
|
default:
|
|
1196
1250
|
break;
|
|
1197
1251
|
}
|
|
1252
|
+
if (v.kind === "sent" || v.kind === "e2e") {
|
|
1253
|
+
return {
|
|
1254
|
+
...v,
|
|
1255
|
+
filename: fname,
|
|
1256
|
+
bytes: buf.length,
|
|
1257
|
+
mime: mt,
|
|
1258
|
+
sent: true,
|
|
1259
|
+
wire_id: v.wireId,
|
|
1260
|
+
history_stored: !consumeOutboundHistoryFailure(id, v.wireId)
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1198
1263
|
return { ...v, filename: fname, bytes: buf.length, mime: mt };
|
|
1199
1264
|
} catch (e) {
|
|
1200
1265
|
throw errTool("send_file", String(e));
|
|
1201
1266
|
}
|
|
1202
1267
|
}
|
|
1203
|
-
async function
|
|
1268
|
+
async function listIncomingMessages2(ctx) {
|
|
1204
1269
|
const id = requireBound(ctx);
|
|
1205
1270
|
try {
|
|
1206
|
-
return
|
|
1271
|
+
return listIncomingMessages(id);
|
|
1207
1272
|
} catch (e) {
|
|
1208
1273
|
throw errTool("list_incoming_messages", String(e));
|
|
1209
1274
|
}
|
|
1210
1275
|
}
|
|
1211
|
-
async function getMessages(ctx) {
|
|
1276
|
+
async function getMessages(ctx, input = {}) {
|
|
1212
1277
|
const id = requireBound(ctx);
|
|
1213
1278
|
try {
|
|
1214
|
-
const fresh =
|
|
1215
|
-
const data = await mutatingTx(id, "::actor::get_messages", {}, lt);
|
|
1216
|
-
return renderInbox(data.Reduce("messages"));
|
|
1217
|
-
});
|
|
1279
|
+
const fresh = takeUnreadMessages(id, input);
|
|
1218
1280
|
refreshUnread(id);
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1281
|
+
const bySender = /* @__PURE__ */ new Map();
|
|
1282
|
+
for (const message of fresh.messages) {
|
|
1283
|
+
let wireIds = bySender.get(message.from.id);
|
|
1284
|
+
if (!wireIds) {
|
|
1285
|
+
wireIds = [];
|
|
1286
|
+
bySender.set(message.from.id, wireIds);
|
|
1287
|
+
}
|
|
1288
|
+
wireIds.push(message.wire_id);
|
|
1289
|
+
}
|
|
1290
|
+
for (const [senderId, wireIds] of bySender) {
|
|
1291
|
+
try {
|
|
1292
|
+
await withScopeAsync(async (lt) => {
|
|
1293
|
+
await mutatingTx(id, "::actor::send_read_receipts", {
|
|
1294
|
+
sender_id: senderId,
|
|
1295
|
+
wire_ids: wireIds
|
|
1296
|
+
}, lt);
|
|
1297
|
+
});
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
log(`[${id.name}] read-receipt attempt failed sender_id=${senderId} count=${wireIds.length}:`, String(error));
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return fresh;
|
|
1221
1303
|
} catch (e) {
|
|
1222
1304
|
throw errTool("get_messages", String(e));
|
|
1223
1305
|
}
|
|
1224
1306
|
}
|
|
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
1307
|
|
|
1240
1308
|
// ../../src/api/files.ts
|
|
1241
|
-
|
|
1309
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
1310
|
+
async function listIncomingFiles2(ctx) {
|
|
1242
1311
|
const id = requireBound(ctx);
|
|
1243
1312
|
try {
|
|
1244
|
-
return
|
|
1313
|
+
return listIncomingFiles(id);
|
|
1245
1314
|
} catch (e) {
|
|
1246
1315
|
throw errTool("list_incoming_files", String(e));
|
|
1247
1316
|
}
|
|
@@ -1257,18 +1326,66 @@ async function getFiles(ctx, a = {}) {
|
|
|
1257
1326
|
if (new Set(wire_ids).size !== wire_ids.length) throw errDuplicateId();
|
|
1258
1327
|
}
|
|
1259
1328
|
try {
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1329
|
+
const selected = takeUnreadFiles(id, { wire_ids, limit: a.limit });
|
|
1330
|
+
const files = [];
|
|
1331
|
+
const lines = [];
|
|
1332
|
+
for (const file of selected.files) {
|
|
1333
|
+
const base = {
|
|
1334
|
+
file_id: file.file_id,
|
|
1335
|
+
wire_id: file.wire_id,
|
|
1336
|
+
from: file.from,
|
|
1337
|
+
filename: file.filename,
|
|
1338
|
+
path: file.blob_path,
|
|
1339
|
+
mime: file.mime,
|
|
1340
|
+
size: file.byte_length,
|
|
1341
|
+
sha256: file.sha256,
|
|
1342
|
+
status: "processed",
|
|
1343
|
+
date: file.date,
|
|
1344
|
+
kind: file.kind,
|
|
1345
|
+
sender: file.from.name
|
|
1346
|
+
};
|
|
1347
|
+
if (file.kind === "voice_message") {
|
|
1348
|
+
const st = sttStatus(CONFIG.stt);
|
|
1349
|
+
let outcome;
|
|
1350
|
+
if (!st.ready) outcome = { kind: "unconfigured", reason: st.reason };
|
|
1351
|
+
else {
|
|
1352
|
+
try {
|
|
1353
|
+
const result = await transcribeVoice(
|
|
1354
|
+
await readFile2(file.blob_path),
|
|
1355
|
+
file.filename,
|
|
1356
|
+
file.mime,
|
|
1357
|
+
CONFIG.stt
|
|
1358
|
+
);
|
|
1359
|
+
outcome = result.ok ? { kind: "transcript", text: result.text } : { kind: "failed", error: result.error };
|
|
1360
|
+
} catch (error) {
|
|
1361
|
+
outcome = { kind: "failed", error: error instanceof Error ? error.message : String(error) };
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
base.transcription = structuredVoiceOutcome(st, outcome, {
|
|
1365
|
+
audioPath: file.blob_path,
|
|
1366
|
+
wireId: file.wire_id
|
|
1367
|
+
});
|
|
1368
|
+
lines.push(voiceDeliveryLine({
|
|
1369
|
+
sender: file.from.name,
|
|
1370
|
+
wire: file.wire_id,
|
|
1371
|
+
savedPath: file.blob_path,
|
|
1372
|
+
sizeBytes: file.byte_length
|
|
1373
|
+
}, outcome));
|
|
1374
|
+
} else {
|
|
1375
|
+
lines.push(
|
|
1376
|
+
` \u2022 ${file.filename} (${file.mime}, ${file.byte_length} B, sha256 ${file.sha256}) from ${file.from.name} \u2192 ${file.blob_path} {${file.wire_id}}`
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
files.push(base);
|
|
1380
|
+
}
|
|
1264
1381
|
refreshUnread(id);
|
|
1265
1382
|
return {
|
|
1266
|
-
files
|
|
1267
|
-
|
|
1268
|
-
|
|
1383
|
+
files,
|
|
1384
|
+
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):
|
|
1385
|
+
${lines.join("\n")}`,
|
|
1269
1386
|
mode: wire_ids === void 0 ? "all_unread" : "selected",
|
|
1270
|
-
|
|
1271
|
-
|
|
1387
|
+
requested: wire_ids ?? null,
|
|
1388
|
+
remaining: selected.remaining
|
|
1272
1389
|
};
|
|
1273
1390
|
} catch (e) {
|
|
1274
1391
|
const message = String(e);
|
|
@@ -1282,20 +1399,6 @@ function saveFileFallbackNotice(ctx, a) {
|
|
|
1282
1399
|
const id = requireBound(ctx);
|
|
1283
1400
|
return { existsOnDisk: findIdentityFile(id, a.wire_id) !== null };
|
|
1284
1401
|
}
|
|
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
1402
|
|
|
1300
1403
|
// ../../src/api/profile.ts
|
|
1301
1404
|
async function setBio2(ctx, a) {
|
|
@@ -1363,82 +1466,45 @@ async function readvertiseOnUpgrade(ctx) {
|
|
|
1363
1466
|
}
|
|
1364
1467
|
}
|
|
1365
1468
|
|
|
1366
|
-
// ../../src/api/
|
|
1367
|
-
function
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
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
|
-
});
|
|
1469
|
+
// ../../src/api/history.ts
|
|
1470
|
+
function listHistory(ctx, query = {}) {
|
|
1471
|
+
const id = requireBound(ctx);
|
|
1472
|
+
try {
|
|
1473
|
+
return listMessageHistory(id, query);
|
|
1474
|
+
} catch (error) {
|
|
1475
|
+
throw errTool("list_history", String(error));
|
|
1386
1476
|
}
|
|
1387
|
-
return out;
|
|
1388
1477
|
}
|
|
1389
|
-
|
|
1478
|
+
function getHistoryItem(ctx, input) {
|
|
1390
1479
|
const id = requireBound(ctx);
|
|
1391
1480
|
try {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
);
|
|
1395
|
-
return { contact: a.contact, messages };
|
|
1396
|
-
} catch (e) {
|
|
1397
|
-
throw errTool("get_conversation", String(e));
|
|
1481
|
+
return getMessageHistoryItem(id, input.wire_id);
|
|
1482
|
+
} catch (error) {
|
|
1483
|
+
throw errTool("get_history_item", String(error));
|
|
1398
1484
|
}
|
|
1399
1485
|
}
|
|
1400
|
-
|
|
1486
|
+
function getHistorySummary(ctx, input) {
|
|
1401
1487
|
const id = requireBound(ctx);
|
|
1402
1488
|
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));
|
|
1489
|
+
return getMessageHistorySummary(id, input);
|
|
1490
|
+
} catch (error) {
|
|
1491
|
+
throw errTool("get_history_summary", String(error));
|
|
1416
1492
|
}
|
|
1417
1493
|
}
|
|
1418
|
-
|
|
1494
|
+
function listFiles(ctx, query = {}) {
|
|
1419
1495
|
const id = requireBound(ctx);
|
|
1420
1496
|
try {
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
});
|
|
1425
|
-
return { contact: a.contact, marked };
|
|
1426
|
-
} catch (e) {
|
|
1427
|
-
throw errTool("mark_read", String(e));
|
|
1497
|
+
return listFileHistory(id, query);
|
|
1498
|
+
} catch (error) {
|
|
1499
|
+
throw errTool("list_files", String(error));
|
|
1428
1500
|
}
|
|
1429
1501
|
}
|
|
1430
|
-
|
|
1502
|
+
function getFileInfo(ctx, input) {
|
|
1431
1503
|
const id = requireBound(ctx);
|
|
1432
1504
|
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));
|
|
1505
|
+
return getFileHistoryItem(id, input.wire_id);
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
throw errTool("get_file_info", String(error));
|
|
1442
1508
|
}
|
|
1443
1509
|
}
|
|
1444
1510
|
|
|
@@ -1478,18 +1544,15 @@ var API_OPERATIONS = {
|
|
|
1478
1544
|
// ----- messaging (Task 12) -------------------------------------------------
|
|
1479
1545
|
sendMessage: op(sendMessage),
|
|
1480
1546
|
sendFile: op(sendFile),
|
|
1481
|
-
listIncomingMessages: op0(
|
|
1482
|
-
getMessages:
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
getReceipts: op(getReceipts),
|
|
1489
|
-
markRead: op(markRead),
|
|
1490
|
-
setConversationPolicy: op(setConversationPolicy),
|
|
1547
|
+
listIncomingMessages: op0(listIncomingMessages2),
|
|
1548
|
+
getMessages: op(getMessages),
|
|
1549
|
+
listHistory: op(listHistory),
|
|
1550
|
+
getHistoryItem: op(getHistoryItem),
|
|
1551
|
+
getHistorySummary: op(getHistorySummary),
|
|
1552
|
+
listFiles: op(listFiles),
|
|
1553
|
+
getFileInfo: op(getFileInfo),
|
|
1491
1554
|
// ----- files (Task 12) -----------------------------------------------------
|
|
1492
|
-
listIncomingFiles: op0(
|
|
1555
|
+
listIncomingFiles: op0(listIncomingFiles2),
|
|
1493
1556
|
getFiles: op(getFiles),
|
|
1494
1557
|
saveFileFallbackNotice: op(saveFileFallbackNotice)
|
|
1495
1558
|
};
|
package/dist/service.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
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
|
}
|