@ours.network/sdk 2.0.1 → 3.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 +25 -2
- package/dist/api/contacts.js +1 -1
- package/dist/api/files.d.ts +4 -6
- package/dist/api/files.js +1 -1
- package/dist/api/history.d.ts +14 -0
- package/dist/api/history.js +2 -0
- package/dist/api/identity.js +1 -1
- package/dist/api/messaging.d.ts +7 -7
- package/dist/api/messaging.js +1 -1
- package/dist/api/profile.js +1 -1
- package/dist/api/types.d.ts +21 -69
- package/dist/book.js +1 -1
- package/dist/boot.js +1 -1
- package/dist/chunk-23BNCGF6.js +2 -0
- package/dist/{chunk-64C2NWXL.js → chunk-2TG2NHED.js} +1 -1
- package/dist/{chunk-HPPNU5YV.js → chunk-32DN6MBS.js} +1 -1
- package/dist/{chunk-T76BFV6S.js → chunk-4NP2YNWX.js} +1 -1
- package/dist/{chunk-7JZS2BAP.js → chunk-5DE7MMDG.js} +1 -1
- package/dist/{chunk-OWZIFNZN.js → chunk-7GBZLXV2.js} +1 -1
- package/dist/{chunk-2PVVBIA7.js → chunk-7M7H7ZAV.js} +1 -1
- package/dist/chunk-DRALQ2W5.js +2 -0
- package/dist/chunk-EPLWWBVB.js +2 -0
- package/dist/chunk-GZNPN3B5.js +4 -0
- package/dist/chunk-H7CVIQ7G.js +2 -0
- package/dist/{chunk-OA7XXAFG.js → chunk-HZCFYJAG.js} +1 -1
- package/dist/chunk-JOKNFUW3.js +4 -0
- package/dist/chunk-JTBQO6IT.js +2 -0
- package/dist/chunk-KIS5USR4.js +2 -0
- package/dist/chunk-OMUFZVAY.js +4 -0
- package/dist/chunk-P62PZ44T.js +2 -0
- package/dist/{chunk-3CDGP5EO.js → chunk-Q44JJZFN.js} +1 -1
- package/dist/chunk-S4JI2DB5.js +2 -0
- package/dist/{chunk-3KI5FM4I.js → chunk-SEZTXIKN.js} +1 -1
- package/dist/chunk-TXAIJEXA.js +171 -0
- package/dist/{chunk-CGAOZPMV.js → chunk-USG7J2P2.js} +1 -1
- package/dist/chunk-UVQY3IFO.js +2 -0
- package/dist/chunk-VIZVYPRQ.js +2 -0
- package/dist/chunk-WXCHUQ3J.js +2 -0
- package/dist/client/http.d.ts +7 -8
- package/dist/client/http.js +1 -1
- package/dist/client/select.js +1 -1
- package/dist/client.js +1 -1
- package/dist/cluster/control.js +1 -1
- package/dist/cluster/manifest.js +1 -1
- package/dist/connector.js +1 -1
- package/dist/events.d.ts +6 -12
- package/dist/events.js +1 -1
- package/dist/gc.js +1 -1
- package/dist/history.d.ts +195 -0
- package/dist/history.js +2 -0
- package/dist/http/api-routes.d.ts +5 -6
- package/dist/http/api-routes.js +1 -1
- package/dist/http/server.js +1 -1
- package/dist/identity/hierarchy.js +1 -1
- package/dist/identity/lease.js +1 -1
- package/dist/identity/lifecycle.js +1 -1
- package/dist/identity/model.d.ts +0 -1
- package/dist/identity/model.js +1 -1
- package/dist/identity/provision.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/messaging/send.d.ts +8 -2
- package/dist/messaging/send.js +1 -1
- package/dist/mufl/handlers.js +1 -1
- package/dist/mufl/tx.js +1 -1
- package/dist/mufl_code/{7962BB01B1D3E782A1F80B083A900AEC30BAC8F8CE79282B31821802B94A39B6.muflo → 351F16D444E6DAA252D4A8D829D17204360D9015FEF670ACE68FB4747BB3B14E.muflo} +0 -0
- package/dist/notify.d.ts +0 -1
- package/dist/notify.js +1 -1
- package/dist/render/adapt-to-json.d.ts +0 -5
- package/dist/render/adapt-to-json.js +1 -1
- package/dist/runtime/env.js +1 -1
- package/dist/state.js +1 -1
- package/dist/sweeps.js +1 -1
- package/dist/uploads.js +1 -1
- package/package.json +5 -3
- package/dist/api/conversations.d.ts +0 -48
- package/dist/api/conversations.js +0 -2
- package/dist/chunk-AQK45DI7.js +0 -2
- package/dist/chunk-CGXQP3Q4.js +0 -2
- package/dist/chunk-CIHGEBUR.js +0 -2
- package/dist/chunk-K7TLSZ3X.js +0 -2
- package/dist/chunk-LKFYUCN7.js +0 -2
- package/dist/chunk-MQ5AXTPT.js +0 -5
- package/dist/chunk-PQXV4GQ5.js +0 -2
- package/dist/chunk-R5ISAB5B.js +0 -2
- package/dist/chunk-TIBWO3T3.js +0 -2
- package/dist/chunk-TUWHVJ37.js +0 -6
- package/dist/chunk-V7PKYHV7.js +0 -2
- package/dist/chunk-W2BPK7VV.js +0 -2
- package/dist/chunk-XT75POTM.js +0 -2
- package/dist/chunk-XYU2DSWR.js +0 -2
- package/dist/inbox.d.ts +0 -38
- package/dist/inbox.js +0 -2
package/README.md
CHANGED
|
@@ -42,6 +42,28 @@ Old `autoStart` JSON and `OURS_AUTOSTART` are ignored in SDK 2. Start the daemon
|
|
|
42
42
|
with `ours daemon start` or install its per-user service with
|
|
43
43
|
`ours daemon install-service`.
|
|
44
44
|
|
|
45
|
+
## Message and file history
|
|
46
|
+
|
|
47
|
+
Application payloads are stored by the daemon, outside the MUFL packet. Each
|
|
48
|
+
identity has a `history.sqlite3` database and immutable content-addressed file
|
|
49
|
+
blobs. Incoming rows are unread until `getMessages({ limit })`, selective
|
|
50
|
+
`getMessages({ wire_ids })`, or
|
|
51
|
+
`getFiles({ wire_ids, limit })` selects and marks exactly that batch read.
|
|
52
|
+
Persistent history is available through `listHistory`, `getHistoryItem`,
|
|
53
|
+
`getHistorySummary`,
|
|
54
|
+
`listFiles`, and `getFileInfo`; `fetchFile` streams stored bytes from the daemon.
|
|
55
|
+
|
|
56
|
+
This design intentionally does not coordinate protocol delivery receipts with
|
|
57
|
+
the filesystem write. A process or local-storage failure after protocol
|
|
58
|
+
acceptance can therefore lose an item even if its sender considers it delivered.
|
|
59
|
+
There is no packet fallback, host outbox, implicit retry queue, or defer API.
|
|
60
|
+
|
|
61
|
+
This is a breaking storage epoch with no migration. A daemon that finds an old
|
|
62
|
+
packet format refuses startup and leaves it untouched. Before upgrading, stop
|
|
63
|
+
applications, make any desired manual backup, remove the old daemon state
|
|
64
|
+
yourself, and start clean. Identities, contacts, invites, pending payloads, and
|
|
65
|
+
history in old state are not carried forward; installers never delete them.
|
|
66
|
+
|
|
45
67
|
## Internal singleton contract
|
|
46
68
|
|
|
47
69
|
The CLI bundle acquires a cross-process lock before importing any module that
|
|
@@ -70,8 +92,9 @@ ownership boundary.
|
|
|
70
92
|
|
|
71
93
|
## Requirements
|
|
72
94
|
|
|
73
|
-
Node ≥ 20. The
|
|
74
|
-
`ours-mufl-core`
|
|
95
|
+
Node ≥ 20. The daemon uses the native `better-sqlite3` runtime dependency. The
|
|
96
|
+
MUFL packet is compiled from `mufl_code/`, which pins the `ours-mufl-core`
|
|
97
|
+
submodule — clone with `--recurse-submodules`.
|
|
75
98
|
|
|
76
99
|
## Build and test
|
|
77
100
|
|
package/dist/api/contacts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d,e,f,g,h,i,j}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e,f,g,h,i,j}from"../chunk-KIS5USR4.js";import"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{d as addContact,a as generateInvite,e as listContacts,b as listInvites,f as listLocalContactBook,h as removeContact,i as renameContact,j as respondToIntroduction,c as revokeInvite,g as setLocalBookPolicy};
|
package/dist/api/files.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
1
|
+
import { type HistoryFile } from '../history.js';
|
|
2
|
+
import type { GetFilesResult, SaveFileNotice, SessionContext } from './types.js';
|
|
3
3
|
export type * from './types.js';
|
|
4
|
-
export declare function listIncomingFiles(ctx: SessionContext): Promise<
|
|
4
|
+
export declare function listIncomingFiles(ctx: SessionContext): Promise<HistoryFile[]>;
|
|
5
5
|
export declare function getFiles(ctx: SessionContext, a?: {
|
|
6
6
|
wire_ids?: string[];
|
|
7
|
+
limit?: number;
|
|
7
8
|
}): Promise<GetFilesResult>;
|
|
8
9
|
export declare function saveFileFallbackNotice(ctx: SessionContext, a: {
|
|
9
10
|
wire_id: string;
|
|
10
11
|
}): SaveFileNotice;
|
|
11
|
-
export declare function deferFiles(ctx: SessionContext, a: {
|
|
12
|
-
file_ids: number[];
|
|
13
|
-
}): Promise<DeferResult>;
|
package/dist/api/files.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c
|
|
2
|
+
import{a,b,c}from"../chunk-OMUFZVAY.js";import"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{b as getFiles,a as listIncomingFiles,c as saveFileFallbackNotice};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type HistoryFile, type HistoryMessage, type HistoryPage, type HistoryQuery, type HistorySummary } from '../history.js';
|
|
2
|
+
import type { SessionContext } from './types.js';
|
|
3
|
+
export type * from '../history.js';
|
|
4
|
+
export declare function listHistory(ctx: SessionContext, query?: HistoryQuery): HistoryPage<HistoryMessage>;
|
|
5
|
+
export declare function getHistoryItem(ctx: SessionContext, input: {
|
|
6
|
+
wire_id: string;
|
|
7
|
+
}): HistoryMessage | null;
|
|
8
|
+
export declare function getHistorySummary(ctx: SessionContext, input: {
|
|
9
|
+
peer_cid: string;
|
|
10
|
+
}): HistorySummary;
|
|
11
|
+
export declare function listFiles(ctx: SessionContext, query?: HistoryQuery): HistoryPage<HistoryFile>;
|
|
12
|
+
export declare function getFileInfo(ctx: SessionContext, input: {
|
|
13
|
+
wire_id: string;
|
|
14
|
+
}): HistoryFile | null;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a,b,c,d,e}from"../chunk-WXCHUQ3J.js";import"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{e as getFileInfo,b as getHistoryItem,c as getHistorySummary,d as listFiles,a as listHistory};
|
package/dist/api/identity.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d,e,f,g,h,i,j,k}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e,f,g,h,i,j,k}from"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{g as chooseIdentity,d as closeTemporaryIdentityOp,b as createIdentity,e as createRootIdentity,c as createTemporaryIdentity,i as currentIdentity,f as defineLocalIdentityFile,h as listIdentities,k as releaseLease,j as removeIdentity,a as requireBound};
|
package/dist/api/messaging.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
1
|
+
import { type IncomingMessageMetadata } from '../history.js';
|
|
2
|
+
import type { FileSendOutcome, MessagesPayload, SendOutcome, SessionContext } from './types.js';
|
|
3
3
|
export type * from './types.js';
|
|
4
4
|
export declare function sendMessage(ctx: SessionContext, a: {
|
|
5
5
|
contact: string;
|
|
@@ -17,8 +17,8 @@ export declare function sendFile(ctx: SessionContext, a: {
|
|
|
17
17
|
reply_to_wire_id?: string;
|
|
18
18
|
reply_to_sentence?: number;
|
|
19
19
|
}): Promise<FileSendOutcome>;
|
|
20
|
-
export declare function listIncomingMessages(ctx: SessionContext): Promise<
|
|
21
|
-
export declare function getMessages(ctx: SessionContext
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}): Promise<
|
|
20
|
+
export declare function listIncomingMessages(ctx: SessionContext): Promise<IncomingMessageMetadata[]>;
|
|
21
|
+
export declare function getMessages(ctx: SessionContext, input?: {
|
|
22
|
+
wire_ids?: string[];
|
|
23
|
+
limit?: number;
|
|
24
|
+
}): Promise<MessagesPayload>;
|
package/dist/api/messaging.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d
|
|
2
|
+
import{a,b,c,d}from"../chunk-P62PZ44T.js";import"../chunk-7GBZLXV2.js";import"../chunk-VXVW4KJU.js";import"../chunk-S4JI2DB5.js";import"../chunk-P55RJGZU.js";import"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{d as getMessages,c as listIncomingMessages,b as sendFile,a as sendMessage};
|
package/dist/api/profile.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"../chunk-
|
|
2
|
+
import{a,b,c,d}from"../chunk-2TG2NHED.js";import"../chunk-32DN6MBS.js";import"../chunk-UVQY3IFO.js";import"../chunk-JOKNFUW3.js";import"../chunk-DIRW7I4S.js";import"../chunk-65KGEJBX.js";import"../chunk-Q44JJZFN.js";import"../chunk-USG7J2P2.js";import"../chunk-7M7H7ZAV.js";import"../chunk-H7CVIQ7G.js";import"../chunk-YRPUM6JG.js";import"../chunk-GZNPN3B5.js";import"../chunk-5DE7MMDG.js";import"../chunk-EPLWWBVB.js";import"../chunk-4NP2YNWX.js";import"../chunk-ZHH3PWEW.js";import"../chunk-Y3VPZJTG.js";import"../chunk-TXAIJEXA.js";import"../chunk-JTBQO6IT.js";import"../chunk-WS6UFNKF.js";export{b as advertiseMigrate,d as readvertiseOnUpgrade,a as setBio,c as setPersona};
|
package/dist/api/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { TempCloseResult } from '../identity/model.js';
|
|
2
|
-
import type { MessageJson } from '../inbox.js';
|
|
3
2
|
import type { SendVerdict } from '../messaging/send.js';
|
|
3
|
+
import type { HistoryMessage } from '../history.js';
|
|
4
4
|
import type { ContactRoot, IncomingFileMeta, InboxMsg, ReceivedFileMeta } from '../render/adapt-to-json.js';
|
|
5
|
-
export type { ContactRoot, IncomingFileMeta, InboxMsg,
|
|
5
|
+
export type { ContactRoot, IncomingFileMeta, InboxMsg, ReceivedFileMeta };
|
|
6
6
|
export interface SessionContext {
|
|
7
7
|
sessionId(): string;
|
|
8
8
|
leaseToken(): string | undefined;
|
|
@@ -147,9 +147,23 @@ export interface AdvertiseMigrateResult {
|
|
|
147
147
|
advertising: boolean;
|
|
148
148
|
offers: number;
|
|
149
149
|
}
|
|
150
|
-
|
|
150
|
+
type TransportPendingVerdict = Extract<SendVerdict, {
|
|
151
|
+
kind: 'refused' | 'migrating' | 'deferred';
|
|
152
|
+
}>;
|
|
153
|
+
type TransportSentVerdict = Extract<SendVerdict, {
|
|
154
|
+
kind: 'e2e' | 'sent';
|
|
155
|
+
}> & {
|
|
156
|
+
sent: true;
|
|
157
|
+
wire_id: string;
|
|
158
|
+
history_stored: boolean;
|
|
159
|
+
};
|
|
160
|
+
export type SendOutcome = TransportPendingVerdict | TransportSentVerdict | {
|
|
151
161
|
kind: 'introduced';
|
|
152
162
|
text: string;
|
|
163
|
+
wireId: string;
|
|
164
|
+
wire_id: string;
|
|
165
|
+
sent: true;
|
|
166
|
+
history_stored: boolean;
|
|
153
167
|
};
|
|
154
168
|
export type FileSendOutcome = SendOutcome & {
|
|
155
169
|
filename: string;
|
|
@@ -157,25 +171,8 @@ export type FileSendOutcome = SendOutcome & {
|
|
|
157
171
|
mime: string;
|
|
158
172
|
};
|
|
159
173
|
export interface MessagesPayload {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
export interface DeferResult {
|
|
164
|
-
/**
|
|
165
|
-
* HOW MANY WERE ACTUALLY RESTORED, which can be lower than the number of ids
|
|
166
|
-
* you passed, with nothing wrong.
|
|
167
|
-
*
|
|
168
|
-
* `defer_files` only restores files in `processed` or `ready_to_delete`
|
|
169
|
-
* (actor.mu:752); an already-unread file and an unknown id are both silently
|
|
170
|
-
* skipped and counted zero. `deferred < ids.length` is therefore a normal
|
|
171
|
-
* outcome of a retry, NOT an error — do not report it as one.
|
|
172
|
-
*
|
|
173
|
-
* NOTE THE IDENTIFIER SPLIT, because it reads as a typo and gets "fixed":
|
|
174
|
-
* `deferFiles` takes **file_id**s while `getFiles` selects by **wire_id**.
|
|
175
|
-
* They are different identifiers on the same file and the two surfaces
|
|
176
|
-
* disagree on purpose — the cell keys on `$file_ids -> ids: int[]`.
|
|
177
|
-
*/
|
|
178
|
-
deferred: string;
|
|
174
|
+
messages: HistoryMessage[];
|
|
175
|
+
remaining: number;
|
|
179
176
|
}
|
|
180
177
|
export interface ReadvertiseResult {
|
|
181
178
|
/**
|
|
@@ -188,7 +185,7 @@ export interface ReadvertiseResult {
|
|
|
188
185
|
* that is the phrasing someone will reach for.
|
|
189
186
|
*
|
|
190
187
|
* The packet's own Visualize() string, unparsed — the same rule as
|
|
191
|
-
*
|
|
188
|
+
* The packet's own Visualize() string.
|
|
192
189
|
*/
|
|
193
190
|
readvertised: string;
|
|
194
191
|
}
|
|
@@ -197,6 +194,7 @@ export interface GetFilesResult {
|
|
|
197
194
|
text: string;
|
|
198
195
|
mode: 'all_unread' | 'selected';
|
|
199
196
|
requested: string[] | null;
|
|
197
|
+
remaining: number;
|
|
200
198
|
}
|
|
201
199
|
export interface ReleaseLeaseResult {
|
|
202
200
|
released: string[];
|
|
@@ -204,49 +202,3 @@ export interface ReleaseLeaseResult {
|
|
|
204
202
|
export interface SaveFileNotice {
|
|
205
203
|
existsOnDisk: boolean;
|
|
206
204
|
}
|
|
207
|
-
/** One entry of a per-contact conversation, oldest first. */
|
|
208
|
-
export interface ConversationMessage {
|
|
209
|
-
dir: 'in' | 'out';
|
|
210
|
-
text: string;
|
|
211
|
-
date: string;
|
|
212
|
-
/**
|
|
213
|
-
* THE HUMAN READ FLAG, and deliberately not the inbox's `status`. A message
|
|
214
|
-
* can be `processed` — handed to an agent by getMessages — and still unread by
|
|
215
|
-
* a person. Conflating the two is what would make a polling frontend send read
|
|
216
|
-
* receipts for messages nobody looked at.
|
|
217
|
-
*/
|
|
218
|
-
read: boolean;
|
|
219
|
-
/** '' for pre-1.4 entries, which have no stable cross-side id. */
|
|
220
|
-
wire_id: string;
|
|
221
|
-
/**
|
|
222
|
-
* What the PEER has told us about this message, for outbound entries.
|
|
223
|
-
* MONOTONIC: null < 'delivered' < 'read', and it can never go backwards —
|
|
224
|
-
* a duplicate or out-of-order receipt collapses to a no-op, so a peer's UI
|
|
225
|
-
* cannot show a read message becoming unread.
|
|
226
|
-
*/
|
|
227
|
-
receipt: 'delivered' | 'read' | null;
|
|
228
|
-
}
|
|
229
|
-
export interface ConversationResult {
|
|
230
|
-
contact: string;
|
|
231
|
-
messages: ConversationMessage[];
|
|
232
|
-
}
|
|
233
|
-
export interface ReceiptsResult {
|
|
234
|
-
contact: string;
|
|
235
|
-
/** wire_id -> state. Absent ids simply have no receipt yet. */
|
|
236
|
-
receipts: Record<string, 'delivered' | 'read'>;
|
|
237
|
-
}
|
|
238
|
-
export interface MarkReadResult {
|
|
239
|
-
contact: string;
|
|
240
|
-
/**
|
|
241
|
-
* HOW MANY ENTRIES TRANSITIONED, which is also how many read receipts were
|
|
242
|
-
* emitted. Zero on a second call is the normal, correct answer — the
|
|
243
|
-
* unread->read transition is the event, not the call — so do not treat it as
|
|
244
|
-
* a failure.
|
|
245
|
-
*/
|
|
246
|
-
marked: number;
|
|
247
|
-
}
|
|
248
|
-
export interface ConversationPolicyResult {
|
|
249
|
-
keepHistory: boolean;
|
|
250
|
-
/** Echoed back unchanged; this operation must never silently move it. */
|
|
251
|
-
autoAccept: boolean;
|
|
252
|
-
}
|
package/dist/book.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{
|
|
2
|
+
import{A as e,B as f,C as g,D as h,E as i,F as j,w as a,x as b,y as c,z as d}from"./chunk-H7CVIQ7G.js";import"./chunk-YRPUM6JG.js";import"./chunk-GZNPN3B5.js";import"./chunk-5DE7MMDG.js";import"./chunk-EPLWWBVB.js";import"./chunk-4NP2YNWX.js";import"./chunk-ZHH3PWEW.js";import"./chunk-Y3VPZJTG.js";import"./chunk-TXAIJEXA.js";import"./chunk-JTBQO6IT.js";import"./chunk-WS6UFNKF.js";export{a as bookDir,c as bookPath,f as exportAdBlob,g as exportSigningSecret,j as pinRegistrar,h as publishToBook,d as readBook,b as registrarKeyPath,i as unpublishFromBook,e as writeBook};
|
package/dist/boot.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b}from"./chunk-
|
|
2
|
+
import{a,b}from"./chunk-VIZVYPRQ.js";import"./chunk-EHCBEY52.js";import"./chunk-UVQY3IFO.js";import"./chunk-JOKNFUW3.js";import"./chunk-DIRW7I4S.js";import"./chunk-Q44JJZFN.js";import"./chunk-USG7J2P2.js";import"./chunk-7M7H7ZAV.js";import"./chunk-H7CVIQ7G.js";import"./chunk-YRPUM6JG.js";import"./chunk-GZNPN3B5.js";import"./chunk-5DE7MMDG.js";import"./chunk-EPLWWBVB.js";import"./chunk-4NP2YNWX.js";import"./chunk-ZHH3PWEW.js";import"./chunk-Y3VPZJTG.js";import"./chunk-TXAIJEXA.js";import"./chunk-JTBQO6IT.js";import"./chunk-WS6UFNKF.js";export{b as bootWrapper,a as wrapperBooted};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{d as a,e as l,g as c}from"./chunk-H7CVIQ7G.js";import{c as o}from"./chunk-EPLWWBVB.js";import{f as r,i as n}from"./chunk-4NP2YNWX.js";var e=null,i=!1;function s(){e||(e=setInterval(()=>{i||(i=!0,(async()=>{try{for(let t of o.values())await a(t),await l(t),await c(t)}finally{i=!1}})())},r),e.unref?.(),n(`protocol maintenance timer armed (every ${r}ms)`))}function u(){e&&(clearInterval(e),e=null)}export{s as a,u as b};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as c}from"./chunk-
|
|
2
|
+
import{a as c}from"./chunk-32DN6MBS.js";import{M as d}from"./chunk-65KGEJBX.js";import{b as g,e as f,f as p}from"./chunk-7M7H7ZAV.js";import{r as o,v as n}from"./chunk-H7CVIQ7G.js";import{c as m}from"./chunk-EPLWWBVB.js";import{i as u}from"./chunk-4NP2YNWX.js";async function h(i,s){let e=c(i),{bio:t}=s;try{await o(async a=>{await n(e,"::a2a_messaging::set_my_bio",{bio:t},a)});let r=0;if(e.name===g){for(let a of m.values())if(a.name!==e.name&&f(a).rootCid===e.cid)try{await p(e,a),r+=1}catch(y){u(`failed to refresh root profile in role "${a.name}":`,String(y))}}return{identity:e.name,rolesRefreshed:r}}catch(r){throw d("set_bio",String(r))}}async function x(i){let s=c(i);try{return await o(async e=>{let t=await n(s,"::a2a_messaging::advertise_migrate",{},e);return{wasAdvertising:t.Reduce("was_advertising").Visualize()==="true",advertising:t.Reduce("advertising").Visualize()==="true",offers:parseInt(t.Reduce("offers_initiated").Visualize(),10)||0}})}catch(e){throw d("advertise_migrate",String(e))}}async function P(i,s){let e=c(i),{persona:t}=s;try{return await o(async r=>{await n(e,"::a2a_messaging::set_my_persona",{persona:t},r)}),{identity:e.name}}catch(r){throw d("set_persona",String(r))}}async function C(i){let s=c(i);try{return{readvertised:await o(async t=>(await n(s,"::a2a_messaging::readvertise_on_upgrade",{},t)).Reduce("readvertised").Visualize())}}catch(e){throw d("readvertise_on_upgrade",String(e))}}export{h as a,x as b,P as c,C as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as se,b as A}from"./chunk-
|
|
2
|
+
import{a as se,b as A}from"./chunk-UVQY3IFO.js";import{M as p,a as T,f as k,g as q,h as W,i as z,j as U,k as Y,l as G,m as J,n as K,o as Q,p as S,q as X,r as Z,s as ee,t as te,u as oe,v as ne,w as re,x as ie}from"./chunk-65KGEJBX.js";import{a as ae,c as de}from"./chunk-Q44JJZFN.js";import{b as f,e as b,f as N,g as E}from"./chunk-7M7H7ZAV.js";import{j as L,k as _,r as M,v as j}from"./chunk-H7CVIQ7G.js";import{a as h,b as v,e as I,f as B,g as H,h as V,i as g}from"./chunk-5DE7MMDG.js";import{c,n as w,o as $}from"./chunk-EPLWWBVB.js";import{i as R,p as x}from"./chunk-4NP2YNWX.js";import{k as D,m as F}from"./chunk-WS6UFNKF.js";import{randomBytes as ce}from"node:crypto";import{isAbsolute as me}from"node:path";function le(r){try{return b(r)}catch{return null}}function C(r){let o=le(r);return{name:r.name,cid:r.cid,bio:o?.bio??"",persona:o?.persona??"",roleId:o?.roleId??"",rootCid:o?.rootCid??"",rootName:o?.rootName??""}}async function P(r,o){o&&await M(async e=>{await j(r,"::a2a_messaging::set_my_bio",{bio:o},e)})}function pe(r){let o=V(r.sessionId());if(!("error"in o))return o.id;throw new T(o.code,o.error)}async function ke(r,o){let{name:e,bio:i,exposeLocal:d,localAutoAccept:s}=o,n=x(e);if(n)throw p("create_identity",n,"NAME_INVALID");if(c.has(e))throw k("create_identity",e);try{let t=await _(e,{exposeLocal:d,localAutoAccept:s});await P(t,i);let a,l=null,m=[],u=[],y=f?c.get(f):void 0;if(y)await N(y,t),a="role",l=y.name,ae()&&de(y);else{a="root";let O=await E(t);m=O.adopted,u=O.failed}return g(r.sessionId(),e),{info:C(t),hierarchy:a,underRoot:l,adopted:m,failed:u,exposedLocal:d,localAutoAccept:s}}catch(t){throw p("create_identity",String(t),"PROVISION_FAILED")}}async function Ae(r,o){let{bio:e,exposeLocal:i,localAutoAccept:d}=o,s=r.leaseToken(),n=r.clientPid();if(!s||!n)throw q();let t=o.name;if(t!==void 0){let l=x(t);if(l)throw p("create_temporary_identity",l,"NAME_INVALID");if(c.has(t)||L.has(t))throw k("create_temporary_identity",t)}else{for(let l=0;l<5&&t===void 0;l++){let m=`tmp-${ce(5).toString("hex")}`;!c.has(m)&&!L.has(m)&&(t=m)}if(t===void 0)throw W()}let a=t;try{let l=await _(a,{exposeLocal:i,localAutoAccept:d,temp:{tokenHash:w(s),pid:n}});return await P(l,e),g(r.sessionId(),a),{info:C(l),ownerPid:n,exposedLocal:i,localAutoAccept:d}}catch(l){throw p("create_temporary_identity",String(l),"PROVISION_FAILED")}}async function Ce(r,o){let e=r.leaseToken(),i;if(o.name!==void 0){if(i=c.get(o.name),!i)return{name:o.name,result:null}}else{let n=e?B(e):void 0;if(i=n?c.get(n.identity):void 0,!i)throw U()}if(!i.temp)throw Y(i.name);let d=i.temp.owner,s=e!==void 0&&d.tokenHash===w(e);if(!s&&!i.temp.closing&&I(d.pid))throw G(i.name,d.pid);try{let n=await A(i,s?"explicit close by owner":"stale reclaim via close_temporary_identity");if(n.deleteError){let t=n.attempted===0?"It had no contacts, so no remove-me notices were needed.":`Remove-me notices: ${n.notified}/${n.attempted} queued, ${n.failed} not sent (best effort \u2014 delivery and remote contact deletion are not guaranteed).`;throw J(i.name,n.deleteError,t)}return{name:i.name,result:n}}catch(n){throw n instanceof T?n:p("close_temporary_identity",String(n),"CLOSE_FAILED")}}async function ve(r,o){let{name:e,bio:i,exposeLocal:d,localAutoAccept:s,skipIfRootExists:n}=o,t=x(e);if(t)throw p("create_root_identity",t,"NAME_INVALID");let a=f;if(n&&a&&c.has(a))throw z(a);if(c.has(e))throw k("create_root_identity",e);try{let l=await _(e,{exposeLocal:d,localAutoAccept:s});await P(l,i);let m=f?c.get(f):void 0;if(m&&m.name!==e)return await N(m,l),g(r.sessionId(),e),{info:C(l),hierarchy:"role",underRoot:m.name,adopted:[],failed:[],exposedLocal:d,localAutoAccept:s};let{adopted:u,failed:y}=await E(l);return g(r.sessionId(),e),{info:C(l),hierarchy:"root",underRoot:null,adopted:u,failed:y,exposedLocal:d,localAutoAccept:s}}catch(l){throw p("create_root_identity",String(l),"PROVISION_FAILED")}}async function Le(r){if(!me(r.path))throw K(r.path);let o={name:r.name,force:r.force,exposeLocal:r.exposeLocal,localAutoAccept:r.localAutoAccept};try{return{written:F(r.path,o,r.overwrite),json:D(o)}}catch(e){throw p("define_local_identity_file",String(e),"WRITE_FAILED")}}async function Se(r,o){let{name:e,force:i}=o;if(!c.has(e))throw Q(e);let d=r.sessionId(),s=r.leaseToken();if(!s)throw S();let n=c.get(e);if(n.temp){if(n.temp.closing)throw X(e);let m=n.temp.owner;if(m.tokenHash!==w(s))throw I(m.pid)?Z(e,m.pid):ee(e,m.pid);let u=r.clientPid();if(u&&u!==m.pid){m.pid=u;try{$(n.dir,n.temp)}catch(y){R(`[${e}] temp marker refresh failed:`,String(y))}}}let t=h.get(e);if(t&&t.token!==s)if(!I(t.pid))R(`auto-reclaiming "${e}" from dead client pid ${t.pid}`),h.delete(e);else if(i)v.add(t.token),h.delete(e);else throw te(e);let a=[...h.values()].find(m=>m.token===s&&m.identity!==e)?.identity,l=a&&c.has(a)?a:null;return g(d,e),{name:e,cid:c.get(e).cid,switchedFrom:l}}async function Ne(r){if(c.size===0)return[];let o=r.leaseToken(),e=t=>{let a=h.get(t);return a?a.token===o?"mine":I(a.pid)?"other-live":null:null},i=t=>{if(!t.temp)return null;let a=t.temp.owner.pid;return t.temp.closing?{state:"closing",ownerPid:a}:o!==void 0&&t.temp.owner.tokenHash===w(o)?{state:"mine",ownerPid:a}:I(a)?{state:"other-live",ownerPid:a}:{state:"stale",ownerPid:a}},d=(t,a)=>({name:t.name,cid:t.cid,kind:a,temp:i(t),session:e(t.name)}),s=f?c.get(f):void 0,n=[];if(s){n.push({...d(s,"root"),temp:null});for(let t of c.values())t.name!==s.name&&b(t).roleId!==""&&n.push(d(t,"role"));for(let t of c.values())t.name===s.name||b(t).roleId!==""||n.push(d(t,"flat"))}else for(let t of c.values())n.push(d(t,"flat"));return n}async function Ee(r){let o=pe(r),e=le(o);return{name:o.name,cid:o.cid,bio:e?.bio??"",persona:e?.persona??"",roleId:e?.roleId??"",rootCid:e?.rootCid??"",rootName:e?.rootName??"",temporary:o.temp!==void 0,isRoot:o.name===f,described:e!==null}}async function Pe(r,o){let{name:e}=o,i=c.get(e);if(!i)throw p("remove_identity",`no identity named "${e}".`,"NO_SUCH_IDENTITY");if(i.temp){let s=r.leaseToken(),n=i.temp.owner;if((s===void 0||n.tokenHash!==w(s))&&!i.temp.closing&&I(n.pid))throw oe(e,n.pid);try{let t=await A(i,"remove_identity");if(t.deleteError){let a=t.attempted===0?"":` Remove-me notices: ${t.notified}/${t.attempted} queued, ${t.failed} not sent (best effort).`;throw ne(e,t.deleteError,a)}return{name:e,kind:"temporary",close:t}}catch(t){throw t instanceof T?t:p("remove_identity",String(t),"CLOSE_FAILED")}}if(e===f){let s=[...c.values()].filter(n=>n.name!==e&&b(n).rootCid===i.cid);if(s.length>0)throw re(e,s.map(n=>n.name))}let d=se(i);if(d)throw ie(e,d);return{name:e,kind:"permanent"}}async function Oe(r){let o=r.leaseToken();if(!o)throw S();let e=[];for(let[i,d]of[...h]){if(d.token!==o)continue;h.delete(i),e.push(i);let s=c.get(i);s?.temp&&s.temp.owner.tokenHash===w(o)&&!s.temp.closing&&A(s,"owning session released its lease").catch(n=>R(`[${i}] close on lease release failed:`,String(n)))}return v.delete(o),H(),R(`lease released by token \u2026${o.slice(-6)}`),{released:e}}export{pe as a,ke as b,Ae as c,Ce as d,ve as e,Le as f,Se as g,Ne as h,Ee as i,Pe as j,Oe as k};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{e as a}from"./chunk-ZHH3PWEW.js";import{d as s,f as i,g as u,h as p}from"./chunk-WS6UFNKF.js";import{timingSafeEqual as d}from"node:crypto";var b="
|
|
2
|
+
import{e as a}from"./chunk-ZHH3PWEW.js";import{d as s,f as i,g as u,h as p}from"./chunk-WS6UFNKF.js";import{timingSafeEqual as d}from"node:crypto";var b="3.0.2",r=s(),_=r.stateDir,k=r.brokerUrl,g=process.env.OURS_TRANSPORT??"http",E=r.port,A=r.gcIntervalMs,c=r.apiVisibility,R=Number(process.env.OURS_TEST_STARTUP_HEARTBEAT_MS||"")||void 0,N=g==="http"?a(_,{heartbeatMs:R}):null,v=(...e)=>process.stderr.write(`ours: ${e.join(" ")}
|
|
3
3
|
`);function S(){if(c==="open")return null;if(c==="shared"){let e=u(r);if(!e)throw new Error(`apiVisibility=shared requires an operator-supplied token so it can be distributed to cross-user agents \u2014 set OURS_API_TOKEN or "apiToken" in config (${i(r)} is not used for shared mode). Use apiVisibility=owner for a same-user-only auto-token, or =open to disable auth.`);return e}return p(r,{generate:!0}).token}var f=S();function T(e){let t=e.headers["x-ours-api-token"];if(typeof t=="string"&&t)return t;let o=e.headers.authorization;if(typeof o=="string"){let n=/^Bearer\s+(.+)$/i.exec(o.trim());if(n)return n[1]}}function h(e){if(f===null)return!0;let t=T(e);if(!t)return!1;let o=Buffer.from(t),n=Buffer.from(f);return o.length===n.length&&d(o,n)}function P(e,t){return h(e)?!0:(t.writeHead(401,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"unauthorized"})),!1)}var O=/^[A-Za-z0-9 _.@-]{1,64}$/,l="contact-book";function y(e){return O.test(e)?e==="."||e===".."||e.includes("/")||e.includes("\\")?"invalid name":e===l?`"${l}" is reserved for the local contact book`:e==="root.json"||e==="bindings.json"?`"${e}" is reserved for daemon bookkeeping`:null:"name must be 1-64 chars of letters, digits, space, _ . @ or -"}export{b as a,r as b,_ as c,k as d,E as e,A as f,c as g,N as h,v as i,f as j,T as k,h as l,P as m,O as n,l as o,y as p};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{c as a}from"./chunk-
|
|
2
|
+
import{c as a}from"./chunk-EPLWWBVB.js";import{c as d,i as u}from"./chunk-4NP2YNWX.js";import{join as h}from"node:path";import*as r from"node:fs";var i=new Map,g=new Set,c=new Map,k=new Set;function E(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}function m(e){for(let t of i.values())if(t.token===e)return t}var f=()=>h(d,"bindings.json");function l(){try{r.mkdirSync(d,{recursive:!0});let e=`${f()}.tmp`;r.writeFileSync(e,JSON.stringify({pid:process.pid,bound:[...i.keys()],holders:[...i.values()].map(t=>({identity:t.identity,pid:t.pid}))})),r.renameSync(e,f())}catch(e){u("failed to persist bindings snapshot:",String(e))}}function _(e){let t=c.get(e)?.token;if(!t)return{code:"NOT_BOUND",error:"No identity bound to this session. Call choose_identity (or create_identity) first."};if(g.has(t))return{code:"BINDING_REASSIGNED",error:"Your identity binding was reassigned to another session. Call choose_identity again to continue."};let n=m(t);if(!n)return{code:"NOT_BOUND",error:"No identity bound to this session. Call choose_identity (or create_identity) first."};let o=a.get(n.identity);if(!o)return i.delete(n.identity),l(),{code:"BOUND_IDENTITY_GONE",error:`The bound identity "${n.identity}" no longer exists. Choose another with choose_identity.`};if(o.temp?.closing)return{code:"TEMP_CLOSING",error:`The temporary identity "${o.name}" is closing and no longer accepts work. Its contacts are being notified and its local state deleted.`};n.sid=e;let s=c.get(e)?.pid;return s&&(n.pid=s),{id:o}}function x(e,t){let n=c.get(e),o=n?.token;if(!o)return;for(let[p,y]of[...i])y.token===o&&p!==t&&i.delete(p);let s=i.get(t)?.epoch??0;i.set(t,{identity:t,token:o,pid:n?.pid??0,sid:e,epoch:s+1,boundAt:Date.now()}),g.delete(o),l()}export{i as a,g as b,c,k as d,E as e,m as f,l as g,_ as h,x as i};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{c as b}from"./chunk-
|
|
2
|
+
import{c as b}from"./chunk-EPLWWBVB.js";import{i as S}from"./chunk-4NP2YNWX.js";import*as n from"node:fs";import{createHash as w}from"node:crypto";import{basename as _,join as f}from"node:path";var u=e=>f(e.dir,"uploads"),D=Number(process.env.OURS_UPLOAD_TTL_MS)>0?Number(process.env.OURS_UPLOAD_TTL_MS):60*60*1e3,I=/^[0-9a-f]{32}$/,L=()=>w("sha256").update(`${process.pid}:${Date.now()}:${Math.random()}`).digest("hex").slice(0,32),O=e=>I.test(e),U=(e,r)=>f(u(e),r),y=(e,r)=>f(u(e),`${r}.json`);function $(e){let r=e.replace(/[\u0000-\u001f\u007f]/g,"").replace(/\\/g,"/"),t=_(r);return(t===""||t==="."||t===".."?"":t).slice(0,255)}var i=class extends Error{constructor(t,s){super(s);this.status=t;this.name="UploadRefused"}};async function T(e,r,t){let s=$(t.filename);if(s==="")throw new i(400,"x-ours-filename is required and must be a plain file name");if(t.declaredBytes===null)throw new i(411,"Content-Length is required");if(t.declaredBytes>=t.cap)throw new i(400,`upload is ${t.declaredBytes} bytes, at or over the transport's ${t.cap}-byte envelope budget \u2014 it could not be sent even with no filename or MIME, so it is refused before it is stored`);let o=L();n.mkdirSync(u(e),{recursive:!0,mode:448});let d=U(e,o),a=w("sha256"),p=0,c=n.createWriteStream(d,{mode:384});try{await new Promise((m,x)=>{let g=l=>{r.unpipe?.(c),c.destroy(),x(l)};r.on("data",l=>{if(p+=l.length,p>t.declaredBytes){g(new i(400,"request body is longer than its Content-Length"));return}a.update(l)}),r.on("error",g),c.on("error",g),c.on("finish",()=>m()),r.pipe(c)})}catch(m){try{n.rmSync(d,{force:!0})}catch{}throw m}let h={upload_id:o,filename:s,mime:t.mime,size:p,sha256:a.digest("hex"),at:new Date().toISOString()};return n.writeFileSync(y(e,o),JSON.stringify(h),{mode:384}),h}function F(e,r){if(!O(r))return null;let t=U(e,r),s,o;try{s=n.readFileSync(t),o=JSON.parse(n.readFileSync(y(e,r),"utf8"))}catch{return null}finally{try{n.rmSync(t,{force:!0})}catch{}try{n.rmSync(y(e,r),{force:!0})}catch{}}return{meta:o,buf:s}}function R(){let e=0,r=Date.now()-D;for(let t of b.values()){let s=u(t),o;try{o=n.readdirSync(s)}catch{continue}for(let d of o){let a=f(s,d);try{if(n.statSync(a).mtimeMs>=r)continue;n.rmSync(a,{force:!0}),e++}catch{}}e>0&&S(`[${t.name}] swept ${e} stale staged upload file(s)`)}return e}export{u as a,D as b,O as c,$ as d,i as e,T as f,F as g,R as h};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{
|
|
2
|
+
import{B as f,q as m,r as p,s as l,v as a}from"./chunk-H7CVIQ7G.js";import{c as u}from"./chunk-EPLWWBVB.js";import{c as d,i}from"./chunk-4NP2YNWX.js";import{join as x}from"node:path";import*as r from"node:fs";function V(e){y=e}var c=()=>x(d,"root.json"),y=null;function $(){try{let e=JSON.parse(r.readFileSync(c(),"utf8"));return typeof e.name=="string"?e.name:null}catch{return null}}function I(e){r.mkdirSync(d,{recursive:!0});let o=`${c()}.tmp`;r.writeFileSync(o,JSON.stringify({v:1,name:e})),r.renameSync(o,c())}function G(){r.rmSync(c(),{force:!0})}function z(e){return m(o=>{let t=l(e,"::actor::describe_identity",o);return{bio:t.Reduce("bio").Visualize(),persona:t.Reduce("persona").Visualize(),hasCert:t.Reduce("has_cert").GetBoolean(),roleId:t.Reduce("role_id").Visualize(),rootCid:t.Reduce("root_cid").Visualize(),rootName:t.Reduce("root_name").Visualize(),monitoringEnabled:t.Reduce("monitoring_enabled").GetBoolean()}})}async function A(e,o){await p(async t=>{let n=f(o),s=await a(e,"::actor::sign_delegation",{role_ad:e.pw.packet.NewBinaryFromBuffer(n).Attach(t),role_id:o.name},t),g=Buffer.from(s.Reduce("cert").GetBinary()),B=await a(e,"::actor::export_root_profile",{},t),w=Buffer.from(B.Reduce("profile").GetBinary()),h=f(e),_=Buffer.from((await a(o,"::actor::export_v1_address_document",{},t)).Reduce("ad").GetBinary()),R=await a(e,"::actor::sign_delegation",{role_ad:e.pw.packet.NewBinaryFromBuffer(_).Attach(t),role_id:o.name},t),b=Buffer.from(R.Reduce("cert").GetBinary());await a(o,"::actor::set_delegation",{cert:o.pw.packet.NewBinaryFromBuffer(g).Attach(t),root_ad:o.pw.packet.NewBinaryFromBuffer(h).Attach(t),root_profile:o.pw.packet.NewBinaryFromBuffer(w).Attach(t),cert_v1:o.pw.packet.NewBinaryFromBuffer(b).Attach(t)},t)}),i(`[${o.name}] delegated as a role under root "${e.name}"`)}async function C(e){y=e.name,I(e.name);let o=[],t=[];for(let n of u.values())if(n.name!==e.name&&!n.temp)try{await A(e,n),o.push(n.name)}catch(s){i(`failed to adopt "${n.name}" as a role under new root "${e.name}":`,String(s)),t.push(n.name)}return i(`[${e.name}] established as the host root${o.length?` (adopted ${o.length} role(s))`:""}`),{adopted:o,failed:t}}export{V as a,y as b,$ as c,G as d,z as e,A as f,C as g};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as P,b,c as w,d as H,e as M,f as T,g as N,h as L,i as B,j}from"./chunk-KIS5USR4.js";import{a as E,b as J,c as _}from"./chunk-OMUFZVAY.js";import{a as $,b as U,c as V,d as X,e as q}from"./chunk-WXCHUQ3J.js";import{a as z,b as D,c as G,d as K}from"./chunk-P62PZ44T.js";import{a as Q,b as W,c as Y,d as Z}from"./chunk-2TG2NHED.js";import{b as u,c as v,d as h,e as S,f as k,g as x,h as O,i as R,j as C,k as F}from"./chunk-32DN6MBS.js";import{a as f}from"./chunk-65KGEJBX.js";import{c as d}from"./chunk-5DE7MMDG.js";import{n as I}from"./chunk-EPLWWBVB.js";import{i as m,m as g}from"./chunk-4NP2YNWX.js";var ie="/api/v1/",e=i=>(t,n)=>i(t,n),s=i=>t=>i(t),ne=i=>(t,n)=>i(n),ee={createIdentity:e(u),createTemporaryIdentity:e(v),closeTemporaryIdentityOp:e(h),createRootIdentity:e(S),defineLocalIdentityFile:ne(k),chooseIdentity:e(x),listIdentities:s(O),currentIdentity:s(R),removeIdentity:e(C),releaseLease:s(F),generateInvite:e(P),listInvites:s(b),revokeInvite:e(w),addContact:e(H),listContacts:s(M),listLocalContactBook:s(T),setLocalBookPolicy:e(N),removeContact:e(L),renameContact:e(B),respondToIntroduction:e(j),setBio:e(Q),advertiseMigrate:s(W),readvertiseOnUpgrade:s(Z),setPersona:e(Y),sendMessage:e(z),sendFile:e(D),listIncomingMessages:s(G),getMessages:e(K),listHistory:e($),getHistoryItem:e(U),getHistorySummary:e(V),listFiles:e(X),getFileInfo:e(q),listIncomingFiles:s(E),getFiles:e(J),saveFileFallbackNotice:e(_)},l=new Map,te=(i,t)=>{let n=i.headers[t];return typeof n=="string"&&n!==""?n:void 0};function oe(i){let t=te(i,"x-ours-lease-token"),n=te(i,"x-ours-client-pid"),y=n?parseInt(n,10):NaN,a=Number.isInteger(y)?y:void 0,o=t?`api:${I(t)}`:"api:anonymous";return d.set(o,{token:t,pid:a}),l.set(o,(l.get(o)??0)+1),{ctx:{sessionId:()=>o,leaseToken:()=>d.get(o)?.token,clientPid:()=>d.get(o)?.pid},release:()=>{let r=(l.get(o)??1)-1;if(r>0){l.set(o,r);return}l.delete(o),d.delete(o)}}}var p=(i,t,n)=>{i.writableEnded||(i.writeHead(t,{"Content-Type":"application/json"}),i.end(JSON.stringify(n??null)))};async function ge(i,t,n,y){let a=n.slice(ie.length);if(!g(i,t))return;if(i.method!=="POST"){p(t,405,{error:"method not allowed: the typed API is POST-only"});return}let o=Object.prototype.hasOwnProperty.call(ee,a)?ee[a]:void 0;if(!o){p(t,404,{error:`unknown operation "${a}"`});return}let r;try{r=await y(i)}catch{p(t,400,{error:"the request body must be JSON"});return}if(r===null||typeof r!="object"||Array.isArray(r)){p(t,400,{error:"the request body must be a JSON object"});return}let A=oe(i);try{p(t,200,await o(A.ctx,r))}catch(c){if(c instanceof f){p(t,400,{error:{code:c.code,message:c.message}});return}m("api handler error:",a,String(c)),p(t,500,{error:`internal error in ${a}: ${String(c)}`})}finally{A.release()}}export{ie as a,ee as b,oe as c,ge as d};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{c as s,i as a}from"./chunk-4NP2YNWX.js";import{a as p,w as f}from"./chunk-TXAIJEXA.js";import{join as n}from"node:path";import{createHash as y}from"node:crypto";import*as r from"node:fs";var g;function I(t){g=t}var W=new Map,h=null,x=null;function $(t){h=t}function E(t){x=t}var H=t=>n(s,t),u=t=>n(t,"identity.key"),b=t=>n(t,"state_data.bin"),w=t=>n(t,"notifications.log"),k=t=>n(t,"unread.json"),m=t=>n(t,"temp.json"),M=t=>y("sha256").update(t).digest("hex");function R(t,e){r.writeFileSync(m(t),JSON.stringify({v:1,owner:{token_sha256:e.owner.tokenHash,pid:e.owner.pid},created_at:e.createdAt}),{mode:384})}function j(t){try{let e=JSON.parse(r.readFileSync(m(t),"utf8"));return e.v!==1||typeof e.owner?.token_sha256!="string"||typeof e.owner?.pid!="number"?null:{owner:{tokenHash:e.owner.token_sha256,pid:e.owner.pid},createdAt:typeof e.created_at=="number"?e.created_at:0}}catch{return null}}function B(){for(let t of A()){let e=n(s,t);try{r.chmodSync(e,448)}catch(o){a(`[${t}] chmod 0700 failed:`,String(o))}for(let o of[b(e),u(e),p({dir:e}),`${p({dir:e})}-wal`,`${p({dir:e})}-shm`,w(e),k(e)])if(r.existsSync(o))try{r.chmodSync(o,384)}catch(i){a(`[${t}] chmod 0600 ${o} failed:`,String(i))}let d=n(e,"blobs");if(r.existsSync(d)){let o=i=>{for(let c of r.readdirSync(i,{withFileTypes:!0})){let l=n(i,c.name);c.isDirectory()?(r.chmodSync(l,448),o(l)):c.isFile()&&r.chmodSync(l,384)}};try{r.chmodSync(d,448),o(d)}catch(i){a(`[${t}] chmod history blobs failed:`,String(i))}}}}var S=t=>/^[A-Za-z0-9]+$/.test(t)&&t.length>0&&t.length<=128,C=t=>/^[A-Fa-f0-9]{64}$/.test(t);function D(t,e){if(!S(e))return null;try{return f(t,e)}catch{return null}}function A(){return r.existsSync(s)?r.readdirSync(s,{withFileTypes:!0}).filter(t=>t.isDirectory()&&r.existsSync(u(n(s,t.name)))).map(t=>t.name):[]}export{g as a,I as b,W as c,h as d,x as e,$ as f,E as g,H as h,u as i,b as j,w as k,k as l,m,M as n,R as o,j as p,B as q,S as r,C as s,D as t,A as u};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{k as b,l as g}from"./chunk-EPLWWBVB.js";import{c as y,i as N,p as v}from"./chunk-4NP2YNWX.js";import{n as O,p as R}from"./chunk-TXAIJEXA.js";import{c as x,f as I,g as F}from"./chunk-JTBQO6IT.js";import{join as T}from"node:path";import*as s from"node:fs";var l=null;function U(n){l?.uninstall(),l=n===null?null:{hook:n,uninstall:x("notification",n)}}function W(n){l?.hook===n&&(l.uninstall(),l=null)}function L(n,e){F(n,e)}var V={onNotify:(n,e)=>L(n,e)},S={inbound:["message_received","file_received"],intro:["local_contact_request","pending_message"],get wake(){return[...S.inbound,...S.intro]}};function A(n){if(n===null||n==="")return null;let e=new Set;for(let r of n.split(",")){let t=r.trim();if(t==="")continue;let f=S[t];if(!f)throw new Error(t);for(let i of f)e.add(i)}return e}function M(n,e){return e===null?!0:typeof n.event=="string"&&e.has(n.event)}var p=new Map;function j(n){let e=p.get(n);if(!(!e||e.size===0))for(let r of[...e])try{r()}catch{}}function D(n,e){return new Promise(r=>{let t=p.get(n);t||(t=new Set,p.set(n,t));let f=!1,i=()=>{f||(f=!0,t.delete(a),t.size===0&&p.delete(n),clearTimeout(u),r())},a=i,u=setTimeout(i,e);t.add(a)})}var Y=new Set(["body","text","payload","data","bytes","content"]);function w(n){if(Buffer.isBuffer(n)||n instanceof Uint8Array)return;if(Array.isArray(n))return n.map(w).filter(r=>r!==void 0);if(!n||typeof n!="object")return n;let e={};for(let[r,t]of Object.entries(n)){if(Y.has(r.toLowerCase()))continue;let f=w(t);f!==void 0&&(e[r]=f)}return e}function q(n,e){let r=w(e);try{s.mkdirSync(n.dir,{recursive:!0,mode:448});let t=b(n.dir);s.appendFileSync(t,JSON.stringify(r)+`
|
|
3
|
+
`,{mode:384}),s.chmodSync(t,384)}catch(t){N(`[${n.name}] failed to append notifications.log:`,String(t))}j(n.name),I(n,r)}function Q(n,e){let r=n.Reduce(e);return r.IsNil()?"":Buffer.from(r.GetBinary()).toString("hex")}var C=Number(process.env.OURS_NOTIFY_LONGPOLL_MS)>0?Number(process.env.OURS_NOTIFY_LONGPOLL_MS):25e3,J=250;function H(n){try{return s.statSync(n).size}catch{return 0}}function z(n,e,r){if(r<=e)return{events:[],cursor:e};let t=Buffer.alloc(r-e),f=0;try{let c=s.openSync(n,"r");try{f=s.readSync(c,t,0,t.length,e)}finally{s.closeSync(c)}}catch{return{events:[],cursor:e}}let i=t.subarray(0,f),a=i.lastIndexOf(10);if(a===-1)return{events:[],cursor:e};let u=[];for(let c of i.subarray(0,a+1).toString("utf8").split(`
|
|
4
|
+
`))if(c.trim())try{u.push(JSON.parse(c))}catch{}return{events:u,cursor:e+a+1}}async function X(n,e,r,t,f=null){let i=b(T(y,r)),a=(d,m)=>{e.writableEnded||(e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify({cursor:d,events:m})))},u;try{u=A(f)}catch(d){e.writableEnded||(e.writeHead(400,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:`unknown notification kind "${String(d.message)}" \u2014 known kinds: ${Object.keys(S).sort().join(", ")}`})));return}if(t===null||t==="tip"){a(H(i),[]);return}let c=parseInt(t,10);if(!Number.isFinite(c)||c<0){e.writableEnded||(e.writeHead(400,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"invalid since cursor"})));return}let o=!1;n.on("close",()=>{o=!0});let _=Date.now()+C;for(;!o;){let d=H(i);if(c>d&&(c=0),d>c){let{events:m,cursor:k}=z(i,c,d);c=k;let h=u===null?m:m.filter(E=>M(E,u));if(h.length>0){a(k,h);return}}if(Date.now()>=_)break;await D(r,Math.min(J,_-Date.now()))}o||a(c,[])}function Z(n){try{let e=O(n),r=R(n).map(i=>({file_id:String(i.file_id),sender_id:i.from.id,from:i.from.name,filename:i.filename,mime:i.mime,bytes:String(i.byte_length),date:i.date,wire_id:i.wire_id})),t={count:e.length,recent:e.slice(-10).map(i=>({from:i.from.name,msg_id:i.msg_id,date:i.date})),files:r.length,unread_files:r.slice(-10)};s.mkdirSync(n.dir,{recursive:!0,mode:448});let f=`${g(n.dir)}.tmp`;s.writeFileSync(f,JSON.stringify(t),{mode:384}),s.chmodSync(f,384),s.renameSync(f,g(n.dir))}catch(e){N(`[${n.name}] failed to refresh unread snapshot:`,String(e))}}function nn(){let n=[],e=[];try{e=s.readdirSync(y,{withFileTypes:!0})}catch{return{identities:n}}for(let r of e){if(!r.isDirectory()||v(r.name)!==null)continue;let t;try{t=JSON.parse(s.readFileSync(g(T(y,r.name)),"utf8"))}catch{continue}let f=Number.isSafeInteger(t.count)&&Number(t.count)>=0?Number(t.count):0,i=Number.isSafeInteger(t.files)&&Number(t.files)>=0?Number(t.files):0;if(f===0&&i===0)continue;let a=Array.isArray(t.recent)?t.recent.slice(-10).flatMap(c=>{if(!c||typeof c!="object")return[];let o=c;return typeof o.from!="string"||!["string","number"].includes(typeof o.msg_id)||typeof o.date!="string"?[]:[{from:o.from,msg_id:o.msg_id,date:o.date}]}):[],u=Array.isArray(t.unread_files)?t.unread_files.slice(-10).flatMap(c=>{if(!c||typeof c!="object")return[];let o=c;return typeof o.from!="string"||typeof o.filename!="string"||typeof o.mime!="string"||typeof o.wire_id!="string"?[]:[{from:o.from,filename:o.filename,mime:o.mime,wire_id:o.wire_id,...typeof o.sender_id=="string"?{sender_id:o.sender_id}:{},...["string","number"].includes(typeof o.file_id)?{file_id:o.file_id}:{},...["string","number"].includes(typeof o.bytes)?{bytes:o.bytes}:{},...typeof o.date=="string"?{date:o.date}:{}}]}):[];n.push({name:r.name,count:f,recent:a,files:i,unread_files:u})}return n.sort((r,t)=>String(r.name).localeCompare(String(t.name))),{identities:n}}export{U as a,W as b,L as c,V as d,S as e,A as f,M as g,j as h,D as i,q as j,Q as k,H as l,z as m,X as n,Z as o,nn as p};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{b as j}from"./chunk-YRPUM6JG.js";import{c as _e,d as ge,j as g,k as T,o as N}from"./chunk-GZNPN3B5.js";import{d as fe}from"./chunk-5DE7MMDG.js";import{a as F,c as k,d as V,e as K,f as ue,g as le,h as G,i as P,j as x,o as pe,u as me}from"./chunk-EPLWWBVB.js";import{c as te,i as d,o as O}from"./chunk-4NP2YNWX.js";import{d as H,f as U,g as ie,h as W,i as re,j as ne,k as oe,l as se,s as ae,v as ce,x as de}from"./chunk-TXAIJEXA.js";import{AdaptObjectLifetime as Ve}from"@adapt-toolkit/sdk/common";import{object_to_adapt_value as Ie}from"@adapt-toolkit/sdk/wrapper";import*as f from"node:fs";import{randomBytes as Te}from"node:crypto";import*as z from"node:fs";import{randomBytes as ze}from"node:crypto";import{PacketWrapperConfigurator as xe}from"@adapt-toolkit/sdk/wrappers";import{AdaptObjectLifetime as ke}from"@adapt-toolkit/sdk/common";function B(e){let i=e.Visualize(),a=Number(i);if(Number.isFinite(a)&&a>=0)return a;let n=Date.parse(i);if(!Number.isFinite(n))throw new Error("invalid host-event date");return n}function ye(e){let i=e.Reduce("reply_to");if(i.IsNil())return{};let a=i.Reduce("wire_id").Visualize(),n=i.Reduce("sentence");return n.IsNil()?{replyToWireId:a}:{replyToWireId:a,replyToSentence:Number(n.Visualize())}}function q(e,i){try{g(e,i)}catch(a){d(`[${e.name}] post-insert history wake failed event=${String(i.event??"")}:`,String(a))}}function we(e,i){e.pw.on_return_data=a=>{let n=new ke;a.Attach(n);try{let c=a.Reduce("kind").Visualize();if(c==="save_state"){E(e);return}if(c==="host_event"){let t=a.Reduce("payload"),l=t.Reduce("event").Visualize();if(l==="application_payload"){let r=t.Reduce("item_kind").Visualize(),o=t.Reduce("direction").Visualize(),s=t.Reduce("wire_id").Visualize(),u=t.Reduce("peer_cid").Visualize(),p=t.Reduce("peer_name").Visualize(),_=t.Reduce("encryption").Visualize(),v=t.Reduce("inbox_state"),b=o==="in"&&!v.IsNil()?v.Visualize():void 0;try{if((r==="message"?W(e,{kind:"message",wireId:s,peerCid:u,peerName:p,direction:o,inboxState:b,body:t.Reduce("body").Visualize(),occurredAtMs:B(t.Reduce("date")),encryption:_,...ye(t)}):W(e,{kind:"file",wireId:s,peerCid:u,peerName:p,direction:o,inboxState:b,filename:t.Reduce("filename").Visualize(),mime:t.Reduce("mime").Visualize(),bytes:Buffer.from(t.Reduce("data").GetBinary()),occurredAtMs:B(t.Reduce("date")),encryption:_,...ye(t)}))&&o==="in"&&b==="unread")if(r==="message"){let y=ae(e,s);q(e,{event:"message_received",from:p,sender_name:p,sender_id:u,msg_id:String(y.msg_id),wire_id:s,date:y.date}),N(e),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] new message from ${p} (#${y.msg_id})`))}else{let y=ce(e,s);q(e,{event:"file_received",from:p,sender_id:u,file_id:String(y.file_id),wire_id:s,filename:y.filename,mime:y.mime,bytes:String(y.byte_length),date:y.date}),N(e),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] new file ${y.filename} (${y.byte_length} B) from ${p} (sender_id ${u}, file_id ${y.file_id}, wire_id ${s})`))}}catch($){let y=r==="file"?"file":"message";H(e,y,s,o),d(`[${e.name}] history ${y} write failed direction=${o} wire_id=${s}:`,String($))}}else if(l==="pending_introduction_decision"){let r=t.Reduce("peer_cid").Visualize(),o=t.Reduce("action").Visualize();try{o==="approve"?oe(e,r):o==="reject"&&se(e,r),N(e)}catch(s){d(`[${e.name}] pending-introduction history update failed action=${o} peer_cid=${r}:`,String(s))}}else if(l==="monitoring_payload"){let r=t.Reduce("item_id").Visualize();try{re(e,{kind:"monitoring_copy",itemId:r,sourceCid:t.Reduce("source_cid").Visualize(),sourceName:t.Reduce("source_name").Visualize(),direction:t.Reduce("direction").Visualize(),peerCid:t.Reduce("peer_cid").Visualize(),peerName:t.Reduce("peer_name").Visualize(),body:t.Reduce("body").Visualize(),occurredAtMs:B(t.Reduce("date"))})&&q(e,{event:"monitoring_copy",item_id:r})}catch(o){d(`[${e.name}] monitoring history write failed item_id=${r}:`,String(o))}}else if(l==="control_payload"){let r=t.Reduce("item_id").Visualize();try{ne(e,{kind:"control_request",itemId:r,senderCid:t.Reduce("sender_cid").Visualize(),senderName:t.Reduce("sender_name").Visualize(),payload:t.Reduce("payload").Visualize(),occurredAtMs:B(t.Reduce("date"))})&&q(e,{event:"control_request",item_id:r})}catch(o){d(`[${e.name}] control history write failed item_id=${r}:`,String(o))}}return}if(c==="notify_agent"){let t=a.Reduce("payload"),l=t.Reduce("event").Visualize();if(l==="receipt_received"){let r=t.Reduce("sender_id"),o=r.IsNil()?"":String(r.Visualize()),s=t.Reduce("kind"),u=s.IsNil()?"":String(s.Visualize()),p=[],_=t.Reduce("wire_ids");if(!_.IsNil())for(let $=0;;$++){let y=_.Reduce($);if(y.IsNil())break;p.push(String(y.Visualize()))}let v=t.Reduce("date"),b=v.IsNil()?new Date().toISOString():String(v.Visualize());if(u==="delivered"||u==="read")try{de(e,o,u,p)}catch($){H(e,"receipt"),d(`[${e.name}] history receipt update failed sender_id=${o} kind=${u} count=${p.length}:`,String($))}g(e,{event:"receipt_received",sender_id:o,kind:u,wire_ids:p,date:b})}else if(l==="contact_accepted"){let r=t.Reduce("name").Visualize(),o=t.Reduce("container_id").Visualize();C(e),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] contact "${r}" (${o}) accepted your invite.`))}else if(l==="local_contact_added"){let r=t.Reduce("name").Visualize(),o=t.Reduce("container_id").Visualize();C(e),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] local contact "${r}" (${o}) connected via the contact book.`))}else if(l==="contact_name_collision"){let r=t.Reduce("message").Visualize(),o=t.Reduce("desired").Visualize(),s=t.Reduce("assigned").Visualize(),u=t.Reduce("existing_container_id").Visualize(),p=t.Reduce("container_id").Visualize();g(e,{event:"contact_name_collision",desired:o,assigned:s,existing_container_id:u,container_id:p}),d(`[${e.name}] CONTACT NAME COLLISION \u2014 ${r}`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] \u26A0 ${r}`))}else if(l==="sibling_contact_added"){let r=t.Reduce("name").Visualize(),o=t.Reduce("container_id").Visualize();g(e,{event:"sibling_contact_added",from:r}),C(e),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] sibling "${r}" (${o}) connected (intra-root auto-accept).`))}else if(l==="local_contact_request"){let r=t.Reduce("name").Visualize(),o=t.Reduce("container_id").Visualize();g(e,{event:"local_contact_request",from:r}),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] pending local introduction from "${r}" (${o}) \u2014 approve or reject with respond_to_introduction.`))}else if(l==="pending_message"){let r=t.Reduce("sender_name").Visualize(),o=t.Reduce("queued").Visualize();g(e,{event:"pending_message",from:r,queued:o}),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] "${r}" queued a message awaiting introduction approval (${o} queued).`))}else if(l==="e2e_restore_rejected")g(e,{event:"e2e_restore_rejected"}),d(`[${e.name}] E2E RESTORE REJECTED \u2014 corrupt session blob failed pickle_key validation; reset to empty e2e state, self-heal fallback will re-establish`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] persisted e2e sessions were corrupt \u2014 rejected cleanly, sessions re-establishing`));else if(l==="contact_restored"){let r=t.Reduce("name").Visualize(),o=t.Reduce("container_id").Visualize();g(e,{event:"contact_restored",from:r}),d(`[${e.name}] contact "${r}" restored (re-keyed)`),process.nextTick(()=>void J(e,String(o)))}else if(l==="migration_active"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("role").Visualize(),s=T(t,"epoch"),u=T(t,"session_id");g(e,{event:"migration_active",cid:String(r),role:String(o),...s?{epoch:s}:{},...u?{session_id:u}:{}}),d(`[migration] active cid=${r} role=${o}${s?` epoch=${s}`:""}${u?` session_id=${u}`:""}`)}else if(l==="e2e_app_send"){let r=t.Reduce("cid").Visualize(),o=T(t,"session_id"),s=t.Reduce("olm_type").Visualize(),u=t.Reduce("wire_id").Visualize(),p=t.Reduce("retained").IsNil()?void 0:t.Reduce("retained").GetBoolean(),_=[],v=t.Reduce("evicted");if(!v.IsNil())for(let b=0;;b++){let $=v.Reduce(b);if($.IsNil())break;_.push(String($.Visualize()))}g(e,{event:"e2e_app_send",cid:String(r),session_id:o,olm_type:String(s),wire_id:String(u),...p===!1?{retained:!1}:{},..._.length?{evicted:_}:{}}),d(`[${e.name}] [e2e-app] send cid=${r} session_id=${o} olm_type=${s} wire_id=${u}${p===!1?" retained=false":""}${_.length?` evicted=${_.join(",")}`:""}`),_.length&&process.nextTick(()=>i.onNotify(e.name,`[${e.name}] redrive window overflow: ${_.length} older unacked send(s) lost their auto-resend guarantee (${_.join(", ")})`))}else if(l==="dedup_degraded"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("dropped_wire_id").Visualize();g(e,{event:"dedup_degraded",cid:String(r),dropped_wire_id:String(o)}),d(`[${e.name}] [e2e-app] DEDUP DEGRADED cid=${r} dropped_wire_id=${o} (storage ceiling \u2014 a late redrive of that id could re-deposit)`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] dedup window overflowed for ${String(r).slice(0,12)}\u2026 \u2014 one oldest entry dropped (guarantee loss surfaced)`))}else if(l==="e2e_delivery_expired"){let r=t.Reduce("cid").Visualize(),o=[],s=t.Reduce("wire_ids");if(!s.IsNil())for(let u=0;;u++){let p=s.Reduce(u);if(p.IsNil())break;o.push(String(p.Visualize()))}g(e,{event:"e2e_delivery_expired",cid:String(r),wire_ids:o}),d(`[${e.name}] [e2e-app] delivery EXPIRED (2-day TTL, receipt never arrived) cid=${r} wire_ids=${o.join(",")}`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] ${o.length} message(s)/file(s) to ${String(r).slice(0,12)}\u2026 expired undelivered (no receipt within 2 days)`))}else if(l==="e2e_app_recv"){let r=t.Reduce("cid").Visualize(),o=T(t,"session_id"),s=t.Reduce("ok").GetBoolean(),u=t.Reduce("wire_id").Visualize(),p=t.Reduce("code").IsNil()?void 0:String(t.Reduce("code").Visualize()),_=!t.Reduce("duplicate").IsNil(),v=!t.Reduce("file").IsNil();g(e,{event:"e2e_app_recv",cid:String(r),session_id:o,ok:s,wire_id:String(u),...p?{code:p}:{},..._?{duplicate:!0}:{},...v?{file:!0}:{}}),d(`[${e.name}] [e2e-app] recv cid=${r} session_id=${o} ok=${s} wire_id=${u}${p?` code=${p}`:""}${_?" duplicate=true":""}${v?" file=true":""}`)}else if(l==="e2e_rekey"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("role").Visualize(),s=T(t,"session_id"),u=t.Reduce("attempts").IsNil()?void 0:String(t.Reduce("attempts").Visualize()),p=t.Reduce("peer_supports").IsNil()?void 0:String(t.Reduce("peer_supports").Visualize()),_=t.Reduce("rejected").IsNil()?void 0:String(t.Reduce("rejected").Visualize());g(e,{event:"e2e_rekey",cid:String(r),role:String(o),...s?{session_id:s}:{},...u?{attempts:u}:{},...p?{peer_supports:p}:{},..._?{rejected:_}:{}}),d(`[${e.name}] [e2e-rekey] cid=${r} role=${o}${s?` session_id=${s}`:""}${u?` attempts=${u}`:""}${p?` peer_supports=${p}`:""}${_?` rejected=${_}`:""}`)}else if(l==="migration_deferred_flush"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("wire_id").Visualize();g(e,{event:"migration_deferred_flush",cid:String(r),wire_id:String(o)}),d(`[migration] flush-notify cid=${r} wire_id=${o} (deferred\u2192e2e; core delivers)`)}else if(l==="migration_stalled"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("phase").Visualize(),s=t.Reduce("attempts").Visualize();g(e,{event:"migration_stalled",cid:String(r),phase:String(o),attempts:String(s)}),d(`[migration] stalled-notify cid=${r} phase=${o} attempts=${s} (core re-drives via sweep)`)}else if(l==="downgrade_refused"){let r=t.Reduce("cid").Visualize(),o=t.Reduce("wire_id"),s=o.IsNil()?"":String(o.Visualize());g(e,{event:"downgrade_refused",cid:String(r),...s?{wire_id:s}:{}}),d(`[e2e-route] downgrade-dropped cid=${r}${s?` wire_id=${s}`:""} (legacy plaintext from a migrated peer \u2014 dropped by core)`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] a message from a migrated contact was rejected as an unsafe downgrade (dropped).`))}else if(l==="contact_removed"){let r=String(t.Reduce("cid").Visualize()),o=fe.has(e.name);g(e,{event:"contact_removed",cid:r,by:o?"local":"peer"}),o||(d(`[${e.name}] contact ${r} removed you (authenticated peer removal notice) \u2014 dropped from contacts`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] contact ${r.slice(0,12)}\u2026 removed you as a contact (the removal was applied locally too).`)))}else if(l==="monitoring_disabled"){let r=String(t.Reduce("cid").Visualize()),o=t.Reduce("cause"),s=o.IsNil()?"":String(o.Visualize());g(e,{event:"monitoring_disabled",cid:r,...s?{cause:s}:{}}),d(`[${e.name}] monitoring disabled (cid=${r}${s?` cause=${s}`:""})`),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] the monitoring/control-plane binding was disabled${s==="control_plane_removed_contact"?" \u2014 the control plane removed you as a contact":""}.`))}else l==="control_request"||l==="host_provision_child"||l==="host_destroy_child"||l==="host_mint_child_invite"||l==="host_set_child_monitoring"?d(`[${e.name}] ${l}: the daemon-side control plane is removed \u2014 ignoring`):g(e,{event:l});return}let m=e.pending.shift();if(!m)return;clearTimeout(m.timer),m.resolve(a.Reduce("payload").Detach())}finally{n.Finalize()}},e.pw.on_transaction_failure=a=>{let n=e.pending.shift();n?(clearTimeout(n.timer),n.reject(new Error(a))):(d(`[${e.name}] inbound transaction rejected:`,a),g(e,{event:"inbound_error",message:a}),process.nextTick(()=>i.onNotify(e.name,`[${e.name}] inbound transaction rejected: ${a}`)))}}import{join as X}from"node:path";import*as I from"node:fs";var A=()=>X(te,O),Y=()=>X(A(),"registrar.key"),Q=()=>X(A(),"book.json");function he(){try{let e=JSON.parse(I.readFileSync(Q(),"utf8"));return e&&typeof e.entries=="object"?e.entries:{}}catch{return{}}}function ve(e){I.mkdirSync(A(),{recursive:!0});let i=`${Q()}.tmp`;I.writeFileSync(i,JSON.stringify({v:1,entries:e},null,2),{mode:384}),I.renameSync(i,Q())}function Z(e){return R(i=>Buffer.from(S(e,"::actor::export_address_document",i).GetBinary()))}function L(e){return R(i=>Buffer.from(S(e,"::actor::export_signing_secret",i).Serialize()).toString("hex"))}async function $e(e){if(!V)throw new Error("registrar is not available");let i=Z(e),a=await w(async c=>{let m=await h(V,"::actor::sign_book_entry",{name:e.name,ad:V.pw.packet.NewBinaryFromBuffer(i).Attach(c)},c);return Buffer.from(m.Reduce("sig").GetBinary()).toString("base64url")}),n=he();n[e.name]={v:1,name:e.name,container_id:e.cid,address_document:i.toString("base64url"),published_at:new Date().toISOString(),registrar_sig:a},ve(n),d(`[${e.name}] published to the local contact book`)}function Ge(e){let i=he(),a=Object.entries(i).find(([,n])=>n.container_id===e.cid);a&&(delete i[a[0]],ve(i),d(`[${e.name}] removed from the local contact book (entry "${a[0]}")`))}async function Re(e){if(!K)throw new Error("registrar is not available");await w(async i=>{await h(e,"::actor::pin_registrar",{registrar_ad:e.pw.packet.NewBinaryFromBuffer(K).Attach(i)},i)})}function M(e,i,a,n=!0,c,m=!1){let t=new xe;t.deferred_exposure=m;let l=["--unit_hash",j.hash,"--seed_phrase",i,"--unit_dir_path",j.dir];return c&&l.push("--init_trn_argument",JSON.stringify(c)),t.process_arguments(l),new Promise((r,o)=>{let s=setTimeout(()=>o(new Error(`packet creation for "${e}" timed out`)),3e4);F.packet_manager.create_packet(t,u=>{clearTimeout(s);let p={name:e,cid:R(_=>u.packet.GetContainerID().Attach(_).Visualize()),pw:u,dir:a,pending:[],lock:Promise.resolve()};we(p,ge),n&&k.set(e,p),d(`[${e}] packet created \u2014 container id ${p.cid}`),r(p)},j.contents)})}var D=new Set(me());D.size>0&&d(`reserved ${D.size} persisted identity name(s) at module load: ${[...D].join(", ")}`);async function ct(e,i={exposeLocal:!0,localAutoAccept:!0}){if(D.has(e)||k.has(e))throw new Error(`identity name "${e}" is reserved \u2014 a persisted identity with this name is restoring, present, or being provisioned; refusing to provision over it`);D.add(e);let a;try{let n=G(e);z.mkdirSync(n,{recursive:!0,mode:448});let c;i.temp&&(c={owner:{tokenHash:i.temp.tokenHash,pid:i.temp.pid},createdAt:Date.now()},pe(n,c));let m=ze(24).toString("hex"),t=await M(e,m,n);return a=t,U(t),c&&(t.temp=c),z.writeFileSync(P(n),L(t),{mode:384}),await w(async l=>{await h(t,"::a2a_messaging::set_my_name",{name:e},l)}),await Re(t),i.localAutoAccept||await w(async l=>{await h(t,"::actor::set_local_policy",{auto_accept:!1},l)}),i.exposeLocal&&await $e(t),E(t),t}catch(n){throw a&&ie(a),D.delete(e),n}}async function dt(e){let i=G(e),a=z.readFileSync(P(i),"utf8").trim(),n=await M(e,"",i,!1,a,!0);d(`[${e}] created QUARANTINED (no routing/broker registration, not client-bindable) \u2014 importing state before exposure`);let c=Number(process.env.OURS_TEST_RESTORE_HOLD_MS||"")||0;c>0&&(d(`[${e}] TEST HOLD: keeping restore open ${c}ms (OURS_TEST_RESTORE_HOLD_MS)`),await new Promise(r=>setTimeout(r,c)));let m=r=>/timed out waiting for the transaction result/.test(String(r)),t=(r,o,s)=>{d(`[${e}] ${r} ${o} \u2014 identity left UNEXPOSED and UNTRACKED (fail-closed)`),k.delete(e);try{F.remove_packet(n.cid)}catch(u){d(`[${e}] quarantined-packet teardown failed:`,String(u))}throw new Error(`identity "${e}": ${r} failed during restore (${o}) \u2014 left unexposed (fail-closed)`)},l=(r,o)=>t(r,"outcome UNKNOWN (timeout): the transaction may still execute and exposure would race it",o);if(be(i)){try{if(process.env.OURS_TEST_FORCE_IMPORT_TIMEOUT==="1")throw new Error("timed out waiting for the transaction result (forced by OURS_TEST_FORCE_IMPORT_TIMEOUT)");let r=z.readFileSync(x(i));await w(async o=>{let s=n.pw.packet.ParseValue(new Uint8Array(r)).Attach(o),u=Number(process.env.OURS_IMPORT_TIMEOUT_MS||"")||void 0;await h(n,"::actor::import_state",s,o,u)}),d(`[${e}] state import completed (positively observed)`)}catch(r){m(r)&&l("import_state",r),t("import_state","REFUSED: this release accepts only direct-host-storage app format 2; existing state was left untouched",r)}{try{let s=await w(async u=>{let p=await h(n,"::a2a_messaging::commit_e2e_restore",{},u),_=p.Reduce("status").Visualize(),v=p.Reduce("sessions").IsNil()?"0":p.Reduce("sessions").Visualize();return{status:String(_),sessions:String(v)}});d(`[${e}] e2e restore commit: status=${s.status} sessions=${s.sessions}`)}catch(s){m(s)&&l("commit_e2e_restore",s),d(`[${e}] E2E RESTORE REJECTED \u2014 staged session blob failed pickle_key validation; discarding it, fresh account + self-heal fallback take over: ${String(s).slice(0,260)}`),g(n,{event:"e2e_restore_rejected",origin:"restore",error:String(s).slice(0,300)});try{await w(async u=>{await h(n,"::a2a_messaging::reject_e2e_restore",{},u)})}catch(u){m(u)&&l("reject_e2e_restore",u),d(`[${e}] reject_e2e_restore failed (staging is transient; continuing):`,String(u))}}try{n.pw.refresh_identity_proof_document(),d(`[${e}] transport IPD refreshed from post-import state`)}catch(s){t("ipd_refresh","FAILED (IPD would advertise a stale bundle)",s)}let r=!1,o="";try{if(process.env.OURS_TEST_FORCE_IPD_INCOHERENT==="1")throw new Error("forced incoherent (OURS_TEST_FORCE_IPD_INCOHERENT)");let s=R(_=>String(S(n,"::a2a_messaging::e2e_self_fp",_).Reduce("ik").Visualize())),u=n.pw.identity_proof_document.Visualize(),p=s.replace(/^0x/i,"");r=p.length>=32&&u.toLowerCase().includes(p.toLowerCase()),o=s.slice(0,18),g(n,{event:"ipd_coherence",ik:s,coherent:r})}catch(s){t("ipd_coherence","probe FAILED (coherence unprovable)",s)}d(`[${e}] IPD/e2e coherence: account_ik=${o}\u2026 ipd_advertises_it=${r}`),r||t("ipd_coherence","IPD does NOT advertise the live account ik",new Error("incoherent transport IPD"))}}try{U(n)}catch(r){t("history_open","FAILED (SQLite history unavailable)",r)}return F.expose_packet(n.cid),k.set(e,n),d(`[${e}] EXPOSED (routing + broker registration) \u2014 import phase complete`),await Se(n),N(n),n}async function wt(){f.mkdirSync(A(),{recursive:!0});let e;try{e=f.readFileSync(Y(),"utf8").trim()}catch{}let i=Te(24).toString("hex");ue(await M(O,i,A(),!1,e)),e||f.writeFileSync(Y(),L(V),{mode:384}),le(Z(V)),d(`contact-book registrar ready (${V.cid})`)}function be(e){try{return f.existsSync(x(e))&&f.statSync(x(e)).size>0}catch{return!1}}function Ne(e){let i=R(m=>Buffer.from(S(e,"::actor::export_state",m).Serialize()));f.mkdirSync(e.dir,{recursive:!0,mode:448});let a=x(e.dir),n=`${a}.tmp`,c;try{c=f.openSync(n,"w",384),f.fchmodSync(c,384),f.writeFileSync(c,i),f.fsyncSync(c),f.closeSync(c),c=void 0,f.renameSync(n,a),f.chmodSync(a,384);try{f.chmodSync(P(e.dir),384)}catch{}let m=f.openSync(e.dir,"r");try{f.fsyncSync(m)}finally{f.closeSync(m)}}catch(m){if(c!==void 0)try{f.closeSync(c)}catch{}try{f.rmSync(n,{force:!0})}catch{}throw m}}function E(e){try{Ne(e),e.persistFailed&&(e.persistFailed=!1,d(`[${e.name}] persist recovered \u2014 quarantine lifted`),g(e,{event:"persist_recovered"}))}catch(i){e.persistFailed=!0,d(`[${e.name}] PERSIST FAILED \u2014 identity quarantined (fail-closed), outbound of this txn withheld:`,String(i));try{g(e,{event:"persist_failed",error:String(i).slice(0,300)})}catch{}throw process.nextTick(()=>_e(e.name,`[${e.name}] PERSIST FAILED \u2014 messaging quarantined until the state file is writable again`)),i}}function R(e){let i=new Ve;try{return e(i)}finally{i.Finalize()}}async function w(e){let i=new Ve;try{return await e(i)}finally{i.Finalize()}}function S(e,i,a,n){let c=Ie({name:i,targ:n}),m=e.pw.packet.ExecuteTransaction(c);return c.Destroy(),a?m.Attach(a):m}async function Ee(e,i){let a=e.lock,n;e.lock=new Promise(c=>n=c),await a;try{return await i()}finally{n()}}function Ae(e,i,a=25e3){return new Promise((n,c)=>{let m=setTimeout(()=>{let t=e.pending.findIndex(l=>l.timer===m);t>=0&&e.pending.splice(t,1),c(new Error("timed out waiting for the transaction result"))},a);e.pending.push({resolve:n,reject:c,timer:m}),e.pw.add_client_message(i)})}function h(e,i,a,n,c){if(e.persistFailed)try{E(e)}catch(t){return Promise.reject(new Error(`identity "${e.name}" is quarantined: state persist is failing (${String(t)}) \u2014 mutations are rejected until state_data.bin is writable again`))}let m=Ie({name:i,targ:a});return Ee(e,()=>Ae(e,m,c)).then(t=>{if(m.Destroy(),e.persistFailed){try{t.Destroy()}catch{}throw new Error(`identity "${e.name}": state persist FAILED \u2014 this transaction's outbound was withheld (fail-closed); fix the state directory and retry`)}return n?t.Attach(n):t},t=>{try{m.Destroy()}catch{}throw t})}function kt(e){let i=[],a=e.Reduce("degraded");if(a.IsNil())return i;for(let n=0;;n++){let c=a.Reduce(n);if(c.IsNil())break;i.push({cid:c.Reduce("container_id").Visualize(),name:c.Reduce("name").Visualize(),attempts:Number(c.Reduce("attempts").Visualize()),queued:Number(c.Reduce("queued").Visualize())})}return i}function De(e){let i=[],a=e.Reduce("queues");if(a.IsNil())return i;for(let n=0;;n++){let c=a.Reduce(n);if(c.IsNil())break;i.push({cid:c.Reduce("container_id").Visualize(),queued:Number(c.Reduce("queued").Visualize()),degraded:c.Reduce("degraded").GetBoolean()})}return i}async function J(e,i){try{let a=await w(async n=>{let c=await h(e,"::a2a_messaging::flush_deferred",{contact:i},n);return Number(c.Reduce("flushed").Visualize())});a>0&&d(`[${e.name}] flushed ${a} deferred message(s) to ${i.slice(0,12)}\u2026`)}catch(a){d(`[${e.name}] deferred flush to ${i.slice(0,12)}\u2026 failed:`,String(a))}}async function Se(e){try{let i=await w(async n=>{let c=await h(e,"::a2a_messaging::restore_degraded_contacts",{},n);return Number(c.Reduce("requested").Visualize())});i>0&&d(`[${e.name}] contact restore requested for ${i} degraded contact(s)`);let a=R(n=>De(S(e,"::a2a_messaging::list_deferred_queues",n)));for(let n of a)n.degraded||await J(e,n.cid)}catch(i){d(`[${e.name}] contact-restore sweep failed:`,String(i))}}async function Pe(e){try{let i=await w(async a=>{let n=await h(e,"::a2a_messaging::reconcile_advertise",{},a),c=m=>n.Reduce(m).IsNil()?0:Number(n.Reduce(m).Visualize());return{changed:/true/i.test(n.Reduce("changed").Visualize()),capabilityAdvertised:c("capability_advertised"),legacyReadvertised:c("legacy_readvertised")}});(i.capabilityAdvertised>0||i.legacyReadvertised>0)&&d(`[${e.name}] capability reconcile: changed=${i.changed} advertised=${i.capabilityAdvertised} legacy_migration_bootstrap=${i.legacyReadvertised}`)}catch(i){d(`[${e.name}] capability reconcile sweep failed:`,String(i))}}var ee=new Set;function C(e){if(!ee.has(e.name)){ee.add(e.name);for(let i of[2e3,15e3])setTimeout(()=>{i===15e3&&ee.delete(e.name);let a=k.get(e.name);a&&Pe(a)},i)}}async function zt(e){try{let i=await w(async a=>{let n=await h(e,"::a2a_messaging::readvertise_e2e_recovery",{},a);return Number(n.Reduce("readvertised").Visualize())});i>0&&d(`[${e.name}] re-advertised fresh AD to ${i} e2e contact(s) (session recovery)`)}catch(i){d(`[${e.name}] e2e recovery re-advertise failed:`,String(i))}try{await w(async i=>{await h(e,"::a2a_messaging::sweep_e2e_migrations",{},i)})}catch(i){d(`[${e.name}] e2e migration sweep failed:`,String(i))}try{let i=await w(async a=>{let n=await h(e,"::a2a_messaging::redrive_unacked_sweep",{},a),c=m=>n.Reduce(m).IsNil()?0:Number(n.Reduce(m).Visualize());return{redriven:c("redriven_contacts"),purged:c("purged_contacts"),deferred:c("deferred_contacts")}});(i.redriven>0||i.purged>0||i.deferred>0)&&d(`[${e.name}] unacked sweep: redriven=${i.redriven} ttl_purged=${i.purged} deferred=${i.deferred} contact(s)`)}catch(i){d(`[${e.name}] unacked redrive sweep failed:`,String(i))}}export{kt as a,De as b,J as c,Se as d,Pe as e,C as f,zt as g,we as h,M as i,D as j,ct as k,dt as l,wt as m,be as n,Ne as o,E as p,R as q,w as r,S as s,Ee as t,Ae as u,h as v,A as w,Y as x,Q as y,he as z,ve as A,Z as B,L as C,$e as D,Ge as E,Re as F};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as p}from"./chunk-65KGEJBX.js";import{a}from"./chunk-
|
|
2
|
+
import{a as p}from"./chunk-65KGEJBX.js";import{a}from"./chunk-JTBQO6IT.js";var c=class{base;leaseToken;clientPid;apiToken;fetchImpl;constructor(e){this.base=e.url.replace(/\/+$/,""),this.leaseToken=e.leaseToken,this.clientPid=e.clientPid??process.pid,this.apiToken=e.apiToken,this.fetchImpl=e.fetch??globalThis.fetch}headers(e={}){return{"x-ours-lease-token":this.leaseToken,"x-ours-client-pid":String(this.clientPid),...this.apiToken?{"x-ours-api-token":this.apiToken}:{},...e}}async post(e,i){let r=await this.fetchImpl(`${this.base}/api/v1/${e}`,{method:"POST",headers:this.headers({"content-type":"application/json"}),body:JSON.stringify(i??{})}),t;try{t=await r.json()}catch{throw new Error(`${e}: the daemon returned a non-JSON response (HTTP ${r.status})`)}if(t&&typeof t=="object"&&!Array.isArray(t)&&"error"in t){let s=t.error,o=s!==null&&typeof s=="object"&&"code"in s&&"message"in s;if(r.status===400&&o){let{code:y,message:d}=s;throw new p(y,d)}let n=o?s.message:String(s);throw new Error(`${e}: ${n} (HTTP ${r.status})`)}if(!r.ok)throw new Error(`${e}: the daemon returned HTTP ${r.status} with no error field`);return t}async get(e,i){let r=await this.fetchImpl(`${this.base}${e}`,{headers:i?this.headers():{}}),t;try{t=await r.json()}catch{throw new Error(`GET ${e}: the daemon returned a non-JSON response (HTTP ${r.status})`)}if(t&&typeof t=="object"&&"error"in t)throw new Error(`GET ${e}: ${String(t.error)} (HTTP ${r.status})`);if(!r.ok)throw new Error(`GET ${e}: the daemon returned HTTP ${r.status} with no error field`);return t}createIdentity(e){return this.post("createIdentity",e)}createTemporaryIdentity(e){return this.post("createTemporaryIdentity",e)}closeTemporaryIdentityOp(e={}){return this.post("closeTemporaryIdentityOp",e)}createRootIdentity(e){return this.post("createRootIdentity",e)}defineLocalIdentityFile(e){return this.post("defineLocalIdentityFile",e)}chooseIdentity(e){return this.post("chooseIdentity",e)}listIdentities(){return this.post("listIdentities",{})}currentIdentity(){return this.post("currentIdentity",{})}removeIdentity(e){return this.post("removeIdentity",e)}releaseLease(){return this.post("releaseLease",{})}generateInvite(e={}){return this.post("generateInvite",e)}listInvites(){return this.post("listInvites",{})}revokeInvite(e){return this.post("revokeInvite",e)}addContact(e){return this.post("addContact",e)}listContacts(){return this.post("listContacts",{})}listLocalContactBook(){return this.post("listLocalContactBook",{})}setLocalBookPolicy(e){return this.post("setLocalBookPolicy",e)}removeContact(e){return this.post("removeContact",e)}renameContact(e){return this.post("renameContact",e)}respondToIntroduction(e){return this.post("respondToIntroduction",e)}setBio(e){return this.post("setBio",e)}advertiseMigrate(){return this.post("advertiseMigrate",{})}readvertiseOnUpgrade(){return this.post("readvertiseOnUpgrade",{})}setPersona(e){return this.post("setPersona",e)}sendMessage(e){return this.post("sendMessage",e)}sendFile(e){return this.post("sendFile",e)}listIncomingMessages(){return this.post("listIncomingMessages",{})}getMessages(e={}){return this.post("getMessages",e)}listHistory(e={}){return this.post("listHistory",e)}getHistoryItem(e){return this.post("getHistoryItem",e)}getHistorySummary(e){return this.post("getHistorySummary",e)}listFiles(e={}){return this.post("listFiles",e)}getFileInfo(e){return this.post("getFileInfo",e)}listIncomingFiles(){return this.post("listIncomingFiles",{})}getFiles(e={}){return this.post("getFiles",e)}saveFileFallbackNotice(e){return this.post("saveFileFallbackNotice",e)}version(){return this.get("/version",!1)}stateDir(){return this.get("/state-dir",!1)}async identities(){return(await this.get("/identities",!0)).identities}unread(){return this.get("/unread",!0)}async*watchNotifications(e,i={}){let r=i.since??"tip",t=`/identities/${encodeURIComponent(e)}/notifications`,s=i.kinds?.length?`&kinds=${encodeURIComponent(i.kinds.join(","))}`:"";for(;!i.signal?.aborted;){let o;try{let n=await this.fetchImpl(`${this.base}${t}?since=${r}${s}`,{headers:this.headers(),signal:i.signal});try{o=await n.json()}catch{throw new Error(`watchNotifications(${e}): the daemon returned a non-JSON response (HTTP ${n.status})`)}}catch(n){if(i.signal?.aborted)return;throw n}if("error"in o)throw new Error(`watchNotifications(${e}): ${o.error}`);r=o.cursor;for(let n of o.events)yield a(n&&typeof n=="object"?n:{})}}async fetchFile(e){let i=await this.fetchImpl(`${this.base}/files/${encodeURIComponent(e)}`,{headers:this.headers()});if(!i.ok){let r=`HTTP ${i.status}`;try{let t=await i.json();t&&t.error!==void 0&&(r=String(t.error))}catch{}throw new Error(`fetchFile(${e}): ${r}`)}return new Uint8Array(await i.arrayBuffer())}async openFile(e){let i=await this.fetchImpl(`${this.base}/files/${encodeURIComponent(e)}`,{headers:this.headers()});if(!i.ok){let r=`HTTP ${i.status}`;try{let t=await i.json();t&&t.error!==void 0&&(r=String(t.error))}catch{}throw new Error(`openFile(${e}): ${r}`)}if(!i.body)throw new Error(`openFile(${e}): the daemon returned no body`);return i.body}async uploadFile(e,i){let r=e instanceof Uint8Array?e.byteLength:i.size;if(r===void 0)throw new Error("uploadFile: `size` is required when the body is a stream (the route needs Content-Length)");let t=await this.fetchImpl(`${this.base}/files/upload`,{method:"POST",headers:{...this.headers(),"x-ours-filename":encodeURIComponent(i.filename),"Content-Type":i.mime||"application/octet-stream","Content-Length":String(r)},body:e,...e instanceof Uint8Array?{}:{duplex:"half"}});if(!t.ok){let s=`HTTP ${t.status}`;try{let o=await t.json();o&&o.error!==void 0&&(s=String(o.error))}catch{}throw new Error(`uploadFile(${i.filename}): ${s}`)}return await t.json()}};export{c as a};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{c}from"./chunk-DIRW7I4S.js";import{brotliCompressSync as l,brotliDecompressSync as f}from"node:zlib";function y(e){let n=[];if(e.IsNil())return n;for(let t of e.GetKeys()){let i=e.Reduce(t);i.IsNil()||n.push({name:i.Reduce("name").Visualize(),container_id:i.Reduce("container_id").Visualize()})}return n}function V(e){let n={};if(e.IsNil())return n;for(let t of e.GetKeys()){let i=e.Reduce(t);i.IsNil()||(n[typeof t=="string"?t:t.Visualize()]=i.Visualize())}return n}function z(e){let n=[];if(e.IsNil())return n;for(let t=0;;t++){let i=e.Reduce(t);if(i.IsNil())break;let o=i.Reduce("reply_to"),s=null;if(!o.IsNil()){s={wire_id:o.Reduce("wire_id").Visualize()};let r=o.Reduce("sentence");r.IsNil()||(s.sentence=parseInt(r.Visualize(),10))}n.push({msg_id:parseInt(i.Reduce("msg_id").Visualize(),10),sender_id:i.Reduce("sender_id").Visualize(),sender_name:i.Reduce("sender_name").Visualize(),text:i.Reduce("text").Visualize(),date:i.Reduce("date").Visualize(),status:i.Reduce("status").Visualize(),wire_id:i.Reduce("wire_id").Visualize(),reply_to:s})}return n}function I(e){let n=[];if(e.IsNil())return n;for(let t=0;;t++){let i=e.Reduce(t);if(i.IsNil())break;let o=i.Reduce("filename").Visualize(),s=i.Reduce("mime").Visualize()||"application/octet-stream",r=i.Reduce("reply_to"),u=null;if(!r.IsNil()){u={wire_id:r.Reduce("wire_id").Visualize()};let a=parseInt(r.Reduce("sentence").Visualize(),10);Number.isSafeInteger(a)&&a>0&&(u.sentence=a)}n.push({file_id:parseInt(i.Reduce("file_id").Visualize(),10),wire_id:i.Reduce("wire_id").Visualize(),from:{id:i.Reduce("sender_id").Visualize(),name:i.Reduce("sender_name").Visualize()},filename:o,mime:s,size:parseInt(i.Reduce("size").Visualize(),10),size_source:"received_payload",status:i.Reduce("status").Visualize(),date:i.Reduce("date").Visualize(),sha256:null,reply_to:u,kind:c(s,o)?"voice_message":"file"})}return n}function b(e){if(e.length===0)return"No files received.";let n=[];for(let t of e){let i=t.kind==="voice_message"?"\u{1F3A4} voice message \xB7 ":"";n.push(` \u2022 ${i}${t.filename} (${t.mime}, ${t.size} B) from ${t.from.name} [${t.status}] {${t.wire_id}} sender_id=${t.from.id}`)}return`${n.length} file(s):
|
|
3
|
+
${n.join(`
|
|
4
|
+
`)}`}function N(e){let n=[];if(e.IsNil())return n;for(let t of e.GetKeys()){let i=e.Reduce(t);i.IsNil()||n.push({container_id:typeof t=="string"?t:t.Visualize(),name:i.Reduce("name").Visualize(),queued:parseInt(i.Reduce("queued").Visualize(),10)||0})}return n}function x(e){let n={};if(e.IsNil())return n;for(let t of e.GetKeys()){let i=e.Reduce(t);i.IsNil()||(n[typeof t=="string"?t:t.Visualize()]={root_cid:i.Reduce("root_cid").Visualize(),root_name:i.Reduce("root_name").Visualize(),role_id:i.Reduce("role_id").Visualize()})}return n}function A(e){if(!e)return"";let n=e.root_name||e.root_cid;return e.role_id?` [role "${e.role_id}" of ${n}]`:` [root identity of ${n}]`}function m(e){return l(e).toString("base64url")}function h(e){return f(Buffer.from(e.replace(/\s+/g,""),"base64url"))}var p=new Set(["members","caps"]);function g(e){try{let n=e.GetNumber();return Number.isInteger(n)?n:NaN}catch{return NaN}}function d(e,n){if(e.IsNil())return null;let t;try{t=e.GetKeys()}catch{try{return m(Buffer.from(e.GetBinary()))}catch{}try{return e.GetBoolean()}catch{}try{let i=e.GetNumber();if(!Number.isNaN(i))return i}catch{}return e.Visualize()}if(t.length>0){if(t.map(g).every((r,u)=>r===u))return t.map((r,u)=>d(e.Reduce(u)));let s={};for(let r of t)s[r.Visualize()]=d(e.Reduce(r),r.Visualize());return s}return n!==void 0&&p.has(n)?[]:{}}export{y as a,V as b,z as c,I as d,b as e,N as f,x as g,A as h,m as i,h as j,d as k};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
var t=e=>typeof e=="string"&&e.length>0,o=e=>({event:"sync_required",reason:"legacy_or_malformed_event",source_event:e});function s(e){if(!t(e.event))return o("unknown");if(e.event==="message_received")return!t(e.sender_id)||!t(e.sender_name)||!t(e.msg_id)||!t(e.wire_id)||!t(e.date)?o("message_received"):{event:"message_received",sender_id:e.sender_id,sender_name:e.sender_name,from:t(e.from)?e.from:e.sender_name,msg_id:e.msg_id,wire_id:e.wire_id,date:e.date};if(e.event==="receipt_received"){let n=e.kind,i=e.wire_ids;return!t(e.sender_id)||n!=="delivered"&&n!=="read"||!Array.isArray(i)||i.length===0||!i.every(t)?o("receipt_received"):{event:"receipt_received",sender_id:e.sender_id,kind:n,wire_ids:[...i],date:t(e.date)?e.date:new Date().toISOString()}}return e}var a=new Set(["receipt_received","contact_name_collision","sibling_contact_added","local_contact_request","pending_message","e2e_restore_rejected","contact_restored","migration_active","e2e_app_send","dedup_degraded","e2e_delivery_expired","e2e_app_recv","e2e_rekey","migration_deferred_flush","migration_stalled","downgrade_refused","contact_removed","monitoring_disabled","inbound_error"]),d={event:()=>{},notification:()=>{}},r={...d};function c(e,n){return r[e]=n,()=>{r[e]===n&&(r[e]=d[e])}}function _(){Object.assign(r,d)}function v(e){return r[e]===d[e]}function g(e,n){let i=s(n);r.event({identity:e.name,event:i.event,record:i})}function m(e,n){r.notification(e,n)}export{s as a,a as b,c,_ as d,v as e,g as f,m as g};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as d}from"./chunk-32DN6MBS.js";import{a as B,b as z,f as P,g as N,i as L,j as A}from"./chunk-JOKNFUW3.js";import{M as r,y as T,z as j}from"./chunk-65KGEJBX.js";import{D as I,E as S,a as V,f,q as y,r as u,s as p,v as l,z as x}from"./chunk-H7CVIQ7G.js";import{o as C}from"./chunk-GZNPN3B5.js";import{d as _,f as k}from"./chunk-5DE7MMDG.js";async function U(s,a={}){let e=d(s),{name:i,mode:o}=a;if(o==="public"&&i)throw T();try{return await u(async t=>{let n={};i&&(n.name=i),o&&(n.mode=o);let c=await l(e,"::a2a_messaging::generate_invite",n,t);return{blob:L(Buffer.from(c.Reduce("invite").GetBinary())),inviteId:c.Reduce("invite_id").Visualize(),mode:c.Reduce("mode").Visualize()==="public"?"public":"one_time"}})}catch(t){throw r("generate_invite",String(t))}}async function $(s){let a=d(s);try{return y(e=>{let i=p(a,"::a2a_messaging::list_invites",e),o=[];if(i.IsNil())return o;for(let t of i.GetKeys()){let n=i.Reduce(t);if(n.IsNil())continue;let c=n.Reduce("assigned").Visualize(),m=n.Reduce("created").Visualize();o.push({invite_id:typeof t=="string"?t:t.Visualize(),mode:n.Reduce("mode").Visualize(),assigned:c==="%%NIL"?"":c,created:m==="%%NIL"?"":m})}return o})}catch(e){throw r("list_invites",String(e))}}async function H(s,a){let e=d(s),{invite_id:i}=a;try{return await u(async o=>{let t=await l(e,"::a2a_messaging::revoke_invite",{invite_id:i},o),n=t.Reduce("was_public");return{revoked:t.Reduce("revoked").GetBoolean(),wasPublic:n.IsNil()?!1:n.GetBoolean()}})}catch(o){throw r("revoke_invite",String(o))}}async function J(s,a){let e=d(s),{invite:i,name:o}=a,t;try{if(t=A(i),t.length===0)throw new Error("the invite blob is empty")}catch(n){throw r("add_contact",n instanceof Error?n.message:"the invite blob is not valid.","INVITE_MALFORMED")}try{return await u(async n=>{let m={invite:e.pw.packet.NewBinaryFromBuffer(t).Attach(n)};o&&(m.name=o);let g=await l(e,"::a2a_messaging::add_contact",m,n),R=g.Reduce("container_id").Visualize(),v=g.Reduce("pending").Visualize(),h=g.Reduce("inviter_name").Visualize(),w=b=>!b||b==="%%NIL",G=w(v)?w(h)?R:h:v;return f(e),{display:G,cid:R}})}catch(n){throw r("add_contact",String(n))}}async function Q(s){let a=d(s);try{return y(e=>({contacts:B(p(a,"::a2a_messaging::list_contacts",e)),pending:P(p(a,"::actor::list_pending_introductions",e)),roots:N(p(a,"::a2a_messaging::list_contact_roots",e)),degraded:V(p(a,"::a2a_messaging::list_degraded_contacts",e)),renames:z(p(a,"::a2a_messaging::list_import_renames",e))}))}catch(e){throw r("list_contacts",String(e))}}async function X(s){let a=Object.values(x()),e=s.leaseToken(),i=e?k(e)?.identity:void 0;return a.map(o=>({name:o.name,container_id:o.container_id,published_at:o.published_at,isMine:o.name===i}))}async function Y(s,a){let e=d(s),{expose:i,auto_accept:o}=a;if(i===void 0&&o===void 0)throw j();let t=[];try{return o!==void 0&&(await u(async n=>{await l(e,"::actor::set_local_policy",{auto_accept:o},n)}),t.push(`auto_accept=${o}`)),i===!0?(await I(e),t.push("published in the local contact book")):i===!1&&(S(e),t.push("removed from the local contact book")),{identity:e.name,changes:t}}catch(n){throw r("set_local_book_policy",String(n))}}async function Z(s,a){let e=d(s),{contact:i}=a;try{return _.add(e.name),await u(async o=>{let t=await l(e,"::a2a_messaging::remove_contact",{contact:i},o),n=t.Reduce("removed").Visualize(),c=t.Reduce("container_id").Visualize(),m=t.Reduce("notified"),g=m.IsNil()?void 0:m.GetBoolean();return{name:n,cid:c,notified:g}})}catch(o){throw r("remove_contact",String(o))}finally{_.delete(e.name)}}async function ee(s,a){let e=d(s),{contact:i,name:o}=a;try{return await u(async t=>{let n=await l(e,"::a2a_messaging::rename_contact",{contact:i,name:o},t);return{from:n.Reduce("renamed").Visualize(),cid:n.Reduce("container_id").Visualize()}})}catch(t){throw r("rename_contact",String(t))}}async function te(s,a){let e=d(s),{contact:i,action:o}=a;try{if(o==="approve"){let t=await u(async n=>{let c=await l(e,"::actor::approve_introduction",{contact:i},n);return{action:"approve",name:c.Reduce("approved").Visualize(),cid:c.Reduce("container_id").Visualize(),flushed:c.Reduce("flushed").Visualize()}});return C(e),f(e),t}return await u(async t=>{let n=await l(e,"::actor::reject_introduction",{contact:i},t);return{action:"reject",name:n.Reduce("rejected").Visualize(),dropped:n.Reduce("dropped_messages").Visualize()}})}catch(t){throw r("respond_to_introduction",String(t))}}export{U as a,$ as b,H as c,J as d,Q as e,X as f,Y as g,Z as h,ee as i,te as j};
|