@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/stdio.js
CHANGED
|
@@ -14,28 +14,52 @@ import { mcpResult, mcpError } from "@walkeros/core";
|
|
|
14
14
|
|
|
15
15
|
// src/schemas/output.ts
|
|
16
16
|
import { z } from "zod";
|
|
17
|
+
var ValidateIssueFields = {
|
|
18
|
+
path: z.string(),
|
|
19
|
+
message: z.string(),
|
|
20
|
+
value: z.unknown().optional(),
|
|
21
|
+
code: z.string().optional().describe("Stable code (the documented validate code list)"),
|
|
22
|
+
keyword: z.string().optional().describe("JSON Schema keyword of an ENTRY_SCHEMA finding")
|
|
23
|
+
};
|
|
17
24
|
var ValidateOutputShape = {
|
|
18
25
|
valid: z.boolean().describe("Whether validation passed"),
|
|
19
26
|
type: z.union([
|
|
20
27
|
z.enum(["contract", "entry", "event", "flow", "mapping"]),
|
|
21
28
|
z.string().regex(/^(destinations|sources|transformers)\.\w+$/)
|
|
22
29
|
]).describe("What was validated"),
|
|
23
|
-
errors: z.array(
|
|
24
|
-
z.object({
|
|
25
|
-
path: z.string(),
|
|
26
|
-
message: z.string(),
|
|
27
|
-
value: z.unknown().optional(),
|
|
28
|
-
code: z.string().optional()
|
|
29
|
-
})
|
|
30
|
-
).describe("Validation errors"),
|
|
30
|
+
errors: z.array(z.object(ValidateIssueFields)).describe("Validation errors"),
|
|
31
31
|
warnings: z.array(
|
|
32
32
|
z.object({
|
|
33
|
-
|
|
34
|
-
message: z.string(),
|
|
33
|
+
...ValidateIssueFields,
|
|
35
34
|
suggestion: z.string().optional()
|
|
36
35
|
})
|
|
37
36
|
).describe("Validation warnings"),
|
|
38
|
-
details: z.
|
|
37
|
+
details: z.object({
|
|
38
|
+
scope: z.object({
|
|
39
|
+
flows: z.array(z.string()),
|
|
40
|
+
entry: z.object({
|
|
41
|
+
section: z.string().optional(),
|
|
42
|
+
key: z.string(),
|
|
43
|
+
flows: z.array(z.string()),
|
|
44
|
+
searchedFlows: z.array(z.string())
|
|
45
|
+
}).optional(),
|
|
46
|
+
checks: z.array(z.string()),
|
|
47
|
+
offline: z.literal(true).optional()
|
|
48
|
+
}).optional().describe("What the run covered"),
|
|
49
|
+
skipped: z.array(
|
|
50
|
+
z.object({
|
|
51
|
+
path: z.string(),
|
|
52
|
+
check: z.string(),
|
|
53
|
+
reason: z.string(),
|
|
54
|
+
code: z.string()
|
|
55
|
+
})
|
|
56
|
+
).optional().describe("Checks in scope that did not run, with the reason"),
|
|
57
|
+
deferred: z.array(z.object({ path: z.string(), reference: z.string() })).optional().describe("Values known only at runtime, not schema-checked")
|
|
58
|
+
}).catchall(z.unknown()).describe("Additional validation details"),
|
|
59
|
+
_hints: z.object({
|
|
60
|
+
next: z.array(z.string()).optional(),
|
|
61
|
+
warnings: z.array(z.string()).optional()
|
|
62
|
+
}).optional().describe("Suggested next steps")
|
|
39
63
|
};
|
|
40
64
|
var BundleOutputShape = {
|
|
41
65
|
success: z.boolean().describe("Whether bundling succeeded"),
|
|
@@ -161,42 +185,14 @@ async function loadValidateInput(runtime, input, type) {
|
|
|
161
185
|
throw error;
|
|
162
186
|
}
|
|
163
187
|
}
|
|
164
|
-
var DEPRECATED_STORE_PACKAGE = "@walkeros/store-memory";
|
|
165
|
-
function detectDeprecatedStorePackages(config) {
|
|
166
|
-
const errors = [];
|
|
167
|
-
if (!config || typeof config !== "object") return errors;
|
|
168
|
-
const flows = config.flows;
|
|
169
|
-
if (!flows || typeof flows !== "object") return errors;
|
|
170
|
-
for (const [flowName, flowEntry] of Object.entries(
|
|
171
|
-
flows
|
|
172
|
-
)) {
|
|
173
|
-
if (!flowEntry || typeof flowEntry !== "object") continue;
|
|
174
|
-
const stores = flowEntry.stores;
|
|
175
|
-
if (!stores || typeof stores !== "object") continue;
|
|
176
|
-
for (const [storeId, storeEntry] of Object.entries(
|
|
177
|
-
stores
|
|
178
|
-
)) {
|
|
179
|
-
if (!storeEntry || typeof storeEntry !== "object") continue;
|
|
180
|
-
const pkg = storeEntry.package;
|
|
181
|
-
if (pkg === DEPRECATED_STORE_PACKAGE) {
|
|
182
|
-
errors.push({
|
|
183
|
-
path: `flows.${flowName}.stores.${storeId}`,
|
|
184
|
-
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.`,
|
|
185
|
-
code: "DEPRECATED_PACKAGE"
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return errors;
|
|
191
|
-
}
|
|
192
188
|
var TITLE = "Validate Flow";
|
|
193
|
-
var 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
|
|
189
|
+
var 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).";
|
|
194
190
|
var inputSchema = schemas.ValidateInputShape;
|
|
195
191
|
var annotations = {
|
|
196
192
|
readOnlyHint: true,
|
|
197
193
|
destructiveHint: false,
|
|
198
194
|
idempotentHint: true,
|
|
199
|
-
openWorldHint:
|
|
195
|
+
openWorldHint: true
|
|
200
196
|
};
|
|
201
197
|
function createFlowValidateToolSpec(runtime) {
|
|
202
198
|
return {
|
|
@@ -209,41 +205,46 @@ function createFlowValidateToolSpec(runtime) {
|
|
|
209
205
|
};
|
|
210
206
|
}
|
|
211
207
|
async function flowValidateHandlerBody(runtime, input) {
|
|
208
|
+
const parsed = schemas.ValidateInputSchema.safeParse(input ?? {});
|
|
209
|
+
if (!parsed.success) {
|
|
210
|
+
return mcpError(parsed.error, "Check the flow_validate input fields");
|
|
211
|
+
}
|
|
212
212
|
const {
|
|
213
213
|
type,
|
|
214
214
|
input: validateInput,
|
|
215
215
|
flow,
|
|
216
|
-
path:
|
|
217
|
-
|
|
216
|
+
path: path3,
|
|
217
|
+
strict,
|
|
218
|
+
offline
|
|
219
|
+
} = parsed.data;
|
|
218
220
|
try {
|
|
219
221
|
const resolved = await loadValidateInput(runtime, validateInput, type);
|
|
222
|
+
const configDir = runtime.baseDir?.(validateInput);
|
|
220
223
|
const result = await validate(type, resolved, {
|
|
221
224
|
flow,
|
|
222
|
-
path:
|
|
225
|
+
path: path3,
|
|
226
|
+
strict,
|
|
227
|
+
offline,
|
|
228
|
+
...configDir ? { configDir } : {}
|
|
223
229
|
});
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
errors: [...result.errors, ...deprecatedErrors]
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
const hints = augmented.valid ? {
|
|
236
|
-
next: runtime.simulate ? [
|
|
237
|
-
"Use flow_simulate to test event flow",
|
|
238
|
-
"Use flow_bundle to build"
|
|
239
|
-
] : [HINT_OUT_OF_PROCESS]
|
|
240
|
-
} : {
|
|
230
|
+
const skipped = result.details.skipped ?? [];
|
|
231
|
+
const next = runtime.simulate ? ["Use flow_simulate to test event flow", "Use flow_bundle to build"] : [HINT_OUT_OF_PROCESS];
|
|
232
|
+
const hints = !result.valid && result.errors.length === 0 ? {
|
|
233
|
+
next: [
|
|
234
|
+
`strict: ${result.warnings.length} warning(s) and ${skipped.length} skipped check(s) count as failures; resolve them, or run without strict`
|
|
235
|
+
]
|
|
236
|
+
} : !result.valid ? {
|
|
241
237
|
next: [
|
|
242
238
|
"Fix errors above, then run flow_validate again",
|
|
243
239
|
"Read walkeros://reference/flow-schema for correct structure"
|
|
244
240
|
]
|
|
245
|
-
}
|
|
246
|
-
|
|
241
|
+
} : skipped.length > 0 ? {
|
|
242
|
+
next: [
|
|
243
|
+
`Valid in checked scope; ${skipped.length} check(s) skipped, see details.skipped`,
|
|
244
|
+
...next
|
|
245
|
+
]
|
|
246
|
+
} : { next };
|
|
247
|
+
return mcpResult(result, hints);
|
|
247
248
|
} catch (error) {
|
|
248
249
|
return mcpError(
|
|
249
250
|
error,
|
|
@@ -266,15 +267,30 @@ function registerFlowValidateTool(server, runtime) {
|
|
|
266
267
|
outputSchema: ValidateOutputShape,
|
|
267
268
|
annotations: spec.annotations
|
|
268
269
|
},
|
|
269
|
-
|
|
270
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
271
|
-
spec.handler
|
|
270
|
+
(args) => flowValidateHandlerBody(runtime, args)
|
|
272
271
|
);
|
|
273
272
|
}
|
|
274
273
|
|
|
275
274
|
// src/tools/bundle.ts
|
|
276
275
|
import { schemas as schemas2 } from "@walkeros/cli/dev";
|
|
277
|
-
import { mcpResult as mcpResult2, mcpError as
|
|
276
|
+
import { mcpResult as mcpResult2, mcpError as mcpError3 } from "@walkeros/core";
|
|
277
|
+
|
|
278
|
+
// src/tools/parse-input.ts
|
|
279
|
+
import { z as z2 } from "zod";
|
|
280
|
+
import { mcpError as mcpError2 } from "@walkeros/core";
|
|
281
|
+
function inputIssuesMessage(error) {
|
|
282
|
+
return error.issues.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`).join("; ");
|
|
283
|
+
}
|
|
284
|
+
function parseToolInput(shape, raw) {
|
|
285
|
+
const parsed = z2.object(shape).safeParse(raw ?? {});
|
|
286
|
+
if (!parsed.success) {
|
|
287
|
+
return {
|
|
288
|
+
ok: false,
|
|
289
|
+
error: mcpError2(new Error(inputIssuesMessage(parsed.error)))
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
return { ok: true, data: parsed.data };
|
|
293
|
+
}
|
|
278
294
|
|
|
279
295
|
// src/tools/resolve-config-path.ts
|
|
280
296
|
async function resolveConfigPath(client, configPath) {
|
|
@@ -306,10 +322,12 @@ function createFlowBundleToolSpec(client, runtime) {
|
|
|
306
322
|
};
|
|
307
323
|
}
|
|
308
324
|
async function flowBundleHandlerBody(client, runtime, input) {
|
|
309
|
-
const
|
|
325
|
+
const parsed = parseToolInput(inputSchema2, input);
|
|
326
|
+
if (!parsed.ok) return parsed.error;
|
|
327
|
+
const { configPath, flow, stats, output } = parsed.data;
|
|
310
328
|
if (!runtime.bundle) {
|
|
311
329
|
const refusal = unavailableOperation("bundle");
|
|
312
|
-
return
|
|
330
|
+
return mcpError3(refusal, refusal.hint);
|
|
313
331
|
}
|
|
314
332
|
try {
|
|
315
333
|
const resolvedConfigPath = await resolveConfigPath(client, configPath);
|
|
@@ -329,9 +347,8 @@ async function flowBundleHandlerBody(client, runtime, input) {
|
|
|
329
347
|
}
|
|
330
348
|
);
|
|
331
349
|
}
|
|
332
|
-
const output_ = result;
|
|
333
350
|
return mcpResult2(
|
|
334
|
-
{ success: true, ...
|
|
351
|
+
{ success: true, ...result },
|
|
335
352
|
{
|
|
336
353
|
next: [
|
|
337
354
|
"Use flow_simulate to test",
|
|
@@ -340,7 +357,7 @@ async function flowBundleHandlerBody(client, runtime, input) {
|
|
|
340
357
|
}
|
|
341
358
|
);
|
|
342
359
|
} catch (error) {
|
|
343
|
-
return
|
|
360
|
+
return mcpError3(
|
|
344
361
|
error,
|
|
345
362
|
refusalHint(error, "Run flow_validate for detailed error messages")
|
|
346
363
|
);
|
|
@@ -358,54 +375,39 @@ function registerFlowBundleTool(server, client, runtime) {
|
|
|
358
375
|
outputSchema: BundleOutputShape,
|
|
359
376
|
annotations: spec.annotations
|
|
360
377
|
},
|
|
361
|
-
|
|
362
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
363
|
-
spec.handler
|
|
378
|
+
(args) => flowBundleHandlerBody(client, runtime, args)
|
|
364
379
|
);
|
|
365
380
|
}
|
|
366
381
|
|
|
367
382
|
// src/tools/simulate.ts
|
|
368
|
-
import { z as
|
|
383
|
+
import { z as z3 } from "zod";
|
|
369
384
|
import { schemas as schemas3 } from "@walkeros/cli/dev";
|
|
370
|
-
import {
|
|
371
|
-
import { scrubSecrets, toPrintable } from "@walkeros/core/node";
|
|
372
|
-
import { maskKnownNumbers } from "@walkeros/cli";
|
|
385
|
+
import { filterValues, mcpResult as mcpResult4, mcpError as mcpError5 } from "@walkeros/core";
|
|
373
386
|
|
|
374
387
|
// src/tools/simulate-description.ts
|
|
375
388
|
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.`;
|
|
376
389
|
|
|
377
|
-
// src/tools/
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
"transformer",
|
|
381
|
-
"collector",
|
|
382
|
-
"destination"
|
|
383
|
-
];
|
|
384
|
-
function isStepType(value) {
|
|
385
|
-
return STEP_TYPES.some((t) => t === value);
|
|
386
|
-
}
|
|
390
|
+
// src/tools/egress.ts
|
|
391
|
+
import { isObject as isObject2, mcpResult as mcpResult3 } from "@walkeros/core";
|
|
392
|
+
import { scrubJson, scrubSecrets } from "@walkeros/core/node";
|
|
387
393
|
function scrubbed(result, known) {
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
{ known }
|
|
391
|
-
);
|
|
392
|
-
let parsed;
|
|
393
|
-
try {
|
|
394
|
-
parsed = JSON.parse(text);
|
|
395
|
-
} catch {
|
|
396
|
-
parsed = void 0;
|
|
397
|
-
}
|
|
398
|
-
if (!isObject2(parsed))
|
|
399
|
-
throw new Error("Simulation result could not be redacted as JSON.");
|
|
394
|
+
const parsed = parseObject(scrubJson(result, { known }));
|
|
395
|
+
if (!parsed) throw new Error("Result could not be redacted as JSON.");
|
|
400
396
|
return parsed;
|
|
401
397
|
}
|
|
402
398
|
function scrubbedError(response, known) {
|
|
403
399
|
let structuredContent;
|
|
404
400
|
try {
|
|
405
|
-
|
|
401
|
+
if (response.structuredContent)
|
|
402
|
+
structuredContent = scrubbed(response.structuredContent, known);
|
|
406
403
|
} catch {
|
|
407
|
-
structuredContent =
|
|
408
|
-
|
|
404
|
+
structuredContent = void 0;
|
|
405
|
+
}
|
|
406
|
+
if (structuredContent) {
|
|
407
|
+
return {
|
|
408
|
+
...response,
|
|
409
|
+
content: [{ type: "text", text: JSON.stringify(structuredContent) }],
|
|
410
|
+
structuredContent
|
|
409
411
|
};
|
|
410
412
|
}
|
|
411
413
|
return {
|
|
@@ -414,9 +416,48 @@ function scrubbedError(response, known) {
|
|
|
414
416
|
...part,
|
|
415
417
|
text: scrubSecrets(part.text, { known })
|
|
416
418
|
})),
|
|
417
|
-
structuredContent
|
|
419
|
+
structuredContent: { error: "The error could not be redacted." }
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function scrubbedPushResult(result, known) {
|
|
423
|
+
const text = scrubJson(result, { known, space: 2 });
|
|
424
|
+
const parsed = parseObject(text);
|
|
425
|
+
if (parsed)
|
|
426
|
+
return mcpResult3({
|
|
427
|
+
...parsed,
|
|
428
|
+
success: result.success,
|
|
429
|
+
duration: result.duration
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
content: [{ type: "text", text }],
|
|
433
|
+
structuredContent: { success: result.success, duration: result.duration }
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function parseObject(text) {
|
|
437
|
+
try {
|
|
438
|
+
const parsed = JSON.parse(text);
|
|
439
|
+
return isObject2(parsed) ? parsed : void 0;
|
|
440
|
+
} catch {
|
|
441
|
+
return void 0;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async function readRun(runtime, input) {
|
|
445
|
+
if (runtime.loadRun) return runtime.loadRun(input);
|
|
446
|
+
return {
|
|
447
|
+
knownSecrets: runtime.knownSecrets ? await runtime.knownSecrets(input) : []
|
|
418
448
|
};
|
|
419
449
|
}
|
|
450
|
+
|
|
451
|
+
// src/tools/simulate.ts
|
|
452
|
+
var STEP_TYPES = [
|
|
453
|
+
"source",
|
|
454
|
+
"transformer",
|
|
455
|
+
"collector",
|
|
456
|
+
"destination"
|
|
457
|
+
];
|
|
458
|
+
function isStepType(value) {
|
|
459
|
+
return STEP_TYPES.some((t) => t === value);
|
|
460
|
+
}
|
|
420
461
|
var TITLE3 = "Simulate Flow";
|
|
421
462
|
var COMMANDS = [
|
|
422
463
|
"config",
|
|
@@ -426,29 +467,29 @@ var COMMANDS = [
|
|
|
426
467
|
];
|
|
427
468
|
var inputSchema3 = {
|
|
428
469
|
configPath: schemas3.SimulateInputShape.configPath,
|
|
429
|
-
event:
|
|
470
|
+
event: z3.union([z3.record(z3.string(), z3.unknown()), z3.string()]).optional().describe(
|
|
430
471
|
"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."
|
|
431
472
|
),
|
|
432
473
|
flow: schemas3.SimulateInputShape.flow,
|
|
433
474
|
platform: schemas3.SimulateInputShape.platform,
|
|
434
475
|
// Override the (optional) CLI `step` shape: the simulate handler hard-requires
|
|
435
476
|
// a target step (no all-steps mode), so the registered schema must be honest.
|
|
436
|
-
step:
|
|
477
|
+
step: z3.string().describe(
|
|
437
478
|
'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).'
|
|
438
479
|
),
|
|
439
|
-
verbose:
|
|
440
|
-
ingest:
|
|
480
|
+
verbose: z3.boolean().optional().describe("Include full payload per destination (default: false)"),
|
|
481
|
+
ingest: z3.record(z3.string(), z3.unknown()).optional().describe(
|
|
441
482
|
"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."
|
|
442
483
|
),
|
|
443
|
-
state:
|
|
444
|
-
consent:
|
|
445
|
-
user:
|
|
446
|
-
globals:
|
|
447
|
-
timing:
|
|
484
|
+
state: z3.object({
|
|
485
|
+
consent: z3.record(z3.string(), z3.boolean()).optional(),
|
|
486
|
+
user: z3.record(z3.string(), z3.unknown()).optional(),
|
|
487
|
+
globals: z3.record(z3.string(), z3.unknown()).optional(),
|
|
488
|
+
timing: z3.number().optional()
|
|
448
489
|
}).optional().describe(
|
|
449
490
|
"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."
|
|
450
491
|
),
|
|
451
|
-
command:
|
|
492
|
+
command: z3.enum(COMMANDS).optional().describe(
|
|
452
493
|
"Destination steps only: run this collector command with event as its data instead of pushing it, as a step example with command does."
|
|
453
494
|
)
|
|
454
495
|
};
|
|
@@ -472,7 +513,18 @@ function createFlowSimulateToolSpec(client, runtime) {
|
|
|
472
513
|
handler: (input) => flowSimulateHandlerBody(client, runtime, input)
|
|
473
514
|
};
|
|
474
515
|
}
|
|
516
|
+
function toProperties(value) {
|
|
517
|
+
if (!value) return void 0;
|
|
518
|
+
const properties = {};
|
|
519
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
520
|
+
const property = filterValues(entry);
|
|
521
|
+
if (property !== void 0) properties[key] = property;
|
|
522
|
+
}
|
|
523
|
+
return properties;
|
|
524
|
+
}
|
|
475
525
|
async function flowSimulateHandlerBody(client, runtime, input) {
|
|
526
|
+
const parsed = parseToolInput(inputSchema3, input);
|
|
527
|
+
if (!parsed.ok) return parsed.error;
|
|
476
528
|
const {
|
|
477
529
|
configPath,
|
|
478
530
|
event,
|
|
@@ -483,10 +535,10 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
483
535
|
ingest,
|
|
484
536
|
state,
|
|
485
537
|
command
|
|
486
|
-
} =
|
|
538
|
+
} = parsed.data;
|
|
487
539
|
if (!runtime.simulate) {
|
|
488
540
|
const refusal = unavailableOperation("simulate");
|
|
489
|
-
return
|
|
541
|
+
return mcpError5(refusal, refusal.hint);
|
|
490
542
|
}
|
|
491
543
|
let known = [];
|
|
492
544
|
try {
|
|
@@ -527,10 +579,25 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
527
579
|
throw new Error("command applies to destination steps only.");
|
|
528
580
|
}
|
|
529
581
|
const resolvedConfigPath = await resolveConfigPath(client, configPath);
|
|
530
|
-
|
|
582
|
+
const run = await readRun(runtime, resolvedConfigPath);
|
|
583
|
+
known = run.knownSecrets;
|
|
531
584
|
const result = await runtime.simulate(
|
|
532
585
|
resolvedConfigPath,
|
|
533
|
-
{
|
|
586
|
+
{
|
|
587
|
+
stepType,
|
|
588
|
+
stepId,
|
|
589
|
+
event: resolvedEvent,
|
|
590
|
+
flow,
|
|
591
|
+
ingest,
|
|
592
|
+
state: state && {
|
|
593
|
+
consent: state.consent,
|
|
594
|
+
user: toProperties(state.user),
|
|
595
|
+
globals: toProperties(state.globals),
|
|
596
|
+
timing: state.timing
|
|
597
|
+
},
|
|
598
|
+
command,
|
|
599
|
+
config: run.config
|
|
600
|
+
}
|
|
534
601
|
);
|
|
535
602
|
const success = !result.error;
|
|
536
603
|
const errorMessage = result.error?.message;
|
|
@@ -541,7 +608,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
541
608
|
).length;
|
|
542
609
|
const summary = `Source captured ${eventCount} event${eventCount !== 1 ? "s" : ""} and ${commandCount} command${commandCount !== 1 ? "s" : ""}`;
|
|
543
610
|
const shownCalls = verbose ? result.calls : result.calls.filter((call) => call.fn === "elb");
|
|
544
|
-
return
|
|
611
|
+
return mcpResult4(
|
|
545
612
|
scrubbed(
|
|
546
613
|
{
|
|
547
614
|
success,
|
|
@@ -563,7 +630,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
563
630
|
);
|
|
564
631
|
}
|
|
565
632
|
if (result.step === "transformer") {
|
|
566
|
-
return
|
|
633
|
+
return mcpResult4(
|
|
567
634
|
scrubbed(
|
|
568
635
|
{
|
|
569
636
|
success,
|
|
@@ -580,7 +647,7 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
580
647
|
);
|
|
581
648
|
}
|
|
582
649
|
if (result.step === "collector") {
|
|
583
|
-
return
|
|
650
|
+
return mcpResult4(
|
|
584
651
|
scrubbed(
|
|
585
652
|
{
|
|
586
653
|
success,
|
|
@@ -620,21 +687,13 @@ async function flowSimulateHandlerBody(client, runtime, input) {
|
|
|
620
687
|
...result.skipped ? { skipped: result.skipped } : {},
|
|
621
688
|
duration: result.duration
|
|
622
689
|
};
|
|
623
|
-
return
|
|
690
|
+
return mcpResult4(scrubbed(resultObj, known), {
|
|
624
691
|
next: ["Use flow_bundle to build for production"],
|
|
625
692
|
...warnings.length > 0 ? { warnings } : {}
|
|
626
693
|
});
|
|
627
694
|
} catch (error) {
|
|
628
695
|
const hint = "Run flow_validate for detailed error messages";
|
|
629
|
-
return scrubbedError(
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
async function knownSecretsOf(runtime, input) {
|
|
633
|
-
if (!runtime.knownSecrets) return [];
|
|
634
|
-
try {
|
|
635
|
-
return await runtime.knownSecrets(input);
|
|
636
|
-
} catch {
|
|
637
|
-
return [];
|
|
696
|
+
return scrubbedError(mcpError5(error, refusalHint(error, hint)), known);
|
|
638
697
|
}
|
|
639
698
|
}
|
|
640
699
|
function keysOf(consent) {
|
|
@@ -666,21 +725,19 @@ function registerFlowSimulateTool(server, client, runtime) {
|
|
|
666
725
|
outputSchema: SimulateOutputShape,
|
|
667
726
|
annotations: spec.annotations
|
|
668
727
|
},
|
|
669
|
-
|
|
670
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
671
|
-
spec.handler
|
|
728
|
+
(args) => flowSimulateHandlerBody(client, runtime, args)
|
|
672
729
|
);
|
|
673
730
|
}
|
|
674
731
|
|
|
675
732
|
// src/tools/push.ts
|
|
676
|
-
import { z as
|
|
733
|
+
import { z as z4 } from "zod";
|
|
677
734
|
import { schemas as schemas4 } from "@walkeros/cli/dev";
|
|
678
|
-
import {
|
|
735
|
+
import { mcpError as mcpError6 } from "@walkeros/core";
|
|
679
736
|
var TITLE4 = "Push Events";
|
|
680
737
|
var DESCRIPTION3 = "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.";
|
|
681
738
|
var inputSchema4 = {
|
|
682
739
|
configPath: schemas4.PushInputShape.configPath,
|
|
683
|
-
event:
|
|
740
|
+
event: z4.record(z4.string(), z4.unknown()).describe(
|
|
684
741
|
'Event object, e.g. { name: "page view", data: { title: "Home" } }'
|
|
685
742
|
),
|
|
686
743
|
flow: schemas4.PushInputShape.flow,
|
|
@@ -703,30 +760,42 @@ function createFlowPushToolSpec(runtime) {
|
|
|
703
760
|
};
|
|
704
761
|
}
|
|
705
762
|
async function flowPushHandlerBody(runtime, input) {
|
|
706
|
-
const
|
|
763
|
+
const parsed = parseToolInput(inputSchema4, input);
|
|
764
|
+
if (!parsed.ok) return parsed.error;
|
|
765
|
+
const { configPath, event, flow, platform } = parsed.data;
|
|
707
766
|
if (!runtime.push) {
|
|
708
767
|
const refusal = unavailableOperation("push");
|
|
709
|
-
return
|
|
768
|
+
return mcpError6(refusal, refusal.hint);
|
|
710
769
|
}
|
|
770
|
+
let known = [];
|
|
711
771
|
try {
|
|
772
|
+
const run = await readRun(runtime, configPath);
|
|
773
|
+
known = run.knownSecrets;
|
|
712
774
|
const result = await runtime.push(configPath, event, {
|
|
713
775
|
flow,
|
|
714
|
-
platform
|
|
776
|
+
platform,
|
|
777
|
+
config: run.config
|
|
715
778
|
});
|
|
716
779
|
if (!result.success) {
|
|
717
|
-
return
|
|
718
|
-
|
|
719
|
-
|
|
780
|
+
return scrubbedError(
|
|
781
|
+
mcpError6(
|
|
782
|
+
new Error(result.error || "Push failed"),
|
|
783
|
+
"Check destination configuration and connectivity."
|
|
784
|
+
),
|
|
785
|
+
known
|
|
720
786
|
);
|
|
721
787
|
}
|
|
722
|
-
return
|
|
788
|
+
return scrubbedPushResult(result, known);
|
|
723
789
|
} catch (error) {
|
|
724
|
-
return
|
|
725
|
-
|
|
726
|
-
refusalHint(
|
|
790
|
+
return scrubbedError(
|
|
791
|
+
mcpError6(
|
|
727
792
|
error,
|
|
728
|
-
|
|
729
|
-
|
|
793
|
+
refusalHint(
|
|
794
|
+
error,
|
|
795
|
+
"Check configPath and event format. For web flows, use flow_simulate."
|
|
796
|
+
)
|
|
797
|
+
),
|
|
798
|
+
known
|
|
730
799
|
);
|
|
731
800
|
}
|
|
732
801
|
}
|
|
@@ -742,15 +811,13 @@ function registerFlowPushTool(server, runtime) {
|
|
|
742
811
|
outputSchema: PushOutputShape,
|
|
743
812
|
annotations: spec.annotations
|
|
744
813
|
},
|
|
745
|
-
|
|
746
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
747
|
-
spec.handler
|
|
814
|
+
(args) => flowPushHandlerBody(runtime, args)
|
|
748
815
|
);
|
|
749
816
|
}
|
|
750
817
|
|
|
751
818
|
// src/tools/examples.ts
|
|
752
|
-
import { z as
|
|
753
|
-
import { fetchPackage, mcpResult as mcpResult5, mcpError as
|
|
819
|
+
import { z as z5 } from "zod";
|
|
820
|
+
import { fetchPackage, mcpResult as mcpResult5, mcpError as mcpError7 } from "@walkeros/core";
|
|
754
821
|
import { resolveExportName, selectDevExamples } from "@walkeros/cli";
|
|
755
822
|
|
|
756
823
|
// src/catalog.ts
|
|
@@ -758,7 +825,7 @@ var NPM_SEARCH_URL = "https://registry.npmjs.org/-/v1/search";
|
|
|
758
825
|
var JSDELIVR_BASE = "https://cdn.jsdelivr.net/npm";
|
|
759
826
|
var WALKEROS_JSON_PATH = "dist/walkerOS.json";
|
|
760
827
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
761
|
-
var CLIENT_HEADER = "walkeros-mcp/4.7.0
|
|
828
|
+
var CLIENT_HEADER = "walkeros-mcp/4.7.0";
|
|
762
829
|
function getPackageBaseUrl() {
|
|
763
830
|
return process.env.WALKEROS_APP_URL || void 0;
|
|
764
831
|
}
|
|
@@ -910,20 +977,53 @@ function applyFilters(entries, filters) {
|
|
|
910
977
|
return results;
|
|
911
978
|
}
|
|
912
979
|
|
|
980
|
+
// src/tools/narrow.ts
|
|
981
|
+
import { schemas as schemas5 } from "@walkeros/core/dev";
|
|
982
|
+
function isRecord(value) {
|
|
983
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
984
|
+
}
|
|
985
|
+
function stringField(value, key) {
|
|
986
|
+
if (!isRecord(value)) return void 0;
|
|
987
|
+
const field = value[key];
|
|
988
|
+
return typeof field === "string" ? field : void 0;
|
|
989
|
+
}
|
|
990
|
+
function recordField(value, key) {
|
|
991
|
+
if (!isRecord(value)) return void 0;
|
|
992
|
+
const field = value[key];
|
|
993
|
+
return isRecord(field) ? field : void 0;
|
|
994
|
+
}
|
|
995
|
+
function fieldsOf(value) {
|
|
996
|
+
return isRecord(value) ? value : {};
|
|
997
|
+
}
|
|
998
|
+
function isFlowJson(value) {
|
|
999
|
+
return isRecord(value) && isRecord(value.flows);
|
|
1000
|
+
}
|
|
1001
|
+
function stepExamplesOf(value) {
|
|
1002
|
+
if (!isRecord(value)) return void 0;
|
|
1003
|
+
const examples = {};
|
|
1004
|
+
const skipped = [];
|
|
1005
|
+
for (const [name, example] of Object.entries(value)) {
|
|
1006
|
+
const parsed = schemas5.FlowSchemas.StepExampleSchema.safeParse(example);
|
|
1007
|
+
if (parsed.success) examples[name] = parsed.data;
|
|
1008
|
+
else skipped.push(name);
|
|
1009
|
+
}
|
|
1010
|
+
return { examples, skipped };
|
|
1011
|
+
}
|
|
1012
|
+
|
|
913
1013
|
// src/tools/examples.ts
|
|
914
1014
|
var MAX_PACKAGE_LOOKUPS = 25;
|
|
915
1015
|
var TITLE5 = "Flow Examples";
|
|
916
1016
|
var DESCRIPTION4 = '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.';
|
|
917
1017
|
var inputSchema5 = {
|
|
918
|
-
configPath:
|
|
1018
|
+
configPath: z5.string().min(1).describe(
|
|
919
1019
|
"Inline JSON string, file path, or URL of a flow configuration (hosted server: inline JSON or a saved flow id only)"
|
|
920
1020
|
),
|
|
921
|
-
flow:
|
|
922
|
-
step:
|
|
923
|
-
full:
|
|
1021
|
+
flow: z5.string().optional().describe("Flow name for multi-flow configs"),
|
|
1022
|
+
step: z5.string().optional().describe('Filter to a specific step (e.g., "destination.gtag")'),
|
|
1023
|
+
full: z5.boolean().optional().describe(
|
|
924
1024
|
"Return full in/out/mapping data for each example (default: false, returns metadata only)"
|
|
925
1025
|
),
|
|
926
|
-
includeHidden:
|
|
1026
|
+
includeHidden: z5.boolean().optional().describe(
|
|
927
1027
|
"Include examples marked public: false (default: false). Set true for test/debug discovery."
|
|
928
1028
|
)
|
|
929
1029
|
};
|
|
@@ -944,9 +1044,14 @@ function createFlowExamplesToolSpec(runtime) {
|
|
|
944
1044
|
};
|
|
945
1045
|
}
|
|
946
1046
|
async function flowExamplesHandlerBody(runtime, input) {
|
|
947
|
-
const
|
|
1047
|
+
const parsed = parseToolInput(inputSchema5, input);
|
|
1048
|
+
if (!parsed.ok) return parsed.error;
|
|
1049
|
+
const { configPath, flow, step, full, includeHidden } = parsed.data;
|
|
948
1050
|
try {
|
|
949
1051
|
const rawConfig = await runtime.load(configPath);
|
|
1052
|
+
if (!isFlowJson(rawConfig)) {
|
|
1053
|
+
throw new Error("Config is not a flow config: it has no flows object.");
|
|
1054
|
+
}
|
|
950
1055
|
const flowNames = Object.keys(rawConfig.flows || {});
|
|
951
1056
|
const flowName = flow || (flowNames.length === 1 ? flowNames[0] : void 0);
|
|
952
1057
|
if (!flowName) {
|
|
@@ -999,6 +1104,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
999
1104
|
};
|
|
1000
1105
|
const packageLookups = /* @__PURE__ */ new Map();
|
|
1001
1106
|
let skippedPackages = false;
|
|
1107
|
+
const skippedExamples = [];
|
|
1002
1108
|
const packageFor = (packageName) => {
|
|
1003
1109
|
const existing = packageLookups.get(packageName);
|
|
1004
1110
|
if (existing) return existing;
|
|
@@ -1015,10 +1121,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
1015
1121
|
{ examples: info.examples, exportExamples: info.exportExamples },
|
|
1016
1122
|
exportName
|
|
1017
1123
|
);
|
|
1018
|
-
|
|
1019
|
-
if (stepExamples && typeof stepExamples === "object")
|
|
1020
|
-
return stepExamples;
|
|
1021
|
-
return void 0;
|
|
1124
|
+
return stepExamplesOf(selected?.step);
|
|
1022
1125
|
};
|
|
1023
1126
|
const stepTypes = [
|
|
1024
1127
|
{ key: "sources", type: "source" },
|
|
@@ -1030,9 +1133,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
1030
1133
|
for (const [name, ref] of Object.entries(refs)) {
|
|
1031
1134
|
if (step && `${type}.${name}` !== step) continue;
|
|
1032
1135
|
if (ref.examples) {
|
|
1033
|
-
examples.push(
|
|
1034
|
-
...toItems(ref.examples, type, name, "inline")
|
|
1035
|
-
);
|
|
1136
|
+
examples.push(...toItems(ref.examples, type, name, "inline"));
|
|
1036
1137
|
continue;
|
|
1037
1138
|
}
|
|
1038
1139
|
if (!ref.package) continue;
|
|
@@ -1040,8 +1141,12 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
1040
1141
|
if (!info) continue;
|
|
1041
1142
|
const { exportName } = resolveExportName(flowSettings, type, name);
|
|
1042
1143
|
const packageExamples = stepExamplesFor(info, exportName);
|
|
1043
|
-
if (packageExamples)
|
|
1044
|
-
|
|
1144
|
+
if (!packageExamples) continue;
|
|
1145
|
+
examples.push(
|
|
1146
|
+
...toItems(packageExamples.examples, type, name, "package")
|
|
1147
|
+
);
|
|
1148
|
+
for (const exampleName of packageExamples.skipped)
|
|
1149
|
+
skippedExamples.push(`${type}.${name}.${exampleName}`);
|
|
1045
1150
|
}
|
|
1046
1151
|
}
|
|
1047
1152
|
const result = {
|
|
@@ -1055,6 +1160,11 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
1055
1160
|
"No examples found. Add examples to step entries, or reference a package that ships examples (see package_get)."
|
|
1056
1161
|
);
|
|
1057
1162
|
}
|
|
1163
|
+
if (skippedExamples.length > 0) {
|
|
1164
|
+
warnings.push(
|
|
1165
|
+
`Skipped ${skippedExamples.length} package example(s) that do not match the step example schema: ${skippedExamples.join(", ")}.`
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1058
1168
|
if (skippedPackages) {
|
|
1059
1169
|
warnings.push(
|
|
1060
1170
|
`Package examples were looked up for the first ${MAX_PACKAGE_LOOKUPS} packages only. Use step to narrow the result.`
|
|
@@ -1068,7 +1178,7 @@ async function flowExamplesHandlerBody(runtime, input) {
|
|
|
1068
1178
|
};
|
|
1069
1179
|
return mcpResult5(result, hints);
|
|
1070
1180
|
} catch (error) {
|
|
1071
|
-
return
|
|
1181
|
+
return mcpError7(
|
|
1072
1182
|
error,
|
|
1073
1183
|
refusalHint(error, "Check configPath \u2014 expected a flow.json file")
|
|
1074
1184
|
);
|
|
@@ -1086,25 +1196,23 @@ function registerFlowExamplesTool(server, runtime) {
|
|
|
1086
1196
|
outputSchema: ExamplesListOutputShape,
|
|
1087
1197
|
annotations: spec.annotations
|
|
1088
1198
|
},
|
|
1089
|
-
|
|
1090
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1091
|
-
spec.handler
|
|
1199
|
+
(args) => flowExamplesHandlerBody(runtime, args)
|
|
1092
1200
|
);
|
|
1093
1201
|
}
|
|
1094
1202
|
|
|
1095
1203
|
// src/tools/package.ts
|
|
1096
|
-
import { z as
|
|
1097
|
-
import { fetchPackage as fetchPackage2, mcpResult as mcpResult6, mcpError as
|
|
1204
|
+
import { z as z6 } from "zod";
|
|
1205
|
+
import { fetchPackage as fetchPackage2, mcpResult as mcpResult6, mcpError as mcpError8 } from "@walkeros/core";
|
|
1098
1206
|
import { mergeConfigSchema } from "@walkeros/core/dev";
|
|
1099
1207
|
var SEARCH_TITLE = "Search Package";
|
|
1100
1208
|
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.";
|
|
1101
1209
|
var searchInputSchema = {
|
|
1102
|
-
package:
|
|
1210
|
+
package: z6.string().min(1).optional().describe(
|
|
1103
1211
|
"Exact npm package name for detailed lookup (e.g., @walkeros/web-destination-snowplow)"
|
|
1104
1212
|
),
|
|
1105
|
-
type:
|
|
1106
|
-
platform:
|
|
1107
|
-
version:
|
|
1213
|
+
type: z6.enum(["source", "destination", "transformer", "store"]).optional().describe("Filter by package type (browse mode)"),
|
|
1214
|
+
platform: z6.enum(["web", "server"]).optional().describe("Filter by platform (browse mode, includes universal packages)"),
|
|
1215
|
+
version: z6.string().optional().describe("Package version for detailed lookup (default: latest)")
|
|
1108
1216
|
};
|
|
1109
1217
|
var searchAnnotations = {
|
|
1110
1218
|
readOnlyHint: true,
|
|
@@ -1123,12 +1231,9 @@ function createPackageSearchToolSpec() {
|
|
|
1123
1231
|
};
|
|
1124
1232
|
}
|
|
1125
1233
|
async function packageSearchHandlerBody(input) {
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
platform,
|
|
1130
|
-
version
|
|
1131
|
-
} = input ?? {};
|
|
1234
|
+
const parsed = parseToolInput(searchInputSchema, input);
|
|
1235
|
+
if (!parsed.ok) return parsed.error;
|
|
1236
|
+
const { package: packageName, type, platform, version } = parsed.data;
|
|
1132
1237
|
const baseUrl = getPackageBaseUrl();
|
|
1133
1238
|
if (!packageName) {
|
|
1134
1239
|
const { entries, warnings } = await fetchCatalog({
|
|
@@ -1161,7 +1266,7 @@ async function packageSearchHandlerBody(input) {
|
|
|
1161
1266
|
next: ["Use package_get for schemas and examples"]
|
|
1162
1267
|
});
|
|
1163
1268
|
} catch (error) {
|
|
1164
|
-
return
|
|
1269
|
+
return mcpError8(
|
|
1165
1270
|
error,
|
|
1166
1271
|
"Package not found. Use package_search without parameters to browse available packages."
|
|
1167
1272
|
);
|
|
@@ -1178,19 +1283,17 @@ function registerPackageSearchTool(server) {
|
|
|
1178
1283
|
// No outputSchema: browse mode returns {catalog, count}, lookup returns metadata — incompatible shapes
|
|
1179
1284
|
annotations: spec.annotations
|
|
1180
1285
|
},
|
|
1181
|
-
|
|
1182
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1183
|
-
spec.handler
|
|
1286
|
+
(args) => packageSearchHandlerBody(args)
|
|
1184
1287
|
);
|
|
1185
1288
|
}
|
|
1186
1289
|
var GET_TITLE = "Get Package";
|
|
1187
1290
|
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".';
|
|
1188
1291
|
var getInputSchema = {
|
|
1189
|
-
package:
|
|
1292
|
+
package: z6.string().min(1).describe(
|
|
1190
1293
|
"Exact npm package name (e.g., @walkeros/web-destination-snowplow)"
|
|
1191
1294
|
),
|
|
1192
|
-
version:
|
|
1193
|
-
section:
|
|
1295
|
+
version: z6.string().optional().describe("Package version (default: latest)"),
|
|
1296
|
+
section: z6.enum(["hints", "examples", "all"]).optional().describe(
|
|
1194
1297
|
"Section to expand with full content. Default: summary view with schemas + hint texts + example descriptions"
|
|
1195
1298
|
)
|
|
1196
1299
|
};
|
|
@@ -1210,12 +1313,35 @@ function createPackageGetToolSpec() {
|
|
|
1210
1313
|
handler: (input) => packageGetHandlerBody(input)
|
|
1211
1314
|
};
|
|
1212
1315
|
}
|
|
1316
|
+
var STEP_PACKAGE_TYPES = [
|
|
1317
|
+
"source",
|
|
1318
|
+
"destination",
|
|
1319
|
+
"transformer",
|
|
1320
|
+
"store"
|
|
1321
|
+
];
|
|
1322
|
+
function isStepPackageType(type) {
|
|
1323
|
+
return STEP_PACKAGE_TYPES.some((stepType) => stepType === type);
|
|
1324
|
+
}
|
|
1325
|
+
function shapeSchemas(type, schemas8) {
|
|
1326
|
+
const shaped = {};
|
|
1327
|
+
if (isStepPackageType(type)) {
|
|
1328
|
+
const settings = recordField(schemas8, "settings");
|
|
1329
|
+
const credentials = recordField(schemas8, "credentials");
|
|
1330
|
+
shaped.config = mergeConfigSchema(type, {
|
|
1331
|
+
...schemas8,
|
|
1332
|
+
settings,
|
|
1333
|
+
credentials
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
for (const [key, value] of Object.entries(schemas8)) {
|
|
1337
|
+
if (key !== "settings") shaped[key] = value;
|
|
1338
|
+
}
|
|
1339
|
+
return shaped;
|
|
1340
|
+
}
|
|
1213
1341
|
async function packageGetHandlerBody(input) {
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
section
|
|
1218
|
-
} = input ?? {};
|
|
1342
|
+
const parsed = parseToolInput(getInputSchema, input);
|
|
1343
|
+
if (!parsed.ok) return parsed.error;
|
|
1344
|
+
const { package: packageName, version, section } = parsed.data;
|
|
1219
1345
|
const baseUrl = getPackageBaseUrl();
|
|
1220
1346
|
try {
|
|
1221
1347
|
const info = await fetchPackage2(packageName, {
|
|
@@ -1223,33 +1349,29 @@ async function packageGetHandlerBody(input) {
|
|
|
1223
1349
|
baseUrl,
|
|
1224
1350
|
client: CLIENT_HEADER
|
|
1225
1351
|
});
|
|
1226
|
-
const mergedSchemas = {};
|
|
1227
|
-
if (info.type) {
|
|
1228
|
-
mergedSchemas.config = mergeConfigSchema(
|
|
1229
|
-
info.type,
|
|
1230
|
-
info.schemas
|
|
1231
|
-
);
|
|
1232
|
-
}
|
|
1233
|
-
for (const [key, value] of Object.entries(info.schemas)) {
|
|
1234
|
-
if (key !== "settings") {
|
|
1235
|
-
mergedSchemas[key] = value;
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
1352
|
const result = {
|
|
1239
1353
|
package: info.packageName,
|
|
1240
1354
|
version: info.version,
|
|
1241
1355
|
type: info.type,
|
|
1242
1356
|
platform: normalizePlatform(info.platform),
|
|
1243
|
-
schemas:
|
|
1357
|
+
schemas: shapeSchemas(info.type, info.schemas)
|
|
1244
1358
|
};
|
|
1359
|
+
if (info.exportSchemas) {
|
|
1360
|
+
result.exportSchemas = Object.fromEntries(
|
|
1361
|
+
Object.entries(info.exportSchemas).map(([name, schemas8]) => [
|
|
1362
|
+
name,
|
|
1363
|
+
shapeSchemas(info.type, schemas8)
|
|
1364
|
+
])
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1245
1367
|
if (info.hints) {
|
|
1246
1368
|
if (section === "hints" || section === "all") {
|
|
1247
1369
|
result.hints = info.hints;
|
|
1248
1370
|
} else {
|
|
1249
1371
|
const hintSummary = {};
|
|
1250
1372
|
for (const [key, hint] of Object.entries(info.hints)) {
|
|
1251
|
-
const
|
|
1252
|
-
hintSummary[key] = { text
|
|
1373
|
+
const text = stringField(hint, "text");
|
|
1374
|
+
if (text !== void 0) hintSummary[key] = { text };
|
|
1253
1375
|
}
|
|
1254
1376
|
result.hints = hintSummary;
|
|
1255
1377
|
}
|
|
@@ -1262,7 +1384,7 @@ async function packageGetHandlerBody(input) {
|
|
|
1262
1384
|
}
|
|
1263
1385
|
return mcpResult6(result);
|
|
1264
1386
|
} catch (error) {
|
|
1265
|
-
return
|
|
1387
|
+
return mcpError8(
|
|
1266
1388
|
error,
|
|
1267
1389
|
"Use package_search to browse available package names."
|
|
1268
1390
|
);
|
|
@@ -1279,15 +1401,13 @@ function registerGetPackageSchemaTool(server) {
|
|
|
1279
1401
|
// No outputSchema: removed to avoid SDK -32602 crashes on unexpected field values
|
|
1280
1402
|
annotations: spec.annotations
|
|
1281
1403
|
},
|
|
1282
|
-
|
|
1283
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1284
|
-
spec.handler
|
|
1404
|
+
(args) => packageGetHandlerBody(args)
|
|
1285
1405
|
);
|
|
1286
1406
|
}
|
|
1287
1407
|
|
|
1288
1408
|
// src/tools/flow-load.ts
|
|
1289
|
-
import { z as
|
|
1290
|
-
import { mcpResult as mcpResult7, mcpError as
|
|
1409
|
+
import { z as z7 } from "zod";
|
|
1410
|
+
import { mcpResult as mcpResult7, mcpError as mcpError9 } from "@walkeros/core";
|
|
1291
1411
|
|
|
1292
1412
|
// src/types.ts
|
|
1293
1413
|
function isAuthError(error) {
|
|
@@ -1394,16 +1514,16 @@ var SERVER_SKELETON = {
|
|
|
1394
1514
|
var TITLE6 = "Load or Create Flow";
|
|
1395
1515
|
var DESCRIPTION5 = "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.";
|
|
1396
1516
|
var inputSchema6 = {
|
|
1397
|
-
source:
|
|
1517
|
+
source: z7.string().optional().describe(
|
|
1398
1518
|
"Flow source: local file path (./flow.json), URL (https://...), inline JSON string, or API flow ID (cfg_...). Omit to create a new flow."
|
|
1399
1519
|
),
|
|
1400
|
-
platform:
|
|
1520
|
+
platform: z7.enum(["web", "server"]).optional().describe(
|
|
1401
1521
|
"Platform for new flows. Required when source is omitted. web = browser tracking, server = Node.js HTTP."
|
|
1402
1522
|
)
|
|
1403
1523
|
};
|
|
1404
1524
|
var outputSchema = {
|
|
1405
|
-
version:
|
|
1406
|
-
flows:
|
|
1525
|
+
version: z7.number().describe("Flow config version"),
|
|
1526
|
+
flows: z7.record(z7.string(), z7.unknown()).describe("Flow entries")
|
|
1407
1527
|
};
|
|
1408
1528
|
var annotations6 = {
|
|
1409
1529
|
readOnlyHint: true,
|
|
@@ -1422,11 +1542,13 @@ function createFlowLoadToolSpec(client, runtime) {
|
|
|
1422
1542
|
};
|
|
1423
1543
|
}
|
|
1424
1544
|
async function flowLoadHandlerBody(client, runtime, input) {
|
|
1425
|
-
const
|
|
1545
|
+
const parsed = parseToolInput(inputSchema6, input);
|
|
1546
|
+
if (!parsed.ok) return parsed.error;
|
|
1547
|
+
const { source, platform } = parsed.data;
|
|
1426
1548
|
if (source && isCloudId(source)) {
|
|
1427
1549
|
const resolvedProjectId = resolveDefaultProject(client, void 0);
|
|
1428
1550
|
if (!resolvedProjectId) {
|
|
1429
|
-
return
|
|
1551
|
+
return mcpError9(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
1430
1552
|
}
|
|
1431
1553
|
try {
|
|
1432
1554
|
const flow = await client.getFlow({
|
|
@@ -1440,7 +1562,7 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
1440
1562
|
}
|
|
1441
1563
|
);
|
|
1442
1564
|
} catch (error) {
|
|
1443
|
-
return
|
|
1565
|
+
return mcpError9(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
1444
1566
|
}
|
|
1445
1567
|
}
|
|
1446
1568
|
try {
|
|
@@ -1451,7 +1573,7 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
1451
1573
|
});
|
|
1452
1574
|
}
|
|
1453
1575
|
if (!platform) {
|
|
1454
|
-
return
|
|
1576
|
+
return mcpError9(
|
|
1455
1577
|
new Error(
|
|
1456
1578
|
"Provide source (file path, URL, or flow ID) to load existing flow, or platform (web/server) to create a new one."
|
|
1457
1579
|
)
|
|
@@ -1465,11 +1587,11 @@ async function flowLoadHandlerBody(client, runtime, input) {
|
|
|
1465
1587
|
]
|
|
1466
1588
|
});
|
|
1467
1589
|
} catch (error) {
|
|
1468
|
-
if (error instanceof RuntimeRefusal) return
|
|
1590
|
+
if (error instanceof RuntimeRefusal) return mcpError9(error, error.hint);
|
|
1469
1591
|
const msg = error instanceof Error ? error.message : "";
|
|
1470
1592
|
if (msg.includes("not found") || msg.includes("ENOENT"))
|
|
1471
|
-
return
|
|
1472
|
-
return
|
|
1593
|
+
return mcpError9(error, "Check configPath \u2014 expected a flow.json file");
|
|
1594
|
+
return mcpError9(error);
|
|
1473
1595
|
}
|
|
1474
1596
|
}
|
|
1475
1597
|
function registerFlowLoadTool(server, client, runtime) {
|
|
@@ -1484,20 +1606,18 @@ function registerFlowLoadTool(server, client, runtime) {
|
|
|
1484
1606
|
outputSchema,
|
|
1485
1607
|
annotations: spec.annotations
|
|
1486
1608
|
},
|
|
1487
|
-
|
|
1488
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1489
|
-
spec.handler
|
|
1609
|
+
(args) => flowLoadHandlerBody(client, runtime, args)
|
|
1490
1610
|
);
|
|
1491
1611
|
}
|
|
1492
1612
|
|
|
1493
1613
|
// src/tools/feedback.ts
|
|
1494
|
-
import { z as
|
|
1495
|
-
import { mcpResult as mcpResult8, mcpError as
|
|
1614
|
+
import { z as z8 } from "zod";
|
|
1615
|
+
import { mcpResult as mcpResult8, mcpError as mcpError10 } from "@walkeros/core";
|
|
1496
1616
|
var TITLE7 = "Send Feedback";
|
|
1497
1617
|
var DESCRIPTION6 = "Send feedback about walkerOS";
|
|
1498
1618
|
var inputSchema7 = {
|
|
1499
|
-
text:
|
|
1500
|
-
anonymous:
|
|
1619
|
+
text: z8.string().describe("Your feedback text"),
|
|
1620
|
+
anonymous: z8.boolean().optional().describe(
|
|
1501
1621
|
"Include user/project info? false = include, true = anonymous. Only needed on first call if not yet configured."
|
|
1502
1622
|
)
|
|
1503
1623
|
};
|
|
@@ -1518,7 +1638,9 @@ function createFeedbackToolSpec(client) {
|
|
|
1518
1638
|
};
|
|
1519
1639
|
}
|
|
1520
1640
|
async function feedbackHandlerBody(client, input) {
|
|
1521
|
-
const
|
|
1641
|
+
const parsed = parseToolInput(inputSchema7, input);
|
|
1642
|
+
if (!parsed.ok) return parsed.error;
|
|
1643
|
+
const { text, anonymous: explicitAnonymous } = parsed.data;
|
|
1522
1644
|
try {
|
|
1523
1645
|
let anonymous = client.getFeedbackPreference();
|
|
1524
1646
|
if (anonymous === void 0 && explicitAnonymous === void 0) {
|
|
@@ -1539,11 +1661,11 @@ async function feedbackHandlerBody(client, input) {
|
|
|
1539
1661
|
const isAnonymous = explicitAnonymous ?? anonymous ?? true;
|
|
1540
1662
|
await client.submitFeedback(text, {
|
|
1541
1663
|
anonymous: isAnonymous,
|
|
1542
|
-
version: "4.7.0
|
|
1664
|
+
version: "4.7.0"
|
|
1543
1665
|
});
|
|
1544
1666
|
return mcpResult8({ ok: true });
|
|
1545
1667
|
} catch (error) {
|
|
1546
|
-
return
|
|
1668
|
+
return mcpError10(error);
|
|
1547
1669
|
}
|
|
1548
1670
|
}
|
|
1549
1671
|
function registerFeedbackTool(server, client) {
|
|
@@ -1556,9 +1678,7 @@ function registerFeedbackTool(server, client) {
|
|
|
1556
1678
|
inputSchema: spec.inputSchema,
|
|
1557
1679
|
annotations: spec.annotations
|
|
1558
1680
|
},
|
|
1559
|
-
|
|
1560
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
1561
|
-
spec.handler
|
|
1681
|
+
(args) => feedbackHandlerBody(client, args)
|
|
1562
1682
|
);
|
|
1563
1683
|
}
|
|
1564
1684
|
|
|
@@ -21271,20 +21391,18 @@ function registerDiagnosticsTool(server, client, packageVersion) {
|
|
|
21271
21391
|
inputSchema: spec.inputSchema,
|
|
21272
21392
|
annotations: spec.annotations
|
|
21273
21393
|
},
|
|
21274
|
-
|
|
21275
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
21276
|
-
spec.handler
|
|
21394
|
+
() => diagnosticsHandlerBody(client, packageVersion)
|
|
21277
21395
|
);
|
|
21278
21396
|
}
|
|
21279
21397
|
|
|
21280
21398
|
// src/tools/auth.ts
|
|
21281
|
-
import { z as
|
|
21282
|
-
import { mcpResult as mcpResult10, mcpError as
|
|
21399
|
+
import { z as z9 } from "zod";
|
|
21400
|
+
import { mcpResult as mcpResult10, mcpError as mcpError11 } from "@walkeros/core";
|
|
21283
21401
|
var TITLE9 = "Authentication";
|
|
21284
21402
|
var DESCRIPTION8 = "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.";
|
|
21285
21403
|
var inputSchema9 = {
|
|
21286
|
-
action:
|
|
21287
|
-
deviceCode:
|
|
21404
|
+
action: z9.enum(["status", "login", "logout"]).describe("Authentication action to perform"),
|
|
21405
|
+
deviceCode: z9.string().optional().describe(
|
|
21288
21406
|
"Device code from a previous pending login attempt. Provide to resume polling without requesting a new code."
|
|
21289
21407
|
)
|
|
21290
21408
|
};
|
|
@@ -21305,7 +21423,9 @@ function createAuthToolSpec(client) {
|
|
|
21305
21423
|
};
|
|
21306
21424
|
}
|
|
21307
21425
|
async function authHandlerBody(client, input) {
|
|
21308
|
-
const
|
|
21426
|
+
const parsed = parseToolInput(inputSchema9, input);
|
|
21427
|
+
if (!parsed.ok) return parsed.error;
|
|
21428
|
+
const { action, deviceCode } = parsed.data;
|
|
21309
21429
|
try {
|
|
21310
21430
|
switch (action) {
|
|
21311
21431
|
case "status": {
|
|
@@ -21318,7 +21438,7 @@ async function authHandlerBody(client, input) {
|
|
|
21318
21438
|
const user = await client.whoami();
|
|
21319
21439
|
return mcpResult10({
|
|
21320
21440
|
authenticated: true,
|
|
21321
|
-
...user
|
|
21441
|
+
...fieldsOf(user)
|
|
21322
21442
|
});
|
|
21323
21443
|
}
|
|
21324
21444
|
case "login": {
|
|
@@ -21346,14 +21466,14 @@ async function authHandlerBody(client, input) {
|
|
|
21346
21466
|
});
|
|
21347
21467
|
}
|
|
21348
21468
|
if (poll.status === "denied")
|
|
21349
|
-
return
|
|
21469
|
+
return mcpError11(new Error("Authorization was denied."));
|
|
21350
21470
|
if (poll.status === "expired")
|
|
21351
|
-
return
|
|
21471
|
+
return mcpError11(
|
|
21352
21472
|
new Error(
|
|
21353
21473
|
'The one-time code expired. Run auth with action "login" for a new one.'
|
|
21354
21474
|
)
|
|
21355
21475
|
);
|
|
21356
|
-
return
|
|
21476
|
+
return mcpError11(new Error(poll.error));
|
|
21357
21477
|
}
|
|
21358
21478
|
const code = await client.requestDeviceCode();
|
|
21359
21479
|
const loginUrl = code.verificationUriComplete;
|
|
@@ -21390,7 +21510,7 @@ async function authHandlerBody(client, input) {
|
|
|
21390
21510
|
);
|
|
21391
21511
|
}
|
|
21392
21512
|
} catch (error) {
|
|
21393
|
-
return
|
|
21513
|
+
return mcpError11(error);
|
|
21394
21514
|
}
|
|
21395
21515
|
}
|
|
21396
21516
|
function registerAuthTool(server, client) {
|
|
@@ -21403,15 +21523,13 @@ function registerAuthTool(server, client) {
|
|
|
21403
21523
|
inputSchema: spec.inputSchema,
|
|
21404
21524
|
annotations: spec.annotations
|
|
21405
21525
|
},
|
|
21406
|
-
|
|
21407
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
21408
|
-
spec.handler
|
|
21526
|
+
(args) => authHandlerBody(client, args)
|
|
21409
21527
|
);
|
|
21410
21528
|
}
|
|
21411
21529
|
|
|
21412
21530
|
// src/tools/project-manage.ts
|
|
21413
|
-
import { z as
|
|
21414
|
-
import { mcpResult as mcpResult11, mcpError as
|
|
21531
|
+
import { z as z10 } from "zod";
|
|
21532
|
+
import { mcpResult as mcpResult11, mcpError as mcpError12 } from "@walkeros/core";
|
|
21415
21533
|
|
|
21416
21534
|
// src/action-requirements.ts
|
|
21417
21535
|
function validateActionInput(toolName, action, input, map) {
|
|
@@ -21532,21 +21650,22 @@ var FRAME_MANAGE_REQUIREMENTS = {
|
|
|
21532
21650
|
};
|
|
21533
21651
|
|
|
21534
21652
|
// src/tools/project-manage.ts
|
|
21535
|
-
function wrapProjectName(
|
|
21536
|
-
|
|
21653
|
+
function wrapProjectName(project) {
|
|
21654
|
+
const name = stringField(project, "name");
|
|
21655
|
+
return isRecord(project) && name !== void 0 ? { ...project, name: wrapUserData(name) } : project;
|
|
21537
21656
|
}
|
|
21538
21657
|
var TITLE10 = "Project Management";
|
|
21539
21658
|
var DESCRIPTION9 = "Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.";
|
|
21540
21659
|
var inputSchema10 = {
|
|
21541
|
-
action:
|
|
21542
|
-
projectId:
|
|
21543
|
-
name:
|
|
21660
|
+
action: z10.enum(["list", "get", "create", "update", "delete", "set_default"]).describe("Project management action to perform"),
|
|
21661
|
+
projectId: z10.string().optional().describe("Required for get, update, delete, set_default."),
|
|
21662
|
+
name: z10.string().optional().describe(
|
|
21544
21663
|
"Required for create and update (update also requires projectId)."
|
|
21545
21664
|
),
|
|
21546
|
-
cursor:
|
|
21665
|
+
cursor: z10.string().optional().describe(
|
|
21547
21666
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
21548
21667
|
),
|
|
21549
|
-
limit:
|
|
21668
|
+
limit: z10.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action.")
|
|
21550
21669
|
};
|
|
21551
21670
|
var annotations10 = {
|
|
21552
21671
|
readOnlyHint: false,
|
|
@@ -21565,19 +21684,22 @@ function createProjectManageToolSpec(client) {
|
|
|
21565
21684
|
};
|
|
21566
21685
|
}
|
|
21567
21686
|
async function projectManageHandlerBody(client, input) {
|
|
21568
|
-
const
|
|
21687
|
+
const parsed = parseToolInput(inputSchema10, input);
|
|
21688
|
+
if (!parsed.ok) return parsed.error;
|
|
21689
|
+
const { action, projectId, name, cursor, limit } = parsed.data;
|
|
21569
21690
|
const validationError = validateActionInput(
|
|
21570
21691
|
"project_manage",
|
|
21571
21692
|
action ?? "",
|
|
21572
21693
|
{ projectId, name },
|
|
21573
21694
|
PROJECT_MANAGE_REQUIREMENTS
|
|
21574
21695
|
);
|
|
21575
|
-
if (validationError) return
|
|
21696
|
+
if (validationError) return mcpError12(new Error(validationError));
|
|
21576
21697
|
try {
|
|
21577
21698
|
switch (action) {
|
|
21578
21699
|
case "list": {
|
|
21579
21700
|
const projects = await client.listProjects({ cursor, limit });
|
|
21580
|
-
const
|
|
21701
|
+
const listed = isRecord(projects) ? projects.projects : void 0;
|
|
21702
|
+
const items = Array.isArray(projects) ? projects : Array.isArray(listed) ? listed : [];
|
|
21581
21703
|
if (items.length === 0) {
|
|
21582
21704
|
return mcpResult11(
|
|
21583
21705
|
{ projects: [] },
|
|
@@ -21589,8 +21711,7 @@ async function projectManageHandlerBody(client, input) {
|
|
|
21589
21711
|
}
|
|
21590
21712
|
);
|
|
21591
21713
|
}
|
|
21592
|
-
const
|
|
21593
|
-
const safe = Array.isArray(projects) ? typedItems.map(wrapProjectName) : { ...projects, projects: typedItems.map(wrapProjectName) };
|
|
21714
|
+
const safe = Array.isArray(projects) ? items.map(wrapProjectName) : { ...fieldsOf(projects), projects: items.map(wrapProjectName) };
|
|
21594
21715
|
return mcpResult11(safe);
|
|
21595
21716
|
}
|
|
21596
21717
|
case "get": {
|
|
@@ -21633,7 +21754,7 @@ async function projectManageHandlerBody(client, input) {
|
|
|
21633
21754
|
);
|
|
21634
21755
|
}
|
|
21635
21756
|
} catch (error) {
|
|
21636
|
-
return
|
|
21757
|
+
return mcpError12(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
21637
21758
|
}
|
|
21638
21759
|
}
|
|
21639
21760
|
function registerProjectManageTool(server, client) {
|
|
@@ -21646,15 +21767,13 @@ function registerProjectManageTool(server, client) {
|
|
|
21646
21767
|
inputSchema: spec.inputSchema,
|
|
21647
21768
|
annotations: spec.annotations
|
|
21648
21769
|
},
|
|
21649
|
-
|
|
21650
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
21651
|
-
spec.handler
|
|
21770
|
+
(args) => projectManageHandlerBody(client, args)
|
|
21652
21771
|
);
|
|
21653
21772
|
}
|
|
21654
21773
|
|
|
21655
21774
|
// src/tools/flow-manage.ts
|
|
21656
|
-
import { z as
|
|
21657
|
-
import { mcpResult as mcpResult12, mcpError as
|
|
21775
|
+
import { z as z11 } from "zod";
|
|
21776
|
+
import { mcpResult as mcpResult12, mcpError as mcpError13 } from "@walkeros/core";
|
|
21658
21777
|
|
|
21659
21778
|
// src/ui-parts.ts
|
|
21660
21779
|
function flowCanvasResult(payload) {
|
|
@@ -21759,19 +21878,10 @@ var links = {
|
|
|
21759
21878
|
|
|
21760
21879
|
// src/tools/flow-manage.ts
|
|
21761
21880
|
function pickPlatform(content) {
|
|
21762
|
-
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
if (flow && typeof flow === "object") {
|
|
21767
|
-
const config = flow.config;
|
|
21768
|
-
if (config && typeof config === "object") {
|
|
21769
|
-
const platform = config.platform;
|
|
21770
|
-
if (platform === "web" || platform === "server") return platform;
|
|
21771
|
-
}
|
|
21772
|
-
}
|
|
21773
|
-
}
|
|
21774
|
-
}
|
|
21881
|
+
const flows = recordField(content, "flows");
|
|
21882
|
+
for (const flow of Object.values(flows ?? {})) {
|
|
21883
|
+
const platform = stringField(recordField(flow, "config"), "platform");
|
|
21884
|
+
if (platform === "web" || platform === "server") return platform;
|
|
21775
21885
|
}
|
|
21776
21886
|
return "server";
|
|
21777
21887
|
}
|
|
@@ -21780,22 +21890,29 @@ function flowPageUrl(client, projectId, flowId) {
|
|
|
21780
21890
|
return links.flow({ baseUrl: client.appBaseUrl(), projectId, flowId });
|
|
21781
21891
|
}
|
|
21782
21892
|
function safeSummary(flow) {
|
|
21783
|
-
|
|
21893
|
+
const name = stringField(flow, "name");
|
|
21894
|
+
return isRecord(flow) && name !== void 0 ? { ...flow, name: wrapUserData(name) } : flow;
|
|
21784
21895
|
}
|
|
21785
21896
|
function safeDetail(flow) {
|
|
21786
|
-
const
|
|
21787
|
-
|
|
21788
|
-
|
|
21789
|
-
|
|
21790
|
-
|
|
21791
|
-
|
|
21897
|
+
const fields = { ...fieldsOf(flow) };
|
|
21898
|
+
const name = stringField(fields, "name");
|
|
21899
|
+
if (name !== void 0) fields.name = wrapUserData(name);
|
|
21900
|
+
if (fields.config !== void 0) {
|
|
21901
|
+
fields.config = redactNestedStrings(fields.config, {
|
|
21902
|
+
skip: keepStructural
|
|
21903
|
+
});
|
|
21792
21904
|
}
|
|
21793
|
-
return
|
|
21905
|
+
return {
|
|
21906
|
+
fields,
|
|
21907
|
+
id: stringField(fields, "id"),
|
|
21908
|
+
name: stringField(fields, "name"),
|
|
21909
|
+
config: recordField(fields, "config")
|
|
21910
|
+
};
|
|
21794
21911
|
}
|
|
21795
21912
|
var TITLE11 = "Flow Management";
|
|
21796
21913
|
var DESCRIPTION10 = "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.";
|
|
21797
21914
|
var inputSchema11 = {
|
|
21798
|
-
action:
|
|
21915
|
+
action: z11.enum([
|
|
21799
21916
|
"list",
|
|
21800
21917
|
"get",
|
|
21801
21918
|
"create",
|
|
@@ -21808,52 +21925,52 @@ var inputSchema11 = {
|
|
|
21808
21925
|
"preview_delete",
|
|
21809
21926
|
"preview_regrant"
|
|
21810
21927
|
]).describe("Flow management action to perform"),
|
|
21811
|
-
flowId:
|
|
21928
|
+
flowId: z11.string().optional().describe(
|
|
21812
21929
|
"Flow ID (flow_...) or config ID (cfg_...). Required for get, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant."
|
|
21813
21930
|
),
|
|
21814
|
-
projectId:
|
|
21931
|
+
projectId: z11.string().optional().describe(
|
|
21815
21932
|
"Project ID. Optional filter for list (omit to list all projects). Required for create if no default project set."
|
|
21816
21933
|
),
|
|
21817
|
-
name:
|
|
21934
|
+
name: z11.string().optional().describe(
|
|
21818
21935
|
"Flow name. Required for create. Optional for update (to rename) and duplicate."
|
|
21819
21936
|
),
|
|
21820
|
-
content:
|
|
21821
|
-
patch:
|
|
21937
|
+
content: z11.record(z11.string(), z11.unknown()).optional().describe("Flow.Json content. Used for create and update."),
|
|
21938
|
+
patch: z11.boolean().optional().describe(
|
|
21822
21939
|
"Merge-patch for update (default true). When true, only provided fields are updated."
|
|
21823
21940
|
),
|
|
21824
|
-
fields:
|
|
21825
|
-
sort:
|
|
21826
|
-
order:
|
|
21827
|
-
includeDeleted:
|
|
21828
|
-
cursor:
|
|
21941
|
+
fields: z11.array(z11.string()).optional().describe("Dot-path selectors for get to return only specific fields."),
|
|
21942
|
+
sort: z11.enum(["name", "updated_at", "created_at"]).optional().describe("Sort field for list."),
|
|
21943
|
+
order: z11.enum(["asc", "desc"]).optional().describe("Sort order for list."),
|
|
21944
|
+
includeDeleted: z11.boolean().optional().describe("Include soft-deleted flows in list results."),
|
|
21945
|
+
cursor: z11.string().optional().describe(
|
|
21829
21946
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
21830
21947
|
),
|
|
21831
|
-
limit:
|
|
21832
|
-
previewId:
|
|
21948
|
+
limit: z11.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action."),
|
|
21949
|
+
previewId: z11.string().optional().describe(
|
|
21833
21950
|
"Preview ID (prv_...). Required for preview_get, preview_delete, and preview_regrant (all also require flowId)."
|
|
21834
21951
|
),
|
|
21835
|
-
flowName:
|
|
21952
|
+
flowName: z11.string().optional().describe(
|
|
21836
21953
|
"Used by preview_create \u2014 provide one of flowName or flowSettingsId (preview_create also requires flowId)."
|
|
21837
21954
|
),
|
|
21838
|
-
flowSettingsId:
|
|
21955
|
+
flowSettingsId: z11.string().optional().describe(
|
|
21839
21956
|
"Used by preview_create \u2014 provide one of flowName or flowSettingsId (preview_create also requires flowId)."
|
|
21840
21957
|
),
|
|
21841
|
-
source:
|
|
21842
|
-
|
|
21843
|
-
|
|
21844
|
-
kind:
|
|
21845
|
-
deploymentVersionId:
|
|
21958
|
+
source: z11.discriminatedUnion("kind", [
|
|
21959
|
+
z11.object({ kind: z11.literal("draft") }),
|
|
21960
|
+
z11.object({
|
|
21961
|
+
kind: z11.literal("deployment-version"),
|
|
21962
|
+
deploymentVersionId: z11.string()
|
|
21846
21963
|
})
|
|
21847
21964
|
]).optional().describe(
|
|
21848
21965
|
"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)."
|
|
21849
21966
|
),
|
|
21850
|
-
siteUrl:
|
|
21967
|
+
siteUrl: z11.string().optional().describe(
|
|
21851
21968
|
"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."
|
|
21852
21969
|
),
|
|
21853
|
-
origins:
|
|
21970
|
+
origins: z11.array(z11.string()).optional().describe(
|
|
21854
21971
|
"Site origins (bare https://host[:port]) to mint a preview activation grant for. Used by preview_regrant; the returned activationUrl targets the first origin."
|
|
21855
21972
|
),
|
|
21856
|
-
sessionId:
|
|
21973
|
+
sessionId: z11.string().optional().describe(
|
|
21857
21974
|
"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."
|
|
21858
21975
|
)
|
|
21859
21976
|
};
|
|
@@ -21879,9 +21996,6 @@ var PREVIEW_SUMMARY_FIELDS = [
|
|
|
21879
21996
|
"createdBy",
|
|
21880
21997
|
"createdAt"
|
|
21881
21998
|
];
|
|
21882
|
-
function isRecord(value) {
|
|
21883
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21884
|
-
}
|
|
21885
21999
|
function redactPreview(data) {
|
|
21886
22000
|
if (!isRecord(data)) return {};
|
|
21887
22001
|
const out = {};
|
|
@@ -21920,6 +22034,8 @@ function createFlowManageToolSpec(client) {
|
|
|
21920
22034
|
};
|
|
21921
22035
|
}
|
|
21922
22036
|
async function flowManageHandlerBody(client, input) {
|
|
22037
|
+
const parsed = parseToolInput(inputSchema11, input);
|
|
22038
|
+
if (!parsed.ok) return parsed.error;
|
|
21923
22039
|
const {
|
|
21924
22040
|
action,
|
|
21925
22041
|
flowId,
|
|
@@ -21940,14 +22056,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
21940
22056
|
siteUrl,
|
|
21941
22057
|
origins,
|
|
21942
22058
|
sessionId
|
|
21943
|
-
} =
|
|
22059
|
+
} = parsed.data;
|
|
21944
22060
|
const validationError = validateActionInput(
|
|
21945
22061
|
"flow_manage",
|
|
21946
22062
|
action ?? "",
|
|
21947
22063
|
{ flowId, projectId, name, previewId, flowName, flowSettingsId },
|
|
21948
22064
|
FLOW_MANAGE_REQUIREMENTS
|
|
21949
22065
|
);
|
|
21950
|
-
if (validationError) return
|
|
22066
|
+
if (validationError) return mcpError13(new Error(validationError));
|
|
21951
22067
|
try {
|
|
21952
22068
|
switch (action) {
|
|
21953
22069
|
case "list": {
|
|
@@ -21960,9 +22076,8 @@ async function flowManageHandlerBody(client, input) {
|
|
|
21960
22076
|
cursor,
|
|
21961
22077
|
limit
|
|
21962
22078
|
});
|
|
21963
|
-
const
|
|
21964
|
-
const
|
|
21965
|
-
const safe2 = Array.isArray(flows) ? { ...dataObj, flows: flows.map(safeSummary) } : data2;
|
|
22079
|
+
const flows = isRecord(data2) ? data2.flows : void 0;
|
|
22080
|
+
const safe2 = isRecord(data2) && Array.isArray(flows) ? { ...data2, flows: flows.map(safeSummary) } : data2;
|
|
21966
22081
|
return mcpResult12(safe2);
|
|
21967
22082
|
}
|
|
21968
22083
|
const data = await client.listAllFlows({
|
|
@@ -21987,16 +22102,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
21987
22102
|
assertParam(flowId, "flowId", "get");
|
|
21988
22103
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
21989
22104
|
if (!resolvedProjectId) {
|
|
21990
|
-
return
|
|
22105
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
21991
22106
|
}
|
|
21992
22107
|
const flow = await client.getFlow({
|
|
21993
22108
|
flowId,
|
|
21994
22109
|
projectId: resolvedProjectId,
|
|
21995
22110
|
fields
|
|
21996
22111
|
});
|
|
21997
|
-
const safe = safeDetail(
|
|
21998
|
-
flow
|
|
21999
|
-
);
|
|
22112
|
+
const safe = safeDetail(flow);
|
|
22000
22113
|
const appUrl = flowPageUrl(client, resolvedProjectId, safe.id);
|
|
22001
22114
|
return flowCanvasResult({
|
|
22002
22115
|
flowId: safe.id,
|
|
@@ -22021,16 +22134,14 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22021
22134
|
assertParam(name, "name", "create");
|
|
22022
22135
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22023
22136
|
if (!resolvedProjectId) {
|
|
22024
|
-
return
|
|
22137
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22025
22138
|
}
|
|
22026
22139
|
const created = await client.createFlow({
|
|
22027
22140
|
name,
|
|
22028
22141
|
content: content ?? {},
|
|
22029
22142
|
projectId: resolvedProjectId
|
|
22030
22143
|
});
|
|
22031
|
-
const safeCreated = safeDetail(
|
|
22032
|
-
created
|
|
22033
|
-
);
|
|
22144
|
+
const safeCreated = safeDetail(created);
|
|
22034
22145
|
const createdAppUrl = flowPageUrl(
|
|
22035
22146
|
client,
|
|
22036
22147
|
resolvedProjectId,
|
|
@@ -22059,7 +22170,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22059
22170
|
assertParam(flowId, "flowId", "update");
|
|
22060
22171
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22061
22172
|
if (!resolvedProjectId) {
|
|
22062
|
-
return
|
|
22173
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22063
22174
|
}
|
|
22064
22175
|
const updated = await client.updateFlow({
|
|
22065
22176
|
flowId,
|
|
@@ -22068,9 +22179,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22068
22179
|
content,
|
|
22069
22180
|
mergePatch: patch ?? true
|
|
22070
22181
|
});
|
|
22071
|
-
const safeUpdated = safeDetail(
|
|
22072
|
-
updated
|
|
22073
|
-
);
|
|
22182
|
+
const safeUpdated = safeDetail(updated);
|
|
22074
22183
|
return flowCanvasResult({
|
|
22075
22184
|
flowId: safeUpdated.id,
|
|
22076
22185
|
configName: safeUpdated.name ?? "default",
|
|
@@ -22093,7 +22202,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22093
22202
|
assertParam(flowId, "flowId", "delete");
|
|
22094
22203
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22095
22204
|
if (!resolvedProjectId) {
|
|
22096
|
-
return
|
|
22205
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22097
22206
|
}
|
|
22098
22207
|
const deleted = await client.deleteFlow({
|
|
22099
22208
|
flowId,
|
|
@@ -22105,22 +22214,20 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22105
22214
|
assertParam(flowId, "flowId", "duplicate");
|
|
22106
22215
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22107
22216
|
if (!resolvedProjectId) {
|
|
22108
|
-
return
|
|
22217
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22109
22218
|
}
|
|
22110
22219
|
const duplicated = await client.duplicateFlow({
|
|
22111
22220
|
flowId,
|
|
22112
22221
|
name,
|
|
22113
22222
|
projectId: resolvedProjectId
|
|
22114
22223
|
});
|
|
22115
|
-
return mcpResult12(
|
|
22116
|
-
safeDetail(duplicated)
|
|
22117
|
-
);
|
|
22224
|
+
return mcpResult12(safeDetail(duplicated).fields);
|
|
22118
22225
|
}
|
|
22119
22226
|
case "preview_list": {
|
|
22120
22227
|
assertParam(flowId, "flowId", "preview_list");
|
|
22121
22228
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22122
22229
|
if (!resolvedProjectId) {
|
|
22123
|
-
return
|
|
22230
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22124
22231
|
}
|
|
22125
22232
|
const data = await client.listPreviews({
|
|
22126
22233
|
projectId: resolvedProjectId,
|
|
@@ -22133,7 +22240,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22133
22240
|
assertParam(previewId, "previewId", "preview_get");
|
|
22134
22241
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22135
22242
|
if (!resolvedProjectId) {
|
|
22136
|
-
return
|
|
22243
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22137
22244
|
}
|
|
22138
22245
|
const data = await client.getPreview({
|
|
22139
22246
|
projectId: resolvedProjectId,
|
|
@@ -22146,7 +22253,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22146
22253
|
assertParam(flowId, "flowId", "preview_create");
|
|
22147
22254
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22148
22255
|
if (!resolvedProjectId) {
|
|
22149
|
-
return
|
|
22256
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22150
22257
|
}
|
|
22151
22258
|
const preview = await client.createPreview({
|
|
22152
22259
|
projectId: resolvedProjectId,
|
|
@@ -22168,7 +22275,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22168
22275
|
assertParam(previewId, "previewId", "preview_delete");
|
|
22169
22276
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22170
22277
|
if (!resolvedProjectId) {
|
|
22171
|
-
return
|
|
22278
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22172
22279
|
}
|
|
22173
22280
|
const data = await client.deletePreview({
|
|
22174
22281
|
projectId: resolvedProjectId,
|
|
@@ -22184,10 +22291,10 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22184
22291
|
assertParam(previewId, "previewId", "preview_regrant");
|
|
22185
22292
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22186
22293
|
if (!resolvedProjectId) {
|
|
22187
|
-
return
|
|
22294
|
+
return mcpError13(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22188
22295
|
}
|
|
22189
22296
|
if (!client.regrantPreview) {
|
|
22190
|
-
return
|
|
22297
|
+
return mcpError13(
|
|
22191
22298
|
new Error("preview_regrant is not supported by this client")
|
|
22192
22299
|
);
|
|
22193
22300
|
}
|
|
@@ -22211,7 +22318,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
22211
22318
|
);
|
|
22212
22319
|
}
|
|
22213
22320
|
} catch (error) {
|
|
22214
|
-
return
|
|
22321
|
+
return mcpError13(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
22215
22322
|
}
|
|
22216
22323
|
}
|
|
22217
22324
|
function registerFlowManageTool(server, client) {
|
|
@@ -22224,15 +22331,13 @@ function registerFlowManageTool(server, client) {
|
|
|
22224
22331
|
inputSchema: spec.inputSchema,
|
|
22225
22332
|
annotations: spec.annotations
|
|
22226
22333
|
},
|
|
22227
|
-
|
|
22228
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
22229
|
-
spec.handler
|
|
22334
|
+
(args) => flowManageHandlerBody(client, args)
|
|
22230
22335
|
);
|
|
22231
22336
|
}
|
|
22232
22337
|
|
|
22233
22338
|
// src/tools/deploy-manage.ts
|
|
22234
|
-
import { z as
|
|
22235
|
-
import { mcpResult as mcpResult13, mcpError as
|
|
22339
|
+
import { z as z12 } from "zod";
|
|
22340
|
+
import { mcpResult as mcpResult13, mcpError as mcpError14 } from "@walkeros/core";
|
|
22236
22341
|
|
|
22237
22342
|
// src/tools/_resolvers.ts
|
|
22238
22343
|
var DeploymentNotFoundError = class extends Error {
|
|
@@ -22288,24 +22393,24 @@ async function resolveDeploymentSlug(args) {
|
|
|
22288
22393
|
var TITLE12 = "Deploy Management";
|
|
22289
22394
|
var DESCRIPTION11 = "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.";
|
|
22290
22395
|
var inputSchema12 = {
|
|
22291
|
-
action:
|
|
22292
|
-
projectId:
|
|
22293
|
-
flowId:
|
|
22294
|
-
slug:
|
|
22396
|
+
action: z12.enum(["deploy", "list", "get", "delete"]).describe("Deployment action to perform"),
|
|
22397
|
+
projectId: z12.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
22398
|
+
flowId: z12.string().optional().describe("Required for deploy, get, delete."),
|
|
22399
|
+
slug: z12.string().optional().describe(
|
|
22295
22400
|
"Deployment slug. Optional disambiguator for get/delete when the flow has multiple active deployments."
|
|
22296
22401
|
),
|
|
22297
|
-
type:
|
|
22298
|
-
status:
|
|
22299
|
-
wait:
|
|
22402
|
+
type: z12.enum(["web", "server"]).optional().describe("Deployment type filter for list."),
|
|
22403
|
+
status: z12.string().optional().describe("Status filter for list."),
|
|
22404
|
+
wait: z12.boolean().optional().describe(
|
|
22300
22405
|
"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."
|
|
22301
22406
|
),
|
|
22302
|
-
flowName:
|
|
22407
|
+
flowName: z12.string().optional().describe(
|
|
22303
22408
|
"Flow name for multi-settings flows. Only used with deploy action."
|
|
22304
22409
|
),
|
|
22305
|
-
cursor:
|
|
22410
|
+
cursor: z12.string().optional().describe(
|
|
22306
22411
|
"Pagination cursor from a previous list response. Only used with the list action."
|
|
22307
22412
|
),
|
|
22308
|
-
limit:
|
|
22413
|
+
limit: z12.number().int().min(1).max(100).optional().describe("Max items per page (1-100). Only used with the list action.")
|
|
22309
22414
|
};
|
|
22310
22415
|
var annotations12 = {
|
|
22311
22416
|
readOnlyHint: false,
|
|
@@ -22340,13 +22445,22 @@ function withAppUrl(data, appUrl) {
|
|
|
22340
22445
|
}
|
|
22341
22446
|
return { ...data, appUrl };
|
|
22342
22447
|
}
|
|
22448
|
+
function readDeploymentSummary(value) {
|
|
22449
|
+
if (!isRecord(value)) return [];
|
|
22450
|
+
const slug = stringField(value, "slug");
|
|
22451
|
+
const type = stringField(value, "type");
|
|
22452
|
+
const status = stringField(value, "status");
|
|
22453
|
+
const updatedAt = stringField(value, "updatedAt");
|
|
22454
|
+
return slug !== void 0 && type !== void 0 && status !== void 0 && updatedAt !== void 0 ? [{ ...value, slug, type, status, updatedAt }] : [];
|
|
22455
|
+
}
|
|
22343
22456
|
function listForResolver(client, projectId) {
|
|
22344
22457
|
return async (q) => {
|
|
22345
22458
|
const resp = await client.listDeployments({
|
|
22346
22459
|
projectId: projectId || q.projectId || void 0,
|
|
22347
22460
|
flowId: q.flowId
|
|
22348
22461
|
});
|
|
22349
|
-
|
|
22462
|
+
const deployments = isRecord(resp) ? resp.deployments : void 0;
|
|
22463
|
+
return Array.isArray(deployments) ? deployments.flatMap(readDeploymentSummary) : [];
|
|
22350
22464
|
};
|
|
22351
22465
|
}
|
|
22352
22466
|
function createDeployManageToolSpec(client) {
|
|
@@ -22360,6 +22474,8 @@ function createDeployManageToolSpec(client) {
|
|
|
22360
22474
|
};
|
|
22361
22475
|
}
|
|
22362
22476
|
async function deployManageHandlerBody(client, input) {
|
|
22477
|
+
const parsed = parseToolInput(inputSchema12, input);
|
|
22478
|
+
if (!parsed.ok) return parsed.error;
|
|
22363
22479
|
const {
|
|
22364
22480
|
action,
|
|
22365
22481
|
projectId,
|
|
@@ -22371,14 +22487,14 @@ async function deployManageHandlerBody(client, input) {
|
|
|
22371
22487
|
flowName,
|
|
22372
22488
|
cursor,
|
|
22373
22489
|
limit
|
|
22374
|
-
} =
|
|
22490
|
+
} = parsed.data;
|
|
22375
22491
|
const validationError = validateActionInput(
|
|
22376
22492
|
"deploy_manage",
|
|
22377
22493
|
action ?? "",
|
|
22378
22494
|
{ flowId, projectId },
|
|
22379
22495
|
DEPLOY_MANAGE_REQUIREMENTS
|
|
22380
22496
|
);
|
|
22381
|
-
if (validationError) return
|
|
22497
|
+
if (validationError) return mcpError14(new Error(validationError));
|
|
22382
22498
|
try {
|
|
22383
22499
|
switch (action) {
|
|
22384
22500
|
case "deploy": {
|
|
@@ -22437,7 +22553,7 @@ async function deployManageHandlerBody(client, input) {
|
|
|
22437
22553
|
return mcpResult13(
|
|
22438
22554
|
redactDisplayNames({
|
|
22439
22555
|
deleted: true,
|
|
22440
|
-
...data
|
|
22556
|
+
...fieldsOf(data)
|
|
22441
22557
|
})
|
|
22442
22558
|
);
|
|
22443
22559
|
}
|
|
@@ -22447,7 +22563,7 @@ async function deployManageHandlerBody(client, input) {
|
|
|
22447
22563
|
);
|
|
22448
22564
|
}
|
|
22449
22565
|
} catch (error) {
|
|
22450
|
-
return
|
|
22566
|
+
return mcpError14(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
22451
22567
|
}
|
|
22452
22568
|
}
|
|
22453
22569
|
function registerDeployTool(server, client) {
|
|
@@ -22460,35 +22576,33 @@ function registerDeployTool(server, client) {
|
|
|
22460
22576
|
inputSchema: spec.inputSchema,
|
|
22461
22577
|
annotations: spec.annotations
|
|
22462
22578
|
},
|
|
22463
|
-
|
|
22464
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
22465
|
-
spec.handler
|
|
22579
|
+
(args) => deployManageHandlerBody(client, args)
|
|
22466
22580
|
);
|
|
22467
22581
|
}
|
|
22468
22582
|
|
|
22469
22583
|
// src/tools/secret-manage.ts
|
|
22470
|
-
import { z as
|
|
22471
|
-
import { mcpResult as mcpResult14, mcpError as
|
|
22584
|
+
import { z as z13 } from "zod";
|
|
22585
|
+
import { mcpResult as mcpResult14, mcpError as mcpError15 } from "@walkeros/core";
|
|
22472
22586
|
var TITLE13 = "Secret Management";
|
|
22473
22587
|
var DESCRIPTION12 = "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.";
|
|
22474
22588
|
var inputSchema13 = {
|
|
22475
|
-
action:
|
|
22476
|
-
projectId:
|
|
22589
|
+
action: z13.enum(["list", "set", "update", "delete"]).describe("Secret management action to perform"),
|
|
22590
|
+
projectId: z13.string().optional().describe(
|
|
22477
22591
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
22478
22592
|
),
|
|
22479
|
-
flowId:
|
|
22593
|
+
flowId: z13.string().describe(
|
|
22480
22594
|
"Flow ID (flow_...) or config ID (cfg_...). Required for list, set, update, and delete: secrets are flow-scoped."
|
|
22481
22595
|
),
|
|
22482
|
-
name:
|
|
22596
|
+
name: z13.string().regex(
|
|
22483
22597
|
/^[A-Z_][A-Z0-9_]*$/,
|
|
22484
22598
|
"Secret name must be uppercase letters, digits, and underscores, starting with a letter or underscore."
|
|
22485
22599
|
).optional().describe(
|
|
22486
22600
|
"Secret name (UPPER_SNAKE_CASE). Required for set. Referenced in flows as $secret.<NAME>."
|
|
22487
22601
|
),
|
|
22488
|
-
value:
|
|
22602
|
+
value: z13.string().min(1).max(65536).optional().describe(
|
|
22489
22603
|
"Secret value (1-65536 chars). Required for set and update. Write-only: never returned or logged."
|
|
22490
22604
|
),
|
|
22491
|
-
secretId:
|
|
22605
|
+
secretId: z13.string().optional().describe(
|
|
22492
22606
|
'Secret ID (sec_...). Required for update and delete. Use action "list" to find it.'
|
|
22493
22607
|
)
|
|
22494
22608
|
};
|
|
@@ -22509,18 +22623,20 @@ function createSecretManageToolSpec(client) {
|
|
|
22509
22623
|
};
|
|
22510
22624
|
}
|
|
22511
22625
|
async function secretManageHandlerBody(client, input) {
|
|
22512
|
-
const
|
|
22626
|
+
const parsed = parseToolInput(inputSchema13, input);
|
|
22627
|
+
if (!parsed.ok) return parsed.error;
|
|
22628
|
+
const { action, projectId, flowId, name, value, secretId } = parsed.data;
|
|
22513
22629
|
const validationError = validateActionInput(
|
|
22514
22630
|
"secret_manage",
|
|
22515
22631
|
action ?? "",
|
|
22516
22632
|
{ flowId, name, value, secretId },
|
|
22517
22633
|
SECRET_MANAGE_REQUIREMENTS
|
|
22518
22634
|
);
|
|
22519
|
-
if (validationError) return
|
|
22635
|
+
if (validationError) return mcpError15(new Error(validationError));
|
|
22520
22636
|
try {
|
|
22521
22637
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
22522
22638
|
if (!resolvedProjectId)
|
|
22523
|
-
return
|
|
22639
|
+
return mcpError15(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
22524
22640
|
switch (action) {
|
|
22525
22641
|
case "list": {
|
|
22526
22642
|
assertParam(flowId, "flowId", "list");
|
|
@@ -22579,7 +22695,7 @@ async function secretManageHandlerBody(client, input) {
|
|
|
22579
22695
|
);
|
|
22580
22696
|
}
|
|
22581
22697
|
} catch (error) {
|
|
22582
|
-
return
|
|
22698
|
+
return mcpError15(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
22583
22699
|
}
|
|
22584
22700
|
}
|
|
22585
22701
|
function registerSecretManageTool(server, client) {
|
|
@@ -22592,22 +22708,20 @@ function registerSecretManageTool(server, client) {
|
|
|
22592
22708
|
inputSchema: spec.inputSchema,
|
|
22593
22709
|
annotations: spec.annotations
|
|
22594
22710
|
},
|
|
22595
|
-
|
|
22596
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
22597
|
-
spec.handler
|
|
22711
|
+
(args) => secretManageHandlerBody(client, args)
|
|
22598
22712
|
);
|
|
22599
22713
|
}
|
|
22600
22714
|
|
|
22601
22715
|
// src/tools/observe-journeys.ts
|
|
22602
|
-
import { z as
|
|
22603
|
-
import { mcpResult as mcpResult15, mcpError as
|
|
22716
|
+
import { z as z14 } from "zod";
|
|
22717
|
+
import { mcpResult as mcpResult15, mcpError as mcpError16 } from "@walkeros/core";
|
|
22604
22718
|
var TITLE14 = "Observe Journeys";
|
|
22605
22719
|
var DESCRIPTION13 = "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.";
|
|
22606
22720
|
var inputSchema14 = {
|
|
22607
|
-
flowId:
|
|
22608
|
-
projectId:
|
|
22609
|
-
traceId:
|
|
22610
|
-
limit:
|
|
22721
|
+
flowId: z14.string().describe("Flow to read journeys for (its active Observe session)."),
|
|
22722
|
+
projectId: z14.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
22723
|
+
traceId: z14.string().optional().describe("Return only the journeys for this trace id."),
|
|
22724
|
+
limit: z14.number().int().min(1).max(100).optional().describe(
|
|
22611
22725
|
"Max journeys to return (1-100, most recent kept). Defaults to 50."
|
|
22612
22726
|
)
|
|
22613
22727
|
};
|
|
@@ -22665,9 +22779,11 @@ function createObserveJourneysToolSpec(client) {
|
|
|
22665
22779
|
};
|
|
22666
22780
|
}
|
|
22667
22781
|
async function observeJourneysHandlerBody(client, input) {
|
|
22668
|
-
const
|
|
22782
|
+
const parsed = parseToolInput(inputSchema14, input);
|
|
22783
|
+
if (!parsed.ok) return parsed.error;
|
|
22784
|
+
const { flowId, projectId, traceId, limit } = parsed.data;
|
|
22669
22785
|
if (!flowId) {
|
|
22670
|
-
return
|
|
22786
|
+
return mcpError16(new Error("flowId is required for observe_journeys."));
|
|
22671
22787
|
}
|
|
22672
22788
|
try {
|
|
22673
22789
|
const result = await client.listJourneys({
|
|
@@ -22694,7 +22810,7 @@ async function observeJourneysHandlerBody(client, input) {
|
|
|
22694
22810
|
]
|
|
22695
22811
|
});
|
|
22696
22812
|
} catch (error) {
|
|
22697
|
-
return
|
|
22813
|
+
return mcpError16(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
22698
22814
|
}
|
|
22699
22815
|
}
|
|
22700
22816
|
function registerObserveJourneysTool(server, client) {
|
|
@@ -22707,15 +22823,13 @@ function registerObserveJourneysTool(server, client) {
|
|
|
22707
22823
|
inputSchema: spec.inputSchema,
|
|
22708
22824
|
annotations: spec.annotations
|
|
22709
22825
|
},
|
|
22710
|
-
|
|
22711
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
22712
|
-
spec.handler
|
|
22826
|
+
(args) => observeJourneysHandlerBody(client, args)
|
|
22713
22827
|
);
|
|
22714
22828
|
}
|
|
22715
22829
|
|
|
22716
22830
|
// src/tools/observe-session.ts
|
|
22717
|
-
import { z as
|
|
22718
|
-
import { mcpResult as mcpResult16, mcpError as
|
|
22831
|
+
import { z as z15 } from "zod";
|
|
22832
|
+
import { mcpResult as mcpResult16, mcpError as mcpError17 } from "@walkeros/core";
|
|
22719
22833
|
var TITLE15 = "Observe Session";
|
|
22720
22834
|
var DESCRIPTION14 = "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.";
|
|
22721
22835
|
var HINT_SIMULATE_FIRST = "Simulate before preview: flow_simulate checks mapping with no browser.";
|
|
@@ -22726,29 +22840,29 @@ var HINT_EMPTY_FEED = "recordsReceived is 0: nothing has reached the feed yet. D
|
|
|
22726
22840
|
var HINT_ENDED = "Session ended and both arms detached. Start a new one with observe_session start.";
|
|
22727
22841
|
var HINT_NO_WINDOW = "No Observe session on this flow. Open one with observe_session start.";
|
|
22728
22842
|
var inputSchema15 = {
|
|
22729
|
-
action:
|
|
22843
|
+
action: z15.enum(["start", "status", "stop"]).describe(
|
|
22730
22844
|
"start opens a session, status reports arm state, stop ends the whole session."
|
|
22731
22845
|
),
|
|
22732
|
-
flowId:
|
|
22733
|
-
projectId:
|
|
22734
|
-
sessionId:
|
|
22846
|
+
flowId: z15.string().describe("Flow the Observe session runs on."),
|
|
22847
|
+
projectId: z15.string().optional().describe("Project ID. Optional; falls back to the default project."),
|
|
22848
|
+
sessionId: z15.string().optional().describe(
|
|
22735
22849
|
"Session to act on for status/stop. Optional; the flow has at most one session and it is resolved for you."
|
|
22736
22850
|
),
|
|
22737
|
-
arms:
|
|
22738
|
-
container:
|
|
22851
|
+
arms: z15.object({
|
|
22852
|
+
container: z15.literal(true).optional().describe(
|
|
22739
22853
|
"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."
|
|
22740
22854
|
),
|
|
22741
|
-
preview:
|
|
22855
|
+
preview: z15.string().optional().describe(
|
|
22742
22856
|
"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."
|
|
22743
22857
|
)
|
|
22744
22858
|
}).optional().describe(
|
|
22745
22859
|
"Which runtimes attach. Omit to attach the default preview arm; a web settings that references a server flow brings its container arm with it."
|
|
22746
22860
|
),
|
|
22747
|
-
origins:
|
|
22861
|
+
origins: z15.array(z15.string()).optional().describe(
|
|
22748
22862
|
"Bare https origins (https://host[:port]) the session may ingest web events from."
|
|
22749
22863
|
),
|
|
22750
|
-
level:
|
|
22751
|
-
replace:
|
|
22864
|
+
level: z15.enum(["off", "standard", "trace"]).optional().describe("Container observation verbosity. Defaults to the app's own."),
|
|
22865
|
+
replace: z15.boolean().optional().describe(
|
|
22752
22866
|
"Replace the flow's existing window instead of attaching to it. Re-provisions from the new config."
|
|
22753
22867
|
)
|
|
22754
22868
|
};
|
|
@@ -22759,14 +22873,14 @@ var annotations15 = {
|
|
|
22759
22873
|
openWorldHint: true
|
|
22760
22874
|
};
|
|
22761
22875
|
function readSettings(flow) {
|
|
22762
|
-
if (!flow
|
|
22876
|
+
if (!isRecord(flow)) return [];
|
|
22763
22877
|
const settings = flow.settings;
|
|
22764
22878
|
if (!Array.isArray(settings)) return [];
|
|
22765
22879
|
const entries = [];
|
|
22766
22880
|
for (const entry of settings) {
|
|
22767
|
-
|
|
22768
|
-
const
|
|
22769
|
-
if (
|
|
22881
|
+
const name = stringField(entry, "name");
|
|
22882
|
+
const platform = stringField(entry, "platform");
|
|
22883
|
+
if (name === void 0) continue;
|
|
22770
22884
|
if (platform !== "web" && platform !== "server") continue;
|
|
22771
22885
|
entries.push({ name, platform });
|
|
22772
22886
|
}
|
|
@@ -22896,6 +23010,8 @@ function createObserveSessionToolSpec(client) {
|
|
|
22896
23010
|
};
|
|
22897
23011
|
}
|
|
22898
23012
|
async function observeSessionHandlerBody(client, input) {
|
|
23013
|
+
const parsed = parseToolInput(inputSchema15, input);
|
|
23014
|
+
if (!parsed.ok) return parsed.error;
|
|
22899
23015
|
const {
|
|
22900
23016
|
action,
|
|
22901
23017
|
flowId,
|
|
@@ -22905,19 +23021,19 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
22905
23021
|
origins,
|
|
22906
23022
|
level,
|
|
22907
23023
|
replace
|
|
22908
|
-
} =
|
|
23024
|
+
} = parsed.data;
|
|
22909
23025
|
if (!flowId) {
|
|
22910
|
-
return
|
|
23026
|
+
return mcpError17(new Error("flowId is required for observe_session."));
|
|
22911
23027
|
}
|
|
22912
23028
|
const resolvedProjectId = resolveProjectId(client, projectId);
|
|
22913
23029
|
if (!resolvedProjectId) {
|
|
22914
|
-
return
|
|
23030
|
+
return mcpError17(new Error(NO_DEFAULT_PROJECT_ERROR2));
|
|
22915
23031
|
}
|
|
22916
23032
|
try {
|
|
22917
23033
|
switch (action) {
|
|
22918
23034
|
case "start": {
|
|
22919
23035
|
if (!client.startObserveSession) {
|
|
22920
|
-
return
|
|
23036
|
+
return mcpError17(
|
|
22921
23037
|
new Error("observe_session start is not supported by this client.")
|
|
22922
23038
|
);
|
|
22923
23039
|
}
|
|
@@ -22943,7 +23059,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
22943
23059
|
}
|
|
22944
23060
|
case "status": {
|
|
22945
23061
|
if (!client.getObserveSession) {
|
|
22946
|
-
return
|
|
23062
|
+
return mcpError17(
|
|
22947
23063
|
new Error(
|
|
22948
23064
|
"observe_session status is not supported by this client."
|
|
22949
23065
|
)
|
|
@@ -22970,7 +23086,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
22970
23086
|
}
|
|
22971
23087
|
case "stop": {
|
|
22972
23088
|
if (!client.endObserveSession) {
|
|
22973
|
-
return
|
|
23089
|
+
return mcpError17(
|
|
22974
23090
|
new Error("observe_session stop is not supported by this client.")
|
|
22975
23091
|
);
|
|
22976
23092
|
}
|
|
@@ -23000,7 +23116,7 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
23000
23116
|
);
|
|
23001
23117
|
}
|
|
23002
23118
|
} catch (error) {
|
|
23003
|
-
return
|
|
23119
|
+
return mcpError17(error, isAuthError(error) ? AUTH_HINT : void 0);
|
|
23004
23120
|
}
|
|
23005
23121
|
}
|
|
23006
23122
|
function registerObserveSessionTool(server, client) {
|
|
@@ -23013,15 +23129,13 @@ function registerObserveSessionTool(server, client) {
|
|
|
23013
23129
|
inputSchema: spec.inputSchema,
|
|
23014
23130
|
annotations: spec.annotations
|
|
23015
23131
|
},
|
|
23016
|
-
|
|
23017
|
-
// type-erased (input: unknown) => Promise<unknown> form by design.
|
|
23018
|
-
spec.handler
|
|
23132
|
+
(args) => observeSessionHandlerBody(client, args)
|
|
23019
23133
|
);
|
|
23020
23134
|
}
|
|
23021
23135
|
|
|
23022
23136
|
// src/tools/hub-manage.ts
|
|
23023
|
-
import { z as
|
|
23024
|
-
import { mcpResult as mcpResult17, mcpError as
|
|
23137
|
+
import { z as z16 } from "zod";
|
|
23138
|
+
import { mcpResult as mcpResult17, mcpError as mcpError18 } from "@walkeros/core";
|
|
23025
23139
|
|
|
23026
23140
|
// src/tools/feature-gate.ts
|
|
23027
23141
|
var FEATURE_NOT_AVAILABLE = "FEATURE_NOT_AVAILABLE";
|
|
@@ -23074,56 +23188,56 @@ var TOOL_ANCHOR_TYPES = [
|
|
|
23074
23188
|
"tag"
|
|
23075
23189
|
];
|
|
23076
23190
|
var HUB_MANAGE_INPUT_SCHEMA = {
|
|
23077
|
-
action:
|
|
23191
|
+
action: z16.enum(ACTIONS, {
|
|
23078
23192
|
error: () => `Unknown action. Use one of: ${ACTIONS.join(", ")}`
|
|
23079
23193
|
}).describe("Which part of the release history to read or write"),
|
|
23080
|
-
projectId:
|
|
23194
|
+
projectId: z16.string().optional().describe(
|
|
23081
23195
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
23082
23196
|
),
|
|
23083
|
-
flowId:
|
|
23197
|
+
flowId: z16.string().optional().describe(
|
|
23084
23198
|
'Flow ID (flow_...). Required for every action except "knowledge", which hangs on a page rather than a flow and refuses this field.'
|
|
23085
23199
|
),
|
|
23086
|
-
versionId:
|
|
23200
|
+
versionId: z16.string().min(1).optional().describe(
|
|
23087
23201
|
'Release version ID (ver_...) from action "releases". Addresses one release for release_get and rationale_set. Pass this or versionNumber.'
|
|
23088
23202
|
),
|
|
23089
|
-
versionNumber:
|
|
23203
|
+
versionNumber: z16.number().int().positive().optional().describe(
|
|
23090
23204
|
'Spine release number for this flow, the `versionNumber` field of action "releases". Alternative to versionId. Not the same as a row\'s deploymentAttempt.'
|
|
23091
23205
|
),
|
|
23092
|
-
step:
|
|
23206
|
+
step: z16.string().optional().describe(
|
|
23093
23207
|
'Step key as "type.name", e.g. "destination.ga4" or "contract.checkout". Required for step_history.'
|
|
23094
23208
|
),
|
|
23095
|
-
flow:
|
|
23209
|
+
flow: z16.string().optional().describe(
|
|
23096
23210
|
'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.'
|
|
23097
23211
|
),
|
|
23098
|
-
text:
|
|
23212
|
+
text: z16.string().trim().min(1).max(MAX_ANNOTATION_TEXT_LENGTH).optional().describe(
|
|
23099
23213
|
`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.`
|
|
23100
23214
|
),
|
|
23101
|
-
limit:
|
|
23215
|
+
limit: z16.number().int().positive().optional().describe(
|
|
23102
23216
|
`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.`
|
|
23103
23217
|
),
|
|
23104
|
-
offset:
|
|
23105
|
-
anchorType:
|
|
23218
|
+
offset: z16.number().int().min(0).optional().describe('Releases to skip. Action "releases" only.'),
|
|
23219
|
+
anchorType: z16.enum(TOOL_ANCHOR_TYPES).optional().describe(
|
|
23106
23220
|
'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.'
|
|
23107
23221
|
),
|
|
23108
|
-
anchorKey:
|
|
23222
|
+
anchorKey: z16.string().min(1).max(MAX_ANCHOR_KEY_LENGTH).optional().describe(
|
|
23109
23223
|
'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.'
|
|
23110
23224
|
),
|
|
23111
|
-
anchorLabel:
|
|
23225
|
+
anchorLabel: z16.string().min(1).max(MAX_ANCHOR_LABEL_LENGTH).optional().describe(
|
|
23112
23226
|
'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.'
|
|
23113
23227
|
),
|
|
23114
|
-
threadId:
|
|
23228
|
+
threadId: z16.string().min(1).optional().describe(
|
|
23115
23229
|
'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.'
|
|
23116
23230
|
),
|
|
23117
|
-
status:
|
|
23231
|
+
status: z16.enum(THREAD_STATUSES).optional().describe(
|
|
23118
23232
|
'Read only threads in this state. Action "threads" only; omit for both.'
|
|
23119
23233
|
),
|
|
23120
|
-
pageKey:
|
|
23234
|
+
pageKey: z16.string().min(1).max(MAX_SOURCE_KEY_LENGTH).optional().describe(
|
|
23121
23235
|
'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.'
|
|
23122
23236
|
),
|
|
23123
|
-
frameId:
|
|
23237
|
+
frameId: z16.string().regex(FRAME_ID_PATTERN).optional().describe(
|
|
23124
23238
|
'One frame (frm_...), the named rectangle a note hangs on. Action "knowledge" only. Narrower than pageKey, since a page holds several frames.'
|
|
23125
23239
|
),
|
|
23126
|
-
markId:
|
|
23240
|
+
markId: z16.string().min(1).max(MAX_MARK_ID_LENGTH).optional().describe(
|
|
23127
23241
|
'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.'
|
|
23128
23242
|
)
|
|
23129
23243
|
};
|
|
@@ -23169,7 +23283,7 @@ var HUB_HINT_ENTRY_NAMES_FLOW = "An entry names the flow it was written against
|
|
|
23169
23283
|
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.";
|
|
23170
23284
|
var HUB_HINT_READ_FRAME = 'Use frame_manage action "get" with the frameId to read the frame and its marks.';
|
|
23171
23285
|
var HUB_NOT_FOUND_HINT = 'Use action "releases" to find version ids and action "threads" to find thread ids.';
|
|
23172
|
-
var hubInputSchema =
|
|
23286
|
+
var hubInputSchema = z16.object(HUB_MANAGE_INPUT_SCHEMA);
|
|
23173
23287
|
var HubToolError = class extends Error {
|
|
23174
23288
|
constructor(code, message) {
|
|
23175
23289
|
super(message);
|
|
@@ -23589,12 +23703,7 @@ async function hubManageHandler(client, rawInput) {
|
|
|
23589
23703
|
try {
|
|
23590
23704
|
const parsed = hubInputSchema.safeParse(rawInput ?? {});
|
|
23591
23705
|
if (!parsed.success) {
|
|
23592
|
-
throw new HubToolError(
|
|
23593
|
-
"INVALID_INPUT",
|
|
23594
|
-
parsed.error.issues.map(
|
|
23595
|
-
(issue) => `${issue.path.join(".") || "input"}: ${issue.message}`
|
|
23596
|
-
).join("; ")
|
|
23597
|
-
);
|
|
23706
|
+
throw new HubToolError("INVALID_INPUT", inputIssuesMessage(parsed.error));
|
|
23598
23707
|
}
|
|
23599
23708
|
const input = parsed.data;
|
|
23600
23709
|
const { action } = input;
|
|
@@ -23627,7 +23736,7 @@ async function hubManageHandler(client, rawInput) {
|
|
|
23627
23736
|
return await handleNoteAdd(client, projectId, flowId, input);
|
|
23628
23737
|
}
|
|
23629
23738
|
} catch (error) {
|
|
23630
|
-
return
|
|
23739
|
+
return mcpError18(error, errorHint(error, "hub", HUB_NOT_FOUND_HINT));
|
|
23631
23740
|
}
|
|
23632
23741
|
}
|
|
23633
23742
|
function createHubManageToolSpec(client) {
|
|
@@ -23655,23 +23764,23 @@ function registerHubManageTool(server, client) {
|
|
|
23655
23764
|
}
|
|
23656
23765
|
|
|
23657
23766
|
// src/tools/frame-manage.ts
|
|
23658
|
-
import { z as
|
|
23659
|
-
import { mcpResult as mcpResult18, mcpError as
|
|
23767
|
+
import { z as z17 } from "zod";
|
|
23768
|
+
import { mcpResult as mcpResult18, mcpError as mcpError19 } from "@walkeros/core";
|
|
23660
23769
|
var FRAME_ID_PATTERN2 = /^frm_[A-Za-z0-9_-]{21}$/;
|
|
23661
23770
|
var MAX_PAGE_KEY_CHARS = 1024;
|
|
23662
23771
|
var TITLE17 = "Frames";
|
|
23663
23772
|
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.';
|
|
23664
23773
|
var FRAME_MANAGE_INPUT_SCHEMA = {
|
|
23665
|
-
action:
|
|
23774
|
+
action: z17.enum(["list", "page", "get"]).describe(
|
|
23666
23775
|
"list the project\u2019s frames, read one page with marks, or read one frame"
|
|
23667
23776
|
),
|
|
23668
|
-
projectId:
|
|
23777
|
+
projectId: z17.string().optional().describe(
|
|
23669
23778
|
"Project ID. Optional: falls back to the default project when omitted."
|
|
23670
23779
|
),
|
|
23671
|
-
pageKey:
|
|
23780
|
+
pageKey: z17.string().min(1).max(MAX_PAGE_KEY_CHARS).optional().describe(
|
|
23672
23781
|
"The page as its frames address it (the `source.key` of a page frame, usually the page URL without query). Required for page."
|
|
23673
23782
|
),
|
|
23674
|
-
frameId:
|
|
23783
|
+
frameId: z17.string().regex(FRAME_ID_PATTERN2).optional().describe(
|
|
23675
23784
|
'Frame ID (frm_...). Required for get. Use action "list" or "page" to find one.'
|
|
23676
23785
|
)
|
|
23677
23786
|
};
|
|
@@ -23781,17 +23890,11 @@ function serializeFrame(frame) {
|
|
|
23781
23890
|
marks: walkMarks(frame.marks)
|
|
23782
23891
|
};
|
|
23783
23892
|
}
|
|
23784
|
-
var frameInputSchema =
|
|
23893
|
+
var frameInputSchema = z17.object(FRAME_MANAGE_INPUT_SCHEMA);
|
|
23785
23894
|
async function frameManageHandler(client, rawInput) {
|
|
23786
23895
|
const parsed = frameInputSchema.safeParse(rawInput ?? {});
|
|
23787
23896
|
if (!parsed.success) {
|
|
23788
|
-
return
|
|
23789
|
-
new Error(
|
|
23790
|
-
parsed.error.issues.map(
|
|
23791
|
-
(issue) => `${issue.path.join(".") || "input"}: ${issue.message}`
|
|
23792
|
-
).join("; ")
|
|
23793
|
-
)
|
|
23794
|
-
);
|
|
23897
|
+
return mcpError19(new Error(inputIssuesMessage(parsed.error)));
|
|
23795
23898
|
}
|
|
23796
23899
|
const { action, projectId, pageKey, frameId } = parsed.data;
|
|
23797
23900
|
const validationError = validateActionInput(
|
|
@@ -23800,11 +23903,11 @@ async function frameManageHandler(client, rawInput) {
|
|
|
23800
23903
|
{ pageKey, frameId },
|
|
23801
23904
|
FRAME_MANAGE_REQUIREMENTS
|
|
23802
23905
|
);
|
|
23803
|
-
if (validationError) return
|
|
23906
|
+
if (validationError) return mcpError19(new Error(validationError));
|
|
23804
23907
|
try {
|
|
23805
23908
|
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
23806
23909
|
if (!resolvedProjectId) {
|
|
23807
|
-
return
|
|
23910
|
+
return mcpError19(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
23808
23911
|
}
|
|
23809
23912
|
switch (action) {
|
|
23810
23913
|
case "list": {
|
|
@@ -23849,7 +23952,7 @@ async function frameManageHandler(client, rawInput) {
|
|
|
23849
23952
|
}
|
|
23850
23953
|
}
|
|
23851
23954
|
} catch (error) {
|
|
23852
|
-
return
|
|
23955
|
+
return mcpError19(error, errorHint(error, "frames", FRAME_NOT_FOUND_HINT));
|
|
23853
23956
|
}
|
|
23854
23957
|
}
|
|
23855
23958
|
function createFrameManageToolSpec(client) {
|
|
@@ -23919,7 +24022,7 @@ function registerPackageSchemaResources(server) {
|
|
|
23919
24022
|
}
|
|
23920
24023
|
|
|
23921
24024
|
// src/resources/references.ts
|
|
23922
|
-
import { schemas as
|
|
24025
|
+
import { schemas as schemas6 } from "@walkeros/core/dev";
|
|
23923
24026
|
function registerReferenceResources(server) {
|
|
23924
24027
|
server.resource(
|
|
23925
24028
|
"flow-schema",
|
|
@@ -23932,7 +24035,7 @@ function registerReferenceResources(server) {
|
|
|
23932
24035
|
contents: [
|
|
23933
24036
|
{
|
|
23934
24037
|
uri: "walkeros://reference/flow-schema",
|
|
23935
|
-
text: JSON.stringify(
|
|
24038
|
+
text: JSON.stringify(schemas6.configJsonSchema, null, 2),
|
|
23936
24039
|
mimeType: "application/json"
|
|
23937
24040
|
}
|
|
23938
24041
|
]
|
|
@@ -23949,7 +24052,7 @@ function registerReferenceResources(server) {
|
|
|
23949
24052
|
contents: [
|
|
23950
24053
|
{
|
|
23951
24054
|
uri: "walkeros://reference/event-model",
|
|
23952
|
-
text: JSON.stringify(
|
|
24055
|
+
text: JSON.stringify(schemas6.eventJsonSchema, null, 2),
|
|
23953
24056
|
mimeType: "application/json"
|
|
23954
24057
|
}
|
|
23955
24058
|
]
|
|
@@ -23968,10 +24071,10 @@ function registerReferenceResources(server) {
|
|
|
23968
24071
|
uri: "walkeros://reference/mapping",
|
|
23969
24072
|
text: JSON.stringify(
|
|
23970
24073
|
{
|
|
23971
|
-
rules:
|
|
23972
|
-
valueConfig:
|
|
23973
|
-
rule:
|
|
23974
|
-
policy:
|
|
24074
|
+
rules: schemas6.rulesJsonSchema,
|
|
24075
|
+
valueConfig: schemas6.valueConfigJsonSchema,
|
|
24076
|
+
rule: schemas6.ruleJsonSchema,
|
|
24077
|
+
policy: schemas6.policyJsonSchema
|
|
23975
24078
|
},
|
|
23976
24079
|
null,
|
|
23977
24080
|
2
|
|
@@ -23992,7 +24095,7 @@ function registerReferenceResources(server) {
|
|
|
23992
24095
|
contents: [
|
|
23993
24096
|
{
|
|
23994
24097
|
uri: "walkeros://reference/consent",
|
|
23995
|
-
text: JSON.stringify(
|
|
24098
|
+
text: JSON.stringify(schemas6.consentJsonSchema, null, 2),
|
|
23996
24099
|
mimeType: "application/json"
|
|
23997
24100
|
}
|
|
23998
24101
|
]
|
|
@@ -24068,7 +24171,7 @@ function registerReferenceResources(server) {
|
|
|
24068
24171
|
contents: [
|
|
24069
24172
|
{
|
|
24070
24173
|
uri: "walkeros://reference/contract",
|
|
24071
|
-
text: JSON.stringify(
|
|
24174
|
+
text: JSON.stringify(schemas6.contractJsonSchema, null, 2),
|
|
24072
24175
|
mimeType: "application/json"
|
|
24073
24176
|
}
|
|
24074
24177
|
]
|
|
@@ -24146,17 +24249,17 @@ function registerReferenceResources(server) {
|
|
|
24146
24249
|
}
|
|
24147
24250
|
|
|
24148
24251
|
// src/prompts/add-step.ts
|
|
24149
|
-
import { z as
|
|
24252
|
+
import { z as z18 } from "zod";
|
|
24150
24253
|
function registerAddStepPrompt(server) {
|
|
24151
24254
|
server.registerPrompt(
|
|
24152
24255
|
"add-step",
|
|
24153
24256
|
{
|
|
24154
24257
|
description: "Add a source, destination, transformer, or store step to a flow configuration. Guides through package selection, config scaffolding, and wiring.",
|
|
24155
24258
|
argsSchema: {
|
|
24156
|
-
stepType:
|
|
24259
|
+
stepType: z18.string().optional().describe(
|
|
24157
24260
|
"Type of step to add: source, destination, transformer, or store"
|
|
24158
24261
|
),
|
|
24159
|
-
flowPath:
|
|
24262
|
+
flowPath: z18.string().optional().describe("Path to the flow.json file to modify")
|
|
24160
24263
|
}
|
|
24161
24264
|
},
|
|
24162
24265
|
async ({ stepType, flowPath }) => ({
|
|
@@ -24202,14 +24305,14 @@ function registerAddStepPrompt(server) {
|
|
|
24202
24305
|
}
|
|
24203
24306
|
|
|
24204
24307
|
// src/prompts/setup-mapping.ts
|
|
24205
|
-
import { z as
|
|
24308
|
+
import { z as z19 } from "zod";
|
|
24206
24309
|
function registerSetupMappingPrompt(server) {
|
|
24207
24310
|
server.registerPrompt(
|
|
24208
24311
|
"setup-mapping",
|
|
24209
24312
|
{
|
|
24210
24313
|
description: "Set up event mapping for any step in a flow. Teaches mapping syntax and uses package examples as templates.",
|
|
24211
24314
|
argsSchema: {
|
|
24212
|
-
stepName:
|
|
24315
|
+
stepName: z19.string().optional().describe('Step name in the flow (e.g., "gtag", "meta", "express")')
|
|
24213
24316
|
}
|
|
24214
24317
|
},
|
|
24215
24318
|
async ({ stepName }) => ({
|
|
@@ -24247,14 +24350,14 @@ function registerSetupMappingPrompt(server) {
|
|
|
24247
24350
|
}
|
|
24248
24351
|
|
|
24249
24352
|
// src/prompts/manage-contract.ts
|
|
24250
|
-
import { z as
|
|
24353
|
+
import { z as z20 } from "zod";
|
|
24251
24354
|
function registerManageContractPrompt(server) {
|
|
24252
24355
|
server.registerPrompt(
|
|
24253
24356
|
"manage-contract",
|
|
24254
24357
|
{
|
|
24255
24358
|
description: "Create or update event contracts for a flow. Can generate contracts from existing mappings or scaffold mappings from contracts.",
|
|
24256
24359
|
argsSchema: {
|
|
24257
|
-
direction:
|
|
24360
|
+
direction: z20.string().optional().describe(
|
|
24258
24361
|
'Direction: "from-mappings" (extract contract from existing mappings), "from-scratch" (create new contract), or "to-mappings" (scaffold mappings from contract)'
|
|
24259
24362
|
)
|
|
24260
24363
|
}
|
|
@@ -24298,7 +24401,7 @@ var SERVER_INSTRUCTIONS = `walkerOS is an open-source, privacy-first event data
|
|
|
24298
24401
|
|
|
24299
24402
|
- **Never guess package names.** Always use \`package_search\` first to find exact names, then \`package_get\` for details.
|
|
24300
24403
|
- **Never construct flow configs from memory.** Read \`walkeros://reference/flow-schema\` and use \`package_get\` for package-specific schemas.
|
|
24301
|
-
- **Always validate.** Run \`flow_validate\` after every config change. If validation fails, fix and re-validate.
|
|
24404
|
+
- **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).
|
|
24302
24405
|
- **Simulate before deploying.** Use \`flow_simulate\` to test with mocked API calls before \`flow_bundle\` or \`flow_push\`.
|
|
24303
24406
|
- **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.
|
|
24304
24407
|
|
|
@@ -24802,8 +24905,11 @@ var HttpToolClient = class {
|
|
|
24802
24905
|
};
|
|
24803
24906
|
|
|
24804
24907
|
// src/runtime/local.ts
|
|
24908
|
+
import * as fs from "fs";
|
|
24909
|
+
import * as path2 from "path";
|
|
24805
24910
|
import {
|
|
24806
24911
|
collectKnownSecrets,
|
|
24912
|
+
loadConfig,
|
|
24807
24913
|
loadJsonConfig,
|
|
24808
24914
|
bundle as bundle2,
|
|
24809
24915
|
push,
|
|
@@ -24812,6 +24918,8 @@ import {
|
|
|
24812
24918
|
simulateCollector,
|
|
24813
24919
|
simulateDestination
|
|
24814
24920
|
} from "@walkeros/cli";
|
|
24921
|
+
import { isObject as isObject3 } from "@walkeros/core";
|
|
24922
|
+
import { schemas as schemas7 } from "@walkeros/core/dev";
|
|
24815
24923
|
|
|
24816
24924
|
// src/runtime/bundle-cache.ts
|
|
24817
24925
|
import { createHash } from "crypto";
|
|
@@ -24902,6 +25010,10 @@ async function getOrBuildBundle(resolvedConfig) {
|
|
|
24902
25010
|
function createLocalRuntime() {
|
|
24903
25011
|
return {
|
|
24904
25012
|
load: (input) => loadJsonConfig(input),
|
|
25013
|
+
baseDir(input) {
|
|
25014
|
+
const file = path2.resolve(input);
|
|
25015
|
+
return fs.existsSync(file) && fs.statSync(file).isFile() ? path2.dirname(file) : void 0;
|
|
25016
|
+
},
|
|
24905
25017
|
bundle: (input, opts) => bundle2(input, {
|
|
24906
25018
|
flowName: opts.flowName,
|
|
24907
25019
|
stats: opts.stats,
|
|
@@ -24915,60 +25027,75 @@ function createLocalRuntime() {
|
|
|
24915
25027
|
bundlePath = void 0;
|
|
24916
25028
|
}
|
|
24917
25029
|
const common = { bundlePath, flow: opts.flow, silent: true };
|
|
25030
|
+
const config = opts.config ?? input;
|
|
24918
25031
|
switch (opts.stepType) {
|
|
24919
25032
|
case "source":
|
|
24920
|
-
return simulateSource(
|
|
25033
|
+
return simulateSource(config, opts.event, {
|
|
24921
25034
|
sourceId: opts.stepId,
|
|
24922
25035
|
...common,
|
|
24923
25036
|
consent: opts.state?.consent
|
|
24924
25037
|
});
|
|
24925
25038
|
case "transformer":
|
|
24926
|
-
return simulateTransformer(
|
|
24927
|
-
|
|
24928
|
-
|
|
24929
|
-
|
|
24930
|
-
|
|
24931
|
-
|
|
24932
|
-
ingest: opts.ingest,
|
|
24933
|
-
consent: opts.state?.consent
|
|
24934
|
-
}
|
|
24935
|
-
);
|
|
25039
|
+
return simulateTransformer(config, partialEvent(opts.event), {
|
|
25040
|
+
transformerId: opts.stepId,
|
|
25041
|
+
...common,
|
|
25042
|
+
ingest: opts.ingest,
|
|
25043
|
+
consent: opts.state?.consent
|
|
25044
|
+
});
|
|
24936
25045
|
case "collector":
|
|
24937
|
-
return simulateCollector(
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
24943
|
-
state: opts.state,
|
|
24944
|
-
ingest: opts.ingest
|
|
24945
|
-
}
|
|
24946
|
-
);
|
|
25046
|
+
return simulateCollector(config, partialEvent(opts.event), {
|
|
25047
|
+
collectorName: opts.stepId,
|
|
25048
|
+
...common,
|
|
25049
|
+
state: opts.state,
|
|
25050
|
+
ingest: opts.ingest
|
|
25051
|
+
});
|
|
24947
25052
|
case "destination":
|
|
24948
|
-
return simulateDestination(
|
|
24949
|
-
|
|
24950
|
-
|
|
24951
|
-
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
consent: opts.state?.consent,
|
|
24956
|
-
command: opts.command
|
|
24957
|
-
}
|
|
24958
|
-
);
|
|
25053
|
+
return simulateDestination(config, eventObject(opts.event), {
|
|
25054
|
+
destinationId: opts.stepId,
|
|
25055
|
+
...common,
|
|
25056
|
+
ingest: opts.ingest,
|
|
25057
|
+
consent: opts.state?.consent,
|
|
25058
|
+
command: opts.command
|
|
25059
|
+
});
|
|
24959
25060
|
}
|
|
24960
25061
|
},
|
|
24961
25062
|
knownSecrets: async (input) => collectKnownSecrets(await loadJsonConfig(input)),
|
|
25063
|
+
async loadRun(input) {
|
|
25064
|
+
const content = await loadConfig(input, { json: false });
|
|
25065
|
+
const config = typeof content === "string" ? parseJson(content) : void 0;
|
|
25066
|
+
if (!isFlowJson(config)) return { knownSecrets: [] };
|
|
25067
|
+
return { config, knownSecrets: collectKnownSecrets(config) };
|
|
25068
|
+
},
|
|
24962
25069
|
push: (input, event, opts) => push(input, event, {
|
|
24963
25070
|
json: true,
|
|
24964
25071
|
flow: opts.flow,
|
|
24965
|
-
platform: opts.platform
|
|
25072
|
+
platform: opts.platform,
|
|
25073
|
+
...opts.config !== void 0 && { raw: opts.config }
|
|
24966
25074
|
})
|
|
24967
25075
|
};
|
|
24968
25076
|
}
|
|
25077
|
+
function partialEvent(value) {
|
|
25078
|
+
if (isPartialEvent(value)) return value;
|
|
25079
|
+
const parsed = schemas7.PartialEventSchema.safeParse(value);
|
|
25080
|
+
throw new Error(parsed.error?.message ?? "Invalid event");
|
|
25081
|
+
}
|
|
25082
|
+
function isPartialEvent(value) {
|
|
25083
|
+
return schemas7.PartialEventSchema.safeParse(value).success;
|
|
25084
|
+
}
|
|
25085
|
+
function eventObject(value) {
|
|
25086
|
+
if (isObject3(value)) return value;
|
|
25087
|
+
throw new Error("event must be an object.");
|
|
25088
|
+
}
|
|
25089
|
+
function parseJson(content) {
|
|
25090
|
+
try {
|
|
25091
|
+
return JSON.parse(content);
|
|
25092
|
+
} catch {
|
|
25093
|
+
return void 0;
|
|
25094
|
+
}
|
|
25095
|
+
}
|
|
24969
25096
|
|
|
24970
25097
|
// src/stdio.ts
|
|
24971
|
-
setClientContext({ type: "mcp", version: "4.7.0
|
|
25098
|
+
setClientContext({ type: "mcp", version: "4.7.0" });
|
|
24972
25099
|
process.on("uncaughtException", (err) => {
|
|
24973
25100
|
const emitter = getMcpEmitterSingleton();
|
|
24974
25101
|
if (emitter) {
|
|
@@ -24988,7 +25115,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
24988
25115
|
async function main() {
|
|
24989
25116
|
const server = createWalkerOSMcpServer({
|
|
24990
25117
|
client: new HttpToolClient(),
|
|
24991
|
-
version: "4.7.0
|
|
25118
|
+
version: "4.7.0",
|
|
24992
25119
|
runtime: createLocalRuntime()
|
|
24993
25120
|
});
|
|
24994
25121
|
const transport = new StdioServerTransport();
|
|
@@ -24999,7 +25126,7 @@ main().catch(async (error) => {
|
|
|
24999
25126
|
try {
|
|
25000
25127
|
const emitter = await createMcpEmitter({
|
|
25001
25128
|
clientInfo: void 0,
|
|
25002
|
-
packageVersion: "4.7.0
|
|
25129
|
+
packageVersion: "4.7.0"
|
|
25003
25130
|
});
|
|
25004
25131
|
await emitter.emitError("startup");
|
|
25005
25132
|
} catch {
|