@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 +18 -0
- package/dist/bridge/index.mjs +93 -35
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +764 -8
- package/dist/index.js +11 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/index.ts +3 -45
- package/src/bridge/json-schema-to-zod.ts +154 -0
- package/src/claude-code-harness.ts +9 -6
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
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -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: "
|
|
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
|
|
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++) {
|