@aopslabs/aops-server 0.2.15 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/THIRD_PARTY_NOTICES +92 -18
  2. package/THIRD_PARTY_NOTICES.inventory.json +42 -32
  3. package/build/client/_app/immutable/chunks/BCjjBhRV.js +1 -0
  4. package/build/client/_app/immutable/entry/{app.DekpYahB.js → app.6eWjPiTT.js} +2 -2
  5. package/build/client/_app/immutable/entry/start.D3gplTQc.js +1 -0
  6. package/build/client/_app/immutable/nodes/{1.C_m2PfHM.js → 1.BvMAhla4.js} +1 -1
  7. package/build/client/_app/version.json +1 -1
  8. package/build/handler.js +4 -4
  9. package/build/index.js +4 -4
  10. package/build/server/chunks/chunks/{internal.js-DfNDnSaz.js → internal.js-AMt3g8E7.js} +1 -1
  11. package/build/server/chunks/{handler-BJwWMzoK.js → handler-BqsTaaMZ.js} +2 -2
  12. package/build/server/chunks/{index.js-lf8q_rBQ.js → index.js-uhRu7SLL.js} +1 -1
  13. package/build/server/chunks/{manifest.js-BbSaGAoy.js → manifest.js-Dn5-mn6R.js} +2 -2
  14. package/build/server/chunks/nodes/{1.js-DzchJAL9.js → 1.js-ClI9U15j.js} +1 -1
  15. package/cockpit/.vite/manifest.json +2 -2
  16. package/cockpit/assets/index-CVNHK-Vk.js +18 -0
  17. package/cockpit/assets/{index-B2e2Kw5U.css → index-DRAd9oM3.css} +1 -1
  18. package/cockpit/community.module-inventory.json +209 -199
  19. package/cockpit/index.html +2 -2
  20. package/npm-shrinkwrap.json +42 -35
  21. package/package.json +7 -6
  22. package/runtime-closure.package.json +15 -13
  23. package/scripts/community-agent-wake-endpoint.mjs +329 -0
  24. package/scripts/community-host.mjs +185 -1
  25. package/build/client/_app/immutable/chunks/DSpwhhgJ.js +0 -1
  26. package/build/client/_app/immutable/entry/start.DBrQBcQx.js +0 -1
  27. package/cockpit/assets/index-DjTrHh8F.js +0 -18
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3E%3Crect%20width='32'%20height='32'%20rx='6'%20fill='%235B8B6F'/%3E%3Cpath%20d='M8%2021h16v3H8v-3Zm0-6h16v3H8v-3Zm0-7h16v4H8V8Z'%20fill='%23FBF6EE'/%3E%3C/svg%3E" />
7
7
  <title>AOPS Cockpit v2</title>
8
- <script type="module" crossorigin src="/assets/index-DjTrHh8F.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-B2e2Kw5U.css">
8
+ <script type="module" crossorigin src="/assets/index-CVNHK-Vk.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DRAd9oM3.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -1,29 +1,30 @@
1
1
  {
2
2
  "name": "@aopslab/aops-server-runtime-closure",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@aopslab/aops-server-runtime-closure",
9
- "version": "0.2.15",
9
+ "version": "0.2.16",
10
10
  "license": "UNLICENSED",
11
11
  "dependencies": {
12
+ "@aopslabs/aops-agent-runtime": "0.1.0",
12
13
  "@aopslabs/aops-error-catalog": "0.2.1",
13
14
  "@aopslabs/aops-host-registration": "0.2.1",
14
15
  "@aopslabs/aops-pg-bootstrap": "0.2.3",
15
16
  "@aopslabs/artifact-trust-contracts": "0.3.1",
16
17
  "@aopslabs/domain-host-plugin-agentspace": "0.3.1",
17
- "@aopslabs/domain-host-plugin-chatv3": "0.4.0",
18
+ "@aopslabs/domain-host-plugin-chatv3": "0.4.1",
18
19
  "@aopslabs/domain-host-plugin-docman": "0.3.2",
19
- "@aopslabs/domain-host-plugin-projectman": "0.3.2",
20
+ "@aopslabs/domain-host-plugin-projectman": "0.3.3",
20
21
  "@aopslabs/domain-host-plugin-sys": "0.3.1",
21
22
  "@aopslabs/domain-kit-agentspace": "0.2.2",
22
- "@aopslabs/domain-kit-chatv3": "0.4.0",
23
+ "@aopslabs/domain-kit-chatv3": "0.4.1",
23
24
  "@aopslabs/domain-kit-docman": "0.3.0",
24
- "@aopslabs/domain-kit-projectman": "0.3.2",
25
+ "@aopslabs/domain-kit-projectman": "0.3.3",
25
26
  "@aopslabs/domain-kit-sys": "0.3.1",
26
- "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.0",
27
+ "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.1",
27
28
  "@aopslabs/domain-pg-bootstrap-docman": "0.2.0",
28
29
  "@aopslabs/domain-pg-bootstrap-projectman": "0.2.0",
29
30
  "@aopslabs/domain-pg-bootstrap-sys": "0.2.0",
@@ -45,6 +46,12 @@
45
46
  "zod": "4.4.3"
46
47
  }
47
48
  },
49
+ "node_modules/@aopslabs/aops-agent-runtime": {
50
+ "version": "0.1.0",
51
+ "resolved": "https://registry.npmjs.org/@aopslabs/aops-agent-runtime/-/aops-agent-runtime-0.1.0.tgz",
52
+ "integrity": "sha512-0qi7ssCk2PztMVbC4KYuzzGHfhEgTX5Ka9mzghslv3eIluL6WK4aPoL+pScT1GyvQWBSmHBRs3HtPklYrndzbQ==",
53
+ "license": "SEE LICENSE IN LICENSE"
54
+ },
48
55
  "node_modules/@aopslabs/aops-error-catalog": {
49
56
  "version": "0.2.1",
50
57
  "resolved": "https://registry.npmjs.org/@aopslabs/aops-error-catalog/-/aops-error-catalog-0.2.1.tgz",
@@ -120,9 +127,9 @@
120
127
  }
121
128
  },
122
129
  "node_modules/@aopslabs/domain-dm-chatv3": {
123
- "version": "0.4.0",
124
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-dm-chatv3/-/domain-dm-chatv3-0.4.0.tgz",
125
- "integrity": "sha512-lv0DBZ7ThyRk2aJrFtVmBmEbgsfMCxRbVj2Lrl9XlJc3dkIfWB7oqCk3JM1E3KCnrs2QeTALf/1grEk8pKzkZw==",
130
+ "version": "0.4.1",
131
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-dm-chatv3/-/domain-dm-chatv3-0.4.1.tgz",
132
+ "integrity": "sha512-GgpX1dhKIpNumZEWU8mHOVidGegskboDioPnst46umksXunzBhFpynJQJsOwjeFT8Oi/l5GCoX6FmsfHY5P81g==",
126
133
  "license": "SEE LICENSE IN LICENSE",
127
134
  "dependencies": {
128
135
  "drizzle-orm": "0.45.2",
@@ -160,9 +167,9 @@
160
167
  }
161
168
  },
162
169
  "node_modules/@aopslabs/domain-dm-projectman": {
163
- "version": "0.2.0",
164
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-dm-projectman/-/domain-dm-projectman-0.2.0.tgz",
165
- "integrity": "sha512-lJeylF8YEC6n907cKHAmkBtk2ToeXKwxhlLSL4Ozr38xcffupr0iZUi/KX7OlV3Ve2a+/TEycH5leb7MIu+dtQ==",
170
+ "version": "0.3.3",
171
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-dm-projectman/-/domain-dm-projectman-0.3.3.tgz",
172
+ "integrity": "sha512-UfQ06o6tTfRDdjiD4ndyZcwFO86VQaPPikEuzKoDBUbNYrhi0mXd9+iOJjVGmXeAv8cxLfU1WoGHbeeEu+ZNgg==",
166
173
  "license": "SEE LICENSE IN LICENSE",
167
174
  "dependencies": {
168
175
  "@aopslabs/xf-bm": "^0.2.0",
@@ -173,7 +180,7 @@
173
180
  "@aopslabs/xf-dm": "^0.2.0",
174
181
  "@aopslabs/xf-i18n": "^0.2.0",
175
182
  "@aopslabs/xf-logger": "^0.2.0",
176
- "@aopslabs/xf-validation": "^0.2.0",
183
+ "@aopslabs/xf-validation": "0.2.0",
177
184
  "drizzle-orm": "0.45.2",
178
185
  "effect": "3.20.0",
179
186
  "tslib": "^2.3.0",
@@ -220,14 +227,14 @@
220
227
  }
221
228
  },
222
229
  "node_modules/@aopslabs/domain-host-plugin-chatv3": {
223
- "version": "0.4.0",
224
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-host-plugin-chatv3/-/domain-host-plugin-chatv3-0.4.0.tgz",
225
- "integrity": "sha512-BK8DRiV6PqExppOW/7IogGbRQyHN59n0Bm4qp7k4er6/SyqbpYJUCD58MzyQjNl7byNLh9mbfPLF3nJ33iIgCw==",
230
+ "version": "0.4.1",
231
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-host-plugin-chatv3/-/domain-host-plugin-chatv3-0.4.1.tgz",
232
+ "integrity": "sha512-l19y5I4E/yFZ0J1it1/xWpCewC2Jz67jY2qNflcowg2MdsFjT5nUG0ebfKl+QyOYay0DAGikvkbRnVa953q+aQ==",
226
233
  "license": "SEE LICENSE IN LICENSE",
227
234
  "dependencies": {
228
- "@aopslabs/domain-dm-chatv3": "0.4.0",
229
- "@aopslabs/domain-kit-chatv3": "0.4.0",
230
- "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.0"
235
+ "@aopslabs/domain-dm-chatv3": "0.4.1",
236
+ "@aopslabs/domain-kit-chatv3": "0.4.1",
237
+ "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.1"
231
238
  }
232
239
  },
233
240
  "node_modules/@aopslabs/domain-host-plugin-docman": {
@@ -242,12 +249,12 @@
242
249
  }
243
250
  },
244
251
  "node_modules/@aopslabs/domain-host-plugin-projectman": {
245
- "version": "0.3.2",
246
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-host-plugin-projectman/-/domain-host-plugin-projectman-0.3.2.tgz",
247
- "integrity": "sha512-AntzkN0fC6IeRbEGw7EqX5pVQS5ARnwlcP5tWMLoWf0RV1fkIwbchZ298zAnPbLgKGD9onoxGZgYdRbeUnvILQ==",
252
+ "version": "0.3.3",
253
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-host-plugin-projectman/-/domain-host-plugin-projectman-0.3.3.tgz",
254
+ "integrity": "sha512-WnhjRVBeE+i5qu7YSlmeO6uyjn6CxvXfdcBV1h61I/9OKmyMD+4gMutJw5r9Qh57RjlOEpD9vahjKrulUxKtJA==",
248
255
  "license": "SEE LICENSE IN LICENSE",
249
256
  "dependencies": {
250
- "@aopslabs/domain-kit-projectman": "0.3.2",
257
+ "@aopslabs/domain-kit-projectman": "0.3.3",
251
258
  "@aopslabs/xf-validation": "0.2.0"
252
259
  }
253
260
  },
@@ -282,12 +289,12 @@
282
289
  }
283
290
  },
284
291
  "node_modules/@aopslabs/domain-kit-chatv3": {
285
- "version": "0.4.0",
286
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-kit-chatv3/-/domain-kit-chatv3-0.4.0.tgz",
287
- "integrity": "sha512-EAEoZgfIzQlIiCz1GBZLun1OwcDxjuI6A7/laeocdBr3nDDNg2QY2x+iVpPp5OnGgayp3fl0G2lcdIOxrun4xA==",
292
+ "version": "0.4.1",
293
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-kit-chatv3/-/domain-kit-chatv3-0.4.1.tgz",
294
+ "integrity": "sha512-AktxZIFL/0Du9kRJi1OfIdOvgZuDiSg57UDbdrzG78L7vp44Vlqnuyn++46z/ST8S6gw27cLemw1gars7XWHSw==",
288
295
  "license": "SEE LICENSE IN LICENSE",
289
296
  "dependencies": {
290
- "@aopslabs/domain-dm-chatv3": "0.4.0",
297
+ "@aopslabs/domain-dm-chatv3": "0.4.1",
291
298
  "zod": "4.4.3"
292
299
  }
293
300
  },
@@ -312,12 +319,12 @@
312
319
  }
313
320
  },
314
321
  "node_modules/@aopslabs/domain-kit-projectman": {
315
- "version": "0.3.2",
316
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-kit-projectman/-/domain-kit-projectman-0.3.2.tgz",
317
- "integrity": "sha512-wVibkK1/6rpn7m6CGNWebHZyQy46+1MakfAbFib2uB8gHpfSkTEnCpkTtimnpGpnt3nFrXu09413ZBnjUZYunw==",
322
+ "version": "0.3.3",
323
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-kit-projectman/-/domain-kit-projectman-0.3.3.tgz",
324
+ "integrity": "sha512-sbnCZEcgX8Hes3qdYyP0YeTxmbX3UE+4VO02b7niM8c7jFmgfvtlabRm9Q7dj2Qukhnum5IyhTAf+8yBugC0gA==",
318
325
  "license": "SEE LICENSE IN LICENSE",
319
326
  "dependencies": {
320
- "@aopslabs/domain-dm-projectman": "0.2.0",
327
+ "@aopslabs/domain-dm-projectman": "0.3.3",
321
328
  "@aopslabs/xf-core": "^0.2.0",
322
329
  "@aopslabs/xf-db": "^0.2.0",
323
330
  "@aopslabs/xf-dm-kits": "^0.2.0",
@@ -350,9 +357,9 @@
350
357
  }
351
358
  },
352
359
  "node_modules/@aopslabs/domain-pg-bootstrap-chatv3": {
353
- "version": "0.4.0",
354
- "resolved": "https://registry.npmjs.org/@aopslabs/domain-pg-bootstrap-chatv3/-/domain-pg-bootstrap-chatv3-0.4.0.tgz",
355
- "integrity": "sha512-1T2D+v3me6WqfeM158A206D+q+Htbxj38wQminHoThhsIsyQnmQU79Xjf7884OtYSlq1DDVRUTu1qZpPzCad9A==",
360
+ "version": "0.4.1",
361
+ "resolved": "https://registry.npmjs.org/@aopslabs/domain-pg-bootstrap-chatv3/-/domain-pg-bootstrap-chatv3-0.4.1.tgz",
362
+ "integrity": "sha512-v/TuaSgPRy5hPjdBXA/mHgU8yqlUWwShGEaHdVzhCHogRRqr50uspSu2q8JzXPuwWc9iOk/lCZjN2wUh3Dl4Iw==",
356
363
  "license": "SEE LICENSE IN LICENSE",
357
364
  "dependencies": {
358
365
  "pg": "8.20.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aopslabs/aops-server",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "type": "module",
5
5
  "description": "AOPS server runtime.",
6
6
  "keywords": [
@@ -39,21 +39,22 @@
39
39
  "postpack": "node ./scripts/stage-public-npm-package.mjs --clean"
40
40
  },
41
41
  "dependencies": {
42
+ "@aopslabs/aops-agent-runtime": "0.1.0",
42
43
  "@aopslabs/aops-error-catalog": "0.2.1",
43
44
  "@aopslabs/aops-host-registration": "0.2.1",
44
45
  "@aopslabs/aops-pg-bootstrap": "0.2.3",
45
46
  "@aopslabs/artifact-trust-contracts": "0.3.1",
46
47
  "@aopslabs/domain-host-plugin-agentspace": "0.3.1",
47
- "@aopslabs/domain-host-plugin-chatv3": "0.4.0",
48
+ "@aopslabs/domain-host-plugin-chatv3": "0.4.1",
48
49
  "@aopslabs/domain-host-plugin-docman": "0.3.2",
49
- "@aopslabs/domain-host-plugin-projectman": "0.3.2",
50
+ "@aopslabs/domain-host-plugin-projectman": "0.3.3",
50
51
  "@aopslabs/domain-host-plugin-sys": "0.3.1",
51
52
  "@aopslabs/domain-kit-agentspace": "0.2.2",
52
- "@aopslabs/domain-kit-chatv3": "0.4.0",
53
- "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.0",
53
+ "@aopslabs/domain-kit-chatv3": "0.4.1",
54
+ "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.1",
54
55
  "@aopslabs/domain-pg-bootstrap-projectman": "0.2.0",
55
56
  "@aopslabs/domain-kit-docman": "0.3.0",
56
- "@aopslabs/domain-kit-projectman": "0.3.2",
57
+ "@aopslabs/domain-kit-projectman": "0.3.3",
57
58
  "@aopslabs/domain-kit-sys": "0.3.1",
58
59
  "@aopslabs/domain-pg-bootstrap-sys": "0.2.0",
59
60
  "@aopslabs/domain-pg-bootstrap-docman": "0.2.0",
@@ -1,25 +1,26 @@
1
1
  {
2
2
  "name": "@aopslab/aops-server-runtime-closure",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
7
7
  "dependencies": {
8
+ "@aopslabs/aops-agent-runtime": "0.1.0",
8
9
  "@aopslabs/aops-error-catalog": "0.2.1",
9
10
  "@aopslabs/aops-host-registration": "0.2.1",
10
11
  "@aopslabs/aops-pg-bootstrap": "0.2.3",
11
12
  "@aopslabs/artifact-trust-contracts": "0.3.1",
12
13
  "@aopslabs/domain-host-plugin-agentspace": "0.3.1",
13
- "@aopslabs/domain-host-plugin-chatv3": "0.4.0",
14
+ "@aopslabs/domain-host-plugin-chatv3": "0.4.1",
14
15
  "@aopslabs/domain-host-plugin-docman": "0.3.2",
15
- "@aopslabs/domain-host-plugin-projectman": "0.3.2",
16
+ "@aopslabs/domain-host-plugin-projectman": "0.3.3",
16
17
  "@aopslabs/domain-host-plugin-sys": "0.3.1",
17
18
  "@aopslabs/domain-kit-agentspace": "0.2.2",
18
- "@aopslabs/domain-kit-chatv3": "0.4.0",
19
+ "@aopslabs/domain-kit-chatv3": "0.4.1",
19
20
  "@aopslabs/domain-kit-docman": "0.3.0",
20
- "@aopslabs/domain-kit-projectman": "0.3.2",
21
+ "@aopslabs/domain-kit-projectman": "0.3.3",
21
22
  "@aopslabs/domain-kit-sys": "0.3.1",
22
- "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.0",
23
+ "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.1",
23
24
  "@aopslabs/domain-pg-bootstrap-docman": "0.2.0",
24
25
  "@aopslabs/domain-pg-bootstrap-projectman": "0.2.0",
25
26
  "@aopslabs/domain-pg-bootstrap-sys": "0.2.0",
@@ -41,26 +42,27 @@
41
42
  "zod": "4.4.3"
42
43
  },
43
44
  "overrides": {
45
+ "@aopslabs/aops-agent-runtime": "0.1.0",
44
46
  "@aopslabs/aops-error-catalog": "0.2.1",
45
47
  "@aopslabs/aops-host-registration": "0.2.1",
46
48
  "@aopslabs/aops-pg-bootstrap": "0.2.3",
47
49
  "@aopslabs/domain-core-docman": "0.2.0",
48
50
  "@aopslabs/domain-dm-agentspace": "0.2.0",
49
- "@aopslabs/domain-dm-chatv3": "0.4.0",
51
+ "@aopslabs/domain-dm-chatv3": "0.4.1",
50
52
  "@aopslabs/domain-dm-docman": "0.2.1",
51
- "@aopslabs/domain-dm-projectman": "0.2.0",
53
+ "@aopslabs/domain-dm-projectman": "0.3.3",
52
54
  "@aopslabs/domain-dm-sys": "0.2.0",
53
55
  "@aopslabs/domain-host-plugin-agentspace": "0.3.1",
54
- "@aopslabs/domain-host-plugin-chatv3": "0.4.0",
56
+ "@aopslabs/domain-host-plugin-chatv3": "0.4.1",
55
57
  "@aopslabs/domain-host-plugin-docman": "0.3.2",
56
- "@aopslabs/domain-host-plugin-projectman": "0.3.2",
58
+ "@aopslabs/domain-host-plugin-projectman": "0.3.3",
57
59
  "@aopslabs/domain-host-plugin-sys": "0.3.1",
58
60
  "@aopslabs/domain-kit-agentspace": "0.2.2",
59
- "@aopslabs/domain-kit-chatv3": "0.4.0",
61
+ "@aopslabs/domain-kit-chatv3": "0.4.1",
60
62
  "@aopslabs/domain-kit-docman": "0.3.0",
61
- "@aopslabs/domain-kit-projectman": "0.3.2",
63
+ "@aopslabs/domain-kit-projectman": "0.3.3",
62
64
  "@aopslabs/domain-kit-sys": "0.3.1",
63
- "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.0",
65
+ "@aopslabs/domain-pg-bootstrap-chatv3": "0.4.1",
64
66
  "@aopslabs/domain-pg-bootstrap-docman": "0.2.0",
65
67
  "@aopslabs/domain-pg-bootstrap-projectman": "0.2.0",
66
68
  "@aopslabs/domain-pg-bootstrap-sys": "0.2.0",
@@ -0,0 +1,329 @@
1
+ import { randomBytes } from 'node:crypto'
2
+ import {
3
+ AGENT_RUNTIME_WAKE_MAX_PROMPT_BYTES,
4
+ resolveAgentWakeTarget,
5
+ } from '@aopslabs/aops-agent-runtime'
6
+
7
+ export const COMMUNITY_AGENT_WAKE_CAPABILITY_PATH = '/_aops/agent-wake/capability'
8
+ export const COMMUNITY_AGENT_WAKE_ACTION_PATH = '/_aops/agent-wake'
9
+ export const COMMUNITY_AGENT_WAKE_GRANT_HEADER = 'x-aops-agent-wake-grant'
10
+
11
+ const MAX_BODY_BYTES = AGENT_RUNTIME_WAKE_MAX_PROMPT_BYTES + 16_384
12
+ export const COMMUNITY_AGENT_WAKE_PROBE_TIMEOUT_MS = 1_500
13
+ export const COMMUNITY_AGENT_WAKE_GRANT_TTL_MS = 30_000
14
+ const MAX_LIVE_GRANTS = 256
15
+
16
+ function jsonResponse(res, status, payload, securityHeaders = {}) {
17
+ res.writeHead(status, {
18
+ ...securityHeaders,
19
+ 'content-type': 'application/json; charset=utf-8',
20
+ 'cache-control': 'no-store',
21
+ })
22
+ res.end(`${JSON.stringify(payload)}\n`)
23
+ }
24
+
25
+ function token() {
26
+ return randomBytes(32).toString('base64url')
27
+ }
28
+
29
+ export function createCommunityAgentWakeContext({
30
+ wake,
31
+ verifyAdmission,
32
+ registryPath,
33
+ securityHeaders = {},
34
+ now = Date.now,
35
+ grantTtlMs = COMMUNITY_AGENT_WAKE_GRANT_TTL_MS,
36
+ }) {
37
+ if (typeof wake !== 'function') throw new Error('community_agent_wake_adapter_required')
38
+ if (typeof verifyAdmission !== 'function') throw new Error('community_agent_wake_admission_verifier_required')
39
+ if (typeof now !== 'function') throw new Error('community_agent_wake_clock_required')
40
+ if (!Number.isInteger(grantTtlMs) || grantTtlMs < 1 || grantTtlMs > 60_000) {
41
+ throw new Error('community_agent_wake_grant_ttl_invalid')
42
+ }
43
+ return Object.freeze({
44
+ wake,
45
+ verifyAdmission,
46
+ registryPath,
47
+ securityHeaders,
48
+ now,
49
+ grantTtlMs,
50
+ grants: new Map(),
51
+ })
52
+ }
53
+
54
+ function admissionFrom(input) {
55
+ return {
56
+ channelId: typeof input.channelId === 'string' ? input.channelId.trim() : '',
57
+ memberId: typeof input.memberId === 'string' ? input.memberId.trim() : '',
58
+ handle: typeof input.handle === 'string' ? input.handle.trim() : '',
59
+ actorKind: typeof input.actorKind === 'string' ? input.actorKind.trim().toLowerCase() : '',
60
+ status: typeof input.status === 'string' ? input.status.trim().toLowerCase() : '',
61
+ }
62
+ }
63
+
64
+ async function inspectCapability(admission, context) {
65
+ if (admission.actorKind !== 'agent') return { enabled: false, reason: 'not_agent', hostMatched: false }
66
+ if (admission.status !== 'active') return { enabled: false, reason: 'member_inactive', hostMatched: false }
67
+ let resolved
68
+ try {
69
+ resolved = resolveAgentWakeTarget(admission.channelId, admission.memberId, context.registryPath)
70
+ } catch (error) {
71
+ const code = error instanceof Error ? error.message : String(error)
72
+ return { enabled: false, reason: code.startsWith('agent_wake_registry_') ? code : 'invalid_target', hostMatched: false }
73
+ }
74
+ if (!resolved.entry) return { enabled: false, reason: 'not_registered', hostMatched: false }
75
+ if (resolved.entry.handle && resolved.entry.handle !== admission.handle) {
76
+ return { enabled: false, reason: 'identity_mismatch', hostMatched: resolved.hostMatched }
77
+ }
78
+ if (!resolved.hostMatched) {
79
+ return {
80
+ enabled: false,
81
+ reason: 'host_mismatch',
82
+ hostMatched: false,
83
+ runtime: resolved.entry.runtime,
84
+ targetSessionIdHash: resolved.entry.targetSessionIdHash,
85
+ lastVerifiedAt: resolved.entry.lastVerifiedAt,
86
+ }
87
+ }
88
+ const probe = await context.wake({
89
+ runtime: resolved.entry.runtime,
90
+ transport: 'desktop-ipc',
91
+ sessionId: resolved.entry.targetSessionId,
92
+ prompt: '',
93
+ dryRun: true,
94
+ handshakeTimeoutMs: COMMUNITY_AGENT_WAKE_PROBE_TIMEOUT_MS,
95
+ })
96
+ if (!probe?.envelope?.ok) {
97
+ return {
98
+ enabled: false,
99
+ reason: `dry_run_failed:${probe?.envelope?.code ?? 'unknown'}`,
100
+ hostMatched: true,
101
+ runtime: resolved.entry.runtime,
102
+ targetSessionIdHash: resolved.entry.targetSessionIdHash,
103
+ lastVerifiedAt: resolved.entry.lastVerifiedAt,
104
+ }
105
+ }
106
+ return {
107
+ enabled: true,
108
+ reason: 'ready',
109
+ hostMatched: true,
110
+ runtime: resolved.entry.runtime,
111
+ targetSessionIdHash: resolved.entry.targetSessionIdHash,
112
+ lastVerifiedAt: resolved.entry.lastVerifiedAt,
113
+ entry: resolved.entry,
114
+ }
115
+ }
116
+
117
+ async function readJsonBody(req) {
118
+ const contentType = String(req.headers['content-type'] ?? '').split(';', 1)[0].trim().toLowerCase()
119
+ if (contentType !== 'application/json') throw new Error('content_type_json_required')
120
+ const contentLength = Number(req.headers['content-length'] ?? 0)
121
+ if (Number.isFinite(contentLength) && contentLength > MAX_BODY_BYTES) throw new Error('request_body_too_large')
122
+ const chunks = []
123
+ let bytes = 0
124
+ for await (const chunk of req) {
125
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
126
+ bytes += buffer.length
127
+ if (bytes > MAX_BODY_BYTES) throw new Error('request_body_too_large')
128
+ chunks.push(buffer)
129
+ }
130
+ const parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'))
131
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('request_body_invalid')
132
+ return parsed
133
+ }
134
+
135
+ function publicCapability(capability) {
136
+ const { entry: _entry, ...safe } = capability
137
+ return safe
138
+ }
139
+
140
+ function admissionKey(admission) {
141
+ return [
142
+ admission.channelId,
143
+ admission.memberId,
144
+ admission.handle,
145
+ admission.actorKind,
146
+ admission.status,
147
+ ].join('\u0000')
148
+ }
149
+
150
+ function cleanupExpiredGrants(context) {
151
+ const now = context.now()
152
+ for (const [grantToken, grant] of context.grants) {
153
+ if (grant.expiresAt <= now) context.grants.delete(grantToken)
154
+ }
155
+ while (context.grants.size >= MAX_LIVE_GRANTS) {
156
+ const oldest = context.grants.keys().next().value
157
+ if (!oldest) break
158
+ context.grants.delete(oldest)
159
+ }
160
+ }
161
+
162
+ function issueGrant(admission, verifiedCaller, context) {
163
+ cleanupExpiredGrants(context)
164
+ const value = token()
165
+ const expiresAt = context.now() + context.grantTtlMs
166
+ context.grants.set(value, {
167
+ principalId: verifiedCaller.principalId,
168
+ callerMemberId: verifiedCaller.callerMemberId,
169
+ callerChannelId: verifiedCaller.callerChannelId,
170
+ admissionKey: admissionKey(admission),
171
+ expiresAt,
172
+ })
173
+ return { value, expiresAt }
174
+ }
175
+
176
+ function consumeGrant(req, admission, verifiedCaller, context) {
177
+ const value = req.headers[COMMUNITY_AGENT_WAKE_GRANT_HEADER]
178
+ if (typeof value !== 'string' || !value) return 'agent_wake_grant_invalid'
179
+ const grant = context.grants.get(value)
180
+ if (!grant) return 'agent_wake_grant_invalid'
181
+ context.grants.delete(value)
182
+ if (grant.expiresAt <= context.now()) return 'agent_wake_grant_expired'
183
+ if (grant.principalId !== verifiedCaller.principalId) return 'agent_wake_grant_principal_mismatch'
184
+ if (
185
+ grant.callerMemberId !== verifiedCaller.callerMemberId
186
+ || grant.callerChannelId !== verifiedCaller.callerChannelId
187
+ ) return 'agent_wake_grant_caller_mismatch'
188
+ if (grant.admissionKey !== admissionKey(admission)) return 'agent_wake_grant_scope_mismatch'
189
+ return null
190
+ }
191
+
192
+ const SAFE_ADMISSION_ERRORS = new Set([
193
+ 'agent_wake_member_token_required',
194
+ 'agent_wake_member_token_invalid_format',
195
+ 'agent_wake_member_token_unknown',
196
+ 'agent_wake_member_token_mismatch',
197
+ 'agent_wake_member_not_active',
198
+ 'agent_wake_member_cross_channel',
199
+ 'agent_wake_target_not_active',
200
+ 'agent_wake_admission_required',
201
+ ])
202
+
203
+ function verifiedTargetAdmission(selector, verified) {
204
+ const member = verified?.targetMember
205
+ const memberId = typeof member?.id === 'string' ? member.id.trim() : ''
206
+ const channelId = typeof member?.channelId === 'string' ? member.channelId.trim() : ''
207
+ if (!memberId || memberId !== selector.memberId || channelId !== selector.channelId) {
208
+ throw new Error('agent_wake_target_not_active')
209
+ }
210
+ return admissionFrom({
211
+ channelId,
212
+ memberId,
213
+ handle: member.handle,
214
+ actorKind: member.actorKind,
215
+ status: member.status,
216
+ })
217
+ }
218
+
219
+ async function verifiedMemberAdmission(req, browser, selector, context) {
220
+ if (!browser.browserOriginPresent) return { error: 'same_origin_required' }
221
+ try {
222
+ const verified = await context.verifyAdmission(req, {
223
+ channelId: selector.channelId,
224
+ targetMemberId: selector.memberId,
225
+ })
226
+ const principalId = typeof verified?.principalId === 'string' ? verified.principalId.trim() : ''
227
+ const callerMemberId = typeof verified?.callerMemberId === 'string' ? verified.callerMemberId.trim() : ''
228
+ const callerChannelId = typeof verified?.callerChannelId === 'string' ? verified.callerChannelId.trim() : ''
229
+ if (!principalId || !callerMemberId || !callerChannelId) return { error: 'agent_wake_admission_required' }
230
+ if (callerChannelId !== selector.channelId) return { error: 'agent_wake_member_cross_channel' }
231
+ return {
232
+ principalId,
233
+ callerMemberId,
234
+ callerChannelId,
235
+ targetAdmission: verifiedTargetAdmission(selector, verified),
236
+ }
237
+ } catch (error) {
238
+ const code = error instanceof Error ? error.message : ''
239
+ return { error: SAFE_ADMISSION_ERRORS.has(code) ? code : 'agent_wake_admission_required' }
240
+ }
241
+ }
242
+
243
+ export async function handleCommunityAgentWakeRequest(req, res, url, browser, context) {
244
+ if (url.pathname !== COMMUNITY_AGENT_WAKE_CAPABILITY_PATH && url.pathname !== COMMUNITY_AGENT_WAKE_ACTION_PATH) return false
245
+ if (url.pathname === COMMUNITY_AGENT_WAKE_CAPABILITY_PATH) {
246
+ if (req.method !== 'POST') {
247
+ res.writeHead(405, { allow: 'POST' })
248
+ res.end()
249
+ return true
250
+ }
251
+ let body
252
+ try {
253
+ body = await readJsonBody(req)
254
+ } catch (error) {
255
+ jsonResponse(res, 400, { ok: false, code: error instanceof Error ? error.message : 'request_body_invalid' }, context.securityHeaders)
256
+ return true
257
+ }
258
+ const selector = admissionFrom(body)
259
+ const verified = await verifiedMemberAdmission(req, browser, selector, context)
260
+ if (verified.error) {
261
+ jsonResponse(res, 403, { ok: false, code: verified.error }, context.securityHeaders)
262
+ return true
263
+ }
264
+ const admission = verified.targetAdmission
265
+ const capability = await inspectCapability(admission, context)
266
+ jsonResponse(res, 200, {
267
+ ok: true,
268
+ capability: publicCapability(capability),
269
+ grant: capability.enabled ? issueGrant(admission, verified, context) : null,
270
+ }, context.securityHeaders)
271
+ return true
272
+ }
273
+ if (req.method !== 'POST') {
274
+ res.writeHead(405, { allow: 'POST' })
275
+ res.end()
276
+ return true
277
+ }
278
+ let body
279
+ try {
280
+ body = await readJsonBody(req)
281
+ } catch (error) {
282
+ jsonResponse(res, 400, { ok: false, code: error instanceof Error ? error.message : 'request_body_invalid' }, context.securityHeaders)
283
+ return true
284
+ }
285
+ const prompt = typeof body.prompt === 'string' ? body.prompt : ''
286
+ if (!prompt.trim() || Buffer.byteLength(prompt, 'utf8') > AGENT_RUNTIME_WAKE_MAX_PROMPT_BYTES) {
287
+ jsonResponse(res, 400, { ok: false, code: 'invalid_prompt' }, context.securityHeaders)
288
+ return true
289
+ }
290
+ const selector = admissionFrom(body)
291
+ const verified = await verifiedMemberAdmission(req, browser, selector, context)
292
+ if (verified.error) {
293
+ jsonResponse(res, 403, { ok: false, code: verified.error }, context.securityHeaders)
294
+ return true
295
+ }
296
+ const admission = verified.targetAdmission
297
+ const grantError = consumeGrant(req, admission, verified, context)
298
+ if (grantError) {
299
+ jsonResponse(res, 403, { ok: false, code: grantError }, context.securityHeaders)
300
+ return true
301
+ }
302
+ const capability = await inspectCapability(admission, context)
303
+ if (!capability.enabled || !capability.entry) {
304
+ jsonResponse(res, 409, { ok: false, code: capability.reason, capability: publicCapability(capability) }, context.securityHeaders)
305
+ return true
306
+ }
307
+ const result = await context.wake({
308
+ runtime: capability.entry.runtime,
309
+ transport: 'desktop-ipc',
310
+ sessionId: capability.entry.targetSessionId,
311
+ prompt,
312
+ })
313
+ if (!result?.envelope?.ok) {
314
+ jsonResponse(res, result?.envelope?.retryable ? 503 : 409, {
315
+ ok: false,
316
+ code: result?.envelope?.code ?? 'wake_failed',
317
+ targetSessionIdHash: capability.entry.targetSessionIdHash,
318
+ }, context.securityHeaders)
319
+ return true
320
+ }
321
+ jsonResponse(res, 200, {
322
+ ok: true,
323
+ code: 'wake_sent',
324
+ runtime: capability.entry.runtime,
325
+ targetSessionIdHash: capability.entry.targetSessionIdHash,
326
+ turnId: result.envelope.turnId ?? null,
327
+ }, context.securityHeaders)
328
+ return true
329
+ }