toolcraft 0.0.41 → 0.0.43
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/dist/cli.js +41 -5
- package/dist/mcp.js +42 -4
- package/dist/sdk.js +38 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -402,10 +402,13 @@ function parseEnumValue(value, values, label) {
|
|
|
402
402
|
return match;
|
|
403
403
|
}
|
|
404
404
|
function validateStringPattern(value, schema, label) {
|
|
405
|
-
if (schema.
|
|
406
|
-
|
|
405
|
+
if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
406
|
+
throw new UserError(`Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`);
|
|
407
|
+
}
|
|
408
|
+
if (schema.maxLength !== undefined && value.length > schema.maxLength) {
|
|
409
|
+
throw new UserError(`Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`);
|
|
407
410
|
}
|
|
408
|
-
if (!matchesStringPattern(value, schema.pattern)) {
|
|
411
|
+
if (schema.pattern !== undefined && !matchesStringPattern(value, schema.pattern)) {
|
|
409
412
|
throw new UserError(`Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`);
|
|
410
413
|
}
|
|
411
414
|
return value;
|
|
@@ -585,6 +588,14 @@ function parseArrayValue(value, schema, label) {
|
|
|
585
588
|
}
|
|
586
589
|
return splitArrayInput(value).map((item) => parseScalarValue(item, itemSchema, label));
|
|
587
590
|
}
|
|
591
|
+
function validateArrayBounds(value, schema, label) {
|
|
592
|
+
if (schema.minItems !== undefined && value.length < schema.minItems) {
|
|
593
|
+
throw new UserError(`Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`);
|
|
594
|
+
}
|
|
595
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems) {
|
|
596
|
+
throw new UserError(`Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
588
599
|
function createOption(field, globalLongOptionFlags) {
|
|
589
600
|
const flags = formatOptionFlags(field, globalLongOptionFlags);
|
|
590
601
|
const collidesWithGlobalFlag = globalLongOptionFlags.has(field.optionFlag);
|
|
@@ -979,7 +990,11 @@ function formatExampleCommand(breadcrumb, rootUsageName, params) {
|
|
|
979
990
|
const commandPath = buildUsageLine(breadcrumb, rootUsageName, "");
|
|
980
991
|
const flags = Object.entries(params).map(([key, value]) => {
|
|
981
992
|
const flag = `--${key}`;
|
|
982
|
-
return typeof value === "boolean"
|
|
993
|
+
return typeof value === "boolean"
|
|
994
|
+
? value
|
|
995
|
+
? flag
|
|
996
|
+
: `--no-${key}`
|
|
997
|
+
: `${flag} ${formatExampleValue(value)}`;
|
|
983
998
|
});
|
|
984
999
|
return [commandPath, ...flags].filter((token) => token.length > 0).join(" ");
|
|
985
1000
|
}
|
|
@@ -1493,6 +1508,9 @@ function describeExpectedPresetValue(schema) {
|
|
|
1493
1508
|
if (schema.kind === "array") {
|
|
1494
1509
|
return "an array";
|
|
1495
1510
|
}
|
|
1511
|
+
if (schema.kind === "number") {
|
|
1512
|
+
return getExpectedNumberDescription(schema);
|
|
1513
|
+
}
|
|
1496
1514
|
if (schema.kind === "json") {
|
|
1497
1515
|
return "valid JSON";
|
|
1498
1516
|
}
|
|
@@ -1510,6 +1528,12 @@ function validatePresetScalarValue(value, schema, fieldPath, presetPath) {
|
|
|
1510
1528
|
if (typeof value !== "string") {
|
|
1511
1529
|
break;
|
|
1512
1530
|
}
|
|
1531
|
+
if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
1532
|
+
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`);
|
|
1533
|
+
}
|
|
1534
|
+
if (schema.maxLength !== undefined && value.length > schema.maxLength) {
|
|
1535
|
+
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`);
|
|
1536
|
+
}
|
|
1513
1537
|
if (schema.pattern !== undefined && !matchesStringPattern(value, schema.pattern)) {
|
|
1514
1538
|
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${fieldPath}": "${value}" does not match pattern "${schema.pattern}".`);
|
|
1515
1539
|
}
|
|
@@ -1548,6 +1572,12 @@ function validatePresetFieldValue(value, field, presetPath) {
|
|
|
1548
1572
|
if (!Array.isArray(value)) {
|
|
1549
1573
|
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array, got ${describeReceived(value)}.`);
|
|
1550
1574
|
}
|
|
1575
|
+
if (field.schema.minItems !== undefined && value.length < field.schema.minItems) {
|
|
1576
|
+
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at least ${field.schema.minItems} items, got array(${value.length}).`);
|
|
1577
|
+
}
|
|
1578
|
+
if (field.schema.maxItems !== undefined && value.length > field.schema.maxItems) {
|
|
1579
|
+
throw new UserError(`Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at most ${field.schema.maxItems} items, got array(${value.length}).`);
|
|
1580
|
+
}
|
|
1551
1581
|
return value.map((item) => validatePresetScalarValue(item, itemSchema, field.displayPath, presetPath));
|
|
1552
1582
|
}
|
|
1553
1583
|
async function loadPresetValues(fields, presetPath) {
|
|
@@ -1959,12 +1989,17 @@ function parseOptionFieldValue(field, value, errors) {
|
|
|
1959
1989
|
}
|
|
1960
1990
|
parsedValues.push(...parsed);
|
|
1961
1991
|
}
|
|
1992
|
+
validateArrayBounds(parsedValues, field.schema, field.displayPath);
|
|
1962
1993
|
return { ok: true, value: parsedValues };
|
|
1963
1994
|
}
|
|
1964
1995
|
if (typeof value !== "string") {
|
|
1965
1996
|
return { ok: true, value };
|
|
1966
1997
|
}
|
|
1967
|
-
|
|
1998
|
+
const parsedValue = parseFieldInputValue(value, field.schema, field.displayPath);
|
|
1999
|
+
if (field.schema.kind === "array" && Array.isArray(parsedValue)) {
|
|
2000
|
+
validateArrayBounds(parsedValue, field.schema, field.displayPath);
|
|
2001
|
+
}
|
|
2002
|
+
return { ok: true, value: parsedValue };
|
|
1968
2003
|
}
|
|
1969
2004
|
catch (error) {
|
|
1970
2005
|
if (error instanceof UserError || error instanceof InvalidArgumentError) {
|
|
@@ -2026,6 +2061,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
|
|
|
2026
2061
|
if (values.length === 0) {
|
|
2027
2062
|
throw new InvalidArgumentError(`option '${label}' argument missing`);
|
|
2028
2063
|
}
|
|
2064
|
+
validateArrayBounds(values, schema, label);
|
|
2029
2065
|
return {
|
|
2030
2066
|
nextIndex,
|
|
2031
2067
|
value: values
|
package/dist/mcp.js
CHANGED
|
@@ -360,6 +360,9 @@ function validateSchemaValue(schema, value, casing, label, errors) {
|
|
|
360
360
|
message: `Invalid value for "${label}". Expected a string, got ${describeReceived(value)}.`
|
|
361
361
|
});
|
|
362
362
|
}
|
|
363
|
+
else {
|
|
364
|
+
validateStringConstraints(unwrappedSchema, value, label, errors);
|
|
365
|
+
}
|
|
363
366
|
return value;
|
|
364
367
|
case "number":
|
|
365
368
|
if (!isValidNumberSchemaValue(value, unwrappedSchema)) {
|
|
@@ -390,6 +393,7 @@ function validateSchemaValue(schema, value, casing, label, errors) {
|
|
|
390
393
|
});
|
|
391
394
|
return value;
|
|
392
395
|
}
|
|
396
|
+
validateArrayConstraints(unwrappedSchema, value, label, errors);
|
|
393
397
|
return value.map((item, index) => validateSchemaValue(unwrappedSchema.item, item, casing, `${label}[${index}]`, errors));
|
|
394
398
|
case "object":
|
|
395
399
|
return validateObjectSchema(unwrappedSchema, value, casing, label, errors);
|
|
@@ -437,6 +441,40 @@ function validateSchemaValue(schema, value, casing, label, errors) {
|
|
|
437
441
|
}
|
|
438
442
|
}
|
|
439
443
|
}
|
|
444
|
+
function validateStringConstraints(schema, value, label, errors) {
|
|
445
|
+
if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
446
|
+
errors.push({
|
|
447
|
+
path: label,
|
|
448
|
+
message: `Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
if (schema.maxLength !== undefined && value.length > schema.maxLength) {
|
|
452
|
+
errors.push({
|
|
453
|
+
path: label,
|
|
454
|
+
message: `Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (schema.pattern !== undefined && !new RegExp(schema.pattern).test(value)) {
|
|
458
|
+
errors.push({
|
|
459
|
+
path: label,
|
|
460
|
+
message: `Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function validateArrayConstraints(schema, value, label, errors) {
|
|
465
|
+
if (schema.minItems !== undefined && value.length < schema.minItems) {
|
|
466
|
+
errors.push({
|
|
467
|
+
path: label,
|
|
468
|
+
message: `Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems) {
|
|
472
|
+
errors.push({
|
|
473
|
+
path: label,
|
|
474
|
+
message: `Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
440
478
|
function validateObjectSchema(schema, value, casing, label, errors) {
|
|
441
479
|
if (!isPlainObject(value)) {
|
|
442
480
|
errors.push({
|
|
@@ -545,7 +583,9 @@ function serializeResultValue(schema, value, casing, label, errors) {
|
|
|
545
583
|
if (branch === undefined) {
|
|
546
584
|
const branchNames = Object.keys(unwrappedSchema.branches);
|
|
547
585
|
errors.push({
|
|
548
|
-
path: label.length === 0
|
|
586
|
+
path: label.length === 0
|
|
587
|
+
? unwrappedSchema.discriminator
|
|
588
|
+
: `${label}.${unwrappedSchema.discriminator}`,
|
|
549
589
|
message: `Invalid value for "${label.length === 0 ? unwrappedSchema.discriminator : `${label}.${unwrappedSchema.discriminator}`}". Expected one of: ${branchNames.join(", ")}, got ${describeReceived(discriminator)}.`
|
|
550
590
|
});
|
|
551
591
|
return value;
|
|
@@ -654,9 +694,7 @@ function throwResultValidationErrors(errors) {
|
|
|
654
694
|
if (errors.length === 1) {
|
|
655
695
|
throw new ToolError(JSON_RPC_ERROR_CODES.INTERNAL_ERROR, errors[0]?.message ?? "Invalid command result.");
|
|
656
696
|
}
|
|
657
|
-
const rendered = errors
|
|
658
|
-
.slice(0, 10)
|
|
659
|
-
.map((error) => ` - ${error.path}: ${error.message}`);
|
|
697
|
+
const rendered = errors.slice(0, 10).map((error) => ` - ${error.path}: ${error.message}`);
|
|
660
698
|
const remaining = errors.length - rendered.length;
|
|
661
699
|
if (remaining > 0) {
|
|
662
700
|
rendered.push(` ... and ${remaining} more`);
|
package/dist/sdk.js
CHANGED
|
@@ -146,6 +146,9 @@ function validateSchemaValue(schema, value, label, errors) {
|
|
|
146
146
|
message: `Invalid value for "${label}". Expected a string, got ${describeReceived(value)}.`
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
|
+
else {
|
|
150
|
+
validateStringConstraints(unwrappedSchema, value, label, errors);
|
|
151
|
+
}
|
|
149
152
|
return value;
|
|
150
153
|
case "number":
|
|
151
154
|
if (!isValidNumberSchemaValue(value, unwrappedSchema)) {
|
|
@@ -176,6 +179,7 @@ function validateSchemaValue(schema, value, label, errors) {
|
|
|
176
179
|
});
|
|
177
180
|
return value;
|
|
178
181
|
}
|
|
182
|
+
validateArrayConstraints(unwrappedSchema, value, label, errors);
|
|
179
183
|
return value.map((item, index) => validateSchemaValue(unwrappedSchema.item, item, `${label}[${index}]`, errors));
|
|
180
184
|
case "object":
|
|
181
185
|
return validateObjectSchema(unwrappedSchema, value, label, errors);
|
|
@@ -220,6 +224,40 @@ function validateSchemaValue(schema, value, label, errors) {
|
|
|
220
224
|
}
|
|
221
225
|
}
|
|
222
226
|
}
|
|
227
|
+
function validateStringConstraints(schema, value, label, errors) {
|
|
228
|
+
if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
229
|
+
errors.push({
|
|
230
|
+
path: label,
|
|
231
|
+
message: `Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
if (schema.maxLength !== undefined && value.length > schema.maxLength) {
|
|
235
|
+
errors.push({
|
|
236
|
+
path: label,
|
|
237
|
+
message: `Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (schema.pattern !== undefined && !new RegExp(schema.pattern).test(value)) {
|
|
241
|
+
errors.push({
|
|
242
|
+
path: label,
|
|
243
|
+
message: `Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function validateArrayConstraints(schema, value, label, errors) {
|
|
248
|
+
if (schema.minItems !== undefined && value.length < schema.minItems) {
|
|
249
|
+
errors.push({
|
|
250
|
+
path: label,
|
|
251
|
+
message: `Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems) {
|
|
255
|
+
errors.push({
|
|
256
|
+
path: label,
|
|
257
|
+
message: `Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
223
261
|
function validateObjectSchema(schema, value, label, errors) {
|
|
224
262
|
if (!isPlainObject(value)) {
|
|
225
263
|
errors.push({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client mcp-oauth auth-store"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"toolcraft-schema": "0.0.
|
|
50
|
+
"toolcraft-schema": "0.0.43",
|
|
51
51
|
"commander": "^14.0.3",
|
|
52
52
|
"fast-string-width": "^3.0.2",
|
|
53
53
|
"fast-wrap-ansi": "^0.2.0",
|