@walkeros/mcp 4.7.0-next-1790722899482 → 4.7.0
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/index.d.ts +24 -2
- package/dist/index.js +809 -680
- package/dist/index.js.map +1 -1
- package/dist/stdio.js +657 -530
- package/dist/stdio.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -94,13 +94,65 @@ function createHostedRuntime(client) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// src/tools/auth.ts
|
|
97
|
+
import { z as z2 } from "zod";
|
|
98
|
+
import { mcpResult, mcpError as mcpError2 } from "@walkeros/core";
|
|
99
|
+
|
|
100
|
+
// src/tools/narrow.ts
|
|
101
|
+
import { schemas } from "@walkeros/core/dev";
|
|
102
|
+
function isRecord(value) {
|
|
103
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
104
|
+
}
|
|
105
|
+
function stringField(value, key) {
|
|
106
|
+
if (!isRecord(value)) return void 0;
|
|
107
|
+
const field = value[key];
|
|
108
|
+
return typeof field === "string" ? field : void 0;
|
|
109
|
+
}
|
|
110
|
+
function recordField(value, key) {
|
|
111
|
+
if (!isRecord(value)) return void 0;
|
|
112
|
+
const field = value[key];
|
|
113
|
+
return isRecord(field) ? field : void 0;
|
|
114
|
+
}
|
|
115
|
+
function fieldsOf(value) {
|
|
116
|
+
return isRecord(value) ? value : {};
|
|
117
|
+
}
|
|
118
|
+
function isFlowJson(value) {
|
|
119
|
+
return isRecord(value) && isRecord(value.flows);
|
|
120
|
+
}
|
|
121
|
+
function stepExamplesOf(value) {
|
|
122
|
+
if (!isRecord(value)) return void 0;
|
|
123
|
+
const examples = {};
|
|
124
|
+
const skipped = [];
|
|
125
|
+
for (const [name, example] of Object.entries(value)) {
|
|
126
|
+
const parsed = schemas.FlowSchemas.StepExampleSchema.safeParse(example);
|
|
127
|
+
if (parsed.success) examples[name] = parsed.data;
|
|
128
|
+
else skipped.push(name);
|
|
129
|
+
}
|
|
130
|
+
return { examples, skipped };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/tools/parse-input.ts
|
|
97
134
|
import { z } from "zod";
|
|
98
|
-
import {
|
|
135
|
+
import { mcpError } from "@walkeros/core";
|
|
136
|
+
function inputIssuesMessage(error) {
|
|
137
|
+
return error.issues.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`).join("; ");
|
|
138
|
+
}
|
|
139
|
+
function parseToolInput(shape, raw) {
|
|
140
|
+
const parsed = z.object(shape).safeParse(raw ?? {});
|
|
141
|
+
if (!parsed.success) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
error: mcpError(new Error(inputIssuesMessage(parsed.error)))
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return { ok: true, data: parsed.data };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/tools/auth.ts
|
|
99
151
|
var TITLE = "Authentication";
|
|
100
152
|
var DESCRIPTION = "Manage walkerOS authentication. Check login status, log in via the device authorization grant, or log out. No terminal or browser required, the MCP client handles the authorization URL.";
|
|
101
153
|
var inputSchema = {
|
|
102
|
-
action:
|
|
103
|
-
deviceCode:
|
|
154
|
+
action: z2.enum(["status", "login", "logout"]).describe("Authentication action to perform"),
|
|
155
|
+
deviceCode: z2.string().optional().describe(
|
|
104
156
|
"Device code from a previous pending login attempt. Provide to resume polling without requesting a new code."
|
|
105
157
|
)
|
|
106
158
|
};
|
|
@@ -121,7 +173,9 @@ function createAuthToolSpec(client) {
|
|
|
121
173
|
};
|
|
122
174
|
}
|
|
123
175
|
async function authHandlerBody(client, input) {
|
|
124
|
-
const
|
|
176
|
+
const parsed = parseToolInput(inputSchema, input);
|
|
177
|
+
if (!parsed.ok) return parsed.error;
|
|
178
|
+
const { action, deviceCode } = parsed.data;
|
|
125
179
|
try {
|
|
126
180
|
switch (action) {
|
|
127
181
|
case "status": {
|
|
@@ -134,7 +188,7 @@ async function authHandlerBody(client, input) {
|
|
|
134
188
|
const user = await client.whoami();
|
|
135
189
|
return mcpResult({
|
|
136
190
|
authenticated: true,
|
|
137
|
-
...user
|
|
191
|
+
...fieldsOf(user)
|
|
138
192
|
});
|
|
139
193
|
}
|
|
140
194
|
case "login": {
|
|
@@ -162,14 +216,14 @@ async function authHandlerBody(client, input) {
|
|
|
162
216
|
});
|
|
163
217
|
}
|
|
164
218
|
if (poll.status === "denied")
|
|
165
|
-
return
|
|
219
|
+
return mcpError2(new Error("Authorization was denied."));
|
|
166
220
|
if (poll.status === "expired")
|
|
167
|
-
return
|
|
221
|
+
return mcpError2(
|
|
168
222
|
new Error(
|
|
169
223
|
'The one-time code expired. Run auth with action "login" for a new one.'
|
|
170
224
|
)
|
|
171
225
|
);
|
|
172
|
-
return
|
|
226
|
+
return mcpError2(new Error(poll.error));
|
|
173
227
|
}
|
|
174
228
|
const code = await client.requestDeviceCode();
|
|
175
229
|
const loginUrl = code.verificationUriComplete;
|
|
@@ -206,7 +260,7 @@ async function authHandlerBody(client, input) {
|
|
|
206
260
|
);
|
|
207
261
|
}
|
|
208
262
|
} catch (error) {
|
|
209
|
-
return
|
|
263
|
+
return mcpError2(error);
|
|
210
264
|
}
|
|
211
265
|
}
|
|
212
266
|
function registerAuthTool(server, client) {
|
|
@@ -219,15 +273,13 @@ function registerAuthTool(server, client) {
|
|
|
219
273
|
inputSchema: spec.inputSchema,
|
|
220
274
|
annotations: spec.annotations
|
|
221
275
|
},
|
|
222
|
-
|
|
223
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
224
|
-
spec.handler
|
|
276
|
+
(args) => authHandlerBody(client, args)
|
|
225
277
|
);
|
|
226
278
|
}
|
|
227
279
|
|
|
228
280
|
// src/tools/project-manage.ts
|
|
229
|
-
import { z as
|
|
230
|
-
import { mcpResult as mcpResult2, mcpError as
|
|
281
|
+
import { z as z3 } from "zod";
|
|
282
|
+
import { mcpResult as mcpResult2, mcpError as mcpError3 } from "@walkeros/core";
|
|
231
283
|
|
|
232
284
|
// src/types.ts
|
|
233
285
|
function isAuthError(error) {
|
|
@@ -423,21 +475,22 @@ var FRAME_MANAGE_REQUIREMENTS = {
|
|
|
423
475
|
};
|
|
424
476
|
|
|
425
477
|
// src/tools/project-manage.ts
|
|
426
|
-
function wrapProjectName(
|
|
427
|
-
|
|
478
|
+
function wrapProjectName(project) {
|
|
479
|
+
const name = stringField(project, "name");
|
|
480
|
+
return isRecord(project) && name !== void 0 ? { ...project, name: wrapUserData(name) } : project;
|
|
428
481
|
}
|
|
429
482
|
var TITLE2 = "Project Management";
|
|
430
483
|
var DESCRIPTION2 = "Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.";
|
|
431
484
|
var inputSchema2 = {
|
|
432
|
-
action:
|
|
433
|
-
projectId:
|
|
434
|
-
name:
|
|
485
|
+
action: z3.enum(["list", "get", "create", "update", "delete", "set_default"]).describe("Project management action to perform"),
|
|
486
|
+
projectId: z3.string().optional().describe("Required for get, update, delete, set_default."),
|
|
487
|
+
name: z3.string().optional().describe(
|
|
435
488
|
"Required for create and update (update also requires projectId)."
|
|
436
489
|
),
|
|
437
|
-
cursor:
|
|
490
|
+
cursor: z3.string().optional().describe(
|
|
438
491
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
439
492
|
),
|
|
440
|
-
limit:
|
|
493
|
+
limit: z3.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action.")
|
|
441
494
|
};
|
|
442
495
|
var annotations2 = {
|
|
443
496
|
readOnlyHint: false,
|
|
@@ -456,19 +509,22 @@ function createProjectManageToolSpec(client) {
|
|
|
456
509
|
};
|
|
457
510
|
}
|
|
458
511
|
async function projectManageHandlerBody(client, input) {
|
|
459
|
-
const
|
|
512
|
+
const parsed = parseToolInput(inputSchema2, input);
|
|
513
|
+
if (!parsed.ok) return parsed.error;
|
|
514
|
+
const { action, projectId, name, cursor, limit } = parsed.data;
|
|
460
515
|
const validationError = validateActionInput(
|
|
461
516
|
"project_manage",
|
|
462
517
|
action ?? "",
|
|
463
518
|
{ projectId, name },
|
|
464
519
|
PROJECT_MANAGE_REQUIREMENTS
|
|
465
520
|
);
|
|
466
|
-
if (validationError) return
|
|
521
|
+
if (validationError) return mcpError3(new Error(validationError));
|
|
467
522
|
try {
|
|
468
523
|
switch (action) {
|
|
469
524
|
case "list": {
|
|
470
525
|
const projects = await client.listProjects({ cursor, limit });
|
|
471
|
-
const
|
|
526
|
+
const listed = isRecord(projects) ? projects.projects : void 0;
|
|
527
|
+
const items = Array.isArray(projects) ? projects : Array.isArray(listed) ? listed : [];
|
|
472
528
|
if (items.length === 0) {
|
|
473
529
|
return mcpResult2(
|
|
474
530
|
{ projects: [] },
|
|
@@ -480,8 +536,7 @@ async function projectManageHandlerBody(client, input) {
|
|
|
480
536
|
}
|
|
481
537
|
);
|
|
482
538
|
}
|
|
483
|
-
const
|
|
484
|
-
const safe = Array.isArray(projects) ? typedItems.map(wrapProjectName) : { ...projects, projects: typedItems.map(wrapProjectName) };
|
|
539
|
+
const safe = Array.isArray(projects) ? items.map(wrapProjectName) : { ...fieldsOf(projects), projects: items.map(wrapProjectName) };
|
|
485
540
|
return mcpResult2(safe);
|
|
486
541
|
}
|
|
487
542
|
case "get": {
|
|
@@ -524,7 +579,7 @@ async function projectManageHandlerBody(client, input) {
|
|
|
524
579
|
);
|
|
525
580
|
}
|
|
526
581
|
} catch (error) {
|
|
527
|
-
return
|
|
582
|
+
return mcpError3(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
528
583
|
}
|
|
529
584
|
}
|
|
530
585
|
function registerProjectManageTool(server, client) {
|
|
@@ -537,15 +592,13 @@ function registerProjectManageTool(server, client) {
|
|
|
537
592
|
inputSchema: spec.inputSchema,
|
|
538
593
|
annotations: spec.annotations
|
|
539
594
|
},
|
|
540
|
-
|
|
541
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
542
|
-
spec.handler
|
|
595
|
+
(args) => projectManageHandlerBody(client, args)
|
|
543
596
|
);
|
|
544
597
|
}
|
|
545
598
|
|
|
546
599
|
// src/tools/flow-manage.ts
|
|
547
|
-
import { z as
|
|
548
|
-
import { mcpResult as mcpResult3, mcpError as
|
|
600
|
+
import { z as z4 } from "zod";
|
|
601
|
+
import { mcpResult as mcpResult3, mcpError as mcpError4 } from "@walkeros/core";
|
|
549
602
|
|
|
550
603
|
// src/ui-parts.ts
|
|
551
604
|
function flowCanvasResult(payload) {
|
|
@@ -659,19 +712,10 @@ function resolveDefaultProject(client, projectId) {
|
|
|
659
712
|
|
|
660
713
|
// src/tools/flow-manage.ts
|
|
661
714
|
function pickPlatform(content) {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (flow && typeof flow === "object") {
|
|
667
|
-
const config = flow.config;
|
|
668
|
-
if (config && typeof config === "object") {
|
|
669
|
-
const platform = config.platform;
|
|
670
|
-
if (platform === "web" || platform === "server") return platform;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
715
|
+
const flows = recordField(content, "flows");
|
|
716
|
+
for (const flow of Object.values(flows ?? {})) {
|
|
717
|
+
const platform = stringField(recordField(flow, "config"), "platform");
|
|
718
|
+
if (platform === "web" || platform === "server") return platform;
|
|
675
719
|
}
|
|
676
720
|
return "server";
|
|
677
721
|
}
|
|
@@ -680,22 +724,29 @@ function flowPageUrl(client, projectId, flowId) {
|
|
|
680
724
|
return links.flow({ baseUrl: client.appBaseUrl(), projectId, flowId });
|
|
681
725
|
}
|
|
682
726
|
function safeSummary(flow) {
|
|
683
|
-
|
|
727
|
+
const name = stringField(flow, "name");
|
|
728
|
+
return isRecord(flow) && name !== void 0 ? { ...flow, name: wrapUserData(name) } : flow;
|
|
684
729
|
}
|
|
685
730
|
function safeDetail(flow) {
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
731
|
+
const fields = { ...fieldsOf(flow) };
|
|
732
|
+
const name = stringField(fields, "name");
|
|
733
|
+
if (name !== void 0) fields.name = wrapUserData(name);
|
|
734
|
+
if (fields.config !== void 0) {
|
|
735
|
+
fields.config = redactNestedStrings(fields.config, {
|
|
736
|
+
skip: keepStructural
|
|
737
|
+
});
|
|
692
738
|
}
|
|
693
|
-
return
|
|
739
|
+
return {
|
|
740
|
+
fields,
|
|
741
|
+
id: stringField(fields, "id"),
|
|
742
|
+
name: stringField(fields, "name"),
|
|
743
|
+
config: recordField(fields, "config")
|
|
744
|
+
};
|
|
694
745
|
}
|
|
695
746
|
var TITLE3 = "Flow Management";
|
|
696
747
|
var DESCRIPTION3 = "Manage walkerOS flows and their previews. List/get/create/update/delete/duplicate flows, or create/inspect/delete preview bundles and mint activation grants (preview_regrant) for testing flow changes on live sites.";
|
|
697
748
|
var inputSchema3 = {
|
|
698
|
-
action:
|
|
749
|
+
action: z4.enum([
|
|
699
750
|
"list",
|
|
700
751
|
"get",
|
|
701
752
|
"create",
|
|
@@ -708,52 +759,52 @@ var inputSchema3 = {
|
|
|
708
759
|
"preview_delete",
|
|
709
760
|
"preview_regrant"
|
|
710
761
|
]).describe("Flow management action to perform"),
|
|
711
|
-
flowId:
|
|
762
|
+
flowId: z4.string().optional().describe(
|
|
712
763
|
"Flow ID (flow_...) or config ID (cfg_...). Required for get, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant."
|
|
713
764
|
),
|
|
714
|
-
projectId:
|
|
765
|
+
projectId: z4.string().optional().describe(
|
|
715
766
|
"Project ID. Optional filter for list (omit to list all projects). Required for create if no default project set."
|
|
716
767
|
),
|
|
717
|
-
name:
|
|
768
|
+
name: z4.string().optional().describe(
|
|
718
769
|
"Flow name. Required for create. Optional for update (to rename) and duplicate."
|
|
719
770
|
),
|
|
720
|
-
content:
|
|
721
|
-
patch:
|
|
771
|
+
content: z4.record(z4.string(), z4.unknown()).optional().describe("Flow.Json content. Used for create and update."),
|
|
772
|
+
patch: z4.boolean().optional().describe(
|
|
722
773
|
"Merge-patch for update (default true). When true, only provided fields are updated."
|
|
723
774
|
),
|
|
724
|
-
fields:
|
|
725
|
-
sort:
|
|
726
|
-
order:
|
|
727
|
-
includeDeleted:
|
|
728
|
-
cursor:
|
|
775
|
+
fields: z4.array(z4.string()).optional().describe("Dot-path selectors for get to return only specific fields."),
|
|
776
|
+
sort: z4.enum(["name", "updated_at", "created_at"]).optional().describe("Sort field for list."),
|
|
777
|
+
order: z4.enum(["asc", "desc"]).optional().describe("Sort order for list."),
|
|
778
|
+
includeDeleted: z4.boolean().optional().describe("Include soft-deleted flows in list results."),
|
|
779
|
+
cursor: z4.string().optional().describe(
|
|
729
780
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
730
781
|
),
|
|
731
|
-
limit:
|
|
732
|
-
previewId:
|
|
782
|
+
limit: z4.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action."),
|
|
783
|
+
previewId: z4.string().optional().describe(
|
|
733
784
|
"Preview ID (prv_...). Required for preview_get, preview_delete, and preview_regrant (all also require flowId)."
|
|
734
785
|
),
|
|
735
|
-
flowName:
|
|
786
|
+
flowName: z4.string().optional().describe(
|
|
736
787
|
"Used by preview_create \u2014 provide one of flowName or flowSettingsId (preview_create also requires flowId)."
|
|
737
788
|
),
|
|
738
|
-
flowSettingsId:
|
|
789
|
+
flowSettingsId: z4.string().optional().describe(
|
|
739
790
|
"Used by preview_create \u2014 provide one of flowName or flowSettingsId (preview_create also requires flowId)."
|
|
740
791
|
),
|
|
741
|
-
source:
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
kind:
|
|
745
|
-
deploymentVersionId:
|
|
792
|
+
source: z4.discriminatedUnion("kind", [
|
|
793
|
+
z4.object({ kind: z4.literal("draft") }),
|
|
794
|
+
z4.object({
|
|
795
|
+
kind: z4.literal("deployment-version"),
|
|
796
|
+
deploymentVersionId: z4.string()
|
|
746
797
|
})
|
|
747
798
|
]).optional().describe(
|
|
748
799
|
"What the preview should run, for preview_create: the flow's draft (default) or a deployed version's stored config (kind 'deployment-version' with its deploymentVersionId)."
|
|
749
800
|
),
|
|
750
|
-
siteUrl:
|
|
801
|
+
siteUrl: z4.string().optional().describe(
|
|
751
802
|
"Optional site URL (e.g. https://shop.example.com) for preview_create. When provided, the activation grant is minted for that origin so the returned activationUrl works there."
|
|
752
803
|
),
|
|
753
|
-
origins:
|
|
804
|
+
origins: z4.array(z4.string()).optional().describe(
|
|
754
805
|
"Site origins (bare https://host[:port]) to mint a preview activation grant for. Used by preview_regrant; the returned activationUrl targets the first origin."
|
|
755
806
|
),
|
|
756
|
-
sessionId:
|
|
807
|
+
sessionId: z4.string().optional().describe(
|
|
757
808
|
"Observe session id \u2014 when set, preview_regrant mints an activation/forwarding grant PAIR: the returned activationUrl both activates the web preview and lets the page forward events to the session container (elbPreviewSession param). Pass it to observe server-side hops; omit for a plain web preview."
|
|
758
809
|
)
|
|
759
810
|
};
|
|
@@ -779,9 +830,6 @@ var PREVIEW_SUMMARY_FIELDS = [
|
|
|
779
830
|
"createdBy",
|
|
780
831
|
"createdAt"
|
|
781
832
|
];
|
|
782
|
-
function isRecord(value) {
|
|
783
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
784
|
-
}
|
|
785
833
|
function redactPreview(data) {
|
|
786
834
|
if (!isRecord(data)) return {};
|
|
787
835
|
const out = {};
|
|
@@ -820,6 +868,8 @@ function createFlowManageToolSpec(client) {
|
|
|
820
868
|
};
|
|
821
869
|
}
|
|
822
870
|
async function flowManageHandlerBody(client, input) {
|
|
871
|
+
const parsed = parseToolInput(inputSchema3, input);
|
|
872
|
+
if (!parsed.ok) return parsed.error;
|
|
823
873
|
const {
|
|
824
874
|
action,
|
|
825
875
|
flowId,
|
|
@@ -840,14 +890,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
840
890
|
siteUrl,
|
|
841
891
|
origins,
|
|
842
892
|
sessionId
|
|
843
|
-
} =
|
|
893
|
+
} = parsed.data;
|
|
844
894
|
const validationError = validateActionInput(
|
|
845
895
|
"flow_manage",
|
|
846
896
|
action ?? "",
|
|
847
897
|
{ flowId, projectId, name, previewId, flowName, flowSettingsId },
|
|
848
898
|
FLOW_MANAGE_REQUIREMENTS
|
|
849
899
|
);
|
|
850
|
-
if (validationError) return
|
|
900
|
+
if (validationError) return mcpError4(new Error(validationError));
|
|
851
901
|
try {
|
|
852
902
|
switch (action) {
|
|
853
903
|
case "list": {
|
|
@@ -860,9 +910,8 @@ async function flowManageHandlerBody(client, input) {
|
|
|
860
910
|
cursor,
|
|
861
911
|
limit
|
|
862
912
|
});
|
|
863
|
-
const
|
|
864
|
-
const
|
|
865
|
-
const safe2 = Array.isArray(flows) ? { ...dataObj, flows: flows.map(safeSummary) } : data2;
|
|
913
|
+
const flows = isRecord(data2) ? data2.flows : void 0;
|
|
914
|
+
const safe2 = isRecord(data2) && Array.isArray(flows) ? { ...data2, flows: flows.map(safeSummary) } : data2;
|
|
866
915
|
return mcpResult3(safe2);
|
|
867
916
|
}
|
|
868
917
|
const data = await client.listAllFlows({
|
|
@@ -887,16 +936,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
887
936
|
assertParam(flowId, "flowId", "get");
|
|
888
937
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
889
938
|
if (!resolvedProjectId) {
|
|
890
|
-
return
|
|
939
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
891
940
|
}
|
|
892
941
|
const flow = await client.getFlow({
|
|
893
942
|
flowId,
|
|
894
943
|
projectId: resolvedProjectId,
|
|
895
944
|
fields
|
|
896
945
|
});
|
|
897
|
-
const safe = safeDetail(
|
|
898
|
-
flow
|
|
899
|
-
);
|
|
946
|
+
const safe = safeDetail(flow);
|
|
900
947
|
const appUrl = flowPageUrl(client, resolvedProjectId, safe.id);
|
|
901
948
|
return flowCanvasResult({
|
|
902
949
|
flowId: safe.id,
|
|
@@ -921,16 +968,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
921
968
|
assertParam(name, "name", "create");
|
|
922
969
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
923
970
|
if (!resolvedProjectId) {
|
|
924
|
-
return
|
|
971
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
925
972
|
}
|
|
926
973
|
const created = await client.createFlow({
|
|
927
974
|
name,
|
|
928
975
|
content: content ?? {},
|
|
929
976
|
projectId: resolvedProjectId
|
|
930
977
|
});
|
|
931
|
-
const safeCreated = safeDetail(
|
|
932
|
-
created
|
|
933
|
-
);
|
|
978
|
+
const safeCreated = safeDetail(created);
|
|
934
979
|
const createdAppUrl = flowPageUrl(
|
|
935
980
|
client,
|
|
936
981
|
resolvedProjectId,
|
|
@@ -959,7 +1004,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
959
1004
|
assertParam(flowId, "flowId", "update");
|
|
960
1005
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
961
1006
|
if (!resolvedProjectId) {
|
|
962
|
-
return
|
|
1007
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
963
1008
|
}
|
|
964
1009
|
const updated = await client.updateFlow({
|
|
965
1010
|
flowId,
|
|
@@ -968,9 +1013,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
968
1013
|
content,
|
|
969
1014
|
mergePatch: patch ?? true
|
|
970
1015
|
});
|
|
971
|
-
const safeUpdated = safeDetail(
|
|
972
|
-
updated
|
|
973
|
-
);
|
|
1016
|
+
const safeUpdated = safeDetail(updated);
|
|
974
1017
|
return flowCanvasResult({
|
|
975
1018
|
flowId: safeUpdated.id,
|
|
976
1019
|
configName: safeUpdated.name ?? "default",
|
|
@@ -993,7 +1036,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
993
1036
|
assertParam(flowId, "flowId", "delete");
|
|
994
1037
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
995
1038
|
if (!resolvedProjectId) {
|
|
996
|
-
return
|
|
1039
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
997
1040
|
}
|
|
998
1041
|
const deleted = await client.deleteFlow({
|
|
999
1042
|
flowId,
|
|
@@ -1005,22 +1048,20 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1005
1048
|
assertParam(flowId, "flowId", "duplicate");
|
|
1006
1049
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1007
1050
|
if (!resolvedProjectId) {
|
|
1008
|
-
return
|
|
1051
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1009
1052
|
}
|
|
1010
1053
|
const duplicated = await client.duplicateFlow({
|
|
1011
1054
|
flowId,
|
|
1012
1055
|
name,
|
|
1013
1056
|
projectId: resolvedProjectId
|
|
1014
1057
|
});
|
|
1015
|
-
return mcpResult3(
|
|
1016
|
-
safeDetail(duplicated)
|
|
1017
|
-
);
|
|
1058
|
+
return mcpResult3(safeDetail(duplicated).fields);
|
|
1018
1059
|
}
|
|
1019
1060
|
case "preview_list": {
|
|
1020
1061
|
assertParam(flowId, "flowId", "preview_list");
|
|
1021
1062
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1022
1063
|
if (!resolvedProjectId) {
|
|
1023
|
-
return
|
|
1064
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1024
1065
|
}
|
|
1025
1066
|
const data = await client.listPreviews({
|
|
1026
1067
|
projectId: resolvedProjectId,
|
|
@@ -1033,7 +1074,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1033
1074
|
assertParam(previewId, "previewId", "preview_get");
|
|
1034
1075
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1035
1076
|
if (!resolvedProjectId) {
|
|
1036
|
-
return
|
|
1077
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1037
1078
|
}
|
|
1038
1079
|
const data = await client.getPreview({
|
|
1039
1080
|
projectId: resolvedProjectId,
|
|
@@ -1046,7 +1087,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1046
1087
|
assertParam(flowId, "flowId", "preview_create");
|
|
1047
1088
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1048
1089
|
if (!resolvedProjectId) {
|
|
1049
|
-
return
|
|
1090
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1050
1091
|
}
|
|
1051
1092
|
const preview = await client.createPreview({
|
|
1052
1093
|
projectId: resolvedProjectId,
|
|
@@ -1068,7 +1109,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1068
1109
|
assertParam(previewId, "previewId", "preview_delete");
|
|
1069
1110
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1070
1111
|
if (!resolvedProjectId) {
|
|
1071
|
-
return
|
|
1112
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1072
1113
|
}
|
|
1073
1114
|
const data = await client.deletePreview({
|
|
1074
1115
|
projectId: resolvedProjectId,
|
|
@@ -1084,10 +1125,10 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1084
1125
|
assertParam(previewId, "previewId", "preview_regrant");
|
|
1085
1126
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1086
1127
|
if (!resolvedProjectId) {
|
|
1087
|
-
return
|
|
1128
|
+
return mcpError4(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1088
1129
|
}
|
|
1089
1130
|
if (!client.regrantPreview) {
|
|
1090
|
-
return
|
|
1131
|
+
return mcpError4(
|
|
1091
1132
|
new Error("preview_regrant is not supported by this client")
|
|
1092
1133
|
);
|
|
1093
1134
|
}
|
|
@@ -1111,7 +1152,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
1111
1152
|
);
|
|
1112
1153
|
}
|
|
1113
1154
|
} catch (error) {
|
|
1114
|
-
return
|
|
1155
|
+
return mcpError4(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1115
1156
|
}
|
|
1116
1157
|
}
|
|
1117
1158
|
function registerFlowManageTool(server, client) {
|
|
@@ -1124,15 +1165,13 @@ function registerFlowManageTool(server, client) {
|
|
|
1124
1165
|
inputSchema: spec.inputSchema,
|
|
1125
1166
|
annotations: spec.annotations
|
|
1126
1167
|
},
|
|
1127
|
-
|
|
1128
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1129
|
-
spec.handler
|
|
1168
|
+
(args) => flowManageHandlerBody(client, args)
|
|
1130
1169
|
);
|
|
1131
1170
|
}
|
|
1132
1171
|
|
|
1133
1172
|
// src/tools/deploy-manage.ts
|
|
1134
|
-
import { z as
|
|
1135
|
-
import { mcpResult as mcpResult4, mcpError as
|
|
1173
|
+
import { z as z5 } from "zod";
|
|
1174
|
+
import { mcpResult as mcpResult4, mcpError as mcpError5 } from "@walkeros/core";
|
|
1136
1175
|
|
|
1137
1176
|
// src/tools/_resolvers.ts
|
|
1138
1177
|
var DeploymentNotFoundError = class extends Error {
|
|
@@ -1188,24 +1227,24 @@ async function resolveDeploymentSlug(args) {
|
|
|
1188
1227
|
var TITLE4 = "Deploy Management";
|
|
1189
1228
|
var DESCRIPTION4 = "Deploy walkerOS flows and manage deployments. deploy waits for the deployment to reach a terminal status by default (wait=true), with a 12-minute budget; pass wait=false to return immediately with the deployment id. A finished deployment carries its status and, on failure, an errorMessage with the user-facing reason; use the get action to re-read it. list supports cursor and limit for pagination. delete removes an active deployment. For get and delete pass flowId (required) plus optional slug to disambiguate when a flow has multiple active deployments. If a flow has >=2 active deployments and no slug is supplied, the tool returns a MULTIPLE_DEPLOYMENTS error with a details[] list showing each deployment's slug, type, status, and updatedAt.";
|
|
1190
1229
|
var inputSchema4 = {
|
|
1191
|
-
action:
|
|
1192
|
-
projectId:
|
|
1193
|
-
flowId:
|
|
1194
|
-
slug:
|
|
1230
|
+
action: z5.enum(["deploy", "list", "get", "delete"]).describe("Deployment action to perform"),
|
|
1231
|
+
projectId: z5.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
1232
|
+
flowId: z5.string().optional().describe("Required for deploy, get, delete."),
|
|
1233
|
+
slug: z5.string().optional().describe(
|
|
1195
1234
|
"Deployment slug. Optional disambiguator for get/delete when the flow has multiple active deployments."
|
|
1196
1235
|
),
|
|
1197
|
-
type:
|
|
1198
|
-
status:
|
|
1199
|
-
wait:
|
|
1236
|
+
type: z5.enum(["web", "server"]).optional().describe("Deployment type filter for list."),
|
|
1237
|
+
status: z5.string().optional().describe("Status filter for list."),
|
|
1238
|
+
wait: z5.boolean().optional().describe(
|
|
1200
1239
|
"Wait for the deployment to reach a terminal status (default true), with a 12-minute budget. Set false to return the deployment id immediately. Only used with deploy action."
|
|
1201
1240
|
),
|
|
1202
|
-
flowName:
|
|
1241
|
+
flowName: z5.string().optional().describe(
|
|
1203
1242
|
"Flow name for multi-settings flows. Only used with deploy action."
|
|
1204
1243
|
),
|
|
1205
|
-
cursor:
|
|
1244
|
+
cursor: z5.string().optional().describe(
|
|
1206
1245
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
1207
1246
|
),
|
|
1208
|
-
limit:
|
|
1247
|
+
limit: z5.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action.")
|
|
1209
1248
|
};
|
|
1210
1249
|
var annotations4 = {
|
|
1211
1250
|
readOnlyHint: false,
|
|
@@ -1240,13 +1279,22 @@ function withAppUrl(data, appUrl) {
|
|
|
1240
1279
|
}
|
|
1241
1280
|
return { ...data, appUrl };
|
|
1242
1281
|
}
|
|
1282
|
+
function readDeploymentSummary(value) {
|
|
1283
|
+
if (!isRecord(value)) return [];
|
|
1284
|
+
const slug = stringField(value, "slug");
|
|
1285
|
+
const type = stringField(value, "type");
|
|
1286
|
+
const status = stringField(value, "status");
|
|
1287
|
+
const updatedAt = stringField(value, "updatedAt");
|
|
1288
|
+
return slug !== void 0 && type !== void 0 && status !== void 0 && updatedAt !== void 0 ? [{ ...value, slug, type, status, updatedAt }] : [];
|
|
1289
|
+
}
|
|
1243
1290
|
function listForResolver(client, projectId) {
|
|
1244
1291
|
return async (q) => {
|
|
1245
1292
|
const resp = await client.listDeployments({
|
|
1246
1293
|
projectId: projectId || q.projectId || void 0,
|
|
1247
1294
|
flowId: q.flowId
|
|
1248
1295
|
});
|
|
1249
|
-
|
|
1296
|
+
const deployments = isRecord(resp) ? resp.deployments : void 0;
|
|
1297
|
+
return Array.isArray(deployments) ? deployments.flatMap(readDeploymentSummary) : [];
|
|
1250
1298
|
};
|
|
1251
1299
|
}
|
|
1252
1300
|
function createDeployManageToolSpec(client) {
|
|
@@ -1260,6 +1308,8 @@ function createDeployManageToolSpec(client) {
|
|
|
1260
1308
|
};
|
|
1261
1309
|
}
|
|
1262
1310
|
async function deployManageHandlerBody(client, input) {
|
|
1311
|
+
const parsed = parseToolInput(inputSchema4, input);
|
|
1312
|
+
if (!parsed.ok) return parsed.error;
|
|
1263
1313
|
const {
|
|
1264
1314
|
action,
|
|
1265
1315
|
projectId,
|
|
@@ -1271,14 +1321,14 @@ async function deployManageHandlerBody(client, input) {
|
|
|
1271
1321
|
flowName,
|
|
1272
1322
|
cursor,
|
|
1273
1323
|
limit
|
|
1274
|
-
} =
|
|
1324
|
+
} = parsed.data;
|
|
1275
1325
|
const validationError = validateActionInput(
|
|
1276
1326
|
"deploy_manage",
|
|
1277
1327
|
action ?? "",
|
|
1278
1328
|
{ flowId, projectId },
|
|
1279
1329
|
DEPLOY_MANAGE_REQUIREMENTS
|
|
1280
1330
|
);
|
|
1281
|
-
if (validationError) return
|
|
1331
|
+
if (validationError) return mcpError5(new Error(validationError));
|
|
1282
1332
|
try {
|
|
1283
1333
|
switch (action) {
|
|
1284
1334
|
case "deploy": {
|
|
@@ -1337,7 +1387,7 @@ async function deployManageHandlerBody(client, input) {
|
|
|
1337
1387
|
return mcpResult4(
|
|
1338
1388
|
redactDisplayNames({
|
|
1339
1389
|
deleted: true,
|
|
1340
|
-
...data
|
|
1390
|
+
...fieldsOf(data)
|
|
1341
1391
|
})
|
|
1342
1392
|
);
|
|
1343
1393
|
}
|
|
@@ -1347,7 +1397,7 @@ async function deployManageHandlerBody(client, input) {
|
|
|
1347
1397
|
);
|
|
1348
1398
|
}
|
|
1349
1399
|
} catch (error) {
|
|
1350
|
-
return
|
|
1400
|
+
return mcpError5(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1351
1401
|
}
|
|
1352
1402
|
}
|
|
1353
1403
|
function registerDeployTool(server, client) {
|
|
@@ -1360,35 +1410,33 @@ function registerDeployTool(server, client) {
|
|
|
1360
1410
|
inputSchema: spec.inputSchema,
|
|
1361
1411
|
annotations: spec.annotations
|
|
1362
1412
|
},
|
|
1363
|
-
|
|
1364
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1365
|
-
spec.handler
|
|
1413
|
+
(args) => deployManageHandlerBody(client, args)
|
|
1366
1414
|
);
|
|
1367
1415
|
}
|
|
1368
1416
|
|
|
1369
1417
|
// src/tools/secret-manage.ts
|
|
1370
|
-
import { z as
|
|
1371
|
-
import { mcpResult as mcpResult5, mcpError as
|
|
1418
|
+
import { z as z6 } from "zod";
|
|
1419
|
+
import { mcpResult as mcpResult5, mcpError as mcpError6 } from "@walkeros/core";
|
|
1372
1420
|
var TITLE5 = "Secret Management";
|
|
1373
1421
|
var DESCRIPTION5 = "Manage a flow\u2019s managed secrets (the $secret.<NAME> values its steps reference at deploy/run time). Actions: list (metadata only), set (create), update (rotate value), delete. Secrets are write-mostly: values are encrypted at rest and are NEVER returned, listed, or echoed. Reference a secret from a flow step as $secret.<NAME>. Credentials, tokens, and private keys must use $secret, not $env: the deploy pipeline only injects values referenced as $secret.<NAME> into the server runner. Server flows only.";
|
|
1374
1422
|
var inputSchema5 = {
|
|
1375
|
-
action:
|
|
1376
|
-
projectId:
|
|
1423
|
+
action: z6.enum(["list", "set", "update", "delete"]).describe("Secret management action to perform"),
|
|
1424
|
+
projectId: z6.string().optional().describe(
|
|
1377
1425
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
1378
1426
|
),
|
|
1379
|
-
flowId:
|
|
1427
|
+
flowId: z6.string().describe(
|
|
1380
1428
|
"Flow ID (flow_...) or config ID (cfg_...). Required for list, set, update, and delete: secrets are flow-scoped."
|
|
1381
1429
|
),
|
|
1382
|
-
name:
|
|
1430
|
+
name: z6.string().regex(
|
|
1383
1431
|
/^[A-Z_][A-Z0-9_]*$/,
|
|
1384
1432
|
"Secret name must be uppercase letters, digits, and underscores, starting with a letter or underscore."
|
|
1385
1433
|
).optional().describe(
|
|
1386
1434
|
"Secret name (UPPER_SNAKE_CASE). Required for set. Referenced in flows as $secret.<NAME>."
|
|
1387
1435
|
),
|
|
1388
|
-
value:
|
|
1436
|
+
value: z6.string().min(1).max(65536).optional().describe(
|
|
1389
1437
|
"Secret value (1-65536 chars). Required for set and update. Write-only: never returned or logged."
|
|
1390
1438
|
),
|
|
1391
|
-
secretId:
|
|
1439
|
+
secretId: z6.string().optional().describe(
|
|
1392
1440
|
'Secret ID (sec_...). Required for update and delete. Use action "list" to find it.'
|
|
1393
1441
|
)
|
|
1394
1442
|
};
|
|
@@ -1409,18 +1457,20 @@ function createSecretManageToolSpec(client) {
|
|
|
1409
1457
|
};
|
|
1410
1458
|
}
|
|
1411
1459
|
async function secretManageHandlerBody(client, input) {
|
|
1412
|
-
const
|
|
1460
|
+
const parsed = parseToolInput(inputSchema5, input);
|
|
1461
|
+
if (!parsed.ok) return parsed.error;
|
|
1462
|
+
const { action, projectId, flowId, name, value, secretId } = parsed.data;
|
|
1413
1463
|
const validationError = validateActionInput(
|
|
1414
1464
|
"secret_manage",
|
|
1415
1465
|
action ?? "",
|
|
1416
1466
|
{ flowId, name, value, secretId },
|
|
1417
1467
|
SECRET_MANAGE_REQUIREMENTS
|
|
1418
1468
|
);
|
|
1419
|
-
if (validationError) return
|
|
1469
|
+
if (validationError) return mcpError6(new Error(validationError));
|
|
1420
1470
|
try {
|
|
1421
1471
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
1422
1472
|
if (!resolvedProjectId)
|
|
1423
|
-
return
|
|
1473
|
+
return mcpError6(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1424
1474
|
switch (action) {
|
|
1425
1475
|
case "list": {
|
|
1426
1476
|
assertParam(flowId, "flowId", "list");
|
|
@@ -1479,7 +1529,7 @@ async function secretManageHandlerBody(client, input) {
|
|
|
1479
1529
|
);
|
|
1480
1530
|
}
|
|
1481
1531
|
} catch (error) {
|
|
1482
|
-
return
|
|
1532
|
+
return mcpError6(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1483
1533
|
}
|
|
1484
1534
|
}
|
|
1485
1535
|
function registerSecretManageTool(server, client) {
|
|
@@ -1492,22 +1542,20 @@ function registerSecretManageTool(server, client) {
|
|
|
1492
1542
|
inputSchema: spec.inputSchema,
|
|
1493
1543
|
annotations: spec.annotations
|
|
1494
1544
|
},
|
|
1495
|
-
|
|
1496
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1497
|
-
spec.handler
|
|
1545
|
+
(args) => secretManageHandlerBody(client, args)
|
|
1498
1546
|
);
|
|
1499
1547
|
}
|
|
1500
1548
|
|
|
1501
1549
|
// src/tools/observe-journeys.ts
|
|
1502
|
-
import { z as
|
|
1503
|
-
import { mcpResult as mcpResult6, mcpError as
|
|
1550
|
+
import { z as z7 } from "zod";
|
|
1551
|
+
import { mcpResult as mcpResult6, mcpError as mcpError7 } from "@walkeros/core";
|
|
1504
1552
|
var TITLE6 = "Observe Journeys";
|
|
1505
1553
|
var DESCRIPTION6 = "Read the assembled, cross-runtime journeys for a flow that is currently being observed (an active Observe session). Pass flowId; the active session is resolved for you (a flow has at most one). Each journey is one traced event reconstructed end to end across web and server: its ordered hops (source, transformer, collector, destination), each hop status (pending/done/skipped/error), captured in/out payloads, consent, and vendor calls. Use this to see what actually happened to live events: which destinations fired, what mapping ran, where an event was skipped or errored, and whether records were lost (gaps + a journey `lossy` flag). When the flow has no active session the result is `{ sessionId: null, journeys: [], gaps: [] }` \u2014 start an Observe session in the app and drive traffic first, then read again. Narrow with traceId (one trace) and limit (page cap, most recent kept; default 50). Read-only.";
|
|
1506
1554
|
var inputSchema6 = {
|
|
1507
|
-
flowId:
|
|
1508
|
-
projectId:
|
|
1509
|
-
traceId:
|
|
1510
|
-
limit:
|
|
1555
|
+
flowId: z7.string().describe("Flow to read journeys for (its active Observe session)."),
|
|
1556
|
+
projectId: z7.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
1557
|
+
traceId: z7.string().optional().describe("Return only the journeys for this trace id."),
|
|
1558
|
+
limit: z7.number().int().min(1).max(100).optional().describe(
|
|
1511
1559
|
"Max journeys to return (1-100, most recent kept). Defaults to 50."
|
|
1512
1560
|
)
|
|
1513
1561
|
};
|
|
@@ -1565,9 +1613,11 @@ function createObserveJourneysToolSpec(client) {
|
|
|
1565
1613
|
};
|
|
1566
1614
|
}
|
|
1567
1615
|
async function observeJourneysHandlerBody(client, input) {
|
|
1568
|
-
const
|
|
1616
|
+
const parsed = parseToolInput(inputSchema6, input);
|
|
1617
|
+
if (!parsed.ok) return parsed.error;
|
|
1618
|
+
const { flowId, projectId, traceId, limit } = parsed.data;
|
|
1569
1619
|
if (!flowId) {
|
|
1570
|
-
return
|
|
1620
|
+
return mcpError7(new Error("flowId is required for observe_journeys."));
|
|
1571
1621
|
}
|
|
1572
1622
|
try {
|
|
1573
1623
|
const result = await client.listJourneys({
|
|
@@ -1594,7 +1644,7 @@ async function observeJourneysHandlerBody(client, input) {
|
|
|
1594
1644
|
]
|
|
1595
1645
|
});
|
|
1596
1646
|
} catch (error) {
|
|
1597
|
-
return
|
|
1647
|
+
return mcpError7(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1598
1648
|
}
|
|
1599
1649
|
}
|
|
1600
1650
|
function registerObserveJourneysTool(server, client) {
|
|
@@ -1607,15 +1657,13 @@ function registerObserveJourneysTool(server, client) {
|
|
|
1607
1657
|
inputSchema: spec.inputSchema,
|
|
1608
1658
|
annotations: spec.annotations
|
|
1609
1659
|
},
|
|
1610
|
-
|
|
1611
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1612
|
-
spec.handler
|
|
1660
|
+
(args) => observeJourneysHandlerBody(client, args)
|
|
1613
1661
|
);
|
|
1614
1662
|
}
|
|
1615
1663
|
|
|
1616
1664
|
// src/tools/observe-session.ts
|
|
1617
|
-
import { z as
|
|
1618
|
-
import { mcpResult as mcpResult7, mcpError as
|
|
1665
|
+
import { z as z8 } from "zod";
|
|
1666
|
+
import { mcpResult as mcpResult7, mcpError as mcpError8 } from "@walkeros/core";
|
|
1619
1667
|
var TITLE7 = "Observe Session";
|
|
1620
1668
|
var DESCRIPTION7 = "Open, inspect, or end an Observe session: a time-boxed window on one flow that runtimes attach to as arms. A preview arm streams from a browser, a container arm runs server-side, and both feed ONE shared journeys feed. start opens the window (arms picks which runtimes attach), status reports per-arm state plus recordsReceived and expiresAt, stop ends the whole session including every arm. A flow has at most one session, so status/stop resolve it from flowId when sessionId is omitted. Read the events with observe_journeys; this tool never returns event data and never judges whether events are correct.";
|
|
1621
1669
|
var HINT_SIMULATE_FIRST = "Simulate before preview: flow_simulate checks mapping with no browser.";
|
|
@@ -1626,29 +1674,29 @@ var HINT_EMPTY_FEED = "recordsReceived is 0: nothing has reached the feed yet. D
|
|
|
1626
1674
|
var HINT_ENDED = "Session ended and both arms detached. Start a new one with observe_session start.";
|
|
1627
1675
|
var HINT_NO_WINDOW = "No Observe session on this flow. Open one with observe_session start.";
|
|
1628
1676
|
var inputSchema7 = {
|
|
1629
|
-
action:
|
|
1677
|
+
action: z8.enum(["start", "status", "stop"]).describe(
|
|
1630
1678
|
"start opens a session, status reports arm state, stop ends the whole session."
|
|
1631
1679
|
),
|
|
1632
|
-
flowId:
|
|
1633
|
-
projectId:
|
|
1634
|
-
sessionId:
|
|
1680
|
+
flowId: z8.string().describe("Flow the Observe session runs on."),
|
|
1681
|
+
projectId: z8.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
1682
|
+
sessionId: z8.string().optional().describe(
|
|
1635
1683
|
"Session to act on for status/stop. Optional; the flow has at most one session and it is resolved for you."
|
|
1636
1684
|
),
|
|
1637
|
-
arms:
|
|
1638
|
-
container:
|
|
1685
|
+
arms: z8.object({
|
|
1686
|
+
container: z8.literal(true).optional().describe(
|
|
1639
1687
|
"Pass true to attach the server container arm, which selects the flow's server settings when no preview arm is named. Only true is accepted: a web settings that references a server flow always brings its container arm along, so a container cannot be suppressed here."
|
|
1640
1688
|
),
|
|
1641
|
-
preview:
|
|
1689
|
+
preview: z8.string().optional().describe(
|
|
1642
1690
|
"Name the flow settings this session observes. A web settings attaches the browser preview arm (plus the container arm of any server flow it references); a server settings attaches the container arm alone. Omit to use the flow's single web settings."
|
|
1643
1691
|
)
|
|
1644
1692
|
}).optional().describe(
|
|
1645
1693
|
"Which runtimes attach. Omit to attach the default preview arm; a web settings that references a server flow brings its container arm with it."
|
|
1646
1694
|
),
|
|
1647
|
-
origins:
|
|
1695
|
+
origins: z8.array(z8.string()).optional().describe(
|
|
1648
1696
|
"Bare https origins (https://host[:port]) the session may ingest web events from."
|
|
1649
1697
|
),
|
|
1650
|
-
level:
|
|
1651
|
-
replace:
|
|
1698
|
+
level: z8.enum(["off", "standard", "trace"]).optional().describe("Container observation verbosity. Defaults to the app's own."),
|
|
1699
|
+
replace: z8.boolean().optional().describe(
|
|
1652
1700
|
"Replace the flow's existing window instead of attaching to it. Re-provisions from the new config."
|
|
1653
1701
|
)
|
|
1654
1702
|
};
|
|
@@ -1659,14 +1707,14 @@ var annotations7 = {
|
|
|
1659
1707
|
openWorldHint: true
|
|
1660
1708
|
};
|
|
1661
1709
|
function readSettings(flow) {
|
|
1662
|
-
if (!flow
|
|
1710
|
+
if (!isRecord(flow)) return [];
|
|
1663
1711
|
const settings = flow.settings;
|
|
1664
1712
|
if (!Array.isArray(settings)) return [];
|
|
1665
1713
|
const entries = [];
|
|
1666
1714
|
for (const entry of settings) {
|
|
1667
|
-
|
|
1668
|
-
const
|
|
1669
|
-
if (
|
|
1715
|
+
const name = stringField(entry, "name");
|
|
1716
|
+
const platform = stringField(entry, "platform");
|
|
1717
|
+
if (name === void 0) continue;
|
|
1670
1718
|
if (platform !== "web" && platform !== "server") continue;
|
|
1671
1719
|
entries.push({ name, platform });
|
|
1672
1720
|
}
|
|
@@ -1796,6 +1844,8 @@ function createObserveSessionToolSpec(client) {
|
|
|
1796
1844
|
};
|
|
1797
1845
|
}
|
|
1798
1846
|
async function observeSessionHandlerBody(client, input) {
|
|
1847
|
+
const parsed = parseToolInput(inputSchema7, input);
|
|
1848
|
+
if (!parsed.ok) return parsed.error;
|
|
1799
1849
|
const {
|
|
1800
1850
|
action,
|
|
1801
1851
|
flowId,
|
|
@@ -1805,19 +1855,19 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
1805
1855
|
origins,
|
|
1806
1856
|
level,
|
|
1807
1857
|
replace
|
|
1808
|
-
} =
|
|
1858
|
+
} = parsed.data;
|
|
1809
1859
|
if (!flowId) {
|
|
1810
|
-
return
|
|
1860
|
+
return mcpError8(new Error("flowId is required for observe_session."));
|
|
1811
1861
|
}
|
|
1812
1862
|
const resolvedProjectId = resolveProjectId(client, projectId);
|
|
1813
1863
|
if (!resolvedProjectId) {
|
|
1814
|
-
return
|
|
1864
|
+
return mcpError8(new Error(NO_DEFAULT_PROJECT_ERROR2));
|
|
1815
1865
|
}
|
|
1816
1866
|
try {
|
|
1817
1867
|
switch (action) {
|
|
1818
1868
|
case "start": {
|
|
1819
1869
|
if (!client.startObserveSession) {
|
|
1820
|
-
return
|
|
1870
|
+
return mcpError8(
|
|
1821
1871
|
new Error("observe_session start is not supported by this client.")
|
|
1822
1872
|
);
|
|
1823
1873
|
}
|
|
@@ -1843,7 +1893,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
1843
1893
|
}
|
|
1844
1894
|
case "status": {
|
|
1845
1895
|
if (!client.getObserveSession) {
|
|
1846
|
-
return
|
|
1896
|
+
return mcpError8(
|
|
1847
1897
|
new Error(
|
|
1848
1898
|
"observe_session status is not supported by this client."
|
|
1849
1899
|
)
|
|
@@ -1870,7 +1920,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
1870
1920
|
}
|
|
1871
1921
|
case "stop": {
|
|
1872
1922
|
if (!client.endObserveSession) {
|
|
1873
|
-
return
|
|
1923
|
+
return mcpError8(
|
|
1874
1924
|
new Error("observe_session stop is not supported by this client.")
|
|
1875
1925
|
);
|
|
1876
1926
|
}
|
|
@@ -1900,7 +1950,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
1900
1950
|
);
|
|
1901
1951
|
}
|
|
1902
1952
|
} catch (error) {
|
|
1903
|
-
return
|
|
1953
|
+
return mcpError8(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1904
1954
|
}
|
|
1905
1955
|
}
|
|
1906
1956
|
function registerObserveSessionTool(server, client) {
|
|
@@ -1913,15 +1963,13 @@ function registerObserveSessionTool(server, client) {
|
|
|
1913
1963
|
inputSchema: spec.inputSchema,
|
|
1914
1964
|
annotations: spec.annotations
|
|
1915
1965
|
},
|
|
1916
|
-
|
|
1917
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1918
|
-
spec.handler
|
|
1966
|
+
(args) => observeSessionHandlerBody(client, args)
|
|
1919
1967
|
);
|
|
1920
1968
|
}
|
|
1921
1969
|
|
|
1922
1970
|
// src/tools/hub-manage.ts
|
|
1923
|
-
import { z as
|
|
1924
|
-
import { mcpResult as mcpResult8, mcpError as
|
|
1971
|
+
import { z as z9 } from "zod";
|
|
1972
|
+
import { mcpResult as mcpResult8, mcpError as mcpError9 } from "@walkeros/core";
|
|
1925
1973
|
|
|
1926
1974
|
// src/tools/feature-gate.ts
|
|
1927
1975
|
var FEATURE_NOT_AVAILABLE = "FEATURE_NOT_AVAILABLE";
|
|
@@ -1974,56 +2022,56 @@ var TOOL_ANCHOR_TYPES = [
|
|
|
1974
2022
|
"tag"
|
|
1975
2023
|
];
|
|
1976
2024
|
var HUB_MANAGE_INPUT_SCHEMA = {
|
|
1977
|
-
action:
|
|
2025
|
+
action: z9.enum(ACTIONS, {
|
|
1978
2026
|
error: () => `Unknown action. Use one of: ${ACTIONS.join(", ")}`
|
|
1979
2027
|
}).describe("Which part of the release history to read or write"),
|
|
1980
|
-
projectId:
|
|
2028
|
+
projectId: z9.string().optional().describe(
|
|
1981
2029
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
1982
2030
|
),
|
|
1983
|
-
flowId:
|
|
2031
|
+
flowId: z9.string().optional().describe(
|
|
1984
2032
|
'Flow ID (flow_...). Required for every action except "knowledge", which hangs on a page rather than a flow and refuses this field.'
|
|
1985
2033
|
),
|
|
1986
|
-
versionId:
|
|
2034
|
+
versionId: z9.string().min(1).optional().describe(
|
|
1987
2035
|
'Release version ID (ver_...) from action "releases". Addresses one release for release_get and rationale_set. Pass this or versionNumber.'
|
|
1988
2036
|
),
|
|
1989
|
-
versionNumber:
|
|
2037
|
+
versionNumber: z9.number().int().positive().optional().describe(
|
|
1990
2038
|
'Spine release number for this flow, the `versionNumber` field of action "releases". Alternative to versionId. Not the same as a row\'s deploymentAttempt.'
|
|
1991
2039
|
),
|
|
1992
|
-
step:
|
|
2040
|
+
step: z9.string().optional().describe(
|
|
1993
2041
|
'Step key as "type.name", e.g. "destination.ga4" or "contract.checkout". Required for step_history.'
|
|
1994
2042
|
),
|
|
1995
|
-
flow:
|
|
2043
|
+
flow: z9.string().optional().describe(
|
|
1996
2044
|
'Named flow inside the config, e.g. "web" or "server". Optional for step_history: omit to scan every named flow. Ignored for contract steps, which are top-level.'
|
|
1997
2045
|
),
|
|
1998
|
-
text:
|
|
2046
|
+
text: z9.string().trim().min(1).max(MAX_ANNOTATION_TEXT_LENGTH).optional().describe(
|
|
1999
2047
|
`The text to write (1-${MAX_ANNOTATION_TEXT_LENGTH} chars). Required for rationale_set and note_add. As rationale it replaces the note already on the release and never touches the machine summary; as a note it is appended to a thread and nothing is ever replaced.`
|
|
2000
2048
|
),
|
|
2001
|
-
limit:
|
|
2049
|
+
limit: z9.number().int().positive().optional().describe(
|
|
2002
2050
|
`Page size. Releases to list for action "releases" (max 100), or releases to SCAN for step_history (max ${MAX_STEP_HISTORY_LIMIT}). For step_history this bounds releases, not entries: a step present in several named flows yields one entry per flow per release, and the scan stops at ${MAX_STEP_HISTORY_ENTRIES} entries with entriesTruncated set. Narrow with "flow" to avoid that. For threads it bounds threads, and a read that carries messages is held to ${MAX_THREADS_WITH_MESSAGES} of them. Knowledge entries are bounded the same way.`
|
|
2003
2051
|
),
|
|
2004
|
-
offset:
|
|
2005
|
-
anchorType:
|
|
2052
|
+
offset: z9.number().int().min(0).optional().describe('Releases to skip. Action "releases" only.'),
|
|
2053
|
+
anchorType: z9.enum(TOOL_ANCHOR_TYPES).optional().describe(
|
|
2006
2054
|
'What a thread hangs on. Defaults to "release", the only anchor the app writes today. Pair it with anchorKey; a key means a different thing under each type.'
|
|
2007
2055
|
),
|
|
2008
|
-
anchorKey:
|
|
2056
|
+
anchorKey: z9.string().min(1).max(MAX_ANCHOR_KEY_LENGTH).optional().describe(
|
|
2009
2057
|
'What the anchor addresses within its type: a release version ID (ver_...) for "release", a "type.name" step key for "step". For a release you can pass versionId or versionNumber instead. Omit entirely on action "threads" to read every thread on the flow.'
|
|
2010
2058
|
),
|
|
2011
|
-
anchorLabel:
|
|
2059
|
+
anchorLabel: z9.string().min(1).max(MAX_ANCHOR_LABEL_LENGTH).optional().describe(
|
|
2012
2060
|
'How the anchor reads on screen, stored once when a thread is opened so a later rename leaves it readable. Derived for a release ("v14"); pass it only when opening a thread on another anchor type.'
|
|
2013
2061
|
),
|
|
2014
|
-
threadId:
|
|
2062
|
+
threadId: z9.string().min(1).optional().describe(
|
|
2015
2063
|
'Thread ID (thr_...) from action "threads". Pass it to note_add to reply in that thread; omit it to open a new thread on the anchor.'
|
|
2016
2064
|
),
|
|
2017
|
-
status:
|
|
2065
|
+
status: z9.enum(THREAD_STATUSES).optional().describe(
|
|
2018
2066
|
'Read only threads in this state. Action "threads" only; omit for both.'
|
|
2019
2067
|
),
|
|
2020
|
-
pageKey:
|
|
2068
|
+
pageKey: z9.string().min(1).max(MAX_SOURCE_KEY_LENGTH).optional().describe(
|
|
2021
2069
|
'The page a note was left on, as Tag Mode addressed it, usually the page URL. Narrows action "knowledge" to every frame that page holds, at any depth; omit it to read the whole project.'
|
|
2022
2070
|
),
|
|
2023
|
-
frameId:
|
|
2071
|
+
frameId: z9.string().regex(FRAME_ID_PATTERN).optional().describe(
|
|
2024
2072
|
'One frame (frm_...), the named rectangle a note hangs on. Action "knowledge" only. Narrower than pageKey, since a page holds several frames.'
|
|
2025
2073
|
),
|
|
2026
|
-
markId:
|
|
2074
|
+
markId: z9.string().min(1).max(MAX_MARK_ID_LENGTH).optional().describe(
|
|
2027
2075
|
'One tag within "frameId", by its tag id (the id of an entry in frame_manage marks.tags). Action "knowledge" only, and refused without frameId, since a mark id alone addresses nothing. Naming a mark is also what attaches the message bodies.'
|
|
2028
2076
|
)
|
|
2029
2077
|
};
|
|
@@ -2069,7 +2117,7 @@ var HUB_HINT_ENTRY_NAMES_FLOW = "An entry names the flow it was written against
|
|
|
2069
2117
|
var HUB_HINT_KNOWLEDGE_READ_ONLY = "This tool only reads knowledge. Answering a note, and settling it, are done by a person in the app.";
|
|
2070
2118
|
var HUB_HINT_READ_FRAME = 'Use frame_manage action "get" with the frameId to read the frame and its marks.';
|
|
2071
2119
|
var HUB_NOT_FOUND_HINT = 'Use action "releases" to find version ids and action "threads" to find thread ids.';
|
|
2072
|
-
var hubInputSchema =
|
|
2120
|
+
var hubInputSchema = z9.object(HUB_MANAGE_INPUT_SCHEMA);
|
|
2073
2121
|
var HubToolError = class extends Error {
|
|
2074
2122
|
constructor(code, message) {
|
|
2075
2123
|
super(message);
|
|
@@ -2489,12 +2537,7 @@ async function hubManageHandler(client, rawInput) {
|
|
|
2489
2537
|
try {
|
|
2490
2538
|
const parsed = hubInputSchema.safeParse(rawInput ?? {});
|
|
2491
2539
|
if (!parsed.success) {
|
|
2492
|
-
throw new HubToolError(
|
|
2493
|
-
"INVALID_INPUT",
|
|
2494
|
-
parsed.error.issues.map(
|
|
2495
|
-
(issue) => `${issue.path.join(".") || "input"}: ${issue.message}`
|
|
2496
|
-
).join("; ")
|
|
2497
|
-
);
|
|
2540
|
+
throw new HubToolError("INVALID_INPUT", inputIssuesMessage(parsed.error));
|
|
2498
2541
|
}
|
|
2499
2542
|
const input = parsed.data;
|
|
2500
2543
|
const { action } = input;
|
|
@@ -2527,7 +2570,7 @@ async function hubManageHandler(client, rawInput) {
|
|
|
2527
2570
|
return await handleNoteAdd(client, projectId, flowId, input);
|
|
2528
2571
|
}
|
|
2529
2572
|
} catch (error) {
|
|
2530
|
-
return
|
|
2573
|
+
return mcpError9(error, errorHint(error, "hub", HUB_NOT_FOUND_HINT));
|
|
2531
2574
|
}
|
|
2532
2575
|
}
|
|
2533
2576
|
function createHubManageToolSpec(client) {
|
|
@@ -2555,23 +2598,23 @@ function registerHubManageTool(server, client) {
|
|
|
2555
2598
|
}
|
|
2556
2599
|
|
|
2557
2600
|
// src/tools/frame-manage.ts
|
|
2558
|
-
import { z as
|
|
2559
|
-
import { mcpResult as mcpResult9, mcpError as
|
|
2601
|
+
import { z as z10 } from "zod";
|
|
2602
|
+
import { mcpResult as mcpResult9, mcpError as mcpError10 } from "@walkeros/core";
|
|
2560
2603
|
var FRAME_ID_PATTERN2 = /^frm_[A-Za-z0-9_-]{21}$/;
|
|
2561
2604
|
var MAX_PAGE_KEY_CHARS = 1024;
|
|
2562
2605
|
var TITLE9 = "Frames";
|
|
2563
2606
|
var FRAME_MANAGE_DESCRIPTION = 'Read the frames of a measurement plan: named rectangles with marks inside them, drawn in Tag Mode or in the app. Actions: list (every frame of the project, without marks), page (the frames of one page at any depth, with marks), get (one frame with its marks). Read-only: frames are drawn and edited in Tag Mode or the app, never here. A frame name is documentation; the marks inside it carry the meaning. A frame that extends another stores only what it adds, so its tags may carry only the fields they change. Marks are { tags, note }: tags is one flat list of tags, each with an id, a kind such as entity, property or action, a name, and a parentId naming the tag it sits under; note is the frame\u2019s own description and thread. Use hub_manage action "knowledge" with a frameId or markId to read what people wrote on a frame. A markId is a tag id: a tag\u2019s id, parentId and threadRef come back literal when they have the shape the app mints, so they can be passed straight back; every other string value in the marks is wrapped as data, and so is an object key that is not a plain identifier.';
|
|
2564
2607
|
var FRAME_MANAGE_INPUT_SCHEMA = {
|
|
2565
|
-
action:
|
|
2608
|
+
action: z10.enum(["list", "page", "get"]).describe(
|
|
2566
2609
|
"list the project\u2019s frames, read one page with marks, or read one frame"
|
|
2567
2610
|
),
|
|
2568
|
-
projectId:
|
|
2611
|
+
projectId: z10.string().optional().describe(
|
|
2569
2612
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
2570
2613
|
),
|
|
2571
|
-
pageKey:
|
|
2614
|
+
pageKey: z10.string().min(1).max(MAX_PAGE_KEY_CHARS).optional().describe(
|
|
2572
2615
|
"The page as its frames address it (the `source.key` of a page frame, usually the page URL without query). Required for page."
|
|
2573
2616
|
),
|
|
2574
|
-
frameId:
|
|
2617
|
+
frameId: z10.string().regex(FRAME_ID_PATTERN2).optional().describe(
|
|
2575
2618
|
'Frame ID (frm_...). Required for get. Use action "list" or "page" to find one.'
|
|
2576
2619
|
)
|
|
2577
2620
|
};
|
|
@@ -2681,17 +2724,11 @@ function serializeFrame(frame) {
|
|
|
2681
2724
|
marks: walkMarks(frame.marks)
|
|
2682
2725
|
};
|
|
2683
2726
|
}
|
|
2684
|
-
var frameInputSchema =
|
|
2727
|
+
var frameInputSchema = z10.object(FRAME_MANAGE_INPUT_SCHEMA);
|
|
2685
2728
|
async function frameManageHandler(client, rawInput) {
|
|
2686
2729
|
const parsed = frameInputSchema.safeParse(rawInput ?? {});
|
|
2687
2730
|
if (!parsed.success) {
|
|
2688
|
-
return
|
|
2689
|
-
new Error(
|
|
2690
|
-
parsed.error.issues.map(
|
|
2691
|
-
(issue) => `${issue.path.join(".") || "input"}: ${issue.message}`
|
|
2692
|
-
).join("; ")
|
|
2693
|
-
)
|
|
2694
|
-
);
|
|
2731
|
+
return mcpError10(new Error(inputIssuesMessage(parsed.error)));
|
|
2695
2732
|
}
|
|
2696
2733
|
const { action, projectId, pageKey, frameId } = parsed.data;
|
|
2697
2734
|
const validationError = validateActionInput(
|
|
@@ -2700,11 +2737,11 @@ async function frameManageHandler(client, rawInput) {
|
|
|
2700
2737
|
{ pageKey, frameId },
|
|
2701
2738
|
FRAME_MANAGE_REQUIREMENTS
|
|
2702
2739
|
);
|
|
2703
|
-
if (validationError) return
|
|
2740
|
+
if (validationError) return mcpError10(new Error(validationError));
|
|
2704
2741
|
try {
|
|
2705
2742
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
2706
2743
|
if (!resolvedProjectId) {
|
|
2707
|
-
return
|
|
2744
|
+
return mcpError10(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
2708
2745
|
}
|
|
2709
2746
|
switch (action) {
|
|
2710
2747
|
case "list": {
|
|
@@ -2749,7 +2786,7 @@ async function frameManageHandler(client, rawInput) {
|
|
|
2749
2786
|
}
|
|
2750
2787
|
}
|
|
2751
2788
|
} catch (error) {
|
|
2752
|
-
return
|
|
2789
|
+
return mcpError10(error, errorHint(error, "frames", FRAME_NOT_FOUND_HINT));
|
|
2753
2790
|
}
|
|
2754
2791
|
}
|
|
2755
2792
|
function createFrameManageToolSpec(client) {
|
|
@@ -2777,13 +2814,13 @@ function registerFrameManageTool(server, client) {
|
|
|
2777
2814
|
}
|
|
2778
2815
|
|
|
2779
2816
|
// src/tools/feedback.ts
|
|
2780
|
-
import { z as
|
|
2781
|
-
import { mcpResult as mcpResult10, mcpError as
|
|
2817
|
+
import { z as z11 } from "zod";
|
|
2818
|
+
import { mcpResult as mcpResult10, mcpError as mcpError11 } from "@walkeros/core";
|
|
2782
2819
|
var TITLE10 = "Send Feedback";
|
|
2783
2820
|
var DESCRIPTION8 = "Send feedback about walkerOS";
|
|
2784
2821
|
var inputSchema8 = {
|
|
2785
|
-
text:
|
|
2786
|
-
anonymous:
|
|
2822
|
+
text: z11.string().describe("Your feedback text"),
|
|
2823
|
+
anonymous: z11.boolean().optional().describe(
|
|
2787
2824
|
"Include user/project info? false = include, true = anonymous. Only needed on first call if not yet configured."
|
|
2788
2825
|
)
|
|
2789
2826
|
};
|
|
@@ -2804,7 +2841,9 @@ function createFeedbackToolSpec(client) {
|
|
|
2804
2841
|
};
|
|
2805
2842
|
}
|
|
2806
2843
|
async function feedbackHandlerBody(client, input) {
|
|
2807
|
-
const
|
|
2844
|
+
const parsed = parseToolInput(inputSchema8, input);
|
|
2845
|
+
if (!parsed.ok) return parsed.error;
|
|
2846
|
+
const { text, anonymous: explicitAnonymous } = parsed.data;
|
|
2808
2847
|
try {
|
|
2809
2848
|
let anonymous = client.getFeedbackPreference();
|
|
2810
2849
|
if (anonymous === void 0 && explicitAnonymous === void 0) {
|
|
@@ -2825,11 +2864,11 @@ async function feedbackHandlerBody(client, input) {
|
|
|
2825
2864
|
const isAnonymous = explicitAnonymous ?? anonymous ?? true;
|
|
2826
2865
|
await client.submitFeedback(text, {
|
|
2827
2866
|
anonymous: isAnonymous,
|
|
2828
|
-
version: "4.7.0
|
|
2867
|
+
version: "4.7.0"
|
|
2829
2868
|
});
|
|
2830
2869
|
return mcpResult10({ ok: true });
|
|
2831
2870
|
} catch (error) {
|
|
2832
|
-
return
|
|
2871
|
+
return mcpError11(error);
|
|
2833
2872
|
}
|
|
2834
2873
|
}
|
|
2835
2874
|
function registerFeedbackTool(server, client) {
|
|
@@ -2842,113 +2881,135 @@ function registerFeedbackTool(server, client) {
|
|
|
2842
2881
|
inputSchema: spec.inputSchema,
|
|
2843
2882
|
annotations: spec.annotations
|
|
2844
2883
|
},
|
|
2845
|
-
|
|
2846
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
2847
|
-
spec.handler
|
|
2884
|
+
(args) => feedbackHandlerBody(client, args)
|
|
2848
2885
|
);
|
|
2849
2886
|
}
|
|
2850
2887
|
|
|
2851
2888
|
// src/tools/validate.ts
|
|
2852
2889
|
import { validate } from "@walkeros/cli";
|
|
2853
|
-
import { schemas } from "@walkeros/cli/dev";
|
|
2854
|
-
import { mcpResult as mcpResult11, mcpError as
|
|
2890
|
+
import { schemas as schemas2 } from "@walkeros/cli/dev";
|
|
2891
|
+
import { mcpResult as mcpResult11, mcpError as mcpError12 } from "@walkeros/core";
|
|
2855
2892
|
|
|
2856
2893
|
// src/schemas/output.ts
|
|
2857
|
-
import { z as
|
|
2894
|
+
import { z as z12 } from "zod";
|
|
2895
|
+
var ValidateIssueFields = {
|
|
2896
|
+
path: z12.string(),
|
|
2897
|
+
message: z12.string(),
|
|
2898
|
+
value: z12.unknown().optional(),
|
|
2899
|
+
code: z12.string().optional().describe("Stable code (the documented validate code list)"),
|
|
2900
|
+
keyword: z12.string().optional().describe("JSON Schema keyword of an ENTRY_SCHEMA finding")
|
|
2901
|
+
};
|
|
2858
2902
|
var ValidateOutputShape = {
|
|
2859
|
-
valid:
|
|
2860
|
-
type:
|
|
2861
|
-
|
|
2862
|
-
|
|
2903
|
+
valid: z12.boolean().describe("Whether validation passed"),
|
|
2904
|
+
type: z12.union([
|
|
2905
|
+
z12.enum(["contract", "entry", "event", "flow", "mapping"]),
|
|
2906
|
+
z12.string().regex(/^(destinations|sources|transformers)\.\w+$/)
|
|
2863
2907
|
]).describe("What was validated"),
|
|
2864
|
-
errors:
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
code: z11.string().optional()
|
|
2870
|
-
})
|
|
2871
|
-
).describe("Validation errors"),
|
|
2872
|
-
warnings: z11.array(
|
|
2873
|
-
z11.object({
|
|
2874
|
-
path: z11.string(),
|
|
2875
|
-
message: z11.string(),
|
|
2876
|
-
suggestion: z11.string().optional()
|
|
2908
|
+
errors: z12.array(z12.object(ValidateIssueFields)).describe("Validation errors"),
|
|
2909
|
+
warnings: z12.array(
|
|
2910
|
+
z12.object({
|
|
2911
|
+
...ValidateIssueFields,
|
|
2912
|
+
suggestion: z12.string().optional()
|
|
2877
2913
|
})
|
|
2878
2914
|
).describe("Validation warnings"),
|
|
2879
|
-
details:
|
|
2915
|
+
details: z12.object({
|
|
2916
|
+
scope: z12.object({
|
|
2917
|
+
flows: z12.array(z12.string()),
|
|
2918
|
+
entry: z12.object({
|
|
2919
|
+
section: z12.string().optional(),
|
|
2920
|
+
key: z12.string(),
|
|
2921
|
+
flows: z12.array(z12.string()),
|
|
2922
|
+
searchedFlows: z12.array(z12.string())
|
|
2923
|
+
}).optional(),
|
|
2924
|
+
checks: z12.array(z12.string()),
|
|
2925
|
+
offline: z12.literal(true).optional()
|
|
2926
|
+
}).optional().describe("What the run covered"),
|
|
2927
|
+
skipped: z12.array(
|
|
2928
|
+
z12.object({
|
|
2929
|
+
path: z12.string(),
|
|
2930
|
+
check: z12.string(),
|
|
2931
|
+
reason: z12.string(),
|
|
2932
|
+
code: z12.string()
|
|
2933
|
+
})
|
|
2934
|
+
).optional().describe("Checks in scope that did not run, with the reason"),
|
|
2935
|
+
deferred: z12.array(z12.object({ path: z12.string(), reference: z12.string() })).optional().describe("Values known only at runtime, not schema-checked")
|
|
2936
|
+
}).catchall(z12.unknown()).describe("Additional validation details"),
|
|
2937
|
+
_hints: z12.object({
|
|
2938
|
+
next: z12.array(z12.string()).optional(),
|
|
2939
|
+
warnings: z12.array(z12.string()).optional()
|
|
2940
|
+
}).optional().describe("Suggested next steps")
|
|
2880
2941
|
};
|
|
2881
2942
|
var BundleOutputShape = {
|
|
2882
|
-
success:
|
|
2883
|
-
totalSize:
|
|
2884
|
-
buildTime:
|
|
2885
|
-
packages:
|
|
2886
|
-
|
|
2887
|
-
name:
|
|
2943
|
+
success: z12.boolean().describe("Whether bundling succeeded"),
|
|
2944
|
+
totalSize: z12.number().optional().describe("Total bundle size in bytes"),
|
|
2945
|
+
buildTime: z12.number().optional().describe("Build time in milliseconds"),
|
|
2946
|
+
packages: z12.array(
|
|
2947
|
+
z12.object({
|
|
2948
|
+
name: z12.string()
|
|
2888
2949
|
})
|
|
2889
2950
|
).optional().describe("Names of packages included in the bundle"),
|
|
2890
|
-
treeshakingEffective:
|
|
2891
|
-
message:
|
|
2951
|
+
treeshakingEffective: z12.boolean().optional().describe("Whether tree-shaking was effective"),
|
|
2952
|
+
message: z12.string().optional().describe("Status message")
|
|
2892
2953
|
};
|
|
2893
2954
|
var SimulateOutputShape = {
|
|
2894
|
-
success:
|
|
2895
|
-
error:
|
|
2896
|
-
summary:
|
|
2897
|
-
destinations:
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
received:
|
|
2901
|
-
calls:
|
|
2902
|
-
payload:
|
|
2955
|
+
success: z12.boolean().describe("Whether simulation succeeded"),
|
|
2956
|
+
error: z12.string().optional().describe("Error message if failed"),
|
|
2957
|
+
summary: z12.string().describe("One-line result summary"),
|
|
2958
|
+
destinations: z12.record(
|
|
2959
|
+
z12.string(),
|
|
2960
|
+
z12.object({
|
|
2961
|
+
received: z12.boolean().describe("Whether destination received the event"),
|
|
2962
|
+
calls: z12.number().describe("Number of API calls made"),
|
|
2963
|
+
payload: z12.unknown().optional().describe("All intercepted API calls (only when verbose: true)")
|
|
2903
2964
|
})
|
|
2904
2965
|
).optional().describe("Per-destination results"),
|
|
2905
|
-
capturedEvents:
|
|
2906
|
-
calls:
|
|
2966
|
+
capturedEvents: z12.array(z12.record(z12.string(), z12.unknown())).optional().describe("Events captured by source simulation"),
|
|
2967
|
+
calls: z12.array(z12.unknown()).optional().describe(
|
|
2907
2968
|
"Calls a simulated source made on its mock env (only when verbose: true)"
|
|
2908
2969
|
),
|
|
2909
|
-
skipped:
|
|
2910
|
-
reason:
|
|
2911
|
-
required:
|
|
2912
|
-
granted:
|
|
2913
|
-
require:
|
|
2970
|
+
skipped: z12.object({
|
|
2971
|
+
reason: z12.enum(["consent", "pending"]),
|
|
2972
|
+
required: z12.record(z12.string(), z12.boolean()).optional(),
|
|
2973
|
+
granted: z12.record(z12.string(), z12.boolean()).optional(),
|
|
2974
|
+
require: z12.array(z12.string()).optional()
|
|
2914
2975
|
}).optional().describe(
|
|
2915
2976
|
"Why the destination sent nothing: a consent skip, or waiting for its require"
|
|
2916
2977
|
),
|
|
2917
|
-
duration:
|
|
2978
|
+
duration: z12.number().optional().describe("Simulation duration in ms")
|
|
2918
2979
|
};
|
|
2919
2980
|
var PushOutputShape = {
|
|
2920
|
-
success:
|
|
2921
|
-
elbResult:
|
|
2922
|
-
duration:
|
|
2923
|
-
error:
|
|
2981
|
+
success: z12.boolean().describe("Whether push succeeded"),
|
|
2982
|
+
elbResult: z12.unknown().optional().describe("Push result from the collector"),
|
|
2983
|
+
duration: z12.number().describe("Push duration in milliseconds"),
|
|
2984
|
+
error: z12.string().optional().describe("Error message if push failed")
|
|
2924
2985
|
};
|
|
2925
2986
|
var ExamplesListOutputShape = {
|
|
2926
|
-
flow:
|
|
2927
|
-
count:
|
|
2928
|
-
examples:
|
|
2929
|
-
|
|
2930
|
-
step:
|
|
2931
|
-
stepType:
|
|
2932
|
-
stepName:
|
|
2933
|
-
exampleName:
|
|
2934
|
-
source:
|
|
2987
|
+
flow: z12.string().describe("Flow name"),
|
|
2988
|
+
count: z12.number().describe("Number of examples found"),
|
|
2989
|
+
examples: z12.array(
|
|
2990
|
+
z12.object({
|
|
2991
|
+
step: z12.string().describe('Step location (e.g., "destination.gtag")'),
|
|
2992
|
+
stepType: z12.enum(["source", "transformer", "destination"]).describe("Step type"),
|
|
2993
|
+
stepName: z12.string().describe("Step name"),
|
|
2994
|
+
exampleName: z12.string().describe("Example name"),
|
|
2995
|
+
source: z12.enum(["inline", "package"]).describe(
|
|
2935
2996
|
'Where the example came from: "inline" (defined in the flow step) or "package" (shipped by the referenced package)'
|
|
2936
2997
|
),
|
|
2937
|
-
title:
|
|
2938
|
-
description:
|
|
2939
|
-
public:
|
|
2998
|
+
title: z12.string().optional().describe("Human-readable title if set"),
|
|
2999
|
+
description: z12.string().optional().describe("Short human-readable description"),
|
|
3000
|
+
public: z12.boolean().optional().describe(
|
|
2940
3001
|
"Whether the example is public (defaults to true if omitted)"
|
|
2941
3002
|
),
|
|
2942
|
-
hasIn:
|
|
2943
|
-
hasOut:
|
|
2944
|
-
hasMapping:
|
|
2945
|
-
hasTrigger:
|
|
2946
|
-
in:
|
|
2947
|
-
out:
|
|
2948
|
-
mapping:
|
|
2949
|
-
trigger:
|
|
2950
|
-
type:
|
|
2951
|
-
options:
|
|
3003
|
+
hasIn: z12.boolean().describe("Whether the example has an input value"),
|
|
3004
|
+
hasOut: z12.boolean().describe("Whether the example has an output value"),
|
|
3005
|
+
hasMapping: z12.boolean().describe("Whether the example has a mapping configuration"),
|
|
3006
|
+
hasTrigger: z12.boolean().describe("Whether the example has trigger metadata"),
|
|
3007
|
+
in: z12.unknown().optional().describe("Input event data"),
|
|
3008
|
+
out: z12.unknown().optional().describe("Expected output data"),
|
|
3009
|
+
mapping: z12.unknown().optional().describe("Mapping configuration for destinations"),
|
|
3010
|
+
trigger: z12.object({
|
|
3011
|
+
type: z12.string().optional(),
|
|
3012
|
+
options: z12.unknown().optional()
|
|
2952
3013
|
}).optional().describe("Trigger metadata for source simulation")
|
|
2953
3014
|
})
|
|
2954
3015
|
).describe("Step examples")
|
|
@@ -2971,42 +3032,14 @@ async function loadValidateInput(runtime, input, type) {
|
|
|
2971
3032
|
throw error;
|
|
2972
3033
|
}
|
|
2973
3034
|
}
|
|
2974
|
-
var DEPRECATED_STORE_PACKAGE = "@walkeros/store-memory";
|
|
2975
|
-
function detectDeprecatedStorePackages(config) {
|
|
2976
|
-
const errors = [];
|
|
2977
|
-
if (!config || typeof config !== "object") return errors;
|
|
2978
|
-
const flows = config.flows;
|
|
2979
|
-
if (!flows || typeof flows !== "object") return errors;
|
|
2980
|
-
for (const [flowName, flowEntry] of Object.entries(
|
|
2981
|
-
flows
|
|
2982
|
-
)) {
|
|
2983
|
-
if (!flowEntry || typeof flowEntry !== "object") continue;
|
|
2984
|
-
const stores = flowEntry.stores;
|
|
2985
|
-
if (!stores || typeof stores !== "object") continue;
|
|
2986
|
-
for (const [storeId, storeEntry] of Object.entries(
|
|
2987
|
-
stores
|
|
2988
|
-
)) {
|
|
2989
|
-
if (!storeEntry || typeof storeEntry !== "object") continue;
|
|
2990
|
-
const pkg = storeEntry.package;
|
|
2991
|
-
if (pkg === DEPRECATED_STORE_PACKAGE) {
|
|
2992
|
-
errors.push({
|
|
2993
|
-
path: `flows.${flowName}.stores.${storeId}`,
|
|
2994
|
-
message: `Store "${storeId}" uses ${DEPRECATED_STORE_PACKAGE}, which has been removed. Use the built-in cache by omitting cache.store, or remove the store declaration if it was only used as a cache target.`,
|
|
2995
|
-
code: "DEPRECATED_PACKAGE"
|
|
2996
|
-
});
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
|
-
}
|
|
3000
|
-
return errors;
|
|
3001
|
-
}
|
|
3002
3035
|
var TITLE11 = "Validate Flow";
|
|
3003
|
-
var DESCRIPTION9 = "Validate walkerOS events, flow configurations, mapping rules, or data contracts. Accepts JSON strings, file paths, or URLs as input; on the hosted server only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. Returns
|
|
3004
|
-
var inputSchema9 =
|
|
3036
|
+
var DESCRIPTION9 = "Validate walkerOS events, flow configurations, mapping rules, or data contracts. Accepts JSON strings, file paths, or URLs as input; on the hosted server only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. With only type and input, a flow runs every check on every flow and step, including each package's settings schema (fetched from the package CDN; offline: true skips that and says so). flow and path narrow the run; strict turns warnings and skips into failures: valid is false. Returns valid, errors and warnings with stable codes, and details.scope (what was checked), details.skipped (checks that could not run) and details.deferred (values known only at runtime).";
|
|
3037
|
+
var inputSchema9 = schemas2.ValidateInputShape;
|
|
3005
3038
|
var annotations11 = {
|
|
3006
3039
|
readOnlyHint: true,
|
|
3007
3040
|
destructiveHint: false,
|
|
3008
3041
|
idempotentHint: true,
|
|
3009
|
-
openWorldHint:
|
|
3042
|
+
openWorldHint: true
|
|
3010
3043
|
};
|
|
3011
3044
|
function createFlowValidateToolSpec(runtime) {
|
|
3012
3045
|
return {
|
|
@@ -3019,43 +3052,48 @@ function createFlowValidateToolSpec(runtime) {
|
|
|
3019
3052
|
};
|
|
3020
3053
|
}
|
|
3021
3054
|
async function flowValidateHandlerBody(runtime, input) {
|
|
3055
|
+
const parsed = schemas2.ValidateInputSchema.safeParse(input ?? {});
|
|
3056
|
+
if (!parsed.success) {
|
|
3057
|
+
return mcpError12(parsed.error, "Check the flow_validate input fields");
|
|
3058
|
+
}
|
|
3022
3059
|
const {
|
|
3023
3060
|
type,
|
|
3024
3061
|
input: validateInput,
|
|
3025
3062
|
flow,
|
|
3026
|
-
path:
|
|
3027
|
-
|
|
3063
|
+
path: path3,
|
|
3064
|
+
strict,
|
|
3065
|
+
offline
|
|
3066
|
+
} = parsed.data;
|
|
3028
3067
|
try {
|
|
3029
3068
|
const resolved = await loadValidateInput(runtime, validateInput, type);
|
|
3069
|
+
const configDir = runtime.baseDir?.(validateInput);
|
|
3030
3070
|
const result = await validate(type, resolved, {
|
|
3031
3071
|
flow,
|
|
3032
|
-
path:
|
|
3072
|
+
path: path3,
|
|
3073
|
+
strict,
|
|
3074
|
+
offline,
|
|
3075
|
+
...configDir ? { configDir } : {}
|
|
3033
3076
|
});
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
errors: [...result.errors, ...deprecatedErrors]
|
|
3042
|
-
};
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
const hints = augmented.valid ? {
|
|
3046
|
-
next: runtime.simulate ? [
|
|
3047
|
-
"Use flow_simulate to test event flow",
|
|
3048
|
-
"Use flow_bundle to build"
|
|
3049
|
-
] : [HINT_OUT_OF_PROCESS]
|
|
3050
|
-
} : {
|
|
3077
|
+
const skipped = result.details.skipped ?? [];
|
|
3078
|
+
const next = runtime.simulate ? ["Use flow_simulate to test event flow", "Use flow_bundle to build"] : [HINT_OUT_OF_PROCESS];
|
|
3079
|
+
const hints = !result.valid && result.errors.length === 0 ? {
|
|
3080
|
+
next: [
|
|
3081
|
+
`strict: ${result.warnings.length} warning(s) and ${skipped.length} skipped check(s) count as failures; resolve them, or run without strict`
|
|
3082
|
+
]
|
|
3083
|
+
} : !result.valid ? {
|
|
3051
3084
|
next: [
|
|
3052
3085
|
"Fix errors above, then run flow_validate again",
|
|
3053
3086
|
"Read walkeros://reference/flow-schema for correct structure"
|
|
3054
3087
|
]
|
|
3055
|
-
}
|
|
3056
|
-
|
|
3088
|
+
} : skipped.length > 0 ? {
|
|
3089
|
+
next: [
|
|
3090
|
+
`Valid in checked scope; ${skipped.length} check(s) skipped, see details.skipped`,
|
|
3091
|
+
...next
|
|
3092
|
+
]
|
|
3093
|
+
} : { next };
|
|
3094
|
+
return mcpResult11(result, hints);
|
|
3057
3095
|
} catch (error) {
|
|
3058
|
-
return
|
|
3096
|
+
return mcpError12(
|
|
3059
3097
|
error,
|
|
3060
3098
|
refusalHint(
|
|
3061
3099
|
error,
|
|
@@ -3076,15 +3114,13 @@ function registerFlowValidateTool(server, runtime) {
|
|
|
3076
3114
|
outputSchema: ValidateOutputShape,
|
|
3077
3115
|
annotations: spec.annotations
|
|
3078
3116
|
},
|
|
3079
|
-
|
|
3080
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
3081
|
-
spec.handler
|
|
3117
|
+
(args) => flowValidateHandlerBody(runtime, args)
|
|
3082
3118
|
);
|
|
3083
3119
|
}
|
|
3084
3120
|
|
|
3085
3121
|
// src/tools/bundle.ts
|
|
3086
|
-
import { schemas as
|
|
3087
|
-
import { mcpResult as mcpResult12, mcpError as
|
|
3122
|
+
import { schemas as schemas3 } from "@walkeros/cli/dev";
|
|
3123
|
+
import { mcpResult as mcpResult12, mcpError as mcpError13 } from "@walkeros/core";
|
|
3088
3124
|
|
|
3089
3125
|
// src/tools/resolve-config-path.ts
|
|
3090
3126
|
async function resolveConfigPath(client, configPath) {
|
|
@@ -3097,7 +3133,7 @@ async function resolveConfigPath(client, configPath) {
|
|
|
3097
3133
|
var TITLE12 = "Bundle Flow";
|
|
3098
3134
|
var DESCRIPTION10 = "Bundle a walkerOS flow configuration into deployable JavaScript. Resolves all destinations, sources, and transformers, then outputs a tree-shaken production bundle. Returns bundle statistics.";
|
|
3099
3135
|
var inputSchema10 = {
|
|
3100
|
-
...
|
|
3136
|
+
...schemas3.BundleInputShape
|
|
3101
3137
|
};
|
|
3102
3138
|
var annotations12 = {
|
|
3103
3139
|
readOnlyHint: false,
|
|
@@ -3116,10 +3152,12 @@ function createFlowBundleToolSpec(client, runtime) {
|
|
|
3116
3152
|
};
|
|
3117
3153
|
}
|
|
3118
3154
|
async function flowBundleHandlerBody(client, runtime, input) {
|
|
3119
|
-
const
|
|
3155
|
+
const parsed = parseToolInput(inputSchema10, input);
|
|
3156
|
+
if (!parsed.ok) return parsed.error;
|
|
3157
|
+
const { configPath, flow, stats, output } = parsed.data;
|
|
3120
3158
|
if (!runtime.bundle) {
|
|
3121
3159
|
const refusal = unavailableOperation("bundle");
|
|
3122
|
-
return
|
|
3160
|
+
return mcpError13(refusal, refusal.hint);
|
|
3123
3161
|
}
|
|
3124
3162
|
try {
|
|
3125
3163
|
const resolvedConfigPath = await resolveConfigPath(client, configPath);
|
|
@@ -3139,9 +3177,8 @@ async function flowBundleHandlerBody(client, runtime, input) {
|
|
|
3139
3177
|
}
|
|
3140
3178
|
);
|
|
3141
3179
|
}
|
|
3142
|
-
const output_ = result;
|
|
3143
3180
|
return mcpResult12(
|
|
3144
|
-
{ success: true, ...
|
|
3181
|
+
{ success: true, ...result },
|
|
3145
3182
|
{
|
|
3146
3183
|
next: [
|
|
3147
3184
|
"Use flow_simulate to test",
|
|
@@ -3150,7 +3187,7 @@ async function flowBundleHandlerBody(client, runtime, input) {
|
|
|
3150
3187
|
}
|
|
3151
3188
|
);
|
|
3152
3189
|
} catch (error) {
|
|
3153
|
-
return
|
|
3190
|
+
return mcpError13(
|
|
3154
3191
|
error,
|
|
3155
3192
|
refusalHint(error, "Run flow_validate for detailed error messages")
|
|
3156
3193
|
);
|
|
@@ -3168,54 +3205,39 @@ function registerFlowBundleTool(server, client, runtime) {
|
|
|
3168
3205
|
outputSchema: BundleOutputShape,
|
|
3169
3206
|
annotations: spec.annotations
|
|
3170
3207
|
},
|
|
3171
|
-
|
|
3172
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
3173
|
-
spec.handler
|
|
3208
|
+
(args) => flowBundleHandlerBody(client, runtime, args)
|
|
3174
3209
|
);
|
|
3175
3210
|
}
|
|
3176
3211
|
|
|
3177
3212
|
// src/tools/simulate.ts
|
|
3178
|
-
import { z as
|
|
3179
|
-
import { schemas as
|
|
3180
|
-
import {
|
|
3181
|
-
import { scrubSecrets, toPrintable } from "@walkeros/core/node";
|
|
3182
|
-
import { maskKnownNumbers } from "@walkeros/cli";
|
|
3213
|
+
import { z as z13 } from "zod";
|
|
3214
|
+
import { schemas as schemas4 } from "@walkeros/cli/dev";
|
|
3215
|
+
import { filterValues, mcpResult as mcpResult14, mcpError as mcpError15 } from "@walkeros/core";
|
|
3183
3216
|
|
|
3184
3217
|
// src/tools/simulate-description.ts
|
|
3185
3218
|
var FLOW_SIMULATE_DESCRIPTION = `Simulate events through a walkerOS flow without making real API calls. For destinations: event is a walkerOS event { name: "entity action", data: {...} }. For sources: event is { content, trigger?: { type?, options? } }, where content is the walkerOS event { name: "entity action", data: {...} }. Only the simulated source starts. step (required) targets the step to simulate, e.g. "destination.gtag". Use flow_examples to discover available test data. A destination simulation starts only its target destination. A source's own walker commands (e.g. a CMP's walker consent) are returned as elb calls. Consent: state.consent is the collector consent the step starts from (any step; a consent-gated source such as the session source waits for it). A destination with require: ["consent"] waits until consent is present, so pass state.consent to start it; a destination with consent: { marketing: true } receives an event only when that consent is granted in state.consent or in the event's own consent. When a destination sends nothing, the result says why (waiting for its require, or a consent skip). command runs a step example with command (e.g. "consent") on a destination: event is the command's data, state.consent still applies first. Mapping transforms event names and data at the destination level. Policy redacts or injects fields before mapping runs.`;
|
|
3186
3219
|
|
|
3187
|
-
// src/tools/
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
"transformer",
|
|
3191
|
-
"collector",
|
|
3192
|
-
"destination"
|
|
3193
|
-
];
|
|
3194
|
-
function isStepType(value) {
|
|
3195
|
-
return STEP_TYPES.some((t) => t === value);
|
|
3196
|
-
}
|
|
3220
|
+
// src/tools/egress.ts
|
|
3221
|
+
import { isObject as isObject2, mcpResult as mcpResult13 } from "@walkeros/core";
|
|
3222
|
+
import { scrubJson, scrubSecrets } from "@walkeros/core/node";
|
|
3197
3223
|
function scrubbed(result, known) {
|
|
3198
|
-
const
|
|
3199
|
-
|
|
3200
|
-
{ known }
|
|
3201
|
-
);
|
|
3202
|
-
let parsed;
|
|
3203
|
-
try {
|
|
3204
|
-
parsed = JSON.parse(text);
|
|
3205
|
-
} catch {
|
|
3206
|
-
parsed = void 0;
|
|
3207
|
-
}
|
|
3208
|
-
if (!isObject2(parsed))
|
|
3209
|
-
throw new Error("Simulation result could not be redacted as JSON.");
|
|
3224
|
+
const parsed = parseObject(scrubJson(result, { known }));
|
|
3225
|
+
if (!parsed) throw new Error("Result could not be redacted as JSON.");
|
|
3210
3226
|
return parsed;
|
|
3211
3227
|
}
|
|
3212
3228
|
function scrubbedError(response, known) {
|
|
3213
3229
|
let structuredContent;
|
|
3214
3230
|
try {
|
|
3215
|
-
|
|
3231
|
+
if (response.structuredContent)
|
|
3232
|
+
structuredContent = scrubbed(response.structuredContent, known);
|
|
3216
3233
|
} catch {
|
|
3217
|
-
structuredContent =
|
|
3218
|
-
|
|
3234
|
+
structuredContent = void 0;
|
|
3235
|
+
}
|
|
3236
|
+
if (structuredContent) {
|
|
3237
|
+
return {
|
|
3238
|
+
...response,
|
|
3239
|
+
content: [{ type: "text", text: JSON.stringify(structuredContent) }],
|
|
3240
|
+
structuredContent
|
|
3219
3241
|
};
|
|
3220
3242
|
}
|
|
3221
3243
|
return {
|
|
@@ -3224,9 +3246,48 @@ function scrubbedError(response, known) {
|
|
|
3224
3246
|
...part,
|
|
3225
3247
|
text: scrubSecrets(part.text, { known })
|
|
3226
3248
|
})),
|
|
3227
|
-
structuredContent
|
|
3249
|
+
structuredContent: { error: "The error could not be redacted." }
|
|
3250
|
+
};
|
|
3251
|
+
}
|
|
3252
|
+
function scrubbedPushResult(result, known) {
|
|
3253
|
+
const text = scrubJson(result, { known, space: 2 });
|
|
3254
|
+
const parsed = parseObject(text);
|
|
3255
|
+
if (parsed)
|
|
3256
|
+
return mcpResult13({
|
|
3257
|
+
...parsed,
|
|
3258
|
+
success: result.success,
|
|
3259
|
+
duration: result.duration
|
|
3260
|
+
});
|
|
3261
|
+
return {
|
|
3262
|
+
content: [{ type: "text", text }],
|
|
3263
|
+
structuredContent: { success: result.success, duration: result.duration }
|
|
3264
|
+
};
|
|
3265
|
+
}
|
|
3266
|
+
function parseObject(text) {
|
|
3267
|
+
try {
|
|
3268
|
+
const parsed = JSON.parse(text);
|
|
3269
|
+
return isObject2(parsed) ? parsed : void 0;
|
|
3270
|
+
} catch {
|
|
3271
|
+
return void 0;
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
async function readRun(runtime, input) {
|
|
3275
|
+
if (runtime.loadRun) return runtime.loadRun(input);
|
|
3276
|
+
return {
|
|
3277
|
+
knownSecrets: runtime.knownSecrets ? await runtime.knownSecrets(input) : []
|
|
3228
3278
|
};
|
|
3229
3279
|
}
|
|
3280
|
+
|
|
3281
|
+
// src/tools/simulate.ts
|
|
3282
|
+
var STEP_TYPES = [
|
|
3283
|
+
"source",
|
|
3284
|
+
"transformer",
|
|
3285
|
+
"collector",
|
|
3286
|
+
"destination"
|
|
3287
|
+
];
|
|
3288
|
+
function isStepType(value) {
|
|
3289
|
+
return STEP_TYPES.some((t) => t === value);
|
|
3290
|
+
}
|
|
3230
3291
|
var TITLE13 = "Simulate Flow";
|
|
3231
3292
|
var COMMANDS = [
|
|
3232
3293
|
"config",
|
|
@@ -3235,30 +3296,30 @@ var COMMANDS = [
|
|
|
3235
3296
|
"run"
|
|
3236
3297
|
];
|
|
3237
3298
|
var inputSchema11 = {
|
|
3238
|
-
configPath:
|
|
3239
|
-
event:
|
|
3299
|
+
configPath: schemas4.SimulateInputShape.configPath,
|
|
3300
|
+
event: z13.union([z13.record(z13.string(), z13.unknown()), z13.string()]).optional().describe(
|
|
3240
3301
|
"For destinations: { name, data, consent? }; the event's consent counts toward the destination's consent requirement, on top of state.consent. With command: the command's data, e.g. { marketing: true } for consent. For sources: { content, trigger? } where content is the walkerOS event { name, data }. A web source's page URL goes in trigger.options.url (default http://localhost). Can also be a JSON string or file path."
|
|
3241
3302
|
),
|
|
3242
|
-
flow:
|
|
3243
|
-
platform:
|
|
3303
|
+
flow: schemas4.SimulateInputShape.flow,
|
|
3304
|
+
platform: schemas4.SimulateInputShape.platform,
|
|
3244
3305
|
// Override the (optional) CLI `step` shape: the simulate handler hard-requires
|
|
3245
3306
|
// a target step (no all-steps mode), so the registered schema must be honest.
|
|
3246
|
-
step:
|
|
3307
|
+
step: z13.string().describe(
|
|
3247
3308
|
'Required. Target step as "type.name", e.g. "source.demo", "collector.default", "destination.gtag", "transformer.router". A collector step runs enrichment and then collector.next, returning every event the destinations would receive (none after a stop).'
|
|
3248
3309
|
),
|
|
3249
|
-
verbose:
|
|
3250
|
-
ingest:
|
|
3310
|
+
verbose: z13.boolean().optional().describe("Include full payload per destination (default: false)"),
|
|
3311
|
+
ingest: z13.record(z13.string(), z13.unknown()).optional().describe(
|
|
3251
3312
|
"Pipeline context a step reads via ctx.ingest, e.g. { url } for a request decoder or { ip, userAgent } for a conversion API. Used for transformer, collector and destination steps (their before chains included); _meta is always set by the runtime."
|
|
3252
3313
|
),
|
|
3253
|
-
state:
|
|
3254
|
-
consent:
|
|
3255
|
-
user:
|
|
3256
|
-
globals:
|
|
3257
|
-
timing:
|
|
3314
|
+
state: z13.object({
|
|
3315
|
+
consent: z13.record(z13.string(), z13.boolean()).optional(),
|
|
3316
|
+
user: z13.record(z13.string(), z13.unknown()).optional(),
|
|
3317
|
+
globals: z13.record(z13.string(), z13.unknown()).optional(),
|
|
3318
|
+
timing: z13.number().optional()
|
|
3258
3319
|
}).optional().describe(
|
|
3259
3320
|
"Collector state the step starts from. consent: every step (starts a destination that requires consent and feeds its consent check; for a source, the consent a consent-gated source waits for). user/globals/timing: collector steps, seeded before enrichment runs."
|
|
3260
3321
|
),
|
|
3261
|
-
command:
|
|
3322
|
+
command: z13.enum(COMMANDS).optional().describe(
|
|
3262
3323
|
"Destination steps only: run this collector command with event as its data instead of pushing it, as a step example with command does."
|
|
3263
3324
|
)
|
|
3264
3325
|
};
|
|
@@ -3282,7 +3343,18 @@ function createFlowSimulateToolSpec(client, runtime) {
|
|
|
3282
3343
|
handler: (input) => flowSimulateHandlerBody(client, runtime, input)
|
|
3283
3344
|
};
|
|
3284
3345
|
}
|
|
3346
|
+
function toProperties(value) {
|
|
3347
|
+
if (!value) return void 0;
|
|
3348
|
+
const properties = {};
|
|
3349
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
3350
|
+
const property = filterValues(entry);
|
|
3351
|
+
if (property !== void 0) properties[key] = property;
|
|
3352
|
+
}
|
|
3353
|
+
return properties;
|
|
3354
|
+
}
|
|
3285
3355
|
async function flowSimulateHandlerBody(client, runtime, input) {
|
|
3356
|
+
const parsed = parseToolInput(inputSchema11, input);
|
|
3357
|
+
if (!parsed.ok) return parsed.error;
|
|
3286
3358
|
const {
|
|
3287
3359
|
configPath,
|
|
3288
3360
|
event,
|
|
@@ -3293,10 +3365,10 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3293
3365
|
ingest,
|
|
3294
3366
|
state,
|
|
3295
3367
|
command
|
|
3296
|
-
} =
|
|
3368
|
+
} = parsed.data;
|
|
3297
3369
|
if (!runtime.simulate) {
|
|
3298
3370
|
const refusal = unavailableOperation("simulate");
|
|
3299
|
-
return
|
|
3371
|
+
return mcpError15(refusal, refusal.hint);
|
|
3300
3372
|
}
|
|
3301
3373
|
let known = [];
|
|
3302
3374
|
try {
|
|
@@ -3337,10 +3409,25 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3337
3409
|
throw new Error("command applies to destination steps only.");
|
|
3338
3410
|
}
|
|
3339
3411
|
const resolvedConfigPath = await resolveConfigPath(client, configPath);
|
|
3340
|
-
|
|
3412
|
+
const run = await readRun(runtime, resolvedConfigPath);
|
|
3413
|
+
known = run.knownSecrets;
|
|
3341
3414
|
const result = await runtime.simulate(
|
|
3342
3415
|
resolvedConfigPath,
|
|
3343
|
-
{
|
|
3416
|
+
{
|
|
3417
|
+
stepType,
|
|
3418
|
+
stepId,
|
|
3419
|
+
event: resolvedEvent,
|
|
3420
|
+
flow,
|
|
3421
|
+
ingest,
|
|
3422
|
+
state: state && {
|
|
3423
|
+
consent: state.consent,
|
|
3424
|
+
user: toProperties(state.user),
|
|
3425
|
+
globals: toProperties(state.globals),
|
|
3426
|
+
timing: state.timing
|
|
3427
|
+
},
|
|
3428
|
+
command,
|
|
3429
|
+
config: run.config
|
|
3430
|
+
}
|
|
3344
3431
|
);
|
|
3345
3432
|
const success = !result.error;
|
|
3346
3433
|
const errorMessage = result.error?.message;
|
|
@@ -3351,7 +3438,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3351
3438
|
).length;
|
|
3352
3439
|
const summary = `Source captured ${eventCount} event${eventCount !== 1 ? "s" : ""} and ${commandCount} command${commandCount !== 1 ? "s" : ""}`;
|
|
3353
3440
|
const shownCalls = verbose ? result.calls : result.calls.filter((call) => call.fn === "elb");
|
|
3354
|
-
return
|
|
3441
|
+
return mcpResult14(
|
|
3355
3442
|
scrubbed(
|
|
3356
3443
|
{
|
|
3357
3444
|
success,
|
|
@@ -3373,7 +3460,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3373
3460
|
);
|
|
3374
3461
|
}
|
|
3375
3462
|
if (result.step === "transformer") {
|
|
3376
|
-
return
|
|
3463
|
+
return mcpResult14(
|
|
3377
3464
|
scrubbed(
|
|
3378
3465
|
{
|
|
3379
3466
|
success,
|
|
@@ -3390,7 +3477,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3390
3477
|
);
|
|
3391
3478
|
}
|
|
3392
3479
|
if (result.step === "collector") {
|
|
3393
|
-
return
|
|
3480
|
+
return mcpResult14(
|
|
3394
3481
|
scrubbed(
|
|
3395
3482
|
{
|
|
3396
3483
|
success,
|
|
@@ -3430,21 +3517,13 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
3430
3517
|
...result.skipped ? { skipped: result.skipped } : {},
|
|
3431
3518
|
duration: result.duration
|
|
3432
3519
|
};
|
|
3433
|
-
return
|
|
3520
|
+
return mcpResult14(scrubbed(resultObj, known), {
|
|
3434
3521
|
next: ["Use flow_bundle to build for production"],
|
|
3435
3522
|
...warnings.length > 0 ? { warnings } : {}
|
|
3436
3523
|
});
|
|
3437
3524
|
} catch (error) {
|
|
3438
3525
|
const hint = "Run flow_validate for detailed error messages";
|
|
3439
|
-
return scrubbedError(
|
|
3440
|
-
}
|
|
3441
|
-
}
|
|
3442
|
-
async function knownSecretsOf(runtime, input) {
|
|
3443
|
-
if (!runtime.knownSecrets) return [];
|
|
3444
|
-
try {
|
|
3445
|
-
return await runtime.knownSecrets(input);
|
|
3446
|
-
} catch {
|
|
3447
|
-
return [];
|
|
3526
|
+
return scrubbedError(mcpError15(error, refusalHint(error, hint)), known);
|
|
3448
3527
|
}
|
|
3449
3528
|
}
|
|
3450
3529
|
function keysOf(consent) {
|
|
@@ -3476,25 +3555,23 @@ function registerFlowSimulateTool(server, client, runtime) {
|
|
|
3476
3555
|
outputSchema: SimulateOutputShape,
|
|
3477
3556
|
annotations: spec.annotations
|
|
3478
3557
|
},
|
|
3479
|
-
|
|
3480
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
3481
|
-
spec.handler
|
|
3558
|
+
(args) => flowSimulateHandlerBody(client, runtime, args)
|
|
3482
3559
|
);
|
|
3483
3560
|
}
|
|
3484
3561
|
|
|
3485
3562
|
// src/tools/push.ts
|
|
3486
|
-
import { z as
|
|
3487
|
-
import { schemas as
|
|
3488
|
-
import {
|
|
3563
|
+
import { z as z14 } from "zod";
|
|
3564
|
+
import { schemas as schemas5 } from "@walkeros/cli/dev";
|
|
3565
|
+
import { mcpError as mcpError16 } from "@walkeros/core";
|
|
3489
3566
|
var TITLE14 = "Push Events";
|
|
3490
3567
|
var DESCRIPTION11 = "Push a real event through a walkerOS flow to actual destinations. Makes real API calls to real endpoints. Best suited for server-side flows \u2014 web flows should use flow_simulate for testing.";
|
|
3491
3568
|
var inputSchema12 = {
|
|
3492
|
-
configPath:
|
|
3493
|
-
event:
|
|
3569
|
+
configPath: schemas5.PushInputShape.configPath,
|
|
3570
|
+
event: z14.record(z14.string(), z14.unknown()).describe(
|
|
3494
3571
|
'Event object, e.g. { name: "page view", data: { title: "Home" } }'
|
|
3495
3572
|
),
|
|
3496
|
-
flow:
|
|
3497
|
-
platform:
|
|
3573
|
+
flow: schemas5.PushInputShape.flow,
|
|
3574
|
+
platform: schemas5.PushInputShape.platform
|
|
3498
3575
|
};
|
|
3499
3576
|
var annotations14 = {
|
|
3500
3577
|
readOnlyHint: false,
|
|
@@ -3513,30 +3590,42 @@ function createFlowPushToolSpec(runtime) {
|
|
|
3513
3590
|
};
|
|
3514
3591
|
}
|
|
3515
3592
|
async function flowPushHandlerBody(runtime, input) {
|
|
3516
|
-
const
|
|
3593
|
+
const parsed = parseToolInput(inputSchema12, input);
|
|
3594
|
+
if (!parsed.ok) return parsed.error;
|
|
3595
|
+
const { configPath, event, flow, platform } = parsed.data;
|
|
3517
3596
|
if (!runtime.push) {
|
|
3518
3597
|
const refusal = unavailableOperation("push");
|
|
3519
|
-
return
|
|
3598
|
+
return mcpError16(refusal, refusal.hint);
|
|
3520
3599
|
}
|
|
3600
|
+
let known = [];
|
|
3521
3601
|
try {
|
|
3602
|
+
const run = await readRun(runtime, configPath);
|
|
3603
|
+
known = run.knownSecrets;
|
|
3522
3604
|
const result = await runtime.push(configPath, event, {
|
|
3523
3605
|
flow,
|
|
3524
|
-
platform
|
|
3606
|
+
platform,
|
|
3607
|
+
config: run.config
|
|
3525
3608
|
});
|
|
3526
3609
|
if (!result.success) {
|
|
3527
|
-
return
|
|
3528
|
-
|
|
3529
|
-
|
|
3610
|
+
return scrubbedError(
|
|
3611
|
+
mcpError16(
|
|
3612
|
+
new Error(result.error || "Push failed"),
|
|
3613
|
+
"Check destination configuration and connectivity."
|
|
3614
|
+
),
|
|
3615
|
+
known
|
|
3530
3616
|
);
|
|
3531
3617
|
}
|
|
3532
|
-
return
|
|
3618
|
+
return scrubbedPushResult(result, known);
|
|
3533
3619
|
} catch (error) {
|
|
3534
|
-
return
|
|
3535
|
-
|
|
3536
|
-
refusalHint(
|
|
3620
|
+
return scrubbedError(
|
|
3621
|
+
mcpError16(
|
|
3537
3622
|
error,
|
|
3538
|
-
|
|
3539
|
-
|
|
3623
|
+
refusalHint(
|
|
3624
|
+
error,
|
|
3625
|
+
"Check configPath and event format. For web flows, use flow_simulate."
|
|
3626
|
+
)
|
|
3627
|
+
),
|
|
3628
|
+
known
|
|
3540
3629
|
);
|
|
3541
3630
|
}
|
|
3542
3631
|
}
|
|
@@ -3552,15 +3641,13 @@ function registerFlowPushTool(server, runtime) {
|
|
|
3552
3641
|
outputSchema: PushOutputShape,
|
|
3553
3642
|
annotations: spec.annotations
|
|
3554
3643
|
},
|
|
3555
|
-
|
|
3556
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
3557
|
-
spec.handler
|
|
3644
|
+
(args) => flowPushHandlerBody(runtime, args)
|
|
3558
3645
|
);
|
|
3559
3646
|
}
|
|
3560
3647
|
|
|
3561
3648
|
// src/tools/examples.ts
|
|
3562
|
-
import { z as
|
|
3563
|
-
import { fetchPackage, mcpResult as mcpResult15, mcpError as
|
|
3649
|
+
import { z as z15 } from "zod";
|
|
3650
|
+
import { fetchPackage, mcpResult as mcpResult15, mcpError as mcpError17 } from "@walkeros/core";
|
|
3564
3651
|
import { resolveExportName, selectDevExamples } from "@walkeros/cli";
|
|
3565
3652
|
|
|
3566
3653
|
// src/catalog.ts
|
|
@@ -3568,7 +3655,7 @@ var NPM_SEARCH_URL = "https://registry.npmjs.org/-/v1/search";
|
|
|
3568
3655
|
var JSDELIVR_BASE = "https://cdn.jsdelivr.net/npm";
|
|
3569
3656
|
var WALKEROS_JSON_PATH = "dist/walkerOS.json";
|
|
3570
3657
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
3571
|
-
var CLIENT_HEADER = "walkeros-mcp/4.7.0
|
|
3658
|
+
var CLIENT_HEADER = "walkeros-mcp/4.7.0";
|
|
3572
3659
|
function getPackageBaseUrl() {
|
|
3573
3660
|
return process.env.WALKEROS_APP_URL || void 0;
|
|
3574
3661
|
}
|
|
@@ -3725,15 +3812,15 @@ var MAX_PACKAGE_LOOKUPS = 25;
|
|
|
3725
3812
|
var TITLE15 = "Flow Examples";
|
|
3726
3813
|
var DESCRIPTION12 = 'List all step examples in a walkerOS flow configuration. Shows example names, step locations, and in/out shapes. Inline examples on a step take precedence; steps without inline examples fall back to the examples shipped by their referenced package. Each result is tagged with its source ("inline" or "package"). On the hosted server configPath accepts only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. Use this to discover available test fixtures and simulation data.';
|
|
3727
3814
|
var inputSchema13 = {
|
|
3728
|
-
configPath:
|
|
3815
|
+
configPath: z15.string().min(1).describe(
|
|
3729
3816
|
"Inline JSON string, file path, or URL of a flow configuration (hosted server: inline JSON or a saved flow id only)"
|
|
3730
3817
|
),
|
|
3731
|
-
flow:
|
|
3732
|
-
step:
|
|
3733
|
-
full:
|
|
3818
|
+
flow: z15.string().optional().describe("Flow name for multi-flow configs"),
|
|
3819
|
+
step: z15.string().optional().describe('Filter to a specific step (e.g., "destination.gtag")'),
|
|
3820
|
+
full: z15.boolean().optional().describe(
|
|
3734
3821
|
"Return full in/out/mapping data for each example (default: false, returns metadata only)"
|
|
3735
3822
|
),
|
|
3736
|
-
includeHidden:
|
|
3823
|
+
includeHidden: z15.boolean().optional().describe(
|
|
3737
3824
|
"Include examples marked public: false (default: false). Set true for test/debug discovery."
|
|
3738
3825
|
)
|
|
3739
3826
|
};
|
|
@@ -3754,9 +3841,14 @@ function createFlowExamplesToolSpec(runtime) {
|
|
|
3754
3841
|
};
|
|
3755
3842
|
}
|
|
3756
3843
|
async function flowExamplesHandlerBody(runtime, input) {
|
|
3757
|
-
const
|
|
3844
|
+
const parsed = parseToolInput(inputSchema13, input);
|
|
3845
|
+
if (!parsed.ok) return parsed.error;
|
|
3846
|
+
const { configPath, flow, step, full, includeHidden } = parsed.data;
|
|
3758
3847
|
try {
|
|
3759
3848
|
const rawConfig = await runtime.load(configPath);
|
|
3849
|
+
if (!isFlowJson(rawConfig)) {
|
|
3850
|
+
throw new Error("Config is not a flow config: it has no flows object.");
|
|
3851
|
+
}
|
|
3760
3852
|
const flowNames = Object.keys(rawConfig.flows || {});
|
|
3761
3853
|
const flowName = flow || (flowNames.length === 1 ? flowNames[0] : void 0);
|
|
3762
3854
|
if (!flowName) {
|
|
@@ -3809,6 +3901,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3809
3901
|
};
|
|
3810
3902
|
const packageLookups = /* @__PURE__ */ new Map();
|
|
3811
3903
|
let skippedPackages = false;
|
|
3904
|
+
const skippedExamples = [];
|
|
3812
3905
|
const packageFor = (packageName) => {
|
|
3813
3906
|
const existing = packageLookups.get(packageName);
|
|
3814
3907
|
if (existing) return existing;
|
|
@@ -3825,10 +3918,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3825
3918
|
{ examples: info.examples, exportExamples: info.exportExamples },
|
|
3826
3919
|
exportName
|
|
3827
3920
|
);
|
|
3828
|
-
|
|
3829
|
-
if (stepExamples && typeof stepExamples === "object")
|
|
3830
|
-
return stepExamples;
|
|
3831
|
-
return void 0;
|
|
3921
|
+
return stepExamplesOf(selected?.step);
|
|
3832
3922
|
};
|
|
3833
3923
|
const stepTypes = [
|
|
3834
3924
|
{ key: "sources", type: "source" },
|
|
@@ -3840,9 +3930,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3840
3930
|
for (const [name, ref] of Object.entries(refs)) {
|
|
3841
3931
|
if (step && `${type}.${name}` !== step) continue;
|
|
3842
3932
|
if (ref.examples) {
|
|
3843
|
-
examples.push(
|
|
3844
|
-
...toItems(ref.examples, type, name, "inline")
|
|
3845
|
-
);
|
|
3933
|
+
examples.push(...toItems(ref.examples, type, name, "inline"));
|
|
3846
3934
|
continue;
|
|
3847
3935
|
}
|
|
3848
3936
|
if (!ref.package) continue;
|
|
@@ -3850,8 +3938,12 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3850
3938
|
if (!info) continue;
|
|
3851
3939
|
const { exportName } = resolveExportName(flowSettings, type, name);
|
|
3852
3940
|
const packageExamples = stepExamplesFor(info, exportName);
|
|
3853
|
-
if (packageExamples)
|
|
3854
|
-
|
|
3941
|
+
if (!packageExamples) continue;
|
|
3942
|
+
examples.push(
|
|
3943
|
+
...toItems(packageExamples.examples, type, name, "package")
|
|
3944
|
+
);
|
|
3945
|
+
for (const exampleName of packageExamples.skipped)
|
|
3946
|
+
skippedExamples.push(`${type}.${name}.${exampleName}`);
|
|
3855
3947
|
}
|
|
3856
3948
|
}
|
|
3857
3949
|
const result = {
|
|
@@ -3865,6 +3957,11 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3865
3957
|
"No examples found. Add examples to step entries, or reference a package that ships examples (see package_get)."
|
|
3866
3958
|
);
|
|
3867
3959
|
}
|
|
3960
|
+
if (skippedExamples.length > 0) {
|
|
3961
|
+
warnings.push(
|
|
3962
|
+
`Skipped ${skippedExamples.length} package example(s) that do not match the step example schema: ${skippedExamples.join(", ")}.`
|
|
3963
|
+
);
|
|
3964
|
+
}
|
|
3868
3965
|
if (skippedPackages) {
|
|
3869
3966
|
warnings.push(
|
|
3870
3967
|
`Package examples were looked up for the first ${MAX_PACKAGE_LOOKUPS} packages only. Use step to narrow the result.`
|
|
@@ -3878,7 +3975,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
3878
3975
|
};
|
|
3879
3976
|
return mcpResult15(result, hints);
|
|
3880
3977
|
} catch (error) {
|
|
3881
|
-
return
|
|
3978
|
+
return mcpError17(
|
|
3882
3979
|
error,
|
|
3883
3980
|
refusalHint(error, "Check configPath \u2014 expected a flow.json file")
|
|
3884
3981
|
);
|
|
@@ -3896,15 +3993,13 @@ function registerFlowExamplesTool(server, runtime) {
|
|
|
3896
3993
|
outputSchema: ExamplesListOutputShape,
|
|
3897
3994
|
annotations: spec.annotations
|
|
3898
3995
|
},
|
|
3899
|
-
|
|
3900
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
3901
|
-
spec.handler
|
|
3996
|
+
(args) => flowExamplesHandlerBody(runtime, args)
|
|
3902
3997
|
);
|
|
3903
3998
|
}
|
|
3904
3999
|
|
|
3905
4000
|
// src/tools/flow-load.ts
|
|
3906
|
-
import { z as
|
|
3907
|
-
import { mcpResult as mcpResult16, mcpError as
|
|
4001
|
+
import { z as z16 } from "zod";
|
|
4002
|
+
import { mcpResult as mcpResult16, mcpError as mcpError18 } from "@walkeros/core";
|
|
3908
4003
|
var WEB_SKELETON = {
|
|
3909
4004
|
version: 4,
|
|
3910
4005
|
flows: {
|
|
@@ -3928,16 +4023,16 @@ var SERVER_SKELETON = {
|
|
|
3928
4023
|
var TITLE16 = "Load or Create Flow";
|
|
3929
4024
|
var DESCRIPTION13 = "Load an existing flow configuration from a local file path, URL, or walkerOS API (by flow ID). On the hosted server only inline JSON or a saved flow id is accepted, no file paths or URLs. Or create a new empty flow by specifying a platform (web or server). Use the add-step prompt to add sources, destinations, transformers, or stores to the flow.";
|
|
3930
4025
|
var inputSchema14 = {
|
|
3931
|
-
source:
|
|
4026
|
+
source: z16.string().optional().describe(
|
|
3932
4027
|
"Flow source: local file path (./flow.json), URL (https://...), inline JSON string, or API flow ID (cfg_...). Omit to create a new flow."
|
|
3933
4028
|
),
|
|
3934
|
-
platform:
|
|
4029
|
+
platform: z16.enum(["web", "server"]).optional().describe(
|
|
3935
4030
|
"Platform for new flows. Required when source is omitted. web = browser tracking, server = Node.js HTTP."
|
|
3936
4031
|
)
|
|
3937
4032
|
};
|
|
3938
4033
|
var outputSchema = {
|
|
3939
|
-
version:
|
|
3940
|
-
flows:
|
|
4034
|
+
version: z16.number().describe("Flow config version"),
|
|
4035
|
+
flows: z16.record(z16.string(), z16.unknown()).describe("Flow entries")
|
|
3941
4036
|
};
|
|
3942
4037
|
var annotations16 = {
|
|
3943
4038
|
readOnlyHint: true,
|
|
@@ -3956,11 +4051,13 @@ function createFlowLoadToolSpec(client, runtime) {
|
|
|
3956
4051
|
};
|
|
3957
4052
|
}
|
|
3958
4053
|
async function flowLoadHandlerBody(client, runtime, input) {
|
|
3959
|
-
const
|
|
4054
|
+
const parsed = parseToolInput(inputSchema14, input);
|
|
4055
|
+
if (!parsed.ok) return parsed.error;
|
|
4056
|
+
const { source, platform } = parsed.data;
|
|
3960
4057
|
if (source && isCloudId(source)) {
|
|
3961
4058
|
const resolvedProjectId = resolveDefaultProject(client, void 0);
|
|
3962
4059
|
if (!resolvedProjectId) {
|
|
3963
|
-
return
|
|
4060
|
+
return mcpError18(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
3964
4061
|
}
|
|
3965
4062
|
try {
|
|
3966
4063
|
const flow = await client.getFlow({
|
|
@@ -3974,7 +4071,7 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
3974
4071
|
}
|
|
3975
4072
|
);
|
|
3976
4073
|
} catch (error) {
|
|
3977
|
-
return
|
|
4074
|
+
return mcpError18(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
3978
4075
|
}
|
|
3979
4076
|
}
|
|
3980
4077
|
try {
|
|
@@ -3985,7 +4082,7 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
3985
4082
|
});
|
|
3986
4083
|
}
|
|
3987
4084
|
if (!platform) {
|
|
3988
|
-
return
|
|
4085
|
+
return mcpError18(
|
|
3989
4086
|
new Error(
|
|
3990
4087
|
"Provide source (file path, URL, or flow ID) to load existing flow, or platform (web/server) to create a new one."
|
|
3991
4088
|
)
|
|
@@ -3999,11 +4096,11 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
3999
4096
|
]
|
|
4000
4097
|
});
|
|
4001
4098
|
} catch (error) {
|
|
4002
|
-
if (error instanceof RuntimeRefusal) return
|
|
4099
|
+
if (error instanceof RuntimeRefusal) return mcpError18(error, error.hint);
|
|
4003
4100
|
const msg = error instanceof Error ? error.message : "";
|
|
4004
4101
|
if (msg.includes("not found") || msg.includes("ENOENT"))
|
|
4005
|
-
return
|
|
4006
|
-
return
|
|
4102
|
+
return mcpError18(error, "Check configPath \u2014 expected a flow.json file");
|
|
4103
|
+
return mcpError18(error);
|
|
4007
4104
|
}
|
|
4008
4105
|
}
|
|
4009
4106
|
function registerFlowLoadTool(server, client, runtime) {
|
|
@@ -4018,25 +4115,23 @@ function registerFlowLoadTool(server, client, runtime) {
|
|
|
4018
4115
|
outputSchema,
|
|
4019
4116
|
annotations: spec.annotations
|
|
4020
4117
|
},
|
|
4021
|
-
|
|
4022
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
4023
|
-
spec.handler
|
|
4118
|
+
(args) => flowLoadHandlerBody(client, runtime, args)
|
|
4024
4119
|
);
|
|
4025
4120
|
}
|
|
4026
4121
|
|
|
4027
4122
|
// src/tools/package.ts
|
|
4028
|
-
import { z as
|
|
4029
|
-
import { fetchPackage as fetchPackage2, mcpResult as mcpResult17, mcpError as
|
|
4123
|
+
import { z as z17 } from "zod";
|
|
4124
|
+
import { fetchPackage as fetchPackage2, mcpResult as mcpResult17, mcpError as mcpError19 } from "@walkeros/core";
|
|
4030
4125
|
import { mergeConfigSchema } from "@walkeros/core/dev";
|
|
4031
4126
|
var SEARCH_TITLE = "Search Package";
|
|
4032
4127
|
var SEARCH_DESCRIPTION = "Start here for package discovery. Never guess package names: use this tool first to find exact names. Without package name: returns catalog filtered by type/platform. With package name: returns metadata, hint keys, and example summaries.";
|
|
4033
4128
|
var searchInputSchema = {
|
|
4034
|
-
package:
|
|
4129
|
+
package: z17.string().min(1).optional().describe(
|
|
4035
4130
|
"Exact npm package name for detailed lookup (e.g., @walkeros/web-destination-snowplow)"
|
|
4036
4131
|
),
|
|
4037
|
-
type:
|
|
4038
|
-
platform:
|
|
4039
|
-
version:
|
|
4132
|
+
type: z17.enum(["source", "destination", "transformer", "store"]).optional().describe("Filter by package type (browse mode)"),
|
|
4133
|
+
platform: z17.enum(["web", "server"]).optional().describe("Filter by platform (browse mode, includes universal packages)"),
|
|
4134
|
+
version: z17.string().optional().describe("Package version for detailed lookup (default: latest)")
|
|
4040
4135
|
};
|
|
4041
4136
|
var searchAnnotations = {
|
|
4042
4137
|
readOnlyHint: true,
|
|
@@ -4055,12 +4150,9 @@ function createPackageSearchToolSpec() {
|
|
|
4055
4150
|
};
|
|
4056
4151
|
}
|
|
4057
4152
|
async function packageSearchHandlerBody(input) {
|
|
4058
|
-
const
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
platform,
|
|
4062
|
-
version
|
|
4063
|
-
} = input ?? {};
|
|
4153
|
+
const parsed = parseToolInput(searchInputSchema, input);
|
|
4154
|
+
if (!parsed.ok) return parsed.error;
|
|
4155
|
+
const { package: packageName, type, platform, version } = parsed.data;
|
|
4064
4156
|
const baseUrl = getPackageBaseUrl();
|
|
4065
4157
|
if (!packageName) {
|
|
4066
4158
|
const { entries, warnings } = await fetchCatalog({
|
|
@@ -4093,7 +4185,7 @@ async function packageSearchHandlerBody(input) {
|
|
|
4093
4185
|
next: ["Use package_get for schemas and examples"]
|
|
4094
4186
|
});
|
|
4095
4187
|
} catch (error) {
|
|
4096
|
-
return
|
|
4188
|
+
return mcpError19(
|
|
4097
4189
|
error,
|
|
4098
4190
|
"Package not found. Use package_search without parameters to browse available packages."
|
|
4099
4191
|
);
|
|
@@ -4110,19 +4202,17 @@ function registerPackageSearchTool(server) {
|
|
|
4110
4202
|
// No outputSchema: browse mode returns {catalog, count}, lookup returns metadata — incompatible shapes
|
|
4111
4203
|
annotations: spec.annotations
|
|
4112
4204
|
},
|
|
4113
|
-
|
|
4114
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
4115
|
-
spec.handler
|
|
4205
|
+
(args) => packageSearchHandlerBody(args)
|
|
4116
4206
|
);
|
|
4117
4207
|
}
|
|
4118
4208
|
var GET_TITLE = "Get Package";
|
|
4119
4209
|
var GET_DESCRIPTION = 'Requires exact package name: do not guess names, use package_search first to find them. Returns schemas + hint texts + example summaries by default (lightweight). Use section parameter for full content: "hints" (with code blocks), "examples" (full in/out data), or "all".';
|
|
4120
4210
|
var getInputSchema = {
|
|
4121
|
-
package:
|
|
4211
|
+
package: z17.string().min(1).describe(
|
|
4122
4212
|
"Exact npm package name (e.g., @walkeros/web-destination-snowplow)"
|
|
4123
4213
|
),
|
|
4124
|
-
version:
|
|
4125
|
-
section:
|
|
4214
|
+
version: z17.string().optional().describe("Package version (default: latest)"),
|
|
4215
|
+
section: z17.enum(["hints", "examples", "all"]).optional().describe(
|
|
4126
4216
|
"Section to expand with full content. Default: summary view with schemas + hint texts + example descriptions"
|
|
4127
4217
|
)
|
|
4128
4218
|
};
|
|
@@ -4142,12 +4232,35 @@ function createPackageGetToolSpec() {
|
|
|
4142
4232
|
handler: (input) => packageGetHandlerBody(input)
|
|
4143
4233
|
};
|
|
4144
4234
|
}
|
|
4235
|
+
var STEP_PACKAGE_TYPES = [
|
|
4236
|
+
"source",
|
|
4237
|
+
"destination",
|
|
4238
|
+
"transformer",
|
|
4239
|
+
"store"
|
|
4240
|
+
];
|
|
4241
|
+
function isStepPackageType(type) {
|
|
4242
|
+
return STEP_PACKAGE_TYPES.some((stepType) => stepType === type);
|
|
4243
|
+
}
|
|
4244
|
+
function shapeSchemas(type, schemas9) {
|
|
4245
|
+
const shaped = {};
|
|
4246
|
+
if (isStepPackageType(type)) {
|
|
4247
|
+
const settings = recordField(schemas9, "settings");
|
|
4248
|
+
const credentials = recordField(schemas9, "credentials");
|
|
4249
|
+
shaped.config = mergeConfigSchema(type, {
|
|
4250
|
+
...schemas9,
|
|
4251
|
+
settings,
|
|
4252
|
+
credentials
|
|
4253
|
+
});
|
|
4254
|
+
}
|
|
4255
|
+
for (const [key, value] of Object.entries(schemas9)) {
|
|
4256
|
+
if (key !== "settings") shaped[key] = value;
|
|
4257
|
+
}
|
|
4258
|
+
return shaped;
|
|
4259
|
+
}
|
|
4145
4260
|
async function packageGetHandlerBody(input) {
|
|
4146
|
-
const
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
section
|
|
4150
|
-
} = input ?? {};
|
|
4261
|
+
const parsed = parseToolInput(getInputSchema, input);
|
|
4262
|
+
if (!parsed.ok) return parsed.error;
|
|
4263
|
+
const { package: packageName, version, section } = parsed.data;
|
|
4151
4264
|
const baseUrl = getPackageBaseUrl();
|
|
4152
4265
|
try {
|
|
4153
4266
|
const info = await fetchPackage2(packageName, {
|
|
@@ -4155,33 +4268,29 @@ async function packageGetHandlerBody(input) {
|
|
|
4155
4268
|
baseUrl,
|
|
4156
4269
|
client: CLIENT_HEADER
|
|
4157
4270
|
});
|
|
4158
|
-
const mergedSchemas = {};
|
|
4159
|
-
if (info.type) {
|
|
4160
|
-
mergedSchemas.config = mergeConfigSchema(
|
|
4161
|
-
info.type,
|
|
4162
|
-
info.schemas
|
|
4163
|
-
);
|
|
4164
|
-
}
|
|
4165
|
-
for (const [key, value] of Object.entries(info.schemas)) {
|
|
4166
|
-
if (key !== "settings") {
|
|
4167
|
-
mergedSchemas[key] = value;
|
|
4168
|
-
}
|
|
4169
|
-
}
|
|
4170
4271
|
const result = {
|
|
4171
4272
|
package: info.packageName,
|
|
4172
4273
|
version: info.version,
|
|
4173
4274
|
type: info.type,
|
|
4174
4275
|
platform: normalizePlatform(info.platform),
|
|
4175
|
-
schemas:
|
|
4276
|
+
schemas: shapeSchemas(info.type, info.schemas)
|
|
4176
4277
|
};
|
|
4278
|
+
if (info.exportSchemas) {
|
|
4279
|
+
result.exportSchemas = Object.fromEntries(
|
|
4280
|
+
Object.entries(info.exportSchemas).map(([name, schemas9]) => [
|
|
4281
|
+
name,
|
|
4282
|
+
shapeSchemas(info.type, schemas9)
|
|
4283
|
+
])
|
|
4284
|
+
);
|
|
4285
|
+
}
|
|
4177
4286
|
if (info.hints) {
|
|
4178
4287
|
if (section === "hints" || section === "all") {
|
|
4179
4288
|
result.hints = info.hints;
|
|
4180
4289
|
} else {
|
|
4181
4290
|
const hintSummary = {};
|
|
4182
4291
|
for (const [key, hint] of Object.entries(info.hints)) {
|
|
4183
|
-
const
|
|
4184
|
-
hintSummary[key] = { text
|
|
4292
|
+
const text = stringField(hint, "text");
|
|
4293
|
+
if (text !== void 0) hintSummary[key] = { text };
|
|
4185
4294
|
}
|
|
4186
4295
|
result.hints = hintSummary;
|
|
4187
4296
|
}
|
|
@@ -4194,7 +4303,7 @@ async function packageGetHandlerBody(input) {
|
|
|
4194
4303
|
}
|
|
4195
4304
|
return mcpResult17(result);
|
|
4196
4305
|
} catch (error) {
|
|
4197
|
-
return
|
|
4306
|
+
return mcpError19(
|
|
4198
4307
|
error,
|
|
4199
4308
|
"Use package_search to browse available package names."
|
|
4200
4309
|
);
|
|
@@ -4211,9 +4320,7 @@ function registerGetPackageSchemaTool(server) {
|
|
|
4211
4320
|
// No outputSchema: removed to avoid SDK -32602 crashes on unexpected field values
|
|
4212
4321
|
annotations: spec.annotations
|
|
4213
4322
|
},
|
|
4214
|
-
|
|
4215
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
4216
|
-
spec.handler
|
|
4323
|
+
(args) => packageGetHandlerBody(args)
|
|
4217
4324
|
);
|
|
4218
4325
|
}
|
|
4219
4326
|
|
|
@@ -23926,9 +24033,7 @@ function registerDiagnosticsTool(server, client, packageVersion) {
|
|
|
23926
24033
|
inputSchema: spec.inputSchema,
|
|
23927
24034
|
annotations: spec.annotations
|
|
23928
24035
|
},
|
|
23929
|
-
|
|
23930
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
23931
|
-
spec.handler
|
|
24036
|
+
() => diagnosticsHandlerBody(client, packageVersion)
|
|
23932
24037
|
);
|
|
23933
24038
|
}
|
|
23934
24039
|
|
|
@@ -23978,7 +24083,7 @@ function registerPackageSchemaResources(server) {
|
|
|
23978
24083
|
}
|
|
23979
24084
|
|
|
23980
24085
|
// src/resources/references.ts
|
|
23981
|
-
import { schemas as
|
|
24086
|
+
import { schemas as schemas6 } from "@walkeros/core/dev";
|
|
23982
24087
|
function registerReferenceResources(server) {
|
|
23983
24088
|
server.resource(
|
|
23984
24089
|
"flow-schema",
|
|
@@ -23991,7 +24096,7 @@ function registerReferenceResources(server) {
|
|
|
23991
24096
|
contents: [
|
|
23992
24097
|
{
|
|
23993
24098
|
uri: "walkeros://reference/flow-schema",
|
|
23994
|
-
text: JSON.stringify(
|
|
24099
|
+
text: JSON.stringify(schemas6.configJsonSchema, null, 2),
|
|
23995
24100
|
mimeType: "application/json"
|
|
23996
24101
|
}
|
|
23997
24102
|
]
|
|
@@ -24008,7 +24113,7 @@ function registerReferenceResources(server) {
|
|
|
24008
24113
|
contents: [
|
|
24009
24114
|
{
|
|
24010
24115
|
uri: "walkeros://reference/event-model",
|
|
24011
|
-
text: JSON.stringify(
|
|
24116
|
+
text: JSON.stringify(schemas6.eventJsonSchema, null, 2),
|
|
24012
24117
|
mimeType: "application/json"
|
|
24013
24118
|
}
|
|
24014
24119
|
]
|
|
@@ -24027,10 +24132,10 @@ function registerReferenceResources(server) {
|
|
|
24027
24132
|
uri: "walkeros://reference/mapping",
|
|
24028
24133
|
text: JSON.stringify(
|
|
24029
24134
|
{
|
|
24030
|
-
rules:
|
|
24031
|
-
valueConfig:
|
|
24032
|
-
rule:
|
|
24033
|
-
policy:
|
|
24135
|
+
rules: schemas6.rulesJsonSchema,
|
|
24136
|
+
valueConfig: schemas6.valueConfigJsonSchema,
|
|
24137
|
+
rule: schemas6.ruleJsonSchema,
|
|
24138
|
+
policy: schemas6.policyJsonSchema
|
|
24034
24139
|
},
|
|
24035
24140
|
null,
|
|
24036
24141
|
2
|
|
@@ -24051,7 +24156,7 @@ function registerReferenceResources(server) {
|
|
|
24051
24156
|
contents: [
|
|
24052
24157
|
{
|
|
24053
24158
|
uri: "walkeros://reference/consent",
|
|
24054
|
-
text: JSON.stringify(
|
|
24159
|
+
text: JSON.stringify(schemas6.consentJsonSchema, null, 2),
|
|
24055
24160
|
mimeType: "application/json"
|
|
24056
24161
|
}
|
|
24057
24162
|
]
|
|
@@ -24127,7 +24232,7 @@ function registerReferenceResources(server) {
|
|
|
24127
24232
|
contents: [
|
|
24128
24233
|
{
|
|
24129
24234
|
uri: "walkeros://reference/contract",
|
|
24130
|
-
text: JSON.stringify(
|
|
24235
|
+
text: JSON.stringify(schemas6.contractJsonSchema, null, 2),
|
|
24131
24236
|
mimeType: "application/json"
|
|
24132
24237
|
}
|
|
24133
24238
|
]
|
|
@@ -24205,17 +24310,17 @@ function registerReferenceResources(server) {
|
|
|
24205
24310
|
}
|
|
24206
24311
|
|
|
24207
24312
|
// src/prompts/add-step.ts
|
|
24208
|
-
import { z as
|
|
24313
|
+
import { z as z18 } from "zod";
|
|
24209
24314
|
function registerAddStepPrompt(server) {
|
|
24210
24315
|
server.registerPrompt(
|
|
24211
24316
|
"add-step",
|
|
24212
24317
|
{
|
|
24213
24318
|
description: "Add a source, destination, transformer, or store step to a flow configuration. Guides through package selection, config scaffolding, and wiring.",
|
|
24214
24319
|
argsSchema: {
|
|
24215
|
-
stepType:
|
|
24320
|
+
stepType: z18.string().optional().describe(
|
|
24216
24321
|
"Type of step to add: source, destination, transformer, or store"
|
|
24217
24322
|
),
|
|
24218
|
-
flowPath:
|
|
24323
|
+
flowPath: z18.string().optional().describe("Path to the flow.json file to modify")
|
|
24219
24324
|
}
|
|
24220
24325
|
},
|
|
24221
24326
|
async ({ stepType, flowPath }) => ({
|
|
@@ -24261,14 +24366,14 @@ function registerAddStepPrompt(server) {
|
|
|
24261
24366
|
}
|
|
24262
24367
|
|
|
24263
24368
|
// src/prompts/setup-mapping.ts
|
|
24264
|
-
import { z as
|
|
24369
|
+
import { z as z19 } from "zod";
|
|
24265
24370
|
function registerSetupMappingPrompt(server) {
|
|
24266
24371
|
server.registerPrompt(
|
|
24267
24372
|
"setup-mapping",
|
|
24268
24373
|
{
|
|
24269
24374
|
description: "Set up event mapping for any step in a flow. Teaches mapping syntax and uses package examples as templates.",
|
|
24270
24375
|
argsSchema: {
|
|
24271
|
-
stepName:
|
|
24376
|
+
stepName: z19.string().optional().describe('Step name in the flow (e.g., "gtag", "meta", "express")')
|
|
24272
24377
|
}
|
|
24273
24378
|
},
|
|
24274
24379
|
async ({ stepName }) => ({
|
|
@@ -24306,14 +24411,14 @@ function registerSetupMappingPrompt(server) {
|
|
|
24306
24411
|
}
|
|
24307
24412
|
|
|
24308
24413
|
// src/prompts/manage-contract.ts
|
|
24309
|
-
import { z as
|
|
24414
|
+
import { z as z20 } from "zod";
|
|
24310
24415
|
function registerManageContractPrompt(server) {
|
|
24311
24416
|
server.registerPrompt(
|
|
24312
24417
|
"manage-contract",
|
|
24313
24418
|
{
|
|
24314
24419
|
description: "Create or update event contracts for a flow. Can generate contracts from existing mappings or scaffold mappings from contracts.",
|
|
24315
24420
|
argsSchema: {
|
|
24316
|
-
direction:
|
|
24421
|
+
direction: z20.string().optional().describe(
|
|
24317
24422
|
'Direction: "from-mappings" (extract contract from existing mappings), "from-scratch" (create new contract), or "to-mappings" (scaffold mappings from contract)'
|
|
24318
24423
|
)
|
|
24319
24424
|
}
|
|
@@ -24357,7 +24462,7 @@ var SERVER_INSTRUCTIONS = `walkerOS is an open-source, privacy-first event data
|
|
|
24357
24462
|
|
|
24358
24463
|
- **Never guess package names.** Always use \`package_search\` first to find exact names, then \`package_get\` for details.
|
|
24359
24464
|
- **Never construct flow configs from memory.** Read \`walkeros://reference/flow-schema\` and use \`package_get\` for package-specific schemas.
|
|
24360
|
-
- **Always validate.** Run \`flow_validate\` after every config change. If validation fails, fix and re-validate.
|
|
24465
|
+
- **Always validate.** Run \`flow_validate\` after every config change. If validation fails, fix and re-validate. By default it checks every flow and step, package settings included; a valid result can still list \`details.skipped\` checks, so read them before trusting it (\`strict: true\` turns warnings and skips into failures: \`valid\` is false).
|
|
24361
24466
|
- **Simulate before deploying.** Use \`flow_simulate\` to test with mocked API calls before \`flow_bundle\` or \`flow_push\`.
|
|
24362
24467
|
- **When a request fails,** call \`diagnostics\` to see which MCP/CLI versions, app URL, and backend you are on, plus whether the app is reachable.
|
|
24363
24468
|
|
|
@@ -24815,8 +24920,11 @@ function createStreamableHttpHandler(server, opts = {}) {
|
|
|
24815
24920
|
}
|
|
24816
24921
|
|
|
24817
24922
|
// src/runtime/local.ts
|
|
24923
|
+
import * as fs from "fs";
|
|
24924
|
+
import * as path2 from "path";
|
|
24818
24925
|
import {
|
|
24819
24926
|
collectKnownSecrets,
|
|
24927
|
+
loadConfig,
|
|
24820
24928
|
loadJsonConfig,
|
|
24821
24929
|
bundle as bundle2,
|
|
24822
24930
|
push,
|
|
@@ -24825,6 +24933,8 @@ import {
|
|
|
24825
24933
|
simulateCollector,
|
|
24826
24934
|
simulateDestination
|
|
24827
24935
|
} from "@walkeros/cli";
|
|
24936
|
+
import { isObject as isObject3 } from "@walkeros/core";
|
|
24937
|
+
import { schemas as schemas7 } from "@walkeros/core/dev";
|
|
24828
24938
|
|
|
24829
24939
|
// src/runtime/bundle-cache.ts
|
|
24830
24940
|
import { createHash } from "crypto";
|
|
@@ -24915,6 +25025,10 @@ async function getOrBuildBundle(resolvedConfig) {
|
|
|
24915
25025
|
function createLocalRuntime() {
|
|
24916
25026
|
return {
|
|
24917
25027
|
load: (input) => loadJsonConfig(input),
|
|
25028
|
+
baseDir(input) {
|
|
25029
|
+
const file = path2.resolve(input);
|
|
25030
|
+
return fs.existsSync(file) && fs.statSync(file).isFile() ? path2.dirname(file) : void 0;
|
|
25031
|
+
},
|
|
24918
25032
|
bundle: (input, opts) => bundle2(input, {
|
|
24919
25033
|
flowName: opts.flowName,
|
|
24920
25034
|
stats: opts.stats,
|
|
@@ -24928,69 +25042,84 @@ function createLocalRuntime() {
|
|
|
24928
25042
|
bundlePath = void 0;
|
|
24929
25043
|
}
|
|
24930
25044
|
const common = { bundlePath, flow: opts.flow, silent: true };
|
|
25045
|
+
const config = opts.config ?? input;
|
|
24931
25046
|
switch (opts.stepType) {
|
|
24932
25047
|
case "source":
|
|
24933
|
-
return simulateSource(
|
|
25048
|
+
return simulateSource(config, opts.event, {
|
|
24934
25049
|
sourceId: opts.stepId,
|
|
24935
25050
|
...common,
|
|
24936
25051
|
consent: opts.state?.consent
|
|
24937
25052
|
});
|
|
24938
25053
|
case "transformer":
|
|
24939
|
-
return simulateTransformer(
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
24943
|
-
|
|
24944
|
-
|
|
24945
|
-
ingest: opts.ingest,
|
|
24946
|
-
consent: opts.state?.consent
|
|
24947
|
-
}
|
|
24948
|
-
);
|
|
25054
|
+
return simulateTransformer(config, partialEvent(opts.event), {
|
|
25055
|
+
transformerId: opts.stepId,
|
|
25056
|
+
...common,
|
|
25057
|
+
ingest: opts.ingest,
|
|
25058
|
+
consent: opts.state?.consent
|
|
25059
|
+
});
|
|
24949
25060
|
case "collector":
|
|
24950
|
-
return simulateCollector(
|
|
24951
|
-
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
24956
|
-
state: opts.state,
|
|
24957
|
-
ingest: opts.ingest
|
|
24958
|
-
}
|
|
24959
|
-
);
|
|
25061
|
+
return simulateCollector(config, partialEvent(opts.event), {
|
|
25062
|
+
collectorName: opts.stepId,
|
|
25063
|
+
...common,
|
|
25064
|
+
state: opts.state,
|
|
25065
|
+
ingest: opts.ingest
|
|
25066
|
+
});
|
|
24960
25067
|
case "destination":
|
|
24961
|
-
return simulateDestination(
|
|
24962
|
-
|
|
24963
|
-
|
|
24964
|
-
|
|
24965
|
-
|
|
24966
|
-
|
|
24967
|
-
|
|
24968
|
-
consent: opts.state?.consent,
|
|
24969
|
-
command: opts.command
|
|
24970
|
-
}
|
|
24971
|
-
);
|
|
25068
|
+
return simulateDestination(config, eventObject(opts.event), {
|
|
25069
|
+
destinationId: opts.stepId,
|
|
25070
|
+
...common,
|
|
25071
|
+
ingest: opts.ingest,
|
|
25072
|
+
consent: opts.state?.consent,
|
|
25073
|
+
command: opts.command
|
|
25074
|
+
});
|
|
24972
25075
|
}
|
|
24973
25076
|
},
|
|
24974
25077
|
knownSecrets: async (input) => collectKnownSecrets(await loadJsonConfig(input)),
|
|
25078
|
+
async loadRun(input) {
|
|
25079
|
+
const content = await loadConfig(input, { json: false });
|
|
25080
|
+
const config = typeof content === "string" ? parseJson(content) : void 0;
|
|
25081
|
+
if (!isFlowJson(config)) return { knownSecrets: [] };
|
|
25082
|
+
return { config, knownSecrets: collectKnownSecrets(config) };
|
|
25083
|
+
},
|
|
24975
25084
|
push: (input, event, opts) => push(input, event, {
|
|
24976
25085
|
json: true,
|
|
24977
25086
|
flow: opts.flow,
|
|
24978
|
-
platform: opts.platform
|
|
25087
|
+
platform: opts.platform,
|
|
25088
|
+
...opts.config !== void 0 && { raw: opts.config }
|
|
24979
25089
|
})
|
|
24980
25090
|
};
|
|
24981
25091
|
}
|
|
25092
|
+
function partialEvent(value) {
|
|
25093
|
+
if (isPartialEvent(value)) return value;
|
|
25094
|
+
const parsed = schemas7.PartialEventSchema.safeParse(value);
|
|
25095
|
+
throw new Error(parsed.error?.message ?? "Invalid event");
|
|
25096
|
+
}
|
|
25097
|
+
function isPartialEvent(value) {
|
|
25098
|
+
return schemas7.PartialEventSchema.safeParse(value).success;
|
|
25099
|
+
}
|
|
25100
|
+
function eventObject(value) {
|
|
25101
|
+
if (isObject3(value)) return value;
|
|
25102
|
+
throw new Error("event must be an object.");
|
|
25103
|
+
}
|
|
25104
|
+
function parseJson(content) {
|
|
25105
|
+
try {
|
|
25106
|
+
return JSON.parse(content);
|
|
25107
|
+
} catch {
|
|
25108
|
+
return void 0;
|
|
25109
|
+
}
|
|
25110
|
+
}
|
|
24982
25111
|
|
|
24983
25112
|
// src/tool-definitions.ts
|
|
24984
|
-
import { z as
|
|
24985
|
-
import { schemas as
|
|
25113
|
+
import { z as z21 } from "zod";
|
|
25114
|
+
import { schemas as schemas8 } from "@walkeros/cli/dev";
|
|
24986
25115
|
var TOOL_DEFINITIONS = [
|
|
24987
25116
|
{
|
|
24988
25117
|
name: "auth",
|
|
24989
25118
|
title: "Authentication",
|
|
24990
25119
|
description: "Manage walkerOS authentication. Check login status, log in via device code flow, or log out. No terminal or browser required, the MCP client handles the authorization URL.",
|
|
24991
25120
|
inputSchema: {
|
|
24992
|
-
action:
|
|
24993
|
-
deviceCode:
|
|
25121
|
+
action: z21.enum(["status", "login", "logout"]),
|
|
25122
|
+
deviceCode: z21.string().optional()
|
|
24994
25123
|
},
|
|
24995
25124
|
annotations: {
|
|
24996
25125
|
readOnlyHint: false,
|
|
@@ -25004,7 +25133,7 @@ var TOOL_DEFINITIONS = [
|
|
|
25004
25133
|
title: "Project Management",
|
|
25005
25134
|
description: "Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.",
|
|
25006
25135
|
inputSchema: {
|
|
25007
|
-
action:
|
|
25136
|
+
action: z21.enum([
|
|
25008
25137
|
"list",
|
|
25009
25138
|
"get",
|
|
25010
25139
|
"create",
|
|
@@ -25012,8 +25141,8 @@ var TOOL_DEFINITIONS = [
|
|
|
25012
25141
|
"delete",
|
|
25013
25142
|
"set_default"
|
|
25014
25143
|
]),
|
|
25015
|
-
projectId:
|
|
25016
|
-
name:
|
|
25144
|
+
projectId: z21.string().optional(),
|
|
25145
|
+
name: z21.string().optional()
|
|
25017
25146
|
},
|
|
25018
25147
|
annotations: {
|
|
25019
25148
|
readOnlyHint: false,
|
|
@@ -25027,7 +25156,7 @@ var TOOL_DEFINITIONS = [
|
|
|
25027
25156
|
title: "Flow Management",
|
|
25028
25157
|
description: "Manage walkerOS flows and their previews. List/get/create/update/delete/duplicate flows, or create/inspect/delete preview bundles for testing flow changes on live sites.",
|
|
25029
25158
|
inputSchema: {
|
|
25030
|
-
action:
|
|
25159
|
+
action: z21.enum([
|
|
25031
25160
|
"list",
|
|
25032
25161
|
"get",
|
|
25033
25162
|
"create",
|
|
@@ -25039,19 +25168,19 @@ var TOOL_DEFINITIONS = [
|
|
|
25039
25168
|
"preview_create",
|
|
25040
25169
|
"preview_delete"
|
|
25041
25170
|
]),
|
|
25042
|
-
flowId:
|
|
25043
|
-
projectId:
|
|
25044
|
-
name:
|
|
25045
|
-
content:
|
|
25046
|
-
patch:
|
|
25047
|
-
fields:
|
|
25048
|
-
sort:
|
|
25049
|
-
order:
|
|
25050
|
-
includeDeleted:
|
|
25051
|
-
previewId:
|
|
25052
|
-
flowName:
|
|
25053
|
-
flowSettingsId:
|
|
25054
|
-
siteUrl:
|
|
25171
|
+
flowId: z21.string().optional(),
|
|
25172
|
+
projectId: z21.string().optional(),
|
|
25173
|
+
name: z21.string().optional(),
|
|
25174
|
+
content: z21.record(z21.string(), z21.unknown()).optional(),
|
|
25175
|
+
patch: z21.boolean().optional(),
|
|
25176
|
+
fields: z21.array(z21.string()).optional(),
|
|
25177
|
+
sort: z21.enum(["name", "updated_at", "created_at"]).optional(),
|
|
25178
|
+
order: z21.enum(["asc", "desc"]).optional(),
|
|
25179
|
+
includeDeleted: z21.boolean().optional(),
|
|
25180
|
+
previewId: z21.string().optional(),
|
|
25181
|
+
flowName: z21.string().optional(),
|
|
25182
|
+
flowSettingsId: z21.string().optional(),
|
|
25183
|
+
siteUrl: z21.string().optional()
|
|
25055
25184
|
},
|
|
25056
25185
|
annotations: {
|
|
25057
25186
|
readOnlyHint: false,
|
|
@@ -25065,14 +25194,14 @@ var TOOL_DEFINITIONS = [
|
|
|
25065
25194
|
title: "Deploy Management",
|
|
25066
25195
|
description: "Deploy walkerOS flows and manage deployments. For get/delete actions pass flowId (required) plus optional slug to disambiguate when a flow has multiple active deployments. If a flow has >=2 active deployments and no slug is supplied, the tool returns a MULTIPLE_DEPLOYMENTS error with a details[] list showing each deployment's slug, type, status, and updatedAt.",
|
|
25067
25196
|
inputSchema: {
|
|
25068
|
-
action:
|
|
25069
|
-
projectId:
|
|
25070
|
-
flowId:
|
|
25071
|
-
slug:
|
|
25072
|
-
type:
|
|
25073
|
-
status:
|
|
25074
|
-
wait:
|
|
25075
|
-
flowName:
|
|
25197
|
+
action: z21.enum(["deploy", "list", "get", "delete"]),
|
|
25198
|
+
projectId: z21.string().optional(),
|
|
25199
|
+
flowId: z21.string().optional(),
|
|
25200
|
+
slug: z21.string().optional(),
|
|
25201
|
+
type: z21.enum(["web", "server"]).optional(),
|
|
25202
|
+
status: z21.string().optional(),
|
|
25203
|
+
wait: z21.boolean().optional(),
|
|
25204
|
+
flowName: z21.string().optional()
|
|
25076
25205
|
},
|
|
25077
25206
|
annotations: {
|
|
25078
25207
|
readOnlyHint: false,
|
|
@@ -25086,12 +25215,12 @@ var TOOL_DEFINITIONS = [
|
|
|
25086
25215
|
title: "Secret Management",
|
|
25087
25216
|
description: "Manage a flow\u2019s managed secrets (the $secret.<NAME> values its steps reference at deploy/run time). Actions: list (metadata only), set (create), update (rotate value), delete. Secrets are write-mostly: values are encrypted at rest and are NEVER returned, listed, or echoed. Reference a secret from a flow step as $secret.<NAME> (credentials, tokens, and private keys use $secret, not $env).",
|
|
25088
25217
|
inputSchema: {
|
|
25089
|
-
action:
|
|
25090
|
-
projectId:
|
|
25091
|
-
flowId:
|
|
25092
|
-
name:
|
|
25093
|
-
value:
|
|
25094
|
-
secretId:
|
|
25218
|
+
action: z21.enum(["list", "set", "update", "delete"]),
|
|
25219
|
+
projectId: z21.string().optional(),
|
|
25220
|
+
flowId: z21.string(),
|
|
25221
|
+
name: z21.string().optional(),
|
|
25222
|
+
value: z21.string().optional(),
|
|
25223
|
+
secretId: z21.string().optional()
|
|
25095
25224
|
},
|
|
25096
25225
|
annotations: {
|
|
25097
25226
|
readOnlyHint: false,
|
|
@@ -25105,17 +25234,17 @@ var TOOL_DEFINITIONS = [
|
|
|
25105
25234
|
title: "Observe Session",
|
|
25106
25235
|
description: "Open, inspect, or end an Observe session: a time-boxed window on one flow that runtimes attach to as arms. A preview arm streams from a browser, a container arm runs server-side, and both feed ONE shared journeys feed. start opens the window (arms picks which runtimes attach), status reports per-arm state plus recordsReceived and expiresAt, stop ends the whole session including every arm. A flow has at most one session, so status/stop resolve it from flowId when sessionId is omitted. Read the events with observe_journeys; this tool never returns event data and never judges whether events are correct.",
|
|
25107
25236
|
inputSchema: {
|
|
25108
|
-
action:
|
|
25109
|
-
flowId:
|
|
25110
|
-
projectId:
|
|
25111
|
-
sessionId:
|
|
25112
|
-
arms:
|
|
25113
|
-
container:
|
|
25114
|
-
preview:
|
|
25237
|
+
action: z21.enum(["start", "status", "stop"]),
|
|
25238
|
+
flowId: z21.string(),
|
|
25239
|
+
projectId: z21.string().optional(),
|
|
25240
|
+
sessionId: z21.string().optional(),
|
|
25241
|
+
arms: z21.object({
|
|
25242
|
+
container: z21.literal(true).optional(),
|
|
25243
|
+
preview: z21.string().optional()
|
|
25115
25244
|
}).optional(),
|
|
25116
|
-
origins:
|
|
25117
|
-
level:
|
|
25118
|
-
replace:
|
|
25245
|
+
origins: z21.array(z21.string()).optional(),
|
|
25246
|
+
level: z21.enum(["off", "standard", "trace"]).optional(),
|
|
25247
|
+
replace: z21.boolean().optional()
|
|
25119
25248
|
},
|
|
25120
25249
|
annotations: {
|
|
25121
25250
|
readOnlyHint: false,
|
|
@@ -25129,10 +25258,10 @@ var TOOL_DEFINITIONS = [
|
|
|
25129
25258
|
title: "Observe Journeys",
|
|
25130
25259
|
description: "Read the assembled, cross-runtime journeys for a flow that is currently being observed (an active Observe session). Pass flowId; the active session is resolved for you (a flow has at most one). Each journey is one traced event reconstructed end to end across web and server: its ordered hops, per-hop status, captured in/out payloads, consent, and vendor calls. When the flow has no active session the result is { sessionId: null, journeys: [], gaps: [] }. Narrow with traceId (one trace) and limit (1-100, most recent kept; default 50). Read-only.",
|
|
25131
25260
|
inputSchema: {
|
|
25132
|
-
flowId:
|
|
25133
|
-
projectId:
|
|
25134
|
-
traceId:
|
|
25135
|
-
limit:
|
|
25261
|
+
flowId: z21.string(),
|
|
25262
|
+
projectId: z21.string().optional(),
|
|
25263
|
+
traceId: z21.string().optional(),
|
|
25264
|
+
limit: z21.number().int().min(1).max(100).optional()
|
|
25136
25265
|
},
|
|
25137
25266
|
annotations: {
|
|
25138
25267
|
readOnlyHint: true,
|
|
@@ -25144,13 +25273,13 @@ var TOOL_DEFINITIONS = [
|
|
|
25144
25273
|
{
|
|
25145
25274
|
name: "flow_validate",
|
|
25146
25275
|
title: "Validate Flow",
|
|
25147
|
-
description: "Validate walkerOS events, flow configurations, mapping rules, or data contracts. Accepts JSON strings, file paths, or URLs as input; on the hosted server only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. Returns
|
|
25148
|
-
inputSchema:
|
|
25276
|
+
description: "Validate walkerOS events, flow configurations, mapping rules, or data contracts. Accepts JSON strings, file paths, or URLs as input; on the hosted server only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. With only type and input, a flow runs every check on every flow and step, including each package's settings schema (fetched from the package CDN; offline: true skips that and says so). flow and path narrow the run; strict turns warnings and skips into failures: valid is false. Returns valid, errors and warnings with stable codes, and details.scope (what was checked), details.skipped (checks that could not run) and details.deferred (values known only at runtime).",
|
|
25277
|
+
inputSchema: schemas8.ValidateInputShape,
|
|
25149
25278
|
annotations: {
|
|
25150
25279
|
readOnlyHint: true,
|
|
25151
25280
|
destructiveHint: false,
|
|
25152
25281
|
idempotentHint: true,
|
|
25153
|
-
openWorldHint:
|
|
25282
|
+
openWorldHint: true
|
|
25154
25283
|
}
|
|
25155
25284
|
},
|
|
25156
25285
|
{
|
|
@@ -25158,9 +25287,9 @@ var TOOL_DEFINITIONS = [
|
|
|
25158
25287
|
title: "Bundle Flow",
|
|
25159
25288
|
description: "Bundle a walkerOS flow configuration into deployable JavaScript. Resolves all destinations, sources, and transformers, then outputs a tree-shaken production bundle. Returns bundle statistics. Set remote: true to use the walkerOS cloud service instead of local build tools.",
|
|
25160
25289
|
inputSchema: {
|
|
25161
|
-
...
|
|
25162
|
-
remote:
|
|
25163
|
-
content:
|
|
25290
|
+
...schemas8.BundleInputShape,
|
|
25291
|
+
remote: z21.boolean().optional(),
|
|
25292
|
+
content: z21.record(z21.string(), z21.unknown()).optional()
|
|
25164
25293
|
},
|
|
25165
25294
|
annotations: {
|
|
25166
25295
|
readOnlyHint: false,
|
|
@@ -25174,12 +25303,12 @@ var TOOL_DEFINITIONS = [
|
|
|
25174
25303
|
title: "Simulate Flow",
|
|
25175
25304
|
description: FLOW_SIMULATE_DESCRIPTION,
|
|
25176
25305
|
inputSchema: {
|
|
25177
|
-
configPath:
|
|
25178
|
-
event:
|
|
25179
|
-
flow:
|
|
25180
|
-
platform:
|
|
25181
|
-
step:
|
|
25182
|
-
verbose:
|
|
25306
|
+
configPath: schemas8.SimulateInputShape.configPath,
|
|
25307
|
+
event: z21.union([z21.record(z21.string(), z21.unknown()), z21.string()]).optional(),
|
|
25308
|
+
flow: schemas8.SimulateInputShape.flow,
|
|
25309
|
+
platform: schemas8.SimulateInputShape.platform,
|
|
25310
|
+
step: schemas8.SimulateInputShape.step,
|
|
25311
|
+
verbose: z21.boolean().optional()
|
|
25183
25312
|
},
|
|
25184
25313
|
annotations: {
|
|
25185
25314
|
// Not read-only: simulation compiles and runs the flow in process.
|
|
@@ -25194,10 +25323,10 @@ var TOOL_DEFINITIONS = [
|
|
|
25194
25323
|
title: "Push Events",
|
|
25195
25324
|
description: "Push a real event through a walkerOS flow to actual destinations. Makes real API calls to real endpoints. Best suited for server-side flows, web flows should use flow_simulate for testing.",
|
|
25196
25325
|
inputSchema: {
|
|
25197
|
-
configPath:
|
|
25198
|
-
event:
|
|
25199
|
-
flow:
|
|
25200
|
-
platform:
|
|
25326
|
+
configPath: schemas8.PushInputShape.configPath,
|
|
25327
|
+
event: z21.record(z21.string(), z21.unknown()),
|
|
25328
|
+
flow: schemas8.PushInputShape.flow,
|
|
25329
|
+
platform: schemas8.PushInputShape.platform
|
|
25201
25330
|
},
|
|
25202
25331
|
annotations: {
|
|
25203
25332
|
readOnlyHint: false,
|
|
@@ -25211,11 +25340,11 @@ var TOOL_DEFINITIONS = [
|
|
|
25211
25340
|
title: "Flow Examples",
|
|
25212
25341
|
description: "List all step examples in a walkerOS flow configuration. Shows example names, step locations, and in/out shapes. On the hosted server configPath accepts only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. Use this to discover available test fixtures and simulation data.",
|
|
25213
25342
|
inputSchema: {
|
|
25214
|
-
configPath:
|
|
25215
|
-
flow:
|
|
25216
|
-
step:
|
|
25217
|
-
full:
|
|
25218
|
-
includeHidden:
|
|
25343
|
+
configPath: z21.string().min(1),
|
|
25344
|
+
flow: z21.string().optional(),
|
|
25345
|
+
step: z21.string().optional(),
|
|
25346
|
+
full: z21.boolean().optional(),
|
|
25347
|
+
includeHidden: z21.boolean().optional()
|
|
25219
25348
|
},
|
|
25220
25349
|
annotations: {
|
|
25221
25350
|
readOnlyHint: true,
|
|
@@ -25229,8 +25358,8 @@ var TOOL_DEFINITIONS = [
|
|
|
25229
25358
|
title: "Load or Create Flow",
|
|
25230
25359
|
description: "Load an existing flow configuration from a local file path, URL, or walkerOS API (by flow ID). On the hosted server only inline JSON or a saved flow id is accepted, no file paths or URLs. Or create a new empty flow by specifying a platform (web or server). Use the add-step prompt to add sources, destinations, transformers, or stores to the flow.",
|
|
25231
25360
|
inputSchema: {
|
|
25232
|
-
source:
|
|
25233
|
-
platform:
|
|
25361
|
+
source: z21.string().optional(),
|
|
25362
|
+
platform: z21.enum(["web", "server"]).optional()
|
|
25234
25363
|
},
|
|
25235
25364
|
annotations: {
|
|
25236
25365
|
readOnlyHint: true,
|
|
@@ -25244,10 +25373,10 @@ var TOOL_DEFINITIONS = [
|
|
|
25244
25373
|
title: "Search Package",
|
|
25245
25374
|
description: "Start here for package discovery. Never guess package names, use this tool first to find exact names. Without package name: returns catalog filtered by type/platform. With package name: returns metadata, hint keys, and example summaries.",
|
|
25246
25375
|
inputSchema: {
|
|
25247
|
-
package:
|
|
25248
|
-
type:
|
|
25249
|
-
platform:
|
|
25250
|
-
version:
|
|
25376
|
+
package: z21.string().min(1).optional(),
|
|
25377
|
+
type: z21.enum(["source", "destination", "transformer", "store"]).optional(),
|
|
25378
|
+
platform: z21.enum(["web", "server"]).optional(),
|
|
25379
|
+
version: z21.string().optional()
|
|
25251
25380
|
},
|
|
25252
25381
|
annotations: {
|
|
25253
25382
|
readOnlyHint: true,
|
|
@@ -25261,9 +25390,9 @@ var TOOL_DEFINITIONS = [
|
|
|
25261
25390
|
title: "Get Package",
|
|
25262
25391
|
description: 'Requires exact package name, do not guess names, use package_search first to find them. Returns schemas + hint texts + example summaries by default (lightweight). Use section parameter for full content: "hints" (with code blocks), "examples" (full in/out data), or "all".',
|
|
25263
25392
|
inputSchema: {
|
|
25264
|
-
package:
|
|
25265
|
-
version:
|
|
25266
|
-
section:
|
|
25393
|
+
package: z21.string().min(1),
|
|
25394
|
+
version: z21.string().optional(),
|
|
25395
|
+
section: z21.enum(["hints", "examples", "all"]).optional()
|
|
25267
25396
|
},
|
|
25268
25397
|
annotations: {
|
|
25269
25398
|
readOnlyHint: true,
|
|
@@ -25277,8 +25406,8 @@ var TOOL_DEFINITIONS = [
|
|
|
25277
25406
|
title: "Send Feedback",
|
|
25278
25407
|
description: "Send feedback about walkerOS",
|
|
25279
25408
|
inputSchema: {
|
|
25280
|
-
text:
|
|
25281
|
-
anonymous:
|
|
25409
|
+
text: z21.string(),
|
|
25410
|
+
anonymous: z21.boolean().optional()
|
|
25282
25411
|
},
|
|
25283
25412
|
annotations: {
|
|
25284
25413
|
readOnlyHint: false,
|