@ai-sdk/harness-claude-code 1.0.65 → 1.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +13 -0
- package/dist/bridge/index.mjs +49 -36
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +24674 -397
- package/dist/index.js +361 -23
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/create-emit-stream-event.ts +18 -1
- package/src/bridge/index.ts +11 -63
- package/src/bridge/tool-filtering.ts +58 -0
- package/src/claude-code-bridge-protocol.ts +2 -0
- package/src/claude-code-harness.ts +401 -19
|
@@ -63,6 +63,11 @@ const CLAUDE_CODE_CLIENT_APP = `ai-sdk/harness-claude-code/${VERSION}`;
|
|
|
63
63
|
|
|
64
64
|
export type ClaudeCodeHarnessSettings = {
|
|
65
65
|
readonly auth?: ClaudeCodeAuthOptions;
|
|
66
|
+
/**
|
|
67
|
+
* MCP server definitions keyed by server name. Each definition uses the
|
|
68
|
+
* underlying runtime's native MCP server configuration format.
|
|
69
|
+
*/
|
|
70
|
+
readonly mcpServers?: Record<string, unknown>;
|
|
66
71
|
/**
|
|
67
72
|
* Anthropic model id the underlying `claude` CLI should use. Leaving this
|
|
68
73
|
* unset defers to the CLI's default.
|
|
@@ -73,6 +78,11 @@ export type ClaudeCodeHarnessSettings = {
|
|
|
73
78
|
* back to the caller. Unset means the CLI's default.
|
|
74
79
|
*/
|
|
75
80
|
readonly maxTurns?: number;
|
|
81
|
+
/**
|
|
82
|
+
* Environment variables for the Claude Code process. These values are
|
|
83
|
+
* merged over the sandbox bridge process environment.
|
|
84
|
+
*/
|
|
85
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
76
86
|
/**
|
|
77
87
|
* Controls extended-thinking behavior and whether reasoning is summarized or
|
|
78
88
|
* omitted. Defaults to `{ type: 'adaptive', display: 'summarized' }`.
|
|
@@ -87,19 +97,53 @@ export type ClaudeCodeHarnessSettings = {
|
|
|
87
97
|
readonly port?: number;
|
|
88
98
|
/** Maximum milliseconds to wait for the bridge to advertise its port. Defaults to 120000. */
|
|
89
99
|
readonly startupTimeoutMs?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Creates the authentication token used by the sandbox bridge. Defaults to
|
|
102
|
+
* a random 32-byte hexadecimal token.
|
|
103
|
+
*/
|
|
104
|
+
readonly mintBridgeToken?: (sandboxId: string) => string;
|
|
90
105
|
};
|
|
91
106
|
|
|
92
107
|
/*
|
|
93
108
|
* Every native tool the Claude Code CLI can invoke, declared as a `ToolSet`
|
|
94
109
|
* keyed by what the bridge emits as `toolName` on the wire
|
|
95
|
-
* (`commonName ?? nativeName`). Schemas transcribed from
|
|
96
|
-
*
|
|
110
|
+
* (`commonName ?? nativeName`). Schemas are transcribed from the generated
|
|
111
|
+
* `sdk-tools.d.ts` and the conditionally registered tool definitions in the
|
|
112
|
+
* pinned Claude Code executable.
|
|
97
113
|
*
|
|
98
114
|
* `MCP` (the generic proxy tool inside the Claude Code SDK) is intentionally
|
|
99
115
|
* omitted — the bridge filters out `mcp__harness-tools__*` tool names before
|
|
100
116
|
* emitting them, and other MCP invocations come through with their own
|
|
101
117
|
* server-tool names rather than the literal `'Mcp'` token.
|
|
102
118
|
*/
|
|
119
|
+
const listMcpResourcesInputSchema = z.object({
|
|
120
|
+
server: z.string().optional(),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const readMcpResourceInputSchema = z.object({
|
|
124
|
+
server: z.string(),
|
|
125
|
+
uri: z.string(),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const structuredTeamMessageSchema = z.discriminatedUnion('type', [
|
|
129
|
+
z.object({
|
|
130
|
+
type: z.literal('shutdown_request'),
|
|
131
|
+
reason: z.string().optional(),
|
|
132
|
+
}),
|
|
133
|
+
z.object({
|
|
134
|
+
type: z.literal('shutdown_response'),
|
|
135
|
+
request_id: z.string(),
|
|
136
|
+
approve: z.boolean(),
|
|
137
|
+
reason: z.string().optional(),
|
|
138
|
+
}),
|
|
139
|
+
z.object({
|
|
140
|
+
type: z.literal('plan_approval_response'),
|
|
141
|
+
request_id: z.string(),
|
|
142
|
+
approve: z.boolean(),
|
|
143
|
+
feedback: z.string().optional(),
|
|
144
|
+
}),
|
|
145
|
+
]);
|
|
146
|
+
|
|
103
147
|
const CLAUDE_CODE_BUILTIN_TOOLS = {
|
|
104
148
|
read: commonTool('read', {
|
|
105
149
|
nativeName: 'Read',
|
|
@@ -291,23 +335,66 @@ const CLAUDE_CODE_BUILTIN_TOOLS = {
|
|
|
291
335
|
timeout: z.number(),
|
|
292
336
|
}),
|
|
293
337
|
}),
|
|
294
|
-
Monitor:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
338
|
+
Monitor: {
|
|
339
|
+
...tool({
|
|
340
|
+
description: 'Run and monitor a shell command or WebSocket',
|
|
341
|
+
inputSchema: z.object({
|
|
342
|
+
description: z.string().optional(),
|
|
343
|
+
timeout_ms: z.number().optional(),
|
|
344
|
+
persistent: z.boolean().optional(),
|
|
345
|
+
command: z.string().optional(),
|
|
346
|
+
ws: z
|
|
347
|
+
.object({
|
|
348
|
+
url: z.string(),
|
|
349
|
+
protocols: z.array(z.string()).optional(),
|
|
350
|
+
})
|
|
351
|
+
.optional(),
|
|
352
|
+
}),
|
|
301
353
|
}),
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
354
|
+
toolUseKind: 'bash',
|
|
355
|
+
},
|
|
356
|
+
ListMcpResources: {
|
|
357
|
+
...tool({
|
|
358
|
+
description: 'List resources available from MCP servers',
|
|
359
|
+
inputSchema: listMcpResourcesInputSchema,
|
|
360
|
+
}),
|
|
361
|
+
toolUseKind: 'readonly',
|
|
362
|
+
},
|
|
363
|
+
ListMcpResourcesTool: {
|
|
364
|
+
...tool({
|
|
365
|
+
description: 'List resources available from MCP servers',
|
|
366
|
+
inputSchema: listMcpResourcesInputSchema,
|
|
367
|
+
}),
|
|
368
|
+
toolUseKind: 'readonly',
|
|
369
|
+
},
|
|
370
|
+
ReadMcpResource: {
|
|
371
|
+
...tool({
|
|
372
|
+
description: 'Read a specific MCP resource by URI',
|
|
373
|
+
inputSchema: readMcpResourceInputSchema,
|
|
374
|
+
}),
|
|
375
|
+
toolUseKind: 'readonly',
|
|
376
|
+
},
|
|
377
|
+
ReadMcpResourceTool: {
|
|
378
|
+
...tool({
|
|
379
|
+
description: 'Read a specific MCP resource by URI',
|
|
380
|
+
inputSchema: readMcpResourceInputSchema,
|
|
381
|
+
}),
|
|
382
|
+
toolUseKind: 'readonly',
|
|
383
|
+
},
|
|
384
|
+
ReadMcpResourceDirTool: {
|
|
385
|
+
...tool({
|
|
386
|
+
description: 'List direct children of an MCP directory resource',
|
|
387
|
+
inputSchema: readMcpResourceInputSchema,
|
|
388
|
+
}),
|
|
389
|
+
toolUseKind: 'readonly',
|
|
390
|
+
},
|
|
391
|
+
RefreshMcpTools: {
|
|
392
|
+
...tool({
|
|
393
|
+
description: 'Refresh tools from one or all connected MCP servers',
|
|
394
|
+
inputSchema: z.object({ server: z.string().optional() }),
|
|
395
|
+
}),
|
|
396
|
+
toolUseKind: 'readonly',
|
|
397
|
+
},
|
|
311
398
|
ExitPlanMode: tool({
|
|
312
399
|
description: 'Exit plan mode with optional permission approvals',
|
|
313
400
|
inputSchema: z.looseObject({
|
|
@@ -321,6 +408,13 @@ const CLAUDE_CODE_BUILTIN_TOOLS = {
|
|
|
321
408
|
.optional(),
|
|
322
409
|
}),
|
|
323
410
|
}),
|
|
411
|
+
EnterPlanMode: {
|
|
412
|
+
...tool({
|
|
413
|
+
description: 'Enter plan mode',
|
|
414
|
+
inputSchema: z.object({}),
|
|
415
|
+
}),
|
|
416
|
+
toolUseKind: 'readonly',
|
|
417
|
+
},
|
|
324
418
|
EnterWorktree: tool({
|
|
325
419
|
description: 'Create or enter an isolated git worktree',
|
|
326
420
|
inputSchema: z.object({
|
|
@@ -386,6 +480,271 @@ const CLAUDE_CODE_BUILTIN_TOOLS = {
|
|
|
386
480
|
max_results: z.number().optional(),
|
|
387
481
|
}),
|
|
388
482
|
}),
|
|
483
|
+
Artifact: {
|
|
484
|
+
...tool({
|
|
485
|
+
description: 'Publish or list claude.ai artifacts',
|
|
486
|
+
inputSchema: z.object({
|
|
487
|
+
action: z.enum(['publish', 'list']).optional(),
|
|
488
|
+
file_path: z.string().optional(),
|
|
489
|
+
favicon: z.string().optional(),
|
|
490
|
+
limit: z.number().optional(),
|
|
491
|
+
scope: z.enum(['mine', 'shared', 'all']).optional(),
|
|
492
|
+
title: z.string().optional(),
|
|
493
|
+
description: z.string().optional(),
|
|
494
|
+
label: z.string().optional(),
|
|
495
|
+
url: z.string().optional(),
|
|
496
|
+
force: z.boolean().optional(),
|
|
497
|
+
}),
|
|
498
|
+
}),
|
|
499
|
+
toolUseKind: 'edit',
|
|
500
|
+
},
|
|
501
|
+
CronCreate: {
|
|
502
|
+
...tool({
|
|
503
|
+
description: 'Schedule a recurring or one-shot prompt',
|
|
504
|
+
inputSchema: z.object({
|
|
505
|
+
cron: z.string(),
|
|
506
|
+
prompt: z.string(),
|
|
507
|
+
recurring: z.boolean().optional(),
|
|
508
|
+
durable: z.boolean().optional(),
|
|
509
|
+
}),
|
|
510
|
+
}),
|
|
511
|
+
toolUseKind: 'edit',
|
|
512
|
+
},
|
|
513
|
+
CronDelete: {
|
|
514
|
+
...tool({
|
|
515
|
+
description: 'Delete a scheduled prompt by id',
|
|
516
|
+
inputSchema: z.object({ id: z.string() }),
|
|
517
|
+
}),
|
|
518
|
+
toolUseKind: 'edit',
|
|
519
|
+
},
|
|
520
|
+
CronList: {
|
|
521
|
+
...tool({
|
|
522
|
+
description: 'List scheduled prompts for the current session',
|
|
523
|
+
inputSchema: z.object({}),
|
|
524
|
+
}),
|
|
525
|
+
toolUseKind: 'readonly',
|
|
526
|
+
},
|
|
527
|
+
DesignSync: {
|
|
528
|
+
...tool({
|
|
529
|
+
description: 'Read or update claude.ai Design projects',
|
|
530
|
+
inputSchema: z.object({
|
|
531
|
+
method: z.enum([
|
|
532
|
+
'list_projects',
|
|
533
|
+
'get_project',
|
|
534
|
+
'list_files',
|
|
535
|
+
'get_file',
|
|
536
|
+
'finalize_plan',
|
|
537
|
+
'write_files',
|
|
538
|
+
'delete_files',
|
|
539
|
+
'register_assets',
|
|
540
|
+
'unregister_assets',
|
|
541
|
+
'create_project',
|
|
542
|
+
'report_validate',
|
|
543
|
+
]),
|
|
544
|
+
projectId: z.string().optional(),
|
|
545
|
+
path: z.string().optional(),
|
|
546
|
+
writes: z.array(z.string()).max(256).optional(),
|
|
547
|
+
deletes: z.array(z.string()).max(256).optional(),
|
|
548
|
+
planId: z.string().optional(),
|
|
549
|
+
files: z
|
|
550
|
+
.array(
|
|
551
|
+
z.object({
|
|
552
|
+
path: z.string(),
|
|
553
|
+
localPath: z.string().optional(),
|
|
554
|
+
data: z.string().optional(),
|
|
555
|
+
encoding: z.literal('base64').optional(),
|
|
556
|
+
mimeType: z.string().optional(),
|
|
557
|
+
}),
|
|
558
|
+
)
|
|
559
|
+
.max(256)
|
|
560
|
+
.optional(),
|
|
561
|
+
paths: z.array(z.string()).max(256).optional(),
|
|
562
|
+
name: z.string().optional(),
|
|
563
|
+
assets: z
|
|
564
|
+
.array(
|
|
565
|
+
z.object({
|
|
566
|
+
name: z.string(),
|
|
567
|
+
path: z.string(),
|
|
568
|
+
subtitle: z.string().optional(),
|
|
569
|
+
viewport: z
|
|
570
|
+
.object({
|
|
571
|
+
width: z.number(),
|
|
572
|
+
height: z.number().optional(),
|
|
573
|
+
})
|
|
574
|
+
.optional(),
|
|
575
|
+
group: z.string().optional(),
|
|
576
|
+
}),
|
|
577
|
+
)
|
|
578
|
+
.max(256)
|
|
579
|
+
.optional(),
|
|
580
|
+
localDir: z.string().optional(),
|
|
581
|
+
counts: z
|
|
582
|
+
.object({
|
|
583
|
+
total: z.number(),
|
|
584
|
+
bad: z.number(),
|
|
585
|
+
thin: z.number(),
|
|
586
|
+
variantsIdentical: z.number(),
|
|
587
|
+
iterations: z.number(),
|
|
588
|
+
})
|
|
589
|
+
.optional(),
|
|
590
|
+
}),
|
|
591
|
+
}),
|
|
592
|
+
toolUseKind: 'edit',
|
|
593
|
+
},
|
|
594
|
+
LSP: {
|
|
595
|
+
...tool({
|
|
596
|
+
description: 'Query a language server for code intelligence',
|
|
597
|
+
inputSchema: z.object({
|
|
598
|
+
operation: z.enum([
|
|
599
|
+
'goToDefinition',
|
|
600
|
+
'findReferences',
|
|
601
|
+
'hover',
|
|
602
|
+
'documentSymbol',
|
|
603
|
+
'workspaceSymbol',
|
|
604
|
+
'goToImplementation',
|
|
605
|
+
'prepareCallHierarchy',
|
|
606
|
+
'incomingCalls',
|
|
607
|
+
'outgoingCalls',
|
|
608
|
+
]),
|
|
609
|
+
filePath: z.string(),
|
|
610
|
+
line: z.number().int().positive(),
|
|
611
|
+
character: z.number().int().positive(),
|
|
612
|
+
query: z.string().optional(),
|
|
613
|
+
}),
|
|
614
|
+
}),
|
|
615
|
+
toolUseKind: 'readonly',
|
|
616
|
+
},
|
|
617
|
+
PowerShell: {
|
|
618
|
+
...tool({
|
|
619
|
+
description: 'Execute a PowerShell command, optionally in background',
|
|
620
|
+
inputSchema: z.object({
|
|
621
|
+
command: z.string(),
|
|
622
|
+
timeout: z.number().optional(),
|
|
623
|
+
description: z.string().optional(),
|
|
624
|
+
run_in_background: z.boolean().optional(),
|
|
625
|
+
dangerouslyDisableSandbox: z.boolean().optional(),
|
|
626
|
+
}),
|
|
627
|
+
}),
|
|
628
|
+
toolUseKind: 'bash',
|
|
629
|
+
},
|
|
630
|
+
PushNotification: {
|
|
631
|
+
...tool({
|
|
632
|
+
description: 'Send a notification for proactive or scheduled work',
|
|
633
|
+
inputSchema: z.object({
|
|
634
|
+
message: z.string(),
|
|
635
|
+
status: z.literal('proactive'),
|
|
636
|
+
}),
|
|
637
|
+
}),
|
|
638
|
+
toolUseKind: 'edit',
|
|
639
|
+
},
|
|
640
|
+
RemoteTrigger: {
|
|
641
|
+
...tool({
|
|
642
|
+
description: 'List, manage, or run a claude.ai Routine trigger',
|
|
643
|
+
inputSchema: z.object({
|
|
644
|
+
action: z.enum(['list', 'get', 'create', 'update', 'run']),
|
|
645
|
+
trigger_id: z.string().optional(),
|
|
646
|
+
body: z.record(z.string(), z.unknown()).optional(),
|
|
647
|
+
}),
|
|
648
|
+
}),
|
|
649
|
+
toolUseKind: 'edit',
|
|
650
|
+
},
|
|
651
|
+
ReportFindings: {
|
|
652
|
+
...tool({
|
|
653
|
+
description: 'Return verified code-review findings',
|
|
654
|
+
inputSchema: z.object({
|
|
655
|
+
level: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
|
|
656
|
+
findings: z
|
|
657
|
+
.array(
|
|
658
|
+
z.object({
|
|
659
|
+
file: z.string(),
|
|
660
|
+
line: z.number().optional(),
|
|
661
|
+
summary: z.string(),
|
|
662
|
+
short_summary: z.string().optional(),
|
|
663
|
+
failure_scenario: z.string(),
|
|
664
|
+
category: z.string().optional(),
|
|
665
|
+
verdict: z.enum(['CONFIRMED', 'PLAUSIBLE']).optional(),
|
|
666
|
+
outcome: z
|
|
667
|
+
.enum(['fixed', 'skipped', 'no_change_needed'])
|
|
668
|
+
.optional(),
|
|
669
|
+
}),
|
|
670
|
+
)
|
|
671
|
+
.max(32),
|
|
672
|
+
}),
|
|
673
|
+
}),
|
|
674
|
+
toolUseKind: 'readonly',
|
|
675
|
+
},
|
|
676
|
+
ScheduleWakeup: {
|
|
677
|
+
...tool({
|
|
678
|
+
description: 'Schedule or stop the next iteration of a dynamic loop',
|
|
679
|
+
inputSchema: z.object({
|
|
680
|
+
delaySeconds: z.number().optional(),
|
|
681
|
+
reason: z.string().optional(),
|
|
682
|
+
prompt: z.string().optional(),
|
|
683
|
+
stop: z.boolean().optional(),
|
|
684
|
+
}),
|
|
685
|
+
}),
|
|
686
|
+
toolUseKind: 'edit',
|
|
687
|
+
},
|
|
688
|
+
SendMessage: {
|
|
689
|
+
...tool({
|
|
690
|
+
description: 'Send a plain-text or protocol message to another agent',
|
|
691
|
+
inputSchema: z.object({
|
|
692
|
+
to: z.string(),
|
|
693
|
+
summary: z.string().max(200).optional(),
|
|
694
|
+
message: z.union([z.string(), structuredTeamMessageSchema]),
|
|
695
|
+
}),
|
|
696
|
+
}),
|
|
697
|
+
toolUseKind: 'edit',
|
|
698
|
+
},
|
|
699
|
+
SendUserFile: {
|
|
700
|
+
...tool({
|
|
701
|
+
description: 'Send one or more files to the user',
|
|
702
|
+
inputSchema: z.object({
|
|
703
|
+
files: z.union([z.string(), z.array(z.string()).min(1)]),
|
|
704
|
+
caption: z.string().optional(),
|
|
705
|
+
status: z.enum(['normal', 'proactive']),
|
|
706
|
+
display: z.enum(['render', 'attach']).optional(),
|
|
707
|
+
}),
|
|
708
|
+
}),
|
|
709
|
+
toolUseKind: 'readonly',
|
|
710
|
+
},
|
|
711
|
+
ShareOnboardingGuide: {
|
|
712
|
+
...tool({
|
|
713
|
+
description: 'Create, update, inspect, or delete an onboarding guide',
|
|
714
|
+
inputSchema: z.object({
|
|
715
|
+
mode: z.enum(['check', 'update', 'create', 'delete']).optional(),
|
|
716
|
+
short_code: z
|
|
717
|
+
.string()
|
|
718
|
+
.regex(/^[A-Za-z0-9_-]{1,64}$/)
|
|
719
|
+
.optional(),
|
|
720
|
+
}),
|
|
721
|
+
}),
|
|
722
|
+
toolUseKind: 'edit',
|
|
723
|
+
},
|
|
724
|
+
WaitForMcpServers: {
|
|
725
|
+
...tool({
|
|
726
|
+
description: 'Wait for MCP servers that are still connecting',
|
|
727
|
+
inputSchema: z.object({
|
|
728
|
+
servers: z.array(z.string()).optional(),
|
|
729
|
+
}),
|
|
730
|
+
}),
|
|
731
|
+
toolUseKind: 'readonly',
|
|
732
|
+
},
|
|
733
|
+
Workflow: {
|
|
734
|
+
...tool({
|
|
735
|
+
description: 'Run or resume a dynamic multi-agent workflow',
|
|
736
|
+
inputSchema: z.object({
|
|
737
|
+
script: z.string().optional(),
|
|
738
|
+
name: z.string().optional(),
|
|
739
|
+
description: z.string().optional(),
|
|
740
|
+
title: z.string().optional(),
|
|
741
|
+
args: z.record(z.string(), z.unknown()).optional(),
|
|
742
|
+
scriptPath: z.string().optional(),
|
|
743
|
+
resumeFromRunId: z.string().optional(),
|
|
744
|
+
}),
|
|
745
|
+
}),
|
|
746
|
+
toolUseKind: 'edit',
|
|
747
|
+
},
|
|
389
748
|
} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;
|
|
390
749
|
|
|
391
750
|
/*
|
|
@@ -432,6 +791,14 @@ type ClaudeCodeBridgeCoords = z.infer<typeof claudeCodeBridgeCoordsSchema>;
|
|
|
432
791
|
export function createClaudeCode(
|
|
433
792
|
settings: ClaudeCodeHarnessSettings = {},
|
|
434
793
|
): HarnessV1<typeof CLAUDE_CODE_BUILTIN_TOOLS> {
|
|
794
|
+
if (
|
|
795
|
+
settings.mcpServers != null &&
|
|
796
|
+
Object.prototype.hasOwnProperty.call(settings.mcpServers, 'harness-tools')
|
|
797
|
+
) {
|
|
798
|
+
throw new Error(
|
|
799
|
+
'Claude Code MCP server name "harness-tools" is reserved for HarnessAgent tools.',
|
|
800
|
+
);
|
|
801
|
+
}
|
|
435
802
|
let cachedBootstrap: HarnessV1Bootstrap | undefined;
|
|
436
803
|
const thinking = settings.thinking ?? {
|
|
437
804
|
type: 'adaptive',
|
|
@@ -549,6 +916,7 @@ export function createClaudeCode(
|
|
|
549
916
|
proc: undefined,
|
|
550
917
|
model: settings.model,
|
|
551
918
|
maxTurns: settings.maxTurns,
|
|
919
|
+
env: settings.env,
|
|
552
920
|
thinking,
|
|
553
921
|
isResume: true,
|
|
554
922
|
continueOnFirstPrompt: false,
|
|
@@ -560,6 +928,7 @@ export function createClaudeCode(
|
|
|
560
928
|
permissionMode: startOpts.permissionMode,
|
|
561
929
|
builtinToolFiltering: startOpts.builtinToolFiltering,
|
|
562
930
|
skills: startOpts.skills ?? [],
|
|
931
|
+
mcpServers: settings.mcpServers,
|
|
563
932
|
});
|
|
564
933
|
} catch {
|
|
565
934
|
// Bridge no longer reachable — recover by respawning below.
|
|
@@ -598,7 +967,10 @@ export function createClaudeCode(
|
|
|
598
967
|
})
|
|
599
968
|
: undefined;
|
|
600
969
|
const port = resolveBridgePort(sandboxSession, settings.port);
|
|
601
|
-
const token =
|
|
970
|
+
const token =
|
|
971
|
+
settings.mintBridgeToken == null
|
|
972
|
+
? randomBytes(32).toString('hex')
|
|
973
|
+
: settings.mintBridgeToken(sandboxId);
|
|
602
974
|
const authEnv = resolveClaudeCodeEnv(settings.auth);
|
|
603
975
|
const env = {
|
|
604
976
|
...authEnv,
|
|
@@ -719,6 +1091,7 @@ export function createClaudeCode(
|
|
|
719
1091
|
proc,
|
|
720
1092
|
model: settings.model,
|
|
721
1093
|
maxTurns: settings.maxTurns,
|
|
1094
|
+
env: settings.env,
|
|
722
1095
|
thinking,
|
|
723
1096
|
isResume: respawnStrategy !== undefined,
|
|
724
1097
|
continueOnFirstPrompt: respawnStrategy !== undefined,
|
|
@@ -730,6 +1103,7 @@ export function createClaudeCode(
|
|
|
730
1103
|
permissionMode: startOpts.permissionMode,
|
|
731
1104
|
builtinToolFiltering: startOpts.builtinToolFiltering,
|
|
732
1105
|
skills: startOpts.skills ?? [],
|
|
1106
|
+
mcpServers: settings.mcpServers,
|
|
733
1107
|
});
|
|
734
1108
|
},
|
|
735
1109
|
};
|
|
@@ -961,6 +1335,7 @@ function createSession({
|
|
|
961
1335
|
proc,
|
|
962
1336
|
model,
|
|
963
1337
|
maxTurns,
|
|
1338
|
+
env,
|
|
964
1339
|
thinking,
|
|
965
1340
|
isResume,
|
|
966
1341
|
continueOnFirstPrompt,
|
|
@@ -972,6 +1347,7 @@ function createSession({
|
|
|
972
1347
|
permissionMode,
|
|
973
1348
|
builtinToolFiltering,
|
|
974
1349
|
skills,
|
|
1350
|
+
mcpServers,
|
|
975
1351
|
}: {
|
|
976
1352
|
sessionId: string;
|
|
977
1353
|
channel: ClaudeCodeChannel;
|
|
@@ -979,6 +1355,7 @@ function createSession({
|
|
|
979
1355
|
proc: Experimental_SandboxProcess | undefined;
|
|
980
1356
|
model: string | undefined;
|
|
981
1357
|
maxTurns: number | undefined;
|
|
1358
|
+
env: Readonly<Record<string, string>> | undefined;
|
|
982
1359
|
thinking: ClaudeCodeThinkingConfig;
|
|
983
1360
|
isResume: boolean;
|
|
984
1361
|
continueOnFirstPrompt: boolean;
|
|
@@ -990,6 +1367,7 @@ function createSession({
|
|
|
990
1367
|
permissionMode: HarnessV1PermissionMode | undefined;
|
|
991
1368
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
992
1369
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
1370
|
+
mcpServers: Record<string, unknown> | undefined;
|
|
993
1371
|
}): HarnessV1Session {
|
|
994
1372
|
let stopped = false;
|
|
995
1373
|
let stopPromise: Promise<void> | undefined;
|
|
@@ -1169,10 +1547,12 @@ function createSession({
|
|
|
1169
1547
|
})),
|
|
1170
1548
|
model,
|
|
1171
1549
|
maxTurns,
|
|
1550
|
+
...(env !== undefined ? { env } : {}),
|
|
1172
1551
|
thinking,
|
|
1173
1552
|
...(skills.length > 0
|
|
1174
1553
|
? { skills: skills.map(skill => skill.name) }
|
|
1175
1554
|
: {}),
|
|
1555
|
+
...(mcpServers == null ? {} : { mcpServers }),
|
|
1176
1556
|
...(permissionMode ? { permissionMode } : {}),
|
|
1177
1557
|
...(builtinToolFiltering ? { builtinToolFiltering } : {}),
|
|
1178
1558
|
...(debug ? { debug } : {}),
|
|
@@ -1221,10 +1601,12 @@ function createSession({
|
|
|
1221
1601
|
})),
|
|
1222
1602
|
model,
|
|
1223
1603
|
maxTurns,
|
|
1604
|
+
...(env !== undefined ? { env } : {}),
|
|
1224
1605
|
thinking,
|
|
1225
1606
|
...(skills.length > 0
|
|
1226
1607
|
? { skills: skills.map(skill => skill.name) }
|
|
1227
1608
|
: {}),
|
|
1609
|
+
...(mcpServers == null ? {} : { mcpServers }),
|
|
1228
1610
|
...(permissionMode ? { permissionMode } : {}),
|
|
1229
1611
|
...(builtinToolFiltering ? { builtinToolFiltering } : {}),
|
|
1230
1612
|
...(debug ? { debug } : {}),
|