@agimon-ai/po-session 0.0.0-alpha.124 → 0.0.0-alpha.125

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.
@@ -2,14 +2,15 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_type = require("../type-CSkVwA6w.cjs");
5
+ const require_type = require("../type-Bzv_vxKC.cjs");
6
+ let _agimon_ai_po_core_hubChannel = require("@agimon-ai/po-core/hubChannel");
7
+ let _agimon_ai_po_core_codemode = require("@agimon-ai/po-core/codemode");
6
8
  let node_path = require("node:path");
7
9
  node_path = require_type.__toESM(node_path, 1);
8
10
  let _agimon_ai_po_core_platform = require("@agimon-ai/po-core/platform");
9
11
  let _agimon_ai_po_core_piSettings = require("@agimon-ai/po-core/piSettings");
10
12
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
11
13
  let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
12
- let _agimon_ai_po_core_hubChannel = require("@agimon-ai/po-core/hubChannel");
13
14
  let _agimon_ai_po_core_remoteOrigin = require("@agimon-ai/po-core/remoteOrigin");
14
15
  let _agimon_ai_po_core_packageApi = require("@agimon-ai/po-core/packageApi");
15
16
  //#region src/extensions/(backend)/root.server.ts
@@ -90,149 +91,216 @@ async function deliverSessionPeerEnvelope(targetSessionId, sourceKey, type, payl
90
91
  return inboxes.get(targetSessionId)?.(sourceKey, type, payload);
91
92
  }
92
93
  //#endregion
94
+ //#region src/services/sessionsNamespace/nodeOperations.ts
95
+ /** Reuses the same authorized peers and durable delivery as Team's peer messaging. */
96
+ function createNodeSessionOperations(host, context, sessionId) {
97
+ const peers = () => [...host.context.sessionCommunication?.listPeers?.() ?? [], ...require_type.readSessionGroupBridge(context)?.peersFor(sessionId) ?? []];
98
+ return {
99
+ async list(signal) {
100
+ signal.throwIfAborted();
101
+ return peers();
102
+ },
103
+ async send(to, text, signal) {
104
+ signal.throwIfAborted();
105
+ const current = peers();
106
+ const exact = current.find((peer) => peer.sessionId === to);
107
+ const matching = current.filter((peer) => peer.name === to);
108
+ if (!exact && matching.length > 1) throw new Error("Ambiguous session name. Use its session ID.");
109
+ const recipient = exact?.sessionId ?? matching[0]?.sessionId ?? to;
110
+ const remote = recipient.startsWith("peer/");
111
+ const metadata = remote ? require_type.readSessionGroupBridge(context)?.metadataFor(sessionId, recipient) : void 0;
112
+ if (remote ? !metadata : host.context.sessionService?.canCommunicate?.(sessionId, recipient) !== true) throw new Error("Session is outside your communication scope.");
113
+ const delivery = require_type.readPoSessionDelivery(context);
114
+ if (!delivery) throw new Error("Session delivery is unavailable.");
115
+ const sender = host.context.sessionCommunication?.sessionName?.trim() || sessionId;
116
+ return {
117
+ ...await delivery.deliver({
118
+ deliveryId: `sessions:${sessionId}:${crypto.randomUUID()}`,
119
+ recipientKey: recipient,
120
+ kind: "session-message",
121
+ prompt: `Message from session ${sender}.\n\n${text}`,
122
+ delivery: "steer",
123
+ metadata
124
+ }),
125
+ to: recipient,
126
+ sender
127
+ };
128
+ }
129
+ };
130
+ }
131
+ //#endregion
93
132
  //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
94
133
  var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)((pluginContext) => ({
95
134
  value: void 0,
96
- services: [require_type.provideBackgroundWorkService, (owner) => {
97
- owner.inject([
98
- require_type.PO_SESSION_PEERS_SERVICE,
99
- require_type.PO_SESSION_GROUP_BRIDGE_SERVICE,
100
- _agimon_ai_po_core_platform.PO_FS_SERVICE,
101
- _agimon_ai_po_core_platform.PO_SQLITE_SERVICE
102
- ], async (context) => {
135
+ services: [
136
+ require_type.provideBackgroundWorkService,
137
+ (owner) => {
103
138
  const agent = pluginContext.agent;
104
- const session = agent?.context.session;
105
- const communication = pluginContext.host.context.sessionCommunication;
106
- const homeDirectory = pluginContext.host.context.homeDirectory;
107
- const sessionService = pluginContext.host.context.sessionService;
108
- if (!agent || !session?.admitPrompt || !communication || !homeDirectory || !sessionService?.canCommunicate) throw new Error("Session delivery requires the headless agent, authenticated session communication, host home directory, and communication policy.");
109
- const fs = (0, _agimon_ai_po_core_platform.requirePoFs)(context);
110
- const sqlite = (0, _agimon_ai_po_core_platform.requirePoSqlite)(context);
111
- const io = _agimon_ai_po_core_platform.BACKGROUND_CONTEXT;
112
- const sessionDirectory = node_path.default.join((0, _agimon_ai_po_core_piSettings.poHomeDirectory)(homeDirectory), "session");
113
- const deliveryDirectory = node_path.default.join(sessionDirectory, "delivery");
114
- await require_type.ensurePrivateDirectory(fs, deliveryDirectory, io);
115
- const peers = require_type.requireSessionPeers(context);
116
- const peerConfig = peers.current();
117
- const peerCommunication = require_type.createPeerCommunication({
118
- local: communication,
119
- config: () => peers.current(),
120
- canPublish: (target, type, payload) => {
121
- if (type === "po/session-delivery/ack") return true;
122
- const metadata = payload?.metadata;
123
- return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === target && peer.sharedGroups.some((name) => require_type.namedSessionGroupId(name) === metadata?.groupId)) === true;
124
- },
125
- onError: (error) => pluginContext.host.context.onNotice(`Peer delivery failed: ${String(error)}`)
139
+ if (!agent) return;
140
+ const options = {
141
+ sessionId: agent.context.sessionId,
142
+ provenance: () => pluginContext.host.context.sessionContext?.provenance,
143
+ coordination: () => pluginContext.host.context.coordination,
144
+ operations: require_type.readSessionOperations(owner) ?? createNodeSessionOperations(pluginContext.host, owner, agent.context.sessionId),
145
+ assertAvailable: () => pluginContext.signal.throwIfAborted()
146
+ };
147
+ const tool = agent.registerTool(require_type.createStartSessionTool(options));
148
+ const eligibility = options.provenance() === _agimon_ai_po_core_hubChannel.COORDINATOR_SESSION_PROVENANCE ? void 0 : agent.registerToolRestriction({ excludedTools: [require_type.START_SESSION_TOOL_NAME] });
149
+ const injection = owner.inject([_agimon_ai_po_core_codemode.PO_CODEMODE_SERVICE], (context) => {
150
+ const registration = (0, _agimon_ai_po_core_codemode.readPoCodemode)(context)?.register("@agimon-ai/po-session", require_type.createSessionsNamespace(options));
151
+ const restriction = registration ? agent.registerToolRestriction({ excludedTools: [require_type.START_SESSION_TOOL_NAME, ...options.operations.fallbackToolName ? [options.operations.fallbackToolName] : []] }) : void 0;
152
+ return () => {
153
+ restriction?.dispose();
154
+ registration?.dispose();
155
+ };
126
156
  });
127
- const remotePeerIsGranted = (peerKey) => {
128
- const peer = require_type.parseRemoteSessionReference(peerKey);
129
- return peer !== void 0 && peers.current()?.peers.some((candidate) => candidate.hostId === peer.hostId && candidate.allowedSessionIds.includes(agent.context.sessionId)) === true;
157
+ return async () => {
158
+ await injection.dispose();
159
+ eligibility?.dispose();
160
+ tool.dispose();
130
161
  };
131
- const fallbackAuthorization = (peerKey) => sessionService.canCommunicate?.(agent.context.sessionId, peerKey) === true || remotePeerIsGranted(peerKey);
132
- const bridge = require_type.readSessionGroupBridge(context);
133
- const groups = bridge?.groups;
134
- await bridge?.updateLocal(agent.context.sessionId, communication.sessionName ?? agent.context.sessionId, communication.groups ?? []);
135
- const localHostId = peerConfig?.hostId;
136
- const selfReference = localHostId ? require_type.peerSessionReference(localHostId, agent.context.sessionId) : void 0;
137
- const groupAuthorization = groups && selfReference && localHostId ? require_type.createSessionGroupDeliveryAuthorizer({
138
- selfReference,
139
- groups,
140
- peerReference: (peerKey) => require_type.parseRemoteSessionReference(peerKey) === void 0 ? require_type.peerSessionReference(localHostId, peerKey) : peerKey,
141
- fallback: fallbackAuthorization
142
- }) : void 0;
143
- let delivery;
144
- try {
145
- delivery = await require_type.provideSessionDeliveryService(context, {
146
- database: await sqlite.open(node_path.default.join(deliveryDirectory, `${agent.context.sessionId}.sqlite`), io),
147
- recipientKey: agent.context.sessionId,
148
- communication: peerCommunication,
149
- authorizePeer: (peerKey, metadata) => {
150
- const remote = require_type.parseRemoteSessionReference(peerKey);
151
- if (remote && !peers.current()?.peers.some((peer) => peer.hostId === remote.hostId)) return false;
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_type.namedSessionGroupId(name) === metadata.groupId)) return false;
154
- return groupAuthorization ? groupAuthorization(peerKey, metadata) : false;
155
- }
156
- return groupAuthorization ? groupAuthorization(peerKey, metadata) : fallbackAuthorization(peerKey);
162
+ },
163
+ (owner) => {
164
+ owner.inject([
165
+ require_type.PO_SESSION_PEERS_SERVICE,
166
+ require_type.PO_SESSION_GROUP_BRIDGE_SERVICE,
167
+ _agimon_ai_po_core_platform.PO_FS_SERVICE,
168
+ _agimon_ai_po_core_platform.PO_SQLITE_SERVICE
169
+ ], async (context) => {
170
+ const agent = pluginContext.agent;
171
+ const session = agent?.context.session;
172
+ const communication = pluginContext.host.context.sessionCommunication;
173
+ const homeDirectory = pluginContext.host.context.homeDirectory;
174
+ const sessionService = pluginContext.host.context.sessionService;
175
+ if (!agent || !session?.admitPrompt || !communication || !homeDirectory || !sessionService?.canCommunicate) throw new Error("Session delivery requires the headless agent, authenticated session communication, host home directory, and communication policy.");
176
+ const fs = (0, _agimon_ai_po_core_platform.requirePoFs)(context);
177
+ const sqlite = (0, _agimon_ai_po_core_platform.requirePoSqlite)(context);
178
+ const io = _agimon_ai_po_core_platform.BACKGROUND_CONTEXT;
179
+ const sessionDirectory = node_path.default.join((0, _agimon_ai_po_core_piSettings.poHomeDirectory)(homeDirectory), "session");
180
+ const deliveryDirectory = node_path.default.join(sessionDirectory, "delivery");
181
+ await require_type.ensurePrivateDirectory(fs, deliveryDirectory, io);
182
+ const peers = require_type.requireSessionPeers(context);
183
+ const peerConfig = peers.current();
184
+ const peerCommunication = require_type.createPeerCommunication({
185
+ local: communication,
186
+ config: () => peers.current(),
187
+ canPublish: (target, type, payload) => {
188
+ if (type === "po/session-delivery/ack") return true;
189
+ const metadata = payload?.metadata;
190
+ return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === target && peer.sharedGroups.some((name) => require_type.namedSessionGroupId(name) === metadata?.groupId)) === true;
157
191
  },
158
- admitPrompt: async (prompt, admission, requestId, metadata) => {
159
- if (!metadata.customType) {
160
- await session.admitPrompt(prompt, admission, void 0, requestId);
161
- return;
162
- }
163
- if (!session.admitMessage) throw new Error("The session cannot admit a custom delivery.");
164
- await session.admitMessage({
165
- type: metadata.customType,
166
- text: prompt,
167
- display: true,
168
- details: metadata.customDetails === void 0 ? void 0 : JSON.parse(metadata.customDetails)
169
- }, admission === "steer" ? "steer" : "followUp", requestId);
170
- }
192
+ onError: (error) => pluginContext.host.context.onNotice(`Peer delivery failed: ${String(error)}`)
171
193
  });
172
- } catch (error) {
173
- await bridge?.removeLocal(agent.context.sessionId);
174
- throw error;
175
- }
176
- const { service, close: closeDelivery } = delivery;
177
- const unprovide = [];
178
- if (groups && selfReference && peerConfig) {
179
- const directory = require_type.createSessionDirectory({ authorizeDiscovery: (_caller, subject) => {
180
- const reference = require_type.peerSessionReference(subject.hostId, subject.sessionId);
181
- return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === reference) ? { capabilities: ["message"] } : void 0;
182
- } });
183
- const observedHosts = /* @__PURE__ */ new Set();
184
- let sequence = 0;
185
- const observeRemote = () => {
186
- const remotePeers = bridge?.peersFor(agent.context.sessionId) ?? [];
187
- for (const peer of remotePeers) observedHosts.add(require_type.parseRemoteSessionReference(peer.sessionId).hostId);
188
- sequence += 1;
189
- for (const hostId of observedHosts) directory.replaceHostSnapshot(hostId, "linked", remotePeers.flatMap((peer) => {
190
- const remote = require_type.parseRemoteSessionReference(peer.sessionId);
191
- return remote.hostId !== hostId ? [] : [{
192
- hostId,
193
- sessionId: remote.sessionId,
194
- label: peer.name,
195
- hostIncarnation: "linked",
196
- sessionIncarnation: "live",
197
- sequence,
198
- observedAt: Date.now(),
199
- staleAfterMs: 12e4,
200
- deliveryTarget: peer.sessionId,
201
- reachability: "unknown",
202
- runtime: "unknown",
203
- activity: "unknown",
204
- voice: {
205
- eligible: "unknown",
206
- readiness: "unknown"
207
- }
208
- }];
209
- }));
194
+ const remotePeerIsGranted = (peerKey) => {
195
+ const peer = require_type.parseRemoteSessionReference(peerKey);
196
+ return peer !== void 0 && peers.current()?.peers.some((candidate) => candidate.hostId === peer.hostId && candidate.allowedSessionIds.includes(agent.context.sessionId)) === true;
210
197
  };
211
- observeRemote();
212
- unprovide.push(bridge.subscribe(() => {
213
- observeRemote();
214
- service.reauthorize?.().catch((error) => pluginContext.host.context.onNotice(`Delivery reauthorization failed: ${String(error)}`));
215
- }));
216
- unprovide.push(context.provide(require_type.PO_SESSION_INTERCOM_SERVICE, require_type.createSessionIntercom({
198
+ const fallbackAuthorization = (peerKey) => sessionService.canCommunicate?.(agent.context.sessionId, peerKey) === true || remotePeerIsGranted(peerKey);
199
+ const bridge = require_type.readSessionGroupBridge(context);
200
+ const groups = bridge?.groups;
201
+ await bridge?.updateLocal(agent.context.sessionId, communication.sessionName ?? agent.context.sessionId, communication.groups ?? []);
202
+ const localHostId = peerConfig?.hostId;
203
+ const selfReference = localHostId ? require_type.peerSessionReference(localHostId, agent.context.sessionId) : void 0;
204
+ const groupAuthorization = groups && selfReference && localHostId ? require_type.createSessionGroupDeliveryAuthorizer({
217
205
  selfReference,
218
- directory,
219
206
  groups,
220
- delivery: service
221
- })));
222
- }
223
- const releaseGroups = pluginContext.host.context.directEvents?.subscribe(_agimon_ai_po_core_hubChannel.PO_SESSION_ATTENTION_EVENT, agent.context.sessionId, () => {
224
- bridge?.updateLocal(agent.context.sessionId, communication.sessionName ?? agent.context.sessionId, communication.groups ?? []).catch((error) => pluginContext.host.context.onNotice(`Group update failed: ${String(error)}`));
207
+ peerReference: (peerKey) => require_type.parseRemoteSessionReference(peerKey) === void 0 ? require_type.peerSessionReference(localHostId, peerKey) : peerKey,
208
+ fallback: fallbackAuthorization
209
+ }) : void 0;
210
+ let delivery;
211
+ try {
212
+ delivery = await require_type.provideSessionDeliveryService(context, {
213
+ database: await sqlite.open(node_path.default.join(deliveryDirectory, `${agent.context.sessionId}.sqlite`), io),
214
+ recipientKey: agent.context.sessionId,
215
+ communication: peerCommunication,
216
+ authorizePeer: (peerKey, metadata) => {
217
+ const remote = require_type.parseRemoteSessionReference(peerKey);
218
+ if (remote && !peers.current()?.peers.some((peer) => peer.hostId === remote.hostId)) return false;
219
+ if (remote) {
220
+ 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;
221
+ return groupAuthorization ? groupAuthorization(peerKey, metadata) : false;
222
+ }
223
+ return groupAuthorization ? groupAuthorization(peerKey, metadata) : fallbackAuthorization(peerKey);
224
+ },
225
+ admitPrompt: async (prompt, admission, requestId, metadata) => {
226
+ if (!metadata.customType) {
227
+ await session.admitPrompt(prompt, admission, void 0, requestId);
228
+ return;
229
+ }
230
+ if (!session.admitMessage) throw new Error("The session cannot admit a custom delivery.");
231
+ await session.admitMessage({
232
+ type: metadata.customType,
233
+ text: prompt,
234
+ display: true,
235
+ details: metadata.customDetails === void 0 ? void 0 : JSON.parse(metadata.customDetails)
236
+ }, admission === "steer" ? "steer" : "followUp", requestId);
237
+ }
238
+ });
239
+ } catch (error) {
240
+ await bridge?.removeLocal(agent.context.sessionId);
241
+ throw error;
242
+ }
243
+ const { service, close: closeDelivery } = delivery;
244
+ const unprovide = [];
245
+ if (groups && selfReference && peerConfig) {
246
+ const directory = require_type.createSessionDirectory({ authorizeDiscovery: (_caller, subject) => {
247
+ const reference = require_type.peerSessionReference(subject.hostId, subject.sessionId);
248
+ return bridge?.peersFor(agent.context.sessionId).some((peer) => peer.sessionId === reference) ? { capabilities: ["message"] } : void 0;
249
+ } });
250
+ const observedHosts = /* @__PURE__ */ new Set();
251
+ let sequence = 0;
252
+ const observeRemote = () => {
253
+ const remotePeers = bridge?.peersFor(agent.context.sessionId) ?? [];
254
+ for (const peer of remotePeers) observedHosts.add(require_type.parseRemoteSessionReference(peer.sessionId).hostId);
255
+ sequence += 1;
256
+ for (const hostId of observedHosts) directory.replaceHostSnapshot(hostId, "linked", remotePeers.flatMap((peer) => {
257
+ const remote = require_type.parseRemoteSessionReference(peer.sessionId);
258
+ return remote.hostId !== hostId ? [] : [{
259
+ hostId,
260
+ sessionId: remote.sessionId,
261
+ label: peer.name,
262
+ hostIncarnation: "linked",
263
+ sessionIncarnation: "live",
264
+ sequence,
265
+ observedAt: Date.now(),
266
+ staleAfterMs: 12e4,
267
+ deliveryTarget: peer.sessionId,
268
+ reachability: "unknown",
269
+ runtime: "unknown",
270
+ activity: "unknown",
271
+ voice: {
272
+ eligible: "unknown",
273
+ readiness: "unknown"
274
+ }
275
+ }];
276
+ }));
277
+ };
278
+ observeRemote();
279
+ unprovide.push(bridge.subscribe(() => {
280
+ observeRemote();
281
+ service.reauthorize?.().catch((error) => pluginContext.host.context.onNotice(`Delivery reauthorization failed: ${String(error)}`));
282
+ }));
283
+ unprovide.push(context.provide(require_type.PO_SESSION_INTERCOM_SERVICE, require_type.createSessionIntercom({
284
+ selfReference,
285
+ directory,
286
+ groups,
287
+ delivery: service
288
+ })));
289
+ }
290
+ const releaseGroups = pluginContext.host.context.directEvents?.subscribe(_agimon_ai_po_core_hubChannel.PO_SESSION_ATTENTION_EVENT, agent.context.sessionId, () => {
291
+ bridge?.updateLocal(agent.context.sessionId, communication.sessionName ?? agent.context.sessionId, communication.groups ?? []).catch((error) => pluginContext.host.context.onNotice(`Group update failed: ${String(error)}`));
292
+ });
293
+ const unregister = registerSessionPeerInbox(agent.context.sessionId, (sourceKey, kind, payload) => service.receive?.(sourceKey, kind, payload));
294
+ return async () => {
295
+ unregister();
296
+ releaseGroups?.();
297
+ await bridge?.removeLocal(agent.context.sessionId);
298
+ for (const release of unprovide.reverse()) release();
299
+ await closeDelivery();
300
+ };
225
301
  });
226
- const unregister = registerSessionPeerInbox(agent.context.sessionId, (sourceKey, kind, payload) => service.receive?.(sourceKey, kind, payload));
227
- return async () => {
228
- unregister();
229
- releaseGroups?.();
230
- await bridge?.removeLocal(agent.context.sessionId);
231
- for (const release of unprovide.reverse()) release();
232
- await closeDelivery();
233
- };
234
- });
235
- }]
302
+ }
303
+ ]
236
304
  }));
237
305
  //#endregion
238
306
  //#region src/services/peerInboxApi/index.ts
@@ -427,6 +495,16 @@ var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(({
427
495
  });
428
496
  });
429
497
  //#endregion
498
+ //#region src/extensions/workspaces/sessions/(backend)/resource/codemode-how-to-session.server.ts
499
+ var codemode_how_to_session_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
500
+ name: "codemode-how-to-session",
501
+ description: "List related sessions, send guidance, and start briefed independent work as a coordinator through the sessions namespace. No stop or delete capability.",
502
+ kind: "skill",
503
+ pinned: true,
504
+ path: (0, _agimon_ai_po_core_serverPlugin.packageResourcePath)(require("url").pathToFileURL(__filename).href, "src/prompts/codemode-how-to-session/SKILL.md"),
505
+ read: () => (0, _agimon_ai_po_core_serverPlugin.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/codemode-how-to-session/SKILL.md")
506
+ });
507
+ //#endregion
430
508
  //#region generated/server.ts
431
509
  const at = (value, context) => typeof value === "function" ? value(context) : value;
432
510
  /* v8 ignore next -- generated normalization branch */
@@ -474,11 +552,18 @@ const serverPlugin = (0, _agimon_ai_po_core_serverPlugin.defineServerPlugin)({
474
552
  root: scopeGlobal.value
475
553
  };
476
554
  const scopeSession = await context.scopeRoot("session", root_server_default, contextGlobal);
555
+ const contextSession = {
556
+ ...contextGlobal,
557
+ root: scopeSession.value
558
+ };
477
559
  return {
478
560
  ...(0, _agimon_ai_po_core_extensionFile.composeRootHooks)(scopeGlobal, scopeSession),
479
561
  get api() {
480
562
  return defined([context.hosted("global") ? void 0 : at(route_server_default, contextGlobal)]);
481
563
  },
564
+ get resources() {
565
+ return [at(codemode_how_to_session_server_default, contextSession)];
566
+ },
482
567
  services: [...scopeGlobal.services ?? [], ...scopeSession.services ?? []],
483
568
  get activities() {
484
569
  return [...scopeGlobal.activities ?? [], ...scopeSession.activities ?? []];