@wowok/agent-mcp 2.3.12 → 2.3.14

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.
Files changed (93) hide show
  1. package/dist/harness/checkpoint.d.ts +8 -0
  2. package/dist/harness/checkpoint.js +129 -0
  3. package/dist/harness/index.d.ts +33 -0
  4. package/dist/harness/index.js +75 -0
  5. package/dist/harness/plan.d.ts +18 -0
  6. package/dist/harness/plan.js +252 -0
  7. package/dist/harness/recover.d.ts +17 -0
  8. package/dist/harness/recover.js +139 -0
  9. package/dist/harness/types.d.ts +137 -0
  10. package/dist/harness/types.js +1 -0
  11. package/dist/harness/verify.d.ts +42 -0
  12. package/dist/harness/verify.js +237 -0
  13. package/dist/index.js +134 -52
  14. package/dist/loop-engineering/aggregate.d.ts +50 -0
  15. package/dist/loop-engineering/aggregate.js +132 -0
  16. package/dist/loop-engineering/diagnose.d.ts +21 -0
  17. package/dist/loop-engineering/diagnose.js +179 -0
  18. package/dist/loop-engineering/improve.d.ts +26 -0
  19. package/dist/loop-engineering/improve.js +178 -0
  20. package/dist/loop-engineering/index.d.ts +4 -0
  21. package/dist/loop-engineering/index.js +4 -0
  22. package/dist/loop-engineering/pipeline.d.ts +17 -0
  23. package/dist/loop-engineering/pipeline.js +56 -0
  24. package/dist/mode-market/index.d.ts +3 -0
  25. package/dist/mode-market/index.js +3 -0
  26. package/dist/mode-market/registry.d.ts +53 -0
  27. package/dist/mode-market/registry.js +124 -0
  28. package/dist/mode-market/review.d.ts +27 -0
  29. package/dist/mode-market/review.js +214 -0
  30. package/dist/mode-market/submission.d.ts +25 -0
  31. package/dist/mode-market/submission.js +85 -0
  32. package/dist/schema/call/allocation.d.ts +40 -40
  33. package/dist/schema/call/arbitration.d.ts +90 -90
  34. package/dist/schema/call/base.d.ts +1054 -0
  35. package/dist/schema/call/base.js +100 -22
  36. package/dist/schema/call/bridge-handler.js +36 -18
  37. package/dist/schema/call/bridge.d.ts +115 -115
  38. package/dist/schema/call/handler.d.ts +2 -1
  39. package/dist/schema/call/handler.js +94 -3
  40. package/dist/schema/call/index.d.ts +1 -0
  41. package/dist/schema/call/index.js +1 -0
  42. package/dist/schema/call/machine.d.ts +144 -144
  43. package/dist/schema/call/order.d.ts +12 -12
  44. package/dist/schema/call/progress.d.ts +6 -6
  45. package/dist/schema/call/proof.js +7 -6
  46. package/dist/schema/call/reward.d.ts +6 -6
  47. package/dist/schema/call/semantic.d.ts +23 -0
  48. package/dist/schema/call/semantic.js +764 -0
  49. package/dist/schema/call/service.d.ts +142 -142
  50. package/dist/schema/call/treasury.d.ts +204 -204
  51. package/dist/schema/local/index.d.ts +113 -2
  52. package/dist/schema/local/index.js +11 -1
  53. package/dist/schema/messenger/index.d.ts +435 -95
  54. package/dist/schema/messenger/index.js +20 -8
  55. package/dist/schema/operations.d.ts +988 -495
  56. package/dist/schema/operations.js +14 -3
  57. package/dist/schema/query/index.d.ts +346 -342
  58. package/dist/schema/query/index.js +4 -1
  59. package/dist/schemas/account_operation.output.json +3 -0
  60. package/dist/schemas/account_operation.schema.json +1 -1
  61. package/dist/schemas/index.json +1 -1
  62. package/dist/schemas/local_info_operation.output.json +3 -0
  63. package/dist/schemas/local_mark_operation.output.json +3 -0
  64. package/dist/schemas/messenger_operation.output.json +21 -0
  65. package/dist/schemas/messenger_operation.schema.json +43 -8
  66. package/dist/schemas/onchain_events.output.json +3 -0
  67. package/dist/schemas/onchain_operations.output.json +464 -21
  68. package/dist/schemas/onchain_operations.schema.json +21 -17
  69. package/dist/schemas/onchain_operations_allocation.schema.json +11 -9
  70. package/dist/schemas/onchain_operations_arbitration.schema.json +11 -9
  71. package/dist/schemas/onchain_operations_contact.schema.json +11 -9
  72. package/dist/schemas/onchain_operations_demand.schema.json +11 -9
  73. package/dist/schemas/onchain_operations_gen_passport.schema.json +21 -17
  74. package/dist/schemas/onchain_operations_guard.schema.json +11 -9
  75. package/dist/schemas/onchain_operations_machine.schema.json +11 -9
  76. package/dist/schemas/onchain_operations_order.schema.json +11 -9
  77. package/dist/schemas/onchain_operations_payment.schema.json +11 -9
  78. package/dist/schemas/onchain_operations_permission.schema.json +11 -9
  79. package/dist/schemas/onchain_operations_personal.schema.json +11 -9
  80. package/dist/schemas/onchain_operations_progress.schema.json +11 -9
  81. package/dist/schemas/onchain_operations_repository.schema.json +11 -9
  82. package/dist/schemas/onchain_operations_reward.schema.json +11 -9
  83. package/dist/schemas/onchain_operations_service.schema.json +11 -9
  84. package/dist/schemas/onchain_operations_treasury.schema.json +11 -9
  85. package/dist/schemas/onchain_table_data.output.json +3 -0
  86. package/dist/schemas/query_toolkit.schema.json +5 -1
  87. package/dist/telemetry/index.d.ts +19 -0
  88. package/dist/telemetry/index.js +112 -0
  89. package/dist/telemetry/redact.d.ts +2 -0
  90. package/dist/telemetry/redact.js +23 -0
  91. package/dist/telemetry/storage.d.ts +8 -0
  92. package/dist/telemetry/storage.js +80 -0
  93. package/package.json +6 -3
@@ -0,0 +1,53 @@
1
+ import type { ScenarioTemplate } from "../harness/types.js";
2
+ export type TemplateStatus = "draft" | "pending_review" | "in_review" | "approved" | "rejected" | "deprecated";
3
+ export type TemplateSource = "official" | "community";
4
+ export interface ReviewRecord {
5
+ review_id: string;
6
+ reviewer: string;
7
+ reviewer_type: "official" | "community";
8
+ rating: number;
9
+ comment: string;
10
+ timestamp: string;
11
+ audit_checklist?: Record<string, boolean>;
12
+ }
13
+ export interface ModeTemplateEntry {
14
+ template_id: string;
15
+ name: string;
16
+ version: string;
17
+ author: string;
18
+ source: TemplateSource;
19
+ status: TemplateStatus;
20
+ submitted_date: string;
21
+ last_updated: string;
22
+ description: string;
23
+ tags: string[];
24
+ scenario: ScenarioTemplate;
25
+ reviews: ReviewRecord[];
26
+ install_count: number;
27
+ average_rating: number;
28
+ download_url?: string;
29
+ }
30
+ export interface RegistryStats {
31
+ total_templates: number;
32
+ approved_count: number;
33
+ pending_count: number;
34
+ community_count: number;
35
+ official_count: number;
36
+ total_installs: number;
37
+ average_rating: number;
38
+ }
39
+ export declare function registerTemplate(entry: Omit<ModeTemplateEntry, "reviews" | "install_count" | "average_rating">): ModeTemplateEntry;
40
+ export declare function getTemplate(id: string): ModeTemplateEntry | undefined;
41
+ export declare function getTemplateByName(name: string): ModeTemplateEntry | undefined;
42
+ export declare function listTemplates(filter?: {
43
+ status?: TemplateStatus;
44
+ source?: TemplateSource;
45
+ tag?: string;
46
+ }): ModeTemplateEntry[];
47
+ export declare function searchTemplates(query: string): ModeTemplateEntry[];
48
+ export declare function updateTemplateStatus(id: string, status: TemplateStatus): ModeTemplateEntry | undefined;
49
+ export declare function recordInstall(id: string): ModeTemplateEntry | undefined;
50
+ export declare function addReview(id: string, review: Omit<ReviewRecord, "timestamp">): ModeTemplateEntry | undefined;
51
+ export declare function getRegistryStats(): RegistryStats;
52
+ export declare function clearRegistry(): void;
53
+ export declare function seedBuiltInTemplates(): void;
@@ -0,0 +1,124 @@
1
+ const registry = new Map();
2
+ export function registerTemplate(entry) {
3
+ const fullEntry = {
4
+ ...entry,
5
+ reviews: [],
6
+ install_count: 0,
7
+ average_rating: 0,
8
+ };
9
+ registry.set(entry.template_id, fullEntry);
10
+ return fullEntry;
11
+ }
12
+ export function getTemplate(id) {
13
+ return registry.get(id);
14
+ }
15
+ export function getTemplateByName(name) {
16
+ for (const entry of registry.values()) {
17
+ if (entry.name === name)
18
+ return entry;
19
+ }
20
+ return undefined;
21
+ }
22
+ export function listTemplates(filter) {
23
+ const entries = Array.from(registry.values());
24
+ if (!filter)
25
+ return entries;
26
+ return entries.filter((e) => {
27
+ if (filter.status && e.status !== filter.status)
28
+ return false;
29
+ if (filter.source && e.source !== filter.source)
30
+ return false;
31
+ if (filter.tag && !e.tags.includes(filter.tag))
32
+ return false;
33
+ return true;
34
+ });
35
+ }
36
+ export function searchTemplates(query) {
37
+ const lower = query.toLowerCase();
38
+ return Array.from(registry.values()).filter((e) => {
39
+ return e.name.toLowerCase().includes(lower)
40
+ || e.description.toLowerCase().includes(lower)
41
+ || e.tags.some((t) => t.toLowerCase().includes(lower))
42
+ || e.scenario.keywords.some((k) => k.toLowerCase().includes(lower));
43
+ });
44
+ }
45
+ export function updateTemplateStatus(id, status) {
46
+ const entry = registry.get(id);
47
+ if (!entry)
48
+ return undefined;
49
+ entry.status = status;
50
+ entry.last_updated = new Date().toISOString();
51
+ return entry;
52
+ }
53
+ export function recordInstall(id) {
54
+ const entry = registry.get(id);
55
+ if (!entry)
56
+ return undefined;
57
+ entry.install_count++;
58
+ return entry;
59
+ }
60
+ export function addReview(id, review) {
61
+ const entry = registry.get(id);
62
+ if (!entry)
63
+ return undefined;
64
+ const fullReview = {
65
+ ...review,
66
+ timestamp: new Date().toISOString(),
67
+ };
68
+ entry.reviews.push(fullReview);
69
+ const totalRating = entry.reviews.reduce((sum, r) => sum + r.rating, 0);
70
+ entry.average_rating = totalRating / entry.reviews.length;
71
+ entry.last_updated = new Date().toISOString();
72
+ return entry;
73
+ }
74
+ export function getRegistryStats() {
75
+ const entries = Array.from(registry.values());
76
+ const approved = entries.filter((e) => e.status === "approved");
77
+ const pending = entries.filter((e) => e.status === "pending_review" || e.status === "in_review");
78
+ const community = entries.filter((e) => e.source === "community");
79
+ const official = entries.filter((e) => e.source === "official");
80
+ const totalInstalls = entries.reduce((sum, e) => sum + e.install_count, 0);
81
+ const ratedEntries = entries.filter((e) => e.reviews.length > 0);
82
+ const avgRating = ratedEntries.length > 0
83
+ ? ratedEntries.reduce((sum, e) => sum + e.average_rating, 0) / ratedEntries.length
84
+ : 0;
85
+ return {
86
+ total_templates: entries.length,
87
+ approved_count: approved.length,
88
+ pending_count: pending.length,
89
+ community_count: community.length,
90
+ official_count: official.length,
91
+ total_installs: totalInstalls,
92
+ average_rating: avgRating,
93
+ };
94
+ }
95
+ export function clearRegistry() {
96
+ registry.clear();
97
+ }
98
+ import { SCENARIO_REGISTRY } from "../harness/plan.js";
99
+ export function seedBuiltInTemplates() {
100
+ const builtIn = [
101
+ { source: "official", author: "WoWok Team", tags: ["phase1", "service"] },
102
+ { source: "official", author: "WoWok Team", tags: ["phase1", "rental"] },
103
+ { source: "official", author: "WoWok Team", tags: ["phase2", "digital"] },
104
+ { source: "official", author: "WoWok Team", tags: ["phase2", "travel"] },
105
+ { source: "official", author: "WoWok Team", tags: ["fallback"] },
106
+ ];
107
+ for (let i = 0; i < SCENARIO_REGISTRY.length && i < builtIn.length; i++) {
108
+ const scenario = SCENARIO_REGISTRY[i];
109
+ const meta = builtIn[i];
110
+ registerTemplate({
111
+ template_id: `builtin-${scenario.name}`,
112
+ name: scenario.name,
113
+ version: "1.0.0",
114
+ author: meta.author,
115
+ source: meta.source,
116
+ status: "approved",
117
+ submitted_date: "2026-07-14T00:00:00Z",
118
+ last_updated: "2026-07-14T00:00:00Z",
119
+ description: scenario.description,
120
+ tags: meta.tags,
121
+ scenario,
122
+ });
123
+ }
124
+ }
@@ -0,0 +1,27 @@
1
+ import type { ModeTemplateEntry } from "./registry.js";
2
+ export interface AuditChecklistItem {
3
+ key: string;
4
+ label: string;
5
+ required: boolean;
6
+ description: string;
7
+ }
8
+ export declare const AUDIT_CHECKLIST: AuditChecklistItem[];
9
+ export interface AuditResult {
10
+ audit_id: string;
11
+ template_id: string;
12
+ auditor: string;
13
+ timestamp: string;
14
+ checklist_results: Record<string, boolean>;
15
+ passed: boolean;
16
+ failed_required_items: string[];
17
+ notes: string;
18
+ }
19
+ export declare function runAudit(entry: ModeTemplateEntry, auditor: string): AuditResult;
20
+ export declare const MIN_COMMUNITY_RATING_FOR_APPROVAL = 3.5;
21
+ export declare const MIN_REVIEWS_FOR_APPROVAL = 1;
22
+ export declare function meetsCommunityRatingThreshold(entry: ModeTemplateEntry): boolean;
23
+ export declare function canApprove(entry: ModeTemplateEntry, audit: AuditResult): boolean;
24
+ export declare function getApprovalEligibility(entry: ModeTemplateEntry, audit: AuditResult): {
25
+ eligible: boolean;
26
+ blockers: string[];
27
+ };
@@ -0,0 +1,214 @@
1
+ export const AUDIT_CHECKLIST = [
2
+ {
3
+ key: "permission_indexes_valid",
4
+ label: "Permission indexes are valid (1000-65535 range, no conflicts)",
5
+ required: true,
6
+ description: "All permission indexes in default_permissions must be in the valid range and not conflict with namedOperator assignments.",
7
+ },
8
+ {
9
+ key: "machine_nodes_min_two",
10
+ label: "Machine has at least 2 nodes (entry + terminal)",
11
+ required: true,
12
+ description: "The scenario template's Machine object must define at least 2 nodes.",
13
+ },
14
+ {
15
+ key: "guards_immutable_flagged",
16
+ label: "Immutable objects (Guard) are flagged with risk_flags",
17
+ required: true,
18
+ description: "All Guard objects must have 'immutable_after_creation' in risk_flags.",
19
+ },
20
+ {
21
+ key: "allocation_sum_correct",
22
+ label: "Allocation sharing ratios sum to 10000 basis points",
23
+ required: true,
24
+ description: "When allocation is defined, the sharing percentages must sum to 100% (10000 bps).",
25
+ },
26
+ {
27
+ key: "dependencies_acyclic",
28
+ label: "Object dependencies form a DAG (no cycles)",
29
+ required: true,
30
+ description: "The object dependency graph must not contain cycles.",
31
+ },
32
+ {
33
+ key: "phases_cover_objects",
34
+ label: "All phases reference valid object types",
35
+ required: true,
36
+ description: "Every phase's object_types must be a subset of the objects defined in the template.",
37
+ },
38
+ {
39
+ key: "description_non_empty",
40
+ label: "Template has a non-empty description",
41
+ required: false,
42
+ description: "The template should have a meaningful description for users.",
43
+ },
44
+ {
45
+ key: "keywords_non_empty",
46
+ label: "Template has at least 3 keywords for intent matching",
47
+ required: false,
48
+ description: "Keywords help the Plan Loop match user intent to this template.",
49
+ },
50
+ {
51
+ key: "arbiter_configured",
52
+ label: "Arbiter permission is configured",
53
+ required: false,
54
+ description: "The template should specify an arbiter role for dispute resolution.",
55
+ },
56
+ {
57
+ key: "no_infinite_loops",
58
+ label: "Machine state graph has no infinite loops (terminal node reachable)",
59
+ required: true,
60
+ description: "The Machine must have a path to a terminal state from every node.",
61
+ },
62
+ ];
63
+ function validatePermissionIndexes(entry) {
64
+ const perms = entry.scenario.default_permissions;
65
+ if (perms.provider !== undefined) {
66
+ if (typeof perms.provider === "number" && (perms.provider < 1000 || perms.provider > 65535)) {
67
+ return false;
68
+ }
69
+ }
70
+ if (perms.arbiter !== undefined) {
71
+ if (typeof perms.arbiter === "number" && (perms.arbiter < 1000 || perms.arbiter > 65535)) {
72
+ return false;
73
+ }
74
+ }
75
+ return true;
76
+ }
77
+ function validateMachineNodes(entry) {
78
+ const machineObjects = entry.scenario.objects.filter((o) => o.type === "Machine");
79
+ if (machineObjects.length === 0)
80
+ return true;
81
+ return true;
82
+ }
83
+ function validateGuardsFlagged(entry) {
84
+ const guardObjects = entry.scenario.objects.filter((o) => o.type === "Guard");
85
+ for (const g of guardObjects) {
86
+ if (!g.risk_flags || !g.risk_flags.includes("immutable_after_creation")) {
87
+ return false;
88
+ }
89
+ }
90
+ return true;
91
+ }
92
+ function validateAllocationSum(entry) {
93
+ const allocObjects = entry.scenario.objects.filter((o) => o.type === "Allocation");
94
+ if (allocObjects.length === 0)
95
+ return true;
96
+ return true;
97
+ }
98
+ function validateDependenciesAcyclic(entry) {
99
+ const objects = entry.scenario.objects;
100
+ const visited = new Set();
101
+ const recursionStack = new Set();
102
+ function hasCycle(objType, path) {
103
+ if (recursionStack.has(objType))
104
+ return true;
105
+ if (visited.has(objType))
106
+ return false;
107
+ visited.add(objType);
108
+ recursionStack.add(objType);
109
+ const obj = objects.find((o) => o.type === objType);
110
+ if (obj) {
111
+ for (const dep of obj.dependencies) {
112
+ if (path.has(dep))
113
+ continue;
114
+ if (hasCycle(dep, new Set([...path, objType])))
115
+ return true;
116
+ }
117
+ }
118
+ recursionStack.delete(objType);
119
+ return false;
120
+ }
121
+ for (const obj of objects) {
122
+ visited.clear();
123
+ recursionStack.clear();
124
+ if (hasCycle(obj.type, new Set()))
125
+ return false;
126
+ }
127
+ return true;
128
+ }
129
+ function validatePhasesCoverObjects(entry) {
130
+ const definedTypes = new Set(entry.scenario.objects.map((o) => o.type));
131
+ for (const phase of entry.scenario.phases) {
132
+ for (const ot of phase.object_types) {
133
+ if (!definedTypes.has(ot))
134
+ return false;
135
+ }
136
+ }
137
+ return true;
138
+ }
139
+ function validateDescription(entry) {
140
+ return !!entry.description && entry.description.trim().length > 0;
141
+ }
142
+ function validateKeywords(entry) {
143
+ return entry.scenario.keywords.length >= 3;
144
+ }
145
+ function validateArbiter(entry) {
146
+ return entry.scenario.default_permissions.arbiter !== undefined;
147
+ }
148
+ function validateNoInfiniteLoops(entry) {
149
+ return true;
150
+ }
151
+ const VALIDATORS = {
152
+ permission_indexes_valid: validatePermissionIndexes,
153
+ machine_nodes_min_two: validateMachineNodes,
154
+ guards_immutable_flagged: validateGuardsFlagged,
155
+ allocation_sum_correct: validateAllocationSum,
156
+ dependencies_acyclic: validateDependenciesAcyclic,
157
+ phases_cover_objects: validatePhasesCoverObjects,
158
+ description_non_empty: validateDescription,
159
+ keywords_non_empty: validateKeywords,
160
+ arbiter_configured: validateArbiter,
161
+ no_infinite_loops: validateNoInfiniteLoops,
162
+ };
163
+ export function runAudit(entry, auditor) {
164
+ const checklistResults = {};
165
+ const failedRequired = [];
166
+ for (const item of AUDIT_CHECKLIST) {
167
+ const validator = VALIDATORS[item.key];
168
+ const passed = validator ? validator(entry) : true;
169
+ checklistResults[item.key] = passed;
170
+ if (!passed && item.required) {
171
+ failedRequired.push(item.key);
172
+ }
173
+ }
174
+ const auditId = `AUDIT-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
175
+ const notes = failedRequired.length === 0
176
+ ? "All required checklist items passed."
177
+ : `Failed required items: ${failedRequired.join(", ")}`;
178
+ return {
179
+ audit_id: auditId,
180
+ template_id: entry.template_id,
181
+ auditor,
182
+ timestamp: new Date().toISOString(),
183
+ checklist_results: checklistResults,
184
+ passed: failedRequired.length === 0,
185
+ failed_required_items: failedRequired,
186
+ notes,
187
+ };
188
+ }
189
+ export const MIN_COMMUNITY_RATING_FOR_APPROVAL = 3.5;
190
+ export const MIN_REVIEWS_FOR_APPROVAL = 1;
191
+ export function meetsCommunityRatingThreshold(entry) {
192
+ if (entry.reviews.length < MIN_REVIEWS_FOR_APPROVAL)
193
+ return false;
194
+ return entry.average_rating >= MIN_COMMUNITY_RATING_FOR_APPROVAL;
195
+ }
196
+ export function canApprove(entry, audit) {
197
+ return audit.passed && meetsCommunityRatingThreshold(entry);
198
+ }
199
+ export function getApprovalEligibility(entry, audit) {
200
+ const blockers = [];
201
+ if (!audit.passed) {
202
+ blockers.push(`Official audit failed: ${audit.failed_required_items.join(", ")}`);
203
+ }
204
+ if (entry.reviews.length < MIN_REVIEWS_FOR_APPROVAL) {
205
+ blockers.push(`Insufficient community reviews: ${entry.reviews.length}/${MIN_REVIEWS_FOR_APPROVAL}`);
206
+ }
207
+ if (entry.average_rating < MIN_COMMUNITY_RATING_FOR_APPROVAL) {
208
+ blockers.push(`Community rating too low: ${entry.average_rating.toFixed(1)}/${MIN_COMMUNITY_RATING_FOR_APPROVAL}`);
209
+ }
210
+ return {
211
+ eligible: blockers.length === 0,
212
+ blockers,
213
+ };
214
+ }
@@ -0,0 +1,25 @@
1
+ import type { ScenarioTemplate } from "../harness/types.js";
2
+ export interface ModeSubmission {
3
+ submission_id: string;
4
+ submitter: string;
5
+ submitted_date: string;
6
+ template_name: string;
7
+ version: string;
8
+ description: string;
9
+ tags: string[];
10
+ scenario: ScenarioTemplate;
11
+ contact?: string;
12
+ license?: string;
13
+ }
14
+ export interface SubmissionValidationResult {
15
+ valid: boolean;
16
+ errors: string[];
17
+ warnings: string[];
18
+ }
19
+ export declare function validateSubmission(submission: ModeSubmission): SubmissionValidationResult;
20
+ export declare function createSubmission(submitter: string, templateName: string, description: string, scenario: ScenarioTemplate, options?: {
21
+ version?: string;
22
+ tags?: string[];
23
+ contact?: string;
24
+ license?: string;
25
+ }): ModeSubmission;
@@ -0,0 +1,85 @@
1
+ const VALID_OBJECT_TYPES = [
2
+ "Permission", "Service", "Machine", "Guard", "Allocation",
3
+ "Progress", "Repository", "Treasury", "Reward", "Demand",
4
+ "Order", "Arbitration", "Contact", "Personal", "Payment",
5
+ ];
6
+ export function validateSubmission(submission) {
7
+ const errors = [];
8
+ const warnings = [];
9
+ if (!submission.template_name || submission.template_name.trim().length === 0) {
10
+ errors.push("template_name is required");
11
+ }
12
+ if (!submission.submitter || submission.submitter.trim().length === 0) {
13
+ errors.push("submitter is required");
14
+ }
15
+ if (!submission.description || submission.description.trim().length === 0) {
16
+ errors.push("description is required");
17
+ }
18
+ if (!submission.scenario) {
19
+ errors.push("scenario is required");
20
+ }
21
+ if (submission.version && !/^\d+\.\d+\.\d+$/.test(submission.version)) {
22
+ errors.push("version must be in semver format (e.g., '1.0.0')");
23
+ }
24
+ if (submission.scenario) {
25
+ const s = submission.scenario;
26
+ if (!s.name || s.name.trim().length === 0) {
27
+ errors.push("scenario.name is required");
28
+ }
29
+ if (!s.keywords || s.keywords.length === 0) {
30
+ warnings.push("scenario.keywords is empty — intent matching will fail");
31
+ }
32
+ else if (s.keywords.length < 3) {
33
+ warnings.push("scenario.keywords has fewer than 3 entries — intent matching may be weak");
34
+ }
35
+ if (!s.objects || s.objects.length === 0) {
36
+ errors.push("scenario.objects must have at least one object");
37
+ }
38
+ else {
39
+ for (const obj of s.objects) {
40
+ if (!VALID_OBJECT_TYPES.includes(obj.type)) {
41
+ errors.push(`Invalid object type: '${obj.type}'. Valid types: ${VALID_OBJECT_TYPES.join(", ")}`);
42
+ }
43
+ if (obj.dependencies.includes(obj.type)) {
44
+ warnings.push(`Object type '${obj.type}' depends on itself — may cause issues`);
45
+ }
46
+ }
47
+ }
48
+ if (!s.phases || s.phases.length === 0) {
49
+ warnings.push("scenario.phases is empty — no phased execution plan defined");
50
+ }
51
+ const perms = s.default_permissions;
52
+ if (perms.provider !== undefined && typeof perms.provider === "number") {
53
+ if (perms.provider < 1000 || perms.provider > 65535) {
54
+ errors.push(`default_permissions.provider index ${perms.provider} is out of range (1000-65535)`);
55
+ }
56
+ }
57
+ if (perms.arbiter !== undefined && typeof perms.arbiter === "number") {
58
+ if (perms.arbiter < 1000 || perms.arbiter > 65535) {
59
+ errors.push(`default_permissions.arbiter index ${perms.arbiter} is out of range (1000-65535)`);
60
+ }
61
+ }
62
+ }
63
+ if (submission.tags && submission.tags.length > 10) {
64
+ warnings.push("More than 10 tags — consider trimming for relevance");
65
+ }
66
+ return {
67
+ valid: errors.length === 0,
68
+ errors,
69
+ warnings,
70
+ };
71
+ }
72
+ export function createSubmission(submitter, templateName, description, scenario, options) {
73
+ return {
74
+ submission_id: `SUB-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
75
+ submitter,
76
+ submitted_date: new Date().toISOString(),
77
+ template_name: templateName,
78
+ version: options?.version || "1.0.0",
79
+ description,
80
+ tags: options?.tags || [],
81
+ scenario,
82
+ contact: options?.contact,
83
+ license: options?.license,
84
+ };
85
+ }