shennian 0.5.44 → 0.5.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/publish-build-manifest.json +109 -49
  2. package/dist/src/agents/claude-permission-protocol.js +1 -1
  3. package/dist/src/agents/claude-permission-relay-server.js +3 -3
  4. package/dist/src/agents/claude.js +7 -7
  5. package/dist/src/agents/codex-runtime.js +10 -9
  6. package/dist/src/agents/codex-user-input-requests.js +3 -0
  7. package/dist/src/agents/project-client.js +1 -1
  8. package/dist/src/agents/shennian.js +2 -2
  9. package/dist/src/commands/english.js +3 -0
  10. package/dist/src/commands/project-coordination.js +3 -0
  11. package/dist/src/commands/project.js +2 -2
  12. package/dist/src/commands/setup.js +3 -3
  13. package/dist/src/commands/steward.js +4 -4
  14. package/dist/src/guides/personal.js +2 -2
  15. package/dist/src/index.js +3 -3
  16. package/dist/src/personal-agent/sdk-session.js +2 -2
  17. package/dist/src/personal-agent/system-prompt.js +1 -1
  18. package/dist/src/project-coordination/admission.js +1 -0
  19. package/dist/src/project-coordination/http.js +1 -0
  20. package/dist/src/project-coordination/ipc.js +1 -0
  21. package/dist/src/project-coordination/runtime.js +8 -0
  22. package/dist/src/project-coordination/store.js +4 -0
  23. package/dist/src/project-coordination/uploads.js +1 -0
  24. package/dist/src/project-coordination/workbench-page.js +65 -0
  25. package/dist/src/schedules/reminder-client.js +1 -1
  26. package/dist/src/session/handlers/chat-abort.js +1 -0
  27. package/dist/src/session/handlers/chat-events.js +2 -2
  28. package/dist/src/session/handlers/chat.js +2 -2
  29. package/dist/src/session/handlers/personal-workspace.js +1 -1
  30. package/dist/src/session/manager.js +1 -1
  31. package/dist/src/session/queue-persistence.js +1 -0
  32. package/dist/src/session/queue.js +1 -1
  33. package/dist/src/steward/configure.js +1 -1
  34. package/dist/src/steward/onboarding.js +1 -1
  35. package/dist/src/steward/session.js +2 -2
  36. package/dist/src/steward/settings.js +1 -1
  37. package/dist/src/steward/templates.js +29 -8
  38. package/dist/src/steward/workspace.js +1 -1
  39. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "jsMinified": true,
4
4
  "minifier": "esbuild",
5
- "fileCount": 325,
5
+ "fileCount": 337,
6
6
  "files": [
7
7
  {
8
8
  "file": "bin/shennian-adapter-host.js",
@@ -141,18 +141,18 @@
141
141
  },
142
142
  {
143
143
  "file": "src/agents/claude-permission-protocol.js",
144
- "beforeBytes": 592,
145
- "afterBytes": 194
144
+ "beforeBytes": 657,
145
+ "afterBytes": 250
146
146
  },
147
147
  {
148
148
  "file": "src/agents/claude-permission-relay-server.js",
149
- "beforeBytes": 4278,
150
- "afterBytes": 1936
149
+ "beforeBytes": 5762,
150
+ "afterBytes": 2866
151
151
  },
152
152
  {
153
153
  "file": "src/agents/claude.js",
154
- "beforeBytes": 26522,
155
- "afterBytes": 12490
154
+ "beforeBytes": 28000,
155
+ "afterBytes": 13430
156
156
  },
157
157
  {
158
158
  "file": "src/agents/codex-approvals.js",
@@ -181,8 +181,13 @@
181
181
  },
182
182
  {
183
183
  "file": "src/agents/codex-runtime.js",
184
- "beforeBytes": 32283,
185
- "afterBytes": 16601
184
+ "beforeBytes": 32730,
185
+ "afterBytes": 16935
186
+ },
187
+ {
188
+ "file": "src/agents/codex-user-input-requests.js",
189
+ "beforeBytes": 3958,
190
+ "afterBytes": 2494
186
191
  },
187
192
  {
188
193
  "file": "src/agents/codex-user-question.js",
@@ -371,8 +376,8 @@
371
376
  },
372
377
  {
373
378
  "file": "src/agents/project-client.js",
374
- "beforeBytes": 3713,
375
- "afterBytes": 2205
379
+ "beforeBytes": 3820,
380
+ "afterBytes": 2281
376
381
  },
377
382
  {
378
383
  "file": "src/agents/public-agent-client.js",
@@ -421,8 +426,8 @@
421
426
  },
422
427
  {
423
428
  "file": "src/agents/shennian.js",
424
- "beforeBytes": 9705,
425
- "afterBytes": 5797
429
+ "beforeBytes": 10024,
430
+ "afterBytes": 6373
426
431
  },
427
432
  {
428
433
  "file": "src/agents/spawn-errors.js",
@@ -524,6 +529,11 @@
524
529
  "beforeBytes": 38859,
525
530
  "afterBytes": 19483
526
531
  },
532
+ {
533
+ "file": "src/commands/english.js",
534
+ "beforeBytes": 2303,
535
+ "afterBytes": 1365
536
+ },
527
537
  {
528
538
  "file": "src/commands/guide.js",
529
539
  "beforeBytes": 2210,
@@ -569,10 +579,15 @@
569
579
  "beforeBytes": 16861,
570
580
  "afterBytes": 9246
571
581
  },
582
+ {
583
+ "file": "src/commands/project-coordination.js",
584
+ "beforeBytes": 3208,
585
+ "afterBytes": 2335
586
+ },
572
587
  {
573
588
  "file": "src/commands/project.js",
574
- "beforeBytes": 8015,
575
- "afterBytes": 5486
589
+ "beforeBytes": 8146,
590
+ "afterBytes": 5571
576
591
  },
577
592
  {
578
593
  "file": "src/commands/queue.js",
@@ -606,8 +621,8 @@
606
621
  },
607
622
  {
608
623
  "file": "src/commands/setup.js",
609
- "beforeBytes": 16589,
610
- "afterBytes": 12325
624
+ "beforeBytes": 17277,
625
+ "afterBytes": 13038
611
626
  },
612
627
  {
613
628
  "file": "src/commands/skill.js",
@@ -616,8 +631,8 @@
616
631
  },
617
632
  {
618
633
  "file": "src/commands/steward.js",
619
- "beforeBytes": 9020,
620
- "afterBytes": 5725
634
+ "beforeBytes": 9503,
635
+ "afterBytes": 5885
621
636
  },
622
637
  {
623
638
  "file": "src/commands/support.js",
@@ -746,8 +761,8 @@
746
761
  },
747
762
  {
748
763
  "file": "src/guides/personal.js",
749
- "beforeBytes": 12162,
750
- "afterBytes": 21484
764
+ "beforeBytes": 12413,
765
+ "afterBytes": 21939
751
766
  },
752
767
  {
753
768
  "file": "src/guides/types.js",
@@ -756,8 +771,8 @@
756
771
  },
757
772
  {
758
773
  "file": "src/index.js",
759
- "beforeBytes": 45958,
760
- "afterBytes": 22449
774
+ "beforeBytes": 46204,
775
+ "afterBytes": 22618
761
776
  },
762
777
  {
763
778
  "file": "src/local-apps/service.js",
@@ -936,13 +951,13 @@
936
951
  },
937
952
  {
938
953
  "file": "src/personal-agent/sdk-session.js",
939
- "beforeBytes": 7127,
940
- "afterBytes": 4038
954
+ "beforeBytes": 7619,
955
+ "afterBytes": 4258
941
956
  },
942
957
  {
943
958
  "file": "src/personal-agent/system-prompt.js",
944
- "beforeBytes": 1539,
945
- "afterBytes": 2010
959
+ "beforeBytes": 1818,
960
+ "afterBytes": 2499
946
961
  },
947
962
  {
948
963
  "file": "src/personal-sync/epoch.js",
@@ -979,6 +994,41 @@
979
994
  "beforeBytes": 10929,
980
995
  "afterBytes": 6203
981
996
  },
997
+ {
998
+ "file": "src/project-coordination/admission.js",
999
+ "beforeBytes": 1527,
1000
+ "afterBytes": 1005
1001
+ },
1002
+ {
1003
+ "file": "src/project-coordination/http.js",
1004
+ "beforeBytes": 4503,
1005
+ "afterBytes": 2826
1006
+ },
1007
+ {
1008
+ "file": "src/project-coordination/ipc.js",
1009
+ "beforeBytes": 448,
1010
+ "afterBytes": 302
1011
+ },
1012
+ {
1013
+ "file": "src/project-coordination/runtime.js",
1014
+ "beforeBytes": 17063,
1015
+ "afterBytes": 12680
1016
+ },
1017
+ {
1018
+ "file": "src/project-coordination/store.js",
1019
+ "beforeBytes": 14226,
1020
+ "afterBytes": 7735
1021
+ },
1022
+ {
1023
+ "file": "src/project-coordination/uploads.js",
1024
+ "beforeBytes": 1613,
1025
+ "afterBytes": 1141
1026
+ },
1027
+ {
1028
+ "file": "src/project-coordination/workbench-page.js",
1029
+ "beforeBytes": 13365,
1030
+ "afterBytes": 28368
1031
+ },
982
1032
  {
983
1033
  "file": "src/region.js",
984
1034
  "beforeBytes": 3029,
@@ -1141,8 +1191,8 @@
1141
1191
  },
1142
1192
  {
1143
1193
  "file": "src/schedules/reminder-client.js",
1144
- "beforeBytes": 1592,
1145
- "afterBytes": 1819
1194
+ "beforeBytes": 4472,
1195
+ "afterBytes": 4749
1146
1196
  },
1147
1197
  {
1148
1198
  "file": "src/schedules/server-client.js",
@@ -1249,6 +1299,11 @@
1249
1299
  "beforeBytes": 2536,
1250
1300
  "afterBytes": 1240
1251
1301
  },
1302
+ {
1303
+ "file": "src/session/handlers/chat-abort.js",
1304
+ "beforeBytes": 1363,
1305
+ "afterBytes": 828
1306
+ },
1252
1307
  {
1253
1308
  "file": "src/session/handlers/chat-adapter-config.js",
1254
1309
  "beforeBytes": 3264,
@@ -1261,8 +1316,8 @@
1261
1316
  },
1262
1317
  {
1263
1318
  "file": "src/session/handlers/chat-events.js",
1264
- "beforeBytes": 20267,
1265
- "afterBytes": 8130
1319
+ "beforeBytes": 20947,
1320
+ "afterBytes": 8517
1266
1321
  },
1267
1322
  {
1268
1323
  "file": "src/session/handlers/chat-recovery.js",
@@ -1276,8 +1331,8 @@
1276
1331
  },
1277
1332
  {
1278
1333
  "file": "src/session/handlers/chat.js",
1279
- "beforeBytes": 37378,
1280
- "afterBytes": 15941
1334
+ "beforeBytes": 36287,
1335
+ "afterBytes": 15364
1281
1336
  },
1282
1337
  {
1283
1338
  "file": "src/session/handlers/codex-settings.js",
@@ -1311,8 +1366,8 @@
1311
1366
  },
1312
1367
  {
1313
1368
  "file": "src/session/handlers/personal-workspace.js",
1314
- "beforeBytes": 804,
1315
- "afterBytes": 444
1369
+ "beforeBytes": 1119,
1370
+ "afterBytes": 661
1316
1371
  },
1317
1372
  {
1318
1373
  "file": "src/session/handlers/personal.js",
@@ -1376,8 +1431,8 @@
1376
1431
  },
1377
1432
  {
1378
1433
  "file": "src/session/manager.js",
1379
- "beforeBytes": 42272,
1380
- "afterBytes": 22324
1434
+ "beforeBytes": 43375,
1435
+ "afterBytes": 23093
1381
1436
  },
1382
1437
  {
1383
1438
  "file": "src/session/native-cleanup-outbox.js",
@@ -1424,6 +1479,11 @@
1424
1479
  "beforeBytes": 3417,
1425
1480
  "afterBytes": 2020
1426
1481
  },
1482
+ {
1483
+ "file": "src/session/queue-persistence.js",
1484
+ "beforeBytes": 1559,
1485
+ "afterBytes": 745
1486
+ },
1427
1487
  {
1428
1488
  "file": "src/session/queue-retry.js",
1429
1489
  "beforeBytes": 1302,
@@ -1441,8 +1501,8 @@
1441
1501
  },
1442
1502
  {
1443
1503
  "file": "src/session/queue.js",
1444
- "beforeBytes": 43881,
1445
- "afterBytes": 19363
1504
+ "beforeBytes": 43511,
1505
+ "afterBytes": 19134
1446
1506
  },
1447
1507
  {
1448
1508
  "file": "src/session/queued-chat-dispatch.js",
@@ -1511,8 +1571,8 @@
1511
1571
  },
1512
1572
  {
1513
1573
  "file": "src/steward/configure.js",
1514
- "beforeBytes": 1912,
1515
- "afterBytes": 1094
1574
+ "beforeBytes": 2184,
1575
+ "afterBytes": 1150
1516
1576
  },
1517
1577
  {
1518
1578
  "file": "src/steward/context.js",
@@ -1526,8 +1586,8 @@
1526
1586
  },
1527
1587
  {
1528
1588
  "file": "src/steward/onboarding.js",
1529
- "beforeBytes": 3176,
1530
- "afterBytes": 5735
1589
+ "beforeBytes": 3212,
1590
+ "afterBytes": 5807
1531
1591
  },
1532
1592
  {
1533
1593
  "file": "src/steward/primary-machine.js",
@@ -1541,8 +1601,8 @@
1541
1601
  },
1542
1602
  {
1543
1603
  "file": "src/steward/session.js",
1544
- "beforeBytes": 5056,
1545
- "afterBytes": 5336
1604
+ "beforeBytes": 5227,
1605
+ "afterBytes": 5462
1546
1606
  },
1547
1607
  {
1548
1608
  "file": "src/steward/settings.js",
@@ -1551,8 +1611,8 @@
1551
1611
  },
1552
1612
  {
1553
1613
  "file": "src/steward/templates.js",
1554
- "beforeBytes": 7150,
1555
- "afterBytes": 12430
1614
+ "beforeBytes": 10090,
1615
+ "afterBytes": 17604
1556
1616
  },
1557
1617
  {
1558
1618
  "file": "src/steward/worker-settings.js",
@@ -1561,8 +1621,8 @@
1561
1621
  },
1562
1622
  {
1563
1623
  "file": "src/steward/workspace.js",
1564
- "beforeBytes": 3740,
1565
- "afterBytes": 1903
1624
+ "beforeBytes": 3728,
1625
+ "afterBytes": 1896
1566
1626
  },
1567
1627
  {
1568
1628
  "file": "src/support/support-client.js",
@@ -1 +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};
1
+ const E="approve",_="request_user_input",S="shennianPermission",N="SHENNIAN_CLAUDE_PERMISSION_SOCKET";export{S as CLAUDE_PERMISSION_MCP_SERVER_NAME,N as CLAUDE_PERMISSION_SOCKET_ENV,E as CLAUDE_PERMISSION_TOOL_NAME,_ as CLAUDE_USER_INPUT_TOOL_NAME};
@@ -1,3 +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
+ import _ from"node:net";import{createInterface as l}from"node:readline";import{CLAUDE_PERMISSION_MCP_SERVER_NAME as y,CLAUDE_PERMISSION_SOCKET_ENV as f,CLAUDE_PERMISSION_TOOL_NAME as u,CLAUDE_USER_INPUT_TOOL_NAME as c}from"./claude-permission-protocol.js";const S=5*6e4;function n(e){process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",...e})}
2
+ `)}function m(e,i){const t=process.env[f];return t?new Promise(h=>{let p=!1;const o=s=>{p||(p=!0,clearTimeout(d),h(s))},d=setTimeout(()=>o({behavior:"deny",message:"shennian_permission_timeout"}),S);d.unref?.();const r=_.connect(t);r.on("error",()=>o({behavior:"deny",message:"shennian_permission_relay_unreachable"})),r.on("connect",()=>r.write(`${JSON.stringify({toolName:e,input:i})}
3
+ `)),l({input:r}).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{r.end()}})}):Promise.resolve({behavior:"deny",message:"shennian_permission_socket_missing"})}function b(e){if(e.method==="initialize"){n({id:e.id,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:y,version:"1.0.0"}}});return}if(!(e.method==="notifications/initialized"||e.id==null&&e.method?.startsWith("notifications/"))){if(e.method==="tools/list"){n({id:e.id,result:{tools:[{name:u,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"]}},{name:c,description:"Ask the user questions and wait for real answers in the Shennian app. Use this instead of AskUserQuestion. This tool does not grant permissions.",inputSchema:{type:"object",properties:{questions:{type:"array",minItems:1,maxItems:8,items:{type:"object",properties:{id:{type:"string"},question:{type:"string"},isOther:{type:"boolean"},isSecret:{type:"boolean"},options:{type:"array",items:{type:"object",properties:{label:{type:"string"},description:{type:"string"}},required:["label"]}}},required:["id","question"]}}},required:["questions"]}}]}});return}if(e.method==="tools/call"){const i=e.params?.arguments??{};if(e.params?.name===c){m("__shennian_user_input__",i).then(t=>{n({id:e.id,result:{content:[{type:"text",text:JSON.stringify(t.behavior==="allow"?t.updatedInput:{error:t.message??"user_input_unavailable"})}],isError:t.behavior!=="allow"}})});return}if(e.params?.name!==u){n({id:e.id,error:{code:-32602,message:"Unknown tool"}});return}m(i.tool_name,i.input).then(t=>{n({id:e.id,result:{content:[{type:"text",text:JSON.stringify(t)}]}})});return}e.id!=null&&n({id:e.id,error:{code:-32601,message:`Unhandled method: ${e.method}`}})}}const E=l({input:process.stdin});E.on("line",e=>{if(e.trim())try{b(JSON.parse(e))}catch{}});
@@ -1,10 +1,10 @@
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?`
1
+ import g from"node:fs";import u from"node:path";import{createInterface as P}from"node:readline";import{randomUUID as m}from"node:crypto";import{fileURLToPath as E}from"node:url";import{AgentAdapter as I,registerAgent as _,summarizeToolInput as C}from"./adapter.js";import{ClaudePermissionBridge as v}from"./claude-permission-bridge.js";import{CodexUserInputRequests as w}from"./codex-user-input-requests.js";import{CLAUDE_PERMISSION_MCP_SERVER_NAME as f,CLAUDE_PERMISSION_SOCKET_ENV as x,CLAUDE_PERMISSION_TOOL_NAME as A}from"./claude-permission-protocol.js";import{resolveBuiltinCommand as c,spawnAgentCommand as k,spawnResolvedCommandSync as R}from"./command-spec.js";import{spawnEnoentError as T}from"./spawn-errors.js";import{buildAgentProcessEnv as M,buildManagedAgentProcessEnv as O,buildManagedNativeFullProcessEnv as N}from"../agent-env.js";import{buildPlatformInstructions as y}from"./platform-instructions.js";import{resolveManagedAgentAdapterEnforcement as U,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 b}from"../daemon-ipc/paths.js";import{CLAUDE_MANAGED_RUNTIME_SECURITY as q,compileClaudeManagedPermissions as B}from"./claude-managed-permissions.js";L("claude",q);function $(n){return n?.trim()||"default"}const F=new Set(["low","medium","high","xhigh","max"]),h=new Map;function z(n){const e=n?.trim();if(e){if(F.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function ce(){h.clear()}function G(n){const e=n.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function J(){const n=c("claude");if(!n)return!1;const e=`${n.kind}:${n.path}:${n.command}:${n.args.join("\0")}`;if(h.has(e))return h.get(e)??!1;try{const t=R(n,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:process.env}),s=`${t.stdout??""}
2
+ ${t.stderr??""}`,i=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return h.set(e,i),i}catch{return h.set(e,!1),!1}}const S=64*1024;function K(n){const e=V(n);return e.length>S?`${e.slice(0,S)}
3
+ \u2026[truncated]`:e}function V(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 H extends I{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;pendingInputReplies=new Map;userInputs=new w((e,t)=>{const s=this.pendingInputReplies.get(String(e));this.pendingInputReplies.delete(String(e));const i=Object.keys(t.answers).length>0;s?.(i?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"user_input_ended"})},e=>this.emitEvent(e),"claude");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,i){this.sessionId=e,this.workDir=this.managedAgentPolicy?.adapterPolicy.workDir??t,this.seq=0,this.persistNativeSession=i?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,i,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=m(),this.resetRunState();const r=["-p",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig(o?.source==="published_agent")?.args??[]];this.persistNativeSession||r.push("--no-session-persistence");const l=this.options.systemPrompt??y(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,a);l&&r.push("--append-system-prompt",l),this.options.hidden&&r.push("--name","Shennian Manager Substrate"),r.push(...await this.buildPermissionModeArgs()),r.push("--model",$(t));const d=z(s);d&&J()&&r.push("--effort",d),this.agentSessionId&&r.push("--resume",this.agentSessionId),this.spawnAndParse(r)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=m(),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",T(this.workDir,'Command "claude" not found. Is Claude Code CLI installed?'));return}const s=k(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 r=JSON.parse(o);this.handleStreamEvent(r)}catch{}});let a="";s.stderr?.on("data",o=>{const r=o.toString();if(a+=r,this.terminalState==="open")for(const l of r.split(`
5
+ `)){const d=l.trim();G(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("--mcp-config",JSON.stringify(s)),this.managedAgentPolicy?e.push("--permission-prompts","host","--permission-prompt-tool",`mcp__${f}__${A}`):e.push("--dangerously-skip-permissions"),e}return this.managedAgentPolicy||e.push("--dangerously-skip-permissions"),e}async startPermissionBridge(){const e=this.permissionBridge??new v((t,s)=>t==="__shennian_user_input__"?this.requestClaudeUserInput(s):this.requestClaudePermission(t,s));return this.permissionBridge=e,e.start()}requestClaudePermission(e,t){const s=m();return new Promise(i=>{const a=setTimeout(()=>{this.pendingClaudePermissions.delete(s),i({behavior:"deny",message:"shennian_permission_timeout"})},3e5);a.unref?.(),this.pendingClaudePermissions.set(s,{resolve:i,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:C(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"}]}})})}requestClaudeUserInput(e){const t=m(),s=this.shennianSessionId??null;return new Promise(i=>{this.pendingInputReplies.set(t,i),this.userInputs.request(t,{...e,threadId:s,turnId:this.runId},s,this.runId,!!(this.managedAgentPolicy&&!p(this.managedAgentPolicy)))})}async respondToPermission(e,t){if(e.startsWith("input-")){this.userInputs.respond(e,t,this.runId);return}if(t!=="allow"&&t!=="deny")throw new Error("claude_permission_invalid");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:[]}:Q();return B(U(t),t.adapterPolicy.workDir,{internalReadPaths:s.readPaths,internalUnixSockets:s.unixSockets,shellSubprocessPolicy:t.environmentPolicy.shellSubprocess})}buildProcessEnv(){return this.managedAgentPolicy?p(this.managedAgentPolicy)?N({NO_COLOR:"1",...this.extraEnv}):O({agentType:"claude",providerEnv:this.extraEnv,sessionEnv:this.extraEnv,runtimeEnv:{NO_COLOR:"1"}}):M(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: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};
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:K(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(){this.userInputs.clear();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 Q(){const n=b(),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(...W(s.path)),{readPaths:[...new Set(e)].sort(),unixSockets:[...new Set(t)].sort()}}function W(n){const e=u.normalize(n.trim());if(!e||!u.isAbsolute(e))return[];const t=[e];try{const s=g.realpathSync(e);t.push(s,u.dirname(s),u.dirname(u.dirname(s)));let i=u.dirname(s);for(let a=0;a<8;a+=1){const o=u.join(i,"package.json");try{if(JSON.parse(g.readFileSync(o,"utf8")).name==="shennian"){t.push(i);break}}catch{}const r=u.dirname(i);if(r===i)break;i=r}}catch{}return[...new Set(t)].sort()}_("claude",()=>new H);export{H as ClaudeAdapter,$ as normalizeClaudeModelId,z as normalizeClaudeReasoningEffort,ce as resetClaudeCapabilityCacheForTests,Q as resolveClaudeManagedInternalAccess,W as resolveClaudeShennianCliReadPaths,G as shouldForwardClaudeStderrLine,J as supportsClaudeReasoningEffort};
@@ -1,15 +1,16 @@
1
- import{AgentAdapter as g,isApprovalLikeName as f}from"./adapter.js";import{CodexApprovals as T}from"./codex-approvals.js";import{buildCodexUserQuestion as c}from"./codex-user-question.js";import{CodexManagedRoomToolBinding as v}from"./codex-managed-room-tools.js";import{extractAppServerErrorMessage as m,formatCodexErrorMessage as y,formatTransientCodexStatus as I,isCodexCollabAgentItem as x,isCodexCollabAgentToolName as o,isCodexLegacyCollabAgentItem as R,isMissingCodexRolloutError as p,isTransientCodexErrorMessage as S,looksLikeCodexInteractiveAuthPrompt as k,looksLikeFatalCodexStderr as C,normalizeCodexStderr as E,normalizeTerminalText as _,safeStringify as h,stripGitDirectiveArtifacts as A}from"./codex-utils.js";class O extends g{options;approvals=new T((e,t)=>{this.process?.stdin?.write(`${JSON.stringify({id:e,result:t})}
2
- `)},e=>this.emitEvent(e));async respondToPermission(e,t){this.approvals.respond(e,t,this.activeTurnId)}process=null;workDir=null;seq=0;runId="";pendingUsage;agentSessionId=null;hasEmittedText=!1;textTail="";terminalState="open";forceCloseTimer=null;stderrBuf="";rpcSeq=1;pendingRequests=new Map;appServerReady=null;appServerStartupError=null;activeTurnId=null;deltaItemIds=new Set;lastTransientStatus="";agentSystemPrompt="";managedAgentPolicy=null;managedPermissionConfig=null;configurationRestartRequired=!1;managedRoomTools=new v;configuredManagedRoomContextToken=null;configuredManagedRoomExecutor=null;managedRoomToolThreadId=null;managedRoomToolSurfaceKey=null;managedRoomCapabilityExpectedForTurn=!1;managedRoomTurnBindingFailed=!1;preparedExternalOwnerThreadId=null;managedTurnReplay=null;managedAsyncRecovery=null;persistNativeSession=!0;nativeSessionVisibility="user";constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};sendRpc(e,t,n=6e4){if(this.appServerStartupError)return Promise.reject(this.appServerStartupError);const s=this.process;if(!s?.stdin)return Promise.reject(new Error("codex app-server is not running"));const r=this.rpcSeq++,i=JSON.stringify({id:r,method:e,params:t});return new Promise((a,l)=>{const d=setTimeout(()=>{this.pendingRequests.delete(r),l(new Error(`codex app-server request timed out: ${e}`))},n);this.pendingRequests.set(r,{resolve:a,reject:l,timer:d}),s.stdin.write(`${i}
3
- `,u=>{u&&(clearTimeout(d),this.pendingRequests.delete(r),l(u))})})}handleAppServerMessage(e){if(e.id!=null&&e.method&&this.approvals.request(e.method,e.id,e.params??{},this.agentSessionId,this.activeTurnId,!!this.managedAgentPolicy))return;if(e.method==="serverRequest/resolved"&&this.approvals.resolved(e.params?.requestId),e.method==="item/tool/requestUserInput"&&e.id!=null){const n=e.params??{};if(n.threadId&&this.agentSessionId&&n.threadId!==this.agentSessionId)return;this.emitEvent({state:"approval-pending",approval:c("requestUserInput",n)});return}if(e.method==="item/tool/call"&&e.id!=null){this.handleManagedRoomToolCall(e.id,e.params??{});return}if(e.id!=null){const n=typeof e.id=="number"?this.pendingRequests.get(e.id):void 0;n&&(clearTimeout(n.timer),this.pendingRequests.delete(e.id),e.error?n.reject(new Error(e.error.message||`codex app-server error ${e.error.code??""}`.trim())):n.resolve(e.result))}if(!e.method)return;const t=e.params??{};switch(e.method){case"turn/started":{const n=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof n?.id=="string"?n.id:null,r=typeof t.threadId=="string"?t.threadId:"";s&&(this.activeTurnId=s,this.managedRoomCapabilityExpectedForTurn&&this.managedRoomToolThreadId===r&&!this.managedRoomTools.bindTurn(r,s)&&(this.managedRoomTurnBindingFailed=!0,this.emitErrorIfOpen("codex_managed_room_turn_binding_failed")));break}case"thread/status/changed":{const n=typeof t.threadId=="string"?t.threadId:"";if(n&&this.agentSessionId&&n!==this.agentSessionId)break;const s=typeof t.status=="object"&&t.status!==null?t.status:null;s?.type==="active"&&this.emitEvent({state:"heartbeat",runPhase:this.mapThreadStatusToRunPhase(s)});break}case"item/agentMessage/delta":{const n=typeof t.itemId=="string"?t.itemId:"";n&&this.deltaItemIds.add(n),typeof t.delta=="string"&&this.emitText(t.delta);break}case"item/completed":this.handleAppServerCompletedItem(t);break;case"thread/tokenUsage/updated":this.handleAppServerUsage(t);break;case"turn/completed":{const n=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof n?.id=="string"?n.id:null;(!this.activeTurnId||s===this.activeTurnId)&&(this.approvals.clear(),this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),this.emitFinalIfOpen());break}case"turn/failed":{const n=m(t);if(this.scheduleManagedAsyncRolloutRecovery(n))return;this.emitErrorIfOpen(n||"turn failed");break}case"error":{const n=m(t);if(S(n)){this.emitTransientStatus(n);return}if(this.scheduleManagedAsyncRolloutRecovery(n))return;this.emitErrorIfOpen(n);break}}}scheduleManagedAsyncRolloutRecovery(e){if(!this.managedAgentPolicy&&!this.managedPermissionConfig||!this.managedTurnReplay||!p(new Error(e)))return!1;if(this.managedAsyncRecovery)return!0;if(this.managedTurnReplay.recoveryCount>=2)return!1;this.managedTurnReplay.recoveryCount+=1;const t=this.managedTurnReplay.recoveryCount;return this.logManagedThreadLifecycle("rollout.failed-async",{threadId:this.agentSessionId,recoveryCount:t}),this.managedAsyncRecovery=this.recoverManagedTurnAfterAsyncRolloutFailure().catch(n=>{const s=p(n)?"no rollout found after managed thread recovery":n instanceof Error?n.message:"managed thread recovery failed";this.emitErrorIfOpen(s)}).finally(()=>{this.managedAsyncRecovery=null}),!0}async recoverManagedTurnAfterAsyncRolloutFailure(){const e=this.managedTurnReplay,t=this.agentSessionId;if(!e||!t||this.terminalState!=="open")return;this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),await this.killProcess(!0),this.agentSessionId=null,this.managedRoomToolThreadId=null,this.managedRoomToolSurfaceKey=null,await this.ensureAppServer(e.modelId);const n=this.agentSessionId;if(!n)throw new Error("codex app-server did not recreate the managed thread");this.logManagedThreadLifecycle("thread.recreated-async",{previousThreadId:t,threadId:n,recoveryCount:e.recoveryCount}),this.emitEvent({state:"start",agentSessionId:n});const s=await this.startFreshManagedTurnWithReadinessRetry(n,e.text,e.modelId,e.reasoningEffort,e.attachments);if(this.activeTurnId=s.turn?.id??null,this.managedRoomTurnBindingFailed)throw new Error("codex_managed_room_turn_binding_failed");if(this.managedRoomCapabilityExpectedForTurn&&this.managedRoomToolThreadId===n&&this.activeTurnId&&!this.managedRoomTools.bindTurn(n,this.activeTurnId))throw new Error("codex_managed_room_turn_binding_failed")}async handleManagedRoomToolCall(e,t){const n=await this.managedRoomTools.execute(t);if(this.writeAppServerResponse(e,n),n.success&&t.tool==="shennian_room_send"){const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:null,r=typeof s?.text=="string"?s.text.trim():"";r&&this.emitText(r,"block")}}writeAppServerResponse(e,t){const n=this.process;n?.stdin&&n.stdin.write(`${JSON.stringify({id:e,result:t})}
4
- `)}mapThreadStatusToRunPhase(e){const t=e?.type==="active"&&Array.isArray(e.activeFlags)?e.activeFlags:[];return t.includes("waitingOnApproval")?"waiting_approval":t.includes("waitingOnUserInput")?"waiting_user_input":"thinking"}handleAppServerNonJsonStdout(e){const t=_(e);k(t)&&this.failAppServerStartup(new Error("Codex \u672A\u767B\u5F55\u3002\u8BF7\u5148\u5728\u8FD9\u53F0\u7535\u8111\u7684\u7EC8\u7AEF\u8FD0\u884C `codex`\uFF0C\u6309\u63D0\u793A\u5B8C\u6210 ChatGPT \u767B\u5F55\u6216\u914D\u7F6E API key\uFF0C\u7136\u540E\u518D\u56DE\u5230\u795E\u5FF5\u53D1\u9001\u6D88\u606F\u3002"))}failAppServerStartup(e){this.appServerStartupError||(this.appServerStartupError=e,this.rejectAllPending(e),this.process?.kill("SIGTERM"))}handleAppServerCompletedItem(e){const t=typeof e.item=="object"&&e.item!==null?e.item:null;if(!(!t||typeof t.type!="string")&&!x(t))switch(t.type){case"agentMessage":{const n=typeof t.id=="string"?t.id:"";if(n&&this.deltaItemIds.has(n))return;typeof t.text=="string"&&this.emitText(t.text,"block");break}case"commandExecution":{const n=typeof t.command=="string"?t.command:"",s=typeof t.aggregatedOutput=="string"?t.aggregatedOutput:"";n&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:n}}),this.emitEvent({state:"tool-result",name:"command_execution",result:[s,t.exitCode!=null?`
5
- (exit ${t.exitCode})`:""].join("").trim()});break}case"mcpToolCall":case"dynamicToolCall":{const n=typeof t.tool=="string"?t.tool:t.type;if(o(n))return;const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:{};this.emitEvent({state:"tool-call",name:n,args:s}),this.emitEvent({state:"tool-result",name:n,result:h(t.error??t.result??t.contentItems??"")});break}case"fileChange":break;case"approvalRequest":case"approval_request":case"permissionRequest":case"permission_request":case"userInputRequired":case"user_input_required":{this.emitApprovalPending(t);break}}}handleAppServerUsage(e){const t=typeof e.tokenUsage=="object"&&e.tokenUsage!==null?e.tokenUsage:null,n=typeof t?.last=="object"&&t.last!==null?t.last:null,s=typeof t?.total=="object"&&t.total!==null?t.total:null,r=n??s;if(!r)return;const i=typeof r.inputTokens=="number"?r.inputTokens:void 0,a=typeof r.outputTokens=="number"?r.outputTokens:void 0;(i!=null||a!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:a??0})}handleCodexItemLine(e){const t=e.item;if(t?.type&&!R(t))switch(t.type){case"agent_message":case"reasoning":{e.type==="item.completed"&&t.text&&this.emitText(t.text,"block");break}case"command_execution":{if(e.type==="item.started"&&t.command&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:t.command}}),e.type==="item.completed"){const n=[t.aggregated_output??"",t.exit_code!=null?`
6
- (exit ${t.exit_code})`:""];this.emitEvent({state:"tool-result",name:"command_execution",result:n.join("").trim()||String(t.status??"")})}break}case"mcp_tool_call":{if(t.tool&&o(t.tool))return;if(e.type==="item.started"&&this.emitEvent({state:"tool-call",name:t.tool??"mcp_tool",args:{server:t.server,...t.arguments&&typeof t.arguments=="object"?t.arguments:{}}}),e.type==="item.completed"){const n=t.error&&typeof t.error=="object"?t.error.message:void 0;this.emitEvent({state:"tool-result",name:t.tool??"mcp_tool",result:n??h(t.result)})}break}case"file_change":break;case"web_search":{e.type==="item.completed"&&t.query&&this.emitText(`[web_search] ${t.query}`,"block");break}case"todo_list":{if(e.type==="item.completed"&&t.items?.length){const n=t.items.map(s=>`- [${s.completed?"x":" "}] ${s.text}`).join(`
7
- `);this.emitText(n,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const s=e.usage;if(s){const r=s.input_tokens??s.prompt_tokens,i=s.output_tokens??s.completion_tokens;(r!=null||i!=null)&&(this.pendingUsage={inputTokens:r??0,outputTokens:i??0})}this.emitFinalIfOpen();return}case"turn.failed":{const s=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(s);return}case"error":{const s=typeof e.message=="string"?e.message:"";if(s.includes("Reconnecting"))return;this.emitErrorIfOpen(s||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const s=e.thread_id??e.session_id??e.id;typeof s=="string"&&s&&(this.agentSessionId=s,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const s=e.content??e.text;s&&this.emitText(s);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&o(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&o(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return f(e)}emitApprovalPending(e){const t=e,n=c(t.name??t.tool,t.arguments??t.input);if(n){this.emitEvent({state:"approval-pending",approval:n});return}const s=typeof e.command=="string"?e.command:"",r=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",i=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:s?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${s}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:r,content:i,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(e=!1){this.approvals.clear();const t=this.process;this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),e||this.clearConfiguredManagedRoomContext(),this.rejectAllPending(new Error("codex app-server stopped")),t&&(this.process=null,this.clearForceCloseTimer(),t.kill("SIGTERM"),await new Promise(n=>{const s=setTimeout(()=>{t.kill("SIGKILL"),n()},3e3);s.unref?.(),t.once("close",()=>{clearTimeout(s),n()})}))}rejectAllPending(e){for(const[t,n]of this.pendingRequests.entries())clearTimeout(n.timer),n.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const n=E(t);if(e!==0&&e!==null){const s=n||`codex exited with code ${e}`;this.emitErrorIfOpen(s)}else C(n)?this.emitErrorIfOpen(n):this.emitFinalIfOpen();this.pendingUsage=void 0}emitFinalIfOpen(){this.approvals.clear(),this.terminalState==="open"&&(this.terminalState="final",this.managedTurnReplay=null,this.managedRoomCapabilityExpectedForTurn=!1,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"final",usage:this.pendingUsage,agentSessionId:this.agentSessionId??void 0}),this.killProcess().catch(()=>{}))}emitErrorIfOpen(e){this.approvals.clear(),this.terminalState==="open"&&(this.terminalState="error",this.managedTurnReplay=null,this.managedRoomCapabilityExpectedForTurn=!1,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"error",message:y(e)}),this.scheduleProcessClose())}resetRunState(){this.pendingUsage=void 0,this.terminalState="open",this.managedRoomTurnBindingFailed=!1,this.deltaItemIds.clear(),this.lastTransientStatus="",this.clearForceCloseTimer(),this.resetTextState()}clearConfiguredManagedRoomContext(){this.configuredManagedRoomContextToken=null,this.configuredManagedRoomExecutor=null}emitTransientStatus(e){const t=I(e);!t||t===this.lastTransientStatus||this.terminalState!=="open"||(this.lastTransientStatus=t,this.emitEvent({state:"delta",text:`${t}
8
- `,thinking:!0}))}resetTextState(){this.hasEmittedText=!1,this.textTail=""}emitText(e,t="delta"){if(!e)return;let n=A(e);n&&(t==="block"&&this.hasEmittedText&&!n.startsWith(`
1
+ import{AgentAdapter as h,isApprovalLikeName as g}from"./adapter.js";import{CodexApprovals as f}from"./codex-approvals.js";import{CodexUserInputRequests as T}from"./codex-user-input-requests.js";import{buildCodexUserQuestion as v}from"./codex-user-question.js";import{CodexManagedRoomToolBinding as y}from"./codex-managed-room-tools.js";import{extractAppServerErrorMessage as c,formatCodexErrorMessage as I,formatTransientCodexStatus as x,isCodexCollabAgentItem as R,isCodexCollabAgentToolName as o,isCodexLegacyCollabAgentItem as S,isMissingCodexRolloutError as p,isTransientCodexErrorMessage as k,looksLikeCodexInteractiveAuthPrompt as C,looksLikeFatalCodexStderr as E,normalizeCodexStderr as _,normalizeTerminalText as A,safeStringify as m,stripGitDirectiveArtifacts as w}from"./codex-utils.js";class $ extends h{options;approvals=new f((e,t)=>{this.process?.stdin?.write(`${JSON.stringify({id:e,result:t})}
2
+ `)},e=>this.emitEvent(e));async respondToPermission(e,t){e.startsWith("input-")?this.userInputs.respond(e,t,this.activeTurnId):this.approvals.respond(e,t,this.activeTurnId)}userInputs=new T((e,t)=>{this.process?.stdin?.write(`${JSON.stringify({id:e,result:t})}
3
+ `)},e=>this.emitEvent(e));process=null;workDir=null;seq=0;runId="";pendingUsage;agentSessionId=null;hasEmittedText=!1;textTail="";terminalState="open";forceCloseTimer=null;stderrBuf="";rpcSeq=1;pendingRequests=new Map;appServerReady=null;appServerStartupError=null;activeTurnId=null;deltaItemIds=new Set;lastTransientStatus="";agentSystemPrompt="";managedAgentPolicy=null;managedPermissionConfig=null;configurationRestartRequired=!1;managedRoomTools=new y;configuredManagedRoomContextToken=null;configuredManagedRoomExecutor=null;managedRoomToolThreadId=null;managedRoomToolSurfaceKey=null;managedRoomCapabilityExpectedForTurn=!1;managedRoomTurnBindingFailed=!1;preparedExternalOwnerThreadId=null;managedTurnReplay=null;managedAsyncRecovery=null;persistNativeSession=!0;nativeSessionVisibility="user";constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};sendRpc(e,t,n=6e4){if(this.appServerStartupError)return Promise.reject(this.appServerStartupError);const s=this.process;if(!s?.stdin)return Promise.reject(new Error("codex app-server is not running"));const r=this.rpcSeq++,i=JSON.stringify({id:r,method:e,params:t});return new Promise((a,l)=>{const d=setTimeout(()=>{this.pendingRequests.delete(r),l(new Error(`codex app-server request timed out: ${e}`))},n);this.pendingRequests.set(r,{resolve:a,reject:l,timer:d}),s.stdin.write(`${i}
4
+ `,u=>{u&&(clearTimeout(d),this.pendingRequests.delete(r),l(u))})})}handleAppServerMessage(e){if(e.id!=null&&e.method&&this.approvals.request(e.method,e.id,e.params??{},this.agentSessionId,this.activeTurnId,!!this.managedAgentPolicy))return;if(e.method==="serverRequest/resolved"&&(this.approvals.resolved(e.params?.requestId),this.userInputs.resolved(e.params?.requestId)),e.method==="item/tool/requestUserInput"&&e.id!=null){this.userInputs.request(e.id,e.params??{},this.agentSessionId,this.activeTurnId,!!this.managedAgentPolicy);return}if(e.method==="item/tool/call"&&e.id!=null){this.handleManagedRoomToolCall(e.id,e.params??{});return}if(e.id!=null){const n=typeof e.id=="number"?this.pendingRequests.get(e.id):void 0;n&&(clearTimeout(n.timer),this.pendingRequests.delete(e.id),e.error?n.reject(new Error(e.error.message||`codex app-server error ${e.error.code??""}`.trim())):n.resolve(e.result))}if(!e.method)return;const t=e.params??{};switch(e.method){case"turn/started":{const n=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof n?.id=="string"?n.id:null,r=typeof t.threadId=="string"?t.threadId:"";s&&(this.activeTurnId=s,this.managedRoomCapabilityExpectedForTurn&&this.managedRoomToolThreadId===r&&!this.managedRoomTools.bindTurn(r,s)&&(this.managedRoomTurnBindingFailed=!0,this.emitErrorIfOpen("codex_managed_room_turn_binding_failed")));break}case"thread/status/changed":{const n=typeof t.threadId=="string"?t.threadId:"";if(n&&this.agentSessionId&&n!==this.agentSessionId)break;const s=typeof t.status=="object"&&t.status!==null?t.status:null;s?.type==="active"&&this.emitEvent({state:"heartbeat",runPhase:this.mapThreadStatusToRunPhase(s)});break}case"item/agentMessage/delta":{const n=typeof t.itemId=="string"?t.itemId:"";n&&this.deltaItemIds.add(n),typeof t.delta=="string"&&this.emitText(t.delta);break}case"item/completed":this.handleAppServerCompletedItem(t);break;case"thread/tokenUsage/updated":this.handleAppServerUsage(t);break;case"turn/completed":{const n=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof n?.id=="string"?n.id:null;(!this.activeTurnId||s===this.activeTurnId)&&(this.approvals.clear(),this.userInputs.clear(),this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),this.emitFinalIfOpen());break}case"turn/failed":{const n=c(t);if(this.scheduleManagedAsyncRolloutRecovery(n))return;this.emitErrorIfOpen(n||"turn failed");break}case"error":{const n=c(t);if(k(n)){this.emitTransientStatus(n);return}if(this.scheduleManagedAsyncRolloutRecovery(n))return;this.emitErrorIfOpen(n);break}}}scheduleManagedAsyncRolloutRecovery(e){if(!this.managedAgentPolicy&&!this.managedPermissionConfig||!this.managedTurnReplay||!p(new Error(e)))return!1;if(this.managedAsyncRecovery)return!0;if(this.managedTurnReplay.recoveryCount>=2)return!1;this.managedTurnReplay.recoveryCount+=1;const t=this.managedTurnReplay.recoveryCount;return this.logManagedThreadLifecycle("rollout.failed-async",{threadId:this.agentSessionId,recoveryCount:t}),this.managedAsyncRecovery=this.recoverManagedTurnAfterAsyncRolloutFailure().catch(n=>{const s=p(n)?"no rollout found after managed thread recovery":n instanceof Error?n.message:"managed thread recovery failed";this.emitErrorIfOpen(s)}).finally(()=>{this.managedAsyncRecovery=null}),!0}async recoverManagedTurnAfterAsyncRolloutFailure(){const e=this.managedTurnReplay,t=this.agentSessionId;if(!e||!t||this.terminalState!=="open")return;this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),await this.killProcess(!0),this.agentSessionId=null,this.managedRoomToolThreadId=null,this.managedRoomToolSurfaceKey=null,await this.ensureAppServer(e.modelId);const n=this.agentSessionId;if(!n)throw new Error("codex app-server did not recreate the managed thread");this.logManagedThreadLifecycle("thread.recreated-async",{previousThreadId:t,threadId:n,recoveryCount:e.recoveryCount}),this.emitEvent({state:"start",agentSessionId:n});const s=await this.startFreshManagedTurnWithReadinessRetry(n,e.text,e.modelId,e.reasoningEffort,e.attachments);if(this.activeTurnId=s.turn?.id??null,this.managedRoomTurnBindingFailed)throw new Error("codex_managed_room_turn_binding_failed");if(this.managedRoomCapabilityExpectedForTurn&&this.managedRoomToolThreadId===n&&this.activeTurnId&&!this.managedRoomTools.bindTurn(n,this.activeTurnId))throw new Error("codex_managed_room_turn_binding_failed")}async handleManagedRoomToolCall(e,t){const n=await this.managedRoomTools.execute(t);if(this.writeAppServerResponse(e,n),n.success&&t.tool==="shennian_room_send"){const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:null,r=typeof s?.text=="string"?s.text.trim():"";r&&this.emitText(r,"block")}}writeAppServerResponse(e,t){const n=this.process;n?.stdin&&n.stdin.write(`${JSON.stringify({id:e,result:t})}
5
+ `)}mapThreadStatusToRunPhase(e){const t=e?.type==="active"&&Array.isArray(e.activeFlags)?e.activeFlags:[];return t.includes("waitingOnApproval")?"waiting_approval":t.includes("waitingOnUserInput")?"waiting_user_input":"thinking"}handleAppServerNonJsonStdout(e){const t=A(e);C(t)&&this.failAppServerStartup(new Error("Codex \u672A\u767B\u5F55\u3002\u8BF7\u5148\u5728\u8FD9\u53F0\u7535\u8111\u7684\u7EC8\u7AEF\u8FD0\u884C `codex`\uFF0C\u6309\u63D0\u793A\u5B8C\u6210 ChatGPT \u767B\u5F55\u6216\u914D\u7F6E API key\uFF0C\u7136\u540E\u518D\u56DE\u5230\u795E\u5FF5\u53D1\u9001\u6D88\u606F\u3002"))}failAppServerStartup(e){this.appServerStartupError||(this.appServerStartupError=e,this.rejectAllPending(e),this.process?.kill("SIGTERM"))}handleAppServerCompletedItem(e){const t=typeof e.item=="object"&&e.item!==null?e.item:null;if(!(!t||typeof t.type!="string")&&!R(t))switch(t.type){case"agentMessage":{const n=typeof t.id=="string"?t.id:"";if(n&&this.deltaItemIds.has(n))return;typeof t.text=="string"&&this.emitText(t.text,"block");break}case"commandExecution":{const n=typeof t.command=="string"?t.command:"",s=typeof t.aggregatedOutput=="string"?t.aggregatedOutput:"";n&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:n}}),this.emitEvent({state:"tool-result",name:"command_execution",result:[s,t.exitCode!=null?`
6
+ (exit ${t.exitCode})`:""].join("").trim()});break}case"mcpToolCall":case"dynamicToolCall":{const n=typeof t.tool=="string"?t.tool:t.type;if(o(n))return;const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:{};this.emitEvent({state:"tool-call",name:n,args:s}),this.emitEvent({state:"tool-result",name:n,result:m(t.error??t.result??t.contentItems??"")});break}case"fileChange":break;case"approvalRequest":case"approval_request":case"permissionRequest":case"permission_request":case"userInputRequired":case"user_input_required":{this.emitApprovalPending(t);break}}}handleAppServerUsage(e){const t=typeof e.tokenUsage=="object"&&e.tokenUsage!==null?e.tokenUsage:null,n=typeof t?.last=="object"&&t.last!==null?t.last:null,s=typeof t?.total=="object"&&t.total!==null?t.total:null,r=n??s;if(!r)return;const i=typeof r.inputTokens=="number"?r.inputTokens:void 0,a=typeof r.outputTokens=="number"?r.outputTokens:void 0;(i!=null||a!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:a??0})}handleCodexItemLine(e){const t=e.item;if(t?.type&&!S(t))switch(t.type){case"agent_message":case"reasoning":{e.type==="item.completed"&&t.text&&this.emitText(t.text,"block");break}case"command_execution":{if(e.type==="item.started"&&t.command&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:t.command}}),e.type==="item.completed"){const n=[t.aggregated_output??"",t.exit_code!=null?`
7
+ (exit ${t.exit_code})`:""];this.emitEvent({state:"tool-result",name:"command_execution",result:n.join("").trim()||String(t.status??"")})}break}case"mcp_tool_call":{if(t.tool&&o(t.tool))return;if(e.type==="item.started"&&this.emitEvent({state:"tool-call",name:t.tool??"mcp_tool",args:{server:t.server,...t.arguments&&typeof t.arguments=="object"?t.arguments:{}}}),e.type==="item.completed"){const n=t.error&&typeof t.error=="object"?t.error.message:void 0;this.emitEvent({state:"tool-result",name:t.tool??"mcp_tool",result:n??m(t.result)})}break}case"file_change":break;case"web_search":{e.type==="item.completed"&&t.query&&this.emitText(`[web_search] ${t.query}`,"block");break}case"todo_list":{if(e.type==="item.completed"&&t.items?.length){const n=t.items.map(s=>`- [${s.completed?"x":" "}] ${s.text}`).join(`
8
+ `);this.emitText(n,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const s=e.usage;if(s){const r=s.input_tokens??s.prompt_tokens,i=s.output_tokens??s.completion_tokens;(r!=null||i!=null)&&(this.pendingUsage={inputTokens:r??0,outputTokens:i??0})}this.emitFinalIfOpen();return}case"turn.failed":{const s=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(s);return}case"error":{const s=typeof e.message=="string"?e.message:"";if(s.includes("Reconnecting"))return;this.emitErrorIfOpen(s||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const s=e.thread_id??e.session_id??e.id;typeof s=="string"&&s&&(this.agentSessionId=s,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const s=e.content??e.text;s&&this.emitText(s);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&o(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&o(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return g(e)}emitApprovalPending(e){const t=e,n=v(t.name??t.tool,t.arguments??t.input);if(n){this.emitEvent({state:"approval-pending",approval:n});return}const s=typeof e.command=="string"?e.command:"",r=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",i=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:s?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${s}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:r,content:i,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(e=!1){this.approvals.clear(),this.userInputs.clear();const t=this.process;this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),e||this.clearConfiguredManagedRoomContext(),this.rejectAllPending(new Error("codex app-server stopped")),t&&(this.process=null,this.clearForceCloseTimer(),t.kill("SIGTERM"),await new Promise(n=>{const s=setTimeout(()=>{t.kill("SIGKILL"),n()},3e3);s.unref?.(),t.once("close",()=>{clearTimeout(s),n()})}))}rejectAllPending(e){for(const[t,n]of this.pendingRequests.entries())clearTimeout(n.timer),n.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const n=_(t);if(e!==0&&e!==null){const s=n||`codex exited with code ${e}`;this.emitErrorIfOpen(s)}else E(n)?this.emitErrorIfOpen(n):this.emitFinalIfOpen();this.pendingUsage=void 0}emitFinalIfOpen(){this.approvals.clear(),this.userInputs.clear(),this.terminalState==="open"&&(this.terminalState="final",this.managedTurnReplay=null,this.managedRoomCapabilityExpectedForTurn=!1,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"final",usage:this.pendingUsage,agentSessionId:this.agentSessionId??void 0}),this.killProcess().catch(()=>{}))}emitErrorIfOpen(e){this.approvals.clear(),this.userInputs.clear(),this.terminalState==="open"&&(this.terminalState="error",this.managedTurnReplay=null,this.managedRoomCapabilityExpectedForTurn=!1,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"error",message:I(e)}),this.scheduleProcessClose())}resetRunState(){this.pendingUsage=void 0,this.terminalState="open",this.managedRoomTurnBindingFailed=!1,this.deltaItemIds.clear(),this.lastTransientStatus="",this.clearForceCloseTimer(),this.resetTextState()}clearConfiguredManagedRoomContext(){this.configuredManagedRoomContextToken=null,this.configuredManagedRoomExecutor=null}emitTransientStatus(e){const t=x(e);!t||t===this.lastTransientStatus||this.terminalState!=="open"||(this.lastTransientStatus=t,this.emitEvent({state:"delta",text:`${t}
9
+ `,thinking:!0}))}resetTextState(){this.hasEmittedText=!1,this.textTail=""}emitText(e,t="delta"){if(!e)return;let n=w(e);n&&(t==="block"&&this.hasEmittedText&&!n.startsWith(`
9
10
  `)&&(this.textTail.endsWith(`
10
11
  `)?n=`
11
12
  ${n}`:this.textTail.endsWith(`
12
13
 
13
14
  `)||(n=`
14
15
 
15
- ${n}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+n).slice(-4),this.emitEvent({state:"delta",text:n}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}export{O as CodexRuntime};
16
+ ${n}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+n).slice(-4),this.emitEvent({state:"delta",text:n}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}export{$ as CodexRuntime};
@@ -0,0 +1,3 @@
1
+ import{randomUUID as u}from"node:crypto";class g{reply;emit;source;pending=new Map;constructor(t,e,n="codex"){this.reply=t,this.emit=e,this.source=n}request(t,e,n,r,a){if(a||!n||!r||e.threadId!==n||e.turnId!==r||!Array.isArray(e.questions)||!e.questions.length||e.questions.length>8){this.reply(t,{answers:{}});return}const d=[];for(const l of e.questions){const i=l;if(!i||typeof i.id!="string"||!/^[\w-]{1,191}$/.test(i.id)||typeof i.question!="string"||i.question.length>8e3||d.some(p=>p.id===i.id)){this.reply(t,{answers:{}});return}const c=Array.isArray(i.options)?i.options.slice(0,20).flatMap(p=>p&&typeof p.label=="string"&&p.label.length<=1e3?[{label:p.label,description:typeof p.description=="string"?p.description.slice(0,2e3):void 0}]:[]):void 0;d.push({id:i.id,question:i.question,header:typeof i.header=="string"?i.header.slice(0,100):void 0,isOther:i.isOther===!0,isSecret:i.isSecret===!0,options:c})}const s=`input-${u()}`,o=setTimeout(()=>{this.pending.delete(s),this.reply(t,{answers:{}})},3e5);o.unref?.(),this.pending.set(s,{rpcId:t,turnId:r,questions:d,timer:o}),this.emit({state:"approval-pending",runPhase:"waiting_user_input",approval:{title:`${this.source==="codex"?"Codex":"Claude Code"} \u7B49\u5F85\u4F60\u56DE\u7B54`,content:d.map(l=>l.question).join(`
2
+
3
+ `),source:this.source,actionHint:"\u8BF7\u5728\u4E0B\u65B9\u56DE\u7B54\u540E\u63D0\u4EA4\u3002"},permission:{id:s,agentSessionId:n,toolCallId:String(e.itemId??s),options:[],questions:d}})}respond(t,e,n){const r=this.pending.get(t);if(!r||r.turnId!==n)throw new Error("codex_input_expired");if(!e.startsWith("input:")||e.length>3e4)throw new Error("codex_input_invalid");const a=JSON.parse(e.slice(6));if(!a||typeof a!="object"||Array.isArray(a)||Object.keys(a).some(s=>!r.questions.some(o=>o.id===s)))throw new Error("codex_input_invalid");const d=Object.create(null);for(const s of r.questions){const o=a[s.id];if(typeof o!="string"||!o.trim()||o.length>8e3)throw new Error("codex_input_invalid");if(s.options?.length&&!s.isOther&&!s.options.some(l=>l.label===o))throw new Error("codex_input_invalid");d[s.id]={answers:[o]}}this.reply(r.rpcId,{answers:d}),clearTimeout(r.timer),this.pending.delete(t),this.emit({state:"notify",runPhase:"thinking"})}resolved(t){for(const[e,n]of this.pending)n.rpcId===t&&(clearTimeout(n.timer),this.pending.delete(e))}clear(){for(const t of this.pending.values())clearTimeout(t.timer),this.reply(t.rpcId,{answers:{}});this.pending.clear()}}export{g as CodexUserInputRequests};
@@ -1 +1 @@
1
- import{loadConfig as u}from"../config/index.js";import{SERVERS as h}from"../region.js";import{PublicAgentClientError as m}from"./public-agent-client.js";class i extends m{}class T{fetchImpl;constructor(e=fetch){this.fetchImpl=e}createProject(e){return this.request("POST","/api/project-cli/projects",e)}updateProject(e,t){return this.request("PATCH",`/api/project-cli/projects/${encodeURIComponent(e)}`,t)}watchTask(e,t){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/watch`,{stewardSessionId:t})}listProjects(){return this.request("GET","/api/project-cli/projects")}listTasks(e,t){return this.request("GET",`/api/project-cli/projects/${encodeURIComponent(e)}/tasks${p({limit:t})}`)}createTask(e,t){return this.request("POST",`/api/project-cli/projects/${encodeURIComponent(e)}/tasks`,t)}readTask(e,t){return this.request("GET",`/api/project-cli/tasks/${encodeURIComponent(e)}/messages${p({limit:t})}`)}sendTask(e,t){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/messages`,t)}stopTask(e){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/stop`,{})}async request(e,t,n){const c=u();if(!c.machineToken)throw new i("not_paired","Shennian CLI is not paired.",{type:"run_command",command:"shennian pair --browser"});const l=(c.serverUrl??h.cn.url).replace(/\/+$/,"");let o;try{o=await this.fetchImpl(`${l}${t}`,{method:e,redirect:"error",headers:{authorization:`Bearer ${c.machineToken}`,...n==null?{}:{"content-type":"application/json"}},...n==null?{}:{body:JSON.stringify(n)},signal:AbortSignal.timeout(3e4)})}catch{throw new i("server_unavailable","Shennian service is unavailable.")}let s=null;try{s=await o.json()}catch{}const r=s&&typeof s=="object"&&!Array.isArray(s)?s:null;if(!o.ok)throw new i(typeof r?.error=="string"?r.error:`http_${o.status}`,typeof r?.message=="string"?r.message:"Project request failed.");if(!r)throw new i("invalid_server_response","Shennian returned an invalid response.");return r}}function p(a){const e=Object.entries(a).filter(t=>t[1]!==void 0).map(([t,n])=>`${t}=${encodeURIComponent(String(n))}`);return e.length?`?${e.join("&")}`:""}export{T as ProjectClient,i as ProjectClientError};
1
+ import{loadConfig as u}from"../config/index.js";import{SERVERS as h}from"../region.js";import{PublicAgentClientError as m}from"./public-agent-client.js";class i extends m{}class T{fetchImpl;constructor(e=fetch){this.fetchImpl=e}createProject(e){return this.request("POST","/api/project-cli/projects",e)}updateProject(e,t){return this.request("PATCH",`/api/project-cli/projects/${encodeURIComponent(e)}`,t)}watchTask(e,t){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/watch`,{stewardSessionId:t})}listProjects(){return this.request("GET","/api/project-cli/projects")}coordinate(e){return this.request("POST","/api/project-cli/coordination",e)}listTasks(e,t){return this.request("GET",`/api/project-cli/projects/${encodeURIComponent(e)}/tasks${p({limit:t})}`)}createTask(e,t){return this.request("POST",`/api/project-cli/projects/${encodeURIComponent(e)}/tasks`,t)}readTask(e,t){return this.request("GET",`/api/project-cli/tasks/${encodeURIComponent(e)}/messages${p({limit:t})}`)}sendTask(e,t){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/messages`,t)}stopTask(e){return this.request("POST",`/api/project-cli/tasks/${encodeURIComponent(e)}/stop`,{})}async request(e,t,n){const c=u();if(!c.machineToken)throw new i("not_paired","Shennian CLI is not paired.",{type:"run_command",command:"shennian pair --browser"});const l=(c.serverUrl??h.cn.url).replace(/\/+$/,"");let s;try{s=await this.fetchImpl(`${l}${t}`,{method:e,redirect:"error",headers:{authorization:`Bearer ${c.machineToken}`,...n==null?{}:{"content-type":"application/json"}},...n==null?{}:{body:JSON.stringify(n)},signal:AbortSignal.timeout(3e4)})}catch{throw new i("server_unavailable","Shennian service is unavailable.")}let o=null;try{o=await s.json()}catch{}const r=o&&typeof o=="object"&&!Array.isArray(o)?o:null;if(!s.ok)throw new i(typeof r?.error=="string"?r.error:`http_${s.status}`,typeof r?.message=="string"?r.message:"Project request failed.");if(!r)throw new i("invalid_server_response","Shennian returned an invalid response.");return r}}function p(a){const e=Object.entries(a).filter(t=>t[1]!==void 0).map(([t,n])=>`${t}=${encodeURIComponent(String(n))}`);return e.length?`?${e.join("&")}`:""}export{T as ProjectClient,i as ProjectClientError};