@wowok/agent-mcp 2.6.0 → 2.6.3
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/README.md +5 -3
- package/dist/customer/info-puzzle.d.ts +1 -1
- package/dist/customer/info-puzzle.js +4 -2
- package/dist/customer/risk-assessment.js +26 -4
- package/dist/customer/types.d.ts +2 -0
- package/dist/examples/guard-template-balance-check.json +38 -0
- package/dist/examples/guard-template-time-lock.json +39 -0
- package/dist/examples/machine-template-7node-rental.json +114 -0
- package/dist/examples/rental-ziroom-machine-create.json +137 -0
- package/dist/examples/rental-ziroom-permission-create.json +35 -0
- package/dist/examples/rental-ziroom-service-create.json +80 -0
- package/dist/examples/retail-myshop-service-create.json +88 -0
- package/dist/extensions/capability-manifest.d.ts +125 -0
- package/dist/extensions/capability-manifest.js +594 -0
- package/dist/extensions/constraint-registry.d.ts +24 -0
- package/dist/extensions/constraint-registry.js +196 -0
- package/dist/extensions/index.d.ts +12 -0
- package/dist/extensions/index.js +6 -0
- package/dist/extensions/metric-registry.d.ts +26 -0
- package/dist/extensions/metric-registry.js +257 -0
- package/dist/extensions/mode-evaluator.d.ts +15 -0
- package/dist/extensions/mode-evaluator.js +170 -0
- package/dist/extensions/modes.d.ts +2 -0
- package/dist/extensions/modes.js +493 -0
- package/dist/extensions/registry.d.ts +50 -0
- package/dist/extensions/registry.js +662 -0
- package/dist/extensions/types.d.ts +219 -0
- package/dist/extensions/types.js +1 -0
- package/dist/index.js +50 -0
- package/dist/knowledge/deployment-scanner.d.ts +3 -0
- package/dist/knowledge/deployment-scanner.js +64 -3
- package/dist/knowledge/fund-layer.d.ts +72 -0
- package/dist/knowledge/fund-layer.js +420 -0
- package/dist/knowledge/guard-render.d.ts +57 -0
- package/dist/knowledge/guard-render.js +700 -0
- package/dist/knowledge/guard-risk.d.ts +13 -0
- package/dist/knowledge/guard-risk.js +57 -0
- package/dist/knowledge/guard-submission-prompt.d.ts +31 -0
- package/dist/knowledge/guard-submission-prompt.js +171 -0
- package/dist/knowledge/guard-templates.js +278 -0
- package/dist/knowledge/machine-ledger.js +1 -1
- package/dist/knowledge/machine-render.d.ts +41 -0
- package/dist/knowledge/machine-render.js +565 -0
- package/dist/knowledge/machine-templates.js +24 -5
- package/dist/knowledge/reward-confirm.js +2 -2
- package/dist/knowledge/reward-puzzle.js +1 -1
- package/dist/knowledge/reward-risk.js +9 -9
- package/dist/knowledge/reward-templates.js +2 -2
- package/dist/knowledge/service-confirm.d.ts +15 -6
- package/dist/knowledge/service-confirm.js +119 -11
- package/dist/knowledge/service-context.js +1 -1
- package/dist/knowledge/service-ledger.js +1 -1
- package/dist/knowledge/service-risk.d.ts +1 -1
- package/dist/knowledge/service-risk.js +3 -3
- package/dist/knowledge/service-templates.js +2 -2
- package/dist/knowledge/service-translation.d.ts +1 -1
- package/dist/knowledge/service-translation.js +7 -7
- package/dist/knowledge/tool-constraints.js +6 -2
- package/dist/project/deployment-bridge.d.ts +1 -1
- package/dist/project/deployment-bridge.js +31 -7
- package/dist/project/deployment-doc.d.ts +3 -0
- package/dist/project/deployment-doc.js +76 -14
- package/dist/project/edit-planner.d.ts +123 -0
- package/dist/project/edit-planner.js +1371 -0
- package/dist/project/evaluation.d.ts +2 -0
- package/dist/project/evaluation.js +873 -88
- package/dist/project/graph-builder.d.ts +4 -1
- package/dist/project/graph-builder.js +132 -62
- package/dist/project/graph.d.ts +1 -0
- package/dist/project/handlers.d.ts +317 -6
- package/dist/project/handlers.js +1171 -19
- package/dist/project/stage-gate.d.ts +4 -0
- package/dist/project/stage-gate.js +64 -5
- package/dist/project/task-tracker.d.ts +26 -0
- package/dist/project/task-tracker.js +78 -0
- package/dist/safety/preview.js +16 -0
- package/dist/schema/call/allocation.d.ts +16 -16
- package/dist/schema/call/allocation.js +2 -2
- package/dist/schema/call/arbitration.js +19 -6
- package/dist/schema/call/base.d.ts +21 -13
- package/dist/schema/call/base.js +27 -6
- package/dist/schema/call/bridge.d.ts +5 -5
- package/dist/schema/call/bridge.js +3 -1
- package/dist/schema/call/contact.js +2 -2
- package/dist/schema/call/demand.d.ts +23 -31
- package/dist/schema/call/demand.js +2 -2
- package/dist/schema/call/guard.js +2 -2
- package/dist/schema/call/machine.d.ts +1976 -752
- package/dist/schema/call/machine.js +50 -4
- package/dist/schema/call/order.d.ts +149 -228
- package/dist/schema/call/order.js +4 -3
- package/dist/schema/call/payment.d.ts +183 -3
- package/dist/schema/call/payment.js +21 -3
- package/dist/schema/call/permission.js +2 -2
- package/dist/schema/call/personal.d.ts +241 -52
- package/dist/schema/call/progress.d.ts +53 -61
- package/dist/schema/call/progress.js +18 -4
- package/dist/schema/call/repository.d.ts +23 -31
- package/dist/schema/call/repository.js +2 -2
- package/dist/schema/call/reward.js +3 -3
- package/dist/schema/call/semantic.d.ts +1 -1
- package/dist/schema/call/semantic.js +37 -2
- package/dist/schema/call/service.d.ts +275 -127
- package/dist/schema/call/service.js +89 -13
- package/dist/schema/call/treasury.js +3 -3
- package/dist/schema/common/index.d.ts +13 -2
- package/dist/schema/common/index.js +80 -15
- package/dist/schema/local/index.d.ts +32 -35
- package/dist/schema/local/index.js +28 -6
- package/dist/schema/messenger/index.d.ts +274 -46
- package/dist/schema/operations.d.ts +1264 -544
- package/dist/schema/operations.js +65 -7
- package/dist/schema/project/index.d.ts +2846 -167
- package/dist/schema/project/index.js +570 -16
- package/dist/schema/query/index.d.ts +922 -349
- package/dist/schema/query/index.js +205 -42
- package/dist/schema/schema-query/index.d.ts +65 -3
- package/dist/schema/schema-query/index.js +38 -5
- package/dist/schema/utils/node-parser.js +20 -4
- package/dist/schema/utils/object-type-utils.d.ts +12 -0
- package/dist/schema/utils/object-type-utils.js +35 -0
- package/dist/schema/utils/permission-machine-check.d.ts +49 -0
- package/dist/schema/utils/permission-machine-check.js +121 -0
- package/dist/schema/utils/skills-recommendation.d.ts +2 -0
- package/dist/schema/utils/skills-recommendation.js +76 -0
- package/dist/schema-query/index.d.ts +20 -1
- package/dist/schema-query/index.js +306 -4
- package/dist/schemas/account_operation.output.json +7 -1
- package/dist/schemas/account_operation.schema.json +3 -3
- package/dist/schemas/bridge_operation.output.json +6 -0
- package/dist/schemas/bridge_operation.schema.json +1 -1
- package/dist/schemas/guard-templates.json +379 -0
- package/dist/schemas/guard2file.schema.json +1 -1
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/local_info_operation.output.json +6 -0
- package/dist/schemas/local_mark_operation.output.json +7 -1
- package/dist/schemas/local_mark_operation.schema.json +1 -1
- package/dist/schemas/machineNode2file.schema.json +1 -1
- package/dist/schemas/messenger_operation.schema.json +4 -4
- package/dist/schemas/onchain_events.output.json +1 -1
- package/dist/schemas/onchain_operations.output.json +2820 -0
- package/dist/schemas/onchain_operations.schema.json +444 -330
- package/dist/schemas/onchain_operations_allocation.schema.json +37 -28
- package/dist/schemas/onchain_operations_arbitration.schema.json +16 -14
- package/dist/schemas/onchain_operations_contact.schema.json +10 -10
- package/dist/schemas/onchain_operations_demand.schema.json +10 -10
- package/dist/schemas/onchain_operations_gen_passport.schema.json +16 -16
- package/dist/schemas/onchain_operations_gen_proof.schema.json +2 -2
- package/dist/schemas/onchain_operations_guard.schema.json +2 -2
- package/dist/schemas/onchain_operations_machine.schema.json +43 -35
- package/dist/schemas/onchain_operations_order.schema.json +72 -78
- package/dist/schemas/onchain_operations_payment.schema.json +141 -111
- package/dist/schemas/onchain_operations_permission.schema.json +3 -3
- package/dist/schemas/onchain_operations_personal.schema.json +7 -7
- package/dist/schemas/onchain_operations_progress.schema.json +9 -9
- package/dist/schemas/onchain_operations_proof.schema.json +8 -8
- package/dist/schemas/onchain_operations_repository.schema.json +10 -10
- package/dist/schemas/onchain_operations_reward.schema.json +14 -14
- package/dist/schemas/onchain_operations_service.schema.json +119 -48
- package/dist/schemas/onchain_operations_treasury.schema.json +11 -11
- package/dist/schemas/onchain_table_data.output.json +33 -25
- package/dist/schemas/onchain_table_data.schema.json +22 -21
- package/dist/schemas/project_operation.output.json +2194 -23
- package/dist/schemas/project_operation.schema.json +84 -6
- package/dist/schemas/query_toolkit.output.json +108 -80
- package/dist/schemas/query_toolkit.schema.json +12 -12
- package/dist/schemas/schema_query.output.json +70 -3
- package/dist/schemas/schema_query.schema.json +18 -3
- package/dist/schemas/wowok_buildin_info.output.json +81 -8
- package/dist/schemas/wowok_buildin_info.schema.json +46 -2
- package/dist/tools/handlers/local.js +20 -5
- package/dist/tools/handlers/onchain.js +594 -6
- package/dist/tools/handlers/project.js +76 -4
- package/dist/tools/handlers/query.js +27 -0
- package/dist/tools/handlers/schema-query.js +43 -1
- package/dist/tools/handlers/task-status.d.ts +170 -0
- package/dist/tools/handlers/task-status.js +55 -0
- package/dist/tools/handlers/wip.js +47 -1
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.js +387 -12
- package/dist/tools/retry.d.ts +8 -0
- package/dist/tools/retry.js +85 -0
- package/dist/tools/wip-deploy-assist.d.ts +28 -0
- package/dist/tools/wip-deploy-assist.js +278 -0
- package/package.json +2 -2
- package/dist/schemas/guard-node-examples.md +0 -199
package/dist/tools/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { handleBridgeOperations } from "./handlers/bridge.js";
|
|
|
24
24
|
import { handleProjectOperation } from "./handlers/project.js";
|
|
25
25
|
import { handleConfigOperation } from "./handlers/config.js";
|
|
26
26
|
import { handleTrustScore } from "./handlers/trust.js";
|
|
27
|
+
import { handleQueryTaskStatus, QueryTaskStatusInputSchema, QueryTaskStatusOutputSchema } from "./handlers/task-status.js";
|
|
27
28
|
import { applyOnchainRules } from "./rules-hook.js";
|
|
28
29
|
import { createToolMeta, OnchainOperationsSchema, AccountOperationSchema, LocalMarkOperationSchema, LocalInfoOperationSchema, WipOperationsSchema, MessengerOperationInputSchema, Guard2File_InputSchema, MachineNode2File_InputSchema, WatchQueryOperationsSchema, WatchQueryOperationsResultSchema, OnchainTableDataSchema, OnchainEventsInputSchema, ProtocolInfoQuerySchema, SchemaQueryInputSchema, BridgeOperationsSchema, ProjectOperationInputSchema, ConfigOperationInputSchema, TrustScoreInputSchema, CallOutputSchema, AccountOperationOutputWrappedSchema, LocalMarkOperationOutputWrappedSchema, LocalInfoOperationOutputWrappedSchema, WipOperationOutputSchema, MessengerOperationOutputSchema, Guard2File_OutputWrappedSchema, MachineNode2File_OutputWrappedSchema, OnchainTableDataResultSchema, OnchainEventsResultSchema, ProtocolInfoResultSchema, SchemaQueryOutputSchema, BridgeCallOutputSchema, ProjectOperationOutputSchema, ConfigOperationOutputSchema, TrustScoreOutputSchema, } from "../schema/index.js";
|
|
29
30
|
export const TOOL_REGISTRY = [
|
|
@@ -84,7 +85,7 @@ export const TOOL_REGISTRY = [
|
|
|
84
85
|
handler: handleWipOperations,
|
|
85
86
|
config: {
|
|
86
87
|
title: "🤝 Witness Immutable Promise File Operations",
|
|
87
|
-
description: "generate (create WIP files from markdown and images), verify (integrity check), sign (add signatures), or wip2html (convert to HTML).\n\n💡 Schema hint: Use schema_query with action='get' and name='wip_file' to retrieve the exact parameter schema before calling.",
|
|
88
|
+
description: "generate (create WIP files from markdown and images), verify (integrity check), sign (add signatures), or wip2html (convert to HTML).\n\n⚠️ IMPORTANT — On-chain WIP URL requirement: When using a WIP file URL in `service.sales[].wip` (stored on-chain), the URL MUST be publicly reachable. Local file paths (e.g., 'C:\\\\path\\\\file.wip' or '/home/user/file.wip') are NOT acceptable on-chain — they only work locally and will fail verification for buyers.\n\nDeployment options for the .wip file:\n • GitHub Pages: https://raw.githubusercontent.com/<user>/<repo>/<branch>/<file>.wip\n • IPFS: https://ipfs.io/ipfs/<CID> or https://cloudflare-ipfs.com/ipfs/<CID> (upload via pinata.cloud)\n • User's own static website URL\n\nUse type='generate' to create the WIP file first, upload it to any of the above, then use the resulting URL in service.sales[].wip.\n\n💡 Schema hint: Use schema_query with action='get' and name='wip_file' to retrieve the exact parameter schema before calling.",
|
|
88
89
|
inputSchema: WipOperationsSchema,
|
|
89
90
|
outputSchema: z.object({
|
|
90
91
|
result: WipOperationOutputSchema,
|
|
@@ -360,6 +361,28 @@ export const TOOL_REGISTRY = [
|
|
|
360
361
|
_meta: createToolMeta("trust", ["trust", "score", "risk", "service", "merchant", "reputation", "safety", "evaluate"]),
|
|
361
362
|
},
|
|
362
363
|
},
|
|
364
|
+
{
|
|
365
|
+
name: "query_task_status",
|
|
366
|
+
handler: handleQueryTaskStatus,
|
|
367
|
+
config: {
|
|
368
|
+
title: "📊 Task Status - Async Operation Tracking",
|
|
369
|
+
description: "Query the status of a long-running async task (created by build_graph or evaluate_project " +
|
|
370
|
+
"with async_mode=true). Returns progress percentage, current status, and the final result " +
|
|
371
|
+
"when completed.\n\n" +
|
|
372
|
+
"Tasks are ephemeral (retained 5 minutes after completion, in-memory only).\n\n" +
|
|
373
|
+
"Usage:\n" +
|
|
374
|
+
" • Pass task_id to query a single task's status.\n" +
|
|
375
|
+
" • Omit task_id to list all recent tasks (max 50, most recent first).\n" +
|
|
376
|
+
" • Pass project_id (with task_id omitted) to filter by project.\n\n" +
|
|
377
|
+
"This tool is read-only and always safe to call. Use it to check if a long-running " +
|
|
378
|
+
"operation (e.g. build_graph with enablePotential=true) has completed.\n\n" +
|
|
379
|
+
"💡 Schema hint: Use schema_query with action='get' and name='query_task_status' to retrieve the exact parameter schema.",
|
|
380
|
+
inputSchema: QueryTaskStatusInputSchema,
|
|
381
|
+
outputSchema: QueryTaskStatusOutputSchema,
|
|
382
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
383
|
+
_meta: createToolMeta("task", ["task", "status", "async", "progress", "background", "tracker"]),
|
|
384
|
+
},
|
|
385
|
+
},
|
|
363
386
|
];
|
|
364
387
|
export const TOOL_REGISTRY_MAP = new Map(TOOL_REGISTRY.map(t => [t.name, t]));
|
|
365
388
|
const SUB_TOOL_NAMES = TOOL_REGISTRY.map(t => t.name);
|
|
@@ -439,10 +462,10 @@ const WOWOK_TOOL_DESCRIPTION = [
|
|
|
439
462
|
"Projects are the core organizing unit for all WoWok workflows. The policy is context-aware:",
|
|
440
463
|
"",
|
|
441
464
|
"CASE 1 — COMPLEX REQUIREMENT (user wants to build/deploy a full service):",
|
|
442
|
-
" Examples: '
|
|
465
|
+
" Examples: 'build a travel guide service', 'open a toy store', 'create a rental service'",
|
|
443
466
|
" → You MUST auto-create a project FIRST, then create objects.",
|
|
444
467
|
" → Check for similar existing projects first: project_operation action='list_projects'",
|
|
445
|
-
" If similar projects exist (same industry), remind the user: '
|
|
468
|
+
" If similar projects exist (same industry), remind the user: 'Found similar project X. Reuse or create new?'",
|
|
446
469
|
" → Workflow:",
|
|
447
470
|
" 1. project_operation action='create_project' (perspective='producer', project_industry=<best match>)",
|
|
448
471
|
" 2. Create on-chain objects via onchain_operations with env.project='<prefix>' (auto-tags + auto-associates to SQLite project)",
|
|
@@ -452,11 +475,11 @@ const WOWOK_TOOL_DESCRIPTION = [
|
|
|
452
475
|
" 6. Report results, fix critical findings, then publish Service",
|
|
453
476
|
"",
|
|
454
477
|
"CASE 2 — SINGLE OBJECT CREATION (user wants one specific object):",
|
|
455
|
-
" Examples: '
|
|
478
|
+
" Examples: 'create a Permission', 'add a Contact', 'build a Guard'",
|
|
456
479
|
" → Do NOT auto-create a project. If the user has an existing project, create with env.project='<prefix>' to auto-associate.",
|
|
457
480
|
" → If no existing project, after creation, REMIND the user:",
|
|
458
|
-
" '
|
|
459
|
-
"
|
|
481
|
+
" 'This object has been created. Consider adding it to a project for management: project_operation action=\"add_object\"",
|
|
482
|
+
" If no project exists yet, use action=\"create_project\" to create one. Existing projects: [list projects if any]'",
|
|
460
483
|
" → If the user then says 'yes, create a project' or 'add to project X', proceed accordingly.",
|
|
461
484
|
"",
|
|
462
485
|
"CASE 3 — CONSUMER FLOW (user wants to buy/evaluate a service):",
|
|
@@ -478,12 +501,215 @@ const WOWOK_TOOL_DESCRIPTION = [
|
|
|
478
501
|
" general → fallback for unclear industry",
|
|
479
502
|
"═══════════════════════════════════════════════════════════════",
|
|
480
503
|
].join("\n");
|
|
481
|
-
function formatZodErrors(error) {
|
|
504
|
+
function formatZodErrors(error, input) {
|
|
505
|
+
return error.issues.map(issue => {
|
|
506
|
+
const path = issue.path.length > 0
|
|
507
|
+
? issue.path.map(p => typeof p === "number" ? `[${p}]` : p).join(".").replace(".[", "[")
|
|
508
|
+
: "(root)";
|
|
509
|
+
const code = issue.code;
|
|
510
|
+
const message = issue.message;
|
|
511
|
+
let extras = "";
|
|
512
|
+
const issueAny = issue;
|
|
513
|
+
if (code === "invalid_type") {
|
|
514
|
+
const expected = issueAny.expected;
|
|
515
|
+
const received = issueAny.received;
|
|
516
|
+
if (typeof expected === "string" && typeof received === "string") {
|
|
517
|
+
extras = ` (expected: ${expected}; received: ${received})`;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
else if (code === "invalid_literal" || code === "invalid_enum_value") {
|
|
521
|
+
const expected = issueAny.expected;
|
|
522
|
+
if (expected !== undefined) {
|
|
523
|
+
const expStr = typeof expected === "string" ? expected : JSON.stringify(expected);
|
|
524
|
+
extras = ` (expected: ${expStr.slice(0, 60)})`;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
else if (code === "too_big" || code === "too_small") {
|
|
528
|
+
const maximum = issueAny.maximum ?? issueAny.minimum;
|
|
529
|
+
const origin = issueAny.origin;
|
|
530
|
+
if (maximum !== undefined && origin !== undefined) {
|
|
531
|
+
extras = ` (${origin}: ${maximum})`;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const receivedVal = extractValueAtPath(input, issue.path);
|
|
535
|
+
if (receivedVal !== undefined) {
|
|
536
|
+
const valStr = typeof receivedVal === "string"
|
|
537
|
+
? `"${receivedVal.slice(0, 60)}"`
|
|
538
|
+
: typeof receivedVal === "object"
|
|
539
|
+
? JSON.stringify(receivedVal).slice(0, 60)
|
|
540
|
+
: String(receivedVal);
|
|
541
|
+
if (!extras.includes("received:")) {
|
|
542
|
+
extras += ` (received value: ${valStr})`;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return `${path} [${code}]: ${message}${extras}`;
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
function generateSuggestion(code, issue, receivedValue) {
|
|
549
|
+
const issueAny = issue;
|
|
550
|
+
switch (code) {
|
|
551
|
+
case "invalid_type": {
|
|
552
|
+
const expected = issueAny.expected;
|
|
553
|
+
const received = issueAny.received;
|
|
554
|
+
if (expected === "number" && typeof receivedValue === "string") {
|
|
555
|
+
return `Convert to number: ${Number(receivedValue)}`;
|
|
556
|
+
}
|
|
557
|
+
if (expected === "string") {
|
|
558
|
+
return `Wrap in quotes or call String(...)`;
|
|
559
|
+
}
|
|
560
|
+
if (expected === "array") {
|
|
561
|
+
return `Wrap in array: [${JSON.stringify(receivedValue)}]`;
|
|
562
|
+
}
|
|
563
|
+
if (expected === "object") {
|
|
564
|
+
return `Provide an object, not a primitive`;
|
|
565
|
+
}
|
|
566
|
+
return `Convert value to ${expected ?? "the expected type"}`;
|
|
567
|
+
}
|
|
568
|
+
case "invalid_enum_value": {
|
|
569
|
+
const options = issueAny.options;
|
|
570
|
+
const optionsStr = Array.isArray(options)
|
|
571
|
+
? options.map((v) => JSON.stringify(v)).join(" | ")
|
|
572
|
+
: String(options);
|
|
573
|
+
return `Use one of: ${optionsStr}`;
|
|
574
|
+
}
|
|
575
|
+
case "invalid_literal": {
|
|
576
|
+
const expected = issueAny.expected;
|
|
577
|
+
return `Use the exact value: ${JSON.stringify(expected)}`;
|
|
578
|
+
}
|
|
579
|
+
case "too_small": {
|
|
580
|
+
const minimum = issueAny.minimum;
|
|
581
|
+
const type = issueAny.type;
|
|
582
|
+
if (type === "array") {
|
|
583
|
+
return `Add at least ${minimum} element(s) to the array`;
|
|
584
|
+
}
|
|
585
|
+
if (type === "string") {
|
|
586
|
+
return `String must be at least ${minimum} character(s) long`;
|
|
587
|
+
}
|
|
588
|
+
if (type === "number") {
|
|
589
|
+
return `Use a value >= ${minimum}`;
|
|
590
|
+
}
|
|
591
|
+
return `Value must be >= ${minimum}`;
|
|
592
|
+
}
|
|
593
|
+
case "too_big": {
|
|
594
|
+
const maximum = issueAny.maximum;
|
|
595
|
+
const type = issueAny.type;
|
|
596
|
+
if (type === "array") {
|
|
597
|
+
return `Reduce array to at most ${maximum} element(s)`;
|
|
598
|
+
}
|
|
599
|
+
if (type === "string") {
|
|
600
|
+
return `Shorten string to at most ${maximum} character(s)`;
|
|
601
|
+
}
|
|
602
|
+
if (type === "number") {
|
|
603
|
+
return `Use a value <= ${maximum}`;
|
|
604
|
+
}
|
|
605
|
+
return `Value must be <= ${maximum}`;
|
|
606
|
+
}
|
|
607
|
+
case "unrecognized_keys": {
|
|
608
|
+
const keys = issueAny.keys;
|
|
609
|
+
return `Remove unknown field(s): ${(keys ?? []).join(", ")}. Check the schema for valid field names.`;
|
|
610
|
+
}
|
|
611
|
+
case "invalid_union": {
|
|
612
|
+
return `Value does not match any of the union variants. Check the schema for valid shapes.`;
|
|
613
|
+
}
|
|
614
|
+
case "invalid_string": {
|
|
615
|
+
const validation = issueAny.validation;
|
|
616
|
+
if (validation === "url")
|
|
617
|
+
return `Provide a valid URL string`;
|
|
618
|
+
if (validation === "email")
|
|
619
|
+
return `Provide a valid email string`;
|
|
620
|
+
if (validation === "uuid")
|
|
621
|
+
return `Provide a valid UUID string`;
|
|
622
|
+
if (validation === "regex")
|
|
623
|
+
return `String does not match the required pattern`;
|
|
624
|
+
return `Provide a valid string matching the validation: ${validation ?? "unknown"}`;
|
|
625
|
+
}
|
|
626
|
+
case "invalid_date": {
|
|
627
|
+
return `Provide a valid Date object or ISO date string`;
|
|
628
|
+
}
|
|
629
|
+
case "not_finite": {
|
|
630
|
+
return `Use a finite number (not Infinity or NaN)`;
|
|
631
|
+
}
|
|
632
|
+
case "invalid_arguments": {
|
|
633
|
+
return `Arguments do not match the expected schema`;
|
|
634
|
+
}
|
|
635
|
+
case "invalid_return_type": {
|
|
636
|
+
return `Return type does not match the expected schema`;
|
|
637
|
+
}
|
|
638
|
+
case "custom": {
|
|
639
|
+
return `Custom validation failed — see the field's description in the schema`;
|
|
640
|
+
}
|
|
641
|
+
default: {
|
|
642
|
+
return `Fix the value at '${issue.path.join(".")}' based on the schema`;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
function formatZodErrorsStructured(error, input) {
|
|
482
647
|
return error.issues.map(issue => {
|
|
483
|
-
const path = issue.path.length > 0
|
|
484
|
-
|
|
648
|
+
const path = issue.path.length > 0
|
|
649
|
+
? issue.path.map(p => typeof p === "number" ? `[${p}]` : p).join(".").replace(".[", "[")
|
|
650
|
+
: "(root)";
|
|
651
|
+
const code = issue.code;
|
|
652
|
+
const message = issue.message;
|
|
653
|
+
const issueAny = issue;
|
|
654
|
+
let expected;
|
|
655
|
+
if (code === "invalid_type") {
|
|
656
|
+
const exp = issueAny.expected;
|
|
657
|
+
const rec = issueAny.received;
|
|
658
|
+
if (typeof exp === "string" && typeof rec === "string") {
|
|
659
|
+
expected = exp;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
else if (code === "invalid_literal") {
|
|
663
|
+
const exp = issueAny.expected;
|
|
664
|
+
if (exp !== undefined) {
|
|
665
|
+
expected = typeof exp === "string" ? exp : JSON.stringify(exp);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
else if (code === "invalid_enum_value") {
|
|
669
|
+
const options = issueAny.options;
|
|
670
|
+
if (Array.isArray(options)) {
|
|
671
|
+
expected = options.map((v) => JSON.stringify(v)).join(" | ");
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
else if (code === "too_big" || code === "too_small") {
|
|
675
|
+
const threshold = issueAny.maximum ?? issueAny.minimum;
|
|
676
|
+
if (threshold !== undefined) {
|
|
677
|
+
expected = String(threshold);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
const receivedVal = extractValueAtPath(input, issue.path);
|
|
681
|
+
const suggestion = generateSuggestion(code, issue, receivedVal);
|
|
682
|
+
return {
|
|
683
|
+
path,
|
|
684
|
+
code,
|
|
685
|
+
message,
|
|
686
|
+
expected,
|
|
687
|
+
received_value: receivedVal,
|
|
688
|
+
suggestion,
|
|
689
|
+
};
|
|
485
690
|
});
|
|
486
691
|
}
|
|
692
|
+
function extractValueAtPath(input, path) {
|
|
693
|
+
if (input === undefined || input === null || path.length === 0) {
|
|
694
|
+
return undefined;
|
|
695
|
+
}
|
|
696
|
+
let current = input;
|
|
697
|
+
for (const key of path) {
|
|
698
|
+
if (current === undefined || current === null)
|
|
699
|
+
return undefined;
|
|
700
|
+
if (typeof key === "number") {
|
|
701
|
+
if (!Array.isArray(current))
|
|
702
|
+
return undefined;
|
|
703
|
+
current = current[key];
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
if (typeof current !== "object")
|
|
707
|
+
return undefined;
|
|
708
|
+
current = current[key];
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return current;
|
|
712
|
+
}
|
|
487
713
|
function checkUnknownFields(schema, input) {
|
|
488
714
|
let innerSchema = schema;
|
|
489
715
|
while (true) {
|
|
@@ -518,6 +744,109 @@ function isSchemaValidationError(message) {
|
|
|
518
744
|
message.includes("Invalid input") ||
|
|
519
745
|
message.includes("Required"));
|
|
520
746
|
}
|
|
747
|
+
function buildSchemaPreview(schema, toolName, data) {
|
|
748
|
+
try {
|
|
749
|
+
const lines = [`Schema preview for ${toolName}:`];
|
|
750
|
+
let topProps;
|
|
751
|
+
let topRequired = [];
|
|
752
|
+
let topDescription = "";
|
|
753
|
+
if (schema.properties && typeof schema.properties === "object") {
|
|
754
|
+
topProps = schema.properties;
|
|
755
|
+
topRequired = Array.isArray(schema.required) ? schema.required : [];
|
|
756
|
+
topDescription = typeof schema.description === "string" ? schema.description : "";
|
|
757
|
+
}
|
|
758
|
+
else if (Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf)) {
|
|
759
|
+
const variants = (schema.oneOf ?? schema.anyOf);
|
|
760
|
+
for (const v of variants) {
|
|
761
|
+
if (v && typeof v === "object") {
|
|
762
|
+
const vo = v;
|
|
763
|
+
if (vo.properties && typeof vo.properties === "object") {
|
|
764
|
+
topProps = vo.properties;
|
|
765
|
+
topRequired = Array.isArray(vo.required) ? vo.required : [];
|
|
766
|
+
topDescription = typeof vo.description === "string" ? vo.description : "";
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (!topProps) {
|
|
772
|
+
lines.push(` (discriminated union with ${variants.length} variants — see structuredContent for full schema)`);
|
|
773
|
+
return lines.join("\n");
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (topDescription && topDescription.length > 0 && topDescription.length < 200) {
|
|
777
|
+
lines.push(` ${topDescription}`);
|
|
778
|
+
}
|
|
779
|
+
if (!topProps) {
|
|
780
|
+
lines.push(" (no properties available — see structuredContent for full schema)");
|
|
781
|
+
return lines.join("\n");
|
|
782
|
+
}
|
|
783
|
+
const requiredSet = new Set(topRequired);
|
|
784
|
+
const requiredList = topRequired.length > 0 ? topRequired.join(", ") : "(none)";
|
|
785
|
+
const optionalList = Object.keys(topProps).filter(k => !requiredSet.has(k)).join(", ");
|
|
786
|
+
lines.push(`Required: ${requiredList}`);
|
|
787
|
+
if (optionalList) {
|
|
788
|
+
lines.push(`Optional: ${optionalList}`);
|
|
789
|
+
}
|
|
790
|
+
lines.push("Fields:");
|
|
791
|
+
for (const [fieldName, fieldSchema] of Object.entries(topProps)) {
|
|
792
|
+
if (fieldSchema && typeof fieldSchema === "object") {
|
|
793
|
+
const f = fieldSchema;
|
|
794
|
+
const type = describeSchemaType(f);
|
|
795
|
+
const required = requiredSet.has(fieldName) ? "required" : "optional";
|
|
796
|
+
let desc = typeof f.description === "string" ? f.description : "";
|
|
797
|
+
if (desc.length > 120)
|
|
798
|
+
desc = desc.slice(0, 117) + "...";
|
|
799
|
+
let subFields = "";
|
|
800
|
+
if (f.properties && typeof f.properties === "object") {
|
|
801
|
+
const subProps = Object.keys(f.properties);
|
|
802
|
+
if (subProps.length > 0) {
|
|
803
|
+
subFields = ` { ${subProps.slice(0, 8).join(", ")}${subProps.length > 8 ? ", ..." : ""} }`;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (f.items && typeof f.items === "object") {
|
|
807
|
+
const items = f.items;
|
|
808
|
+
const itemType = describeSchemaType(items);
|
|
809
|
+
subFields = ` (array of ${itemType})`;
|
|
810
|
+
}
|
|
811
|
+
if (Array.isArray(f.enum)) {
|
|
812
|
+
subFields = ` (enum: ${f.enum.slice(0, 6).map(v => JSON.stringify(v)).join(", ")}${f.enum.length > 6 ? ", ..." : ""})`;
|
|
813
|
+
}
|
|
814
|
+
lines.push(` - ${fieldName} (${type}, ${required})${subFields}${desc ? ` — ${desc}` : ""}`);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (toolName === "onchain_operations" && typeof data === "object" && data !== null) {
|
|
818
|
+
const opType = data.operation_type;
|
|
819
|
+
if (typeof opType === "string") {
|
|
820
|
+
lines.push(``);
|
|
821
|
+
lines.push(`operation_type-specific schema: onchain_operations_${opType}`);
|
|
822
|
+
lines.push(`(Use schema_query with action='get' and name='onchain_operations_${opType}' for the full sub-schema.)`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return lines.join("\n");
|
|
826
|
+
}
|
|
827
|
+
catch {
|
|
828
|
+
return `Schema preview for ${toolName}: (unable to build preview — see structuredContent for full schema)`;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
function describeSchemaType(schema) {
|
|
832
|
+
if (typeof schema.type === "string")
|
|
833
|
+
return schema.type;
|
|
834
|
+
if (Array.isArray(schema.type))
|
|
835
|
+
return schema.type.join("|");
|
|
836
|
+
if (schema.$ref)
|
|
837
|
+
return "$ref";
|
|
838
|
+
if (Array.isArray(schema.oneOf))
|
|
839
|
+
return "oneOf";
|
|
840
|
+
if (Array.isArray(schema.anyOf))
|
|
841
|
+
return "anyOf";
|
|
842
|
+
if (Array.isArray(schema.allOf))
|
|
843
|
+
return "allOf";
|
|
844
|
+
if (schema.enum)
|
|
845
|
+
return "enum";
|
|
846
|
+
if (schema.const)
|
|
847
|
+
return `const(${JSON.stringify(schema.const)})`;
|
|
848
|
+
return "object";
|
|
849
|
+
}
|
|
521
850
|
export async function dispatchToolCall(name, args, options) {
|
|
522
851
|
if (name === "wowok") {
|
|
523
852
|
return handleWowok(args);
|
|
@@ -647,22 +976,52 @@ async function handleWowok(args) {
|
|
|
647
976
|
if (!validationResult.success || unknownFields.length > 0) {
|
|
648
977
|
const allErrors = [];
|
|
649
978
|
if (!validationResult.success) {
|
|
650
|
-
allErrors.push(...formatZodErrors(validationResult.error));
|
|
979
|
+
allErrors.push(...formatZodErrors(validationResult.error, normalizedData));
|
|
651
980
|
}
|
|
652
981
|
if (unknownFields.length > 0) {
|
|
653
982
|
allErrors.push(`Unknown field(s): ${unknownFields.join(", ")}`);
|
|
654
983
|
}
|
|
984
|
+
const structuredErrors = [];
|
|
985
|
+
if (!validationResult.success) {
|
|
986
|
+
structuredErrors.push(...formatZodErrorsStructured(validationResult.error, normalizedData));
|
|
987
|
+
}
|
|
988
|
+
if (unknownFields.length > 0) {
|
|
989
|
+
for (const f of unknownFields) {
|
|
990
|
+
structuredErrors.push({
|
|
991
|
+
path: f,
|
|
992
|
+
code: "unrecognized_keys",
|
|
993
|
+
message: `Unknown field '${f}' is not allowed`,
|
|
994
|
+
suggestion: `Remove field '${f}' or check the schema for valid field names`,
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
}
|
|
655
998
|
const fullSchema = loadPreGeneratedSchema(normalizedToolName) ?? zodToJsonSchemaSafe(entry.config.inputSchema, normalizedToolName);
|
|
656
999
|
const relevantSchema = extractRelevantSchema(fullSchema, normalizedToolName, normalizedData);
|
|
1000
|
+
const firstSuggestion = structuredErrors[0]?.suggestion
|
|
1001
|
+
? ` FIRST ERROR SUGGESTION: ${structuredErrors[0].suggestion}`
|
|
1002
|
+
: '';
|
|
1003
|
+
const errorPreview = allErrors.slice(0, 5).map((e, i) => ` ${i + 1}. ${e}`).join("\n");
|
|
1004
|
+
const schemaPreview = buildSchemaPreview(relevantSchema, normalizedToolName, normalizedData);
|
|
1005
|
+
const textContent = [
|
|
1006
|
+
`Schema mismatch for ${normalizedToolName}. ${allErrors.length} error(s).${firstSuggestion}`,
|
|
1007
|
+
errorPreview,
|
|
1008
|
+
"",
|
|
1009
|
+
schemaPreview,
|
|
1010
|
+
"",
|
|
1011
|
+
"Fix the parameters based on the errors above and the schema summary, then retry.",
|
|
1012
|
+
`Full JSON Schema is in the structuredContent.schema.input field (cache it for future ${normalizedToolName} calls).`,
|
|
1013
|
+
`Structured errors with fix suggestions are in structuredContent.result.structured_errors (ARCH-02).`,
|
|
1014
|
+
].filter(Boolean).join("\n");
|
|
657
1015
|
return {
|
|
658
1016
|
content: [{
|
|
659
1017
|
type: "text",
|
|
660
|
-
text:
|
|
1018
|
+
text: textContent,
|
|
661
1019
|
}],
|
|
662
1020
|
structuredContent: {
|
|
663
1021
|
result: {
|
|
664
1022
|
status: "schema_mismatch",
|
|
665
1023
|
errors: allErrors,
|
|
1024
|
+
structured_errors: structuredErrors,
|
|
666
1025
|
hint: `Fix your parameters based on the schema below and retry. CACHE THIS SCHEMA for future ${normalizedToolName} calls — you don't need to query it again.`,
|
|
667
1026
|
},
|
|
668
1027
|
schema: {
|
|
@@ -706,15 +1065,31 @@ async function handleWowok(args) {
|
|
|
706
1065
|
if (isSchemaValidationError(errorMessage)) {
|
|
707
1066
|
const fullSchema = loadPreGeneratedSchema(normalizedToolName) ?? zodToJsonSchemaSafe(entry.config.inputSchema, normalizedToolName);
|
|
708
1067
|
const relevantSchema = extractRelevantSchema(fullSchema, normalizedToolName, normalizedData);
|
|
1068
|
+
const schemaPreview = buildSchemaPreview(relevantSchema, normalizedToolName, normalizedData);
|
|
1069
|
+
const structuredErrors = [{
|
|
1070
|
+
path: "(runtime)",
|
|
1071
|
+
code: "schema_validation_error",
|
|
1072
|
+
message: errorMessage,
|
|
1073
|
+
suggestion: "Check the error message and the schema below for the correct field format",
|
|
1074
|
+
}];
|
|
1075
|
+
const textContent = [
|
|
1076
|
+
`Schema mismatch for ${normalizedToolName}: ${errorMessage}`,
|
|
1077
|
+
"",
|
|
1078
|
+
schemaPreview,
|
|
1079
|
+
"",
|
|
1080
|
+
"Fix the parameters and retry. Full JSON Schema is in structuredContent.schema.input.",
|
|
1081
|
+
"Structured errors with fix suggestions are in structuredContent.result.structured_errors (ARCH-02).",
|
|
1082
|
+
].join("\n");
|
|
709
1083
|
return {
|
|
710
1084
|
content: [{
|
|
711
1085
|
type: "text",
|
|
712
|
-
text:
|
|
1086
|
+
text: textContent,
|
|
713
1087
|
}],
|
|
714
1088
|
structuredContent: {
|
|
715
1089
|
result: {
|
|
716
1090
|
status: "schema_mismatch",
|
|
717
1091
|
errors: [errorMessage],
|
|
1092
|
+
structured_errors: structuredErrors,
|
|
718
1093
|
hint: `Fix your parameters based on the schema below and retry. CACHE THIS SCHEMA for future ${normalizedToolName} calls.`,
|
|
719
1094
|
},
|
|
720
1095
|
schema: {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface RetryConfig {
|
|
2
|
+
maxRetries: number;
|
|
3
|
+
intervalMs: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const DEFAULT_FAUCET_RETRY_CONFIG: RetryConfig;
|
|
6
|
+
export declare function loadFaucetRetryConfig(): RetryConfig;
|
|
7
|
+
export declare function isFaucetRateLimitError(error: unknown): boolean;
|
|
8
|
+
export declare function withFaucetRetry<T, R>(fn: (input: T) => Promise<R>, config?: RetryConfig): (input: T) => Promise<R>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const DEFAULT_FAUCET_RETRY_CONFIG = {
|
|
2
|
+
maxRetries: 5,
|
|
3
|
+
intervalMs: 3000,
|
|
4
|
+
};
|
|
5
|
+
export function loadFaucetRetryConfig() {
|
|
6
|
+
const maxRetries = Number(process.env.WOWOK_FAUCET_RETRY_COUNT);
|
|
7
|
+
const intervalMs = Number(process.env.WOWOK_FAUCET_RETRY_INTERVAL_MS);
|
|
8
|
+
return {
|
|
9
|
+
maxRetries: Number.isFinite(maxRetries) && maxRetries > 0
|
|
10
|
+
? Math.floor(maxRetries)
|
|
11
|
+
: DEFAULT_FAUCET_RETRY_CONFIG.maxRetries,
|
|
12
|
+
intervalMs: Number.isFinite(intervalMs) && intervalMs > 0
|
|
13
|
+
? Math.floor(intervalMs)
|
|
14
|
+
: DEFAULT_FAUCET_RETRY_CONFIG.intervalMs,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function isFaucetRateLimitError(error) {
|
|
18
|
+
if (!error)
|
|
19
|
+
return false;
|
|
20
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
21
|
+
const lower = msg.toLowerCase();
|
|
22
|
+
if (lower.includes("429"))
|
|
23
|
+
return true;
|
|
24
|
+
if (lower.includes("rate limit"))
|
|
25
|
+
return true;
|
|
26
|
+
if (lower.includes("rate-limit"))
|
|
27
|
+
return true;
|
|
28
|
+
if (lower.includes("too many requests"))
|
|
29
|
+
return true;
|
|
30
|
+
if (lower.includes("try again in"))
|
|
31
|
+
return true;
|
|
32
|
+
if (lower.includes("throttle"))
|
|
33
|
+
return true;
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function isFaucetOperation(input) {
|
|
37
|
+
if (typeof input !== "object" || input === null)
|
|
38
|
+
return false;
|
|
39
|
+
const obj = input;
|
|
40
|
+
return obj.faucet !== undefined && obj.faucet !== null;
|
|
41
|
+
}
|
|
42
|
+
export function withFaucetRetry(fn, config = loadFaucetRetryConfig()) {
|
|
43
|
+
return async (input) => {
|
|
44
|
+
if (!isFaucetOperation(input)) {
|
|
45
|
+
return fn(input);
|
|
46
|
+
}
|
|
47
|
+
let lastError;
|
|
48
|
+
for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await fn(input);
|
|
51
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
52
|
+
const obj = result;
|
|
53
|
+
if (obj.faucet_retry_count === undefined && attempt > 1) {
|
|
54
|
+
obj.faucet_retry_count = attempt;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
lastError = error;
|
|
61
|
+
if (!isFaucetRateLimitError(error)) {
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
if (attempt === config.maxRetries) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, config.intervalMs));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const lastMsg = lastError instanceof Error ? lastError.message : String(lastError);
|
|
71
|
+
const err = new Error(`Faucet request failed after ${config.maxRetries} attempts ` +
|
|
72
|
+
`(interval ${config.intervalMs}ms). Last error: ${lastMsg}. ` +
|
|
73
|
+
`The faucet endpoint is currently rate-limiting this account. ` +
|
|
74
|
+
`Suggestions:\n` +
|
|
75
|
+
` 1. Wait a few minutes and try again.\n` +
|
|
76
|
+
` 2. Use a different faucet network if available.\n` +
|
|
77
|
+
` 3. Override retry config via env vars: ` +
|
|
78
|
+
`WOWOK_FAUCET_RETRY_COUNT (default 5), ` +
|
|
79
|
+
`WOWOK_FAUCET_RETRY_INTERVAL_MS (default 3000).`);
|
|
80
|
+
if (lastError instanceof Error && lastError.code) {
|
|
81
|
+
err.code = lastError.code;
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type WipPathType = "local_unix" | "local_windows" | "local_relative" | "http_url" | "ipfs" | "data_url" | "unknown";
|
|
2
|
+
export interface WipPathClassification {
|
|
3
|
+
type: WipPathType;
|
|
4
|
+
is_local: boolean;
|
|
5
|
+
is_network: boolean;
|
|
6
|
+
description: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function classifyWipPath(path: string): WipPathClassification;
|
|
9
|
+
export interface WipDeployOption {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
difficulty: "easy" | "medium" | "hard";
|
|
13
|
+
free: boolean;
|
|
14
|
+
result_url_pattern: string;
|
|
15
|
+
steps: string[];
|
|
16
|
+
notes?: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function getDeployOptions(localFilePath: string): WipDeployOption[];
|
|
19
|
+
export interface WipDeploySuggestion {
|
|
20
|
+
path: string;
|
|
21
|
+
classification: WipPathClassification;
|
|
22
|
+
needs_deployment: boolean;
|
|
23
|
+
reason: string;
|
|
24
|
+
options: WipDeployOption[];
|
|
25
|
+
remind_update_hash: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function analyzeWipDeployment(path: string): WipDeploySuggestion;
|
|
28
|
+
export declare function formatDeployHints(suggestion: WipDeploySuggestion): string;
|