shennian 0.4.11 → 0.4.14
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/dist/publish-build-manifest.json +183 -53
- package/dist/src/agents/acp/adapter.d.ts +78 -0
- package/dist/src/agents/acp/adapter.js +3 -0
- package/dist/src/agents/acp/auth-state.d.ts +3 -0
- package/dist/src/agents/acp/auth-state.js +1 -0
- package/dist/src/agents/acp/auth.d.ts +7 -0
- package/dist/src/agents/acp/auth.js +1 -0
- package/dist/src/agents/acp/capability-cache.d.ts +14 -0
- package/dist/src/agents/acp/capability-cache.js +2 -0
- package/dist/src/agents/acp/catalog.d.ts +11 -0
- package/dist/src/agents/acp/catalog.js +2 -0
- package/dist/src/agents/acp/client-services.d.ts +32 -0
- package/dist/src/agents/acp/client-services.js +3 -0
- package/dist/src/agents/acp/discovery.d.ts +9 -0
- package/dist/src/agents/acp/discovery.js +1 -0
- package/dist/src/agents/acp/events.d.ts +4 -0
- package/dist/src/agents/acp/events.js +3 -0
- package/dist/src/agents/acp/manifests.d.ts +63 -0
- package/dist/src/agents/acp/manifests.js +2 -0
- package/dist/src/agents/acp/metrics.d.ts +24 -0
- package/dist/src/agents/acp/metrics.js +1 -0
- package/dist/src/agents/acp/package-commands.d.ts +4 -0
- package/dist/src/agents/acp/package-commands.js +1 -0
- package/dist/src/agents/acp/process-client.d.ts +39 -0
- package/dist/src/agents/acp/process-client.js +1 -0
- package/dist/src/agents/acp/process-tree.d.ts +2 -0
- package/dist/src/agents/acp/process-tree.js +1 -0
- package/dist/src/agents/acp/types.d.ts +31 -0
- package/dist/src/agents/acp/types.js +1 -0
- package/dist/src/agents/acp/watcher.d.ts +22 -0
- package/dist/src/agents/acp/watcher.js +1 -0
- package/dist/src/agents/adapter.d.ts +96 -2
- package/dist/src/agents/adapter.js +1 -1
- package/dist/src/agents/claude.d.ts +14 -0
- package/dist/src/agents/claude.js +5 -5
- package/dist/src/agents/codex.d.ts +6 -0
- package/dist/src/agents/codex.js +1 -1
- package/dist/src/agents/command-spec.d.ts +5 -0
- package/dist/src/agents/command-spec.js +3 -3
- package/dist/src/agents/cursor.d.ts +6 -0
- package/dist/src/agents/cursor.js +1 -1
- package/dist/src/agents/custom-recovery-conformance.d.ts +2 -0
- package/dist/src/agents/custom-recovery-conformance.js +2 -0
- package/dist/src/agents/custom.d.ts +9 -0
- package/dist/src/agents/custom.js +4 -4
- package/dist/src/agents/detect.d.ts +11 -2
- package/dist/src/agents/detect.js +1 -1
- package/dist/src/agents/gemini.d.ts +6 -0
- package/dist/src/agents/gemini.js +1 -1
- package/dist/src/agents/manager.d.ts +2 -0
- package/dist/src/agents/manager.js +5 -5
- package/dist/src/agents/model-registry/service.js +1 -1
- package/dist/src/agents/opencode.d.ts +6 -0
- package/dist/src/agents/opencode.js +1 -1
- package/dist/src/agents/pi-coding-agent.d.ts +6 -0
- package/dist/src/agents/pi-coding-agent.js +4 -4
- package/dist/src/agents/workbuddy.d.ts +6 -0
- package/dist/src/agents/workbuddy.js +2 -2
- package/dist/src/commands/agent.d.ts +2 -0
- package/dist/src/commands/agent.js +2 -0
- package/dist/src/commands/daemon.d.ts +6 -2
- package/dist/src/commands/daemon.js +19 -23
- package/dist/src/commands/pair.js +10 -10
- package/dist/src/commands/upgrade.d.ts +7 -1
- package/dist/src/commands/upgrade.js +1 -1
- package/dist/src/config/index.d.ts +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/daemon-ipc/control.d.ts +16 -0
- package/dist/src/daemon-ipc/control.js +1 -0
- package/dist/src/index.js +3 -3
- package/dist/src/log-reporter.d.ts +23 -0
- package/dist/src/log-reporter.js +1 -1
- package/dist/src/relay/client.d.ts +1 -0
- package/dist/src/relay/client.js +1 -1
- package/dist/src/session/handlers/agents.d.ts +1 -0
- package/dist/src/session/handlers/agents.js +1 -1
- package/dist/src/session/handlers/chat.d.ts +3 -0
- package/dist/src/session/handlers/chat.js +2 -2
- package/dist/src/session/manager.d.ts +20 -2
- package/dist/src/session/manager.js +3 -1
- package/dist/src/session/queue.js +2 -2
- package/dist/src/session/run-recovery/barrier.d.ts +12 -0
- package/dist/src/session/run-recovery/barrier.js +1 -0
- package/dist/src/session/run-recovery/coordinator.d.ts +32 -0
- package/dist/src/session/run-recovery/coordinator.js +1 -0
- package/dist/src/session/run-recovery/journal.d.ts +30 -0
- package/dist/src/session/run-recovery/journal.js +2 -0
- package/dist/src/session/run-recovery/schema.d.ts +43 -0
- package/dist/src/session/run-recovery/schema.js +1 -0
- package/dist/src/session/types.d.ts +10 -0
- package/dist/src/upgrade/engine.d.ts +6 -5
- package/dist/src/upgrade/engine.js +2 -2
- package/dist/src/upgrade/scheduler.d.ts +14 -0
- package/dist/src/upgrade/scheduler.js +1 -1
- package/dist/src/upgrade/updater-bootstrap.d.ts +12 -0
- package/dist/src/upgrade/updater-bootstrap.js +2 -0
- package/dist/src/upgrade/updater-launcher.d.ts +28 -0
- package/dist/src/upgrade/updater-launcher.js +3 -0
- package/dist/src/upgrade/updater-protocol.d.ts +37 -0
- package/dist/src/upgrade/updater-protocol.js +1 -0
- package/dist/src/upgrade/updater-worker.d.ts +11 -0
- package/dist/src/upgrade/updater-worker.js +2 -0
- package/node_modules/@shennian/wire/dist/events.d.ts +31 -0
- package/node_modules/@shennian/wire/dist/index.d.ts +1 -0
- package/node_modules/@shennian/wire/dist/index.js +1 -0
- package/node_modules/@shennian/wire/dist/machine.d.ts +49 -1
- package/node_modules/@shennian/wire/dist/message-payload.d.ts +1 -0
- package/node_modules/@shennian/wire/dist/message-payload.js +4 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
- package/node_modules/@shennian/wire/dist/relay-connectivity.d.ts +30 -0
- package/node_modules/@shennian/wire/dist/relay-connectivity.js +29 -0
- package/node_modules/@shennian/wire/dist/session-sync.d.ts +2 -2
- package/node_modules/@shennian/wire/dist/session-sync.js +2 -0
- package/node_modules/@shennian/wire/dist/session.d.ts +84 -1
- package/node_modules/@shennian/wire/dist/session.js +5 -1
- package/package.json +5 -3
- package/dist/native/macos-background-client/Shennian.app/Contents/CodeResources +0 -0
- package/dist/native/macos-background-client/Shennian.app/Contents/Info.plist +0 -17
- package/dist/native/macos-background-client/Shennian.app/Contents/MacOS/ShennianClientLauncher +0 -0
- package/dist/native/macos-background-client/Shennian.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -2
- package/dist/native/macos-background-client/Shennian.app/Contents/Resources/zh-Hans.lproj/InfoPlist.strings +0 -2
- package/dist/native/macos-background-client/Shennian.app/Contents/_CodeSignature/CodeResources +0 -153
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 178,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -14,10 +14,85 @@
|
|
|
14
14
|
"beforeBytes": 9854,
|
|
15
15
|
"afterBytes": 4529
|
|
16
16
|
},
|
|
17
|
+
{
|
|
18
|
+
"file": "src/agents/acp/adapter.js",
|
|
19
|
+
"beforeBytes": 24351,
|
|
20
|
+
"afterBytes": 12664
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"file": "src/agents/acp/auth-state.js",
|
|
24
|
+
"beforeBytes": 297,
|
|
25
|
+
"afterBytes": 138
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"file": "src/agents/acp/auth.js",
|
|
29
|
+
"beforeBytes": 1112,
|
|
30
|
+
"afterBytes": 651
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"file": "src/agents/acp/capability-cache.js",
|
|
34
|
+
"beforeBytes": 2374,
|
|
35
|
+
"afterBytes": 1411
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"file": "src/agents/acp/catalog.js",
|
|
39
|
+
"beforeBytes": 5188,
|
|
40
|
+
"afterBytes": 2657
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"file": "src/agents/acp/client-services.js",
|
|
44
|
+
"beforeBytes": 5088,
|
|
45
|
+
"afterBytes": 2769
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"file": "src/agents/acp/discovery.js",
|
|
49
|
+
"beforeBytes": 9047,
|
|
50
|
+
"afterBytes": 4281
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"file": "src/agents/acp/events.js",
|
|
54
|
+
"beforeBytes": 3018,
|
|
55
|
+
"afterBytes": 1463
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"file": "src/agents/acp/manifests.js",
|
|
59
|
+
"beforeBytes": 4036,
|
|
60
|
+
"afterBytes": 2299
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"file": "src/agents/acp/metrics.js",
|
|
64
|
+
"beforeBytes": 1229,
|
|
65
|
+
"afterBytes": 807
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"file": "src/agents/acp/package-commands.js",
|
|
69
|
+
"beforeBytes": 3450,
|
|
70
|
+
"afterBytes": 1693
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"file": "src/agents/acp/process-client.js",
|
|
74
|
+
"beforeBytes": 7214,
|
|
75
|
+
"afterBytes": 4379
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"file": "src/agents/acp/process-tree.js",
|
|
79
|
+
"beforeBytes": 698,
|
|
80
|
+
"afterBytes": 371
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"file": "src/agents/acp/types.js",
|
|
84
|
+
"beforeBytes": 148,
|
|
85
|
+
"afterBytes": 58
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"file": "src/agents/acp/watcher.js",
|
|
89
|
+
"beforeBytes": 2743,
|
|
90
|
+
"afterBytes": 1533
|
|
91
|
+
},
|
|
17
92
|
{
|
|
18
93
|
"file": "src/agents/adapter.js",
|
|
19
|
-
"beforeBytes":
|
|
20
|
-
"afterBytes":
|
|
94
|
+
"beforeBytes": 3557,
|
|
95
|
+
"afterBytes": 1913
|
|
21
96
|
},
|
|
22
97
|
{
|
|
23
98
|
"file": "src/agents/claude-managed-permissions.js",
|
|
@@ -26,8 +101,8 @@
|
|
|
26
101
|
},
|
|
27
102
|
{
|
|
28
103
|
"file": "src/agents/claude.js",
|
|
29
|
-
"beforeBytes":
|
|
30
|
-
"afterBytes":
|
|
104
|
+
"beforeBytes": 17063,
|
|
105
|
+
"afterBytes": 8544
|
|
31
106
|
},
|
|
32
107
|
{
|
|
33
108
|
"file": "src/agents/codex-managed-permissions.js",
|
|
@@ -46,13 +121,13 @@
|
|
|
46
121
|
},
|
|
47
122
|
{
|
|
48
123
|
"file": "src/agents/codex.js",
|
|
49
|
-
"beforeBytes":
|
|
50
|
-
"afterBytes":
|
|
124
|
+
"beforeBytes": 66278,
|
|
125
|
+
"afterBytes": 33907
|
|
51
126
|
},
|
|
52
127
|
{
|
|
53
128
|
"file": "src/agents/command-spec.js",
|
|
54
|
-
"beforeBytes":
|
|
55
|
-
"afterBytes":
|
|
129
|
+
"beforeBytes": 18239,
|
|
130
|
+
"afterBytes": 8225
|
|
56
131
|
},
|
|
57
132
|
{
|
|
58
133
|
"file": "src/agents/config-status.js",
|
|
@@ -66,23 +141,28 @@
|
|
|
66
141
|
},
|
|
67
142
|
{
|
|
68
143
|
"file": "src/agents/cursor.js",
|
|
69
|
-
"beforeBytes":
|
|
70
|
-
"afterBytes":
|
|
144
|
+
"beforeBytes": 12192,
|
|
145
|
+
"afterBytes": 5890
|
|
71
146
|
},
|
|
72
147
|
{
|
|
73
148
|
"file": "src/agents/custom-managed-runtime.js",
|
|
74
149
|
"beforeBytes": 9992,
|
|
75
150
|
"afterBytes": 5280
|
|
76
151
|
},
|
|
152
|
+
{
|
|
153
|
+
"file": "src/agents/custom-recovery-conformance.js",
|
|
154
|
+
"beforeBytes": 1998,
|
|
155
|
+
"afterBytes": 1084
|
|
156
|
+
},
|
|
77
157
|
{
|
|
78
158
|
"file": "src/agents/custom.js",
|
|
79
|
-
"beforeBytes":
|
|
80
|
-
"afterBytes":
|
|
159
|
+
"beforeBytes": 17754,
|
|
160
|
+
"afterBytes": 9426
|
|
81
161
|
},
|
|
82
162
|
{
|
|
83
163
|
"file": "src/agents/detect.js",
|
|
84
|
-
"beforeBytes":
|
|
85
|
-
"afterBytes":
|
|
164
|
+
"beforeBytes": 3496,
|
|
165
|
+
"afterBytes": 1591
|
|
86
166
|
},
|
|
87
167
|
{
|
|
88
168
|
"file": "src/agents/external-channel-instructions.js",
|
|
@@ -91,13 +171,13 @@
|
|
|
91
171
|
},
|
|
92
172
|
{
|
|
93
173
|
"file": "src/agents/gemini.js",
|
|
94
|
-
"beforeBytes":
|
|
95
|
-
"afterBytes":
|
|
174
|
+
"beforeBytes": 6353,
|
|
175
|
+
"afterBytes": 3309
|
|
96
176
|
},
|
|
97
177
|
{
|
|
98
178
|
"file": "src/agents/manager.js",
|
|
99
|
-
"beforeBytes":
|
|
100
|
-
"afterBytes":
|
|
179
|
+
"beforeBytes": 10984,
|
|
180
|
+
"afterBytes": 5949
|
|
101
181
|
},
|
|
102
182
|
{
|
|
103
183
|
"file": "src/agents/model-registry/cache.js",
|
|
@@ -121,8 +201,8 @@
|
|
|
121
201
|
},
|
|
122
202
|
{
|
|
123
203
|
"file": "src/agents/model-registry/service.js",
|
|
124
|
-
"beforeBytes":
|
|
125
|
-
"afterBytes":
|
|
204
|
+
"beforeBytes": 5605,
|
|
205
|
+
"afterBytes": 2531
|
|
126
206
|
},
|
|
127
207
|
{
|
|
128
208
|
"file": "src/agents/model-registry/types.js",
|
|
@@ -151,8 +231,8 @@
|
|
|
151
231
|
},
|
|
152
232
|
{
|
|
153
233
|
"file": "src/agents/opencode.js",
|
|
154
|
-
"beforeBytes":
|
|
155
|
-
"afterBytes":
|
|
234
|
+
"beforeBytes": 11451,
|
|
235
|
+
"afterBytes": 6348
|
|
156
236
|
},
|
|
157
237
|
{
|
|
158
238
|
"file": "src/agents/pi-coding-agent-managed-permissions.js",
|
|
@@ -161,8 +241,8 @@
|
|
|
161
241
|
},
|
|
162
242
|
{
|
|
163
243
|
"file": "src/agents/pi-coding-agent.js",
|
|
164
|
-
"beforeBytes":
|
|
165
|
-
"afterBytes":
|
|
244
|
+
"beforeBytes": 24381,
|
|
245
|
+
"afterBytes": 13151
|
|
166
246
|
},
|
|
167
247
|
{
|
|
168
248
|
"file": "src/agents/pi-managed-extension.js",
|
|
@@ -201,8 +281,13 @@
|
|
|
201
281
|
},
|
|
202
282
|
{
|
|
203
283
|
"file": "src/agents/workbuddy.js",
|
|
204
|
-
"beforeBytes":
|
|
205
|
-
"afterBytes":
|
|
284
|
+
"beforeBytes": 18228,
|
|
285
|
+
"afterBytes": 9483
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"file": "src/commands/agent.js",
|
|
289
|
+
"beforeBytes": 5136,
|
|
290
|
+
"afterBytes": 2826
|
|
206
291
|
},
|
|
207
292
|
{
|
|
208
293
|
"file": "src/commands/daemon-process.js",
|
|
@@ -221,8 +306,8 @@
|
|
|
221
306
|
},
|
|
222
307
|
{
|
|
223
308
|
"file": "src/commands/daemon.js",
|
|
224
|
-
"beforeBytes":
|
|
225
|
-
"afterBytes":
|
|
309
|
+
"beforeBytes": 44904,
|
|
310
|
+
"afterBytes": 21716
|
|
226
311
|
},
|
|
227
312
|
{
|
|
228
313
|
"file": "src/commands/integration.js",
|
|
@@ -256,8 +341,8 @@
|
|
|
256
341
|
},
|
|
257
342
|
{
|
|
258
343
|
"file": "src/commands/pair.js",
|
|
259
|
-
"beforeBytes":
|
|
260
|
-
"afterBytes":
|
|
344
|
+
"beforeBytes": 16528,
|
|
345
|
+
"afterBytes": 9150
|
|
261
346
|
},
|
|
262
347
|
{
|
|
263
348
|
"file": "src/commands/room.js",
|
|
@@ -276,19 +361,24 @@
|
|
|
276
361
|
},
|
|
277
362
|
{
|
|
278
363
|
"file": "src/commands/upgrade.js",
|
|
279
|
-
"beforeBytes":
|
|
280
|
-
"afterBytes":
|
|
364
|
+
"beforeBytes": 9789,
|
|
365
|
+
"afterBytes": 5176
|
|
281
366
|
},
|
|
282
367
|
{
|
|
283
368
|
"file": "src/config/index.js",
|
|
284
|
-
"beforeBytes":
|
|
285
|
-
"afterBytes":
|
|
369
|
+
"beforeBytes": 2801,
|
|
370
|
+
"afterBytes": 1662
|
|
286
371
|
},
|
|
287
372
|
{
|
|
288
373
|
"file": "src/daemon-ipc/client.js",
|
|
289
374
|
"beforeBytes": 2754,
|
|
290
375
|
"afterBytes": 1393
|
|
291
376
|
},
|
|
377
|
+
{
|
|
378
|
+
"file": "src/daemon-ipc/control.js",
|
|
379
|
+
"beforeBytes": 3975,
|
|
380
|
+
"afterBytes": 2196
|
|
381
|
+
},
|
|
292
382
|
{
|
|
293
383
|
"file": "src/daemon-ipc/json.js",
|
|
294
384
|
"beforeBytes": 11,
|
|
@@ -346,8 +436,8 @@
|
|
|
346
436
|
},
|
|
347
437
|
{
|
|
348
438
|
"file": "src/index.js",
|
|
349
|
-
"beforeBytes":
|
|
350
|
-
"afterBytes":
|
|
439
|
+
"beforeBytes": 35733,
|
|
440
|
+
"afterBytes": 17671
|
|
351
441
|
},
|
|
352
442
|
{
|
|
353
443
|
"file": "src/log-redaction.js",
|
|
@@ -356,8 +446,8 @@
|
|
|
356
446
|
},
|
|
357
447
|
{
|
|
358
448
|
"file": "src/log-reporter.js",
|
|
359
|
-
"beforeBytes":
|
|
360
|
-
"afterBytes":
|
|
449
|
+
"beforeBytes": 2022,
|
|
450
|
+
"afterBytes": 970
|
|
361
451
|
},
|
|
362
452
|
{
|
|
363
453
|
"file": "src/manager/prompt.js",
|
|
@@ -481,8 +571,8 @@
|
|
|
481
571
|
},
|
|
482
572
|
{
|
|
483
573
|
"file": "src/relay/client.js",
|
|
484
|
-
"beforeBytes":
|
|
485
|
-
"afterBytes":
|
|
574
|
+
"beforeBytes": 15242,
|
|
575
|
+
"afterBytes": 7525
|
|
486
576
|
},
|
|
487
577
|
{
|
|
488
578
|
"file": "src/room/activation-audit.js",
|
|
@@ -641,13 +731,13 @@
|
|
|
641
731
|
},
|
|
642
732
|
{
|
|
643
733
|
"file": "src/session/handlers/agents.js",
|
|
644
|
-
"beforeBytes":
|
|
645
|
-
"afterBytes":
|
|
734
|
+
"beforeBytes": 2274,
|
|
735
|
+
"afterBytes": 1134
|
|
646
736
|
},
|
|
647
737
|
{
|
|
648
738
|
"file": "src/session/handlers/chat.js",
|
|
649
|
-
"beforeBytes":
|
|
650
|
-
"afterBytes":
|
|
739
|
+
"beforeBytes": 56203,
|
|
740
|
+
"afterBytes": 24136
|
|
651
741
|
},
|
|
652
742
|
{
|
|
653
743
|
"file": "src/session/handlers/control.js",
|
|
@@ -706,8 +796,8 @@
|
|
|
706
796
|
},
|
|
707
797
|
{
|
|
708
798
|
"file": "src/session/manager.js",
|
|
709
|
-
"beforeBytes":
|
|
710
|
-
"afterBytes":
|
|
799
|
+
"beforeBytes": 48167,
|
|
800
|
+
"afterBytes": 25714
|
|
711
801
|
},
|
|
712
802
|
{
|
|
713
803
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -726,8 +816,28 @@
|
|
|
726
816
|
},
|
|
727
817
|
{
|
|
728
818
|
"file": "src/session/queue.js",
|
|
729
|
-
"beforeBytes":
|
|
730
|
-
"afterBytes":
|
|
819
|
+
"beforeBytes": 36642,
|
|
820
|
+
"afterBytes": 16429
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
"file": "src/session/run-recovery/barrier.js",
|
|
824
|
+
"beforeBytes": 1061,
|
|
825
|
+
"afterBytes": 521
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"file": "src/session/run-recovery/coordinator.js",
|
|
829
|
+
"beforeBytes": 7193,
|
|
830
|
+
"afterBytes": 3313
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
"file": "src/session/run-recovery/journal.js",
|
|
834
|
+
"beforeBytes": 8568,
|
|
835
|
+
"afterBytes": 4162
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"file": "src/session/run-recovery/schema.js",
|
|
839
|
+
"beforeBytes": 5964,
|
|
840
|
+
"afterBytes": 3907
|
|
731
841
|
},
|
|
732
842
|
{
|
|
733
843
|
"file": "src/session/store.js",
|
|
@@ -751,13 +861,33 @@
|
|
|
751
861
|
},
|
|
752
862
|
{
|
|
753
863
|
"file": "src/upgrade/engine.js",
|
|
754
|
-
"beforeBytes":
|
|
755
|
-
"afterBytes":
|
|
864
|
+
"beforeBytes": 15883,
|
|
865
|
+
"afterBytes": 6563
|
|
756
866
|
},
|
|
757
867
|
{
|
|
758
868
|
"file": "src/upgrade/scheduler.js",
|
|
759
|
-
"beforeBytes":
|
|
760
|
-
"afterBytes":
|
|
869
|
+
"beforeBytes": 7340,
|
|
870
|
+
"afterBytes": 4250
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"file": "src/upgrade/updater-bootstrap.js",
|
|
874
|
+
"beforeBytes": 3291,
|
|
875
|
+
"afterBytes": 1732
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"file": "src/upgrade/updater-launcher.js",
|
|
879
|
+
"beforeBytes": 7949,
|
|
880
|
+
"afterBytes": 3904
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
"file": "src/upgrade/updater-protocol.js",
|
|
884
|
+
"beforeBytes": 2814,
|
|
885
|
+
"afterBytes": 1677
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"file": "src/upgrade/updater-worker.js",
|
|
889
|
+
"beforeBytes": 13960,
|
|
890
|
+
"afterBytes": 7446
|
|
761
891
|
},
|
|
762
892
|
{
|
|
763
893
|
"file": "src/windows-shell.js",
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { AcpAgentType, ChatAttachmentMeta } from '@shennian/wire';
|
|
2
|
+
import { AgentAdapter, type ImportedAgentMessage } from '../adapter.js';
|
|
3
|
+
import { type AcpAgentManifest } from './types.js';
|
|
4
|
+
import type { CompiledManagedAgentPolicy } from '../../security/managed-agent-policy.js';
|
|
5
|
+
export declare class AcpAgentAdapter extends AgentAdapter {
|
|
6
|
+
private readonly manifest;
|
|
7
|
+
private readonly options;
|
|
8
|
+
readonly type: AcpAgentType;
|
|
9
|
+
get recoveryCapabilities(): {
|
|
10
|
+
inspectTerminal: boolean;
|
|
11
|
+
reattachRun: boolean;
|
|
12
|
+
resumeRun: boolean;
|
|
13
|
+
resumeSession: boolean;
|
|
14
|
+
};
|
|
15
|
+
private client;
|
|
16
|
+
private workDir;
|
|
17
|
+
private shennianSessionId;
|
|
18
|
+
private requestedSessionId;
|
|
19
|
+
private agentSessionId;
|
|
20
|
+
private runId;
|
|
21
|
+
private seq;
|
|
22
|
+
private active;
|
|
23
|
+
private extraEnv;
|
|
24
|
+
private pendingPermissions;
|
|
25
|
+
private configOptions;
|
|
26
|
+
private modes;
|
|
27
|
+
private importCapture;
|
|
28
|
+
private emittedToolStates;
|
|
29
|
+
private pendingAuthRetry;
|
|
30
|
+
private retryingAfterAuth;
|
|
31
|
+
private managedAgentPolicy;
|
|
32
|
+
constructor(manifest: AcpAgentManifest, options?: {
|
|
33
|
+
permissionTimeoutMs?: number;
|
|
34
|
+
promptTimeoutMs?: number;
|
|
35
|
+
});
|
|
36
|
+
configure(options: {
|
|
37
|
+
env?: NodeJS.ProcessEnv;
|
|
38
|
+
managedAgentPolicy?: CompiledManagedAgentPolicy | null;
|
|
39
|
+
}): void;
|
|
40
|
+
start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
41
|
+
send(text: string, modelId?: string, reasoningEffort?: string, attachments?: ChatAttachmentMeta[], systemPrompt?: string | null): Promise<void>;
|
|
42
|
+
resume(agentSessionId: string): Promise<void>;
|
|
43
|
+
stop(): Promise<void>;
|
|
44
|
+
getStatus(): Promise<{
|
|
45
|
+
active: boolean;
|
|
46
|
+
runId: string | null;
|
|
47
|
+
canStop: boolean;
|
|
48
|
+
}>;
|
|
49
|
+
respondToPermission(permissionId: string, optionId: string): Promise<void>;
|
|
50
|
+
getAuthMethods(): import('@agentclientprotocol/sdk').AuthMethod[];
|
|
51
|
+
hasPendingAuthenticationRetry(): boolean;
|
|
52
|
+
getSessionOptions(): import('../adapter.js').AgentSessionOptions;
|
|
53
|
+
authenticate(methodId: string, options?: {
|
|
54
|
+
interactiveTerminal?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
logout(): Promise<void>;
|
|
57
|
+
resumeAfterExternalAuthentication(): Promise<void>;
|
|
58
|
+
listExternalSessions(options?: {
|
|
59
|
+
cwd?: string;
|
|
60
|
+
}): Promise<import("@shennian/wire").AcpExternalSessionInfo[]>;
|
|
61
|
+
loadExternalSession(agentSessionId: string): Promise<ImportedAgentMessage[]>;
|
|
62
|
+
closeExternalSession(agentSessionId: string): Promise<void>;
|
|
63
|
+
deleteExternalSession(agentSessionId: string): Promise<void>;
|
|
64
|
+
private ensureSession;
|
|
65
|
+
private applyDynamicConfig;
|
|
66
|
+
private handleSessionUpdate;
|
|
67
|
+
private captureImportedUpdate;
|
|
68
|
+
private handlePermission;
|
|
69
|
+
private requireClient;
|
|
70
|
+
private buildEnvironment;
|
|
71
|
+
private buildClientCapabilities;
|
|
72
|
+
private retryAfterAuthentication;
|
|
73
|
+
private promptWithTimeout;
|
|
74
|
+
private cancelPendingPermissions;
|
|
75
|
+
private makeEvent;
|
|
76
|
+
private emitEvent;
|
|
77
|
+
}
|
|
78
|
+
export declare function registerAcpAgent(manifest: AcpAgentManifest): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{randomUUID as p}from"node:crypto";import{createHash as w}from"node:crypto";import{realpathSync as m}from"node:fs";import{pathToFileURL as I}from"node:url";import*as l from"@agentclientprotocol/sdk";import{RequestError as S}from"@agentclientprotocol/sdk";import{AgentAdapter as v,registerAgent as C}from"../adapter.js";import{mapAcpSessionUpdate as A}from"./events.js";import{AcpProcessClient as f}from"./process-client.js";import{acpAgentType as g}from"./types.js";import{runAcpTerminalAuthentication as P}from"./auth.js";import{setAcpRuntimeAuthState as u}from"./auth-state.js";import{recordAcpAuthFailure as q,recordAcpImportResult as y}from"./metrics.js";class b extends v{manifest;options;type;get recoveryCapabilities(){const e=this.client?.capabilities;return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!!(e?.sessionCapabilities?.resume||e?.loadSession)}}client=null;workDir="";shennianSessionId="";requestedSessionId=null;agentSessionId=null;runId="";seq=0;active=!1;extraEnv={};pendingPermissions=new Map;configOptions=[];modes=null;importCapture=null;emittedToolStates=new Map;pendingAuthRetry=null;retryingAfterAuth=!1;managedAgentPolicy=null;constructor(e,i={}){super(),this.manifest=e,this.options=i,this.type=g(e.id)}configure(e){this.extraEnv=e.env??{},this.managedAgentPolicy=e.managedAgentPolicy??null}async start(e,i,s){this.shennianSessionId=e;try{this.workDir=m.native(i)}catch{this.workDir=i}this.requestedSessionId=s??null,this.agentSessionId=null,this.client=new f(this.manifest.launch,{onSessionUpdate:t=>this.handleSessionUpdate(t),onPermission:t=>this.handlePermission(t)},this.buildEnvironment(),{...this.buildClientCapabilities(),terminalAuth:!0}),await this.client.start(this.workDir)}async send(e,i,s,t,n){const o=this.requireClient();this.runId=p(),this.seq=0,this.emittedToolStates.clear();try{await this.ensureSession(),await this.applyDynamicConfig(i,s),this.active=!0,this.emitEvent({state:"start",runPhase:"thinking",agentSessionId:this.agentSessionId??void 0});const r=[],a=[];n?.trim()&&a.push(n.trim()),a.push(e),r.push({type:"text",text:a.join(`
|
|
2
|
+
|
|
3
|
+
`)});for(const h of t??[])r.push({type:"resource_link",uri:I(h.path).href,name:h.name,mimeType:h.mimeType,size:h.byteSize});const c=await this.promptWithTimeout(o,r);this.active=!1,c.stopReason==="cancelled"?this.emitEvent({state:"aborted",agentSessionId:this.agentSessionId??void 0}):this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0})}catch(r){this.active=!1,this.cancelPendingPermissions();const a=r instanceof Error?r.message:String(r),c=r instanceof S&&r.code===-32e3;throw c&&(u(this.type,"required"),this.retryingAfterAuth||(this.pendingAuthRetry={text:e,...i?{modelId:i}:{},...s?{reasoningEffort:s}:{},...t?{attachments:[...t]}:{},...n!==void 0?{systemPrompt:n}:{}})),this.emitEvent({state:"error",message:a,...c?{errorCode:"acp_auth_required"}:{},agentSessionId:this.agentSessionId??void 0}),r}}async resume(e){this.requestedSessionId=e,this.agentSessionId=null,await this.ensureSession()}async stop(){this.active&&this.agentSessionId&&this.client&&await this.client.agent.notify(l.methods.agent.session.cancel,{sessionId:this.agentSessionId}),this.cancelPendingPermissions(),this.active=!1,await this.client?.close(),this.client=null}async getStatus(){return{active:this.active,runId:this.active?this.runId:null,canStop:this.active}}async respondToPermission(e,i){const s=this.pendingPermissions.get(e);if(!s)throw new Error("ACP permission request is no longer pending");if(!s.optionIds.has(i))throw new Error("Invalid ACP permission option");this.pendingPermissions.delete(e),clearTimeout(s.timer),s.resolve({outcome:{outcome:"selected",optionId:i}})}getAuthMethods(){return[...this.requireClient().initializeResponse?.authMethods??[]]}hasPendingAuthenticationRetry(){return this.pendingAuthRetry!==null}getSessionOptions(){const e=this.configOptions.find(o=>o.category==="model"&&o.type==="select"),i=this.configOptions.find(o=>o.category==="thought_level"&&o.type==="select"),s=this.modes?.availableModes.map(o=>({id:o.id,name:o.name,...o.description?{description:o.description}:{}}))??[],t=o=>(o?.options??[]).flatMap(r=>"options"in r?r.options:[r]),n=(i?t(i):s).map(o=>({id:"value"in o?o.value:o.id,name:o.name,...o.description?{description:o.description}:{}}));return{models:t(e).map(o=>({id:o.value,name:o.name,...o.description?{description:o.description}:{},...o.value===e?.currentValue?{isDefault:!0}:{},...n.length?{supportedReasoningEfforts:n}:{}})),modes:s}}async authenticate(e,i={}){const s=this.requireClient(),t=s.initializeResponse?.authMethods?.find(n=>n.id===e);if(!t)throw new Error("ACP authentication method is unavailable");try{if("type"in t&&t.type==="terminal"){if(!i.interactiveTerminal)throw new Error("ACP terminal authentication must be completed on the target machine with `shennian agent auth`");await s.close(),await P({...this.manifest.authLaunch??this.manifest.launch,env:Object.fromEntries(Object.entries({...this.extraEnv,...this.manifest.authLaunch?.env??this.manifest.launch.env}).filter(n=>typeof n[1]=="string"))},t,this.workDir)}else await s.authenticate(e);await this.resumeAfterExternalAuthentication()}catch(n){throw q(),n}}async logout(){await this.requireClient().logout(),u(this.type,"required")}async resumeAfterExternalAuthentication(){await this.client?.close(),this.client=new f(this.manifest.launch,{onSessionUpdate:i=>this.handleSessionUpdate(i),onPermission:i=>this.handlePermission(i)},this.buildEnvironment(),{...this.buildClientCapabilities(),terminalAuth:!0}),await this.client.start(this.workDir),u(this.type,"ready");const e=this.pendingAuthRetry;this.pendingAuthRetry=null,e&&this.retryAfterAuthentication(e)}async listExternalSessions(e={}){const i=this.requireClient();if(!i.capabilities.sessionCapabilities?.list)return[];const s=[];let t;for(let n=0;n<10&&s.length<500;n+=1){let o=e.cwd;if(o)try{o=m.native(o)}catch{}const r=await i.listSessions(o,t);if(s.push(...r.sessions.slice(0,500-s.length).map(a=>({agentSessionId:a.sessionId,cwd:a.cwd,...a.title?{title:a.title.slice(0,200)}:{},...a.updatedAt?{updatedAt:a.updatedAt}:{}}))),t=r.nextCursor,!t)break}return s}async loadExternalSession(e){const i=this.requireClient();if(!i.capabilities.loadSession)throw new Error("ACP session history import is unsupported");this.requestedSessionId=e,this.agentSessionId=e;const s=[];this.importCapture=s;try{const t=await i.agent.request(l.methods.agent.session.load,{sessionId:e,cwd:this.workDir,mcpServers:[]});this.configOptions=t.configOptions??[],this.modes=t.modes??null,y(!0)}catch(t){throw y(!1),t}finally{this.importCapture=null}return s.map((t,n)=>({sourceId:t.sourceHint??w("sha256").update(`${e}\0${n}\0${t.role}\0${t.payload}`).digest("hex"),role:t.role,payload:t.payload}))}async closeExternalSession(e){if(!this.requireClient().capabilities.sessionCapabilities?.close)throw new Error("ACP session close is unsupported");await this.requireClient().closeSession(e)}async deleteExternalSession(e){if(!this.requireClient().capabilities.sessionCapabilities?.delete)throw new Error("ACP session delete is unsupported");await this.requireClient().deleteSession(e)}async ensureSession(){if(this.agentSessionId)return;const e=this.requireClient();if(this.requestedSessionId){const s=e.capabilities;if(s.sessionCapabilities?.resume){const t=await e.agent.request(l.methods.agent.session.resume,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=t.configOptions??[],this.modes=t.modes??null}else if(s.loadSession){this.agentSessionId=this.requestedSessionId;const t=await e.agent.request(l.methods.agent.session.load,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=t.configOptions??[],this.modes=t.modes??null}else throw new Error(`${this.manifest.name} cannot resume ACP sessions`);this.agentSessionId=this.requestedSessionId;return}const i=await e.agent.request(l.methods.agent.session.new,{cwd:this.workDir,mcpServers:[]});this.agentSessionId=i.sessionId,this.configOptions=i.configOptions??[],this.modes=i.modes??null}async applyDynamicConfig(e,i){if(!this.agentSessionId)return;i&&this.modes?.availableModes.some(t=>t.id===i)&&(this.modes.currentModeId!==i&&(await this.requireClient().agent.request(l.methods.agent.session.setMode,{sessionId:this.agentSessionId,modeId:i}),this.modes.currentModeId=i),i=void 0);const s=[{category:"model",value:e},{category:"thought_level",value:i}];for(const t of s){if(!t.value)continue;const n=this.configOptions.find(o=>o.category===t.category&&o.type==="select");!n||n.currentValue===t.value||(await this.requireClient().agent.request(l.methods.agent.session.setConfigOption,{sessionId:this.agentSessionId,configId:n.id,value:t.value}),n.currentValue=t.value)}}handleSessionUpdate(e){if(e.sessionId===this.agentSessionId){if(this.importCapture){this.captureImportedUpdate(e.update);return}if(this.active){if(e.update.sessionUpdate==="tool_call"||e.update.sessionUpdate==="tool_call_update"){const i=JSON.stringify(e.update);if(this.emittedToolStates.get(e.update.toolCallId)===i)return;this.emittedToolStates.set(e.update.toolCallId,i)}for(const i of A(e.update,s=>this.makeEvent(s)))this.emit("agentEvent",i)}}}captureImportedUpdate(e){if(this.importCapture){if(e.sessionUpdate==="user_message_chunk"||e.sessionUpdate==="agent_message_chunk"){const i=e.content.type==="text"?e.content.text:e.content.type==="resource_link"?e.content.name||e.content.uri:`[${e.content.type}]`,s=e.sessionUpdate==="user_message_chunk"?"user":"agent",t=e.messageId?`message:${e.messageId}`:void 0,n=t?this.importCapture.find(o=>o.sourceHint===t):this.importCapture.at(-1);n?.role===s&&n.sourceHint===t?n.payload+=i:this.importCapture.push({role:s,payload:i,...t?{sourceHint:t}:{}});return}if(e.sessionUpdate==="tool_call"){const i=`tool:${e.toolCallId}`,s=this.importCapture.find(n=>n.sourceHint===i),t={role:"agent",sourceHint:i,payload:JSON.stringify({v:1,type:"tool_use",name:e.title,toolCallId:e.toolCallId,status:e.status??"running"})};s?s.payload=t.payload:this.importCapture.push(t);return}if(e.sessionUpdate==="tool_call_update"&&(e.status==="completed"||e.status==="failed")){const i=this.importCapture.find(t=>t.sourceHint===`tool:${e.toolCallId}`),s=JSON.stringify({v:1,type:"tool_result",name:e.title??"tool",toolCallId:e.toolCallId,status:e.status});i?i.payload=s:this.importCapture.push({role:"agent",sourceHint:`tool:${e.toolCallId}`,payload:s})}}}handlePermission(e){if(!this.active||e.sessionId!==this.agentSessionId)return Promise.resolve({outcome:{outcome:"cancelled"}});const i=p();return new Promise(s=>{const t=setTimeout(()=>{this.pendingPermissions.delete(i),s({outcome:{outcome:"cancelled"}})},this.options.permissionTimeoutMs??3e5);t.unref?.(),this.pendingPermissions.set(i,{optionIds:new Set(e.options.map(n=>n.optionId)),resolve:s,timer:t}),this.emitEvent({state:"approval-pending",runPhase:"waiting_approval",approval:{title:e.toolCall.title??void 0,source:this.manifest.name},permission:{id:i,sessionId:this.shennianSessionId,agentSessionId:this.agentSessionId??void 0,runId:this.runId,toolCallId:e.toolCall.toolCallId,options:e.options.map(n=>({id:n.optionId,name:n.name,kind:n.kind}))}})})}requireClient(){if(!this.client)throw new Error("ACP adapter has not started");return this.client}buildEnvironment(){return this.managedAgentPolicy?{...this.extraEnv}:{...process.env,...this.extraEnv}}buildClientCapabilities(){const e=this.manifest.clientCapabilities??{},i=this.managedAgentPolicy?.adapterPolicy;return i?{readTextFile:!!e.readTextFile,writeTextFile:!!(e.writeTextFile&&i.fileAccess!=="workspace-read"),terminal:!1}:e}async retryAfterAuthentication(e){this.retryingAfterAuth=!0;try{await this.send(e.text,e.modelId,e.reasoningEffort,e.attachments,e.systemPrompt)}catch{}finally{this.retryingAfterAuth=!1}}async promptWithTimeout(e,i){let s;try{return await Promise.race([e.agent.request(l.methods.agent.session.prompt,{sessionId:this.agentSessionId,prompt:i}),new Promise((t,n)=>{s=setTimeout(()=>n(new Error("ACP prompt timed out")),this.options.promptTimeoutMs??720*6e4),s.unref?.()})])}catch(t){throw t instanceof Error&&t.message==="ACP prompt timed out"&&(await e.close(),this.client===e&&(this.client=null)),t}finally{s&&clearTimeout(s)}}cancelPendingPermissions(){for(const e of this.pendingPermissions.values())clearTimeout(e.timer),e.resolve({outcome:{outcome:"cancelled"}});this.pendingPermissions.clear()}makeEvent(e){return{...e,runId:this.runId,seq:this.seq++}}emitEvent(e){this.emit("agentEvent",this.makeEvent(e))}}function F(d){C(g(d.id),()=>new b(d))}export{b as AcpAgentAdapter,F as registerAcpAgent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=new Map;function u(t){return e.get(t)}function c(t,n){e.set(t,n)}export{u as getAcpRuntimeAuthState,c as setAcpRuntimeAuthState};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type StdioOptions } from 'node:child_process';
|
|
2
|
+
import type { AuthMethodTerminal } from '@agentclientprotocol/sdk';
|
|
3
|
+
import type { AcpLaunchSpec } from './types.js';
|
|
4
|
+
export declare function runAcpTerminalAuthentication(launch: AcpLaunchSpec, method: AuthMethodTerminal, cwd: string, options?: {
|
|
5
|
+
requireTty?: boolean;
|
|
6
|
+
stdio?: StdioOptions;
|
|
7
|
+
}): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{spawn as d}from"node:child_process";import{buildCommandStringLaunchSpec as u}from"../command-spec.js";async function w(n,r,e,i={}){if(i.requireTty!==!1&&(!process.stdin.isTTY||!process.stdout.isTTY))throw new Error("ACP terminal authentication requires an interactive terminal");const t=u(n.command,[...n.args??[],...r.args??[]],e);await new Promise((c,o)=>{const s=d(t.command,t.args??[],{cwd:e,env:{...process.env,...n.env,...r.env},stdio:i.stdio??"inherit",windowsHide:!1});s.once("error",o),s.once("exit",(a,m)=>a===0?c():o(new Error(`ACP terminal authentication failed (${a??m??"unknown"})`)))})}export{w as runAcpTerminalAuthentication};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DetectedAgent } from '../detect.js';
|
|
2
|
+
import type { AcpAgentManifest } from './types.js';
|
|
3
|
+
export declare function buildAcpCapabilityCacheKey(input: {
|
|
4
|
+
manifest: AcpAgentManifest;
|
|
5
|
+
platform: NodeJS.Platform;
|
|
6
|
+
catalogRevision?: string;
|
|
7
|
+
executableIdentity?: {
|
|
8
|
+
pathHash: string;
|
|
9
|
+
fingerprint: string;
|
|
10
|
+
} | null;
|
|
11
|
+
}): string | null;
|
|
12
|
+
export declare function readAcpCapabilityCache(key: string): DetectedAgent | null;
|
|
13
|
+
export declare function writeAcpCapabilityCache(key: string, agent: DetectedAgent): void;
|
|
14
|
+
export declare function clearAcpCapabilityCache(): void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import c from"node:crypto";import n from"node:fs";import l from"node:path";import{resolveShennianPath as r}from"../../config/index.js";const a="acp-capabilities-v1.json",m=2*1024*1024;function h(e){return e.executableIdentity?c.createHash("sha256").update(JSON.stringify({id:e.manifest.id,command:e.manifest.launch.command,args:e.manifest.launch.args??[],env:e.manifest.launch.env??{},clientCapabilities:e.manifest.clientCapabilities??{},platform:e.platform,catalogRevision:e.catalogRevision??"local",executable:e.executableIdentity})).digest("hex"):null}function b(e){return o().entries[e]??null}function C(e,t){const i=o();i.entries[e]=t;const s=Object.entries(i.entries).slice(-256);f({version:1,entries:Object.fromEntries(s)})}function v(){try{n.unlinkSync(r(a))}catch{}}function o(){try{const e=r(a);if(n.statSync(e).size>m)return{version:1,entries:{}};const t=JSON.parse(n.readFileSync(e,"utf8"));if(t.version!==1||!t.entries||typeof t.entries!="object")throw new Error("invalid");return t}catch{return{version:1,entries:{}}}}function f(e){const t=r(a);n.mkdirSync(l.dirname(t),{recursive:!0,mode:448});const i=`${t}.tmp-${process.pid}-${c.randomUUID()}`;try{n.writeFileSync(i,`${JSON.stringify(e)}
|
|
2
|
+
`,{mode:384,flag:"wx"}),n.renameSync(i,t)}finally{try{n.unlinkSync(i)}catch{}}}export{h as buildAcpCapabilityCacheKey,v as clearAcpCapabilityCache,b as readAcpCapabilityCache,C as writeAcpCapabilityCache};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AcpCatalogPlatform } from '@shennian/wire';
|
|
2
|
+
import type { AcpAgentManifest } from './types.js';
|
|
3
|
+
export declare function loadAcpCatalog(options?: {
|
|
4
|
+
serverUrl?: string;
|
|
5
|
+
authToken?: string;
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
revision?: string;
|
|
9
|
+
candidates: AcpAgentManifest[];
|
|
10
|
+
}>;
|
|
11
|
+
export declare function currentAcpPlatform(): AcpCatalogPlatform;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import n from"node:fs";import u from"node:path";import{resolveShennianPath as f}from"../../config/index.js";import{deriveInstalledPackageCommands as g}from"./package-commands.js";const p="acp-registry-v1.json",s=2*1024*1024;async function S(a={}){const r=i();let e=null;return a.serverUrl&&a.authToken&&(e=await w(a).catch(()=>null),e&&(!r||Date.parse(e.fetchedAt)>=Date.parse(r.fetchedAt))?y(e):e&&r&&(e=r)),e??=r,!e||e.platform!==c()?{candidates:[]}:{revision:e.revision,candidates:e.candidates.flatMap(t=>t.duplicateOf?[]:[...new Set([...t.commands,...g({npm:t.npmPackage,uv:t.uvPackage})])].map(l=>({id:t.id,name:t.name,source:"registry",...t.website?{homepage:t.website}:{},...t.npmPackage||t.uvPackage?{packageHints:{...t.npmPackage?{npm:t.npmPackage}:{},...t.uvPackage?{uv:t.uvPackage}:{}}}:{},launch:{command:l,args:t.args}})))}}function c(){const a=process.platform==="win32"?"windows":process.platform==="darwin"?"darwin":"linux",r=process.arch==="arm64"?"aarch64":"x86_64";return`${a}-${r}`}async function w(a){const r=new AbortController,e=setTimeout(()=>r.abort(),5e3);try{const t=new URL("/api/acp/registry",a.serverUrl);t.searchParams.set("platform",c());const o=await(a.fetchImpl??fetch)(t,{headers:{authorization:`Bearer ${a.authToken}`,...i()?.revision?{"x-shennian-acp-revision":i().revision}:{}},signal:r.signal});if(!o.ok)throw new Error(`ACP catalog request failed (${o.status})`);if(Number(o.headers.get("content-length")??0)>s)throw new Error("ACP catalog exceeds size limit");const m=new Uint8Array(await o.arrayBuffer());if(m.byteLength>s)throw new Error("ACP catalog exceeds size limit");return h(JSON.parse(new TextDecoder().decode(m)))}finally{clearTimeout(e)}}function h(a){if(!a||typeof a!="object")throw new Error("Invalid ACP catalog");const r=a;if(!/^[a-z0-9]+-[a-f0-9]{16}$/.test(r.revision)||!/^[a-f0-9]{64}$/.test(r.digest)||Number.isNaN(Date.parse(r.fetchedAt))||r.platform!==c()||!Array.isArray(r.candidates))throw new Error("Invalid ACP catalog");for(const e of r.candidates)if(!/^[a-z][a-z0-9-]{0,63}$/.test(e.id)||!e.name||e.name.length>80||!Array.isArray(e.commands)||e.commands.some(t=>!/^[a-zA-Z0-9._-]{1,128}$/.test(t))||!Array.isArray(e.args))throw new Error("Invalid ACP catalog candidate");return r}function i(){try{const a=f(p);return n.statSync(a).size>s?null:h(JSON.parse(n.readFileSync(a,"utf8")))}catch{return null}}function y(a){const r=f(p);n.mkdirSync(u.dirname(r),{recursive:!0,mode:448});const e=`${r}.tmp-${process.pid}`;try{n.writeFileSync(e,`${JSON.stringify(a)}
|
|
2
|
+
`,{mode:384,flag:"wx"}),n.renameSync(e,r)}finally{try{n.unlinkSync(e)}catch{}}}export{c as currentAcpPlatform,S as loadAcpCatalog};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type * as acp from '@agentclientprotocol/sdk';
|
|
2
|
+
export declare class AcpClientServices {
|
|
3
|
+
readonly enabled: {
|
|
4
|
+
readTextFile?: boolean;
|
|
5
|
+
writeTextFile?: boolean;
|
|
6
|
+
terminal?: boolean;
|
|
7
|
+
};
|
|
8
|
+
private readonly root;
|
|
9
|
+
private readonly terminals;
|
|
10
|
+
constructor(workDir: string, enabled: {
|
|
11
|
+
readTextFile?: boolean;
|
|
12
|
+
writeTextFile?: boolean;
|
|
13
|
+
terminal?: boolean;
|
|
14
|
+
});
|
|
15
|
+
get capabilities(): {
|
|
16
|
+
fs: {
|
|
17
|
+
readTextFile: boolean;
|
|
18
|
+
writeTextFile: boolean;
|
|
19
|
+
};
|
|
20
|
+
terminal: boolean;
|
|
21
|
+
};
|
|
22
|
+
readTextFile(params: acp.ReadTextFileRequest): Promise<acp.ReadTextFileResponse>;
|
|
23
|
+
writeTextFile(params: acp.WriteTextFileRequest): Promise<void>;
|
|
24
|
+
createTerminal(params: acp.CreateTerminalRequest): Promise<acp.CreateTerminalResponse>;
|
|
25
|
+
terminalOutput(params: acp.TerminalOutputRequest): acp.TerminalOutputResponse;
|
|
26
|
+
waitForTerminalExit(params: acp.WaitForTerminalExitRequest): Promise<acp.WaitForTerminalExitResponse>;
|
|
27
|
+
killTerminal(params: acp.KillTerminalRequest): void;
|
|
28
|
+
releaseTerminal(params: acp.ReleaseTerminalRequest): void;
|
|
29
|
+
close(): void;
|
|
30
|
+
private requireTerminal;
|
|
31
|
+
private resolve;
|
|
32
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import c from"node:fs";import n from"node:path";import{randomUUID as p}from"node:crypto";import{spawn as w}from"node:child_process";import{terminateProcessTree as m}from"./process-tree.js";class F{enabled;root;terminals=new Map;constructor(t,e){this.enabled=e,this.root=c.realpathSync(t)}get capabilities(){return{fs:{readTextFile:!!this.enabled.readTextFile,writeTextFile:!!this.enabled.writeTextFile},terminal:!!this.enabled.terminal}}async readTextFile(t){if(!this.enabled.readTextFile)throw new Error("ACP file reads are disabled");const r=(await c.promises.readFile(await this.resolve(t.path,!1),"utf8")).split(`
|
|
2
|
+
`),a=Math.max(0,(t.line??1)-1),i=Math.min(Math.max(0,t.limit??r.length),1e5);return{content:r.slice(a,a+i).join(`
|
|
3
|
+
`)}}async writeTextFile(t){if(!this.enabled.writeTextFile)throw new Error("ACP file writes are disabled");const e=await this.resolve(t.path,!0);await c.promises.writeFile(e,t.content,"utf8")}async createTerminal(t){if(!this.enabled.terminal)throw new Error("ACP terminals are disabled");const e=await this.resolve(t.cwd??this.root,!1),r=w(t.command,t.args??[],{cwd:e,env:{...process.env,...Object.fromEntries((t.env??[]).map(s=>[s.name,s.value]))},stdio:["pipe","pipe","pipe"],detached:process.platform!=="win32",windowsHide:!0}),a=Math.min(Number(t.outputByteLimit??1024*1024),4*1024*1024),i={child:r,output:Buffer.alloc(0),limit:a,truncated:!1,exitStatus:null,exited:new Promise(s=>r.once("exit",(o,h)=>{const d={exitCode:o,signal:h};i.exitStatus=d,s(d)}))},l=s=>{if(i.output=Buffer.concat([i.output,s]),i.output.byteLength>i.limit){let o=i.output.byteLength-i.limit;for(;o<i.output.byteLength&&(i.output[o]&192)===128;)o+=1;i.output=i.output.subarray(o),i.truncated=!0}};r.stdout.on("data",l),r.stderr.on("data",l);const u=p();return this.terminals.set(u,i),{terminalId:u}}terminalOutput(t){const e=this.requireTerminal(t.terminalId);return{output:e.output.toString("utf8"),truncated:e.truncated,exitStatus:e.exitStatus}}async waitForTerminalExit(t){return this.requireTerminal(t.terminalId).exited}killTerminal(t){m(this.requireTerminal(t.terminalId).child)}releaseTerminal(t){const e=this.requireTerminal(t.terminalId);e.exitStatus||m(e.child),this.terminals.delete(t.terminalId)}close(){for(const t of this.terminals.values())t.exitStatus||m(t.child);this.terminals.clear()}requireTerminal(t){const e=this.terminals.get(t);if(!e)throw new Error("Unknown ACP terminal");return e}async resolve(t,e){if(!n.isAbsolute(t))throw new Error("ACP path must be absolute");const r=n.resolve(t),a=e?n.dirname(r):r,i=await c.promises.realpath(a),l=e?n.join(i,n.basename(r)):i,u=n.relative(this.root,l);if(u.startsWith("..")||n.isAbsolute(u))throw new Error("ACP path is outside the session workspace");return l}}export{F as AcpClientServices};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DetectedAgent } from '../detect.js';
|
|
2
|
+
import { type AcpAgentManifest } from './types.js';
|
|
3
|
+
export declare function discoverAcpAgents(options?: {
|
|
4
|
+
candidates?: AcpAgentManifest[];
|
|
5
|
+
cwd?: string;
|
|
6
|
+
serverUrl?: string;
|
|
7
|
+
authToken?: string;
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
}): Promise<DetectedAgent[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{RequestError as B}from"@agentclientprotocol/sdk";import{buildCommandStringLaunchSpec as k,commandExists as x,resolveCommandFileIdentity as M}from"../command-spec.js";import{registerAcpAgent as v}from"./adapter.js";import{getRegisteredAgents as R,unregisterAgent as T}from"../adapter.js";import{readAcpManifests as E}from"./manifests.js";import{AcpProcessClient as L}from"./process-client.js";import{acpAgentType as h}from"./types.js";import{loadAcpCatalog as D}from"./catalog.js";import{buildAcpCapabilityCacheKey as F,readAcpCapabilityCache as N,writeAcpCapabilityCache as P}from"./capability-cache.js";import{getAcpRuntimeAuthState as S,setAcpRuntimeAuthState as _}from"./auth-state.js";import{recordAcpScan as q}from"./metrics.js";const K=[{id:"qwen-code",name:"Qwen Code",source:"registry",launch:{command:"qwen",args:["--acp"]}},{id:"kimi",name:"Kimi CLI",source:"registry",launch:{command:"kimi",args:["acp"]}}],O=new Set(["claude","codex","codebuddy","cursor","opencode","pi"]);async function ne(t={}){const i=Date.now();let r=0,n=0;const c={};for(const e of R())e.startsWith("acp:")&&T(e);const s=t.candidates?{candidates:t.candidates,revision:void 0}:await D(t),y=$([...s.candidates.length?s.candidates:K,...E()]),b=y.filter(e=>{const f=e.launch.command;return O.has(f)?!1:x(f)}).filter((e,f,o)=>o.findIndex(m=>m.id===e.id)===f),C=(await H(b,3,async e=>{const o={...k(e.launch.command,e.launch.args??[],t.cwd??process.cwd()),...e.launch.env?{env:e.launch.env}:{}},m=F({manifest:e,platform:process.platform,catalogRevision:s.revision,executableIdentity:M(e.launch.command)}),d=m?N(m):null;if(d?.type===h(e.id)&&d.integration==="acp"&&d.acpCapabilities?.protocolVersion===1)return r+=1,v({...e,launch:o,authLaunch:e.launch}),{...d,authState:S(h(e.id))??d.authState,command:o.command,args:o.args??[],display:{...d.display,name:e.name},...s.revision?{catalogRevision:s.revision}:{}};const g=new L(o,{onSessionUpdate:()=>{},onPermission:async()=>({outcome:{outcome:"cancelled"}})},process.env,{terminalAuth:!0});try{const l=await g.start(t.cwd??process.cwd()),a=l.agentCapabilities??{},I={protocolVersion:1,listSessions:!!a.sessionCapabilities?.list,loadSession:!!a.loadSession,resumeSession:!!a.sessionCapabilities?.resume,closeSession:!!a.sessionCapabilities?.close,deleteSession:!!a.sessionCapabilities?.delete,terminal:!!e.clientCapabilities?.terminal,fileRead:!!e.clientCapabilities?.readTextFile,fileWrite:!!e.clientCapabilities?.writeTextFile,permission:!0,modelConfig:!1};let p=l.authMethods?.length?"unknown":"ready";if(a.sessionCapabilities?.list)try{await g.listSessions(t.cwd??process.cwd()),p=l.authMethods?.length?"unknown":"ready"}catch(u){p=u instanceof B&&u.code===-32e3?"required":"unknown"}const A=S(h(e.id));A?p=A:p==="required"&&_(h(e.id),p),v({...e,launch:o,authLaunch:e.launch});const w={type:h(e.id),command:o.command,args:o.args??[],version:l.agentInfo?.version??void 0,runtimePlatform:process.platform,integration:"acp",display:{name:e.name,version:l.agentInfo?.version??void 0},acpCapabilities:I,authState:p,acpAuthMethods:(l.authMethods??[]).slice(0,8).map(u=>({id:u.id.slice(0,128),name:u.name.slice(0,80),type:"type"in u&&u.type==="terminal"?"terminal":"agent"})),...s.revision?{catalogRevision:s.revision}:{}};return m&&P(m,w),w}catch(l){n+=1;const a=W(l);return c[a]=(c[a]??0)+1,null}finally{await g.close()}})).filter(e=>!!e);return q({durationMs:Date.now()-i,candidateCount:y.length,installedCount:C.length,cacheHits:r,handshakeFailures:n,handshakeFailuresByKind:c}),C}function W(t){const i=t instanceof Error?t.message:"";return/timed out/i.test(i)?"timeout":/protocol version/i.test(i)?"version":/safety limit|exceeded/i.test(i)?"output_limit":/json|parse/i.test(i)?"invalid_protocol":/enoent|not found/i.test(i)?"launch":"other"}function $(t){const i=new Set(t.filter(n=>n.source==="local").map(n=>n.id)),r=new Map;for(const n of t){if(n.source!=="local"&&i.has(n.id))continue;const c=`${n.id}\0${n.launch.command}\0${JSON.stringify(n.launch.args??[])}`;r.has(c)||r.set(c,n)}return[...r.values()]}async function H(t,i,r){const n=new Array(t.length);let c=0;return await Promise.all(Array.from({length:Math.min(i,t.length)},async()=>{for(;;){const s=c++;if(s>=t.length)return;n[s]=await r(t[s])}})),n}export{ne as discoverAcpAgents};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionUpdate } from '@agentclientprotocol/sdk';
|
|
2
|
+
import type { AgentEvent } from '../adapter.js';
|
|
3
|
+
export type AcpEventFactory = (partial: Omit<AgentEvent, 'runId' | 'seq'>) => AgentEvent;
|
|
4
|
+
export declare function mapAcpSessionUpdate(update: SessionUpdate, makeEvent: AcpEventFactory): AgentEvent[];
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
function n(t){if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return String(t)}}function r(t){return t.type==="text"?t.text:t.type==="resource_link"?t.name||t.uri:t.type==="resource"?"text"in t.resource?t.resource.text:`[${t.resource.mimeType??"resource"}]`:`[${t.type}: ${t.mimeType}]`}function o(t){return t?.length?t.map(e=>e.type==="content"?r(e.content):e.type==="diff"?`${e.path}
|
|
2
|
+
${e.newText}`:`[terminal: ${e.terminalId}]`).join(`
|
|
3
|
+
`):""}function l(t,e){switch(t.sessionUpdate){case"agent_message_chunk":return[e({state:"delta",text:r(t.content)})];case"agent_thought_chunk":return[e({state:"delta",text:r(t.content),thinking:!0})];case"tool_call":return[e({state:"tool-call",toolCallId:t.toolCallId,toolStatus:"running",name:t.title,args:typeof t.rawInput=="object"&&t.rawInput!==null?t.rawInput:t.rawInput===void 0?void 0:{input:t.rawInput}})];case"tool_call_update":{if(t.status!=="completed"&&t.status!=="failed")return[];const s=o(t.content)||(t.rawOutput===void 0?t.status:n(t.rawOutput));return[e({state:"tool-result",toolCallId:t.toolCallId,toolStatus:t.status,name:t.title??t.toolCallId,result:s})]}case"usage_update":return[e({state:"notify",title:"Context usage",text:`${t.used}/${t.size}`})];case"plan":case"plan_update":return[e({state:"notify",title:"Plan updated",text:n(t)})];case"session_info_update":return t.title?[e({state:"notify",title:"Session",text:t.title})]:[];default:return[]}}export{l as mapAcpSessionUpdate};
|