@agimon-ai/po-session 0.0.0-alpha.52 → 0.0.0-alpha.54

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 CHANGED
@@ -50,3 +50,27 @@ pnpm typecheck
50
50
  pnpm test
51
51
  pnpm lint
52
52
  ```
53
+
54
+ ## Account network peer links
55
+
56
+ `createRosterPeerLink(ports)` adds direct host-key-authenticated sealed links using
57
+ an already verified C6 snapshot. Supply it as `createPeerLink({ network, ... })`
58
+ to expose it alongside the existing invite control as `control.network`.
59
+ `connect(hostId, token, exchange)` and `accept(proof, token)` sign fresh ephemeral
60
+ handshake keys with `signEnvelope` using the roster host key. The receiving host's
61
+ `authorize` port must validate the identity token's issuer, audience, current
62
+ membership, and proof-bound caller host. The `verifyRequest` port must perform
63
+ normal destination C3/C4 verification, including durable replay admission.
64
+ Neither a roster entry, an identity token alone, nor a channel grants application
65
+ permissions. Roster keys use base64url DER P-256 SPKI encoding.
66
+
67
+ Channels recheck roster epoch, membership and keys on each use. Publish C6 changes
68
+ before admitting new traffic; removal or key rotation refuses existing channels.
69
+ Fresh handshakes are required after restart. The account path does not write
70
+ legacy peer secrets or session permission lists. Existing 60-second invites and
71
+ pre-account session links retain their behavior and confer no network capability.
72
+ Direct links do not require an elected coordinator: in a two-voter network with
73
+ one down, existing direct authorized traffic can continue even though neither
74
+ roster writes nor coordinated relay service can progress. Election is CFT, not
75
+ Byzantine-safe. Actual host roster-sync and network activation are composition
76
+ responsibilities, not implicit consequences of enabling session peers.
@@ -2,9 +2,9 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_sessionGroupBridge = require("../sessionGroupBridge-DL3QTIaH.cjs");
5
+ const require_type = require("../type-CSkVwA6w.cjs");
6
6
  let node_path = require("node:path");
7
- node_path = require_sessionGroupBridge.__toESM(node_path, 1);
7
+ node_path = require_type.__toESM(node_path, 1);
8
8
  let _agimon_ai_po_core_platform = require("@agimon-ai/po-core/platform");
9
9
  let _agimon_ai_po_core_piSettings = require("@agimon-ai/po-core/piSettings");
10
10
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
@@ -23,18 +23,18 @@ var root_server_default$1 = (0, _agimon_ai_po_core_extensionFile.defineRoot)((pl
23
23
  ], async (scoped) => {
24
24
  const homeDirectory = plugin.host.context.homeDirectory;
25
25
  if (!homeDirectory) throw new Error("Host links require an explicit host home directory.");
26
- const peers = await require_sessionGroupBridge.createSessionPeers({
26
+ const peers = await require_type.createSessionPeers({
27
27
  fs: (0, _agimon_ai_po_core_platform.requirePoFs)(scoped),
28
28
  homeDirectory
29
29
  });
30
30
  await peers.identity();
31
31
  const directory = node_path.default.join((0, _agimon_ai_po_core_piSettings.poHomeDirectory)(homeDirectory), "session");
32
- await require_sessionGroupBridge.ensurePrivateDirectory((0, _agimon_ai_po_core_platform.requirePoFs)(scoped), directory, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
32
+ await require_type.ensurePrivateDirectory((0, _agimon_ai_po_core_platform.requirePoFs)(scoped), directory, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
33
33
  const database = await (0, _agimon_ai_po_core_platform.requirePoSqlite)(scoped).open(node_path.default.join(directory, "groups.sqlite"), _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
34
- const groups = await require_sessionGroupBridge.createSessionGroupStore({ database });
34
+ const groups = await require_type.createSessionGroupStore({ database });
35
35
  await database.run("DELETE FROM session_group_members WHERE group_id IN (SELECT group_id FROM session_groups WHERE owner_authority = 'session-group-bridge')");
36
36
  await database.run("DELETE FROM session_groups WHERE owner_authority = 'session-group-bridge'");
37
- const bridge = require_sessionGroupBridge.createSessionGroupBridge({
37
+ const bridge = require_type.createSessionGroupBridge({
38
38
  groups,
39
39
  peers,
40
40
  onError: (error) => plugin.host.context.onNotice(`Group bridge failed: ${String(error)}`),
@@ -42,7 +42,7 @@ var root_server_default$1 = (0, _agimon_ai_po_core_extensionFile.defineRoot)((pl
42
42
  const config = peers.current();
43
43
  const peer = config?.peers.find((entry) => entry.hostId === hostId);
44
44
  if (!config || !peer) return;
45
- await require_sessionGroupBridge.authenticatedPeerPost({
45
+ await require_type.authenticatedPeerPost({
46
46
  config,
47
47
  peer,
48
48
  path: "/api/plugins/session-peer/control",
@@ -54,10 +54,10 @@ var root_server_default$1 = (0, _agimon_ai_po_core_extensionFile.defineRoot)((pl
54
54
  }
55
55
  });
56
56
  const scope = (0, _agimon_ai_po_core_serverPlugin.requirePoServerScope)(scoped);
57
- const releasePeers = plugin.host.scope === "global" ? await scope.provide(require_sessionGroupBridge.PO_SESSION_PEERS_CONTRACT, peers) : scoped.provide(require_sessionGroupBridge.PO_SESSION_PEERS_SERVICE, peers);
57
+ const releasePeers = plugin.host.scope === "global" ? await scope.provide(require_type.PO_SESSION_PEERS_CONTRACT, peers) : scoped.provide(require_type.PO_SESSION_PEERS_SERVICE, peers);
58
58
  let releaseBridge;
59
59
  try {
60
- releaseBridge = plugin.host.scope === "global" ? await scope.provide(require_sessionGroupBridge.PO_SESSION_GROUP_BRIDGE_CONTRACT, bridge) : scoped.provide(require_sessionGroupBridge.PO_SESSION_GROUP_BRIDGE_SERVICE, bridge);
60
+ releaseBridge = plugin.host.scope === "global" ? await scope.provide(require_type.PO_SESSION_GROUP_BRIDGE_CONTRACT, bridge) : scoped.provide(require_type.PO_SESSION_GROUP_BRIDGE_SERVICE, bridge);
61
61
  } catch (error) {
62
62
  await Promise.resolve(releasePeers());
63
63
  await bridge.close();
@@ -93,10 +93,10 @@ async function deliverSessionPeerEnvelope(targetSessionId, sourceKey, type, payl
93
93
  //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
94
94
  var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)((pluginContext) => ({
95
95
  value: void 0,
96
- services: [require_sessionGroupBridge.provideBackgroundWorkService, (owner) => {
96
+ services: [require_type.provideBackgroundWorkService, (owner) => {
97
97
  owner.inject([
98
- require_sessionGroupBridge.PO_SESSION_PEERS_SERVICE,
99
- require_sessionGroupBridge.PO_SESSION_GROUP_BRIDGE_SERVICE,
98
+ require_type.PO_SESSION_PEERS_SERVICE,
99
+ require_type.PO_SESSION_GROUP_BRIDGE_SERVICE,
100
100
  _agimon_ai_po_core_platform.PO_FS_SERVICE,
101
101
  _agimon_ai_po_core_platform.PO_SQLITE_SERVICE
102
102
  ], async (context) => {
@@ -111,46 +111,46 @@ var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)((plug
111
111
  const io = _agimon_ai_po_core_platform.BACKGROUND_CONTEXT;
112
112
  const sessionDirectory = node_path.default.join((0, _agimon_ai_po_core_piSettings.poHomeDirectory)(homeDirectory), "session");
113
113
  const deliveryDirectory = node_path.default.join(sessionDirectory, "delivery");
114
- await require_sessionGroupBridge.ensurePrivateDirectory(fs, deliveryDirectory, io);
115
- const peers = require_sessionGroupBridge.requireSessionPeers(context);
114
+ await require_type.ensurePrivateDirectory(fs, deliveryDirectory, io);
115
+ const peers = require_type.requireSessionPeers(context);
116
116
  const peerConfig = peers.current();
117
- const peerCommunication = require_sessionGroupBridge.createPeerCommunication({
117
+ const peerCommunication = require_type.createPeerCommunication({
118
118
  local: communication,
119
119
  config: () => peers.current(),
120
120
  canPublish: (target, type, payload) => {
121
121
  if (type === "po/session-delivery/ack") return true;
122
122
  const metadata = payload?.metadata;
123
- return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === target && peer.sharedGroups.some((name) => require_sessionGroupBridge.namedSessionGroupId(name) === metadata?.groupId)) === true;
123
+ return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === target && peer.sharedGroups.some((name) => require_type.namedSessionGroupId(name) === metadata?.groupId)) === true;
124
124
  },
125
125
  onError: (error) => pluginContext.host.context.onNotice(`Peer delivery failed: ${String(error)}`)
126
126
  });
127
127
  const remotePeerIsGranted = (peerKey) => {
128
- const peer = require_sessionGroupBridge.parseRemoteSessionReference(peerKey);
128
+ const peer = require_type.parseRemoteSessionReference(peerKey);
129
129
  return peer !== void 0 && peers.current()?.peers.some((candidate) => candidate.hostId === peer.hostId && candidate.allowedSessionIds.includes(agent.context.sessionId)) === true;
130
130
  };
131
131
  const fallbackAuthorization = (peerKey) => sessionService.canCommunicate?.(agent.context.sessionId, peerKey) === true || remotePeerIsGranted(peerKey);
132
- const bridge = require_sessionGroupBridge.readSessionGroupBridge(context);
132
+ const bridge = require_type.readSessionGroupBridge(context);
133
133
  const groups = bridge?.groups;
134
134
  await bridge?.updateLocal(agent.context.sessionId, communication.sessionName ?? agent.context.sessionId, communication.groups ?? []);
135
135
  const localHostId = peerConfig?.hostId;
136
- const selfReference = localHostId ? require_sessionGroupBridge.peerSessionReference(localHostId, agent.context.sessionId) : void 0;
137
- const groupAuthorization = groups && selfReference && localHostId ? require_sessionGroupBridge.createSessionGroupDeliveryAuthorizer({
136
+ const selfReference = localHostId ? require_type.peerSessionReference(localHostId, agent.context.sessionId) : void 0;
137
+ const groupAuthorization = groups && selfReference && localHostId ? require_type.createSessionGroupDeliveryAuthorizer({
138
138
  selfReference,
139
139
  groups,
140
- peerReference: (peerKey) => require_sessionGroupBridge.parseRemoteSessionReference(peerKey) === void 0 ? require_sessionGroupBridge.peerSessionReference(localHostId, peerKey) : peerKey,
140
+ peerReference: (peerKey) => require_type.parseRemoteSessionReference(peerKey) === void 0 ? require_type.peerSessionReference(localHostId, peerKey) : peerKey,
141
141
  fallback: fallbackAuthorization
142
142
  }) : void 0;
143
143
  let delivery;
144
144
  try {
145
- delivery = await require_sessionGroupBridge.provideSessionDeliveryService(context, {
145
+ delivery = await require_type.provideSessionDeliveryService(context, {
146
146
  database: await sqlite.open(node_path.default.join(deliveryDirectory, `${agent.context.sessionId}.sqlite`), io),
147
147
  recipientKey: agent.context.sessionId,
148
148
  communication: peerCommunication,
149
149
  authorizePeer: (peerKey, metadata) => {
150
- const remote = require_sessionGroupBridge.parseRemoteSessionReference(peerKey);
150
+ const remote = require_type.parseRemoteSessionReference(peerKey);
151
151
  if (remote && !peers.current()?.peers.some((peer) => peer.hostId === remote.hostId)) return false;
152
152
  if (remote) {
153
- if (!bridge?.metadataFor(agent.context.sessionId, peerKey) || !metadata?.groupId || !bridge?.peersFor(agent.context.sessionId).find((peer) => peer.sessionId === peerKey)?.sharedGroups.some((name) => require_sessionGroupBridge.namedSessionGroupId(name) === metadata.groupId)) return false;
153
+ if (!bridge?.metadataFor(agent.context.sessionId, peerKey) || !metadata?.groupId || !bridge?.peersFor(agent.context.sessionId).find((peer) => peer.sessionId === peerKey)?.sharedGroups.some((name) => require_type.namedSessionGroupId(name) === metadata.groupId)) return false;
154
154
  return groupAuthorization ? groupAuthorization(peerKey, metadata) : false;
155
155
  }
156
156
  return groupAuthorization ? groupAuthorization(peerKey, metadata) : fallbackAuthorization(peerKey);
@@ -176,18 +176,18 @@ var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)((plug
176
176
  const { service, close: closeDelivery } = delivery;
177
177
  const unprovide = [];
178
178
  if (groups && selfReference && peerConfig) {
179
- const directory = require_sessionGroupBridge.createSessionDirectory({ authorizeDiscovery: (_caller, subject) => {
180
- const reference = require_sessionGroupBridge.peerSessionReference(subject.hostId, subject.sessionId);
179
+ const directory = require_type.createSessionDirectory({ authorizeDiscovery: (_caller, subject) => {
180
+ const reference = require_type.peerSessionReference(subject.hostId, subject.sessionId);
181
181
  return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === reference) ? { capabilities: ["message"] } : void 0;
182
182
  } });
183
183
  const observedHosts = /* @__PURE__ */ new Set();
184
184
  let sequence = 0;
185
185
  const observeRemote = () => {
186
186
  const remotePeers = bridge?.peersFor(agent.context.sessionId) ?? [];
187
- for (const peer of remotePeers) observedHosts.add(require_sessionGroupBridge.parseRemoteSessionReference(peer.sessionId).hostId);
187
+ for (const peer of remotePeers) observedHosts.add(require_type.parseRemoteSessionReference(peer.sessionId).hostId);
188
188
  sequence += 1;
189
189
  for (const hostId of observedHosts) directory.replaceHostSnapshot(hostId, "linked", remotePeers.flatMap((peer) => {
190
- const remote = require_sessionGroupBridge.parseRemoteSessionReference(peer.sessionId);
190
+ const remote = require_type.parseRemoteSessionReference(peer.sessionId);
191
191
  return remote.hostId !== hostId ? [] : [{
192
192
  hostId,
193
193
  sessionId: remote.sessionId,
@@ -213,7 +213,7 @@ var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)((plug
213
213
  observeRemote();
214
214
  service.reauthorize?.().catch((error) => pluginContext.host.context.onNotice(`Delivery reauthorization failed: ${String(error)}`));
215
215
  }));
216
- unprovide.push(context.provide(require_sessionGroupBridge.PO_SESSION_INTERCOM_SERVICE, require_sessionGroupBridge.createSessionIntercom({
216
+ unprovide.push(context.provide(require_type.PO_SESSION_INTERCOM_SERVICE, require_type.createSessionIntercom({
217
217
  selfReference,
218
218
  directory,
219
219
  groups,
@@ -248,7 +248,7 @@ function createPeerInboxApi(platform) {
248
248
  start(context) {
249
249
  const homeDirectory = context.homeDirectory;
250
250
  let opened;
251
- const channels = require_sessionGroupBridge.createSealedPeerChannels();
251
+ const channels = require_type.createSealedPeerChannels();
252
252
  let link;
253
253
  let announcing = false;
254
254
  const announce = () => {
@@ -267,12 +267,13 @@ function createPeerInboxApi(platform) {
267
267
  config: void 0,
268
268
  replay: void 0
269
269
  };
270
- const config = platform.peers ? platform.peers.current() : await require_sessionGroupBridge.readSessionPeerConfigAsync(platform.fs, homeDirectory, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
271
- const file = node_path.default.join(node_path.default.dirname(require_sessionGroupBridge.sessionPeerConfigPath(homeDirectory)), require_sessionGroupBridge.PEER_REPLAY_DATABASE_FILE);
272
- await require_sessionGroupBridge.ensurePrivateDirectory(platform.fs, node_path.default.dirname(file), _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
273
- const replay = await require_sessionGroupBridge.createPeerReplayGuardAsync(await platform.sqlite.open(file, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT));
274
- if (platform.peers) link = require_sessionGroupBridge.createPeerLink({
270
+ const config = platform.peers ? platform.peers.current() : await require_type.readSessionPeerConfigAsync(platform.fs, homeDirectory, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
271
+ const file = node_path.default.join(node_path.default.dirname(require_type.sessionPeerConfigPath(homeDirectory)), require_type.PEER_REPLAY_DATABASE_FILE);
272
+ await require_type.ensurePrivateDirectory(platform.fs, node_path.default.dirname(file), _agimon_ai_po_core_platform.BACKGROUND_CONTEXT);
273
+ const replay = await require_type.createPeerReplayGuardAsync(await platform.sqlite.open(file, _agimon_ai_po_core_platform.BACKGROUND_CONTEXT));
274
+ if (platform.peers) link = require_type.createPeerLink({
275
275
  peers: platform.peers,
276
+ network: platform.network,
276
277
  groups: platform.groups,
277
278
  replay,
278
279
  channels,
@@ -349,7 +350,7 @@ function createPeerInboxApi(platform) {
349
350
  }
350
351
  }
351
352
  if (!config) return response(503, "Paired Session delivery is not configured.");
352
- const peer = require_sessionGroupBridge.verifyPeerRequest(config, request, body);
353
+ const peer = require_type.verifyPeerRequest(config, request, body);
353
354
  if (!peer) return response(401, "Paired Session request is unauthorized.");
354
355
  if (!await replay?.admit(request)) return response(409, "Paired Session request was already received.");
355
356
  let parsed;
@@ -370,10 +371,10 @@ function createPeerInboxApi(platform) {
370
371
  return response(400, "Invalid sealed peer envelope.");
371
372
  }
372
373
  }
373
- const envelope = require_sessionGroupBridge.parseSessionPeerEnvelope(parsed);
374
+ const envelope = require_type.parseSessionPeerEnvelope(parsed);
374
375
  if (!envelope || !DELIVERY_TYPES.has(envelope.type)) return response(400, "Paired Session envelope is invalid.");
375
376
  if (!peer.linkGeneration && !peer.allowedSessionIds.includes(envelope.targetSessionId)) return response(403, "Peer is not granted this session.");
376
- const state = await deliverSessionPeerEnvelope(envelope.targetSessionId, require_sessionGroupBridge.peerSessionReference(peer.hostId, envelope.sourceSessionId), envelope.type, envelope.payload);
377
+ const state = await deliverSessionPeerEnvelope(envelope.targetSessionId, require_type.peerSessionReference(peer.hostId, envelope.sourceSessionId), envelope.type, envelope.payload);
377
378
  if (state !== void 0 && peerChannel) {
378
379
  const sealed = peerChannel.seal(Buffer.from(JSON.stringify({
379
380
  accepted: true,
@@ -381,7 +382,7 @@ function createPeerInboxApi(platform) {
381
382
  })));
382
383
  if (!sealed.ok) return response(503, "Peer acknowledgement could not be sealed.");
383
384
  const text = JSON.stringify(sealed.envelope);
384
- return new Response(text, { headers: require_sessionGroupBridge.peerRequestHeaders(config.hostId, peer, "RESPONSE", "/inbox", text) });
385
+ return new Response(text, { headers: require_type.peerRequestHeaders(config.hostId, peer, "RESPONSE", "/inbox", text) });
385
386
  }
386
387
  return state === void 0 ? response(404, "Target Session is unavailable.") : Response.json({
387
388
  accepted: true,
@@ -402,6 +403,13 @@ function createPeerInboxApi(platform) {
402
403
  //#region src/extensions/(backend)/api/session-peer/route.server.ts
403
404
  var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(({ context }) => {
404
405
  let origin;
406
+ let network;
407
+ context.inject([require_type.PO_ROSTER_PEER_SERVICE], (scoped) => {
408
+ network = scoped.get(require_type.PO_ROSTER_PEER_SERVICE);
409
+ return () => {
410
+ network = void 0;
411
+ };
412
+ });
405
413
  context.inject([_agimon_ai_po_core_remoteOrigin.PO_REMOTE_ORIGIN_SERVICE], (scoped) => {
406
414
  origin = scoped.get(_agimon_ai_po_core_remoteOrigin.PO_REMOTE_ORIGIN_SERVICE);
407
415
  return () => {
@@ -412,8 +420,9 @@ var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(({
412
420
  return createPeerInboxApi({
413
421
  fs: (0, _agimon_ai_po_core_platform.requirePoFs)(context),
414
422
  sqlite: (0, _agimon_ai_po_core_platform.requirePoSqlite)(context),
415
- peers: require_sessionGroupBridge.requireSessionPeers(context),
416
- groups: () => require_sessionGroupBridge.readSessionGroupBridge(context),
423
+ peers: require_type.requireSessionPeers(context),
424
+ network,
425
+ groups: () => require_type.readSessionGroupBridge(context),
417
426
  ...hasOrigin ? { origin: () => origin?.current() } : {}
418
427
  });
419
428
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.cjs","names":["defineRoot","PO_FS_SERVICE","PO_SQLITE_SERVICE","PO_SERVER_SCOPE_SERVICE","createSessionPeers","requirePoFs","path","poHomeDirectory","ensurePrivateDirectory","BACKGROUND_CONTEXT","requirePoSqlite","createSessionGroupStore","createSessionGroupBridge","authenticatedPeerPost","requirePoServerScope","PO_SESSION_PEERS_CONTRACT","PO_SESSION_PEERS_SERVICE","PO_SESSION_GROUP_BRIDGE_CONTRACT","PO_SESSION_GROUP_BRIDGE_SERVICE","defineRoot","provideBackgroundWorkService","PO_SESSION_PEERS_SERVICE","PO_SESSION_GROUP_BRIDGE_SERVICE","PO_FS_SERVICE","PO_SQLITE_SERVICE","requirePoFs","requirePoSqlite","BACKGROUND_CONTEXT","path","poHomeDirectory","ensurePrivateDirectory","requireSessionPeers","createPeerCommunication","namedSessionGroupId","parseRemoteSessionReference","readSessionGroupBridge","peerSessionReference","createSessionGroupDeliveryAuthorizer","provideSessionDeliveryService","createSessionDirectory","PO_SESSION_INTERCOM_SERVICE","createSessionIntercom","PO_SESSION_ATTENTION_EVENT","createSealedPeerChannels","readSessionPeerConfigAsync","BACKGROUND_CONTEXT","path","sessionPeerConfigPath","PEER_REPLAY_DATABASE_FILE","ensurePrivateDirectory","createPeerReplayGuardAsync","createPeerLink","poApiCallerFrom","verifyPeerRequest","parseSessionPeerEnvelope","peerSessionReference","peerRequestHeaders","defineRoute","PO_REMOTE_ORIGIN_SERVICE","requirePoFs","requirePoSqlite","requireSessionPeers","readSessionGroupBridge","defineServerPlugin","composeServerProviderOverrides","rootGlobal","rootSession","composeRootInjects","composeRootHooks","apiRoute"],"sources":["../../src/extensions/(backend)/root.server.ts","../../src/services/peerInbox/index.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/peerInboxApi/index.ts","../../src/extensions/(backend)/api/session-peer/route.server.ts","../../generated/server.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\nimport {\n PO_FS_SERVICE,\n PO_SQLITE_SERVICE,\n requirePoFs,\n requirePoSqlite,\n BACKGROUND_CONTEXT,\n} from '@agimon-ai/po-core/platform';\nimport {\n PO_SERVER_SCOPE_SERVICE,\n requirePoServerScope,\n type PoServerPluginContext,\n} from '@agimon-ai/po-core/serverPlugin';\n\nimport { ensurePrivateDirectory } from '../../services/peerTransport';\nimport { authenticatedPeerPost } from '../../services/sealedPeerChannel';\nimport {\n createSessionGroupBridge,\n PO_SESSION_GROUP_BRIDGE_CONTRACT,\n PO_SESSION_GROUP_BRIDGE_SERVICE,\n} from '../../services/sessionGroupBridge';\nimport { createSessionGroupStore } from '../../services/sessionGroups';\nimport { createSessionPeers, PO_SESSION_PEERS_CONTRACT, PO_SESSION_PEERS_SERVICE } from '../../services/sessionPeers';\n\nexport default defineRoot((plugin: PoServerPluginContext) => ({\n value: undefined,\n services: [\n async (context) => {\n // Routes require these bindings as soon as the service plugin finishes loading.\n await context.inject([PO_FS_SERVICE, PO_SQLITE_SERVICE, PO_SERVER_SCOPE_SERVICE], async (scoped) => {\n const homeDirectory = plugin.host.context.homeDirectory;\n if (!homeDirectory) throw new Error('Host links require an explicit host home directory.');\n const peers = await createSessionPeers({ fs: requirePoFs(scoped), homeDirectory });\n await peers.identity();\n const directory = path.join(poHomeDirectory(homeDirectory), 'session');\n await ensurePrivateDirectory(requirePoFs(scoped), directory, BACKGROUND_CONTEXT);\n const database = await requirePoSqlite(scoped).open(path.join(directory, 'groups.sqlite'), BACKGROUND_CONTEXT);\n const groups = await createSessionGroupStore({ database });\n // Snapshots are rebuilt from live sessions and fresh authenticated adverts after a restart.\n await database.run(\n \"DELETE FROM session_group_members WHERE group_id IN (SELECT group_id FROM session_groups WHERE owner_authority = 'session-group-bridge')\",\n );\n await database.run(\"DELETE FROM session_groups WHERE owner_authority = 'session-group-bridge'\");\n const bridge = createSessionGroupBridge({\n groups,\n peers,\n onError: (error) => plugin.host.context.onNotice(`Group bridge failed: ${String(error)}`),\n send: async (hostId, advert) => {\n const config = peers.current();\n const peer = config?.peers.find((entry) => entry.hostId === hostId);\n if (!config || !peer) return;\n await authenticatedPeerPost({\n config,\n peer,\n path: '/api/plugins/session-peer/control',\n value: { type: 'groups', groups: advert },\n });\n },\n });\n const scope = requirePoServerScope(scoped);\n const releasePeers =\n plugin.host.scope === 'global'\n ? await scope.provide(PO_SESSION_PEERS_CONTRACT, peers)\n : scoped.provide(PO_SESSION_PEERS_SERVICE, peers);\n let releaseBridge: () => void | Promise<void>;\n try {\n releaseBridge =\n plugin.host.scope === 'global'\n ? await scope.provide(PO_SESSION_GROUP_BRIDGE_CONTRACT, bridge)\n : scoped.provide(PO_SESSION_GROUP_BRIDGE_SERVICE, bridge);\n } catch (error) {\n await Promise.resolve(releasePeers());\n await bridge.close();\n throw error;\n }\n return async () => {\n await releaseBridge();\n await Promise.resolve(releasePeers());\n await bridge.close();\n };\n });\n },\n ],\n}));\n","import type { PoSessionDeliveryInboxState } from '../sessionDelivery';\n\nexport type SessionPeerInbox = (\n sourceKey: string,\n type: string,\n payload: unknown,\n) => Promise<PoSessionDeliveryInboxState | undefined> | undefined;\n\nconst inboxes = new Map<string, SessionPeerInbox>();\n\n/**\n * Registers one live session-owned peer inbox. This registry is reachable only by the Session route.\n * The newest registration wins: a Durable Object evicted without disposal leaves its entry in the\n * isolate's module state, and the restarted session must replace it. The hub still rejects two live\n * sessions with one id, and an older unregister cannot remove a newer inbox.\n */\nexport function registerSessionPeerInbox(sessionId: string, inbox: SessionPeerInbox): () => void {\n inboxes.set(sessionId, inbox);\n return () => {\n if (inboxes.get(sessionId) === inbox) inboxes.delete(sessionId);\n };\n}\n\nexport async function deliverSessionPeerEnvelope(\n targetSessionId: string,\n sourceKey: string,\n type: string,\n payload: unknown,\n): Promise<PoSessionDeliveryInboxState | undefined> {\n return inboxes.get(targetSessionId)?.(sourceKey, type, payload);\n}\n","import path from 'node:path';\n\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { PO_SESSION_ATTENTION_EVENT } from '@agimon-ai/po-core/hubChannel';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\nimport {\n BACKGROUND_CONTEXT,\n PO_FS_SERVICE,\n PO_SQLITE_SERVICE,\n requirePoFs,\n requirePoSqlite,\n} from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { provideBackgroundWorkService } from '../../../../services/backgroundWorkService';\nimport { registerSessionPeerInbox } from '../../../../services/peerInbox';\nimport {\n createPeerCommunication,\n ensurePrivateDirectory,\n parseRemoteSessionReference,\n peerSessionReference,\n} from '../../../../services/peerTransport';\nimport { provideSessionDeliveryService } from '../../../../services/sessionDelivery';\nimport { createSessionDirectory } from '../../../../services/sessionDirectory';\nimport {\n PO_SESSION_GROUP_BRIDGE_SERVICE,\n readSessionGroupBridge,\n namedSessionGroupId,\n} from '../../../../services/sessionGroupBridge';\nimport {\n PO_SESSION_INTERCOM_SERVICE,\n createSessionGroupDeliveryAuthorizer,\n createSessionIntercom,\n} from '../../../../services/sessionIntercom';\nimport { PO_SESSION_PEERS_SERVICE, requireSessionPeers } from '../../../../services/sessionPeers';\n\nexport default defineRoot((pluginContext: PoServerPluginContext) => ({\n value: undefined,\n services: [\n provideBackgroundWorkService,\n (owner) => {\n owner.inject(\n [PO_SESSION_PEERS_SERVICE, PO_SESSION_GROUP_BRIDGE_SERVICE, PO_FS_SERVICE, PO_SQLITE_SERVICE],\n async (context) => {\n const agent = pluginContext.agent;\n const session = agent?.context.session;\n const communication = pluginContext.host.context.sessionCommunication;\n const homeDirectory = pluginContext.host.context.homeDirectory;\n const sessionService = pluginContext.host.context.sessionService;\n if (!agent || !session?.admitPrompt || !communication || !homeDirectory || !sessionService?.canCommunicate) {\n throw new Error(\n 'Session delivery requires the headless agent, authenticated session communication, host home directory, and communication policy.',\n );\n }\n const fs = requirePoFs(context);\n const sqlite = requirePoSqlite(context);\n const io = BACKGROUND_CONTEXT;\n const sessionDirectory = path.join(poHomeDirectory(homeDirectory), 'session');\n const deliveryDirectory = path.join(sessionDirectory, 'delivery');\n await ensurePrivateDirectory(fs, deliveryDirectory, io);\n const peers = requireSessionPeers(context);\n const peerConfig = peers.current();\n const peerCommunication = createPeerCommunication({\n local: communication,\n config: () => peers.current(),\n canPublish: (target, type, payload) => {\n if (type === 'po/session-delivery/ack') return true;\n const metadata = (payload as { metadata?: { groupId?: string } } | null)?.metadata;\n return (\n bridge\n ?.peersFor(agent.context.sessionId)\n .some(\n (peer) =>\n peer.sessionId === target &&\n peer.sharedGroups.some((name) => namedSessionGroupId(name) === metadata?.groupId),\n ) === true\n );\n },\n onError: (error) => pluginContext.host.context.onNotice(`Peer delivery failed: ${String(error)}`),\n });\n const remotePeerIsGranted = (peerKey: string): boolean => {\n const peer = parseRemoteSessionReference(peerKey);\n return (\n peer !== undefined &&\n peers\n .current()\n ?.peers.some(\n (candidate) =>\n candidate.hostId === peer.hostId && candidate.allowedSessionIds.includes(agent.context.sessionId),\n ) === true\n );\n };\n const fallbackAuthorization = (peerKey: string): boolean =>\n sessionService.canCommunicate?.(agent.context.sessionId, peerKey) === true || remotePeerIsGranted(peerKey);\n const bridge = readSessionGroupBridge(context);\n const groups = bridge?.groups;\n await bridge?.updateLocal(\n agent.context.sessionId,\n communication.sessionName ?? agent.context.sessionId,\n communication.groups ?? [],\n );\n const localHostId = peerConfig?.hostId;\n const selfReference = localHostId ? peerSessionReference(localHostId, agent.context.sessionId) : undefined;\n const groupAuthorization =\n groups && selfReference && localHostId\n ? createSessionGroupDeliveryAuthorizer({\n selfReference,\n groups,\n peerReference: (peerKey) =>\n parseRemoteSessionReference(peerKey) === undefined\n ? peerSessionReference(localHostId, peerKey)\n : peerKey,\n fallback: fallbackAuthorization,\n })\n : undefined;\n let delivery: Awaited<ReturnType<typeof provideSessionDeliveryService>>;\n try {\n delivery = await provideSessionDeliveryService(context, {\n database: await sqlite.open(path.join(deliveryDirectory, `${agent.context.sessionId}.sqlite`), io),\n recipientKey: agent.context.sessionId,\n communication: peerCommunication,\n authorizePeer: (peerKey, metadata) => {\n const remote = parseRemoteSessionReference(peerKey);\n if (remote && !peers.current()?.peers.some((peer) => peer.hostId === remote.hostId)) return false;\n if (remote) {\n // Local membership is authoritative even before the SQLite mirror update finishes.\n const expected = bridge?.metadataFor(agent.context.sessionId, peerKey);\n if (\n !expected ||\n !metadata?.groupId ||\n !bridge\n ?.peersFor(agent.context.sessionId)\n .find((peer) => peer.sessionId === peerKey)\n ?.sharedGroups.some((name) => namedSessionGroupId(name) === metadata.groupId)\n )\n return false;\n return groupAuthorization ? groupAuthorization(peerKey, metadata) : false;\n }\n return groupAuthorization ? groupAuthorization(peerKey, metadata) : fallbackAuthorization(peerKey);\n },\n admitPrompt: async (prompt, admission, requestId, metadata) => {\n if (!metadata.customType) {\n await session.admitPrompt!(prompt, admission, undefined, requestId);\n return;\n }\n if (!session.admitMessage) throw new Error('The session cannot admit a custom delivery.');\n await session.admitMessage(\n {\n type: metadata.customType,\n text: prompt,\n display: true,\n details: metadata.customDetails === undefined ? undefined : JSON.parse(metadata.customDetails),\n },\n admission === 'steer' ? 'steer' : 'followUp',\n requestId,\n );\n },\n });\n } catch (error) {\n await bridge?.removeLocal(agent.context.sessionId);\n throw error;\n }\n const { service, close: closeDelivery } = delivery;\n const unprovide: (() => void)[] = [];\n if (groups && selfReference && peerConfig) {\n const directory = createSessionDirectory({\n authorizeDiscovery: (_caller, subject) => {\n const reference = peerSessionReference(subject.hostId, subject.sessionId);\n return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === reference)\n ? { capabilities: ['message'] }\n : undefined;\n },\n });\n const observedHosts = new Set<string>();\n let sequence = 0;\n const observeRemote = (): void => {\n const remotePeers = bridge?.peersFor(agent.context.sessionId) ?? [];\n for (const peer of remotePeers) observedHosts.add(parseRemoteSessionReference(peer.sessionId)!.hostId);\n sequence += 1;\n for (const hostId of observedHosts)\n directory.replaceHostSnapshot(\n hostId,\n 'linked',\n remotePeers.flatMap((peer) => {\n const remote = parseRemoteSessionReference(peer.sessionId)!;\n return remote.hostId !== hostId\n ? []\n : [\n {\n hostId,\n sessionId: remote.sessionId,\n label: peer.name,\n hostIncarnation: 'linked',\n sessionIncarnation: 'live',\n sequence,\n observedAt: Date.now(),\n staleAfterMs: 120_000,\n deliveryTarget: peer.sessionId,\n reachability: 'unknown' as const,\n runtime: 'unknown' as const,\n activity: 'unknown' as const,\n voice: { eligible: 'unknown' as const, readiness: 'unknown' as const },\n },\n ];\n }),\n );\n };\n observeRemote();\n unprovide.push(\n bridge!.subscribe(() => {\n observeRemote();\n void service\n .reauthorize?.()\n .catch((error: unknown) =>\n pluginContext.host.context.onNotice(`Delivery reauthorization failed: ${String(error)}`),\n );\n }),\n );\n unprovide.push(\n context.provide(\n PO_SESSION_INTERCOM_SERVICE,\n createSessionIntercom({ selfReference, directory, groups, delivery: service }),\n ),\n );\n }\n const releaseGroups = pluginContext.host.context.directEvents?.subscribe(\n PO_SESSION_ATTENTION_EVENT,\n agent.context.sessionId,\n () => {\n void bridge\n ?.updateLocal(\n agent.context.sessionId,\n communication.sessionName ?? agent.context.sessionId,\n communication.groups ?? [],\n )\n .catch((error: unknown) =>\n pluginContext.host.context.onNotice(`Group update failed: ${String(error)}`),\n );\n },\n );\n const unregister = registerSessionPeerInbox(agent.context.sessionId, (sourceKey, kind, payload) =>\n service.receive?.(sourceKey, kind, payload),\n );\n return async () => {\n unregister();\n releaseGroups?.();\n await bridge?.removeLocal(agent.context.sessionId);\n for (const release of unprovide.reverse()) release();\n await closeDelivery();\n };\n },\n );\n },\n ],\n}));\n","import path from 'node:path';\n\nimport { poApiCallerFrom, type PoApi, type PoApiHandler } from '@agimon-ai/po-core/packageApi';\nimport { BACKGROUND_CONTEXT, type PoSqliteService, type FileSystem } from '@agimon-ai/po-core/platform';\n\nimport { deliverSessionPeerEnvelope } from '../peerInbox';\nimport { createPeerLink, type PeerLinkControl } from '../peerLink';\nimport {\n PEER_REPLAY_DATABASE_FILE,\n createPeerReplayGuardAsync,\n ensurePrivateDirectory,\n parseSessionPeerEnvelope,\n peerSessionReference,\n peerRequestHeaders,\n readSessionPeerConfigAsync,\n sessionPeerConfigPath,\n verifyPeerRequest,\n type SessionPeerConfig,\n type SessionPeerReplayGuardAsync,\n} from '../peerTransport';\nimport { createSealedPeerChannels } from '../sealedPeerChannel';\nimport type { SessionGroupBridge } from '../sessionGroupBridge';\nimport type { SessionPeers } from '../sessionPeers';\n\nconst MAX_BODY_BYTES = 64 * 1024;\nconst DELIVERY_TYPES = new Set(['po/session-delivery/envelope', 'po/session-delivery/ack']);\n\nfunction response(status: number, error: string): Response {\n return Response.json({ error }, { status });\n}\n\ninterface PeerInboxState {\n readonly config: SessionPeerConfig | undefined;\n readonly replay: SessionPeerReplayGuardAsync | undefined;\n}\n\n/** Narrow HMAC-authenticated endpoint that a trusted tunnel may forward without device authentication. */\nexport function createPeerInboxApi(platform: {\n readonly fs: FileSystem;\n readonly sqlite: PoSqliteService;\n readonly peers?: SessionPeers;\n readonly groups?: () => SessionGroupBridge | undefined;\n readonly origin?: () => string | undefined;\n readonly fetch?: typeof fetch;\n}): PoApi {\n return {\n basePath: 'session-peer',\n start(context): PoApiHandler {\n const homeDirectory = context.homeDirectory;\n // Opened once on first use: the handler starts synchronously, the platform services are async.\n let opened: Promise<PeerInboxState> | undefined;\n const channels = createSealedPeerChannels();\n let link: PeerLinkControl | undefined;\n let announcing = false;\n const announce = (): void => {\n if (!link || announcing) return;\n announcing = true;\n void link\n .announce()\n .catch((error: unknown) => context.onNotice(`Peer URL announcement failed: ${String(error)}`))\n .finally(() => {\n announcing = false;\n });\n };\n // Retry announcements as well as detecting origin revisions. A peer may be offline at rotation.\n const timer =\n platform.peers && platform.origin\n ? setInterval(() => {\n void open()\n .then(announce)\n .catch((error: unknown) => context.onNotice(`Host links could not start: ${String(error)}`));\n }, 1_000)\n : undefined;\n timer?.unref?.();\n const open = (): Promise<PeerInboxState> =>\n (opened ??= (async () => {\n if (homeDirectory === undefined) return { config: undefined, replay: undefined };\n const config = platform.peers\n ? platform.peers.current()\n : await readSessionPeerConfigAsync(platform.fs, homeDirectory, BACKGROUND_CONTEXT);\n const file = path.join(path.dirname(sessionPeerConfigPath(homeDirectory)), PEER_REPLAY_DATABASE_FILE);\n await ensurePrivateDirectory(platform.fs, path.dirname(file), BACKGROUND_CONTEXT);\n const replay = await createPeerReplayGuardAsync(await platform.sqlite.open(file, BACKGROUND_CONTEXT));\n if (platform.peers)\n link = createPeerLink({\n peers: platform.peers,\n groups: platform.groups,\n replay,\n channels,\n origin: platform.origin ?? (() => undefined),\n fetch: platform.fetch,\n });\n announce();\n return { config, replay };\n })().catch((error: unknown) => {\n // A failed open is retried by the next request rather than cached.\n opened = undefined;\n throw error;\n }));\n if (platform.peers)\n void open().catch((error: unknown) => context.onNotice(`Host links could not start: ${String(error)}`));\n return {\n async fetch(request) {\n const pathname = new URL(request.url).pathname;\n const openedState = await open();\n const config = platform.peers ? platform.peers.current() : openedState.config;\n const replay = openedState.replay;\n if (request.method === 'GET' && pathname === '/links' && platform.peers) {\n if (!poApiCallerFrom(request.headers)) return response(403, 'An authenticated caller is required.');\n return Response.json({\n hostId: config?.hostId,\n peers: config?.peers.map(({ hostId, url, urlGeneration }) => ({ hostId, url, urlGeneration })) ?? [],\n });\n }\n if (\n request.method !== 'POST' ||\n !['/inbox', '/control', '/link/prepare', '/link/accept', '/link/unlink', '/link/hint'].includes(pathname)\n )\n return response(404, 'Not found.');\n const length = request.headers.get('content-length');\n if (length !== null && (!/^\\d+$/u.test(length) || Number(length) > MAX_BODY_BYTES))\n return response(413, 'Request body is too large.');\n const body = await request.text();\n if (Buffer.byteLength(body) > MAX_BODY_BYTES) return response(413, 'Request body is too large.');\n if (pathname.startsWith('/link/')) {\n const caller = poApiCallerFrom(request.headers);\n if (!caller || (caller.locality === 'remote' && pathname !== '/link/hint' && caller.stepUp !== 'verified'))\n return response(403, 'Linking hosts needs a fresh peer.link step-up.');\n if (!link) return response(503, 'Host links are unavailable.');\n try {\n const input = (body === '' ? {} : JSON.parse(body)) as {\n invite?: unknown;\n hostId?: unknown;\n url?: unknown;\n };\n if (pathname === '/link/prepare') return Response.json(await link.prepare());\n if (pathname === '/link/accept') {\n await link.accept(input.invite as Parameters<PeerLinkControl['accept']>[0]);\n return Response.json({ linked: true });\n }\n if (typeof input.hostId !== 'string') return response(400, 'A host identity is required.');\n if (pathname === '/link/unlink') {\n await link.unlink(input.hostId);\n return Response.json({ unlinked: true });\n }\n if (typeof input.url !== 'string') return response(400, 'A URL hint is required.');\n return Response.json({ rebound: await link.hint(input.hostId, input.url) });\n } catch (error) {\n return response(400, error instanceof Error ? error.message : 'Host link failed.');\n }\n }\n if (pathname === '/control') {\n if (!link) return response(503, 'Host links are unavailable.');\n try {\n return await link.control(request, body);\n } catch (error) {\n return response(400, error instanceof Error ? error.message : 'Invalid peer control.');\n }\n }\n if (!config) return response(503, 'Paired Session delivery is not configured.');\n const peer = verifyPeerRequest(config, request, body);\n if (!peer) return response(401, 'Paired Session request is unauthorized.');\n if (!(await replay?.admit(request))) return response(409, 'Paired Session request was already received.');\n let parsed: unknown;\n try {\n parsed = JSON.parse(body) as unknown;\n } catch {\n return response(400, 'Paired Session request is malformed.');\n }\n let peerChannel: ReturnType<typeof channels.take>;\n if (peer.linkGeneration) {\n const sealed = parsed as { epochId?: unknown; envelope?: unknown } | null;\n peerChannel = typeof sealed?.epochId === 'string' ? channels.take(peer, sealed.epochId) : undefined;\n const opened = peerChannel?.open(sealed?.envelope);\n if (!opened?.ok) return response(401, 'A fresh sealed peer channel is required.');\n try {\n parsed = JSON.parse(Buffer.from(opened.plaintext).toString('utf8')) as unknown;\n } catch {\n return response(400, 'Invalid sealed peer envelope.');\n }\n }\n const envelope = parseSessionPeerEnvelope(parsed);\n if (!envelope || !DELIVERY_TYPES.has(envelope.type))\n return response(400, 'Paired Session envelope is invalid.');\n if (!peer.linkGeneration && !peer.allowedSessionIds.includes(envelope.targetSessionId))\n return response(403, 'Peer is not granted this session.');\n const state = await deliverSessionPeerEnvelope(\n envelope.targetSessionId,\n peerSessionReference(peer.hostId, envelope.sourceSessionId),\n envelope.type,\n envelope.payload,\n );\n if (state !== undefined && peerChannel) {\n const sealed = peerChannel.seal(Buffer.from(JSON.stringify({ accepted: true, state })));\n if (!sealed.ok) return response(503, 'Peer acknowledgement could not be sealed.');\n const text = JSON.stringify(sealed.envelope);\n return new Response(text, { headers: peerRequestHeaders(config.hostId, peer, 'RESPONSE', '/inbox', text) });\n }\n return state === undefined\n ? response(404, 'Target Session is unavailable.')\n : Response.json({ accepted: true, state }, { status: 202 });\n },\n async close() {\n if (timer) clearInterval(timer);\n const state = await opened?.catch(() => undefined);\n link?.close();\n await state?.replay?.close();\n },\n };\n },\n };\n}\n","import { defineRoute } from '@agimon-ai/po-core/extensionFile';\nimport { requirePoFs, requirePoSqlite } from '@agimon-ai/po-core/platform';\nimport { PO_REMOTE_ORIGIN_SERVICE, type RemoteOrigin } from '@agimon-ai/po-core/remoteOrigin';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createPeerInboxApi } from '../../../../services/peerInboxApi';\nimport { readSessionGroupBridge } from '../../../../services/sessionGroupBridge';\nimport { requireSessionPeers } from '../../../../services/sessionPeers';\n\nexport default defineRoute(({ context }: PoServerPluginContext) => {\n let origin: RemoteOrigin | undefined;\n context.inject([PO_REMOTE_ORIGIN_SERVICE], (scoped) => {\n origin = scoped.get(PO_REMOTE_ORIGIN_SERVICE);\n return () => {\n origin = undefined;\n };\n });\n // Hosts without public routing have nothing to announce and must not keep a polling timer alive.\n const hasOrigin = origin !== undefined;\n return createPeerInboxApi({\n fs: requirePoFs(context),\n sqlite: requirePoSqlite(context),\n peers: requireSessionPeers(context),\n groups: () => readSessionGroupBridge(context),\n ...(hasOrigin ? { origin: () => origin?.current() } : {}),\n });\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/session-peer/route.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-session',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextGlobal)]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get api(): PoServerSessionPlugin['api'] { return defined([context.hosted('global') ? undefined : at(apiRoute, contextGlobal)]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return defined([context.hosted('global') ? undefined : at(apiRoute, contextGlobal)]); },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"server.cjs","names":["defineRoot","PO_FS_SERVICE","PO_SQLITE_SERVICE","PO_SERVER_SCOPE_SERVICE","createSessionPeers","requirePoFs","path","poHomeDirectory","ensurePrivateDirectory","BACKGROUND_CONTEXT","requirePoSqlite","createSessionGroupStore","createSessionGroupBridge","authenticatedPeerPost","requirePoServerScope","PO_SESSION_PEERS_CONTRACT","PO_SESSION_PEERS_SERVICE","PO_SESSION_GROUP_BRIDGE_CONTRACT","PO_SESSION_GROUP_BRIDGE_SERVICE","defineRoot","provideBackgroundWorkService","PO_SESSION_PEERS_SERVICE","PO_SESSION_GROUP_BRIDGE_SERVICE","PO_FS_SERVICE","PO_SQLITE_SERVICE","requirePoFs","requirePoSqlite","BACKGROUND_CONTEXT","path","poHomeDirectory","ensurePrivateDirectory","requireSessionPeers","createPeerCommunication","namedSessionGroupId","parseRemoteSessionReference","readSessionGroupBridge","peerSessionReference","createSessionGroupDeliveryAuthorizer","provideSessionDeliveryService","createSessionDirectory","PO_SESSION_INTERCOM_SERVICE","createSessionIntercom","PO_SESSION_ATTENTION_EVENT","createSealedPeerChannels","readSessionPeerConfigAsync","BACKGROUND_CONTEXT","path","sessionPeerConfigPath","PEER_REPLAY_DATABASE_FILE","ensurePrivateDirectory","createPeerReplayGuardAsync","createPeerLink","poApiCallerFrom","verifyPeerRequest","parseSessionPeerEnvelope","peerSessionReference","peerRequestHeaders","defineRoute","PO_ROSTER_PEER_SERVICE","PO_REMOTE_ORIGIN_SERVICE","requirePoFs","requirePoSqlite","requireSessionPeers","readSessionGroupBridge","defineServerPlugin","composeServerProviderOverrides","rootGlobal","rootSession","composeRootInjects","composeRootHooks","apiRoute"],"sources":["../../src/extensions/(backend)/root.server.ts","../../src/services/peerInbox/index.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/peerInboxApi/index.ts","../../src/extensions/(backend)/api/session-peer/route.server.ts","../../generated/server.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\nimport {\n PO_FS_SERVICE,\n PO_SQLITE_SERVICE,\n requirePoFs,\n requirePoSqlite,\n BACKGROUND_CONTEXT,\n} from '@agimon-ai/po-core/platform';\nimport {\n PO_SERVER_SCOPE_SERVICE,\n requirePoServerScope,\n type PoServerPluginContext,\n} from '@agimon-ai/po-core/serverPlugin';\n\nimport { ensurePrivateDirectory } from '../../services/peerTransport';\nimport { authenticatedPeerPost } from '../../services/sealedPeerChannel';\nimport {\n createSessionGroupBridge,\n PO_SESSION_GROUP_BRIDGE_CONTRACT,\n PO_SESSION_GROUP_BRIDGE_SERVICE,\n} from '../../services/sessionGroupBridge';\nimport { createSessionGroupStore } from '../../services/sessionGroups';\nimport { createSessionPeers, PO_SESSION_PEERS_CONTRACT, PO_SESSION_PEERS_SERVICE } from '../../services/sessionPeers';\n\nexport default defineRoot((plugin: PoServerPluginContext) => ({\n value: undefined,\n services: [\n async (context) => {\n // Routes require these bindings as soon as the service plugin finishes loading.\n await context.inject([PO_FS_SERVICE, PO_SQLITE_SERVICE, PO_SERVER_SCOPE_SERVICE], async (scoped) => {\n const homeDirectory = plugin.host.context.homeDirectory;\n if (!homeDirectory) throw new Error('Host links require an explicit host home directory.');\n const peers = await createSessionPeers({ fs: requirePoFs(scoped), homeDirectory });\n await peers.identity();\n const directory = path.join(poHomeDirectory(homeDirectory), 'session');\n await ensurePrivateDirectory(requirePoFs(scoped), directory, BACKGROUND_CONTEXT);\n const database = await requirePoSqlite(scoped).open(path.join(directory, 'groups.sqlite'), BACKGROUND_CONTEXT);\n const groups = await createSessionGroupStore({ database });\n // Snapshots are rebuilt from live sessions and fresh authenticated adverts after a restart.\n await database.run(\n \"DELETE FROM session_group_members WHERE group_id IN (SELECT group_id FROM session_groups WHERE owner_authority = 'session-group-bridge')\",\n );\n await database.run(\"DELETE FROM session_groups WHERE owner_authority = 'session-group-bridge'\");\n const bridge = createSessionGroupBridge({\n groups,\n peers,\n onError: (error) => plugin.host.context.onNotice(`Group bridge failed: ${String(error)}`),\n send: async (hostId, advert) => {\n const config = peers.current();\n const peer = config?.peers.find((entry) => entry.hostId === hostId);\n if (!config || !peer) return;\n await authenticatedPeerPost({\n config,\n peer,\n path: '/api/plugins/session-peer/control',\n value: { type: 'groups', groups: advert },\n });\n },\n });\n const scope = requirePoServerScope(scoped);\n const releasePeers =\n plugin.host.scope === 'global'\n ? await scope.provide(PO_SESSION_PEERS_CONTRACT, peers)\n : scoped.provide(PO_SESSION_PEERS_SERVICE, peers);\n let releaseBridge: () => void | Promise<void>;\n try {\n releaseBridge =\n plugin.host.scope === 'global'\n ? await scope.provide(PO_SESSION_GROUP_BRIDGE_CONTRACT, bridge)\n : scoped.provide(PO_SESSION_GROUP_BRIDGE_SERVICE, bridge);\n } catch (error) {\n await Promise.resolve(releasePeers());\n await bridge.close();\n throw error;\n }\n return async () => {\n await releaseBridge();\n await Promise.resolve(releasePeers());\n await bridge.close();\n };\n });\n },\n ],\n}));\n","import type { PoSessionDeliveryInboxState } from '../sessionDelivery';\n\nexport type SessionPeerInbox = (\n sourceKey: string,\n type: string,\n payload: unknown,\n) => Promise<PoSessionDeliveryInboxState | undefined> | undefined;\n\nconst inboxes = new Map<string, SessionPeerInbox>();\n\n/**\n * Registers one live session-owned peer inbox. This registry is reachable only by the Session route.\n * The newest registration wins: a Durable Object evicted without disposal leaves its entry in the\n * isolate's module state, and the restarted session must replace it. The hub still rejects two live\n * sessions with one id, and an older unregister cannot remove a newer inbox.\n */\nexport function registerSessionPeerInbox(sessionId: string, inbox: SessionPeerInbox): () => void {\n inboxes.set(sessionId, inbox);\n return () => {\n if (inboxes.get(sessionId) === inbox) inboxes.delete(sessionId);\n };\n}\n\nexport async function deliverSessionPeerEnvelope(\n targetSessionId: string,\n sourceKey: string,\n type: string,\n payload: unknown,\n): Promise<PoSessionDeliveryInboxState | undefined> {\n return inboxes.get(targetSessionId)?.(sourceKey, type, payload);\n}\n","import path from 'node:path';\n\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { PO_SESSION_ATTENTION_EVENT } from '@agimon-ai/po-core/hubChannel';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\nimport {\n BACKGROUND_CONTEXT,\n PO_FS_SERVICE,\n PO_SQLITE_SERVICE,\n requirePoFs,\n requirePoSqlite,\n} from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { provideBackgroundWorkService } from '../../../../services/backgroundWorkService';\nimport { registerSessionPeerInbox } from '../../../../services/peerInbox';\nimport {\n createPeerCommunication,\n ensurePrivateDirectory,\n parseRemoteSessionReference,\n peerSessionReference,\n} from '../../../../services/peerTransport';\nimport { provideSessionDeliveryService } from '../../../../services/sessionDelivery';\nimport { createSessionDirectory } from '../../../../services/sessionDirectory';\nimport {\n PO_SESSION_GROUP_BRIDGE_SERVICE,\n readSessionGroupBridge,\n namedSessionGroupId,\n} from '../../../../services/sessionGroupBridge';\nimport {\n PO_SESSION_INTERCOM_SERVICE,\n createSessionGroupDeliveryAuthorizer,\n createSessionIntercom,\n} from '../../../../services/sessionIntercom';\nimport { PO_SESSION_PEERS_SERVICE, requireSessionPeers } from '../../../../services/sessionPeers';\n\nexport default defineRoot((pluginContext: PoServerPluginContext) => ({\n value: undefined,\n services: [\n provideBackgroundWorkService,\n (owner) => {\n owner.inject(\n [PO_SESSION_PEERS_SERVICE, PO_SESSION_GROUP_BRIDGE_SERVICE, PO_FS_SERVICE, PO_SQLITE_SERVICE],\n async (context) => {\n const agent = pluginContext.agent;\n const session = agent?.context.session;\n const communication = pluginContext.host.context.sessionCommunication;\n const homeDirectory = pluginContext.host.context.homeDirectory;\n const sessionService = pluginContext.host.context.sessionService;\n if (!agent || !session?.admitPrompt || !communication || !homeDirectory || !sessionService?.canCommunicate) {\n throw new Error(\n 'Session delivery requires the headless agent, authenticated session communication, host home directory, and communication policy.',\n );\n }\n const fs = requirePoFs(context);\n const sqlite = requirePoSqlite(context);\n const io = BACKGROUND_CONTEXT;\n const sessionDirectory = path.join(poHomeDirectory(homeDirectory), 'session');\n const deliveryDirectory = path.join(sessionDirectory, 'delivery');\n await ensurePrivateDirectory(fs, deliveryDirectory, io);\n const peers = requireSessionPeers(context);\n const peerConfig = peers.current();\n const peerCommunication = createPeerCommunication({\n local: communication,\n config: () => peers.current(),\n canPublish: (target, type, payload) => {\n if (type === 'po/session-delivery/ack') return true;\n const metadata = (payload as { metadata?: { groupId?: string } } | null)?.metadata;\n return (\n bridge\n ?.peersFor(agent.context.sessionId)\n .some(\n (peer) =>\n peer.sessionId === target &&\n peer.sharedGroups.some((name) => namedSessionGroupId(name) === metadata?.groupId),\n ) === true\n );\n },\n onError: (error) => pluginContext.host.context.onNotice(`Peer delivery failed: ${String(error)}`),\n });\n const remotePeerIsGranted = (peerKey: string): boolean => {\n const peer = parseRemoteSessionReference(peerKey);\n return (\n peer !== undefined &&\n peers\n .current()\n ?.peers.some(\n (candidate) =>\n candidate.hostId === peer.hostId && candidate.allowedSessionIds.includes(agent.context.sessionId),\n ) === true\n );\n };\n const fallbackAuthorization = (peerKey: string): boolean =>\n sessionService.canCommunicate?.(agent.context.sessionId, peerKey) === true || remotePeerIsGranted(peerKey);\n const bridge = readSessionGroupBridge(context);\n const groups = bridge?.groups;\n await bridge?.updateLocal(\n agent.context.sessionId,\n communication.sessionName ?? agent.context.sessionId,\n communication.groups ?? [],\n );\n const localHostId = peerConfig?.hostId;\n const selfReference = localHostId ? peerSessionReference(localHostId, agent.context.sessionId) : undefined;\n const groupAuthorization =\n groups && selfReference && localHostId\n ? createSessionGroupDeliveryAuthorizer({\n selfReference,\n groups,\n peerReference: (peerKey) =>\n parseRemoteSessionReference(peerKey) === undefined\n ? peerSessionReference(localHostId, peerKey)\n : peerKey,\n fallback: fallbackAuthorization,\n })\n : undefined;\n let delivery: Awaited<ReturnType<typeof provideSessionDeliveryService>>;\n try {\n delivery = await provideSessionDeliveryService(context, {\n database: await sqlite.open(path.join(deliveryDirectory, `${agent.context.sessionId}.sqlite`), io),\n recipientKey: agent.context.sessionId,\n communication: peerCommunication,\n authorizePeer: (peerKey, metadata) => {\n const remote = parseRemoteSessionReference(peerKey);\n if (remote && !peers.current()?.peers.some((peer) => peer.hostId === remote.hostId)) return false;\n if (remote) {\n // Local membership is authoritative even before the SQLite mirror update finishes.\n const expected = bridge?.metadataFor(agent.context.sessionId, peerKey);\n if (\n !expected ||\n !metadata?.groupId ||\n !bridge\n ?.peersFor(agent.context.sessionId)\n .find((peer) => peer.sessionId === peerKey)\n ?.sharedGroups.some((name) => namedSessionGroupId(name) === metadata.groupId)\n )\n return false;\n return groupAuthorization ? groupAuthorization(peerKey, metadata) : false;\n }\n return groupAuthorization ? groupAuthorization(peerKey, metadata) : fallbackAuthorization(peerKey);\n },\n admitPrompt: async (prompt, admission, requestId, metadata) => {\n if (!metadata.customType) {\n await session.admitPrompt!(prompt, admission, undefined, requestId);\n return;\n }\n if (!session.admitMessage) throw new Error('The session cannot admit a custom delivery.');\n await session.admitMessage(\n {\n type: metadata.customType,\n text: prompt,\n display: true,\n details: metadata.customDetails === undefined ? undefined : JSON.parse(metadata.customDetails),\n },\n admission === 'steer' ? 'steer' : 'followUp',\n requestId,\n );\n },\n });\n } catch (error) {\n await bridge?.removeLocal(agent.context.sessionId);\n throw error;\n }\n const { service, close: closeDelivery } = delivery;\n const unprovide: (() => void)[] = [];\n if (groups && selfReference && peerConfig) {\n const directory = createSessionDirectory({\n authorizeDiscovery: (_caller, subject) => {\n const reference = peerSessionReference(subject.hostId, subject.sessionId);\n return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === reference)\n ? { capabilities: ['message'] }\n : undefined;\n },\n });\n const observedHosts = new Set<string>();\n let sequence = 0;\n const observeRemote = (): void => {\n const remotePeers = bridge?.peersFor(agent.context.sessionId) ?? [];\n for (const peer of remotePeers) observedHosts.add(parseRemoteSessionReference(peer.sessionId)!.hostId);\n sequence += 1;\n for (const hostId of observedHosts)\n directory.replaceHostSnapshot(\n hostId,\n 'linked',\n remotePeers.flatMap((peer) => {\n const remote = parseRemoteSessionReference(peer.sessionId)!;\n return remote.hostId !== hostId\n ? []\n : [\n {\n hostId,\n sessionId: remote.sessionId,\n label: peer.name,\n hostIncarnation: 'linked',\n sessionIncarnation: 'live',\n sequence,\n observedAt: Date.now(),\n staleAfterMs: 120_000,\n deliveryTarget: peer.sessionId,\n reachability: 'unknown' as const,\n runtime: 'unknown' as const,\n activity: 'unknown' as const,\n voice: { eligible: 'unknown' as const, readiness: 'unknown' as const },\n },\n ];\n }),\n );\n };\n observeRemote();\n unprovide.push(\n bridge!.subscribe(() => {\n observeRemote();\n void service\n .reauthorize?.()\n .catch((error: unknown) =>\n pluginContext.host.context.onNotice(`Delivery reauthorization failed: ${String(error)}`),\n );\n }),\n );\n unprovide.push(\n context.provide(\n PO_SESSION_INTERCOM_SERVICE,\n createSessionIntercom({ selfReference, directory, groups, delivery: service }),\n ),\n );\n }\n const releaseGroups = pluginContext.host.context.directEvents?.subscribe(\n PO_SESSION_ATTENTION_EVENT,\n agent.context.sessionId,\n () => {\n void bridge\n ?.updateLocal(\n agent.context.sessionId,\n communication.sessionName ?? agent.context.sessionId,\n communication.groups ?? [],\n )\n .catch((error: unknown) =>\n pluginContext.host.context.onNotice(`Group update failed: ${String(error)}`),\n );\n },\n );\n const unregister = registerSessionPeerInbox(agent.context.sessionId, (sourceKey, kind, payload) =>\n service.receive?.(sourceKey, kind, payload),\n );\n return async () => {\n unregister();\n releaseGroups?.();\n await bridge?.removeLocal(agent.context.sessionId);\n for (const release of unprovide.reverse()) release();\n await closeDelivery();\n };\n },\n );\n },\n ],\n}));\n","import path from 'node:path';\n\nimport { poApiCallerFrom, type PoApi, type PoApiHandler } from '@agimon-ai/po-core/packageApi';\nimport { BACKGROUND_CONTEXT, type PoSqliteService, type FileSystem } from '@agimon-ai/po-core/platform';\n\nimport { deliverSessionPeerEnvelope } from '../peerInbox';\nimport { createPeerLink, type PeerLinkControl } from '../peerLink';\nimport type { RosterPeerLinks } from '../peerLink/type';\nimport {\n PEER_REPLAY_DATABASE_FILE,\n createPeerReplayGuardAsync,\n ensurePrivateDirectory,\n parseSessionPeerEnvelope,\n peerSessionReference,\n peerRequestHeaders,\n readSessionPeerConfigAsync,\n sessionPeerConfigPath,\n verifyPeerRequest,\n type SessionPeerConfig,\n type SessionPeerReplayGuardAsync,\n} from '../peerTransport';\nimport { createSealedPeerChannels } from '../sealedPeerChannel';\nimport type { SessionGroupBridge } from '../sessionGroupBridge';\nimport type { SessionPeers } from '../sessionPeers';\n\nconst MAX_BODY_BYTES = 64 * 1024;\nconst DELIVERY_TYPES = new Set(['po/session-delivery/envelope', 'po/session-delivery/ack']);\n\nfunction response(status: number, error: string): Response {\n return Response.json({ error }, { status });\n}\n\ninterface PeerInboxState {\n readonly config: SessionPeerConfig | undefined;\n readonly replay: SessionPeerReplayGuardAsync | undefined;\n}\n\n/** Narrow HMAC-authenticated endpoint that a trusted tunnel may forward without device authentication. */\nexport function createPeerInboxApi(platform: {\n readonly fs: FileSystem;\n readonly sqlite: PoSqliteService;\n readonly peers?: SessionPeers;\n readonly network?: RosterPeerLinks;\n readonly groups?: () => SessionGroupBridge | undefined;\n readonly origin?: () => string | undefined;\n readonly fetch?: typeof fetch;\n}): PoApi {\n return {\n basePath: 'session-peer',\n start(context): PoApiHandler {\n const homeDirectory = context.homeDirectory;\n // Opened once on first use: the handler starts synchronously, the platform services are async.\n let opened: Promise<PeerInboxState> | undefined;\n const channels = createSealedPeerChannels();\n let link: PeerLinkControl | undefined;\n let announcing = false;\n const announce = (): void => {\n if (!link || announcing) return;\n announcing = true;\n void link\n .announce()\n .catch((error: unknown) => context.onNotice(`Peer URL announcement failed: ${String(error)}`))\n .finally(() => {\n announcing = false;\n });\n };\n // Retry announcements as well as detecting origin revisions. A peer may be offline at rotation.\n const timer =\n platform.peers && platform.origin\n ? setInterval(() => {\n void open()\n .then(announce)\n .catch((error: unknown) => context.onNotice(`Host links could not start: ${String(error)}`));\n }, 1_000)\n : undefined;\n timer?.unref?.();\n const open = (): Promise<PeerInboxState> =>\n (opened ??= (async () => {\n if (homeDirectory === undefined) return { config: undefined, replay: undefined };\n const config = platform.peers\n ? platform.peers.current()\n : await readSessionPeerConfigAsync(platform.fs, homeDirectory, BACKGROUND_CONTEXT);\n const file = path.join(path.dirname(sessionPeerConfigPath(homeDirectory)), PEER_REPLAY_DATABASE_FILE);\n await ensurePrivateDirectory(platform.fs, path.dirname(file), BACKGROUND_CONTEXT);\n const replay = await createPeerReplayGuardAsync(await platform.sqlite.open(file, BACKGROUND_CONTEXT));\n if (platform.peers)\n link = createPeerLink({\n peers: platform.peers,\n network: platform.network,\n groups: platform.groups,\n replay,\n channels,\n origin: platform.origin ?? (() => undefined),\n fetch: platform.fetch,\n });\n announce();\n return { config, replay };\n })().catch((error: unknown) => {\n // A failed open is retried by the next request rather than cached.\n opened = undefined;\n throw error;\n }));\n if (platform.peers)\n void open().catch((error: unknown) => context.onNotice(`Host links could not start: ${String(error)}`));\n return {\n async fetch(request) {\n const pathname = new URL(request.url).pathname;\n const openedState = await open();\n const config = platform.peers ? platform.peers.current() : openedState.config;\n const replay = openedState.replay;\n if (request.method === 'GET' && pathname === '/links' && platform.peers) {\n if (!poApiCallerFrom(request.headers)) return response(403, 'An authenticated caller is required.');\n return Response.json({\n hostId: config?.hostId,\n peers: config?.peers.map(({ hostId, url, urlGeneration }) => ({ hostId, url, urlGeneration })) ?? [],\n });\n }\n if (\n request.method !== 'POST' ||\n !['/inbox', '/control', '/link/prepare', '/link/accept', '/link/unlink', '/link/hint'].includes(pathname)\n )\n return response(404, 'Not found.');\n const length = request.headers.get('content-length');\n if (length !== null && (!/^\\d+$/u.test(length) || Number(length) > MAX_BODY_BYTES))\n return response(413, 'Request body is too large.');\n const body = await request.text();\n if (Buffer.byteLength(body) > MAX_BODY_BYTES) return response(413, 'Request body is too large.');\n if (pathname.startsWith('/link/')) {\n const caller = poApiCallerFrom(request.headers);\n if (!caller || (caller.locality === 'remote' && pathname !== '/link/hint' && caller.stepUp !== 'verified'))\n return response(403, 'Linking hosts needs a fresh peer.link step-up.');\n if (!link) return response(503, 'Host links are unavailable.');\n try {\n const input = (body === '' ? {} : JSON.parse(body)) as {\n invite?: unknown;\n hostId?: unknown;\n url?: unknown;\n };\n if (pathname === '/link/prepare') return Response.json(await link.prepare());\n if (pathname === '/link/accept') {\n await link.accept(input.invite as Parameters<PeerLinkControl['accept']>[0]);\n return Response.json({ linked: true });\n }\n if (typeof input.hostId !== 'string') return response(400, 'A host identity is required.');\n if (pathname === '/link/unlink') {\n await link.unlink(input.hostId);\n return Response.json({ unlinked: true });\n }\n if (typeof input.url !== 'string') return response(400, 'A URL hint is required.');\n return Response.json({ rebound: await link.hint(input.hostId, input.url) });\n } catch (error) {\n return response(400, error instanceof Error ? error.message : 'Host link failed.');\n }\n }\n if (pathname === '/control') {\n if (!link) return response(503, 'Host links are unavailable.');\n try {\n return await link.control(request, body);\n } catch (error) {\n return response(400, error instanceof Error ? error.message : 'Invalid peer control.');\n }\n }\n if (!config) return response(503, 'Paired Session delivery is not configured.');\n const peer = verifyPeerRequest(config, request, body);\n if (!peer) return response(401, 'Paired Session request is unauthorized.');\n if (!(await replay?.admit(request))) return response(409, 'Paired Session request was already received.');\n let parsed: unknown;\n try {\n parsed = JSON.parse(body) as unknown;\n } catch {\n return response(400, 'Paired Session request is malformed.');\n }\n let peerChannel: ReturnType<typeof channels.take>;\n if (peer.linkGeneration) {\n const sealed = parsed as { epochId?: unknown; envelope?: unknown } | null;\n peerChannel = typeof sealed?.epochId === 'string' ? channels.take(peer, sealed.epochId) : undefined;\n const opened = peerChannel?.open(sealed?.envelope);\n if (!opened?.ok) return response(401, 'A fresh sealed peer channel is required.');\n try {\n parsed = JSON.parse(Buffer.from(opened.plaintext).toString('utf8')) as unknown;\n } catch {\n return response(400, 'Invalid sealed peer envelope.');\n }\n }\n const envelope = parseSessionPeerEnvelope(parsed);\n if (!envelope || !DELIVERY_TYPES.has(envelope.type))\n return response(400, 'Paired Session envelope is invalid.');\n if (!peer.linkGeneration && !peer.allowedSessionIds.includes(envelope.targetSessionId))\n return response(403, 'Peer is not granted this session.');\n const state = await deliverSessionPeerEnvelope(\n envelope.targetSessionId,\n peerSessionReference(peer.hostId, envelope.sourceSessionId),\n envelope.type,\n envelope.payload,\n );\n if (state !== undefined && peerChannel) {\n const sealed = peerChannel.seal(Buffer.from(JSON.stringify({ accepted: true, state })));\n if (!sealed.ok) return response(503, 'Peer acknowledgement could not be sealed.');\n const text = JSON.stringify(sealed.envelope);\n return new Response(text, { headers: peerRequestHeaders(config.hostId, peer, 'RESPONSE', '/inbox', text) });\n }\n return state === undefined\n ? response(404, 'Target Session is unavailable.')\n : Response.json({ accepted: true, state }, { status: 202 });\n },\n async close() {\n if (timer) clearInterval(timer);\n const state = await opened?.catch(() => undefined);\n link?.close();\n await state?.replay?.close();\n },\n };\n },\n };\n}\n","import { defineRoute } from '@agimon-ai/po-core/extensionFile';\nimport { requirePoFs, requirePoSqlite } from '@agimon-ai/po-core/platform';\nimport { PO_REMOTE_ORIGIN_SERVICE, type RemoteOrigin } from '@agimon-ai/po-core/remoteOrigin';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createPeerInboxApi } from '../../../../services/peerInboxApi';\nimport { PO_ROSTER_PEER_SERVICE, type RosterPeerLinks } from '../../../../services/peerLink/type';\nimport { readSessionGroupBridge } from '../../../../services/sessionGroupBridge';\nimport { requireSessionPeers } from '../../../../services/sessionPeers';\n\nexport default defineRoute(({ context }: PoServerPluginContext) => {\n let origin: RemoteOrigin | undefined;\n let network: RosterPeerLinks | undefined;\n context.inject([PO_ROSTER_PEER_SERVICE], (scoped) => {\n network = scoped.get(PO_ROSTER_PEER_SERVICE);\n return () => {\n network = undefined;\n };\n });\n context.inject([PO_REMOTE_ORIGIN_SERVICE], (scoped) => {\n origin = scoped.get(PO_REMOTE_ORIGIN_SERVICE);\n return () => {\n origin = undefined;\n };\n });\n // Hosts without public routing have nothing to announce and must not keep a polling timer alive.\n const hasOrigin = origin !== undefined;\n return createPeerInboxApi({\n fs: requirePoFs(context),\n sqlite: requirePoSqlite(context),\n peers: requireSessionPeers(context),\n network,\n groups: () => readSessionGroupBridge(context),\n ...(hasOrigin ? { origin: () => origin?.current() } : {}),\n });\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/session-peer/route.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-session',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextGlobal)]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get api(): PoServerSessionPlugin['api'] { return defined([context.hosted('global') ? undefined : at(apiRoute, contextGlobal)]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return defined([context.hosted('global') ? undefined : at(apiRoute, contextGlobal)]); },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as peerSessionReference, B as provideBackgroundWorkService, C as createSessionDirectory, D as parseRemoteSessionReference, E as ensurePrivateDirectory, F as authenticatedPeerPost, I as createSealedPeerChannels, L as PEER_REPLAY_DATABASE_FILE, M as verifyPeerRequest, O as parseSessionPeerEnvelope, R as sessionPeerConfigPath, T as createPeerReplayGuardAsync, _ as createSessionIntercom, a as readSessionGroupBridge, c as PO_SESSION_PEERS_SERVICE, d as requireSessionPeers, g as createSessionGroupDeliveryAuthorizer, i as namedSessionGroupId, j as readSessionPeerConfigAsync, k as peerRequestHeaders, l as createSessionPeers, n as PO_SESSION_GROUP_BRIDGE_SERVICE, o as createPeerLink, p as provideSessionDeliveryService, r as createSessionGroupBridge, s as PO_SESSION_PEERS_CONTRACT, t as PO_SESSION_GROUP_BRIDGE_CONTRACT, v as PO_SESSION_INTERCOM_SERVICE, w as createPeerCommunication, x as createSessionGroupStore } from "../sessionGroupBridge-DQeabG52.mjs";
1
+ import { A as parseSessionPeerEnvelope, B as sessionPeerConfigPath, C as createSessionGroupStore, D as createPeerReplayGuardAsync, E as createPeerCommunication, H as provideBackgroundWorkService, L as authenticatedPeerPost, M as peerSessionReference, N as readSessionPeerConfigAsync, O as ensurePrivateDirectory, P as verifyPeerRequest, R as createSealedPeerChannels, T as createSessionDirectory, a as createSessionGroupBridge, b as PO_SESSION_INTERCOM_SERVICE, c as createPeerLink, d as createSessionPeers, h as provideSessionDeliveryService, i as PO_SESSION_GROUP_BRIDGE_SERVICE, j as peerRequestHeaders, k as parseRemoteSessionReference, l as PO_SESSION_PEERS_CONTRACT, n as PO_ROSTER_PEER_SERVICE, o as namedSessionGroupId, p as requireSessionPeers, r as PO_SESSION_GROUP_BRIDGE_CONTRACT, s as readSessionGroupBridge, u as PO_SESSION_PEERS_SERVICE, v as createSessionGroupDeliveryAuthorizer, y as createSessionIntercom, z as PEER_REPLAY_DATABASE_FILE } from "../type-BeV2gpe6.mjs";
2
2
  import path from "node:path";
3
3
  import { BACKGROUND_CONTEXT, PO_FS_SERVICE, PO_SQLITE_SERVICE, requirePoFs, requirePoSqlite } from "@agimon-ai/po-core/platform";
4
4
  import { poHomeDirectory } from "@agimon-ai/po-core/piSettings";
@@ -268,6 +268,7 @@ function createPeerInboxApi(platform) {
268
268
  const replay = await createPeerReplayGuardAsync(await platform.sqlite.open(file, BACKGROUND_CONTEXT));
269
269
  if (platform.peers) link = createPeerLink({
270
270
  peers: platform.peers,
271
+ network: platform.network,
271
272
  groups: platform.groups,
272
273
  replay,
273
274
  channels,
@@ -397,6 +398,13 @@ function createPeerInboxApi(platform) {
397
398
  //#region src/extensions/(backend)/api/session-peer/route.server.ts
398
399
  var route_server_default = defineRoute(({ context }) => {
399
400
  let origin;
401
+ let network;
402
+ context.inject([PO_ROSTER_PEER_SERVICE], (scoped) => {
403
+ network = scoped.get(PO_ROSTER_PEER_SERVICE);
404
+ return () => {
405
+ network = void 0;
406
+ };
407
+ });
400
408
  context.inject([PO_REMOTE_ORIGIN_SERVICE], (scoped) => {
401
409
  origin = scoped.get(PO_REMOTE_ORIGIN_SERVICE);
402
410
  return () => {
@@ -408,6 +416,7 @@ var route_server_default = defineRoute(({ context }) => {
408
416
  fs: requirePoFs(context),
409
417
  sqlite: requirePoSqlite(context),
410
418
  peers: requireSessionPeers(context),
419
+ network,
411
420
  groups: () => readSessionGroupBridge(context),
412
421
  ...hasOrigin ? { origin: () => origin?.current() } : {}
413
422
  });