@ours.network/sdk 1.7.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -29
- package/dist/api/contacts.js +1 -1
- package/dist/api/conversations.js +1 -1
- package/dist/api/files.js +1 -1
- package/dist/api/identity.js +1 -1
- package/dist/api/messaging.js +1 -1
- package/dist/api/profile.js +1 -1
- package/dist/book.js +1 -1
- package/dist/boot.js +1 -1
- package/dist/{chunk-2BSXRX6I.js → chunk-2PVVBIA7.js} +1 -1
- package/dist/{chunk-EWT5DWPA.js → chunk-3CDGP5EO.js} +1 -1
- package/dist/chunk-3KI5FM4I.js +2 -0
- package/dist/{chunk-WOPXC4VC.js → chunk-64C2NWXL.js} +1 -1
- package/dist/{chunk-BCVDO2DW.js → chunk-7JZS2BAP.js} +1 -1
- package/dist/{chunk-ZTGUX6EV.js → chunk-AQK45DI7.js} +1 -1
- package/dist/{chunk-BWTNLYDF.js → chunk-CGAOZPMV.js} +1 -1
- package/dist/{chunk-4SXZ6CUL.js → chunk-CGXQP3Q4.js} +1 -1
- package/dist/chunk-CHDY74S7.js +3 -0
- package/dist/chunk-CIHGEBUR.js +2 -0
- package/dist/{chunk-IU6MOFTJ.js → chunk-EHCBEY52.js} +1 -1
- package/dist/{chunk-SBQCXH54.js → chunk-HPPNU5YV.js} +1 -1
- package/dist/{chunk-K2UCTMMS.js → chunk-K7TLSZ3X.js} +1 -1
- package/dist/{chunk-G3CKYZJ7.js → chunk-MQ5AXTPT.js} +1 -1
- package/dist/{chunk-E2RQVNQK.js → chunk-OWZIFNZN.js} +1 -1
- package/dist/{chunk-JHS7YUMA.js → chunk-PQXV4GQ5.js} +1 -1
- package/dist/chunk-R5ISAB5B.js +2 -0
- package/dist/{chunk-QXKDTQMT.js → chunk-T76BFV6S.js} +1 -1
- package/dist/{chunk-ARYFH7MF.js → chunk-TIBWO3T3.js} +1 -1
- package/dist/{chunk-3RZX2WOJ.js → chunk-TUWHVJ37.js} +1 -1
- package/dist/{chunk-LIJDSFUD.js → chunk-V7PKYHV7.js} +1 -1
- package/dist/{chunk-UOHHUOWR.js → chunk-W2BPK7VV.js} +1 -1
- package/dist/chunk-WS6UFNKF.js +5 -0
- package/dist/{chunk-PPJAMKLP.js → chunk-XT75POTM.js} +1 -1
- package/dist/chunk-Y3VPZJTG.js +2 -0
- package/dist/client/http.d.ts +5 -0
- package/dist/client/select.d.ts +29 -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/config.d.ts +0 -1
- package/dist/config.js +1 -1
- package/dist/connector.js +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/gc.js +1 -1
- package/dist/http/api-routes.js +1 -1
- package/dist/http/server.d.ts +2 -0
- 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 +1 -2
- package/dist/identity/model.js +1 -1
- package/dist/identity/provision.js +1 -1
- package/dist/index.d.ts +3 -11
- package/dist/index.js +1 -1
- package/dist/internal/daemon.d.ts +11 -0
- package/dist/internal/daemon.js +2 -0
- package/dist/internal/state-root-lock.d.ts +25 -0
- package/dist/internal/state-root-lock.js +2 -0
- 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 +0 -0
- package/dist/notify.js +1 -1
- package/dist/render/adapt-to-json.js +1 -1
- package/dist/runtime/config-drift.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 +3 -7
- package/dist/chunk-EUILVQOZ.js +0 -2
- package/dist/chunk-IB2U7K6Y.js +0 -5
- package/dist/chunk-IDH22QWU.js +0 -2
- package/dist/chunk-NOOGH2RZ.js +0 -2
- package/dist/chunk-SYRQA3MQ.js +0 -2
- package/dist/daemon.d.ts +0 -5
- package/dist/daemon.js +0 -2
package/README.md
CHANGED
|
@@ -1,52 +1,69 @@
|
|
|
1
1
|
# @ours.network/sdk
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
3
|
+
The typed application client for the shared [ours](https://ours.network)
|
|
4
|
+
daemon, plus the daemon's package-private runtime used by the operator CLI.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
definitions, result formatting and CLI text.
|
|
6
|
+
One loopback daemon normally owns all runtime and global identity state for an
|
|
7
|
+
OS user. Applications attach as clients and keep any application-specific
|
|
8
|
+
identity lists in their own configuration. Those lists are organizational
|
|
9
|
+
bookkeeping, not a daemon authorization boundary.
|
|
11
10
|
|
|
12
11
|
## Exports
|
|
13
12
|
|
|
14
13
|
| Entry point | What it gives you |
|
|
15
14
|
|---|---|
|
|
16
|
-
| `@ours.network/sdk` |
|
|
17
|
-
| `@ours.network/sdk/
|
|
15
|
+
| `@ours.network/sdk` | Client-only default: `attachOursClient`, `OursClient`, client errors/types, and engine-free utilities |
|
|
16
|
+
| `@ours.network/sdk/client` | The same client/attach surface for dependency-graph enforcement |
|
|
18
17
|
| `@ours.network/sdk/connector` | `runProxy(opts)` — the stdio↔HTTP connector client |
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
There is deliberately no public daemon or kernel entry. `startDaemon` and
|
|
20
|
+
`bootWrapper` are not package exports. Install and operate the daemon through
|
|
21
|
+
`@ours.network/cli`; SDK applications never fall back to an embedded runtime.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
`SIGTERM` handlers that tear down the daemon and exit the process. An embedded
|
|
24
|
-
host can retain process ownership by passing `handleSignals: false`:
|
|
23
|
+
## Attach to the shared daemon
|
|
25
24
|
|
|
26
25
|
```ts
|
|
27
|
-
|
|
26
|
+
import { attachOursClient } from '@ours.network/sdk';
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const ours = await attachOursClient({
|
|
29
|
+
leaseToken: 'a-stable-token-owned-by-this-application-session',
|
|
30
|
+
});
|
|
31
|
+
const identities = await ours.listIdentities();
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
`attachOursClient` resolves endpoint, state directory and token as one coherent
|
|
35
|
+
selection. It calls unauthenticated `/state-dir` first; only after the daemon
|
|
36
|
+
proves it owns the expected state root can a credential-bearing request be sent.
|
|
37
|
+
A missing daemon raises `DaemonUnavailableError` with the CLI install/start
|
|
38
|
+
commands. Direct `new OursClient(...)` remains a low-level, unverified seam for
|
|
39
|
+
injected tests and expert transports.
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
Old `autoStart` JSON and `OURS_AUTOSTART` are ignored in SDK 2. Start the daemon
|
|
42
|
+
with `ours daemon start` or install its per-user service with
|
|
43
|
+
`ours daemon install-service`.
|
|
44
|
+
|
|
45
|
+
## Internal singleton contract
|
|
46
|
+
|
|
47
|
+
The CLI bundle acquires a cross-process lock before importing any module that
|
|
48
|
+
can write startup progress, mint the daemon token, restore identities, start the
|
|
49
|
+
native engine, or arm GC. The lock is keyed by the canonical state directory and
|
|
50
|
+
uses this live Unix-domain socket:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
/tmp/ours-<uid>/locks/<sha256(canonical-state-dir)>.sock
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`/tmp/ours-<uid>` and `locks` must be real, owner-owned mode-0700 directories.
|
|
57
|
+
The fixed ASCII pathname is at most 96 bytes for a ten-digit uid, below macOS's
|
|
58
|
+
approximately 104-byte `sun_path` limit. A live socket reports the owner PID and
|
|
59
|
+
state root; an `ECONNREFUSED` stale pathname after crash/SIGKILL is removed and
|
|
60
|
+
retried. Ambiguous probes are never stolen. This contract supports Linux and
|
|
61
|
+
macOS only; other platforms refuse daemon startup instead of skipping the lock.
|
|
45
62
|
|
|
46
63
|
## Operator CLI
|
|
47
64
|
|
|
48
65
|
The supported operator surface is the separate `@ours.network/cli` workspace,
|
|
49
|
-
whose executable is `ours`. The SDK package remains library
|
|
66
|
+
whose executable is `ours`. The SDK package remains client/library-only and
|
|
50
67
|
does not claim a bin. See [packages/cli/README.md](packages/cli/README.md) for
|
|
51
68
|
commands and [CLI-MIGRATION.md](CLI-MIGRATION.md) for the ours-mcp and connector
|
|
52
69
|
ownership boundary.
|
|
@@ -59,7 +76,9 @@ Node ≥ 20. The MUFL packet is compiled from `mufl_code/`, which pins the
|
|
|
59
76
|
## Build and test
|
|
60
77
|
|
|
61
78
|
```bash
|
|
62
|
-
npm ci
|
|
79
|
+
# This helper is a normal lockfile-strict npm ci; on a pre-release 1.x checkout
|
|
80
|
+
# it temporarily presents the automation-owned 2.0 workspace version, then restores it.
|
|
81
|
+
bash scripts/npm-ci-major-workspace.sh
|
|
63
82
|
npm run build
|
|
64
83
|
npm test
|
|
65
84
|
```
|
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-TIBWO3T3.js";import"../chunk-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.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};
|
|
@@ -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-XT75POTM.js";import"../chunk-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{a as getConversation,b as getReceipts,c as markRead,d as setConversationPolicy};
|
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,d}from"../chunk-
|
|
2
|
+
import{a,b,c,d}from"../chunk-R5ISAB5B.js";import"../chunk-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{d as deferFiles,b as getFiles,a as listIncomingFiles,c as saveFileFallbackNotice};
|
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-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.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.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}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e}from"../chunk-AQK45DI7.js";import"../chunk-OWZIFNZN.js";import"../chunk-VXVW4KJU.js";import"../chunk-V7PKYHV7.js";import"../chunk-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{e as deferMessages,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-64C2NWXL.js";import"../chunk-HPPNU5YV.js";import"../chunk-K7TLSZ3X.js";import"../chunk-65KGEJBX.js";import"../chunk-3CDGP5EO.js";import"../chunk-CGAOZPMV.js";import"../chunk-2PVVBIA7.js";import"../chunk-MQ5AXTPT.js";import"../chunk-YRPUM6JG.js";import"../chunk-TUWHVJ37.js";import"../chunk-DIRW7I4S.js";import"../chunk-7JZS2BAP.js";import"../chunk-CIHGEBUR.js";import"../chunk-T76BFV6S.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{b as advertiseMigrate,d as readvertiseOnUpgrade,a as setBio,c as setPersona};
|
package/dist/book.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{N as a,O as b,P as c,Q as d,R as e,S as f,T as g,U as h,V as i,W as j}from"./chunk-
|
|
2
|
+
import{N as a,O as b,P as c,Q as d,R as e,S as f,T as g,U as h,V as i,W as j}from"./chunk-MQ5AXTPT.js";import"./chunk-YRPUM6JG.js";import"./chunk-TUWHVJ37.js";import"./chunk-DIRW7I4S.js";import"./chunk-7JZS2BAP.js";import"./chunk-CIHGEBUR.js";import"./chunk-T76BFV6S.js";import"./chunk-ZHH3PWEW.js";import"./chunk-LKFYUCN7.js";import"./chunk-Y3VPZJTG.js";import"./chunk-P55RJGZU.js";import"./chunk-XYU2DSWR.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-W2BPK7VV.js";import"./chunk-EHCBEY52.js";import"./chunk-K7TLSZ3X.js";import"./chunk-3CDGP5EO.js";import"./chunk-CGAOZPMV.js";import"./chunk-2PVVBIA7.js";import"./chunk-MQ5AXTPT.js";import"./chunk-YRPUM6JG.js";import"./chunk-TUWHVJ37.js";import"./chunk-DIRW7I4S.js";import"./chunk-7JZS2BAP.js";import"./chunk-CIHGEBUR.js";import"./chunk-T76BFV6S.js";import"./chunk-ZHH3PWEW.js";import"./chunk-LKFYUCN7.js";import"./chunk-Y3VPZJTG.js";import"./chunk-P55RJGZU.js";import"./chunk-XYU2DSWR.js";import"./chunk-WS6UFNKF.js";export{b as bootWrapper,a as wrapperBooted};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{H as m,I as p,J as l,M as a,S as f}from"./chunk-
|
|
2
|
+
import{H as m,I as p,J as l,M as a,S as f}from"./chunk-MQ5AXTPT.js";import{c as u}from"./chunk-CIHGEBUR.js";import{c as d,i}from"./chunk-T76BFV6S.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};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as l}from"./chunk-
|
|
2
|
+
import{a as l}from"./chunk-CGAOZPMV.js";import{e as o}from"./chunk-2PVVBIA7.js";import{I as p,J as f,M as m}from"./chunk-MQ5AXTPT.js";import{c as r}from"./chunk-CIHGEBUR.js";import{i as u}from"./chunk-T76BFV6S.js";var A=()=>d,d=!0,C=d?2:1;function g(e,n){let a=[];for(let t of r.values()){if(t.name===e.name)continue;let i=o(t);if(i.rootCid!==e.cid)continue;let c=f(t,"::actor::export_address_document_native",n);a.push({cid:c.Reduce("identity").Reduce("container_id"),role_id:i.roleId,name:t.name,bio:i.bio,persona:i.persona,caps:l(t),child_ad:c})}return a}var s=new Set;async function y(e){if(!s.has(e.name)){s.add(e.name);try{await p(async n=>{await m(e,"::a2a_cluster::reconcile",{pending_handle:"",children:g(e,n)},n)})}catch(n){u(`[${e.name}] cluster sweep failed:`,String(n))}finally{s.delete(e.name)}}}var w=6e4;function T(){setInterval(()=>{if(d)for(let e of r.values())o(e).roleId===""&&y(e)},w).unref()}export{A as a,C as b,y as c,T as d};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as O}from"./chunk-OA7XXAFG.js";import{b as N,e as T}from"./chunk-WS6UFNKF.js";import{randomBytes as I}from"node:crypto";import{readFileSync as w}from"node:fs";import{homedir as x}from"node:os";import{join as v,resolve as p}from"node:path";var a=class extends Error{constructor(i,n){super(n);this.code=i;this.name="DaemonSelectionError"}},S=class extends a{constructor(i,n,d={}){super("DAEMON_UNAVAILABLE",`no ours daemon is running at ${i} for state directory ${JSON.stringify(n)}. Install the operator CLI with \`npm install --global @ours.network/cli\`, then start the shared daemon with \`ours daemon start\` or install/start its per-user service through \`ours daemon install-service\`. SDK applications attach to the shared daemon and do not start an embedded daemon.`);this.endpoint=i;this.stateDir=n;this.name="DaemonUnavailableError",d.cause!==void 0&&(this.cause=d.cause)}},b=N.port,C=T,R=".ours",k=["explicit","environment","config-file"];function _(e={}){let t=e.env??process.env,i=e.readTextFile??(h=>w(h,"utf8")),n=e.homeDir??x(),d=f(t,"OURS_INSTANCE");if(d!==void 0)throw new a("INCOHERENT_SELECTION",`OURS_INSTANCE=${JSON.stringify(d)} is set, but named daemon instances are not implemented. Select the daemon with an explicit endpoint/port option or with OURS_PORT, and unset OURS_INSTANCE.`);if(e.stateDir!==void 0&&e.expectStateDir!==void 0){let h=p(e.stateDir),D=p(e.expectStateDir);if(h!==D)throw new a("INCOHERENT_SELECTION",`stateDir ${JSON.stringify(h)} and expectStateDir ${JSON.stringify(D)} name different directories. The state directory decides which token is read; the expected one decides which daemon that token may be sent to. Reconcile them, or pass only one.`)}let r=V(e.configPath,f(t,"OURS_CONFIG")),s=r?L(r.value,i):{},o=E(e.port,F(f(t,"OURS_PORT")),s.port,b),c=E(e.stateDir??e.expectStateDir,f(t,"OURS_STATE_DIR"),s.stateDir,v(n,R)),l={value:p(c.value),source:c.source},g=e.endpoint!==void 0?{value:P(e.endpoint),source:"explicit"}:{value:`http://127.0.0.1:${o.value}`,source:o.source},m=f(t,"OURS_API_TOKEN");A({endpointSelected:e.endpoint!==void 0||o.source!=="default",endpointSource:g.source,stateDirIntentional:k.includes(l.source),stateDirSource:l.source,hasExplicitToken:e.token!==void 0&&e.token!=="",hasEnvToken:m!==void 0,requireExplicitSelection:e.requireExplicitSelection===!0,portSource:o.source});let y=U(e.token,m,s,l,i);return{baseUrl:g,port:o,stateDir:l,expectStateDir:e.expectStateDir!==void 0?p(e.expectStateDir):l.value,...y?{token:y}:{},...r?{configPath:r}:{}}}function K(e){return{baseUrl:e.baseUrl.value,baseUrlSource:e.baseUrl.source,port:e.port.value,portSource:e.port.source,stateDir:e.stateDir.value,stateDirSource:e.stateDir.source,expectStateDir:e.expectStateDir,tokenSource:e.token?.source??"none",configPath:e.configPath?.value??null}}function A(e){if(e.requireExplicitSelection){if(e.endpointSource==="default"&&e.portSource==="default")throw u(`requireExplicitSelection is set, but no daemon was selected. Pass endpoint/port, set OURS_PORT, or point OURS_CONFIG at a config file. Refusing the built-in default 127.0.0.1:${b}.`);if(!e.stateDirIntentional)throw u("requireExplicitSelection is set, but the state directory is the built-in default. Every auth-affecting field must be chosen deliberately: pass stateDir or expectStateDir, set OURS_STATE_DIR, or name a config file. Refusing before reading any token or opening any socket.")}if(e.endpointSelected&&!e.stateDirIntentional)throw u(`the endpoint was selected (source: ${e.endpointSource}) but the state directory is the built-in default. A daemon's API token belongs to one state directory, so reading the default token and sending it to a separately chosen endpoint would disclose a credential to it. Select the state directory too: stateDir, expectStateDir, OURS_STATE_DIR, or one config file. An explicit token alone is not enough \u2014 without an expected state directory there is nothing to assert the endpoint against before the token is sent.`);if(e.hasEnvToken&&!e.stateDirIntentional)throw u("OURS_API_TOKEN is set, but the state directory is the built-in default. An environment token is process-wide and authenticates to every daemon it is offered to, so it requires an explicitly expected state directory: pass stateDir or expectStateDir, or set OURS_STATE_DIR.");if(e.hasExplicitToken&&!e.stateDirIntentional)throw u("an explicit token was given, but the state directory is the built-in default, so there would be nothing to assert the daemon against before the token is sent. Pass expectStateDir (or stateDir) naming the state directory that token belongs to.")}function u(e){return new a("INCOHERENT_SELECTION",e)}function U(e,t,i,n,d){if(e!==void 0&&e!=="")return{value:e,source:"explicit"};if(t!==void 0)return{value:t,source:"environment"};let r=i.apiToken?.trim();if(r)return{value:r,source:"config-file"};try{let s=d(v(n.value,C)).trim();if(s)return{value:s,source:"token-file"}}catch{}}function L(e,t){let i;try{i=t(e)}catch{throw new a("CONFIG_UNREADABLE",`the daemon config file ${JSON.stringify(e)} could not be read.`)}let n;try{n=JSON.parse(i)}catch{throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} is not valid JSON.`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} is not a JSON object.`);let d=n,r={},s=d.port;if(s!==void 0){if(typeof s!="number"||!Number.isInteger(s)||s<1||s>65535)throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid port; expected an integer 1-65535.`);r.port=s}let o=d.stateDir;if(o!==void 0){if(typeof o!="string"||o.trim()==="")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid stateDir; expected a non-empty string.`);r.stateDir=o}let c=d.apiToken;if(c!==void 0){if(typeof c!="string"||c.trim()==="")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid apiToken; expected a non-empty string.`);r.apiToken=c}let l=d.apiVisibility;if(l!==void 0){if(l!=="owner"&&l!=="shared"&&l!=="open")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an unknown apiVisibility ${JSON.stringify(l)}; expected "owner", "shared" or "open".`);r.apiVisibility=l}return r}function f(e,t){let i=e[t];if(i===void 0)return;let n=i.trim();return n===""?void 0:n}function F(e){if(e===void 0)return;let t=Number.parseInt(e,10);if(!Number.isInteger(t)||t<1||t>65535)throw new a("INCOHERENT_SELECTION",`OURS_PORT=${JSON.stringify(e)} is not a TCP port between 1 and 65535.`);return t}function P(e){return e.endsWith("/")?e.slice(0,-1):e}function E(e,t,i,n){return e!==void 0?{value:e,source:"explicit"}:t!==void 0?{value:t,source:"environment"}:i!==void 0?{value:i,source:"config-file"}:{value:n,source:"default"}}function V(e,t){if(e!==void 0)return{value:e,source:"explicit"};if(t!==void 0)return{value:t,source:"environment"}}async function $(e,t={}){let i=t.fetch??globalThis.fetch,n=new AbortController,d=setTimeout(()=>n.abort(),t.timeoutMs??5e3),r;try{let o=await i(`${e.baseUrl.value}/state-dir`,{signal:n.signal});if(!o.ok)throw new a("INCOHERENT_SELECTION",`${e.baseUrl.value}/state-dir answered HTTP ${o.status}, so the daemon at that address could not be identified. Refusing to send a credential to it.`);r=await o.json()}catch(o){throw o instanceof a?o:new S(e.baseUrl.value,e.expectStateDir,{cause:o})}finally{clearTimeout(d)}let s=typeof r.stateDir=="string"?p(r.stateDir):null;if(s===null)throw new a("INCOHERENT_SELECTION",`${e.baseUrl.value}/state-dir did not report a state directory, so this is not an ours daemon or not one this client understands. Refusing to send a credential to it.`);if(s!==e.expectStateDir)throw new a("INCOHERENT_SELECTION",`the daemon at ${e.baseUrl.value} owns state directory ${JSON.stringify(s)}, but this selection expects ${JSON.stringify(e.expectStateDir)}. The token belongs to the expected directory, so it is NOT being sent. Point the endpoint and the state directory at the same daemon.`)}async function j(e={}){let{leaseToken:t,clientPid:i,fetch:n,...d}=e,r=_(d);return await $(r,{fetch:n}),new O({url:r.baseUrl.value,leaseToken:t??I(32).toString("hex"),clientPid:i,apiToken:r.token?.value,fetch:n})}export{a,S as b,b as c,C as d,_ as e,K as f,$ as g,j as h};
|
|
@@ -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-HPPNU5YV.js";import{M as d}from"./chunk-65KGEJBX.js";import{b as g,e as f,f as p}from"./chunk-2PVVBIA7.js";import{I as o,M as n}from"./chunk-MQ5AXTPT.js";import{c as m}from"./chunk-CIHGEBUR.js";import{i as u}from"./chunk-T76BFV6S.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{c as a}from"./chunk-
|
|
2
|
+
import{c as a}from"./chunk-CIHGEBUR.js";import{c as d,i as u}from"./chunk-T76BFV6S.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{g as z}from"./chunk-
|
|
2
|
+
import{g as z}from"./chunk-OWZIFNZN.js";import{b as D,g as V}from"./chunk-VXVW4KJU.js";import{a as O,b as q,c as L,d as v}from"./chunk-V7PKYHV7.js";import{a as u}from"./chunk-HPPNU5YV.js";import{A as P,B as M,C as N,D as T,E as U,F as C,M as c,a as F}from"./chunk-65KGEJBX.js";import{H as k,I as p,J as E,M as _,j as S,k as A,p as x}from"./chunk-MQ5AXTPT.js";import{c as b}from"./chunk-TUWHVJ37.js";import{i as f}from"./chunk-T76BFV6S.js";import{d as $}from"./chunk-LKFYUCN7.js";import{a as R}from"./chunk-P55RJGZU.js";import{readFile as G}from"node:fs/promises";import{basename as H}from"node:path";function j(s,i){if(s)return i!==void 0?{wire_id:s,sentence:i}:{wire_id:s}}async function de(s,i){let t=u(s),{contact:a,text:n}=i,d=j(i.reply_to_wire_id,i.reply_to_sentence);try{let r=await p(async o=>v(await _(t,"::a2a_messaging::send_message",{contact:a,text:n,...d?{reply_to:d}:{}},o)));switch(r.kind){case"refused":f(`[e2e-route] refused cid=${r.cid} wire_id=${r.wireId} (downgrade_refused)`);break;case"migrating":f(`[migration] queued cid=${r.cid} wire_id=${r.wireId} (migrating, ${r.queued} queued)`);break;case"e2e":f(`[e2e-route] cid=${r.cid} wire_id=${r.wireId} verdict=e2e (core delivered over migrated session)${r.notRetained?" NOT RETAINED (oversized)":""}`),r.notRetained&&S(t,{event:"send_not_retained",wire_id:r.wireId,kind:"message"});break;default:break}return r}catch(r){if(!/Unknown contact/.test(String(r)))throw c("send_message",String(r));try{let o=O(t,a);return{kind:"introduced",text:o?await q(t,o,n):await L(t,a,n)}}catch(o){throw c("send_message",String(o),"FALLBACK_FAILED")}}}async function ce(s,i){let t=u(s),{contact:a,path:n,data_base64:d,upload_id:r,filename:o,mime:B}=i;if((n?1:0)+(d?1:0)+(r?1:0)!=1)throw r?T():P();let l,m,I=null;try{if(n)l=await G(n),m=o??H(n);else if(r){let e=z(t,r);if(!e)throw U(r);I=e.meta,l=e.buf,m=o??e.meta.filename}else{if(!o)throw M();l=Buffer.from(d,"base64"),m=o}}catch(e){throw e instanceof F?e:N(String(e))}let y=B??(n?R(n):I?.mime||""),h=j(i.reply_to_wire_id,i.reply_to_sentence),W=D(),g;try{g=k(e=>V({packet:{NewBinaryFromBuffer:w=>t.pw.packet.NewBinaryFromBuffer(w)},lifetime:e,filename:m,mime:y,payload:l,replyTo:h,cap:W}))}catch(e){throw e instanceof F?e:c("send_file",String(e))}if(!g.ok)throw C({filename:m,bytes:g.bytes,limit:g.cap,envelopeBytes:g.envelopeBytes,maxPayloadBytes:g.maxPayloadBytes});try{let e=await p(async w=>{let K=t.pw.packet.NewBinaryFromBuffer(l).Attach(w);return v(await _(t,"::a2a_messaging::send_file",{contact:a,filename:m,mime:y,data:K,...h?{reply_to:h}:{}},w))});switch(e.kind){case"refused":f(`[e2e-route] refused cid=${e.cid} wire_id=${e.wireId} (downgrade_refused, file)`);break;case"migrating":f(`[migration] file-defer cid=${e.cid} wire_id=${e.wireId} (migrating, not queued)`);break;case"e2e":f(`[e2e-route] cid=${e.cid} wire_id=${e.wireId} verdict=e2e file (core delivered over migrated session)${e.notRetained?" NOT RETAINED (oversized)":""}`),e.notRetained&&S(t,{event:"send_not_retained",wire_id:e.wireId,kind:"file"});break;default:break}return{...e,filename:m,bytes:l.length,mime:y}}catch(e){throw c("send_file",String(e))}}async function me(s){let i=u(s);try{return k(t=>b(E(i,"::actor::list_incoming_messages",t)))}catch(t){throw c("list_incoming_messages",String(t))}}async function fe(s){let i=u(s);try{let t=await p(async n=>{let d=await _(i,"::actor::get_messages",{},n);return b(d.Reduce("messages"))});x(i);let a=A(i);return $(t,a)}catch(t){throw c("get_messages",String(t))}}async function le(s,i){let t=u(s),{msg_ids:a}=i;try{let n=await p(async d=>(await _(t,"::actor::defer_messages",{msg_ids:a},d)).Reduce("deferred").Visualize());return x(t),{deferred:n}}catch(n){throw c("defer_messages",String(n))}}export{de as a,ce as b,me as c,fe as d,le as e};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{e as d}from"./chunk-
|
|
2
|
+
import{e as d}from"./chunk-2PVVBIA7.js";import{H as a,J as c}from"./chunk-MQ5AXTPT.js";import{c as s}from"./chunk-CIHGEBUR.js";function y(e){try{return a(n=>{let i=c(e,"::a2a_capabilities::get_manifest",n).Reduce("capabilities");return i.IsNil()?[]:[...i.GetKeys()].map(t=>typeof t=="string"?t:t.Visualize())})}catch{return[]}}function R(e){let n="",i="",t="",u="",l=[];try{a(g=>{let p=c(e,"::a2a_capabilities::get_manifest",g),r=o=>{let f=p.Reduce(o);return f.IsNil()?"":f.Visualize()};n=r("app_id"),i=r("name"),t=r("description"),u=r("version");let m=p.Reduce("capabilities");m.IsNil()||(l=[...m.GetKeys()].map(o=>typeof o=="string"?o:o.Visualize()))})}catch{}return{app_id:n,name:i,description:t,version:u,capabilities:l,monitoring_status:"unbound"}}function h(e){let n=[];for(let i of s.values()){if(i.name===e.name)continue;let t=d(i);t.rootCid===e.cid&&n.push({name:i.name,cid:i.cid,role_id:t.roleId,bio:t.bio,monitoring:t.monitoringEnabled,capabilities:y(i)})}return n}function v(e,n){let i=s.get(n)??[...s.values()].find(t=>t.cid===n);return!i||i.name===e.name?null:d(i).rootCid===e.cid?i:null}export{y as a,R as b,h as c,v as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as M,b,c as F,d as w,e as T,f as N,g as L,h as H,i as B,j}from"./chunk-
|
|
2
|
+
import{a as M,b,c as F,d as w,e as T,f as N,g as L,h as H,i as B,j}from"./chunk-TIBWO3T3.js";import{a as E,b as J,c as _,d as $}from"./chunk-XT75POTM.js";import{a as U,b as V,c as X,d as q}from"./chunk-R5ISAB5B.js";import{a as z,b as D,c as G,d as K,e as Q}from"./chunk-AQK45DI7.js";import{a as W,b as Y,c as Z,d as ee}from"./chunk-64C2NWXL.js";import{b as u,c as v,d as k,e as R,f as C,g as S,h as x,i as h,j as P,k as O}from"./chunk-HPPNU5YV.js";import{a as I}from"./chunk-65KGEJBX.js";import{c as d}from"./chunk-7JZS2BAP.js";import{o as f}from"./chunk-CIHGEBUR.js";import{i as m,m as y}from"./chunk-T76BFV6S.js";var ne="/api/v1/",e=i=>(t,n)=>i(t,n),s=i=>t=>i(t),oe=i=>(t,n)=>i(n),te={createIdentity:e(u),createTemporaryIdentity:e(v),closeTemporaryIdentityOp:e(k),createRootIdentity:e(R),defineLocalIdentityFile:oe(C),chooseIdentity:e(S),listIdentities:s(x),currentIdentity:s(h),removeIdentity:e(P),releaseLease:s(O),generateInvite:e(M),listInvites:s(b),revokeInvite:e(F),addContact:e(w),listContacts:s(T),listLocalContactBook:s(N),setLocalBookPolicy:e(L),removeContact:e(H),renameContact:e(B),respondToIntroduction:e(j),setBio:e(W),advertiseMigrate:s(Y),readvertiseOnUpgrade:s(ee),setPersona:e(Z),sendMessage:e(z),sendFile:e(D),listIncomingMessages:s(G),getMessages:s(K),deferMessages:e(Q),deferFiles:e(q),getConversation:e(E),getReceipts:e(J),markRead:e(_),setConversationPolicy:e($),listIncomingFiles:s(U),getFiles:e(V),saveFileFallbackNotice:e(X)},l=new Map,ie=(i,t)=>{let n=i.headers[t];return typeof n=="string"&&n!==""?n:void 0};function se(i){let t=ie(i,"x-ours-lease-token"),n=ie(i,"x-ours-client-pid"),A=n?parseInt(n,10):NaN,a=Number.isInteger(A)?A:void 0,o=t?`api:${f(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 fe(i,t,n,A){let a=n.slice(ne.length);if(!y(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(te,a)?te[a]:void 0;if(!o){p(t,404,{error:`unknown operation "${a}"`});return}let r;try{r=await A(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 g=se(i);try{p(t,200,await o(g.ctx,r))}catch(c){if(c instanceof I){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{g.release()}}export{ne as a,te as b,se as c,fe as d};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{createHash as k}from"node:crypto";import*as a from"node:fs";import*as l from"node:net";import{dirname as S,join as m,resolve as y}from"node:path";var g=new Set(["linux","darwin"]),h=103,p=8,u=class extends Error{constructor(t,n,i){super(`ours daemon state directory ${JSON.stringify(t)} is already owned by `+(n===null?"another live process":`pid ${n}`)+". Stop that daemon through the ours CLI before starting another one for the same state directory.");this.stateDir=t;this.ownerPid=n;this.owner=i;this.name="StateRootLockedError"}code="STATE_ROOT_LOCKED"};function d(r){return r&&typeof r=="object"&&"code"in r?String(r.code):void 0}function E(r){let o=y(r),t=[];for(;;)try{let n=a.realpathSync.native(o);return y(n,...t.reverse())}catch(n){if(d(n)!=="ENOENT")throw n;let i=S(o);if(i===o)throw n;t.push(o.slice(i.length+(i.endsWith("/")?0:1))),o=i}}function w(r,o){try{a.mkdirSync(r,{mode:448})}catch(n){if(d(n)!=="EEXIST")throw n}let t=a.lstatSync(r);if(!t.isDirectory()||t.isSymbolicLink())throw new Error(`daemon lock path ${JSON.stringify(r)} must be a real directory, not a symlink or file`);if(t.uid!==o)throw new Error(`daemon lock path ${JSON.stringify(r)} is owned by uid ${t.uid}, expected uid ${o}`);a.chmodSync(r,448)}function O(r){if(!g.has(process.platform))throw new Error(`the ours daemon state-root lock supports Linux and macOS only; platform ${JSON.stringify(process.platform)} has no verified Unix-domain-socket lock contract, so startup is refused`);let o=process.getuid;if(typeof o!="function")throw new Error("the ours daemon state-root lock requires a Unix uid; startup is refused");let t=o.call(process),n=`/tmp/ours-${t}`,i=m(n,"locks");w(n,t),w(i,t);let c=k("sha256").update(r).digest("hex"),e=m(i,`${c}.sock`);if(Buffer.byteLength(e)>h)throw new Error(`daemon lock socket path is ${Buffer.byteLength(e)} bytes, exceeding the portable ${h}-byte Linux/macOS contract: ${JSON.stringify(e)}`);return{directory:i,socketPath:e}}function b(r){return new Promise(o=>{let t=l.createConnection(r),n="",i=!1,c=e=>{i||(i=!0,t.destroy(),o(e))};t.setEncoding("utf8"),t.setTimeout(1e3),t.on("data",e=>{n+=e}),t.once("end",()=>{try{let e=JSON.parse(n),s=Number.isInteger(e.pid)&&typeof e.stateDir=="string"&&typeof e.startedAt=="string"?e:null;c({kind:"live",owner:s})}catch{c({kind:"live",owner:null})}}),t.once("timeout",()=>c({kind:"ambiguous",error:new Error("timed out probing the live lock socket")})),t.once("error",e=>{let s=d(e);c(s==="ECONNREFUSED"||s==="ENOENT"?{kind:"stale"}:{kind:"ambiguous",error:e})})})}function N(r,o){return new Promise((t,n)=>{let i=c=>n(c);r.once("error",i),r.listen(o,()=>{r.off("error",i),t()})})}async function L(r){let o=E(r),{socketPath:t}=O(o),n={pid:process.pid,stateDir:o,startedAt:new Date().toISOString()};for(let i=1;i<=p;i++){let c=l.createServer(e=>e.end(`${JSON.stringify(n)}
|
|
3
|
+
`));try{await N(c,t),c.unref();let e=!1;return{stateDir:o,socketPath:t,owner:n,close:async()=>{if(!e){e=!0,await new Promise(s=>c.close(()=>s()));try{a.unlinkSync(t)}catch(s){if(d(s)!=="ENOENT")throw s}}}}}catch(e){try{c.close()}catch{}if(d(e)!=="EADDRINUSE")throw e;let s=await b(t);if(s.kind==="live")throw new u(o,s.owner?.pid??null,s.owner);if(s.kind==="ambiguous")throw new Error(`could not prove whether daemon lock ${JSON.stringify(t)} is live or stale; refusing to remove it: ${s.error.message}`);try{a.unlinkSync(t)}catch(f){if(d(f)!=="ENOENT")throw f}}}throw new Error(`could not acquire daemon state-root lock for ${JSON.stringify(o)} after ${p} races`)}export{u as a,E as b,O as c,L as d};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{c as i,i as a}from"./chunk-T76BFV6S.js";import{join as n}from"node:path";import{createHash as u}from"node:crypto";import*as r from"node:fs";var m;function v(t){m=t}var T=new Map,g=null,y=null;function I(t){g=t}function _(t){y=t}var F=t=>n(i,t),d=t=>n(t,"identity.key"),h=t=>n(t,"state_data.bin"),W=t=>n(t,"notifications.log"),E=t=>n(t,"unread.json"),x=t=>n(t.dir,"files"),c=t=>n(t,"temp.json"),H=t=>u("sha256").update(t).digest("hex");function M(t,e){r.writeFileSync(c(t),JSON.stringify({v:1,owner:{token_sha256:e.owner.tokenHash,pid:e.owner.pid},created_at:e.createdAt}),{mode:384})}function R(t){try{let e=JSON.parse(r.readFileSync(c(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 $(){for(let t of w()){let e=n(i,t);try{r.chmodSync(e,448)}catch(o){a(`[${t}] chmod 0700 failed:`,String(o))}for(let o of[h(e),d(e)])if(r.existsSync(o))try{r.chmodSync(o,384)}catch(s){a(`[${t}] chmod 0600 ${o} failed:`,String(s))}}}var k=t=>/^[A-Za-z0-9]+$/.test(t)&&t.length>0&&t.length<=128,j=t=>/^[A-Fa-f0-9]{64}$/.test(t);function B(t,e){if(!k(e))return null;let o=x(t),s;try{s=r.readdirSync(o)}catch{return null}let l=`${e}-`,p=s.find(f=>f.startsWith(l));return p?n(o,p):null}function w(){return r.existsSync(i)?r.readdirSync(i,{withFileTypes:!0}).filter(t=>t.isDirectory()&&r.existsSync(d(n(i,t.name)))).map(t=>t.name):[]}export{m as a,v as b,T as c,g as d,y as e,I as f,_ as g,F as h,d as i,h as j,W as k,E as l,x as m,c as n,H as o,M as p,R as q,$ as r,k as s,j as t,B as u,w as v};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{d as o}from"./chunk-
|
|
2
|
+
import{d as o}from"./chunk-WS6UFNKF.js";var n=["OURS_STATE_DIR","OURS_BROKER_URL","OURS_PORT","OURS_API_VISIBILITY","OURS_CONFIG"],i=Object.fromEntries(n.map(e=>[e,process.env[e]])),{stateDir:s,brokerUrl:a}=o();function c(){let e=n.filter(t=>process.env[t]!==i[t]);if(e.length===0)return;let r=e.map(t=>`${t}: was ${JSON.stringify(i[t]??"(unset)")} at import, is now ${JSON.stringify(process.env[t]??"(unset)")}`).join("; ");throw new Error(`configuration changed after @ours.network/sdk was imported (${r}). The SDK reads its config ONCE, at module load, because CONFIG and STATE_DIR back process-wide singletons that cannot be re-pointed once identities exist. Setting these after the import does not fail and does not take effect \u2014 without this check the daemon would boot against ${JSON.stringify(s)} and broker ${JSON.stringify(a)} and look like it worked. Set every OURS_* config variable BEFORE the first import of this package.`)}export{c as a};
|
|
@@ -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-K7TLSZ3X.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-3CDGP5EO.js";import{b as f,e as b,f as N,g as E}from"./chunk-2PVVBIA7.js";import{A as L,B as _,I as M,M as j}from"./chunk-MQ5AXTPT.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-7JZS2BAP.js";import{c,o as w,p as $}from"./chunk-CIHGEBUR.js";import{i as R,p as x}from"./chunk-T76BFV6S.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,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as E,b as k,d as A}from"./chunk-
|
|
2
|
+
import{a as E,b as k,d as A}from"./chunk-2PVVBIA7.js";import{A as y,H as T,I,J as _,M as R,V as x}from"./chunk-MQ5AXTPT.js";import{a as S}from"./chunk-TUWHVJ37.js";import{a as l,d as u,e as d,g as w}from"./chunk-7JZS2BAP.js";import{a as $,c as m,q as v}from"./chunk-CIHGEBUR.js";import{c as s,i as r}from"./chunk-T76BFV6S.js";import{join as b}from"node:path";import*as i from"node:fs";function D(e){try{$.remove_packet(e.cid)}catch(t){r(`remove_packet(${e.cid}) failed:`,String(t))}m.delete(e.name);try{x(e)}catch(t){r(`failed to unpublish "${e.name}" from the contact book:`,String(t))}l.has(e.name)&&(l.delete(e.name),w()),e.name===k&&(E(null),A());try{i.rmSync(e.dir,{recursive:!0,force:!0}),y.delete(e.name)}catch(t){return`deleting ${e.dir} failed: ${String(t)}`}return null}function F(e,t){let n=e.temp;return n?(n.closing||(n.closing=(async()=>{r(`[${e.name}] closing temporary identity (${t})`);let o=[];try{o=T(a=>S(_(e,"::a2a_messaging::list_contacts",a)))}catch(a){r(`[${e.name}] contact snapshot failed during close (continuing with local cleanup):`,String(a))}let p=0,c=0;u.add(e.name);try{for(let a of o)try{await I(async C=>{let h=(await R(e,"::a2a_messaging::remove_contact",{contact:a.container_id},C)).Reduce("notified");return h.IsNil()?!1:h.GetBoolean()})?p++:c++}catch(g){c++,r(`[${e.name}] remove-me to ${a.container_id} failed (continuing):`,String(g))}}finally{u.delete(e.name)}let f=D(e);return f?r(`[${e.name}] temporary identity close: LOCAL DELETE FAILED \u2014 ${f}`):r(`[${e.name}] temporary identity closed: ${o.length} contact(s), ${p} remove-me notice(s) queued, ${c} not sent (delivery unverified by design)`),{attempted:o.length,notified:p,failed:c,deleteError:f}})()),n.closing):Promise.reject(new Error(`identity "${e.name}" is not temporary`))}function H(){for(let e of[...m.values()]){let t=e.temp;if(!t||t.closing||d(t.owner.pid))continue;let n=l.get(e.name);n&&d(n.pid)||F(e,`stale lease \u2014 owner pid ${t.owner.pid} is dead`).catch(o=>r(`[${e.name}] stale-temp reclaim failed:`,String(o)))}}function J(){if(i.existsSync(s))for(let e of i.readdirSync(s,{withFileTypes:!0})){if(!e.isDirectory()||m.has(e.name))continue;let t=b(s,e.name),n=v(t);if(!(!n||d(n.owner.pid)))try{i.rmSync(t,{recursive:!0,force:!0}),y.delete(e.name),r(`[${e.name}] removed orphaned temporary-identity dir (owner pid ${n.owner.pid} dead, no live packet)`)}catch(o){r(`[${e.name}] failed to remove orphaned temporary-identity dir:`,String(o))}}}export{D as a,F as b,H as c,J as d};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{b as H}from"./chunk-YRPUM6JG.js";import{c as me}from"./chunk-3RZX2WOJ.js";import{d as de}from"./chunk-BCVDO2DW.js";import{a as L,c as x,d as k,e as G,f as oe,g as se,h as K,i as D,j as I,k as B,l as M,p as ae,w as ce}from"./chunk-NOOGH2RZ.js";import{c as V,i as l,o as j,p as ne}from"./chunk-QXKDTQMT.js";import{a as ue}from"./chunk-LKFYUCN7.js";import{c as le,f as fe,g as pe}from"./chunk-XYU2DSWR.js";import{join as Ie}from"node:path";import*as _ from"node:fs";import{AdaptObjectLifetime as $e}from"@adapt-toolkit/sdk/common";import{object_to_adapt_value as be}from"@adapt-toolkit/sdk/wrapper";import*as y from"node:fs";import{randomBytes as Ee}from"node:crypto";import*as $ from"node:fs";import{randomBytes as Te}from"node:crypto";import{PacketWrapperConfigurator as ze}from"@adapt-toolkit/sdk/wrappers";import{AdaptObjectLifetime as Ve}from"@adapt-toolkit/sdk/common";function Je(e){let t=[],s=e.Reduce("degraded");if(s.IsNil())return t;for(let r=0;;r++){let a=s.Reduce(r);if(a.IsNil())break;t.push({cid:a.Reduce("container_id").Visualize(),name:a.Reduce("name").Visualize(),attempts:Number(a.Reduce("attempts").Visualize()),queued:Number(a.Reduce("queued").Visualize())})}return t}function Ne(e){let t=[],s=e.Reduce("queues");if(s.IsNil())return t;for(let r=0;;r++){let a=s.Reduce(r);if(a.IsNil())break;t.push({cid:a.Reduce("container_id").Visualize(),queued:Number(a.Reduce("queued").Visualize()),degraded:a.Reduce("degraded").GetBoolean()})}return t}async function X(e,t){try{let s=await h(async r=>{let a=await v(e,"::a2a_messaging::flush_deferred",{contact:t},r);return Number(a.Reduce("flushed").Visualize())});s>0&&l(`[${e.name}] flushed ${s} deferred message(s) to ${t.slice(0,12)}\u2026`)}catch(s){l(`[${e.name}] deferred flush to ${t.slice(0,12)}\u2026 failed:`,String(s))}}async function ge(e){try{let t=await h(async r=>{let a=await v(e,"::a2a_messaging::restore_degraded_contacts",{},r);return Number(a.Reduce("requested").Visualize())});t>0&&l(`[${e.name}] contact restore requested for ${t} degraded contact(s)`);let s=S(r=>Ne(R(e,"::a2a_messaging::list_deferred_queues",r)));for(let r of s)r.degraded||await X(e,r.cid)}catch(t){l(`[${e.name}] contact-restore sweep failed:`,String(t))}}async function xe(e){try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::reconcile_advertise",{},s),a=d=>r.Reduce(d).IsNil()?0:Number(r.Reduce(d).Visualize());return{changed:/true/i.test(r.Reduce("changed").Visualize()),capabilityAdvertised:a("capability_advertised"),legacyReadvertised:a("legacy_readvertised")}});(t.capabilityAdvertised>0||t.legacyReadvertised>0)&&l(`[${e.name}] capability reconcile: changed=${t.changed} advertised=${t.capabilityAdvertised} legacy_migration_bootstrap=${t.legacyReadvertised}`)}catch(t){l(`[${e.name}] capability reconcile sweep failed:`,String(t))}}var Y=new Set;function q(e){if(!Y.has(e.name)){Y.add(e.name);for(let t of[2e3,15e3])setTimeout(()=>{t===15e3&&Y.delete(e.name);let s=x.get(e.name);s&&xe(s)},t)}}async function We(e){try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::readvertise_e2e_recovery",{},s);return Number(r.Reduce("readvertised").Visualize())});t>0&&l(`[${e.name}] re-advertised fresh AD to ${t} e2e contact(s) (session recovery)`)}catch(t){l(`[${e.name}] e2e recovery re-advertise failed:`,String(t))}try{await h(async t=>{await v(e,"::a2a_messaging::sweep_e2e_migrations",{},t)})}catch(t){l(`[${e.name}] e2e migration sweep failed:`,String(t))}try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::redrive_unacked_sweep",{},s),a=d=>r.Reduce(d).IsNil()?0:Number(r.Reduce(d).Visualize());return{redriven:a("redriven_contacts"),purged:a("purged_contacts"),deferred:a("deferred_contacts")}});(t.redriven>0||t.purged>0||t.deferred>0)&&l(`[${e.name}] unacked sweep: redriven=${t.redriven} ttl_purged=${t.purged} deferred=${t.deferred} contact(s)`)}catch(t){l(`[${e.name}] unacked redrive sweep failed:`,String(t))}}function ye(e,t){e.pw.on_return_data=s=>{let r=new Ve;s.Attach(r);try{let a=s.Reduce("kind").Visualize();if(a==="save_state"){z(e);return}if(a==="notify_agent"){let i=s.Reduce("payload"),f=i.Reduce("event").Visualize();if(f==="message_received"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("sender_id"),u=n.IsNil()?"":n.Visualize(),c=i.Reduce("msg_id").Visualize(),p=i.Reduce("wire_id"),m=p.IsNil()?"":p.Visualize(),w=i.Reduce("date").Visualize();g(e,{event:"message_received",from:o,sender_name:o,sender_id:u,msg_id:c,wire_id:m,date:w}),P(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] new message from ${o} (#${c})`))}else if(f==="receipt_received"){let o=i.Reduce("sender_id"),n=o.IsNil()?"":String(o.Visualize()),u=i.Reduce("kind"),c=u.IsNil()?"":String(u.Visualize()),p=[],m=i.Reduce("wire_ids");if(!m.IsNil())for(let O=0;;O++){let re=m.Reduce(O);if(re.IsNil())break;p.push(String(re.Visualize()))}let w=i.Reduce("date"),b=w.IsNil()?new Date().toISOString():String(w.Visualize());g(e,{event:"receipt_received",sender_id:n,kind:c,wire_ids:p,date:b})}else if(f==="file_received"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("sender_id").Visualize(),u=i.Reduce("file_id").Visualize(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("filename").Visualize(),m=i.Reduce("mime").Visualize(),w=i.Reduce("bytes").Visualize(),b=i.Reduce("date").Visualize();g(e,{event:"file_received",from:o,sender_id:n,file_id:u,wire_id:c,filename:p,mime:m,bytes:w,date:b}),P(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] new file ${p} (${w} B) from ${o} (sender_id ${n}, file_id ${u}, wire_id ${c})`))}else if(f==="contact_accepted"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] contact "${o}" (${n}) accepted your invite.`))}else if(f==="local_contact_added"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] local contact "${o}" (${n}) connected via the contact book.`))}else if(f==="contact_name_collision"){let o=i.Reduce("message").Visualize(),n=i.Reduce("desired").Visualize(),u=i.Reduce("assigned").Visualize(),c=i.Reduce("existing_container_id").Visualize(),p=i.Reduce("container_id").Visualize();g(e,{event:"contact_name_collision",desired:n,assigned:u,existing_container_id:c,container_id:p}),l(`[${e.name}] CONTACT NAME COLLISION \u2014 ${o}`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] \u26A0 ${o}`))}else if(f==="sibling_contact_added"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"sibling_contact_added",from:o}),q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] sibling "${o}" (${n}) connected (intra-root auto-accept).`))}else if(f==="local_contact_request"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"local_contact_request",from:o}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] pending local introduction from "${o}" (${n}) \u2014 approve or reject with respond_to_introduction.`))}else if(f==="pending_message"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("queued").Visualize();g(e,{event:"pending_message",from:o,queued:n}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] "${o}" queued a message awaiting introduction approval (${n} queued).`))}else if(f==="e2e_restore_rejected")g(e,{event:"e2e_restore_rejected"}),l(`[${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(()=>t.onNotify(e.name,`[${e.name}] persisted e2e sessions were corrupt \u2014 rejected cleanly, sessions re-establishing`));else if(f==="contact_restored"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"contact_restored",from:o}),l(`[${e.name}] contact "${o}" restored (re-keyed)`),process.nextTick(()=>void X(e,String(n)))}else if(f==="migration_active"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("role").Visualize(),u=T(i,"epoch"),c=T(i,"session_id");g(e,{event:"migration_active",cid:String(o),role:String(n),...u?{epoch:u}:{},...c?{session_id:c}:{}}),l(`[migration] active cid=${o} role=${n}${u?` epoch=${u}`:""}${c?` session_id=${c}`:""}`)}else if(f==="e2e_app_send"){let o=i.Reduce("cid").Visualize(),n=T(i,"session_id"),u=i.Reduce("olm_type").Visualize(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("retained").IsNil()?void 0:i.Reduce("retained").GetBoolean(),m=[],w=i.Reduce("evicted");if(!w.IsNil())for(let b=0;;b++){let O=w.Reduce(b);if(O.IsNil())break;m.push(String(O.Visualize()))}g(e,{event:"e2e_app_send",cid:String(o),session_id:n,olm_type:String(u),wire_id:String(c),...p===!1?{retained:!1}:{},...m.length?{evicted:m}:{}}),l(`[${e.name}] [e2e-app] send cid=${o} session_id=${n} olm_type=${u} wire_id=${c}${p===!1?" retained=false":""}${m.length?` evicted=${m.join(",")}`:""}`),m.length&&process.nextTick(()=>t.onNotify(e.name,`[${e.name}] redrive window overflow: ${m.length} older unacked send(s) lost their auto-resend guarantee (${m.join(", ")})`))}else if(f==="dedup_degraded"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("dropped_wire_id").Visualize();g(e,{event:"dedup_degraded",cid:String(o),dropped_wire_id:String(n)}),l(`[${e.name}] [e2e-app] DEDUP DEGRADED cid=${o} dropped_wire_id=${n} (storage ceiling \u2014 a late redrive of that id could re-deposit)`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] dedup window overflowed for ${String(o).slice(0,12)}\u2026 \u2014 one oldest entry dropped (guarantee loss surfaced)`))}else if(f==="e2e_delivery_expired"){let o=i.Reduce("cid").Visualize(),n=[],u=i.Reduce("wire_ids");if(!u.IsNil())for(let c=0;;c++){let p=u.Reduce(c);if(p.IsNil())break;n.push(String(p.Visualize()))}g(e,{event:"e2e_delivery_expired",cid:String(o),wire_ids:n}),l(`[${e.name}] [e2e-app] delivery EXPIRED (2-day TTL, receipt never arrived) cid=${o} wire_ids=${n.join(",")}`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] ${n.length} message(s)/file(s) to ${String(o).slice(0,12)}\u2026 expired undelivered (no receipt within 2 days)`))}else if(f==="e2e_app_recv"){let o=i.Reduce("cid").Visualize(),n=T(i,"session_id"),u=i.Reduce("ok").GetBoolean(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("code").IsNil()?void 0:String(i.Reduce("code").Visualize()),m=!i.Reduce("duplicate").IsNil(),w=!i.Reduce("file").IsNil();g(e,{event:"e2e_app_recv",cid:String(o),session_id:n,ok:u,wire_id:String(c),...p?{code:p}:{},...m?{duplicate:!0}:{},...w?{file:!0}:{}}),l(`[${e.name}] [e2e-app] recv cid=${o} session_id=${n} ok=${u} wire_id=${c}${p?` code=${p}`:""}${m?" duplicate=true":""}${w?" file=true":""}`)}else if(f==="e2e_rekey"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("role").Visualize(),u=T(i,"session_id"),c=i.Reduce("attempts").IsNil()?void 0:String(i.Reduce("attempts").Visualize()),p=i.Reduce("peer_supports").IsNil()?void 0:String(i.Reduce("peer_supports").Visualize()),m=i.Reduce("rejected").IsNil()?void 0:String(i.Reduce("rejected").Visualize());g(e,{event:"e2e_rekey",cid:String(o),role:String(n),...u?{session_id:u}:{},...c?{attempts:c}:{},...p?{peer_supports:p}:{},...m?{rejected:m}:{}}),l(`[${e.name}] [e2e-rekey] cid=${o} role=${n}${u?` session_id=${u}`:""}${c?` attempts=${c}`:""}${p?` peer_supports=${p}`:""}${m?` rejected=${m}`:""}`)}else if(f==="migration_deferred_flush"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("wire_id").Visualize();g(e,{event:"migration_deferred_flush",cid:String(o),wire_id:String(n)}),l(`[migration] flush-notify cid=${o} wire_id=${n} (deferred\u2192e2e; core delivers)`)}else if(f==="migration_stalled"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("phase").Visualize(),u=i.Reduce("attempts").Visualize();g(e,{event:"migration_stalled",cid:String(o),phase:String(n),attempts:String(u)}),l(`[migration] stalled-notify cid=${o} phase=${n} attempts=${u} (core re-drives via sweep)`)}else if(f==="downgrade_refused"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("wire_id"),u=n.IsNil()?"":String(n.Visualize());g(e,{event:"downgrade_refused",cid:String(o),...u?{wire_id:u}:{}}),l(`[e2e-route] downgrade-dropped cid=${o}${u?` wire_id=${u}`:""} (legacy plaintext from a migrated peer \u2014 dropped by core)`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] a message from a migrated contact was rejected as an unsafe downgrade (dropped).`))}else if(f==="contact_removed"){let o=String(i.Reduce("cid").Visualize()),n=de.has(e.name);g(e,{event:"contact_removed",cid:o,by:n?"local":"peer"}),n||(l(`[${e.name}] contact ${o} removed you (authenticated peer removal notice) \u2014 dropped from contacts`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] contact ${o.slice(0,12)}\u2026 removed you as a contact (the removal was applied locally too).`)))}else if(f==="monitoring_disabled"){let o=String(i.Reduce("cid").Visualize()),n=i.Reduce("cause"),u=n.IsNil()?"":String(n.Visualize());g(e,{event:"monitoring_disabled",cid:o,...u?{cause:u}:{}}),l(`[${e.name}] monitoring disabled (cid=${o}${u?` cause=${u}`:""})`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] the monitoring/control-plane binding was disabled${u==="control_plane_removed_contact"?" \u2014 the control plane removed you as a contact":""}.`))}else f==="control_request"||f==="host_provision_child"||f==="host_destroy_child"||f==="host_mint_child_invite"||f==="host_set_child_monitoring"?l(`[${e.name}] ${f}: the daemon-side control plane is removed \u2014 ignoring`):g(e,{event:f});return}let d=e.pending.shift();if(!d)return;clearTimeout(d.timer),d.resolve(s.Reduce("payload").Detach())}finally{r.Finalize()}},e.pw.on_transaction_failure=s=>{let r=e.pending.shift();r?(clearTimeout(r.timer),r.reject(new Error(s))):(l(`[${e.name}] inbound transaction rejected:`,s),g(e,{event:"inbound_error",message:s}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] inbound transaction rejected: ${s}`)))}}import{join as Z}from"node:path";import*as N from"node:fs";var E=()=>Z(V,j),ee=()=>Z(E(),"registrar.key"),Q=()=>Z(E(),"book.json");function _e(){try{let e=JSON.parse(N.readFileSync(Q(),"utf8"));return e&&typeof e.entries=="object"?e.entries:{}}catch{return{}}}function we(e){N.mkdirSync(E(),{recursive:!0});let t=`${Q()}.tmp`;N.writeFileSync(t,JSON.stringify({v:1,entries:e},null,2),{mode:384}),N.renameSync(t,Q())}function te(e){return S(t=>Buffer.from(R(e,"::actor::export_address_document",t).GetBinary()))}function C(e){return S(t=>Buffer.from(R(e,"::actor::export_signing_secret",t).Serialize()).toString("hex"))}async function he(e){if(!k)throw new Error("registrar is not available");let t=te(e),s=await h(async a=>{let d=await v(k,"::actor::sign_book_entry",{name:e.name,ad:k.pw.packet.NewBinaryFromBuffer(t).Attach(a)},a);return Buffer.from(d.Reduce("sig").GetBinary()).toString("base64url")}),r=_e();r[e.name]={v:1,name:e.name,container_id:e.cid,address_document:t.toString("base64url"),published_at:new Date().toISOString(),registrar_sig:s},we(r),l(`[${e.name}] published to the local contact book`)}function st(e){let t=_e(),s=Object.entries(t).find(([,r])=>r.container_id===e.cid);s&&(delete t[s[0]],we(t),l(`[${e.name}] removed from the local contact book (entry "${s[0]}")`))}async function ve(e){if(!G)throw new Error("registrar is not available");await h(async t=>{await v(e,"::actor::pin_registrar",{registrar_ad:e.pw.packet.NewBinaryFromBuffer(G).Attach(t)},t)})}function U(e,t,s,r=!0,a,d=!1){let i=new ze;i.deferred_exposure=d;let f=["--unit_hash",H.hash,"--seed_phrase",t,"--unit_dir_path",H.dir];return a&&f.push("--init_trn_argument",JSON.stringify(a)),i.process_arguments(f),new Promise((o,n)=>{let u=setTimeout(()=>n(new Error(`packet creation for "${e}" timed out`)),3e4);L.packet_manager.create_packet(i,c=>{clearTimeout(u);let p={name:e,cid:S(m=>c.packet.GetContainerID().Attach(m).Visualize()),pw:c,dir:s,pending:[],lock:Promise.resolve()};ye(p,Se),r&&x.set(e,p),l(`[${e}] packet created \u2014 container id ${p.cid}`),o(p)},H.contents)})}var A=new Set(ce());A.size>0&&l(`reserved ${A.size} persisted identity name(s) at module load: ${[...A].join(", ")}`);async function ht(e,t={exposeLocal:!0,localAutoAccept:!0}){if(A.has(e)||x.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`);A.add(e);try{let s=K(e);$.mkdirSync(s,{recursive:!0,mode:448});let r;t.temp&&(r={owner:{tokenHash:t.temp.tokenHash,pid:t.temp.pid},createdAt:Date.now()},ae(s,r));let a=Te(24).toString("hex"),d=await U(e,a,s);return r&&(d.temp=r),$.writeFileSync(D(s),C(d),{mode:384}),await h(async i=>{await v(d,"::a2a_messaging::set_my_name",{name:e},i)}),await ve(d),t.localAutoAccept||await h(async i=>{await v(d,"::actor::set_local_policy",{auto_accept:!1},i)}),t.exposeLocal&&await he(d),z(d),d}catch(s){throw A.delete(e),s}}async function vt(e){let t=K(e),s=$.readFileSync(D(t),"utf8").trim(),r=await U(e,"",t,!1,s,!0);l(`[${e}] created QUARANTINED (no routing/broker registration, not client-bindable) \u2014 importing state before exposure`);let a=Number(process.env.OURS_TEST_RESTORE_HOLD_MS||"")||0;a>0&&(l(`[${e}] TEST HOLD: keeping restore open ${a}ms (OURS_TEST_RESTORE_HOLD_MS)`),await new Promise(o=>setTimeout(o,a)));let d=o=>/timed out waiting for the transaction result/.test(String(o)),i=(o,n,u)=>{l(`[${e}] ${o} ${n} \u2014 identity left UNEXPOSED and UNTRACKED (fail-closed)`);try{g(r,{event:"restore_fail_closed",step:o,error:String(u).slice(0,300)})}catch{}x.delete(e);try{L.remove_packet(r.cid)}catch(c){l(`[${e}] quarantined-packet teardown failed:`,String(c))}throw new Error(`identity "${e}": ${o} failed during restore (${n}) \u2014 left unexposed (fail-closed)`)},f=(o,n)=>i(o,"outcome UNKNOWN (timeout): the transaction may still execute and exposure would race it",n);if(Re(t)){let o=!1;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 n=$.readFileSync(I(t));await h(async u=>{let c=r.pw.packet.ParseValue(new Uint8Array(n)).Attach(u),p=Number(process.env.OURS_IMPORT_TIMEOUT_MS||"")||void 0;await v(r,"::actor::import_state",c,u,p)}),o=!0,l(`[${e}] state import completed (positively observed)`)}catch(n){d(n)&&f("import_state",n),l(`[${e}] FAILED TO IMPORT SAVED STATE \u2014 continuing with the reseeded identity; surviving contacts (if the blob was partially migrated) self-heal via contact restore:`,String(n)),g(r,{event:"state_import_failed",error:String(n).slice(0,300)});try{let u=`${I(t)}.failed-${Date.now()}`;$.renameSync(I(t),u),$.chmodSync(u,384),l(`[${e}] unreadable state blob preserved as state_data.bin.failed-*`)}catch{}}if(o){try{let c=await h(async p=>{let m=await v(r,"::a2a_messaging::commit_e2e_restore",{},p),w=m.Reduce("status").Visualize(),b=m.Reduce("sessions").IsNil()?"0":m.Reduce("sessions").Visualize();return{status:String(w),sessions:String(b)}});l(`[${e}] e2e restore commit: status=${c.status} sessions=${c.sessions}`)}catch(c){d(c)&&f("commit_e2e_restore",c),l(`[${e}] E2E RESTORE REJECTED \u2014 staged session blob failed pickle_key validation; discarding it, fresh account + self-heal fallback take over: ${String(c).slice(0,260)}`),g(r,{event:"e2e_restore_rejected",origin:"restore",error:String(c).slice(0,300)});try{await h(async p=>{await v(r,"::a2a_messaging::reject_e2e_restore",{},p)})}catch(p){d(p)&&f("reject_e2e_restore",p),l(`[${e}] reject_e2e_restore failed (staging is transient; continuing):`,String(p))}}try{r.pw.refresh_identity_proof_document(),l(`[${e}] transport IPD refreshed from post-import state`)}catch(c){i("ipd_refresh","FAILED (IPD would advertise a stale bundle)",c)}let n=!1,u="";try{if(process.env.OURS_TEST_FORCE_IPD_INCOHERENT==="1")throw new Error("forced incoherent (OURS_TEST_FORCE_IPD_INCOHERENT)");let c=S(w=>String(R(r,"::a2a_messaging::e2e_self_fp",w).Reduce("ik").Visualize())),p=r.pw.identity_proof_document.Visualize(),m=c.replace(/^0x/i,"");n=m.length>=32&&p.toLowerCase().includes(m.toLowerCase()),u=c.slice(0,18),g(r,{event:"ipd_coherence",ik:c,coherent:n})}catch(c){i("ipd_coherence","probe FAILED (coherence unprovable)",c)}l(`[${e}] IPD/e2e coherence: account_ik=${u}\u2026 ipd_advertises_it=${n}`),n||i("ipd_coherence","IPD does NOT advertise the live account ik",new Error("incoherent transport IPD"))}}return L.expose_packet(r.cid),x.set(e,r),l(`[${e}] EXPOSED (routing + broker registration) \u2014 import phase complete`),await ge(r),P(r),r}async function Vt(){y.mkdirSync(E(),{recursive:!0});let e;try{e=y.readFileSync(ee(),"utf8").trim()}catch{}let t=Ee(24).toString("hex");oe(await U(j,t,E(),!1,e)),e||y.writeFileSync(ee(),C(k),{mode:384}),se(te(k)),l(`contact-book registrar ready (${k.cid})`)}function Re(e){try{return y.existsSync(I(e))&&y.statSync(I(e)).size>0}catch{return!1}}function Ae(e){let t=S(d=>Buffer.from(R(e,"::actor::export_state",d).Serialize()));y.mkdirSync(e.dir,{recursive:!0,mode:448});let s=I(e.dir),r=`${s}.tmp`,a;try{a=y.openSync(r,"w",384),y.fchmodSync(a,384),y.writeFileSync(a,t),y.fsyncSync(a),y.closeSync(a),a=void 0,y.renameSync(r,s),y.chmodSync(s,384);try{y.chmodSync(D(e.dir),384)}catch{}let d=y.openSync(e.dir,"r");try{y.fsyncSync(d)}finally{y.closeSync(d)}}catch(d){if(a!==void 0)try{y.closeSync(a)}catch{}try{y.rmSync(r,{force:!0})}catch{}throw d}}function z(e){try{Ae(e),e.persistFailed&&(e.persistFailed=!1,l(`[${e.name}] persist recovered \u2014 quarantine lifted`),g(e,{event:"persist_recovered"}))}catch(t){e.persistFailed=!0,l(`[${e.name}] PERSIST FAILED \u2014 identity quarantined (fail-closed), outbound of this txn withheld:`,String(t));try{g(e,{event:"persist_failed",error:String(t).slice(0,300)})}catch{}throw process.nextTick(()=>ie(e.name,`[${e.name}] PERSIST FAILED \u2014 messaging quarantined until the state file is writable again`)),t}}function S(e){let t=new $e;try{return e(t)}finally{t.Finalize()}}async function h(e){let t=new $e;try{return await e(t)}finally{t.Finalize()}}function R(e,t,s,r){let a=be({name:t,targ:r}),d=e.pw.packet.ExecuteTransaction(a);return a.Destroy(),s?d.Attach(s):d}async function Oe(e,t){let s=e.lock,r;e.lock=new Promise(a=>r=a),await s;try{return await t()}finally{r()}}function De(e,t,s=25e3){return new Promise((r,a)=>{let d=setTimeout(()=>{let i=e.pending.findIndex(f=>f.timer===d);i>=0&&e.pending.splice(i,1),a(new Error("timed out waiting for the transaction result"))},s);e.pending.push({resolve:r,reject:a,timer:d}),e.pw.add_client_message(t)})}function v(e,t,s,r,a){if(e.persistFailed)try{z(e)}catch(i){return Promise.reject(new Error(`identity "${e.name}" is quarantined: state persist is failing (${String(i)}) \u2014 mutations are rejected until state_data.bin is writable again`))}let d=be({name:t,targ:s});return Oe(e,()=>De(e,d,a)).then(i=>{if(d.Destroy(),e.persistFailed){try{i.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 r?i.Attach(r):i},i=>{try{d.Destroy()}catch{}throw i})}var F=null;function Ht(e){F?.uninstall(),F=e===null?null:{hook:e,uninstall:le("notification",e)}}function qt(e){F?.hook===e&&(F.uninstall(),F=null)}function ie(e,t){pe(e,t)}var Se={onNotify:(e,t)=>ie(e,t)},W={inbound:["message_received","file_received"],intro:["local_contact_request","pending_message"],get wake(){return[...W.inbound,...W.intro]}};function Pe(e){if(e===null||e==="")return null;let t=new Set;for(let s of e.split(",")){let r=s.trim();if(r==="")continue;let a=W[r];if(!a)throw new Error(r);for(let d of a)t.add(d)}return t}function Fe(e,t){return t===null?!0:typeof e.event=="string"&&t.has(e.event)}var J=new Map;function je(e){let t=J.get(e);if(!(!t||t.size===0))for(let s of[...t])try{s()}catch{}}function Le(e,t){return new Promise(s=>{let r=J.get(e);r||(r=new Set,J.set(e,r));let a=!1,d=()=>{a||(a=!0,r.delete(i),r.size===0&&J.delete(e),clearTimeout(f),s())},i=d,f=setTimeout(d,t);r.add(i)})}function g(e,t){try{_.mkdirSync(e.dir,{recursive:!0,mode:448}),_.appendFileSync(B(e.dir),JSON.stringify(t)+`
|
|
2
|
+
import{b as H}from"./chunk-YRPUM6JG.js";import{c as me}from"./chunk-TUWHVJ37.js";import{d as de}from"./chunk-7JZS2BAP.js";import{a as L,c as x,d as k,e as G,f as oe,g as se,h as K,i as D,j as I,k as B,l as M,p as ae,v as ce}from"./chunk-CIHGEBUR.js";import{c as V,i as l,o as j,p as ne}from"./chunk-T76BFV6S.js";import{a as ue}from"./chunk-LKFYUCN7.js";import{c as le,f as fe,g as pe}from"./chunk-XYU2DSWR.js";import{join as Ie}from"node:path";import*as _ from"node:fs";import{AdaptObjectLifetime as $e}from"@adapt-toolkit/sdk/common";import{object_to_adapt_value as be}from"@adapt-toolkit/sdk/wrapper";import*as y from"node:fs";import{randomBytes as Ee}from"node:crypto";import*as $ from"node:fs";import{randomBytes as Te}from"node:crypto";import{PacketWrapperConfigurator as ze}from"@adapt-toolkit/sdk/wrappers";import{AdaptObjectLifetime as Ve}from"@adapt-toolkit/sdk/common";function Je(e){let t=[],s=e.Reduce("degraded");if(s.IsNil())return t;for(let r=0;;r++){let a=s.Reduce(r);if(a.IsNil())break;t.push({cid:a.Reduce("container_id").Visualize(),name:a.Reduce("name").Visualize(),attempts:Number(a.Reduce("attempts").Visualize()),queued:Number(a.Reduce("queued").Visualize())})}return t}function Ne(e){let t=[],s=e.Reduce("queues");if(s.IsNil())return t;for(let r=0;;r++){let a=s.Reduce(r);if(a.IsNil())break;t.push({cid:a.Reduce("container_id").Visualize(),queued:Number(a.Reduce("queued").Visualize()),degraded:a.Reduce("degraded").GetBoolean()})}return t}async function X(e,t){try{let s=await h(async r=>{let a=await v(e,"::a2a_messaging::flush_deferred",{contact:t},r);return Number(a.Reduce("flushed").Visualize())});s>0&&l(`[${e.name}] flushed ${s} deferred message(s) to ${t.slice(0,12)}\u2026`)}catch(s){l(`[${e.name}] deferred flush to ${t.slice(0,12)}\u2026 failed:`,String(s))}}async function ge(e){try{let t=await h(async r=>{let a=await v(e,"::a2a_messaging::restore_degraded_contacts",{},r);return Number(a.Reduce("requested").Visualize())});t>0&&l(`[${e.name}] contact restore requested for ${t} degraded contact(s)`);let s=S(r=>Ne(R(e,"::a2a_messaging::list_deferred_queues",r)));for(let r of s)r.degraded||await X(e,r.cid)}catch(t){l(`[${e.name}] contact-restore sweep failed:`,String(t))}}async function xe(e){try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::reconcile_advertise",{},s),a=d=>r.Reduce(d).IsNil()?0:Number(r.Reduce(d).Visualize());return{changed:/true/i.test(r.Reduce("changed").Visualize()),capabilityAdvertised:a("capability_advertised"),legacyReadvertised:a("legacy_readvertised")}});(t.capabilityAdvertised>0||t.legacyReadvertised>0)&&l(`[${e.name}] capability reconcile: changed=${t.changed} advertised=${t.capabilityAdvertised} legacy_migration_bootstrap=${t.legacyReadvertised}`)}catch(t){l(`[${e.name}] capability reconcile sweep failed:`,String(t))}}var Y=new Set;function q(e){if(!Y.has(e.name)){Y.add(e.name);for(let t of[2e3,15e3])setTimeout(()=>{t===15e3&&Y.delete(e.name);let s=x.get(e.name);s&&xe(s)},t)}}async function We(e){try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::readvertise_e2e_recovery",{},s);return Number(r.Reduce("readvertised").Visualize())});t>0&&l(`[${e.name}] re-advertised fresh AD to ${t} e2e contact(s) (session recovery)`)}catch(t){l(`[${e.name}] e2e recovery re-advertise failed:`,String(t))}try{await h(async t=>{await v(e,"::a2a_messaging::sweep_e2e_migrations",{},t)})}catch(t){l(`[${e.name}] e2e migration sweep failed:`,String(t))}try{let t=await h(async s=>{let r=await v(e,"::a2a_messaging::redrive_unacked_sweep",{},s),a=d=>r.Reduce(d).IsNil()?0:Number(r.Reduce(d).Visualize());return{redriven:a("redriven_contacts"),purged:a("purged_contacts"),deferred:a("deferred_contacts")}});(t.redriven>0||t.purged>0||t.deferred>0)&&l(`[${e.name}] unacked sweep: redriven=${t.redriven} ttl_purged=${t.purged} deferred=${t.deferred} contact(s)`)}catch(t){l(`[${e.name}] unacked redrive sweep failed:`,String(t))}}function ye(e,t){e.pw.on_return_data=s=>{let r=new Ve;s.Attach(r);try{let a=s.Reduce("kind").Visualize();if(a==="save_state"){z(e);return}if(a==="notify_agent"){let i=s.Reduce("payload"),f=i.Reduce("event").Visualize();if(f==="message_received"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("sender_id"),u=n.IsNil()?"":n.Visualize(),c=i.Reduce("msg_id").Visualize(),p=i.Reduce("wire_id"),m=p.IsNil()?"":p.Visualize(),w=i.Reduce("date").Visualize();g(e,{event:"message_received",from:o,sender_name:o,sender_id:u,msg_id:c,wire_id:m,date:w}),P(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] new message from ${o} (#${c})`))}else if(f==="receipt_received"){let o=i.Reduce("sender_id"),n=o.IsNil()?"":String(o.Visualize()),u=i.Reduce("kind"),c=u.IsNil()?"":String(u.Visualize()),p=[],m=i.Reduce("wire_ids");if(!m.IsNil())for(let O=0;;O++){let re=m.Reduce(O);if(re.IsNil())break;p.push(String(re.Visualize()))}let w=i.Reduce("date"),b=w.IsNil()?new Date().toISOString():String(w.Visualize());g(e,{event:"receipt_received",sender_id:n,kind:c,wire_ids:p,date:b})}else if(f==="file_received"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("sender_id").Visualize(),u=i.Reduce("file_id").Visualize(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("filename").Visualize(),m=i.Reduce("mime").Visualize(),w=i.Reduce("bytes").Visualize(),b=i.Reduce("date").Visualize();g(e,{event:"file_received",from:o,sender_id:n,file_id:u,wire_id:c,filename:p,mime:m,bytes:w,date:b}),P(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] new file ${p} (${w} B) from ${o} (sender_id ${n}, file_id ${u}, wire_id ${c})`))}else if(f==="contact_accepted"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] contact "${o}" (${n}) accepted your invite.`))}else if(f==="local_contact_added"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] local contact "${o}" (${n}) connected via the contact book.`))}else if(f==="contact_name_collision"){let o=i.Reduce("message").Visualize(),n=i.Reduce("desired").Visualize(),u=i.Reduce("assigned").Visualize(),c=i.Reduce("existing_container_id").Visualize(),p=i.Reduce("container_id").Visualize();g(e,{event:"contact_name_collision",desired:n,assigned:u,existing_container_id:c,container_id:p}),l(`[${e.name}] CONTACT NAME COLLISION \u2014 ${o}`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] \u26A0 ${o}`))}else if(f==="sibling_contact_added"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"sibling_contact_added",from:o}),q(e),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] sibling "${o}" (${n}) connected (intra-root auto-accept).`))}else if(f==="local_contact_request"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"local_contact_request",from:o}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] pending local introduction from "${o}" (${n}) \u2014 approve or reject with respond_to_introduction.`))}else if(f==="pending_message"){let o=i.Reduce("sender_name").Visualize(),n=i.Reduce("queued").Visualize();g(e,{event:"pending_message",from:o,queued:n}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] "${o}" queued a message awaiting introduction approval (${n} queued).`))}else if(f==="e2e_restore_rejected")g(e,{event:"e2e_restore_rejected"}),l(`[${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(()=>t.onNotify(e.name,`[${e.name}] persisted e2e sessions were corrupt \u2014 rejected cleanly, sessions re-establishing`));else if(f==="contact_restored"){let o=i.Reduce("name").Visualize(),n=i.Reduce("container_id").Visualize();g(e,{event:"contact_restored",from:o}),l(`[${e.name}] contact "${o}" restored (re-keyed)`),process.nextTick(()=>void X(e,String(n)))}else if(f==="migration_active"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("role").Visualize(),u=T(i,"epoch"),c=T(i,"session_id");g(e,{event:"migration_active",cid:String(o),role:String(n),...u?{epoch:u}:{},...c?{session_id:c}:{}}),l(`[migration] active cid=${o} role=${n}${u?` epoch=${u}`:""}${c?` session_id=${c}`:""}`)}else if(f==="e2e_app_send"){let o=i.Reduce("cid").Visualize(),n=T(i,"session_id"),u=i.Reduce("olm_type").Visualize(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("retained").IsNil()?void 0:i.Reduce("retained").GetBoolean(),m=[],w=i.Reduce("evicted");if(!w.IsNil())for(let b=0;;b++){let O=w.Reduce(b);if(O.IsNil())break;m.push(String(O.Visualize()))}g(e,{event:"e2e_app_send",cid:String(o),session_id:n,olm_type:String(u),wire_id:String(c),...p===!1?{retained:!1}:{},...m.length?{evicted:m}:{}}),l(`[${e.name}] [e2e-app] send cid=${o} session_id=${n} olm_type=${u} wire_id=${c}${p===!1?" retained=false":""}${m.length?` evicted=${m.join(",")}`:""}`),m.length&&process.nextTick(()=>t.onNotify(e.name,`[${e.name}] redrive window overflow: ${m.length} older unacked send(s) lost their auto-resend guarantee (${m.join(", ")})`))}else if(f==="dedup_degraded"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("dropped_wire_id").Visualize();g(e,{event:"dedup_degraded",cid:String(o),dropped_wire_id:String(n)}),l(`[${e.name}] [e2e-app] DEDUP DEGRADED cid=${o} dropped_wire_id=${n} (storage ceiling \u2014 a late redrive of that id could re-deposit)`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] dedup window overflowed for ${String(o).slice(0,12)}\u2026 \u2014 one oldest entry dropped (guarantee loss surfaced)`))}else if(f==="e2e_delivery_expired"){let o=i.Reduce("cid").Visualize(),n=[],u=i.Reduce("wire_ids");if(!u.IsNil())for(let c=0;;c++){let p=u.Reduce(c);if(p.IsNil())break;n.push(String(p.Visualize()))}g(e,{event:"e2e_delivery_expired",cid:String(o),wire_ids:n}),l(`[${e.name}] [e2e-app] delivery EXPIRED (2-day TTL, receipt never arrived) cid=${o} wire_ids=${n.join(",")}`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] ${n.length} message(s)/file(s) to ${String(o).slice(0,12)}\u2026 expired undelivered (no receipt within 2 days)`))}else if(f==="e2e_app_recv"){let o=i.Reduce("cid").Visualize(),n=T(i,"session_id"),u=i.Reduce("ok").GetBoolean(),c=i.Reduce("wire_id").Visualize(),p=i.Reduce("code").IsNil()?void 0:String(i.Reduce("code").Visualize()),m=!i.Reduce("duplicate").IsNil(),w=!i.Reduce("file").IsNil();g(e,{event:"e2e_app_recv",cid:String(o),session_id:n,ok:u,wire_id:String(c),...p?{code:p}:{},...m?{duplicate:!0}:{},...w?{file:!0}:{}}),l(`[${e.name}] [e2e-app] recv cid=${o} session_id=${n} ok=${u} wire_id=${c}${p?` code=${p}`:""}${m?" duplicate=true":""}${w?" file=true":""}`)}else if(f==="e2e_rekey"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("role").Visualize(),u=T(i,"session_id"),c=i.Reduce("attempts").IsNil()?void 0:String(i.Reduce("attempts").Visualize()),p=i.Reduce("peer_supports").IsNil()?void 0:String(i.Reduce("peer_supports").Visualize()),m=i.Reduce("rejected").IsNil()?void 0:String(i.Reduce("rejected").Visualize());g(e,{event:"e2e_rekey",cid:String(o),role:String(n),...u?{session_id:u}:{},...c?{attempts:c}:{},...p?{peer_supports:p}:{},...m?{rejected:m}:{}}),l(`[${e.name}] [e2e-rekey] cid=${o} role=${n}${u?` session_id=${u}`:""}${c?` attempts=${c}`:""}${p?` peer_supports=${p}`:""}${m?` rejected=${m}`:""}`)}else if(f==="migration_deferred_flush"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("wire_id").Visualize();g(e,{event:"migration_deferred_flush",cid:String(o),wire_id:String(n)}),l(`[migration] flush-notify cid=${o} wire_id=${n} (deferred\u2192e2e; core delivers)`)}else if(f==="migration_stalled"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("phase").Visualize(),u=i.Reduce("attempts").Visualize();g(e,{event:"migration_stalled",cid:String(o),phase:String(n),attempts:String(u)}),l(`[migration] stalled-notify cid=${o} phase=${n} attempts=${u} (core re-drives via sweep)`)}else if(f==="downgrade_refused"){let o=i.Reduce("cid").Visualize(),n=i.Reduce("wire_id"),u=n.IsNil()?"":String(n.Visualize());g(e,{event:"downgrade_refused",cid:String(o),...u?{wire_id:u}:{}}),l(`[e2e-route] downgrade-dropped cid=${o}${u?` wire_id=${u}`:""} (legacy plaintext from a migrated peer \u2014 dropped by core)`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] a message from a migrated contact was rejected as an unsafe downgrade (dropped).`))}else if(f==="contact_removed"){let o=String(i.Reduce("cid").Visualize()),n=de.has(e.name);g(e,{event:"contact_removed",cid:o,by:n?"local":"peer"}),n||(l(`[${e.name}] contact ${o} removed you (authenticated peer removal notice) \u2014 dropped from contacts`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] contact ${o.slice(0,12)}\u2026 removed you as a contact (the removal was applied locally too).`)))}else if(f==="monitoring_disabled"){let o=String(i.Reduce("cid").Visualize()),n=i.Reduce("cause"),u=n.IsNil()?"":String(n.Visualize());g(e,{event:"monitoring_disabled",cid:o,...u?{cause:u}:{}}),l(`[${e.name}] monitoring disabled (cid=${o}${u?` cause=${u}`:""})`),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] the monitoring/control-plane binding was disabled${u==="control_plane_removed_contact"?" \u2014 the control plane removed you as a contact":""}.`))}else f==="control_request"||f==="host_provision_child"||f==="host_destroy_child"||f==="host_mint_child_invite"||f==="host_set_child_monitoring"?l(`[${e.name}] ${f}: the daemon-side control plane is removed \u2014 ignoring`):g(e,{event:f});return}let d=e.pending.shift();if(!d)return;clearTimeout(d.timer),d.resolve(s.Reduce("payload").Detach())}finally{r.Finalize()}},e.pw.on_transaction_failure=s=>{let r=e.pending.shift();r?(clearTimeout(r.timer),r.reject(new Error(s))):(l(`[${e.name}] inbound transaction rejected:`,s),g(e,{event:"inbound_error",message:s}),process.nextTick(()=>t.onNotify(e.name,`[${e.name}] inbound transaction rejected: ${s}`)))}}import{join as Z}from"node:path";import*as N from"node:fs";var E=()=>Z(V,j),ee=()=>Z(E(),"registrar.key"),Q=()=>Z(E(),"book.json");function _e(){try{let e=JSON.parse(N.readFileSync(Q(),"utf8"));return e&&typeof e.entries=="object"?e.entries:{}}catch{return{}}}function we(e){N.mkdirSync(E(),{recursive:!0});let t=`${Q()}.tmp`;N.writeFileSync(t,JSON.stringify({v:1,entries:e},null,2),{mode:384}),N.renameSync(t,Q())}function te(e){return S(t=>Buffer.from(R(e,"::actor::export_address_document",t).GetBinary()))}function C(e){return S(t=>Buffer.from(R(e,"::actor::export_signing_secret",t).Serialize()).toString("hex"))}async function he(e){if(!k)throw new Error("registrar is not available");let t=te(e),s=await h(async a=>{let d=await v(k,"::actor::sign_book_entry",{name:e.name,ad:k.pw.packet.NewBinaryFromBuffer(t).Attach(a)},a);return Buffer.from(d.Reduce("sig").GetBinary()).toString("base64url")}),r=_e();r[e.name]={v:1,name:e.name,container_id:e.cid,address_document:t.toString("base64url"),published_at:new Date().toISOString(),registrar_sig:s},we(r),l(`[${e.name}] published to the local contact book`)}function st(e){let t=_e(),s=Object.entries(t).find(([,r])=>r.container_id===e.cid);s&&(delete t[s[0]],we(t),l(`[${e.name}] removed from the local contact book (entry "${s[0]}")`))}async function ve(e){if(!G)throw new Error("registrar is not available");await h(async t=>{await v(e,"::actor::pin_registrar",{registrar_ad:e.pw.packet.NewBinaryFromBuffer(G).Attach(t)},t)})}function U(e,t,s,r=!0,a,d=!1){let i=new ze;i.deferred_exposure=d;let f=["--unit_hash",H.hash,"--seed_phrase",t,"--unit_dir_path",H.dir];return a&&f.push("--init_trn_argument",JSON.stringify(a)),i.process_arguments(f),new Promise((o,n)=>{let u=setTimeout(()=>n(new Error(`packet creation for "${e}" timed out`)),3e4);L.packet_manager.create_packet(i,c=>{clearTimeout(u);let p={name:e,cid:S(m=>c.packet.GetContainerID().Attach(m).Visualize()),pw:c,dir:s,pending:[],lock:Promise.resolve()};ye(p,Se),r&&x.set(e,p),l(`[${e}] packet created \u2014 container id ${p.cid}`),o(p)},H.contents)})}var A=new Set(ce());A.size>0&&l(`reserved ${A.size} persisted identity name(s) at module load: ${[...A].join(", ")}`);async function ht(e,t={exposeLocal:!0,localAutoAccept:!0}){if(A.has(e)||x.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`);A.add(e);try{let s=K(e);$.mkdirSync(s,{recursive:!0,mode:448});let r;t.temp&&(r={owner:{tokenHash:t.temp.tokenHash,pid:t.temp.pid},createdAt:Date.now()},ae(s,r));let a=Te(24).toString("hex"),d=await U(e,a,s);return r&&(d.temp=r),$.writeFileSync(D(s),C(d),{mode:384}),await h(async i=>{await v(d,"::a2a_messaging::set_my_name",{name:e},i)}),await ve(d),t.localAutoAccept||await h(async i=>{await v(d,"::actor::set_local_policy",{auto_accept:!1},i)}),t.exposeLocal&&await he(d),z(d),d}catch(s){throw A.delete(e),s}}async function vt(e){let t=K(e),s=$.readFileSync(D(t),"utf8").trim(),r=await U(e,"",t,!1,s,!0);l(`[${e}] created QUARANTINED (no routing/broker registration, not client-bindable) \u2014 importing state before exposure`);let a=Number(process.env.OURS_TEST_RESTORE_HOLD_MS||"")||0;a>0&&(l(`[${e}] TEST HOLD: keeping restore open ${a}ms (OURS_TEST_RESTORE_HOLD_MS)`),await new Promise(o=>setTimeout(o,a)));let d=o=>/timed out waiting for the transaction result/.test(String(o)),i=(o,n,u)=>{l(`[${e}] ${o} ${n} \u2014 identity left UNEXPOSED and UNTRACKED (fail-closed)`);try{g(r,{event:"restore_fail_closed",step:o,error:String(u).slice(0,300)})}catch{}x.delete(e);try{L.remove_packet(r.cid)}catch(c){l(`[${e}] quarantined-packet teardown failed:`,String(c))}throw new Error(`identity "${e}": ${o} failed during restore (${n}) \u2014 left unexposed (fail-closed)`)},f=(o,n)=>i(o,"outcome UNKNOWN (timeout): the transaction may still execute and exposure would race it",n);if(Re(t)){let o=!1;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 n=$.readFileSync(I(t));await h(async u=>{let c=r.pw.packet.ParseValue(new Uint8Array(n)).Attach(u),p=Number(process.env.OURS_IMPORT_TIMEOUT_MS||"")||void 0;await v(r,"::actor::import_state",c,u,p)}),o=!0,l(`[${e}] state import completed (positively observed)`)}catch(n){d(n)&&f("import_state",n),l(`[${e}] FAILED TO IMPORT SAVED STATE \u2014 continuing with the reseeded identity; surviving contacts (if the blob was partially migrated) self-heal via contact restore:`,String(n)),g(r,{event:"state_import_failed",error:String(n).slice(0,300)});try{let u=`${I(t)}.failed-${Date.now()}`;$.renameSync(I(t),u),$.chmodSync(u,384),l(`[${e}] unreadable state blob preserved as state_data.bin.failed-*`)}catch{}}if(o){try{let c=await h(async p=>{let m=await v(r,"::a2a_messaging::commit_e2e_restore",{},p),w=m.Reduce("status").Visualize(),b=m.Reduce("sessions").IsNil()?"0":m.Reduce("sessions").Visualize();return{status:String(w),sessions:String(b)}});l(`[${e}] e2e restore commit: status=${c.status} sessions=${c.sessions}`)}catch(c){d(c)&&f("commit_e2e_restore",c),l(`[${e}] E2E RESTORE REJECTED \u2014 staged session blob failed pickle_key validation; discarding it, fresh account + self-heal fallback take over: ${String(c).slice(0,260)}`),g(r,{event:"e2e_restore_rejected",origin:"restore",error:String(c).slice(0,300)});try{await h(async p=>{await v(r,"::a2a_messaging::reject_e2e_restore",{},p)})}catch(p){d(p)&&f("reject_e2e_restore",p),l(`[${e}] reject_e2e_restore failed (staging is transient; continuing):`,String(p))}}try{r.pw.refresh_identity_proof_document(),l(`[${e}] transport IPD refreshed from post-import state`)}catch(c){i("ipd_refresh","FAILED (IPD would advertise a stale bundle)",c)}let n=!1,u="";try{if(process.env.OURS_TEST_FORCE_IPD_INCOHERENT==="1")throw new Error("forced incoherent (OURS_TEST_FORCE_IPD_INCOHERENT)");let c=S(w=>String(R(r,"::a2a_messaging::e2e_self_fp",w).Reduce("ik").Visualize())),p=r.pw.identity_proof_document.Visualize(),m=c.replace(/^0x/i,"");n=m.length>=32&&p.toLowerCase().includes(m.toLowerCase()),u=c.slice(0,18),g(r,{event:"ipd_coherence",ik:c,coherent:n})}catch(c){i("ipd_coherence","probe FAILED (coherence unprovable)",c)}l(`[${e}] IPD/e2e coherence: account_ik=${u}\u2026 ipd_advertises_it=${n}`),n||i("ipd_coherence","IPD does NOT advertise the live account ik",new Error("incoherent transport IPD"))}}return L.expose_packet(r.cid),x.set(e,r),l(`[${e}] EXPOSED (routing + broker registration) \u2014 import phase complete`),await ge(r),P(r),r}async function Vt(){y.mkdirSync(E(),{recursive:!0});let e;try{e=y.readFileSync(ee(),"utf8").trim()}catch{}let t=Ee(24).toString("hex");oe(await U(j,t,E(),!1,e)),e||y.writeFileSync(ee(),C(k),{mode:384}),se(te(k)),l(`contact-book registrar ready (${k.cid})`)}function Re(e){try{return y.existsSync(I(e))&&y.statSync(I(e)).size>0}catch{return!1}}function Ae(e){let t=S(d=>Buffer.from(R(e,"::actor::export_state",d).Serialize()));y.mkdirSync(e.dir,{recursive:!0,mode:448});let s=I(e.dir),r=`${s}.tmp`,a;try{a=y.openSync(r,"w",384),y.fchmodSync(a,384),y.writeFileSync(a,t),y.fsyncSync(a),y.closeSync(a),a=void 0,y.renameSync(r,s),y.chmodSync(s,384);try{y.chmodSync(D(e.dir),384)}catch{}let d=y.openSync(e.dir,"r");try{y.fsyncSync(d)}finally{y.closeSync(d)}}catch(d){if(a!==void 0)try{y.closeSync(a)}catch{}try{y.rmSync(r,{force:!0})}catch{}throw d}}function z(e){try{Ae(e),e.persistFailed&&(e.persistFailed=!1,l(`[${e.name}] persist recovered \u2014 quarantine lifted`),g(e,{event:"persist_recovered"}))}catch(t){e.persistFailed=!0,l(`[${e.name}] PERSIST FAILED \u2014 identity quarantined (fail-closed), outbound of this txn withheld:`,String(t));try{g(e,{event:"persist_failed",error:String(t).slice(0,300)})}catch{}throw process.nextTick(()=>ie(e.name,`[${e.name}] PERSIST FAILED \u2014 messaging quarantined until the state file is writable again`)),t}}function S(e){let t=new $e;try{return e(t)}finally{t.Finalize()}}async function h(e){let t=new $e;try{return await e(t)}finally{t.Finalize()}}function R(e,t,s,r){let a=be({name:t,targ:r}),d=e.pw.packet.ExecuteTransaction(a);return a.Destroy(),s?d.Attach(s):d}async function Oe(e,t){let s=e.lock,r;e.lock=new Promise(a=>r=a),await s;try{return await t()}finally{r()}}function De(e,t,s=25e3){return new Promise((r,a)=>{let d=setTimeout(()=>{let i=e.pending.findIndex(f=>f.timer===d);i>=0&&e.pending.splice(i,1),a(new Error("timed out waiting for the transaction result"))},s);e.pending.push({resolve:r,reject:a,timer:d}),e.pw.add_client_message(t)})}function v(e,t,s,r,a){if(e.persistFailed)try{z(e)}catch(i){return Promise.reject(new Error(`identity "${e.name}" is quarantined: state persist is failing (${String(i)}) \u2014 mutations are rejected until state_data.bin is writable again`))}let d=be({name:t,targ:s});return Oe(e,()=>De(e,d,a)).then(i=>{if(d.Destroy(),e.persistFailed){try{i.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 r?i.Attach(r):i},i=>{try{d.Destroy()}catch{}throw i})}var F=null;function Ht(e){F?.uninstall(),F=e===null?null:{hook:e,uninstall:le("notification",e)}}function qt(e){F?.hook===e&&(F.uninstall(),F=null)}function ie(e,t){pe(e,t)}var Se={onNotify:(e,t)=>ie(e,t)},W={inbound:["message_received","file_received"],intro:["local_contact_request","pending_message"],get wake(){return[...W.inbound,...W.intro]}};function Pe(e){if(e===null||e==="")return null;let t=new Set;for(let s of e.split(",")){let r=s.trim();if(r==="")continue;let a=W[r];if(!a)throw new Error(r);for(let d of a)t.add(d)}return t}function Fe(e,t){return t===null?!0:typeof e.event=="string"&&t.has(e.event)}var J=new Map;function je(e){let t=J.get(e);if(!(!t||t.size===0))for(let s of[...t])try{s()}catch{}}function Le(e,t){return new Promise(s=>{let r=J.get(e);r||(r=new Set,J.set(e,r));let a=!1,d=()=>{a||(a=!0,r.delete(i),r.size===0&&J.delete(e),clearTimeout(f),s())},i=d,f=setTimeout(d,t);r.add(i)})}function g(e,t){try{_.mkdirSync(e.dir,{recursive:!0,mode:448}),_.appendFileSync(B(e.dir),JSON.stringify(t)+`
|
|
3
3
|
`)}catch(s){l(`[${e.name}] failed to append notifications.log:`,String(s))}je(e.name),fe(e,t)}function Ct(e){let t=B(e.dir),s="";try{s=_.readFileSync(t,"utf8")}catch{return new Set}let r=[];for(let a of s.split(`
|
|
4
4
|
`))if(a.trim())try{r.push(JSON.parse(a))}catch{}return ue(r)}function T(e,t){let s=e.Reduce(t);return s.IsNil()?"":Buffer.from(s.GetBinary()).toString("hex")}var Be=Number(process.env.OURS_NOTIFY_LONGPOLL_MS)>0?Number(process.env.OURS_NOTIFY_LONGPOLL_MS):25e3,Me=250;function ke(e){try{return _.statSync(e).size}catch{return 0}}function He(e,t,s){if(s<=t)return{events:[],cursor:t};let r=Buffer.alloc(s-t),a=0;try{let o=_.openSync(e,"r");try{a=_.readSync(o,r,0,r.length,t)}finally{_.closeSync(o)}}catch{return{events:[],cursor:t}}let d=r.subarray(0,a),i=d.lastIndexOf(10);if(i===-1)return{events:[],cursor:t};let f=[];for(let o of d.subarray(0,i+1).toString("utf8").split(`
|
|
5
5
|
`))if(o.trim())try{f.push(JSON.parse(o))}catch{}return{events:f,cursor:t+i+1}}async function Ut(e,t,s,r,a=null){let d=B(Ie(V,s)),i=(c,p)=>{t.writableEnded||(t.writeHead(200,{"Content-Type":"application/json"}),t.end(JSON.stringify({cursor:c,events:p})))},f;try{f=Pe(a)}catch(c){t.writableEnded||(t.writeHead(400,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:`unknown notification kind "${String(c.message)}" \u2014 known kinds: ${Object.keys(W).sort().join(", ")}`})));return}if(r===null||r==="tip"){i(ke(d),[]);return}let o=parseInt(r,10);if(!Number.isFinite(o)||o<0){t.writableEnded||(t.writeHead(400,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"invalid since cursor"})));return}let n=!1;e.on("close",()=>{n=!0});let u=Date.now()+Be;for(;!n;){let c=ke(d);if(o>c&&(o=0),c>o){let{events:p,cursor:m}=He(d,o,c);o=m;let w=f===null?p:p.filter(b=>Fe(b,f));if(w.length>0){i(m,w);return}}if(Date.now()>=u)break;await Le(s,Math.min(Me,u-Date.now()))}n||i(o,[])}function P(e){try{let{unread:t,unreadFiles:s}=S(d=>{let f=me(R(e,"::actor::list_incoming_messages",d)).filter(u=>u.status==="unread"),o=R(e,"::actor::list_incoming_files",d),n=[];if(!o.IsNil())for(let u=0;;u++){let c=o.Reduce(u);if(c.IsNil())break;c.Reduce("status").Visualize()==="unread"&&n.push({file_id:c.Reduce("file_id").Visualize(),sender_id:c.Reduce("sender_id").Visualize(),from:c.Reduce("sender_name").Visualize(),filename:c.Reduce("filename").Visualize(),mime:c.Reduce("mime").Visualize(),bytes:c.Reduce("size").Visualize(),date:c.Reduce("date").Visualize(),wire_id:c.Reduce("wire_id").Visualize()})}return{unread:f,unreadFiles:n}}),r={count:t.length,recent:t.slice(-10).map(d=>({from:d.sender_name,msg_id:d.msg_id,date:d.date})),files:s.length,unread_files:s.slice(-10)};_.mkdirSync(e.dir,{recursive:!0,mode:448});let a=`${M(e.dir)}.tmp`;_.writeFileSync(a,JSON.stringify(r)),_.renameSync(a,M(e.dir))}catch(t){l(`[${e.name}] failed to refresh unread snapshot:`,String(t))}}function Jt(){let e=[],t=[];try{t=_.readdirSync(V,{withFileTypes:!0})}catch{return{identities:e}}for(let s of t){if(!s.isDirectory()||ne(s.name)!==null)continue;let r;try{r=JSON.parse(_.readFileSync(M(Ie(V,s.name)),"utf8"))}catch{continue}let a=Number.isSafeInteger(r.count)&&Number(r.count)>=0?Number(r.count):0,d=Number.isSafeInteger(r.files)&&Number(r.files)>=0?Number(r.files):0;if(a===0&&d===0)continue;let i=Array.isArray(r.recent)?r.recent.slice(-10).flatMap(o=>{if(!o||typeof o!="object")return[];let n=o;return typeof n.from!="string"||!["string","number"].includes(typeof n.msg_id)||typeof n.date!="string"?[]:[{from:n.from,msg_id:n.msg_id,date:n.date}]}):[],f=Array.isArray(r.unread_files)?r.unread_files.slice(-10).flatMap(o=>{if(!o||typeof o!="object")return[];let n=o;return typeof n.from!="string"||typeof n.filename!="string"||typeof n.mime!="string"||typeof n.wire_id!="string"?[]:[{from:n.from,filename:n.filename,mime:n.mime,wire_id:n.wire_id,...typeof n.sender_id=="string"?{sender_id:n.sender_id}:{},...["string","number"].includes(typeof n.file_id)?{file_id:n.file_id}:{},...["string","number"].includes(typeof n.bytes)?{bytes:n.bytes}:{},...typeof n.date=="string"?{date:n.date}:{}}]}):[];e.push({name:s.name,count:a,recent:i,files:d,unread_files:f})}return e.sort((s,r)=>String(s.name).localeCompare(String(r.name))),{identities:e}}export{Ht as a,qt as b,ie as c,Se as d,W as e,Pe as f,Fe as g,je as h,Le as i,g as j,Ct as k,T as l,ke as m,He as n,Ut as o,P as p,Jt as q,Je as r,Ne as s,X as t,ge as u,xe as v,q as w,We as x,ye as y,U as z,A,ht as B,vt as C,Vt as D,Re as E,Ae as F,z as G,S as H,h as I,R as J,Oe as K,De as L,v as M,E as N,ee as O,Q as P,_e as Q,we as R,te as S,C as T,he as U,st as V,ve as W};
|
|
@@ -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-CIHGEBUR.js";import{i as S}from"./chunk-T76BFV6S.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{I as m,M as s,u as c,v as l,x as f}from"./chunk-
|
|
2
|
+
import{I as m,M as s,u as c,v as l,x as f}from"./chunk-MQ5AXTPT.js";import{c as o}from"./chunk-CIHGEBUR.js";import{f as i,i as a}from"./chunk-T76BFV6S.js";var e=null,n=!1;function v(){e||(e=setInterval(()=>{n||(n=!0,(async()=>{try{for(let t of o.values()){try{await m(async r=>{await s(t,"::actor::gc",{},r)})}catch(r){a(`gc(${t.name}) failed:`,String(r))}await c(t),await l(t),await f(t)}}finally{n=!1}})())},i),e.unref?.(),a(`message GC timer armed (every ${i}ms)`))}function w(){e&&(clearInterval(e),e=null)}export{v as a,w as b};
|