@ai-sdk/harness-claude-code 1.0.136 → 1.0.138

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-claude-code",
3
- "version": "1.0.136",
3
+ "version": "1.0.138",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,8 +26,9 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@ai-sdk/harness": "1.0.132",
30
- "@ai-sdk/provider-utils": "5.0.51",
29
+ "@ai-sdk/harness": "1.0.134",
30
+ "@ai-sdk/provider": "4.0.20",
31
+ "@ai-sdk/provider-utils": "5.0.52",
31
32
  "ws": "^8.21.0"
32
33
  },
33
34
  "peerDependencies": {
@@ -39,7 +40,7 @@
39
40
  "@types/node": "22.19.19",
40
41
  "@types/ws": "^8.5.13",
41
42
  "@vercel/ai-tsconfig": "0.0.0",
42
- "tsup": "^8.5.1",
43
+ "tsdown": "^0.23.0",
43
44
  "typescript": "5.8.3",
44
45
  "zod": "3.25.76"
45
46
  },
@@ -65,9 +66,9 @@
65
66
  "claude-code"
66
67
  ],
67
68
  "scripts": {
68
- "build": "pnpm clean && tsup --tsconfig tsconfig.build.json && pnpm copy-bridge-assets",
69
- "build:watch": "pnpm clean && tsup --watch",
70
- "clean": "del-cli dist *.tsbuildinfo",
69
+ "build": "pnpm clean && tsdown && pnpm copy-bridge-assets",
70
+ "build:watch": "pnpm clean && tsdown --watch",
71
+ "clean": "del-cli *.tsbuildinfo",
71
72
  "copy-bridge-assets": "node -e \"import('node:fs/promises').then(async fs => { await fs.copyFile('src/bridge/package.json', 'dist/bridge/package.json'); await fs.copyFile('src/bridge/pnpm-lock.yaml', 'dist/bridge/pnpm-lock.yaml'); await fs.copyFile('src/bridge/pnpm-workspace.yaml', 'dist/bridge/pnpm-workspace.yaml'); })\"",
72
73
  "type-check": "tsc --build",
73
74
  "test": "pnpm test:node",
@@ -22,6 +22,9 @@ export type ClaudeMessage = {
22
22
  type?: string;
23
23
  index?: number;
24
24
  usage?: Record<string, unknown>;
25
+ message?: {
26
+ usage?: Record<string, unknown>;
27
+ };
25
28
  content_block?: {
26
29
  type?: string;
27
30
  id?: string;
@@ -76,6 +79,7 @@ export type ClaudeStreamEventState = {
76
79
  pendingStepAssistantUsage: Record<string, unknown> | undefined;
77
80
  pendingStepDeltaUsage: Record<string, unknown> | undefined;
78
81
  pendingStepUsage: Record<string, unknown> | undefined;
82
+ pendingResponseUsage: Record<string, unknown> | undefined;
79
83
  stepOpen: boolean;
80
84
  /*
81
85
  * Tool-use ids that originated from the MCP server hosting user-supplied
@@ -103,6 +107,7 @@ export function createClaudeStreamEventState(): ClaudeStreamEventState {
103
107
  pendingStepAssistantUsage: undefined,
104
108
  pendingStepDeltaUsage: undefined,
105
109
  pendingStepUsage: undefined,
110
+ pendingResponseUsage: undefined,
106
111
  stepOpen: false,
107
112
  mcpToolUseIds: new Set(),
108
113
  externalMcpToolUseIds: new Set(),
@@ -113,6 +118,13 @@ export function createClaudeStreamEventState(): ClaudeStreamEventState {
113
118
 
114
119
  const UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);
115
120
  const HOST_TOOL_PREFIX = 'mcp__harness-tools__';
121
+ const RAW_TASK_MESSAGE_SUBTYPES = new Set([
122
+ 'background_tasks_changed',
123
+ 'task_started',
124
+ 'task_progress',
125
+ 'task_updated',
126
+ 'task_notification',
127
+ ]);
116
128
 
117
129
  export function isExternalMcpTool(nativeName: string): boolean {
118
130
  return (
@@ -215,16 +227,28 @@ export function createEmitStreamEvent({
215
227
  return;
216
228
  }
217
229
 
230
+ if (
231
+ type === 'tool_progress' ||
232
+ (type === 'system' &&
233
+ msg.subtype != null &&
234
+ RAW_TASK_MESSAGE_SUBTYPES.has(msg.subtype))
235
+ ) {
236
+ emit({ type: 'raw', rawValue: msg });
237
+ return;
238
+ }
239
+
218
240
  // Messages emitted by a Task-tool subagent carry the parent tool-use id.
219
- // They belong to the subagent stream and must not affect the parent step,
220
- // including partial stream events that arrive before assistant messages.
241
+ // Forward them for correlation and nested rendering, but do not map them
242
+ // into regular stream parts or let them affect the parent step.
221
243
  if (msg.parent_tool_use_id != null) {
244
+ emit({ type: 'raw', rawValue: msg });
222
245
  return;
223
246
  }
224
247
 
225
248
  if (type === 'stream_event') {
226
249
  handleStreamEvent({
227
250
  event: msg.event,
251
+ message: msg,
228
252
  state,
229
253
  send: emit,
230
254
  toCommonName,
@@ -414,20 +438,31 @@ function formatApiRetryWarning(msg: ClaudeMessage): string {
414
438
 
415
439
  function handleStreamEvent({
416
440
  event,
441
+ message,
417
442
  state,
418
443
  send,
419
444
  toCommonName,
420
445
  }: {
421
446
  event: ClaudeMessage['event'] | undefined;
447
+ message: ClaudeMessage;
422
448
  state: ClaudeStreamEventState;
423
449
  send: Emit;
424
450
  toCommonName: (nativeName: string) => string;
425
451
  }): void {
426
452
  if (!event) return;
427
453
 
454
+ if (event.type === 'message_start') {
455
+ state.pendingResponseUsage = toUsageRecord(event.message?.usage);
456
+ return;
457
+ }
458
+
428
459
  if (event.type === 'message_delta') {
429
460
  const usage = toUsageRecord(event.usage);
430
461
  if (usage) {
462
+ state.pendingResponseUsage = mergeNonNullUsage(
463
+ state.pendingResponseUsage,
464
+ usage,
465
+ );
431
466
  state.pendingStepDeltaUsage = mergeNonNullUsage(
432
467
  state.pendingStepDeltaUsage,
433
468
  usage,
@@ -437,6 +472,18 @@ function handleStreamEvent({
437
472
  return;
438
473
  }
439
474
 
475
+ if (event.type === 'message_stop') {
476
+ send({
477
+ type: 'raw',
478
+ rawValue: {
479
+ ...message,
480
+ usage: state.pendingResponseUsage ?? {},
481
+ },
482
+ });
483
+ state.pendingResponseUsage = undefined;
484
+ return;
485
+ }
486
+
440
487
  if (typeof event.index !== 'number') return;
441
488
  const index = event.index;
442
489
  const partialBlocks = state.partialBlocks;
@@ -19,7 +19,7 @@ import { argv, env as procEnv, stdout } from 'node:process';
19
19
  /*
20
20
  * CONSTRAINT — the third-party imports below are NEVER bundled into the
21
21
  * compiled `bridge/index.mjs`. They are declared `external` in
22
- * tsup.config.ts and resolved at runtime from the node_modules that this
22
+ * tsdown.config.ts and resolved at runtime from the node_modules that this
23
23
  * bridge installs *inside the sandbox* from `src/bridge/package.json` (and
24
24
  * its pinned `pnpm-lock.yaml`). That bridge package.json — NOT this host
25
25
  * package — is the single source of truth for these packages and their
@@ -30,7 +30,7 @@ import { argv, env as procEnv, stdout } from 'node:process';
30
30
  * in sync, or the bridge will either get the dependency bundled in or fail
31
31
  * to resolve it in the sandbox:
32
32
  * 1. the import statement below,
33
- * 2. the `external` array in tsup.config.ts, and
33
+ * 2. the `external` array in tsdown.config.ts, and
34
34
  * 3. the dependency entry in `src/bridge/package.json`.
35
35
  */
36
36
  import * as claudeAgentSdk from '@anthropic-ai/claude-agent-sdk';
@@ -484,6 +484,12 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
484
484
  options: {
485
485
  ...(start.model ? { model: start.model } : {}),
486
486
  ...(start.maxTurns !== undefined ? { maxTurns: start.maxTurns } : {}),
487
+ ...(start.agentProgressSummaries !== undefined
488
+ ? { agentProgressSummaries: start.agentProgressSummaries }
489
+ : {}),
490
+ ...(start.forwardSubagentText !== undefined
491
+ ? { forwardSubagentText: start.forwardSubagentText }
492
+ : {}),
487
493
  ...(start.env !== undefined ? { env: { ...procEnv, ...start.env } } : {}),
488
494
  ...(skillsOption ? { skills: skillsOption } : {}),
489
495
  ...(nativeTools !== undefined ? { tools: nativeTools } : {}),
@@ -35,6 +35,8 @@ export const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
35
35
  thinking: thinkingSchema,
36
36
  effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
37
37
  maxTurns: z.number().optional(),
38
+ agentProgressSummaries: z.boolean().optional(),
39
+ forwardSubagentText: z.boolean().optional(),
38
40
  env: z.record(z.string(), z.string()).optional(),
39
41
  skills: z.array(z.string()).optional(),
40
42
  mcpServers: z.record(z.string(), z.unknown()).optional(),
@@ -27,7 +27,7 @@ import {
27
27
  import {
28
28
  applyCredentialForwarding,
29
29
  classifyDiskLog,
30
- createSandboxCredentialEnvironment,
30
+ resolveSandboxCredentialEnvironment,
31
31
  createBridgeToken,
32
32
  experimental_createBridgeUserMessageSubmitter,
33
33
  createBridgeErrorHandler,
@@ -102,6 +102,16 @@ export type ClaudeCodeHarnessSettings = {
102
102
  * back to the caller. Unset means the CLI's default.
103
103
  */
104
104
  readonly maxTurns?: number;
105
+ /**
106
+ * Enables periodic AI-generated progress summaries for running subagents.
107
+ * The summaries are forwarded in raw `task_progress` stream parts.
108
+ */
109
+ readonly agentProgressSummaries?: boolean;
110
+ /**
111
+ * Forwards subagent text and thinking messages in addition to tool activity.
112
+ * Subagent messages are exposed as raw stream parts.
113
+ */
114
+ readonly forwardSubagentText?: boolean;
105
115
  /**
106
116
  * Environment variables for the Claude Code process. These values are
107
117
  * merged over the sandbox bridge process environment.
@@ -887,13 +897,14 @@ export function createClaudeCode(
887
897
  sandboxSession.addRequestTransformations != null
888
898
  ) {
889
899
  sandboxCredentialEnvironment =
890
- resumeData?.sandboxCredentialEnvironment ??
891
- (await createSandboxCredentialEnvironment({
900
+ await resolveSandboxCredentialEnvironment({
892
901
  environment: claudeEnvironment,
893
902
  credentialEnvironmentVariables:
894
903
  CLAUDE_CODE_CREDENTIAL_ENVIRONMENT_VARIABLES,
895
904
  credentialForwarding: settings.credentialForwarding,
896
- }));
905
+ previousSandboxCredentialEnvironment:
906
+ resumeData?.sandboxCredentialEnvironment,
907
+ });
897
908
  sandboxClaudeEnvironment = {
898
909
  ...claudeEnvironment,
899
910
  ...sandboxCredentialEnvironment,
@@ -1035,6 +1046,8 @@ export function createClaudeCode(
1035
1046
  // sandbox is left running, stopped, or destroyed.
1036
1047
  proc: undefined,
1037
1048
  maxTurns: settings.maxTurns,
1049
+ agentProgressSummaries: settings.agentProgressSummaries,
1050
+ forwardSubagentText: settings.forwardSubagentText,
1038
1051
  env: sandboxClaudeEnvironment,
1039
1052
  thinking,
1040
1053
  effort: settings.effort,
@@ -1196,6 +1209,8 @@ export function createClaudeCode(
1196
1209
  finishListenerAttachment,
1197
1210
  proc,
1198
1211
  maxTurns: settings.maxTurns,
1212
+ agentProgressSummaries: settings.agentProgressSummaries,
1213
+ forwardSubagentText: settings.forwardSubagentText,
1199
1214
  env: sandboxClaudeEnvironment,
1200
1215
  thinking,
1201
1216
  effort: settings.effort,
@@ -1512,6 +1527,8 @@ function createSession({
1512
1527
  finishListenerAttachment,
1513
1528
  proc,
1514
1529
  maxTurns,
1530
+ agentProgressSummaries,
1531
+ forwardSubagentText,
1515
1532
  env,
1516
1533
  thinking,
1517
1534
  effort,
@@ -1537,6 +1554,8 @@ function createSession({
1537
1554
  /** Undefined on `attach` — the live bridge was spawned by another process. */
1538
1555
  proc: Experimental_SandboxProcess | undefined;
1539
1556
  maxTurns: number | undefined;
1557
+ agentProgressSummaries: boolean | undefined;
1558
+ forwardSubagentText: boolean | undefined;
1540
1559
  env: Readonly<Record<string, string>> | undefined;
1541
1560
  thinking: ClaudeCodeThinkingConfig;
1542
1561
  effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | undefined;
@@ -1810,6 +1829,10 @@ function createSession({
1810
1829
  : {}),
1811
1830
  model: promptOpts.model,
1812
1831
  maxTurns,
1832
+ ...(agentProgressSummaries !== undefined
1833
+ ? { agentProgressSummaries }
1834
+ : {}),
1835
+ ...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
1813
1836
  ...(env !== undefined ? { env } : {}),
1814
1837
  thinking,
1815
1838
  ...(effort !== undefined ? { effort } : {}),
@@ -1874,6 +1897,10 @@ function createSession({
1874
1897
  : {}),
1875
1898
  model: continueOpts.model,
1876
1899
  maxTurns,
1900
+ ...(agentProgressSummaries !== undefined
1901
+ ? { agentProgressSummaries }
1902
+ : {}),
1903
+ ...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
1877
1904
  ...(env !== undefined ? { env } : {}),
1878
1905
  thinking,
1879
1906
  ...(effort !== undefined ? { effort } : {}),
package/src/index.ts CHANGED
@@ -12,3 +12,4 @@ export { VERSION } from './version';
12
12
  export type { ClaudeCodeHarnessSettings } from './claude-code-harness';
13
13
  export type { ClaudeCodeAuthenticationMode } from './claude-code-auth';
14
14
  export type { ClaudeCodeThinkingConfig } from './claude-code-thinking';
15
+ export type { JSONObject } from '@ai-sdk/provider';