@stackwright-pro/mcp 0.2.0-alpha.80 → 0.2.0-alpha.82
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 +436 -78
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +448 -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;
|
|
@@ -2945,6 +3289,7 @@ var OFF_SCRIPT_PATTERNS = [
|
|
|
2945
3289
|
var PHASE_REQUIRED_KEYS = {
|
|
2946
3290
|
designer: ["designLanguage", "themeTokenSeeds"],
|
|
2947
3291
|
theme: ["tokens"],
|
|
3292
|
+
scaffold: ["version", "generatedBy", "appRouterFiles"],
|
|
2948
3293
|
api: ["entities", "version", "generatedBy"],
|
|
2949
3294
|
auth: ["version", "generatedBy"],
|
|
2950
3295
|
data: ["version", "generatedBy", "strategy", "collections"],
|
|
@@ -3285,7 +3630,7 @@ function handleValidateArtifact(input) {
|
|
|
3285
3630
|
workflow: (artifact2) => {
|
|
3286
3631
|
const workflowConfig = artifact2["workflowConfig"];
|
|
3287
3632
|
if (!workflowConfig) return { success: true };
|
|
3288
|
-
const result =
|
|
3633
|
+
const result = import_types3.WorkflowFileSchema.safeParse(workflowConfig);
|
|
3289
3634
|
if (!result.success) {
|
|
3290
3635
|
const issues = result.error.issues.slice(0, 3).map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
3291
3636
|
return { success: false, error: { message: issues } };
|
|
@@ -3295,7 +3640,7 @@ function handleValidateArtifact(input) {
|
|
|
3295
3640
|
auth: (artifact2) => {
|
|
3296
3641
|
const authConfig = artifact2["authConfig"];
|
|
3297
3642
|
if (!authConfig) return { success: true };
|
|
3298
|
-
const result =
|
|
3643
|
+
const result = import_types3.authConfigSchema.safeParse(authConfig);
|
|
3299
3644
|
if (!result.success) {
|
|
3300
3645
|
const issues = result.error.issues.slice(0, 3).map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
3301
3646
|
return { success: false, error: { message: issues } };
|
|
@@ -3367,21 +3712,21 @@ function registerPipelineTools(server2) {
|
|
|
3367
3712
|
"stackwright_pro_set_pipeline_state",
|
|
3368
3713
|
`Atomic read\u2192modify\u2192write pipeline state. ${DESC}`,
|
|
3369
3714
|
{
|
|
3370
|
-
phase:
|
|
3371
|
-
field:
|
|
3372
|
-
value: boolCoerce(
|
|
3715
|
+
phase: import_zod13.z.string().optional().describe('Phase to update, e.g. "designer"'),
|
|
3716
|
+
field: import_zod13.z.enum(["questionsCollected", "answered", "executed", "artifactWritten"]).optional().describe("Boolean field to set"),
|
|
3717
|
+
value: boolCoerce(import_zod13.z.boolean().optional()).describe(
|
|
3373
3718
|
'Value for the field \u2014 must be a JSON boolean (true/false), NOT the string "true"/"false"'
|
|
3374
3719
|
),
|
|
3375
|
-
status:
|
|
3376
|
-
incrementRetry: boolCoerce(
|
|
3720
|
+
status: import_zod13.z.enum(["setup", "questions", "execution", "done"]).optional().describe("Top-level status override"),
|
|
3721
|
+
incrementRetry: boolCoerce(import_zod13.z.boolean().optional()).describe(
|
|
3377
3722
|
"Bump retryCount by 1 \u2014 must be a JSON boolean"
|
|
3378
3723
|
),
|
|
3379
3724
|
updates: jsonCoerce(
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
phase:
|
|
3383
|
-
field:
|
|
3384
|
-
value:
|
|
3725
|
+
import_zod13.z.array(
|
|
3726
|
+
import_zod13.z.object({
|
|
3727
|
+
phase: import_zod13.z.string(),
|
|
3728
|
+
field: import_zod13.z.enum(["questionsCollected", "answered", "executed", "artifactWritten"]),
|
|
3729
|
+
value: import_zod13.z.boolean()
|
|
3385
3730
|
})
|
|
3386
3731
|
).optional()
|
|
3387
3732
|
).describe("Batch updates \u2014 apply multiple field changes in one atomic read\u2192modify\u2192write")
|
|
@@ -3401,7 +3746,7 @@ function registerPipelineTools(server2) {
|
|
|
3401
3746
|
"stackwright_pro_check_execution_ready",
|
|
3402
3747
|
`Check all phases have answer files in .stackwright/answers/. If phase is provided, check only that phase. ${DESC}`,
|
|
3403
3748
|
{
|
|
3404
|
-
phase:
|
|
3749
|
+
phase: import_zod13.z.string().optional().describe("If provided, check only this phase's readiness. Omit to check all phases.")
|
|
3405
3750
|
},
|
|
3406
3751
|
async ({ phase }) => res(handleCheckExecutionReady(void 0, phase))
|
|
3407
3752
|
);
|
|
@@ -3421,9 +3766,9 @@ function registerPipelineTools(server2) {
|
|
|
3421
3766
|
"stackwright_pro_write_phase_questions",
|
|
3422
3767
|
`Parse otter question-collection response \u2192 .stackwright/questions/{phase}.json. Specialists may also call this directly with a parsed questions array. ${DESC}`,
|
|
3423
3768
|
{
|
|
3424
|
-
phase:
|
|
3425
|
-
responseText:
|
|
3426
|
-
questions: jsonCoerce(
|
|
3769
|
+
phase: import_zod13.z.string().optional().describe('Phase name, e.g. "designer" (required for direct write)'),
|
|
3770
|
+
responseText: import_zod13.z.string().optional().describe("Raw LLM response from QUESTION_COLLECTION_MODE"),
|
|
3771
|
+
questions: jsonCoerce(import_zod13.z.array(import_zod13.z.any()).optional()).describe(
|
|
3427
3772
|
"Questions array for direct specialist write"
|
|
3428
3773
|
)
|
|
3429
3774
|
},
|
|
@@ -3465,16 +3810,16 @@ function registerPipelineTools(server2) {
|
|
|
3465
3810
|
server2.tool(
|
|
3466
3811
|
"stackwright_pro_build_specialist_prompt",
|
|
3467
3812
|
`Assemble execution prompt from answers + upstream artifacts. Foreman passes verbatim. ${DESC}`,
|
|
3468
|
-
{ phase:
|
|
3813
|
+
{ phase: import_zod13.z.string().describe('Phase to build prompt for, e.g. "pages"') },
|
|
3469
3814
|
async ({ phase }) => res(handleBuildSpecialistPrompt({ phase }))
|
|
3470
3815
|
);
|
|
3471
3816
|
server2.tool(
|
|
3472
3817
|
"stackwright_pro_validate_artifact",
|
|
3473
3818
|
`Validate and write artifact to .stackwright/artifacts/. Returns retryPrompt on failure. ${DESC}`,
|
|
3474
3819
|
{
|
|
3475
|
-
phase:
|
|
3476
|
-
responseText:
|
|
3477
|
-
artifact: jsonCoerce(
|
|
3820
|
+
phase: import_zod13.z.string().describe('Phase that produced this artifact, e.g. "designer"'),
|
|
3821
|
+
responseText: import_zod13.z.string().optional().describe("Raw response text from the specialist otter (Foreman-mediated path, legacy)"),
|
|
3822
|
+
artifact: jsonCoerce(import_zod13.z.record(import_zod13.z.string(), import_zod13.z.unknown()).optional()).describe(
|
|
3478
3823
|
"Artifact object to validate and write directly (specialist direct path \u2014 skips off-script detection and JSON parsing)"
|
|
3479
3824
|
)
|
|
3480
3825
|
},
|
|
@@ -3490,7 +3835,7 @@ function registerPipelineTools(server2) {
|
|
|
3490
3835
|
}
|
|
3491
3836
|
|
|
3492
3837
|
// src/tools/safe-write.ts
|
|
3493
|
-
var
|
|
3838
|
+
var import_zod14 = require("zod");
|
|
3494
3839
|
var import_fs6 = require("fs");
|
|
3495
3840
|
var import_path6 = require("path");
|
|
3496
3841
|
var OTTER_WRITE_ALLOWLISTS = {
|
|
@@ -3566,11 +3911,20 @@ var OTTER_WRITE_ALLOWLISTS = {
|
|
|
3566
3911
|
suffix: "",
|
|
3567
3912
|
description: "Stackwright config (navigation updates)"
|
|
3568
3913
|
},
|
|
3914
|
+
{
|
|
3915
|
+
prefix: "stackwright.navigation.",
|
|
3916
|
+
suffix: ".yml",
|
|
3917
|
+
description: "Navigation config YAML (merged at build time)"
|
|
3918
|
+
},
|
|
3569
3919
|
{ prefix: "pages/", suffix: "/content.yml", description: "Landing page content" },
|
|
3570
3920
|
{ prefix: "pages/", suffix: "/content.yaml", description: "Landing page content" },
|
|
3571
3921
|
{ prefix: ".stackwright/artifacts/", suffix: ".json", description: "Polish artifact" },
|
|
3572
3922
|
{ prefix: "README.md", suffix: "", description: "Project README rewrite" }
|
|
3573
3923
|
],
|
|
3924
|
+
// domain-expert-otter is a reader/answerer only — it writes via stackwright_pro_save_phase_answers,
|
|
3925
|
+
// not via safe_write. Entry required here because the MCP tool availability guard boilerplate
|
|
3926
|
+
// in its system prompt mentions stackwright_pro_safe_write (triggering the coherence test).
|
|
3927
|
+
"stackwright-pro-domain-expert-otter": [],
|
|
3574
3928
|
"stackwright-services-otter": [
|
|
3575
3929
|
{ prefix: ".stackwright/artifacts/", suffix: ".json", description: "Services config artifact" },
|
|
3576
3930
|
{ prefix: "services/", suffix: ".ts", description: "Service implementation files" },
|
|
@@ -3890,10 +4244,10 @@ function registerSafeWriteTools(server2) {
|
|
|
3890
4244
|
"stackwright_pro_safe_write",
|
|
3891
4245
|
DESC,
|
|
3892
4246
|
{
|
|
3893
|
-
callerOtter:
|
|
3894
|
-
filePath:
|
|
3895
|
-
content:
|
|
3896
|
-
createDirectories: boolCoerce(
|
|
4247
|
+
callerOtter: import_zod14.z.string().describe('The otter agent name requesting the write, e.g. "stackwright-pro-page-otter"'),
|
|
4248
|
+
filePath: import_zod14.z.string().describe('Relative path from project root, e.g. "pages/dashboard/content.yml"'),
|
|
4249
|
+
content: import_zod14.z.string().describe("File content to write"),
|
|
4250
|
+
createDirectories: boolCoerce(import_zod14.z.boolean().optional().default(true)).describe(
|
|
3897
4251
|
"Create parent directories if they don't exist. Default: true"
|
|
3898
4252
|
)
|
|
3899
4253
|
},
|
|
@@ -3910,7 +4264,7 @@ function registerSafeWriteTools(server2) {
|
|
|
3910
4264
|
}
|
|
3911
4265
|
|
|
3912
4266
|
// src/tools/auth.ts
|
|
3913
|
-
var
|
|
4267
|
+
var import_zod15 = require("zod");
|
|
3914
4268
|
var import_fs7 = require("fs");
|
|
3915
4269
|
var import_path7 = require("path");
|
|
3916
4270
|
function buildHierarchy(roles) {
|
|
@@ -4782,38 +5136,38 @@ function registerAuthTools(server2) {
|
|
|
4782
5136
|
"stackwright_pro_configure_auth",
|
|
4783
5137
|
"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
5138
|
{
|
|
4785
|
-
method:
|
|
4786
|
-
provider:
|
|
5139
|
+
method: import_zod15.z.enum(["cac", "oidc", "oauth2", "none"]),
|
|
5140
|
+
provider: import_zod15.z.enum(["azure-ad", "okta", "ping", "cognito", "custom"]).optional(),
|
|
4787
5141
|
// CAC
|
|
4788
|
-
cacCaBundle:
|
|
4789
|
-
cacEdipiLookup:
|
|
4790
|
-
cacOcspEndpoint:
|
|
4791
|
-
cacCertHeader:
|
|
5142
|
+
cacCaBundle: import_zod15.z.string().optional(),
|
|
5143
|
+
cacEdipiLookup: import_zod15.z.string().optional(),
|
|
5144
|
+
cacOcspEndpoint: import_zod15.z.string().optional(),
|
|
5145
|
+
cacCertHeader: import_zod15.z.string().optional(),
|
|
4792
5146
|
// OIDC
|
|
4793
|
-
oidcDiscoveryUrl:
|
|
4794
|
-
oidcClientId:
|
|
4795
|
-
oidcClientSecret:
|
|
4796
|
-
oidcScopes:
|
|
4797
|
-
oidcRoleClaim:
|
|
5147
|
+
oidcDiscoveryUrl: import_zod15.z.string().optional(),
|
|
5148
|
+
oidcClientId: import_zod15.z.string().optional(),
|
|
5149
|
+
oidcClientSecret: import_zod15.z.string().optional(),
|
|
5150
|
+
oidcScopes: import_zod15.z.string().optional(),
|
|
5151
|
+
oidcRoleClaim: import_zod15.z.string().optional(),
|
|
4798
5152
|
// OAuth2
|
|
4799
|
-
oauth2AuthUrl:
|
|
4800
|
-
oauth2TokenUrl:
|
|
4801
|
-
oauth2ClientId:
|
|
4802
|
-
oauth2ClientSecret:
|
|
4803
|
-
oauth2Scopes:
|
|
5153
|
+
oauth2AuthUrl: import_zod15.z.string().optional(),
|
|
5154
|
+
oauth2TokenUrl: import_zod15.z.string().optional(),
|
|
5155
|
+
oauth2ClientId: import_zod15.z.string().optional(),
|
|
5156
|
+
oauth2ClientSecret: import_zod15.z.string().optional(),
|
|
5157
|
+
oauth2Scopes: import_zod15.z.string().optional(),
|
|
4804
5158
|
// RBAC
|
|
4805
|
-
rbacRoles: jsonCoerce(
|
|
4806
|
-
rbacDefaultRole:
|
|
5159
|
+
rbacRoles: jsonCoerce(import_zod15.z.array(import_zod15.z.string()).optional()),
|
|
5160
|
+
rbacDefaultRole: import_zod15.z.string().optional(),
|
|
4807
5161
|
// Audit
|
|
4808
|
-
auditEnabled: boolCoerce(
|
|
4809
|
-
auditRetentionDays: numCoerce(
|
|
5162
|
+
auditEnabled: boolCoerce(import_zod15.z.boolean().optional()),
|
|
5163
|
+
auditRetentionDays: numCoerce(import_zod15.z.number().int().positive().optional()),
|
|
4810
5164
|
// Routes
|
|
4811
|
-
protectedRoutes: jsonCoerce(
|
|
5165
|
+
protectedRoutes: jsonCoerce(import_zod15.z.array(import_zod15.z.string()).optional()),
|
|
4812
5166
|
// Injection for tests
|
|
4813
|
-
_cwd:
|
|
4814
|
-
devOnly: boolCoerce(
|
|
4815
|
-
mockUsers: jsonCoerce(
|
|
4816
|
-
nextMajorVersion: numCoerce(
|
|
5167
|
+
_cwd: import_zod15.z.string().optional(),
|
|
5168
|
+
devOnly: boolCoerce(import_zod15.z.boolean().optional()),
|
|
5169
|
+
mockUsers: jsonCoerce(import_zod15.z.array(import_zod15.z.object({ name: import_zod15.z.string(), email: import_zod15.z.string() })).optional()),
|
|
5170
|
+
nextMajorVersion: numCoerce(import_zod15.z.number().int().positive().optional())
|
|
4817
5171
|
},
|
|
4818
5172
|
async (params) => {
|
|
4819
5173
|
const cwd = params._cwd ?? process.cwd();
|
|
@@ -4829,59 +5183,59 @@ var import_path8 = require("path");
|
|
|
4829
5183
|
var _checksums = /* @__PURE__ */ new Map([
|
|
4830
5184
|
[
|
|
4831
5185
|
"stackwright-pro-api-otter.json",
|
|
4832
|
-
"
|
|
5186
|
+
"df79f4389a576c2885efa07b04f613c60eb8ebf4a8b1d4c7da5e4bb6ee4248dd"
|
|
4833
5187
|
],
|
|
4834
5188
|
[
|
|
4835
5189
|
"stackwright-pro-auth-otter.json",
|
|
4836
|
-
"
|
|
5190
|
+
"539c7145e88dd2afa7f2417be8cfa8e0e7d82608d051271a20f9c7e4e77d98e7"
|
|
4837
5191
|
],
|
|
4838
5192
|
[
|
|
4839
5193
|
"stackwright-pro-dashboard-otter.json",
|
|
4840
|
-
"
|
|
5194
|
+
"160af221e04200f53709f8c3e249ca6dafb38a325b232fabd478b28f5492ab01"
|
|
4841
5195
|
],
|
|
4842
5196
|
[
|
|
4843
5197
|
"stackwright-pro-data-otter.json",
|
|
4844
|
-
"
|
|
5198
|
+
"b135cb0013edaa40baaf8a03f1d8795920dc0ce611183f047e55104bf8cf35be"
|
|
4845
5199
|
],
|
|
4846
5200
|
[
|
|
4847
5201
|
"stackwright-pro-designer-otter.json",
|
|
4848
|
-
"
|
|
5202
|
+
"1364b2c235c07b0b798e9aab90a68604f60019a5508d41ba576977f173e20cd9"
|
|
4849
5203
|
],
|
|
4850
5204
|
[
|
|
4851
5205
|
"stackwright-pro-domain-expert-otter.json",
|
|
4852
|
-
"
|
|
5206
|
+
"1f21b8ff3450bdae29a4d31b31462ba22583995a448af3c11ab0a5071f46bd72"
|
|
4853
5207
|
],
|
|
4854
5208
|
[
|
|
4855
5209
|
"stackwright-pro-foreman-otter.json",
|
|
4856
|
-
"
|
|
5210
|
+
"438b03d2c35f64536055c68b3a9044fe3b5e4f2889acde4500dd801fad724be1"
|
|
4857
5211
|
],
|
|
4858
5212
|
[
|
|
4859
5213
|
"stackwright-pro-geo-otter.json",
|
|
4860
|
-
"
|
|
5214
|
+
"2ec83c26a08c413d9553ff8b8f0f0f643c1a8da043741b356e27106cad78f05f"
|
|
4861
5215
|
],
|
|
4862
5216
|
[
|
|
4863
5217
|
"stackwright-pro-page-otter.json",
|
|
4864
|
-
"
|
|
5218
|
+
"0057ea97f7c2e33a8673140f59a0237eb627d82c676af3fae4faa31033598e03"
|
|
4865
5219
|
],
|
|
4866
5220
|
[
|
|
4867
5221
|
"stackwright-pro-polish-otter.json",
|
|
4868
|
-
"
|
|
5222
|
+
"02cfa56354bfcd33af6d634ac647f38812a2353e487816b67edc2e9eb2c3e357"
|
|
4869
5223
|
],
|
|
4870
5224
|
[
|
|
4871
5225
|
"stackwright-pro-scaffold-otter.json",
|
|
4872
|
-
"
|
|
5226
|
+
"ccbc9d20a65dcf7cc2eacb5ac3060cd95a10a3ef795883170684658872299e7b"
|
|
4873
5227
|
],
|
|
4874
5228
|
[
|
|
4875
5229
|
"stackwright-pro-theme-otter.json",
|
|
4876
|
-
"
|
|
5230
|
+
"a271eac375db9d014afb781536f60f2e6716a9054b12b9c35713af09a63912ff"
|
|
4877
5231
|
],
|
|
4878
5232
|
[
|
|
4879
5233
|
"stackwright-pro-workflow-otter.json",
|
|
4880
|
-
"
|
|
5234
|
+
"6cc800374de6e723a283e4757af97f7b8337c64ee78053d7e50a79e17314a049"
|
|
4881
5235
|
],
|
|
4882
5236
|
[
|
|
4883
5237
|
"stackwright-services-otter.json",
|
|
4884
|
-
"
|
|
5238
|
+
"c013d7fc2475e62d0af54d57bc988182feee7766bac0edf841cbfad5c73e9261"
|
|
4885
5239
|
]
|
|
4886
5240
|
]);
|
|
4887
5241
|
Object.freeze(_checksums);
|
|
@@ -5097,7 +5451,7 @@ function registerIntegrityTools(server2) {
|
|
|
5097
5451
|
}
|
|
5098
5452
|
|
|
5099
5453
|
// src/tools/domain.ts
|
|
5100
|
-
var
|
|
5454
|
+
var import_zod16 = require("zod");
|
|
5101
5455
|
var import_fs9 = require("fs");
|
|
5102
5456
|
var import_path9 = require("path");
|
|
5103
5457
|
function handleListCollections(input) {
|
|
@@ -5483,7 +5837,7 @@ function registerDomainTools(server2) {
|
|
|
5483
5837
|
"stackwright_pro_resolve_data_strategy",
|
|
5484
5838
|
"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
5839
|
{
|
|
5486
|
-
strategy:
|
|
5840
|
+
strategy: import_zod16.z.string().describe(
|
|
5487
5841
|
'The data-1 answer value: "pulse-fast", "isr-fast", "isr-standard", or "isr-slow"'
|
|
5488
5842
|
)
|
|
5489
5843
|
},
|
|
@@ -5493,7 +5847,7 @@ function registerDomainTools(server2) {
|
|
|
5493
5847
|
"stackwright_pro_validate_workflow",
|
|
5494
5848
|
"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
5849
|
{
|
|
5496
|
-
workflow: jsonCoerce(
|
|
5850
|
+
workflow: jsonCoerce(import_zod16.z.record(import_zod16.z.string(), import_zod16.z.unknown()).optional()).describe(
|
|
5497
5851
|
"Parsed workflow object. If omitted, reads from .stackwright/artifacts/workflow-config.json"
|
|
5498
5852
|
)
|
|
5499
5853
|
},
|
|
@@ -5502,7 +5856,7 @@ function registerDomainTools(server2) {
|
|
|
5502
5856
|
}
|
|
5503
5857
|
|
|
5504
5858
|
// src/tools/type-schemas.ts
|
|
5505
|
-
var
|
|
5859
|
+
var import_zod17 = require("zod");
|
|
5506
5860
|
function buildTypeSchemaSummary() {
|
|
5507
5861
|
return {
|
|
5508
5862
|
version: "1.0",
|
|
@@ -5579,7 +5933,7 @@ function registerTypeSchemasTool(server2) {
|
|
|
5579
5933
|
"stackwright_pro_get_type_schemas",
|
|
5580
5934
|
"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
5935
|
{
|
|
5582
|
-
format:
|
|
5936
|
+
format: import_zod17.z.enum(["full", "domains-only"]).optional().default("full").describe("full = complete summary with all fields; domains-only = just domain names")
|
|
5583
5937
|
},
|
|
5584
5938
|
async ({ format }) => {
|
|
5585
5939
|
const summary = buildTypeSchemaSummary();
|
|
@@ -5768,7 +6122,7 @@ function registerScaffoldCleanupTools(server2) {
|
|
|
5768
6122
|
}
|
|
5769
6123
|
|
|
5770
6124
|
// src/tools/contrast.ts
|
|
5771
|
-
var
|
|
6125
|
+
var import_zod18 = require("zod");
|
|
5772
6126
|
function linearizeChannel(c255) {
|
|
5773
6127
|
const c = c255 / 255;
|
|
5774
6128
|
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
@@ -5940,8 +6294,8 @@ function registerContrastTools(server2) {
|
|
|
5940
6294
|
"stackwright_pro_check_contrast",
|
|
5941
6295
|
'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
6296
|
{
|
|
5943
|
-
fg:
|
|
5944
|
-
bg:
|
|
6297
|
+
fg: import_zod18.z.string().describe("Foreground (text) color \u2014 hex or HSL"),
|
|
6298
|
+
bg: import_zod18.z.string().describe("Background color \u2014 hex or HSL")
|
|
5945
6299
|
},
|
|
5946
6300
|
async ({ fg, bg }) => {
|
|
5947
6301
|
let result;
|
|
@@ -5971,8 +6325,8 @@ function registerContrastTools(server2) {
|
|
|
5971
6325
|
"stackwright_pro_derive_accessible_palette",
|
|
5972
6326
|
'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
6327
|
{
|
|
5974
|
-
seed:
|
|
5975
|
-
targetRatio: numCoerce(
|
|
6328
|
+
seed: import_zod18.z.string().describe("Background (seed) color \u2014 hex or HSL"),
|
|
6329
|
+
targetRatio: numCoerce(import_zod18.z.number().default(4.5)).describe(
|
|
5976
6330
|
"Minimum required contrast ratio (default 4.5 for WCAG AA)"
|
|
5977
6331
|
)
|
|
5978
6332
|
},
|
|
@@ -6009,9 +6363,11 @@ function registerContrastTools(server2) {
|
|
|
6009
6363
|
// package.json
|
|
6010
6364
|
var package_default = {
|
|
6011
6365
|
dependencies: {
|
|
6012
|
-
"@stackwright-pro/types": "workspace:*",
|
|
6013
6366
|
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
6014
6367
|
"@stackwright-pro/cli-data-explorer": "workspace:*",
|
|
6368
|
+
"@stackwright-pro/types": "workspace:*",
|
|
6369
|
+
"@types/js-yaml": "^4.0.9",
|
|
6370
|
+
"js-yaml": "^4.2.0",
|
|
6015
6371
|
zod: "^4.4.3"
|
|
6016
6372
|
},
|
|
6017
6373
|
devDependencies: {
|
|
@@ -6029,7 +6385,7 @@ var package_default = {
|
|
|
6029
6385
|
"test:coverage": "vitest run --coverage"
|
|
6030
6386
|
},
|
|
6031
6387
|
name: "@stackwright-pro/mcp",
|
|
6032
|
-
version: "0.2.0-alpha.
|
|
6388
|
+
version: "0.2.0-alpha.82",
|
|
6033
6389
|
description: "MCP tools for Stackwright Pro - Data Explorer, Security, ISR, and Dashboard generation",
|
|
6034
6390
|
license: "SEE LICENSE IN LICENSE",
|
|
6035
6391
|
main: "./dist/server.js",
|
|
@@ -6083,6 +6439,8 @@ registerIntegrityTools(server);
|
|
|
6083
6439
|
registerArtifactSigningTools(server);
|
|
6084
6440
|
registerDomainTools(server);
|
|
6085
6441
|
registerTypeSchemasTool(server);
|
|
6442
|
+
registerValidateYamlFragmentTool(server);
|
|
6443
|
+
registerGetSchemaTool(server);
|
|
6086
6444
|
registerScaffoldCleanupTools(server);
|
|
6087
6445
|
registerContrastTools(server);
|
|
6088
6446
|
async function main() {
|