@ai-sdk/harness-claude-code 1.0.36 → 1.0.38

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @ai-sdk/harness-claude-code
2
2
 
3
+ ## 1.0.38
4
+
5
+ ### Patch Changes
6
+
7
+ - 6c3e639: fix(harness-claude-code): classify the Skill tool as readonly so `allow-reads` permission mode no longer requires approval for skill activations
8
+ - 0534507: fix(harness-claude-code): preserve nested user tool JSON schemas when exposing tools through the MCP bridge
9
+ - Updated dependencies [b460541]
10
+ - Updated dependencies [079591e]
11
+ - @ai-sdk/harness@1.0.37
12
+
13
+ ## 1.0.37
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [cd06458]
18
+ - @ai-sdk/provider-utils@5.0.11
19
+ - @ai-sdk/harness@1.0.36
20
+
3
21
  ## 1.0.36
4
22
 
5
23
  ### Patch Changes
@@ -510,13 +510,103 @@ import { randomUUID } from "crypto";
510
510
  import { argv, stdout as stdout2 } from "process";
511
511
  import * as claudeAgentSdk from "@anthropic-ai/claude-agent-sdk";
512
512
  import * as mcpServerModule from "@modelcontextprotocol/sdk/server/mcp.js";
513
- import { z } from "zod/v4";
514
513
 
515
514
  // src/bridge/claude-skills-option.ts
516
515
  function toClaudeSkillsOption(skills) {
517
516
  return skills && skills.length > 0 ? "all" : void 0;
518
517
  }
519
518
 
519
+ // src/bridge/json-schema-to-zod.ts
520
+ import { z } from "zod/v4";
521
+ function jsonSchemaToZodShape(input) {
522
+ const schema = isJsonSchemaObject(input) ? input : {};
523
+ return toZodShape(schema);
524
+ }
525
+ function toZodShape(schema) {
526
+ if (!schema?.properties) return {};
527
+ const required = new Set(schema.required ?? []);
528
+ const shape = {};
529
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
530
+ const propType = toZodType(propSchema);
531
+ let propertyType = required.has(key) ? propType : propType.optional();
532
+ if (propSchema.description) {
533
+ propertyType = propertyType.describe(propSchema.description);
534
+ }
535
+ shape[key] = propertyType;
536
+ }
537
+ return shape;
538
+ }
539
+ function toZodType(schema) {
540
+ if (!schema) return z.any();
541
+ let zType = zodForConst(schema) ?? zodForEnum(schema) ?? zodForNullableUnion(schema) ?? zodForType(schema);
542
+ if (isNullable(schema)) zType = zType.nullable();
543
+ if (schema.description) zType = zType.describe(schema.description);
544
+ return zType;
545
+ }
546
+ function zodForType(schema) {
547
+ const types = getNonNullTypes(schema);
548
+ if (types.length > 1) return z.any();
549
+ if (Array.isArray(schema.type) && types.length === 0) return z.null();
550
+ const type = types[0] ?? (schema.properties ? "object" : void 0);
551
+ switch (type) {
552
+ case "string":
553
+ return z.string();
554
+ case "number":
555
+ return z.number();
556
+ case "integer":
557
+ return z.number().int();
558
+ case "boolean":
559
+ return z.boolean();
560
+ case "array":
561
+ return z.array(
562
+ Array.isArray(schema.items) ? z.any() : toZodType(schema.items)
563
+ );
564
+ case "object":
565
+ return z.object(toZodShape(schema));
566
+ case "null":
567
+ return z.null();
568
+ default:
569
+ return z.any();
570
+ }
571
+ }
572
+ function zodForConst(schema) {
573
+ if (!("const" in schema)) return void 0;
574
+ return isJsonLiteral(schema.const) ? z.literal(schema.const) : z.any();
575
+ }
576
+ function zodForEnum(schema) {
577
+ if (!Array.isArray(schema.enum)) return void 0;
578
+ if (!schema.enum.every(isJsonLiteral)) return z.any();
579
+ return zodForLiterals(schema.enum);
580
+ }
581
+ function zodForNullableUnion(schema) {
582
+ const unionSchemas = schema.anyOf ?? schema.oneOf;
583
+ if (!unionSchemas || unionSchemas.length < 2) return void 0;
584
+ const nonNullSchemas = unionSchemas.filter((item) => !isNullOnlySchema(item));
585
+ if (nonNullSchemas.length !== 1) return void 0;
586
+ return toZodType(nonNullSchemas[0]).nullable();
587
+ }
588
+ function zodForLiterals(values) {
589
+ if (values.length === 0) return z.any();
590
+ if (values.length === 1) return z.literal(values[0]);
591
+ const literals = values.map((value) => z.literal(value));
592
+ return z.union(literals);
593
+ }
594
+ function getNonNullTypes(schema) {
595
+ return Array.isArray(schema.type) ? schema.type.filter((type) => type !== "null") : [schema.type].filter(Boolean);
596
+ }
597
+ function isNullable(schema) {
598
+ return schema.nullable === true || Array.isArray(schema.type) && schema.type.includes("null");
599
+ }
600
+ function isNullOnlySchema(schema) {
601
+ return schema.type === "null" || Array.isArray(schema.type) && schema.type.length === 1 && schema.type[0] === "null" || schema.const === null || Array.isArray(schema.enum) && schema.enum.length === 1 && schema.enum[0] === null;
602
+ }
603
+ function isJsonSchemaObject(input) {
604
+ return input != null && typeof input === "object" && !Array.isArray(input);
605
+ }
606
+ function isJsonLiteral(value) {
607
+ return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
608
+ }
609
+
520
610
  // src/bridge/index.ts
521
611
  var NATIVE_TO_COMMON = {
522
612
  Read: "read",
@@ -578,7 +668,7 @@ var NATIVE_TOOL_KINDS = {
578
668
  EnterWorktree: "edit",
579
669
  ExitWorktree: "edit",
580
670
  ExitPlanMode: "edit",
581
- Skill: "edit",
671
+ Skill: "readonly",
582
672
  AskUserQuestion: "readonly",
583
673
  ToolSearch: "readonly",
584
674
  Bash: "bash",
@@ -739,7 +829,7 @@ async function runTurn(start, turn) {
739
829
  version: "1.0.0"
740
830
  });
741
831
  for (const tool of start.tools) {
742
- const shape = jsonSchemaToZodShape(tool.inputSchema, z);
832
+ const shape = jsonSchemaToZodShape(tool.inputSchema);
743
833
  server.tool(
744
834
  tool.name,
745
835
  tool.description ?? "",
@@ -1145,38 +1235,6 @@ function defaultUsage() {
1145
1235
  outputTokens: { total: 0, text: 0 }
1146
1236
  };
1147
1237
  }
1148
- function jsonSchemaToZodShape(schema, z2) {
1149
- if (!schema || typeof schema !== "object") return {};
1150
- const s = schema;
1151
- const shape = {};
1152
- const required = new Set(s.required ?? []);
1153
- for (const [key, val] of Object.entries(s.properties ?? {})) {
1154
- let z_;
1155
- switch (val.type) {
1156
- case "string":
1157
- z_ = z2.string();
1158
- break;
1159
- case "number":
1160
- case "integer":
1161
- z_ = z2.number();
1162
- break;
1163
- case "boolean":
1164
- z_ = z2.boolean();
1165
- break;
1166
- case "array":
1167
- z_ = z2.array(z2.any());
1168
- break;
1169
- default:
1170
- z_ = z2.any();
1171
- }
1172
- if (val.description)
1173
- z_ = z_.describe(
1174
- val.description
1175
- );
1176
- shape[key] = required.has(key) ? z_ : z_.optional();
1177
- }
1178
- return shape;
1179
- }
1180
1238
  function parseArgs(args2) {
1181
1239
  const out = {};
1182
1240
  for (let i = 0; i < args2.length; i++) {