@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.
@@ -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-MHVYJY3H.js";
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(`message GC timer armed (every ${GC_INTERVAL_MS}ms)`);
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 basename2 } from "node:path";
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 `"${target.name}" was not a contact yet \u2014 connected as an intra-root sibling (delegation-cert auto-accept) and delivered the message.`;
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 `"${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.`;
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 { kind: "introduced", text: sent };
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 ?? basename2(path);
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 listIncomingMessages(ctx) {
1268
+ async function listIncomingMessages2(ctx) {
1204
1269
  const id = requireBound(ctx);
1205
1270
  try {
1206
- return withScope((lt) => renderInbox(readonlyTx(id, "::actor::list_incoming_messages", lt)));
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 = await withScopeAsync(async (lt) => {
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 e2eWireIds = readE2eWireIds(id);
1220
- return buildMessagesPayload(fresh, e2eWireIds);
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
- async function listIncomingFiles(ctx) {
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 withScope((lt) => renderFileMetadata(readonlyTx(id, "::actor::list_incoming_files", lt)));
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 out = await withScopeAsync(async (lt) => {
1261
- const data = await mutatingTx(id, "::actor::get_files", wire_ids === void 0 ? {} : { wire_ids }, lt);
1262
- return await writeIncomingFiles(id, data.Reduce("files"));
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: out.files,
1267
- // The finished summary travels; ours-mcp cannot re-derive it. See GetFilesResult.
1268
- text: out.text,
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
- // null NOT [] — for the bulk form. See GetFilesResult.
1271
- requested: wire_ids ?? null
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/conversations.ts
1367
- function renderConversation(av) {
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
- });
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
- async function getConversation(ctx, a) {
1478
+ function getHistoryItem(ctx, input) {
1390
1479
  const id = requireBound(ctx);
1391
1480
  try {
1392
- const messages = withScope(
1393
- (lt) => renderConversation(readonlyTx(id, "::actor::get_conversation", lt, { contact: a.contact }))
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
- async function getReceipts(ctx, a) {
1486
+ function getHistorySummary(ctx, input) {
1401
1487
  const id = requireBound(ctx);
1402
1488
  try {
1403
- const receipts = withScope((lt) => {
1404
- const av = readonlyTx(id, "::actor::get_receipts", lt, { contact: a.contact }).Reduce("receipts");
1405
- const out = {};
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
- async function markRead(ctx, a) {
1494
+ function listFiles(ctx, query = {}) {
1419
1495
  const id = requireBound(ctx);
1420
1496
  try {
1421
- const marked = await withScopeAsync(async (lt) => {
1422
- const data = await mutatingTx(id, "::actor::mark_read", { contact: a.contact }, lt);
1423
- return Number(data.Reduce("marked").Visualize());
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
- async function setConversationPolicy(ctx, a) {
1502
+ function getFileInfo(ctx, input) {
1431
1503
  const id = requireBound(ctx);
1432
1504
  try {
1433
- return await withScopeAsync(async (lt) => {
1434
- const data = await mutatingTx(id, "::actor::set_local_policy", { keep_history: a.keep_history }, lt);
1435
- return {
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(listIncomingMessages),
1482
- getMessages: op0(getMessages),
1483
- deferMessages: op(deferMessages),
1484
- deferFiles: op(deferFiles),
1485
- // The messenger conversation surface. getConversation and getReceipts read
1486
- // without consuming or emitting; markRead is the human read event.
1487
- getConversation: op(getConversation),
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(listIncomingFiles),
1555
+ listIncomingFiles: op0(listIncomingFiles2),
1493
1556
  getFiles: op(getFiles),
1494
1557
  saveFileFallbackNotice: op(saveFileFallbackNotice)
1495
1558
  };
package/dist/service.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  createLinuxUserSystemdAdapter,
6
6
  createMacosUserLaunchdAdapter,
7
7
  createServiceAdapter
8
- } from "./chunk-TNNBVUKK.js";
8
+ } from "./chunk-NBAZ2NEL.js";
9
9
  import "./chunk-UZQWSOUB.js";
10
10
  export {
11
11
  SERVICE_NAME,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/cli",
3
- "version": "1.0.1",
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": "^2.0.0"
28
+ "@ours.network/sdk": "^3.0.0",
29
+ "better-sqlite3": "^11.10.0"
29
30
  }
30
31
  }