shennian 0.3.73 → 0.3.75

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 (91) hide show
  1. package/dist/publish-build-manifest.json +124 -59
  2. package/dist/src/agent-env.d.ts +30 -0
  3. package/dist/src/agent-env.js +4 -4
  4. package/dist/src/agents/adapter.d.ts +5 -0
  5. package/dist/src/agents/claude-managed-permissions.d.ts +33 -0
  6. package/dist/src/agents/claude-managed-permissions.js +1 -0
  7. package/dist/src/agents/claude.d.ts +11 -2
  8. package/dist/src/agents/claude.js +5 -5
  9. package/dist/src/agents/codex-managed-permissions.d.ts +32 -0
  10. package/dist/src/agents/codex-managed-permissions.js +1 -0
  11. package/dist/src/agents/codex-managed-room-tools.d.ts +40 -0
  12. package/dist/src/agents/codex-managed-room-tools.js +1 -0
  13. package/dist/src/agents/codex.d.ts +20 -2
  14. package/dist/src/agents/codex.js +11 -10
  15. package/dist/src/agents/command-spec.d.ts +8 -0
  16. package/dist/src/agents/command-spec.js +3 -2
  17. package/dist/src/agents/cursor-managed-permissions.d.ts +28 -0
  18. package/dist/src/agents/cursor-managed-permissions.js +2 -0
  19. package/dist/src/agents/cursor.d.ts +8 -2
  20. package/dist/src/agents/cursor.js +1 -1
  21. package/dist/src/agents/custom-managed-runtime.d.ts +37 -0
  22. package/dist/src/agents/custom-managed-runtime.js +2 -0
  23. package/dist/src/agents/custom.d.ts +12 -2
  24. package/dist/src/agents/custom.js +4 -4
  25. package/dist/src/agents/detect.d.ts +3 -0
  26. package/dist/src/agents/detect.js +1 -1
  27. package/dist/src/agents/model-registry/service.js +1 -1
  28. package/dist/src/agents/opencode-managed-permissions.d.ts +25 -0
  29. package/dist/src/agents/opencode-managed-permissions.js +2 -0
  30. package/dist/src/agents/opencode.d.ts +8 -2
  31. package/dist/src/agents/opencode.js +1 -1
  32. package/dist/src/agents/workbuddy-managed-permissions.d.ts +37 -0
  33. package/dist/src/agents/workbuddy-managed-permissions.js +2 -0
  34. package/dist/src/agents/workbuddy.d.ts +8 -0
  35. package/dist/src/agents/workbuddy.js +2 -2
  36. package/dist/src/commands/daemon.d.ts +29 -0
  37. package/dist/src/commands/daemon.js +14 -14
  38. package/dist/src/commands/room.js +3 -3
  39. package/dist/src/commands/runtime.js +5 -5
  40. package/dist/src/config/index.d.ts +22 -0
  41. package/dist/src/daemon-ipc/paths.d.ts +8 -0
  42. package/dist/src/daemon-ipc/paths.js +1 -1
  43. package/dist/src/daemon-ipc/server.d.ts +1 -0
  44. package/dist/src/daemon-ipc/server.js +3 -3
  45. package/dist/src/index.js +3 -3
  46. package/dist/src/log-redaction.d.ts +4 -0
  47. package/dist/src/log-redaction.js +1 -0
  48. package/dist/src/relay/client.d.ts +1 -0
  49. package/dist/src/relay/client.js +1 -1
  50. package/dist/src/room/activation-service.d.ts +23 -1
  51. package/dist/src/room/activation-service.js +7 -7
  52. package/dist/src/room/attachment-cache.d.ts +3 -0
  53. package/dist/src/room/attachment-cache.js +2 -2
  54. package/dist/src/room/attachment-upload.js +1 -1
  55. package/dist/src/room/managed-prompt-composer.d.ts +16 -3
  56. package/dist/src/room/managed-prompt-composer.js +26 -13
  57. package/dist/src/room/managed-room-binding.d.ts +3 -3
  58. package/dist/src/room/managed-room-binding.js +1 -1
  59. package/dist/src/room/managed-room-ipc.d.ts +32 -0
  60. package/dist/src/room/managed-room-ipc.js +3 -1
  61. package/dist/src/room/room-action-client.d.ts +5 -1
  62. package/dist/src/room/room-action-client.js +1 -1
  63. package/dist/src/security/managed-agent-credential-paths.d.ts +6 -0
  64. package/dist/src/security/managed-agent-credential-paths.js +1 -0
  65. package/dist/src/security/managed-agent-executable.d.ts +19 -0
  66. package/dist/src/security/managed-agent-executable.js +1 -0
  67. package/dist/src/security/managed-agent-policy.d.ts +55 -0
  68. package/dist/src/security/managed-agent-policy.js +1 -0
  69. package/dist/src/security/managed-agent-runtime.d.ts +44 -0
  70. package/dist/src/security/managed-agent-runtime.js +1 -0
  71. package/dist/src/session/handlers/chat.d.ts +8 -1
  72. package/dist/src/session/handlers/chat.js +2 -2
  73. package/dist/src/session/handlers/remote-access.d.ts +4 -0
  74. package/dist/src/session/handlers/remote-access.js +1 -0
  75. package/dist/src/session/handlers/room-managed.d.ts +1 -1
  76. package/dist/src/session/handlers/room-managed.js +1 -1
  77. package/dist/src/session/history-subscriptions.d.ts +6 -0
  78. package/dist/src/session/history-subscriptions.js +1 -1
  79. package/dist/src/session/manager.d.ts +7 -2
  80. package/dist/src/session/manager.js +1 -1
  81. package/dist/src/session/queue.d.ts +4 -0
  82. package/dist/src/session/queue.js +4 -4
  83. package/dist/src/session/types.d.ts +14 -0
  84. package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +70 -0
  85. package/node_modules/@shennian/wire/dist/agent-workspace.js +111 -1
  86. package/node_modules/@shennian/wire/dist/machine.d.ts +2 -0
  87. package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
  88. package/node_modules/@shennian/wire/dist/session-sync.d.ts +53 -3
  89. package/node_modules/@shennian/wire/dist/session-sync.js +5 -1
  90. package/node_modules/@shennian/wire/dist/session.d.ts +2 -0
  91. package/package.json +3 -1
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "jsMinified": true,
4
4
  "minifier": "esbuild",
5
- "fileCount": 131,
5
+ "fileCount": 144,
6
6
  "files": [
7
7
  {
8
8
  "file": "bin/shennian.js",
@@ -11,18 +11,33 @@
11
11
  },
12
12
  {
13
13
  "file": "src/agent-env.js",
14
- "beforeBytes": 4611,
15
- "afterBytes": 2531
14
+ "beforeBytes": 9273,
15
+ "afterBytes": 4197
16
16
  },
17
17
  {
18
18
  "file": "src/agents/adapter.js",
19
19
  "beforeBytes": 552,
20
20
  "afterBytes": 322
21
21
  },
22
+ {
23
+ "file": "src/agents/claude-managed-permissions.js",
24
+ "beforeBytes": 10147,
25
+ "afterBytes": 4390
26
+ },
22
27
  {
23
28
  "file": "src/agents/claude.js",
24
- "beforeBytes": 12169,
25
- "afterBytes": 6313
29
+ "beforeBytes": 15474,
30
+ "afterBytes": 8088
31
+ },
32
+ {
33
+ "file": "src/agents/codex-managed-permissions.js",
34
+ "beforeBytes": 12579,
35
+ "afterBytes": 4943
36
+ },
37
+ {
38
+ "file": "src/agents/codex-managed-room-tools.js",
39
+ "beforeBytes": 8618,
40
+ "afterBytes": 4667
26
41
  },
27
42
  {
28
43
  "file": "src/agents/codex-utils.js",
@@ -31,33 +46,43 @@
31
46
  },
32
47
  {
33
48
  "file": "src/agents/codex.js",
34
- "beforeBytes": 46603,
35
- "afterBytes": 23409
49
+ "beforeBytes": 55539,
50
+ "afterBytes": 29007
36
51
  },
37
52
  {
38
53
  "file": "src/agents/command-spec.js",
39
- "beforeBytes": 16528,
40
- "afterBytes": 7521
54
+ "beforeBytes": 17437,
55
+ "afterBytes": 7807
41
56
  },
42
57
  {
43
58
  "file": "src/agents/config-status.js",
44
59
  "beforeBytes": 7583,
45
60
  "afterBytes": 3900
46
61
  },
62
+ {
63
+ "file": "src/agents/cursor-managed-permissions.js",
64
+ "beforeBytes": 12138,
65
+ "afterBytes": 5991
66
+ },
47
67
  {
48
68
  "file": "src/agents/cursor.js",
49
- "beforeBytes": 9236,
50
- "afterBytes": 4191
69
+ "beforeBytes": 12051,
70
+ "afterBytes": 5791
71
+ },
72
+ {
73
+ "file": "src/agents/custom-managed-runtime.js",
74
+ "beforeBytes": 9992,
75
+ "afterBytes": 5280
51
76
  },
52
77
  {
53
78
  "file": "src/agents/custom.js",
54
- "beforeBytes": 10938,
55
- "afterBytes": 5449
79
+ "beforeBytes": 16524,
80
+ "afterBytes": 8695
56
81
  },
57
82
  {
58
83
  "file": "src/agents/detect.js",
59
- "beforeBytes": 1506,
60
- "afterBytes": 701
84
+ "beforeBytes": 2358,
85
+ "afterBytes": 1204
61
86
  },
62
87
  {
63
88
  "file": "src/agents/external-channel-instructions.js",
@@ -96,8 +121,8 @@
96
121
  },
97
122
  {
98
123
  "file": "src/agents/model-registry/service.js",
99
- "beforeBytes": 3262,
100
- "afterBytes": 1409
124
+ "beforeBytes": 4344,
125
+ "afterBytes": 1743
101
126
  },
102
127
  {
103
128
  "file": "src/agents/model-registry/types.js",
@@ -119,10 +144,15 @@
119
144
  "beforeBytes": 11104,
120
145
  "afterBytes": 4973
121
146
  },
147
+ {
148
+ "file": "src/agents/opencode-managed-permissions.js",
149
+ "beforeBytes": 7040,
150
+ "afterBytes": 3492
151
+ },
122
152
  {
123
153
  "file": "src/agents/opencode.js",
124
- "beforeBytes": 8314,
125
- "afterBytes": 4377
154
+ "beforeBytes": 11310,
155
+ "afterBytes": 6249
126
156
  },
127
157
  {
128
158
  "file": "src/agents/platform-instructions.js",
@@ -134,10 +164,15 @@
134
164
  "beforeBytes": 1705,
135
165
  "afterBytes": 810
136
166
  },
167
+ {
168
+ "file": "src/agents/workbuddy-managed-permissions.js",
169
+ "beforeBytes": 13486,
170
+ "afterBytes": 6431
171
+ },
137
172
  {
138
173
  "file": "src/agents/workbuddy.js",
139
- "beforeBytes": 14475,
140
- "afterBytes": 7299
174
+ "beforeBytes": 18087,
175
+ "afterBytes": 9384
141
176
  },
142
177
  {
143
178
  "file": "src/commands/daemon-process.js",
@@ -156,8 +191,8 @@
156
191
  },
157
192
  {
158
193
  "file": "src/commands/daemon.js",
159
- "beforeBytes": 39845,
160
- "afterBytes": 19471
194
+ "beforeBytes": 43216,
195
+ "afterBytes": 20705
161
196
  },
162
197
  {
163
198
  "file": "src/commands/integration.js",
@@ -191,13 +226,13 @@
191
226
  },
192
227
  {
193
228
  "file": "src/commands/room.js",
194
- "beforeBytes": 16423,
195
- "afterBytes": 9464
229
+ "beforeBytes": 17175,
230
+ "afterBytes": 9722
196
231
  },
197
232
  {
198
233
  "file": "src/commands/runtime.js",
199
- "beforeBytes": 4986,
200
- "afterBytes": 2765
234
+ "beforeBytes": 5624,
235
+ "afterBytes": 3146
201
236
  },
202
237
  {
203
238
  "file": "src/commands/tools.js",
@@ -226,8 +261,8 @@
226
261
  },
227
262
  {
228
263
  "file": "src/daemon-ipc/paths.js",
229
- "beforeBytes": 1010,
230
- "afterBytes": 558
264
+ "beforeBytes": 2006,
265
+ "afterBytes": 902
231
266
  },
232
267
  {
233
268
  "file": "src/daemon-ipc/protocol.js",
@@ -241,8 +276,8 @@
241
276
  },
242
277
  {
243
278
  "file": "src/daemon-ipc/server.js",
244
- "beforeBytes": 5882,
245
- "afterBytes": 2986
279
+ "beforeBytes": 6704,
280
+ "afterBytes": 3447
246
281
  },
247
282
  {
248
283
  "file": "src/daemon-log.js",
@@ -276,8 +311,13 @@
276
311
  },
277
312
  {
278
313
  "file": "src/index.js",
279
- "beforeBytes": 25214,
280
- "afterBytes": 12983
314
+ "beforeBytes": 25818,
315
+ "afterBytes": 13311
316
+ },
317
+ {
318
+ "file": "src/log-redaction.js",
319
+ "beforeBytes": 5228,
320
+ "afterBytes": 2828
281
321
  },
282
322
  {
283
323
  "file": "src/log-reporter.js",
@@ -406,8 +446,8 @@
406
446
  },
407
447
  {
408
448
  "file": "src/relay/client.js",
409
- "beforeBytes": 14515,
410
- "afterBytes": 7173
449
+ "beforeBytes": 15036,
450
+ "afterBytes": 7402
411
451
  },
412
452
  {
413
453
  "file": "src/room/activation-audit.js",
@@ -421,18 +461,18 @@
421
461
  },
422
462
  {
423
463
  "file": "src/room/activation-service.js",
424
- "beforeBytes": 14897,
425
- "afterBytes": 6867
464
+ "beforeBytes": 20861,
465
+ "afterBytes": 10189
426
466
  },
427
467
  {
428
468
  "file": "src/room/attachment-cache.js",
429
- "beforeBytes": 12558,
430
- "afterBytes": 6015
469
+ "beforeBytes": 13659,
470
+ "afterBytes": 6480
431
471
  },
432
472
  {
433
473
  "file": "src/room/attachment-upload.js",
434
- "beforeBytes": 4871,
435
- "afterBytes": 2617
474
+ "beforeBytes": 6996,
475
+ "afterBytes": 3546
436
476
  },
437
477
  {
438
478
  "file": "src/room/device-authorization-client.js",
@@ -461,18 +501,18 @@
461
501
  },
462
502
  {
463
503
  "file": "src/room/managed-prompt-composer.js",
464
- "beforeBytes": 4610,
465
- "afterBytes": 4552
504
+ "beforeBytes": 8405,
505
+ "afterBytes": 7995
466
506
  },
467
507
  {
468
508
  "file": "src/room/managed-room-binding.js",
469
- "beforeBytes": 6014,
470
- "afterBytes": 3277
509
+ "beforeBytes": 6604,
510
+ "afterBytes": 3782
471
511
  },
472
512
  {
473
513
  "file": "src/room/managed-room-ipc.js",
474
- "beforeBytes": 7658,
475
- "afterBytes": 3766
514
+ "beforeBytes": 11388,
515
+ "afterBytes": 5518
476
516
  },
477
517
  {
478
518
  "file": "src/room/mirror-sync-service.js",
@@ -491,8 +531,8 @@
491
531
  },
492
532
  {
493
533
  "file": "src/room/room-action-client.js",
494
- "beforeBytes": 23728,
495
- "afterBytes": 11957
534
+ "beforeBytes": 27147,
535
+ "afterBytes": 13584
496
536
  },
497
537
  {
498
538
  "file": "src/room/room-binding-client.js",
@@ -504,6 +544,26 @@
504
544
  "beforeBytes": 27871,
505
545
  "afterBytes": 15713
506
546
  },
547
+ {
548
+ "file": "src/security/managed-agent-credential-paths.js",
549
+ "beforeBytes": 1853,
550
+ "afterBytes": 748
551
+ },
552
+ {
553
+ "file": "src/security/managed-agent-executable.js",
554
+ "beforeBytes": 3298,
555
+ "afterBytes": 1589
556
+ },
557
+ {
558
+ "file": "src/security/managed-agent-policy.js",
559
+ "beforeBytes": 7298,
560
+ "afterBytes": 3524
561
+ },
562
+ {
563
+ "file": "src/security/managed-agent-runtime.js",
564
+ "beforeBytes": 6814,
565
+ "afterBytes": 3251
566
+ },
507
567
  {
508
568
  "file": "src/session/archive-zip.js",
509
569
  "beforeBytes": 8037,
@@ -546,8 +606,8 @@
546
606
  },
547
607
  {
548
608
  "file": "src/session/handlers/chat.js",
549
- "beforeBytes": 36577,
550
- "afterBytes": 15412
609
+ "beforeBytes": 41468,
610
+ "afterBytes": 17513
551
611
  },
552
612
  {
553
613
  "file": "src/session/handlers/control.js",
@@ -564,10 +624,15 @@
564
624
  "beforeBytes": 676,
565
625
  "afterBytes": 392
566
626
  },
627
+ {
628
+ "file": "src/session/handlers/remote-access.js",
629
+ "beforeBytes": 1644,
630
+ "afterBytes": 821
631
+ },
567
632
  {
568
633
  "file": "src/session/handlers/room-managed.js",
569
- "beforeBytes": 3724,
570
- "afterBytes": 2153
634
+ "beforeBytes": 4009,
635
+ "afterBytes": 2276
571
636
  },
572
637
  {
573
638
  "file": "src/session/handlers/session-refresh.js",
@@ -591,8 +656,8 @@
591
656
  },
592
657
  {
593
658
  "file": "src/session/history-subscriptions.js",
594
- "beforeBytes": 13799,
595
- "afterBytes": 6616
659
+ "beforeBytes": 21124,
660
+ "afterBytes": 10285
596
661
  },
597
662
  {
598
663
  "file": "src/session/index-publisher.js",
@@ -601,8 +666,8 @@
601
666
  },
602
667
  {
603
668
  "file": "src/session/manager.js",
604
- "beforeBytes": 28780,
605
- "afterBytes": 14785
669
+ "beforeBytes": 30450,
670
+ "afterBytes": 15750
606
671
  },
607
672
  {
608
673
  "file": "src/session/native-cleanup-outbox.js",
@@ -621,8 +686,8 @@
621
686
  },
622
687
  {
623
688
  "file": "src/session/queue.js",
624
- "beforeBytes": 24780,
625
- "afterBytes": 11354
689
+ "beforeBytes": 25631,
690
+ "afterBytes": 11668
626
691
  },
627
692
  {
628
693
  "file": "src/session/store.js",
@@ -1,3 +1,24 @@
1
+ import type { AgentType } from '@shennian/wire';
2
+ /**
3
+ * Session-scoped Shennian capabilities that are intentionally available to a
4
+ * managed Agent. Any new entry is a security boundary change and must have a
5
+ * matching authorization test before being added here.
6
+ */
7
+ export declare const MANAGED_AGENT_SESSION_ENV_KEYS: readonly ["SHENNIAN_MANAGED_ROOM_CONTEXT", "SHENNIAN_MANAGED_ROOM_IPC_ROOT"];
8
+ export declare function getManagedAgentProviderEnvKeys(agentType: AgentType): readonly string[];
9
+ export declare function getManagedAgentBaseEnvKeys(platform?: NodeJS.Platform): readonly string[];
10
+ export type ManagedAgentProcessEnvInput = {
11
+ agentType: AgentType;
12
+ /** The daemon snapshot is read only for explicitly allowlisted OS values. */
13
+ daemonEnv?: NodeJS.ProcessEnv;
14
+ /** Provider credentials already selected by Shennian's provider config. */
15
+ providerEnv?: NodeJS.ProcessEnv;
16
+ /** Short-lived Room or Manager capabilities issued for this exact session. */
17
+ sessionEnv?: NodeJS.ProcessEnv;
18
+ /** Harmless process behavior flags such as NO_COLOR. */
19
+ runtimeEnv?: NodeJS.ProcessEnv;
20
+ platform?: NodeJS.Platform;
21
+ };
1
22
  export declare function readLatestUserEnv(): NodeJS.ProcessEnv;
2
23
  export declare function mergeAgentProcessEnv(input: {
3
24
  daemonEnv: NodeJS.ProcessEnv;
@@ -5,3 +26,12 @@ export declare function mergeAgentProcessEnv(input: {
5
26
  extra?: NodeJS.ProcessEnv;
6
27
  }): NodeJS.ProcessEnv;
7
28
  export declare function buildAgentProcessEnv(extra?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
29
+ /**
30
+ * Builds the environment for an automatically activated managed Agent.
31
+ *
32
+ * Unlike buildAgentProcessEnv(), this function never starts a login shell and
33
+ * never merges the daemon environment wholesale. Provider and Shennian
34
+ * capability values must be supplied in their dedicated buckets; unexpected
35
+ * keys are dropped instead of silently broadening the child's authority.
36
+ */
37
+ export declare function buildManagedAgentProcessEnv(input: ManagedAgentProcessEnvInput): NodeJS.ProcessEnv;
@@ -1,8 +1,8 @@
1
- import E from"node:os";import u from"node:path";import{spawnSync as d}from"node:child_process";import{buildAugmentedPath as h}from"./env-path.js";import{buildWindowsSystemEnv as m,resolveWindowsPowerShellPath as _}from"./windows-shell.js";const a="__SHENNIAN_AGENT_ENV_START__",p="__SHENNIAN_AGENT_ENV_END__";function l(e){return`'${e.replace(/'/g,"'\\''")}'`}function v(e){const n=e.indexOf(a),i=e.indexOf(p,n+a.length);if(n===-1||i===-1)return null;const r=e.slice(n+a.length,i);try{const t=JSON.parse(r),c={};for(const[s,o]of Object.entries(t))typeof o=="string"&&(c[s]=o);return c}catch{return null}}function g(){const e=process.env.SHELL?.trim()||"/bin/sh",n=[`printf ${l(a)}`,`${l(process.execPath)} -e ${l("process.stdout.write(JSON.stringify(process.env))")}`,`printf ${l(p)}`].join("; ");for(const i of[["-ilc",n],["-lc",n]]){const r=d(e,i,{env:process.env,encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0}),t=typeof r.stdout=="string"?v(r.stdout):null;if(t)return t}return null}function w(){const e=`
1
+ import S from"node:os";import a from"node:path";import{spawnSync as _}from"node:child_process";import{buildAugmentedPath as g}from"./env-path.js";import{buildWindowsSystemEnv as u,resolveWindowsPowerShellPath as h}from"./windows-shell.js";const l="__SHENNIAN_AGENT_ENV_START__",A="__SHENNIAN_AGENT_ENV_END__",m=["HOME","USER","LOGNAME","LANG","LANGUAGE","LC_ALL","LC_CTYPE","TMPDIR","TMP","TEMP","TZ"],N=["SystemRoot","WINDIR","ComSpec","PATHEXT","USERPROFILE","APPDATA","LOCALAPPDATA","ProgramData","ProgramFiles","ProgramFiles(x86)","TEMP","TMP","TZ"],P=["NO_COLOR"],O=["SHENNIAN_MANAGED_ROOM_CONTEXT","SHENNIAN_MANAGED_ROOM_IPC_ROOT"],T={codex:["OPENAI_BASE_URL","OPENAI_API_KEY"],claude:["ANTHROPIC_BASE_URL","ANTHROPIC_API_KEY"],pi:["DASHSCOPE_BASE_URL","DASHSCOPE_API_KEY"]};function w(e){return T[e]??[]}function V(e=process.platform){return["PATH",...e==="win32"?N:m,...P]}function p(e){return`'${e.replace(/'/g,"'\\''")}'`}function v(e){const n=e.indexOf(l),r=e.indexOf(A,n+l.length);if(n===-1||r===-1)return null;const t=e.slice(n+l.length,r);try{const o=JSON.parse(t),i={};for(const[c,s]of Object.entries(o))typeof s=="string"&&(i[c]=s);return i}catch{return null}}function R(){const e=process.env.SHELL?.trim()||"/bin/sh",n=[`printf ${p(l)}`,`${p(process.execPath)} -e ${p("process.stdout.write(JSON.stringify(process.env))")}`,`printf ${p(A)}`].join("; ");for(const r of[["-ilc",n],["-lc",n]]){const t=_(e,r,{env:process.env,encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0}),o=typeof t.stdout=="string"?v(t.stdout):null;if(o)return o}return null}function y(){const e=`
2
2
  $envs = @{}
3
3
  [Environment]::GetEnvironmentVariables('Machine').GetEnumerator() | ForEach-Object { $envs[$_.Key] = [string]$_.Value }
4
4
  [Environment]::GetEnvironmentVariables('User').GetEnumerator() | ForEach-Object { $envs[$_.Key] = [string]$_.Value }
5
- Write-Output '${a}'
5
+ Write-Output '${l}'
6
6
  $envs | ConvertTo-Json -Compress
7
- Write-Output '${p}'
8
- `,n=d(_(),["-NoProfile","-Command",e],{env:{...process.env,...m(process.env)},encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0});return typeof n.stdout=="string"?v(n.stdout):null}function N(){return(E.platform()==="win32"?w():g())??{}}function S(e){const n={...e.daemonEnv,...e.userEnv,...e.extra};return process.platform==="win32"&&Object.assign(n,m(n)),n.PATH=P(e.daemonEnv,e.userEnv,e.extra,n),delete n.Path,delete n.path,n}function j(e={}){return S({daemonEnv:process.env,userEnv:N(),extra:e})}function f(e){return e?.PATH??e?.Path??e?.path}function P(e,n,i,r){const t=[];for(const s of[f(e),f(n),f(i)])for(const o of(s??"").split(u.delimiter))o&&!t.includes(o)&&t.push(o);if(process.platform==="win32"){const s=r.SystemRoot||r.WINDIR||process.env.SystemRoot||process.env.WINDIR||"C:\\Windows";for(const o of[u.win32.join(s,"System32"),u.win32.join(s,"System32","WindowsPowerShell","v1.0"),u.win32.join(s)])o&&!t.includes(o)&&t.push(o)}const c=u.dirname(process.execPath);return c&&!t.includes(c)&&t.unshift(c),h({pathValue:t.join(u.delimiter),env:r})}export{j as buildAgentProcessEnv,S as mergeAgentProcessEnv,N as readLatestUserEnv};
7
+ Write-Output '${A}'
8
+ `,n=_(h(),["-NoProfile","-Command",e],{env:{...process.env,...u(process.env)},encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0});return typeof n.stdout=="string"?v(n.stdout):null}function I(){return(S.platform()==="win32"?y():R())??{}}function G(e){const n={...e.daemonEnv,...e.userEnv,...e.extra};return process.platform==="win32"&&Object.assign(n,u(n)),n.PATH=M(e.daemonEnv,e.userEnv,e.extra,n),delete n.Path,delete n.path,n}function j(e={}){return G({daemonEnv:process.env,userEnv:I(),extra:e})}function W(e){const n=e.daemonEnv??process.env,r=e.platform??process.platform,t={};return f(t,n,r==="win32"?N:m,r),f(t,e.providerEnv,w(e.agentType),r),f(t,e.sessionEnv,O,r),f(t,e.runtimeEnv,P,r),r==="win32"&&Object.assign(t,u({...n,...t})),t.PATH=D(n,t,r),delete t.Path,delete t.path,t}function f(e,n,r,t){if(!n)return;const o=Object.entries(n);for(const i of r){const s=(t==="win32"?o.find(([E])=>E.toUpperCase()===i.toUpperCase()):o.find(([E])=>E===i))?.[1];typeof s=="string"&&s.length>0&&(e[i]=s)}}function D(e,n,r){const t=r==="win32"?a.win32.delimiter:a.posix.delimiter,o=[],i=(c,s=!1)=>{if(c)for(const E of c.split(t))!E||o.includes(E)||(s?o.unshift(E):o.push(E))};if(i(d(e)),i(a.dirname(process.execPath),!0),r==="win32"){const c=u({...e,...n}),s=c.SystemRoot??c.WINDIR??"C:\\Windows";i(a.win32.join(s,"System32")),i(a.win32.join(s,"System32","WindowsPowerShell","v1.0")),i(s)}else i("/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin");return o.join(t)}function d(e){return e?.PATH??e?.Path??e?.path}function M(e,n,r,t){const o=[];for(const c of[d(e),d(n),d(r)])for(const s of(c??"").split(a.delimiter))s&&!o.includes(s)&&o.push(s);if(process.platform==="win32"){const c=t.SystemRoot||t.WINDIR||process.env.SystemRoot||process.env.WINDIR||"C:\\Windows";for(const s of[a.win32.join(c,"System32"),a.win32.join(c,"System32","WindowsPowerShell","v1.0"),a.win32.join(c)])s&&!o.includes(s)&&o.push(s)}const i=a.dirname(process.execPath);return i&&!o.includes(i)&&o.unshift(i),g({pathValue:o.join(a.delimiter),env:t})}export{O as MANAGED_AGENT_SESSION_ENV_KEYS,j as buildAgentProcessEnv,W as buildManagedAgentProcessEnv,V as getManagedAgentBaseEnvKeys,w as getManagedAgentProviderEnvKeys,G as mergeAgentProcessEnv,I as readLatestUserEnv};
@@ -1,5 +1,7 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import type { AgentType, ChatAttachmentMeta, ExternalChannelSessionStatus, SessionRunPhase } from '@shennian/wire';
3
+ import type { CompiledManagedAgentPolicy } from '../security/managed-agent-policy.js';
4
+ import type { ManagedRoomExecutor } from '../room/managed-room-ipc.js';
3
5
  export type AgentEvent = {
4
6
  state: string;
5
7
  runId: string;
@@ -47,6 +49,9 @@ export declare abstract class AgentAdapter extends EventEmitter<AgentAdapterEven
47
49
  sessionId?: string;
48
50
  externalChannel?: ExternalChannelSessionStatus | null;
49
51
  env?: NodeJS.ProcessEnv;
52
+ managedAgentPolicy?: CompiledManagedAgentPolicy | null;
53
+ managedRoomContextToken?: string | null;
54
+ managedRoomExecutor?: ManagedRoomExecutor | null;
50
55
  }): void;
51
56
  getStatus?(): Promise<{
52
57
  active: boolean;
@@ -0,0 +1,33 @@
1
+ import type { ManagedAgentEnforcement } from '@shennian/wire';
2
+ import type { ManagedAgentRuntimeSecurityDeclaration } from '../security/managed-agent-runtime.js';
3
+ type JsonObject = Record<string, unknown>;
4
+ export type ClaudeManagedPermissionOptions = {
5
+ /** Exact runtime files required by Shennian's managed Room transport. */
6
+ internalReadPaths?: readonly string[];
7
+ /** Exact local sockets required by Shennian's managed Room transport. */
8
+ internalUnixSockets?: readonly string[];
9
+ shellSubprocessPolicy?: {
10
+ inherit: 'none';
11
+ allowedEnvKeys: readonly string[];
12
+ deniedEnvKeys: readonly string[];
13
+ };
14
+ };
15
+ export type ClaudeManagedPermissionConfig = {
16
+ /** One-invocation-only settings passed inline through --settings. */
17
+ settings: JsonObject;
18
+ args: string[];
19
+ };
20
+ /**
21
+ * v2.1.260 is the first evidence baseline used by Shennian: it includes
22
+ * restricted mode, source isolation, fail-closed sandbox startup, credential
23
+ * scrubbing, outside-workspace read blocking, and the macOS fix for that read
24
+ * boundary. Unknown and older builds therefore resolve as unverified.
25
+ */
26
+ export declare const CLAUDE_MANAGED_RUNTIME_SECURITY: ManagedAgentRuntimeSecurityDeclaration;
27
+ /**
28
+ * Converts the daemon-verified effective policy into Claude Code's native,
29
+ * invocation-scoped permission and sandbox configuration. It never writes to
30
+ * ~/.claude or the project's .claude directory.
31
+ */
32
+ export declare function compileClaudeManagedPermissions(enforcement: ManagedAgentEnforcement, resolvedWorkDir: string, options?: ClaudeManagedPermissionOptions): ClaudeManagedPermissionConfig;
33
+ export {};
@@ -0,0 +1 @@
1
+ import g from"node:fs";import n from"node:path";import{resolveProtectedShennianDirectories as N}from"../security/managed-agent-credential-paths.js";const m={commandNetwork:{allow:!0,deny:!0},webSearch:{allow:!0,deny:!0},browser:{allow:!0,deny:!0},computerUse:{allow:!1,deny:!0},mcp:{allow:!0,deny:!0}},M={minimumRuntimeVersion:"2.1.260",maximumRuntimeVersionExclusive:"2.2.0",platforms:{darwin:{level:"hard",fileAccess:{"workspace-read":!0,"workspace-write":!0,"host-full":!0},externalCapabilities:m},linux:{level:"partial",fileAccess:{"workspace-read":!0,"workspace-write":!0,"host-full":!0},externalCapabilities:m,knownGaps:["internalTransport.unixSocketGranularity"]},wsl:{level:"partial",fileAccess:{"workspace-read":!0,"workspace-write":!0,"host-full":!0},externalCapabilities:m,knownGaps:["internalTransport.unixSocketGranularity"]},win32:{level:"partial",fileAccess:{"workspace-read":!1,"workspace-write":!1,"host-full":!0},externalCapabilities:{commandNetwork:{allow:!0,deny:!1},webSearch:{allow:!0,deny:!0},browser:{allow:!0,deny:!0},computerUse:{allow:!1,deny:!0},mcp:{allow:!0,deny:!0}},knownGaps:["sandbox.nativeWindowsUnavailable"]}}},P=["//**/.env","//**/.env.*","//**/*.key","//**/*.pem","~/.ssh/**","~/.aws/**","~/.azure/**","~/.config/gcloud/**","~/.netrc","~/.npmrc","~/.shennian/**"],f=["/**/.env","/**/.env.*","/**/*.key","/**/*.pem","~/.ssh","~/.aws","~/.azure","~/.config/gcloud","~/.netrc","~/.npmrc"],x="~/.shennian",W=["Read","Glob","Grep","LSP"],z=["Edit","Write","NotebookEdit"];function G(a,e,l={}){const b=D(e),t=a.effectivePolicy,s=a.platform!=="win32",_=A(l.internalReadPaths),h=A(l.internalUnixSockets),S=d(n.parse(b).root),u=d(b),i=t.fileAccess==="host-full",c=t.fileAccess==="workspace-write",p=N(),o=[];c&&o.push("Edit(/**)"),i&&o.push("Read","Edit"),t.externalCapabilities.webSearch&&o.push("WebSearch","WebFetch"),t.externalCapabilities.mcp&&o.push("mcp__*"),s||o.push("Bash","PowerShell");const E=[...P.flatMap(r=>[`Read(${r})`,`Edit(${r})`]),...p.flatMap(r=>[`Read(${y(r)}/**)`,`Edit(${y(r)}/**)`]),...t.externalCapabilities.webSearch?[]:["WebSearch","WebFetch"],...t.externalCapabilities.mcp?[]:["mcp__*"]],C=s?{disabled:!1,allowRead:[...new Set([u,..._])],allowWrite:i?[S]:c?[u]:[],denyRead:[...f,x,...p],denyWrite:[...f,x,...p,...!i&&!c?[u]:[]]}:void 0,v=s?{allowedDomains:t.externalCapabilities.commandNetwork?["*"]:[],deniedDomains:t.externalCapabilities.commandNetwork?[]:["*"],strictAllowlist:!0,allowLocalBinding:t.externalCapabilities.commandNetwork,allowUnixSockets:a.platform==="darwin"?h:[],allowAllUnixSockets:(a.platform==="linux"||a.platform==="wsl")&&h.length>0}:void 0,k={permissions:{defaultMode:"dontAsk",disableBypassPermissionsMode:"disable",disableAutoMode:"disable",blockReadsOutsideWorkingDirectories:!i,allow:[...new Set(o)].sort(),deny:[...new Set(E)].sort()},disableArtifact:!0,disableRemoteControl:!0,disableWorkflows:!0,disableClaudeAiConnectors:!t.externalCapabilities.mcp,...s?{sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,allowUnsandboxedCommands:!1,excludedCommands:[],allowAppleEvents:!1,filesystem:C,network:v,credentials:{files:f.map(r=>({path:r,mode:"deny"})),envVars:I(l.shellSubprocessPolicy?.deniedEnvKeys).map(r=>({name:r,mode:"deny"}))}}}:{}},R=["Bash",...W,...c||i?z:[],...t.externalCapabilities.webSearch?["WebSearch","WebFetch"]:[]],w=["--restricted","--setting-sources","","--settings",JSON.stringify(k),"--permission-mode","dontAsk","--tools",[...new Set(R)].join(","),t.externalCapabilities.browser?"--chrome":"--no-chrome"];return i&&w.push("--add-dir",S),t.externalCapabilities.mcp||w.push("--strict-mcp-config","--mcp-config",JSON.stringify({mcpServers:{}})),{settings:k,args:w}}function D(a){const e=n.normalize(a.trim());if(!e||!n.isAbsolute(e))throw new Error("claude_managed_workdir_invalid");let l;try{l=g.realpathSync(e)}catch{throw new Error("claude_managed_workdir_unavailable")}if(n.normalize(l)!==e)throw new Error("claude_managed_workdir_not_realpath");return e}function A(a){return[...new Set(a??[])].map(e=>n.normalize(e.trim())).filter(e=>e&&n.isAbsolute(e)).map(d).sort()}function d(a){return a.replaceAll("\\","/")}function y(a){const e=d(a);return e.startsWith("/")?`/${e}`:`//${e}`}function I(a){return[...new Set(a??[])].filter(e=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)).sort()}export{M as CLAUDE_MANAGED_RUNTIME_SECURITY,G as compileClaudeManagedPermissions};
@@ -1,5 +1,6 @@
1
- import { AgentAdapter, type AgentStartOptions } from './adapter.js';
1
+ import { AgentAdapter, type AgentSendContext, type AgentStartOptions } from './adapter.js';
2
2
  import type { ChatAttachmentMeta, ExternalChannelSessionStatus } from '@shennian/wire';
3
+ import { type CompiledManagedAgentPolicy } from '../security/managed-agent-policy.js';
3
4
  export declare function normalizeClaudeModelId(modelId?: string | null): string;
4
5
  export declare function normalizeClaudeReasoningEffort(reasoningEffort?: string | null): string | undefined;
5
6
  export declare function resetClaudeCapabilityCacheForTests(): void;
@@ -17,6 +18,7 @@ export declare class ClaudeAdapter extends AgentAdapter {
17
18
  private hasEmittedText;
18
19
  private terminalState;
19
20
  private persistNativeSession;
21
+ private managedAgentPolicy;
20
22
  constructor(options?: {
21
23
  systemPrompt?: string;
22
24
  hidden?: boolean;
@@ -28,12 +30,15 @@ export declare class ClaudeAdapter extends AgentAdapter {
28
30
  sessionId?: string;
29
31
  externalChannel?: ExternalChannelSessionStatus | null;
30
32
  env?: NodeJS.ProcessEnv;
33
+ managedAgentPolicy?: CompiledManagedAgentPolicy | null;
31
34
  }): void;
32
35
  start(sessionId: string, workDir: string, agentSessionId?: string | null, options?: AgentStartOptions): Promise<void>;
33
- send(text: string, modelId?: string, reasoningEffort?: string, _attachments?: ChatAttachmentMeta[], agentSystemPrompt?: string | null): Promise<void>;
36
+ send(text: string, modelId?: string, reasoningEffort?: string, _attachments?: ChatAttachmentMeta[], agentSystemPrompt?: string | null, context?: AgentSendContext): Promise<void>;
34
37
  resume(agentSessionId: string): Promise<void>;
35
38
  stop(): Promise<void>;
36
39
  private spawnAndParse;
40
+ private buildManagedPermissionConfig;
41
+ private buildProcessEnv;
37
42
  private handleStreamEvent;
38
43
  private handleProcessClose;
39
44
  private emitFinalIfOpen;
@@ -42,3 +47,7 @@ export declare class ClaudeAdapter extends AgentAdapter {
42
47
  private emitEvent;
43
48
  private killProcess;
44
49
  }
50
+ export declare function resolveClaudeManagedInternalAccess(): {
51
+ readPaths: string[];
52
+ unixSockets: string[];
53
+ };
@@ -1,8 +1,8 @@
1
- import{createInterface as f}from"node:readline";import{randomUUID as d}from"node:crypto";import{AgentAdapter as g,registerAgent as S}from"./adapter.js";import{resolveBuiltinCommand as p,spawnAgentCommand as I,spawnResolvedCommandSync as E}from"./command-spec.js";import{buildAgentProcessEnv as m}from"../agent-env.js";import{buildPlatformInstructions as c}from"./platform-instructions.js";function x(i){return i?.trim()||"default"}const y=new Set(["low","medium","high","xhigh","max"]),o=new Map;function v(i){const e=i?.trim();if(e){if(y.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function R(){o.clear()}function w(i){const e=i.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function C(){const i=p("claude");if(!i)return!1;const e=`${i.kind}:${i.path}:${i.command}:${i.args.join("\0")}`;if(o.has(e))return o.get(e)??!1;try{const t=E(i,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:m()}),s=`${t.stdout??""}
2
- ${t.stderr??""}`,a=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return o.set(e,a),a}catch{return o.set(e,!1),!1}}class k extends g{options;type="claude";process=null;agentSessionId=null;sessionId=null;workDir=null;seq=0;runId="";hasEmittedText=!1;terminalState="open";persistNativeSession=!0;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??{}}async start(e,t,s,a){this.sessionId=e,this.workDir=t,this.seq=0,this.persistNativeSession=a?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,a,u){await this.killProcess(),this.runId=d(),this.resetRunState();const n=["-p",e,"--output-format","stream-json","--verbose"];this.persistNativeSession||n.push("--no-session-persistence");const r=this.options.systemPrompt??c(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,u);r&&n.push("--append-system-prompt",r),this.options.hidden&&n.push("--name","Shennian Manager Substrate"),process.getuid?.()!==0&&n.push("--dangerously-skip-permissions"),n.push("--model",x(t));const l=v(s);l&&C()&&n.push("--effort",l),this.agentSessionId&&n.push("--resume",this.agentSessionId),this.spawnAndParse(n)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=d(),this.resetRunState();const t=["--resume",e,"--output-format","stream-json","--verbose"],s=this.options.systemPrompt??c(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"),process.getuid?.()!==0&&t.push("--dangerously-skip-permissions"),this.spawnAndParse(t)}async stop(){await this.killProcess()}spawnAndParse(e){const t=p("claude");if(!t){this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?'));return}const s=I(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:m(this.extraEnv)});this.process=s,f({input:s.stdout}).on("line",n=>{if(n.trim())try{const r=JSON.parse(n);this.handleStreamEvent(r)}catch{}});let u="";s.stderr?.on("data",n=>{const r=n.toString();if(u+=r,this.terminalState==="open")for(const l of r.split(`
3
- `)){const h=l.trim();w(h)&&this.emitEvent({state:"delta",text:h+`
4
- `})}}),s.on("close",n=>{this.process===s&&(this.process=null,this.handleProcessClose(n,u))}),s.on("error",n=>{this.process===s&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",n))})}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.emitErrorIfOpen({state:"error",message:'Claude authentication failed. Run "claude auth login" and retry.'});return}if(e.type==="assistant"){if(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 h from"node:path";import{createInterface as y}from"node:readline";import{randomUUID as c}from"node:crypto";import{AgentAdapter as S,registerAgent as E}from"./adapter.js";import{resolveBuiltinCommand as m,spawnAgentCommand as x,spawnResolvedCommandSync as I}from"./command-spec.js";import{buildAgentProcessEnv as p,buildManagedAgentProcessEnv as v}from"../agent-env.js";import{buildPlatformInstructions as f}from"./platform-instructions.js";import{resolveManagedAgentAdapterEnforcement as P}from"../security/managed-agent-policy.js";import{registerManagedAgentRuntimeSecurity as k}from"../security/managed-agent-runtime.js";import{resolveManagedRoomIpcPaths as w}from"../daemon-ipc/paths.js";import{CLAUDE_MANAGED_RUNTIME_SECURITY as C,compileClaudeManagedPermissions as A}from"./claude-managed-permissions.js";k("claude",C);function _(n){return n?.trim()||"default"}const M=new Set(["low","medium","high","xhigh","max"]),l=new Map;function R(n){const e=n?.trim();if(e){if(M.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function Q(){l.clear()}function T(n){const e=n.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function O(){const n=m("claude");if(!n)return!1;const e=`${n.kind}:${n.path}:${n.command}:${n.args.join("\0")}`;if(l.has(e))return l.get(e)??!1;try{const t=I(n,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:p()}),s=`${t.stdout??""}
2
+ ${t.stderr??""}`,a=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return l.set(e,a),a}catch{return l.set(e,!1),!1}}class D extends S{options;type="claude";process=null;agentSessionId=null;sessionId=null;workDir=null;seq=0;runId="";hasEmittedText=!1;terminalState="open";persistNativeSession=!0;managedAgentPolicy=null;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,a){this.sessionId=e,this.workDir=this.managedAgentPolicy?.adapterPolicy.workDir??t,this.seq=0,this.persistNativeSession=a?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,a,u,r){if(r?.source==="room_activation"&&!this.managedAgentPolicy)throw new Error("managed_agent_policy_missing");await this.killProcess(),this.runId=c(),this.resetRunState();const i=["-p",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig()?.args??[]];this.persistNativeSession||i.push("--no-session-persistence");const d=this.options.systemPrompt??f(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,u);d&&i.push("--append-system-prompt",d),this.options.hidden&&i.push("--name","Shennian Manager Substrate"),!this.managedAgentPolicy&&process.getuid?.()!==0&&i.push("--dangerously-skip-permissions"),i.push("--model",_(t));const o=R(s);o&&O()&&i.push("--effort",o),this.agentSessionId&&i.push("--resume",this.agentSessionId),this.spawnAndParse(i)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=c(),this.resetRunState();const t=["--resume",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig()?.args??[]],s=this.options.systemPrompt??f(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"),!this.managedAgentPolicy&&process.getuid?.()!==0&&t.push("--dangerously-skip-permissions"),this.spawnAndParse(t)}async stop(){await this.killProcess()}spawnAndParse(e){const t=m("claude");if(!t){this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?'));return}const s=x(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv()});this.process=s,y({input:s.stdout}).on("line",r=>{if(r.trim())try{const i=JSON.parse(r);this.handleStreamEvent(i)}catch{}});let u="";s.stderr?.on("data",r=>{const i=r.toString();if(u+=i,this.terminalState==="open")for(const d of i.split(`
3
+ `)){const o=d.trim();T(o)&&this.emitEvent({state:"delta",text:o+`
4
+ `})}}),s.on("close",r=>{this.process===s&&(this.process=null,this.handleProcessClose(r,u))}),s.on("error",r=>{this.process===s&&(this.process=null,r.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",r))})}buildManagedPermissionConfig(){const e=this.managedAgentPolicy;if(!e)return null;const t=N();return A(P(e),e.adapterPolicy.workDir,{internalReadPaths:t.readPaths,internalUnixSockets:t.unixSockets,shellSubprocessPolicy:e.environmentPolicy.shellSubprocess})}buildProcessEnv(){return this.managedAgentPolicy?v({agentType:"claude",providerEnv:this.extraEnv,sessionEnv:this.extraEnv,runtimeEnv:{NO_COLOR:"1"}}):p(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.emitErrorIfOpen({state:"error",message:'Claude authentication failed. Run "claude auth login" and retry.'});return}if(e.type==="assistant"){if(e.message?.content){for(const t of e.message.content)if(t.type==="text"&&t.text){const s=this.hasEmittedText?`
5
5
 
6
6
  `:"";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"&&this.emitEvent({state:"tool-call",name:t.name,args:t.input});return}if(e.subtype==="text"&&e.text){const t=this.hasEmittedText?`
7
7
 
8
- `:"";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==="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=e.usage??e.message?.usage;this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0,usage:t?{inputTokens:t.input_tokens,outputTokens:t.output_tokens}:void 0})}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error"})}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}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.terminalState="open"}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){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)}))}}S("claude",()=>new k);export{k as ClaudeAdapter,x as normalizeClaudeModelId,v as normalizeClaudeReasoningEffort,R as resetClaudeCapabilityCacheForTests,w as shouldForwardClaudeStderrLine,C as supportsClaudeReasoningEffort};
8
+ `:"";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==="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=e.usage??e.message?.usage;this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0,usage:t?{inputTokens:t.input_tokens,outputTokens:t.output_tokens}:void 0})}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error"})}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}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.terminalState="open"}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){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 N(){const n=w(),e=[n.secretFile],t=n.transport==="unix_socket"?[n.endpoint]:[];n.transport==="unix_socket"&&e.push(n.endpoint);const s=m("pi");if(s?.path){e.push(s.path);try{const a=g.realpathSync(s.path);e.push(a,h.dirname(a),h.dirname(h.dirname(a)))}catch{}}return{readPaths:[...new Set(e)].sort(),unixSockets:[...new Set(t)].sort()}}E("claude",()=>new D);export{D as ClaudeAdapter,_ as normalizeClaudeModelId,R as normalizeClaudeReasoningEffort,Q as resetClaudeCapabilityCacheForTests,N as resolveClaudeManagedInternalAccess,T as shouldForwardClaudeStderrLine,O as supportsClaudeReasoningEffort};
@@ -0,0 +1,32 @@
1
+ import type { ManagedAgentEnforcement } from '@shennian/wire';
2
+ import type { ManagedAgentRuntimeSecurityDeclaration } from '../security/managed-agent-runtime.js';
3
+ export declare const CODEX_MANAGED_PERMISSION_PROFILE_ID = "shennian-managed";
4
+ type JsonObject = Record<string, unknown>;
5
+ export type CodexManagedPermissionOptions = {
6
+ /** Effective MCP server ids read from Codex before the thread starts. */
7
+ configuredMcpServerNames?: readonly string[];
8
+ shellSubprocessPolicy?: {
9
+ inherit: 'none';
10
+ allowedEnvKeys: readonly string[];
11
+ deniedEnvKeys: readonly string[];
12
+ };
13
+ };
14
+ export type CodexManagedPermissionConfig = {
15
+ profileId: typeof CODEX_MANAGED_PERMISSION_PROFILE_ID;
16
+ threadConfig: JsonObject;
17
+ };
18
+ /**
19
+ * Codex 0.138+ permission profiles are available on all supported local
20
+ * platforms. A profile is still verified at thread start; registration alone
21
+ * never permits a silent fallback to a legacy sandbox.
22
+ */
23
+ export declare const CODEX_MANAGED_RUNTIME_SECURITY: ManagedAgentRuntimeSecurityDeclaration;
24
+ /**
25
+ * Compile one immutable Codex thread configuration from daemon-verified
26
+ * effective permissions. The config is passed only as an app-server thread
27
+ * override and never written into the user's global Codex configuration.
28
+ */
29
+ export declare function compileCodexManagedPermissions(enforcement: ManagedAgentEnforcement, resolvedWorkDir: string, options?: CodexManagedPermissionOptions): CodexManagedPermissionConfig;
30
+ export declare function extractCodexMcpServerNames(configReadResponse: unknown): string[];
31
+ export declare function assertCodexManagedPermissionProfile(response: unknown, expectedProfileId?: string): void;
32
+ export {};
@@ -0,0 +1 @@
1
+ import a from"node:fs";import h from"node:os";import s from"node:path";import{resolveProtectedShennianDirectories as y}from"../security/managed-agent-credential-paths.js";const i="shennian-managed",E={".env":"deny",".env.*":"deny","**/.env":"deny","**/.env.*":"deny","*.key":"deny","**/*.key":"deny","*.pem":"deny","**/*.pem":"deny",".ssh":"deny","**/.ssh":"deny",".aws":"deny","**/.aws":"deny",".azure":"deny","**/.azure":"deny",".config/gcloud":"deny","**/.config/gcloud":"deny"},l=e=>({commandNetwork:{allow:e,deny:!0},webSearch:{allow:e,deny:!0},browser:{allow:e,deny:!0},computerUse:{allow:e,deny:!0},mcp:{allow:e,deny:!0}}),I={minimumRuntimeVersion:"0.138.0",maximumRuntimeVersionExclusive:"0.153.0",platforms:{darwin:{level:"hard",fileAccess:{"workspace-read":!0,"workspace-write":!0,"host-full":!0},externalCapabilities:l(!0)},linux:{level:"hard",fileAccess:{"workspace-read":!0,"workspace-write":!0,"host-full":!0},externalCapabilities:l(!0)},win32:{level:"partial",fileAccess:{"workspace-read":!1,"workspace-write":!1,"host-full":!1},externalCapabilities:l(!0),knownGaps:["sandbox.nativeWindowsReadIsolationUnavailable"]}}};function M(e,n,r={}){const t=O(n),o=e.effectivePolicy,m=g(x(e.platform)),f=o.fileAccess==="workspace-write"?"write":"read",c=o.fileAccess==="workspace-read"?":read-only":o.fileAccess==="workspace-write"?":workspace":null,_={":root":o.fileAccess==="host-full"?"write":"deny",...o.fileAccess==="host-full"?{}:{":minimal":"read",":tmpdir":"deny",":slash_tmp":"deny",...Object.fromEntries(m.map(w=>[w,"read"]))},...b(),glob_scan_max_depth:8,":workspace_roots":{".":o.fileAccess==="host-full"?"write":f,...E}},d=o.externalCapabilities.commandNetwork,p={enabled:!0,domains:d?{"*":"allow"}:{},unix_sockets:{},allow_local_binding:d,dangerously_allow_all_unix_sockets:!1};return{profileId:i,threadConfig:{default_permissions:i,permissions:{[i]:{description:"Shennian managed Agent permissions",...c?{extends:c}:{},workspace_roots:{[t]:!0},filesystem:_,network:p}},web_search:o.externalCapabilities.webSearch?"live":"disabled",features:v(o.externalCapabilities),allow_login_shell:!1,shell_environment_policy:A(r.shellSubprocessPolicy),...P(o.externalCapabilities.mcp,r.configuredMcpServerNames),...e.platform==="win32"?{windows:{sandbox:"elevated"}}:{}}}}function x(e){return e==="darwin"&&a.existsSync("/System/Library/OpenSSL")?["/System/Library/OpenSSL"]:[]}function b(){const e=s.normalize(h.homedir()),n=[...y(),...e&&s.isAbsolute(e)?[".shennian",".ssh",".aws",".azure",s.join(".config","gcloud"),".netrc",".npmrc"].map(r=>s.join(e,r)):[]].filter(r=>r&&s.isAbsolute(r));return Object.fromEntries([...new Set(n)].map(r=>[r,"deny"]))}function A(e){const n=[...new Set(e?.allowedEnvKeys??["PATH","HOME","USERPROFILE","LANG","LC_ALL","LC_CTYPE","TMPDIR","TMP","TEMP"])].filter(u).filter(t=>!S.has(t)).sort(),r=[...new Set(e?.deniedEnvKeys??["OPENAI_BASE_URL","OPENAI_API_KEY"])].filter(u).sort();return{inherit:"all",experimental_use_profile:!1,ignore_default_excludes:!0,filters:{...Object.fromEntries(n.map(t=>[t,"include"])),...Object.fromEntries(r.map(t=>[t,"exclude"]))}}}const S=new Set(["SHENNIAN_MANAGED_ROOM_CONTEXT","SHENNIAN_MANAGED_ROOM_IPC_ROOT"]);function u(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}function D(e){if(!e||typeof e!="object")throw new Error("codex_managed_config_read_invalid");const n=e.config;if(!n||typeof n!="object"||Array.isArray(n))throw new Error("codex_managed_config_read_invalid");const r=n.mcp_servers;if(r===void 0)return[];if(!r||typeof r!="object"||Array.isArray(r))throw new Error("codex_managed_config_read_invalid");return Object.keys(r).sort()}function j(e,n=i){if((e&&typeof e=="object"?e.activePermissionProfile:void 0)?.id!==n)throw new Error("codex_managed_permission_profile_unavailable")}function v(e){return{network_proxy:!0,apps:e.mcp,plugins:e.mcp,hooks:e.mcp,request_permissions_tool:!1,browser_use:e.browser,browser_use_external:e.browser,browser_use_full_cdp_access:!1,computer_use:e.computerUse}}function P(e,n){if(e)return{};const r=[...new Set(n??[])].filter(Boolean).sort();return r.length?{mcp_servers:Object.fromEntries(r.map(t=>[t,{enabled:!1}]))}:{}}function O(e){const n=s.normalize(e.trim());if(!n||!s.isAbsolute(n))throw new Error("codex_managed_workdir_invalid");let r;try{r=a.realpathSync(n)}catch{throw new Error("codex_managed_workdir_unavailable")}if(s.normalize(r)!==n)throw new Error("codex_managed_workdir_not_realpath");return n}function g(e){const n=[...new Set(e??[])].map(r=>s.normalize(r.trim())).filter(r=>r&&s.isAbsolute(r)).flatMap(r=>{try{const t=a.realpathSync(r);return t===r?[r]:[r,t]}catch{try{const t=a.realpathSync(s.dirname(r)),o=s.join(t,s.basename(r));return o===r?[r]:[r,o]}catch{return[r]}}});return[...new Set(n)].sort()}export{i as CODEX_MANAGED_PERMISSION_PROFILE_ID,I as CODEX_MANAGED_RUNTIME_SECURITY,j as assertCodexManagedPermissionProfile,M as compileCodexManagedPermissions,D as extractCodexMcpServerNames};