@stackwright-pro/mcp 0.2.0-alpha.80 → 0.2.0-alpha.81
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/integrity.js +14 -14
- package/dist/integrity.js.map +1 -1
- package/dist/integrity.mjs +14 -14
- package/dist/integrity.mjs.map +1 -1
- package/dist/server.js +426 -78
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +438 -78
- package/dist/server.mjs.map +1 -1
- package/package.json +5 -3
package/dist/server.js
CHANGED
|
@@ -1613,24 +1613,28 @@ var import_path3 = require("path");
|
|
|
1613
1613
|
var OTTER_NAME_TO_PHASE = [
|
|
1614
1614
|
["designer", "designer"],
|
|
1615
1615
|
["theme", "theme"],
|
|
1616
|
+
["scaffold", "scaffold"],
|
|
1616
1617
|
["api", "api"],
|
|
1617
1618
|
["auth", "auth"],
|
|
1618
1619
|
["dashboard", "dashboard"],
|
|
1619
1620
|
["data", "data"],
|
|
1620
1621
|
["page", "pages"],
|
|
1621
1622
|
["workflow", "workflow"],
|
|
1623
|
+
["services", "services"],
|
|
1622
1624
|
["polish", "polish"],
|
|
1623
1625
|
["geo", "geo"]
|
|
1624
1626
|
];
|
|
1625
1627
|
var PHASE_TO_OTTER = {
|
|
1626
1628
|
designer: "stackwright-pro-designer-otter",
|
|
1627
1629
|
theme: "stackwright-pro-theme-otter",
|
|
1630
|
+
scaffold: "stackwright-pro-scaffold-otter",
|
|
1628
1631
|
api: "stackwright-pro-api-otter",
|
|
1629
1632
|
auth: "stackwright-pro-auth-otter",
|
|
1630
1633
|
pages: "stackwright-pro-page-otter",
|
|
1631
1634
|
dashboard: "stackwright-pro-dashboard-otter",
|
|
1632
1635
|
data: "stackwright-pro-data-otter",
|
|
1633
1636
|
workflow: "stackwright-pro-workflow-otter",
|
|
1637
|
+
services: "stackwright-services-otter",
|
|
1634
1638
|
polish: "stackwright-pro-polish-otter",
|
|
1635
1639
|
geo: "stackwright-pro-geo-otter"
|
|
1636
1640
|
};
|
|
@@ -2015,7 +2019,7 @@ function registerOrchestrationTools(server2) {
|
|
|
2015
2019
|
}
|
|
2016
2020
|
|
|
2017
2021
|
// src/tools/pipeline.ts
|
|
2018
|
-
var
|
|
2022
|
+
var import_zod13 = require("zod");
|
|
2019
2023
|
var import_fs5 = require("fs");
|
|
2020
2024
|
var import_path5 = require("path");
|
|
2021
2025
|
var import_crypto3 = require("crypto");
|
|
@@ -2343,7 +2347,343 @@ function registerArtifactSigningTools(server2) {
|
|
|
2343
2347
|
}
|
|
2344
2348
|
|
|
2345
2349
|
// src/tools/pipeline.ts
|
|
2350
|
+
var import_types3 = require("@stackwright-pro/types");
|
|
2351
|
+
|
|
2352
|
+
// src/tools/get-schema.ts
|
|
2353
|
+
var import_zod12 = require("zod");
|
|
2354
|
+
var import_types2 = require("@stackwright-pro/types");
|
|
2355
|
+
|
|
2356
|
+
// src/tools/validate-yaml-fragment.ts
|
|
2357
|
+
var import_zod11 = require("zod");
|
|
2358
|
+
var import_js_yaml = require("js-yaml");
|
|
2346
2359
|
var import_types = require("@stackwright-pro/types");
|
|
2360
|
+
var SUPPORTED_SCHEMA_NAMES = [
|
|
2361
|
+
"workflow_step",
|
|
2362
|
+
"workflow_definition",
|
|
2363
|
+
"workflow_field",
|
|
2364
|
+
"workflow_action",
|
|
2365
|
+
"navigation_item",
|
|
2366
|
+
"auth_config"
|
|
2367
|
+
];
|
|
2368
|
+
var NavigationLinkSchema = import_zod11.z.lazy(
|
|
2369
|
+
() => import_zod11.z.object({
|
|
2370
|
+
label: import_zod11.z.string().min(1),
|
|
2371
|
+
href: import_zod11.z.string().min(1),
|
|
2372
|
+
children: import_zod11.z.array(NavigationLinkSchema).optional()
|
|
2373
|
+
})
|
|
2374
|
+
);
|
|
2375
|
+
var NavigationSectionSchema = import_zod11.z.object({
|
|
2376
|
+
section: import_zod11.z.string().min(1),
|
|
2377
|
+
items: import_zod11.z.array(NavigationLinkSchema)
|
|
2378
|
+
});
|
|
2379
|
+
var NavigationItemSchema = import_zod11.z.union([
|
|
2380
|
+
NavigationLinkSchema,
|
|
2381
|
+
NavigationSectionSchema
|
|
2382
|
+
]);
|
|
2383
|
+
var FIELD_SYNONYMS = {
|
|
2384
|
+
workflow_step: {
|
|
2385
|
+
title: "label",
|
|
2386
|
+
name: "label (at step level, use label: not name:)",
|
|
2387
|
+
description: "message (use message: for step-level descriptive text)",
|
|
2388
|
+
style: 'theme.variant \u2014 use theme: { variant: "primary" } not style: "primary"',
|
|
2389
|
+
transitions: 'on_submit.transition \u2014 use on_submit: { transition: "next_step" } not transitions: [{then:...}]'
|
|
2390
|
+
},
|
|
2391
|
+
workflow_definition: {
|
|
2392
|
+
title: "label",
|
|
2393
|
+
name: "label (workflow-level label, not name:)",
|
|
2394
|
+
description: "description is valid here \u2014 but message: is not (that is a step field)",
|
|
2395
|
+
type: "id (workflows are identified by id:, not type:)"
|
|
2396
|
+
},
|
|
2397
|
+
workflow_field: {
|
|
2398
|
+
id: "name (field-level identifier is name:, NOT id:)",
|
|
2399
|
+
title: "label (field display text is label:, NOT title:)",
|
|
2400
|
+
description: "placeholder or label (no description field on WorkflowField)"
|
|
2401
|
+
},
|
|
2402
|
+
workflow_action: {
|
|
2403
|
+
style: 'theme.variant \u2014 use theme: { variant: "primary" } not style: "primary"',
|
|
2404
|
+
then: "transition (action-level next-step is transition:, NOT then:)",
|
|
2405
|
+
on_click: 'action: "service:..." (extract the service reference from on_click.action)',
|
|
2406
|
+
title: "label (action display text is label:, NOT title:)",
|
|
2407
|
+
name: "label (action display text is label:, NOT name:)"
|
|
2408
|
+
},
|
|
2409
|
+
navigation_item: {
|
|
2410
|
+
children: "items (NavigationSection uses items: not children: \u2014 also use section: instead of label: for section headers)",
|
|
2411
|
+
label: 'section (if this is a nav group/section, use section: "Title" and items: [...], not label:)',
|
|
2412
|
+
title: "section (NavigationSection header field is section:, NOT title:)"
|
|
2413
|
+
},
|
|
2414
|
+
auth_config: {
|
|
2415
|
+
method: 'type \u2014 auth config discriminates on type: "oidc" | "pki", NOT method:',
|
|
2416
|
+
provider_type: 'type \u2014 use type: "oidc" or type: "pki"',
|
|
2417
|
+
strategy: "type \u2014 top-level discriminator is type:, not strategy:"
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
function getSchema(name) {
|
|
2421
|
+
switch (name) {
|
|
2422
|
+
case "workflow_step":
|
|
2423
|
+
return import_types.WorkflowStepSchema;
|
|
2424
|
+
case "workflow_definition":
|
|
2425
|
+
return import_types.WorkflowDefinitionSchema;
|
|
2426
|
+
case "workflow_field":
|
|
2427
|
+
return import_types.WorkflowFieldSchema;
|
|
2428
|
+
case "workflow_action":
|
|
2429
|
+
return import_types.WorkflowActionSchema;
|
|
2430
|
+
case "navigation_item":
|
|
2431
|
+
return NavigationItemSchema;
|
|
2432
|
+
case "auth_config":
|
|
2433
|
+
return import_types.authConfigSchema;
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
function enrichErrors(issues, synonyms) {
|
|
2437
|
+
return issues.map((issue) => {
|
|
2438
|
+
const pathStr = issue.path.join(".");
|
|
2439
|
+
const lastSegment = issue.path[issue.path.length - 1];
|
|
2440
|
+
const fieldName = typeof lastSegment === "string" ? lastSegment : void 0;
|
|
2441
|
+
const didYouMean = fieldName ? synonyms[fieldName] : void 0;
|
|
2442
|
+
return {
|
|
2443
|
+
path: pathStr || "(root)",
|
|
2444
|
+
message: issue.message,
|
|
2445
|
+
...didYouMean ? { didYouMean } : {}
|
|
2446
|
+
};
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
function handleValidateYamlFragment(input) {
|
|
2450
|
+
const { schemaName, yaml } = input;
|
|
2451
|
+
if (!SUPPORTED_SCHEMA_NAMES.includes(schemaName)) {
|
|
2452
|
+
return {
|
|
2453
|
+
valid: false,
|
|
2454
|
+
parseError: `Unknown schemaName: "${schemaName}". Supported: ${SUPPORTED_SCHEMA_NAMES.join(", ")}`
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
const name = schemaName;
|
|
2458
|
+
let parsed;
|
|
2459
|
+
try {
|
|
2460
|
+
parsed = (0, import_js_yaml.load)(yaml);
|
|
2461
|
+
} catch (err) {
|
|
2462
|
+
return {
|
|
2463
|
+
valid: false,
|
|
2464
|
+
parseError: `YAML parse error: ${err instanceof Error ? err.message : String(err)}`
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2467
|
+
const schema = getSchema(name);
|
|
2468
|
+
const result = schema.safeParse(parsed);
|
|
2469
|
+
if (result.success) {
|
|
2470
|
+
return { valid: true };
|
|
2471
|
+
}
|
|
2472
|
+
const synonyms = FIELD_SYNONYMS[name];
|
|
2473
|
+
const errors = enrichErrors(result.error.issues, synonyms);
|
|
2474
|
+
return { valid: false, errors };
|
|
2475
|
+
}
|
|
2476
|
+
function registerValidateYamlFragmentTool(server2) {
|
|
2477
|
+
server2.tool(
|
|
2478
|
+
"stackwright_pro_validate_yaml_fragment",
|
|
2479
|
+
'Validates a YAML snippet against a canonical Zod schema before writing to disk. Returns actionable errors with "did you mean?" suggestions for common field-name drift (title vs label, id vs name, style vs theme.variant, etc.). Call this before stackwright_pro_safe_write to catch schema violations in-session.',
|
|
2480
|
+
{
|
|
2481
|
+
schemaName: import_zod11.z.enum(SUPPORTED_SCHEMA_NAMES).describe(
|
|
2482
|
+
"Schema to validate against. One of: workflow_step, workflow_definition, workflow_field, workflow_action, navigation_item, auth_config"
|
|
2483
|
+
),
|
|
2484
|
+
yaml: import_zod11.z.string().describe("YAML string to validate (can also be JSON \u2014 js-yaml parses both)")
|
|
2485
|
+
},
|
|
2486
|
+
async ({ schemaName, yaml }) => {
|
|
2487
|
+
const result = handleValidateYamlFragment({ schemaName, yaml });
|
|
2488
|
+
return {
|
|
2489
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
);
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
// src/tools/get-schema.ts
|
|
2496
|
+
var NavigationLinkSchema2 = import_zod12.z.lazy(
|
|
2497
|
+
() => import_zod12.z.object({
|
|
2498
|
+
label: import_zod12.z.string().min(1),
|
|
2499
|
+
href: import_zod12.z.string().min(1),
|
|
2500
|
+
children: import_zod12.z.array(NavigationLinkSchema2).optional()
|
|
2501
|
+
})
|
|
2502
|
+
);
|
|
2503
|
+
var NavigationSectionSchema2 = import_zod12.z.object({
|
|
2504
|
+
section: import_zod12.z.string().min(1),
|
|
2505
|
+
items: import_zod12.z.array(NavigationLinkSchema2)
|
|
2506
|
+
});
|
|
2507
|
+
var NavigationItemSchema2 = import_zod12.z.union([
|
|
2508
|
+
NavigationLinkSchema2,
|
|
2509
|
+
NavigationSectionSchema2
|
|
2510
|
+
]);
|
|
2511
|
+
function getZodSchema(name) {
|
|
2512
|
+
switch (name) {
|
|
2513
|
+
case "workflow_step":
|
|
2514
|
+
return import_types2.WorkflowStepSchema;
|
|
2515
|
+
case "workflow_definition":
|
|
2516
|
+
return import_types2.WorkflowDefinitionSchema;
|
|
2517
|
+
case "workflow_field":
|
|
2518
|
+
return import_types2.WorkflowFieldSchema;
|
|
2519
|
+
case "workflow_action":
|
|
2520
|
+
return import_types2.WorkflowActionSchema;
|
|
2521
|
+
case "navigation_item":
|
|
2522
|
+
return NavigationItemSchema2;
|
|
2523
|
+
case "auth_config":
|
|
2524
|
+
return import_types2.authConfigSchema;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
function formatType(node, depth = 0) {
|
|
2528
|
+
if (node.const !== void 0) return JSON.stringify(node.const);
|
|
2529
|
+
if (node.enum) return node.enum.map((v) => JSON.stringify(v)).join(" | ");
|
|
2530
|
+
if (node.oneOf || node.anyOf) {
|
|
2531
|
+
const branches = node.oneOf ?? node.anyOf ?? [];
|
|
2532
|
+
return branches.map((b) => {
|
|
2533
|
+
const disc = b.properties ? Object.entries(b.properties).filter(([, v]) => v.const !== void 0).map(([k, v]) => `${k}: ${JSON.stringify(v.const)}`).join(", ") : "";
|
|
2534
|
+
return disc ? `{ ${disc}, ... }` : "{ ... }";
|
|
2535
|
+
}).join(" | ");
|
|
2536
|
+
}
|
|
2537
|
+
if (node.type === "array" && node.items) {
|
|
2538
|
+
return `${formatType(node.items, depth)}[]`;
|
|
2539
|
+
}
|
|
2540
|
+
if (node.type === "object" && node.properties && depth < 2) {
|
|
2541
|
+
const inner = Object.entries(node.properties).map(([k, v]) => `${k}: ${formatType(v, depth + 1)}`).join(", ");
|
|
2542
|
+
return `{ ${inner} }`;
|
|
2543
|
+
}
|
|
2544
|
+
const base = Array.isArray(node.type) ? node.type.join(" | ") : node.type ?? "unknown";
|
|
2545
|
+
const constraints = [];
|
|
2546
|
+
if (node.maxLength !== void 0) constraints.push(`max ${node.maxLength} chars`);
|
|
2547
|
+
if (node.minLength !== void 0) constraints.push(`min ${node.minLength} chars`);
|
|
2548
|
+
if (node.pattern) constraints.push(`pattern: ${node.pattern}`);
|
|
2549
|
+
if (node.minimum !== void 0) constraints.push(`min ${node.minimum}`);
|
|
2550
|
+
if (node.maximum !== void 0) constraints.push(`max ${node.maximum}`);
|
|
2551
|
+
return constraints.length > 0 ? `${base} (${constraints.join(", ")})` : base;
|
|
2552
|
+
}
|
|
2553
|
+
function formatObjectSchema(node, schemaName, synonyms) {
|
|
2554
|
+
const lines = [];
|
|
2555
|
+
const displayName = schemaName.split("_").map((w) => w[0].toUpperCase() + w.slice(1)).join("");
|
|
2556
|
+
lines.push(`${displayName}:`);
|
|
2557
|
+
if (node.oneOf || node.anyOf) {
|
|
2558
|
+
const branches = node.oneOf ?? node.anyOf ?? [];
|
|
2559
|
+
lines.push(" Discriminated union \u2014 choose one variant:");
|
|
2560
|
+
for (const branch of branches) {
|
|
2561
|
+
const req = new Set(branch.required ?? []);
|
|
2562
|
+
const disc = Object.entries(branch.properties ?? {}).filter(([, v]) => v.const !== void 0).map(([k, v]) => `${k}: ${JSON.stringify(v.const)}`).join(", ");
|
|
2563
|
+
lines.push(` VARIANT (${disc}):`);
|
|
2564
|
+
for (const [field, fieldNode] of Object.entries(branch.properties ?? {})) {
|
|
2565
|
+
if (fieldNode.const !== void 0) continue;
|
|
2566
|
+
const isRequired = req.has(field);
|
|
2567
|
+
const hint = synonyms[field] ? ` -- WARNING: use ${field}: not ${synonyms[field]}` : "";
|
|
2568
|
+
lines.push(
|
|
2569
|
+
` ${isRequired ? "REQUIRED" : "optional"}: ${field}: ${formatType(fieldNode)}${hint}`
|
|
2570
|
+
);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
return lines.join("\n");
|
|
2574
|
+
}
|
|
2575
|
+
const required = new Set(node.required ?? []);
|
|
2576
|
+
const properties = node.properties ?? {};
|
|
2577
|
+
const requiredFields = Object.entries(properties).filter(([k]) => required.has(k));
|
|
2578
|
+
const optionalFields = Object.entries(properties).filter(([k]) => !required.has(k));
|
|
2579
|
+
if (requiredFields.length > 0) {
|
|
2580
|
+
lines.push(" REQUIRED:");
|
|
2581
|
+
for (const [field, fieldNode] of requiredFields) {
|
|
2582
|
+
const typeStr = formatType(fieldNode);
|
|
2583
|
+
const warn = synonyms[field] ? ` -- CAUTION: this schema uses ${field}` : "";
|
|
2584
|
+
lines.push(` ${field}: ${typeStr}${warn}`);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
if (optionalFields.length > 0) {
|
|
2588
|
+
lines.push(" OPTIONAL:");
|
|
2589
|
+
for (const [field, fieldNode] of optionalFields) {
|
|
2590
|
+
const typeStr = formatType(fieldNode);
|
|
2591
|
+
lines.push(` ${field}: ${typeStr}`);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
return lines.join("\n");
|
|
2595
|
+
}
|
|
2596
|
+
function handleGetSchema(input) {
|
|
2597
|
+
const { schemaName } = input;
|
|
2598
|
+
if (!SUPPORTED_SCHEMA_NAMES.includes(schemaName)) {
|
|
2599
|
+
return {
|
|
2600
|
+
error: `Unknown schemaName: "${schemaName}". Supported: ${SUPPORTED_SCHEMA_NAMES.join(", ")}`
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
const name = schemaName;
|
|
2604
|
+
const schema = getZodSchema(name);
|
|
2605
|
+
const synonyms = FIELD_SYNONYMS[name];
|
|
2606
|
+
let jsonSchema;
|
|
2607
|
+
try {
|
|
2608
|
+
const raw = import_zod12.z.toJSONSchema(schema, { unrepresentable: "any" });
|
|
2609
|
+
jsonSchema = raw;
|
|
2610
|
+
} catch {
|
|
2611
|
+
jsonSchema = { type: "object", description: "Schema introspection unavailable for this type" };
|
|
2612
|
+
}
|
|
2613
|
+
const summary = formatObjectSchema(jsonSchema, name, synonyms);
|
|
2614
|
+
const synonymWarnings = Object.entries(synonyms).map(
|
|
2615
|
+
([wrong, correct]) => ` WARNING: use "${correct}" \u2014 NOT "${wrong}"`
|
|
2616
|
+
);
|
|
2617
|
+
const fullText = [
|
|
2618
|
+
summary,
|
|
2619
|
+
"",
|
|
2620
|
+
"FIELD NAME WARNINGS (common drift patterns):",
|
|
2621
|
+
...synonymWarnings
|
|
2622
|
+
].join("\n");
|
|
2623
|
+
const tokenEstimate = Math.ceil(fullText.length / 4);
|
|
2624
|
+
return {
|
|
2625
|
+
schemaName: name,
|
|
2626
|
+
summary,
|
|
2627
|
+
synonymWarnings,
|
|
2628
|
+
tokenEstimate
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
var PHASE_SCHEMA_NAMES = {
|
|
2632
|
+
workflow: ["workflow_step", "workflow_definition", "workflow_field", "workflow_action"],
|
|
2633
|
+
pages: ["navigation_item"],
|
|
2634
|
+
dashboard: ["navigation_item"],
|
|
2635
|
+
polish: ["navigation_item"],
|
|
2636
|
+
auth: ["auth_config"]
|
|
2637
|
+
};
|
|
2638
|
+
function buildSchemaReferenceBlock(phase) {
|
|
2639
|
+
const schemaNames = PHASE_SCHEMA_NAMES[phase];
|
|
2640
|
+
if (!schemaNames || schemaNames.length === 0) return null;
|
|
2641
|
+
const sections = [
|
|
2642
|
+
"CANONICAL_SCHEMA_REFERENCE (authoritative \u2014 use exact field names below):",
|
|
2643
|
+
""
|
|
2644
|
+
];
|
|
2645
|
+
for (const name of schemaNames) {
|
|
2646
|
+
const result = handleGetSchema({ schemaName: name });
|
|
2647
|
+
if ("error" in result) continue;
|
|
2648
|
+
sections.push(result.summary);
|
|
2649
|
+
if (result.synonymWarnings.length > 0) {
|
|
2650
|
+
sections.push(" Common mistakes to avoid:");
|
|
2651
|
+
sections.push(...result.synonymWarnings);
|
|
2652
|
+
}
|
|
2653
|
+
sections.push("");
|
|
2654
|
+
}
|
|
2655
|
+
return sections.join("\n");
|
|
2656
|
+
}
|
|
2657
|
+
function registerGetSchemaTool(server2) {
|
|
2658
|
+
server2.tool(
|
|
2659
|
+
"stackwright_pro_get_schema",
|
|
2660
|
+
'Returns a compact, LLM-friendly summary of a canonical schema derived programmatically from Zod. Includes required/optional fields, types, constraints, and "did you mean?" warnings for common field-name drift. Use before authoring YAML to confirm exact field names.',
|
|
2661
|
+
{
|
|
2662
|
+
schemaName: import_zod12.z.enum(SUPPORTED_SCHEMA_NAMES).describe(
|
|
2663
|
+
"Schema to summarize. One of: workflow_step, workflow_definition, workflow_field, workflow_action, navigation_item, auth_config"
|
|
2664
|
+
)
|
|
2665
|
+
},
|
|
2666
|
+
async ({ schemaName }) => {
|
|
2667
|
+
const result = handleGetSchema({ schemaName });
|
|
2668
|
+
if ("error" in result) {
|
|
2669
|
+
return {
|
|
2670
|
+
content: [{ type: "text", text: JSON.stringify({ error: result.error }) }],
|
|
2671
|
+
isError: true
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
return {
|
|
2675
|
+
content: [
|
|
2676
|
+
{
|
|
2677
|
+
type: "text",
|
|
2678
|
+
text: JSON.stringify(result, null, 2)
|
|
2679
|
+
}
|
|
2680
|
+
]
|
|
2681
|
+
};
|
|
2682
|
+
}
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
// src/tools/pipeline.ts
|
|
2347
2687
|
var PHASE_ORDER = [
|
|
2348
2688
|
"designer",
|
|
2349
2689
|
"theme",
|
|
@@ -2911,6 +3251,10 @@ ${JSON.stringify(content, null, 2)}`
|
|
|
2911
3251
|
const artifactSchema = PHASE_ARTIFACT_SCHEMA[phase];
|
|
2912
3252
|
parts.push("", "REQUIRED_ARTIFACT_SCHEMA:");
|
|
2913
3253
|
parts.push(artifactSchema);
|
|
3254
|
+
const schemaRef = buildSchemaReferenceBlock(phase);
|
|
3255
|
+
if (schemaRef) {
|
|
3256
|
+
parts.push("", schemaRef);
|
|
3257
|
+
}
|
|
2914
3258
|
parts.push("", "Execute using these answers and the upstream artifacts provided.");
|
|
2915
3259
|
const prompt = parts.join("\n");
|
|
2916
3260
|
const dependenciesSatisfied = missingDependencies.length === 0;
|
|
@@ -3285,7 +3629,7 @@ function handleValidateArtifact(input) {
|
|
|
3285
3629
|
workflow: (artifact2) => {
|
|
3286
3630
|
const workflowConfig = artifact2["workflowConfig"];
|
|
3287
3631
|
if (!workflowConfig) return { success: true };
|
|
3288
|
-
const result =
|
|
3632
|
+
const result = import_types3.WorkflowFileSchema.safeParse(workflowConfig);
|
|
3289
3633
|
if (!result.success) {
|
|
3290
3634
|
const issues = result.error.issues.slice(0, 3).map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
3291
3635
|
return { success: false, error: { message: issues } };
|
|
@@ -3295,7 +3639,7 @@ function handleValidateArtifact(input) {
|
|
|
3295
3639
|
auth: (artifact2) => {
|
|
3296
3640
|
const authConfig = artifact2["authConfig"];
|
|
3297
3641
|
if (!authConfig) return { success: true };
|
|
3298
|
-
const result =
|
|
3642
|
+
const result = import_types3.authConfigSchema.safeParse(authConfig);
|
|
3299
3643
|
if (!result.success) {
|
|
3300
3644
|
const issues = result.error.issues.slice(0, 3).map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
3301
3645
|
return { success: false, error: { message: issues } };
|
|
@@ -3367,21 +3711,21 @@ function registerPipelineTools(server2) {
|
|
|
3367
3711
|
"stackwright_pro_set_pipeline_state",
|
|
3368
3712
|
`Atomic read\u2192modify\u2192write pipeline state. ${DESC}`,
|
|
3369
3713
|
{
|
|
3370
|
-
phase:
|
|
3371
|
-
field:
|
|
3372
|
-
value: boolCoerce(
|
|
3714
|
+
phase: import_zod13.z.string().optional().describe('Phase to update, e.g. "designer"'),
|
|
3715
|
+
field: import_zod13.z.enum(["questionsCollected", "answered", "executed", "artifactWritten"]).optional().describe("Boolean field to set"),
|
|
3716
|
+
value: boolCoerce(import_zod13.z.boolean().optional()).describe(
|
|
3373
3717
|
'Value for the field \u2014 must be a JSON boolean (true/false), NOT the string "true"/"false"'
|
|
3374
3718
|
),
|
|
3375
|
-
status:
|
|
3376
|
-
incrementRetry: boolCoerce(
|
|
3719
|
+
status: import_zod13.z.enum(["setup", "questions", "execution", "done"]).optional().describe("Top-level status override"),
|
|
3720
|
+
incrementRetry: boolCoerce(import_zod13.z.boolean().optional()).describe(
|
|
3377
3721
|
"Bump retryCount by 1 \u2014 must be a JSON boolean"
|
|
3378
3722
|
),
|
|
3379
3723
|
updates: jsonCoerce(
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
phase:
|
|
3383
|
-
field:
|
|
3384
|
-
value:
|
|
3724
|
+
import_zod13.z.array(
|
|
3725
|
+
import_zod13.z.object({
|
|
3726
|
+
phase: import_zod13.z.string(),
|
|
3727
|
+
field: import_zod13.z.enum(["questionsCollected", "answered", "executed", "artifactWritten"]),
|
|
3728
|
+
value: import_zod13.z.boolean()
|
|
3385
3729
|
})
|
|
3386
3730
|
).optional()
|
|
3387
3731
|
).describe("Batch updates \u2014 apply multiple field changes in one atomic read\u2192modify\u2192write")
|
|
@@ -3401,7 +3745,7 @@ function registerPipelineTools(server2) {
|
|
|
3401
3745
|
"stackwright_pro_check_execution_ready",
|
|
3402
3746
|
`Check all phases have answer files in .stackwright/answers/. If phase is provided, check only that phase. ${DESC}`,
|
|
3403
3747
|
{
|
|
3404
|
-
phase:
|
|
3748
|
+
phase: import_zod13.z.string().optional().describe("If provided, check only this phase's readiness. Omit to check all phases.")
|
|
3405
3749
|
},
|
|
3406
3750
|
async ({ phase }) => res(handleCheckExecutionReady(void 0, phase))
|
|
3407
3751
|
);
|
|
@@ -3421,9 +3765,9 @@ function registerPipelineTools(server2) {
|
|
|
3421
3765
|
"stackwright_pro_write_phase_questions",
|
|
3422
3766
|
`Parse otter question-collection response \u2192 .stackwright/questions/{phase}.json. Specialists may also call this directly with a parsed questions array. ${DESC}`,
|
|
3423
3767
|
{
|
|
3424
|
-
phase:
|
|
3425
|
-
responseText:
|
|
3426
|
-
questions: jsonCoerce(
|
|
3768
|
+
phase: import_zod13.z.string().optional().describe('Phase name, e.g. "designer" (required for direct write)'),
|
|
3769
|
+
responseText: import_zod13.z.string().optional().describe("Raw LLM response from QUESTION_COLLECTION_MODE"),
|
|
3770
|
+
questions: jsonCoerce(import_zod13.z.array(import_zod13.z.any()).optional()).describe(
|
|
3427
3771
|
"Questions array for direct specialist write"
|
|
3428
3772
|
)
|
|
3429
3773
|
},
|
|
@@ -3465,16 +3809,16 @@ function registerPipelineTools(server2) {
|
|
|
3465
3809
|
server2.tool(
|
|
3466
3810
|
"stackwright_pro_build_specialist_prompt",
|
|
3467
3811
|
`Assemble execution prompt from answers + upstream artifacts. Foreman passes verbatim. ${DESC}`,
|
|
3468
|
-
{ phase:
|
|
3812
|
+
{ phase: import_zod13.z.string().describe('Phase to build prompt for, e.g. "pages"') },
|
|
3469
3813
|
async ({ phase }) => res(handleBuildSpecialistPrompt({ phase }))
|
|
3470
3814
|
);
|
|
3471
3815
|
server2.tool(
|
|
3472
3816
|
"stackwright_pro_validate_artifact",
|
|
3473
3817
|
`Validate and write artifact to .stackwright/artifacts/. Returns retryPrompt on failure. ${DESC}`,
|
|
3474
3818
|
{
|
|
3475
|
-
phase:
|
|
3476
|
-
responseText:
|
|
3477
|
-
artifact: jsonCoerce(
|
|
3819
|
+
phase: import_zod13.z.string().describe('Phase that produced this artifact, e.g. "designer"'),
|
|
3820
|
+
responseText: import_zod13.z.string().optional().describe("Raw response text from the specialist otter (Foreman-mediated path, legacy)"),
|
|
3821
|
+
artifact: jsonCoerce(import_zod13.z.record(import_zod13.z.string(), import_zod13.z.unknown()).optional()).describe(
|
|
3478
3822
|
"Artifact object to validate and write directly (specialist direct path \u2014 skips off-script detection and JSON parsing)"
|
|
3479
3823
|
)
|
|
3480
3824
|
},
|
|
@@ -3490,7 +3834,7 @@ function registerPipelineTools(server2) {
|
|
|
3490
3834
|
}
|
|
3491
3835
|
|
|
3492
3836
|
// src/tools/safe-write.ts
|
|
3493
|
-
var
|
|
3837
|
+
var import_zod14 = require("zod");
|
|
3494
3838
|
var import_fs6 = require("fs");
|
|
3495
3839
|
var import_path6 = require("path");
|
|
3496
3840
|
var OTTER_WRITE_ALLOWLISTS = {
|
|
@@ -3890,10 +4234,10 @@ function registerSafeWriteTools(server2) {
|
|
|
3890
4234
|
"stackwright_pro_safe_write",
|
|
3891
4235
|
DESC,
|
|
3892
4236
|
{
|
|
3893
|
-
callerOtter:
|
|
3894
|
-
filePath:
|
|
3895
|
-
content:
|
|
3896
|
-
createDirectories: boolCoerce(
|
|
4237
|
+
callerOtter: import_zod14.z.string().describe('The otter agent name requesting the write, e.g. "stackwright-pro-page-otter"'),
|
|
4238
|
+
filePath: import_zod14.z.string().describe('Relative path from project root, e.g. "pages/dashboard/content.yml"'),
|
|
4239
|
+
content: import_zod14.z.string().describe("File content to write"),
|
|
4240
|
+
createDirectories: boolCoerce(import_zod14.z.boolean().optional().default(true)).describe(
|
|
3897
4241
|
"Create parent directories if they don't exist. Default: true"
|
|
3898
4242
|
)
|
|
3899
4243
|
},
|
|
@@ -3910,7 +4254,7 @@ function registerSafeWriteTools(server2) {
|
|
|
3910
4254
|
}
|
|
3911
4255
|
|
|
3912
4256
|
// src/tools/auth.ts
|
|
3913
|
-
var
|
|
4257
|
+
var import_zod15 = require("zod");
|
|
3914
4258
|
var import_fs7 = require("fs");
|
|
3915
4259
|
var import_path7 = require("path");
|
|
3916
4260
|
function buildHierarchy(roles) {
|
|
@@ -4782,38 +5126,38 @@ function registerAuthTools(server2) {
|
|
|
4782
5126
|
"stackwright_pro_configure_auth",
|
|
4783
5127
|
"Generate authentication middleware and configuration for a Next.js Stackwright application. Writes `middleware.ts` from a secure template, appends/updates the `auth:` section in `stackwright.yml`, and generates `.env.example` with required environment variables. \u26A0\uFE0F For CAC/PKI: generated `middleware.ts` carries a SECURITY REVIEW REQUIRED comment \u2014 certificate chain validation must be verified by a DoD security officer before production deployment. This is the ONLY approved path to generating `middleware.ts`. Never write TypeScript auth files directly.",
|
|
4784
5128
|
{
|
|
4785
|
-
method:
|
|
4786
|
-
provider:
|
|
5129
|
+
method: import_zod15.z.enum(["cac", "oidc", "oauth2", "none"]),
|
|
5130
|
+
provider: import_zod15.z.enum(["azure-ad", "okta", "ping", "cognito", "custom"]).optional(),
|
|
4787
5131
|
// CAC
|
|
4788
|
-
cacCaBundle:
|
|
4789
|
-
cacEdipiLookup:
|
|
4790
|
-
cacOcspEndpoint:
|
|
4791
|
-
cacCertHeader:
|
|
5132
|
+
cacCaBundle: import_zod15.z.string().optional(),
|
|
5133
|
+
cacEdipiLookup: import_zod15.z.string().optional(),
|
|
5134
|
+
cacOcspEndpoint: import_zod15.z.string().optional(),
|
|
5135
|
+
cacCertHeader: import_zod15.z.string().optional(),
|
|
4792
5136
|
// OIDC
|
|
4793
|
-
oidcDiscoveryUrl:
|
|
4794
|
-
oidcClientId:
|
|
4795
|
-
oidcClientSecret:
|
|
4796
|
-
oidcScopes:
|
|
4797
|
-
oidcRoleClaim:
|
|
5137
|
+
oidcDiscoveryUrl: import_zod15.z.string().optional(),
|
|
5138
|
+
oidcClientId: import_zod15.z.string().optional(),
|
|
5139
|
+
oidcClientSecret: import_zod15.z.string().optional(),
|
|
5140
|
+
oidcScopes: import_zod15.z.string().optional(),
|
|
5141
|
+
oidcRoleClaim: import_zod15.z.string().optional(),
|
|
4798
5142
|
// OAuth2
|
|
4799
|
-
oauth2AuthUrl:
|
|
4800
|
-
oauth2TokenUrl:
|
|
4801
|
-
oauth2ClientId:
|
|
4802
|
-
oauth2ClientSecret:
|
|
4803
|
-
oauth2Scopes:
|
|
5143
|
+
oauth2AuthUrl: import_zod15.z.string().optional(),
|
|
5144
|
+
oauth2TokenUrl: import_zod15.z.string().optional(),
|
|
5145
|
+
oauth2ClientId: import_zod15.z.string().optional(),
|
|
5146
|
+
oauth2ClientSecret: import_zod15.z.string().optional(),
|
|
5147
|
+
oauth2Scopes: import_zod15.z.string().optional(),
|
|
4804
5148
|
// RBAC
|
|
4805
|
-
rbacRoles: jsonCoerce(
|
|
4806
|
-
rbacDefaultRole:
|
|
5149
|
+
rbacRoles: jsonCoerce(import_zod15.z.array(import_zod15.z.string()).optional()),
|
|
5150
|
+
rbacDefaultRole: import_zod15.z.string().optional(),
|
|
4807
5151
|
// Audit
|
|
4808
|
-
auditEnabled: boolCoerce(
|
|
4809
|
-
auditRetentionDays: numCoerce(
|
|
5152
|
+
auditEnabled: boolCoerce(import_zod15.z.boolean().optional()),
|
|
5153
|
+
auditRetentionDays: numCoerce(import_zod15.z.number().int().positive().optional()),
|
|
4810
5154
|
// Routes
|
|
4811
|
-
protectedRoutes: jsonCoerce(
|
|
5155
|
+
protectedRoutes: jsonCoerce(import_zod15.z.array(import_zod15.z.string()).optional()),
|
|
4812
5156
|
// Injection for tests
|
|
4813
|
-
_cwd:
|
|
4814
|
-
devOnly: boolCoerce(
|
|
4815
|
-
mockUsers: jsonCoerce(
|
|
4816
|
-
nextMajorVersion: numCoerce(
|
|
5157
|
+
_cwd: import_zod15.z.string().optional(),
|
|
5158
|
+
devOnly: boolCoerce(import_zod15.z.boolean().optional()),
|
|
5159
|
+
mockUsers: jsonCoerce(import_zod15.z.array(import_zod15.z.object({ name: import_zod15.z.string(), email: import_zod15.z.string() })).optional()),
|
|
5160
|
+
nextMajorVersion: numCoerce(import_zod15.z.number().int().positive().optional())
|
|
4817
5161
|
},
|
|
4818
5162
|
async (params) => {
|
|
4819
5163
|
const cwd = params._cwd ?? process.cwd();
|
|
@@ -4829,59 +5173,59 @@ var import_path8 = require("path");
|
|
|
4829
5173
|
var _checksums = /* @__PURE__ */ new Map([
|
|
4830
5174
|
[
|
|
4831
5175
|
"stackwright-pro-api-otter.json",
|
|
4832
|
-
"
|
|
5176
|
+
"1610b34c2bfd89aa18ef62fe052fe5aaba21cb2aa9c5d58a4fff06af2a1f0e6e"
|
|
4833
5177
|
],
|
|
4834
5178
|
[
|
|
4835
5179
|
"stackwright-pro-auth-otter.json",
|
|
4836
|
-
"
|
|
5180
|
+
"5a876d3614e62a7817e69bbe7fe7cc6976035ccaa0e7c29fb1e1a32caf8cea93"
|
|
4837
5181
|
],
|
|
4838
5182
|
[
|
|
4839
5183
|
"stackwright-pro-dashboard-otter.json",
|
|
4840
|
-
"
|
|
5184
|
+
"9550e565fb467d7956cf6b50e7b30a481e6e4b26d609dfe1f0d8f991fc6681de"
|
|
4841
5185
|
],
|
|
4842
5186
|
[
|
|
4843
5187
|
"stackwright-pro-data-otter.json",
|
|
4844
|
-
"
|
|
5188
|
+
"5cd8caca50bfcc00ebaf1f9a83158e5580e0e51d25495244f8465d9c20f31e17"
|
|
4845
5189
|
],
|
|
4846
5190
|
[
|
|
4847
5191
|
"stackwright-pro-designer-otter.json",
|
|
4848
|
-
"
|
|
5192
|
+
"d44b307299c2b65568a708920b819eec7d3b5fe1191ace24b166cbfb2d6e5209"
|
|
4849
5193
|
],
|
|
4850
5194
|
[
|
|
4851
5195
|
"stackwright-pro-domain-expert-otter.json",
|
|
4852
|
-
"
|
|
5196
|
+
"dc060aacdf67ee5758921c72225aa669a76cb962f0f8eedf1741f58f18e870d3"
|
|
4853
5197
|
],
|
|
4854
5198
|
[
|
|
4855
5199
|
"stackwright-pro-foreman-otter.json",
|
|
4856
|
-
"
|
|
5200
|
+
"ab3d821d9217ccbe112d68ce25798bfe637aef15814168037caa2a98994e8d2d"
|
|
4857
5201
|
],
|
|
4858
5202
|
[
|
|
4859
5203
|
"stackwright-pro-geo-otter.json",
|
|
4860
|
-
"
|
|
5204
|
+
"3c9fc96e79d9ac22be8a293cf3ec904c4ed033842864107515aacdf71285791c"
|
|
4861
5205
|
],
|
|
4862
5206
|
[
|
|
4863
5207
|
"stackwright-pro-page-otter.json",
|
|
4864
|
-
"
|
|
5208
|
+
"0057ea97f7c2e33a8673140f59a0237eb627d82c676af3fae4faa31033598e03"
|
|
4865
5209
|
],
|
|
4866
5210
|
[
|
|
4867
5211
|
"stackwright-pro-polish-otter.json",
|
|
4868
|
-
"
|
|
5212
|
+
"1e534dfbc5644a5efbc566d77b512929760715365d54ce030da177a535c23ea6"
|
|
4869
5213
|
],
|
|
4870
5214
|
[
|
|
4871
5215
|
"stackwright-pro-scaffold-otter.json",
|
|
4872
|
-
"
|
|
5216
|
+
"2ed0adb316aaecb849153d44f52b177de539f21d4a7ce5ae4cc1c3c7470e15d4"
|
|
4873
5217
|
],
|
|
4874
5218
|
[
|
|
4875
5219
|
"stackwright-pro-theme-otter.json",
|
|
4876
|
-
"
|
|
5220
|
+
"730bc16b24b4612552389fe9de662f233044bcbf5ef1e0f27f2cc1e1af4c989f"
|
|
4877
5221
|
],
|
|
4878
5222
|
[
|
|
4879
5223
|
"stackwright-pro-workflow-otter.json",
|
|
4880
|
-
"
|
|
5224
|
+
"8ece2a1f1ec30163600b5ce8b666c915ab0d00a1fa70c38ed58d1bb20cbd9979"
|
|
4881
5225
|
],
|
|
4882
5226
|
[
|
|
4883
5227
|
"stackwright-services-otter.json",
|
|
4884
|
-
"
|
|
5228
|
+
"2a36a07eaf34b59a2dab7059f3748a5742ff1f6b80b4bd6a739c59cf114703d6"
|
|
4885
5229
|
]
|
|
4886
5230
|
]);
|
|
4887
5231
|
Object.freeze(_checksums);
|
|
@@ -5097,7 +5441,7 @@ function registerIntegrityTools(server2) {
|
|
|
5097
5441
|
}
|
|
5098
5442
|
|
|
5099
5443
|
// src/tools/domain.ts
|
|
5100
|
-
var
|
|
5444
|
+
var import_zod16 = require("zod");
|
|
5101
5445
|
var import_fs9 = require("fs");
|
|
5102
5446
|
var import_path9 = require("path");
|
|
5103
5447
|
function handleListCollections(input) {
|
|
@@ -5483,7 +5827,7 @@ function registerDomainTools(server2) {
|
|
|
5483
5827
|
"stackwright_pro_resolve_data_strategy",
|
|
5484
5828
|
"Look up the data freshness strategy configuration from the user's answer. Returns mechanism, revalidation seconds, required packages, and the exact MCP tool call to make. Replaces the strategy table in the data-otter prompt.",
|
|
5485
5829
|
{
|
|
5486
|
-
strategy:
|
|
5830
|
+
strategy: import_zod16.z.string().describe(
|
|
5487
5831
|
'The data-1 answer value: "pulse-fast", "isr-fast", "isr-standard", or "isr-slow"'
|
|
5488
5832
|
)
|
|
5489
5833
|
},
|
|
@@ -5493,7 +5837,7 @@ function registerDomainTools(server2) {
|
|
|
5493
5837
|
"stackwright_pro_validate_workflow",
|
|
5494
5838
|
"Validate a workflow definition against the Stackwright workflow schema. Checks step ID uniqueness, transition targets, terminal state existence, and service references. Call this after the workflow otter produces output.",
|
|
5495
5839
|
{
|
|
5496
|
-
workflow: jsonCoerce(
|
|
5840
|
+
workflow: jsonCoerce(import_zod16.z.record(import_zod16.z.string(), import_zod16.z.unknown()).optional()).describe(
|
|
5497
5841
|
"Parsed workflow object. If omitted, reads from .stackwright/artifacts/workflow-config.json"
|
|
5498
5842
|
)
|
|
5499
5843
|
},
|
|
@@ -5502,7 +5846,7 @@ function registerDomainTools(server2) {
|
|
|
5502
5846
|
}
|
|
5503
5847
|
|
|
5504
5848
|
// src/tools/type-schemas.ts
|
|
5505
|
-
var
|
|
5849
|
+
var import_zod17 = require("zod");
|
|
5506
5850
|
function buildTypeSchemaSummary() {
|
|
5507
5851
|
return {
|
|
5508
5852
|
version: "1.0",
|
|
@@ -5579,7 +5923,7 @@ function registerTypeSchemasTool(server2) {
|
|
|
5579
5923
|
"stackwright_pro_get_type_schemas",
|
|
5580
5924
|
"Returns a structured summary of all canonical @stackwright-pro/types schemas, organized by domain. Use this to determine which otter owns a given schema and what artifact key to expect.",
|
|
5581
5925
|
{
|
|
5582
|
-
format:
|
|
5926
|
+
format: import_zod17.z.enum(["full", "domains-only"]).optional().default("full").describe("full = complete summary with all fields; domains-only = just domain names")
|
|
5583
5927
|
},
|
|
5584
5928
|
async ({ format }) => {
|
|
5585
5929
|
const summary = buildTypeSchemaSummary();
|
|
@@ -5768,7 +6112,7 @@ function registerScaffoldCleanupTools(server2) {
|
|
|
5768
6112
|
}
|
|
5769
6113
|
|
|
5770
6114
|
// src/tools/contrast.ts
|
|
5771
|
-
var
|
|
6115
|
+
var import_zod18 = require("zod");
|
|
5772
6116
|
function linearizeChannel(c255) {
|
|
5773
6117
|
const c = c255 / 255;
|
|
5774
6118
|
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
@@ -5940,8 +6284,8 @@ function registerContrastTools(server2) {
|
|
|
5940
6284
|
"stackwright_pro_check_contrast",
|
|
5941
6285
|
'Compute the exact WCAG 2.1 contrast ratio between a foreground and background color. Returns the ratio and AA/AAA pass/fail flags. Use this to verify any foreground/background color pair before writing it to the token set. Accepts #RGB, #RRGGBB, hsl(...), or shadcn HSL format ("H S% L%").',
|
|
5942
6286
|
{
|
|
5943
|
-
fg:
|
|
5944
|
-
bg:
|
|
6287
|
+
fg: import_zod18.z.string().describe("Foreground (text) color \u2014 hex or HSL"),
|
|
6288
|
+
bg: import_zod18.z.string().describe("Background color \u2014 hex or HSL")
|
|
5945
6289
|
},
|
|
5946
6290
|
async ({ fg, bg }) => {
|
|
5947
6291
|
let result;
|
|
@@ -5971,8 +6315,8 @@ function registerContrastTools(server2) {
|
|
|
5971
6315
|
"stackwright_pro_derive_accessible_palette",
|
|
5972
6316
|
'Given a seed color (treated as a background), derive the best accessible foreground (text) color that meets the target contrast ratio. Evaluates #ffffff and #000000 against the seed and picks whichever satisfies the target ratio with the highest contrast. Use this for every {name}-foreground token derivation instead of guessing white vs black. Accepts #RGB, #RRGGBB, hsl(...), or shadcn HSL format ("H S% L%").',
|
|
5973
6317
|
{
|
|
5974
|
-
seed:
|
|
5975
|
-
targetRatio: numCoerce(
|
|
6318
|
+
seed: import_zod18.z.string().describe("Background (seed) color \u2014 hex or HSL"),
|
|
6319
|
+
targetRatio: numCoerce(import_zod18.z.number().default(4.5)).describe(
|
|
5976
6320
|
"Minimum required contrast ratio (default 4.5 for WCAG AA)"
|
|
5977
6321
|
)
|
|
5978
6322
|
},
|
|
@@ -6009,9 +6353,11 @@ function registerContrastTools(server2) {
|
|
|
6009
6353
|
// package.json
|
|
6010
6354
|
var package_default = {
|
|
6011
6355
|
dependencies: {
|
|
6012
|
-
"@stackwright-pro/types": "workspace:*",
|
|
6013
6356
|
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
6014
6357
|
"@stackwright-pro/cli-data-explorer": "workspace:*",
|
|
6358
|
+
"@stackwright-pro/types": "workspace:*",
|
|
6359
|
+
"@types/js-yaml": "^4.0.9",
|
|
6360
|
+
"js-yaml": "^4.2.0",
|
|
6015
6361
|
zod: "^4.4.3"
|
|
6016
6362
|
},
|
|
6017
6363
|
devDependencies: {
|
|
@@ -6029,7 +6375,7 @@ var package_default = {
|
|
|
6029
6375
|
"test:coverage": "vitest run --coverage"
|
|
6030
6376
|
},
|
|
6031
6377
|
name: "@stackwright-pro/mcp",
|
|
6032
|
-
version: "0.2.0-alpha.
|
|
6378
|
+
version: "0.2.0-alpha.81",
|
|
6033
6379
|
description: "MCP tools for Stackwright Pro - Data Explorer, Security, ISR, and Dashboard generation",
|
|
6034
6380
|
license: "SEE LICENSE IN LICENSE",
|
|
6035
6381
|
main: "./dist/server.js",
|
|
@@ -6083,6 +6429,8 @@ registerIntegrityTools(server);
|
|
|
6083
6429
|
registerArtifactSigningTools(server);
|
|
6084
6430
|
registerDomainTools(server);
|
|
6085
6431
|
registerTypeSchemasTool(server);
|
|
6432
|
+
registerValidateYamlFragmentTool(server);
|
|
6433
|
+
registerGetSchemaTool(server);
|
|
6086
6434
|
registerScaffoldCleanupTools(server);
|
|
6087
6435
|
registerContrastTools(server);
|
|
6088
6436
|
async function main() {
|