@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.
@@ -12,7 +12,7 @@ import {
12
12
  import { createCompactionLatch } from './compaction-latch';
13
13
  import type { StartMessage } from '../claude-code-bridge-protocol';
14
14
  import { randomUUID } from 'node:crypto';
15
- import { argv, stdout } from 'node:process';
15
+ import { argv, env as procEnv, stdout } from 'node:process';
16
16
 
17
17
  /*
18
18
  * CONSTRAINT — the third-party imports below are NEVER bundled into the
@@ -44,6 +44,10 @@ import {
44
44
  type ClaudeMessage,
45
45
  } from './create-emit-stream-event';
46
46
  import { jsonSchemaToZodShape } from './json-schema-to-zod';
47
+ import {
48
+ resolveInactiveNativeTools,
49
+ resolveNativeTools,
50
+ } from './tool-filtering';
47
51
 
48
52
  /*
49
53
  * Native Claude Code tool name → cross-harness common name. Tools outside this
@@ -69,37 +73,6 @@ const NATIVE_TO_COMMON: Readonly<Record<string, CommonBuiltinToolName>> = {
69
73
  WebSearch: 'webSearch',
70
74
  };
71
75
 
72
- const PUBLIC_TO_NATIVE: Readonly<Record<string, string>> = {
73
- read: 'Read',
74
- write: 'Write',
75
- edit: 'Edit',
76
- bash: 'Bash',
77
- glob: 'Glob',
78
- grep: 'Grep',
79
- webSearch: 'WebSearch',
80
- WebFetch: 'WebFetch',
81
- NotebookEdit: 'NotebookEdit',
82
- TodoWrite: 'TodoWrite',
83
- Agent: 'Agent',
84
- TaskCreate: 'TaskCreate',
85
- TaskGet: 'TaskGet',
86
- TaskUpdate: 'TaskUpdate',
87
- TaskList: 'TaskList',
88
- TaskStop: 'TaskStop',
89
- TaskOutput: 'TaskOutput',
90
- Monitor: 'Monitor',
91
- ListMcpResources: 'ListMcpResources',
92
- ReadMcpResource: 'ReadMcpResource',
93
- ExitPlanMode: 'ExitPlanMode',
94
- EnterWorktree: 'EnterWorktree',
95
- ExitWorktree: 'ExitWorktree',
96
- AskUserQuestion: 'AskUserQuestion',
97
- Skill: 'Skill',
98
- ToolSearch: 'ToolSearch',
99
- };
100
-
101
- const PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);
102
-
103
76
  const NATIVE_TOOL_KINDS: Readonly<
104
77
  Record<string, 'readonly' | 'edit' | 'bash'>
105
78
  > = {
@@ -134,34 +107,6 @@ function toCommonName(nativeName: string): CommonBuiltinToolName | string {
134
107
  return NATIVE_TO_COMMON[nativeName] ?? nativeName;
135
108
  }
136
109
 
137
- function toNativeName(toolName: string): string {
138
- return PUBLIC_TO_NATIVE[toolName] ?? toolName;
139
- }
140
-
141
- function resolveNativeTools(start: StartMessage): string[] | undefined {
142
- const toolFiltering = start.builtinToolFiltering;
143
- if (toolFiltering == null) return undefined;
144
- const activeToolNames =
145
- toolFiltering.mode === 'allow'
146
- ? toolFiltering.toolNames
147
- : PUBLIC_TOOL_NAMES.filter(
148
- name => !toolFiltering.toolNames.includes(name),
149
- );
150
- return activeToolNames.map(name => toNativeName(name));
151
- }
152
-
153
- function resolveInactiveNativeTools(start: StartMessage): string[] {
154
- const toolFiltering = start.builtinToolFiltering;
155
- if (toolFiltering == null) return [];
156
- const inactiveToolNames =
157
- toolFiltering.mode === 'allow'
158
- ? PUBLIC_TOOL_NAMES.filter(
159
- name => !toolFiltering.toolNames.includes(name),
160
- )
161
- : toolFiltering.toolNames;
162
- return inactiveToolNames.map(name => toNativeName(name));
163
- }
164
-
165
110
  const args = parseArgs(argv.slice(2));
166
111
  const workdir = args.workdir;
167
112
  const bridgeStateDir = args.bridgeStateDir;
@@ -315,7 +260,7 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
315
260
 
316
261
  const streamEventState = createClaudeStreamEventState();
317
262
 
318
- const mcpServers: Record<string, unknown> = {};
263
+ const mcpServers: Record<string, unknown> = { ...(start.mcpServers ?? {}) };
319
264
  if (start.tools && start.tools.length > 0) {
320
265
  const server = new mcpModule.McpServer({
321
266
  name: 'harness-tools',
@@ -372,8 +317,10 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
372
317
  abortSignal: abortCtl.signal,
373
318
  });
374
319
  const skillsOption = toClaudeSkillsOption(start.skills);
375
- const nativeTools = resolveNativeTools(start);
376
- const inactiveNativeTools = resolveInactiveNativeTools(start);
320
+ const nativeTools = resolveNativeTools(start.builtinToolFiltering);
321
+ const inactiveNativeTools = resolveInactiveNativeTools(
322
+ start.builtinToolFiltering,
323
+ );
377
324
  const permissionOptions = createPermissionOptions({
378
325
  start,
379
326
  inactiveNativeTools,
@@ -391,6 +338,7 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
391
338
  options: {
392
339
  ...(start.model ? { model: start.model } : {}),
393
340
  ...(start.maxTurns !== undefined ? { maxTurns: start.maxTurns } : {}),
341
+ ...(start.env !== undefined ? { env: { ...procEnv, ...start.env } } : {}),
394
342
  ...(skillsOption ? { skills: skillsOption } : {}),
395
343
  ...(nativeTools !== undefined ? { tools: nativeTools } : {}),
396
344
  ...(inactiveNativeTools.length > 0
@@ -0,0 +1,58 @@
1
+ import type { StartMessage } from '../claude-code-bridge-protocol';
2
+
3
+ type BuiltinToolFiltering = StartMessage['builtinToolFiltering'];
4
+
5
+ const PUBLIC_TO_NATIVE: Readonly<Record<string, string>> = {
6
+ read: 'Read',
7
+ write: 'Write',
8
+ edit: 'Edit',
9
+ bash: 'Bash',
10
+ glob: 'Glob',
11
+ grep: 'Grep',
12
+ webSearch: 'WebSearch',
13
+ WebFetch: 'WebFetch',
14
+ NotebookEdit: 'NotebookEdit',
15
+ TodoWrite: 'TodoWrite',
16
+ Agent: 'Agent',
17
+ TaskCreate: 'TaskCreate',
18
+ TaskGet: 'TaskGet',
19
+ TaskUpdate: 'TaskUpdate',
20
+ TaskList: 'TaskList',
21
+ TaskStop: 'TaskStop',
22
+ TaskOutput: 'TaskOutput',
23
+ Monitor: 'Monitor',
24
+ ListMcpResources: 'ListMcpResources',
25
+ ReadMcpResource: 'ReadMcpResource',
26
+ ExitPlanMode: 'ExitPlanMode',
27
+ EnterWorktree: 'EnterWorktree',
28
+ ExitWorktree: 'ExitWorktree',
29
+ AskUserQuestion: 'AskUserQuestion',
30
+ Skill: 'Skill',
31
+ ToolSearch: 'ToolSearch',
32
+ };
33
+
34
+ const PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);
35
+
36
+ function toNativeName(toolName: string): string {
37
+ return PUBLIC_TO_NATIVE[toolName] ?? toolName;
38
+ }
39
+
40
+ export function resolveNativeTools(
41
+ toolFiltering: BuiltinToolFiltering,
42
+ ): string[] | undefined {
43
+ if (toolFiltering == null || toolFiltering.mode === 'deny') return undefined;
44
+ return toolFiltering.toolNames.map(name => toNativeName(name));
45
+ }
46
+
47
+ export function resolveInactiveNativeTools(
48
+ toolFiltering: BuiltinToolFiltering,
49
+ ): string[] {
50
+ if (toolFiltering == null) return [];
51
+ const inactiveToolNames =
52
+ toolFiltering.mode === 'allow'
53
+ ? PUBLIC_TOOL_NAMES.filter(
54
+ name => !toolFiltering.toolNames.includes(name),
55
+ )
56
+ : toolFiltering.toolNames;
57
+ return inactiveToolNames.map(name => toNativeName(name));
58
+ }
@@ -33,7 +33,9 @@ const thinkingSchema = z.discriminatedUnion('type', [
33
33
  export const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
34
34
  thinking: thinkingSchema,
35
35
  maxTurns: z.number().optional(),
36
+ env: z.record(z.string(), z.string()).optional(),
36
37
  skills: z.array(z.string()).optional(),
38
+ mcpServers: z.record(z.string(), z.unknown()).optional(),
37
39
  // Resume signal. When true, the bridge passes `{ continue: true }` to the
38
40
  // Claude SDK so the in-workdir thread state is rehydrated. The host sets this
39
41
  // on the first prompt after a cross-process resume.