@ours.network/messenger-server 1.0.30 → 1.0.31-nightly.10

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.
Files changed (154) hide show
  1. package/README.md +132 -24
  2. package/dist/chunks/{chunk-3EUXH4PV.js → chunk-O34PQ4M6.js} +15 -1
  3. package/dist/chunks/{server-WOE26ICL.js → server-Q2BQSKMJ.js} +3035 -2206
  4. package/dist/cli.js +14 -3
  5. package/package.json +8 -35
  6. package/dist/web/assets/abnfDiagram-N423BO3Z-C-iag_Nj.js +0 -2
  7. package/dist/web/assets/abnfDiagram-N423BO3Z-C-iag_Nj.js.map +0 -1
  8. package/dist/web/assets/arc-Bcm2sZNj.js +0 -2
  9. package/dist/web/assets/arc-Bcm2sZNj.js.map +0 -1
  10. package/dist/web/assets/architectureDiagram-T3A2C74G-Cf8AnIVp.js +0 -37
  11. package/dist/web/assets/architectureDiagram-T3A2C74G-Cf8AnIVp.js.map +0 -1
  12. package/dist/web/assets/blockDiagram-VBNYF7ZC-Ch9RzKmh.js +0 -133
  13. package/dist/web/assets/blockDiagram-VBNYF7ZC-Ch9RzKmh.js.map +0 -1
  14. package/dist/web/assets/browser-mCqw9EMW.js +0 -9
  15. package/dist/web/assets/browser-mCqw9EMW.js.map +0 -1
  16. package/dist/web/assets/c4Diagram-5PPSVZJV-vFBfClLI.js +0 -11
  17. package/dist/web/assets/c4Diagram-5PPSVZJV-vFBfClLI.js.map +0 -1
  18. package/dist/web/assets/channel-B7e1tuOt.js +0 -2
  19. package/dist/web/assets/channel-B7e1tuOt.js.map +0 -1
  20. package/dist/web/assets/chunk-2GRJ4B5K-CovDVQb1.js +0 -2
  21. package/dist/web/assets/chunk-2GRJ4B5K-CovDVQb1.js.map +0 -1
  22. package/dist/web/assets/chunk-2Q5K7J3B-DMq4JEsX.js +0 -2
  23. package/dist/web/assets/chunk-2Q5K7J3B-DMq4JEsX.js.map +0 -1
  24. package/dist/web/assets/chunk-5RXB4S5H-CrraHros.js +0 -232
  25. package/dist/web/assets/chunk-5RXB4S5H-CrraHros.js.map +0 -1
  26. package/dist/web/assets/chunk-5VM5RSS4-Dtkchtl6.js +0 -16
  27. package/dist/web/assets/chunk-5VM5RSS4-Dtkchtl6.js.map +0 -1
  28. package/dist/web/assets/chunk-6Q2QTUOP-C7hewS6C.js +0 -89
  29. package/dist/web/assets/chunk-6Q2QTUOP-C7hewS6C.js.map +0 -1
  30. package/dist/web/assets/chunk-GF5L2VYU-lRYUPE4E.js +0 -207
  31. package/dist/web/assets/chunk-GF5L2VYU-lRYUPE4E.js.map +0 -1
  32. package/dist/web/assets/chunk-JWPE2WC7-DmDsLF1N.js +0 -2
  33. package/dist/web/assets/chunk-JWPE2WC7-DmDsLF1N.js.map +0 -1
  34. package/dist/web/assets/chunk-KBJHAD2P-C4tA-lat.js +0 -2
  35. package/dist/web/assets/chunk-KBJHAD2P-C4tA-lat.js.map +0 -1
  36. package/dist/web/assets/chunk-RYQCIY6F-CWf-qdbG.js +0 -2
  37. package/dist/web/assets/chunk-RYQCIY6F-CWf-qdbG.js.map +0 -1
  38. package/dist/web/assets/chunk-XXDRQBXY-C0-3Uouc.js +0 -2
  39. package/dist/web/assets/chunk-XXDRQBXY-C0-3Uouc.js.map +0 -1
  40. package/dist/web/assets/classDiagram-JCYQIIEL-D0TeT53t.js +0 -2
  41. package/dist/web/assets/classDiagram-JCYQIIEL-D0TeT53t.js.map +0 -1
  42. package/dist/web/assets/classDiagram-v2-OCEON4UE-D0TeT53t.js +0 -2
  43. package/dist/web/assets/classDiagram-v2-OCEON4UE-D0TeT53t.js.map +0 -1
  44. package/dist/web/assets/cose-bilkent-JH36ORCC-C8vPfGok.js +0 -2
  45. package/dist/web/assets/cose-bilkent-JH36ORCC-C8vPfGok.js.map +0 -1
  46. package/dist/web/assets/cynefin-VYW2F7L2-Qz363tl0.js +0 -179
  47. package/dist/web/assets/cynefin-VYW2F7L2-Qz363tl0.js.map +0 -1
  48. package/dist/web/assets/cynefinDiagram-MW4NZA55-CCZz9fIq.js +0 -63
  49. package/dist/web/assets/cynefinDiagram-MW4NZA55-CCZz9fIq.js.map +0 -1
  50. package/dist/web/assets/cytoscape.esm-BvX2Lq_V.js +0 -332
  51. package/dist/web/assets/cytoscape.esm-BvX2Lq_V.js.map +0 -1
  52. package/dist/web/assets/dagre-VZM6K2ZE-TEwK45KH.js +0 -5
  53. package/dist/web/assets/dagre-VZM6K2ZE-TEwK45KH.js.map +0 -1
  54. package/dist/web/assets/defaultLocale-DX6XiGOO.js +0 -2
  55. package/dist/web/assets/defaultLocale-DX6XiGOO.js.map +0 -1
  56. package/dist/web/assets/diagram-7IWD3JNH-CpCoKfEC.js +0 -31
  57. package/dist/web/assets/diagram-7IWD3JNH-CpCoKfEC.js.map +0 -1
  58. package/dist/web/assets/diagram-B4RE2ZJO-CJS8Rz4d.js +0 -4
  59. package/dist/web/assets/diagram-B4RE2ZJO-CJS8Rz4d.js.map +0 -1
  60. package/dist/web/assets/diagram-LBJQPF4R-Dp-7zIWd.js +0 -25
  61. package/dist/web/assets/diagram-LBJQPF4R-Dp-7zIWd.js.map +0 -1
  62. package/dist/web/assets/diagram-Q27KOJAE-BeOOSo_Y.js +0 -25
  63. package/dist/web/assets/diagram-Q27KOJAE-BeOOSo_Y.js.map +0 -1
  64. package/dist/web/assets/diagram-UB23O5K3-wtVvpUaS.js +0 -42
  65. package/dist/web/assets/diagram-UB23O5K3-wtVvpUaS.js.map +0 -1
  66. package/dist/web/assets/ebnfDiagram-BXEA7PRR-BUZU6kcO.js +0 -2
  67. package/dist/web/assets/ebnfDiagram-BXEA7PRR-BUZU6kcO.js.map +0 -1
  68. package/dist/web/assets/erDiagram-JOGREHBK-BeLhinfN.js +0 -86
  69. package/dist/web/assets/erDiagram-JOGREHBK-BeLhinfN.js.map +0 -1
  70. package/dist/web/assets/flowDiagram-UKHOOZJN-BWAl9KvX.js +0 -157
  71. package/dist/web/assets/flowDiagram-UKHOOZJN-BWAl9KvX.js.map +0 -1
  72. package/dist/web/assets/ganttDiagram-PKOTCBZU-BQM681Qz.js +0 -293
  73. package/dist/web/assets/ganttDiagram-PKOTCBZU-BQM681Qz.js.map +0 -1
  74. package/dist/web/assets/gitGraphDiagram-DS77QQ5N-B90O3LS2.js +0 -107
  75. package/dist/web/assets/gitGraphDiagram-DS77QQ5N-B90O3LS2.js.map +0 -1
  76. package/dist/web/assets/graph-gxHQN9-b.js +0 -2
  77. package/dist/web/assets/graph-gxHQN9-b.js.map +0 -1
  78. package/dist/web/assets/index-C65oKF4f.js +0 -332
  79. package/dist/web/assets/index-C65oKF4f.js.map +0 -1
  80. package/dist/web/assets/index-SAASLXJR.css +0 -1
  81. package/dist/web/assets/infoDiagram-6WML65LV-DL7wlrUp.js +0 -3
  82. package/dist/web/assets/infoDiagram-6WML65LV-DL7wlrUp.js.map +0 -1
  83. package/dist/web/assets/init-Gi6I4Gst.js +0 -2
  84. package/dist/web/assets/init-Gi6I4Gst.js.map +0 -1
  85. package/dist/web/assets/ishikawaDiagram-WSZJBQD7-CGJ65gLl.js +0 -71
  86. package/dist/web/assets/ishikawaDiagram-WSZJBQD7-CGJ65gLl.js.map +0 -1
  87. package/dist/web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  88. package/dist/web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  89. package/dist/web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  90. package/dist/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  91. package/dist/web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  92. package/dist/web/assets/journeyDiagram-NVQOT4AX-CWln_1Vi.js +0 -140
  93. package/dist/web/assets/journeyDiagram-NVQOT4AX-CWln_1Vi.js.map +0 -1
  94. package/dist/web/assets/jsQR-C-e-dPgH.js +0 -2
  95. package/dist/web/assets/jsQR-C-e-dPgH.js.map +0 -1
  96. package/dist/web/assets/kanban-definition-27J2QSJJ-Ch_LASS_.js +0 -90
  97. package/dist/web/assets/kanban-definition-27J2QSJJ-Ch_LASS_.js.map +0 -1
  98. package/dist/web/assets/katex-HP8lGamR.js +0 -258
  99. package/dist/web/assets/katex-HP8lGamR.js.map +0 -1
  100. package/dist/web/assets/layout-CpcJW2by.js +0 -2
  101. package/dist/web/assets/layout-CpcJW2by.js.map +0 -1
  102. package/dist/web/assets/linear-DLAFoEik.js +0 -2
  103. package/dist/web/assets/linear-DLAFoEik.js.map +0 -1
  104. package/dist/web/assets/map-CKPHyBGT.js +0 -2
  105. package/dist/web/assets/map-CKPHyBGT.js.map +0 -1
  106. package/dist/web/assets/mermaid.core-11YjnhKz.js +0 -315
  107. package/dist/web/assets/mermaid.core-11YjnhKz.js.map +0 -1
  108. package/dist/web/assets/mindmap-definition-FAOFIHXS-j-6HQbPv.js +0 -97
  109. package/dist/web/assets/mindmap-definition-FAOFIHXS-j-6HQbPv.js.map +0 -1
  110. package/dist/web/assets/ordinal-Cboi1Yqb.js +0 -2
  111. package/dist/web/assets/ordinal-Cboi1Yqb.js.map +0 -1
  112. package/dist/web/assets/pegDiagram-VL7TDLO6-1XHHRMUK.js +0 -2
  113. package/dist/web/assets/pegDiagram-VL7TDLO6-1XHHRMUK.js.map +0 -1
  114. package/dist/web/assets/pieDiagram-7S7Q4E2Y-Cu-3GzNo.js +0 -40
  115. package/dist/web/assets/pieDiagram-7S7Q4E2Y-Cu-3GzNo.js.map +0 -1
  116. package/dist/web/assets/quadrantDiagram-CIZ2JOQS-DkP9Oaqo.js +0 -8
  117. package/dist/web/assets/quadrantDiagram-CIZ2JOQS-DkP9Oaqo.js.map +0 -1
  118. package/dist/web/assets/railroadDiagram-AXF67PYL-BFaH77uW.js +0 -2
  119. package/dist/web/assets/railroadDiagram-AXF67PYL-BFaH77uW.js.map +0 -1
  120. package/dist/web/assets/requirementDiagram-LRYGKXZP-D4D1Up4W.js +0 -85
  121. package/dist/web/assets/requirementDiagram-LRYGKXZP-D4D1Up4W.js.map +0 -1
  122. package/dist/web/assets/sankeyDiagram-W5VNT64P-BrHCAjc9.js +0 -41
  123. package/dist/web/assets/sankeyDiagram-W5VNT64P-BrHCAjc9.js.map +0 -1
  124. package/dist/web/assets/sequenceDiagram-SI44F4Z6-CWxNfjdi.js +0 -163
  125. package/dist/web/assets/sequenceDiagram-SI44F4Z6-CWxNfjdi.js.map +0 -1
  126. package/dist/web/assets/sizeCapture-X5ZJPWSS-ePEYSWdD.js +0 -2
  127. package/dist/web/assets/sizeCapture-X5ZJPWSS-ePEYSWdD.js.map +0 -1
  128. package/dist/web/assets/stateDiagram-OKZ733FA-BLfZi2Ah.js +0 -2
  129. package/dist/web/assets/stateDiagram-OKZ733FA-BLfZi2Ah.js.map +0 -1
  130. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-CtzDIhSY.js +0 -2
  131. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-CtzDIhSY.js.map +0 -1
  132. package/dist/web/assets/swimlanes-SLNWSIFB-HnXWSaTr.js +0 -3
  133. package/dist/web/assets/swimlanes-SLNWSIFB-HnXWSaTr.js.map +0 -1
  134. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-DEnvqxAR.js +0 -9
  135. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-DEnvqxAR.js.map +0 -1
  136. package/dist/web/assets/timeline-definition-Z64GVDOM-D4kboPkf.js +0 -121
  137. package/dist/web/assets/timeline-definition-Z64GVDOM-D4kboPkf.js.map +0 -1
  138. package/dist/web/assets/vennDiagram-T6HMQDX7-CmUlC-yb.js +0 -35
  139. package/dist/web/assets/vennDiagram-T6HMQDX7-CmUlC-yb.js.map +0 -1
  140. package/dist/web/assets/wardleyDiagram-T6FBY63Y-DoLIyOSu.js +0 -79
  141. package/dist/web/assets/wardleyDiagram-T6FBY63Y-DoLIyOSu.js.map +0 -1
  142. package/dist/web/assets/xychartDiagram-ELKLHX3M-BII0rBQD.js +0 -8
  143. package/dist/web/assets/xychartDiagram-ELKLHX3M-BII0rBQD.js.map +0 -1
  144. package/dist/web/icons/apple-touch-icon.png +0 -0
  145. package/dist/web/icons/favicon-16.png +0 -0
  146. package/dist/web/icons/favicon-32.png +0 -0
  147. package/dist/web/icons/icon-192-maskable.png +0 -0
  148. package/dist/web/icons/icon-192.png +0 -0
  149. package/dist/web/icons/icon-512-maskable.png +0 -0
  150. package/dist/web/icons/icon-512.png +0 -0
  151. package/dist/web/index.html +0 -19
  152. package/dist/web/manifest.webmanifest +0 -17
  153. package/dist/web/sw.js +0 -181
  154. package/dist/web/version.json +0 -1
package/README.md CHANGED
@@ -12,12 +12,31 @@ invalidations; the browser rebuilds durable truth from REST snapshots.
12
12
 
13
13
  ## Shared daemon and identity
14
14
 
15
- `start()` calls the SDK's client-only `attachOursClient`, using the standard
16
- `OURS_CONFIG`, `OURS_STATE_DIR`, `OURS_PORT`, endpoint, and API-token selection.
17
- The SDK verifies that the endpoint belongs to the expected state directory
18
- before sending credentials. Messenger then calls `chooseIdentity` for exactly
19
- `OURS_MESSENGER_IDENTITY`; it never creates an identity or chooses one
20
- implicitly.
15
+ For V1, set all three variables: `OURS_DAEMON_URL` (HTTP endpoint),
16
+ `OURS_DAEMON_ID` (expected daemon instance ID), and
17
+ `OURS_DAEMON_CREDENTIAL_PATH` (protected current API-token file).
18
+ The same SDK client handles identity operations and complete notification pages.
19
+ It checks daemon selection, refuses redirects and rereads the token file on
20
+ each request, including after an official CLI token update. Partial selection
21
+ fails before attachment; API errors never activate legacy selection.
22
+
23
+ One opaque process owner survives ordinary reconnect and daemon restart.
24
+ Messenger binds exactly `OURS_MESSENGER_IDENTITY`, preserving its existing
25
+ permanent identity; it never implicitly provisions or forces takeover.
26
+ When all three V1 inputs are absent, the existing SDK local configuration
27
+ selection remains temporary compatibility. Its removal is post-V1 work.
28
+
29
+ Example against an already provisioned V1 daemon (use the endpoint, instance ID
30
+ and protected credential path supplied by your deployment):
31
+
32
+ ```bash
33
+ OURS_DAEMON_URL=http://127.0.0.1:38351 \
34
+ OURS_DAEMON_ID='<daemon-instance-id>' \
35
+ OURS_DAEMON_CREDENTIAL_PATH=/srv/messenger/daemon-token \
36
+ OURS_MESSENGER_IDENTITY='Ada@server' \
37
+ OURS_MESSENGER_PUBLIC_ORIGIN=http://127.0.0.1:8420 \
38
+ node dist/cli.js serve
39
+ ```
21
40
 
22
41
  The shared daemon owns identity keys, MUFL protocol state, message/file history,
23
42
  and file blobs. Messenger owns only its public HTTP server and application state
@@ -28,20 +47,24 @@ but does not stop the daemon.
28
47
  Startup is transactional: a daemon-attach, identity-bind, application-store,
29
48
  watcher, or listener failure closes the public server if present, stops the
30
49
  watcher, releases the lease, and preserves existing state. Normal `close()` is
31
- idempotent and follows the same ordered path.
50
+ idempotent and follows the same ordered path. It waits for admitted HTTP work,
51
+ notification watching and delivery before retiring the owner and closing the
52
+ SDK transport. An incomplete owner release rejects close and makes CLI shutdown
53
+ exit unsuccessfully; repeated close calls retain that result.
32
54
 
33
55
  ## Running
34
56
 
35
- Install and start the shared daemon with `@ours.network/cli`, create the identity
36
- there, then start messenger with the same daemon selection:
57
+ Install and start the shared daemon with `@ours.network/daemon`, create the identity
58
+ there, then start messenger with the same daemon selection. The following
59
+ example uses the temporary local configuration path:
37
60
 
38
61
  ```bash
39
62
  npm install
40
63
  npm run build
41
64
 
42
- # One-time host setup. These commands come from @ours.network/cli.
43
- ours config setup --port 3070 --state-dir /srv/ours
44
- ours daemon start
65
+ # One-time host setup: daemon lifecycle is separate from API client commands.
66
+ ours-daemon config setup --port 3070 --state-dir /srv/ours
67
+ ours-daemon start
45
68
  ours identity create-root --name 'Ada@server'
46
69
 
47
70
  OURS_MESSENGER_STATE_DIR=/srv/ours-messenger \
@@ -72,11 +95,11 @@ OURS_MESSENGER_VAPID_PRIVATE_KEY optional secret; never expose to the browser
72
95
  OURS_MESSENGER_VAPID_SUBJECT default mailto:admin@localhost
73
96
  ```
74
97
 
75
- The production build is an installable React 18 + TypeScript PWA emitted by Vite under
76
- `dist/web`: `index.html` is no-cache, while content-hashed `/assets/*` are served
77
- immutable with explicit MIME types and `nosniff`. During frontend-only work,
78
- `npm run dev` starts Vite on loopback and proxies `/api` and `/mcp` to the
79
- messenger server; use `npm run dev:server` for the backend process.
98
+ The browser application is built in the standalone `ours-web` repository. Set
99
+ `OURS_MESSENGER_WEB_DIR` to its `dist/web` directory if this server should host
100
+ that artifact; without it the API remains available and frontend routes report
101
+ 503. Static hosting keeps `index.html` uncached and hashed assets immutable.
102
+ Use `npm run dev:server` for backend development.
80
103
 
81
104
  Every state-changing HTTP request must carry `Content-Type: application/json`,
82
105
  an exact single `Origin` equal to `OURS_MESSENGER_PUBLIC_ORIGIN`, and
@@ -111,9 +134,7 @@ The focused client does not persist messages, identities, receipts, or API
111
134
  responses in browser storage. Its service worker caches only the application
112
135
  shell and static assets for offline launch; all `/api/*` requests bypass it.
113
136
 
114
- The web UI and its same-origin transport adapter are maintained together in
115
- this repository; their presentation scope and transport exclusions are recorded
116
- in `web/src/CANONICAL_UI_PROVENANCE.md`. The interface
137
+ The web UI and its same-origin transport adapter now live in the standalone `ours-web` repository. This repository builds only the Messenger backend. To optionally serve a separately built frontend, set `OURS_MESSENGER_WEB_DIR` to its `dist/web` directory; otherwise deploy the API behind the same-origin frontend gateway. The interface
117
138
  includes grouped identity-root contacts; contact add, approval, rename and
118
139
  removal; one-time/public invite creation and revocation; public bio editing;
119
140
  message and attachment replies; drag/drop/paste and picker uploads with bounded
@@ -290,10 +311,11 @@ conversation reads, graceful lease release, bundle execution, token redaction,
290
311
  `/mcp` 404, programmatic shutdown and partial-start rollback, receipt semantics,
291
312
  REST/WebPush encryption and full payloads, reply correlation, immutable media and
292
313
  version round-trips, hostile top-level media navigation, exact voice MIME/bytes,
293
- sandboxed previews, corrupt push-state preservation/recovery, PWA cache
294
- isolation/installability/offline launch in Chromium, SSE backpressure and
295
- reconnect, cursor paging with stable scroll anchoring, invite-dialog reopen,
296
- focused-client contracts and the exact-dialog read gate.
314
+ sandboxed preview responses, corrupt push-state preservation/recovery and SSE
315
+ backpressure. UI, PWA, browser layout, and client read-gate tests live in `ours-web`.
316
+ The optional `tests/v1-live-push.integration.mjs` service integration requires
317
+ Firefox, public Autopush egress, and an explicit `OURS_MESSENGER_WEB_DIR` pointing
318
+ to a separately built frontend; it is outside the default local test suite.
297
319
 
298
320
  ## SDK lifecycle boundary
299
321
 
@@ -301,3 +323,89 @@ Messenger imports only the public client surface of `@ours.network/sdk`.
301
323
  Bundle-contract tests reject daemon/native/MUFL artifacts and embedded-runtime
302
324
  imports. Process signals stop the messenger HTTP application and release its
303
325
  identity lease; daemon lifecycle remains exclusively under the ours CLI.
326
+
327
+ ### Retained messenger session
328
+
329
+ With complete V1 selection and the available Linux activation primitive, messenger
330
+ retains one logical owner in private
331
+ `owner-session.json` and holds the stable `owner-session.lock` descriptor for its
332
+ entire active lifetime. The existing `flock` utility must support this filesystem;
333
+ a competing activation refuses before daemon attachment. Foreground/container
334
+ restart with the same state continues the nonterminal owner and permanent identity.
335
+ The lock is not process-death evidence, and restart does not replay ambiguous sends.
336
+
337
+ After existing work drains, normal shutdown saves terminal intent before the
338
+ official bounded SDK release. Incomplete acknowledgement preserves that same
339
+ intent; ordinary startup completes it before creating a fresh logical owner.
340
+ Changed daemon/credential-path/identity selection cannot retarget saved state.
341
+ Corrupt or unsafe state is preserved and refused. Keep the lock file and its inode.
342
+
343
+ This recovery is qualified initially for the tested Linux Docker local-volume
344
+ profile. Existing legacy/non-Linux entrypoints without retained V1 state keep their prior
345
+ behavior. On Linux, an absent `flock` executable also preserves the original
346
+ process-session behavior only when no owner record exists; V1 daemon selection
347
+ stays unchanged. Contention, invalid state and other activation errors refuse;
348
+ there is no unlocked resume or fallback after a daemon/API failure.
349
+ A saved V1 owner cannot resume through an unqualified or legacy path. Native,
350
+ bind-mount and other runtime conformance remains required; no utility is installed
351
+ automatically. The state contains owner/selection/terminal metadata, not API-token
352
+ bytes. Existing push/VAPID/cursor state and live-push requirements remain unchanged.
353
+
354
+ ## Container-runtime checks
355
+
356
+ After the normal build, `npm run test:offline` includes the existing owner-session
357
+ and V1 runtime tests. They exercise lifecycle, explicit selection and notification
358
+ behavior with temporary fixtures. For the built server plus installed selected CLI/SDK and local development broker,
359
+ run `node tests/v1-messenger.integration.mjs lifecycle` (also supports `crash` and
360
+ `incomplete`). `node tests/v1-live-push.integration.mjs` additionally requires
361
+ Playwright Firefox and public HTTPS/WSS access to Mozilla Autopush; keep it outside
362
+ offline checks. `MESSENGER_V1_DIST` selects an alternative prepared build directory.
363
+ Package test results alone do not establish complete Compose or live push acceptance.
364
+
365
+ ### Build with selected SDK and CLI archives
366
+
367
+ Run in the build container with Node 22+, npm and tar available:
368
+
369
+ ```sh
370
+ node scripts/build-selected.mjs --sdk /artifacts/ours.network-sdk-3.7.2.tgz --cli /artifacts/ours.network-cli-2.7.2.tgz --out-dir /artifacts/consumer
371
+ ```
372
+
373
+ The recipe validates package names, installs and builds in disposable staging,
374
+ then writes one complete portable npm archive. Stdout is a JSON object with its
375
+ actual `filename`; build/npm logs go to stderr. Normal source manifests, locks
376
+ and installed dependencies are preserved. The installer must install the same
377
+ selected SDK and CLI archives alongside this package; its final dependency
378
+ versions come from those archives. Existing bundling choices are unchanged.
379
+
380
+ Git source provenance is captured before staging. For source-only input, supply
381
+ `OURS_MESSENGER_BUILD_SHA` (full source commit) and truthful
382
+ `OURS_MESSENGER_BUILD_CLEAN=1` for a clean snapshot, as required by `build.mjs`.
383
+ `OURS_MESSENGER_RELEASE_BUILD=1` retains the existing clean-source gate.
384
+
385
+ Focused build/install verification (two real builds, including changed bytes
386
+ under identical input names and versions, plus a missing-vendor negative check):
387
+
388
+ ```sh
389
+ node scripts/check-build-selected.mjs --sdk /artifacts/ours.network-sdk-3.7.2.tgz --cli /artifacts/ours.network-cli-2.7.2.tgz
390
+ ```
391
+
392
+ For development against the selected, unpublished SDK/CLI sources, see [selected-source development](docs/selected-source-development.md).
393
+
394
+ ### Gateway mount path
395
+
396
+ Set `OURS_MESSENGER_BASE_PATH=/base/messenger/` when a reverse proxy strips that prefix before forwarding to Messenger. `OURS_MESSENGER_PUBLIC_ORIGIN` remains the exact external origin, for example `https://ours.example`, with no path. Assets, API requests, browser routes, service-worker scope and presence WebSockets retain the configured mount. `ours-messenger-server capabilities` reports `messenger.gateway-prefix-v1`.
397
+
398
+ Messenger still has no application authentication. Use the installer's loopback gateway or an authenticated external proxy/tunnel. A shared gateway origin trusts every hosted application; path prefixes and Cowork's separate server-token prompt do not isolate or authenticate Messenger. Keep backend ports private and use the installer documentation's browser-authenticated entry configuration.
399
+
400
+ ### Fleet web application
401
+
402
+ The live local Fleet application is available at `/fleet`; Messenger remains at `/chats`.
403
+ Use the companion Fleet gateway and its local password/session authentication.
404
+ See [Fleet setup and verification](docs/FLEET-PREVIEW.md) for connection requirements,
405
+ current coverage and limitations. `npm run test:fleet` runs the current isolated fixture gates.
406
+ The older mock walkthrough and its browser tests describe an earlier design stage.
407
+
408
+
409
+ ### Dedicated notification service
410
+
411
+ Set `OURS_NOTIFICATIONS_ORIGIN` and a Messenger-scoped `OURS_NOTIFICATIONS_PRODUCER_TOKEN` to forward incoming messages/files to [ours-notifications](https://github.com/adapt-toolkit/ours-notifications). Both settings must be provided together. The canonical watcher durably queues notifications even without a local push binding, freezes projected content before its first HTTP attempt, and retries the same payload after outages/restarts. Keep the Messenger state directory across restarts. When configured, new events use the dedicated service; legacy pending push jobs may finish. Existing standalone push endpoints remain for compatibility.
@@ -1,3 +1,4 @@
1
+ import { createRequire as __messengerCreateRequire } from "node:module"; const require = __messengerCreateRequire(import.meta.url);
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -37,10 +38,21 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
38
  var define_MESSENGER_BUILD_INFO_default;
38
39
  var init_define_MESSENGER_BUILD_INFO = __esm({
39
40
  "<define:__MESSENGER_BUILD_INFO__>"() {
40
- define_MESSENGER_BUILD_INFO_default = { name: "@ours.network/messenger-server", version: "1.0.30", sha: "85ef389e9da7ddd984a456db550ce39978fd8a18", dirty: false };
41
+ define_MESSENGER_BUILD_INFO_default = { name: "@ours.network/messenger-server", version: "1.0.31-nightly.10", sha: "8439d0b521650da63b97749c8bd7ebd48826ef05", dirty: true };
41
42
  }
42
43
  });
43
44
 
45
+ // src/base-path.ts
46
+ init_define_MESSENGER_BUILD_INFO();
47
+ function normalizeBasePath(value = "/") {
48
+ if (!/^\/(?:[A-Za-z0-9_-]+\/)*[A-Za-z0-9_-]*$/.test(value)) throw new Error("Base path must contain plain URL path segments");
49
+ return value === "/" ? "/" : value.replace(/\/$/, "") + "/";
50
+ }
51
+ function prefixDocument(html, basePath) {
52
+ const base = normalizeBasePath(basePath);
53
+ return html.replace("<head>", `<head><meta name="ours-base-path" content="${base}">`).replace(/((?:src|href)=")\.?\/(?!\/)([^"\s]+)(")/g, `$1${base}$2$3`);
54
+ }
55
+
44
56
  // src/security.ts
45
57
  init_define_MESSENGER_BUILD_INFO();
46
58
  import { randomUUID } from "node:crypto";
@@ -83,6 +95,8 @@ export {
83
95
  __toESM,
84
96
  init_define_MESSENGER_BUILD_INFO,
85
97
  define_MESSENGER_BUILD_INFO_default,
98
+ normalizeBasePath,
99
+ prefixDocument,
86
100
  ConfigurationError,
87
101
  operatorError,
88
102
  reportFailure,