shennian 0.5.14 → 0.5.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.
- package/dist/publish-build-manifest.json +115 -45
- package/dist/src/agents/acp/adapter.js +2 -2
- package/dist/src/agents/acp/discovery.js +1 -1
- package/dist/src/agents/adapter.js +2 -1
- package/dist/src/agents/claude-permission-bridge.js +3 -0
- package/dist/src/agents/claude-permission-protocol.js +1 -0
- package/dist/src/agents/claude-permission-relay-server.js +3 -0
- package/dist/src/agents/claude.js +7 -7
- package/dist/src/agents/codex-runtime.js +7 -7
- package/dist/src/agents/project-client.js +1 -0
- package/dist/src/agents/workbuddy.js +3 -2
- package/dist/src/commands/daemon.js +9 -9
- package/dist/src/commands/pair-browser.js +1 -1
- package/dist/src/commands/pair.js +11 -11
- package/dist/src/commands/project.js +4 -0
- package/dist/src/commands/setup.js +4 -0
- package/dist/src/commands/steward.js +3 -0
- package/dist/src/daemon-ipc/agent-readiness.js +1 -1
- package/dist/src/daemon-ipc/control.js +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/session/handlers/chat-adapter-config.js +1 -1
- package/dist/src/session/handlers/chat-events.js +2 -2
- package/dist/src/session/handlers/chat-session-lifecycle.js +1 -1
- package/dist/src/session/handlers/chat.js +2 -1
- package/dist/src/session/handlers/steward.js +1 -0
- package/dist/src/session/manager.js +1 -1
- package/dist/src/session/queue.js +1 -1
- package/dist/src/session/store.js +2 -2
- package/dist/src/skill/hosts.js +1 -0
- package/dist/src/skill/updater.js +1 -1
- package/dist/src/steward/failover.js +1 -0
- package/dist/src/steward/session.js +2 -0
- package/dist/src/steward/templates.js +66 -0
- package/dist/src/steward/workspace.js +1 -0
- package/dist/src/upgrade/engine.js +2 -2
- package/dist/src/upgrade/npm-command.js +1 -0
- package/dist/src/upgrade/updater-launcher.js +3 -3
- package/node_modules/@shennian/wire/dist/message-payload.js +4 -4
- package/node_modules/@shennian/wire/dist/session.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 279,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian-adapter-host.js",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"file": "src/agents/acp/adapter.js",
|
|
54
|
-
"beforeBytes":
|
|
55
|
-
"afterBytes":
|
|
54
|
+
"beforeBytes": 29185,
|
|
55
|
+
"afterBytes": 14875
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"file": "src/agents/acp/auth-state.js",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"file": "src/agents/acp/discovery.js",
|
|
84
|
-
"beforeBytes":
|
|
85
|
-
"afterBytes":
|
|
84
|
+
"beforeBytes": 11154,
|
|
85
|
+
"afterBytes": 5045
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"file": "src/agents/acp/events.js",
|
|
@@ -121,8 +121,8 @@
|
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"file": "src/agents/adapter.js",
|
|
124
|
-
"beforeBytes":
|
|
125
|
-
"afterBytes":
|
|
124
|
+
"beforeBytes": 5709,
|
|
125
|
+
"afterBytes": 2700
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"file": "src/agents/auth-status.js",
|
|
@@ -134,10 +134,25 @@
|
|
|
134
134
|
"beforeBytes": 10147,
|
|
135
135
|
"afterBytes": 4390
|
|
136
136
|
},
|
|
137
|
+
{
|
|
138
|
+
"file": "src/agents/claude-permission-bridge.js",
|
|
139
|
+
"beforeBytes": 2349,
|
|
140
|
+
"afterBytes": 901
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"file": "src/agents/claude-permission-protocol.js",
|
|
144
|
+
"beforeBytes": 592,
|
|
145
|
+
"afterBytes": 194
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"file": "src/agents/claude-permission-relay-server.js",
|
|
149
|
+
"beforeBytes": 4278,
|
|
150
|
+
"afterBytes": 1936
|
|
151
|
+
},
|
|
137
152
|
{
|
|
138
153
|
"file": "src/agents/claude.js",
|
|
139
|
-
"beforeBytes":
|
|
140
|
-
"afterBytes":
|
|
154
|
+
"beforeBytes": 26522,
|
|
155
|
+
"afterBytes": 12490
|
|
141
156
|
},
|
|
142
157
|
{
|
|
143
158
|
"file": "src/agents/codex-managed-permissions.js",
|
|
@@ -156,8 +171,8 @@
|
|
|
156
171
|
},
|
|
157
172
|
{
|
|
158
173
|
"file": "src/agents/codex-runtime.js",
|
|
159
|
-
"beforeBytes":
|
|
160
|
-
"afterBytes":
|
|
174
|
+
"beforeBytes": 30637,
|
|
175
|
+
"afterBytes": 15640
|
|
161
176
|
},
|
|
162
177
|
{
|
|
163
178
|
"file": "src/agents/codex-utils.js",
|
|
@@ -334,6 +349,11 @@
|
|
|
334
349
|
"beforeBytes": 2647,
|
|
335
350
|
"afterBytes": 856
|
|
336
351
|
},
|
|
352
|
+
{
|
|
353
|
+
"file": "src/agents/project-client.js",
|
|
354
|
+
"beforeBytes": 3287,
|
|
355
|
+
"afterBytes": 1907
|
|
356
|
+
},
|
|
337
357
|
{
|
|
338
358
|
"file": "src/agents/public-agent-client.js",
|
|
339
359
|
"beforeBytes": 8149,
|
|
@@ -386,8 +406,8 @@
|
|
|
386
406
|
},
|
|
387
407
|
{
|
|
388
408
|
"file": "src/agents/workbuddy.js",
|
|
389
|
-
"beforeBytes":
|
|
390
|
-
"afterBytes":
|
|
409
|
+
"beforeBytes": 20120,
|
|
410
|
+
"afterBytes": 10409
|
|
391
411
|
},
|
|
392
412
|
{
|
|
393
413
|
"file": "src/commands/adapter.js",
|
|
@@ -456,8 +476,8 @@
|
|
|
456
476
|
},
|
|
457
477
|
{
|
|
458
478
|
"file": "src/commands/daemon.js",
|
|
459
|
-
"beforeBytes":
|
|
460
|
-
"afterBytes":
|
|
479
|
+
"beforeBytes": 38777,
|
|
480
|
+
"afterBytes": 19473
|
|
461
481
|
},
|
|
462
482
|
{
|
|
463
483
|
"file": "src/commands/integration.js",
|
|
@@ -481,8 +501,8 @@
|
|
|
481
501
|
},
|
|
482
502
|
{
|
|
483
503
|
"file": "src/commands/pair-browser.js",
|
|
484
|
-
"beforeBytes":
|
|
485
|
-
"afterBytes":
|
|
504
|
+
"beforeBytes": 8274,
|
|
505
|
+
"afterBytes": 4389
|
|
486
506
|
},
|
|
487
507
|
{
|
|
488
508
|
"file": "src/commands/pair-qr.js",
|
|
@@ -491,8 +511,13 @@
|
|
|
491
511
|
},
|
|
492
512
|
{
|
|
493
513
|
"file": "src/commands/pair.js",
|
|
494
|
-
"beforeBytes":
|
|
495
|
-
"afterBytes":
|
|
514
|
+
"beforeBytes": 16665,
|
|
515
|
+
"afterBytes": 9147
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"file": "src/commands/project.js",
|
|
519
|
+
"beforeBytes": 5588,
|
|
520
|
+
"afterBytes": 3743
|
|
496
521
|
},
|
|
497
522
|
{
|
|
498
523
|
"file": "src/commands/queue.js",
|
|
@@ -514,11 +539,21 @@
|
|
|
514
539
|
"beforeBytes": 1288,
|
|
515
540
|
"afterBytes": 936
|
|
516
541
|
},
|
|
542
|
+
{
|
|
543
|
+
"file": "src/commands/setup.js",
|
|
544
|
+
"beforeBytes": 16589,
|
|
545
|
+
"afterBytes": 12325
|
|
546
|
+
},
|
|
517
547
|
{
|
|
518
548
|
"file": "src/commands/skill.js",
|
|
519
549
|
"beforeBytes": 1616,
|
|
520
550
|
"afterBytes": 991
|
|
521
551
|
},
|
|
552
|
+
{
|
|
553
|
+
"file": "src/commands/steward.js",
|
|
554
|
+
"beforeBytes": 3628,
|
|
555
|
+
"afterBytes": 1852
|
|
556
|
+
},
|
|
522
557
|
{
|
|
523
558
|
"file": "src/commands/support.js",
|
|
524
559
|
"beforeBytes": 5435,
|
|
@@ -546,8 +581,8 @@
|
|
|
546
581
|
},
|
|
547
582
|
{
|
|
548
583
|
"file": "src/daemon-ipc/agent-readiness.js",
|
|
549
|
-
"beforeBytes":
|
|
550
|
-
"afterBytes":
|
|
584
|
+
"beforeBytes": 5262,
|
|
585
|
+
"afterBytes": 2622
|
|
551
586
|
},
|
|
552
587
|
{
|
|
553
588
|
"file": "src/daemon-ipc/client.js",
|
|
@@ -556,8 +591,8 @@
|
|
|
556
591
|
},
|
|
557
592
|
{
|
|
558
593
|
"file": "src/daemon-ipc/control.js",
|
|
559
|
-
"beforeBytes":
|
|
560
|
-
"afterBytes":
|
|
594
|
+
"beforeBytes": 5406,
|
|
595
|
+
"afterBytes": 3042
|
|
561
596
|
},
|
|
562
597
|
{
|
|
563
598
|
"file": "src/daemon-ipc/json.js",
|
|
@@ -626,8 +661,8 @@
|
|
|
626
661
|
},
|
|
627
662
|
{
|
|
628
663
|
"file": "src/index.js",
|
|
629
|
-
"beforeBytes":
|
|
630
|
-
"afterBytes":
|
|
664
|
+
"beforeBytes": 45702,
|
|
665
|
+
"afterBytes": 22628
|
|
631
666
|
},
|
|
632
667
|
{
|
|
633
668
|
"file": "src/log-redaction.js",
|
|
@@ -1046,8 +1081,8 @@
|
|
|
1046
1081
|
},
|
|
1047
1082
|
{
|
|
1048
1083
|
"file": "src/session/handlers/chat-adapter-config.js",
|
|
1049
|
-
"beforeBytes":
|
|
1050
|
-
"afterBytes":
|
|
1084
|
+
"beforeBytes": 3004,
|
|
1085
|
+
"afterBytes": 1276
|
|
1051
1086
|
},
|
|
1052
1087
|
{
|
|
1053
1088
|
"file": "src/session/handlers/chat-context.js",
|
|
@@ -1056,8 +1091,8 @@
|
|
|
1056
1091
|
},
|
|
1057
1092
|
{
|
|
1058
1093
|
"file": "src/session/handlers/chat-events.js",
|
|
1059
|
-
"beforeBytes":
|
|
1060
|
-
"afterBytes":
|
|
1094
|
+
"beforeBytes": 20196,
|
|
1095
|
+
"afterBytes": 8099
|
|
1061
1096
|
},
|
|
1062
1097
|
{
|
|
1063
1098
|
"file": "src/session/handlers/chat-recovery.js",
|
|
@@ -1066,13 +1101,13 @@
|
|
|
1066
1101
|
},
|
|
1067
1102
|
{
|
|
1068
1103
|
"file": "src/session/handlers/chat-session-lifecycle.js",
|
|
1069
|
-
"beforeBytes":
|
|
1070
|
-
"afterBytes":
|
|
1104
|
+
"beforeBytes": 4614,
|
|
1105
|
+
"afterBytes": 2217
|
|
1071
1106
|
},
|
|
1072
1107
|
{
|
|
1073
1108
|
"file": "src/session/handlers/chat.js",
|
|
1074
|
-
"beforeBytes":
|
|
1075
|
-
"afterBytes":
|
|
1109
|
+
"beforeBytes": 36868,
|
|
1110
|
+
"afterBytes": 15693
|
|
1076
1111
|
},
|
|
1077
1112
|
{
|
|
1078
1113
|
"file": "src/session/handlers/control.js",
|
|
@@ -1109,6 +1144,11 @@
|
|
|
1109
1144
|
"beforeBytes": 979,
|
|
1110
1145
|
"afterBytes": 451
|
|
1111
1146
|
},
|
|
1147
|
+
{
|
|
1148
|
+
"file": "src/session/handlers/steward.js",
|
|
1149
|
+
"beforeBytes": 7468,
|
|
1150
|
+
"afterBytes": 3596
|
|
1151
|
+
},
|
|
1112
1152
|
{
|
|
1113
1153
|
"file": "src/session/handlers/title.js",
|
|
1114
1154
|
"beforeBytes": 3146,
|
|
@@ -1141,8 +1181,8 @@
|
|
|
1141
1181
|
},
|
|
1142
1182
|
{
|
|
1143
1183
|
"file": "src/session/manager.js",
|
|
1144
|
-
"beforeBytes":
|
|
1145
|
-
"afterBytes":
|
|
1184
|
+
"beforeBytes": 41740,
|
|
1185
|
+
"afterBytes": 21934
|
|
1146
1186
|
},
|
|
1147
1187
|
{
|
|
1148
1188
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -1206,8 +1246,8 @@
|
|
|
1206
1246
|
},
|
|
1207
1247
|
{
|
|
1208
1248
|
"file": "src/session/queue.js",
|
|
1209
|
-
"beforeBytes":
|
|
1210
|
-
"afterBytes":
|
|
1249
|
+
"beforeBytes": 43664,
|
|
1250
|
+
"afterBytes": 19298
|
|
1211
1251
|
},
|
|
1212
1252
|
{
|
|
1213
1253
|
"file": "src/session/queued-chat-dispatch.js",
|
|
@@ -1246,8 +1286,8 @@
|
|
|
1246
1286
|
},
|
|
1247
1287
|
{
|
|
1248
1288
|
"file": "src/session/store.js",
|
|
1249
|
-
"beforeBytes":
|
|
1250
|
-
"afterBytes":
|
|
1289
|
+
"beforeBytes": 34234,
|
|
1290
|
+
"afterBytes": 17184
|
|
1251
1291
|
},
|
|
1252
1292
|
{
|
|
1253
1293
|
"file": "src/session/tool-detail-store.js",
|
|
@@ -1264,10 +1304,35 @@
|
|
|
1264
1304
|
"beforeBytes": 164,
|
|
1265
1305
|
"afterBytes": 1
|
|
1266
1306
|
},
|
|
1307
|
+
{
|
|
1308
|
+
"file": "src/skill/hosts.js",
|
|
1309
|
+
"beforeBytes": 3462,
|
|
1310
|
+
"afterBytes": 1577
|
|
1311
|
+
},
|
|
1267
1312
|
{
|
|
1268
1313
|
"file": "src/skill/updater.js",
|
|
1269
|
-
"beforeBytes":
|
|
1270
|
-
"afterBytes":
|
|
1314
|
+
"beforeBytes": 18411,
|
|
1315
|
+
"afterBytes": 9229
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
"file": "src/steward/failover.js",
|
|
1319
|
+
"beforeBytes": 3819,
|
|
1320
|
+
"afterBytes": 2378
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
"file": "src/steward/session.js",
|
|
1324
|
+
"beforeBytes": 2700,
|
|
1325
|
+
"afterBytes": 1758
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
"file": "src/steward/templates.js",
|
|
1329
|
+
"beforeBytes": 4650,
|
|
1330
|
+
"afterBytes": 7878
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
"file": "src/steward/workspace.js",
|
|
1334
|
+
"beforeBytes": 3881,
|
|
1335
|
+
"afterBytes": 1828
|
|
1271
1336
|
},
|
|
1272
1337
|
{
|
|
1273
1338
|
"file": "src/support/support-client.js",
|
|
@@ -1291,8 +1356,13 @@
|
|
|
1291
1356
|
},
|
|
1292
1357
|
{
|
|
1293
1358
|
"file": "src/upgrade/engine.js",
|
|
1294
|
-
"beforeBytes":
|
|
1295
|
-
"afterBytes":
|
|
1359
|
+
"beforeBytes": 16784,
|
|
1360
|
+
"afterBytes": 7123
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
"file": "src/upgrade/npm-command.js",
|
|
1364
|
+
"beforeBytes": 1670,
|
|
1365
|
+
"afterBytes": 566
|
|
1296
1366
|
},
|
|
1297
1367
|
{
|
|
1298
1368
|
"file": "src/upgrade/scheduler.js",
|
|
@@ -1306,8 +1376,8 @@
|
|
|
1306
1376
|
},
|
|
1307
1377
|
{
|
|
1308
1378
|
"file": "src/upgrade/updater-launcher.js",
|
|
1309
|
-
"beforeBytes":
|
|
1310
|
-
"afterBytes":
|
|
1379
|
+
"beforeBytes": 10380,
|
|
1380
|
+
"afterBytes": 5299
|
|
1311
1381
|
},
|
|
1312
1382
|
{
|
|
1313
1383
|
"file": "src/upgrade/updater-protocol.js",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{randomUUID as
|
|
1
|
+
import{randomUUID as S}from"node:crypto";import{createHash as I}from"node:crypto";import{readFileSync as P,realpathSync as w,statSync as b}from"node:fs";import{pathToFileURL as q}from"node:url";import*as l from"@agentclientprotocol/sdk";import{RequestError as T}from"@agentclientprotocol/sdk";import{AgentAdapter as E,registerAgent as x,summarizeToolInput as O}from"../adapter.js";import{mapAcpSessionUpdate as _}from"./events.js";import{AcpProcessClient as k}from"./process-client.js";import{acpAgentType as C}from"./types.js";import{runAcpTerminalAuthentication as M}from"./auth.js";import{setAcpRuntimeAuthState as p}from"./auth-state.js";import{recordAcpAuthFailure as R,recordAcpImportResult as v}from"./metrics.js";import{isManagedAgentNativeFull as m}from"../../security/managed-agent-policy.js";import{buildManagedNativeFullProcessEnv as F}from"../../agent-env.js";import{assertPublicAgentPolicy as U}from"../../security/public-agent-policy.js";const D=10*1024*1024;function $(r){if(r.kind!=="image"||!r.mimeType.startsWith("image/"))return null;let e=r.previewData?.trim()??"";const t=e.indexOf(",");if(e.startsWith("data:")&&t>=0&&(e=e.slice(t+1)),!e&&r.path&&!/^https?:\/\//i.test(r.path))try{const s=b(r.path);s.isFile()&&s.size<=D&&(e=P(r.path).toString("base64"))}catch{e=""}return e?{data:e}:null}function g(r,e){return r.find(t=>t.category===e&&t.type==="select")}function f(r){return(r?.options??[]).flatMap(e=>"options"in e?e.options:[e])}class H extends E{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;publicTurn=!1;baseConfigurationSignature="";startedConfigurationSignature="";constructor(e,t={}){super(),this.manifest=e,this.options=t,this.type=C(e.id)}configure(e){this.extraEnv=e.env??{},this.managedAgentPolicy=e.managedAgentPolicy??null,this.baseConfigurationSignature=I("sha256").update(JSON.stringify({env:Object.entries(this.extraEnv).sort(([t],[s])=>t.localeCompare(s)),managedAgentPolicy:this.managedAgentPolicy})).digest("hex")}get configurationSignature(){return`${this.baseConfigurationSignature}:${this.publicTurn?"public":"room"}`}async start(e,t,s){this.shennianSessionId=e;try{this.workDir=w.native(t)}catch{this.workDir=t}this.requestedSessionId=s??null,this.agentSessionId=null,this.client=this.createProcessClient(),await this.client.start(this.workDir),this.startedConfigurationSignature=this.configurationSignature}async send(e,t,s,i,n,a){a?.source==="published_agent"&&U(this.managedAgentPolicy),this.publicTurn=a?.source==="published_agent",await this.refreshProcessConfiguration();const u=this.requireClient();this.runId=S(),this.seq=0,this.emittedToolStates.clear();try{await this.ensureSession(),await this.applyDynamicConfig(t,s),this.active=!0,this.emitEvent({state:"start",runPhase:"thinking",agentSessionId:this.agentSessionId??void 0});const o=[],h=[];n?.trim()&&h.push(n.trim()),h.push(e),o.push({type:"text",text:h.join(`
|
|
2
2
|
|
|
3
|
-
`)});for(const d of i??[])o.push({type:"resource_link",uri:v(d.path).href,name:d.name,mimeType:d.mimeType,size:d.byteSize});const h=await this.promptWithTimeout(u,o);this.active=!1,h.stopReason==="cancelled"?this.emitEvent({state:"aborted",agentSessionId:this.agentSessionId??void 0}):this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0})}catch(o){this.active=!1,this.cancelPendingPermissions();const c=o instanceof Error?o.message:String(o),h=o instanceof A&&o.code===-32e3;throw h&&(p(this.type,"required"),this.retryingAfterAuth||(this.pendingAuthRetry={text:e,...t?{modelId:t}:{},...n?{reasoningEffort:n}:{},...i?{attachments:[...i]}:{},...s!==void 0?{systemPrompt:s}:{}})),this.emitEvent({state:"error",message:c,...h?{errorCode:"acp_auth_required"}:{},agentSessionId:this.agentSessionId??void 0}),o}}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(a.methods.agent.session.cancel,{sessionId:this.agentSessionId}),this.cancelPendingPermissions(),this.active=!1,await this.client?.close(),this.client=null,this.startedConfigurationSignature=""}async getStatus(){return{active:this.active,runId:this.active?this.runId:null,canStop:this.active}}async respondToPermission(e,t){const n=this.pendingPermissions.get(e);if(!n)throw new Error("ACP permission request is no longer pending");if(!n.optionIds.has(t))throw new Error("Invalid ACP permission option");this.pendingPermissions.delete(e),clearTimeout(n.timer),n.resolve({outcome:{outcome:"selected",optionId:t}})}getAuthMethods(){return[...this.requireClient().initializeResponse?.authMethods??[]]}hasPendingAuthenticationRetry(){return this.pendingAuthRetry!==null}getSessionOptions(){const e=g(this.configOptions,"model"),t=g(this.configOptions,"thought_level"),n=this.modes?.availableModes.map(s=>({id:s.id,name:s.name,...s.description?{description:s.description}:{}}))??[],i=(t?f(t):n).map(s=>({id:"value"in s?s.value:s.id,name:s.name,...s.description?{description:s.description}:{}}));return{models:f(e).map(s=>({id:s.value,name:s.name,...s.description?{description:s.description}:{},...s.value===e?.currentValue?{isDefault:!0}:{},...i.length?{supportedReasoningEfforts:i}:{}})),modes:n}}async authenticate(e,t={}){const n=this.requireClient(),i=n.initializeResponse?.authMethods?.find(s=>s.id===e);if(!i)throw new Error("ACP authentication method is unavailable");try{if("type"in i&&i.type==="terminal"){if(!t.interactiveTerminal)throw new Error("ACP terminal authentication must be completed on the target machine with `shennian agent auth`");await n.close(),await T({...this.manifest.authLaunch??this.manifest.launch,env:Object.fromEntries(Object.entries({...this.extraEnv,...this.manifest.authLaunch?.env??this.manifest.launch.env}).filter(s=>typeof s[1]=="string"))},i,this.workDir)}else await n.authenticate(e);await this.resumeAfterExternalAuthentication()}catch(s){throw x(),s}}async logout(){await this.requireClient().logout(),p(this.type,"required")}async resumeAfterExternalAuthentication(){await this.client?.close(),this.client=this.createProcessClient(),await this.client.start(this.workDir),this.startedConfigurationSignature=this.configurationSignature,p(this.type,"ready");const e=this.pendingAuthRetry;this.pendingAuthRetry=null,e&&this.retryAfterAuthentication(e)}async listExternalSessions(e={}){const t=this.requireClient();if(!t.capabilities.sessionCapabilities?.list)return[];const n=[];let i;for(let s=0;s<10&&n.length<500;s+=1){let r=e.cwd;if(r)try{r=w.native(r)}catch{}const u=await t.listSessions(r,i);if(n.push(...u.sessions.slice(0,500-n.length).map(o=>({agentSessionId:o.sessionId,cwd:o.cwd,...o.title?{title:o.title.slice(0,200)}:{},...o.updatedAt?{updatedAt:o.updatedAt}:{}}))),i=u.nextCursor,!i)break}return n}async loadExternalSession(e){const t=this.requireClient();if(!t.capabilities.loadSession)throw new Error("ACP session history import is unsupported");this.requestedSessionId=e,this.agentSessionId=e;const n=[];this.importCapture=n;try{const i=await t.agent.request(a.methods.agent.session.load,{sessionId:e,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null,C(!0)}catch(i){throw C(!1),i}finally{this.importCapture=null}return n.map((i,s)=>({sourceId:i.sourceHint??S("sha256").update(`${e}\0${s}\0${i.role}\0${i.payload}`).digest("hex"),role:i.role,payload:i.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 n=e.capabilities;if(n.sessionCapabilities?.resume){const i=await e.agent.request(a.methods.agent.session.resume,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null}else if(n.loadSession){this.agentSessionId=this.requestedSessionId;const i=await e.agent.request(a.methods.agent.session.load,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null}else throw new Error(`${this.manifest.name} cannot resume ACP sessions`);this.agentSessionId=this.requestedSessionId,this.emit("sessionOptions");return}const t=await e.agent.request(a.methods.agent.session.new,{cwd:this.workDir,mcpServers:[]});this.agentSessionId=t.sessionId,this.configOptions=t.configOptions??[],this.modes=t.modes??null,this.emit("sessionOptions")}async applyDynamicConfig(e,t){if(!this.agentSessionId)return;t&&this.modes?.availableModes.some(i=>i.id===t)&&(this.modes.currentModeId!==t&&(await this.requireClient().agent.request(a.methods.agent.session.setMode,{sessionId:this.agentSessionId,modeId:t}),this.modes.currentModeId=t),t=void 0);const n=[{category:"model",value:e},{category:"thought_level",value:t}];for(const i of n){if(!i.value)continue;const s=g(this.configOptions,i.category);!s||s.currentValue===i.value||f(s).some(r=>r.value===i.value)&&(await this.requireClient().agent.request(a.methods.agent.session.setConfigOption,{sessionId:this.agentSessionId,configId:s.id,value:i.value}),s.currentValue=i.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 t=JSON.stringify(e.update);if(this.emittedToolStates.get(e.update.toolCallId)===t)return;this.emittedToolStates.set(e.update.toolCallId,t)}for(const t of q(e.update,n=>this.makeEvent(n)))this.emit("agentEvent",t)}}}captureImportedUpdate(e){if(this.importCapture){if(e.sessionUpdate==="user_message_chunk"||e.sessionUpdate==="agent_message_chunk"){const t=e.content.type==="text"?e.content.text:e.content.type==="resource_link"?e.content.name||e.content.uri:`[${e.content.type}]`,n=e.sessionUpdate==="user_message_chunk"?"user":"agent",i=e.messageId?`message:${e.messageId}`:void 0,s=i?this.importCapture.find(r=>r.sourceHint===i):this.importCapture.at(-1);s?.role===n&&s.sourceHint===i?s.payload+=t:this.importCapture.push({role:n,payload:t,...i?{sourceHint:i}:{}});return}if(e.sessionUpdate==="tool_call"){const t=`tool:${e.toolCallId}`,n=this.importCapture.find(s=>s.sourceHint===t),i={role:"agent",sourceHint:t,payload:JSON.stringify({v:1,type:"tool_use",name:e.title,toolCallId:e.toolCallId,status:e.status??"running"})};n?n.payload=i.payload:this.importCapture.push(i);return}if(e.sessionUpdate==="tool_call_update"&&(e.status==="completed"||e.status==="failed")){const t=this.importCapture.find(i=>i.sourceHint===`tool:${e.toolCallId}`),n=JSON.stringify({v:1,type:"tool_result",name:e.title??"tool",toolCallId:e.toolCallId,status:e.status});t?t.payload=n:this.importCapture.push({role:"agent",sourceHint:`tool:${e.toolCallId}`,payload:n})}}}handlePermission(e){if(!this.active||e.sessionId!==this.agentSessionId)return Promise.resolve({outcome:{outcome:"cancelled"}});const t=y();return new Promise(n=>{const i=setTimeout(()=>{this.pendingPermissions.delete(t),n({outcome:{outcome:"cancelled"}})},this.options.permissionTimeoutMs??3e5);i.unref?.(),this.pendingPermissions.set(t,{optionIds:new Set(e.options.map(s=>s.optionId)),resolve:n,timer:i}),this.emitEvent({state:"approval-pending",runPhase:"waiting_approval",approval:{title:e.toolCall.title??void 0,source:this.manifest.name},permission:{id:t,sessionId:this.shennianSessionId,agentSessionId:this.agentSessionId??void 0,runId:this.runId,toolCallId:e.toolCall.toolCallId,options:e.options.map(s=>({id:s.optionId,name:s.name,kind:s.kind}))}})})}requireClient(){if(!this.client)throw new Error("ACP adapter has not started");return this.client}createProcessClient(){return new E(this.manifest.launch,{onSessionUpdate:e=>this.handleSessionUpdate(e),onPermission:e=>this.handlePermission(e)},this.buildEnvironment(),{...this.buildClientCapabilities(),terminalAuth:!0})}async refreshProcessConfiguration(){if(!this.client||this.startedConfigurationSignature===this.configurationSignature)return;const e=this.agentSessionId??this.requestedSessionId;await this.client.close(),this.requestedSessionId=e,this.agentSessionId=null,this.configOptions=[],this.modes=null,this.client=this.createProcessClient(),await this.client.start(this.workDir),this.startedConfigurationSignature=this.configurationSignature}buildEnvironment(){return this.managedAgentPolicy?m(this.managedAgentPolicy)?O(this.extraEnv):{...this.extraEnv}:{...process.env,...this.extraEnv}}buildClientCapabilities(){const e=this.manifest.clientCapabilities??{},t=this.managedAgentPolicy?.adapterPolicy;return t?this.publicTurn?m(this.managedAgentPolicy)?{readTextFile:!!e.readTextFile,writeTextFile:!!e.writeTextFile,terminal:!1}:{readTextFile:!1,writeTextFile:!1,terminal:!1}:m(this.managedAgentPolicy)?{...e,terminal:!0,terminalPolicy:"managed-room-only"}:{readTextFile:!!e.readTextFile,writeTextFile:!!(e.writeTextFile&&t.fileAccess!=="workspace-read"),terminal:!0,terminalPolicy:"managed-room-only"}: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,t){let n;try{return await Promise.race([e.agent.request(a.methods.agent.session.prompt,{sessionId:this.agentSessionId,prompt:t}),new Promise((i,s)=>{n=setTimeout(()=>s(new Error("ACP prompt timed out")),this.options.promptTimeoutMs??720*6e4),n.unref?.()})])}catch(i){throw i instanceof Error&&i.message==="ACP prompt timed out"&&(await e.close(),this.client===e&&(this.client=null)),i}finally{n&&clearTimeout(n)}}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 G(l){b(I(l.id),()=>new k(l))}export{k as AcpAgentAdapter,G as registerAcpAgent};
|
|
3
|
+
`)});const d=u.capabilities.promptCapabilities?.image===!0;for(const c of i??[]){const y=d?$(c):null;y&&o.push({type:"image",data:y.data,mimeType:c.mimeType}),o.push({type:"resource_link",uri:q(c.path).href,name:c.name,mimeType:c.mimeType,size:c.byteSize})}const A=await this.promptWithTimeout(u,o);this.active=!1,A.stopReason==="cancelled"?this.emitEvent({state:"aborted",agentSessionId:this.agentSessionId??void 0}):this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0})}catch(o){this.active=!1,this.cancelPendingPermissions();const h=o instanceof Error?o.message:String(o),d=o instanceof T&&o.code===-32e3;throw d&&(p(this.type,"required"),this.retryingAfterAuth||(this.pendingAuthRetry={text:e,...t?{modelId:t}:{},...s?{reasoningEffort:s}:{},...i?{attachments:[...i]}:{},...n!==void 0?{systemPrompt:n}:{}})),this.emitEvent({state:"error",message:h,...d?{errorCode:"acp_auth_required"}:{},agentSessionId:this.agentSessionId??void 0}),o}}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,this.startedConfigurationSignature=""}async getStatus(){return{active:this.active,runId:this.active?this.runId:null,canStop:this.active}}async respondToPermission(e,t){const s=this.pendingPermissions.get(e);if(!s)throw new Error("ACP permission request is no longer pending");if(!s.optionIds.has(t))throw new Error("Invalid ACP permission option");this.pendingPermissions.delete(e),clearTimeout(s.timer),s.resolve({outcome:{outcome:"selected",optionId:t}})}getAuthMethods(){return[...this.requireClient().initializeResponse?.authMethods??[]]}hasPendingAuthenticationRetry(){return this.pendingAuthRetry!==null}getSessionOptions(){const e=g(this.configOptions,"model"),t=g(this.configOptions,"thought_level"),s=this.modes?.availableModes.map(n=>({id:n.id,name:n.name,...n.description?{description:n.description}:{}}))??[],i=(t?f(t):s).map(n=>({id:"value"in n?n.value:n.id,name:n.name,...n.description?{description:n.description}:{}}));return{models:f(e).map(n=>({id:n.value,name:n.name,...n.description?{description:n.description}:{},...n.value===e?.currentValue?{isDefault:!0}:{},...i.length?{supportedReasoningEfforts:i}:{}})),modes:s}}async authenticate(e,t={}){const s=this.requireClient(),i=s.initializeResponse?.authMethods?.find(n=>n.id===e);if(!i)throw new Error("ACP authentication method is unavailable");try{if("type"in i&&i.type==="terminal"){if(!t.interactiveTerminal)throw new Error("ACP terminal authentication must be completed on the target machine with `shennian agent auth`");await s.close(),await M({...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"))},i,this.workDir)}else await s.authenticate(e);await this.resumeAfterExternalAuthentication()}catch(n){throw R(),n}}async logout(){await this.requireClient().logout(),p(this.type,"required")}async resumeAfterExternalAuthentication(){await this.client?.close(),this.client=this.createProcessClient(),await this.client.start(this.workDir),this.startedConfigurationSignature=this.configurationSignature,p(this.type,"ready");const e=this.pendingAuthRetry;this.pendingAuthRetry=null,e&&this.retryAfterAuthentication(e)}async listExternalSessions(e={}){const t=this.requireClient();if(!t.capabilities.sessionCapabilities?.list)return[];const s=[];let i;for(let n=0;n<10&&s.length<500;n+=1){let a=e.cwd;if(a)try{a=w.native(a)}catch{}const u=await t.listSessions(a,i);if(s.push(...u.sessions.slice(0,500-s.length).map(o=>({agentSessionId:o.sessionId,cwd:o.cwd,...o.title?{title:o.title.slice(0,200)}:{},...o.updatedAt?{updatedAt:o.updatedAt}:{}}))),i=u.nextCursor,!i)break}return s}async loadExternalSession(e){const t=this.requireClient();if(!t.capabilities.loadSession)throw new Error("ACP session history import is unsupported");this.requestedSessionId=e,this.agentSessionId=e;const s=[];this.importCapture=s;try{const i=await t.agent.request(l.methods.agent.session.load,{sessionId:e,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null,v(!0)}catch(i){throw v(!1),i}finally{this.importCapture=null}return s.map((i,n)=>({sourceId:i.sourceHint??I("sha256").update(`${e}\0${n}\0${i.role}\0${i.payload}`).digest("hex"),role:i.role,payload:i.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 i=await e.agent.request(l.methods.agent.session.resume,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null}else if(s.loadSession){this.agentSessionId=this.requestedSessionId;const i=await e.agent.request(l.methods.agent.session.load,{sessionId:this.requestedSessionId,cwd:this.workDir,mcpServers:[]});this.configOptions=i.configOptions??[],this.modes=i.modes??null}else throw new Error(`${this.manifest.name} cannot resume ACP sessions`);this.agentSessionId=this.requestedSessionId,this.emit("sessionOptions");return}const t=await e.agent.request(l.methods.agent.session.new,{cwd:this.workDir,mcpServers:[]});this.agentSessionId=t.sessionId,this.configOptions=t.configOptions??[],this.modes=t.modes??null,this.emit("sessionOptions")}async applyDynamicConfig(e,t){if(!this.agentSessionId)return;t&&this.modes?.availableModes.some(i=>i.id===t)&&(this.modes.currentModeId!==t&&(await this.requireClient().agent.request(l.methods.agent.session.setMode,{sessionId:this.agentSessionId,modeId:t}),this.modes.currentModeId=t),t=void 0);const s=[{category:"model",value:e},{category:"thought_level",value:t}];for(const i of s){if(!i.value)continue;const n=g(this.configOptions,i.category);!n||n.currentValue===i.value||f(n).some(a=>a.value===i.value)&&(await this.requireClient().agent.request(l.methods.agent.session.setConfigOption,{sessionId:this.agentSessionId,configId:n.id,value:i.value}),n.currentValue=i.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 t=JSON.stringify(e.update);if(this.emittedToolStates.get(e.update.toolCallId)===t)return;this.emittedToolStates.set(e.update.toolCallId,t)}for(const t of _(e.update,s=>this.makeEvent(s)))this.emit("agentEvent",t)}}}captureImportedUpdate(e){if(this.importCapture){if(e.sessionUpdate==="user_message_chunk"||e.sessionUpdate==="agent_message_chunk"){const t=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",i=e.messageId?`message:${e.messageId}`:void 0,n=i?this.importCapture.find(a=>a.sourceHint===i):this.importCapture.at(-1);n?.role===s&&n.sourceHint===i?n.payload+=t:this.importCapture.push({role:s,payload:t,...i?{sourceHint:i}:{}});return}if(e.sessionUpdate==="tool_call"){const t=`tool:${e.toolCallId}`,s=this.importCapture.find(n=>n.sourceHint===t),i={role:"agent",sourceHint:t,payload:JSON.stringify({v:1,type:"tool_use",name:e.title,toolCallId:e.toolCallId,status:e.status??"running"})};s?s.payload=i.payload:this.importCapture.push(i);return}if(e.sessionUpdate==="tool_call_update"&&(e.status==="completed"||e.status==="failed")){const t=this.importCapture.find(i=>i.sourceHint===`tool:${e.toolCallId}`),s=JSON.stringify({v:1,type:"tool_result",name:e.title??"tool",toolCallId:e.toolCallId,status:e.status});t?t.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 t=S();return new Promise(s=>{const i=setTimeout(()=>{this.pendingPermissions.delete(t),s({outcome:{outcome:"cancelled"}})},this.options.permissionTimeoutMs??3e5);i.unref?.(),this.pendingPermissions.set(t,{optionIds:new Set(e.options.map(n=>n.optionId)),resolve:s,timer:i}),this.emitEvent({state:"approval-pending",runPhase:"waiting_approval",approval:{title:e.toolCall.title??void 0,content:O(e.toolCall.rawInput),source:this.manifest.name},permission:{id:t,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}createProcessClient(){return new k(this.manifest.launch,{onSessionUpdate:e=>this.handleSessionUpdate(e),onPermission:e=>this.handlePermission(e)},this.buildEnvironment(),{...this.buildClientCapabilities(),terminalAuth:!0})}async refreshProcessConfiguration(){if(!this.client||this.startedConfigurationSignature===this.configurationSignature)return;const e=this.agentSessionId??this.requestedSessionId;await this.client.close(),this.requestedSessionId=e,this.agentSessionId=null,this.configOptions=[],this.modes=null,this.client=this.createProcessClient(),await this.client.start(this.workDir),this.startedConfigurationSignature=this.configurationSignature}buildEnvironment(){return this.managedAgentPolicy?m(this.managedAgentPolicy)?F(this.extraEnv):{...this.extraEnv}:{...process.env,...this.extraEnv}}buildClientCapabilities(){const e=this.manifest.clientCapabilities??{},t=this.managedAgentPolicy?.adapterPolicy;return t?this.publicTurn?m(this.managedAgentPolicy)?{readTextFile:!!e.readTextFile,writeTextFile:!!e.writeTextFile,terminal:!1}:{readTextFile:!1,writeTextFile:!1,terminal:!1}:m(this.managedAgentPolicy)?{...e,terminal:!0,terminalPolicy:"managed-room-only"}:{readTextFile:!!e.readTextFile,writeTextFile:!!(e.writeTextFile&&t.fileAccess!=="workspace-read"),terminal:!0,terminalPolicy:"managed-room-only"}: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,t){let s;try{return await Promise.race([e.agent.request(l.methods.agent.session.prompt,{sessionId:this.agentSessionId,prompt:t}),new Promise((i,n)=>{s=setTimeout(()=>n(new Error("ACP prompt timed out")),this.options.promptTimeoutMs??720*6e4),s.unref?.()})])}catch(i){throw i instanceof Error&&i.message==="ACP prompt timed out"&&(await e.close(),this.client===e&&(this.client=null)),i}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 te(r){x(C(r.id),()=>new H(r))}export{H as AcpAgentAdapter,te as registerAcpAgent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RequestError as
|
|
1
|
+
import{RequestError as P}from"@agentclientprotocol/sdk";import{buildCommandStringLaunchSpec as D,commandExists as L,resolveCommandFileIdentity as N,resolveCommandFilePath as _}from"../command-spec.js";import{registerAcpAgent as B}from"./adapter.js";import{getRegisteredAgents as q,unregisterAgent as K}from"../adapter.js";import{readAcpManifests as U}from"./manifests.js";import{AcpProcessClient as H}from"./process-client.js";import{acpAgentType as p}from"./types.js";import{loadAcpCatalog as O}from"./catalog.js";import{buildAcpCapabilityCacheKey as W,readAcpCapabilityCache as $,writeAcpCapabilityCache as V}from"./capability-cache.js";import{getAcpRuntimeAuthState as k,setAcpRuntimeAuthState as j}from"./auth-state.js";import{recordAcpScan as z}from"./metrics.js";import{fingerprintNativeExecutable as G}from"../../security/managed-agent-executable.js";const J=[{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"]}},{id:"dsh",name:"DSH",source:"registry",launch:{command:"dsh",args:["--profile","acp"]}}];let A=[];function de(){return A.map(t=>({...t,args:[...t.args]}))}const Q=new Set(["claude","codex","codebuddy","cursor","opencode","pi"]);async function fe(t={}){const a=Date.now();let o=0,n=0;const r={},g=new Set(q().filter(e=>e.startsWith("acp:"))),l=t.candidates?{candidates:t.candidates,revision:void 0}:await O(t),S=Y([...l.candidates.length?l.candidates:J,...U()]).filter(e=>!t.agentType||p(e.id)===t.agentType),M=S.filter(e=>{const s=e.launch.command;return Q.has(s)?!1:L(s)}).filter((e,s,d)=>d.findIndex(C=>C.id===e.id)===s),b=[],y=(await Z(M,3,async e=>{const s=_(e.launch.command),d=s?G(s):void 0,u={...D(e.launch.command,e.launch.args??[],t.cwd??process.cwd()),...e.launch.env?{env:e.launch.env}:{}},v=W({manifest:e,platform:process.platform,catalogRevision:l.revision,executableIdentity:N(e.launch.command)}),f=v?$(v):null;if(f?.type===p(e.id)&&f.integration==="acp"&&f.acpCapabilities?.protocolVersion===1)return o+=1,B({...e,launch:u,authLaunch:e.launch}),{...f,authState:k(p(e.id))??f.authState,command:u.command,args:u.args??[],executableFingerprint:d,display:{...f.display,name:e.name},...l.revision?{catalogRevision:l.revision}:{}};const w=new H(u,{onSessionUpdate:()=>{},onPermission:async()=>({outcome:{outcome:"cancelled"}})},process.env,{terminalAuth:!0});try{const c=await w.start(t.cwd??process.cwd()),i=c.agentCapabilities??{},F={protocolVersion:1,listSessions:!!i.sessionCapabilities?.list,loadSession:!!i.loadSession,resumeSession:!!i.sessionCapabilities?.resume,closeSession:!!i.sessionCapabilities?.close,deleteSession:!!i.sessionCapabilities?.delete,terminal:!!e.clientCapabilities?.terminal,fileRead:!!e.clientCapabilities?.readTextFile,fileWrite:!!e.clientCapabilities?.writeTextFile,permission:!0,modelConfig:!1};let h=c.authMethods?.length?"unknown":"ready";if(i.sessionCapabilities?.list)try{await w.listSessions(t.cwd??process.cwd()),h=c.authMethods?.length?"unknown":"ready"}catch(m){h=m instanceof P&&m.code===-32e3?"required":"unknown"}const I=k(p(e.id));I?h=I:h==="required"&&j(p(e.id),h),B({...e,launch:u,authLaunch:e.launch});const T={type:p(e.id),command:u.command,args:u.args??[],version:c.agentInfo?.version??void 0,runtimePlatform:process.platform,executableFingerprint:d,integration:"acp",display:{name:e.name,version:c.agentInfo?.version??void 0},acpCapabilities:F,authState:h,acpAuthMethods:(c.authMethods??[]).slice(0,8).map(m=>({id:m.id.slice(0,128),name:m.name.slice(0,80),type:"type"in m&&m.type==="terminal"?"terminal":"agent"})),...l.revision?{catalogRevision:l.revision}:{}};return v&&V(v,T),T}catch(c){n+=1;const i=X(c);return r[i]=(r[i]??0)+1,b.push({type:p(e.id),name:e.name,command:e.launch.command,args:[...e.launch.args??[]],reason:i}),null}finally{await w.close()}})).filter(e=>!!e),R=new Set(y.map(e=>e.type)),x=b.filter((e,s,d)=>!R.has(e.type)&&d.findIndex(C=>C.type===e.type)===s);A=t.agentType?[...A.filter(e=>e.type!==t.agentType),...x]:x;const E=new Set(y.map(e=>e.type));for(const e of g)E.has(e)||K(e);return z({durationMs:Date.now()-a,candidateCount:S.length,installedCount:y.length,cacheHits:o,handshakeFailures:n,handshakeFailuresByKind:r}),y}function X(t){const a=t instanceof Error?t.message:"";return/timed out/i.test(a)?"timeout":/protocol version/i.test(a)?"version":/safety limit|exceeded/i.test(a)?"output_limit":/json|parse/i.test(a)?"invalid_protocol":/enoent|not found/i.test(a)?"launch":"other"}function Y(t){const a=new Set(t.filter(n=>n.source==="local").map(n=>n.id)),o=new Map;for(const n of t){if(n.source!=="local"&&a.has(n.id))continue;const r=`${n.id}\0${n.launch.command}\0${JSON.stringify(n.launch.args??[])}`;o.has(r)||o.set(r,n)}return[...o.values()]}async function Z(t,a,o){const n=new Array(t.length);let r=0;return await Promise.all(Array.from({length:Math.min(a,t.length)},async()=>{for(;;){const g=r++;if(g>=t.length)return;n[g]=await o(t[g])}})),n}export{fe as discoverAcpAgents,de as getUnavailableAcpAgents};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{EventEmitter as
|
|
1
|
+
import{EventEmitter as a}from"node:events";import{RECOVERY_CONTINUE_TEXT as u}from"../session/run-recovery/schema.js";const c=/approval|permission|confirm|user[_-]?input|request[_-]?user|ask.*question|exit.*plan/i;function p(t){return typeof t!="string"?!1:c.test(t)}function f(t){if(t==null)return;if(typeof t=="string")return t.trim().slice(0,600)||void 0;const e=typeof t=="object"?t:null;if(e){if(Array.isArray(e.questions)){const n=e.questions.map(s=>s&&typeof s=="object"?s.question:void 0).filter(s=>typeof s=="string"&&s.trim().length>0).join(`
|
|
2
|
+
`);if(n)return n.slice(0,600)}const r=[e.question,e.command,e.file_path,e.path,e.url,e.pattern,e.prompt,e.reason,e.message].find(n=>typeof n=="string"&&n.trim());if(typeof r=="string")return r.trim().slice(0,600)}try{return JSON.stringify(t).slice(0,600)}catch{return}}class m extends a{get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!1}}get supportsActiveInput(){return!1}async inspectInterruptedRun(e){if(!this.getStatus)return{state:"interrupted",providerRunId:e.providerRunId};const r=await this.getStatus().catch(()=>null);return r?.active?{state:"active",providerRunId:r.runId??e.providerRunId,runPhase:r.runPhase}:{state:"interrupted",providerRunId:e.providerRunId}}async recoverInterruptedRun(e){const r=await this.inspectInterruptedRun(e);if(r.state==="terminal"&&this.recoveryCapabilities.inspectTerminal)return{result:"terminal_reconciled"};if(r.state==="active"&&this.recoveryCapabilities.reattachRun)return{result:"reattached"};if(!e.agentSessionId)return{result:"interrupted_by_upgrade",reason:"missing_agent_session"};if(!this.recoveryCapabilities.resumeSession)return{result:"interrupted_by_upgrade",reason:"resume_unsupported"};if(e.continueDispatchState!=="none")return{result:"recovery_failed",reason:"continue_dispatch_outcome_unknown"};try{return e.beforeContinueDispatch?.(),await this.send(u,e.modelId??void 0,e.reasoningEffort??void 0,void 0,e.systemPrompt,e.sendContext),{result:"continued"}}catch(n){const s=n instanceof Error?n.message:String(n),i=s.toLowerCase();return{result:"recovery_failed",reason:i.includes("auth")||i.includes("login")?"authentication_required":i.includes("permission")||i.includes("capability")?"permission_context_unavailable":i.includes("session")&&i.includes("not")?"provider_session_missing":"provider_error",message:s.slice(0,500)}}}}const o=new Map;function g(t,e){o.set(t,e)}function y(t){o.delete(t)}function _(t){const e=o.get(t);return e?e():null}function h(){return[...o.keys()]}export{m as AgentAdapter,_ as createAgent,h as getRegisteredAgents,p as isApprovalLikeName,g as registerAgent,f as summarizeToolInput,y as unregisterAgent};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import a from"node:net";import m from"node:os";import c from"node:path";import{randomBytes as h}from"node:crypto";import{createInterface as l}from"node:readline";class P{onRequest;server=null;socketPath=null;constructor(e){this.onRequest=e}async start(){await this.stop();const e=c.join(m.tmpdir(),`shp${process.pid}-${h(4).toString("hex")}.sock`),r=a.createServer(t=>{l({input:t}).once("line",n=>{let o;try{o=JSON.parse(n)}catch{t.end(`${JSON.stringify({behavior:"deny",message:"shennian_permission_request_malformed"})}
|
|
2
|
+
`);return}this.onRequest(o.toolName,o.input).then(i=>{t.end(`${JSON.stringify(i)}
|
|
3
|
+
`)})})});return await new Promise((t,s)=>{r.once("error",s),r.listen(e,()=>{r.removeListener("error",s),t()})}),this.server=r,this.socketPath=e,e}async stop(){const e=this.server;this.server=null,this.socketPath=null,e&&await new Promise(r=>e.close(()=>r()))}}export{P as ClaudePermissionBridge};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E="approve",_="shennianPermission",S="SHENNIAN_CLAUDE_PERMISSION_SOCKET";export{_ as CLAUDE_PERMISSION_MCP_SERVER_NAME,S as CLAUDE_PERMISSION_SOCKET_ENV,E as CLAUDE_PERMISSION_TOOL_NAME};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import u from"node:net";import{createInterface as c}from"node:readline";import{CLAUDE_PERMISSION_MCP_SERVER_NAME as m,CLAUDE_PERMISSION_SOCKET_ENV as h,CLAUDE_PERMISSION_TOOL_NAME as _}from"./claude-permission-protocol.js";const f=5*6e4;function r(e){process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",...e})}
|
|
2
|
+
`)}function y(e,n){const i=process.env[h];return i?new Promise(p=>{let l=!1;const o=s=>{l||(l=!0,clearTimeout(d),p(s))},d=setTimeout(()=>o({behavior:"deny",message:"shennian_permission_timeout"}),f);d.unref?.();const t=u.connect(i);t.on("error",()=>o({behavior:"deny",message:"shennian_permission_relay_unreachable"})),t.on("connect",()=>t.write(`${JSON.stringify({toolName:e,input:n})}
|
|
3
|
+
`)),c({input:t}).on("line",s=>{try{const a=JSON.parse(s);o({behavior:a.behavior==="allow"?"allow":"deny",updatedInput:a.updatedInput,message:a.message})}catch{o({behavior:"deny",message:"shennian_permission_relay_malformed_response"})}finally{t.end()}})}):Promise.resolve({behavior:"deny",message:"shennian_permission_socket_missing"})}function S(e){if(e.method==="initialize"){r({id:e.id,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:m,version:"1.0.0"}}});return}if(!(e.method==="notifications/initialized"||e.id==null&&e.method?.startsWith("notifications/"))){if(e.method==="tools/list"){r({id:e.id,result:{tools:[{name:_,description:"Relays a Claude Code permission request to the Shennian app for the user to approve.",inputSchema:{type:"object",properties:{tool_name:{type:"string"},input:{type:"object"}},required:["tool_name","input"]}}]}});return}if(e.method==="tools/call"){const n=e.params?.arguments??{};y(n.tool_name,n.input).then(i=>{r({id:e.id,result:{content:[{type:"text",text:JSON.stringify(i)}]}})});return}e.id!=null&&r({id:e.id,error:{code:-32601,message:`Unhandled method: ${e.method}`}})}}const E=c({input:process.stdin});E.on("line",e=>{if(e.trim())try{S(JSON.parse(e))}catch{}});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
${t.stderr??""}`,
|
|
3
|
-
\u2026[truncated]`:e}function
|
|
4
|
-
`):""}class
|
|
5
|
-
`)){const d=u.trim();
|
|
6
|
-
`})}}),s.on("close",
|
|
1
|
+
import g from"node:fs";import l from"node:path";import{createInterface as P}from"node:readline";import{randomUUID as h}from"node:crypto";import{fileURLToPath as E}from"node:url";import{AgentAdapter as C,registerAgent as v,summarizeToolInput as I}from"./adapter.js";import{ClaudePermissionBridge as _}from"./claude-permission-bridge.js";import{CLAUDE_PERMISSION_MCP_SERVER_NAME as f,CLAUDE_PERMISSION_SOCKET_ENV as x,CLAUDE_PERMISSION_TOOL_NAME as w}from"./claude-permission-protocol.js";import{resolveBuiltinCommand as c,spawnAgentCommand as A,spawnResolvedCommandSync as k}from"./command-spec.js";import{spawnEnoentError as R}from"./spawn-errors.js";import{buildAgentProcessEnv as T,buildManagedAgentProcessEnv as M,buildManagedNativeFullProcessEnv as O}from"../agent-env.js";import{buildPlatformInstructions as y}from"./platform-instructions.js";import{resolveManagedAgentAdapterEnforcement as N,isManagedAgentNativeFull as p}from"../security/managed-agent-policy.js";import{assertPublicAgentPolicy as D}from"../security/public-agent-policy.js";import{registerManagedAgentRuntimeSecurity as L}from"../security/managed-agent-runtime.js";import{resolveManagedRoomIpcPaths as U}from"../daemon-ipc/paths.js";import{CLAUDE_MANAGED_RUNTIME_SECURITY as B,compileClaudeManagedPermissions as b}from"./claude-managed-permissions.js";L("claude",B);function $(n){return n?.trim()||"default"}const q=new Set(["low","medium","high","xhigh","max"]),m=new Map;function F(n){const e=n?.trim();if(e){if(q.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function he(){m.clear()}function z(n){const e=n.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function G(){const n=c("claude");if(!n)return!1;const e=`${n.kind}:${n.path}:${n.command}:${n.args.join("\0")}`;if(m.has(e))return m.get(e)??!1;try{const t=k(n,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:process.env}),s=`${t.stdout??""}
|
|
2
|
+
${t.stderr??""}`,r=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return m.set(e,r),r}catch{return m.set(e,!1),!1}}const S=64*1024;function J(n){const e=K(n);return e.length>S?`${e.slice(0,S)}
|
|
3
|
+
\u2026[truncated]`:e}function K(n){return typeof n=="string"?n:Array.isArray(n)?n.map(e=>{if(typeof e=="string")return e;if(typeof e!="object"||e===null)return"";const t=e;return typeof t.text=="string"?t.text:t.type==="image"?"[image]":""}).filter(Boolean).join(`
|
|
4
|
+
`):""}class V extends C{options;type="claude";get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!0}}process=null;agentSessionId=null;sessionId=null;workDir=null;seq=0;runId="";hasEmittedText=!1;toolNames=new Map;terminalState="open";authenticationRetrying=!1;pendingSuccess=null;persistNativeSession=!0;managedAgentPolicy=null;permissionBridge=null;pendingClaudePermissions=new Map;constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{},"managedAgentPolicy"in e&&(this.managedAgentPolicy=e.managedAgentPolicy??null),this.managedAgentPolicy&&(this.workDir=this.managedAgentPolicy.adapterPolicy.workDir)}async start(e,t,s,r){this.sessionId=e,this.workDir=this.managedAgentPolicy?.adapterPolicy.workDir??t,this.seq=0,this.persistNativeSession=r?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,r,a,o){if(o?.source==="published_agent"&&D(this.managedAgentPolicy),o?.source==="room_activation"&&!this.managedAgentPolicy)throw new Error("managed_agent_policy_missing");await this.killProcess(),this.runId=h(),this.resetRunState();const i=["-p",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig(o?.source==="published_agent")?.args??[]];this.persistNativeSession||i.push("--no-session-persistence");const u=this.options.systemPrompt??y(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,a);u&&i.push("--append-system-prompt",u),this.options.hidden&&i.push("--name","Shennian Manager Substrate"),i.push(...await this.buildPermissionModeArgs()),i.push("--model",$(t));const d=F(s);d&&G()&&i.push("--effort",d),this.agentSessionId&&i.push("--resume",this.agentSessionId),this.spawnAndParse(i)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=h(),this.resetRunState();const t=["--resume",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig()?.args??[]],s=this.options.systemPrompt??y(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0);s&&t.push("--append-system-prompt",s),this.options.hidden&&t.push("--name","Shennian Manager Substrate"),t.push(...await this.buildPermissionModeArgs()),this.spawnAndParse(t)}async stop(){await this.killProcess()}spawnAndParse(e){const t=c("claude");if(!t){this.emit("error",R(this.workDir,'Command "claude" not found. Is Claude Code CLI installed?'));return}const s=A(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv()});this.process=s,P({input:s.stdout}).on("line",o=>{if(o.trim())try{const i=JSON.parse(o);this.handleStreamEvent(i)}catch{}});let a="";s.stderr?.on("data",o=>{const i=o.toString();if(a+=i,this.terminalState==="open")for(const u of i.split(`
|
|
5
|
+
`)){const d=u.trim();z(d)&&this.emitEvent({state:"delta",text:d+`
|
|
6
|
+
`})}}),s.on("close",o=>{this.process===s&&(this.process=null,this.handleProcessClose(o,a))}),s.on("error",o=>{this.process===s&&(this.process=null,o.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",o))})}async buildPermissionModeArgs(){const e=["--disallowedTools","AskUserQuestion"];if(process.getuid?.()===0)return e;if(this.managedAgentPolicy&&p(this.managedAgentPolicy)){const t=await this.startPermissionBridge(),s={mcpServers:{[f]:{command:process.execPath,args:[E(new URL("./claude-permission-relay-server.js",import.meta.url))],env:{[x]:t}}}};return e.push("--permission-prompts","host","--permission-prompt-tool",`mcp__${f}__${w}`,"--mcp-config",JSON.stringify(s)),e}return this.managedAgentPolicy||e.push("--dangerously-skip-permissions"),e}async startPermissionBridge(){const e=this.permissionBridge??new _((t,s)=>this.requestClaudePermission(t,s));return this.permissionBridge=e,e.start()}requestClaudePermission(e,t){const s=h();return new Promise(r=>{const a=setTimeout(()=>{this.pendingClaudePermissions.delete(s),r({behavior:"deny",message:"shennian_permission_timeout"})},3e5);a.unref?.(),this.pendingClaudePermissions.set(s,{resolve:r,timer:a}),this.emitEvent({state:"approval-pending",runPhase:"waiting_approval",approval:{title:typeof e=="string"&&e.trim()?e:"\u9700\u8981\u7528\u6237\u786E\u8BA4",content:I(t),source:"claude"},permission:{id:s,sessionId:this.shennianSessionId??void 0,agentSessionId:this.agentSessionId??void 0,runId:this.runId,toolCallId:s,options:[{id:"allow",name:"\u5141\u8BB8",kind:"allow_once"},{id:"deny",name:"\u62D2\u7EDD",kind:"reject_once"}]}})})}async respondToPermission(e,t){const s=this.pendingClaudePermissions.get(e);if(!s)throw new Error("Claude permission request is no longer pending");this.pendingClaudePermissions.delete(e),clearTimeout(s.timer),s.resolve({behavior:t==="allow"?"allow":"deny"})}buildManagedPermissionConfig(e=!1){const t=this.managedAgentPolicy;if(!t||p(t))return null;const s=e?{readPaths:[],unixSockets:[]}:H();return b(N(t),t.adapterPolicy.workDir,{internalReadPaths:s.readPaths,internalUnixSockets:s.unixSockets,shellSubprocessPolicy:t.environmentPolicy.shellSubprocess})}buildProcessEnv(){return this.managedAgentPolicy?p(this.managedAgentPolicy)?O({NO_COLOR:"1",...this.extraEnv}):M({agentType:"claude",providerEnv:this.extraEnv,sessionEnv:this.extraEnv,runtimeEnv:{NO_COLOR:"1"}}):T(this.extraEnv)}handleStreamEvent(e){if(e.type==="system"&&e.subtype==="init"&&e.session_id){this.agentSessionId=e.session_id,this.emitEvent({state:"start",agentSessionId:this.agentSessionId});return}if(e.type==="system"&&e.subtype==="api_retry"&&e.error==="authentication_failed"){this.authenticationRetrying=!0,this.emitEvent({state:"heartbeat",runPhase:"thinking",errorCode:"auth_retrying",message:"Claude authentication is retrying."});return}if(e.type==="assistant"){if(this.authenticationRetrying=!1,e.message?.content){for(const t of e.message.content)if(t.type==="text"&&t.text){const s=this.hasEmittedText?`
|
|
7
7
|
|
|
8
8
|
`:"";this.emitEvent({state:"delta",text:s+t.text}),this.hasEmittedText=!0}else t.type==="thinking"&&t.thinking?this.emitEvent({state:"delta",text:t.thinking,thinking:!0}):t.type==="tool_use"&&(t.id&&t.name&&this.toolNames.set(t.id,t.name),this.emitEvent({state:"tool-call",name:t.name,args:t.input,...t.id?{toolCallId:t.id}:{}}));return}if(e.subtype==="text"&&e.text){const t=this.hasEmittedText?`
|
|
9
9
|
|
|
10
|
-
`:"";this.emitEvent({state:"delta",text:t+e.text}),this.hasEmittedText=!0}else e.subtype==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.subtype==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});return}if(e.type==="user"){for(const t of e.message?.content??[])t.type!=="tool_result"||!t.tool_use_id||this.emitEvent({state:"tool-result",name:this.toolNames.get(t.tool_use_id),toolCallId:t.tool_use_id,toolStatus:t.is_error===!0?"failed":"completed",result
|
|
10
|
+
`:"";this.emitEvent({state:"delta",text:t+e.text}),this.hasEmittedText=!0}else e.subtype==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.subtype==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});return}if(e.type==="user"){for(const t of e.message?.content??[])t.type!=="tool_result"||!t.tool_use_id||this.emitEvent({state:"tool-result",name:this.toolNames.get(t.tool_use_id),toolCallId:t.tool_use_id,toolStatus:t.is_error===!0?"failed":"completed",result:J(t.content)});return}if(e.type==="result")if(e.subtype==="tool_result"){const t=typeof e.content=="string"?e.content:JSON.stringify(e.content);this.emitEvent({state:"tool-result",name:e.name,result:t})}else if(e.subtype==="success"){e.session_id&&(this.agentSessionId=e.session_id);const t=typeof e.result=="string"?e.result:"";!this.hasEmittedText&&t.trim()&&(this.emitEvent({state:"delta",text:t}),this.hasEmittedText=!0);const s=e.usage??e.message?.usage;this.pendingSuccess={agentSessionId:this.agentSessionId??void 0,usage:s?{inputTokens:s.input_tokens,outputTokens:s.output_tokens}:void 0}}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error",...this.authenticationRetrying?{errorCode:"auth_required"}:{}})}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s,...this.authenticationRetrying?{errorCode:"auth_required"}:{}});return}if(!this.hasEmittedText){this.emitErrorIfOpen({state:"error",message:"Claude completed without response text"});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.pendingSuccess?.agentSessionId??this.agentSessionId??void 0,usage:this.pendingSuccess?.usage})}emitFinalIfOpen(e){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent(e))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent(e))}resetRunState(){this.seq=0,this.hasEmittedText=!1,this.toolNames.clear(),this.terminalState="open",this.authenticationRetrying=!1,this.pendingSuccess=null}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){for(const[t,s]of this.pendingClaudePermissions)clearTimeout(s.timer),s.resolve({behavior:"deny",message:"shennian_permission_run_ended"}),this.pendingClaudePermissions.delete(t);if(this.permissionBridge){const t=this.permissionBridge;this.permissionBridge=null,await t.stop()}const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}))}}function H(){const n=U(),e=[n.secretFile],t=n.transport==="unix_socket"?[n.endpoint]:[];n.transport==="unix_socket"&&e.push(n.endpoint);const s=c("pi");return s?.path&&e.push(...Q(s.path)),{readPaths:[...new Set(e)].sort(),unixSockets:[...new Set(t)].sort()}}function Q(n){const e=l.normalize(n.trim());if(!e||!l.isAbsolute(e))return[];const t=[e];try{const s=g.realpathSync(e);t.push(s,l.dirname(s),l.dirname(l.dirname(s)));let r=l.dirname(s);for(let a=0;a<8;a+=1){const o=l.join(r,"package.json");try{if(JSON.parse(g.readFileSync(o,"utf8")).name==="shennian"){t.push(r);break}}catch{}const i=l.dirname(r);if(i===r)break;r=i}}catch{}return[...new Set(t)].sort()}v("claude",()=>new V);export{V as ClaudeAdapter,$ as normalizeClaudeModelId,F as normalizeClaudeReasoningEffort,he as resetClaudeCapabilityCacheForTests,H as resolveClaudeManagedInternalAccess,Q as resolveClaudeShennianCliReadPaths,z as shouldForwardClaudeStderrLine,G as supportsClaudeReasoningEffort};
|