@ai-sdk/harness-claude-code 1.0.137 → 1.0.139

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.137",
3
+ "version": "1.0.139",
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.133",
30
- "@ai-sdk/provider-utils": "5.0.51",
29
+ "@ai-sdk/harness": "1.0.135",
30
+ "@ai-sdk/provider": "4.0.21",
31
+ "@ai-sdk/provider-utils": "5.0.53",
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(),
@@ -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.
@@ -1036,6 +1046,8 @@ export function createClaudeCode(
1036
1046
  // sandbox is left running, stopped, or destroyed.
1037
1047
  proc: undefined,
1038
1048
  maxTurns: settings.maxTurns,
1049
+ agentProgressSummaries: settings.agentProgressSummaries,
1050
+ forwardSubagentText: settings.forwardSubagentText,
1039
1051
  env: sandboxClaudeEnvironment,
1040
1052
  thinking,
1041
1053
  effort: settings.effort,
@@ -1197,6 +1209,8 @@ export function createClaudeCode(
1197
1209
  finishListenerAttachment,
1198
1210
  proc,
1199
1211
  maxTurns: settings.maxTurns,
1212
+ agentProgressSummaries: settings.agentProgressSummaries,
1213
+ forwardSubagentText: settings.forwardSubagentText,
1200
1214
  env: sandboxClaudeEnvironment,
1201
1215
  thinking,
1202
1216
  effort: settings.effort,
@@ -1513,6 +1527,8 @@ function createSession({
1513
1527
  finishListenerAttachment,
1514
1528
  proc,
1515
1529
  maxTurns,
1530
+ agentProgressSummaries,
1531
+ forwardSubagentText,
1516
1532
  env,
1517
1533
  thinking,
1518
1534
  effort,
@@ -1538,6 +1554,8 @@ function createSession({
1538
1554
  /** Undefined on `attach` — the live bridge was spawned by another process. */
1539
1555
  proc: Experimental_SandboxProcess | undefined;
1540
1556
  maxTurns: number | undefined;
1557
+ agentProgressSummaries: boolean | undefined;
1558
+ forwardSubagentText: boolean | undefined;
1541
1559
  env: Readonly<Record<string, string>> | undefined;
1542
1560
  thinking: ClaudeCodeThinkingConfig;
1543
1561
  effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | undefined;
@@ -1811,6 +1829,10 @@ function createSession({
1811
1829
  : {}),
1812
1830
  model: promptOpts.model,
1813
1831
  maxTurns,
1832
+ ...(agentProgressSummaries !== undefined
1833
+ ? { agentProgressSummaries }
1834
+ : {}),
1835
+ ...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
1814
1836
  ...(env !== undefined ? { env } : {}),
1815
1837
  thinking,
1816
1838
  ...(effort !== undefined ? { effort } : {}),
@@ -1875,6 +1897,10 @@ function createSession({
1875
1897
  : {}),
1876
1898
  model: continueOpts.model,
1877
1899
  maxTurns,
1900
+ ...(agentProgressSummaries !== undefined
1901
+ ? { agentProgressSummaries }
1902
+ : {}),
1903
+ ...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
1878
1904
  ...(env !== undefined ? { env } : {}),
1879
1905
  thinking,
1880
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';