@walkeros/mcp 4.7.2-next-1791147139360 → 4.7.2

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/stdio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stdio.ts","../src/server.ts","../src/tools/validate.ts","../src/schemas/output.ts","../src/runtime/types.ts","../src/cloud-flow.ts","../src/tools/bundle.ts","../src/tools/parse-input.ts","../src/tools/resolve-config-path.ts","../src/tools/simulate.ts","../src/tools/simulate-description.ts","../src/tools/egress.ts","../src/tools/push.ts","../src/tools/examples.ts","../src/catalog.ts","../src/tools/narrow.ts","../src/tools/package.ts","../src/tools/flow-load.ts","../src/types.ts","../src/user-data.ts","../src/tools/project-context.ts","../src/tools/feedback.ts","../src/tools/diagnostics.ts","../src/base-url.ts","../src/tools/auth.ts","../src/tools/project-manage.ts","../src/action-requirements.ts","../src/tools/flow-manage.ts","../src/ui-parts.ts","../src/links.ts","../src/tools/deploy-manage.ts","../src/tools/_resolvers.ts","../src/tools/secret-manage.ts","../src/tools/observe-journeys.ts","../src/tools/observe-session.ts","../src/tools/feature-gate.ts","../src/tools/hub-manage.ts","../src/tools/frame-manage.ts","../src/resources/package-schemas.ts","../src/resources/references.ts","../src/prompts/add-step.ts","../src/prompts/setup-mapping.ts","../src/prompts/manage-contract.ts","../src/instructions.ts","../src/telemetry.ts","../src/runtime/hosted.ts","../src/http-tool-client.ts","../src/runtime/local.ts","../src/runtime/bundle-cache.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { setClientContext } from '@walkeros/cli';\n\nimport { createWalkerOSMcpServer, getMcpEmitterSingleton } from './server.js';\nimport { HttpToolClient } from './http-tool-client.js';\nimport { createMcpEmitter } from './telemetry.js';\nimport { createLocalRuntime } from './runtime/local.js';\n\ndeclare const __VERSION__: string;\n\nsetClientContext({ type: 'mcp', version: __VERSION__ });\n\n// Hook process-level error channels so we can emit `error throw` before the\n// process tears down. Both handlers look up the emitter lazily: if the MCP\n// handshake never completed, no emitter exists and we silently skip.\n// We don't call process.exit — stdio transport already propagates failures\n// up to the parent client via the JSON-RPC channel.\nprocess.on('uncaughtException', (err) => {\n const emitter = getMcpEmitterSingleton();\n if (emitter) {\n emitter.emitError('uncaught').catch(() => {});\n }\n console.error('Uncaught exception in Flow MCP server:', err);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n const emitter = getMcpEmitterSingleton();\n if (emitter) {\n emitter.emitError('unhandledRejection').catch(() => {});\n }\n console.error('Unhandled rejection in Flow MCP server:', reason);\n});\n\nasync function main() {\n // stdio runs on the user's own machine: the local runtime keeps file, URL and\n // in-process bundle, simulate and push behaviour exactly as before.\n const server = createWalkerOSMcpServer({\n client: new HttpToolClient(),\n version: __VERSION__,\n runtime: createLocalRuntime(),\n });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('walkerOS Flow MCP server running on stdio');\n}\n\nmain().catch(async (error) => {\n // Startup failure — no client handshake happened, so there's no emitter in\n // the module singleton. Build a one-shot emitter with an unknown client so\n // the error is still visible to telemetry.\n try {\n const emitter = await createMcpEmitter({\n clientInfo: undefined,\n packageVersion: __VERSION__,\n });\n await emitter.emitError('startup');\n } catch {\n // swallow — telemetry must never mask the original startup error\n }\n console.error('Failed to start Flow MCP server:', error);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport type { ToolClient } from './tool-client.js';\nimport { registerFlowValidateTool } from './tools/validate.js';\nimport { registerFlowBundleTool } from './tools/bundle.js';\nimport { registerFlowSimulateTool } from './tools/simulate.js';\nimport { registerFlowPushTool } from './tools/push.js';\nimport { registerFlowExamplesTool } from './tools/examples.js';\nimport {\n registerPackageSearchTool,\n registerGetPackageSchemaTool,\n} from './tools/package.js';\nimport { registerFlowLoadTool } from './tools/flow-load.js';\nimport { registerFeedbackTool } from './tools/feedback.js';\nimport { registerDiagnosticsTool } from './tools/diagnostics.js';\nimport { registerAuthTool } from './tools/auth.js';\nimport { registerProjectManageTool } from './tools/project-manage.js';\nimport { registerFlowManageTool } from './tools/flow-manage.js';\nimport { registerDeployTool } from './tools/deploy-manage.js';\nimport { registerSecretManageTool } from './tools/secret-manage.js';\nimport { registerObserveJourneysTool } from './tools/observe-journeys.js';\nimport { registerObserveSessionTool } from './tools/observe-session.js';\nimport { registerHubManageTool } from './tools/hub-manage.js';\nimport { registerFrameManageTool } from './tools/frame-manage.js';\nimport { registerPackageSchemaResources } from './resources/package-schemas.js';\nimport { registerReferenceResources } from './resources/references.js';\nimport { registerAddStepPrompt } from './prompts/add-step.js';\nimport { registerSetupMappingPrompt } from './prompts/setup-mapping.js';\nimport { registerManageContractPrompt } from './prompts/manage-contract.js';\nimport { SERVER_INSTRUCTIONS } from './instructions.js';\nimport { createMcpEmitter, type McpEmitter } from './telemetry.js';\nimport type { FlowRuntime } from './runtime/types.js';\nimport { createHostedRuntime } from './runtime/hosted.js';\n\nexport interface Logger {\n debug?(message: string, meta?: Record<string, unknown>): void;\n info?(message: string, meta?: Record<string, unknown>): void;\n warn?(message: string, meta?: Record<string, unknown>): void;\n error?(message: string, meta?: Record<string, unknown>): void;\n}\n\nexport interface CreateServerOptions {\n client: ToolClient;\n logger?: Logger;\n version?: string;\n catalogBaseUrl?: string;\n /**\n * The capability runtime the flow tools read, build and run flows through.\n * Omitted, the HOSTED runtime is used, the safe default for any shared or\n * network-reached process: inline JSON and saved flow ids only, no local\n * files, no URLs, no in-process bundle, simulate or push. Pass\n * `createLocalRuntime()` only on the user's own machine (stdio, the CLI) to\n * keep local file, URL and execution behaviour. See `FlowRuntime`.\n */\n runtime?: FlowRuntime;\n}\n\n/**\n * Module-scoped singleton emitter, populated once the MCP `initialize`\n * handshake completes and clientInfo is known. The stdio entrypoint reads\n * this to emit process-level `error throw` events from uncaughtException /\n * unhandledRejection hooks, where the Server instance isn't in scope.\n */\nlet currentEmitter: McpEmitter | undefined;\n\nexport function getMcpEmitterSingleton(): McpEmitter | undefined {\n return currentEmitter;\n}\n\n/**\n * Internal: reset for tests that want a clean slate between cases.\n * Not exported from the package.\n */\nexport function __resetMcpEmitterSingletonForTesting(): void {\n currentEmitter = undefined;\n}\n\n/**\n * Minimal shape of a `_registeredTools` entry we rely on for handler\n * wrapping. Typed locally to avoid leaking SDK internals while keeping\n * strict typing on the handler signature.\n */\ntype WrappableRegisteredTool = {\n handler: (...args: unknown[]) => unknown;\n};\n\ntype RegisteredToolsRecord = Record<string, WrappableRegisteredTool>;\n\n/**\n * Wrap every already-registered tool handler with telemetry. The wrapper\n * emits `cmd invoke` with outcome + timing, swallowing any telemetry error\n * so it never surfaces to the tool caller. We look up the emitter lazily at\n * call time so wrapping can happen before the emitter is created.\n */\nfunction wrapRegisteredToolsWithTelemetry(server: McpServer): void {\n const internal = server as unknown as {\n _registeredTools: RegisteredToolsRecord;\n };\n const tools = internal._registeredTools;\n if (!tools) return;\n for (const [toolName, tool] of Object.entries(tools)) {\n const original = tool.handler;\n tool.handler = async (...args: unknown[]): Promise<unknown> => {\n const start = Date.now();\n try {\n const result = await original(...args);\n const emitter = currentEmitter;\n if (emitter) {\n emitter\n .emitInvoke(toolName, 'success', Date.now() - start)\n .catch(() => {});\n }\n return result;\n } catch (err) {\n const emitter = currentEmitter;\n if (emitter) {\n emitter\n .emitInvoke(toolName, 'error', Date.now() - start)\n .catch(() => {});\n }\n throw err;\n }\n };\n }\n}\n\nexport function createWalkerOSMcpServer(opts: CreateServerOptions): McpServer {\n const packageVersion = opts.version ?? '0.0.0';\n const runtime = opts.runtime ?? createHostedRuntime(opts.client);\n const server = new McpServer(\n {\n name: 'walkeros-flow',\n version: packageVersion,\n },\n { instructions: SERVER_INSTRUCTIONS },\n );\n\n registerAuthTool(server, opts.client);\n registerProjectManageTool(server, opts.client);\n registerFlowManageTool(server, opts.client);\n registerDeployTool(server, opts.client);\n registerSecretManageTool(server, opts.client);\n registerObserveSessionTool(server, opts.client);\n registerObserveJourneysTool(server, opts.client);\n registerHubManageTool(server, opts.client);\n registerFrameManageTool(server, opts.client);\n registerFeedbackTool(server, opts.client);\n registerDiagnosticsTool(server, opts.client, packageVersion);\n\n registerFlowValidateTool(server, runtime);\n registerFlowBundleTool(server, opts.client, runtime);\n registerFlowSimulateTool(server, opts.client, runtime);\n registerFlowPushTool(server, runtime);\n registerFlowExamplesTool(server, runtime);\n registerFlowLoadTool(server, opts.client, runtime);\n\n registerPackageSearchTool(server);\n registerGetPackageSchemaTool(server);\n\n registerPackageSchemaResources(server);\n registerReferenceResources(server, opts.client);\n registerAddStepPrompt(server);\n registerSetupMappingPrompt(server);\n registerManageContractPrompt(server);\n\n wrapRegisteredToolsWithTelemetry(server);\n\n // MCP SDK fires `oninitialized` after the `initialized` notification, which\n // follows a successful `initialize` request. At that point `getClientVersion`\n // returns the negotiated client identity. We create the emitter here and\n // emit `mcp start`, so consent, debug, and endpoint resolution happen lazily\n // at the moment a real client connects.\n const priorOnInitialized = server.server.oninitialized;\n server.server.oninitialized = () => {\n try {\n priorOnInitialized?.();\n } catch {\n // existing handler must not prevent telemetry setup\n }\n const clientInfo = server.server.getClientVersion();\n void createMcpEmitter({\n clientInfo,\n packageVersion,\n })\n .then(async (emitter) => {\n currentEmitter = emitter;\n await emitter.emitStart();\n })\n .catch(() => {\n // telemetry must never break the server; swallow setup/emit errors.\n });\n };\n\n return server;\n}\n","import { validate } from '@walkeros/cli';\nimport type { ValidateResult } from '@walkeros/cli';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { ValidateOutputShape } from '../schemas/output.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport {\n HINT_OUT_OF_PROCESS,\n refusalHint,\n RuntimeRefusal,\n type FlowRuntime,\n} from '../runtime/types.js';\nimport { isCloudId } from '../cloud-flow.js';\n\ntype ValidateType = 'contract' | 'event' | 'flow' | 'mapping';\n\n/**\n * Resolve the validate input through the runtime. For `type: 'event'`, a bare\n * string the runtime cannot resolve is the event-name shorthand and becomes\n * `{ name }`; the shorthand reads nothing, so it holds under every runtime.\n * Every other failure surfaces: a `RuntimeRefusal` (a policy decision), a\n * failed saved-id lookup, and any load error for a flow, mapping or contract.\n */\nasync function loadValidateInput(\n runtime: FlowRuntime,\n input: string,\n type: ValidateType,\n): Promise<unknown> {\n if (!input || input.trim() === '') throw new Error(`${type} is required`);\n const trimmed = input.trim();\n const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');\n try {\n return await runtime.load(input);\n } catch (error) {\n if (error instanceof RuntimeRefusal || isCloudId(trimmed)) throw error;\n if (looksLikeJson) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse ${type}. ${message}`);\n }\n if (type === 'event') return { name: trimmed };\n throw error;\n }\n}\n\nconst TITLE = 'Validate Flow';\nconst DESCRIPTION =\n 'Validate walkerOS events, flow configurations, mapping rules, or data contracts. ' +\n '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. ' +\n \"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). \" +\n 'flow and path narrow the run; strict turns warnings and skips into failures: valid is false. ' +\n '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).';\n\nconst inputSchema = schemas.ValidateInputShape;\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createFlowValidateToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_validate',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowValidateHandlerBody(runtime, input),\n };\n}\n\nasync function flowValidateHandlerBody(runtime: FlowRuntime, input: unknown) {\n const parsed = schemas.ValidateInputSchema.safeParse(input ?? {});\n if (!parsed.success) {\n return mcpError(parsed.error, 'Check the flow_validate input fields');\n }\n const {\n type,\n input: validateInput,\n flow,\n path,\n strict,\n offline,\n } = parsed.data;\n try {\n // Resolve the input through the runtime and validate the parsed document.\n // Handed a string, the cli `validate` would read files and URLs itself;\n // handing it the parsed object keeps every read behind the runtime.\n const resolved = await loadValidateInput(runtime, validateInput, type);\n const configDir = runtime.baseDir?.(validateInput);\n const result: ValidateResult = await validate(type, resolved, {\n flow,\n path,\n strict,\n offline,\n ...(configDir ? { configDir } : {}),\n });\n\n const skipped = result.details.skipped ?? [];\n const next = runtime.simulate\n ? ['Use flow_simulate to test event flow', 'Use flow_bundle to build']\n : [HINT_OUT_OF_PROCESS];\n const hints =\n !result.valid && result.errors.length === 0\n ? {\n next: [\n `strict: ${result.warnings.length} warning(s) and ${skipped.length} skipped check(s) count as failures; resolve them, or run without strict`,\n ],\n }\n : !result.valid\n ? {\n next: [\n 'Fix errors above, then run flow_validate again',\n 'Read walkeros://reference/flow-schema for correct structure',\n ],\n }\n : skipped.length > 0\n ? {\n next: [\n `Valid in checked scope; ${skipped.length} check(s) skipped, see details.skipped`,\n ...next,\n ],\n }\n : { next };\n // Validation `message` and `path` are tool-generated, not echoed user\n // input — both stay literal, never wrapped in <user_data>.\n return mcpResult(result, hints);\n } catch (error) {\n return mcpError(\n error,\n refusalHint(\n error,\n 'Check the input parameter — expected a JSON string, file path, or URL',\n ),\n );\n }\n}\n\nexport function registerFlowValidateTool(\n server: McpServer,\n runtime: FlowRuntime,\n) {\n const spec = createFlowValidateToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: ValidateOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowValidateHandlerBody(runtime, args),\n );\n}\n","import { z } from 'zod';\n\n// CLI tool output shapes\nconst ValidateIssueFields = {\n path: z.string(),\n message: z.string(),\n value: z.unknown().optional(),\n code: z\n .string()\n .optional()\n .describe('Stable code (the documented validate code list)'),\n keyword: z\n .string()\n .optional()\n .describe('JSON Schema keyword of an ENTRY_SCHEMA finding'),\n};\n\nexport const ValidateOutputShape = {\n valid: z.boolean().describe('Whether validation passed'),\n type: z\n .union([\n z.enum(['contract', 'entry', 'event', 'flow', 'mapping']),\n z.string().regex(/^(destinations|sources|transformers)\\.\\w+$/),\n ])\n .describe('What was validated'),\n errors: z.array(z.object(ValidateIssueFields)).describe('Validation errors'),\n warnings: z\n .array(\n z.object({\n ...ValidateIssueFields,\n suggestion: z.string().optional(),\n }),\n )\n .describe('Validation warnings'),\n details: z\n .object({\n scope: z\n .object({\n flows: z.array(z.string()),\n entry: z\n .object({\n section: z.string().optional(),\n key: z.string(),\n flows: z.array(z.string()),\n searchedFlows: z.array(z.string()),\n })\n .optional(),\n checks: z.array(z.string()),\n offline: z.literal(true).optional(),\n })\n .optional()\n .describe('What the run covered'),\n skipped: z\n .array(\n z.object({\n path: z.string(),\n check: z.string(),\n reason: z.string(),\n code: z.string(),\n }),\n )\n .optional()\n .describe('Checks in scope that did not run, with the reason'),\n deferred: z\n .array(z.object({ path: z.string(), reference: z.string() }))\n .optional()\n .describe('Values known only at runtime, not schema-checked'),\n })\n .catchall(z.unknown())\n .describe('Additional validation details'),\n _hints: z\n .object({\n next: z.array(z.string()).optional(),\n warnings: z.array(z.string()).optional(),\n })\n .optional()\n .describe('Suggested next steps'),\n};\n\nexport const BundleOutputShape = {\n success: z.boolean().describe('Whether bundling succeeded'),\n totalSize: z.number().optional().describe('Total bundle size in bytes'),\n buildTime: z.number().optional().describe('Build time in milliseconds'),\n packages: z\n .array(\n z.object({\n name: z.string(),\n }),\n )\n .optional()\n .describe('Names of packages included in the bundle'),\n treeshakingEffective: z\n .boolean()\n .optional()\n .describe('Whether tree-shaking was effective'),\n message: z.string().optional().describe('Status message'),\n};\n\nexport const SimulateOutputShape = {\n success: z.boolean().describe('Whether simulation succeeded'),\n error: z.string().optional().describe('Error message if failed'),\n summary: z.string().describe('One-line result summary'),\n destinations: z\n .record(\n z.string(),\n z.object({\n received: z\n .boolean()\n .describe('Whether destination received the event'),\n calls: z.number().describe('Number of API calls made'),\n payload: z\n .unknown()\n .optional()\n .describe('All intercepted API calls (only when verbose: true)'),\n }),\n )\n .optional()\n .describe('Per-destination results'),\n capturedEvents: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe('Events captured by source simulation'),\n calls: z\n .array(z.unknown())\n .optional()\n .describe(\n 'Calls a simulated source made on its mock env (only when verbose: true)',\n ),\n skipped: z\n .object({\n reason: z.enum(['consent', 'pending']),\n required: z.record(z.string(), z.boolean()).optional(),\n granted: z.record(z.string(), z.boolean()).optional(),\n require: z.array(z.string()).optional(),\n })\n .optional()\n .describe(\n 'Why the destination sent nothing: a consent skip, or waiting for its require',\n ),\n duration: z.number().optional().describe('Simulation duration in ms'),\n};\n\nexport const PushOutputShape = {\n success: z.boolean().describe('Whether push succeeded'),\n elbResult: z.unknown().optional().describe('Push result from the collector'),\n duration: z.number().describe('Push duration in milliseconds'),\n error: z.string().optional().describe('Error message if push failed'),\n};\n\n// Examples List output shape\nexport const ExamplesListOutputShape = {\n flow: z.string().describe('Flow name'),\n count: z.number().describe('Number of examples found'),\n examples: z\n .array(\n z.object({\n step: z.string().describe('Step location (e.g., \"destination.gtag\")'),\n stepType: z\n .enum(['source', 'transformer', 'destination'])\n .describe('Step type'),\n stepName: z.string().describe('Step name'),\n exampleName: z.string().describe('Example name'),\n source: z\n .enum(['inline', 'package'])\n .describe(\n 'Where the example came from: \"inline\" (defined in the flow step) or \"package\" (shipped by the referenced package)',\n ),\n title: z.string().optional().describe('Human-readable title if set'),\n description: z\n .string()\n .optional()\n .describe('Short human-readable description'),\n public: z\n .boolean()\n .optional()\n .describe(\n 'Whether the example is public (defaults to true if omitted)',\n ),\n hasIn: z.boolean().describe('Whether the example has an input value'),\n hasOut: z.boolean().describe('Whether the example has an output value'),\n hasMapping: z\n .boolean()\n .describe('Whether the example has a mapping configuration'),\n hasTrigger: z\n .boolean()\n .describe('Whether the example has trigger metadata'),\n in: z.unknown().optional().describe('Input event data'),\n out: z.unknown().optional().describe('Expected output data'),\n mapping: z\n .unknown()\n .optional()\n .describe('Mapping configuration for destinations'),\n trigger: z\n .object({\n type: z.string().optional(),\n options: z.unknown().optional(),\n })\n .optional()\n .describe('Trigger metadata for source simulation'),\n }),\n )\n .describe('Step examples'),\n};\n","import type { Flow, Ingest, Simulation, WalkerOS } from '@walkeros/core';\nimport type { BundleStats, PushResult } from '@walkeros/cli';\n\n/**\n * The capability seam between the flow tools and the machine they run on.\n *\n * Every file read, URL fetch, bundle, simulation and push a tool performs goes\n * through a `FlowRuntime` and nothing else, so the runtime alone decides what\n * the process it lives in may do:\n *\n * - `createLocalRuntime()` keeps every capability. It is for the user's own\n * machine (stdio, the developer CLI), where the user is responsible for what\n * runs there.\n * - `createHostedRuntime(client)` is least privilege for a shared, network\n * reached process: it loads inline JSON and saved flow ids only, refuses\n * local paths and URLs, and has no `bundle`, `simulate` or `push` at all.\n *\n * A tool whose operation the runtime does not provide refuses with a hint that\n * names only out-of-process routes.\n */\nexport interface FlowRuntime {\n /**\n * Resolve a config input to parsed JSON. Local: a file path, an http(s) URL\n * or inline JSON. Hosted: inline JSON or a saved `flow_`/`cfg_` id; a local\n * path or URL is refused with a `RuntimeRefusal`.\n */\n load(input: string): Promise<unknown>;\n /**\n * The directory local `path` packages of a loaded input resolve against:\n * the input file's directory. Absent on a runtime without a filesystem,\n * where such packages stay a reported skip.\n */\n baseDir?(input: string): string | undefined;\n /** Compile a flow. Absent on a runtime that must not build in its process. */\n bundle?(input: string, opts: BundleOptions): Promise<BundleStats | void>;\n /** Build and run one step of a flow. Absent where that must not happen. */\n simulate?(input: string, opts: SimulateOptions): Promise<Simulation.Result>;\n /**\n * The values of the secrets a flow config references (`$secret.NAME`),\n * masked wherever a simulation or push result egresses. Read by the tools\n * only on a runtime without `loadRun`; a read that fails stops the run.\n */\n knownSecrets?(input: string): Promise<string[]>;\n /**\n * Read a push or simulate input once: the config and the values of the\n * secrets it references. A prebuilt bundle yields no config. A read that\n * fails rejects. Absent with `simulate` and `push`.\n */\n loadRun?(input: string): Promise<LoadedRun>;\n /** Build and run a flow against real destinations. Absent where forbidden. */\n push?(\n input: string,\n event: Record<string, unknown>,\n opts: PushOptions,\n ): Promise<PushResult>;\n}\n\nexport interface BundleOptions {\n flowName?: string;\n stats?: boolean;\n output?: string;\n}\n\nexport type SimulateStepType =\n | 'source'\n | 'transformer'\n | 'collector'\n | 'destination';\n\nexport interface SimulateOptions {\n stepType: SimulateStepType;\n stepId: string;\n event: unknown;\n flow?: string;\n /** The config from `loadRun`: the runtime does not read the input again. */\n config?: Flow.Json;\n /**\n * Transformer, collector and destination steps: pipeline context the step\n * reads via `ctx.ingest`. Source steps ignore it.\n */\n ingest?: Omit<Ingest, '_meta'>;\n /**\n * Collector state the step starts from. `consent` applies to every step\n * (the collector's starting consent); `user`, `globals` and `timing` to\n * collector steps only.\n */\n state?: {\n consent?: WalkerOS.Consent;\n user?: WalkerOS.User;\n globals?: WalkerOS.Properties;\n timing?: number;\n };\n /**\n * Destination steps only: run this collector command with `event` as its\n * data instead of pushing it (a step example with `command`).\n */\n command?: Flow.StepCommand;\n}\n\n/** A push or simulate input as read once by `loadRun`. */\nexport interface LoadedRun {\n config?: Flow.Json;\n knownSecrets: string[];\n}\n\nexport interface PushOptions {\n flow?: string;\n platform?: 'web' | 'server';\n /** The config from `loadRun`: the runtime does not read the input again. */\n config?: Flow.Json;\n}\n\n/**\n * Thrown by a runtime when it refuses an input on principle rather than on a\n * fault. Carries the hint a tool should surface next to the message.\n */\nexport class RuntimeRefusal extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n super(message);\n this.name = 'RuntimeRefusal';\n this.hint = hint;\n }\n}\n\n/** The hint for a refused runtime error, or a tool's own fallback otherwise. */\nexport function refusalHint(error: unknown, fallback: string): string {\n return error instanceof RuntimeRefusal ? error.hint : fallback;\n}\n\n/**\n * Every route named here runs outside the tool's process: the app's own deploy\n * pipeline, or the caller's own machine. A refused\n * caller is never pointed at another in-process route, such as saving the\n * flow and simulating it by id, which would be the same execution one step\n * later.\n */\nexport const HINT_OUT_OF_PROCESS =\n 'Build and deploy through the app with deploy_manage. To simulate, validate or bundle, use the walkerOS CLI on your own machine.';\n\n/** The refusal a tool raises when its runtime does not provide an operation. */\nexport function unavailableOperation(\n operation: 'bundle' | 'simulate' | 'push',\n): RuntimeRefusal {\n const verb =\n operation === 'bundle'\n ? 'Bundling'\n : operation === 'simulate'\n ? 'Simulating'\n : 'Running';\n return new RuntimeRefusal(\n `${verb} a flow is not available on the hosted walkerOS MCP server.`,\n HINT_OUT_OF_PROCESS,\n );\n}\n","import { isObject, type WalkerOS } from '@walkeros/core';\n\n/**\n * Saved flow references, shared by every place that recognises or reads one.\n *\n * `flow_` and `cfg_` are the reserved cloud flow/config id namespaces. The\n * pattern is anchored and limited to id characters, so a path that merely\n * starts with a prefix (`flow_../x`) is never mistaken for an id.\n */\nexport const CLOUD_ID_PATTERN = /^(flow|cfg)_[A-Za-z0-9_-]+$/;\n\nexport function isCloudId(input: string): boolean {\n return CLOUD_ID_PATTERN.test(input);\n}\n\n/**\n * The config of a flow record returned by the tool client, or `{}` when the\n * record carries none. The client seam returns an opaque shape, so this is the\n * one narrowing every reader shares.\n */\nexport function flowConfigOf(flow: unknown): WalkerOS.AnyObject {\n return isObject(flow) && isObject(flow.config) ? flow.config : {};\n}\n","import { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { BundleOutputShape } from '../schemas/output.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { resolveConfigPath } from './resolve-config-path.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n} from '../runtime/types.js';\n\nconst TITLE = 'Bundle Flow';\nconst DESCRIPTION =\n 'Bundle a walkerOS flow configuration into deployable JavaScript. ' +\n 'Resolves all destinations, sources, and transformers, then outputs ' +\n 'a tree-shaken production bundle. Returns bundle statistics.';\n\nconst inputSchema = {\n ...schemas.BundleInputShape,\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowBundleToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_bundle',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowBundleHandlerBody(client, runtime, input),\n };\n}\n\nasync function flowBundleHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, flow, stats, output } = parsed.data;\n // Bundling compiles the config and resolves every package it names. A\n // runtime that must not do that in its process provides no `bundle`.\n if (!runtime.bundle) {\n const refusal = unavailableOperation('bundle');\n return mcpError(refusal, refusal.hint);\n }\n try {\n // Accept a cloud flow/config id as configPath, resolving it to inline JSON.\n const resolvedConfigPath = await resolveConfigPath(client, configPath);\n const result = await runtime.bundle(resolvedConfigPath, {\n flowName: flow,\n stats: stats ?? true,\n output,\n });\n\n if (!result) {\n return mcpResult(\n { success: false, message: 'Bundle produced no output' },\n {\n warnings: [\n 'The build returned no result. The flow may be empty or misconfigured.',\n ],\n next: ['Run flow_validate to check your configuration'],\n },\n );\n }\n\n return mcpResult(\n { success: true, ...result },\n {\n next: [\n 'Use flow_simulate to test',\n 'Use deploy_manage with action \"deploy\" to publish',\n ],\n },\n );\n } catch (error) {\n return mcpError(\n error,\n refusalHint(error, 'Run flow_validate for detailed error messages'),\n );\n }\n}\n\nexport function registerFlowBundleTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowBundleToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: BundleOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowBundleHandlerBody(client, runtime, args),\n );\n}\n","import { z, type ZodRawShape } from 'zod';\nimport { mcpError } from '@walkeros/core';\n\n/** A tool's input as its input shape parses it, defaults applied. */\nexport type ToolInput<S extends ZodRawShape> = z.output<z.ZodObject<S>>;\n\n/**\n * Every issue as one readable line, `path: message; ...`. A raw ZodError\n * stringifies its whole issue list into `message`, so it is never passed on\n * as is.\n */\nexport function inputIssuesMessage(error: z.ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.join('.') || 'input'}: ${issue.message}`)\n .join('; ');\n}\n\n/**\n * Parse, never assert: a tool spec is drivable without a transport, so its\n * handler applies the same input shape the transport validates against.\n * Input that fails it comes back as an error result.\n */\nexport function parseToolInput<S extends ZodRawShape>(\n shape: S,\n raw: unknown,\n):\n | { ok: true; data: ToolInput<S> }\n | { ok: false; error: ReturnType<typeof mcpError> } {\n const parsed = z.object(shape).safeParse(raw ?? {});\n if (!parsed.success) {\n return {\n ok: false,\n error: mcpError(new Error(inputIssuesMessage(parsed.error))),\n };\n }\n return { ok: true, data: parsed.data };\n}\n","import type { ToolClient } from '../tool-client.js';\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\n\n/**\n * Resolve a `configPath` for tools that consume it (simulate, bundle). When it\n * is a cloud flow/config id, fetch the flow via the same client seam `flow_load`\n * uses and return its config serialized as JSON (the underlying CLI functions\n * accept inline JSON as `configPath`). Otherwise return the value unchanged so\n * file paths, URLs, and inline JSON pass through as before.\n */\nexport async function resolveConfigPath(\n client: Pick<ToolClient, 'getFlow'>,\n configPath: string,\n): Promise<string> {\n if (!isCloudId(configPath)) return configPath;\n\n const flow = await client.getFlow({ flowId: configPath });\n return JSON.stringify(flowConfigOf(flow));\n}\n","import { z } from 'zod';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { filterValues, mcpResult, mcpError } from '@walkeros/core';\nimport type { Flow, Ingest, Simulation, WalkerOS } from '@walkeros/core';\nimport { SimulateOutputShape } from '../schemas/output.js';\nimport { FLOW_SIMULATE_DESCRIPTION } from './simulate-description.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { resolveConfigPath } from './resolve-config-path.js';\nimport { readRun, scrubbed, scrubbedError } from './egress.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n type SimulateStepType,\n} from '../runtime/types.js';\n\ninterface DestinationSummary {\n received: boolean;\n calls: number;\n payload?: unknown;\n}\n\nconst STEP_TYPES: readonly SimulateStepType[] = [\n 'source',\n 'transformer',\n 'collector',\n 'destination',\n];\n\nfunction isStepType(value: string): value is SimulateStepType {\n return STEP_TYPES.some((t) => t === value);\n}\n\nconst TITLE = 'Simulate Flow';\nconst COMMANDS: readonly [Flow.StepCommand, ...Flow.StepCommand[]] = [\n 'config',\n 'consent',\n 'user',\n 'run',\n];\n\nconst inputSchema = {\n configPath: schemas.SimulateInputShape.configPath,\n event: z\n .union([z.record(z.string(), z.unknown()), z.string()])\n .optional()\n .describe(\n \"For destinations: { name, data, consent? }; the event's consent counts \" +\n \"toward the destination's consent requirement, on top of state.consent. \" +\n \"With command: the command's data, e.g. { marketing: true } for consent. \" +\n 'For sources: { content, trigger? } where content is the walkerOS event ' +\n \"{ name, data }. A web source's page URL goes in trigger.options.url \" +\n '(default http://localhost). ' +\n 'Can also be a JSON string or file path.',\n ),\n flow: schemas.SimulateInputShape.flow,\n platform: schemas.SimulateInputShape.platform,\n // Override the (optional) CLI `step` shape: the simulate handler hard-requires\n // a target step (no all-steps mode), so the registered schema must be honest.\n step: z\n .string()\n .describe(\n 'Required. Target step as \"type.name\", e.g. \"source.demo\", \"collector.default\", \"destination.gtag\", \"transformer.router\". ' +\n 'A collector step runs enrichment and then collector.next, returning every event the destinations would receive (none after a stop).',\n ),\n verbose: z\n .boolean()\n .optional()\n .describe('Include full payload per destination (default: false)'),\n ingest: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\n 'Pipeline context a step reads via ctx.ingest, e.g. { url } for a ' +\n 'request decoder or { ip, userAgent } for a conversion API. Used for ' +\n 'transformer, collector and destination steps (their before chains ' +\n 'included); _meta is always set by the runtime.',\n ),\n state: z\n .object({\n consent: z.record(z.string(), z.boolean()).optional(),\n user: z.record(z.string(), z.unknown()).optional(),\n globals: z.record(z.string(), z.unknown()).optional(),\n timing: z.number().optional(),\n })\n .optional()\n .describe(\n 'Collector state the step starts from. consent: every step (starts a ' +\n 'destination that requires consent and feeds its consent check; for a ' +\n 'source, the consent a consent-gated source waits for). ' +\n 'user/globals/timing: collector steps, seeded before enrichment runs.',\n ),\n command: z\n .enum(COMMANDS)\n .optional()\n .describe(\n 'Destination steps only: run this collector command with event as its ' +\n 'data instead of pushing it, as a step example with command does.',\n ),\n};\n\nconst annotations = {\n // Simulation downloads the packages a config names and runs caller-controlled\n // flow code in process. Destinations are mocked, but that code is not, so the\n // hints stay conservative: side effects possible, repeat calls not assumed\n // safe, external systems reachable.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowSimulateToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_simulate',\n title: TITLE,\n description: FLOW_SIMULATE_DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowSimulateHandlerBody(client, runtime, input),\n };\n}\n\n/** Plain values kept as walkerOS properties; values no property can hold dropped. */\nfunction toProperties(\n value: Record<string, unknown> | undefined,\n): WalkerOS.Properties | undefined {\n if (!value) return undefined;\n const properties: WalkerOS.Properties = {};\n for (const [key, entry] of Object.entries(value)) {\n const property = filterValues(entry);\n if (property !== undefined) properties[key] = property;\n }\n return properties;\n}\n\nasync function flowSimulateHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n configPath,\n event,\n flow,\n platform,\n step,\n verbose,\n ingest,\n state,\n command,\n } = parsed.data;\n // Simulation compiles the config and imports the bundle, running caller\n // controlled flow code. A runtime that must not do that in its process\n // provides no `simulate`, whatever the input looks like.\n if (!runtime.simulate) {\n const refusal = unavailableOperation('simulate');\n return mcpError(refusal, refusal.hint);\n }\n let known: string[] = [];\n try {\n if (!event) {\n throw new Error(\n 'event is required. For sources provide { content, trigger? }, for destinations provide { name, data }.',\n );\n }\n\n if (!step) {\n throw new Error(\n 'step is required. Specify a target like \"source.browser\", \"destination.gtag\", or \"transformer.demo\".',\n );\n }\n\n // Resolve string event input (JSON string)\n let resolvedEvent: unknown = event;\n if (typeof event === 'string') {\n try {\n resolvedEvent = JSON.parse(event);\n } catch {\n throw new Error(\n 'Event string must be valid JSON. Got: ' + event.substring(0, 50),\n );\n }\n }\n\n // Parse step into type and id\n const dotIndex = step.indexOf('.');\n if (dotIndex === -1) {\n throw new Error(\n `Invalid step format \"${step}\". Use \"type.name\" (e.g. \"source.browser\", \"destination.gtag\").`,\n );\n }\n const stepType = step.substring(0, dotIndex);\n const stepId = step.substring(dotIndex + 1);\n\n if (!isStepType(stepType)) {\n throw new Error(\n `Unknown step type \"${stepType}\". Use \"source\", \"collector\", \"transformer\", or \"destination\".`,\n );\n }\n\n if (command !== undefined && stepType !== 'destination') {\n throw new Error('command applies to destination steps only.');\n }\n\n // Accept a cloud flow/config id as configPath, resolving it to inline JSON.\n const resolvedConfigPath = await resolveConfigPath(client, configPath);\n // Read once: the simulation runs on exactly the config whose secrets\n // mask the result.\n const run = await readRun(runtime, resolvedConfigPath);\n known = run.knownSecrets;\n\n const result: Simulation.Result = await runtime.simulate(\n resolvedConfigPath,\n {\n stepType,\n stepId,\n event: resolvedEvent,\n flow,\n ingest,\n state: state && {\n consent: state.consent,\n user: toProperties(state.user),\n globals: toProperties(state.globals),\n timing: state.timing,\n },\n command,\n config: run.config,\n },\n );\n\n const success = !result.error;\n const errorMessage = result.error?.message;\n\n // Source simulation: captured events are result.events, the source's\n // own walker commands its `elb` calls. Mock-env calls stay verbose-only.\n if (result.step === 'source') {\n const eventCount = result.events.length;\n const commandCount = result.calls.filter(\n (call) => call.fn === 'elb',\n ).length;\n const summary =\n `Source captured ${eventCount} event${eventCount !== 1 ? 's' : ''}` +\n ` and ${commandCount} command${commandCount !== 1 ? 's' : ''}`;\n const shownCalls = verbose\n ? result.calls\n : result.calls.filter((call) => call.fn === 'elb');\n\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary,\n capturedEvents: result.events,\n ...(shownCalls.length > 0 ? { calls: shownCalls } : {}),\n duration: result.duration,\n },\n known,\n ),\n {\n next:\n eventCount + commandCount > 0\n ? [\n 'Use flow_simulate with a destination step to test downstream processing',\n ]\n : [\n 'Check source package examples with package_get, verify trigger type matches',\n ],\n },\n );\n }\n\n // Transformer simulation: surface the transformed events\n if (result.step === 'transformer') {\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary: `Transformer processed event`,\n capturedEvents: result.events,\n duration: result.duration,\n },\n known,\n ),\n {\n next: ['Use flow_bundle to build for production'],\n },\n );\n }\n\n // Collector simulation: surface the enriched event\n if (result.step === 'collector') {\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary: `Collector enriched event`,\n capturedEvents: result.events,\n duration: result.duration,\n },\n known,\n ),\n {\n next: ['Use flow_simulate with a destination step to test delivery'],\n },\n );\n }\n\n // Destination simulation: count intercepted env calls, key by step name\n const destinations: Record<string, DestinationSummary> = {};\n const callCount = result.calls.length;\n const destSummary: DestinationSummary = {\n received: callCount > 0,\n calls: callCount,\n };\n if (verbose && callCount > 0) {\n destSummary.payload = result.calls;\n }\n destinations[result.name] = destSummary;\n\n const destCount = Object.keys(destinations).length;\n const receivedCount = Object.values(destinations).filter(\n (d) => d.received,\n ).length;\n\n const warnings: string[] = [];\n if (receivedCount === 0 && success) warnings.push(notReceived(result));\n\n const resultObj = {\n success,\n error: errorMessage,\n summary: `${receivedCount}/${destCount} destinations received the event`,\n destinations,\n ...(result.skipped ? { skipped: result.skipped } : {}),\n duration: result.duration,\n };\n\n return mcpResult(scrubbed(resultObj, known), {\n next: ['Use flow_bundle to build for production'],\n ...(warnings.length > 0 ? { warnings } : {}),\n });\n } catch (error) {\n const hint = 'Run flow_validate for detailed error messages';\n return scrubbedError(mcpError(error, refusalHint(error, hint)), known);\n }\n}\n\nfunction keysOf(consent: WalkerOS.Consent | undefined): string {\n const keys = Object.entries(consent ?? {})\n .filter(([, granted]) => granted)\n .map(([key]) => key);\n return keys.length > 0 ? keys.join(', ') : 'none';\n}\n\n/** Why a destination received nothing, from the result's own `skipped`. */\nfunction notReceived(result: Simulation.Result): string {\n const { skipped } = result;\n if (skipped?.reason === 'pending') {\n const require = skipped.require ?? [];\n const waits = require.length ? require.join(', ') : 'its require';\n const advice = require.includes('consent')\n ? 'pass state.consent (e.g. { functional: true }) to start it.'\n : `it starts once the flow provides ${waits}; a simulation cannot seed that.`;\n return `Destination waits for ${waits} (require) and never started: ${advice}`;\n }\n if (skipped?.reason === 'consent') {\n return (\n `Consent skip: requires ${keysOf(skipped.required)}; granted ${keysOf(skipped.granted)}. ` +\n \"Grant it in state.consent or in the event's consent.\"\n );\n }\n return (\n 'Destination made no calls. Common causes: ' +\n '(1) mapping rules do not match the event name or ignore it, ' +\n '(2) policy redacted required fields, ' +\n '(3) a before chain stopped the event.'\n );\n}\n\nexport function registerFlowSimulateTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowSimulateToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: SimulateOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowSimulateHandlerBody(client, runtime, args),\n );\n}\n","/**\n * The flow_simulate tool description, shared by the registered tool and the\n * declarative `TOOL_DEFINITIONS` registry (which must not import the tool's\n * node-only code).\n */\nexport const FLOW_SIMULATE_DESCRIPTION =\n 'Simulate events through a walkerOS flow without making real API calls. ' +\n 'For destinations: event is a walkerOS event { name: \"entity action\", data: {...} }. ' +\n 'For sources: event is { content, trigger?: { type?, options? } }, where content is the ' +\n 'walkerOS event { name: \"entity action\", data: {...} }. Only the simulated source starts. ' +\n 'step (required) targets the step to simulate, e.g. \"destination.gtag\". ' +\n 'Use flow_examples to discover available test data. ' +\n 'A destination simulation starts only its target destination. ' +\n \"A source's own walker commands (e.g. a CMP's walker consent) are returned as elb calls. \" +\n 'Consent: state.consent is the collector consent the step starts from ' +\n '(any step; a consent-gated source such as the session source waits for it). A destination with ' +\n 'require: [\"consent\"] waits until consent is present, so pass state.consent to start it; ' +\n 'a destination with consent: { marketing: true } receives an event only when that ' +\n \"consent is granted in state.consent or in the event's own consent. \" +\n 'When a destination sends nothing, the result says why (waiting for its require, or a consent skip). ' +\n 'command runs a step example with command (e.g. \"consent\") on a destination: ' +\n \"event is the command's data, state.consent still applies first. \" +\n 'Mapping transforms event names and data at the destination level. ' +\n 'Policy redacts or injects fields before mapping runs.';\n","import type { PushResult } from '@walkeros/cli';\nimport { isObject, mcpError, mcpResult } from '@walkeros/core';\nimport { scrubJson, scrubSecrets } from '@walkeros/core/node';\nimport type { FlowRuntime, LoadedRun } from '../runtime/types.js';\n\n/**\n * Simulate and push results carry recorded vendor calls, network requests and\n * vendor responses whose values can hold credentials. They egress like a log\n * line: `scrubJson` (masking the values of the secrets the flow references,\n * `known`, and credential patterns), then parse back into the structured\n * result.\n */\nexport function scrubbed(\n result: Record<string, unknown>,\n known: readonly string[],\n): Record<string, unknown> {\n const parsed = parseObject(scrubJson(result, { known }));\n if (!parsed) throw new Error('Result could not be redacted as JSON.');\n return parsed;\n}\n\n/** An error response as built by `mcpError`; a stub may lack the structured copy. */\ntype ErrorResponse = Omit<ReturnType<typeof mcpError>, 'structuredContent'> & {\n structuredContent?: Record<string, unknown>;\n};\n\n/**\n * The error response egresses the same way: its structured copy is scrubbed,\n * and the text is that copy serialized (as `mcpError` builds it), so it stays\n * valid JSON. Without a structured copy that scrubs, each text part is\n * scrubbed as a line instead, so the error message is never lost.\n */\nexport function scrubbedError(\n response: ErrorResponse,\n known: readonly string[],\n): ReturnType<typeof mcpError> {\n let structuredContent: Record<string, unknown> | undefined;\n try {\n if (response.structuredContent)\n structuredContent = scrubbed(response.structuredContent, known);\n } catch {\n structuredContent = undefined;\n }\n if (structuredContent) {\n return {\n ...response,\n content: [{ type: 'text', text: JSON.stringify(structuredContent) }],\n structuredContent,\n };\n }\n return {\n ...response,\n content: response.content.map((part) => ({\n ...part,\n text: scrubSecrets(part.text, { known }),\n })),\n structuredContent: { error: 'The error could not be redacted.' },\n };\n}\n\n/**\n * A push result as it egresses: scrubbed and parsed back. `success` and\n * `duration` come from the CLI, never from a vendor, and stay as they are so\n * the output schema always holds. A push already happened, so this never\n * throws: if the scrubbed text does not parse, the text alone carries the\n * result and the structured copy keeps the scalars.\n */\nexport function scrubbedPushResult(\n result: PushResult,\n known: readonly string[],\n): ReturnType<typeof mcpResult> {\n const text = scrubJson(result, { known, space: 2 });\n const parsed = parseObject(text);\n if (parsed)\n return mcpResult({\n ...parsed,\n success: result.success,\n duration: result.duration,\n });\n return {\n content: [{ type: 'text', text }],\n structuredContent: { success: result.success, duration: result.duration },\n };\n}\n\nfunction parseObject(text: string): Record<string, unknown> | undefined {\n try {\n const parsed: unknown = JSON.parse(text);\n return isObject(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The run input read once: `loadRun`, else, on a runtime without it, the\n * values its `knownSecrets` returns. A failed read rejects, so the caller\n * stops instead of egressing with pattern masking only.\n */\nexport async function readRun(\n runtime: FlowRuntime,\n input: string,\n): Promise<LoadedRun> {\n if (runtime.loadRun) return runtime.loadRun(input);\n return {\n knownSecrets: runtime.knownSecrets ? await runtime.knownSecrets(input) : [],\n };\n}\n","import { z } from 'zod';\nimport type { PushResult } from '@walkeros/cli';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { mcpError } from '@walkeros/core';\nimport { PushOutputShape } from '../schemas/output.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { readRun, scrubbedError, scrubbedPushResult } from './egress.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n} from '../runtime/types.js';\n\nconst TITLE = 'Push Events';\nconst DESCRIPTION =\n 'Push a real event through a walkerOS flow to actual destinations. ' +\n 'Makes real API calls to real endpoints. ' +\n 'Best suited for server-side flows — web flows should use flow_simulate for testing.';\n\nconst inputSchema = {\n configPath: schemas.PushInputShape.configPath,\n event: z\n .record(z.string(), z.unknown())\n .describe(\n 'Event object, e.g. { name: \"page view\", data: { title: \"Home\" } }',\n ),\n flow: schemas.PushInputShape.flow,\n platform: schemas.PushInputShape.platform,\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowPushToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_push',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowPushHandlerBody(runtime, input),\n };\n}\n\nasync function flowPushHandlerBody(\n runtime: FlowRuntime,\n input: unknown,\n): Promise<CallToolResult> {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, event, flow, platform } = parsed.data;\n // Push compiles the config, imports it, and makes real outbound calls. A\n // runtime that must not do that in its process provides no `push`.\n if (!runtime.push) {\n const refusal = unavailableOperation('push');\n return mcpError(refusal, refusal.hint);\n }\n // Push results can carry vendor requests and responses: they egress with\n // the flow's secret values and credential patterns masked. The config is\n // read once, so the push runs on exactly the config whose secrets mask the\n // result; a config that cannot be read stops the push.\n let known: string[] = [];\n try {\n const run = await readRun(runtime, configPath);\n known = run.knownSecrets;\n const result: PushResult = await runtime.push(configPath, event, {\n flow,\n platform,\n config: run.config,\n });\n\n if (!result.success) {\n return scrubbedError(\n mcpError(\n new Error(result.error || 'Push failed'),\n 'Check destination configuration and connectivity.',\n ),\n known,\n );\n }\n\n return scrubbedPushResult(result, known);\n } catch (error) {\n return scrubbedError(\n mcpError(\n error,\n refusalHint(\n error,\n 'Check configPath and event format. For web flows, use flow_simulate.',\n ),\n ),\n known,\n );\n }\n}\n\nexport function registerFlowPushTool(server: McpServer, runtime: FlowRuntime) {\n const spec = createFlowPushToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: PushOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowPushHandlerBody(runtime, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackage, mcpResult, mcpError } from '@walkeros/core';\nimport type { Flow, WalkerOSPackage } from '@walkeros/core';\nimport { resolveExportName, selectDevExamples } from '@walkeros/cli';\nimport { ExamplesListOutputShape } from '../schemas/output.js';\nimport { getPackageBaseUrl, CLIENT_HEADER } from '../catalog.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { isFlowJson, stepExamplesOf, type StepExampleView } from './narrow.js';\nimport {\n HINT_OUT_OF_PROCESS,\n refusalHint,\n type FlowRuntime,\n} from '../runtime/types.js';\n\n/** Upper bound on distinct package example lookups per call. */\nexport const MAX_PACKAGE_LOOKUPS = 25;\n\nconst TITLE = 'Flow Examples';\nconst DESCRIPTION =\n 'List all step examples in a walkerOS flow configuration. ' +\n 'Shows example names, step locations, and in/out shapes. ' +\n 'Inline examples on a step take precedence; steps without inline examples ' +\n 'fall back to the examples shipped by their referenced package. ' +\n 'Each result is tagged with its source (\"inline\" or \"package\"). ' +\n 'On the hosted server configPath accepts only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. ' +\n 'Use this to discover available test fixtures and simulation data.';\n\nconst inputSchema = {\n configPath: z\n .string()\n .min(1)\n .describe(\n 'Inline JSON string, file path, or URL of a flow configuration (hosted server: inline JSON or a saved flow id only)',\n ),\n flow: z.string().optional().describe('Flow name for multi-flow configs'),\n step: z\n .string()\n .optional()\n .describe('Filter to a specific step (e.g., \"destination.gtag\")'),\n full: z\n .boolean()\n .optional()\n .describe(\n 'Return full in/out/mapping data for each example (default: false, returns metadata only)',\n ),\n includeHidden: z\n .boolean()\n .optional()\n .describe(\n 'Include examples marked public: false (default: false). Set true for test/debug discovery.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n} as const;\n\nexport function createFlowExamplesToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_examples',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowExamplesHandlerBody(runtime, input),\n };\n}\n\nasync function flowExamplesHandlerBody(runtime: FlowRuntime, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, flow, step, full, includeHidden } = parsed.data;\n try {\n const rawConfig = await runtime.load(configPath);\n if (!isFlowJson(rawConfig)) {\n throw new Error('Config is not a flow config: it has no flows object.');\n }\n\n // Resolve flow name\n const flowNames = Object.keys(rawConfig.flows || {});\n const flowName =\n flow || (flowNames.length === 1 ? flowNames[0] : undefined);\n\n if (!flowName) {\n throw new Error(\n `Multiple flows found. Specify flow parameter. Available: ${flowNames.join(', ')}`,\n );\n }\n\n const flowSettings = rawConfig.flows[flowName];\n if (!flowSettings) {\n throw new Error(`Flow \"${flowName}\" not found`);\n }\n\n // Collect all examples\n type ExampleItem = {\n step: string;\n stepType: string;\n stepName: string;\n exampleName: string;\n source: 'inline' | 'package';\n title?: string;\n description?: string;\n public?: boolean;\n hasIn: boolean;\n hasOut: boolean;\n hasMapping: boolean;\n hasTrigger: boolean;\n in?: unknown;\n out?: unknown;\n mapping?: unknown;\n trigger?: unknown;\n };\n const examples: ExampleItem[] = [];\n\n const toItems = (\n stepExamples: Record<string, StepExampleView>,\n type: string,\n name: string,\n source: 'inline' | 'package',\n ): ExampleItem[] => {\n const items: ExampleItem[] = [];\n for (const [exName, ex] of Object.entries(stepExamples)) {\n if (!includeHidden && ex.public === false) continue;\n items.push({\n step: `${type}.${name}`,\n stepType: type,\n stepName: name,\n exampleName: exName,\n source,\n title: ex.title,\n description: ex.description,\n public: ex.public,\n hasIn: ex.in !== undefined,\n hasOut: ex.out !== undefined,\n hasMapping: ex.mapping !== undefined,\n hasTrigger: ex.trigger !== undefined,\n ...(full\n ? {\n in: ex.in,\n out: ex.out,\n mapping: ex.mapping,\n trigger: ex.trigger,\n }\n : {}),\n });\n }\n return items;\n };\n\n // Pull a referenced package's shipped examples via the same path\n // package_get uses. A failed fetch must not break the whole tool: the\n // step is skipped and inline examples from other steps still return.\n const baseUrl = getPackageBaseUrl();\n const loadPackage = async (\n packageName: string,\n ): Promise<WalkerOSPackage | undefined> => {\n try {\n return await fetchPackage(packageName, {\n baseUrl,\n client: CLIENT_HEADER,\n });\n } catch {\n // Swallow: graceful fallback skip for this package.\n }\n return undefined;\n };\n\n // One lookup per distinct package, capped per call, so a config naming\n // many packages cannot fan out into an unbounded number of fetches.\n const packageLookups = new Map<\n string,\n Promise<WalkerOSPackage | undefined>\n >();\n let skippedPackages = false;\n const skippedExamples: string[] = [];\n const packageFor = (\n packageName: string,\n ): Promise<WalkerOSPackage | undefined> => {\n const existing = packageLookups.get(packageName);\n if (existing) return existing;\n if (packageLookups.size >= MAX_PACKAGE_LOOKUPS) {\n skippedPackages = true;\n return Promise.resolve(undefined);\n }\n const lookup = loadPackage(packageName);\n packageLookups.set(packageName, lookup);\n return lookup;\n };\n\n // The step examples of the step's own export: a multi-export package\n // ships `exportExamples` keyed by export name, the same rule simulate\n // uses (an export missing from the map has no examples).\n const stepExamplesFor = (\n info: WalkerOSPackage,\n exportName: string | undefined,\n ): ReturnType<typeof stepExamplesOf> => {\n const selected = selectDevExamples(\n { examples: info.examples, exportExamples: info.exportExamples },\n exportName,\n );\n return stepExamplesOf(selected?.step);\n };\n\n const stepTypes = [\n { key: 'sources' as const, type: 'source' as const },\n { key: 'transformers' as const, type: 'transformer' as const },\n { key: 'destinations' as const, type: 'destination' as const },\n ];\n\n for (const { key, type } of stepTypes) {\n const refs = flowSettings[key] || {};\n for (const [name, ref] of Object.entries(refs)) {\n // Apply step filter\n if (step && `${type}.${name}` !== step) continue;\n\n // Inline examples take precedence over package-shipped ones.\n if (ref.examples) {\n examples.push(...toItems(ref.examples, type, name, 'inline'));\n continue;\n }\n\n // No inline examples: fall back to the referenced package's shipped\n // examples (only for refs that actually name a package).\n if (!ref.package) continue;\n const info = await packageFor(ref.package);\n if (!info) continue;\n const { exportName } = resolveExportName(flowSettings, type, name);\n const packageExamples = stepExamplesFor(info, exportName);\n if (!packageExamples) continue;\n examples.push(\n ...toItems(packageExamples.examples, type, name, 'package'),\n );\n for (const exampleName of packageExamples.skipped)\n skippedExamples.push(`${type}.${name}.${exampleName}`);\n }\n }\n\n const result = {\n flow: flowName,\n count: examples.length,\n examples,\n };\n\n const warnings: string[] = [];\n if (examples.length === 0) {\n warnings.push(\n 'No examples found. Add examples to step entries, or reference a package that ships examples (see package_get).',\n );\n }\n if (skippedExamples.length > 0) {\n warnings.push(\n `Skipped ${skippedExamples.length} package example(s) that do not match the step example schema: ${skippedExamples.join(', ')}.`,\n );\n }\n if (skippedPackages) {\n warnings.push(\n `Package examples were looked up for the first ${MAX_PACKAGE_LOOKUPS} packages only. Use step to narrow the result.`,\n );\n }\n const hints: { next: string[]; warnings?: string[] } = {\n next: [\n runtime.simulate\n ? 'Use flow_simulate with step and event to simulate'\n : HINT_OUT_OF_PROCESS,\n ],\n ...(warnings.length > 0 ? { warnings } : {}),\n };\n return mcpResult(result, hints);\n } catch (error) {\n return mcpError(\n error,\n refusalHint(error, 'Check configPath — expected a flow.json file'),\n );\n }\n}\n\nexport function registerFlowExamplesTool(\n server: McpServer,\n runtime: FlowRuntime,\n) {\n const spec = createFlowExamplesToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: ExamplesListOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowExamplesHandlerBody(runtime, args),\n );\n}\n","import { apiRequest } from '@walkeros/cli';\nimport type { ResponseJson } from '@walkeros/cli';\n\n// __VERSION__ is replaced at build time by tsup's `define` (see tsup.config.ts).\n// In tests, it's set on globalThis (see src/__tests__/support/version.ts).\ndeclare const __VERSION__: string;\n\nconst NPM_SEARCH_URL = 'https://registry.npmjs.org/-/v1/search';\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/npm';\nconst WALKEROS_JSON_PATH = 'dist/walkerOS.json';\nconst CACHE_TTL = 5 * 60 * 1000;\n\nexport const CLIENT_HEADER = 'walkeros-mcp/' + __VERSION__;\n\n/**\n * Resolve the walkerOS app base URL for MCP outbound calls.\n *\n * Env-only by design: the MCP runs in an editor with explicit `.mcp.json`\n * env. No config-file precedence (which is what `@walkeros/cli`'s\n * `resolveAppUrl()` does for the `walkeros` CLI binary). Hard-cut:\n * `APP_URL` is no longer recognized.\n *\n * Lives here (not in tools/package.ts) because both the package tools and the\n * catalog resources need to resolve the same app-primary base URL. This is an\n * in-package helper, not a cross-package registry.\n */\nexport function getPackageBaseUrl(): string | undefined {\n return process.env.WALKEROS_APP_URL || undefined;\n}\n\nexport interface CatalogEntry {\n name: string;\n version: string;\n description?: string;\n type: string;\n platform: string[];\n}\n\nexport interface CatalogResult {\n entries: CatalogEntry[];\n warnings: string[];\n}\n\n/**\n * Provenance of the most recent `fetchCatalog` call. Module-scoped and\n * last-call-wins: the stdio MCP is a single process, so the diagnostics tool\n * reads which source (`app` vs `npm` fallback) served the last catalog fetch,\n * how many entries it produced, and whether any were dropped (partial).\n * `undefined` until the first fetch.\n */\nexport interface LastCatalogFetchInfo {\n source: 'app' | 'npm';\n count: number;\n partial: boolean;\n timestamp: number;\n}\n\nlet lastFetchInfo: LastCatalogFetchInfo | undefined;\n\nexport function getLastCatalogSource(): LastCatalogFetchInfo | undefined {\n return lastFetchInfo;\n}\n\n// Cache keyed by effective source (app baseUrl or 'npm'). The tool reads\n// app-primary and the resources read npm-primary; a shared cache let one\n// source's result leak into the other. Only complete, non-empty results are\n// cached, so a transient empty/partial fetch never freezes for the TTL.\nconst cache = new Map<string, { entries: CatalogEntry[]; timestamp: number }>();\n\nexport function clearCatalogCache() {\n cache.clear();\n}\n\nexport function normalizePlatform(platform?: unknown): string[] {\n if (platform == null) return [];\n if (typeof platform === 'string') {\n return platform === 'universal' ? ['web', 'server'] : [platform];\n }\n if (Array.isArray(platform)) {\n return platform.filter((v): v is string => typeof v === 'string');\n }\n return [];\n}\n\ninterface SourceResult {\n entries: CatalogEntry[];\n complete: boolean;\n // Number of packages the source listed before enrichment, so the caller can\n // compute how many were dropped (listed minus enriched).\n requested: number;\n}\n\nexport async function fetchCatalog(filters?: {\n type?: string;\n platform?: string;\n baseUrl?: string;\n}): Promise<CatalogResult> {\n const sourceKey = filters?.baseUrl ?? 'npm';\n const warnings: string[] = [];\n\n const cached = cache.get(sourceKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n lastFetchInfo = {\n source: filters?.baseUrl ? 'app' : 'npm',\n count: cached.entries.length,\n partial: false,\n timestamp: Date.now(),\n };\n return { entries: applyFilters(cached.entries, filters), warnings };\n }\n\n let result: SourceResult;\n // Which source actually served. Starts as the requested source, flips to\n // 'npm' when an app fetch fails over to the npm fallback.\n let servedBy: 'app' | 'npm' = filters?.baseUrl ? 'app' : 'npm';\n if (filters?.baseUrl) {\n try {\n result = await fetchCatalogFrom(filters.baseUrl, filters);\n } catch {\n warnings.push(\n 'app catalog endpoint unavailable, fell back to npm; results may be incomplete',\n );\n servedBy = 'npm';\n try {\n result = await fetchFromNpm();\n } catch {\n lastFetchInfo = {\n source: 'npm',\n count: 0,\n partial: true,\n timestamp: Date.now(),\n };\n return { entries: [], warnings };\n }\n }\n } else {\n try {\n result = await fetchFromNpm();\n } catch {\n lastFetchInfo = {\n source: 'npm',\n count: 0,\n partial: true,\n timestamp: Date.now(),\n };\n return { entries: [], warnings };\n }\n }\n\n const dropped = result.requested - result.entries.length;\n if (dropped > 0) {\n warnings.push(\n `${dropped} package(s) could not be enriched and were omitted`,\n );\n }\n\n lastFetchInfo = {\n source: servedBy,\n count: result.entries.length,\n partial: !result.complete,\n timestamp: Date.now(),\n };\n\n // Only freeze a complete, non-empty result. Empty or partial fetches must\n // retry on the next call rather than serve a stale shortfall for the TTL.\n if (result.entries.length > 0 && result.complete) {\n cache.set(sourceKey, { entries: result.entries, timestamp: Date.now() });\n }\n\n return { entries: applyFilters(result.entries, filters), warnings };\n}\n\nasync function fetchCatalogFrom(\n baseUrl: string,\n filters?: { type?: string; platform?: string },\n): Promise<SourceResult> {\n const res = await apiRequest('GET /api/packages', {\n auth: 'none',\n baseUrl,\n query: {\n type: filters?.type || undefined,\n platform: filters?.platform || undefined,\n },\n signal: AbortSignal.timeout(15000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n });\n if (!res.ok) throw new Error(`Catalog fetch failed: ${res.status}`);\n\n const data: ResponseJson<'GET /api/packages', 200> = await res.json();\n const entries: CatalogEntry[] = data.catalog;\n return { entries, complete: entries.length > 0, requested: entries.length };\n}\n\nasync function fetchFromNpm(): Promise<SourceResult> {\n const res = await fetch(`${NPM_SEARCH_URL}?text=@walkeros/&size=250`, {\n signal: AbortSignal.timeout(10000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n });\n if (!res.ok) throw new Error(`npm search failed: ${res.status}`);\n\n const data = (await res.json()) as {\n objects: Array<{\n package: { name: string; version: string; description?: string };\n }>;\n };\n\n const requested = data.objects.length;\n\n const metaResults = await Promise.allSettled(\n data.objects.map((obj) => enrichWithMeta(obj.package)),\n );\n\n const entries = metaResults\n .filter(\n (r): r is PromiseFulfilledResult<CatalogEntry | undefined> =>\n r.status === 'fulfilled',\n )\n .map((r) => r.value)\n .filter((entry): entry is CatalogEntry => entry !== undefined);\n\n // A non-empty npm list with fewer enriched entries means jsdelivr silently\n // dropped some packages; treat that as incomplete so it is not cached.\n const complete = requested === 0 || entries.length === requested;\n return { entries, complete, requested };\n}\n\nasync function enrichWithMeta(pkg: {\n name: string;\n version: string;\n description?: string;\n}): Promise<CatalogEntry | undefined> {\n try {\n const res = await fetch(\n `${JSDELIVR_BASE}/${pkg.name}@${pkg.version}/${WALKEROS_JSON_PATH}`,\n {\n signal: AbortSignal.timeout(5000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n },\n );\n if (!res.ok) return undefined;\n\n const json = (await res.json()) as { $meta?: Record<string, unknown> };\n const meta = json.$meta;\n if (!meta || typeof meta.type !== 'string') return undefined;\n\n return {\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n type: meta.type,\n platform: normalizePlatform(meta.platform),\n };\n } catch {\n return undefined;\n }\n}\n\nfunction applyFilters(\n entries: CatalogEntry[],\n filters?: { type?: string; platform?: string },\n): CatalogEntry[] {\n let results = entries;\n if (filters?.type) {\n results = results.filter((e) => e.type === filters.type);\n }\n if (filters?.platform) {\n // Empty platform means platform-agnostic → matches any filter\n results = results.filter(\n (e) => e.platform.length === 0 || e.platform.includes(filters.platform!),\n );\n }\n return results;\n}\n","/**\n * Structural reads of values the tools receive untyped: app responses\n * (`ToolClient` returns `unknown`) and loaded configs. Each reader checks the\n * shape it returns, so a field that is not what a tool expects reads as\n * absent instead of being asserted into place.\n */\nimport type { Flow } from '@walkeros/core';\nimport { schemas, type z } from '@walkeros/core/dev';\n\n/** A plain JSON object. */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** A string field of an object, absent when it is not a string. */\nexport function stringField(value: unknown, key: string): string | undefined {\n if (!isRecord(value)) return undefined;\n const field = value[key];\n return typeof field === 'string' ? field : undefined;\n}\n\n/** An object field of an object, absent when it is not an object. */\nexport function recordField(\n value: unknown,\n key: string,\n): Record<string, unknown> | undefined {\n if (!isRecord(value)) return undefined;\n const field = value[key];\n return isRecord(field) ? field : undefined;\n}\n\n/** The fields of an object response to spread into a result; none otherwise. */\nexport function fieldsOf(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\n/**\n * A flow config (`Flow.Json`): an object with a `flows` object, the same\n * shallow check the CLI's push makes. Every consumer passes it on to the CLI,\n * which validates the config in depth.\n */\nexport function isFlowJson(value: unknown): value is Flow.Json {\n return isRecord(value) && isRecord(value.flows);\n}\n\n/** A step example as core's `StepExampleSchema` reads it. */\nexport type StepExampleView = z.infer<\n typeof schemas.FlowSchemas.StepExampleSchema\n>;\n\n/**\n * The step examples of an object, each checked with core's\n * `StepExampleSchema`. Names that fail it are returned as `skipped`, so a\n * caller reports them instead of dropping them unseen.\n */\nexport function stepExamplesOf(\n value: unknown,\n):\n | { examples: Record<string, StepExampleView>; skipped: string[] }\n | undefined {\n if (!isRecord(value)) return undefined;\n const examples: Record<string, StepExampleView> = {};\n const skipped: string[] = [];\n for (const [name, example] of Object.entries(value)) {\n const parsed = schemas.FlowSchemas.StepExampleSchema.safeParse(example);\n if (parsed.success) examples[name] = parsed.data;\n else skipped.push(name);\n }\n return { examples, skipped };\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackage, mcpResult, mcpError } from '@walkeros/core';\nimport { mergeConfigSchema } from '@walkeros/core/dev';\nimport {\n fetchCatalog,\n normalizePlatform,\n getPackageBaseUrl,\n CLIENT_HEADER,\n} from '../catalog.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { recordField, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\n\n// `getPackageBaseUrl` lives in ../catalog.js because both these tools and the\n// catalog resources resolve the same app-primary base URL. Re-exported here so\n// existing importers of `tools/package.js` keep working.\nexport { getPackageBaseUrl };\n\n// ---------- package_search ----------\n\nconst SEARCH_TITLE = 'Search Package';\nconst SEARCH_DESCRIPTION =\n 'Start here for package discovery. Never guess package names: use this tool first to find exact names. ' +\n 'Without package name: returns catalog filtered by type/platform. ' +\n 'With package name: returns metadata, hint keys, and example summaries.';\n\nconst searchInputSchema = {\n package: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Exact npm package name for detailed lookup (e.g., @walkeros/web-destination-snowplow)',\n ),\n type: z\n .enum(['source', 'destination', 'transformer', 'store'])\n .optional()\n .describe('Filter by package type (browse mode)'),\n platform: z\n .enum(['web', 'server'])\n .optional()\n .describe('Filter by platform (browse mode, includes universal packages)'),\n version: z\n .string()\n .optional()\n .describe('Package version for detailed lookup (default: latest)'),\n};\n\nconst searchAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n} as const;\n\nexport function createPackageSearchToolSpec(): ToolSpec {\n return {\n name: 'package_search',\n title: SEARCH_TITLE,\n description: SEARCH_DESCRIPTION,\n inputSchema: searchInputSchema,\n annotations: searchAnnotations,\n handler: (input) => packageSearchHandlerBody(input),\n };\n}\n\nasync function packageSearchHandlerBody(input: unknown) {\n const parsed = parseToolInput(searchInputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { package: packageName, type, platform, version } = parsed.data;\n const baseUrl = getPackageBaseUrl();\n\n // Browse mode: no package specified → return catalog\n if (!packageName) {\n const { entries, warnings } = await fetchCatalog({\n type,\n platform,\n baseUrl,\n });\n const result = { catalog: entries, count: entries.length };\n return mcpResult(result, {\n next: ['Use package_get for schemas and examples'],\n ...(warnings.length > 0 ? { warnings } : {}),\n });\n }\n\n // Lookup mode: fetch specific package details\n try {\n const info = await fetchPackage(packageName, {\n version,\n baseUrl,\n client: CLIENT_HEADER,\n });\n\n const result = {\n package: info.packageName,\n version: info.version,\n description: info.description,\n type: info.type,\n platform: normalizePlatform(info.platform),\n hintKeys: info.hintKeys,\n exampleSummaries: info.exampleSummaries,\n };\n\n return mcpResult(result, {\n next: ['Use package_get for schemas and examples'],\n });\n } catch (error) {\n return mcpError(\n error,\n 'Package not found. Use package_search without parameters to browse available packages.',\n );\n }\n}\n\nexport function registerPackageSearchTool(server: McpServer) {\n const spec = createPackageSearchToolSpec();\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // No outputSchema: browse mode returns {catalog, count}, lookup returns metadata — incompatible shapes\n annotations: spec.annotations,\n },\n (args) => packageSearchHandlerBody(args),\n );\n}\n\n// ---------- package_get ----------\n\nconst GET_TITLE = 'Get Package';\nconst GET_DESCRIPTION =\n 'Requires exact package name: do not guess names, use package_search first to find them. ' +\n 'Returns schemas + hint texts + example summaries by default (lightweight). ' +\n 'Use section parameter for full content: \"hints\" (with code blocks), \"examples\" (full in/out data), or \"all\".';\n\nconst getInputSchema = {\n package: z\n .string()\n .min(1)\n .describe(\n 'Exact npm package name (e.g., @walkeros/web-destination-snowplow)',\n ),\n version: z.string().optional().describe('Package version (default: latest)'),\n section: z\n .enum(['hints', 'examples', 'all'])\n .optional()\n .describe(\n 'Section to expand with full content. Default: summary view with schemas + hint texts + example descriptions',\n ),\n};\n\nconst getAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createPackageGetToolSpec(): ToolSpec {\n return {\n name: 'package_get',\n title: GET_TITLE,\n description: GET_DESCRIPTION,\n inputSchema: getInputSchema,\n annotations: getAnnotations,\n handler: (input) => packageGetHandlerBody(input),\n };\n}\n\nconst STEP_PACKAGE_TYPES = [\n 'source',\n 'destination',\n 'transformer',\n 'store',\n] as const;\n\nfunction isStepPackageType(\n type: string | undefined,\n): type is (typeof STEP_PACKAGE_TYPES)[number] {\n return STEP_PACKAGE_TYPES.some((stepType) => stepType === type);\n}\n\n/**\n * Base config merged with the package settings as `config`; every other\n * schema (mapping, setup, ga4, ...) kept as a sibling.\n */\nfunction shapeSchemas(\n type: string | undefined,\n schemas: Record<string, unknown>,\n): Record<string, unknown> {\n const shaped: Record<string, unknown> = {};\n\n if (isStepPackageType(type)) {\n const settings = recordField(schemas, 'settings');\n const credentials = recordField(schemas, 'credentials');\n shaped.config = mergeConfigSchema(type, {\n ...schemas,\n settings,\n credentials,\n });\n }\n\n for (const [key, value] of Object.entries(schemas)) {\n if (key !== 'settings') shaped[key] = value;\n }\n return shaped;\n}\n\nasync function packageGetHandlerBody(input: unknown) {\n const parsed = parseToolInput(getInputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { package: packageName, version, section } = parsed.data;\n const baseUrl = getPackageBaseUrl();\n\n try {\n const info = await fetchPackage(packageName, {\n version,\n baseUrl,\n client: CLIENT_HEADER,\n });\n\n const result: Record<string, unknown> = {\n package: info.packageName,\n version: info.version,\n type: info.type,\n platform: normalizePlatform(info.platform),\n schemas: shapeSchemas(info.type, info.schemas),\n };\n\n // Multi-export packages: schemas per export, each with its own config\n if (info.exportSchemas) {\n result.exportSchemas = Object.fromEntries(\n Object.entries(info.exportSchemas).map(([name, schemas]) => [\n name,\n shapeSchemas(info.type, schemas),\n ]),\n );\n }\n\n // Hints\n if (info.hints) {\n if (section === 'hints' || section === 'all') {\n result.hints = info.hints;\n } else {\n const hintSummary: Record<string, { text: string }> = {};\n for (const [key, hint] of Object.entries(info.hints)) {\n const text = stringField(hint, 'text');\n if (text !== undefined) hintSummary[key] = { text };\n }\n result.hints = hintSummary;\n }\n }\n\n // Examples\n if (section === 'examples' || section === 'all') {\n result.examples = info.examples;\n // Multi-export packages: examples per export, keyed by export name\n if (info.exportExamples) result.exportExamples = info.exportExamples;\n } else {\n result.exampleSummaries = info.exampleSummaries;\n }\n\n return mcpResult(result);\n } catch (error) {\n return mcpError(\n error,\n 'Use package_search to browse available package names.',\n );\n }\n}\n\nexport function registerGetPackageSchemaTool(server: McpServer) {\n const spec = createPackageGetToolSpec();\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // No outputSchema: removed to avoid SDK -32602 crashes on unexpected field values\n annotations: spec.annotations,\n },\n (args) => packageGetHandlerBody(args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactNestedStrings, keepStructural } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { RuntimeRefusal, type FlowRuntime } from '../runtime/types.js';\n\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\n\nconst WEB_SKELETON = {\n version: 4,\n flows: {\n default: {\n config: { platform: 'web', bundle: { packages: {} } },\n sources: {},\n destinations: {},\n },\n },\n};\n\nconst SERVER_SKELETON = {\n version: 4,\n flows: {\n default: {\n config: { platform: 'server', bundle: { packages: {} } },\n sources: {},\n destinations: {},\n },\n },\n};\n\nconst TITLE = 'Load or Create Flow';\nconst DESCRIPTION =\n 'Load an existing flow configuration from a local file path, URL, or walkerOS API (by flow ID). ' +\n 'On the hosted server only inline JSON or a saved flow id is accepted, no file paths or URLs. ' +\n 'Or create a new empty flow by specifying a platform (web or server). ' +\n 'Use the add-step prompt to add sources, destinations, transformers, or stores to the flow.';\n\nconst inputSchema = {\n source: z\n .string()\n .optional()\n .describe(\n 'Flow source: local file path (./flow.json), URL (https://...), ' +\n 'inline JSON string, or API flow ID (cfg_...). Omit to create a new flow.',\n ),\n platform: z\n .enum(['web', 'server'])\n .optional()\n .describe(\n 'Platform for new flows. Required when source is omitted. ' +\n 'web = browser tracking, server = Node.js HTTP.',\n ),\n};\n\nconst outputSchema = {\n version: z.number().describe('Flow config version'),\n flows: z.record(z.string(), z.unknown()).describe('Flow entries'),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createFlowLoadToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_load',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowLoadHandlerBody(client, runtime, input),\n };\n}\n\nasync function flowLoadHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { source, platform } = parsed.data;\n\n // Load by cloud flow/config id (flow_… / cfg_…) via the same client seam\n // flow_manage `get` uses. Its NOT_FOUND surfaces directly, never remapped\n // to the local \"file not found\" hint below.\n if (source && isCloudId(source)) {\n const resolvedProjectId = resolveDefaultProject(client, undefined);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n try {\n const flow = await client.getFlow({\n flowId: source,\n projectId: resolvedProjectId,\n });\n return mcpResult(\n redactNestedStrings(flowConfigOf(flow), { skip: keepStructural }),\n {\n next: ['Use flow_validate to check', 'Use add-step prompt to modify'],\n },\n );\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n }\n\n try {\n if (source) {\n // Every file or URL read goes through the runtime, which decides what\n // this process may load.\n const config = await runtime.load(source);\n return mcpResult(redactNestedStrings(config, { skip: keepStructural }), {\n next: ['Use flow_validate to check', 'Use add-step prompt to modify'],\n });\n }\n\n if (!platform) {\n return mcpError(\n new Error(\n 'Provide source (file path, URL, or flow ID) to load existing flow, ' +\n 'or platform (web/server) to create a new one.',\n ),\n );\n }\n\n const skeleton = platform === 'web' ? WEB_SKELETON : SERVER_SKELETON;\n return mcpResult(skeleton, {\n next: [\n 'Read walkeros://reference/flow-schema for config structure',\n 'Use add-step prompt to add sources and destinations',\n ],\n });\n } catch (error) {\n if (error instanceof RuntimeRefusal) return mcpError(error, error.hint);\n const msg = error instanceof Error ? error.message : '';\n if (msg.includes('not found') || msg.includes('ENOENT'))\n return mcpError(error, 'Check configPath — expected a flow.json file');\n return mcpError(error);\n }\n}\n\nexport function registerFlowLoadTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowLoadToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema,\n annotations: spec.annotations,\n },\n (args) => flowLoadHandlerBody(client, runtime, args),\n );\n}\n","// Shared types for MCP management tools.\n// Keep this file dependency-light: only type-level imports from SDK/core.\n\n/**\n * Discriminated input shape for action-based MCP tools.\n * Example: ActionToolInput<'list', { projectId?: string }>\n */\nexport type ActionToolInput<A extends string, T = Record<string, never>> = {\n action: A;\n} & T;\n\n/**\n * Uniform handler return shape used by all mgmt tools.\n * Matches mcpResult / mcpError from @walkeros/core.\n */\nexport type ToolHandlerResult = {\n content: Array<{ type: 'text'; text: string }>;\n structuredContent: Record<string, unknown>;\n isError?: true;\n};\n\n/**\n * True when the walkerOS cloud API refused the caller as unauthenticated: an\n * HTTP 401, or the code `UNAUTHORIZED` that the app answers a missing, invalid\n * or expired token with and the CLI raises when no login is stored. A 403\n * (`FORBIDDEN`, `INSUFFICIENT_SCOPE`, a feature gate) never is: that caller is\n * logged in and lacks a role, a scope or an entitlement. Read from the\n * structured `status` and `code`, never from the message.\n */\nexport function isAuthenticationError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('status' in error && error.status === 401) return true;\n return 'code' in error && error.code === 'UNAUTHORIZED';\n}\n\n/**\n * True when the walkerOS cloud API refused a logged-in caller: an HTTP 403, or\n * the code `FORBIDDEN` (a role) or `INSUFFICIENT_SCOPE` (a token scope) that\n * the hosted door carries without a status. Read from the structured `status`\n * and `code`, never from the message.\n */\nexport function isAccessRefusal(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('status' in error && error.status === 403) return true;\n return (\n 'code' in error &&\n (error.code === 'FORBIDDEN' || error.code === 'INSUFFICIENT_SCOPE')\n );\n}\n\nexport const AUTH_HINT =\n 'Are you logged in? Use auth(action: \"status\") to check.';\n","/**\n * Wraps a user-writable string in `<user_data>…</user_data>` so the chat\n * assistant treats it as data, never as instructions. Inner `</user_data>`\n * sequences are mangled (`</user_data_>`) so a malicious string can't close\n * the envelope early.\n *\n * Idempotent: a string that is already a well-formed envelope with no inner\n * `</user_data>` is returned unchanged.\n */\nexport function wrapUserData(s: string): string {\n const alreadyWrapped =\n s.startsWith('<user_data>') &&\n s.endsWith('</user_data>') &&\n s.slice(11, -12).indexOf('</user_data>') === -1;\n if (alreadyWrapped) return s;\n const neutralised = s.replace(/<\\/user_data>/g, '</user_data_>');\n return `<user_data>${neutralised}</user_data>`;\n}\n\n/**\n * The single redaction rule for every tool that echoes flow/deployment data\n * back to the chat assistant:\n *\n * wrap only the human-facing display `name`/`flowName` field and deep config\n * VALUES; leave all structural ids/keys literal everywhere.\n *\n * Redaction exists to neutralise user-CONTROLLED string VALUES so an injected\n * `</user_data>` can't escape the envelope. It must NOT touch:\n * - structural keys (ids, slugs, dates, immutable identifiers): the LLM needs\n * to reference them verbatim, and wrapping them breaks get→edit→update\n * round-trips (e.g. wrapping `package`/`platform` corrupts a config the\n * user pushes straight back).\n * - tool-generated text (validation messages, error strings): that text is\n * authored by us, not echoed user input, so it stays literal like `path`.\n *\n * `STRUCTURAL_KEYS` is the union of every key whose value is an id/slug/date/\n * immutable identifier rather than user free-text. Confirmed: none of these key\n * names ever hold a genuine user-authored free-text value — `package`/`platform`\n * are enum/package-name fields, `kind` is a discriminator, the rest are\n * server-generated ids/timestamps.\n */\nexport const STRUCTURAL_KEYS = new Set([\n 'id',\n 'flowId',\n 'projectId',\n 'previewId',\n 'version',\n 'slug',\n 'kind',\n 'createdAt',\n 'updatedAt',\n 'deletedAt',\n 'package',\n 'platform',\n]);\n\n/** Return `true` for keys that must stay literal (ids, slugs, dates, package,\n * platform). Use as the `skip` predicate for {@link redactNestedStrings}. */\nexport const keepStructural = (key: string): boolean =>\n STRUCTURAL_KEYS.has(key);\n\nexport interface RedactOptions {\n /** Return `true` to skip wrapping for a given object key. Only invoked for\n * string values on object entries — not for array elements or scalar\n * roots. Use to keep ids / slugs / dates literal. */\n skip?: (key: string) => boolean;\n}\n\n/**\n * Recursively walks `value` and returns a deep-copied structure where every\n * string leaf has been passed through `wrapUserData`. Pass `skip` to exclude\n * specific keys (e.g. `id`) from wrapping.\n */\nexport function redactNestedStrings<T>(value: T, opts?: RedactOptions): T {\n return walk(value, opts) as T;\n}\n\n/** Human-facing display fields wrapped on echoed flow/deployment summaries even\n * when the rest of the object is left literal. */\nconst DISPLAY_NAME_KEYS = new Set(['name', 'flowName']);\n\n/**\n * Recursively wraps ONLY the human-facing display `name`/`flowName` fields,\n * leaving every other value (ids, slugs, status, type, dates) literal. Use on\n * tool responses that echo deployment/flow summaries where the only\n * user-authored free-text is the display name.\n */\nexport function redactDisplayNames<T>(value: T): T {\n return walkDisplay(value) as T;\n}\n\nfunction walkDisplay(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(walkDisplay);\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (DISPLAY_NAME_KEYS.has(k) && typeof v === 'string') {\n out[k] = wrapUserData(v);\n } else {\n out[k] = walkDisplay(v);\n }\n }\n return out;\n }\n return value;\n}\n\nfunction walk(value: unknown, opts?: RedactOptions): unknown {\n if (typeof value === 'string') return wrapUserData(value);\n if (Array.isArray(value)) return value.map((v) => walk(v, opts));\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (opts?.skip?.(k) && typeof v === 'string') {\n out[k] = v;\n } else {\n out[k] = walk(v, opts);\n }\n }\n return out;\n }\n return value;\n}\n","import type { ToolClient } from '../tool-client.js';\n\n/**\n * Shared by every project-bound tool, so the remedy is worded once.\n *\n * It names what to do, not just what went wrong, and it names where to get the\n * missing value. The per-call remedy leads because it always works: a selection\n * made with `set_default` is held by the process serving the connection and is\n * gone after a reconnect, by the ruling in the app's MCP route.\n */\nexport const NO_DEFAULT_PROJECT_ERROR =\n 'No project selected and no projectId given. Pass projectId on this call, or call project_manage action \"set_default\" to select one. project_manage action \"list\" returns the available ids.';\n\n/** Resolves the project for actions that fall back to the CLI default when\n * `projectId` is omitted. Returns the resolved id, or undefined when there is\n * no default to fall back to (the no-project-at-all case). An explicit\n * `projectId` is always honoured as-is so the app's genuine NOT_FOUND still\n * surfaces for an explicit-but-wrong id. */\nexport function resolveDefaultProject(\n client: ToolClient,\n projectId: string | undefined,\n): string | undefined {\n return projectId ?? client.getDefaultProject() ?? undefined;\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\n\ndeclare const __VERSION__: string;\n\nconst TITLE = 'Send Feedback';\nconst DESCRIPTION = 'Send feedback about walkerOS';\n\nconst inputSchema = {\n text: z.string().describe('Your feedback text'),\n anonymous: z\n .boolean()\n .optional()\n .describe(\n 'Include user/project info? false = include, true = anonymous. Only needed on first call if not yet configured.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFeedbackToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'feedback',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => feedbackHandlerBody(client, input),\n };\n}\n\nasync function feedbackHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { text, anonymous: explicitAnonymous } = parsed.data;\n try {\n let anonymous = client.getFeedbackPreference();\n\n if (anonymous === undefined && explicitAnonymous === undefined) {\n return mcpResult(\n { needsConsent: true },\n {\n next: [\n 'Ask the user if they want to include their info',\n 'Call feedback again with anonymous: true or false',\n ],\n },\n );\n }\n\n if (anonymous === undefined && explicitAnonymous !== undefined) {\n anonymous = explicitAnonymous;\n client.setFeedbackPreference(anonymous);\n }\n\n const isAnonymous = explicitAnonymous ?? anonymous ?? true;\n\n await client.submitFeedback(text, {\n anonymous: isAnonymous,\n version: __VERSION__,\n });\n\n return mcpResult({ ok: true });\n } catch (error) {\n return mcpError(error);\n }\n}\n\nexport function registerFeedbackTool(server: McpServer, client: ToolClient) {\n const spec = createFeedbackToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => feedbackHandlerBody(client, args),\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult } from '@walkeros/core';\nimport {\n VERSION as CLI_VERSION,\n bakedContractVersion,\n operationUrl,\n} from '@walkeros/cli';\nimport type { ContractComparison } from '@walkeros/cli';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { getPackageBaseUrl, getLastCatalogSource } from '../catalog.js';\nimport { normalizeBaseUrl } from '../base-url.js';\n\nconst TITLE = 'Diagnostics';\nconst DESCRIPTION =\n 'Report the MCP runtime surface: MCP and CLI versions, the resolved app URL ' +\n 'and its source, app /api/health reachability, the API contract verdict ' +\n 'against that app, and which source served the last package catalog fetch. ' +\n 'Read-only and callable when logged out; use it when a request fails to see ' +\n 'which versions and backend you are on.';\n\n// No input fields: diagnostics is callable with `{}`, including logged out.\nconst inputSchema = {};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createDiagnosticsToolSpec(\n client: ToolClient,\n packageVersion: string,\n): ToolSpec {\n return {\n name: 'diagnostics',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: () => diagnosticsHandlerBody(client, packageVersion),\n };\n}\n\nasync function diagnosticsHandlerBody(\n client: ToolClient,\n packageVersion: string,\n) {\n // The backend comes from the CLIENT, never from the local CLI: the local\n // door resolves the user's machine, the hosted door is served by the app it\n // reports, and a tool that resolved this itself would name the wrong backend\n // on one of them.\n const resolved = client.appBaseUrl();\n\n // Provenance via the same helper the catalog uses; do not add a parallel\n // process.env check. It is a claim about the OVERRIDE only, and a proven\n // one: `env` means this process's WALKEROS_APP_URL is the URL the client\n // actually named. A client that ignores the variable (the hosted door does,\n // it is served on its own URL) therefore never reports `env` merely because\n // the variable happens to be set in its environment.\n // Normalized on both sides of the comparison: `resolved` is a base without a\n // trailing slash, and the env var is under no such obligation, so comparing\n // raw would report `default` for a slashed value that did set the URL.\n const envAppUrl = getPackageBaseUrl();\n const appUrlSource: 'env' | 'default' =\n envAppUrl !== undefined && normalizeBaseUrl(envAppUrl) === resolved\n ? 'env'\n : 'default';\n\n // checkHealth is optional on ToolClient: clients that cannot probe\n // reachability omit it, in which case diagnostics degrades to\n // { reachable: false }. When present, its contract is to resolve\n // { reachable: false } on failure, but catch here too so a throwing client\n // never breaks diagnostics.\n const healthCheck: Promise<{\n reachable: boolean;\n status?: string;\n version?: string;\n error?: string;\n }> = client.checkHealth\n ? client.checkHealth().catch((error: unknown) => ({\n reachable: false,\n error: errorMessage(error),\n }))\n : Promise.resolve({ reachable: false });\n\n // The contract verdict comes from the CLIENT, like the URL: the local door\n // compares per operation against the app it resolves, a hosted door served\n // inside the app answers `in-process`. A client without the method, or one\n // that throws, yields `unknown` with the reason.\n const contractCheck: Promise<ContractComparison> = client.checkContract\n ? client\n .checkContract()\n .catch((error: unknown) =>\n unknownContract(\n resolved,\n packageVersion,\n `contract check failed: ${errorMessage(error)}`,\n ),\n )\n : Promise.resolve(\n unknownContract(\n resolved,\n packageVersion,\n 'no contract check on this client',\n ),\n );\n\n const [health, contract] = await Promise.all([healthCheck, contractCheck]);\n\n const catalogInfo = getLastCatalogSource();\n\n const warnings: string[] = [];\n if (envAppUrl === undefined) {\n warnings.push(`WALKEROS_APP_URL is not set; app URL from ${appUrlSource}`);\n }\n if (!client.checkHealth) {\n warnings.push('no health check on this client');\n } else if (!health.reachable) {\n const url = operationUrl('GET /api/health', { baseUrl: resolved });\n warnings.push(`GET ${url} failed: ${health.error ?? 'no response'}`);\n }\n\n const result = {\n mcp: { version: packageVersion },\n cli: { version: CLI_VERSION },\n appUrl: { resolved, source: appUrlSource },\n app: {\n reachable: health.reachable,\n ...(health.status !== undefined && { status: health.status }),\n ...(health.version !== undefined && { version: health.version }),\n },\n contract: { openapiVersion: bakedContractVersion, ...contract },\n catalog: catalogInfo\n ? {\n lastSource: catalogInfo.source,\n lastCount: catalogInfo.count,\n partial: catalogInfo.partial,\n }\n : { lastSource: undefined, lastCount: undefined, partial: undefined },\n };\n\n return mcpResult(result, warnings.length > 0 ? { warnings } : undefined);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The `unknown` verdict this MCP reports when its client gives none. */\nfunction unknownContract(\n appUrl: string,\n packageVersion: string,\n reason: string,\n): ContractComparison {\n return {\n verdict: 'unknown',\n appUrl,\n client: {\n package: '@walkeros/mcp',\n version: packageVersion,\n contract: bakedContractVersion,\n },\n reason,\n };\n}\n\nexport function registerDiagnosticsTool(\n server: McpServer,\n client: ToolClient,\n packageVersion: string,\n) {\n const spec = createDiagnosticsToolSpec(client, packageVersion);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n () => diagnosticsHandlerBody(client, packageVersion),\n );\n}\n","/**\n * One spelling of a walkerOS app base URL, so every consumer concatenates a\n * path onto the same shape.\n *\n * The two doors resolve their base from different worlds and neither\n * guarantees the shape on its own: the local door hands back whatever\n * `WALKEROS_APP_URL` or the CLI config file holds, and a valid URL may carry a\n * trailing slash, a query string or a fragment. Normalizing at the seam is what\n * keeps a link built from one door from reading\n * `https://app.example.com//projects/...` while the same link from the other\n * door reads cleanly.\n *\n * A query or a fragment is worse than a stray slash, because a path appended to\n * one lands INSIDE it: `https://app.example.com?a=b` plus `/projects/p1` reads\n * `https://app.example.com?a=b/projects/p1`, which is a broken link that a tool\n * then puts in somebody's chat transcript. Neither belongs on a base URL, so\n * both are dropped. The path is kept: an app mounted under a subpath is a real\n * deployment, and dropping it would break every link instead of fixing one.\n *\n * This never throws, deliberately. Its callers include `diagnostics`, whose job\n * is to NAME a misconfigured app URL; a normalizer that threw would take out\n * the tool that exists to report the problem. A string that does not parse as a\n * URL is handed back with only its trailing slashes trimmed, and fails later at\n * the request, where the error names the URL.\n */\nexport function normalizeBaseUrl(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return stripTrailingSlashes(url);\n }\n\n parsed.search = '';\n parsed.hash = '';\n return stripTrailingSlashes(parsed.toString());\n}\n\nfunction stripTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\n\nconst TITLE = 'Authentication';\nconst DESCRIPTION =\n 'Manage walkerOS authentication. Check login status, log in via the device authorization grant, or log out. ' +\n 'No terminal or browser required, the MCP client handles the authorization URL.';\n\nconst inputSchema = {\n action: z\n .enum(['status', 'login', 'logout'])\n .describe('Authentication action to perform'),\n deviceCode: z\n .string()\n .optional()\n .describe(\n 'Device code from a previous pending login attempt. Provide to resume polling without requesting a new code.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createAuthToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'auth',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => authHandlerBody(client, input),\n };\n}\n\nasync function authHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, deviceCode } = parsed.data;\n try {\n switch (action) {\n case 'status': {\n if (!client.credentialSource()) {\n return mcpResult(\n { authenticated: false },\n { next: ['Use auth with action \"login\" to authenticate'] },\n );\n }\n const user = await client.whoami();\n return mcpResult({\n authenticated: true,\n ...fieldsOf(user),\n });\n }\n\n case 'login': {\n if (deviceCode) {\n const poll = await client.pollForToken(deviceCode, {\n timeoutMs: 60000,\n });\n\n if (poll.status === 'ok') {\n return mcpResult(\n { authenticated: true },\n {\n next: [\n 'Use auth with action \"status\" to see which account you are on',\n 'Use project_manage with action \"list\" to see your projects',\n ],\n },\n );\n }\n\n // The approval is still outstanding, so the code is still good and\n // the same one comes back for the next attempt. `slow_down` is the\n // server asking for a wider gap before that attempt.\n if (poll.status === 'pending' || poll.status === 'slow_down') {\n return mcpResult({\n authenticated: false,\n status: 'pending',\n message:\n poll.status === 'slow_down'\n ? 'Still waiting, and the server asked for a longer gap between checks. Try again in a minute.'\n : 'Still waiting for authorization. Try again shortly.',\n deviceCode,\n });\n }\n\n if (poll.status === 'denied')\n return mcpError(new Error('Authorization was denied.'));\n if (poll.status === 'expired')\n return mcpError(\n new Error(\n 'The one-time code expired. Run auth with action \"login\" for a new one.',\n ),\n );\n\n return mcpError(new Error(poll.error));\n }\n\n const code = await client.requestDeviceCode();\n const loginUrl = code.verificationUriComplete;\n\n return mcpResult({\n authenticated: false,\n status: 'awaiting_authorization',\n loginUrl,\n message: `Open this link to authorize: ${loginUrl}`,\n deviceCode: code.deviceCode,\n });\n }\n\n case 'logout': {\n const { deleted } = await client.logout();\n const hadEnvToken =\n typeof process.env.WALKEROS_TOKEN === 'string' &&\n process.env.WALKEROS_TOKEN.length > 0;\n delete process.env.WALKEROS_TOKEN;\n let message: string;\n if (deleted && hadEnvToken) {\n message =\n 'Logged out. Config removed and WALKEROS_TOKEN cleared from process environment.';\n } else if (deleted) {\n message = 'Logged out and config removed.';\n } else if (hadEnvToken) {\n message =\n 'No config found. WALKEROS_TOKEN cleared from process environment.';\n } else {\n message = 'No config found, already logged out.';\n }\n return mcpResult({\n loggedOut: true,\n message,\n });\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: status, login, logout`,\n );\n }\n } catch (error) {\n return mcpError(error);\n }\n}\n\nexport function registerAuthTool(server: McpServer, client: ToolClient) {\n const spec = createAuthToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => authHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { wrapUserData } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n PROJECT_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\n\n/** A project record with its display name wrapped as user data. */\nfunction wrapProjectName(project: unknown): unknown {\n const name = stringField(project, 'name');\n return isRecord(project) && name !== undefined\n ? { ...project, name: wrapUserData(name) }\n : project;\n}\n\nconst TITLE = 'Project Management';\nconst DESCRIPTION =\n 'Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.';\n\nconst inputSchema = {\n action: z\n .enum(['list', 'get', 'create', 'update', 'delete', 'set_default'])\n .describe('Project management action to perform'),\n projectId: z\n .string()\n .optional()\n .describe('Required for get, update, delete, set_default.'),\n name: z\n .string()\n .optional()\n .describe(\n 'Required for create and update (update also requires projectId).',\n ),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createProjectManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'project_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => projectManageHandlerBody(client, input),\n };\n}\n\nasync function projectManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, projectId, name, cursor, limit } = parsed.data;\n const validationError = validateActionInput(\n 'project_manage',\n action ?? '',\n { projectId, name },\n PROJECT_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'list': {\n const projects = await client.listProjects({ cursor, limit });\n const listed = isRecord(projects) ? projects.projects : undefined;\n const items = Array.isArray(projects)\n ? projects\n : Array.isArray(listed)\n ? listed\n : [];\n if (items.length === 0) {\n return mcpResult(\n { projects: [] },\n {\n next: [\n 'Use project_manage with action \"create\" to create your first project',\n 'Use project_manage with action \"set_default\" after creating to set it as default',\n ],\n },\n );\n }\n const safe = Array.isArray(projects)\n ? items.map(wrapProjectName)\n : { ...fieldsOf(projects), projects: items.map(wrapProjectName) };\n return mcpResult(safe);\n }\n\n case 'get': {\n const project = await client.getProject({ projectId });\n return mcpResult(wrapProjectName(project));\n }\n\n case 'create': {\n assertParam(name, 'name', 'create');\n const created = await client.createProject({ name });\n return mcpResult(wrapProjectName(created), {\n next: [\n 'Use project_manage with action \"set_default\" to make this your active project',\n ],\n });\n }\n\n case 'update': {\n assertParam(name, 'name', 'update');\n const updated = await client.updateProject({ projectId, name });\n return mcpResult(wrapProjectName(updated));\n }\n\n case 'delete': {\n const deleted = await client.deleteProject({ projectId });\n return mcpResult(deleted);\n }\n\n case 'set_default': {\n assertParam(projectId, 'projectId', 'set_default');\n client.setDefaultProject(projectId);\n return mcpResult(\n { defaultProjectId: projectId },\n {\n next: [\n 'Use flow_manage with action \"list\" to see flows in this project',\n ],\n },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, get, create, update, delete, set_default`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerProjectManageTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createProjectManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => projectManageHandlerBody(client, args),\n );\n}\n","export interface ActionRule {\n /** Params that must each be present for this action. */\n required?: string[];\n /** Param groups where at least one of each group must be present. */\n oneOf?: string[][];\n /** Optional discovery hint appended to the error (e.g. 'Use action \"list\" ...'). */\n hint?: string;\n}\n\nexport type ActionRequirementMap = Record<string, ActionRule>;\n\n/**\n * Returns a canonical error message string when `input` is missing a\n * required (or one-of) param for `action`, otherwise null. The message is\n * uniform across tools so error quality cannot drift between tools.\n * Required params are checked (and reported) before oneOf groups.\n */\nexport function validateActionInput(\n toolName: string,\n action: string,\n input: Record<string, unknown>,\n map: ActionRequirementMap,\n): string | null {\n const rule = map[action];\n if (!rule) return null;\n for (const param of rule.required ?? []) {\n if (\n input[param] === undefined ||\n input[param] === null ||\n input[param] === ''\n ) {\n return missing(toolName, action, param, rule.hint);\n }\n }\n for (const group of rule.oneOf ?? []) {\n const satisfied = group.some(\n (p) => input[p] !== undefined && input[p] !== null && input[p] !== '',\n );\n if (!satisfied) {\n return `${toolName} action \"${action}\" requires one of: ${group.join(', ')}.${rule.hint ? ' ' + rule.hint : ''}`;\n }\n }\n return null;\n}\n\n/**\n * Narrows a param that the action's requirement map has already validated as\n * present, so typed client calls accept it without re-checking. The companion\n * to `validateActionInput`: callers run that first to produce a friendly error,\n * then use this assertion at the use site to recover the non-nullable type.\n * Because validation guarantees presence, this never throws in practice; the\n * throw exists only to satisfy the assertion-signature contract. The thrown\n * message mirrors the `missing()` form (\"<param> is required for <action> action.\").\n */\nexport function assertParam(\n value: string | undefined,\n param: string,\n action: string,\n): asserts value is string {\n if (value === undefined || value === null || value === '')\n throw new Error(`${param} is required for ${action} action.`);\n}\n\nfunction missing(\n tool: string,\n action: string,\n param: string,\n hint?: string,\n): string {\n // Keep the substring \"<param> is required\" so existing assertions/docs that\n // string-match it stay green.\n return `${param} is required for ${action} action.${hint ? ' ' + hint : ''}`;\n}\n\nexport const FLOW_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n get: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n update: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n delete: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n duplicate: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n create: { required: ['name'] },\n preview_list: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n preview_get: { required: ['flowId', 'previewId'] },\n preview_create: {\n required: ['flowId'],\n oneOf: [['flowName', 'flowSettingsId']],\n },\n preview_delete: { required: ['flowId', 'previewId'] },\n preview_regrant: { required: ['flowId', 'previewId'] },\n};\n\nexport const DEPLOY_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n deploy: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n get: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n delete: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n};\n\nexport const SECRET_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n list: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n set: {\n required: ['flowId', 'name', 'value'],\n hint: 'Use action \"list\" to see existing secret names for this flow.',\n },\n update: {\n required: ['flowId', 'secretId', 'value'],\n hint: 'Use action \"list\" to find the secretId.',\n },\n delete: {\n required: ['flowId', 'secretId'],\n hint: 'Use action \"list\" to find the secretId.',\n },\n};\n\nexport const PROJECT_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n get: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n update: {\n required: ['projectId', 'name'],\n hint: 'Use action \"list\" to see available projects.',\n },\n delete: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n set_default: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n create: { required: ['name'] },\n};\n\nexport const FRAME_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n page: {\n required: ['pageKey'],\n hint: 'Use action \"list\" to see the source keys of the project’s frames.',\n },\n get: {\n required: ['frameId'],\n hint: 'Use action \"list\" or \"page\" to find a frameId.',\n },\n};\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport {\n wrapUserData,\n redactNestedStrings,\n keepStructural,\n} from '../user-data.js';\nimport { flowCanvasResult } from '../ui-parts.js';\nimport { links } from '../links.js';\n\n/** Peek at a Flow.Json root (v4) and decide whether the bubble should render\n * as web-flavoured or server-flavoured. The platform is recorded on\n * `flows[name].config.platform`. We pick the first flow's platform; if no\n * platform is set we fall back to `'server'` so the chat bubble can still\n * render even if the user is mid-edit. */\nfunction pickPlatform(content: unknown): 'web' | 'server' {\n const flows = recordField(content, 'flows');\n for (const flow of Object.values(flows ?? {})) {\n const platform = stringField(recordField(flow, 'config'), 'platform');\n if (platform === 'web' || platform === 'server') return platform;\n }\n return 'server';\n}\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord, recordField, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n FLOW_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\n\n/**\n * The flow's page in the app, or nothing when the response carried no id (a\n * shape this module already tolerates everywhere else it reads `id`). The base\n * URL comes from the door, so one definition serves both of them.\n */\nfunction flowPageUrl(\n client: ToolClient,\n projectId: string,\n flowId: string | undefined,\n): string | undefined {\n if (flowId === undefined) return undefined;\n return links.flow({ baseUrl: client.appBaseUrl(), projectId, flowId });\n}\n\n/** A flow summary with its display name wrapped as user data. */\nfunction safeSummary(flow: unknown): unknown {\n const name = stringField(flow, 'name');\n return isRecord(flow) && name !== undefined\n ? { ...flow, name: wrapUserData(name) }\n : flow;\n}\n\n/** A flow record with its name wrapped and its config's strings redacted. */\ninterface SafeFlowDetail {\n fields: Record<string, unknown>;\n id?: string;\n name?: string;\n config?: Record<string, unknown>;\n}\n\nfunction safeDetail(flow: unknown): SafeFlowDetail {\n const fields: Record<string, unknown> = { ...fieldsOf(flow) };\n const name = stringField(fields, 'name');\n if (name !== undefined) fields.name = wrapUserData(name);\n if (fields.config !== undefined) {\n fields.config = redactNestedStrings(fields.config, {\n skip: keepStructural,\n });\n }\n return {\n fields,\n id: stringField(fields, 'id'),\n name: stringField(fields, 'name'),\n config: recordField(fields, 'config'),\n };\n}\n\nconst TITLE = 'Flow Management';\nconst DESCRIPTION =\n '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.';\n\nconst inputSchema = {\n action: z\n .enum([\n 'list',\n 'get',\n 'create',\n 'update',\n 'delete',\n 'duplicate',\n 'preview_list',\n 'preview_get',\n 'preview_create',\n 'preview_delete',\n 'preview_regrant',\n ])\n .describe('Flow management action to perform'),\n flowId: z\n .string()\n .optional()\n .describe(\n 'Flow ID (flow_...) or config ID (cfg_...). Required for get, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant.',\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional filter for list (omit to list all projects). Required for create if no default project set.',\n ),\n name: z\n .string()\n .optional()\n .describe(\n 'Flow name. Required for create. Optional for update (to rename) and duplicate.',\n ),\n content: z\n .record(z.string(), z.unknown())\n .optional()\n .describe('Flow.Json content. Used for create and update.'),\n patch: z\n .boolean()\n .optional()\n .describe(\n 'Merge-patch for update (default true). When true, only provided fields are updated.',\n ),\n fields: z\n .array(z.string())\n .optional()\n .describe('Dot-path selectors for get to return only specific fields.'),\n sort: z\n .enum(['name', 'updated_at', 'created_at'])\n .optional()\n .describe('Sort field for list.'),\n order: z.enum(['asc', 'desc']).optional().describe('Sort order for list.'),\n includeDeleted: z\n .boolean()\n .optional()\n .describe('Include soft-deleted flows in list results.'),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n previewId: z\n .string()\n .optional()\n .describe(\n 'Preview ID (prv_...). Required for preview_get, preview_delete, and preview_regrant (all also require flowId).',\n ),\n flowName: z\n .string()\n .optional()\n .describe(\n 'Used by preview_create — provide one of flowName or flowSettingsId (preview_create also requires flowId).',\n ),\n flowSettingsId: z\n .string()\n .optional()\n .describe(\n 'Used by preview_create — provide one of flowName or flowSettingsId (preview_create also requires flowId).',\n ),\n source: z\n .discriminatedUnion('kind', [\n z.object({ kind: z.literal('draft') }),\n z.object({\n kind: z.literal('deployment-version'),\n deploymentVersionId: z.string(),\n }),\n ])\n .optional()\n .describe(\n \"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).\",\n ),\n siteUrl: z\n .string()\n .optional()\n .describe(\n '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.',\n ),\n origins: z\n .array(z.string())\n .optional()\n .describe(\n 'Site origins (bare https://host[:port]) to mint a preview activation grant for. Used by preview_regrant; the returned activationUrl targets the first origin.',\n ),\n sessionId: z\n .string()\n .optional()\n .describe(\n 'Observe session id — 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.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n// Preview results land in agent transcripts and logs, so the MCP boundary\n// enforces a field whitelist instead of trusting whatever shape a client\n// returns: the raw ingest `token` and `projectId` must never surface here.\n// Grants (`grant`, `sessionGrant`, `activationUrl`) are deliberate outputs —\n// short-lived, origin/session-bound capabilities the caller needs to activate\n// a preview or forward events to an observe session. The list covers both\n// client shapes: the app's in-process summary (`previewId`, `status`,\n// `observeFeed`) and the CLI-backed HTTP client's raw API response (`id`,\n// `createdBy`, `createdAt`).\nconst PREVIEW_SUMMARY_FIELDS = [\n 'id',\n 'previewId',\n 'flowId',\n 'flowSettingsId',\n 'bundleUrl',\n 'activationUrl',\n 'grant',\n 'sessionGrant',\n 'sessionExpiresAt',\n 'sessionId',\n 'status',\n 'observeFeed',\n 'createdBy',\n 'createdAt',\n] as const;\n\nfunction redactPreview(data: unknown): Record<string, unknown> {\n if (!isRecord(data)) return {};\n const out: Record<string, unknown> = {};\n for (const field of PREVIEW_SUMMARY_FIELDS) {\n if (data[field] !== undefined) out[field] = data[field];\n }\n return out;\n}\n\nfunction redactPreviewList(data: unknown): Record<string, unknown> {\n if (!isRecord(data)) return { previews: [] };\n return {\n previews: Array.isArray(data.previews)\n ? data.previews.map(redactPreview)\n : [],\n ...(data.total !== undefined ? { total: data.total } : {}),\n };\n}\n\n/**\n * Resolve the flow's live Observe session, or null when there is none.\n *\n * `listJourneys` is the flow-keyed read the app already exposes and its\n * `sessionId` IS the flow's single active window, so it doubles as the\n * resolver. Best-effort by design: this only enriches a regrant, so a failing\n * or unavailable read degrades to a plain web preview grant instead of failing\n * the mint the caller actually asked for.\n */\nasync function resolveLiveSessionId(\n client: ToolClient,\n flowId: string,\n projectId: string | undefined,\n): Promise<string | null> {\n try {\n const result = await client.listJourneys({\n flowId,\n ...(projectId !== undefined && { projectId }),\n limit: 1,\n });\n return result.sessionId;\n } catch {\n return null;\n }\n}\n\nexport function createFlowManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'flow_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowManageHandlerBody(client, input),\n };\n}\n\nasync function flowManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n flowId,\n projectId,\n name,\n content,\n patch,\n fields,\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n previewId,\n flowName,\n flowSettingsId,\n source,\n siteUrl,\n origins,\n sessionId,\n } = parsed.data;\n const validationError = validateActionInput(\n 'flow_manage',\n action ?? '',\n { flowId, projectId, name, previewId, flowName, flowSettingsId },\n FLOW_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'list': {\n if (projectId) {\n const data = await client.listFlows({\n projectId,\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n });\n const flows = isRecord(data) ? data.flows : undefined;\n const safe =\n isRecord(data) && Array.isArray(flows)\n ? { ...data, flows: flows.map(safeSummary) }\n : data;\n return mcpResult(safe);\n }\n const data = await client.listAllFlows({\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n });\n const safe = Array.isArray(data) ? data.map(safeSummary) : data;\n return mcpResult(\n { projects: safe },\n {\n next: [\n 'Use flow_manage with action \"get\" and a flowId to inspect a specific flow',\n 'Use flow_load to open a flow for editing',\n ],\n },\n );\n }\n\n case 'get': {\n assertParam(flowId, 'flowId', 'get');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const flow = await client.getFlow({\n flowId,\n projectId: resolvedProjectId,\n fields,\n });\n const safe = safeDetail(flow);\n const appUrl = flowPageUrl(client, resolvedProjectId, safe.id);\n return flowCanvasResult({\n flowId: safe.id,\n configName: safe.name ?? 'default',\n platform: pickPlatform(safe.config),\n flowConfig: safe.config ?? {},\n ...(appUrl !== undefined && { appUrl }),\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safe.id}`,\n autoSend: true,\n },\n {\n label: 'Add a destination',\n prompt: `Help me add a destination to flow ${safe.id}`,\n },\n ],\n });\n }\n\n case 'create': {\n assertParam(name, 'name', 'create');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const created = await client.createFlow({\n name,\n content: content ?? {},\n projectId: resolvedProjectId,\n });\n const safeCreated = safeDetail(created);\n const createdAppUrl = flowPageUrl(\n client,\n resolvedProjectId,\n safeCreated.id,\n );\n return flowCanvasResult({\n flowId: safeCreated.id,\n configName: safeCreated.name ?? 'default',\n platform: pickPlatform(safeCreated.config),\n flowConfig: safeCreated.config ?? {},\n ...(createdAppUrl !== undefined && { appUrl: createdAppUrl }),\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safeCreated.id}`,\n autoSend: true,\n },\n {\n label: 'Deploy it',\n prompt: `Deploy flow ${safeCreated.id}`,\n },\n ],\n });\n }\n\n case 'update': {\n assertParam(flowId, 'flowId', 'update');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const updated = await client.updateFlow({\n flowId,\n projectId: resolvedProjectId,\n name,\n content,\n mergePatch: patch ?? true,\n });\n const safeUpdated = safeDetail(updated);\n return flowCanvasResult({\n flowId: safeUpdated.id,\n configName: safeUpdated.name ?? 'default',\n platform: pickPlatform(safeUpdated.config),\n flowConfig: safeUpdated.config ?? {},\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safeUpdated.id}`,\n autoSend: true,\n },\n {\n label: 'Deploy it',\n prompt: `Deploy flow ${safeUpdated.id}`,\n },\n ],\n });\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const deleted = await client.deleteFlow({\n flowId,\n projectId: resolvedProjectId,\n });\n return mcpResult(deleted);\n }\n\n case 'duplicate': {\n assertParam(flowId, 'flowId', 'duplicate');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const duplicated = await client.duplicateFlow({\n flowId,\n name,\n projectId: resolvedProjectId,\n });\n return mcpResult(safeDetail(duplicated).fields);\n }\n\n case 'preview_list': {\n assertParam(flowId, 'flowId', 'preview_list');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.listPreviews({\n projectId: resolvedProjectId,\n flowId,\n });\n return mcpResult(redactPreviewList(data));\n }\n\n case 'preview_get': {\n assertParam(flowId, 'flowId', 'preview_get');\n assertParam(previewId, 'previewId', 'preview_get');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.getPreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n });\n return mcpResult(redactPreview(data));\n }\n\n case 'preview_create': {\n assertParam(flowId, 'flowId', 'preview_create');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n // Whitelist the summary at the boundary: the HTTP client returns the\n // raw API response (which carries the ingest token and project id),\n // and the handler must never surface those regardless of the client.\n // It also adds no token-derived URL of its own.\n const preview = await client.createPreview({\n projectId: resolvedProjectId,\n flowId,\n flowName,\n flowSettingsId,\n ...(source ? { source } : {}),\n ...(siteUrl ? { siteUrl } : {}),\n });\n return mcpResult(redactPreview(preview), {\n next: [\n 'Open activationUrl on your site to activate preview mode. When activationUrl is null, no grant has been minted for a site yet — use action \"preview_regrant\" with your site origins to mint one.',\n 'Poll observeFeed (observe_journeys with this flowId) to watch preview events arrive.',\n ],\n });\n }\n\n case 'preview_delete': {\n assertParam(flowId, 'flowId', 'preview_delete');\n assertParam(previewId, 'previewId', 'preview_delete');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.deletePreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n });\n // The app responds 204 No Content; an older CLI maps that to null.\n // mcpResult requires a record for structuredContent, so synthesize a\n // confirmation when the body is empty.\n return mcpResult(\n data && typeof data === 'object'\n ? data\n : { deleted: true, previewId },\n );\n }\n\n case 'preview_regrant': {\n assertParam(flowId, 'flowId', 'preview_regrant');\n assertParam(previewId, 'previewId', 'preview_regrant');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n if (!client.regrantPreview) {\n return mcpError(\n new Error('preview_regrant is not supported by this client'),\n );\n }\n // Auto-pair with the flow's live Observe window so a regrant made\n // while the flow is being observed forwards into it by default. An\n // explicit sessionId stays the override, and an unresolvable window is\n // not a failure: it degrades to a plain web preview grant.\n // Resolve under the SAME project the regrant is sent to: this path\n // degrades silently, so a project mismatch would never surface.\n const pairedSessionId =\n sessionId ??\n (await resolveLiveSessionId(client, flowId, resolvedProjectId));\n // Whitelisted grant summary: activationUrl plus the raw grant values\n // the caller may need (`sessionGrant` is how an agent authenticates\n // direct server-hop test events) — never the ingest token.\n const data = await client.regrantPreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n origins: origins ?? [],\n ...(pairedSessionId ? { sessionId: pairedSessionId } : {}),\n });\n return mcpResult(redactPreview(data), {\n next: [\n pairedSessionId\n ? 'Open activationUrl on the target origin: it activates the web preview AND forwards its events to the observe session. Use sessionGrant as the X-Walkeros-Preview header for direct server-hop test events.'\n : 'Open activationUrl on the target origin to activate preview mode.',\n ],\n });\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, get, create, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerFlowManageTool(server: McpServer, client: ToolClient) {\n const spec = createFlowManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => flowManageHandlerBody(client, args),\n );\n}\n","export type SuggestionTile = {\n label: string;\n description?: string;\n prompt: string;\n autoSend?: boolean;\n};\n\nexport interface FlowCanvasPayload {\n flowId?: string;\n configName: string;\n platform: 'web' | 'server';\n flowConfig: Record<string, unknown>;\n highlight?: { stepAddress: string; reason: string };\n suggestions?: SuggestionTile[];\n /**\n * Absolute link to this flow's page in the app, from `links.flow`.\n *\n * Named for the `appBaseUrl()` seam it is built from, and never `url`: that\n * is a field several app responses already use for something of their own\n * (a deployment's `url` is where it SERVES), and one key meaning one thing\n * across every tool is what keeps a link from ever landing on top of it.\n *\n * Optional because a tool that cannot name the project or the flow emits no\n * link rather than a guess, and because the in-app chat renders the canvas\n * itself and has no use for a link to the page it is already on.\n */\n appUrl?: string;\n}\n\nexport interface FlowCanvasToolResult extends FlowCanvasPayload {\n kind: 'flow-canvas';\n}\n\n/**\n * Tool-result helper that marks a response as renderable as a FlowCanvas.\n * The chat UI inspects `structuredContent.kind === 'flow-canvas'` and mounts\n * a `FlowCanvasBubble` instead of the generic JSON fallback. The `content[0]`\n * text is the same JSON stringified — the LLM sees a self-describing object.\n */\nexport function flowCanvasResult(payload: FlowCanvasPayload) {\n const structured: FlowCanvasToolResult = { kind: 'flow-canvas', ...payload };\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(structured, null, 2),\n },\n ],\n structuredContent: structured as unknown as Record<string, unknown> & {\n kind: 'flow-canvas';\n },\n };\n}\n\nexport function isFlowCanvasResult(v: unknown): v is FlowCanvasToolResult {\n return (\n typeof v === 'object' &&\n v !== null &&\n (v as { kind?: unknown }).kind === 'flow-canvas'\n );\n}\n","/**\n * Addresses of walkerOS app screens, built in one place so every tool hands a\n * person the same link for the same screen.\n *\n * WHY THIS EXISTS. A tool that names a release, a step, or a deployment in\n * prose leaves the person to go find it. A link ends that: the answer and the\n * screen it is about arrive together. Building the address in each tool would\n * instead give as many spellings of `/projects/.../flows/...` as there are\n * emission points, and the first one to drift would send someone to a 404 that\n * no test here could see.\n *\n * THE BASE URL IS CONSUMED RAW. `client.appBaseUrl()` is already normalized by\n * the door that answers it (the CLI-backed door wraps `resolveAppUrl()` in\n * `normalizeBaseUrl`; the hosted door returns the same expression it publishes\n * as its OAuth issuer, which cannot carry a trailing slash). Normalizing again\n * here would put a second opinion about the shape in the system, which is\n * exactly what one normalization point per door exists to prevent.\n *\n * ONE DEFINITION, BOTH DOORS. Nothing here branches on which door is calling.\n * The base URL is the only thing that differs between them, and it arrives as\n * an argument.\n *\n * EVERY LINK IS ABSOLUTE. These land in a chat transcript, where a path\n * relative to nothing is useless.\n *\n * AN UNBUILDABLE LINK IS `undefined`, NEVER A GUESS. Every builder returns\n * `undefined` when it cannot name a screen that exists, and callers spread the\n * field conditionally so the result simply carries no link. A link that lands\n * on a 404, or on the app's \"can't open that\" notice, is worse than no link:\n * it costs the person a click and teaches them the tool's links are unreliable.\n *\n * THE URL SHAPES ARE THE APP'S, NOT OURS. They mirror what the app routes\n * today: `/projects/{projectId}/flows/{flowId}` and\n * `/projects/{projectId}/deployments/{deploymentId}`, with a view on the flow\n * page addressed by the `view` query param whose value names a SUBJECT\n * (`variables`, `secrets`, `contract`, `history`, `releases`, `knowledge`,\n * `step`). A step is `?view=step&flow=<named flow>&step=<type.name>`, the same\n * vocabulary `hub_manage` already takes as its `flow` and `step` params.\n */\n\n/** A flow page: the address every flow-scoped view hangs off. */\nexport interface FlowLinkTarget {\n /** From `client.appBaseUrl()`. Consumed as given. */\n baseUrl: string;\n projectId: string;\n flowId: string;\n}\n\n/**\n * One step inside a flow. `flow` is the named flow within the config (\"web\",\n * \"server\"); `step` is `\"type.name\"`, e.g. `\"destination.ga4\"`.\n */\nexport interface StepLinkTarget extends FlowLinkTarget {\n step: string;\n /**\n * Null and undefined both mean \"the caller did not name one\", which is the\n * shape `hub_manage`'s step history answers with when it was not filtered by\n * flow.\n */\n flow?: string | null;\n}\n\n/** One discussion thread, addressed by what it hangs on. */\nexport interface ThreadLinkTarget extends FlowLinkTarget {\n anchorType: string;\n}\n\n/**\n * One deployment.\n *\n * Pass the `dep_...` id, not the slug. The detail route resolves either, but\n * the page's live-status stream matches on the id alone, so a slug link opens a\n * page whose status stream fails while the deployment is still deploying. This\n * builder does not inspect the value: naming the id is the caller's job.\n */\nexport interface DeploymentLinkTarget {\n baseUrl: string;\n projectId: string;\n deploymentId: string;\n}\n\n/**\n * Contract entries are top-level and carry no named flow, so they are not\n * `?view=step` addresses.\n */\nconst CONTRACT_PREFIX = 'contract.';\n\n/** Every address component has to be a non-empty string, or there is no link. */\nfunction addressable(...parts: string[]): boolean {\n return parts.every((part) => part !== '');\n}\n\nfunction flowPage(target: FlowLinkTarget): string | undefined {\n const { baseUrl, projectId, flowId } = target;\n if (!addressable(baseUrl, projectId, flowId)) return undefined;\n return `${baseUrl}/projects/${encodeURIComponent(projectId)}/flows/${encodeURIComponent(flowId)}`;\n}\n\n/**\n * A view on the flow page. `view` leads because it is the primary key: the\n * other params only mean anything beside it.\n */\nfunction flowView(\n target: FlowLinkTarget,\n view: string,\n params: Record<string, string> = {},\n): string | undefined {\n const page = flowPage(target);\n if (page === undefined) return undefined;\n const query = new URLSearchParams({ view, ...params });\n return `${page}?${query.toString()}`;\n}\n\nexport const links = {\n /** The flow page itself. `undefined` when any part of the address is empty. */\n flow(target: FlowLinkTarget): string | undefined {\n return flowPage(target);\n },\n\n /**\n * The screen showing one step.\n *\n * A `contract` step, in any of its spellings, is answered with the CONTRACT\n * view rather than a step address. `?view=step&step=contract.checkout` is a\n * legitimate address in the vocabulary this tool speaks, but the app has\n * deliberately deferred opening ONE contract entry and refuses that link with\n * a notice. `?view=contract` opens the contract editor the entry lives in,\n * which is the nearest screen that actually exists. A `flow` alongside a\n * contract step is a caller mistake (contract entries are top-level) and is\n * ignored rather than turned into a refused link.\n *\n * Otherwise a step needs its named flow: `type.name` alone is not unique in a\n * config holding both a web and a server flow, and the app resolves an\n * address without one to nothing and says so on screen. So an unnamed flow\n * yields `undefined` here. Callers that want the link can re-ask with `flow`.\n *\n * What this cannot check is whether the step is still IN that flow. The\n * address is resolved against the live config when the page opens, and a step\n * since renamed or removed gets a notice there rather than a broken screen.\n */\n step(target: StepLinkTarget): string | undefined {\n const { step, flow } = target;\n if (step === '') return undefined;\n if (step === 'contract' || step.startsWith(CONTRACT_PREFIX))\n return flowView(target, 'contract');\n if (typeof flow !== 'string' || flow === '') return undefined;\n return flowView(target, 'step', { flow, step });\n },\n\n /**\n * The release history of a flow.\n *\n * The app has no address for ONE release: `?view=releases` declares no params\n * and opens the list the release is a row of. That is the screen a person\n * asking about a release wants to be on, so this takes the flow and nothing\n * else rather than pretending to a precision the app does not have.\n */\n release(target: FlowLinkTarget): string | undefined {\n return flowView(target, 'releases');\n },\n\n /**\n * The screen a thread is read on.\n *\n * Only a release anchor can be addressed from the wire shape this tool\n * holds. The app renders release-anchored discussions inside the release\n * history, beside the release they hang on. Step and entity-action anchors\n * have no surface at all yet. A TAG anchor does have one, the knowledge list\n * on `?view=knowledge`, but only when the thread was captured in Tag Mode\n * and carries a frame: `HubThreadWire` has no `frameId`, so nothing here can\n * tell such a thread from one written over MCP against a null frame, and a\n * knowledge link would open a list the thread may be absent from. So\n * everything but a release anchor gets no link rather than a possibly empty\n * one.\n */\n thread(target: ThreadLinkTarget): string | undefined {\n if (target.anchorType !== 'release') return undefined;\n return flowView(target, 'releases');\n },\n\n /** One deployment's detail page. */\n deployment(target: DeploymentLinkTarget): string | undefined {\n const { baseUrl, projectId, deploymentId } = target;\n if (!addressable(baseUrl, projectId, deploymentId)) return undefined;\n return `${baseUrl}/projects/${encodeURIComponent(projectId)}/deployments/${encodeURIComponent(deploymentId)}`;\n },\n};\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DeploymentStatus, DeploymentType } from '@walkeros/cli';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactDisplayNames } from '../user-data.js';\nimport { links } from '../links.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n resolveDeploymentSlug,\n type DeploymentSummaryForResolver,\n type ListDeploymentsForResolver,\n} from './_resolvers.js';\nimport { resolveDefaultProject } from './project-context.js';\nimport {\n validateActionInput,\n assertParam,\n DEPLOY_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\n\nconst TITLE = 'Deploy Management';\nconst DESCRIPTION =\n 'Deploy walkerOS flows and manage deployments. ' +\n '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. ' +\n 'A finished deployment carries its status and, on failure, an errorMessage with the user-facing reason; use the get action to re-read it. ' +\n 'list supports cursor and limit for pagination. ' +\n 'delete removes an active deployment. ' +\n 'For get and delete pass flowId (required) plus optional slug to disambiguate when a flow has multiple active deployments. ' +\n \"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.\";\n\n// The list filters' values. The compiler holds each record equal to the\n// contract's enum, which the CLI types as DeploymentStatus and DeploymentType.\nconst DEPLOYMENT_STATUSES = {\n idle: true,\n deploying: true,\n published: true,\n active: true,\n stopped: true,\n failed: true,\n} satisfies Record<DeploymentStatus, true>;\n\nconst DEPLOYMENT_TYPES = {\n web: true,\n server: true,\n} satisfies Record<DeploymentType, true>;\n\n/** A record's keys, each narrowed to the record's key type. */\nfunction membersOf<T extends string>(members: Readonly<Record<T, true>>): T[] {\n return Object.keys(members).filter((key): key is T =>\n Object.hasOwn(members, key),\n );\n}\n\nconst inputSchema = {\n action: z\n .enum(['deploy', 'list', 'get', 'delete'])\n .describe('Deployment action to perform'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n flowId: z.string().optional().describe('Required for deploy, get, delete.'),\n slug: z\n .string()\n .optional()\n .describe(\n 'Deployment slug. Optional disambiguator for get/delete when the flow has multiple active deployments.',\n ),\n type: z\n .enum(membersOf(DEPLOYMENT_TYPES))\n .optional()\n .describe('Deployment type filter for list.'),\n status: z\n .enum(membersOf(DEPLOYMENT_STATUSES))\n .optional()\n .describe('Status filter for list.'),\n wait: z\n .boolean()\n .optional()\n .describe(\n '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.',\n ),\n flowName: z\n .string()\n .optional()\n .describe(\n 'Flow name for multi-settings flows. Only used with deploy action.',\n ),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n/**\n * The deployment's ID, however the response spells it: the deploy start body\n * carries `deploymentId`, the detail read carries `id`.\n *\n * The `slug` both bodies also carry is deliberately NOT an address here. The\n * detail route resolves a slug, but the page's live-status stream matches on\n * the id alone, so a slug link opens a page whose status stream fails on a\n * deployment that is still deploying. A response carrying neither id spelling\n * gets no link.\n */\nfunction deploymentAddress(data: unknown): string | undefined {\n if (data === null || typeof data !== 'object' || Array.isArray(data))\n return undefined;\n const record: Record<string, unknown> = { ...data };\n for (const key of ['id', 'deploymentId']) {\n const value = record[key];\n if (typeof value === 'string' && value !== '') return value;\n }\n return undefined;\n}\n\n/**\n * The deployment's page in the app.\n *\n * The project is resolved the way every other project-bound tool resolves it,\n * falling back to the door's default. That fallback is for the LINK only:\n * nothing here changes which project the call itself reads, and a door with no\n * default simply yields no link rather than a wrong one.\n */\nfunction deploymentUrl(\n client: ToolClient,\n projectId: string | undefined,\n data: unknown,\n): string | undefined {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (resolvedProjectId === undefined) return undefined;\n const deploymentId = deploymentAddress(data);\n if (deploymentId === undefined) return undefined;\n return links.deployment({\n baseUrl: client.appBaseUrl(),\n projectId: resolvedProjectId,\n deploymentId,\n });\n}\n\n/**\n * Attach the link to a response body without disturbing what it already\n * carries.\n *\n * The key is `appUrl`, and it may never be `url`. A deployment response\n * ALREADY carries `url`, and it means where this deployment is SERVING: the\n * app sets it to the deployment's target while published or active. Writing\n * the app page over it would silently replace a live endpoint with a UI link,\n * with nothing to signal that the meaning of the field had changed. `appUrl`\n * also names the `appBaseUrl()` seam it is built from.\n *\n * A non-object body (nothing the app returns today, but the client types are\n * `unknown`) is passed through untouched rather than wrapped.\n */\nfunction withAppUrl(data: unknown, appUrl: string | undefined): unknown {\n if (\n appUrl === undefined ||\n data === null ||\n typeof data !== 'object' ||\n Array.isArray(data)\n ) {\n return data;\n }\n return { ...data, appUrl };\n}\n\n/** One deployment summary, or none when a field the resolver reads is missing. */\nfunction readDeploymentSummary(value: unknown): DeploymentSummaryForResolver[] {\n if (!isRecord(value)) return [];\n const slug = stringField(value, 'slug');\n const type = stringField(value, 'type');\n const status = stringField(value, 'status');\n const updatedAt = stringField(value, 'updatedAt');\n return slug !== undefined &&\n type !== undefined &&\n status !== undefined &&\n updatedAt !== undefined\n ? [{ ...value, slug, type, status, updatedAt }]\n : [];\n}\n\nfunction listForResolver(\n client: ToolClient,\n projectId: string | undefined,\n): ListDeploymentsForResolver {\n return async (q) => {\n const resp = await client.listDeployments({\n projectId: projectId || q.projectId || undefined,\n flowId: q.flowId,\n });\n const deployments = isRecord(resp) ? resp.deployments : undefined;\n return Array.isArray(deployments)\n ? deployments.flatMap(readDeploymentSummary)\n : [];\n };\n}\n\nexport function createDeployManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'deploy_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => deployManageHandlerBody(client, input),\n };\n}\n\nasync function deployManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n projectId,\n flowId,\n slug,\n type,\n status,\n wait,\n flowName,\n cursor,\n limit,\n } = parsed.data;\n const validationError = validateActionInput(\n 'deploy_manage',\n action ?? '',\n { flowId, projectId },\n DEPLOY_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'deploy': {\n assertParam(flowId, 'flowId', 'deploy');\n // `projectId` travels with the deploy itself, not just with the link.\n // Without it the deploy resolved the door's default while the link\n // resolved the explicit id, so an explicit projectId that differed\n // from the default deployed in one project and linked into another,\n // and the project-scoped deployment route answered that link with a\n // 404.\n const result = await client.deploy({\n flowId,\n projectId,\n wait: wait ?? true,\n flowName,\n });\n // The deployment's own page, whether this call waited for a terminal\n // status or returned the id straight away. It is where the status the\n // hint tells the agent to re-read is shown, so the person can watch it\n // instead of asking again.\n const appUrl = deploymentUrl(client, projectId, result);\n return mcpResult(withAppUrl(redactDisplayNames(result), appUrl), {\n next: [\n 'Use deploy_manage with action \"get\" to check deployment status',\n ],\n });\n }\n\n case 'list': {\n const data = await client.listDeployments({\n projectId,\n flowId,\n type,\n status,\n cursor,\n limit,\n });\n return mcpResult(redactDisplayNames(data));\n }\n\n case 'get': {\n assertParam(flowId, 'flowId', 'get');\n const resolvedSlug = await resolveDeploymentSlug({\n projectId: projectId ?? '',\n flowId,\n slug,\n list: listForResolver(client, projectId),\n });\n const data = await client.getDeploymentBySlug({\n slug: resolvedSlug,\n projectId,\n });\n const appUrl = deploymentUrl(client, projectId, data);\n return mcpResult(withAppUrl(redactDisplayNames(data), appUrl));\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n const resolvedSlug = await resolveDeploymentSlug({\n projectId: projectId ?? '',\n flowId,\n slug,\n list: listForResolver(client, projectId),\n });\n const data = await client.deleteDeployment({\n slug: resolvedSlug,\n projectId,\n });\n return mcpResult(\n redactDisplayNames({\n deleted: true,\n ...fieldsOf(data),\n }),\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: deploy, list, get, delete`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerDeployTool(server: McpServer, client: ToolClient) {\n const spec = createDeployManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => deployManageHandlerBody(client, args),\n );\n}\n","/**\n * Internal helpers shared by deploy_manage actions. Not re-exported from the\n * tools barrel; leading underscore marks this as tool-module internal.\n *\n * All collaborators are passed in as arguments so unit tests can inject fakes\n * without relying on jest.mock. This keeps resolver tests local to the\n * resolver signature and avoids shared-mock drift.\n */\n\n/**\n * The subset of a deployment summary the resolver needs to decide 0 / 1 / many\n * and to surface a useful MULTIPLE_DEPLOYMENTS error. Kept structurally\n * compatible with the CLI's DeploymentSummaryForFlow.\n */\nexport interface DeploymentSummaryForResolver {\n slug: string;\n type: string;\n status: string;\n updatedAt: string;\n}\n\n/**\n * Dependency injected list function. Must return only non-deleted deployments\n * for the given project + flow. The production wiring calls\n * `listDeployments({ projectId, flowId })` from `@walkeros/cli`, which hits\n * the app API; the API excludes soft-deleted rows.\n */\nexport type ListDeploymentsForResolver = (q: {\n projectId: string;\n flowId: string;\n}) => Promise<DeploymentSummaryForResolver[]>;\n\n/**\n * Error thrown when a flow has 0 matching deployments, or when a caller passed\n * a slug that does not match any active deployment of the flow. The MCP layer\n * translates this into an mcpError with `code: 'NOT_FOUND'`.\n */\nexport class DeploymentNotFoundError extends Error {\n readonly code = 'NOT_FOUND';\n constructor(message: string) {\n super(message);\n this.name = 'DeploymentNotFoundError';\n }\n}\n\n/**\n * Error thrown when a flow has >= 2 active deployments and the caller did not\n * pass a slug. Carries a `details[]` list so the MCP layer can surface the\n * options to the user.\n */\nexport class MultipleDeploymentsError extends Error {\n readonly code = 'MULTIPLE_DEPLOYMENTS';\n readonly details: DeploymentSummaryForResolver[];\n constructor(message: string, details: DeploymentSummaryForResolver[]) {\n super(message);\n this.name = 'MultipleDeploymentsError';\n this.details = details;\n }\n}\n\n/**\n * Resolve a concrete deployment slug for a (projectId, flowId, slug?) tuple.\n *\n * Behavior:\n * - 0 matches: throws DeploymentNotFoundError.\n * - 1 match, no slug: returns the single slug.\n * - slug provided and matches: returns the slug.\n * - slug provided and does not match: throws DeploymentNotFoundError.\n * - >= 2 matches, no slug: throws MultipleDeploymentsError with details[].\n */\nexport async function resolveDeploymentSlug(args: {\n projectId: string;\n flowId: string;\n slug?: string;\n list: ListDeploymentsForResolver;\n}): Promise<string> {\n const matches = await args.list({\n projectId: args.projectId,\n flowId: args.flowId,\n });\n\n if (matches.length === 0) {\n throw new DeploymentNotFoundError(\n `No deployments found for flow ${args.flowId}`,\n );\n }\n\n if (args.slug !== undefined) {\n const hit = matches.find((m) => m.slug === args.slug);\n if (!hit) {\n throw new DeploymentNotFoundError(\n `No deployment with slug ${args.slug} in flow ${args.flowId}`,\n );\n }\n return hit.slug;\n }\n\n if (matches.length === 1) {\n return matches[0].slug;\n }\n\n throw new MultipleDeploymentsError(\n `Flow ${args.flowId} has ${matches.length} active deployments; pass slug to disambiguate`,\n matches.map((m) => ({\n slug: m.slug,\n type: m.type,\n status: m.status,\n updatedAt: m.updatedAt,\n })),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n SECRET_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\n\nconst TITLE = 'Secret Management';\nconst DESCRIPTION =\n 'Manage a flow’s managed secrets (the $secret.<NAME> values its steps reference at deploy/run time). ' +\n 'Actions: list (metadata only), set (create), update (rotate value), delete. ' +\n 'Secrets are write-mostly: values are encrypted at rest and are NEVER returned, listed, or echoed. ' +\n 'Reference a secret from a flow step as $secret.<NAME>. Credentials, tokens, and private keys must use $secret, not $env: ' +\n 'the deploy pipeline only injects values referenced as $secret.<NAME> into the server runner. Server flows only.';\n\nconst inputSchema = {\n action: z\n .enum(['list', 'set', 'update', 'delete'])\n .describe('Secret management action to perform'),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n flowId: z\n .string()\n .describe(\n 'Flow ID (flow_...) or config ID (cfg_...). Required for list, set, update, and delete: secrets are flow-scoped.',\n ),\n name: z\n .string()\n .regex(\n /^[A-Z_][A-Z0-9_]*$/,\n 'Secret name must be uppercase letters, digits, and underscores, starting with a letter or underscore.',\n )\n .optional()\n .describe(\n 'Secret name (UPPER_SNAKE_CASE). Required for set. Referenced in flows as $secret.<NAME>.',\n ),\n value: z\n .string()\n .min(1)\n .max(65536)\n .optional()\n .describe(\n 'Secret value (1-65536 chars). Required for set and update. Write-only: never returned or logged.',\n ),\n secretId: z\n .string()\n .optional()\n .describe(\n 'Secret ID (sec_...). Required for update and delete. Use action \"list\" to find it.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createSecretManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'secret_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => secretManageHandlerBody(client, input),\n };\n}\n\nasync function secretManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, projectId, flowId, name, value, secretId } = parsed.data;\n const validationError = validateActionInput(\n 'secret_manage',\n action ?? '',\n { flowId, name, value, secretId },\n SECRET_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId)\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n\n switch (action) {\n case 'list': {\n assertParam(flowId, 'flowId', 'list');\n const data = await client.listSecrets({\n projectId: resolvedProjectId,\n flowId,\n });\n return mcpResult(data, {\n next: [\n 'Reference a listed secret from a flow step as $secret.<NAME>.',\n 'Use action \"set\" to add a secret or \"update\" to rotate one.',\n ],\n });\n }\n\n case 'set': {\n assertParam(flowId, 'flowId', 'set');\n assertParam(name, 'name', 'set');\n assertParam(value, 'value', 'set');\n const created = await client.createSecret({\n projectId: resolvedProjectId,\n flowId,\n name,\n value,\n });\n // Response is metadata only; value is never echoed back.\n return mcpResult(created, {\n next: [`Reference it in this flow as $secret.${name}.`],\n });\n }\n\n case 'update': {\n assertParam(flowId, 'flowId', 'update');\n assertParam(secretId, 'secretId', 'update');\n assertParam(value, 'value', 'update');\n const updated = await client.updateSecret({\n projectId: resolvedProjectId,\n flowId,\n secretId,\n value,\n });\n return mcpResult(updated);\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n assertParam(secretId, 'secretId', 'delete');\n const deleted = await client.deleteSecret({\n projectId: resolvedProjectId,\n flowId,\n secretId,\n });\n return mcpResult(\n deleted && typeof deleted === 'object'\n ? deleted\n : { deleted: true, secretId },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, set, update, delete`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerSecretManageTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createSecretManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => secretManageHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport type { Journey, JourneyHop, JourneyBranch } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactNestedStrings } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\n\nconst TITLE = 'Observe Journeys';\nconst DESCRIPTION =\n 'Read the assembled, cross-runtime journeys for a flow that is currently being observed (an active Observe session). ' +\n 'Pass flowId; the active session is resolved for you (a flow has at most one). ' +\n '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. ' +\n '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). ' +\n 'When the flow has no active session the result is `{ sessionId: null, journeys: [], gaps: [] }` — start an Observe session in the app and drive traffic first, then read again. ' +\n 'Narrow with traceId (one trace) and limit (page cap, most recent kept; default 50). ' +\n 'Read-only.';\n\nconst inputSchema = {\n flowId: z\n .string()\n .describe('Flow to read journeys for (its active Observe session).'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n traceId: z\n .string()\n .optional()\n .describe('Return only the journeys for this trace id.'),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\n 'Max journeys to return (1-100, most recent kept). Defaults to 50.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/**\n * Neutralise ONLY the captured, event-controlled payload fields of a journey for\n * third-party LLM context, deep-wrapping every string inside them in\n * <user_data>. Everything else stays literal.\n *\n * The distinction is load-bearing, not cosmetic: `observe_journeys` takes\n * `traceId` as a filter input, so the trigger -> read -> filter-by-traceId loop\n * only works if `traceId` (and the other correlation handles the agent\n * references) comes back verbatim. Wrapping them would break re-querying.\n *\n * KEEP LITERAL (assembler/wire-generated correlation handles, enums, numbers, or\n * the user's own config vocabulary):\n * id, correlation, traceId, entry.eventId/sourceId/timestamp, hop.stepId,\n * stepType, eventId, parentEventId, status, terminalPhase, skipReason,\n * mappingKey, contractRule, consent/consentApplied (config category -> bool),\n * platform(s), branchId, batched/flushConfirmed, and every timestamp/duration/\n * seq/gap-bound number.\n *\n * WRAP (data captured off the live event stream, attacker-influenceable):\n * entry.name (inbound event name), hop.in, hop.out, hop.error, hop.calls,\n * hop.meta, and the same out/error/calls on each fan-out branch.\n *\n * A structure-aware transform rather than a key-skip over `redactNestedStrings`,\n * because a flat key skip is depth-agnostic: it would either wrap the correlation\n * handles (breaking the query loop) or, if it skipped keys like `stepId`\n * globally, leave a captured payload field that happens to be named `stepId`\n * unwrapped. Wrapping whole payload sub-trees keeps every correlation handle\n * literal AND wraps every captured string, whatever its key.\n */\nfunction redactJourneyPayloads(journeys: Journey[]): Journey[] {\n return journeys.map((journey) => ({\n ...journey,\n entry: {\n ...journey.entry,\n ...(journey.entry.name !== undefined && {\n name: redactNestedStrings(journey.entry.name),\n }),\n },\n hops: journey.hops.map(redactHopPayloads),\n }));\n}\n\nfunction redactHopPayloads(hop: JourneyHop): JourneyHop {\n return {\n ...hop,\n ...(hop.in !== undefined && { in: redactNestedStrings(hop.in) }),\n ...(hop.out !== undefined && { out: redactNestedStrings(hop.out) }),\n ...(hop.error !== undefined && { error: redactNestedStrings(hop.error) }),\n ...(hop.calls !== undefined && { calls: redactNestedStrings(hop.calls) }),\n ...(hop.meta !== undefined && { meta: redactNestedStrings(hop.meta) }),\n ...(hop.branches !== undefined && {\n branches: hop.branches.map(redactBranchPayloads),\n }),\n };\n}\n\nfunction redactBranchPayloads(branch: JourneyBranch): JourneyBranch {\n return {\n ...branch,\n ...(branch.out !== undefined && { out: redactNestedStrings(branch.out) }),\n ...(branch.error !== undefined && {\n error: redactNestedStrings(branch.error),\n }),\n ...(branch.calls !== undefined && {\n calls: redactNestedStrings(branch.calls),\n }),\n };\n}\n\nexport function createObserveJourneysToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'observe_journeys',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => observeJourneysHandlerBody(client, input),\n };\n}\n\nasync function observeJourneysHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { flowId, projectId, traceId, limit } = parsed.data;\n if (!flowId) {\n return mcpError(new Error('flowId is required for observe_journeys.'));\n }\n try {\n const result = await client.listJourneys({\n flowId,\n ...(projectId !== undefined && { projectId }),\n ...(traceId !== undefined && { traceId }),\n ...(limit !== undefined && { limit }),\n });\n // Wrap only the captured, event-controlled payload sub-trees (in/out/error/\n // calls/meta + entry.name) in <user_data> for third-party LLM context, while\n // keeping every correlation handle (traceId/stepId/eventId/mappingKey) and\n // enum/number literal so the agent can feed them straight back as filter\n // input. gaps are numeric + platform enum only, so they pass through, and\n // so does unattributed: platform enum, numbers, and stepIds from the user's\n // own config, with no captured event payload to wrap. Absent stays absent,\n // since \"no loss to report\" reads differently from an empty array.\n const safe = {\n sessionId: result.sessionId,\n flowId: result.flowId,\n assembledAt: result.assembledAt,\n journeys: redactJourneyPayloads(result.journeys),\n gaps: result.gaps,\n ...(result.unattributed !== undefined && {\n unattributed: result.unattributed,\n }),\n };\n return mcpResult(safe, {\n next:\n result.sessionId === null\n ? [\n 'No active Observe session for this flow. Start one in the app and drive traffic, then read again.',\n ]\n : [\n 'Inspect a single trace with traceId, or adjust the flow config and re-read to confirm the change.',\n ],\n });\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerObserveJourneysTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createObserveJourneysToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => observeJourneysHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAccessRefusal, isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { isFeatureDenial } from './feature-gate.js';\n\nimport type {\n ToolClient,\n ObserveSessionResult,\n ObserveLevel,\n} from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { isRecord, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\n\nconst TITLE = 'Observe Session';\n/**\n * Exported so the hosted plane can assert parity against this exact string\n * instead of retyping it.\n */\nexport const DESCRIPTION =\n 'Open, inspect, or end an Observe session: a time-boxed window on one flow that runtimes attach to as arms. ' +\n 'A preview arm streams from a browser, a container arm runs server-side, and both feed ONE shared journeys feed. ' +\n '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. ' +\n 'A flow has at most one session, so status/stop resolve it from flowId when sessionId is omitted. ' +\n 'Read the events with observe_journeys; this tool never returns event data and never judges whether events are correct.';\n\n/**\n * Hints carry the verb ladder rather than the description. Module constants so\n * the wording is one string per idea, quotable verbatim, and identical across\n * planes. Exported so the hosted plane imports them instead of retyping them,\n * which makes cross-plane parity a compiler concern.\n */\nexport const HINT_SIMULATE_FIRST =\n 'Simulate before preview: flow_simulate checks mapping with no browser.';\nexport const HINT_PREVIEW_STREAMS =\n 'Preview streams into this session: mint a link with flow_manage preview_regrant, then open it on your site.';\nexport const HINT_READ =\n 'Read with observe_journeys (flowId); it is the only read.';\nexport const HINT_STOP = 'End both arms with observe_session stop.';\nexport const HINT_EMPTY_FEED =\n 'recordsReceived is 0: nothing has reached the feed yet. Drive traffic on an attached arm.';\nexport const HINT_ENDED =\n 'Session ended and both arms detached. Start a new one with observe_session start.';\nexport const HINT_NO_WINDOW =\n 'No Observe session on this flow. Open one with observe_session start.';\n\nconst inputSchema = {\n action: z\n .enum(['start', 'status', 'stop'])\n .describe(\n 'start opens a session, status reports arm state, stop ends the whole session.',\n ),\n flowId: z.string().describe('Flow the Observe session runs on.'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n sessionId: z\n .string()\n .optional()\n .describe(\n 'Session to act on for status/stop. Optional; the flow has at most one session and it is resolved for you.',\n ),\n arms: z\n .object({\n container: z\n .literal(true)\n .optional()\n .describe(\n \"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.\",\n ),\n preview: z\n .string()\n .optional()\n .describe(\n \"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.\",\n ),\n })\n .optional()\n .describe(\n 'Which runtimes attach. Omit to attach the default preview arm; a web settings that references a server flow brings its container arm with it.',\n ),\n origins: z\n .array(z.string())\n .optional()\n .describe(\n 'Bare https origins (https://host[:port]) the session may ingest web events from.',\n ),\n level: z\n .enum(['off', 'standard', 'trace'])\n .optional()\n .describe(\"Container observation verbosity. Defaults to the app's own.\"),\n replace: z\n .boolean()\n .optional()\n .describe(\n \"Replace the flow's existing window instead of attaching to it. Re-provisions from the new config.\",\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\ninterface ArmsInput {\n container?: true;\n preview?: string;\n}\n\ninterface SettingsEntry {\n name: string;\n platform: 'web' | 'server';\n}\n\n/**\n * Read the settings summaries off a flow response. `getFlow` is typed\n * `Promise<unknown>` on the client, so it is read structurally:\n * anything that is not a well-formed settings entry is simply not a candidate.\n */\nfunction readSettings(flow: unknown): SettingsEntry[] {\n if (!isRecord(flow)) return [];\n const settings = flow.settings;\n if (!Array.isArray(settings)) return [];\n const entries: SettingsEntry[] = [];\n for (const entry of settings) {\n const name = stringField(entry, 'name');\n const platform = stringField(entry, 'platform');\n if (name === undefined) continue;\n if (platform !== 'web' && platform !== 'server') continue;\n entries.push({ name, platform });\n }\n return entries;\n}\n\n/**\n * Translate the arms shape onto the one field the session contract takes.\n *\n * The app derives a session's arms from the flow topology under a single\n * `settingsName`: a web settings that references a server flow provisions both\n * arms, a server settings provisions the container alone. So arms selects a\n * NAME here rather than toggling arms on the wire.\n */\nfunction resolveSettingsName(\n settings: SettingsEntry[],\n arms: ArmsInput | undefined,\n): string {\n if (arms?.preview !== undefined) {\n const named = settings.find((entry) => entry.name === arms.preview);\n if (!named) {\n throw new Error(\n `This flow has no settings named \"${arms.preview}\". Available: ${describeSettings(settings)}`,\n );\n }\n return named.name;\n }\n\n if (arms?.container === true) {\n const servers = settings.filter((entry) => entry.platform === 'server');\n const only = servers[0];\n if (!only) {\n throw new Error(\n `The container arm needs a server settings, and this flow has no server settings. Available: ${describeSettings(settings)}`,\n );\n }\n if (servers.length > 1) {\n throw new Error(\n `This flow has several server settings. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n }\n return only.name;\n }\n\n const webs = settings.filter((entry) => entry.platform === 'web');\n const onlyWeb = webs[0];\n if (onlyWeb && webs.length === 1) return onlyWeb.name;\n if (webs.length > 1) {\n throw new Error(\n `This flow has several web settings. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n }\n\n const onlySettings = settings[0];\n if (onlySettings && settings.length === 1) return onlySettings.name;\n throw new Error(\n `Could not pick a settings to observe. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n}\n\nfunction describeSettings(settings: SettingsEntry[]): string {\n if (settings.length === 0) return 'none';\n return settings\n .map((entry) => `${entry.name} (${entry.platform})`)\n .join(', ');\n}\n\n/**\n * Per-arm state derived from the response shape: a part being non-null is what\n * makes its arm attached. Connect secrets (the web credential, the container\n * env trio) stay out by construction.\n */\nfunction toArms(session: ObserveSessionResult) {\n return {\n preview: {\n attached: session.web !== null,\n settingsName: session.observedFlowName,\n activationUrl: session.web?.activationUrl ?? null,\n previewEnabled: session.web?.previewEnabled ?? false,\n },\n container: {\n attached: session.server !== null,\n settingsName: session.serverFlowName,\n endpoint: session.server?.endpoint ?? null,\n },\n };\n}\n\nfunction toSummary(session: ObserveSessionResult) {\n return {\n sessionId: session.id,\n flowId: session.flowId,\n status: session.status,\n errorMessage: session.errorMessage,\n expiresAt: session.expiresAt,\n recordsReceived: session.recordsReceived,\n arms: toArms(session),\n };\n}\n\nexport const SESSION_RESOLUTION_FAILED =\n \"Could not resolve this flow's Observe session because the journeys read that identifies it is unavailable. Pass sessionId explicitly to act on the session without that lookup.\";\n\n/**\n * Wraps a failed lookup while preserving the structured fields `mcpError`\n * renders, so the caller keeps the machine-readable code alongside the\n * recovery instruction. The original failure rides along as `cause`.\n */\nclass SessionResolutionError extends Error {\n readonly code: string | undefined;\n readonly details: unknown[] | undefined;\n\n constructor(message: string, cause: unknown) {\n super(message, { cause });\n this.name = 'SessionResolutionError';\n this.code = readStringField(cause, 'code');\n this.details = readArrayField(cause, 'details');\n }\n}\n\nfunction readStringField(source: unknown, key: string): string | undefined {\n if (source === null || typeof source !== 'object' || !(key in source))\n return undefined;\n const value = Reflect.get(source, key);\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction readArrayField(source: unknown, key: string): unknown[] | undefined {\n if (source === null || typeof source !== 'object' || !(key in source))\n return undefined;\n const value = Reflect.get(source, key);\n return Array.isArray(value) ? value : undefined;\n}\n\n/**\n * Resolve the flow's live window. `listJourneys` is the flow-keyed read the app\n * already exposes and its `sessionId` IS the flow's single active session, so\n * it doubles as the resolver: no second lookup contract is needed.\n *\n * That read depends on the observer, which status and stop themselves do not.\n * A failing lookup therefore reports the fallback rather than reading as \"this\n * flow has no session\", so stop stays reachable when the observer is down.\n */\nasync function resolveSessionId(\n client: ToolClient,\n options: { flowId: string; projectId?: string },\n): Promise<string | null> {\n try {\n const result = await client.listJourneys({\n flowId: options.flowId,\n ...(options.projectId !== undefined && { projectId: options.projectId }),\n limit: 1,\n });\n return result.sessionId;\n } catch (error) {\n // A refused caller is refused by the session read and end as well, so\n // passing sessionId would not help: let the refusal through unwrapped. The\n // handler reports it as is and attaches AUTH_HINT to an authentication\n // failure.\n if (\n isAuthenticationError(error) ||\n isAccessRefusal(error) ||\n isFeatureDenial(error)\n )\n throw error;\n const detail = error instanceof Error ? error.message : String(error);\n // Carry the structured fields across: `mcpError` reads `code` and\n // `details` off the thrown error, so a bare `new Error` would strip the\n // machine-readable code and leave callers only the prose.\n throw new SessionResolutionError(\n `${SESSION_RESOLUTION_FAILED} (${detail})`,\n error,\n );\n }\n}\n\nfunction resolveProjectId(\n client: ToolClient,\n projectId: string | undefined,\n): string | null {\n return projectId ?? client.getDefaultProject();\n}\n\nconst NO_DEFAULT_PROJECT_ERROR =\n 'No project ID given and no default project set. Pass projectId or set one with project_manage set_default.';\n\nexport function createObserveSessionToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'observe_session',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => observeSessionHandlerBody(client, input),\n };\n}\n\nasync function observeSessionHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n flowId,\n projectId,\n sessionId,\n arms,\n origins,\n level,\n replace,\n } = parsed.data;\n\n if (!flowId) {\n return mcpError(new Error('flowId is required for observe_session.'));\n }\n const resolvedProjectId = resolveProjectId(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n\n try {\n switch (action) {\n case 'start': {\n if (!client.startObserveSession) {\n return mcpError(\n new Error('observe_session start is not supported by this client.'),\n );\n }\n const settings = readSettings(\n await client.getFlow({\n flowId,\n projectId: resolvedProjectId,\n fields: ['settings'],\n }),\n );\n const settingsName = resolveSettingsName(settings, arms);\n const session = await client.startObserveSession({\n projectId: resolvedProjectId,\n flowId,\n settingsName,\n ...(origins !== undefined && { origins }),\n ...(level !== undefined && { level }),\n ...(replace !== undefined && { replace }),\n });\n return mcpResult(toSummary(session), {\n next: [HINT_SIMULATE_FIRST, HINT_PREVIEW_STREAMS, HINT_READ],\n });\n }\n\n case 'status': {\n if (!client.getObserveSession) {\n return mcpError(\n new Error(\n 'observe_session status is not supported by this client.',\n ),\n );\n }\n const resolvedSessionId =\n sessionId ??\n (await resolveSessionId(client, {\n flowId,\n projectId: resolvedProjectId,\n }));\n if (!resolvedSessionId) {\n return mcpResult(\n { sessionId: null, flowId },\n { next: [HINT_NO_WINDOW, HINT_SIMULATE_FIRST] },\n );\n }\n const session = await client.getObserveSession({\n projectId: resolvedProjectId,\n flowId,\n sessionId: resolvedSessionId,\n });\n return mcpResult(toSummary(session), {\n next:\n session.recordsReceived === 0\n ? [HINT_EMPTY_FEED, HINT_READ, HINT_STOP]\n : [HINT_READ, HINT_STOP],\n });\n }\n\n case 'stop': {\n if (!client.endObserveSession) {\n return mcpError(\n new Error('observe_session stop is not supported by this client.'),\n );\n }\n const resolvedSessionId =\n sessionId ??\n (await resolveSessionId(client, {\n flowId,\n projectId: resolvedProjectId,\n }));\n if (!resolvedSessionId) {\n return mcpResult(\n { sessionId: null, flowId, ended: false },\n { next: [HINT_NO_WINDOW] },\n );\n }\n await client.endObserveSession({\n projectId: resolvedProjectId,\n flowId,\n sessionId: resolvedSessionId,\n });\n return mcpResult(\n { sessionId: resolvedSessionId, flowId, ended: true },\n { next: [HINT_ENDED] },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${String(action)}. Use one of: start, status, stop`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerObserveSessionTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createObserveSessionToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => observeSessionHandlerBody(client, args),\n );\n}\n","import { isAuthenticationError, AUTH_HINT } from '../types.js';\n\n/** The code every door answers a plan or project gate with. */\nexport const FEATURE_NOT_AVAILABLE = 'FEATURE_NOT_AVAILABLE';\n\n/** The features a door can refuse a whole tool for. */\nexport type GatedFeature = 'hub' | 'frames';\n\nfunction codeOf(error: unknown): string | undefined {\n if (!(error instanceof Error) || !('code' in error)) return undefined;\n const code = error.code;\n return typeof code === 'string' ? code : undefined;\n}\n\n/**\n * A denial is recognised by its code, never by its wording: the two doors phrase\n * the refusal differently and only the code is contractual.\n */\nexport function isFeatureDenial(error: unknown): boolean {\n return codeOf(error) === FEATURE_NOT_AVAILABLE;\n}\n\n/**\n * Names the feature so an agent can tell the person what is missing. Enabling\n * it is a plan or project entitlement change made in the app, never something\n * a tool can do, and the hint says so instead of inviting a retry.\n */\nexport function featureDenialHint(feature: GatedFeature): string {\n return `The \"${feature}\" feature is not enabled for this project. Tell the person that \"${feature}\" needs a plan or project entitlement that unlocks it, which is changed in the app, not through this tool.`;\n}\n\n/**\n * One hint rule for the gated tools: a feature denial names the feature, an\n * authentication failure points at the auth tool, a NOT_FOUND points at\n * discovery, and anything else carries no hint. Each reads the error's\n * structured code or status, so a denial's wording never decides its hint.\n */\nexport function errorHint(\n error: unknown,\n feature: GatedFeature,\n notFoundHint: string,\n): string | undefined {\n if (isFeatureDenial(error)) return featureDenialHint(feature);\n if (isAuthenticationError(error)) return AUTH_HINT;\n if (codeOf(error) === 'NOT_FOUND') return notFoundHint;\n return undefined;\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { wrapUserData } from '../user-data.js';\nimport { links } from '../links.js';\nimport type {\n ToolClient,\n ReleaseRef,\n ReleaseDetailWire,\n StepHistoryWire,\n VersionAnnotationWire,\n HubThreadWire,\n KnowledgeEntryWire,\n ThreadAnchorType,\n} from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { inputIssuesMessage } from './parse-input.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { errorHint } from './feature-gate.js';\n\n/**\n * `hub_manage`: the time-and-why dimension of a flow over MCP.\n *\n * The rest of the MCP surface answers what a flow IS right now. Nothing else\n * exposes the version spine, so this is the only door an agent has to the\n * release history and the reasoning attached to it. It registers on the SAME\n * server instance as `flow_manage`, `package_get`, and the rest, which is what\n * lets an agent compose the two: current config from those tools, history and\n * rationale from this one.\n *\n * Reads are progressive: `releases` is a lean index and never carries a\n * snapshot, `release_get` opens exactly one release in full. The diff in\n * `release_get` is computed by the server from the two stored snapshots, never\n * supplied by the caller, because capture is optional by design and an\n * unannotated release's diff is the only truth left to read.\n *\n * `knowledge` is the page dimension of the same story: what people wrote on the\n * frames of a page in Tag Mode. It is addressed by frame and mark rather than\n * by flow, because a note outlives the flow it was written against and one page\n * carries notes about several. `pageKey` narrows to a whole page, resolved to\n * its frames server-side. It reads only. Writing one happens where the mark is,\n * and settling one is a person's call, the same rule the threads actions\n * follow.\n *\n * Writes are additive only. `rationale_set` replaces the human note on one\n * release and `note_add` appends to a discussion; this tool has no delete\n * action of any kind, and no way to resolve a thread. Resolving states that a\n * release settled a question, which is a person's call to make in the app.\n */\n\n// Caps and patterns the server enforces. Duplicated here so the schema can\n// describe them; the app's src/lib/hub/threads.ts, src/lib/versions/step-history.ts,\n// src/lib/hub/knowledge.ts and src/lib/api/schemas/frames.ts are the authority.\nconst MAX_ANNOTATION_TEXT_LENGTH = 4000;\nconst MAX_ANCHOR_KEY_LENGTH = 255;\nconst MAX_ANCHOR_LABEL_LENGTH = 255;\nconst MAX_STEP_HISTORY_LIMIT = 50;\nconst MAX_STEP_HISTORY_ENTRIES = 200;\nconst MAX_THREAD_LIMIT = 100;\nconst MAX_THREADS_WITH_MESSAGES = 20;\nconst MAX_SOURCE_KEY_LENGTH = 1024;\nconst MAX_MARK_ID_LENGTH = 200;\nconst FRAME_ID_PATTERN = /^frm_[A-Za-z0-9_-]{21}$/;\nconst THREAD_STATUSES = ['open', 'resolved'] as const;\n\nconst TITLE = 'Release History and Rationale';\n\n/**\n * Exported so a host asserts parity against this exact string instead of\n * retyping it.\n */\nexport const HUB_MANAGE_DESCRIPTION =\n 'Read a flow’s release history and the reasoning behind it: what each release changed, and why. ' +\n 'Actions: releases (lean index of a flow’s releases, newest first, no snapshots), ' +\n 'release_get (one release in full: its rationale plus a server-computed diff against the release before it), ' +\n 'step_history (which releases added, changed, or removed one step), ' +\n 'rationale_set (write the human rationale for one release; additive, nothing is ever deleted), ' +\n 'threads (the discussion anchored to one release, or every open discussion on the flow), ' +\n 'note_add (add a message to a thread, or open a new one on a release), ' +\n 'knowledge (read what people wrote on the marks of a page in Tag Mode: one page, one mark, or the whole project). ' +\n 'Threads are resolved by a person in the app, never here: this tool can only add to a discussion. ' +\n 'Knowledge is read-only here for the same reason, and is addressed by frame and mark rather than by flow. ' +\n 'Steps are addressed as \"type.name\", the same form flow_simulate takes, for example \"destination.ga4\", ' +\n '\"transformer.router\", \"source.browser\", \"store.session\", or \"contract.checkout\" for a contract entry. ' +\n 'This tool carries history only: use flow_manage for the current config and package_get for step schemas.';\n\nconst ACTIONS = [\n 'releases',\n 'release_get',\n 'step_history',\n 'rationale_set',\n 'threads',\n 'note_add',\n 'knowledge',\n] as const;\n\n/**\n * The anchors a caller may name here: the stored vocabulary MINUS `page`.\n *\n * A `page` anchor hangs on a FRAME, and every action here that opens a thread\n * opens it on a flow. The flow's threads response is parsed on the way out, so\n * a single page-anchored flow thread written from here would make the read fail\n * its own parse from then on, permanently, for everyone. Fencing the write is\n * what keeps that row from ever existing. Notes on a frame are written where\n * the frame is, never here.\n *\n * `satisfies` is the fence: the list is proved to be values the response\n * schemas can carry, so a member that only the storage layer knows about\n * cannot be added here without the wire contract moving first.\n */\nconst TOOL_ANCHOR_TYPES = [\n 'step',\n 'entity_action',\n 'release',\n 'contract',\n 'tag',\n] as const satisfies readonly ThreadAnchorType[];\n\n/**\n * One flat schema with an `action` enum and per-action optional fields, the\n * shape `flow_manage`, `project_manage`, and `secret_manage` already use.\n * Per-action requirements are enforced in the handler, so later actions add a\n * field and an enum member without reshaping what callers already send.\n *\n * Exported so the declarative registry holds the same object rather than a\n * second copy of it.\n */\nexport const HUB_MANAGE_INPUT_SCHEMA = {\n action: z\n .enum(ACTIONS, {\n error: () => `Unknown action. Use one of: ${ACTIONS.join(', ')}`,\n })\n .describe('Which part of the release history to read or write'),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n flowId: z\n .string()\n .optional()\n .describe(\n 'Flow ID (flow_...). Required for every action except \"knowledge\", which hangs on a page rather than a flow and refuses this field.',\n ),\n versionId: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Release version ID (ver_...) from action \"releases\". Addresses one release for release_get and rationale_set. Pass this or versionNumber.',\n ),\n versionNumber: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Spine release number for this flow, the `versionNumber` field of action \"releases\". Alternative to versionId. Not the same as a row\\'s deploymentAttempt.',\n ),\n step: z\n .string()\n .optional()\n .describe(\n 'Step key as \"type.name\", e.g. \"destination.ga4\" or \"contract.checkout\". Required for step_history.',\n ),\n flow: z\n .string()\n .optional()\n .describe(\n '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.',\n ),\n text: z\n .string()\n // Trimmed BEFORE the checks. Whitespace-only text otherwise satisfies\n // min(1) and then normalizes to empty downstream, which stores a blank\n // message, and on `rationale_set` reaches the annotation writer where\n // empty means CLEAR: the delete this additive-only tool does not have.\n .trim()\n .min(1)\n .max(MAX_ANNOTATION_TEXT_LENGTH)\n .optional()\n .describe(\n `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.`,\n ),\n limit: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n `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.`,\n ),\n offset: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Releases to skip. Action \"releases\" only.'),\n anchorType: z\n .enum(TOOL_ANCHOR_TYPES)\n .optional()\n .describe(\n '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.',\n ),\n anchorKey: z\n .string()\n .min(1)\n .max(MAX_ANCHOR_KEY_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n anchorLabel: z\n .string()\n .min(1)\n .max(MAX_ANCHOR_LABEL_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n threadId: z\n .string()\n .min(1)\n .optional()\n .describe(\n '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.',\n ),\n status: z\n .enum(THREAD_STATUSES)\n .optional()\n .describe(\n 'Read only threads in this state. Action \"threads\" only; omit for both.',\n ),\n pageKey: z\n .string()\n .min(1)\n .max(MAX_SOURCE_KEY_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n frameId: z\n .string()\n .regex(FRAME_ID_PATTERN)\n .optional()\n .describe(\n 'One frame (frm_...), the named rectangle a note hangs on. Action \"knowledge\" only. Narrower than pageKey, since a page holds several frames.',\n ),\n markId: z\n .string()\n .min(1)\n .max(MAX_MARK_ID_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n // False because of `note_add`, which APPENDS. `rationale_set` is an upsert\n // and repeating it is harmless, but this block covers the whole tool, and a\n // client that retries a timed-out call on the strength of an idempotent hint\n // would post the same remark twice into a human discussion. Nothing here is\n // destructive either way: a duplicate message can be read past, and there is\n // no delete to undo it with.\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n/**\n * Hints carry the verb ladder rather than the description. One constant per\n * sentence the tool can emit, so the surface fixture pins wording and ordering\n * by name and a reword fails a test instead of drifting.\n */\nexport const HUB_HINT_RELEASE_GET =\n 'Use action \"release_get\" with a versionId or versionNumber to read one release in full, with its diff.';\nexport const HUB_HINT_ROWS_ARE_DEPLOYMENTS =\n 'Rows are deployments, not releases: the same versionId on several rows is a redeploy of identical content, so count distinct versionId values, and note that total counts deployments.';\nexport const HUB_HINT_STEP_HISTORY =\n 'Use action \"step_history\" to see which releases touched one step.';\nexport const HUB_HINT_MASKED_ONLY =\n 'The diff is empty because the only changes are inside masked values. Say that the change is not visible here rather than that nothing changed.';\nexport const HUB_HINT_TRACE_STEP =\n 'Use action \"step_history\" to trace one step across releases.';\nexport const HUB_HINT_WRITE_RATIONALE =\n 'This release has no human rationale. Read the diff, then use action \"rationale_set\" to record why it changed.';\nexport const HUB_HINT_SCAN_CAPPED =\n 'The scan stopped at the entry cap, so older releases were not compared. Narrow with \"flow\" to see the whole history of one occurrence.';\nexport const HUB_HINT_NO_MATCH =\n 'No scanned release touched this step. Check the step key against knownSteps, or raise limit to scan further back.';\nexport const HUB_HINT_OPEN_RELEASE =\n 'Use action \"release_get\" on one of these versionIds to read the full diff and rationale.';\nexport const HUB_HINT_RATIONALE_VISIBLE =\n 'The rationale is now visible on this release in the app.';\nexport const HUB_HINT_CONFIRM_INDEX =\n 'Use action \"releases\" to confirm it appears in the index.';\nexport const HUB_HINT_THREADS_PAGE_CAPPED = `More threads match than were returned (the page is capped at ${MAX_THREADS_WITH_MESSAGES} when messages are attached). Narrow with anchorType and anchorKey, or with status, rather than treating this as the complete list.`;\nexport const HUB_HINT_NOTHING_DISCUSSED =\n 'Nothing is being discussed on this flow. Use action \"note_add\" with a versionId to start a thread on a release.';\nexport const HUB_HINT_NO_THREAD_ON_ANCHOR =\n 'No thread hangs on this anchor yet. Use action \"note_add\" to open one.';\nexport const HUB_HINT_THREADS_INDEX =\n 'This is an index: message bodies are omitted. Pass a versionId, or anchorType with anchorKey, to read one discussion in full.';\nexport const HUB_HINT_MESSAGES_TRUNCATED =\n 'A thread here is marked hasMoreMessages: only its newest messages were returned. Say the discussion is longer than what you read rather than summarizing it as complete.';\nexport const HUB_HINT_REPLY_OR_OPEN =\n 'Use action \"note_add\" with a threadId to reply in one of these threads, or without one to open another.';\nexport const HUB_HINT_RESOLVE_IN_APP =\n 'Resolving a thread into a release is done by a person in the app, not through this tool.';\nexport const HUB_HINT_MESSAGE_VISIBLE =\n 'The message is now visible in this thread in the app.';\nexport const HUB_HINT_STAYS_RESOLVED =\n 'This thread is resolved and stayed resolved: a reply never retracts the release link.';\nexport const HUB_HINT_READ_BACK =\n 'Use action \"threads\" to read the discussion back.';\nexport const HUB_HINT_THREAD_OPEN =\n 'The thread is now open on this anchor in the app.';\nexport const HUB_HINT_KEEP_ONE_THREAD =\n 'Pass its threadId back to action \"note_add\" to keep the conversation in one place instead of opening another thread.';\nexport const HUB_HINT_KNOWLEDGE_PAGE_CAPPED =\n 'More knowledge matches than was returned. Narrow with pageKey, then frameId, then markId, rather than treating this as everything that was written.';\nexport const HUB_HINT_NOTHING_WRITTEN =\n 'Nothing has been written here. Notes are left on the page in Tag Mode, not through this tool.';\nexport const HUB_HINT_KNOWLEDGE_INDEX =\n 'This is an index: message bodies are omitted. Pass markId with frameId to read one mark in full.';\nexport const HUB_HINT_ENTRY_NAMES_FLOW =\n 'An entry names the flow it was written against in flowId, and validity says which release was live at the time.';\nexport const HUB_HINT_KNOWLEDGE_READ_ONLY =\n 'This tool only reads knowledge. Answering a note, and settling it, are done by a person in the app.';\nexport const HUB_HINT_READ_FRAME =\n 'Use frame_manage action \"get\" with the frameId to read the frame and its marks.';\nexport const HUB_NOT_FOUND_HINT =\n 'Use action \"releases\" to find version ids and action \"threads\" to find thread ids.';\n\n/**\n * The same shape the transport validates against, applied again here.\n *\n * The MCP SDK does parse arguments before invoking a tool callback, but that\n * parse happens in whichever SDK copy the host linked, and this module's spec\n * is deliberately drivable without a transport at all. Parsing here is what\n * keeps the 4000-char cap and the additive-only guarantee inside this file:\n * `text: null` would otherwise reach the annotation writer, where null means\n * CLEAR, and quietly become the delete action this tool does not have.\n */\nconst hubInputSchema = z.object(HUB_MANAGE_INPUT_SCHEMA);\n\ntype HubInput = z.infer<typeof hubInputSchema>;\n\n/**\n * Why a call was refused. Carried as `code` so an agent can branch on the\n * denial it is most likely to hit instead of matching prose. A denial the\n * server raises, such as FEATURE_NOT_AVAILABLE, arrives with its own code and\n * never needs a member here.\n */\nexport type HubToolErrorCode = 'INVALID_INPUT' | 'NOT_FOUND';\n\nexport class HubToolError extends Error {\n constructor(\n public readonly code: HubToolErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'HubToolError';\n }\n}\n\nfunction requireParam<T>(\n value: T | undefined,\n name: string,\n action: string,\n): T {\n if (value === undefined) {\n throw new HubToolError(\n 'INVALID_INPUT',\n `${name} is required for action \"${action}\"`,\n );\n }\n return value;\n}\n\n/**\n * Resolve the release address a caller gave. `versionId` wins when both are\n * present, so an explicit id is never silently reinterpreted as a number.\n */\nfunction releaseRef(input: HubInput, action: string): ReleaseRef {\n if (input.versionId !== undefined) return { versionId: input.versionId };\n if (input.versionNumber !== undefined) {\n return { versionNumber: input.versionNumber };\n }\n throw new HubToolError(\n 'INVALID_INPUT',\n `versionId or versionNumber is required for action \"${action}\". Use action \"releases\" to find one.`,\n );\n}\n\n/**\n * Stored annotation text is written by people and lands in third-party model\n * context, so it is wrapped as data. Ids, numbers, and timestamps stay literal:\n * the agent has to echo them back verbatim in the next call.\n */\nfunction serializeAnnotation(annotation: VersionAnnotationWire) {\n return {\n versionId: annotation.versionId,\n humanText:\n annotation.humanText === null ? null : wrapUserData(annotation.humanText),\n generatedSummary:\n annotation.generatedSummary === null\n ? null\n : wrapUserData(annotation.generatedSummary),\n author: annotation.author,\n createdAt: annotation.createdAt,\n updatedAt: annotation.updatedAt,\n };\n}\n\n/**\n * The scan result as an index. An entry's own rationale text is not surfaced\n * here: `release_get` is the detail read, and repeating every note across a\n * fifty-release scan would make this the opposite of an index.\n */\nfunction serializeStepHistory(history: StepHistoryWire) {\n return {\n step: history.step,\n flow: history.flow,\n entries: history.entries.map((entry) => ({\n versionId: entry.versionId,\n versionNumber: entry.versionNumber,\n createdAt: entry.createdAt,\n flow: entry.flow,\n change: entry.change,\n })),\n scanned: history.scanned,\n truncated: history.truncated,\n entriesTruncated: history.entriesTruncated,\n // Step keys and flow names are addresses the caller passes straight back,\n // so they stay literal for the same reason ids do.\n ...(history.knownSteps !== undefined && { knownSteps: history.knownSteps }),\n };\n}\n\n/**\n * Thread text is written by people and lands in third-party model context, so\n * message bodies and the anchor label are wrapped as data. Ids, the status, and\n * timestamps stay literal: the agent echoes them back in the next call.\n */\nfunction serializeThread(thread: HubThreadWire) {\n return {\n threadId: thread.id,\n anchorType: thread.anchorType,\n anchorKey: thread.anchorKey,\n anchorLabel: wrapUserData(thread.anchorLabel),\n status: thread.status,\n // The release that settled it, null while open AND once that release is\n // gone. `status` is what separates those two, never this field.\n resolvedByVersionId: thread.resolvedByVersionId,\n resolvedByVersionNumber: thread.resolvedByVersionNumber,\n resolvedBy: thread.resolvedBy,\n createdBy: thread.createdBy,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n messageCount: thread.messageCount,\n ...(thread.messages !== undefined\n ? {\n // Set when the thread holds more than this call carried. The tail is\n // the OLD end: what is here is always the newest exchange.\n hasMoreMessages: thread.hasMoreMessages === true,\n messages: thread.messages.map((message) => ({\n author: message.author,\n text: wrapUserData(message.text),\n createdAt: message.createdAt,\n })),\n }\n : {}),\n };\n}\n\n/**\n * Knowledge is written on a live page and lands in third-party model context,\n * so the description body, the message bodies, the anchor's label, the frame's\n * name and the author's display name are wrapped as data. Ids, keys, the\n * derived validity and freshness, and timestamps stay literal: the agent\n * addresses the next call with the first and branches on the rest.\n *\n * The spatial placement is dropped rather than serialized. Its `element` is an\n * opaque DOM anchor captured from the page, of unbounded size and shape, and\n * the fractional point beside it only means something to something that draws\n * the overlay. Neither tells a reader here anything, and the first is page\n * content this tool would then have to wrap.\n */\nfunction serializeKnowledge(entry: KnowledgeEntryWire) {\n const shared = {\n id: entry.id,\n anchorType: entry.anchorType,\n anchorKey: entry.anchorKey,\n anchorLabel: wrapUserData(entry.anchorLabel),\n frameId: entry.frameId,\n /** A person names a frame, so the name is page content like any other. */\n frameName: entry.frameName === null ? null : wrapUserData(entry.frameName),\n /** The flow it was written against, or null. Never a filter. */\n flowId: entry.flowId,\n subjectKey: entry.subjectKey,\n /** When it was true, and whether it still is. Derived at read time. */\n validity: entry.validity,\n freshness: entry.freshness,\n author: {\n kind: entry.author.kind,\n id: entry.author.id,\n label: wrapUserData(entry.author.label),\n },\n source: entry.source,\n updatedAt: entry.updatedAt,\n };\n\n if (entry.kind === 'description') {\n return { ...shared, kind: entry.kind, body: wrapUserData(entry.body) };\n }\n\n return {\n ...shared,\n kind: entry.kind,\n status: entry.status,\n createdAt: entry.createdAt,\n messageCount: entry.messageCount,\n ...(entry.messages !== undefined\n ? {\n // Set when the thread holds more than this call carried, and only\n // meaningful beside the messages it describes.\n hasMoreMessages: entry.hasMoreMessages === true,\n messages: entry.messages.map((message) => ({\n author: message.author,\n text: wrapUserData(message.text),\n createdAt: message.createdAt,\n })),\n }\n : {}),\n };\n}\n\nasync function handleReleases(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const { releases, total } = await client.listReleases({\n projectId,\n flowId,\n ...(input.limit !== undefined && { limit: input.limit }),\n ...(input.offset !== undefined && { offset: input.offset }),\n });\n\n // The screen this index is of. Structured rather than only mentioned in a\n // hint, so an agent can hand it on as data instead of re-typing it out of\n // prose. Named `appUrl`, the one key every tool here emits a link under, so\n // it can never collide with a `url` that some response already uses for\n // something of its own.\n const appUrl = links.release({\n baseUrl: client.appBaseUrl(),\n projectId,\n flowId,\n });\n\n return mcpResult(\n {\n releases: releases.map((release) => ({\n // The spine address. `release_get` and `rationale_set` take this pair\n // and nothing else.\n versionId: release.flowVersionId,\n versionNumber: release.flowVersionNumber,\n deployment: release.deploymentSlug,\n deploymentType: release.deploymentType,\n // The publish attempt within that deployment lineage. Deliberately NOT\n // called a version: it addresses nothing in this tool, and a row\n // carrying two numbers both named \"version\" is a trap.\n deploymentAttempt: release.versionNumber,\n status: release.status,\n source: release.source,\n errorCode: release.errorCode,\n createdAt: release.createdAt,\n createdBy: release.createdBy,\n rationale: release.rationale\n ? {\n hasHumanText: release.rationale.hasHumanText,\n hasGeneratedSummary: release.rationale.hasGeneratedSummary,\n firstLine:\n release.rationale.firstLine === null\n ? null\n : wrapUserData(release.rationale.firstLine),\n }\n : null,\n })),\n total,\n ...(appUrl !== undefined && { appUrl }),\n },\n {\n next: [\n HUB_HINT_RELEASE_GET,\n HUB_HINT_ROWS_ARE_DEPLOYMENTS,\n HUB_HINT_STEP_HISTORY,\n ],\n },\n );\n}\n\nasync function handleReleaseGet(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const release = await client.getRelease({\n projectId,\n flowId,\n ref: releaseRef(input, 'release_get'),\n });\n\n // The rendered diff is built from MASKED content, so an empty diff does not\n // mean the releases are the same: a change confined to an inline secret\n // renders as nothing. `contentIdentical` is decided over unmasked content,\n // so it is the only trustworthy identity signal, and the gap between the two\n // is stated rather than left for the reader to infer.\n const contentIdentical =\n release.diff !== null && release.diff.contentIdentical;\n const maskedOnly =\n release.diff !== null && release.diff.text === '' && !contentIdentical;\n\n return mcpResult(\n {\n versionId: release.versionId,\n versionNumber: release.versionNumber,\n contentHash: release.contentHash,\n createdAt: release.createdAt,\n createdBy: release.createdBy,\n rationale: release.rationale\n ? serializeAnnotation(release.rationale)\n : null,\n diff: release.diff\n ? {\n prevVersionId: release.diff.prevVersionId,\n prevVersionNumber: release.diff.prevVersionNumber,\n // Config values are user-authored, and inline secrets are masked\n // before the text is built.\n text:\n release.diff.text === '' ? null : wrapUserData(release.diff.text),\n /** Compared over unmasked content, so this is the real answer. */\n contentIdentical,\n note: maskedOnly\n ? 'These releases differ, but only inside values that are masked in the diff, typically inline secrets. Do not report this release as unchanged.'\n : null,\n }\n : null,\n diffUnavailable: release.diff\n ? null\n : 'This is the flow’s oldest release, so there is nothing to diff it against.',\n },\n {\n next: maskedOnly\n ? [HUB_HINT_MASKED_ONLY]\n : release.rationale?.humanText\n ? [HUB_HINT_TRACE_STEP]\n : [HUB_HINT_WRITE_RATIONALE],\n },\n );\n}\n\nasync function handleStepHistory(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const step = requireParam(input.step, 'step', 'step_history');\n\n const history = await client.listStepHistory({\n projectId,\n flowId,\n step,\n ...(input.flow !== undefined && { flow: input.flow }),\n ...(input.limit !== undefined && { limit: input.limit }),\n });\n\n const next = history.entriesTruncated\n ? [HUB_HINT_SCAN_CAPPED]\n : history.entries.length === 0\n ? [HUB_HINT_NO_MATCH]\n : [HUB_HINT_OPEN_RELEASE];\n\n // The step on screen, linked only when the scan itself says the step is\n // still there.\n //\n // `history.flow` is the caller's own filter echoed back, unvalidated, so a\n // scan that named no flow gets no link (a step address without one resolves\n // to nothing in the app) and a scan that named a wrong one would otherwise\n // build an address the flow page opens and then refuses. Entries come back\n // newest first, so an empty scan found the step in no release at all, and a\n // newest entry of `removed` means the last thing that happened to it was its\n // removal. Both are exactly the cases the app answers with its \"not found in\n // this flow\" notice, and no link beats a link to a notice.\n //\n // The flow names on the ENTRIES are deliberately not used as the address\n // instead: they say where the step USED to live. What remains is a step\n // renamed since the newest release, which no signal in hand can catch; the\n // app names that on screen.\n const newest = history.entries[0];\n const stepIsLive = newest !== undefined && newest.change !== 'removed';\n const appUrl = stepIsLive\n ? links.step({\n baseUrl: client.appBaseUrl(),\n projectId,\n flowId,\n step: history.step,\n flow: history.flow,\n })\n : undefined;\n\n return mcpResult(\n {\n ...serializeStepHistory(history),\n ...(appUrl !== undefined && { appUrl }),\n },\n { next },\n );\n}\n\n/**\n * Every release address goes through the detail read, by id as much as by\n * number: it is the one call that proves the release belongs to THIS flow and\n * hands back the number the app shows. A sibling flow's id therefore meets\n * NOT_FOUND from the client before anything is written.\n */\nasync function resolveRelease(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n action: string,\n): Promise<ReleaseDetailWire> {\n return client.getRelease({\n projectId,\n flowId,\n ref: releaseRef(input, action),\n });\n}\n\nasync function handleRationaleSet(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const text = requireParam(input.text, 'text', 'rationale_set');\n const release = await resolveRelease(\n client,\n projectId,\n flowId,\n input,\n 'rationale_set',\n );\n\n const annotation = await client.setReleaseRationale({\n projectId,\n flowId,\n versionId: release.versionId,\n text,\n });\n\n return mcpResult(\n {\n versionId: annotation.versionId,\n versionNumber: release.versionNumber,\n rationale: serializeAnnotation(annotation),\n },\n { next: [HUB_HINT_RATIONALE_VISIBLE, HUB_HINT_CONFIRM_INDEX] },\n );\n}\n\n/** One anchor a thread hangs on, resolved from whatever the caller addressed. */\ninterface ResolvedAnchor {\n anchorType: ThreadAnchorType;\n anchorKey: string;\n anchorLabel: string;\n}\n\n/**\n * The anchor the caller addressed, or null when they addressed none.\n *\n * A release can be addressed the way every other action here takes one\n * (`versionId` / `versionNumber`), which is resolved through the flow so a\n * sibling flow's release is refused and the display label is derived from the\n * real release number rather than trusted from the caller. Any other anchor\n * type is taken as given: this tool cannot verify a step key against a config\n * it does not load, and a thread on a key that no longer exists is exactly what\n * `anchorLabel` and the unanchored bucket are for.\n */\nasync function resolveAnchor(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n action: string,\n): Promise<ResolvedAnchor | null> {\n const type = input.anchorType ?? 'release';\n\n if (type === 'release') {\n if (input.versionId === undefined && input.versionNumber === undefined) {\n if (input.anchorKey === undefined) return null;\n // An explicit key for a release anchor still has to be a release of this\n // flow, or the thread would point at nothing readable.\n const byKey = await client.getRelease({\n projectId,\n flowId,\n ref: { versionId: input.anchorKey },\n });\n return {\n anchorType: 'release',\n anchorKey: byKey.versionId,\n anchorLabel: `v${byKey.versionNumber}`,\n };\n }\n\n const release = await resolveRelease(\n client,\n projectId,\n flowId,\n input,\n action,\n );\n return {\n anchorType: 'release',\n anchorKey: release.versionId,\n anchorLabel: `v${release.versionNumber}`,\n };\n }\n\n if (input.anchorKey === undefined) return null;\n return {\n anchorType: type,\n anchorKey: input.anchorKey,\n anchorLabel: input.anchorLabel ?? input.anchorKey,\n };\n}\n\nasync function handleThreads(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const anchor = await resolveAnchor(\n client,\n projectId,\n flowId,\n input,\n 'threads',\n );\n\n // Message bodies come back only for ONE anchor. A whole-flow listing is an\n // index, and carrying every word ever written on every anchor would make it\n // the opposite of one.\n const { threads, hasMoreThreads } = await client.listThreads({\n projectId,\n flowId,\n includeMessages: anchor !== null,\n ...(anchor !== null\n ? { anchorType: anchor.anchorType, anchorKey: anchor.anchorKey }\n : {}),\n ...(input.status !== undefined && { status: input.status }),\n ...(input.limit !== undefined && {\n limit: Math.min(input.limit, MAX_THREAD_LIMIT),\n }),\n });\n\n const truncated = threads.some((thread) => thread.hasMoreMessages === true);\n\n // The page ceiling is not what the caller asked for: a read that carries\n // message bodies is clamped hard. Saying so keeps an agent from reporting a\n // truncated page as the whole of a flow's discussion.\n const pageHint = hasMoreThreads ? [HUB_HINT_THREADS_PAGE_CAPPED] : [];\n\n const next =\n threads.length === 0\n ? [\n anchor === null\n ? HUB_HINT_NOTHING_DISCUSSED\n : HUB_HINT_NO_THREAD_ON_ANCHOR,\n ]\n : anchor === null\n ? [...pageHint, HUB_HINT_THREADS_INDEX]\n : [\n ...pageHint,\n ...(truncated ? [HUB_HINT_MESSAGES_TRUNCATED] : []),\n HUB_HINT_REPLY_OR_OPEN,\n HUB_HINT_RESOLVE_IN_APP,\n ];\n\n // Where these are read. An anchored read links the anchor's own screen, and\n // only a release anchor can be addressed from the shape held here. An\n // unanchored read is the flow's whole discussion, which is read in the\n // release history, so it links that.\n const flowTarget = { baseUrl: client.appBaseUrl(), projectId, flowId };\n const appUrl =\n anchor === null\n ? links.release(flowTarget)\n : links.thread({ ...flowTarget, anchorType: anchor.anchorType });\n\n return mcpResult(\n {\n threads: threads.map(serializeThread),\n hasMoreThreads,\n ...(appUrl !== undefined && { appUrl }),\n },\n { next },\n );\n}\n\nasync function handleNoteAdd(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const text = requireParam(input.text, 'text', 'note_add');\n\n if (input.threadId !== undefined) {\n const thread = await client.addThreadMessage({\n projectId,\n flowId,\n threadId: input.threadId,\n text,\n });\n return mcpResult(\n { thread: serializeThread(thread) },\n {\n next: [\n HUB_HINT_MESSAGE_VISIBLE,\n thread.status === 'resolved'\n ? HUB_HINT_STAYS_RESOLVED\n : HUB_HINT_READ_BACK,\n ],\n },\n );\n }\n\n const anchor = await resolveAnchor(\n client,\n projectId,\n flowId,\n input,\n 'note_add',\n );\n if (anchor === null) {\n throw new HubToolError(\n 'INVALID_INPUT',\n 'note_add needs somewhere to write: pass threadId to reply, or versionId (or anchorType with anchorKey) to open a thread on an anchor.',\n );\n }\n\n const thread = await client.createThread({\n projectId,\n flowId,\n anchorType: anchor.anchorType,\n anchorKey: anchor.anchorKey,\n // A release anchor is labeled by the server from the release number, so the\n // label travels only for the other anchor types.\n ...(anchor.anchorType !== 'release' && { anchorLabel: anchor.anchorLabel }),\n text,\n });\n\n return mcpResult(\n { thread: serializeThread(thread) },\n { next: [HUB_HINT_THREAD_OPEN, HUB_HINT_KEEP_ONE_THREAD] },\n );\n}\n\nasync function handleKnowledge(\n client: ToolClient,\n projectId: string,\n input: HubInput,\n) {\n // Message bodies come back only for ONE mark, the rule `threads` follows for\n // one anchor: a page-wide or project-wide read is an index, and carrying\n // every word written on every mark would make it the opposite of one.\n const oneMark = input.markId !== undefined;\n\n // The server refuses a mark without its page rather than answering an\n // unnarrowed list, and that refusal carries its own code through mcpError.\n const { entries, hasMoreEntries } = await client.listKnowledge({\n projectId,\n includeMessages: oneMark,\n ...(input.pageKey !== undefined && { pageKey: input.pageKey }),\n ...(input.frameId !== undefined && { frameId: input.frameId }),\n ...(input.markId !== undefined && { markId: input.markId }),\n ...(input.limit !== undefined && { limit: input.limit }),\n });\n\n const truncated = entries.some(\n (entry) => entry.kind === 'thread' && entry.hasMoreMessages === true,\n );\n\n const pageHint = hasMoreEntries ? [HUB_HINT_KNOWLEDGE_PAGE_CAPPED] : [];\n\n const next =\n entries.length === 0\n ? [HUB_HINT_NOTHING_WRITTEN]\n : [\n ...pageHint,\n ...(oneMark\n ? truncated\n ? [HUB_HINT_MESSAGES_TRUNCATED]\n : []\n : [HUB_HINT_KNOWLEDGE_INDEX]),\n HUB_HINT_ENTRY_NAMES_FLOW,\n HUB_HINT_KNOWLEDGE_READ_ONLY,\n HUB_HINT_READ_FRAME,\n ];\n\n return mcpResult(\n { entries: entries.map(serializeKnowledge), hasMoreEntries },\n { next },\n );\n}\n\nexport async function hubManageHandler(client: ToolClient, rawInput: unknown) {\n try {\n // Parse, never assert: see the note on `hubInputSchema`. A raw ZodError\n // stringifies its whole issue list into `message`, so the issues are\n // rewritten as one readable line carrying the same code as every other\n // refusal here.\n const parsed = hubInputSchema.safeParse(rawInput ?? {});\n if (!parsed.success) {\n throw new HubToolError('INVALID_INPUT', inputIssuesMessage(parsed.error));\n }\n const input: HubInput = parsed.data;\n const { action } = input;\n\n const projectId = resolveDefaultProject(client, input.projectId);\n if (!projectId) {\n throw new HubToolError('INVALID_INPUT', NO_DEFAULT_PROJECT_ERROR);\n }\n\n if (action === 'knowledge') {\n // Nothing here narrows knowledge by flow. Taking the field and answering\n // with every page's notes anyway is the failure mode this refuses: the\n // caller asked for one flow's and would read the answer as that.\n if (input.flowId !== undefined) {\n throw new HubToolError(\n 'INVALID_INPUT',\n 'flowId does not narrow action \"knowledge\", which is addressed by frame and mark: pass pageKey, frameId or markId instead. Each entry names the flow it was written against.',\n );\n }\n return await handleKnowledge(client, projectId, input);\n }\n\n const flowId = requireParam(input.flowId, 'flowId', action);\n\n switch (action) {\n case 'releases':\n return await handleReleases(client, projectId, flowId, input);\n case 'release_get':\n return await handleReleaseGet(client, projectId, flowId, input);\n case 'step_history':\n return await handleStepHistory(client, projectId, flowId, input);\n case 'rationale_set':\n return await handleRationaleSet(client, projectId, flowId, input);\n case 'threads':\n return await handleThreads(client, projectId, flowId, input);\n case 'note_add':\n return await handleNoteAdd(client, projectId, flowId, input);\n }\n } catch (error) {\n // `mcpError` lifts a `code` property off the error, so a HubToolError and\n // whatever the client raises both surface their code without a branch here.\n return mcpError(error, errorHint(error, 'hub', HUB_NOT_FOUND_HINT));\n }\n}\n\n/**\n * The tool as data, so it can be driven without an MCP transport (tests, and\n * any in-process bridge).\n */\nexport function createHubManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'hub_manage',\n title: TITLE,\n description: HUB_MANAGE_DESCRIPTION,\n inputSchema: HUB_MANAGE_INPUT_SCHEMA,\n annotations,\n handler: (input) => hubManageHandler(client, input),\n };\n}\n\nexport function registerHubManageTool(server: McpServer, client: ToolClient) {\n const spec = createHubManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => hubManageHandler(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { redactNestedStrings, wrapUserData } from '../user-data.js';\nimport type { ToolClient, FrameLeanWire, FrameWire } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { inputIssuesMessage } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n FRAME_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { errorHint } from './feature-gate.js';\n\n/**\n * `frame_manage`: the place dimension of a measurement plan over MCP.\n *\n * A frame is a named rectangle over a page, with marks inside it. It answers\n * WHERE something is measured, which nothing else on this surface carries:\n * `flow_manage` holds the config, `hub_manage` holds the history and the\n * reasoning, and this holds the drawing those two are argued about on.\n *\n * Read-only, on purpose. A frame is drawn against a live page or an import,\n * and its geometry only means anything next to the pixels it was drawn on.\n * A tool that cannot see the page cannot place a rectangle on it, so writing\n * one from here would be guessing. Editing happens in Tag Mode or the app.\n *\n * Reads are progressive, the same ladder `hub_manage` uses. `list` is the lean\n * project index and never carries marks, because the marks of a whole project\n * are the largest thing this tool could return and are almost never what a\n * caller wanted. `page` opens one page's frames with their marks, and `get`\n * opens exactly one frame.\n *\n * It composes with `hub_manage` through ids: a tag id read here is the\n * `markId` that tool's \"knowledge\" action takes, which is why tag ids stay\n * literal while everything else inside the marks is wrapped as user data.\n */\n\n// Caps and patterns the server enforces. Duplicated here so the schema can\n// describe them; the app's src/lib/api/schemas/frames.ts is the authority.\nconst FRAME_ID_PATTERN = /^frm_[A-Za-z0-9_-]{21}$/;\nconst MAX_PAGE_KEY_CHARS = 1024;\n\nconst TITLE = 'Frames';\n\n/**\n * Exported so a host asserts parity against this exact string instead of\n * retyping it.\n */\nexport const FRAME_MANAGE_DESCRIPTION =\n 'Read the frames of a measurement plan: named rectangles with marks inside them, drawn in Tag Mode or in the app. ' +\n '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). ' +\n 'Read-only: frames are drawn and edited in Tag Mode or the app, never here. ' +\n '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. ' +\n '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’s own description and thread. ' +\n 'Use hub_manage action \"knowledge\" with a frameId or markId to read what people wrote on a frame. ' +\n 'A markId is a tag id: a tag’s 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.';\n\n/**\n * Exported so the declarative registry holds the same object rather than a\n * second copy of it.\n */\nexport const FRAME_MANAGE_INPUT_SCHEMA = {\n action: z\n .enum(['list', 'page', 'get'])\n .describe(\n 'list the project’s frames, read one page with marks, or read one frame',\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n pageKey: z\n .string()\n .min(1)\n .max(MAX_PAGE_KEY_CHARS)\n .optional()\n .describe(\n 'The page as its frames address it (the `source.key` of a page frame, usually the page URL without query). Required for page.',\n ),\n frameId: z\n .string()\n .regex(FRAME_ID_PATTERN)\n .optional()\n .describe(\n 'Frame ID (frm_...). Required for get. Use action \"list\" or \"page\" to find one.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/**\n * Hints carry the verb ladder rather than the description. One constant per\n * sentence the tool can emit, so the surface fixture pins wording and ordering\n * by name and a reword fails a test instead of drifting.\n */\nexport const FRAME_HINT_OPEN_PAGE_OR_GET =\n 'Use action \"page\" with a pageKey (a frame’s source.key) to read a page with marks, or action \"get\" with a frameId.';\nexport const FRAME_HINT_NAMES_ARE_DOCUMENTATION =\n 'Frame names are documentation; the marks inside a frame carry the meaning.';\nexport const FRAME_HINT_NONE_YET =\n 'This project has no frames yet. Frames are drawn in Tag Mode or the app, not through this tool.';\nexport const FRAME_HINT_MARK_SPACE =\n 'Tag geometry is fractional: a rect is 0..1 of its frame, and an at is 0..1 of its parent tag’s box, or of the frame for a root tag; a child frame sits inside its parent through placements[].rect.';\nexport const FRAME_HINT_READ_KNOWLEDGE =\n 'Use hub_manage action \"knowledge\" with frameId (and markId) to read what people wrote here. A markId is a tag id from these marks, and a tag’s threadRef is the id of its thread entry there.';\nexport const FRAME_HINT_NONE_ON_PAGE =\n 'No frames on this page. Check the pageKey against the source.key values from action \"list\".';\nexport const FRAME_HINT_EXTENDS_BASE =\n 'This frame extends another and stores only what it adds; read the base frame (extends) for the rest.';\nexport const FRAME_NOT_FOUND_HINT =\n 'Use action \"list\" or \"page\" to find frame ids.';\n\n/**\n * The two source keys that stay literal, and only those. `kind` is the\n * discriminator a reader branches on, and `key` is the pageKey the `page`\n * action takes, so it has to be echoed back verbatim. Every other string in a\n * source is text a reader only ever looks at: the page `url`, and the `fileKey`\n * and `nodeId` of an imported design. No action takes any of them, so they are\n * wrapped like any other value.\n */\nconst keepSourceAddress = (key: string): boolean =>\n key === 'kind' || key === 'key';\n\n/**\n * A placement's `selector` and `anchor` are opaque DOM anchors captured off a\n * live page, of unbounded size: page content a reader gains nothing from and\n * this tool would otherwise have to wrap. Only the rectangle is kept.\n *\n * `projectId` and `deletedAt` are dropped for a different reason: the caller\n * named the project, and a listing only ever carries live frames, so both\n * would be noise on every row.\n */\nfunction serializeLean(frame: FrameLeanWire) {\n return {\n id: frame.id,\n name: wrapUserData(frame.name),\n parentId: frame.parentId,\n extends: frame.extends,\n source: redactNestedStrings(frame.source, { skip: keepSourceAddress }),\n origin: frame.origin,\n flowId: frame.flowId,\n placements: frame.placements.map((placement) => ({\n id: placement.id,\n rect: placement.rect,\n })),\n size: frame.size,\n screenshot: frame.screenshot\n ? {\n assetId: frame.screenshot.assetId,\n capturedAt: frame.screenshot.capturedAt,\n size: frame.screenshot.size,\n dpr: frame.screenshot.dpr,\n capturedRect: frame.screenshot.capturedRect,\n }\n : null,\n version: frame.version,\n createdAt: frame.createdAt,\n updatedAt: frame.updatedAt,\n createdBy: frame.createdBy,\n updatedBy: frame.updatedBy,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The rule for everything inside a marks document, in one place.\n *\n * - An ADDRESS stays literal, because another tool consumes it and it has to\n * be passed back exactly as it came. A sanitised address names a tag the app\n * never stored, so cleaning one trades a working lookup for a silent miss.\n * - Everything else is text a person or a page wrote, and is always wrapped,\n * so it cannot close the envelope and be read as instructions.\n *\n * Marks are a passthrough record: the server checks nothing inside them, so a\n * client writes whatever keys and values it likes, and a name that means\n * \"identifier\" in a flow config means nothing here. An address is therefore\n * decided by WHERE a value lives and by WHAT it looks like, never by the\n * spelling of its key alone.\n *\n * Where: a marks document is `{ tags, note }`. `tags` is one flat list of tags,\n * related through `parentId`, and `note` is the frame's own description and\n * thread. Only the top-level fields of a tag in that list, and of that note, can\n * be addresses. Below them nothing is, whatever it is called: `id` inside an\n * anchor is `el.id` read off the host page, and `id` on a thread message is a\n * row id no tool takes, so both are text like their siblings.\n *\n * What: a value in an address position stays literal only when it has the shape\n * the app mints for that address. Nothing upstream enforces the shape, so a\n * sentence stored under `id` is text and is wrapped like any other. A real\n * address that falls outside the shape comes back wrapped too, which costs a\n * lookup and never leaks an instruction.\n *\n * A key this file does not name, at any level, is walked as text. Object keys\n * are client-written too, so a key keeps its spelling only when it is a plain\n * identifier (see {@link markKey}); any other key is wrapped like a value.\n */\n\n/**\n * A tag id as the app mints it, and nothing wider:\n *\n * - `<prefix>_<n>` from the editor (`nextMarkId` in `tag-plan/frames.ts`,\n * `freshId` in `tag-plan/write.ts`);\n * - `e_<entity>`, `...#data.v<n>` and `...#action.<n>` from a contract or observed\n * events (`tag-plan/contract.ts`, `tag-plan/infer.ts`);\n * - `<entity>-<n>`, a nested `.../<entity>-<n>`, `...#data.<n>`, `...#action.<n>`,\n * `...#context.<n>`, `globals#<n>` and `page#action.<n>` from a page read\n * (`tag-plan/walker-plan.ts`).\n *\n * No colon, which keeps the hub key `<frameId>:<markId>` parseable, and no\n * whitespace, quote or angle bracket. An entity name outside `[A-Za-z0-9_-]`\n * makes the last two minters spell an id this does not match, which then wraps.\n */\nconst TAG_ID_PATTERN =\n /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*(?:#(?:data\\.v?[0-9]+|action\\.[0-9]+|context\\.[0-9]+|[0-9]+))?$/;\n\n/** The longest mark id the hub accepts (`MAX_MARK_ID_LENGTH` in the app's\n * `src/lib/hub/knowledge.ts`), so a longer value cannot be a markId. */\nconst MAX_TAG_ID_CHARS = 200;\n\n/** A hub thread id as the app mints it: `thr_` plus a 21-character lowercase\n * alphanumeric nanoid (`src/lib/id.ts`, `src/lib/hub/knowledge.ts`). */\nconst THREAD_ID_PATTERN = /^thr_[a-z0-9]{21}$/;\n\nconst isTagId = (value: string): boolean =>\n value.length <= MAX_TAG_ID_CHARS && TAG_ID_PATTERN.test(value);\n\nconst isThreadId = (value: string): boolean => THREAD_ID_PATTERN.test(value);\n\n/** The fields of a tag that are addresses, each with the shape it must have. */\nconst TAG_ADDRESSES: ReadonlyMap<string, (value: string) => boolean> = new Map([\n // The tag id: the markId `hub_manage` action \"knowledge\" takes, which the\n // app joins to the frame id as the anchor key `<frameId>:<markId>`.\n ['id', isTagId],\n // The tag this one sits under, which is that tag's id: the only relation\n // between tags, so a reader joins it to `id` to rebuild the tree, and it is\n // a markId in its own right.\n ['parentId', isTagId],\n // The hub thread this tag's note thread became: the `id` of the thread\n // entry `hub_manage` action \"knowledge\" returns for this tag.\n ['threadRef', isThreadId],\n]);\n\n/** The fields of the frame note that are addresses. The note belongs to the\n * frame, which `hub_manage` addresses by frameId, so its one address is the hub\n * thread it became, read the same way as a tag's. */\nconst NOTE_ADDRESSES: ReadonlyMap<string, (value: string) => boolean> = new Map(\n [['threadRef', isThreadId]],\n);\n\n/** A key the app writes: a JavaScript-style identifier, dashes allowed for\n * attribute names, bounded in length. Such a key cannot close the envelope or\n * carry a sentence, so it stays readable. */\nconst MARK_KEY_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$-]{0,63}$/;\n\n/** A marks key as it is handed back: literal when it has the shape of a key the\n * app writes, wrapped as data otherwise. */\nconst markKey = (key: string): string =>\n MARK_KEY_PATTERN.test(key) ? key : wrapUserData(key);\n\n/** Text below the addresses: every string wrapped, every key through\n * {@link markKey}. */\nfunction walkText(value: unknown): unknown {\n if (typeof value === 'string') return wrapUserData(value);\n if (Array.isArray(value)) return value.map(walkText);\n if (!isRecord(value)) return value;\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n out[markKey(key)] = walkText(child);\n }\n return out;\n}\n\n/** Walks a marks document applying the rule above. */\nfunction walkMarks(marks: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(marks)) {\n if (key === 'tags' && Array.isArray(value)) {\n out[key] = value.map((tag) => walkAddressed(tag, TAG_ADDRESSES));\n } else if (key === 'note') {\n out[key] = walkAddressed(value, NOTE_ADDRESSES);\n } else {\n out[markKey(key)] = walkText(value);\n }\n }\n return out;\n}\n\n/**\n * One record whose own fields named in `addresses` stay literal when their\n * value has that address's shape. A value there without the shape, a string or\n * not, is not an address, so it is walked like anything else rather than passed\n * through unseen, and so is everything below the record's own fields. A value\n * that is not a record has no fields to address and is text.\n */\nfunction walkAddressed(\n value: unknown,\n addresses: ReadonlyMap<string, (value: string) => boolean>,\n): unknown {\n if (!isRecord(value)) return walkText(value);\n const out: Record<string, unknown> = {};\n for (const [key, field] of Object.entries(value)) {\n const isAddress = addresses.get(key);\n out[markKey(key)] =\n isAddress !== undefined && typeof field === 'string' && isAddress(field)\n ? field\n : walkText(field);\n }\n return out;\n}\n\nfunction serializeFrame(frame: FrameWire) {\n return {\n ...serializeLean(frame),\n marks: walkMarks(frame.marks),\n };\n}\n\n/**\n * The same shape the transport validates against, applied again here, on the\n * rule `hub_manage` states: this module's spec is deliberately drivable without\n * a transport, so the caps and the id pattern have to hold inside this file\n * rather than in whichever SDK copy a host linked.\n */\nconst frameInputSchema = z.object(FRAME_MANAGE_INPUT_SCHEMA);\n\n/**\n * Annotated so the `action` switch below is checked for exhaustiveness: a\n * member added to the enum without a case makes the function fall off its end,\n * which a declared non-undefined return type refuses.\n */\ntype FrameManageResult =\n | ReturnType<typeof mcpResult>\n | ReturnType<typeof mcpError>;\n\nasync function frameManageHandler(\n client: ToolClient,\n rawInput: unknown,\n): Promise<FrameManageResult> {\n // Parse, never assert: a raw ZodError stringifies its whole issue list into\n // `message`, so the issues are rewritten as one readable line.\n const parsed = frameInputSchema.safeParse(rawInput ?? {});\n if (!parsed.success) {\n return mcpError(new Error(inputIssuesMessage(parsed.error)));\n }\n const { action, projectId, pageKey, frameId } = parsed.data;\n const validationError = validateActionInput(\n 'frame_manage',\n action,\n { pageKey, frameId },\n FRAME_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n\n try {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n\n switch (action) {\n case 'list': {\n const { frames } = await client.listFrames({\n projectId: resolvedProjectId,\n });\n return mcpResult(\n { frames: frames.map(serializeLean) },\n {\n next:\n frames.length === 0\n ? [FRAME_HINT_NONE_YET]\n : [\n FRAME_HINT_OPEN_PAGE_OR_GET,\n FRAME_HINT_NAMES_ARE_DOCUMENTATION,\n ],\n },\n );\n }\n case 'page': {\n assertParam(pageKey, 'pageKey', 'page');\n const { frames } = await client.listPageFrames({\n projectId: resolvedProjectId,\n pageKey,\n });\n return mcpResult(\n { pageKey, frames: frames.map(serializeFrame) },\n {\n next:\n frames.length === 0\n ? [FRAME_HINT_NONE_ON_PAGE]\n : [FRAME_HINT_MARK_SPACE, FRAME_HINT_READ_KNOWLEDGE],\n },\n );\n }\n case 'get': {\n assertParam(frameId, 'frameId', 'get');\n const frame = await client.getFrame({\n projectId: resolvedProjectId,\n frameId,\n });\n return mcpResult(\n { frame: serializeFrame(frame) },\n {\n next:\n frame.extends !== null\n ? [FRAME_HINT_EXTENDS_BASE, FRAME_HINT_READ_KNOWLEDGE]\n : [FRAME_HINT_READ_KNOWLEDGE],\n },\n );\n }\n }\n } catch (error) {\n // `mcpError` lifts a `code` property off the error, so whatever the client\n // raises surfaces its code without a branch here.\n return mcpError(error, errorHint(error, 'frames', FRAME_NOT_FOUND_HINT));\n }\n}\n\n/**\n * The tool as data, so it can be driven without an MCP transport (tests, and\n * any in-process bridge).\n */\nexport function createFrameManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'frame_manage',\n title: TITLE,\n description: FRAME_MANAGE_DESCRIPTION,\n inputSchema: FRAME_MANAGE_INPUT_SCHEMA,\n annotations,\n handler: (input) => frameManageHandler(client, input),\n };\n}\n\nexport function registerFrameManageTool(server: McpServer, client: ToolClient) {\n const spec = createFrameManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => frameManageHandler(client, args),\n );\n}\n","import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackageSchema } from '@walkeros/core';\nimport { fetchCatalog, getPackageBaseUrl } from '../catalog.js';\n\nexport function registerPackageSchemaResources(server: McpServer) {\n const template = new ResourceTemplate('walkeros://schema/{packageName}', {\n list: async () => {\n const { entries } = await fetchCatalog({ baseUrl: getPackageBaseUrl() });\n return {\n resources: entries.map((pkg) => ({\n uri: `walkeros://schema/${encodeURIComponent(pkg.name)}`,\n name: pkg.name,\n description: `Schema and examples for ${pkg.name}`,\n mimeType: 'application/json' as const,\n })),\n };\n },\n });\n\n server.registerResource(\n 'package-schema',\n template,\n {\n title: 'walkerOS Package Schema',\n description:\n 'JSON Schema and configuration examples for walkerOS packages',\n mimeType: 'application/json',\n },\n async (uri, { packageName }) => {\n const info = await fetchPackageSchema(\n decodeURIComponent(packageName as string),\n );\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'application/json' as const,\n text: JSON.stringify(info, null, 2),\n },\n ],\n };\n },\n );\n}\n","/**\n * Reference resources — pure schema and structural data only.\n *\n * Design principle: resources are loaded into context and should contain\n * only schemas, type definitions, and structural references. Behavioral\n * guidance, tutorials, and step-by-step instructions belong in prompts.\n * Vendor-specific examples belong in packages (fetched via package_get).\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { schemas } from '@walkeros/core/dev';\nimport { fetchCatalog, getPackageBaseUrl } from '../catalog.js';\nimport type { ToolClient } from '../tool-client.js';\n\nconst OPENAPI_URI = 'walkeros://reference/openapi';\n\n/** The live OpenAPI document as text, or why it is unavailable. */\nasync function openapiText(\n client: ToolClient,\n): Promise<{ text: string; mimeType: string }> {\n if (!client.openapiDocument) {\n return {\n text: 'openapi document unavailable: no openapi document on this client',\n mimeType: 'text/plain',\n };\n }\n try {\n const document = await client.openapiDocument();\n return {\n text: JSON.stringify(document, null, 2),\n mimeType: 'application/json',\n };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return {\n text: `openapi document unavailable: ${reason}`,\n mimeType: 'text/plain',\n };\n }\n}\n\nexport function registerReferenceResources(\n server: McpServer,\n client: ToolClient,\n) {\n // Flow Schema reference (generated from Zod)\n server.resource(\n 'flow-schema',\n 'walkeros://reference/flow-schema',\n {\n description:\n 'JSON Schema for Flow.Json — the complete flow configuration structure',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/flow-schema',\n text: JSON.stringify(schemas.configJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Event Model reference (generated from Zod)\n server.resource(\n 'event-model',\n 'walkeros://reference/event-model',\n {\n description:\n 'JSON Schema for walkerOS events: entity-action naming, data, context, globals, user, consent',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/event-model',\n text: JSON.stringify(schemas.eventJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Mapping reference (generated from Zod — composite of related schemas)\n server.resource(\n 'mapping',\n 'walkeros://reference/mapping',\n {\n description:\n 'JSON Schemas for walkerOS mapping: rules, valueConfig, rule, policy',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/mapping',\n text: JSON.stringify(\n {\n rules: schemas.rulesJsonSchema,\n valueConfig: schemas.valueConfigJsonSchema,\n rule: schemas.ruleJsonSchema,\n policy: schemas.policyJsonSchema,\n },\n null,\n 2,\n ),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Consent reference (generated from Zod)\n server.resource(\n 'consent',\n 'walkeros://reference/consent',\n {\n description:\n 'JSON Schema for walkerOS consent: destination-level and field-level consent gating',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/consent',\n text: JSON.stringify(schemas.consentJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Variables reference (hand-maintained — runtime interpolation patterns not captured in Zod schemas)\n server.resource(\n 'variables',\n 'walkeros://reference/variables',\n {\n description:\n 'walkerOS variable patterns: $var, $env, $contract, $code, $store, $secret substitution',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/variables',\n text: JSON.stringify(\n {\n separatorRule:\n '`.` for names and paths; `:` for literal values or raw-code payloads.',\n patterns: {\n '$var.name':\n 'Variable reference. Whole-string preserves native type (object, array, scalar). Inline interpolation requires a scalar. Reusable fragments (mapping templates, matcher lists, consent objects) live in the variables block and are referenced by name.',\n '$var.name.deep.path':\n 'Deep-path access into a structured variable. Walks nested keys/indices. Whole-string preserves type at the leaf; inline still requires a scalar leaf.',\n '$env.NAME':\n 'Environment variable, resolved at bundle/deploy time. $env.GA_ID reads process.env.GA_ID. Use for non-secret config (IDs, hostnames, regions), never for credentials.',\n '$env.NAME:default':\n 'Environment variable with fallback. $env.GA_ID:G-DEFAULT (the `:` is the literal default separator).',\n '$contract.name':\n 'Contract reference. Links to a named contract for validation.',\n '$contract.name.path':\n 'Nested contract access. $contract.ecommerce.product.',\n '$code:(expr)':\n 'Inline JavaScript. $code:(event) => event.data.price * 100 (the `:` carries the raw-code payload).',\n '$store.storeId':\n 'Store injection in env values. Wires runtime store access.',\n '$secret.NAME':\n 'Managed secret injection (created via the secret manager). The deploy pipeline detects $secret.NAME references and injects the secret value into the server runner’s environment at runtime. Use for credentials, tokens, and private keys. Server flows only; $env does NOT inject managed secrets.',\n },\n cascade: {\n priority: [\n '1. Step-level variables (highest)',\n '2. Flow-level variables',\n '3. Config-level variables (lowest)',\n ],\n example: {\n variables: {\n apiUrl: 'https://x.io',\n mapping: { id: 'data.id' },\n },\n flows: {\n production: {\n destinations: {\n api: {\n config: {\n url: '$var.apiUrl',\n idPath: '$var.mapping.id',\n },\n },\n },\n },\n },\n },\n },\n },\n null,\n 2,\n ),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Contract reference (generated from Zod)\n server.resource(\n 'contract',\n 'walkeros://reference/contract',\n {\n description:\n 'JSON Schema for walkerOS contracts: event schema validation with entity-action keying',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/contract',\n text: JSON.stringify(schemas.contractJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Examples reference (loaded from @walkeros/cli at runtime)\n server.resource(\n 'examples',\n 'walkeros://reference/examples',\n {\n description:\n 'Complete, tested flow config (flow-complete.json): web, server and warehouse flows with mapping, consent, contracts, routes, state, stores and step examples. Its guide is examples/flow-complete.md in @walkeros/cli.',\n mimeType: 'application/json',\n },\n async () => {\n let example: string;\n try {\n const { readFileSync } = await import('fs');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n const examplePath =\n require.resolve('@walkeros/cli/examples/flow-complete.json');\n example = readFileSync(examplePath, 'utf-8');\n } catch {\n example = JSON.stringify({ error: 'Example not found' });\n }\n return {\n contents: [\n {\n uri: 'walkeros://reference/examples',\n text: example,\n mimeType: 'application/json',\n },\n ],\n };\n },\n );\n\n // The live OpenAPI 3.1 document of the app the client talks to, read on\n // each request, so it always describes the backend the tools reach.\n server.resource(\n 'openapi',\n OPENAPI_URI,\n {\n description:\n 'walkerOS cloud API: the live OpenAPI 3.1 document of the app this server talks to',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [{ uri: OPENAPI_URI, ...(await openapiText(client)) }],\n }),\n );\n\n // Packages catalog resource\n server.resource(\n 'packages',\n 'walkeros://reference/packages',\n {\n description:\n 'Complete walkerOS package catalog — all sources, destinations, transformers, and stores',\n mimeType: 'application/json',\n },\n async () => {\n const { entries } = await fetchCatalog({ baseUrl: getPackageBaseUrl() });\n return {\n contents: [\n {\n uri: 'walkeros://reference/packages',\n text: JSON.stringify(entries, null, 2),\n mimeType: 'application/json',\n },\n ],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerAddStepPrompt(server: McpServer) {\n server.registerPrompt(\n 'add-step',\n {\n description:\n 'Add a source, destination, transformer, or store step to a flow configuration. ' +\n 'Guides through package selection, config scaffolding, and wiring.',\n argsSchema: {\n stepType: z\n .string()\n .optional()\n .describe(\n 'Type of step to add: source, destination, transformer, or store',\n ),\n flowPath: z\n .string()\n .optional()\n .describe('Path to the flow.json file to modify'),\n },\n },\n async ({ stepType, flowPath }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me add a ${stepType || 'new'} step to my flow${flowPath ? ` at ${flowPath}` : ''}.`,\n '',\n 'Follow these steps:',\n `1. ${stepType ? '' : 'Ask what type of step (source, destination, transformer, store). Then '}Use package_search to browse available packages for the selected type and platform.`,\n '2. Use package_get to read the package\\'s config schema (schemas.config contains the full config shape: base fields like consent/require/logger + package-specific settings). Use section=\"hints\" for additional guidance.',\n '3. Use package_get with section=\"examples\" to see working configuration examples.',\n '4. Scaffold the step config using the package schemas — include required settings with placeholder values.',\n '5. Wire the step into the flow: add to packages section (with version if needed), connect via next/before chains if needed.',\n '6. For destinations: configure mapping using nested entity → action keys. Event \"product add\" maps to `{ \"product\": { \"add\": { name: \"AddToCart\" } } }`. Use the setup-mapping prompt for guidance.',\n '7. For destinations: if consent-gated loading is needed, add require: [\"consent\"] to config. ' +\n 'Note: require delays initialization until a \"walker consent\" event fires. ' +\n 'When simulating with flow_simulate, destinations with require will error \"not found\" — ' +\n 'remove require temporarily or test without it. ' +\n 'For per-event consent filtering, add consent: { marketing: true } to config.',\n '8. Use flow_validate to verify the result.',\n '9. For server sources: check if the package supports `ingest` configuration via package_get. Ingest extracts request metadata (IP, user-agent, headers) using mapping syntax. Transformers like fingerprint depend on ingest data.',\n '10. When adding a transformer that uses ingest fields, verify the source has `ingest` configured — otherwise ingest fields resolve to empty values.',\n '',\n 'Important:',\n '- Read the walkeros://reference/flow-schema resource to understand connection rules.',\n '- Sources connect to transformers via `next` (runs before the collector).',\n '- The collector connects to transformers via `collector.next` (runs once per event before the destination fan-out, for every destination).',\n '- Destinations connect to transformers via `before` (runs for that destination only; put per-destination filtering here).',\n '- Routing uses one grammar in every chain field: string IDs, sequences (`[\"a\", \"b\"]`, where a member\\'s own `next` runs right after it), or RouteConfig (`{ match?, next }` for a gated link, `{ match?, one: [...] }` for first-match dispatch, `{ match?, many: [...] }` to fork each match into its own copy that finishes the rest of the path, `{ match?, stop: true }` to drop). A `stop` in `collector.next` drops the event for all destinations. Omit `match` for always-match.',\n '- A transformer entry can be code-bearing (`code`), package-bearing (`package`), or a **pass-through step** (no `code`, no `package`). Pass-through synthesis is automatic at runtime. Three flavors of pass-through: `before`/`next`-only (named hop reusable across destinations), `cache`-only (dedup, rate-limit), or `mapping`-only (declarative event-to-event transform). A pass-through must declare at least one of `before`, `next`, `cache`, or `mapping`.',\n '- The `mapping` field on a transformer step uses the same `Mapping.Config` shape as destinations, but the semantic is event-to-event (mutates the event in place via `policy`, per-rule `policy`, `mapping[].name` for renames, `mapping[].ignore` to drop). Vendor-payload fields (`data`, `silent`) are no-ops at this position.',\n '- Closed schema: unknown top-level keys on a transformer step are errors (catches typos like `dedup` instead of `cache`). `code` + `package` together is a conflict.',\n '- Stores are passive — referenced via `$store.storeName` in env values.',\n '- Use variables ($var) for values that change between environments.',\n '- For required settings without defaults in the package schema, ask the user which value to use. Do not guess credentials, IDs, or environment-specific values.',\n '- If $meta.exports lists named exports, set the `code` field on the step to the chosen export name. If only one export exists, use it automatically.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerSetupMappingPrompt(server: McpServer) {\n server.registerPrompt(\n 'setup-mapping',\n {\n description:\n 'Set up event mapping for any step in a flow. Teaches mapping syntax and uses package examples as templates.',\n argsSchema: {\n stepName: z\n .string()\n .optional()\n .describe('Step name in the flow (e.g., \"gtag\", \"meta\", \"express\")'),\n },\n },\n async ({ stepName }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me set up mapping${stepName ? ` for the \"${stepName}\" step` : ''}.`,\n '',\n 'Follow these steps:',\n '1. Read the walkeros://reference/mapping resource for syntax reference.',\n `2. ${stepName ? `Identify the package for \"${stepName}\" in the flow, then u` : 'U'}se package_get with section=\"examples\" to see the source output shape — mapping keys must match the actual events the source emits.`,\n '3. Ask whether this is source mapping (raw input → walkerOS events) or destination mapping (walkerOS events → vendor format).',\n '4. Ask which events to map (one at a time, not all at once).',\n '5. Generate one mapping rule using the package examples as templates. Validate it with flow_validate before moving to the next.',\n '6. Repeat for each event.',\n '',\n 'Mapping uses nested entity → action keys. Event \"product add\" maps to `{ \"product\": { \"add\": Rule } }`. Wildcards: `{ \"*\": { \"view\": Rule } }`.',\n '',\n 'Extract shared mapping shapes into variables, reference via $var.name (deep paths supported).',\n '',\n 'Policy and consent in mapping:',\n '- config.policy runs BEFORE mapping rules — use it to inject or redact fields on the event.',\n '- rule.policy runs after config.policy but before data transformation — use for event-specific pre-processing.',\n '- config.consent gates ALL events to this destination. rule.consent is not enforced yet.',\n '- Individual value configs support consent: { marketing: true } for field-level gating.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerManageContractPrompt(server: McpServer) {\n server.registerPrompt(\n 'manage-contract',\n {\n description:\n 'Create or update event contracts for a flow. Can generate contracts from existing mappings or scaffold mappings from contracts.',\n argsSchema: {\n direction: z\n .string()\n .optional()\n .describe(\n 'Direction: \"from-mappings\" (extract contract from existing mappings), ' +\n '\"from-scratch\" (create new contract), or \"to-mappings\" (scaffold mappings from contract)',\n ),\n },\n },\n async ({ direction }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me ${direction === 'to-mappings' ? 'scaffold mappings from a contract' : direction === 'from-mappings' ? 'generate a contract from existing mappings' : 'manage event contracts'}.`,\n '',\n 'Follow these steps:',\n '1. Read the walkeros://reference/contract resource to understand contract structure.',\n direction === 'from-mappings'\n ? '2. Read all destination mappings in the flow, extract referenced event fields, and generate a contract with those as required properties.'\n : direction === 'to-mappings'\n ? '2. Read the contract from the flow, then scaffold mapping stubs for each destination based on the contract fields.'\n : '2. Ask for entity-action names and required properties, or ask whether to generate from existing mappings.',\n '3. Use entity-action keying with wildcards (*.*, *.action, entity.*) for broad rules.',\n '4. Define JSON Schema for events, globals, context, custom, user, and consent.',\n '5. Use flow_validate to verify the contract.',\n '',\n 'Contracts and mappings are bidirectional:',\n '- **Contract → Mappings**: contract defines what events look like, mappings are scaffolded to match.',\n '- **Mappings → Contract**: existing mappings reveal which fields are used, contract formalizes them.',\n '',\n 'For server flows: if the contract references fields populated by ingest (e.g., user fingerprint hash), verify the source config.ingest extracts the needed request metadata.',\n '',\n 'Use $contract.name references to link contracts in the flow.',\n 'Contracts support extends for inheritance between event types.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","export const SERVER_INSTRUCTIONS = `walkerOS is an open-source, privacy-first event data collection platform. Define event pipelines as code using JSON flow configurations.\n\n## Rules\n\n- **Never guess package names.** Always use \\`package_search\\` first to find exact names, then \\`package_get\\` for details.\n- **Never construct flow configs from memory.** Read \\`walkeros://reference/flow-schema\\` and use \\`package_get\\` for package-specific schemas.\n- **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).\n- **Simulate before deploying.** Use \\`flow_simulate\\` to test with mocked API calls before \\`flow_bundle\\` or \\`flow_push\\`.\n- **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.\n\n## Workflow\n\n1. \\`auth({ action: \"status\" })\\` — check if logged in, or \\`auth({ action: \"login\" })\\` to connect\n2. \\`project_manage({ action: \"list\" })\\` — see your projects\n3. \\`flow_manage({ action: \"list\" })\\` — see all flows across projects\n4. \\`flow_load({ platform: \"web\" })\\` or \\`flow_load({ source: \"./flow.json\" })\\` — create or load\n5. \\`package_search({ type: \"destination\", platform: \"web\" })\\` — discover packages\n6. \\`package_get({ package: \"...\" })\\` — read schemas, hints, examples\n7. Use the \\`add-step\\` prompt — guided step addition\n8. Use the \\`setup-mapping\\` prompt — event transformation config\n9. \\`flow_validate({ type: \"flow\", input: \"flow.json\" })\\` — verify\n10. \\`flow_simulate({ configPath: \"flow.json\", event: \"...\" })\\` — test\n11. \\`flow_manage({ action: \"update\", flowId: \"...\", content: {...} })\\` — save to cloud\n12. \\`deploy_manage({ action: \"deploy\", flowId: \"...\" })\\` — deploy\n13. \\`observe_session({ action: \"start\", flowId: \"...\" })\\` - open an Observe session: a time-boxed window on one flow that runtimes attach to as arms\n14. \\`flow_manage({ action: \"preview_regrant\", flowId: \"...\", previewId: \"...\", origins: [...] })\\` - mint an activation link; minted while the flow is observed, it pairs with that Observe session automatically, so the previewed page streams into the same feed\n15. \\`observe_journeys({ flowId: \"...\" })\\` - read what arrived; it is the only read, and it never judges whether events are correct\n16. \\`hub_manage({ action: \"releases\", flowId: \"...\" })\\` - read what changed across releases and why; \\`release_get\\` carries a server-computed diff, \\`rationale_set\\` records why\n17. \\`frame_manage({ action: \"page\", pageKey: \"...\" })\\` - read the frames of a page with their marks; read-only, edited in Tag Mode or the app\n\n## Architecture: Source → Collector → Destination(s)\n\nEvery component in a flow is a **step**: sources capture events, transformers process them, destinations deliver them, stores provide shared state. Steps connect via chains: \\`source.next\\` runs before the collector, \\`collector.next\\` runs once per event before the destination fan-out (all destinations), and \\`destination.before\\` runs for one destination.\n\n## Flow Config Structure\n\n\\`\\`\\`json\n{\n \"version\": 4,\n \"flows\": {\n \"default\": {\n \"config\": { \"platform\": \"web\" },\n \"sources\": { \"<name>\": { \"package\": \"<npm-package>\", \"config\": {} } },\n \"destinations\": { \"<name>\": { \"package\": \"<npm-package>\", \"config\": { \"settings\": {} } } }\n }\n }\n}\n\\`\\`\\`\n\n- \\`version: 4\\` is required\n- Each flow declares its target via \\`config.platform\\` (\\`\"web\"\\` or \\`\"server\"\\`)\n- Destination settings go inside \\`config.settings\\`, not directly on the destination\n- Event format: \\`{ name: \"entity action\", data: {...}, entity: \"...\", action: \"...\" }\\`\n\n## Key Concepts\n\n- **Mapping** transforms events using data/map/loop/set/condition rules. Same syntax on sources and destinations. Mapping rules use NESTED entity → action keying: event name \"product add\" maps to \\`{ \"product\": { \"add\": Rule } }\\`. Wildcards: \\`{ \"*\": { \"view\": Rule } }\\`.\n- **Contracts** define event schemas using entity-action keying. Can generate FROM mappings or scaffold mappings FROM contracts.\n- **Variables** (\\$var, \\$env, \\$secret, \\$code, \\$store) enable DRY, environment-aware config. \\`$var.name\\` is a reusable flow variable from the top-level \\`variables\\` block; whole-string refs preserve native type (object/array/scalar), inline interpolation requires a scalar, deep paths via \\`$var.name.deep.path\\`. \\`$env.NAME[:default]\\` is an environment variable resolved at bundle/deploy time (non-secret config only). \\`$secret.NAME\\` is a managed secret the deploy pipeline injects into the server runner at runtime; credentials, tokens, and private keys must use \\`$secret\\`, not \\`$env\\`.\n- **Consent** gates destinations (\\`config.consent\\`) and individual fields (a value's \\`consent\\`). A mapping rule's \\`consent\\` is not enforced yet. Privacy-first by design.\n- **Routing** uses one grammar in every chain field (\\`source.before\\`, \\`source.next\\`, \\`transformer.before\\`, \\`transformer.next\\`, \\`collector.next\\`, \\`destination.before\\`, \\`destination.next\\`). A route is a string ID, a sequence (\\`[\"a\", \"b\"]\\`), or a RouteConfig: \\`{ match?, next }\\`, \\`{ match?, one: [...] }\\` (first match wins), \\`{ match?, many: [...] }\\` (every match becomes its own copy of the event with its own id and finishes the rest of the path on its own, never merged), or \\`{ match?, stop: true }\\` (ends that copy). In a sequence, a member's own \\`next\\` runs right after it, then the sequence continues. \\`match\\` reads \\`{ ingest, event }\\` and each route is evaluated when the event reaches it. A \\`stop\\` in \\`collector.next\\` drops the event for every destination; per-destination filtering belongs in \\`destination.before\\`. An array of only route configs is an implicit \\`one\\`. The optional \\`match\\` field is omitted to mean always-match (no wildcard literal).\n- **Pass-through steps** are transformer entries with no \\`code\\` and no \\`package\\`. The runtime synthesizes the push for them automatically. Three flavors share this shape: a \\`before\\` / \\`next\\`-only step (named hop reusable across destinations), a \\`cache\\`-only step (dedup, rate-limit), and a \\`mapping\\`-only step (declarative event-to-event transform). A pass-through must declare at least one of \\`before\\`, \\`next\\`, \\`cache\\`, or \\`mapping\\`.\n- **Mapping at the transformer position** uses the same \\`Mapping.Config\\` shape as destinations, but the semantic is event-to-event: \\`policy\\` and per-rule \\`policy\\`, \\`mapping[].name\\` (rename), \\`mapping[].ignore\\` (drop from chain), and \\`include\\` apply. \\`consent\\` is not enforced at this position. Vendor-payload fields (\\`data\\`, \\`silent\\`, \\`mapping[].data\\`) are no-ops at this position.\n- **Closed-schema rule on transformer entries:** known keys only. Operative keys are \\`code\\`, \\`package\\`, \\`before\\`, \\`next\\`, \\`cache\\`, \\`mapping\\`. Combined with structural keys (\\`config\\`, \\`env\\`, \\`validate\\`, \\`disabled\\`, \\`id\\`, etc.). Unknown top-level keys on a transformer step are errors (catches typos like \\`dedup: {}\\` instead of nested under \\`cache\\`). \\`code\\` + \\`package\\` together is a conflict.\n- **Cache** memoizes step output on a configured store. Set \\`cache.stop: true\\` to short-circuit the chain on HIT (sources default to stop-on-HIT); in a source chain or \\`collector.next\\` that halts the event for all destinations. Set \\`cache.namespace\\` to prefix keys; omit it to write keys directly. \\`CacheRule.match\\` is optional, omit for always-match.\n\n## Simulation Tips\n\n- Destinations with \\`require: [\"consent\"]\\` stay **pending** until a \\`\"walker consent\"\\` event fires. Simulation will error \"not found\" for pending destinations, remove \\`require\\` from config when testing with \\`flow_simulate\\`.\n- Destinations with \\`consent: { marketing: true }\\` silently skip events that lack matching consent. Include \\`consent\\` in the event: \\`{ name: \"page view\", data: {...}, consent: { marketing: true } }\\`.\n- **Mapping** transforms event names and data at the destination level. Events without a matching mapping rule pass through unmodified.\n- **Policy** modifies the event before mapping runs, use it to inject computed fields or redact sensitive data.\n\n## Reference Resources\n\nRead these before constructing configs manually: \\`walkeros://reference/flow-schema\\`, \\`walkeros://reference/mapping\\`, \\`walkeros://reference/event-model\\`, \\`walkeros://reference/consent\\`, \\`walkeros://reference/variables\\`, \\`walkeros://reference/contract\\`, \\`walkeros://reference/examples\\`.`;\n","import { randomUUID } from 'crypto';\nimport { telemetry } from '@walkeros/cli';\n\n/**\n * Options for the MCP telemetry emitter wrapper.\n *\n * `clientInfo` mirrors the MCP SDK shape negotiated during initialize.\n * When the client doesn't send one, we record the client name as \"unknown\"\n * inside the per-event data so downstream analytics can still bucket the\n * event. The walkerOS source identifier is the package itself (`mcp`), not\n * the client.\n */\nexport interface McpEmitterOptions {\n clientInfo?: { name: string; version: string };\n packageVersion: string;\n}\n\n/**\n * MCP-specific event emitter.\n *\n * Wraps `@walkeros/cli`'s `telemetry.createEmitter` with:\n * - `source.type` fixed to `\"mcp\"`\n * - `source.platform` fixed to `\"server\"`\n * - per-emission `source.tool` for `cmd invoke` events\n * - a fresh session UUID per MCP server instance\n *\n * Surfaces the narrow set of events the MCP server needs to emit.\n */\nexport interface McpEmitter {\n emitStart(): Promise<void>;\n emitInvoke(\n tool: string,\n outcome: 'success' | 'error',\n timingMs: number,\n ): Promise<void>;\n emitError(kind: 'uncaught' | 'unhandledRejection' | 'startup'): Promise<void>;\n}\n\n/**\n * Build an MCP telemetry emitter.\n *\n * All consent, debug, and endpoint resolution is delegated to the CLI's\n * underlying `telemetry.createEmitter`. This wrapper only provides\n * MCP-specific field mapping and event shorthands.\n */\nexport async function createMcpEmitter(\n opts: McpEmitterOptions,\n): Promise<McpEmitter> {\n const clientName = opts.clientInfo?.name || 'unknown';\n const session = randomUUID();\n\n const emitter = await telemetry.createEmitter({\n source: {\n type: 'mcp',\n platform: 'server',\n },\n packageVersion: opts.packageVersion,\n session,\n });\n\n return {\n async emitStart() {\n const ci = telemetry.getCiInfo();\n await emitter.send('mcp start', {\n ...ci,\n client: clientName,\n });\n },\n async emitInvoke(tool, outcome, timingMs) {\n await emitter.send(\n 'cmd invoke',\n { outcome, client: clientName },\n timingMs,\n { tool },\n );\n },\n async emitError(kind) {\n await emitter.send('error throw', { kind });\n },\n };\n}\n","import type { ToolClient } from '../tool-client.js';\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\nimport { RuntimeRefusal, type FlowRuntime } from './types.js';\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Whether a bare string is shaped like a filesystem path: it names a directory\n * hop, starts with a dot, or carries a file extension. Nothing is ever read\n * either way; the distinction only decides which error a hosted load raises.\n * A path-shaped input is refused outright, while a plain phrase such as an\n * event name is merely unresolvable here, which is what lets `flow_validate`\n * keep its event-name shorthand.\n */\nfunction looksLikePath(value: string): boolean {\n return (\n /[\\\\/]/.test(value) ||\n value.startsWith('.') ||\n /\\.[A-Za-z0-9]+$/.test(value)\n );\n}\n\nexport type ConfigInputKind =\n | 'inline-json'\n | 'cloud-id'\n | 'url'\n | 'local-path'\n | 'bare-string';\n\n/**\n * Classify a config input the way the local loader would resolve it: an\n * http(s) URL, a reserved cloud id, an inline JSON document, a path-shaped\n * string, or a bare string that names none of these. Order matters, a URL is\n * checked before the cloud-id and JSON shapes.\n */\nexport function classifyConfigInput(input: string): ConfigInputKind {\n const trimmed = input.trim();\n if (isHttpUrl(trimmed)) return 'url';\n if (isCloudId(trimmed)) return 'cloud-id';\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) return 'inline-json';\n if (looksLikePath(trimmed)) return 'local-path';\n return 'bare-string';\n}\n\nconst HINT_INLINE_OR_ID =\n 'Pass the flow inline as JSON, or reference a saved flow by its flow_ or cfg_ id.';\n\nfunction refuseLocalPath(): RuntimeRefusal {\n return new RuntimeRefusal(\n 'Local file paths are not available on the hosted walkerOS MCP server.',\n HINT_INLINE_OR_ID,\n );\n}\n\nfunction refuseUrl(): RuntimeRefusal {\n return new RuntimeRefusal(\n 'Fetching URLs is not available on the hosted walkerOS MCP server.',\n HINT_INLINE_OR_ID,\n );\n}\n\nfunction parseInline(trimmed: string): unknown {\n try {\n return JSON.parse(trimmed);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Input appears to be JSON but contains errors: ${message}`);\n }\n}\n\n/**\n * The least-privilege runtime for a shared, network-reached process: the app's\n * OAuth door, in-app chat, and any third-party HTTP host.\n *\n * It never touches the filesystem or the network on the caller's behalf. A\n * saved `flow_`/`cfg_` id is resolved through the access-scoped tool client, a\n * document is parsed inline, and everything else is refused. `bundle`,\n * `simulate` and `push` are deliberately absent: compiling or importing a\n * caller's flow pulls that caller's code (inline or by package name) into this\n * process, and no input shape makes that safe here.\n */\nexport function createHostedRuntime(\n client: Pick<ToolClient, 'getFlow'>,\n): FlowRuntime {\n return {\n async load(input) {\n const trimmed = input.trim();\n if (trimmed === '') throw new Error('Input is required');\n switch (classifyConfigInput(trimmed)) {\n case 'url':\n throw refuseUrl();\n case 'cloud-id':\n return flowConfigOf(await client.getFlow({ flowId: trimmed }));\n case 'inline-json':\n return parseInline(trimmed);\n case 'local-path':\n throw refuseLocalPath();\n case 'bare-string':\n // Not a refusal: nothing was withheld, the input simply names nothing\n // this runtime can resolve.\n throw new Error(\n `Cannot resolve \"${trimmed}\" on the hosted walkerOS MCP server. ${HINT_INLINE_OR_ID}`,\n );\n }\n },\n };\n}\n","import {\n listProjects,\n getProject,\n createProject,\n updateProject,\n deleteProject,\n setDefaultProject,\n getDefaultProject,\n listAllFlows,\n listFlows,\n getFlow,\n createFlow,\n updateFlow,\n deleteFlow,\n duplicateFlow,\n listPreviews,\n getPreview,\n createPreview,\n deletePreview,\n regrantPreview,\n listSecrets,\n createSecret,\n updateSecret,\n deleteSecret,\n deploy,\n listDeployments,\n getDeploymentBySlug,\n deleteDeployment,\n listJourneys,\n startObserveSession,\n getObserveSession,\n endObserveSession,\n listReleases,\n getRelease,\n listStepHistory,\n setReleaseRationale,\n listThreads,\n createThread,\n addThreadMessage,\n listKnowledge,\n listFrames,\n listPageFrames,\n getFrame,\n startDeviceAuthorization,\n completeDeviceLogin,\n whoami,\n credentialSource,\n resolveAppUrl,\n logout,\n feedback,\n getFeedbackPreference,\n setFeedbackPreference,\n fetchHealth,\n fetchOpenApi,\n compareContract,\n} from '@walkeros/cli';\nimport type {\n ContractComparison,\n DeviceAuthorization,\n DeviceLoginResult,\n ListFlowsOptions,\n DeployOptions,\n ListDeploymentsOptions,\n ListPreviewsOptions,\n GetPreviewOptions,\n CreatePreviewOptions,\n DeletePreviewOptions,\n ListSecretsOptions,\n CreateSecretOptions,\n UpdateSecretOptions,\n DeleteSecretOptions,\n FeedbackOptions,\n} from '@walkeros/cli';\n\nimport { normalizeBaseUrl } from './base-url.js';\nimport type {\n ToolClient,\n JourneysResult,\n RegrantPreviewOptions,\n ObserveSessionResult,\n ObserveSessionRef,\n StartObserveSessionOptions,\n ReleaseRef,\n ReleaseIndexWire,\n ReleaseDetailWire,\n StepHistoryWire,\n VersionAnnotationWire,\n ThreadAnchorType,\n ThreadStatus,\n HubThreadWire,\n ListThreadsWire,\n ListKnowledgeWire,\n FrameWire,\n FrameListWire,\n FrameLeanListWire,\n} from './tool-client.js';\n\n// __VERSION__ is this package's version, replaced at build time by tsup's\n// `define` (see tsup.config.ts). In tests, it is set on globalThis (see\n// src/__tests__/support/version.ts).\ndeclare const __VERSION__: string;\n\n/**\n * Default ToolClient implementation backed by @walkeros/cli. Every method\n * delegates to the CLI's programmatic API, which in turn talks to the\n * walkerOS app over HTTPS via openapi-fetch. Token resolution and the\n * base URL come from the CLI's config file and environment\n * (WALKEROS_TOKEN, WALKEROS_APP_URL), so no constructor args are required.\n */\nexport class HttpToolClient implements ToolClient {\n async listProjects(options?: {\n cursor?: string;\n limit?: number;\n }): Promise<unknown> {\n return listProjects(options);\n }\n async getProject(options: { projectId?: string }): Promise<unknown> {\n return getProject(options);\n }\n async createProject(options: { name: string }): Promise<unknown> {\n return createProject(options);\n }\n async updateProject(options: {\n projectId?: string;\n name: string;\n }): Promise<unknown> {\n return updateProject(options);\n }\n async deleteProject(options: { projectId?: string }): Promise<unknown> {\n return deleteProject(options);\n }\n setDefaultProject(projectId: string): void {\n setDefaultProject(projectId);\n }\n getDefaultProject(): string | null {\n return getDefaultProject();\n }\n\n async listAllFlows(options?: {\n sort?: string;\n order?: 'asc' | 'desc';\n includeDeleted?: boolean;\n cursor?: string;\n limit?: number;\n }): Promise<unknown> {\n return listAllFlows(options as Parameters<typeof listAllFlows>[0]);\n }\n async listFlows(options: ListFlowsOptions): Promise<unknown> {\n return listFlows(options);\n }\n async getFlow(options: {\n flowId: string;\n projectId?: string;\n fields?: string[];\n }): Promise<unknown> {\n return getFlow(options);\n }\n async createFlow(options: {\n name: string;\n content: Record<string, unknown>;\n projectId?: string;\n }): Promise<unknown> {\n return createFlow(options);\n }\n async updateFlow(options: {\n flowId: string;\n projectId?: string;\n name?: string;\n content?: Record<string, unknown>;\n mergePatch?: boolean;\n }): Promise<unknown> {\n return updateFlow(options);\n }\n async deleteFlow(options: {\n flowId: string;\n projectId?: string;\n }): Promise<unknown> {\n return deleteFlow(options);\n }\n async duplicateFlow(options: {\n flowId: string;\n name?: string;\n projectId?: string;\n }): Promise<unknown> {\n return duplicateFlow(options);\n }\n\n async listPreviews(options: ListPreviewsOptions): Promise<unknown> {\n return listPreviews(options);\n }\n async getPreview(options: GetPreviewOptions): Promise<unknown> {\n return getPreview(options);\n }\n async createPreview(\n options: CreatePreviewOptions & { siteUrl?: string },\n ): Promise<unknown> {\n // flow-manage passes `siteUrl` (the shared handler's field); the CLI's\n // createPreview mints an origin-bound grant when given `url`. Bridge the two\n // so a preview_create with a site URL over the HTTP client mints a real\n // grant instead of returning a null activationUrl.\n return createPreview({ ...options, url: options.url ?? options.siteUrl });\n }\n async deletePreview(options: DeletePreviewOptions): Promise<unknown> {\n return deletePreview(options);\n }\n async regrantPreview(options: RegrantPreviewOptions): Promise<unknown> {\n return regrantPreview(options);\n }\n\n async listSecrets(options: ListSecretsOptions): Promise<unknown> {\n return listSecrets(options);\n }\n async createSecret(options: CreateSecretOptions): Promise<unknown> {\n return createSecret(options);\n }\n async updateSecret(options: UpdateSecretOptions): Promise<unknown> {\n return updateSecret(options);\n }\n async deleteSecret(options: DeleteSecretOptions): Promise<unknown> {\n return deleteSecret(options);\n }\n\n async deploy(options: DeployOptions): Promise<unknown> {\n return deploy(options);\n }\n async listDeployments(options: ListDeploymentsOptions): Promise<unknown> {\n return listDeployments(options);\n }\n async getDeploymentBySlug(options: {\n slug: string;\n projectId?: string;\n }): Promise<unknown> {\n return getDeploymentBySlug(options);\n }\n async deleteDeployment(options: {\n slug: string;\n projectId?: string;\n }): Promise<unknown> {\n return deleteDeployment(options);\n }\n\n async listJourneys(options: {\n flowId: string;\n projectId?: string;\n traceId?: string;\n limit?: number;\n }): Promise<JourneysResult> {\n return listJourneys(options);\n }\n\n /**\n * Observe session lifecycle over the CLI's authenticated boundary. The trio\n * routes through the same `apiFetch` as every other method here, so token\n * resolution, base URL, and `ApiError` shaping (which\n * `isAuthenticationError` reads) stay identical to the rest of the client.\n */\n async startObserveSession(\n options: StartObserveSessionOptions,\n ): Promise<ObserveSessionResult> {\n return startObserveSession(options);\n }\n async getObserveSession(\n options: ObserveSessionRef,\n ): Promise<ObserveSessionResult> {\n return getObserveSession(options);\n }\n async endObserveSession(options: ObserveSessionRef): Promise<void> {\n return endObserveSession(options);\n }\n\n async listReleases(options: {\n projectId: string;\n flowId: string;\n limit?: number;\n offset?: number;\n }): Promise<ReleaseIndexWire> {\n return listReleases(options);\n }\n async getRelease(options: {\n projectId: string;\n flowId: string;\n ref: ReleaseRef;\n }): Promise<ReleaseDetailWire> {\n return getRelease(options);\n }\n async listStepHistory(options: {\n projectId: string;\n flowId: string;\n step: string;\n flow?: string;\n limit?: number;\n }): Promise<StepHistoryWire> {\n return listStepHistory(options);\n }\n async setReleaseRationale(options: {\n projectId: string;\n flowId: string;\n versionId: string;\n text: string;\n }): Promise<VersionAnnotationWire> {\n return setReleaseRationale(options);\n }\n async listThreads(options: {\n projectId: string;\n flowId: string;\n anchorType?: ThreadAnchorType;\n anchorKey?: string;\n status?: ThreadStatus;\n includeMessages: boolean;\n limit?: number;\n }): Promise<ListThreadsWire> {\n return listThreads(options);\n }\n async createThread(options: {\n projectId: string;\n flowId: string;\n anchorType: ThreadAnchorType;\n anchorKey: string;\n anchorLabel?: string;\n text: string;\n }): Promise<HubThreadWire> {\n return createThread(options);\n }\n async addThreadMessage(options: {\n projectId: string;\n flowId: string;\n threadId: string;\n text: string;\n }): Promise<HubThreadWire> {\n return addThreadMessage(options);\n }\n async listKnowledge(options: {\n projectId: string;\n pageKey?: string;\n frameId?: string;\n markId?: string;\n includeMessages: boolean;\n limit?: number;\n }): Promise<ListKnowledgeWire> {\n return listKnowledge(options);\n }\n\n async listFrames(options: { projectId: string }): Promise<FrameLeanListWire> {\n return listFrames(options);\n }\n async listPageFrames(options: {\n projectId: string;\n pageKey: string;\n }): Promise<FrameListWire> {\n return listPageFrames(options);\n }\n async getFrame(options: {\n projectId: string;\n frameId: string;\n }): Promise<FrameWire> {\n return getFrame(options);\n }\n\n async requestDeviceCode(): Promise<DeviceAuthorization> {\n return startDeviceAuthorization(resolveAppUrl());\n }\n async pollForToken(\n deviceCode: string,\n options?: { timeoutMs?: number },\n ): Promise<DeviceLoginResult> {\n return completeDeviceLogin(deviceCode, options);\n }\n async whoami(): Promise<unknown> {\n return whoami();\n }\n credentialSource(): 'env' | 'config' | null {\n return credentialSource();\n }\n async logout(): Promise<{ deleted: boolean }> {\n return logout();\n }\n\n /**\n * The app this local door talks to: `WALKEROS_APP_URL`, then the CLI config\n * file, then the built-in default, which is exactly the chain every other\n * method here already resolves its base URL through. Normalized, because\n * neither the env var nor the config file is obliged to omit a trailing\n * slash and the interface promises a base without one.\n */\n appBaseUrl(): string {\n return normalizeBaseUrl(resolveAppUrl());\n }\n\n /**\n * Unauthenticated reachability probe of the app's PUBLIC health route\n * (`GET /api/health`) at `appBaseUrl()`, through the CLI's `fetchHealth`.\n * Sends no credential, so diagnostics works logged-out. Resolves\n * `{ reachable: false, error }` only on a real network/timeout failure.\n */\n async checkHealth(): Promise<{\n reachable: boolean;\n status?: string;\n version?: string;\n error?: string;\n }> {\n const health = await fetchHealth(this.appBaseUrl());\n return {\n reachable: health.reachable,\n ...(health.status !== undefined && { status: health.status }),\n ...(health.appVersion !== undefined && { version: health.appVersion }),\n ...(health.error !== undefined && { error: health.error }),\n };\n }\n\n /**\n * The contract verdict for this MCP against `appBaseUrl()`, per operation,\n * naming `@walkeros/mcp` as the client.\n */\n async checkContract(): Promise<ContractComparison> {\n return compareContract({\n baseUrl: this.appBaseUrl(),\n client: { type: 'mcp', version: __VERSION__ },\n });\n }\n\n /** The live public OpenAPI document of `appBaseUrl()`, without a credential. */\n async openapiDocument(): Promise<unknown> {\n const result = await fetchOpenApi(this.appBaseUrl());\n if (!result.ok) throw new Error(`GET ${result.url}: ${result.error}`);\n return result.document;\n }\n\n async submitFeedback(text: string, options?: FeedbackOptions): Promise<void> {\n await feedback(text, options);\n }\n getFeedbackPreference(): boolean | undefined {\n return getFeedbackPreference();\n }\n setFeedbackPreference(anonymous: boolean): void {\n setFeedbackPreference(anonymous);\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n collectKnownSecrets,\n loadConfig,\n loadJsonConfig,\n bundle,\n push,\n simulateSource,\n simulateTransformer,\n simulateCollector,\n simulateDestination,\n} from '@walkeros/cli';\nimport { isObject } from '@walkeros/core';\nimport { isFlowJson } from '../tools/narrow.js';\nimport type { Flow, WalkerOS } from '@walkeros/core';\nimport { schemas } from '@walkeros/core/dev';\nimport { getOrBuildBundle } from './bundle-cache.js';\nimport type { FlowRuntime } from './types.js';\n\n/**\n * The full-capability runtime for the user's own machine (stdio, the developer\n * CLI). It wraps the `@walkeros/cli` loaders and runners exactly as the tools\n * called them before the runtime seam existed, so local behaviour is unchanged:\n * a config may be a file path, an http(s) URL or inline JSON, and bundling,\n * simulation and push run in this process.\n *\n * This is the only module in the package that may bind those cli functions;\n * the tools reach them through the `FlowRuntime` interface and nothing else.\n */\nexport function createLocalRuntime(): FlowRuntime {\n return {\n load: (input) => loadJsonConfig(input),\n\n baseDir(input) {\n const file = path.resolve(input);\n return fs.existsSync(file) && fs.statSync(file).isFile()\n ? path.dirname(file)\n : undefined;\n },\n\n bundle: (input, opts) =>\n bundle(input, {\n flowName: opts.flowName,\n stats: opts.stats,\n buildOverrides: opts.output ? { output: opts.output } : undefined,\n }),\n\n async simulate(input, opts) {\n // Reuse a prebuilt bundle across calls with the same resolved config. The\n // simulate fns take their fast `mode: 'prebuilt'` branch when given a\n // bundlePath, skipping the per-call rebuild. On any bundle failure fall\n // back to undefined so the simulate fn rebuilds and surfaces its own error.\n let bundlePath: string | undefined;\n try {\n bundlePath = await getOrBuildBundle(input);\n } catch {\n bundlePath = undefined;\n }\n const common = { bundlePath, flow: opts.flow, silent: true };\n const config = opts.config ?? input;\n\n switch (opts.stepType) {\n case 'source':\n return simulateSource(config, opts.event, {\n sourceId: opts.stepId,\n ...common,\n consent: opts.state?.consent,\n });\n case 'transformer':\n return simulateTransformer(config, partialEvent(opts.event), {\n transformerId: opts.stepId,\n ...common,\n ingest: opts.ingest,\n consent: opts.state?.consent,\n });\n case 'collector':\n return simulateCollector(config, partialEvent(opts.event), {\n collectorName: opts.stepId,\n ...common,\n state: opts.state,\n ingest: opts.ingest,\n });\n case 'destination':\n return simulateDestination(config, eventObject(opts.event), {\n destinationId: opts.stepId,\n ...common,\n ingest: opts.ingest,\n consent: opts.state?.consent,\n command: opts.command,\n });\n }\n },\n\n knownSecrets: async (input) =>\n collectKnownSecrets(await loadJsonConfig<Flow.Json>(input)),\n\n async loadRun(input) {\n // One read, detected the way push detects its input: content that\n // parses as JSON is a config, anything else a prebuilt bundle, which\n // carries no config and so no secrets to resolve.\n const content = await loadConfig(input, { json: false });\n const config =\n typeof content === 'string' ? parseJson(content) : undefined;\n if (!isFlowJson(config)) return { knownSecrets: [] };\n return { config, knownSecrets: collectKnownSecrets(config) };\n },\n\n push: (input, event, opts) =>\n push(input, event, {\n json: true,\n flow: opts.flow,\n platform: opts.platform,\n ...(opts.config !== undefined && { raw: opts.config }),\n }),\n };\n}\n\n/**\n * The event a transformer or collector step runs on, checked against the\n * partial event schema the CLI applies. The value passes through as given.\n */\nfunction partialEvent(value: unknown): WalkerOS.DeepPartialEvent {\n if (isPartialEvent(value)) return value;\n const parsed = schemas.PartialEventSchema.safeParse(value);\n throw new Error(parsed.error?.message ?? 'Invalid event');\n}\n\nfunction isPartialEvent(value: unknown): value is WalkerOS.DeepPartialEvent {\n return schemas.PartialEventSchema.safeParse(value).success;\n}\n\n/** A destination step's event, or a command's data: an object. */\nfunction eventObject(value: unknown): Record<string, unknown> {\n if (isObject(value)) return value;\n throw new Error('event must be an object.');\n}\n\nfunction parseJson(content: string): unknown {\n try {\n return JSON.parse(content);\n } catch {\n return undefined;\n }\n}\n","import { createHash } from 'node:crypto';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport { rmSync } from 'node:fs';\nimport { bundle } from '@walkeros/cli';\n\n/**\n * Content-addressed cache of prebuilt simulate bundles for the MCP\n * `flow_simulate` tool. Each `flow_simulate` call otherwise re-bundles the\n * whole flow (`mode: 'build'`), which dominates latency. By keying a prebuilt\n * ESM by the hash of the *resolved* config content, repeated simulations of the\n * same flow reuse one bundle and a changed flow rebuilds.\n *\n * The CLI simulate functions accept a `bundlePath`; passing it takes their\n * `mode: 'prebuilt'` branch and skips the bundle step entirely.\n */\n\ninterface CacheEntry {\n bundlePath: string;\n dir: string;\n}\n\n/** LRU bound: enough to cover a few flows iterated in one session without\n * leaking temp dirs. Oldest entry is evicted (and its dir removed) on insert. */\nconst MAX_ENTRIES = 8;\n\n/** Insertion-ordered map gives us LRU for free: delete+set on access moves the\n * key to the end; the first key is the least-recently used. */\nconst cache = new Map<string, CacheEntry>();\n\n/** In-flight builds, deduped by key so two concurrent identical simulate calls\n * bundle once instead of racing to write the same artifact. */\nconst inFlight = new Map<string, Promise<string>>();\n\nlet cleanupRegistered = false;\n\nfunction hashConfig(resolvedConfig: string): string {\n return createHash('sha256').update(resolvedConfig).digest('hex');\n}\n\n/**\n * Inline JSON config content is cacheable: its full content is the cache key,\n * so an edit always re-keys. A file path or URL is NOT: `resolveConfigPath`\n * returns it unchanged, so the key would be the path string and an edit to the\n * file behind it would silently reuse a stale bundle. Such inputs skip the\n * cache and take the simulate fns' build path (which re-reads the file).\n *\n * The discriminator matches how the CLI simulate fns treat `configPath`: a\n * string that parses as JSON is inline config; anything else is a path/URL.\n */\nfunction isInlineJsonConfig(resolvedConfig: string): boolean {\n const trimmed = resolvedConfig.trimStart();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return false;\n try {\n JSON.parse(resolvedConfig);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction registerProcessCleanup(): void {\n if (cleanupRegistered) return;\n cleanupRegistered = true;\n const cleanup = () => {\n for (const entry of cache.values()) {\n // Synchronous best-effort removal on exit; async fs is not safe here.\n try {\n rmSync(entry.dir, { recursive: true, force: true });\n } catch {\n // Temp dir already gone or unwritable; nothing to recover.\n }\n }\n cache.clear();\n };\n process.once('exit', cleanup);\n}\n\nasync function evictIfNeeded(): Promise<void> {\n while (cache.size > MAX_ENTRIES) {\n const oldestKey = cache.keys().next().value;\n if (oldestKey === undefined) break;\n const evicted = cache.get(oldestKey);\n cache.delete(oldestKey);\n if (evicted) await rm(evicted.dir, { recursive: true, force: true });\n }\n}\n\n/**\n * Build the resolved config into a prebuilt simulate ESM and return its path,\n * reusing a cached bundle when the same resolved config was bundled before.\n *\n * `resolvedConfig` is the exact string the simulate functions would otherwise\n * receive as `configPath` (inline JSON for cloud ids after id resolution, or a\n * file path / URL / inline JSON otherwise). Keying on it means a cloud id whose\n * underlying content changes between calls rebuilds correctly.\n *\n * Returns `undefined` for file-path / URL configs (see `isInlineJsonConfig`):\n * those bypass the cache so an edited file is never served from a stale bundle.\n * The caller then passes the original configPath with no bundlePath, taking the\n * simulate fns' build path exactly as before.\n *\n * The producer mirrors the CLI build-mode bundle: target `simulate`\n * (skipWrapper + withDev, /dev graph inlined) written as ESM. The flow's own\n * platform is preserved via the bundler's platform defaults; only the output\n * format is pinned to ESM so the CLI can import it directly.\n */\nexport async function getOrBuildBundle(\n resolvedConfig: string,\n): Promise<string | undefined> {\n if (!isInlineJsonConfig(resolvedConfig)) return undefined;\n\n registerProcessCleanup();\n const key = hashConfig(resolvedConfig);\n\n const cached = cache.get(key);\n if (cached) {\n // Refresh LRU position.\n cache.delete(key);\n cache.set(key, cached);\n return cached.bundlePath;\n }\n\n const pending = inFlight.get(key);\n if (pending) return pending;\n\n const build = (async () => {\n const dir = path.join(\n os.tmpdir(),\n `walkeros-mcp-bundle-${key.slice(0, 16)}`,\n );\n await rm(dir, { recursive: true, force: true });\n await mkdir(dir, { recursive: true });\n const bundlePath = path.join(dir, 'flow.mjs');\n\n // Touch the file first so a producer that only mutates (rather than writes)\n // still leaves a real artifact; the bundler overwrites it with the real ESM.\n await writeFile(bundlePath, '', 'utf-8');\n\n // Load-bearing: `bundle()` derives platform from the flow config and\n // intentionally ignores `preset.platform` (the 'simulate' preset is node),\n // so a web flow still bundles browser-platform, equivalent to build-mode.\n // If `bundle()` ever honors `preset.platform`, web simulations via this\n // cache would silently bundle for node and diverge.\n await bundle(resolvedConfig, {\n target: 'simulate',\n silent: true,\n buildOverrides: { output: bundlePath, format: 'esm', minify: false },\n });\n\n cache.set(key, { bundlePath, dir });\n await evictIfNeeded();\n return bundlePath;\n })();\n\n inFlight.set(key, build);\n try {\n return await build;\n } finally {\n inFlight.delete(key);\n }\n}\n\n/** Test-only: clear the cache and remove all temp dirs. */\nexport async function __resetBundleCacheForTests(): Promise<void> {\n inFlight.clear();\n const dirs = Array.from(cache.values(), (e) => e.dir);\n cache.clear();\n await Promise.all(\n dirs.map((dir) => rm(dir, { recursive: true, force: true })),\n );\n}\n"],"mappings":"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","names":["path","schemas","mcpResult","mcpError","z","mcpError","TITLE","DESCRIPTION","inputSchema","schemas","annotations","mcpError","mcpResult","z","schemas","mcpResult","mcpError","isObject","mcpResult","TITLE","inputSchema","schemas","z","annotations","mcpError","errorMessage","mcpResult","require","z","schemas","mcpError","TITLE","DESCRIPTION","inputSchema","schemas","z","annotations","mcpError","z","mcpResult","mcpError","schemas","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","z","fetchPackage","mcpResult","mcpError","z","mcpResult","fetchPackage","mcpError","schemas","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","mcpResult","TITLE","DESCRIPTION","inputSchema","annotations","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","data","safe","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","NO_DEFAULT_PROJECT_ERROR","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","z","annotations","mcpResult","thread","mcpError","z","mcpResult","mcpError","FRAME_ID_PATTERN","TITLE","z","annotations","isRecord","mcpError","mcpResult","schemas","schemas","require","z","z","z","path","bundle","isObject","schemas","cache","bundle","schemas","isObject"]}
1
+ {"version":3,"sources":["../src/stdio.ts","../src/server.ts","../src/tools/validate.ts","../src/schemas/output.ts","../src/runtime/types.ts","../src/cloud-flow.ts","../src/tools/bundle.ts","../src/tools/parse-input.ts","../src/tools/resolve-config-path.ts","../src/tools/simulate.ts","../src/tools/simulate-description.ts","../src/tools/egress.ts","../src/tools/push.ts","../src/tools/examples.ts","../src/catalog.ts","../src/tools/narrow.ts","../src/tools/package.ts","../src/tools/flow-load.ts","../src/types.ts","../src/user-data.ts","../src/tools/project-context.ts","../src/tools/feedback.ts","../src/tools/diagnostics.ts","../src/base-url.ts","../src/tools/auth.ts","../src/tools/project-manage.ts","../src/action-requirements.ts","../src/tools/flow-manage.ts","../src/ui-parts.ts","../src/links.ts","../src/tools/deploy-manage.ts","../src/tools/_resolvers.ts","../src/tools/secret-manage.ts","../src/tools/observe-journeys.ts","../src/tools/observe-session.ts","../src/tools/feature-gate.ts","../src/tools/hub-manage.ts","../src/tools/frame-manage.ts","../src/resources/package-schemas.ts","../src/resources/references.ts","../src/prompts/add-step.ts","../src/prompts/setup-mapping.ts","../src/prompts/manage-contract.ts","../src/instructions.ts","../src/telemetry.ts","../src/runtime/hosted.ts","../src/http-tool-client.ts","../src/runtime/local.ts","../src/runtime/bundle-cache.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { setClientContext } from '@walkeros/cli';\n\nimport { createWalkerOSMcpServer, getMcpEmitterSingleton } from './server.js';\nimport { HttpToolClient } from './http-tool-client.js';\nimport { createMcpEmitter } from './telemetry.js';\nimport { createLocalRuntime } from './runtime/local.js';\n\ndeclare const __VERSION__: string;\n\nsetClientContext({ type: 'mcp', version: __VERSION__ });\n\n// Hook process-level error channels so we can emit `error throw` before the\n// process tears down. Both handlers look up the emitter lazily: if the MCP\n// handshake never completed, no emitter exists and we silently skip.\n// We don't call process.exit — stdio transport already propagates failures\n// up to the parent client via the JSON-RPC channel.\nprocess.on('uncaughtException', (err) => {\n const emitter = getMcpEmitterSingleton();\n if (emitter) {\n emitter.emitError('uncaught').catch(() => {});\n }\n console.error('Uncaught exception in Flow MCP server:', err);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n const emitter = getMcpEmitterSingleton();\n if (emitter) {\n emitter.emitError('unhandledRejection').catch(() => {});\n }\n console.error('Unhandled rejection in Flow MCP server:', reason);\n});\n\nasync function main() {\n // stdio runs on the user's own machine: the local runtime keeps file, URL and\n // in-process bundle, simulate and push behaviour exactly as before.\n const server = createWalkerOSMcpServer({\n client: new HttpToolClient(),\n version: __VERSION__,\n runtime: createLocalRuntime(),\n });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('walkerOS Flow MCP server running on stdio');\n}\n\nmain().catch(async (error) => {\n // Startup failure — no client handshake happened, so there's no emitter in\n // the module singleton. Build a one-shot emitter with an unknown client so\n // the error is still visible to telemetry.\n try {\n const emitter = await createMcpEmitter({\n clientInfo: undefined,\n packageVersion: __VERSION__,\n });\n await emitter.emitError('startup');\n } catch {\n // swallow — telemetry must never mask the original startup error\n }\n console.error('Failed to start Flow MCP server:', error);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport type { ToolClient } from './tool-client.js';\nimport { registerFlowValidateTool } from './tools/validate.js';\nimport { registerFlowBundleTool } from './tools/bundle.js';\nimport { registerFlowSimulateTool } from './tools/simulate.js';\nimport { registerFlowPushTool } from './tools/push.js';\nimport { registerFlowExamplesTool } from './tools/examples.js';\nimport {\n registerPackageSearchTool,\n registerGetPackageSchemaTool,\n} from './tools/package.js';\nimport { registerFlowLoadTool } from './tools/flow-load.js';\nimport { registerFeedbackTool } from './tools/feedback.js';\nimport { registerDiagnosticsTool } from './tools/diagnostics.js';\nimport { registerAuthTool } from './tools/auth.js';\nimport { registerProjectManageTool } from './tools/project-manage.js';\nimport { registerFlowManageTool } from './tools/flow-manage.js';\nimport { registerDeployTool } from './tools/deploy-manage.js';\nimport { registerSecretManageTool } from './tools/secret-manage.js';\nimport { registerObserveJourneysTool } from './tools/observe-journeys.js';\nimport { registerObserveSessionTool } from './tools/observe-session.js';\nimport { registerHubManageTool } from './tools/hub-manage.js';\nimport { registerFrameManageTool } from './tools/frame-manage.js';\nimport { registerPackageSchemaResources } from './resources/package-schemas.js';\nimport { registerReferenceResources } from './resources/references.js';\nimport { registerAddStepPrompt } from './prompts/add-step.js';\nimport { registerSetupMappingPrompt } from './prompts/setup-mapping.js';\nimport { registerManageContractPrompt } from './prompts/manage-contract.js';\nimport { SERVER_INSTRUCTIONS } from './instructions.js';\nimport { createMcpEmitter, type McpEmitter } from './telemetry.js';\nimport type { FlowRuntime } from './runtime/types.js';\nimport { createHostedRuntime } from './runtime/hosted.js';\n\nexport interface Logger {\n debug?(message: string, meta?: Record<string, unknown>): void;\n info?(message: string, meta?: Record<string, unknown>): void;\n warn?(message: string, meta?: Record<string, unknown>): void;\n error?(message: string, meta?: Record<string, unknown>): void;\n}\n\nexport interface CreateServerOptions {\n client: ToolClient;\n logger?: Logger;\n version?: string;\n catalogBaseUrl?: string;\n /**\n * The capability runtime the flow tools read, build and run flows through.\n * Omitted, the HOSTED runtime is used, the safe default for any shared or\n * network-reached process: inline JSON and saved flow ids only, no local\n * files, no URLs, no in-process bundle, simulate or push. Pass\n * `createLocalRuntime()` only on the user's own machine (stdio, the CLI) to\n * keep local file, URL and execution behaviour. See `FlowRuntime`.\n */\n runtime?: FlowRuntime;\n}\n\n/**\n * Module-scoped singleton emitter, populated once the MCP `initialize`\n * handshake completes and clientInfo is known. The stdio entrypoint reads\n * this to emit process-level `error throw` events from uncaughtException /\n * unhandledRejection hooks, where the Server instance isn't in scope.\n */\nlet currentEmitter: McpEmitter | undefined;\n\nexport function getMcpEmitterSingleton(): McpEmitter | undefined {\n return currentEmitter;\n}\n\n/**\n * Internal: reset for tests that want a clean slate between cases.\n * Not exported from the package.\n */\nexport function __resetMcpEmitterSingletonForTesting(): void {\n currentEmitter = undefined;\n}\n\n/**\n * Minimal shape of a `_registeredTools` entry we rely on for handler\n * wrapping. Typed locally to avoid leaking SDK internals while keeping\n * strict typing on the handler signature.\n */\ntype WrappableRegisteredTool = {\n handler: (...args: unknown[]) => unknown;\n};\n\ntype RegisteredToolsRecord = Record<string, WrappableRegisteredTool>;\n\n/**\n * Wrap every already-registered tool handler with telemetry. The wrapper\n * emits `cmd invoke` with outcome + timing, swallowing any telemetry error\n * so it never surfaces to the tool caller. We look up the emitter lazily at\n * call time so wrapping can happen before the emitter is created.\n */\nfunction wrapRegisteredToolsWithTelemetry(server: McpServer): void {\n const internal = server as unknown as {\n _registeredTools: RegisteredToolsRecord;\n };\n const tools = internal._registeredTools;\n if (!tools) return;\n for (const [toolName, tool] of Object.entries(tools)) {\n const original = tool.handler;\n tool.handler = async (...args: unknown[]): Promise<unknown> => {\n const start = Date.now();\n try {\n const result = await original(...args);\n const emitter = currentEmitter;\n if (emitter) {\n emitter\n .emitInvoke(toolName, 'success', Date.now() - start)\n .catch(() => {});\n }\n return result;\n } catch (err) {\n const emitter = currentEmitter;\n if (emitter) {\n emitter\n .emitInvoke(toolName, 'error', Date.now() - start)\n .catch(() => {});\n }\n throw err;\n }\n };\n }\n}\n\nexport function createWalkerOSMcpServer(opts: CreateServerOptions): McpServer {\n const packageVersion = opts.version ?? '0.0.0';\n const runtime = opts.runtime ?? createHostedRuntime(opts.client);\n const server = new McpServer(\n {\n name: 'walkeros-flow',\n version: packageVersion,\n },\n { instructions: SERVER_INSTRUCTIONS },\n );\n\n registerAuthTool(server, opts.client);\n registerProjectManageTool(server, opts.client);\n registerFlowManageTool(server, opts.client);\n registerDeployTool(server, opts.client);\n registerSecretManageTool(server, opts.client);\n registerObserveSessionTool(server, opts.client);\n registerObserveJourneysTool(server, opts.client);\n registerHubManageTool(server, opts.client);\n registerFrameManageTool(server, opts.client);\n registerFeedbackTool(server, opts.client);\n registerDiagnosticsTool(server, opts.client, packageVersion);\n\n registerFlowValidateTool(server, runtime);\n registerFlowBundleTool(server, opts.client, runtime);\n registerFlowSimulateTool(server, opts.client, runtime);\n registerFlowPushTool(server, runtime);\n registerFlowExamplesTool(server, runtime);\n registerFlowLoadTool(server, opts.client, runtime);\n\n registerPackageSearchTool(server);\n registerGetPackageSchemaTool(server);\n\n registerPackageSchemaResources(server);\n registerReferenceResources(server, opts.client);\n registerAddStepPrompt(server);\n registerSetupMappingPrompt(server);\n registerManageContractPrompt(server);\n\n wrapRegisteredToolsWithTelemetry(server);\n\n // MCP SDK fires `oninitialized` after the `initialized` notification, which\n // follows a successful `initialize` request. At that point `getClientVersion`\n // returns the negotiated client identity. We create the emitter here and\n // emit `mcp start`, so consent, debug, and endpoint resolution happen lazily\n // at the moment a real client connects.\n const priorOnInitialized = server.server.oninitialized;\n server.server.oninitialized = () => {\n try {\n priorOnInitialized?.();\n } catch {\n // existing handler must not prevent telemetry setup\n }\n const clientInfo = server.server.getClientVersion();\n void createMcpEmitter({\n clientInfo,\n packageVersion,\n })\n .then(async (emitter) => {\n currentEmitter = emitter;\n await emitter.emitStart();\n })\n .catch(() => {\n // telemetry must never break the server; swallow setup/emit errors.\n });\n };\n\n return server;\n}\n","import { validate } from '@walkeros/cli';\nimport type { ValidateResult } from '@walkeros/cli';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { ValidateOutputShape } from '../schemas/output.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport {\n HINT_OUT_OF_PROCESS,\n refusalHint,\n RuntimeRefusal,\n type FlowRuntime,\n} from '../runtime/types.js';\nimport { isCloudId } from '../cloud-flow.js';\n\ntype ValidateType = 'contract' | 'event' | 'flow' | 'mapping';\n\n/**\n * Resolve the validate input through the runtime. For `type: 'event'`, a bare\n * string the runtime cannot resolve is the event-name shorthand and becomes\n * `{ name }`; the shorthand reads nothing, so it holds under every runtime.\n * Every other failure surfaces: a `RuntimeRefusal` (a policy decision), a\n * failed saved-id lookup, and any load error for a flow, mapping or contract.\n */\nasync function loadValidateInput(\n runtime: FlowRuntime,\n input: string,\n type: ValidateType,\n): Promise<unknown> {\n if (!input || input.trim() === '') throw new Error(`${type} is required`);\n const trimmed = input.trim();\n const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');\n try {\n return await runtime.load(input);\n } catch (error) {\n if (error instanceof RuntimeRefusal || isCloudId(trimmed)) throw error;\n if (looksLikeJson) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse ${type}. ${message}`);\n }\n if (type === 'event') return { name: trimmed };\n throw error;\n }\n}\n\nconst TITLE = 'Validate Flow';\nconst DESCRIPTION =\n 'Validate walkerOS events, flow configurations, mapping rules, or data contracts. ' +\n '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. ' +\n \"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). \" +\n 'flow and path narrow the run; strict turns warnings and skips into failures: valid is false. ' +\n '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).';\n\nconst inputSchema = schemas.ValidateInputShape;\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createFlowValidateToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_validate',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowValidateHandlerBody(runtime, input),\n };\n}\n\nasync function flowValidateHandlerBody(runtime: FlowRuntime, input: unknown) {\n const parsed = schemas.ValidateInputSchema.safeParse(input ?? {});\n if (!parsed.success) {\n return mcpError(parsed.error, 'Check the flow_validate input fields');\n }\n const {\n type,\n input: validateInput,\n flow,\n path,\n strict,\n offline,\n } = parsed.data;\n try {\n // Resolve the input through the runtime and validate the parsed document.\n // Handed a string, the cli `validate` would read files and URLs itself;\n // handing it the parsed object keeps every read behind the runtime.\n const resolved = await loadValidateInput(runtime, validateInput, type);\n const configDir = runtime.baseDir?.(validateInput);\n const result: ValidateResult = await validate(type, resolved, {\n flow,\n path,\n strict,\n offline,\n ...(configDir ? { configDir } : {}),\n });\n\n const skipped = result.details.skipped ?? [];\n const next = runtime.simulate\n ? ['Use flow_simulate to test event flow', 'Use flow_bundle to build']\n : [HINT_OUT_OF_PROCESS];\n const hints =\n !result.valid && result.errors.length === 0\n ? {\n next: [\n `strict: ${result.warnings.length} warning(s) and ${skipped.length} skipped check(s) count as failures; resolve them, or run without strict`,\n ],\n }\n : !result.valid\n ? {\n next: [\n 'Fix errors above, then run flow_validate again',\n 'Read walkeros://reference/flow-schema for correct structure',\n ],\n }\n : skipped.length > 0\n ? {\n next: [\n `Valid in checked scope; ${skipped.length} check(s) skipped, see details.skipped`,\n ...next,\n ],\n }\n : { next };\n // Validation `message` and `path` are tool-generated, not echoed user\n // input — both stay literal, never wrapped in <user_data>.\n return mcpResult(result, hints);\n } catch (error) {\n return mcpError(\n error,\n refusalHint(\n error,\n 'Check the input parameter — expected a JSON string, file path, or URL',\n ),\n );\n }\n}\n\nexport function registerFlowValidateTool(\n server: McpServer,\n runtime: FlowRuntime,\n) {\n const spec = createFlowValidateToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: ValidateOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowValidateHandlerBody(runtime, args),\n );\n}\n","import { z } from 'zod';\n\n// CLI tool output shapes\nconst ValidateIssueFields = {\n path: z.string(),\n message: z.string(),\n value: z.unknown().optional(),\n code: z\n .string()\n .optional()\n .describe('Stable code (the documented validate code list)'),\n keyword: z\n .string()\n .optional()\n .describe('JSON Schema keyword of an ENTRY_SCHEMA finding'),\n};\n\nexport const ValidateOutputShape = {\n valid: z.boolean().describe('Whether validation passed'),\n type: z\n .union([\n z.enum(['contract', 'entry', 'event', 'flow', 'mapping']),\n z.string().regex(/^(destinations|sources|transformers)\\.\\w+$/),\n ])\n .describe('What was validated'),\n errors: z.array(z.object(ValidateIssueFields)).describe('Validation errors'),\n warnings: z\n .array(\n z.object({\n ...ValidateIssueFields,\n suggestion: z.string().optional(),\n }),\n )\n .describe('Validation warnings'),\n details: z\n .object({\n scope: z\n .object({\n flows: z.array(z.string()),\n entry: z\n .object({\n section: z.string().optional(),\n key: z.string(),\n flows: z.array(z.string()),\n searchedFlows: z.array(z.string()),\n })\n .optional(),\n checks: z.array(z.string()),\n offline: z.literal(true).optional(),\n })\n .optional()\n .describe('What the run covered'),\n skipped: z\n .array(\n z.object({\n path: z.string(),\n check: z.string(),\n reason: z.string(),\n code: z.string(),\n }),\n )\n .optional()\n .describe('Checks in scope that did not run, with the reason'),\n deferred: z\n .array(z.object({ path: z.string(), reference: z.string() }))\n .optional()\n .describe('Values known only at runtime, not schema-checked'),\n })\n .catchall(z.unknown())\n .describe('Additional validation details'),\n _hints: z\n .object({\n next: z.array(z.string()).optional(),\n warnings: z.array(z.string()).optional(),\n })\n .optional()\n .describe('Suggested next steps'),\n};\n\nexport const BundleOutputShape = {\n success: z.boolean().describe('Whether bundling succeeded'),\n totalSize: z.number().optional().describe('Total bundle size in bytes'),\n buildTime: z.number().optional().describe('Build time in milliseconds'),\n packages: z\n .array(\n z.object({\n name: z.string(),\n }),\n )\n .optional()\n .describe('Names of packages included in the bundle'),\n treeshakingEffective: z\n .boolean()\n .optional()\n .describe('Whether tree-shaking was effective'),\n message: z.string().optional().describe('Status message'),\n};\n\nexport const SimulateOutputShape = {\n success: z.boolean().describe('Whether simulation succeeded'),\n error: z.string().optional().describe('Error message if failed'),\n summary: z.string().describe('One-line result summary'),\n destinations: z\n .record(\n z.string(),\n z.object({\n received: z\n .boolean()\n .describe('Whether destination received the event'),\n calls: z.number().describe('Number of API calls made'),\n payload: z\n .unknown()\n .optional()\n .describe('All intercepted API calls (only when verbose: true)'),\n }),\n )\n .optional()\n .describe('Per-destination results'),\n capturedEvents: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe('Events captured by source simulation'),\n calls: z\n .array(z.unknown())\n .optional()\n .describe(\n 'Calls a simulated source made on its mock env (only when verbose: true)',\n ),\n skipped: z\n .object({\n reason: z.enum(['consent', 'pending']),\n required: z.record(z.string(), z.boolean()).optional(),\n granted: z.record(z.string(), z.boolean()).optional(),\n require: z.array(z.string()).optional(),\n })\n .optional()\n .describe(\n 'Why the destination sent nothing: a consent skip, or waiting for its require',\n ),\n duration: z.number().optional().describe('Simulation duration in ms'),\n};\n\nexport const PushOutputShape = {\n success: z.boolean().describe('Whether push succeeded'),\n elbResult: z.unknown().optional().describe('Push result from the collector'),\n duration: z.number().describe('Push duration in milliseconds'),\n error: z.string().optional().describe('Error message if push failed'),\n};\n\n// Examples List output shape\nexport const ExamplesListOutputShape = {\n flow: z.string().describe('Flow name'),\n count: z.number().describe('Number of examples found'),\n examples: z\n .array(\n z.object({\n step: z.string().describe('Step location (e.g., \"destination.gtag\")'),\n stepType: z\n .enum(['source', 'transformer', 'destination'])\n .describe('Step type'),\n stepName: z.string().describe('Step name'),\n exampleName: z.string().describe('Example name'),\n source: z\n .enum(['inline', 'package'])\n .describe(\n 'Where the example came from: \"inline\" (defined in the flow step) or \"package\" (shipped by the referenced package)',\n ),\n title: z.string().optional().describe('Human-readable title if set'),\n description: z\n .string()\n .optional()\n .describe('Short human-readable description'),\n public: z\n .boolean()\n .optional()\n .describe(\n 'Whether the example is public (defaults to true if omitted)',\n ),\n hasIn: z.boolean().describe('Whether the example has an input value'),\n hasOut: z.boolean().describe('Whether the example has an output value'),\n hasMapping: z\n .boolean()\n .describe('Whether the example has a mapping configuration'),\n hasTrigger: z\n .boolean()\n .describe('Whether the example has trigger metadata'),\n in: z.unknown().optional().describe('Input event data'),\n out: z.unknown().optional().describe('Expected output data'),\n mapping: z\n .unknown()\n .optional()\n .describe('Mapping configuration for destinations'),\n trigger: z\n .object({\n type: z.string().optional(),\n options: z.unknown().optional(),\n })\n .optional()\n .describe('Trigger metadata for source simulation'),\n }),\n )\n .describe('Step examples'),\n};\n","import type { Flow, Ingest, Simulation, WalkerOS } from '@walkeros/core';\nimport type { BundleStats, PushResult } from '@walkeros/cli';\n\n/**\n * The capability seam between the flow tools and the machine they run on.\n *\n * Every file read, URL fetch, bundle, simulation and push a tool performs goes\n * through a `FlowRuntime` and nothing else, so the runtime alone decides what\n * the process it lives in may do:\n *\n * - `createLocalRuntime()` keeps every capability. It is for the user's own\n * machine (stdio, the developer CLI), where the user is responsible for what\n * runs there.\n * - `createHostedRuntime(client)` is least privilege for a shared, network\n * reached process: it loads inline JSON and saved flow ids only, refuses\n * local paths and URLs, and has no `bundle`, `simulate` or `push` at all.\n *\n * A tool whose operation the runtime does not provide refuses with a hint that\n * names only out-of-process routes.\n */\nexport interface FlowRuntime {\n /**\n * Resolve a config input to parsed JSON. Local: a file path, an http(s) URL\n * or inline JSON. Hosted: inline JSON or a saved `flow_`/`cfg_` id; a local\n * path or URL is refused with a `RuntimeRefusal`.\n */\n load(input: string): Promise<unknown>;\n /**\n * The directory local `path` packages of a loaded input resolve against:\n * the input file's directory. Absent on a runtime without a filesystem,\n * where such packages stay a reported skip.\n */\n baseDir?(input: string): string | undefined;\n /** Compile a flow. Absent on a runtime that must not build in its process. */\n bundle?(input: string, opts: BundleOptions): Promise<BundleStats | void>;\n /** Build and run one step of a flow. Absent where that must not happen. */\n simulate?(input: string, opts: SimulateOptions): Promise<Simulation.Result>;\n /**\n * The values of the secrets a flow config references (`$secret.NAME`),\n * masked wherever a simulation or push result egresses. Read by the tools\n * only on a runtime without `loadRun`; a read that fails stops the run.\n */\n knownSecrets?(input: string): Promise<string[]>;\n /**\n * Read a push or simulate input once: the config and the values of the\n * secrets it references. A prebuilt bundle yields no config. A read that\n * fails rejects. Absent with `simulate` and `push`.\n */\n loadRun?(input: string): Promise<LoadedRun>;\n /** Build and run a flow against real destinations. Absent where forbidden. */\n push?(\n input: string,\n event: Record<string, unknown>,\n opts: PushOptions,\n ): Promise<PushResult>;\n}\n\nexport interface BundleOptions {\n flowName?: string;\n stats?: boolean;\n output?: string;\n}\n\nexport type SimulateStepType =\n | 'source'\n | 'transformer'\n | 'collector'\n | 'destination';\n\nexport interface SimulateOptions {\n stepType: SimulateStepType;\n stepId: string;\n event: unknown;\n flow?: string;\n /** The config from `loadRun`: the runtime does not read the input again. */\n config?: Flow.Json;\n /**\n * Transformer, collector and destination steps: pipeline context the step\n * reads via `ctx.ingest`. Source steps ignore it.\n */\n ingest?: Omit<Ingest, '_meta'>;\n /**\n * Collector state the step starts from. `consent` applies to every step\n * (the collector's starting consent); `user`, `globals` and `timing` to\n * collector steps only.\n */\n state?: {\n consent?: WalkerOS.Consent;\n user?: WalkerOS.User;\n globals?: WalkerOS.Properties;\n timing?: number;\n };\n /**\n * Destination steps only: run this collector command with `event` as its\n * data instead of pushing it (a step example with `command`).\n */\n command?: Flow.StepCommand;\n}\n\n/** A push or simulate input as read once by `loadRun`. */\nexport interface LoadedRun {\n config?: Flow.Json;\n knownSecrets: string[];\n}\n\nexport interface PushOptions {\n flow?: string;\n platform?: 'web' | 'server';\n /** The config from `loadRun`: the runtime does not read the input again. */\n config?: Flow.Json;\n}\n\n/**\n * Thrown by a runtime when it refuses an input on principle rather than on a\n * fault. Carries the hint a tool should surface next to the message.\n */\nexport class RuntimeRefusal extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n super(message);\n this.name = 'RuntimeRefusal';\n this.hint = hint;\n }\n}\n\n/** The hint for a refused runtime error, or a tool's own fallback otherwise. */\nexport function refusalHint(error: unknown, fallback: string): string {\n return error instanceof RuntimeRefusal ? error.hint : fallback;\n}\n\n/**\n * Every route named here runs outside the tool's process: the app's own deploy\n * pipeline, or the caller's own machine. A refused\n * caller is never pointed at another in-process route, such as saving the\n * flow and simulating it by id, which would be the same execution one step\n * later.\n */\nexport const HINT_OUT_OF_PROCESS =\n 'Build and deploy through the app with deploy_manage. To simulate, validate or bundle, use the walkerOS CLI on your own machine.';\n\n/** The refusal a tool raises when its runtime does not provide an operation. */\nexport function unavailableOperation(\n operation: 'bundle' | 'simulate' | 'push',\n): RuntimeRefusal {\n const verb =\n operation === 'bundle'\n ? 'Bundling'\n : operation === 'simulate'\n ? 'Simulating'\n : 'Running';\n return new RuntimeRefusal(\n `${verb} a flow is not available on the hosted walkerOS MCP server.`,\n HINT_OUT_OF_PROCESS,\n );\n}\n","import { isObject, type WalkerOS } from '@walkeros/core';\n\n/**\n * Saved flow references, shared by every place that recognises or reads one.\n *\n * `flow_` and `cfg_` are the reserved cloud flow/config id namespaces. The\n * pattern is anchored and limited to id characters, so a path that merely\n * starts with a prefix (`flow_../x`) is never mistaken for an id.\n */\nexport const CLOUD_ID_PATTERN = /^(flow|cfg)_[A-Za-z0-9_-]+$/;\n\nexport function isCloudId(input: string): boolean {\n return CLOUD_ID_PATTERN.test(input);\n}\n\n/**\n * The config of a flow record returned by the tool client, or `{}` when the\n * record carries none. The client seam returns an opaque shape, so this is the\n * one narrowing every reader shares.\n */\nexport function flowConfigOf(flow: unknown): WalkerOS.AnyObject {\n return isObject(flow) && isObject(flow.config) ? flow.config : {};\n}\n","import { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { BundleOutputShape } from '../schemas/output.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { resolveConfigPath } from './resolve-config-path.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n} from '../runtime/types.js';\n\nconst TITLE = 'Bundle Flow';\nconst DESCRIPTION =\n 'Bundle a walkerOS flow configuration into deployable JavaScript. ' +\n 'Resolves all destinations, sources, and transformers, then outputs ' +\n 'a tree-shaken production bundle. Returns bundle statistics.';\n\nconst inputSchema = {\n ...schemas.BundleInputShape,\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowBundleToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_bundle',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowBundleHandlerBody(client, runtime, input),\n };\n}\n\nasync function flowBundleHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, flow, stats, output } = parsed.data;\n // Bundling compiles the config and resolves every package it names. A\n // runtime that must not do that in its process provides no `bundle`.\n if (!runtime.bundle) {\n const refusal = unavailableOperation('bundle');\n return mcpError(refusal, refusal.hint);\n }\n try {\n // Accept a cloud flow/config id as configPath, resolving it to inline JSON.\n const resolvedConfigPath = await resolveConfigPath(client, configPath);\n const result = await runtime.bundle(resolvedConfigPath, {\n flowName: flow,\n stats: stats ?? true,\n output,\n });\n\n if (!result) {\n return mcpResult(\n { success: false, message: 'Bundle produced no output' },\n {\n warnings: [\n 'The build returned no result. The flow may be empty or misconfigured.',\n ],\n next: ['Run flow_validate to check your configuration'],\n },\n );\n }\n\n return mcpResult(\n { success: true, ...result },\n {\n next: [\n 'Use flow_simulate to test',\n 'Use deploy_manage with action \"deploy\" to publish',\n ],\n },\n );\n } catch (error) {\n return mcpError(\n error,\n refusalHint(error, 'Run flow_validate for detailed error messages'),\n );\n }\n}\n\nexport function registerFlowBundleTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowBundleToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: BundleOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowBundleHandlerBody(client, runtime, args),\n );\n}\n","import { z, type ZodRawShape } from 'zod';\nimport { mcpError } from '@walkeros/core';\n\n/** A tool's input as its input shape parses it, defaults applied. */\nexport type ToolInput<S extends ZodRawShape> = z.output<z.ZodObject<S>>;\n\n/**\n * Every issue as one readable line, `path: message; ...`. A raw ZodError\n * stringifies its whole issue list into `message`, so it is never passed on\n * as is.\n */\nexport function inputIssuesMessage(error: z.ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.join('.') || 'input'}: ${issue.message}`)\n .join('; ');\n}\n\n/**\n * Parse, never assert: a tool spec is drivable without a transport, so its\n * handler applies the same input shape the transport validates against.\n * Input that fails it comes back as an error result.\n */\nexport function parseToolInput<S extends ZodRawShape>(\n shape: S,\n raw: unknown,\n):\n | { ok: true; data: ToolInput<S> }\n | { ok: false; error: ReturnType<typeof mcpError> } {\n const parsed = z.object(shape).safeParse(raw ?? {});\n if (!parsed.success) {\n return {\n ok: false,\n error: mcpError(new Error(inputIssuesMessage(parsed.error))),\n };\n }\n return { ok: true, data: parsed.data };\n}\n","import type { ToolClient } from '../tool-client.js';\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\n\n/**\n * Resolve a `configPath` for tools that consume it (simulate, bundle). When it\n * is a cloud flow/config id, fetch the flow via the same client seam `flow_load`\n * uses and return its config serialized as JSON (the underlying CLI functions\n * accept inline JSON as `configPath`). Otherwise return the value unchanged so\n * file paths, URLs, and inline JSON pass through as before.\n */\nexport async function resolveConfigPath(\n client: Pick<ToolClient, 'getFlow'>,\n configPath: string,\n): Promise<string> {\n if (!isCloudId(configPath)) return configPath;\n\n const flow = await client.getFlow({ flowId: configPath });\n return JSON.stringify(flowConfigOf(flow));\n}\n","import { z } from 'zod';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { filterValues, mcpResult, mcpError } from '@walkeros/core';\nimport type { Flow, Ingest, Simulation, WalkerOS } from '@walkeros/core';\nimport { SimulateOutputShape } from '../schemas/output.js';\nimport { FLOW_SIMULATE_DESCRIPTION } from './simulate-description.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { resolveConfigPath } from './resolve-config-path.js';\nimport { readRun, scrubbed, scrubbedError } from './egress.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n type SimulateStepType,\n} from '../runtime/types.js';\n\ninterface DestinationSummary {\n received: boolean;\n calls: number;\n payload?: unknown;\n}\n\nconst STEP_TYPES: readonly SimulateStepType[] = [\n 'source',\n 'transformer',\n 'collector',\n 'destination',\n];\n\nfunction isStepType(value: string): value is SimulateStepType {\n return STEP_TYPES.some((t) => t === value);\n}\n\nconst TITLE = 'Simulate Flow';\nconst COMMANDS: readonly [Flow.StepCommand, ...Flow.StepCommand[]] = [\n 'config',\n 'consent',\n 'user',\n 'run',\n];\n\nconst inputSchema = {\n configPath: schemas.SimulateInputShape.configPath,\n event: z\n .union([z.record(z.string(), z.unknown()), z.string()])\n .optional()\n .describe(\n \"For destinations: { name, data, consent? }; the event's consent counts \" +\n \"toward the destination's consent requirement, on top of state.consent. \" +\n \"With command: the command's data, e.g. { marketing: true } for consent. \" +\n 'For sources: { content, trigger? } where content is the walkerOS event ' +\n \"{ name, data }. A web source's page URL goes in trigger.options.url \" +\n '(default http://localhost). ' +\n 'Can also be a JSON string or file path.',\n ),\n flow: schemas.SimulateInputShape.flow,\n platform: schemas.SimulateInputShape.platform,\n // Override the (optional) CLI `step` shape: the simulate handler hard-requires\n // a target step (no all-steps mode), so the registered schema must be honest.\n step: z\n .string()\n .describe(\n 'Required. Target step as \"type.name\", e.g. \"source.demo\", \"collector.default\", \"destination.gtag\", \"transformer.router\". ' +\n 'A collector step runs enrichment and then collector.next, returning every event the destinations would receive (none after a stop).',\n ),\n verbose: z\n .boolean()\n .optional()\n .describe('Include full payload per destination (default: false)'),\n ingest: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\n 'Pipeline context a step reads via ctx.ingest, e.g. { url } for a ' +\n 'request decoder or { ip, userAgent } for a conversion API. Used for ' +\n 'transformer, collector and destination steps (their before chains ' +\n 'included); _meta is always set by the runtime.',\n ),\n state: z\n .object({\n consent: z.record(z.string(), z.boolean()).optional(),\n user: z.record(z.string(), z.unknown()).optional(),\n globals: z.record(z.string(), z.unknown()).optional(),\n timing: z.number().optional(),\n })\n .optional()\n .describe(\n 'Collector state the step starts from. consent: every step (starts a ' +\n 'destination that requires consent and feeds its consent check; for a ' +\n 'source, the consent a consent-gated source waits for). ' +\n 'user/globals/timing: collector steps, seeded before enrichment runs.',\n ),\n command: z\n .enum(COMMANDS)\n .optional()\n .describe(\n 'Destination steps only: run this collector command with event as its ' +\n 'data instead of pushing it, as a step example with command does.',\n ),\n};\n\nconst annotations = {\n // Simulation downloads the packages a config names and runs caller-controlled\n // flow code in process. Destinations are mocked, but that code is not, so the\n // hints stay conservative: side effects possible, repeat calls not assumed\n // safe, external systems reachable.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowSimulateToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_simulate',\n title: TITLE,\n description: FLOW_SIMULATE_DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowSimulateHandlerBody(client, runtime, input),\n };\n}\n\n/** Plain values kept as walkerOS properties; values no property can hold dropped. */\nfunction toProperties(\n value: Record<string, unknown> | undefined,\n): WalkerOS.Properties | undefined {\n if (!value) return undefined;\n const properties: WalkerOS.Properties = {};\n for (const [key, entry] of Object.entries(value)) {\n const property = filterValues(entry);\n if (property !== undefined) properties[key] = property;\n }\n return properties;\n}\n\nasync function flowSimulateHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n configPath,\n event,\n flow,\n platform,\n step,\n verbose,\n ingest,\n state,\n command,\n } = parsed.data;\n // Simulation compiles the config and imports the bundle, running caller\n // controlled flow code. A runtime that must not do that in its process\n // provides no `simulate`, whatever the input looks like.\n if (!runtime.simulate) {\n const refusal = unavailableOperation('simulate');\n return mcpError(refusal, refusal.hint);\n }\n let known: string[] = [];\n try {\n if (!event) {\n throw new Error(\n 'event is required. For sources provide { content, trigger? }, for destinations provide { name, data }.',\n );\n }\n\n if (!step) {\n throw new Error(\n 'step is required. Specify a target like \"source.browser\", \"destination.gtag\", or \"transformer.demo\".',\n );\n }\n\n // Resolve string event input (JSON string)\n let resolvedEvent: unknown = event;\n if (typeof event === 'string') {\n try {\n resolvedEvent = JSON.parse(event);\n } catch {\n throw new Error(\n 'Event string must be valid JSON. Got: ' + event.substring(0, 50),\n );\n }\n }\n\n // Parse step into type and id\n const dotIndex = step.indexOf('.');\n if (dotIndex === -1) {\n throw new Error(\n `Invalid step format \"${step}\". Use \"type.name\" (e.g. \"source.browser\", \"destination.gtag\").`,\n );\n }\n const stepType = step.substring(0, dotIndex);\n const stepId = step.substring(dotIndex + 1);\n\n if (!isStepType(stepType)) {\n throw new Error(\n `Unknown step type \"${stepType}\". Use \"source\", \"collector\", \"transformer\", or \"destination\".`,\n );\n }\n\n if (command !== undefined && stepType !== 'destination') {\n throw new Error('command applies to destination steps only.');\n }\n\n // Accept a cloud flow/config id as configPath, resolving it to inline JSON.\n const resolvedConfigPath = await resolveConfigPath(client, configPath);\n // Read once: the simulation runs on exactly the config whose secrets\n // mask the result.\n const run = await readRun(runtime, resolvedConfigPath);\n known = run.knownSecrets;\n\n const result: Simulation.Result = await runtime.simulate(\n resolvedConfigPath,\n {\n stepType,\n stepId,\n event: resolvedEvent,\n flow,\n ingest,\n state: state && {\n consent: state.consent,\n user: toProperties(state.user),\n globals: toProperties(state.globals),\n timing: state.timing,\n },\n command,\n config: run.config,\n },\n );\n\n const success = !result.error;\n const errorMessage = result.error?.message;\n\n // Source simulation: captured events are result.events, the source's\n // own walker commands its `elb` calls. Mock-env calls stay verbose-only.\n if (result.step === 'source') {\n const eventCount = result.events.length;\n const commandCount = result.calls.filter(\n (call) => call.fn === 'elb',\n ).length;\n const summary =\n `Source captured ${eventCount} event${eventCount !== 1 ? 's' : ''}` +\n ` and ${commandCount} command${commandCount !== 1 ? 's' : ''}`;\n const shownCalls = verbose\n ? result.calls\n : result.calls.filter((call) => call.fn === 'elb');\n\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary,\n capturedEvents: result.events,\n ...(shownCalls.length > 0 ? { calls: shownCalls } : {}),\n duration: result.duration,\n },\n known,\n ),\n {\n next:\n eventCount + commandCount > 0\n ? [\n 'Use flow_simulate with a destination step to test downstream processing',\n ]\n : [\n 'Check source package examples with package_get, verify trigger type matches',\n ],\n },\n );\n }\n\n // Transformer simulation: surface the transformed events\n if (result.step === 'transformer') {\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary: `Transformer processed event`,\n capturedEvents: result.events,\n duration: result.duration,\n },\n known,\n ),\n {\n next: ['Use flow_bundle to build for production'],\n },\n );\n }\n\n // Collector simulation: surface the enriched event\n if (result.step === 'collector') {\n return mcpResult(\n scrubbed(\n {\n success,\n error: errorMessage,\n summary: `Collector enriched event`,\n capturedEvents: result.events,\n duration: result.duration,\n },\n known,\n ),\n {\n next: ['Use flow_simulate with a destination step to test delivery'],\n },\n );\n }\n\n // Destination simulation: count intercepted env calls, key by step name\n const destinations: Record<string, DestinationSummary> = {};\n const callCount = result.calls.length;\n const destSummary: DestinationSummary = {\n received: callCount > 0,\n calls: callCount,\n };\n if (verbose && callCount > 0) {\n destSummary.payload = result.calls;\n }\n destinations[result.name] = destSummary;\n\n const destCount = Object.keys(destinations).length;\n const receivedCount = Object.values(destinations).filter(\n (d) => d.received,\n ).length;\n\n const warnings: string[] = [];\n if (receivedCount === 0 && success) warnings.push(notReceived(result));\n\n const resultObj = {\n success,\n error: errorMessage,\n summary: `${receivedCount}/${destCount} destinations received the event`,\n destinations,\n ...(result.skipped ? { skipped: result.skipped } : {}),\n duration: result.duration,\n };\n\n return mcpResult(scrubbed(resultObj, known), {\n next: ['Use flow_bundle to build for production'],\n ...(warnings.length > 0 ? { warnings } : {}),\n });\n } catch (error) {\n const hint = 'Run flow_validate for detailed error messages';\n return scrubbedError(mcpError(error, refusalHint(error, hint)), known);\n }\n}\n\nfunction keysOf(consent: WalkerOS.Consent | undefined): string {\n const keys = Object.entries(consent ?? {})\n .filter(([, granted]) => granted)\n .map(([key]) => key);\n return keys.length > 0 ? keys.join(', ') : 'none';\n}\n\n/** Why a destination received nothing, from the result's own `skipped`. */\nfunction notReceived(result: Simulation.Result): string {\n const { skipped } = result;\n if (skipped?.reason === 'pending') {\n const require = skipped.require ?? [];\n const waits = require.length ? require.join(', ') : 'its require';\n const advice = require.includes('consent')\n ? 'pass state.consent (e.g. { functional: true }) to start it.'\n : `it starts once the flow provides ${waits}; a simulation cannot seed that.`;\n return `Destination waits for ${waits} (require) and never started: ${advice}`;\n }\n if (skipped?.reason === 'consent') {\n return (\n `Consent skip: requires ${keysOf(skipped.required)}; granted ${keysOf(skipped.granted)}. ` +\n \"Grant it in state.consent or in the event's consent.\"\n );\n }\n return (\n 'Destination made no calls. Common causes: ' +\n '(1) mapping rules do not match the event name or ignore it, ' +\n '(2) policy redacted required fields, ' +\n '(3) a before chain stopped the event.'\n );\n}\n\nexport function registerFlowSimulateTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowSimulateToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: SimulateOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowSimulateHandlerBody(client, runtime, args),\n );\n}\n","/**\n * The flow_simulate tool description, shared by the registered tool and the\n * declarative `TOOL_DEFINITIONS` registry (which must not import the tool's\n * node-only code).\n */\nexport const FLOW_SIMULATE_DESCRIPTION =\n 'Simulate events through a walkerOS flow without making real API calls. ' +\n 'For destinations: event is a walkerOS event { name: \"entity action\", data: {...} }. ' +\n 'For sources: event is { content, trigger?: { type?, options? } }, where content is the ' +\n 'walkerOS event { name: \"entity action\", data: {...} }. Only the simulated source starts. ' +\n 'step (required) targets the step to simulate, e.g. \"destination.gtag\". ' +\n 'Use flow_examples to discover available test data. ' +\n 'A destination simulation starts only its target destination. ' +\n \"A source's own walker commands (e.g. a CMP's walker consent) are returned as elb calls. \" +\n 'Consent: state.consent is the collector consent the step starts from ' +\n '(any step; a consent-gated source such as the session source waits for it). A destination with ' +\n 'require: [\"consent\"] waits until consent is present, so pass state.consent to start it; ' +\n 'a destination with consent: { marketing: true } receives an event only when that ' +\n \"consent is granted in state.consent or in the event's own consent. \" +\n 'When a destination sends nothing, the result says why (waiting for its require, or a consent skip). ' +\n 'command runs a step example with command (e.g. \"consent\") on a destination: ' +\n \"event is the command's data, state.consent still applies first. \" +\n 'Mapping transforms event names and data at the destination level. ' +\n 'Policy redacts or injects fields before mapping runs.';\n","import type { PushResult } from '@walkeros/cli';\nimport { isObject, mcpError, mcpResult } from '@walkeros/core';\nimport { scrubJson, scrubSecrets } from '@walkeros/core/node';\nimport type { FlowRuntime, LoadedRun } from '../runtime/types.js';\n\n/**\n * Simulate and push results carry recorded vendor calls, network requests and\n * vendor responses whose values can hold credentials. They egress like a log\n * line: `scrubJson` (masking the values of the secrets the flow references,\n * `known`, and credential patterns), then parse back into the structured\n * result.\n */\nexport function scrubbed(\n result: Record<string, unknown>,\n known: readonly string[],\n): Record<string, unknown> {\n const parsed = parseObject(scrubJson(result, { known }));\n if (!parsed) throw new Error('Result could not be redacted as JSON.');\n return parsed;\n}\n\n/** An error response as built by `mcpError`; a stub may lack the structured copy. */\ntype ErrorResponse = Omit<ReturnType<typeof mcpError>, 'structuredContent'> & {\n structuredContent?: Record<string, unknown>;\n};\n\n/**\n * The error response egresses the same way: its structured copy is scrubbed,\n * and the text is that copy serialized (as `mcpError` builds it), so it stays\n * valid JSON. Without a structured copy that scrubs, each text part is\n * scrubbed as a line instead, so the error message is never lost.\n */\nexport function scrubbedError(\n response: ErrorResponse,\n known: readonly string[],\n): ReturnType<typeof mcpError> {\n let structuredContent: Record<string, unknown> | undefined;\n try {\n if (response.structuredContent)\n structuredContent = scrubbed(response.structuredContent, known);\n } catch {\n structuredContent = undefined;\n }\n if (structuredContent) {\n return {\n ...response,\n content: [{ type: 'text', text: JSON.stringify(structuredContent) }],\n structuredContent,\n };\n }\n return {\n ...response,\n content: response.content.map((part) => ({\n ...part,\n text: scrubSecrets(part.text, { known }),\n })),\n structuredContent: { error: 'The error could not be redacted.' },\n };\n}\n\n/**\n * A push result as it egresses: scrubbed and parsed back. `success` and\n * `duration` come from the CLI, never from a vendor, and stay as they are so\n * the output schema always holds. A push already happened, so this never\n * throws: if the scrubbed text does not parse, the text alone carries the\n * result and the structured copy keeps the scalars.\n */\nexport function scrubbedPushResult(\n result: PushResult,\n known: readonly string[],\n): ReturnType<typeof mcpResult> {\n const text = scrubJson(result, { known, space: 2 });\n const parsed = parseObject(text);\n if (parsed)\n return mcpResult({\n ...parsed,\n success: result.success,\n duration: result.duration,\n });\n return {\n content: [{ type: 'text', text }],\n structuredContent: { success: result.success, duration: result.duration },\n };\n}\n\nfunction parseObject(text: string): Record<string, unknown> | undefined {\n try {\n const parsed: unknown = JSON.parse(text);\n return isObject(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The run input read once: `loadRun`, else, on a runtime without it, the\n * values its `knownSecrets` returns. A failed read rejects, so the caller\n * stops instead of egressing with pattern masking only.\n */\nexport async function readRun(\n runtime: FlowRuntime,\n input: string,\n): Promise<LoadedRun> {\n if (runtime.loadRun) return runtime.loadRun(input);\n return {\n knownSecrets: runtime.knownSecrets ? await runtime.knownSecrets(input) : [],\n };\n}\n","import { z } from 'zod';\nimport type { PushResult } from '@walkeros/cli';\nimport { schemas } from '@walkeros/cli/dev';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { mcpError } from '@walkeros/core';\nimport { PushOutputShape } from '../schemas/output.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { readRun, scrubbedError, scrubbedPushResult } from './egress.js';\nimport {\n refusalHint,\n unavailableOperation,\n type FlowRuntime,\n} from '../runtime/types.js';\n\nconst TITLE = 'Push Events';\nconst DESCRIPTION =\n 'Push a real event through a walkerOS flow to actual destinations. ' +\n 'Makes real API calls to real endpoints. ' +\n 'Best suited for server-side flows — web flows should use flow_simulate for testing.';\n\nconst inputSchema = {\n configPath: schemas.PushInputShape.configPath,\n event: z\n .record(z.string(), z.unknown())\n .describe(\n 'Event object, e.g. { name: \"page view\", data: { title: \"Home\" } }',\n ),\n flow: schemas.PushInputShape.flow,\n platform: schemas.PushInputShape.platform,\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFlowPushToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_push',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowPushHandlerBody(runtime, input),\n };\n}\n\nasync function flowPushHandlerBody(\n runtime: FlowRuntime,\n input: unknown,\n): Promise<CallToolResult> {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, event, flow, platform } = parsed.data;\n // Push compiles the config, imports it, and makes real outbound calls. A\n // runtime that must not do that in its process provides no `push`.\n if (!runtime.push) {\n const refusal = unavailableOperation('push');\n return mcpError(refusal, refusal.hint);\n }\n // Push results can carry vendor requests and responses: they egress with\n // the flow's secret values and credential patterns masked. The config is\n // read once, so the push runs on exactly the config whose secrets mask the\n // result; a config that cannot be read stops the push.\n let known: string[] = [];\n try {\n const run = await readRun(runtime, configPath);\n known = run.knownSecrets;\n const result: PushResult = await runtime.push(configPath, event, {\n flow,\n platform,\n config: run.config,\n });\n\n if (!result.success) {\n return scrubbedError(\n mcpError(\n new Error(result.error || 'Push failed'),\n 'Check destination configuration and connectivity.',\n ),\n known,\n );\n }\n\n return scrubbedPushResult(result, known);\n } catch (error) {\n return scrubbedError(\n mcpError(\n error,\n refusalHint(\n error,\n 'Check configPath and event format. For web flows, use flow_simulate.',\n ),\n ),\n known,\n );\n }\n}\n\nexport function registerFlowPushTool(server: McpServer, runtime: FlowRuntime) {\n const spec = createFlowPushToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: PushOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowPushHandlerBody(runtime, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackage, mcpResult, mcpError } from '@walkeros/core';\nimport type { Flow, WalkerOSPackage } from '@walkeros/core';\nimport { resolveExportName, selectDevExamples } from '@walkeros/cli';\nimport { ExamplesListOutputShape } from '../schemas/output.js';\nimport { getPackageBaseUrl, CLIENT_HEADER } from '../catalog.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport { isFlowJson, stepExamplesOf, type StepExampleView } from './narrow.js';\nimport {\n HINT_OUT_OF_PROCESS,\n refusalHint,\n type FlowRuntime,\n} from '../runtime/types.js';\n\n/** Upper bound on distinct package example lookups per call. */\nexport const MAX_PACKAGE_LOOKUPS = 25;\n\nconst TITLE = 'Flow Examples';\nconst DESCRIPTION =\n 'List all step examples in a walkerOS flow configuration. ' +\n 'Shows example names, step locations, and in/out shapes. ' +\n 'Inline examples on a step take precedence; steps without inline examples ' +\n 'fall back to the examples shipped by their referenced package. ' +\n 'Each result is tagged with its source (\"inline\" or \"package\"). ' +\n 'On the hosted server configPath accepts only inline JSON or a saved flow id (flow_ or cfg_), no file paths or URLs. ' +\n 'Use this to discover available test fixtures and simulation data.';\n\nconst inputSchema = {\n configPath: z\n .string()\n .min(1)\n .describe(\n 'Inline JSON string, file path, or URL of a flow configuration (hosted server: inline JSON or a saved flow id only)',\n ),\n flow: z.string().optional().describe('Flow name for multi-flow configs'),\n step: z\n .string()\n .optional()\n .describe('Filter to a specific step (e.g., \"destination.gtag\")'),\n full: z\n .boolean()\n .optional()\n .describe(\n 'Return full in/out/mapping data for each example (default: false, returns metadata only)',\n ),\n includeHidden: z\n .boolean()\n .optional()\n .describe(\n 'Include examples marked public: false (default: false). Set true for test/debug discovery.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n} as const;\n\nexport function createFlowExamplesToolSpec(runtime: FlowRuntime): ToolSpec {\n return {\n name: 'flow_examples',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowExamplesHandlerBody(runtime, input),\n };\n}\n\nasync function flowExamplesHandlerBody(runtime: FlowRuntime, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { configPath, flow, step, full, includeHidden } = parsed.data;\n try {\n const rawConfig = await runtime.load(configPath);\n if (!isFlowJson(rawConfig)) {\n throw new Error('Config is not a flow config: it has no flows object.');\n }\n\n // Resolve flow name\n const flowNames = Object.keys(rawConfig.flows || {});\n const flowName =\n flow || (flowNames.length === 1 ? flowNames[0] : undefined);\n\n if (!flowName) {\n throw new Error(\n `Multiple flows found. Specify flow parameter. Available: ${flowNames.join(', ')}`,\n );\n }\n\n const flowSettings = rawConfig.flows[flowName];\n if (!flowSettings) {\n throw new Error(`Flow \"${flowName}\" not found`);\n }\n\n // Collect all examples\n type ExampleItem = {\n step: string;\n stepType: string;\n stepName: string;\n exampleName: string;\n source: 'inline' | 'package';\n title?: string;\n description?: string;\n public?: boolean;\n hasIn: boolean;\n hasOut: boolean;\n hasMapping: boolean;\n hasTrigger: boolean;\n in?: unknown;\n out?: unknown;\n mapping?: unknown;\n trigger?: unknown;\n };\n const examples: ExampleItem[] = [];\n\n const toItems = (\n stepExamples: Record<string, StepExampleView>,\n type: string,\n name: string,\n source: 'inline' | 'package',\n ): ExampleItem[] => {\n const items: ExampleItem[] = [];\n for (const [exName, ex] of Object.entries(stepExamples)) {\n if (!includeHidden && ex.public === false) continue;\n items.push({\n step: `${type}.${name}`,\n stepType: type,\n stepName: name,\n exampleName: exName,\n source,\n title: ex.title,\n description: ex.description,\n public: ex.public,\n hasIn: ex.in !== undefined,\n hasOut: ex.out !== undefined,\n hasMapping: ex.mapping !== undefined,\n hasTrigger: ex.trigger !== undefined,\n ...(full\n ? {\n in: ex.in,\n out: ex.out,\n mapping: ex.mapping,\n trigger: ex.trigger,\n }\n : {}),\n });\n }\n return items;\n };\n\n // Pull a referenced package's shipped examples via the same path\n // package_get uses. A failed fetch must not break the whole tool: the\n // step is skipped and inline examples from other steps still return.\n const baseUrl = getPackageBaseUrl();\n const loadPackage = async (\n packageName: string,\n ): Promise<WalkerOSPackage | undefined> => {\n try {\n return await fetchPackage(packageName, {\n baseUrl,\n client: CLIENT_HEADER,\n });\n } catch {\n // Swallow: graceful fallback skip for this package.\n }\n return undefined;\n };\n\n // One lookup per distinct package, capped per call, so a config naming\n // many packages cannot fan out into an unbounded number of fetches.\n const packageLookups = new Map<\n string,\n Promise<WalkerOSPackage | undefined>\n >();\n let skippedPackages = false;\n const skippedExamples: string[] = [];\n const packageFor = (\n packageName: string,\n ): Promise<WalkerOSPackage | undefined> => {\n const existing = packageLookups.get(packageName);\n if (existing) return existing;\n if (packageLookups.size >= MAX_PACKAGE_LOOKUPS) {\n skippedPackages = true;\n return Promise.resolve(undefined);\n }\n const lookup = loadPackage(packageName);\n packageLookups.set(packageName, lookup);\n return lookup;\n };\n\n // The step examples of the step's own export: a multi-export package\n // ships `exportExamples` keyed by export name, the same rule simulate\n // uses (an export missing from the map has no examples).\n const stepExamplesFor = (\n info: WalkerOSPackage,\n exportName: string | undefined,\n ): ReturnType<typeof stepExamplesOf> => {\n const selected = selectDevExamples(\n { examples: info.examples, exportExamples: info.exportExamples },\n exportName,\n );\n return stepExamplesOf(selected?.step);\n };\n\n const stepTypes = [\n { key: 'sources' as const, type: 'source' as const },\n { key: 'transformers' as const, type: 'transformer' as const },\n { key: 'destinations' as const, type: 'destination' as const },\n ];\n\n for (const { key, type } of stepTypes) {\n const refs = flowSettings[key] || {};\n for (const [name, ref] of Object.entries(refs)) {\n // Apply step filter\n if (step && `${type}.${name}` !== step) continue;\n\n // Inline examples take precedence over package-shipped ones.\n if (ref.examples) {\n examples.push(...toItems(ref.examples, type, name, 'inline'));\n continue;\n }\n\n // No inline examples: fall back to the referenced package's shipped\n // examples (only for refs that actually name a package).\n if (!ref.package) continue;\n const info = await packageFor(ref.package);\n if (!info) continue;\n const { exportName } = resolveExportName(flowSettings, type, name);\n const packageExamples = stepExamplesFor(info, exportName);\n if (!packageExamples) continue;\n examples.push(\n ...toItems(packageExamples.examples, type, name, 'package'),\n );\n for (const exampleName of packageExamples.skipped)\n skippedExamples.push(`${type}.${name}.${exampleName}`);\n }\n }\n\n const result = {\n flow: flowName,\n count: examples.length,\n examples,\n };\n\n const warnings: string[] = [];\n if (examples.length === 0) {\n warnings.push(\n 'No examples found. Add examples to step entries, or reference a package that ships examples (see package_get).',\n );\n }\n if (skippedExamples.length > 0) {\n warnings.push(\n `Skipped ${skippedExamples.length} package example(s) that do not match the step example schema: ${skippedExamples.join(', ')}.`,\n );\n }\n if (skippedPackages) {\n warnings.push(\n `Package examples were looked up for the first ${MAX_PACKAGE_LOOKUPS} packages only. Use step to narrow the result.`,\n );\n }\n const hints: { next: string[]; warnings?: string[] } = {\n next: [\n runtime.simulate\n ? 'Use flow_simulate with step and event to simulate'\n : HINT_OUT_OF_PROCESS,\n ],\n ...(warnings.length > 0 ? { warnings } : {}),\n };\n return mcpResult(result, hints);\n } catch (error) {\n return mcpError(\n error,\n refusalHint(error, 'Check configPath — expected a flow.json file'),\n );\n }\n}\n\nexport function registerFlowExamplesTool(\n server: McpServer,\n runtime: FlowRuntime,\n) {\n const spec = createFlowExamplesToolSpec(runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema: ExamplesListOutputShape,\n annotations: spec.annotations,\n },\n (args) => flowExamplesHandlerBody(runtime, args),\n );\n}\n","import { apiRequest } from '@walkeros/cli';\nimport type { ResponseJson } from '@walkeros/cli';\n\n// __VERSION__ is replaced at build time by tsup's `define` (see tsup.config.ts).\n// In tests, it's set on globalThis (see src/__tests__/support/version.ts).\ndeclare const __VERSION__: string;\n\nconst NPM_SEARCH_URL = 'https://registry.npmjs.org/-/v1/search';\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/npm';\nconst WALKEROS_JSON_PATH = 'dist/walkerOS.json';\nconst CACHE_TTL = 5 * 60 * 1000;\n\nexport const CLIENT_HEADER = 'walkeros-mcp/' + __VERSION__;\n\n/**\n * Resolve the walkerOS app base URL for MCP outbound calls.\n *\n * Env-only by design: the MCP runs in an editor with explicit `.mcp.json`\n * env. No config-file precedence (which is what `@walkeros/cli`'s\n * `resolveAppUrl()` does for the `walkeros` CLI binary). Hard-cut:\n * `APP_URL` is no longer recognized.\n *\n * Lives here (not in tools/package.ts) because both the package tools and the\n * catalog resources need to resolve the same app-primary base URL. This is an\n * in-package helper, not a cross-package registry.\n */\nexport function getPackageBaseUrl(): string | undefined {\n return process.env.WALKEROS_APP_URL || undefined;\n}\n\nexport interface CatalogEntry {\n name: string;\n version: string;\n description?: string;\n type: string;\n platform: string[];\n}\n\nexport interface CatalogResult {\n entries: CatalogEntry[];\n warnings: string[];\n}\n\n/**\n * Provenance of the most recent `fetchCatalog` call. Module-scoped and\n * last-call-wins: the stdio MCP is a single process, so the diagnostics tool\n * reads which source (`app` vs `npm` fallback) served the last catalog fetch,\n * how many entries it produced, and whether any were dropped (partial).\n * `undefined` until the first fetch.\n */\nexport interface LastCatalogFetchInfo {\n source: 'app' | 'npm';\n count: number;\n partial: boolean;\n timestamp: number;\n}\n\nlet lastFetchInfo: LastCatalogFetchInfo | undefined;\n\nexport function getLastCatalogSource(): LastCatalogFetchInfo | undefined {\n return lastFetchInfo;\n}\n\n// Cache keyed by effective source (app baseUrl or 'npm'). The tool reads\n// app-primary and the resources read npm-primary; a shared cache let one\n// source's result leak into the other. Only complete, non-empty results are\n// cached, so a transient empty/partial fetch never freezes for the TTL.\nconst cache = new Map<string, { entries: CatalogEntry[]; timestamp: number }>();\n\nexport function clearCatalogCache() {\n cache.clear();\n}\n\nexport function normalizePlatform(platform?: unknown): string[] {\n if (platform == null) return [];\n if (typeof platform === 'string') {\n return platform === 'universal' ? ['web', 'server'] : [platform];\n }\n if (Array.isArray(platform)) {\n return platform.filter((v): v is string => typeof v === 'string');\n }\n return [];\n}\n\ninterface SourceResult {\n entries: CatalogEntry[];\n complete: boolean;\n // Number of packages the source listed before enrichment, so the caller can\n // compute how many were dropped (listed minus enriched).\n requested: number;\n}\n\nexport async function fetchCatalog(filters?: {\n type?: string;\n platform?: string;\n baseUrl?: string;\n}): Promise<CatalogResult> {\n const sourceKey = filters?.baseUrl ?? 'npm';\n const warnings: string[] = [];\n\n const cached = cache.get(sourceKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n lastFetchInfo = {\n source: filters?.baseUrl ? 'app' : 'npm',\n count: cached.entries.length,\n partial: false,\n timestamp: Date.now(),\n };\n return { entries: applyFilters(cached.entries, filters), warnings };\n }\n\n let result: SourceResult;\n // Which source actually served. Starts as the requested source, flips to\n // 'npm' when an app fetch fails over to the npm fallback.\n let servedBy: 'app' | 'npm' = filters?.baseUrl ? 'app' : 'npm';\n if (filters?.baseUrl) {\n try {\n result = await fetchCatalogFrom(filters.baseUrl, filters);\n } catch {\n warnings.push(\n 'app catalog endpoint unavailable, fell back to npm; results may be incomplete',\n );\n servedBy = 'npm';\n try {\n result = await fetchFromNpm();\n } catch {\n lastFetchInfo = {\n source: 'npm',\n count: 0,\n partial: true,\n timestamp: Date.now(),\n };\n return { entries: [], warnings };\n }\n }\n } else {\n try {\n result = await fetchFromNpm();\n } catch {\n lastFetchInfo = {\n source: 'npm',\n count: 0,\n partial: true,\n timestamp: Date.now(),\n };\n return { entries: [], warnings };\n }\n }\n\n const dropped = result.requested - result.entries.length;\n if (dropped > 0) {\n warnings.push(\n `${dropped} package(s) could not be enriched and were omitted`,\n );\n }\n\n lastFetchInfo = {\n source: servedBy,\n count: result.entries.length,\n partial: !result.complete,\n timestamp: Date.now(),\n };\n\n // Only freeze a complete, non-empty result. Empty or partial fetches must\n // retry on the next call rather than serve a stale shortfall for the TTL.\n if (result.entries.length > 0 && result.complete) {\n cache.set(sourceKey, { entries: result.entries, timestamp: Date.now() });\n }\n\n return { entries: applyFilters(result.entries, filters), warnings };\n}\n\nasync function fetchCatalogFrom(\n baseUrl: string,\n filters?: { type?: string; platform?: string },\n): Promise<SourceResult> {\n const res = await apiRequest('GET /api/packages', {\n auth: 'none',\n baseUrl,\n query: {\n type: filters?.type || undefined,\n platform: filters?.platform || undefined,\n },\n signal: AbortSignal.timeout(15000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n });\n if (!res.ok) throw new Error(`Catalog fetch failed: ${res.status}`);\n\n const data: ResponseJson<'GET /api/packages', 200> = await res.json();\n const entries: CatalogEntry[] = data.catalog;\n return { entries, complete: entries.length > 0, requested: entries.length };\n}\n\nasync function fetchFromNpm(): Promise<SourceResult> {\n const res = await fetch(`${NPM_SEARCH_URL}?text=@walkeros/&size=250`, {\n signal: AbortSignal.timeout(10000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n });\n if (!res.ok) throw new Error(`npm search failed: ${res.status}`);\n\n const data = (await res.json()) as {\n objects: Array<{\n package: { name: string; version: string; description?: string };\n }>;\n };\n\n const requested = data.objects.length;\n\n const metaResults = await Promise.allSettled(\n data.objects.map((obj) => enrichWithMeta(obj.package)),\n );\n\n const entries = metaResults\n .filter(\n (r): r is PromiseFulfilledResult<CatalogEntry | undefined> =>\n r.status === 'fulfilled',\n )\n .map((r) => r.value)\n .filter((entry): entry is CatalogEntry => entry !== undefined);\n\n // A non-empty npm list with fewer enriched entries means jsdelivr silently\n // dropped some packages; treat that as incomplete so it is not cached.\n const complete = requested === 0 || entries.length === requested;\n return { entries, complete, requested };\n}\n\nasync function enrichWithMeta(pkg: {\n name: string;\n version: string;\n description?: string;\n}): Promise<CatalogEntry | undefined> {\n try {\n const res = await fetch(\n `${JSDELIVR_BASE}/${pkg.name}@${pkg.version}/${WALKEROS_JSON_PATH}`,\n {\n signal: AbortSignal.timeout(5000),\n headers: { 'X-Walkeros-Client': CLIENT_HEADER },\n },\n );\n if (!res.ok) return undefined;\n\n const json = (await res.json()) as { $meta?: Record<string, unknown> };\n const meta = json.$meta;\n if (!meta || typeof meta.type !== 'string') return undefined;\n\n return {\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n type: meta.type,\n platform: normalizePlatform(meta.platform),\n };\n } catch {\n return undefined;\n }\n}\n\nfunction applyFilters(\n entries: CatalogEntry[],\n filters?: { type?: string; platform?: string },\n): CatalogEntry[] {\n let results = entries;\n if (filters?.type) {\n results = results.filter((e) => e.type === filters.type);\n }\n if (filters?.platform) {\n // Empty platform means platform-agnostic → matches any filter\n results = results.filter(\n (e) => e.platform.length === 0 || e.platform.includes(filters.platform!),\n );\n }\n return results;\n}\n","/**\n * Structural reads of values the tools receive untyped: app responses\n * (`ToolClient` returns `unknown`) and loaded configs. Each reader checks the\n * shape it returns, so a field that is not what a tool expects reads as\n * absent instead of being asserted into place.\n */\nimport type { Flow } from '@walkeros/core';\nimport { schemas, type z } from '@walkeros/core/dev';\n\n/** A plain JSON object. */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** A string field of an object, absent when it is not a string. */\nexport function stringField(value: unknown, key: string): string | undefined {\n if (!isRecord(value)) return undefined;\n const field = value[key];\n return typeof field === 'string' ? field : undefined;\n}\n\n/** An object field of an object, absent when it is not an object. */\nexport function recordField(\n value: unknown,\n key: string,\n): Record<string, unknown> | undefined {\n if (!isRecord(value)) return undefined;\n const field = value[key];\n return isRecord(field) ? field : undefined;\n}\n\n/** The fields of an object response to spread into a result; none otherwise. */\nexport function fieldsOf(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\n/**\n * A flow config (`Flow.Json`): an object with a `flows` object, the same\n * shallow check the CLI's push makes. Every consumer passes it on to the CLI,\n * which validates the config in depth.\n */\nexport function isFlowJson(value: unknown): value is Flow.Json {\n return isRecord(value) && isRecord(value.flows);\n}\n\n/** A step example as core's `StepExampleSchema` reads it. */\nexport type StepExampleView = z.infer<\n typeof schemas.FlowSchemas.StepExampleSchema\n>;\n\n/**\n * The step examples of an object, each checked with core's\n * `StepExampleSchema`. Names that fail it are returned as `skipped`, so a\n * caller reports them instead of dropping them unseen.\n */\nexport function stepExamplesOf(\n value: unknown,\n):\n | { examples: Record<string, StepExampleView>; skipped: string[] }\n | undefined {\n if (!isRecord(value)) return undefined;\n const examples: Record<string, StepExampleView> = {};\n const skipped: string[] = [];\n for (const [name, example] of Object.entries(value)) {\n const parsed = schemas.FlowSchemas.StepExampleSchema.safeParse(example);\n if (parsed.success) examples[name] = parsed.data;\n else skipped.push(name);\n }\n return { examples, skipped };\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackage, mcpResult, mcpError } from '@walkeros/core';\nimport { mergeConfigSchema } from '@walkeros/core/dev';\nimport {\n fetchCatalog,\n normalizePlatform,\n getPackageBaseUrl,\n CLIENT_HEADER,\n} from '../catalog.js';\n\nimport type { ToolSpec } from '../tool-spec.js';\nimport { recordField, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\n\n// `getPackageBaseUrl` lives in ../catalog.js because both these tools and the\n// catalog resources resolve the same app-primary base URL. Re-exported here so\n// existing importers of `tools/package.js` keep working.\nexport { getPackageBaseUrl };\n\n// ---------- package_search ----------\n\nconst SEARCH_TITLE = 'Search Package';\nconst SEARCH_DESCRIPTION =\n 'Start here for package discovery. Never guess package names: use this tool first to find exact names. ' +\n 'Without package name: returns catalog filtered by type/platform. ' +\n 'With package name: returns metadata, hint keys, and example summaries.';\n\nconst searchInputSchema = {\n package: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Exact npm package name for detailed lookup (e.g., @walkeros/web-destination-snowplow)',\n ),\n type: z\n .enum(['source', 'destination', 'transformer', 'store'])\n .optional()\n .describe('Filter by package type (browse mode)'),\n platform: z\n .enum(['web', 'server'])\n .optional()\n .describe('Filter by platform (browse mode, includes universal packages)'),\n version: z\n .string()\n .optional()\n .describe('Package version for detailed lookup (default: latest)'),\n};\n\nconst searchAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n} as const;\n\nexport function createPackageSearchToolSpec(): ToolSpec {\n return {\n name: 'package_search',\n title: SEARCH_TITLE,\n description: SEARCH_DESCRIPTION,\n inputSchema: searchInputSchema,\n annotations: searchAnnotations,\n handler: (input) => packageSearchHandlerBody(input),\n };\n}\n\nasync function packageSearchHandlerBody(input: unknown) {\n const parsed = parseToolInput(searchInputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { package: packageName, type, platform, version } = parsed.data;\n const baseUrl = getPackageBaseUrl();\n\n // Browse mode: no package specified → return catalog\n if (!packageName) {\n const { entries, warnings } = await fetchCatalog({\n type,\n platform,\n baseUrl,\n });\n const result = { catalog: entries, count: entries.length };\n return mcpResult(result, {\n next: ['Use package_get for schemas and examples'],\n ...(warnings.length > 0 ? { warnings } : {}),\n });\n }\n\n // Lookup mode: fetch specific package details\n try {\n const info = await fetchPackage(packageName, {\n version,\n baseUrl,\n client: CLIENT_HEADER,\n });\n\n const result = {\n package: info.packageName,\n version: info.version,\n description: info.description,\n type: info.type,\n platform: normalizePlatform(info.platform),\n hintKeys: info.hintKeys,\n exampleSummaries: info.exampleSummaries,\n };\n\n return mcpResult(result, {\n next: ['Use package_get for schemas and examples'],\n });\n } catch (error) {\n return mcpError(\n error,\n 'Package not found. Use package_search without parameters to browse available packages.',\n );\n }\n}\n\nexport function registerPackageSearchTool(server: McpServer) {\n const spec = createPackageSearchToolSpec();\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // No outputSchema: browse mode returns {catalog, count}, lookup returns metadata — incompatible shapes\n annotations: spec.annotations,\n },\n (args) => packageSearchHandlerBody(args),\n );\n}\n\n// ---------- package_get ----------\n\nconst GET_TITLE = 'Get Package';\nconst GET_DESCRIPTION =\n 'Requires exact package name: do not guess names, use package_search first to find them. ' +\n 'Returns schemas + hint texts + example summaries by default (lightweight). ' +\n 'Use section parameter for full content: \"hints\" (with code blocks), \"examples\" (full in/out data), or \"all\".';\n\nconst getInputSchema = {\n package: z\n .string()\n .min(1)\n .describe(\n 'Exact npm package name (e.g., @walkeros/web-destination-snowplow)',\n ),\n version: z.string().optional().describe('Package version (default: latest)'),\n section: z\n .enum(['hints', 'examples', 'all'])\n .optional()\n .describe(\n 'Section to expand with full content. Default: summary view with schemas + hint texts + example descriptions',\n ),\n};\n\nconst getAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createPackageGetToolSpec(): ToolSpec {\n return {\n name: 'package_get',\n title: GET_TITLE,\n description: GET_DESCRIPTION,\n inputSchema: getInputSchema,\n annotations: getAnnotations,\n handler: (input) => packageGetHandlerBody(input),\n };\n}\n\nconst STEP_PACKAGE_TYPES = [\n 'source',\n 'destination',\n 'transformer',\n 'store',\n] as const;\n\nfunction isStepPackageType(\n type: string | undefined,\n): type is (typeof STEP_PACKAGE_TYPES)[number] {\n return STEP_PACKAGE_TYPES.some((stepType) => stepType === type);\n}\n\n/**\n * Base config merged with the package settings as `config`; every other\n * schema (mapping, setup, ga4, ...) kept as a sibling.\n */\nfunction shapeSchemas(\n type: string | undefined,\n schemas: Record<string, unknown>,\n): Record<string, unknown> {\n const shaped: Record<string, unknown> = {};\n\n if (isStepPackageType(type)) {\n const settings = recordField(schemas, 'settings');\n const credentials = recordField(schemas, 'credentials');\n shaped.config = mergeConfigSchema(type, {\n ...schemas,\n settings,\n credentials,\n });\n }\n\n for (const [key, value] of Object.entries(schemas)) {\n if (key !== 'settings') shaped[key] = value;\n }\n return shaped;\n}\n\nasync function packageGetHandlerBody(input: unknown) {\n const parsed = parseToolInput(getInputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { package: packageName, version, section } = parsed.data;\n const baseUrl = getPackageBaseUrl();\n\n try {\n const info = await fetchPackage(packageName, {\n version,\n baseUrl,\n client: CLIENT_HEADER,\n });\n\n const result: Record<string, unknown> = {\n package: info.packageName,\n version: info.version,\n type: info.type,\n platform: normalizePlatform(info.platform),\n schemas: shapeSchemas(info.type, info.schemas),\n };\n\n // Multi-export packages: schemas per export, each with its own config\n if (info.exportSchemas) {\n result.exportSchemas = Object.fromEntries(\n Object.entries(info.exportSchemas).map(([name, schemas]) => [\n name,\n shapeSchemas(info.type, schemas),\n ]),\n );\n }\n\n // Hints\n if (info.hints) {\n if (section === 'hints' || section === 'all') {\n result.hints = info.hints;\n } else {\n const hintSummary: Record<string, { text: string }> = {};\n for (const [key, hint] of Object.entries(info.hints)) {\n const text = stringField(hint, 'text');\n if (text !== undefined) hintSummary[key] = { text };\n }\n result.hints = hintSummary;\n }\n }\n\n // Examples\n if (section === 'examples' || section === 'all') {\n result.examples = info.examples;\n // Multi-export packages: examples per export, keyed by export name\n if (info.exportExamples) result.exportExamples = info.exportExamples;\n } else {\n result.exampleSummaries = info.exampleSummaries;\n }\n\n return mcpResult(result);\n } catch (error) {\n return mcpError(\n error,\n 'Use package_search to browse available package names.',\n );\n }\n}\n\nexport function registerGetPackageSchemaTool(server: McpServer) {\n const spec = createPackageGetToolSpec();\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // No outputSchema: removed to avoid SDK -32602 crashes on unexpected field values\n annotations: spec.annotations,\n },\n (args) => packageGetHandlerBody(args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactNestedStrings, keepStructural } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { RuntimeRefusal, type FlowRuntime } from '../runtime/types.js';\n\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\n\nconst WEB_SKELETON = {\n version: 4,\n flows: {\n default: {\n config: { platform: 'web', bundle: { packages: {} } },\n sources: {},\n destinations: {},\n },\n },\n};\n\nconst SERVER_SKELETON = {\n version: 4,\n flows: {\n default: {\n config: { platform: 'server', bundle: { packages: {} } },\n sources: {},\n destinations: {},\n },\n },\n};\n\nconst TITLE = 'Load or Create Flow';\nconst DESCRIPTION =\n 'Load an existing flow configuration from a local file path, URL, or walkerOS API (by flow ID). ' +\n 'On the hosted server only inline JSON or a saved flow id is accepted, no file paths or URLs. ' +\n 'Or create a new empty flow by specifying a platform (web or server). ' +\n 'Use the add-step prompt to add sources, destinations, transformers, or stores to the flow.';\n\nconst inputSchema = {\n source: z\n .string()\n .optional()\n .describe(\n 'Flow source: local file path (./flow.json), URL (https://...), ' +\n 'inline JSON string, or API flow ID (cfg_...). Omit to create a new flow.',\n ),\n platform: z\n .enum(['web', 'server'])\n .optional()\n .describe(\n 'Platform for new flows. Required when source is omitted. ' +\n 'web = browser tracking, server = Node.js HTTP.',\n ),\n};\n\nconst outputSchema = {\n version: z.number().describe('Flow config version'),\n flows: z.record(z.string(), z.unknown()).describe('Flow entries'),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createFlowLoadToolSpec(\n client: ToolClient,\n runtime: FlowRuntime,\n): ToolSpec {\n return {\n name: 'flow_load',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowLoadHandlerBody(client, runtime, input),\n };\n}\n\nasync function flowLoadHandlerBody(\n client: ToolClient,\n runtime: FlowRuntime,\n input: unknown,\n) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { source, platform } = parsed.data;\n\n // Load by cloud flow/config id (flow_… / cfg_…) via the same client seam\n // flow_manage `get` uses. Its NOT_FOUND surfaces directly, never remapped\n // to the local \"file not found\" hint below.\n if (source && isCloudId(source)) {\n const resolvedProjectId = resolveDefaultProject(client, undefined);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n try {\n const flow = await client.getFlow({\n flowId: source,\n projectId: resolvedProjectId,\n });\n return mcpResult(\n redactNestedStrings(flowConfigOf(flow), { skip: keepStructural }),\n {\n next: ['Use flow_validate to check', 'Use add-step prompt to modify'],\n },\n );\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n }\n\n try {\n if (source) {\n // Every file or URL read goes through the runtime, which decides what\n // this process may load.\n const config = await runtime.load(source);\n return mcpResult(redactNestedStrings(config, { skip: keepStructural }), {\n next: ['Use flow_validate to check', 'Use add-step prompt to modify'],\n });\n }\n\n if (!platform) {\n return mcpError(\n new Error(\n 'Provide source (file path, URL, or flow ID) to load existing flow, ' +\n 'or platform (web/server) to create a new one.',\n ),\n );\n }\n\n const skeleton = platform === 'web' ? WEB_SKELETON : SERVER_SKELETON;\n return mcpResult(skeleton, {\n next: [\n 'Read walkeros://reference/flow-schema for config structure',\n 'Use add-step prompt to add sources and destinations',\n ],\n });\n } catch (error) {\n if (error instanceof RuntimeRefusal) return mcpError(error, error.hint);\n const msg = error instanceof Error ? error.message : '';\n if (msg.includes('not found') || msg.includes('ENOENT'))\n return mcpError(error, 'Check configPath — expected a flow.json file');\n return mcpError(error);\n }\n}\n\nexport function registerFlowLoadTool(\n server: McpServer,\n client: ToolClient,\n runtime: FlowRuntime,\n) {\n const spec = createFlowLoadToolSpec(client, runtime);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n // outputSchema is wire-only; not part of ToolSpec\n outputSchema,\n annotations: spec.annotations,\n },\n (args) => flowLoadHandlerBody(client, runtime, args),\n );\n}\n","// Shared types for MCP management tools.\n// Keep this file dependency-light: only type-level imports from SDK/core.\n\n/**\n * Discriminated input shape for action-based MCP tools.\n * Example: ActionToolInput<'list', { projectId?: string }>\n */\nexport type ActionToolInput<A extends string, T = Record<string, never>> = {\n action: A;\n} & T;\n\n/**\n * Uniform handler return shape used by all mgmt tools.\n * Matches mcpResult / mcpError from @walkeros/core.\n */\nexport type ToolHandlerResult = {\n content: Array<{ type: 'text'; text: string }>;\n structuredContent: Record<string, unknown>;\n isError?: true;\n};\n\n/**\n * True when the walkerOS cloud API refused the caller as unauthenticated: an\n * HTTP 401, or the code `UNAUTHORIZED` that the app answers a missing, invalid\n * or expired token with and the CLI raises when no login is stored. A 403\n * (`FORBIDDEN`, `INSUFFICIENT_SCOPE`, a feature gate) never is: that caller is\n * logged in and lacks a role, a scope or an entitlement. Read from the\n * structured `status` and `code`, never from the message.\n */\nexport function isAuthenticationError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('status' in error && error.status === 401) return true;\n return 'code' in error && error.code === 'UNAUTHORIZED';\n}\n\n/**\n * True when the walkerOS cloud API refused a logged-in caller: an HTTP 403, or\n * the code `FORBIDDEN` (a role) or `INSUFFICIENT_SCOPE` (a token scope) that\n * the hosted door carries without a status. Read from the structured `status`\n * and `code`, never from the message.\n */\nexport function isAccessRefusal(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('status' in error && error.status === 403) return true;\n return (\n 'code' in error &&\n (error.code === 'FORBIDDEN' || error.code === 'INSUFFICIENT_SCOPE')\n );\n}\n\nexport const AUTH_HINT =\n 'Are you logged in? Use auth(action: \"status\") to check.';\n","/**\n * Wraps a user-writable string in `<user_data>…</user_data>` so the chat\n * assistant treats it as data, never as instructions. Inner `</user_data>`\n * sequences are mangled (`</user_data_>`) so a malicious string can't close\n * the envelope early.\n *\n * Idempotent: a string that is already a well-formed envelope with no inner\n * `</user_data>` is returned unchanged.\n */\nexport function wrapUserData(s: string): string {\n const alreadyWrapped =\n s.startsWith('<user_data>') &&\n s.endsWith('</user_data>') &&\n s.slice(11, -12).indexOf('</user_data>') === -1;\n if (alreadyWrapped) return s;\n const neutralised = s.replace(/<\\/user_data>/g, '</user_data_>');\n return `<user_data>${neutralised}</user_data>`;\n}\n\n/**\n * Human-facing display text: user-authored strings the assistant should only\n * read. `name` and `flowName` are display names, `summary` is a flow's\n * one-line summary built from its step keys. The one key list behind both\n * {@link wrapListedRecord} (top level) and {@link redactDisplayNames} (deep).\n */\nconst DISPLAY_TEXT_KEYS: ReadonlySet<string> = new Set([\n 'name',\n 'flowName',\n 'summary',\n]);\n\n/**\n * A listed record (a project, a flow summary, the project of a flow group)\n * with its top-level display text wrapped as user data. Every other field\n * stays literal, nested ones included, so a flow's `settings[].name` (an\n * identifier the assistant passes back as `flowName`) is never wrapped.\n * Anything that is not an object passes through unchanged.\n */\nexport function wrapListedRecord(value: unknown): unknown {\n if (typeof value !== 'object' || value === null || Array.isArray(value))\n return value;\n const fields: Array<[string, unknown]> = Object.entries(value);\n const out: Record<string, unknown> = {};\n for (const [key, field] of fields) {\n out[key] =\n DISPLAY_TEXT_KEYS.has(key) && typeof field === 'string'\n ? wrapUserData(field)\n : field;\n }\n return out;\n}\n\n/**\n * The single redaction rule for every tool that echoes flow/deployment data\n * back to the chat assistant:\n *\n * wrap only the human-facing display `name`/`flowName` field and deep config\n * VALUES; leave all structural ids/keys literal everywhere.\n *\n * Redaction exists to neutralise user-CONTROLLED string VALUES so an injected\n * `</user_data>` can't escape the envelope. It must NOT touch:\n * - structural keys (ids, slugs, dates, immutable identifiers): the LLM needs\n * to reference them verbatim, and wrapping them breaks get→edit→update\n * round-trips (e.g. wrapping `package`/`platform` corrupts a config the\n * user pushes straight back).\n * - tool-generated text (validation messages, error strings): that text is\n * authored by us, not echoed user input, so it stays literal like `path`.\n *\n * `STRUCTURAL_KEYS` is the union of every key whose value is an id/slug/date/\n * immutable identifier rather than user free-text. Confirmed: none of these key\n * names ever hold a genuine user-authored free-text value — `package`/`platform`\n * are enum/package-name fields, `kind` is a discriminator, the rest are\n * server-generated ids/timestamps.\n */\nexport const STRUCTURAL_KEYS = new Set([\n 'id',\n 'flowId',\n 'projectId',\n 'previewId',\n 'version',\n 'slug',\n 'kind',\n 'createdAt',\n 'updatedAt',\n 'deletedAt',\n 'package',\n 'platform',\n]);\n\n/** Return `true` for keys that must stay literal (ids, slugs, dates, package,\n * platform). Use as the `skip` predicate for {@link redactNestedStrings}. */\nexport const keepStructural = (key: string): boolean =>\n STRUCTURAL_KEYS.has(key);\n\nexport interface RedactOptions {\n /** Return `true` to skip wrapping for a given object key. Only invoked for\n * string values on object entries — not for array elements or scalar\n * roots. Use to keep ids / slugs / dates literal. */\n skip?: (key: string) => boolean;\n}\n\n/**\n * Recursively walks `value` and returns a deep-copied structure where every\n * string leaf has been passed through `wrapUserData`. Pass `skip` to exclude\n * specific keys (e.g. `id`) from wrapping.\n */\nexport function redactNestedStrings<T>(value: T, opts?: RedactOptions): T {\n return walk(value, opts) as T;\n}\n\n/**\n * Recursively wraps ONLY the human-facing display text fields (`name`,\n * `flowName`, `summary`), leaving every other value (ids, slugs, status, type,\n * dates) literal. Use on tool responses that echo deployment/flow summaries\n * where the only user-authored free-text is display text.\n */\nexport function redactDisplayNames<T>(value: T): T {\n return walkDisplay(value) as T;\n}\n\nfunction walkDisplay(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(walkDisplay);\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (DISPLAY_TEXT_KEYS.has(k) && typeof v === 'string') {\n out[k] = wrapUserData(v);\n } else {\n out[k] = walkDisplay(v);\n }\n }\n return out;\n }\n return value;\n}\n\nfunction walk(value: unknown, opts?: RedactOptions): unknown {\n if (typeof value === 'string') return wrapUserData(value);\n if (Array.isArray(value)) return value.map((v) => walk(v, opts));\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (opts?.skip?.(k) && typeof v === 'string') {\n out[k] = v;\n } else {\n out[k] = walk(v, opts);\n }\n }\n return out;\n }\n return value;\n}\n","import type { ToolClient } from '../tool-client.js';\n\n/**\n * Shared by every project-bound tool, so the remedy is worded once.\n *\n * It names what to do, not just what went wrong, and it names where to get the\n * missing value. The per-call remedy leads because it always works: a selection\n * made with `set_default` is held by the process serving the connection and is\n * gone after a reconnect, by the ruling in the app's MCP route.\n */\nexport const NO_DEFAULT_PROJECT_ERROR =\n 'No project selected and no projectId given. Pass projectId on this call, or call project_manage action \"set_default\" to select one. project_manage action \"list\" returns the available ids.';\n\n/** Resolves the project for actions that fall back to the door's default\n * when `projectId` is omitted. Returns the resolved id, or undefined when\n * there is no default to fall back to (the no-project-at-all case). An\n * explicit `projectId` is always honoured as-is so the app's genuine\n * NOT_FOUND still surfaces for an explicit-but-wrong id. The default comes\n * from the door only: this shared layer never reads `WALKEROS_PROJECT_ID`,\n * because a hosted door runs it in a server process. */\nexport function resolveDefaultProject(\n client: ToolClient,\n projectId: string | undefined,\n): string | undefined {\n return projectId ?? client.getDefaultProject() ?? undefined;\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\n\ndeclare const __VERSION__: string;\n\nconst TITLE = 'Send Feedback';\nconst DESCRIPTION = 'Send feedback about walkerOS';\n\nconst inputSchema = {\n text: z.string().describe('Your feedback text'),\n anonymous: z\n .boolean()\n .optional()\n .describe(\n 'Include user/project info? false = include, true = anonymous. Only needed on first call if not yet configured.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createFeedbackToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'feedback',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => feedbackHandlerBody(client, input),\n };\n}\n\nasync function feedbackHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { text, anonymous: explicitAnonymous } = parsed.data;\n try {\n let anonymous = client.getFeedbackPreference();\n\n if (anonymous === undefined && explicitAnonymous === undefined) {\n return mcpResult(\n { needsConsent: true },\n {\n next: [\n 'Ask the user if they want to include their info',\n 'Call feedback again with anonymous: true or false',\n ],\n },\n );\n }\n\n if (anonymous === undefined && explicitAnonymous !== undefined) {\n anonymous = explicitAnonymous;\n client.setFeedbackPreference(anonymous);\n }\n\n const isAnonymous = explicitAnonymous ?? anonymous ?? true;\n\n await client.submitFeedback(text, {\n anonymous: isAnonymous,\n version: __VERSION__,\n });\n\n return mcpResult({ ok: true });\n } catch (error) {\n return mcpError(error);\n }\n}\n\nexport function registerFeedbackTool(server: McpServer, client: ToolClient) {\n const spec = createFeedbackToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => feedbackHandlerBody(client, args),\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult } from '@walkeros/core';\nimport {\n VERSION as CLI_VERSION,\n bakedContractVersion,\n operationUrl,\n} from '@walkeros/cli';\nimport type { ContractComparison } from '@walkeros/cli';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { getPackageBaseUrl, getLastCatalogSource } from '../catalog.js';\nimport { normalizeBaseUrl } from '../base-url.js';\n\nconst TITLE = 'Diagnostics';\nconst DESCRIPTION =\n 'Report the MCP runtime surface: MCP and CLI versions, the resolved app URL ' +\n 'and its source, app /api/health reachability, the API contract verdict ' +\n 'against that app, and which source served the last package catalog fetch. ' +\n 'Read-only and callable when logged out; use it when a request fails to see ' +\n 'which versions and backend you are on.';\n\n// No input fields: diagnostics is callable with `{}`, including logged out.\nconst inputSchema = {};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\nexport function createDiagnosticsToolSpec(\n client: ToolClient,\n packageVersion: string,\n): ToolSpec {\n return {\n name: 'diagnostics',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: () => diagnosticsHandlerBody(client, packageVersion),\n };\n}\n\nasync function diagnosticsHandlerBody(\n client: ToolClient,\n packageVersion: string,\n) {\n // The backend comes from the CLIENT, never from the local CLI: the local\n // door resolves the user's machine, the hosted door is served by the app it\n // reports, and a tool that resolved this itself would name the wrong backend\n // on one of them.\n const resolved = client.appBaseUrl();\n\n // Provenance via the same helper the catalog uses; do not add a parallel\n // process.env check. It is a claim about the OVERRIDE only, and a proven\n // one: `env` means this process's WALKEROS_APP_URL is the URL the client\n // actually named. A client that ignores the variable (the hosted door does,\n // it is served on its own URL) therefore never reports `env` merely because\n // the variable happens to be set in its environment.\n // Normalized on both sides of the comparison: `resolved` is a base without a\n // trailing slash, and the env var is under no such obligation, so comparing\n // raw would report `default` for a slashed value that did set the URL.\n const envAppUrl = getPackageBaseUrl();\n const appUrlSource: 'env' | 'default' =\n envAppUrl !== undefined && normalizeBaseUrl(envAppUrl) === resolved\n ? 'env'\n : 'default';\n\n // checkHealth is optional on ToolClient: clients that cannot probe\n // reachability omit it, in which case diagnostics degrades to\n // { reachable: false }. When present, its contract is to resolve\n // { reachable: false } on failure, but catch here too so a throwing client\n // never breaks diagnostics.\n const healthCheck: Promise<{\n reachable: boolean;\n status?: string;\n version?: string;\n error?: string;\n }> = client.checkHealth\n ? client.checkHealth().catch((error: unknown) => ({\n reachable: false,\n error: errorMessage(error),\n }))\n : Promise.resolve({ reachable: false });\n\n // The contract verdict comes from the CLIENT, like the URL: the local door\n // compares per operation against the app it resolves, a hosted door served\n // inside the app answers `in-process`. A client without the method, or one\n // that throws, yields `unknown` with the reason.\n const contractCheck: Promise<ContractComparison> = client.checkContract\n ? client\n .checkContract()\n .catch((error: unknown) =>\n unknownContract(\n resolved,\n packageVersion,\n `contract check failed: ${errorMessage(error)}`,\n ),\n )\n : Promise.resolve(\n unknownContract(\n resolved,\n packageVersion,\n 'no contract check on this client',\n ),\n );\n\n const [health, contract] = await Promise.all([healthCheck, contractCheck]);\n\n const catalogInfo = getLastCatalogSource();\n\n const warnings: string[] = [];\n if (envAppUrl === undefined) {\n warnings.push(`WALKEROS_APP_URL is not set; app URL from ${appUrlSource}`);\n }\n if (!client.checkHealth) {\n warnings.push('no health check on this client');\n } else if (!health.reachable) {\n const url = operationUrl('GET /api/health', { baseUrl: resolved });\n warnings.push(`GET ${url} failed: ${health.error ?? 'no response'}`);\n }\n\n const result = {\n mcp: { version: packageVersion },\n cli: { version: CLI_VERSION },\n appUrl: { resolved, source: appUrlSource },\n app: {\n reachable: health.reachable,\n ...(health.status !== undefined && { status: health.status }),\n ...(health.version !== undefined && { version: health.version }),\n },\n contract: { openapiVersion: bakedContractVersion, ...contract },\n catalog: catalogInfo\n ? {\n lastSource: catalogInfo.source,\n lastCount: catalogInfo.count,\n partial: catalogInfo.partial,\n }\n : { lastSource: undefined, lastCount: undefined, partial: undefined },\n };\n\n return mcpResult(result, warnings.length > 0 ? { warnings } : undefined);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The `unknown` verdict this MCP reports when its client gives none. */\nfunction unknownContract(\n appUrl: string,\n packageVersion: string,\n reason: string,\n): ContractComparison {\n return {\n verdict: 'unknown',\n appUrl,\n client: {\n package: '@walkeros/mcp',\n version: packageVersion,\n contract: bakedContractVersion,\n },\n reason,\n };\n}\n\nexport function registerDiagnosticsTool(\n server: McpServer,\n client: ToolClient,\n packageVersion: string,\n) {\n const spec = createDiagnosticsToolSpec(client, packageVersion);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n () => diagnosticsHandlerBody(client, packageVersion),\n );\n}\n","/**\n * One spelling of a walkerOS app base URL, so every consumer concatenates a\n * path onto the same shape.\n *\n * The two doors resolve their base from different worlds and neither\n * guarantees the shape on its own: the local door hands back whatever\n * `WALKEROS_APP_URL` or the CLI config file holds, and a valid URL may carry a\n * trailing slash, a query string or a fragment. Normalizing at the seam is what\n * keeps a link built from one door from reading\n * `https://app.example.com//projects/...` while the same link from the other\n * door reads cleanly.\n *\n * A query or a fragment is worse than a stray slash, because a path appended to\n * one lands INSIDE it: `https://app.example.com?a=b` plus `/projects/p1` reads\n * `https://app.example.com?a=b/projects/p1`, which is a broken link that a tool\n * then puts in somebody's chat transcript. Neither belongs on a base URL, so\n * both are dropped. The path is kept: an app mounted under a subpath is a real\n * deployment, and dropping it would break every link instead of fixing one.\n *\n * This never throws, deliberately. Its callers include `diagnostics`, whose job\n * is to NAME a misconfigured app URL; a normalizer that threw would take out\n * the tool that exists to report the problem. A string that does not parse as a\n * URL is handed back with only its trailing slashes trimmed, and fails later at\n * the request, where the error names the URL.\n */\nexport function normalizeBaseUrl(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return stripTrailingSlashes(url);\n }\n\n parsed.search = '';\n parsed.hash = '';\n return stripTrailingSlashes(parsed.toString());\n}\n\nfunction stripTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { redactDisplayNames } from '../user-data.js';\nimport { fieldsOf } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\n\nconst TITLE = 'Authentication';\nconst DESCRIPTION =\n 'Manage walkerOS authentication. Check login status, log in via the device authorization grant, or log out. ' +\n 'No terminal or browser required, the MCP client handles the authorization URL.';\n\n/** A `'host'` door has no login of its own: the host checks every request. */\nconst HOST_LOGIN_MESSAGE =\n 'This connection is already authenticated by the host; no login needed.';\n\n/** Logging out of a `'host'` door is the host's job, so the tool says where. */\nconst HOST_LOGOUT_MESSAGE =\n 'This connection is authorized by the host, so there is no session here to log out of. ' +\n 'To end it, disconnect walkerOS in your MCP client, or revoke it in the walkerOS app under Account, Connected apps.';\n\n/**\n * What a logout says when a credential is still there afterwards, by where it\n * comes from: a session stored while the revocation was in flight (a parallel\n * login or token refresh), or a `WALKEROS_TOKEN` the door did not clear.\n */\nconst STILL_AUTHENTICATED: Record<\n Exclude<ReturnType<ToolClient['credentialSource']>, null>,\n string\n> = {\n config:\n 'A newer session was stored while logging out and was kept. Call auth logout again to remove it.',\n env: 'WALKEROS_TOKEN is still set for this server process, so calls stay authenticated. Remove it from the MCP server configuration.',\n host: HOST_LOGOUT_MESSAGE,\n};\n\nconst inputSchema = {\n action: z\n .enum(['status', 'login', 'logout'])\n .describe('Authentication action to perform'),\n deviceCode: z\n .string()\n .optional()\n .describe(\n 'Device code from a previous pending login attempt. Provide to resume polling without requesting a new code.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createAuthToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'auth',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => authHandlerBody(client, input),\n };\n}\n\nasync function authHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, deviceCode } = parsed.data;\n try {\n switch (action) {\n case 'status': {\n if (!client.credentialSource()) {\n return mcpResult(\n { authenticated: false },\n { next: ['Use auth with action \"login\" to authenticate'] },\n );\n }\n // A hosted whoami lists the person's projects by name, and a name is\n // user-writable text, so every door's answer is wrapped.\n const user = await client.whoami();\n return mcpResult({\n authenticated: true,\n ...redactDisplayNames(fieldsOf(user)),\n });\n }\n\n case 'login': {\n if (client.credentialSource() === 'host') {\n return mcpResult(\n { authenticated: true, message: HOST_LOGIN_MESSAGE },\n {\n next: [\n 'Use auth with action \"status\" to see which account you are on',\n ],\n },\n );\n }\n if (deviceCode) {\n const poll = await client.pollForToken(deviceCode, {\n timeoutMs: 60000,\n });\n\n if (poll.status === 'ok') {\n return mcpResult(\n { authenticated: true },\n {\n next: [\n 'Use auth with action \"status\" to see which account you are on',\n 'Use project_manage with action \"list\" to see your projects',\n ],\n },\n );\n }\n\n // The approval is still outstanding, so the code is still good and\n // the same one comes back for the next attempt. `slow_down` is the\n // server asking for a wider gap before that attempt.\n if (poll.status === 'pending' || poll.status === 'slow_down') {\n return mcpResult({\n authenticated: false,\n status: 'pending',\n message:\n poll.status === 'slow_down'\n ? 'Still waiting, and the server asked for a longer gap between checks. Try again in a minute.'\n : 'Still waiting for authorization. Try again shortly.',\n deviceCode,\n });\n }\n\n if (poll.status === 'denied')\n return mcpError(new Error('Authorization was denied.'));\n if (poll.status === 'expired')\n return mcpError(\n new Error(\n 'The one-time code expired. Run auth with action \"login\" for a new one.',\n ),\n );\n\n return mcpError(new Error(poll.error));\n }\n\n const code = await client.requestDeviceCode();\n const loginUrl = code.verificationUriComplete;\n\n return mcpResult({\n authenticated: false,\n status: 'awaiting_authorization',\n loginUrl,\n message: `Open this link to authorize: ${loginUrl}`,\n deviceCode: code.deviceCode,\n });\n }\n\n case 'logout': {\n if (client.credentialSource() === 'host') {\n return mcpError(new Error(HOST_LOGOUT_MESSAGE));\n }\n const { deleted, envCleared } = await client.logout();\n // Never report a logout the credential survived: ask the door again\n // rather than trust what this logout removed.\n const remaining = client.credentialSource();\n if (remaining !== null) {\n return mcpResult({\n loggedOut: false,\n message: STILL_AUTHENTICATED[remaining],\n });\n }\n let message: string;\n if (deleted && envCleared) {\n message =\n 'Logged out. Config removed and WALKEROS_TOKEN cleared from process environment.';\n } else if (deleted) {\n message = 'Logged out and config removed.';\n } else if (envCleared) {\n message =\n 'No config found. WALKEROS_TOKEN cleared from process environment.';\n } else {\n message = 'No config found, already logged out.';\n }\n return mcpResult({\n loggedOut: true,\n message,\n });\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: status, login, logout`,\n );\n }\n } catch (error) {\n return mcpError(error);\n }\n}\n\nexport function registerAuthTool(server: McpServer, client: ToolClient) {\n const spec = createAuthToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => authHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { wrapListedRecord } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n PROJECT_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\n\nconst TITLE = 'Project Management';\nconst DESCRIPTION =\n 'Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.';\n\nconst inputSchema = {\n action: z\n .enum(['list', 'get', 'create', 'update', 'delete', 'set_default'])\n .describe('Project management action to perform'),\n projectId: z\n .string()\n .optional()\n .describe('Required for get, update, delete, set_default.'),\n name: z\n .string()\n .optional()\n .describe(\n 'Required for create and update (update also requires projectId).',\n ),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createProjectManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'project_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => projectManageHandlerBody(client, input),\n };\n}\n\nasync function projectManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, projectId, name, cursor, limit } = parsed.data;\n const validationError = validateActionInput(\n 'project_manage',\n action ?? '',\n { projectId, name },\n PROJECT_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'list': {\n const projects = await client.listProjects({ cursor, limit });\n const listed = isRecord(projects) ? projects.projects : undefined;\n const items = Array.isArray(projects)\n ? projects\n : Array.isArray(listed)\n ? listed\n : [];\n if (items.length === 0) {\n return mcpResult(\n { projects: [] },\n {\n next: [\n 'Use project_manage with action \"create\" to create your first project',\n 'Use project_manage with action \"set_default\" after creating to set it as default',\n ],\n },\n );\n }\n // A door that answers a bare array gets the same `{ projects }` body\n // as one that answers a page, never a generic wrapper key.\n return mcpResult({\n ...fieldsOf(projects),\n projects: items.map(wrapListedRecord),\n });\n }\n\n case 'get': {\n const project = await client.getProject({ projectId });\n return mcpResult(wrapListedRecord(project));\n }\n\n case 'create': {\n assertParam(name, 'name', 'create');\n const created = await client.createProject({ name });\n return mcpResult(wrapListedRecord(created), {\n next: [\n 'Use project_manage with action \"set_default\" to make this your active project',\n ],\n });\n }\n\n case 'update': {\n assertParam(name, 'name', 'update');\n const updated = await client.updateProject({ projectId, name });\n return mcpResult(wrapListedRecord(updated));\n }\n\n case 'delete': {\n const deleted = await client.deleteProject({ projectId });\n return mcpResult(deleted);\n }\n\n case 'set_default': {\n assertParam(projectId, 'projectId', 'set_default');\n client.setDefaultProject(projectId);\n return mcpResult(\n { defaultProjectId: projectId },\n {\n next: [\n 'Use flow_manage with action \"list\" to see flows in this project',\n ],\n },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, get, create, update, delete, set_default`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerProjectManageTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createProjectManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => projectManageHandlerBody(client, args),\n );\n}\n","export interface ActionRule {\n /** Params that must each be present for this action. */\n required?: string[];\n /** Param groups where at least one of each group must be present. */\n oneOf?: string[][];\n /** Optional discovery hint appended to the error (e.g. 'Use action \"list\" ...'). */\n hint?: string;\n}\n\nexport type ActionRequirementMap = Record<string, ActionRule>;\n\n/**\n * Returns a canonical error message string when `input` is missing a\n * required (or one-of) param for `action`, otherwise null. The message is\n * uniform across tools so error quality cannot drift between tools.\n * Required params are checked (and reported) before oneOf groups.\n */\nexport function validateActionInput(\n toolName: string,\n action: string,\n input: Record<string, unknown>,\n map: ActionRequirementMap,\n): string | null {\n const rule = map[action];\n if (!rule) return null;\n for (const param of rule.required ?? []) {\n if (\n input[param] === undefined ||\n input[param] === null ||\n input[param] === ''\n ) {\n return missing(toolName, action, param, rule.hint);\n }\n }\n for (const group of rule.oneOf ?? []) {\n const satisfied = group.some(\n (p) => input[p] !== undefined && input[p] !== null && input[p] !== '',\n );\n if (!satisfied) {\n return `${toolName} action \"${action}\" requires one of: ${group.join(', ')}.${rule.hint ? ' ' + rule.hint : ''}`;\n }\n }\n return null;\n}\n\n/**\n * Narrows a param that the action's requirement map has already validated as\n * present, so typed client calls accept it without re-checking. The companion\n * to `validateActionInput`: callers run that first to produce a friendly error,\n * then use this assertion at the use site to recover the non-nullable type.\n * Because validation guarantees presence, this never throws in practice; the\n * throw exists only to satisfy the assertion-signature contract. The thrown\n * message mirrors the `missing()` form (\"<param> is required for <action> action.\").\n */\nexport function assertParam(\n value: string | undefined,\n param: string,\n action: string,\n): asserts value is string {\n if (value === undefined || value === null || value === '')\n throw new Error(`${param} is required for ${action} action.`);\n}\n\nfunction missing(\n tool: string,\n action: string,\n param: string,\n hint?: string,\n): string {\n // Keep the substring \"<param> is required\" so existing assertions/docs that\n // string-match it stay green.\n return `${param} is required for ${action} action.${hint ? ' ' + hint : ''}`;\n}\n\nexport const FLOW_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n get: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n update: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n delete: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n duplicate: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n create: { required: ['name'] },\n preview_list: {\n required: ['flowId'],\n hint: 'Use action \"list\" to see available flows.',\n },\n preview_get: { required: ['flowId', 'previewId'] },\n preview_create: {\n required: ['flowId'],\n oneOf: [['flowName', 'flowSettingsId']],\n },\n preview_delete: { required: ['flowId', 'previewId'] },\n preview_regrant: { required: ['flowId', 'previewId'] },\n};\n\nexport const DEPLOY_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n deploy: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n get: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n delete: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n};\n\nexport const SECRET_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n list: {\n required: ['flowId'],\n hint: 'Use flow_manage action \"list\" to see available flows.',\n },\n set: {\n required: ['flowId', 'name', 'value'],\n hint: 'Use action \"list\" to see existing secret names for this flow.',\n },\n update: {\n required: ['flowId', 'secretId', 'value'],\n hint: 'Use action \"list\" to find the secretId.',\n },\n delete: {\n required: ['flowId', 'secretId'],\n hint: 'Use action \"list\" to find the secretId.',\n },\n};\n\nexport const PROJECT_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n get: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n update: {\n required: ['projectId', 'name'],\n hint: 'Use action \"list\" to see available projects.',\n },\n delete: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n set_default: {\n required: ['projectId'],\n hint: 'Use action \"list\" to see available projects.',\n },\n create: { required: ['name'] },\n};\n\nexport const FRAME_MANAGE_REQUIREMENTS: ActionRequirementMap = {\n page: {\n required: ['pageKey'],\n hint: 'Use action \"list\" to see the source keys of the project’s frames.',\n },\n get: {\n required: ['frameId'],\n hint: 'Use action \"list\" or \"page\" to find a frameId.',\n },\n};\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport {\n wrapUserData,\n wrapListedRecord,\n redactDisplayNames,\n redactNestedStrings,\n keepStructural,\n} from '../user-data.js';\nimport { flowCanvasResult } from '../ui-parts.js';\nimport { links } from '../links.js';\n\n/** Peek at a Flow.Json root (v4) and decide whether the bubble should render\n * as web-flavoured or server-flavoured. The platform is recorded on\n * `flows[name].config.platform`. We pick the first flow's platform; if no\n * platform is set we fall back to `'server'` so the chat bubble can still\n * render even if the user is mid-edit. */\nfunction pickPlatform(content: unknown): 'web' | 'server' {\n const flows = recordField(content, 'flows');\n for (const flow of Object.values(flows ?? {})) {\n const platform = stringField(recordField(flow, 'config'), 'platform');\n if (platform === 'web' || platform === 'server') return platform;\n }\n return 'server';\n}\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord, recordField, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n FLOW_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\n\n/**\n * The flow's page in the app, or nothing when the response carried no id (a\n * shape this module already tolerates everywhere else it reads `id`). The base\n * URL comes from the door, so one definition serves both of them.\n */\nfunction flowPageUrl(\n client: ToolClient,\n projectId: string,\n flowId: string | undefined,\n): string | undefined {\n if (flowId === undefined) return undefined;\n return links.flow({ baseUrl: client.appBaseUrl(), projectId, flowId });\n}\n\n/**\n * One page of a project's flows, each flow through the same wrapper the\n * grouped list uses, so one flow answers one shape on both list paths. A door\n * that answers a bare array gets the same `{ flows }` body; a shape this tool\n * does not know has every display name in it wrapped.\n */\nfunction safeFlowPage(data: unknown): unknown {\n if (Array.isArray(data)) return { flows: data.map(wrapListedRecord) };\n const flows = isRecord(data) ? data.flows : undefined;\n return isRecord(data) && Array.isArray(flows)\n ? { ...data, flows: flows.map(wrapListedRecord) }\n : redactDisplayNames(data);\n}\n\n/**\n * One group of the all-projects list (`{ project, flows }`): the project's\n * name and every flow wrapped like the per-project list. The group itself goes\n * through the wrapper too, so a door answering flat flow rows instead of\n * groups still never hands over a raw name.\n */\nfunction safeFlowGroup(group: unknown): unknown {\n const safe = wrapListedRecord(group);\n if (!isRecord(safe)) return safe;\n const { project, flows } = safe;\n return {\n ...safe,\n ...(project !== undefined && { project: wrapListedRecord(project) }),\n ...(Array.isArray(flows) && { flows: flows.map(wrapListedRecord) }),\n };\n}\n\n/** A flow record with its name wrapped and its config's strings redacted. */\ninterface SafeFlowDetail {\n fields: Record<string, unknown>;\n id?: string;\n name?: string;\n config?: Record<string, unknown>;\n}\n\nfunction safeDetail(flow: unknown): SafeFlowDetail {\n const fields: Record<string, unknown> = { ...fieldsOf(flow) };\n const name = stringField(fields, 'name');\n if (name !== undefined) fields.name = wrapUserData(name);\n if (fields.config !== undefined) {\n fields.config = redactNestedStrings(fields.config, {\n skip: keepStructural,\n });\n }\n return {\n fields,\n id: stringField(fields, 'id'),\n name: stringField(fields, 'name'),\n config: recordField(fields, 'config'),\n };\n}\n\nconst TITLE = 'Flow Management';\nconst DESCRIPTION =\n '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.';\n\nconst inputSchema = {\n action: z\n .enum([\n 'list',\n 'get',\n 'create',\n 'update',\n 'delete',\n 'duplicate',\n 'preview_list',\n 'preview_get',\n 'preview_create',\n 'preview_delete',\n 'preview_regrant',\n ])\n .describe('Flow management action to perform'),\n flowId: z\n .string()\n .optional()\n .describe(\n 'Flow ID (flow_...) or config ID (cfg_...). Required for get, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant.',\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional filter for list (omit to list all projects). Required for create if no default project set.',\n ),\n name: z\n .string()\n .optional()\n .describe(\n 'Flow name. Required for create. Optional for update (to rename) and duplicate.',\n ),\n content: z\n .record(z.string(), z.unknown())\n .optional()\n .describe('Flow.Json content. Used for create and update.'),\n patch: z\n .boolean()\n .optional()\n .describe(\n 'Merge-patch for update (default true). When true, only provided fields are updated.',\n ),\n fields: z\n .array(z.string())\n .optional()\n .describe('Dot-path selectors for get to return only specific fields.'),\n sort: z\n .enum(['name', 'updated_at', 'created_at'])\n .optional()\n .describe('Sort field for list.'),\n order: z.enum(['asc', 'desc']).optional().describe('Sort order for list.'),\n includeDeleted: z\n .boolean()\n .optional()\n .describe('Include soft-deleted flows in list results.'),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n previewId: z\n .string()\n .optional()\n .describe(\n 'Preview ID (prv_...). Required for preview_get, preview_delete, and preview_regrant (all also require flowId).',\n ),\n flowName: z\n .string()\n .optional()\n .describe(\n 'Used by preview_create — provide one of flowName or flowSettingsId (preview_create also requires flowId).',\n ),\n flowSettingsId: z\n .string()\n .optional()\n .describe(\n 'Used by preview_create — provide one of flowName or flowSettingsId (preview_create also requires flowId).',\n ),\n source: z\n .discriminatedUnion('kind', [\n z.object({ kind: z.literal('draft') }),\n z.object({\n kind: z.literal('deployment-version'),\n deploymentVersionId: z.string(),\n }),\n ])\n .optional()\n .describe(\n \"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).\",\n ),\n siteUrl: z\n .string()\n .optional()\n .describe(\n '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.',\n ),\n origins: z\n .array(z.string())\n .optional()\n .describe(\n 'Site origins (bare https://host[:port]) to mint a preview activation grant for. Used by preview_regrant; the returned activationUrl targets the first origin.',\n ),\n sessionId: z\n .string()\n .optional()\n .describe(\n 'Observe session id — 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.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n// Preview results land in agent transcripts and logs, so the MCP boundary\n// enforces a field whitelist instead of trusting whatever shape a client\n// returns: the raw ingest `token` and `projectId` must never surface here.\n// Grants (`grant`, `sessionGrant`, `activationUrl`) are deliberate outputs —\n// short-lived, origin/session-bound capabilities the caller needs to activate\n// a preview or forward events to an observe session. The list covers both\n// client shapes: the app's in-process summary (`previewId`, `status`,\n// `observeFeed`) and the CLI-backed HTTP client's raw API response (`id`,\n// `createdBy`, `createdAt`).\nconst PREVIEW_SUMMARY_FIELDS = [\n 'id',\n 'previewId',\n 'flowId',\n 'flowSettingsId',\n 'bundleUrl',\n 'activationUrl',\n 'grant',\n 'sessionGrant',\n 'sessionExpiresAt',\n 'sessionId',\n 'status',\n 'observeFeed',\n 'createdBy',\n 'createdAt',\n] as const;\n\nfunction redactPreview(data: unknown): Record<string, unknown> {\n if (!isRecord(data)) return {};\n const out: Record<string, unknown> = {};\n for (const field of PREVIEW_SUMMARY_FIELDS) {\n if (data[field] !== undefined) out[field] = data[field];\n }\n return out;\n}\n\nfunction redactPreviewList(data: unknown): Record<string, unknown> {\n if (!isRecord(data)) return { previews: [] };\n return {\n previews: Array.isArray(data.previews)\n ? data.previews.map(redactPreview)\n : [],\n ...(data.total !== undefined ? { total: data.total } : {}),\n };\n}\n\n/**\n * Resolve the flow's live Observe session, or null when there is none.\n *\n * `listJourneys` is the flow-keyed read the app already exposes and its\n * `sessionId` IS the flow's single active window, so it doubles as the\n * resolver. Best-effort by design: this only enriches a regrant, so a failing\n * or unavailable read degrades to a plain web preview grant instead of failing\n * the mint the caller actually asked for.\n */\nasync function resolveLiveSessionId(\n client: ToolClient,\n flowId: string,\n projectId: string | undefined,\n): Promise<string | null> {\n try {\n const result = await client.listJourneys({\n flowId,\n ...(projectId !== undefined && { projectId }),\n limit: 1,\n });\n return result.sessionId;\n } catch {\n return null;\n }\n}\n\nexport function createFlowManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'flow_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => flowManageHandlerBody(client, input),\n };\n}\n\nasync function flowManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n flowId,\n projectId,\n name,\n content,\n patch,\n fields,\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n previewId,\n flowName,\n flowSettingsId,\n source,\n siteUrl,\n origins,\n sessionId,\n } = parsed.data;\n const validationError = validateActionInput(\n 'flow_manage',\n action ?? '',\n { flowId, projectId, name, previewId, flowName, flowSettingsId },\n FLOW_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'list': {\n if (projectId) {\n const data = await client.listFlows({\n projectId,\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n });\n return mcpResult(safeFlowPage(data));\n }\n const data = await client.listAllFlows({\n sort,\n order,\n includeDeleted,\n cursor,\n limit,\n });\n // Both doors answer an array of groups. Any other shape is not one\n // this tool knows, so every display name in it is wrapped.\n const safe = Array.isArray(data)\n ? data.map(safeFlowGroup)\n : redactDisplayNames(data);\n return mcpResult(\n { projects: safe },\n {\n next: [\n 'Use flow_manage with action \"get\" and a flowId to inspect a specific flow',\n 'Use flow_load to open a flow for editing',\n ],\n },\n );\n }\n\n case 'get': {\n assertParam(flowId, 'flowId', 'get');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const flow = await client.getFlow({\n flowId,\n projectId: resolvedProjectId,\n fields,\n });\n const safe = safeDetail(flow);\n const appUrl = flowPageUrl(client, resolvedProjectId, safe.id);\n return flowCanvasResult({\n flowId: safe.id,\n configName: safe.name ?? 'default',\n platform: pickPlatform(safe.config),\n flowConfig: safe.config ?? {},\n ...(appUrl !== undefined && { appUrl }),\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safe.id}`,\n autoSend: true,\n },\n {\n label: 'Add a destination',\n prompt: `Help me add a destination to flow ${safe.id}`,\n },\n ],\n });\n }\n\n case 'create': {\n assertParam(name, 'name', 'create');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const created = await client.createFlow({\n name,\n content: content ?? {},\n projectId: resolvedProjectId,\n });\n const safeCreated = safeDetail(created);\n const createdAppUrl = flowPageUrl(\n client,\n resolvedProjectId,\n safeCreated.id,\n );\n return flowCanvasResult({\n flowId: safeCreated.id,\n configName: safeCreated.name ?? 'default',\n platform: pickPlatform(safeCreated.config),\n flowConfig: safeCreated.config ?? {},\n ...(createdAppUrl !== undefined && { appUrl: createdAppUrl }),\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safeCreated.id}`,\n autoSend: true,\n },\n {\n label: 'Deploy it',\n prompt: `Deploy flow ${safeCreated.id}`,\n },\n ],\n });\n }\n\n case 'update': {\n assertParam(flowId, 'flowId', 'update');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const updated = await client.updateFlow({\n flowId,\n projectId: resolvedProjectId,\n name,\n content,\n mergePatch: patch ?? true,\n });\n const safeUpdated = safeDetail(updated);\n return flowCanvasResult({\n flowId: safeUpdated.id,\n configName: safeUpdated.name ?? 'default',\n platform: pickPlatform(safeUpdated.config),\n flowConfig: safeUpdated.config ?? {},\n suggestions: [\n {\n label: 'Validate this flow',\n prompt: `Validate flow ${safeUpdated.id}`,\n autoSend: true,\n },\n {\n label: 'Deploy it',\n prompt: `Deploy flow ${safeUpdated.id}`,\n },\n ],\n });\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const deleted = await client.deleteFlow({\n flowId,\n projectId: resolvedProjectId,\n });\n return mcpResult(deleted);\n }\n\n case 'duplicate': {\n assertParam(flowId, 'flowId', 'duplicate');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const duplicated = await client.duplicateFlow({\n flowId,\n name,\n projectId: resolvedProjectId,\n });\n return mcpResult(safeDetail(duplicated).fields);\n }\n\n case 'preview_list': {\n assertParam(flowId, 'flowId', 'preview_list');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.listPreviews({\n projectId: resolvedProjectId,\n flowId,\n });\n return mcpResult(redactPreviewList(data));\n }\n\n case 'preview_get': {\n assertParam(flowId, 'flowId', 'preview_get');\n assertParam(previewId, 'previewId', 'preview_get');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.getPreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n });\n return mcpResult(redactPreview(data));\n }\n\n case 'preview_create': {\n assertParam(flowId, 'flowId', 'preview_create');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n // Whitelist the summary at the boundary: the HTTP client returns the\n // raw API response (which carries the ingest token and project id),\n // and the handler must never surface those regardless of the client.\n // It also adds no token-derived URL of its own.\n const preview = await client.createPreview({\n projectId: resolvedProjectId,\n flowId,\n flowName,\n flowSettingsId,\n ...(source ? { source } : {}),\n ...(siteUrl ? { siteUrl } : {}),\n });\n return mcpResult(redactPreview(preview), {\n next: [\n 'Open activationUrl on your site to activate preview mode. When activationUrl is null, no grant has been minted for a site yet — use action \"preview_regrant\" with your site origins to mint one.',\n 'Poll observeFeed (observe_journeys with this flowId) to watch preview events arrive.',\n ],\n });\n }\n\n case 'preview_delete': {\n assertParam(flowId, 'flowId', 'preview_delete');\n assertParam(previewId, 'previewId', 'preview_delete');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n const data = await client.deletePreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n });\n // The app responds 204 No Content; an older CLI maps that to null.\n // mcpResult requires a record for structuredContent, so synthesize a\n // confirmation when the body is empty.\n return mcpResult(\n data && typeof data === 'object'\n ? data\n : { deleted: true, previewId },\n );\n }\n\n case 'preview_regrant': {\n assertParam(flowId, 'flowId', 'preview_regrant');\n assertParam(previewId, 'previewId', 'preview_regrant');\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n if (!client.regrantPreview) {\n return mcpError(\n new Error('preview_regrant is not supported by this client'),\n );\n }\n // Auto-pair with the flow's live Observe window so a regrant made\n // while the flow is being observed forwards into it by default. An\n // explicit sessionId stays the override, and an unresolvable window is\n // not a failure: it degrades to a plain web preview grant.\n // Resolve under the SAME project the regrant is sent to: this path\n // degrades silently, so a project mismatch would never surface.\n const pairedSessionId =\n sessionId ??\n (await resolveLiveSessionId(client, flowId, resolvedProjectId));\n // Whitelisted grant summary: activationUrl plus the raw grant values\n // the caller may need (`sessionGrant` is how an agent authenticates\n // direct server-hop test events) — never the ingest token.\n const data = await client.regrantPreview({\n projectId: resolvedProjectId,\n flowId,\n previewId,\n origins: origins ?? [],\n ...(pairedSessionId ? { sessionId: pairedSessionId } : {}),\n });\n return mcpResult(redactPreview(data), {\n next: [\n pairedSessionId\n ? 'Open activationUrl on the target origin: it activates the web preview AND forwards its events to the observe session. Use sessionGrant as the X-Walkeros-Preview header for direct server-hop test events.'\n : 'Open activationUrl on the target origin to activate preview mode.',\n ],\n });\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, get, create, update, delete, duplicate, preview_list, preview_get, preview_create, preview_delete, preview_regrant`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerFlowManageTool(server: McpServer, client: ToolClient) {\n const spec = createFlowManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => flowManageHandlerBody(client, args),\n );\n}\n","export type SuggestionTile = {\n label: string;\n description?: string;\n prompt: string;\n autoSend?: boolean;\n};\n\nexport interface FlowCanvasPayload {\n flowId?: string;\n configName: string;\n platform: 'web' | 'server';\n flowConfig: Record<string, unknown>;\n highlight?: { stepAddress: string; reason: string };\n suggestions?: SuggestionTile[];\n /**\n * Absolute link to this flow's page in the app, from `links.flow`.\n *\n * Named for the `appBaseUrl()` seam it is built from, and never `url`: that\n * is a field several app responses already use for something of their own\n * (a deployment's `url` is where it SERVES), and one key meaning one thing\n * across every tool is what keeps a link from ever landing on top of it.\n *\n * Optional because a tool that cannot name the project or the flow emits no\n * link rather than a guess, and because the in-app chat renders the canvas\n * itself and has no use for a link to the page it is already on.\n */\n appUrl?: string;\n}\n\nexport interface FlowCanvasToolResult extends FlowCanvasPayload {\n kind: 'flow-canvas';\n}\n\n/**\n * Tool-result helper that marks a response as renderable as a FlowCanvas.\n * The chat UI inspects `structuredContent.kind === 'flow-canvas'` and mounts\n * a `FlowCanvasBubble` instead of the generic JSON fallback. The `content[0]`\n * text is the same JSON stringified — the LLM sees a self-describing object.\n */\nexport function flowCanvasResult(payload: FlowCanvasPayload) {\n const structured: FlowCanvasToolResult = { kind: 'flow-canvas', ...payload };\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(structured, null, 2),\n },\n ],\n structuredContent: structured as unknown as Record<string, unknown> & {\n kind: 'flow-canvas';\n },\n };\n}\n\nexport function isFlowCanvasResult(v: unknown): v is FlowCanvasToolResult {\n return (\n typeof v === 'object' &&\n v !== null &&\n (v as { kind?: unknown }).kind === 'flow-canvas'\n );\n}\n","/**\n * Addresses of walkerOS app screens, built in one place so every tool hands a\n * person the same link for the same screen.\n *\n * WHY THIS EXISTS. A tool that names a release, a step, or a deployment in\n * prose leaves the person to go find it. A link ends that: the answer and the\n * screen it is about arrive together. Building the address in each tool would\n * instead give as many spellings of `/projects/.../flows/...` as there are\n * emission points, and the first one to drift would send someone to a 404 that\n * no test here could see.\n *\n * THE BASE URL IS CONSUMED RAW. `client.appBaseUrl()` is already normalized by\n * the door that answers it (the CLI-backed door wraps `resolveAppUrl()` in\n * `normalizeBaseUrl`; the hosted door returns the same expression it publishes\n * as its OAuth issuer, which cannot carry a trailing slash). Normalizing again\n * here would put a second opinion about the shape in the system, which is\n * exactly what one normalization point per door exists to prevent.\n *\n * ONE DEFINITION, BOTH DOORS. Nothing here branches on which door is calling.\n * The base URL is the only thing that differs between them, and it arrives as\n * an argument.\n *\n * EVERY LINK IS ABSOLUTE. These land in a chat transcript, where a path\n * relative to nothing is useless.\n *\n * AN UNBUILDABLE LINK IS `undefined`, NEVER A GUESS. Every builder returns\n * `undefined` when it cannot name a screen that exists, and callers spread the\n * field conditionally so the result simply carries no link. A link that lands\n * on a 404, or on the app's \"can't open that\" notice, is worse than no link:\n * it costs the person a click and teaches them the tool's links are unreliable.\n *\n * THE URL SHAPES ARE THE APP'S, NOT OURS. They mirror what the app routes\n * today: `/projects/{projectId}/flows/{flowId}` and\n * `/projects/{projectId}/deployments/{deploymentId}`, with a view on the flow\n * page addressed by the `view` query param whose value names a SUBJECT\n * (`variables`, `secrets`, `contract`, `history`, `releases`, `knowledge`,\n * `step`). A step is `?view=step&flow=<named flow>&step=<type.name>`, the same\n * vocabulary `hub_manage` already takes as its `flow` and `step` params.\n */\n\n/** A flow page: the address every flow-scoped view hangs off. */\nexport interface FlowLinkTarget {\n /** From `client.appBaseUrl()`. Consumed as given. */\n baseUrl: string;\n projectId: string;\n flowId: string;\n}\n\n/**\n * One step inside a flow. `flow` is the named flow within the config (\"web\",\n * \"server\"); `step` is `\"type.name\"`, e.g. `\"destination.ga4\"`.\n */\nexport interface StepLinkTarget extends FlowLinkTarget {\n step: string;\n /**\n * Null and undefined both mean \"the caller did not name one\", which is the\n * shape `hub_manage`'s step history answers with when it was not filtered by\n * flow.\n */\n flow?: string | null;\n}\n\n/** One discussion thread, addressed by what it hangs on. */\nexport interface ThreadLinkTarget extends FlowLinkTarget {\n anchorType: string;\n}\n\n/**\n * One deployment.\n *\n * Pass the `dep_...` id, not the slug. The detail route resolves either, but\n * the page's live-status stream matches on the id alone, so a slug link opens a\n * page whose status stream fails while the deployment is still deploying. This\n * builder does not inspect the value: naming the id is the caller's job.\n */\nexport interface DeploymentLinkTarget {\n baseUrl: string;\n projectId: string;\n deploymentId: string;\n}\n\n/**\n * Contract entries are top-level and carry no named flow, so they are not\n * `?view=step` addresses.\n */\nconst CONTRACT_PREFIX = 'contract.';\n\n/** Every address component has to be a non-empty string, or there is no link. */\nfunction addressable(...parts: string[]): boolean {\n return parts.every((part) => part !== '');\n}\n\nfunction flowPage(target: FlowLinkTarget): string | undefined {\n const { baseUrl, projectId, flowId } = target;\n if (!addressable(baseUrl, projectId, flowId)) return undefined;\n return `${baseUrl}/projects/${encodeURIComponent(projectId)}/flows/${encodeURIComponent(flowId)}`;\n}\n\n/**\n * A view on the flow page. `view` leads because it is the primary key: the\n * other params only mean anything beside it.\n */\nfunction flowView(\n target: FlowLinkTarget,\n view: string,\n params: Record<string, string> = {},\n): string | undefined {\n const page = flowPage(target);\n if (page === undefined) return undefined;\n const query = new URLSearchParams({ view, ...params });\n return `${page}?${query.toString()}`;\n}\n\nexport const links = {\n /** The flow page itself. `undefined` when any part of the address is empty. */\n flow(target: FlowLinkTarget): string | undefined {\n return flowPage(target);\n },\n\n /**\n * The screen showing one step.\n *\n * A `contract` step, in any of its spellings, is answered with the CONTRACT\n * view rather than a step address. `?view=step&step=contract.checkout` is a\n * legitimate address in the vocabulary this tool speaks, but the app has\n * deliberately deferred opening ONE contract entry and refuses that link with\n * a notice. `?view=contract` opens the contract editor the entry lives in,\n * which is the nearest screen that actually exists. A `flow` alongside a\n * contract step is a caller mistake (contract entries are top-level) and is\n * ignored rather than turned into a refused link.\n *\n * Otherwise a step needs its named flow: `type.name` alone is not unique in a\n * config holding both a web and a server flow, and the app resolves an\n * address without one to nothing and says so on screen. So an unnamed flow\n * yields `undefined` here. Callers that want the link can re-ask with `flow`.\n *\n * What this cannot check is whether the step is still IN that flow. The\n * address is resolved against the live config when the page opens, and a step\n * since renamed or removed gets a notice there rather than a broken screen.\n */\n step(target: StepLinkTarget): string | undefined {\n const { step, flow } = target;\n if (step === '') return undefined;\n if (step === 'contract' || step.startsWith(CONTRACT_PREFIX))\n return flowView(target, 'contract');\n if (typeof flow !== 'string' || flow === '') return undefined;\n return flowView(target, 'step', { flow, step });\n },\n\n /**\n * The release history of a flow.\n *\n * The app has no address for ONE release: `?view=releases` declares no params\n * and opens the list the release is a row of. That is the screen a person\n * asking about a release wants to be on, so this takes the flow and nothing\n * else rather than pretending to a precision the app does not have.\n */\n release(target: FlowLinkTarget): string | undefined {\n return flowView(target, 'releases');\n },\n\n /**\n * The screen a thread is read on.\n *\n * Only a release anchor can be addressed from the wire shape this tool\n * holds. The app renders release-anchored discussions inside the release\n * history, beside the release they hang on. Step and entity-action anchors\n * have no surface at all yet. A TAG anchor does have one, the knowledge list\n * on `?view=knowledge`, but only when the thread was captured in Tag Mode\n * and carries a frame: `HubThreadWire` has no `frameId`, so nothing here can\n * tell such a thread from one written over MCP against a null frame, and a\n * knowledge link would open a list the thread may be absent from. So\n * everything but a release anchor gets no link rather than a possibly empty\n * one.\n */\n thread(target: ThreadLinkTarget): string | undefined {\n if (target.anchorType !== 'release') return undefined;\n return flowView(target, 'releases');\n },\n\n /** One deployment's detail page. */\n deployment(target: DeploymentLinkTarget): string | undefined {\n const { baseUrl, projectId, deploymentId } = target;\n if (!addressable(baseUrl, projectId, deploymentId)) return undefined;\n return `${baseUrl}/projects/${encodeURIComponent(projectId)}/deployments/${encodeURIComponent(deploymentId)}`;\n },\n};\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DeploymentStatus, DeploymentType } from '@walkeros/cli';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactDisplayNames } from '../user-data.js';\nimport { links } from '../links.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { fieldsOf, isRecord, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n resolveDeploymentSlug,\n type DeploymentSummaryForResolver,\n type ListDeploymentsForResolver,\n} from './_resolvers.js';\nimport { resolveDefaultProject } from './project-context.js';\nimport {\n validateActionInput,\n assertParam,\n DEPLOY_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\n\nconst TITLE = 'Deploy Management';\nconst DESCRIPTION =\n 'Deploy walkerOS flows and manage deployments. ' +\n '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. ' +\n 'A finished deployment carries its status and, on failure, an errorMessage with the user-facing reason; use the get action to re-read it. ' +\n 'list supports cursor and limit for pagination. ' +\n 'delete removes an active deployment. ' +\n 'For get and delete pass flowId (required) plus optional slug to disambiguate when a flow has multiple active deployments. ' +\n \"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.\";\n\n// The list filters' values. The compiler holds each record equal to the\n// contract's enum, which the CLI types as DeploymentStatus and DeploymentType.\nconst DEPLOYMENT_STATUSES = {\n idle: true,\n deploying: true,\n published: true,\n active: true,\n stopped: true,\n failed: true,\n} satisfies Record<DeploymentStatus, true>;\n\nconst DEPLOYMENT_TYPES = {\n web: true,\n server: true,\n} satisfies Record<DeploymentType, true>;\n\n/** A record's keys, each narrowed to the record's key type. */\nfunction membersOf<T extends string>(members: Readonly<Record<T, true>>): T[] {\n return Object.keys(members).filter((key): key is T =>\n Object.hasOwn(members, key),\n );\n}\n\nconst inputSchema = {\n action: z\n .enum(['deploy', 'list', 'get', 'delete'])\n .describe('Deployment action to perform'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n flowId: z.string().optional().describe('Required for deploy, get, delete.'),\n slug: z\n .string()\n .optional()\n .describe(\n 'Deployment slug. Optional disambiguator for get/delete when the flow has multiple active deployments.',\n ),\n type: z\n .enum(membersOf(DEPLOYMENT_TYPES))\n .optional()\n .describe('Deployment type filter for list.'),\n status: z\n .enum(membersOf(DEPLOYMENT_STATUSES))\n .optional()\n .describe('Status filter for list.'),\n wait: z\n .boolean()\n .optional()\n .describe(\n '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.',\n ),\n flowName: z\n .string()\n .optional()\n .describe(\n 'Flow name for multi-settings flows. Only used with deploy action.',\n ),\n cursor: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from a previous list response. Only used with the list action.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Max items per page (1-100). Only used with the list action.'),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n/**\n * The deployment's ID, however the response spells it: the deploy start body\n * carries `deploymentId`, the detail read carries `id`.\n *\n * The `slug` both bodies also carry is deliberately NOT an address here. The\n * detail route resolves a slug, but the page's live-status stream matches on\n * the id alone, so a slug link opens a page whose status stream fails on a\n * deployment that is still deploying. A response carrying neither id spelling\n * gets no link.\n */\nfunction deploymentAddress(data: unknown): string | undefined {\n if (data === null || typeof data !== 'object' || Array.isArray(data))\n return undefined;\n const record: Record<string, unknown> = { ...data };\n for (const key of ['id', 'deploymentId']) {\n const value = record[key];\n if (typeof value === 'string' && value !== '') return value;\n }\n return undefined;\n}\n\n/**\n * The deployment's page in the app.\n *\n * The project is resolved the way every other project-bound tool resolves it,\n * falling back to the door's default. That fallback is for the LINK only:\n * nothing here changes which project the call itself reads, and a door with no\n * default simply yields no link rather than a wrong one.\n */\nfunction deploymentUrl(\n client: ToolClient,\n projectId: string | undefined,\n data: unknown,\n): string | undefined {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (resolvedProjectId === undefined) return undefined;\n const deploymentId = deploymentAddress(data);\n if (deploymentId === undefined) return undefined;\n return links.deployment({\n baseUrl: client.appBaseUrl(),\n projectId: resolvedProjectId,\n deploymentId,\n });\n}\n\n/**\n * Attach the link to a response body without disturbing what it already\n * carries.\n *\n * The key is `appUrl`, and it may never be `url`. A deployment response\n * ALREADY carries `url`, and it means where this deployment is SERVING: the\n * app sets it to the deployment's target while published or active. Writing\n * the app page over it would silently replace a live endpoint with a UI link,\n * with nothing to signal that the meaning of the field had changed. `appUrl`\n * also names the `appBaseUrl()` seam it is built from.\n *\n * A non-object body (nothing the app returns today, but the client types are\n * `unknown`) is passed through untouched rather than wrapped.\n */\nfunction withAppUrl(data: unknown, appUrl: string | undefined): unknown {\n if (\n appUrl === undefined ||\n data === null ||\n typeof data !== 'object' ||\n Array.isArray(data)\n ) {\n return data;\n }\n return { ...data, appUrl };\n}\n\n/** One deployment summary, or none when a field the resolver reads is missing. */\nfunction readDeploymentSummary(value: unknown): DeploymentSummaryForResolver[] {\n if (!isRecord(value)) return [];\n const slug = stringField(value, 'slug');\n const type = stringField(value, 'type');\n const status = stringField(value, 'status');\n const updatedAt = stringField(value, 'updatedAt');\n return slug !== undefined &&\n type !== undefined &&\n status !== undefined &&\n updatedAt !== undefined\n ? [{ ...value, slug, type, status, updatedAt }]\n : [];\n}\n\nfunction listForResolver(\n client: ToolClient,\n projectId: string | undefined,\n): ListDeploymentsForResolver {\n return async (q) => {\n const resp = await client.listDeployments({\n projectId: projectId || q.projectId || undefined,\n flowId: q.flowId,\n });\n const deployments = isRecord(resp) ? resp.deployments : undefined;\n return Array.isArray(deployments)\n ? deployments.flatMap(readDeploymentSummary)\n : [];\n };\n}\n\nexport function createDeployManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'deploy_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => deployManageHandlerBody(client, input),\n };\n}\n\nasync function deployManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n projectId,\n flowId,\n slug,\n type,\n status,\n wait,\n flowName,\n cursor,\n limit,\n } = parsed.data;\n const validationError = validateActionInput(\n 'deploy_manage',\n action ?? '',\n { flowId, projectId },\n DEPLOY_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n switch (action) {\n case 'deploy': {\n assertParam(flowId, 'flowId', 'deploy');\n // `projectId` travels with the deploy itself, not just with the link.\n // Without it the deploy resolved the door's default while the link\n // resolved the explicit id, so an explicit projectId that differed\n // from the default deployed in one project and linked into another,\n // and the project-scoped deployment route answered that link with a\n // 404.\n const result = await client.deploy({\n flowId,\n projectId,\n wait: wait ?? true,\n flowName,\n });\n // The deployment's own page, whether this call waited for a terminal\n // status or returned the id straight away. It is where the status the\n // hint tells the agent to re-read is shown, so the person can watch it\n // instead of asking again.\n const appUrl = deploymentUrl(client, projectId, result);\n return mcpResult(withAppUrl(redactDisplayNames(result), appUrl), {\n next: [\n 'Use deploy_manage with action \"get\" to check deployment status',\n ],\n });\n }\n\n case 'list': {\n const data = await client.listDeployments({\n projectId,\n flowId,\n type,\n status,\n cursor,\n limit,\n });\n return mcpResult(redactDisplayNames(data));\n }\n\n case 'get': {\n assertParam(flowId, 'flowId', 'get');\n const resolvedSlug = await resolveDeploymentSlug({\n projectId: projectId ?? '',\n flowId,\n slug,\n list: listForResolver(client, projectId),\n });\n const data = await client.getDeploymentBySlug({\n slug: resolvedSlug,\n projectId,\n });\n const appUrl = deploymentUrl(client, projectId, data);\n return mcpResult(withAppUrl(redactDisplayNames(data), appUrl));\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n const resolvedSlug = await resolveDeploymentSlug({\n projectId: projectId ?? '',\n flowId,\n slug,\n list: listForResolver(client, projectId),\n });\n const data = await client.deleteDeployment({\n slug: resolvedSlug,\n projectId,\n });\n return mcpResult(\n redactDisplayNames({\n deleted: true,\n ...fieldsOf(data),\n }),\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: deploy, list, get, delete`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerDeployTool(server: McpServer, client: ToolClient) {\n const spec = createDeployManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => deployManageHandlerBody(client, args),\n );\n}\n","/**\n * Internal helpers shared by deploy_manage actions. Not re-exported from the\n * tools barrel; leading underscore marks this as tool-module internal.\n *\n * All collaborators are passed in as arguments so unit tests can inject fakes\n * without relying on jest.mock. This keeps resolver tests local to the\n * resolver signature and avoids shared-mock drift.\n */\n\n/**\n * The subset of a deployment summary the resolver needs to decide 0 / 1 / many\n * and to surface a useful MULTIPLE_DEPLOYMENTS error. Kept structurally\n * compatible with the CLI's DeploymentSummaryForFlow.\n */\nexport interface DeploymentSummaryForResolver {\n slug: string;\n type: string;\n status: string;\n updatedAt: string;\n}\n\n/**\n * Dependency injected list function. Must return only non-deleted deployments\n * for the given project + flow. The production wiring calls\n * `listDeployments({ projectId, flowId })` from `@walkeros/cli`, which hits\n * the app API; the API excludes soft-deleted rows.\n */\nexport type ListDeploymentsForResolver = (q: {\n projectId: string;\n flowId: string;\n}) => Promise<DeploymentSummaryForResolver[]>;\n\n/**\n * Error thrown when a flow has 0 matching deployments, or when a caller passed\n * a slug that does not match any active deployment of the flow. The MCP layer\n * translates this into an mcpError with `code: 'NOT_FOUND'`.\n */\nexport class DeploymentNotFoundError extends Error {\n readonly code = 'NOT_FOUND';\n constructor(message: string) {\n super(message);\n this.name = 'DeploymentNotFoundError';\n }\n}\n\n/**\n * Error thrown when a flow has >= 2 active deployments and the caller did not\n * pass a slug. Carries a `details[]` list so the MCP layer can surface the\n * options to the user.\n */\nexport class MultipleDeploymentsError extends Error {\n readonly code = 'MULTIPLE_DEPLOYMENTS';\n readonly details: DeploymentSummaryForResolver[];\n constructor(message: string, details: DeploymentSummaryForResolver[]) {\n super(message);\n this.name = 'MultipleDeploymentsError';\n this.details = details;\n }\n}\n\n/**\n * Resolve a concrete deployment slug for a (projectId, flowId, slug?) tuple.\n *\n * Behavior:\n * - 0 matches: throws DeploymentNotFoundError.\n * - 1 match, no slug: returns the single slug.\n * - slug provided and matches: returns the slug.\n * - slug provided and does not match: throws DeploymentNotFoundError.\n * - >= 2 matches, no slug: throws MultipleDeploymentsError with details[].\n */\nexport async function resolveDeploymentSlug(args: {\n projectId: string;\n flowId: string;\n slug?: string;\n list: ListDeploymentsForResolver;\n}): Promise<string> {\n const matches = await args.list({\n projectId: args.projectId,\n flowId: args.flowId,\n });\n\n if (matches.length === 0) {\n throw new DeploymentNotFoundError(\n `No deployments found for flow ${args.flowId}`,\n );\n }\n\n if (args.slug !== undefined) {\n const hit = matches.find((m) => m.slug === args.slug);\n if (!hit) {\n throw new DeploymentNotFoundError(\n `No deployment with slug ${args.slug} in flow ${args.flowId}`,\n );\n }\n return hit.slug;\n }\n\n if (matches.length === 1) {\n return matches[0].slug;\n }\n\n throw new MultipleDeploymentsError(\n `Flow ${args.flowId} has ${matches.length} active deployments; pass slug to disambiguate`,\n matches.map((m) => ({\n slug: m.slug,\n type: m.type,\n status: m.status,\n updatedAt: m.updatedAt,\n })),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n SECRET_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\n\nconst TITLE = 'Secret Management';\nconst DESCRIPTION =\n 'Manage a flow’s managed secrets (the $secret.<NAME> values its steps reference at deploy/run time). ' +\n 'Actions: list (metadata only), set (create), update (rotate value), delete. ' +\n 'Secrets are write-mostly: values are encrypted at rest and are NEVER returned, listed, or echoed. ' +\n 'Reference a secret from a flow step as $secret.<NAME>. Credentials, tokens, and private keys must use $secret, not $env: ' +\n 'the deploy pipeline only injects values referenced as $secret.<NAME> into the server runner. Server flows only.';\n\nconst inputSchema = {\n action: z\n .enum(['list', 'set', 'update', 'delete'])\n .describe('Secret management action to perform'),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n flowId: z\n .string()\n .describe(\n 'Flow ID (flow_...) or config ID (cfg_...). Required for list, set, update, and delete: secrets are flow-scoped.',\n ),\n name: z\n .string()\n .regex(\n /^[A-Z_][A-Z0-9_]*$/,\n 'Secret name must be uppercase letters, digits, and underscores, starting with a letter or underscore.',\n )\n .optional()\n .describe(\n 'Secret name (UPPER_SNAKE_CASE). Required for set. Referenced in flows as $secret.<NAME>.',\n ),\n value: z\n .string()\n .min(1)\n .max(65536)\n .optional()\n .describe(\n 'Secret value (1-65536 chars). Required for set and update. Write-only: never returned or logged.',\n ),\n secretId: z\n .string()\n .optional()\n .describe(\n 'Secret ID (sec_...). Required for update and delete. Use action \"list\" to find it.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\nexport function createSecretManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'secret_manage',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => secretManageHandlerBody(client, input),\n };\n}\n\nasync function secretManageHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { action, projectId, flowId, name, value, secretId } = parsed.data;\n const validationError = validateActionInput(\n 'secret_manage',\n action ?? '',\n { flowId, name, value, secretId },\n SECRET_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n try {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId)\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n\n switch (action) {\n case 'list': {\n assertParam(flowId, 'flowId', 'list');\n const data = await client.listSecrets({\n projectId: resolvedProjectId,\n flowId,\n });\n return mcpResult(data, {\n next: [\n 'Reference a listed secret from a flow step as $secret.<NAME>.',\n 'Use action \"set\" to add a secret or \"update\" to rotate one.',\n ],\n });\n }\n\n case 'set': {\n assertParam(flowId, 'flowId', 'set');\n assertParam(name, 'name', 'set');\n assertParam(value, 'value', 'set');\n const created = await client.createSecret({\n projectId: resolvedProjectId,\n flowId,\n name,\n value,\n });\n // Response is metadata only; value is never echoed back.\n return mcpResult(created, {\n next: [`Reference it in this flow as $secret.${name}.`],\n });\n }\n\n case 'update': {\n assertParam(flowId, 'flowId', 'update');\n assertParam(secretId, 'secretId', 'update');\n assertParam(value, 'value', 'update');\n const updated = await client.updateSecret({\n projectId: resolvedProjectId,\n flowId,\n secretId,\n value,\n });\n return mcpResult(updated);\n }\n\n case 'delete': {\n assertParam(flowId, 'flowId', 'delete');\n assertParam(secretId, 'secretId', 'delete');\n const deleted = await client.deleteSecret({\n projectId: resolvedProjectId,\n flowId,\n secretId,\n });\n return mcpResult(\n deleted && typeof deleted === 'object'\n ? deleted\n : { deleted: true, secretId },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${action}. Use one of: list, set, update, delete`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerSecretManageTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createSecretManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => secretManageHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport type { Journey, JourneyHop, JourneyBranch } from '@walkeros/core';\nimport { isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { redactNestedStrings } from '../user-data.js';\n\nimport type { ToolClient } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { parseToolInput } from './parse-input.js';\n\nconst TITLE = 'Observe Journeys';\nconst DESCRIPTION =\n 'Read the assembled, cross-runtime journeys for a flow that is currently being observed (an active Observe session). ' +\n 'Pass flowId; the active session is resolved for you (a flow has at most one). ' +\n '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. ' +\n '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). ' +\n 'When the flow has no active session the result is `{ sessionId: null, journeys: [], gaps: [] }` — start an Observe session in the app and drive traffic first, then read again. ' +\n 'Narrow with traceId (one trace) and limit (page cap, most recent kept; default 50). ' +\n 'Read-only.';\n\nconst inputSchema = {\n flowId: z\n .string()\n .describe('Flow to read journeys for (its active Observe session).'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n traceId: z\n .string()\n .optional()\n .describe('Return only the journeys for this trace id.'),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\n 'Max journeys to return (1-100, most recent kept). Defaults to 50.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/**\n * Neutralise ONLY the captured, event-controlled payload fields of a journey for\n * third-party LLM context, deep-wrapping every string inside them in\n * <user_data>. Everything else stays literal.\n *\n * The distinction is load-bearing, not cosmetic: `observe_journeys` takes\n * `traceId` as a filter input, so the trigger -> read -> filter-by-traceId loop\n * only works if `traceId` (and the other correlation handles the agent\n * references) comes back verbatim. Wrapping them would break re-querying.\n *\n * KEEP LITERAL (assembler/wire-generated correlation handles, enums, numbers, or\n * the user's own config vocabulary):\n * id, correlation, traceId, entry.eventId/sourceId/timestamp, hop.stepId,\n * stepType, eventId, parentEventId, status, terminalPhase, skipReason,\n * mappingKey, contractRule, consent/consentApplied (config category -> bool),\n * platform(s), branchId, batched/flushConfirmed, and every timestamp/duration/\n * seq/gap-bound number.\n *\n * WRAP (data captured off the live event stream, attacker-influenceable):\n * entry.name (inbound event name), hop.in, hop.out, hop.error, hop.calls,\n * hop.meta, and the same out/error/calls on each fan-out branch.\n *\n * A structure-aware transform rather than a key-skip over `redactNestedStrings`,\n * because a flat key skip is depth-agnostic: it would either wrap the correlation\n * handles (breaking the query loop) or, if it skipped keys like `stepId`\n * globally, leave a captured payload field that happens to be named `stepId`\n * unwrapped. Wrapping whole payload sub-trees keeps every correlation handle\n * literal AND wraps every captured string, whatever its key.\n */\nfunction redactJourneyPayloads(journeys: Journey[]): Journey[] {\n return journeys.map((journey) => ({\n ...journey,\n entry: {\n ...journey.entry,\n ...(journey.entry.name !== undefined && {\n name: redactNestedStrings(journey.entry.name),\n }),\n },\n hops: journey.hops.map(redactHopPayloads),\n }));\n}\n\nfunction redactHopPayloads(hop: JourneyHop): JourneyHop {\n return {\n ...hop,\n ...(hop.in !== undefined && { in: redactNestedStrings(hop.in) }),\n ...(hop.out !== undefined && { out: redactNestedStrings(hop.out) }),\n ...(hop.error !== undefined && { error: redactNestedStrings(hop.error) }),\n ...(hop.calls !== undefined && { calls: redactNestedStrings(hop.calls) }),\n ...(hop.meta !== undefined && { meta: redactNestedStrings(hop.meta) }),\n ...(hop.branches !== undefined && {\n branches: hop.branches.map(redactBranchPayloads),\n }),\n };\n}\n\nfunction redactBranchPayloads(branch: JourneyBranch): JourneyBranch {\n return {\n ...branch,\n ...(branch.out !== undefined && { out: redactNestedStrings(branch.out) }),\n ...(branch.error !== undefined && {\n error: redactNestedStrings(branch.error),\n }),\n ...(branch.calls !== undefined && {\n calls: redactNestedStrings(branch.calls),\n }),\n };\n}\n\nexport function createObserveJourneysToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'observe_journeys',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => observeJourneysHandlerBody(client, input),\n };\n}\n\nasync function observeJourneysHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const { flowId, projectId, traceId, limit } = parsed.data;\n if (!flowId) {\n return mcpError(new Error('flowId is required for observe_journeys.'));\n }\n try {\n const result = await client.listJourneys({\n flowId,\n ...(projectId !== undefined && { projectId }),\n ...(traceId !== undefined && { traceId }),\n ...(limit !== undefined && { limit }),\n });\n // Wrap only the captured, event-controlled payload sub-trees (in/out/error/\n // calls/meta + entry.name) in <user_data> for third-party LLM context, while\n // keeping every correlation handle (traceId/stepId/eventId/mappingKey) and\n // enum/number literal so the agent can feed them straight back as filter\n // input. gaps are numeric + platform enum only, so they pass through, and\n // so does unattributed: platform enum, numbers, and stepIds from the user's\n // own config, with no captured event payload to wrap. Absent stays absent,\n // since \"no loss to report\" reads differently from an empty array.\n const safe = {\n sessionId: result.sessionId,\n flowId: result.flowId,\n assembledAt: result.assembledAt,\n journeys: redactJourneyPayloads(result.journeys),\n gaps: result.gaps,\n ...(result.unattributed !== undefined && {\n unattributed: result.unattributed,\n }),\n };\n return mcpResult(safe, {\n next:\n result.sessionId === null\n ? [\n 'No active Observe session for this flow. Start one in the app and drive traffic, then read again.',\n ]\n : [\n 'Inspect a single trace with traceId, or adjust the flow config and re-read to confirm the change.',\n ],\n });\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerObserveJourneysTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createObserveJourneysToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => observeJourneysHandlerBody(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { isAccessRefusal, isAuthenticationError, AUTH_HINT } from '../types.js';\nimport { isFeatureDenial } from './feature-gate.js';\n\nimport type {\n ToolClient,\n ObserveSessionResult,\n ObserveLevel,\n} from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { isRecord, stringField } from './narrow.js';\nimport { parseToolInput } from './parse-input.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\n\nconst TITLE = 'Observe Session';\n/**\n * Exported so the hosted plane can assert parity against this exact string\n * instead of retyping it.\n */\nexport const DESCRIPTION =\n 'Open, inspect, or end an Observe session: a time-boxed window on one flow that runtimes attach to as arms. ' +\n 'A preview arm streams from a browser, a container arm runs server-side, and both feed ONE shared journeys feed. ' +\n '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. ' +\n 'A flow has at most one session, so status/stop resolve it from flowId when sessionId is omitted. ' +\n 'Read the events with observe_journeys; this tool never returns event data and never judges whether events are correct.';\n\n/**\n * Hints carry the verb ladder rather than the description. Module constants so\n * the wording is one string per idea, quotable verbatim, and identical across\n * planes. Exported so the hosted plane imports them instead of retyping them,\n * which makes cross-plane parity a compiler concern.\n */\nexport const HINT_SIMULATE_FIRST =\n 'Simulate before preview: flow_simulate checks mapping with no browser.';\nexport const HINT_PREVIEW_STREAMS =\n 'Preview streams into this session: mint a link with flow_manage preview_regrant, then open it on your site.';\nexport const HINT_READ =\n 'Read with observe_journeys (flowId); it is the only read.';\nexport const HINT_STOP = 'End both arms with observe_session stop.';\nexport const HINT_EMPTY_FEED =\n 'recordsReceived is 0: nothing has reached the feed yet. Drive traffic on an attached arm.';\nexport const HINT_ENDED =\n 'Session ended and both arms detached. Start a new one with observe_session start.';\nexport const HINT_NO_WINDOW =\n 'No Observe session on this flow. Open one with observe_session start.';\n\nconst inputSchema = {\n action: z\n .enum(['start', 'status', 'stop'])\n .describe(\n 'start opens a session, status reports arm state, stop ends the whole session.',\n ),\n flowId: z.string().describe('Flow the Observe session runs on.'),\n projectId: z\n .string()\n .optional()\n .describe('Project ID. Optional; falls back to the default project.'),\n sessionId: z\n .string()\n .optional()\n .describe(\n 'Session to act on for status/stop. Optional; the flow has at most one session and it is resolved for you.',\n ),\n arms: z\n .object({\n container: z\n .literal(true)\n .optional()\n .describe(\n \"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.\",\n ),\n preview: z\n .string()\n .optional()\n .describe(\n \"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.\",\n ),\n })\n .optional()\n .describe(\n 'Which runtimes attach. Omit to attach the default preview arm; a web settings that references a server flow brings its container arm with it.',\n ),\n origins: z\n .array(z.string())\n .optional()\n .describe(\n 'Bare https origins (https://host[:port]) the session may ingest web events from.',\n ),\n level: z\n .enum(['off', 'standard', 'trace'])\n .optional()\n .describe(\"Container observation verbosity. Defaults to the app's own.\"),\n replace: z\n .boolean()\n .optional()\n .describe(\n \"Replace the flow's existing window instead of attaching to it. Re-provisions from the new config.\",\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\ninterface ArmsInput {\n container?: true;\n preview?: string;\n}\n\ninterface SettingsEntry {\n name: string;\n platform: 'web' | 'server';\n}\n\n/**\n * Read the settings summaries off a flow response. `getFlow` is typed\n * `Promise<unknown>` on the client, so it is read structurally:\n * anything that is not a well-formed settings entry is simply not a candidate.\n */\nfunction readSettings(flow: unknown): SettingsEntry[] {\n if (!isRecord(flow)) return [];\n const settings = flow.settings;\n if (!Array.isArray(settings)) return [];\n const entries: SettingsEntry[] = [];\n for (const entry of settings) {\n const name = stringField(entry, 'name');\n const platform = stringField(entry, 'platform');\n if (name === undefined) continue;\n if (platform !== 'web' && platform !== 'server') continue;\n entries.push({ name, platform });\n }\n return entries;\n}\n\n/**\n * Translate the arms shape onto the one field the session contract takes.\n *\n * The app derives a session's arms from the flow topology under a single\n * `settingsName`: a web settings that references a server flow provisions both\n * arms, a server settings provisions the container alone. So arms selects a\n * NAME here rather than toggling arms on the wire.\n */\nfunction resolveSettingsName(\n settings: SettingsEntry[],\n arms: ArmsInput | undefined,\n): string {\n if (arms?.preview !== undefined) {\n const named = settings.find((entry) => entry.name === arms.preview);\n if (!named) {\n throw new Error(\n `This flow has no settings named \"${arms.preview}\". Available: ${describeSettings(settings)}`,\n );\n }\n return named.name;\n }\n\n if (arms?.container === true) {\n const servers = settings.filter((entry) => entry.platform === 'server');\n const only = servers[0];\n if (!only) {\n throw new Error(\n `The container arm needs a server settings, and this flow has no server settings. Available: ${describeSettings(settings)}`,\n );\n }\n if (servers.length > 1) {\n throw new Error(\n `This flow has several server settings. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n }\n return only.name;\n }\n\n const webs = settings.filter((entry) => entry.platform === 'web');\n const onlyWeb = webs[0];\n if (onlyWeb && webs.length === 1) return onlyWeb.name;\n if (webs.length > 1) {\n throw new Error(\n `This flow has several web settings. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n }\n\n const onlySettings = settings[0];\n if (onlySettings && settings.length === 1) return onlySettings.name;\n throw new Error(\n `Could not pick a settings to observe. Name one with arms.preview. Available: ${describeSettings(settings)}`,\n );\n}\n\nfunction describeSettings(settings: SettingsEntry[]): string {\n if (settings.length === 0) return 'none';\n return settings\n .map((entry) => `${entry.name} (${entry.platform})`)\n .join(', ');\n}\n\n/**\n * Per-arm state derived from the response shape: a part being non-null is what\n * makes its arm attached. Connect secrets (the web credential, the container\n * env trio) stay out by construction.\n */\nfunction toArms(session: ObserveSessionResult) {\n return {\n preview: {\n attached: session.web !== null,\n settingsName: session.observedFlowName,\n activationUrl: session.web?.activationUrl ?? null,\n previewEnabled: session.web?.previewEnabled ?? false,\n },\n container: {\n attached: session.server !== null,\n settingsName: session.serverFlowName,\n endpoint: session.server?.endpoint ?? null,\n },\n };\n}\n\nfunction toSummary(session: ObserveSessionResult) {\n return {\n sessionId: session.id,\n flowId: session.flowId,\n status: session.status,\n errorMessage: session.errorMessage,\n expiresAt: session.expiresAt,\n recordsReceived: session.recordsReceived,\n arms: toArms(session),\n };\n}\n\nexport const SESSION_RESOLUTION_FAILED =\n \"Could not resolve this flow's Observe session because the journeys read that identifies it is unavailable. Pass sessionId explicitly to act on the session without that lookup.\";\n\n/**\n * Wraps a failed lookup while preserving the structured fields `mcpError`\n * renders, so the caller keeps the machine-readable code alongside the\n * recovery instruction. The original failure rides along as `cause`.\n */\nclass SessionResolutionError extends Error {\n readonly code: string | undefined;\n readonly details: unknown[] | undefined;\n\n constructor(message: string, cause: unknown) {\n super(message, { cause });\n this.name = 'SessionResolutionError';\n this.code = readStringField(cause, 'code');\n this.details = readArrayField(cause, 'details');\n }\n}\n\nfunction readStringField(source: unknown, key: string): string | undefined {\n if (source === null || typeof source !== 'object' || !(key in source))\n return undefined;\n const value = Reflect.get(source, key);\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction readArrayField(source: unknown, key: string): unknown[] | undefined {\n if (source === null || typeof source !== 'object' || !(key in source))\n return undefined;\n const value = Reflect.get(source, key);\n return Array.isArray(value) ? value : undefined;\n}\n\n/**\n * Resolve the flow's live window. `listJourneys` is the flow-keyed read the app\n * already exposes and its `sessionId` IS the flow's single active session, so\n * it doubles as the resolver: no second lookup contract is needed.\n *\n * That read depends on the observer, which status and stop themselves do not.\n * A failing lookup therefore reports the fallback rather than reading as \"this\n * flow has no session\", so stop stays reachable when the observer is down.\n */\nasync function resolveSessionId(\n client: ToolClient,\n options: { flowId: string; projectId?: string },\n): Promise<string | null> {\n try {\n const result = await client.listJourneys({\n flowId: options.flowId,\n ...(options.projectId !== undefined && { projectId: options.projectId }),\n limit: 1,\n });\n return result.sessionId;\n } catch (error) {\n // A refused caller is refused by the session read and end as well, so\n // passing sessionId would not help: let the refusal through unwrapped. The\n // handler reports it as is and attaches AUTH_HINT to an authentication\n // failure.\n if (\n isAuthenticationError(error) ||\n isAccessRefusal(error) ||\n isFeatureDenial(error)\n )\n throw error;\n const detail = error instanceof Error ? error.message : String(error);\n // Carry the structured fields across: `mcpError` reads `code` and\n // `details` off the thrown error, so a bare `new Error` would strip the\n // machine-readable code and leave callers only the prose.\n throw new SessionResolutionError(\n `${SESSION_RESOLUTION_FAILED} (${detail})`,\n error,\n );\n }\n}\n\nexport function createObserveSessionToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'observe_session',\n title: TITLE,\n description: DESCRIPTION,\n inputSchema,\n annotations,\n handler: (input) => observeSessionHandlerBody(client, input),\n };\n}\n\nasync function observeSessionHandlerBody(client: ToolClient, input: unknown) {\n const parsed = parseToolInput(inputSchema, input);\n if (!parsed.ok) return parsed.error;\n const {\n action,\n flowId,\n projectId,\n sessionId,\n arms,\n origins,\n level,\n replace,\n } = parsed.data;\n\n if (!flowId) {\n return mcpError(new Error('flowId is required for observe_session.'));\n }\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n\n try {\n switch (action) {\n case 'start': {\n if (!client.startObserveSession) {\n return mcpError(\n new Error('observe_session start is not supported by this client.'),\n );\n }\n const settings = readSettings(\n await client.getFlow({\n flowId,\n projectId: resolvedProjectId,\n fields: ['settings'],\n }),\n );\n const settingsName = resolveSettingsName(settings, arms);\n const session = await client.startObserveSession({\n projectId: resolvedProjectId,\n flowId,\n settingsName,\n ...(origins !== undefined && { origins }),\n ...(level !== undefined && { level }),\n ...(replace !== undefined && { replace }),\n });\n return mcpResult(toSummary(session), {\n next: [HINT_SIMULATE_FIRST, HINT_PREVIEW_STREAMS, HINT_READ],\n });\n }\n\n case 'status': {\n if (!client.getObserveSession) {\n return mcpError(\n new Error(\n 'observe_session status is not supported by this client.',\n ),\n );\n }\n const resolvedSessionId =\n sessionId ??\n (await resolveSessionId(client, {\n flowId,\n projectId: resolvedProjectId,\n }));\n if (!resolvedSessionId) {\n return mcpResult(\n { sessionId: null, flowId },\n { next: [HINT_NO_WINDOW, HINT_SIMULATE_FIRST] },\n );\n }\n const session = await client.getObserveSession({\n projectId: resolvedProjectId,\n flowId,\n sessionId: resolvedSessionId,\n });\n return mcpResult(toSummary(session), {\n next:\n session.recordsReceived === 0\n ? [HINT_EMPTY_FEED, HINT_READ, HINT_STOP]\n : [HINT_READ, HINT_STOP],\n });\n }\n\n case 'stop': {\n if (!client.endObserveSession) {\n return mcpError(\n new Error('observe_session stop is not supported by this client.'),\n );\n }\n const resolvedSessionId =\n sessionId ??\n (await resolveSessionId(client, {\n flowId,\n projectId: resolvedProjectId,\n }));\n if (!resolvedSessionId) {\n return mcpResult(\n { sessionId: null, flowId, ended: false },\n { next: [HINT_NO_WINDOW] },\n );\n }\n await client.endObserveSession({\n projectId: resolvedProjectId,\n flowId,\n sessionId: resolvedSessionId,\n });\n return mcpResult(\n { sessionId: resolvedSessionId, flowId, ended: true },\n { next: [HINT_ENDED] },\n );\n }\n\n default:\n throw new Error(\n `Unknown action: ${String(action)}. Use one of: start, status, stop`,\n );\n }\n } catch (error) {\n return mcpError(\n error,\n isAuthenticationError(error) ? AUTH_HINT : undefined,\n );\n }\n}\n\nexport function registerObserveSessionTool(\n server: McpServer,\n client: ToolClient,\n) {\n const spec = createObserveSessionToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => observeSessionHandlerBody(client, args),\n );\n}\n","import { isAuthenticationError, AUTH_HINT } from '../types.js';\n\n/** The code every door answers a plan or project gate with. */\nexport const FEATURE_NOT_AVAILABLE = 'FEATURE_NOT_AVAILABLE';\n\n/** The features a door can refuse a whole tool for. */\nexport type GatedFeature = 'hub' | 'frames';\n\nfunction codeOf(error: unknown): string | undefined {\n if (!(error instanceof Error) || !('code' in error)) return undefined;\n const code = error.code;\n return typeof code === 'string' ? code : undefined;\n}\n\n/**\n * A denial is recognised by its code, never by its wording: the two doors phrase\n * the refusal differently and only the code is contractual.\n */\nexport function isFeatureDenial(error: unknown): boolean {\n return codeOf(error) === FEATURE_NOT_AVAILABLE;\n}\n\n/**\n * Names the feature so an agent can tell the person what is missing. Enabling\n * it is a plan or project entitlement change made in the app, never something\n * a tool can do, and the hint says so instead of inviting a retry.\n */\nexport function featureDenialHint(feature: GatedFeature): string {\n return `The \"${feature}\" feature is not enabled for this project. Tell the person that \"${feature}\" needs a plan or project entitlement that unlocks it, which is changed in the app, not through this tool.`;\n}\n\n/**\n * One hint rule for the gated tools: a feature denial names the feature, an\n * authentication failure points at the auth tool, a NOT_FOUND points at\n * discovery, and anything else carries no hint. Each reads the error's\n * structured code or status, so a denial's wording never decides its hint.\n */\nexport function errorHint(\n error: unknown,\n feature: GatedFeature,\n notFoundHint: string,\n): string | undefined {\n if (isFeatureDenial(error)) return featureDenialHint(feature);\n if (isAuthenticationError(error)) return AUTH_HINT;\n if (codeOf(error) === 'NOT_FOUND') return notFoundHint;\n return undefined;\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { wrapUserData } from '../user-data.js';\nimport { links } from '../links.js';\nimport type {\n ToolClient,\n ReleaseRef,\n ReleaseDetailWire,\n StepHistoryWire,\n VersionAnnotationWire,\n HubThreadWire,\n KnowledgeEntryWire,\n ThreadAnchorType,\n} from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { inputIssuesMessage } from './parse-input.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { errorHint } from './feature-gate.js';\n\n/**\n * `hub_manage`: the time-and-why dimension of a flow over MCP.\n *\n * The rest of the MCP surface answers what a flow IS right now. Nothing else\n * exposes the version spine, so this is the only door an agent has to the\n * release history and the reasoning attached to it. It registers on the SAME\n * server instance as `flow_manage`, `package_get`, and the rest, which is what\n * lets an agent compose the two: current config from those tools, history and\n * rationale from this one.\n *\n * Reads are progressive: `releases` is a lean index and never carries a\n * snapshot, `release_get` opens exactly one release in full. The diff in\n * `release_get` is computed by the server from the two stored snapshots, never\n * supplied by the caller, because capture is optional by design and an\n * unannotated release's diff is the only truth left to read.\n *\n * `knowledge` is the page dimension of the same story: what people wrote on the\n * frames of a page in Tag Mode. It is addressed by frame and mark rather than\n * by flow, because a note outlives the flow it was written against and one page\n * carries notes about several. `pageKey` narrows to a whole page, resolved to\n * its frames server-side. It reads only. Writing one happens where the mark is,\n * and settling one is a person's call, the same rule the threads actions\n * follow.\n *\n * Writes are additive only. `rationale_set` replaces the human note on one\n * release and `note_add` appends to a discussion; this tool has no delete\n * action of any kind, and no way to resolve a thread. Resolving states that a\n * release settled a question, which is a person's call to make in the app.\n */\n\n// Caps and patterns the server enforces. Duplicated here so the schema can\n// describe them; the app's src/lib/hub/threads.ts, src/lib/versions/step-history.ts,\n// src/lib/hub/knowledge.ts and src/lib/api/schemas/frames.ts are the authority.\nconst MAX_ANNOTATION_TEXT_LENGTH = 4000;\nconst MAX_ANCHOR_KEY_LENGTH = 255;\nconst MAX_ANCHOR_LABEL_LENGTH = 255;\nconst MAX_STEP_HISTORY_LIMIT = 50;\nconst MAX_STEP_HISTORY_ENTRIES = 200;\nconst MAX_THREAD_LIMIT = 100;\nconst MAX_THREADS_WITH_MESSAGES = 20;\nconst MAX_SOURCE_KEY_LENGTH = 1024;\nconst MAX_MARK_ID_LENGTH = 200;\nconst FRAME_ID_PATTERN = /^frm_[A-Za-z0-9_-]{21}$/;\nconst THREAD_STATUSES = ['open', 'resolved'] as const;\n\nconst TITLE = 'Release History and Rationale';\n\n/**\n * Exported so a host asserts parity against this exact string instead of\n * retyping it.\n */\nexport const HUB_MANAGE_DESCRIPTION =\n 'Read a flow’s release history and the reasoning behind it: what each release changed, and why. ' +\n 'Actions: releases (lean index of a flow’s releases, newest first, no snapshots), ' +\n 'release_get (one release in full: its rationale plus a server-computed diff against the release before it), ' +\n 'step_history (which releases added, changed, or removed one step), ' +\n 'rationale_set (write the human rationale for one release; additive, nothing is ever deleted), ' +\n 'threads (the discussion anchored to one release, or every open discussion on the flow), ' +\n 'note_add (add a message to a thread, or open a new one on a release), ' +\n 'knowledge (read what people wrote on the marks of a page in Tag Mode: one page, one mark, or the whole project). ' +\n 'Threads are resolved by a person in the app, never here: this tool can only add to a discussion. ' +\n 'Knowledge is read-only here for the same reason, and is addressed by frame and mark rather than by flow. ' +\n 'Steps are addressed as \"type.name\", the same form flow_simulate takes, for example \"destination.ga4\", ' +\n '\"transformer.router\", \"source.browser\", \"store.session\", or \"contract.checkout\" for a contract entry. ' +\n 'This tool carries history only: use flow_manage for the current config and package_get for step schemas.';\n\nconst ACTIONS = [\n 'releases',\n 'release_get',\n 'step_history',\n 'rationale_set',\n 'threads',\n 'note_add',\n 'knowledge',\n] as const;\n\n/**\n * The anchors a caller may name here: the stored vocabulary MINUS `page`.\n *\n * A `page` anchor hangs on a FRAME, and every action here that opens a thread\n * opens it on a flow. The flow's threads response is parsed on the way out, so\n * a single page-anchored flow thread written from here would make the read fail\n * its own parse from then on, permanently, for everyone. Fencing the write is\n * what keeps that row from ever existing. Notes on a frame are written where\n * the frame is, never here.\n *\n * `satisfies` is the fence: the list is proved to be values the response\n * schemas can carry, so a member that only the storage layer knows about\n * cannot be added here without the wire contract moving first.\n */\nconst TOOL_ANCHOR_TYPES = [\n 'step',\n 'entity_action',\n 'release',\n 'contract',\n 'tag',\n] as const satisfies readonly ThreadAnchorType[];\n\n/**\n * One flat schema with an `action` enum and per-action optional fields, the\n * shape `flow_manage`, `project_manage`, and `secret_manage` already use.\n * Per-action requirements are enforced in the handler, so later actions add a\n * field and an enum member without reshaping what callers already send.\n *\n * Exported so the declarative registry holds the same object rather than a\n * second copy of it.\n */\nexport const HUB_MANAGE_INPUT_SCHEMA = {\n action: z\n .enum(ACTIONS, {\n error: () => `Unknown action. Use one of: ${ACTIONS.join(', ')}`,\n })\n .describe('Which part of the release history to read or write'),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n flowId: z\n .string()\n .optional()\n .describe(\n 'Flow ID (flow_...). Required for every action except \"knowledge\", which hangs on a page rather than a flow and refuses this field.',\n ),\n versionId: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Release version ID (ver_...) from action \"releases\". Addresses one release for release_get and rationale_set. Pass this or versionNumber.',\n ),\n versionNumber: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Spine release number for this flow, the `versionNumber` field of action \"releases\". Alternative to versionId. Not the same as a row\\'s deploymentAttempt.',\n ),\n step: z\n .string()\n .optional()\n .describe(\n 'Step key as \"type.name\", e.g. \"destination.ga4\" or \"contract.checkout\". Required for step_history.',\n ),\n flow: z\n .string()\n .optional()\n .describe(\n '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.',\n ),\n text: z\n .string()\n // Trimmed BEFORE the checks. Whitespace-only text otherwise satisfies\n // min(1) and then normalizes to empty downstream, which stores a blank\n // message, and on `rationale_set` reaches the annotation writer where\n // empty means CLEAR: the delete this additive-only tool does not have.\n .trim()\n .min(1)\n .max(MAX_ANNOTATION_TEXT_LENGTH)\n .optional()\n .describe(\n `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.`,\n ),\n limit: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n `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.`,\n ),\n offset: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Releases to skip. Action \"releases\" only.'),\n anchorType: z\n .enum(TOOL_ANCHOR_TYPES)\n .optional()\n .describe(\n '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.',\n ),\n anchorKey: z\n .string()\n .min(1)\n .max(MAX_ANCHOR_KEY_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n anchorLabel: z\n .string()\n .min(1)\n .max(MAX_ANCHOR_LABEL_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n threadId: z\n .string()\n .min(1)\n .optional()\n .describe(\n '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.',\n ),\n status: z\n .enum(THREAD_STATUSES)\n .optional()\n .describe(\n 'Read only threads in this state. Action \"threads\" only; omit for both.',\n ),\n pageKey: z\n .string()\n .min(1)\n .max(MAX_SOURCE_KEY_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n frameId: z\n .string()\n .regex(FRAME_ID_PATTERN)\n .optional()\n .describe(\n 'One frame (frm_...), the named rectangle a note hangs on. Action \"knowledge\" only. Narrower than pageKey, since a page holds several frames.',\n ),\n markId: z\n .string()\n .min(1)\n .max(MAX_MARK_ID_LENGTH)\n .optional()\n .describe(\n '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.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: false,\n destructiveHint: false,\n // False because of `note_add`, which APPENDS. `rationale_set` is an upsert\n // and repeating it is harmless, but this block covers the whole tool, and a\n // client that retries a timed-out call on the strength of an idempotent hint\n // would post the same remark twice into a human discussion. Nothing here is\n // destructive either way: a duplicate message can be read past, and there is\n // no delete to undo it with.\n idempotentHint: false,\n openWorldHint: true,\n} as const;\n\n/**\n * Hints carry the verb ladder rather than the description. One constant per\n * sentence the tool can emit, so the surface fixture pins wording and ordering\n * by name and a reword fails a test instead of drifting.\n */\nexport const HUB_HINT_RELEASE_GET =\n 'Use action \"release_get\" with a versionId or versionNumber to read one release in full, with its diff.';\nexport const HUB_HINT_ROWS_ARE_DEPLOYMENTS =\n 'Rows are deployments, not releases: the same versionId on several rows is a redeploy of identical content, so count distinct versionId values, and note that total counts deployments.';\nexport const HUB_HINT_STEP_HISTORY =\n 'Use action \"step_history\" to see which releases touched one step.';\nexport const HUB_HINT_MASKED_ONLY =\n 'The diff is empty because the only changes are inside masked values. Say that the change is not visible here rather than that nothing changed.';\nexport const HUB_HINT_TRACE_STEP =\n 'Use action \"step_history\" to trace one step across releases.';\nexport const HUB_HINT_WRITE_RATIONALE =\n 'This release has no human rationale. Read the diff, then use action \"rationale_set\" to record why it changed.';\nexport const HUB_HINT_SCAN_CAPPED =\n 'The scan stopped at the entry cap, so older releases were not compared. Narrow with \"flow\" to see the whole history of one occurrence.';\nexport const HUB_HINT_NO_MATCH =\n 'No scanned release touched this step. Check the step key against knownSteps, or raise limit to scan further back.';\nexport const HUB_HINT_OPEN_RELEASE =\n 'Use action \"release_get\" on one of these versionIds to read the full diff and rationale.';\nexport const HUB_HINT_RATIONALE_VISIBLE =\n 'The rationale is now visible on this release in the app.';\nexport const HUB_HINT_CONFIRM_INDEX =\n 'Use action \"releases\" to confirm it appears in the index.';\nexport const HUB_HINT_THREADS_PAGE_CAPPED = `More threads match than were returned (the page is capped at ${MAX_THREADS_WITH_MESSAGES} when messages are attached). Narrow with anchorType and anchorKey, or with status, rather than treating this as the complete list.`;\nexport const HUB_HINT_NOTHING_DISCUSSED =\n 'Nothing is being discussed on this flow. Use action \"note_add\" with a versionId to start a thread on a release.';\nexport const HUB_HINT_NO_THREAD_ON_ANCHOR =\n 'No thread hangs on this anchor yet. Use action \"note_add\" to open one.';\nexport const HUB_HINT_THREADS_INDEX =\n 'This is an index: message bodies are omitted. Pass a versionId, or anchorType with anchorKey, to read one discussion in full.';\nexport const HUB_HINT_MESSAGES_TRUNCATED =\n 'A thread here is marked hasMoreMessages: only its newest messages were returned. Say the discussion is longer than what you read rather than summarizing it as complete.';\nexport const HUB_HINT_REPLY_OR_OPEN =\n 'Use action \"note_add\" with a threadId to reply in one of these threads, or without one to open another.';\nexport const HUB_HINT_RESOLVE_IN_APP =\n 'Resolving a thread into a release is done by a person in the app, not through this tool.';\nexport const HUB_HINT_MESSAGE_VISIBLE =\n 'The message is now visible in this thread in the app.';\nexport const HUB_HINT_STAYS_RESOLVED =\n 'This thread is resolved and stayed resolved: a reply never retracts the release link.';\nexport const HUB_HINT_READ_BACK =\n 'Use action \"threads\" to read the discussion back.';\nexport const HUB_HINT_THREAD_OPEN =\n 'The thread is now open on this anchor in the app.';\nexport const HUB_HINT_KEEP_ONE_THREAD =\n 'Pass its threadId back to action \"note_add\" to keep the conversation in one place instead of opening another thread.';\nexport const HUB_HINT_KNOWLEDGE_PAGE_CAPPED =\n 'More knowledge matches than was returned. Narrow with pageKey, then frameId, then markId, rather than treating this as everything that was written.';\nexport const HUB_HINT_NOTHING_WRITTEN =\n 'Nothing has been written here. Notes are left on the page in Tag Mode, not through this tool.';\nexport const HUB_HINT_KNOWLEDGE_INDEX =\n 'This is an index: message bodies are omitted. Pass markId with frameId to read one mark in full.';\nexport const HUB_HINT_ENTRY_NAMES_FLOW =\n 'An entry names the flow it was written against in flowId, and validity says which release was live at the time.';\nexport const HUB_HINT_KNOWLEDGE_READ_ONLY =\n 'This tool only reads knowledge. Answering a note, and settling it, are done by a person in the app.';\nexport const HUB_HINT_READ_FRAME =\n 'Use frame_manage action \"get\" with the frameId to read the frame and its marks.';\nexport const HUB_NOT_FOUND_HINT =\n 'Use action \"releases\" to find version ids and action \"threads\" to find thread ids.';\n\n/**\n * The same shape the transport validates against, applied again here.\n *\n * The MCP SDK does parse arguments before invoking a tool callback, but that\n * parse happens in whichever SDK copy the host linked, and this module's spec\n * is deliberately drivable without a transport at all. Parsing here is what\n * keeps the 4000-char cap and the additive-only guarantee inside this file:\n * `text: null` would otherwise reach the annotation writer, where null means\n * CLEAR, and quietly become the delete action this tool does not have.\n */\nconst hubInputSchema = z.object(HUB_MANAGE_INPUT_SCHEMA);\n\ntype HubInput = z.infer<typeof hubInputSchema>;\n\n/**\n * Why a call was refused. Carried as `code` so an agent can branch on the\n * denial it is most likely to hit instead of matching prose. A denial the\n * server raises, such as FEATURE_NOT_AVAILABLE, arrives with its own code and\n * never needs a member here.\n */\nexport type HubToolErrorCode = 'INVALID_INPUT' | 'NOT_FOUND';\n\nexport class HubToolError extends Error {\n constructor(\n public readonly code: HubToolErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'HubToolError';\n }\n}\n\nfunction requireParam<T>(\n value: T | undefined,\n name: string,\n action: string,\n): T {\n if (value === undefined) {\n throw new HubToolError(\n 'INVALID_INPUT',\n `${name} is required for action \"${action}\"`,\n );\n }\n return value;\n}\n\n/**\n * Resolve the release address a caller gave. `versionId` wins when both are\n * present, so an explicit id is never silently reinterpreted as a number.\n */\nfunction releaseRef(input: HubInput, action: string): ReleaseRef {\n if (input.versionId !== undefined) return { versionId: input.versionId };\n if (input.versionNumber !== undefined) {\n return { versionNumber: input.versionNumber };\n }\n throw new HubToolError(\n 'INVALID_INPUT',\n `versionId or versionNumber is required for action \"${action}\". Use action \"releases\" to find one.`,\n );\n}\n\n/**\n * Stored annotation text is written by people and lands in third-party model\n * context, so it is wrapped as data. Ids, numbers, and timestamps stay literal:\n * the agent has to echo them back verbatim in the next call.\n */\nfunction serializeAnnotation(annotation: VersionAnnotationWire) {\n return {\n versionId: annotation.versionId,\n humanText:\n annotation.humanText === null ? null : wrapUserData(annotation.humanText),\n generatedSummary:\n annotation.generatedSummary === null\n ? null\n : wrapUserData(annotation.generatedSummary),\n author: annotation.author,\n createdAt: annotation.createdAt,\n updatedAt: annotation.updatedAt,\n };\n}\n\n/**\n * The scan result as an index. An entry's own rationale text is not surfaced\n * here: `release_get` is the detail read, and repeating every note across a\n * fifty-release scan would make this the opposite of an index.\n */\nfunction serializeStepHistory(history: StepHistoryWire) {\n return {\n step: history.step,\n flow: history.flow,\n entries: history.entries.map((entry) => ({\n versionId: entry.versionId,\n versionNumber: entry.versionNumber,\n createdAt: entry.createdAt,\n flow: entry.flow,\n change: entry.change,\n })),\n scanned: history.scanned,\n truncated: history.truncated,\n entriesTruncated: history.entriesTruncated,\n // Step keys and flow names are addresses the caller passes straight back,\n // so they stay literal for the same reason ids do.\n ...(history.knownSteps !== undefined && { knownSteps: history.knownSteps }),\n };\n}\n\n/**\n * Thread text is written by people and lands in third-party model context, so\n * message bodies and the anchor label are wrapped as data. Ids, the status, and\n * timestamps stay literal: the agent echoes them back in the next call.\n */\nfunction serializeThread(thread: HubThreadWire) {\n return {\n threadId: thread.id,\n anchorType: thread.anchorType,\n anchorKey: thread.anchorKey,\n anchorLabel: wrapUserData(thread.anchorLabel),\n status: thread.status,\n // The release that settled it, null while open AND once that release is\n // gone. `status` is what separates those two, never this field.\n resolvedByVersionId: thread.resolvedByVersionId,\n resolvedByVersionNumber: thread.resolvedByVersionNumber,\n resolvedBy: thread.resolvedBy,\n createdBy: thread.createdBy,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n messageCount: thread.messageCount,\n ...(thread.messages !== undefined\n ? {\n // Set when the thread holds more than this call carried. The tail is\n // the OLD end: what is here is always the newest exchange.\n hasMoreMessages: thread.hasMoreMessages === true,\n messages: thread.messages.map((message) => ({\n author: message.author,\n text: wrapUserData(message.text),\n createdAt: message.createdAt,\n })),\n }\n : {}),\n };\n}\n\n/**\n * Knowledge is written on a live page and lands in third-party model context,\n * so the description body, the message bodies, the anchor's label, the frame's\n * name and the author's display name are wrapped as data. Ids, keys, the\n * derived validity and freshness, and timestamps stay literal: the agent\n * addresses the next call with the first and branches on the rest.\n *\n * The spatial placement is dropped rather than serialized. Its `element` is an\n * opaque DOM anchor captured from the page, of unbounded size and shape, and\n * the fractional point beside it only means something to something that draws\n * the overlay. Neither tells a reader here anything, and the first is page\n * content this tool would then have to wrap.\n */\nfunction serializeKnowledge(entry: KnowledgeEntryWire) {\n const shared = {\n id: entry.id,\n anchorType: entry.anchorType,\n anchorKey: entry.anchorKey,\n anchorLabel: wrapUserData(entry.anchorLabel),\n frameId: entry.frameId,\n /** A person names a frame, so the name is page content like any other. */\n frameName: entry.frameName === null ? null : wrapUserData(entry.frameName),\n /** The flow it was written against, or null. Never a filter. */\n flowId: entry.flowId,\n subjectKey: entry.subjectKey,\n /** When it was true, and whether it still is. Derived at read time. */\n validity: entry.validity,\n freshness: entry.freshness,\n author: {\n kind: entry.author.kind,\n id: entry.author.id,\n label: wrapUserData(entry.author.label),\n },\n source: entry.source,\n updatedAt: entry.updatedAt,\n };\n\n if (entry.kind === 'description') {\n return { ...shared, kind: entry.kind, body: wrapUserData(entry.body) };\n }\n\n return {\n ...shared,\n kind: entry.kind,\n status: entry.status,\n createdAt: entry.createdAt,\n messageCount: entry.messageCount,\n ...(entry.messages !== undefined\n ? {\n // Set when the thread holds more than this call carried, and only\n // meaningful beside the messages it describes.\n hasMoreMessages: entry.hasMoreMessages === true,\n messages: entry.messages.map((message) => ({\n author: message.author,\n text: wrapUserData(message.text),\n createdAt: message.createdAt,\n })),\n }\n : {}),\n };\n}\n\nasync function handleReleases(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const { releases, total } = await client.listReleases({\n projectId,\n flowId,\n ...(input.limit !== undefined && { limit: input.limit }),\n ...(input.offset !== undefined && { offset: input.offset }),\n });\n\n // The screen this index is of. Structured rather than only mentioned in a\n // hint, so an agent can hand it on as data instead of re-typing it out of\n // prose. Named `appUrl`, the one key every tool here emits a link under, so\n // it can never collide with a `url` that some response already uses for\n // something of its own.\n const appUrl = links.release({\n baseUrl: client.appBaseUrl(),\n projectId,\n flowId,\n });\n\n return mcpResult(\n {\n releases: releases.map((release) => ({\n // The spine address. `release_get` and `rationale_set` take this pair\n // and nothing else.\n versionId: release.flowVersionId,\n versionNumber: release.flowVersionNumber,\n deployment: release.deploymentSlug,\n deploymentType: release.deploymentType,\n // The publish attempt within that deployment lineage. Deliberately NOT\n // called a version: it addresses nothing in this tool, and a row\n // carrying two numbers both named \"version\" is a trap.\n deploymentAttempt: release.versionNumber,\n status: release.status,\n source: release.source,\n errorCode: release.errorCode,\n createdAt: release.createdAt,\n createdBy: release.createdBy,\n rationale: release.rationale\n ? {\n hasHumanText: release.rationale.hasHumanText,\n hasGeneratedSummary: release.rationale.hasGeneratedSummary,\n firstLine:\n release.rationale.firstLine === null\n ? null\n : wrapUserData(release.rationale.firstLine),\n }\n : null,\n })),\n total,\n ...(appUrl !== undefined && { appUrl }),\n },\n {\n next: [\n HUB_HINT_RELEASE_GET,\n HUB_HINT_ROWS_ARE_DEPLOYMENTS,\n HUB_HINT_STEP_HISTORY,\n ],\n },\n );\n}\n\nasync function handleReleaseGet(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const release = await client.getRelease({\n projectId,\n flowId,\n ref: releaseRef(input, 'release_get'),\n });\n\n // The rendered diff is built from MASKED content, so an empty diff does not\n // mean the releases are the same: a change confined to an inline secret\n // renders as nothing. `contentIdentical` is decided over unmasked content,\n // so it is the only trustworthy identity signal, and the gap between the two\n // is stated rather than left for the reader to infer.\n const contentIdentical =\n release.diff !== null && release.diff.contentIdentical;\n const maskedOnly =\n release.diff !== null && release.diff.text === '' && !contentIdentical;\n\n return mcpResult(\n {\n versionId: release.versionId,\n versionNumber: release.versionNumber,\n contentHash: release.contentHash,\n createdAt: release.createdAt,\n createdBy: release.createdBy,\n rationale: release.rationale\n ? serializeAnnotation(release.rationale)\n : null,\n diff: release.diff\n ? {\n prevVersionId: release.diff.prevVersionId,\n prevVersionNumber: release.diff.prevVersionNumber,\n // Config values are user-authored, and inline secrets are masked\n // before the text is built.\n text:\n release.diff.text === '' ? null : wrapUserData(release.diff.text),\n /** Compared over unmasked content, so this is the real answer. */\n contentIdentical,\n note: maskedOnly\n ? 'These releases differ, but only inside values that are masked in the diff, typically inline secrets. Do not report this release as unchanged.'\n : null,\n }\n : null,\n diffUnavailable: release.diff\n ? null\n : 'This is the flow’s oldest release, so there is nothing to diff it against.',\n },\n {\n next: maskedOnly\n ? [HUB_HINT_MASKED_ONLY]\n : release.rationale?.humanText\n ? [HUB_HINT_TRACE_STEP]\n : [HUB_HINT_WRITE_RATIONALE],\n },\n );\n}\n\nasync function handleStepHistory(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const step = requireParam(input.step, 'step', 'step_history');\n\n const history = await client.listStepHistory({\n projectId,\n flowId,\n step,\n ...(input.flow !== undefined && { flow: input.flow }),\n ...(input.limit !== undefined && { limit: input.limit }),\n });\n\n const next = history.entriesTruncated\n ? [HUB_HINT_SCAN_CAPPED]\n : history.entries.length === 0\n ? [HUB_HINT_NO_MATCH]\n : [HUB_HINT_OPEN_RELEASE];\n\n // The step on screen, linked only when the scan itself says the step is\n // still there.\n //\n // `history.flow` is the caller's own filter echoed back, unvalidated, so a\n // scan that named no flow gets no link (a step address without one resolves\n // to nothing in the app) and a scan that named a wrong one would otherwise\n // build an address the flow page opens and then refuses. Entries come back\n // newest first, so an empty scan found the step in no release at all, and a\n // newest entry of `removed` means the last thing that happened to it was its\n // removal. Both are exactly the cases the app answers with its \"not found in\n // this flow\" notice, and no link beats a link to a notice.\n //\n // The flow names on the ENTRIES are deliberately not used as the address\n // instead: they say where the step USED to live. What remains is a step\n // renamed since the newest release, which no signal in hand can catch; the\n // app names that on screen.\n const newest = history.entries[0];\n const stepIsLive = newest !== undefined && newest.change !== 'removed';\n const appUrl = stepIsLive\n ? links.step({\n baseUrl: client.appBaseUrl(),\n projectId,\n flowId,\n step: history.step,\n flow: history.flow,\n })\n : undefined;\n\n return mcpResult(\n {\n ...serializeStepHistory(history),\n ...(appUrl !== undefined && { appUrl }),\n },\n { next },\n );\n}\n\n/**\n * Every release address goes through the detail read, by id as much as by\n * number: it is the one call that proves the release belongs to THIS flow and\n * hands back the number the app shows. A sibling flow's id therefore meets\n * NOT_FOUND from the client before anything is written.\n */\nasync function resolveRelease(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n action: string,\n): Promise<ReleaseDetailWire> {\n return client.getRelease({\n projectId,\n flowId,\n ref: releaseRef(input, action),\n });\n}\n\nasync function handleRationaleSet(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const text = requireParam(input.text, 'text', 'rationale_set');\n const release = await resolveRelease(\n client,\n projectId,\n flowId,\n input,\n 'rationale_set',\n );\n\n const annotation = await client.setReleaseRationale({\n projectId,\n flowId,\n versionId: release.versionId,\n text,\n });\n\n return mcpResult(\n {\n versionId: annotation.versionId,\n versionNumber: release.versionNumber,\n rationale: serializeAnnotation(annotation),\n },\n { next: [HUB_HINT_RATIONALE_VISIBLE, HUB_HINT_CONFIRM_INDEX] },\n );\n}\n\n/** One anchor a thread hangs on, resolved from whatever the caller addressed. */\ninterface ResolvedAnchor {\n anchorType: ThreadAnchorType;\n anchorKey: string;\n anchorLabel: string;\n}\n\n/**\n * The anchor the caller addressed, or null when they addressed none.\n *\n * A release can be addressed the way every other action here takes one\n * (`versionId` / `versionNumber`), which is resolved through the flow so a\n * sibling flow's release is refused and the display label is derived from the\n * real release number rather than trusted from the caller. Any other anchor\n * type is taken as given: this tool cannot verify a step key against a config\n * it does not load, and a thread on a key that no longer exists is exactly what\n * `anchorLabel` and the unanchored bucket are for.\n */\nasync function resolveAnchor(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n action: string,\n): Promise<ResolvedAnchor | null> {\n const type = input.anchorType ?? 'release';\n\n if (type === 'release') {\n if (input.versionId === undefined && input.versionNumber === undefined) {\n if (input.anchorKey === undefined) return null;\n // An explicit key for a release anchor still has to be a release of this\n // flow, or the thread would point at nothing readable.\n const byKey = await client.getRelease({\n projectId,\n flowId,\n ref: { versionId: input.anchorKey },\n });\n return {\n anchorType: 'release',\n anchorKey: byKey.versionId,\n anchorLabel: `v${byKey.versionNumber}`,\n };\n }\n\n const release = await resolveRelease(\n client,\n projectId,\n flowId,\n input,\n action,\n );\n return {\n anchorType: 'release',\n anchorKey: release.versionId,\n anchorLabel: `v${release.versionNumber}`,\n };\n }\n\n if (input.anchorKey === undefined) return null;\n return {\n anchorType: type,\n anchorKey: input.anchorKey,\n anchorLabel: input.anchorLabel ?? input.anchorKey,\n };\n}\n\nasync function handleThreads(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const anchor = await resolveAnchor(\n client,\n projectId,\n flowId,\n input,\n 'threads',\n );\n\n // Message bodies come back only for ONE anchor. A whole-flow listing is an\n // index, and carrying every word ever written on every anchor would make it\n // the opposite of one.\n const { threads, hasMoreThreads } = await client.listThreads({\n projectId,\n flowId,\n includeMessages: anchor !== null,\n ...(anchor !== null\n ? { anchorType: anchor.anchorType, anchorKey: anchor.anchorKey }\n : {}),\n ...(input.status !== undefined && { status: input.status }),\n ...(input.limit !== undefined && {\n limit: Math.min(input.limit, MAX_THREAD_LIMIT),\n }),\n });\n\n const truncated = threads.some((thread) => thread.hasMoreMessages === true);\n\n // The page ceiling is not what the caller asked for: a read that carries\n // message bodies is clamped hard. Saying so keeps an agent from reporting a\n // truncated page as the whole of a flow's discussion.\n const pageHint = hasMoreThreads ? [HUB_HINT_THREADS_PAGE_CAPPED] : [];\n\n const next =\n threads.length === 0\n ? [\n anchor === null\n ? HUB_HINT_NOTHING_DISCUSSED\n : HUB_HINT_NO_THREAD_ON_ANCHOR,\n ]\n : anchor === null\n ? [...pageHint, HUB_HINT_THREADS_INDEX]\n : [\n ...pageHint,\n ...(truncated ? [HUB_HINT_MESSAGES_TRUNCATED] : []),\n HUB_HINT_REPLY_OR_OPEN,\n HUB_HINT_RESOLVE_IN_APP,\n ];\n\n // Where these are read. An anchored read links the anchor's own screen, and\n // only a release anchor can be addressed from the shape held here. An\n // unanchored read is the flow's whole discussion, which is read in the\n // release history, so it links that.\n const flowTarget = { baseUrl: client.appBaseUrl(), projectId, flowId };\n const appUrl =\n anchor === null\n ? links.release(flowTarget)\n : links.thread({ ...flowTarget, anchorType: anchor.anchorType });\n\n return mcpResult(\n {\n threads: threads.map(serializeThread),\n hasMoreThreads,\n ...(appUrl !== undefined && { appUrl }),\n },\n { next },\n );\n}\n\nasync function handleNoteAdd(\n client: ToolClient,\n projectId: string,\n flowId: string,\n input: HubInput,\n) {\n const text = requireParam(input.text, 'text', 'note_add');\n\n if (input.threadId !== undefined) {\n const thread = await client.addThreadMessage({\n projectId,\n flowId,\n threadId: input.threadId,\n text,\n });\n return mcpResult(\n { thread: serializeThread(thread) },\n {\n next: [\n HUB_HINT_MESSAGE_VISIBLE,\n thread.status === 'resolved'\n ? HUB_HINT_STAYS_RESOLVED\n : HUB_HINT_READ_BACK,\n ],\n },\n );\n }\n\n const anchor = await resolveAnchor(\n client,\n projectId,\n flowId,\n input,\n 'note_add',\n );\n if (anchor === null) {\n throw new HubToolError(\n 'INVALID_INPUT',\n 'note_add needs somewhere to write: pass threadId to reply, or versionId (or anchorType with anchorKey) to open a thread on an anchor.',\n );\n }\n\n const thread = await client.createThread({\n projectId,\n flowId,\n anchorType: anchor.anchorType,\n anchorKey: anchor.anchorKey,\n // A release anchor is labeled by the server from the release number, so the\n // label travels only for the other anchor types.\n ...(anchor.anchorType !== 'release' && { anchorLabel: anchor.anchorLabel }),\n text,\n });\n\n return mcpResult(\n { thread: serializeThread(thread) },\n { next: [HUB_HINT_THREAD_OPEN, HUB_HINT_KEEP_ONE_THREAD] },\n );\n}\n\nasync function handleKnowledge(\n client: ToolClient,\n projectId: string,\n input: HubInput,\n) {\n // Message bodies come back only for ONE mark, the rule `threads` follows for\n // one anchor: a page-wide or project-wide read is an index, and carrying\n // every word written on every mark would make it the opposite of one.\n const oneMark = input.markId !== undefined;\n\n // The server refuses a mark without its page rather than answering an\n // unnarrowed list, and that refusal carries its own code through mcpError.\n const { entries, hasMoreEntries } = await client.listKnowledge({\n projectId,\n includeMessages: oneMark,\n ...(input.pageKey !== undefined && { pageKey: input.pageKey }),\n ...(input.frameId !== undefined && { frameId: input.frameId }),\n ...(input.markId !== undefined && { markId: input.markId }),\n ...(input.limit !== undefined && { limit: input.limit }),\n });\n\n const truncated = entries.some(\n (entry) => entry.kind === 'thread' && entry.hasMoreMessages === true,\n );\n\n const pageHint = hasMoreEntries ? [HUB_HINT_KNOWLEDGE_PAGE_CAPPED] : [];\n\n const next =\n entries.length === 0\n ? [HUB_HINT_NOTHING_WRITTEN]\n : [\n ...pageHint,\n ...(oneMark\n ? truncated\n ? [HUB_HINT_MESSAGES_TRUNCATED]\n : []\n : [HUB_HINT_KNOWLEDGE_INDEX]),\n HUB_HINT_ENTRY_NAMES_FLOW,\n HUB_HINT_KNOWLEDGE_READ_ONLY,\n HUB_HINT_READ_FRAME,\n ];\n\n return mcpResult(\n { entries: entries.map(serializeKnowledge), hasMoreEntries },\n { next },\n );\n}\n\nexport async function hubManageHandler(client: ToolClient, rawInput: unknown) {\n try {\n // Parse, never assert: see the note on `hubInputSchema`. A raw ZodError\n // stringifies its whole issue list into `message`, so the issues are\n // rewritten as one readable line carrying the same code as every other\n // refusal here.\n const parsed = hubInputSchema.safeParse(rawInput ?? {});\n if (!parsed.success) {\n throw new HubToolError('INVALID_INPUT', inputIssuesMessage(parsed.error));\n }\n const input: HubInput = parsed.data;\n const { action } = input;\n\n const projectId = resolveDefaultProject(client, input.projectId);\n if (!projectId) {\n throw new HubToolError('INVALID_INPUT', NO_DEFAULT_PROJECT_ERROR);\n }\n\n if (action === 'knowledge') {\n // Nothing here narrows knowledge by flow. Taking the field and answering\n // with every page's notes anyway is the failure mode this refuses: the\n // caller asked for one flow's and would read the answer as that.\n if (input.flowId !== undefined) {\n throw new HubToolError(\n 'INVALID_INPUT',\n 'flowId does not narrow action \"knowledge\", which is addressed by frame and mark: pass pageKey, frameId or markId instead. Each entry names the flow it was written against.',\n );\n }\n return await handleKnowledge(client, projectId, input);\n }\n\n const flowId = requireParam(input.flowId, 'flowId', action);\n\n switch (action) {\n case 'releases':\n return await handleReleases(client, projectId, flowId, input);\n case 'release_get':\n return await handleReleaseGet(client, projectId, flowId, input);\n case 'step_history':\n return await handleStepHistory(client, projectId, flowId, input);\n case 'rationale_set':\n return await handleRationaleSet(client, projectId, flowId, input);\n case 'threads':\n return await handleThreads(client, projectId, flowId, input);\n case 'note_add':\n return await handleNoteAdd(client, projectId, flowId, input);\n }\n } catch (error) {\n // `mcpError` lifts a `code` property off the error, so a HubToolError and\n // whatever the client raises both surface their code without a branch here.\n return mcpError(error, errorHint(error, 'hub', HUB_NOT_FOUND_HINT));\n }\n}\n\n/**\n * The tool as data, so it can be driven without an MCP transport (tests, and\n * any in-process bridge).\n */\nexport function createHubManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'hub_manage',\n title: TITLE,\n description: HUB_MANAGE_DESCRIPTION,\n inputSchema: HUB_MANAGE_INPUT_SCHEMA,\n annotations,\n handler: (input) => hubManageHandler(client, input),\n };\n}\n\nexport function registerHubManageTool(server: McpServer, client: ToolClient) {\n const spec = createHubManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => hubManageHandler(client, args),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { mcpResult, mcpError } from '@walkeros/core';\nimport { redactNestedStrings, wrapUserData } from '../user-data.js';\nimport type { ToolClient, FrameLeanWire, FrameWire } from '../tool-client.js';\nimport type { ToolSpec } from '../tool-spec.js';\nimport { inputIssuesMessage } from './parse-input.js';\nimport {\n validateActionInput,\n assertParam,\n FRAME_MANAGE_REQUIREMENTS,\n} from '../action-requirements.js';\nimport {\n NO_DEFAULT_PROJECT_ERROR,\n resolveDefaultProject,\n} from './project-context.js';\nimport { errorHint } from './feature-gate.js';\n\n/**\n * `frame_manage`: the place dimension of a measurement plan over MCP.\n *\n * A frame is a named rectangle over a page, with marks inside it. It answers\n * WHERE something is measured, which nothing else on this surface carries:\n * `flow_manage` holds the config, `hub_manage` holds the history and the\n * reasoning, and this holds the drawing those two are argued about on.\n *\n * Read-only, on purpose. A frame is drawn against a live page or an import,\n * and its geometry only means anything next to the pixels it was drawn on.\n * A tool that cannot see the page cannot place a rectangle on it, so writing\n * one from here would be guessing. Editing happens in Tag Mode or the app.\n *\n * Reads are progressive, the same ladder `hub_manage` uses. `list` is the lean\n * project index and never carries marks, because the marks of a whole project\n * are the largest thing this tool could return and are almost never what a\n * caller wanted. `page` opens one page's frames with their marks, and `get`\n * opens exactly one frame.\n *\n * It composes with `hub_manage` through ids: a tag id read here is the\n * `markId` that tool's \"knowledge\" action takes, which is why tag ids stay\n * literal while everything else inside the marks is wrapped as user data.\n */\n\n// Caps and patterns the server enforces. Duplicated here so the schema can\n// describe them; the app's src/lib/api/schemas/frames.ts is the authority.\nconst FRAME_ID_PATTERN = /^frm_[A-Za-z0-9_-]{21}$/;\nconst MAX_PAGE_KEY_CHARS = 1024;\n\nconst TITLE = 'Frames';\n\n/**\n * Exported so a host asserts parity against this exact string instead of\n * retyping it.\n */\nexport const FRAME_MANAGE_DESCRIPTION =\n 'Read the frames of a measurement plan: named rectangles with marks inside them, drawn in Tag Mode or in the app. ' +\n '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). ' +\n 'Read-only: frames are drawn and edited in Tag Mode or the app, never here. ' +\n '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. ' +\n '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’s own description and thread. ' +\n 'Use hub_manage action \"knowledge\" with a frameId or markId to read what people wrote on a frame. ' +\n 'A markId is a tag id: a tag’s 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.';\n\n/**\n * Exported so the declarative registry holds the same object rather than a\n * second copy of it.\n */\nexport const FRAME_MANAGE_INPUT_SCHEMA = {\n action: z\n .enum(['list', 'page', 'get'])\n .describe(\n 'list the project’s frames, read one page with marks, or read one frame',\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n 'Project ID. Optional: falls back to the default project when omitted.',\n ),\n pageKey: z\n .string()\n .min(1)\n .max(MAX_PAGE_KEY_CHARS)\n .optional()\n .describe(\n 'The page as its frames address it (the `source.key` of a page frame, usually the page URL without query). Required for page.',\n ),\n frameId: z\n .string()\n .regex(FRAME_ID_PATTERN)\n .optional()\n .describe(\n 'Frame ID (frm_...). Required for get. Use action \"list\" or \"page\" to find one.',\n ),\n};\n\nconst annotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/**\n * Hints carry the verb ladder rather than the description. One constant per\n * sentence the tool can emit, so the surface fixture pins wording and ordering\n * by name and a reword fails a test instead of drifting.\n */\nexport const FRAME_HINT_OPEN_PAGE_OR_GET =\n 'Use action \"page\" with a pageKey (a frame’s source.key) to read a page with marks, or action \"get\" with a frameId.';\nexport const FRAME_HINT_NAMES_ARE_DOCUMENTATION =\n 'Frame names are documentation; the marks inside a frame carry the meaning.';\nexport const FRAME_HINT_NONE_YET =\n 'This project has no frames yet. Frames are drawn in Tag Mode or the app, not through this tool.';\nexport const FRAME_HINT_MARK_SPACE =\n 'Tag geometry is fractional: a rect is 0..1 of its frame, and an at is 0..1 of its parent tag’s box, or of the frame for a root tag; a child frame sits inside its parent through placements[].rect.';\nexport const FRAME_HINT_READ_KNOWLEDGE =\n 'Use hub_manage action \"knowledge\" with frameId (and markId) to read what people wrote here. A markId is a tag id from these marks, and a tag’s threadRef is the id of its thread entry there.';\nexport const FRAME_HINT_NONE_ON_PAGE =\n 'No frames on this page. Check the pageKey against the source.key values from action \"list\".';\nexport const FRAME_HINT_EXTENDS_BASE =\n 'This frame extends another and stores only what it adds; read the base frame (extends) for the rest.';\nexport const FRAME_NOT_FOUND_HINT =\n 'Use action \"list\" or \"page\" to find frame ids.';\n\n/**\n * The two source keys that stay literal, and only those. `kind` is the\n * discriminator a reader branches on, and `key` is the pageKey the `page`\n * action takes, so it has to be echoed back verbatim. Every other string in a\n * source is text a reader only ever looks at: the page `url`, and the `fileKey`\n * and `nodeId` of an imported design. No action takes any of them, so they are\n * wrapped like any other value.\n */\nconst keepSourceAddress = (key: string): boolean =>\n key === 'kind' || key === 'key';\n\n/**\n * A placement's `selector` and `anchor` are opaque DOM anchors captured off a\n * live page, of unbounded size: page content a reader gains nothing from and\n * this tool would otherwise have to wrap. Only the rectangle is kept.\n *\n * `projectId` and `deletedAt` are dropped for a different reason: the caller\n * named the project, and a listing only ever carries live frames, so both\n * would be noise on every row.\n */\nfunction serializeLean(frame: FrameLeanWire) {\n return {\n id: frame.id,\n name: wrapUserData(frame.name),\n parentId: frame.parentId,\n extends: frame.extends,\n source: redactNestedStrings(frame.source, { skip: keepSourceAddress }),\n origin: frame.origin,\n flowId: frame.flowId,\n placements: frame.placements.map((placement) => ({\n id: placement.id,\n rect: placement.rect,\n })),\n size: frame.size,\n screenshot: frame.screenshot\n ? {\n assetId: frame.screenshot.assetId,\n capturedAt: frame.screenshot.capturedAt,\n size: frame.screenshot.size,\n dpr: frame.screenshot.dpr,\n capturedRect: frame.screenshot.capturedRect,\n }\n : null,\n version: frame.version,\n createdAt: frame.createdAt,\n updatedAt: frame.updatedAt,\n createdBy: frame.createdBy,\n updatedBy: frame.updatedBy,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The rule for everything inside a marks document, in one place.\n *\n * - An ADDRESS stays literal, because another tool consumes it and it has to\n * be passed back exactly as it came. A sanitised address names a tag the app\n * never stored, so cleaning one trades a working lookup for a silent miss.\n * - Everything else is text a person or a page wrote, and is always wrapped,\n * so it cannot close the envelope and be read as instructions.\n *\n * Marks are a passthrough record: the server checks nothing inside them, so a\n * client writes whatever keys and values it likes, and a name that means\n * \"identifier\" in a flow config means nothing here. An address is therefore\n * decided by WHERE a value lives and by WHAT it looks like, never by the\n * spelling of its key alone.\n *\n * Where: a marks document is `{ tags, note }`. `tags` is one flat list of tags,\n * related through `parentId`, and `note` is the frame's own description and\n * thread. Only the top-level fields of a tag in that list, and of that note, can\n * be addresses. Below them nothing is, whatever it is called: `id` inside an\n * anchor is `el.id` read off the host page, and `id` on a thread message is a\n * row id no tool takes, so both are text like their siblings.\n *\n * What: a value in an address position stays literal only when it has the shape\n * the app mints for that address. Nothing upstream enforces the shape, so a\n * sentence stored under `id` is text and is wrapped like any other. A real\n * address that falls outside the shape comes back wrapped too, which costs a\n * lookup and never leaks an instruction.\n *\n * A key this file does not name, at any level, is walked as text. Object keys\n * are client-written too, so a key keeps its spelling only when it is a plain\n * identifier (see {@link markKey}); any other key is wrapped like a value.\n */\n\n/**\n * A tag id as the app mints it, and nothing wider:\n *\n * - `<prefix>_<n>` from the editor (`nextMarkId` in `tag-plan/frames.ts`,\n * `freshId` in `tag-plan/write.ts`);\n * - `e_<entity>`, `...#data.v<n>` and `...#action.<n>` from a contract or observed\n * events (`tag-plan/contract.ts`, `tag-plan/infer.ts`);\n * - `<entity>-<n>`, a nested `.../<entity>-<n>`, `...#data.<n>`, `...#action.<n>`,\n * `...#context.<n>`, `globals#<n>` and `page#action.<n>` from a page read\n * (`tag-plan/walker-plan.ts`).\n *\n * No colon, which keeps the hub key `<frameId>:<markId>` parseable, and no\n * whitespace, quote or angle bracket. An entity name outside `[A-Za-z0-9_-]`\n * makes the last two minters spell an id this does not match, which then wraps.\n */\nconst TAG_ID_PATTERN =\n /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*(?:#(?:data\\.v?[0-9]+|action\\.[0-9]+|context\\.[0-9]+|[0-9]+))?$/;\n\n/** The longest mark id the hub accepts (`MAX_MARK_ID_LENGTH` in the app's\n * `src/lib/hub/knowledge.ts`), so a longer value cannot be a markId. */\nconst MAX_TAG_ID_CHARS = 200;\n\n/** A hub thread id as the app mints it: `thr_` plus a 21-character lowercase\n * alphanumeric nanoid (`src/lib/id.ts`, `src/lib/hub/knowledge.ts`). */\nconst THREAD_ID_PATTERN = /^thr_[a-z0-9]{21}$/;\n\nconst isTagId = (value: string): boolean =>\n value.length <= MAX_TAG_ID_CHARS && TAG_ID_PATTERN.test(value);\n\nconst isThreadId = (value: string): boolean => THREAD_ID_PATTERN.test(value);\n\n/** The fields of a tag that are addresses, each with the shape it must have. */\nconst TAG_ADDRESSES: ReadonlyMap<string, (value: string) => boolean> = new Map([\n // The tag id: the markId `hub_manage` action \"knowledge\" takes, which the\n // app joins to the frame id as the anchor key `<frameId>:<markId>`.\n ['id', isTagId],\n // The tag this one sits under, which is that tag's id: the only relation\n // between tags, so a reader joins it to `id` to rebuild the tree, and it is\n // a markId in its own right.\n ['parentId', isTagId],\n // The hub thread this tag's note thread became: the `id` of the thread\n // entry `hub_manage` action \"knowledge\" returns for this tag.\n ['threadRef', isThreadId],\n]);\n\n/** The fields of the frame note that are addresses. The note belongs to the\n * frame, which `hub_manage` addresses by frameId, so its one address is the hub\n * thread it became, read the same way as a tag's. */\nconst NOTE_ADDRESSES: ReadonlyMap<string, (value: string) => boolean> = new Map(\n [['threadRef', isThreadId]],\n);\n\n/** A key the app writes: a JavaScript-style identifier, dashes allowed for\n * attribute names, bounded in length. Such a key cannot close the envelope or\n * carry a sentence, so it stays readable. */\nconst MARK_KEY_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$-]{0,63}$/;\n\n/** A marks key as it is handed back: literal when it has the shape of a key the\n * app writes, wrapped as data otherwise. */\nconst markKey = (key: string): string =>\n MARK_KEY_PATTERN.test(key) ? key : wrapUserData(key);\n\n/** Text below the addresses: every string wrapped, every key through\n * {@link markKey}. */\nfunction walkText(value: unknown): unknown {\n if (typeof value === 'string') return wrapUserData(value);\n if (Array.isArray(value)) return value.map(walkText);\n if (!isRecord(value)) return value;\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n out[markKey(key)] = walkText(child);\n }\n return out;\n}\n\n/** Walks a marks document applying the rule above. */\nfunction walkMarks(marks: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(marks)) {\n if (key === 'tags' && Array.isArray(value)) {\n out[key] = value.map((tag) => walkAddressed(tag, TAG_ADDRESSES));\n } else if (key === 'note') {\n out[key] = walkAddressed(value, NOTE_ADDRESSES);\n } else {\n out[markKey(key)] = walkText(value);\n }\n }\n return out;\n}\n\n/**\n * One record whose own fields named in `addresses` stay literal when their\n * value has that address's shape. A value there without the shape, a string or\n * not, is not an address, so it is walked like anything else rather than passed\n * through unseen, and so is everything below the record's own fields. A value\n * that is not a record has no fields to address and is text.\n */\nfunction walkAddressed(\n value: unknown,\n addresses: ReadonlyMap<string, (value: string) => boolean>,\n): unknown {\n if (!isRecord(value)) return walkText(value);\n const out: Record<string, unknown> = {};\n for (const [key, field] of Object.entries(value)) {\n const isAddress = addresses.get(key);\n out[markKey(key)] =\n isAddress !== undefined && typeof field === 'string' && isAddress(field)\n ? field\n : walkText(field);\n }\n return out;\n}\n\nfunction serializeFrame(frame: FrameWire) {\n return {\n ...serializeLean(frame),\n marks: walkMarks(frame.marks),\n };\n}\n\n/**\n * The same shape the transport validates against, applied again here, on the\n * rule `hub_manage` states: this module's spec is deliberately drivable without\n * a transport, so the caps and the id pattern have to hold inside this file\n * rather than in whichever SDK copy a host linked.\n */\nconst frameInputSchema = z.object(FRAME_MANAGE_INPUT_SCHEMA);\n\n/**\n * Annotated so the `action` switch below is checked for exhaustiveness: a\n * member added to the enum without a case makes the function fall off its end,\n * which a declared non-undefined return type refuses.\n */\ntype FrameManageResult =\n | ReturnType<typeof mcpResult>\n | ReturnType<typeof mcpError>;\n\nasync function frameManageHandler(\n client: ToolClient,\n rawInput: unknown,\n): Promise<FrameManageResult> {\n // Parse, never assert: a raw ZodError stringifies its whole issue list into\n // `message`, so the issues are rewritten as one readable line.\n const parsed = frameInputSchema.safeParse(rawInput ?? {});\n if (!parsed.success) {\n return mcpError(new Error(inputIssuesMessage(parsed.error)));\n }\n const { action, projectId, pageKey, frameId } = parsed.data;\n const validationError = validateActionInput(\n 'frame_manage',\n action,\n { pageKey, frameId },\n FRAME_MANAGE_REQUIREMENTS,\n );\n if (validationError) return mcpError(new Error(validationError));\n\n try {\n const resolvedProjectId = resolveDefaultProject(client, projectId);\n if (!resolvedProjectId) {\n return mcpError(new Error(NO_DEFAULT_PROJECT_ERROR));\n }\n\n switch (action) {\n case 'list': {\n const { frames } = await client.listFrames({\n projectId: resolvedProjectId,\n });\n return mcpResult(\n { frames: frames.map(serializeLean) },\n {\n next:\n frames.length === 0\n ? [FRAME_HINT_NONE_YET]\n : [\n FRAME_HINT_OPEN_PAGE_OR_GET,\n FRAME_HINT_NAMES_ARE_DOCUMENTATION,\n ],\n },\n );\n }\n case 'page': {\n assertParam(pageKey, 'pageKey', 'page');\n const { frames } = await client.listPageFrames({\n projectId: resolvedProjectId,\n pageKey,\n });\n return mcpResult(\n { pageKey, frames: frames.map(serializeFrame) },\n {\n next:\n frames.length === 0\n ? [FRAME_HINT_NONE_ON_PAGE]\n : [FRAME_HINT_MARK_SPACE, FRAME_HINT_READ_KNOWLEDGE],\n },\n );\n }\n case 'get': {\n assertParam(frameId, 'frameId', 'get');\n const frame = await client.getFrame({\n projectId: resolvedProjectId,\n frameId,\n });\n return mcpResult(\n { frame: serializeFrame(frame) },\n {\n next:\n frame.extends !== null\n ? [FRAME_HINT_EXTENDS_BASE, FRAME_HINT_READ_KNOWLEDGE]\n : [FRAME_HINT_READ_KNOWLEDGE],\n },\n );\n }\n }\n } catch (error) {\n // `mcpError` lifts a `code` property off the error, so whatever the client\n // raises surfaces its code without a branch here.\n return mcpError(error, errorHint(error, 'frames', FRAME_NOT_FOUND_HINT));\n }\n}\n\n/**\n * The tool as data, so it can be driven without an MCP transport (tests, and\n * any in-process bridge).\n */\nexport function createFrameManageToolSpec(client: ToolClient): ToolSpec {\n return {\n name: 'frame_manage',\n title: TITLE,\n description: FRAME_MANAGE_DESCRIPTION,\n inputSchema: FRAME_MANAGE_INPUT_SCHEMA,\n annotations,\n handler: (input) => frameManageHandler(client, input),\n };\n}\n\nexport function registerFrameManageTool(server: McpServer, client: ToolClient) {\n const spec = createFrameManageToolSpec(client);\n server.registerTool(\n spec.name,\n {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n annotations: spec.annotations,\n },\n (args) => frameManageHandler(client, args),\n );\n}\n","import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { fetchPackageSchema } from '@walkeros/core';\nimport { fetchCatalog, getPackageBaseUrl } from '../catalog.js';\n\nexport function registerPackageSchemaResources(server: McpServer) {\n const template = new ResourceTemplate('walkeros://schema/{packageName}', {\n list: async () => {\n const { entries } = await fetchCatalog({ baseUrl: getPackageBaseUrl() });\n return {\n resources: entries.map((pkg) => ({\n uri: `walkeros://schema/${encodeURIComponent(pkg.name)}`,\n name: pkg.name,\n description: `Schema and examples for ${pkg.name}`,\n mimeType: 'application/json' as const,\n })),\n };\n },\n });\n\n server.registerResource(\n 'package-schema',\n template,\n {\n title: 'walkerOS Package Schema',\n description:\n 'JSON Schema and configuration examples for walkerOS packages',\n mimeType: 'application/json',\n },\n async (uri, { packageName }) => {\n const info = await fetchPackageSchema(\n decodeURIComponent(packageName as string),\n );\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'application/json' as const,\n text: JSON.stringify(info, null, 2),\n },\n ],\n };\n },\n );\n}\n","/**\n * Reference resources — pure schema and structural data only.\n *\n * Design principle: resources are loaded into context and should contain\n * only schemas, type definitions, and structural references. Behavioral\n * guidance, tutorials, and step-by-step instructions belong in prompts.\n * Vendor-specific examples belong in packages (fetched via package_get).\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { schemas } from '@walkeros/core/dev';\nimport { fetchCatalog, getPackageBaseUrl } from '../catalog.js';\nimport type { ToolClient } from '../tool-client.js';\n\nconst OPENAPI_URI = 'walkeros://reference/openapi';\n\n/** The live OpenAPI document as text, or why it is unavailable. */\nasync function openapiText(\n client: ToolClient,\n): Promise<{ text: string; mimeType: string }> {\n if (!client.openapiDocument) {\n return {\n text: 'openapi document unavailable: no openapi document on this client',\n mimeType: 'text/plain',\n };\n }\n try {\n const document = await client.openapiDocument();\n return {\n text: JSON.stringify(document, null, 2),\n mimeType: 'application/json',\n };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return {\n text: `openapi document unavailable: ${reason}`,\n mimeType: 'text/plain',\n };\n }\n}\n\nexport function registerReferenceResources(\n server: McpServer,\n client: ToolClient,\n) {\n // Flow Schema reference (generated from Zod)\n server.resource(\n 'flow-schema',\n 'walkeros://reference/flow-schema',\n {\n description:\n 'JSON Schema for Flow.Json — the complete flow configuration structure',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/flow-schema',\n text: JSON.stringify(schemas.configJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Event Model reference (generated from Zod)\n server.resource(\n 'event-model',\n 'walkeros://reference/event-model',\n {\n description:\n 'JSON Schema for walkerOS events: entity-action naming, data, context, globals, user, consent',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/event-model',\n text: JSON.stringify(schemas.eventJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Mapping reference (generated from Zod — composite of related schemas)\n server.resource(\n 'mapping',\n 'walkeros://reference/mapping',\n {\n description:\n 'JSON Schemas for walkerOS mapping: rules, valueConfig, rule, policy',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/mapping',\n text: JSON.stringify(\n {\n rules: schemas.rulesJsonSchema,\n valueConfig: schemas.valueConfigJsonSchema,\n rule: schemas.ruleJsonSchema,\n policy: schemas.policyJsonSchema,\n },\n null,\n 2,\n ),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Consent reference (generated from Zod)\n server.resource(\n 'consent',\n 'walkeros://reference/consent',\n {\n description:\n 'JSON Schema for walkerOS consent: destination-level and field-level consent gating',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/consent',\n text: JSON.stringify(schemas.consentJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Variables reference (hand-maintained — runtime interpolation patterns not captured in Zod schemas)\n server.resource(\n 'variables',\n 'walkeros://reference/variables',\n {\n description:\n 'walkerOS variable patterns: $var, $env, $contract, $code, $store, $secret substitution',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/variables',\n text: JSON.stringify(\n {\n separatorRule:\n '`.` for names and paths; `:` for literal values or raw-code payloads.',\n patterns: {\n '$var.name':\n 'Variable reference. Whole-string preserves native type (object, array, scalar). Inline interpolation requires a scalar. Reusable fragments (mapping templates, matcher lists, consent objects) live in the variables block and are referenced by name.',\n '$var.name.deep.path':\n 'Deep-path access into a structured variable. Walks nested keys/indices. Whole-string preserves type at the leaf; inline still requires a scalar leaf.',\n '$env.NAME':\n 'Environment variable, resolved at bundle/deploy time. $env.GA_ID reads process.env.GA_ID. Use for non-secret config (IDs, hostnames, regions), never for credentials.',\n '$env.NAME:default':\n 'Environment variable with fallback. $env.GA_ID:G-DEFAULT (the `:` is the literal default separator).',\n '$contract.name':\n 'Contract reference. Links to a named contract for validation.',\n '$contract.name.path':\n 'Nested contract access. $contract.ecommerce.product.',\n '$code:(expr)':\n 'Inline JavaScript. $code:(event) => event.data.price * 100 (the `:` carries the raw-code payload).',\n '$store.storeId':\n 'Store injection in env values. Wires runtime store access.',\n '$secret.NAME':\n 'Managed secret injection (created via the secret manager). The deploy pipeline detects $secret.NAME references and injects the secret value into the server runner’s environment at runtime. Use for credentials, tokens, and private keys. Server flows only; $env does NOT inject managed secrets.',\n },\n cascade: {\n priority: [\n '1. Step-level variables (highest)',\n '2. Flow-level variables',\n '3. Config-level variables (lowest)',\n ],\n example: {\n variables: {\n apiUrl: 'https://x.io',\n mapping: { id: 'data.id' },\n },\n flows: {\n production: {\n destinations: {\n api: {\n config: {\n url: '$var.apiUrl',\n idPath: '$var.mapping.id',\n },\n },\n },\n },\n },\n },\n },\n },\n null,\n 2,\n ),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Contract reference (generated from Zod)\n server.resource(\n 'contract',\n 'walkeros://reference/contract',\n {\n description:\n 'JSON Schema for walkerOS contracts: event schema validation with entity-action keying',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [\n {\n uri: 'walkeros://reference/contract',\n text: JSON.stringify(schemas.contractJsonSchema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }),\n );\n\n // Examples reference (loaded from @walkeros/cli at runtime)\n server.resource(\n 'examples',\n 'walkeros://reference/examples',\n {\n description:\n 'Complete, tested flow config (flow-complete.json): web, server and warehouse flows with mapping, consent, contracts, routes, state, stores and step examples. Its guide is examples/flow-complete.md in @walkeros/cli.',\n mimeType: 'application/json',\n },\n async () => {\n let example: string;\n try {\n const { readFileSync } = await import('fs');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n const examplePath =\n require.resolve('@walkeros/cli/examples/flow-complete.json');\n example = readFileSync(examplePath, 'utf-8');\n } catch {\n example = JSON.stringify({ error: 'Example not found' });\n }\n return {\n contents: [\n {\n uri: 'walkeros://reference/examples',\n text: example,\n mimeType: 'application/json',\n },\n ],\n };\n },\n );\n\n // The live OpenAPI 3.1 document of the app the client talks to, read on\n // each request, so it always describes the backend the tools reach.\n server.resource(\n 'openapi',\n OPENAPI_URI,\n {\n description:\n 'walkerOS cloud API: the live OpenAPI 3.1 document of the app this server talks to',\n mimeType: 'application/json',\n },\n async () => ({\n contents: [{ uri: OPENAPI_URI, ...(await openapiText(client)) }],\n }),\n );\n\n // Packages catalog resource\n server.resource(\n 'packages',\n 'walkeros://reference/packages',\n {\n description:\n 'Complete walkerOS package catalog — all sources, destinations, transformers, and stores',\n mimeType: 'application/json',\n },\n async () => {\n const { entries } = await fetchCatalog({ baseUrl: getPackageBaseUrl() });\n return {\n contents: [\n {\n uri: 'walkeros://reference/packages',\n text: JSON.stringify(entries, null, 2),\n mimeType: 'application/json',\n },\n ],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerAddStepPrompt(server: McpServer) {\n server.registerPrompt(\n 'add-step',\n {\n description:\n 'Add a source, destination, transformer, or store step to a flow configuration. ' +\n 'Guides through package selection, config scaffolding, and wiring.',\n argsSchema: {\n stepType: z\n .string()\n .optional()\n .describe(\n 'Type of step to add: source, destination, transformer, or store',\n ),\n flowPath: z\n .string()\n .optional()\n .describe('Path to the flow.json file to modify'),\n },\n },\n async ({ stepType, flowPath }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me add a ${stepType || 'new'} step to my flow${flowPath ? ` at ${flowPath}` : ''}.`,\n '',\n 'Follow these steps:',\n `1. ${stepType ? '' : 'Ask what type of step (source, destination, transformer, store). Then '}Use package_search to browse available packages for the selected type and platform.`,\n '2. Use package_get to read the package\\'s config schema (schemas.config contains the full config shape: base fields like consent/require/logger + package-specific settings). Use section=\"hints\" for additional guidance.',\n '3. Use package_get with section=\"examples\" to see working configuration examples.',\n '4. Scaffold the step config using the package schemas — include required settings with placeholder values.',\n '5. Wire the step into the flow: add to packages section (with version if needed), connect via next/before chains if needed.',\n '6. For destinations: configure mapping using nested entity → action keys. Event \"product add\" maps to `{ \"product\": { \"add\": { name: \"AddToCart\" } } }`. Use the setup-mapping prompt for guidance.',\n '7. For destinations: if consent-gated loading is needed, add require: [\"consent\"] to config. ' +\n 'Note: require delays initialization until a \"walker consent\" event fires. ' +\n 'When simulating with flow_simulate, destinations with require will error \"not found\" — ' +\n 'remove require temporarily or test without it. ' +\n 'For per-event consent filtering, add consent: { marketing: true } to config.',\n '8. Use flow_validate to verify the result.',\n '9. For server sources: check if the package supports `ingest` configuration via package_get. Ingest extracts request metadata (IP, user-agent, headers) using mapping syntax. Transformers like fingerprint depend on ingest data.',\n '10. When adding a transformer that uses ingest fields, verify the source has `ingest` configured — otherwise ingest fields resolve to empty values.',\n '',\n 'Important:',\n '- Read the walkeros://reference/flow-schema resource to understand connection rules.',\n '- Sources connect to transformers via `next` (runs before the collector).',\n '- The collector connects to transformers via `collector.next` (runs once per event before the destination fan-out, for every destination).',\n '- Destinations connect to transformers via `before` (runs for that destination only; put per-destination filtering here).',\n '- Routing uses one grammar in every chain field: string IDs, sequences (`[\"a\", \"b\"]`, where a member\\'s own `next` runs right after it), or RouteConfig (`{ match?, next }` for a gated link, `{ match?, one: [...] }` for first-match dispatch, `{ match?, many: [...] }` to fork each match into its own copy that finishes the rest of the path, `{ match?, stop: true }` to drop). A `stop` in `collector.next` drops the event for all destinations. Omit `match` for always-match.',\n '- A transformer entry can be code-bearing (`code`), package-bearing (`package`), or a **pass-through step** (no `code`, no `package`). Pass-through synthesis is automatic at runtime. Three flavors of pass-through: `before`/`next`-only (named hop reusable across destinations), `cache`-only (dedup, rate-limit), or `mapping`-only (declarative event-to-event transform). A pass-through must declare at least one of `before`, `next`, `cache`, or `mapping`.',\n '- The `mapping` field on a transformer step uses the same `Mapping.Config` shape as destinations, but the semantic is event-to-event (mutates the event in place via `policy`, per-rule `policy`, `mapping[].name` for renames, `mapping[].ignore` to drop). Vendor-payload fields (`data`, `silent`) are no-ops at this position.',\n '- Closed schema: unknown top-level keys on a transformer step are errors (catches typos like `dedup` instead of `cache`). `code` + `package` together is a conflict.',\n '- Stores are passive — referenced via `$store.storeName` in env values.',\n '- Use variables ($var) for values that change between environments.',\n '- For required settings without defaults in the package schema, ask the user which value to use. Do not guess credentials, IDs, or environment-specific values.',\n '- If $meta.exports lists named exports, set the `code` field on the step to the chosen export name. If only one export exists, use it automatically.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerSetupMappingPrompt(server: McpServer) {\n server.registerPrompt(\n 'setup-mapping',\n {\n description:\n 'Set up event mapping for any step in a flow. Teaches mapping syntax and uses package examples as templates.',\n argsSchema: {\n stepName: z\n .string()\n .optional()\n .describe('Step name in the flow (e.g., \"gtag\", \"meta\", \"express\")'),\n },\n },\n async ({ stepName }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me set up mapping${stepName ? ` for the \"${stepName}\" step` : ''}.`,\n '',\n 'Follow these steps:',\n '1. Read the walkeros://reference/mapping resource for syntax reference.',\n `2. ${stepName ? `Identify the package for \"${stepName}\" in the flow, then u` : 'U'}se package_get with section=\"examples\" to see the source output shape — mapping keys must match the actual events the source emits.`,\n '3. Ask whether this is source mapping (raw input → walkerOS events) or destination mapping (walkerOS events → vendor format).',\n '4. Ask which events to map (one at a time, not all at once).',\n '5. Generate one mapping rule using the package examples as templates. Validate it with flow_validate before moving to the next.',\n '6. Repeat for each event.',\n '',\n 'Mapping uses nested entity → action keys. Event \"product add\" maps to `{ \"product\": { \"add\": Rule } }`. Wildcards: `{ \"*\": { \"view\": Rule } }`.',\n '',\n 'Extract shared mapping shapes into variables, reference via $var.name (deep paths supported).',\n '',\n 'Policy and consent in mapping:',\n '- config.policy runs BEFORE mapping rules — use it to inject or redact fields on the event.',\n '- rule.policy runs after config.policy but before data transformation — use for event-specific pre-processing.',\n '- config.consent gates ALL events to this destination. rule.consent is not enforced yet.',\n '- Individual value configs support consent: { marketing: true } for field-level gating.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport function registerManageContractPrompt(server: McpServer) {\n server.registerPrompt(\n 'manage-contract',\n {\n description:\n 'Create or update event contracts for a flow. Can generate contracts from existing mappings or scaffold mappings from contracts.',\n argsSchema: {\n direction: z\n .string()\n .optional()\n .describe(\n 'Direction: \"from-mappings\" (extract contract from existing mappings), ' +\n '\"from-scratch\" (create new contract), or \"to-mappings\" (scaffold mappings from contract)',\n ),\n },\n },\n async ({ direction }) => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: [\n `Help me ${direction === 'to-mappings' ? 'scaffold mappings from a contract' : direction === 'from-mappings' ? 'generate a contract from existing mappings' : 'manage event contracts'}.`,\n '',\n 'Follow these steps:',\n '1. Read the walkeros://reference/contract resource to understand contract structure.',\n direction === 'from-mappings'\n ? '2. Read all destination mappings in the flow, extract referenced event fields, and generate a contract with those as required properties.'\n : direction === 'to-mappings'\n ? '2. Read the contract from the flow, then scaffold mapping stubs for each destination based on the contract fields.'\n : '2. Ask for entity-action names and required properties, or ask whether to generate from existing mappings.',\n '3. Use entity-action keying with wildcards (*.*, *.action, entity.*) for broad rules.',\n '4. Define JSON Schema for events, globals, context, custom, user, and consent.',\n '5. Use flow_validate to verify the contract.',\n '',\n 'Contracts and mappings are bidirectional:',\n '- **Contract → Mappings**: contract defines what events look like, mappings are scaffolded to match.',\n '- **Mappings → Contract**: existing mappings reveal which fields are used, contract formalizes them.',\n '',\n 'For server flows: if the contract references fields populated by ingest (e.g., user fingerprint hash), verify the source config.ingest extracts the needed request metadata.',\n '',\n 'Use $contract.name references to link contracts in the flow.',\n 'Contracts support extends for inheritance between event types.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n}\n","export const SERVER_INSTRUCTIONS = `walkerOS is an open-source, privacy-first event data collection platform. Define event pipelines as code using JSON flow configurations.\n\n## Rules\n\n- **Never guess package names.** Always use \\`package_search\\` first to find exact names, then \\`package_get\\` for details.\n- **Never construct flow configs from memory.** Read \\`walkeros://reference/flow-schema\\` and use \\`package_get\\` for package-specific schemas.\n- **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).\n- **Simulate before deploying.** Use \\`flow_simulate\\` to test with mocked API calls before \\`flow_bundle\\` or \\`flow_push\\`.\n- **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.\n\n## Workflow\n\n1. \\`auth({ action: \"status\" })\\` — check if logged in, or \\`auth({ action: \"login\" })\\` to connect\n2. \\`project_manage({ action: \"list\" })\\` — see your projects\n3. \\`flow_manage({ action: \"list\" })\\` — see all flows across projects\n4. \\`flow_load({ platform: \"web\" })\\` or \\`flow_load({ source: \"./flow.json\" })\\` — create or load\n5. \\`package_search({ type: \"destination\", platform: \"web\" })\\` — discover packages\n6. \\`package_get({ package: \"...\" })\\` — read schemas, hints, examples\n7. Use the \\`add-step\\` prompt — guided step addition\n8. Use the \\`setup-mapping\\` prompt — event transformation config\n9. \\`flow_validate({ type: \"flow\", input: \"flow.json\" })\\` — verify\n10. \\`flow_simulate({ configPath: \"flow.json\", event: \"...\" })\\` — test\n11. \\`flow_manage({ action: \"update\", flowId: \"...\", content: {...} })\\` — save to cloud\n12. \\`deploy_manage({ action: \"deploy\", flowId: \"...\" })\\` — deploy\n13. \\`observe_session({ action: \"start\", flowId: \"...\" })\\` - open an Observe session: a time-boxed window on one flow that runtimes attach to as arms\n14. \\`flow_manage({ action: \"preview_regrant\", flowId: \"...\", previewId: \"...\", origins: [...] })\\` - mint an activation link; minted while the flow is observed, it pairs with that Observe session automatically, so the previewed page streams into the same feed\n15. \\`observe_journeys({ flowId: \"...\" })\\` - read what arrived; it is the only read, and it never judges whether events are correct\n16. \\`hub_manage({ action: \"releases\", flowId: \"...\" })\\` - read what changed across releases and why; \\`release_get\\` carries a server-computed diff, \\`rationale_set\\` records why\n17. \\`frame_manage({ action: \"page\", pageKey: \"...\" })\\` - read the frames of a page with their marks; read-only, edited in Tag Mode or the app\n\n## Architecture: Source → Collector → Destination(s)\n\nEvery component in a flow is a **step**: sources capture events, transformers process them, destinations deliver them, stores provide shared state. Steps connect via chains: \\`source.next\\` runs before the collector, \\`collector.next\\` runs once per event before the destination fan-out (all destinations), and \\`destination.before\\` runs for one destination.\n\n## Flow Config Structure\n\n\\`\\`\\`json\n{\n \"version\": 4,\n \"flows\": {\n \"default\": {\n \"config\": { \"platform\": \"web\" },\n \"sources\": { \"<name>\": { \"package\": \"<npm-package>\", \"config\": {} } },\n \"destinations\": { \"<name>\": { \"package\": \"<npm-package>\", \"config\": { \"settings\": {} } } }\n }\n }\n}\n\\`\\`\\`\n\n- \\`version: 4\\` is required\n- Each flow declares its target via \\`config.platform\\` (\\`\"web\"\\` or \\`\"server\"\\`)\n- Destination settings go inside \\`config.settings\\`, not directly on the destination\n- Event format: \\`{ name: \"entity action\", data: {...}, entity: \"...\", action: \"...\" }\\`\n\n## Key Concepts\n\n- **Mapping** transforms events using data/map/loop/set/condition rules. Same syntax on sources and destinations. Mapping rules use NESTED entity → action keying: event name \"product add\" maps to \\`{ \"product\": { \"add\": Rule } }\\`. Wildcards: \\`{ \"*\": { \"view\": Rule } }\\`.\n- **Contracts** define event schemas using entity-action keying. Can generate FROM mappings or scaffold mappings FROM contracts.\n- **Variables** (\\$var, \\$env, \\$secret, \\$code, \\$store) enable DRY, environment-aware config. \\`$var.name\\` is a reusable flow variable from the top-level \\`variables\\` block; whole-string refs preserve native type (object/array/scalar), inline interpolation requires a scalar, deep paths via \\`$var.name.deep.path\\`. \\`$env.NAME[:default]\\` is an environment variable resolved at bundle/deploy time (non-secret config only). \\`$secret.NAME\\` is a managed secret the deploy pipeline injects into the server runner at runtime; credentials, tokens, and private keys must use \\`$secret\\`, not \\`$env\\`.\n- **Consent** gates destinations (\\`config.consent\\`) and individual fields (a value's \\`consent\\`). A mapping rule's \\`consent\\` is not enforced yet. Privacy-first by design.\n- **Routing** uses one grammar in every chain field (\\`source.before\\`, \\`source.next\\`, \\`transformer.before\\`, \\`transformer.next\\`, \\`collector.next\\`, \\`destination.before\\`, \\`destination.next\\`). A route is a string ID, a sequence (\\`[\"a\", \"b\"]\\`), or a RouteConfig: \\`{ match?, next }\\`, \\`{ match?, one: [...] }\\` (first match wins), \\`{ match?, many: [...] }\\` (every match becomes its own copy of the event with its own id and finishes the rest of the path on its own, never merged), or \\`{ match?, stop: true }\\` (ends that copy). In a sequence, a member's own \\`next\\` runs right after it, then the sequence continues. \\`match\\` reads \\`{ ingest, event }\\` and each route is evaluated when the event reaches it. A \\`stop\\` in \\`collector.next\\` drops the event for every destination; per-destination filtering belongs in \\`destination.before\\`. An array of only route configs is an implicit \\`one\\`. The optional \\`match\\` field is omitted to mean always-match (no wildcard literal).\n- **Pass-through steps** are transformer entries with no \\`code\\` and no \\`package\\`. The runtime synthesizes the push for them automatically. Three flavors share this shape: a \\`before\\` / \\`next\\`-only step (named hop reusable across destinations), a \\`cache\\`-only step (dedup, rate-limit), and a \\`mapping\\`-only step (declarative event-to-event transform). A pass-through must declare at least one of \\`before\\`, \\`next\\`, \\`cache\\`, or \\`mapping\\`.\n- **Mapping at the transformer position** uses the same \\`Mapping.Config\\` shape as destinations, but the semantic is event-to-event: only config-level \\`policy\\` and a rule's \\`condition\\`, \\`policy\\`, \\`name\\` (rename) and \\`ignore\\` (drop from chain) apply. Everything that shapes a vendor payload or gates a destination is a no-op there: config-level \\`consent\\`, \\`include\\`, \\`data\\`, and a rule's \\`consent\\`, \\`include\\`, \\`remove\\`, \\`batch\\`, \\`settings\\`, \\`extend\\`, \\`data\\`, \\`silent\\`; validation warns about them (\\`TRANSFORMER_MAPPING_NO_OP\\`). A \\`config.mapping\\` wins over a step-level \\`mapping\\`.\n- **Closed-schema rule on transformer entries:** known keys only. Operative keys are \\`code\\`, \\`package\\`, \\`before\\`, \\`next\\`, \\`cache\\`, \\`mapping\\`. Combined with structural keys (\\`config\\`, \\`env\\`, \\`validate\\`, \\`disabled\\`, \\`id\\`, etc.). Unknown top-level keys on a transformer step are errors (catches typos like \\`dedup: {}\\` instead of nested under \\`cache\\`). \\`code\\` + \\`package\\` together is a conflict.\n- **Cache** memoizes step output on a configured store. Set \\`cache.stop: true\\` to short-circuit the chain on HIT (sources default to stop-on-HIT); in a source chain or \\`collector.next\\` that halts the event for all destinations. Set \\`cache.namespace\\` to prefix keys; omit it to write keys directly. \\`CacheRule.match\\` is optional, omit for always-match.\n\n## Simulation Tips\n\n- Destinations with \\`require: [\"consent\"]\\` stay **pending** until a \\`\"walker consent\"\\` event fires. Simulation will error \"not found\" for pending destinations, remove \\`require\\` from config when testing with \\`flow_simulate\\`.\n- Destinations with \\`consent: { marketing: true }\\` silently skip events that lack matching consent. Include \\`consent\\` in the event: \\`{ name: \"page view\", data: {...}, consent: { marketing: true } }\\`.\n- **Mapping** transforms event names and data at the destination level. Events without a matching mapping rule pass through unmodified.\n- **Policy** modifies the event before mapping runs, use it to inject computed fields or redact sensitive data.\n\n## Reference Resources\n\nRead these before constructing configs manually: \\`walkeros://reference/flow-schema\\`, \\`walkeros://reference/mapping\\`, \\`walkeros://reference/event-model\\`, \\`walkeros://reference/consent\\`, \\`walkeros://reference/variables\\`, \\`walkeros://reference/contract\\`, \\`walkeros://reference/examples\\`.`;\n","import { randomUUID } from 'crypto';\nimport { telemetry } from '@walkeros/cli';\n\n/**\n * Options for the MCP telemetry emitter wrapper.\n *\n * `clientInfo` mirrors the MCP SDK shape negotiated during initialize.\n * When the client doesn't send one, we record the client name as \"unknown\"\n * inside the per-event data so downstream analytics can still bucket the\n * event. The walkerOS source identifier is the package itself (`mcp`), not\n * the client.\n */\nexport interface McpEmitterOptions {\n clientInfo?: { name: string; version: string };\n packageVersion: string;\n}\n\n/**\n * MCP-specific event emitter.\n *\n * Wraps `@walkeros/cli`'s `telemetry.createEmitter` with:\n * - `source.type` fixed to `\"mcp\"`\n * - `source.platform` fixed to `\"server\"`\n * - per-emission `source.tool` for `cmd invoke` events\n * - a fresh session UUID per MCP server instance\n *\n * Surfaces the narrow set of events the MCP server needs to emit.\n */\nexport interface McpEmitter {\n emitStart(): Promise<void>;\n emitInvoke(\n tool: string,\n outcome: 'success' | 'error',\n timingMs: number,\n ): Promise<void>;\n emitError(kind: 'uncaught' | 'unhandledRejection' | 'startup'): Promise<void>;\n}\n\n/**\n * Build an MCP telemetry emitter.\n *\n * All consent, debug, and endpoint resolution is delegated to the CLI's\n * underlying `telemetry.createEmitter`. This wrapper only provides\n * MCP-specific field mapping and event shorthands.\n */\nexport async function createMcpEmitter(\n opts: McpEmitterOptions,\n): Promise<McpEmitter> {\n const clientName = opts.clientInfo?.name || 'unknown';\n const session = randomUUID();\n\n const emitter = await telemetry.createEmitter({\n source: {\n type: 'mcp',\n platform: 'server',\n },\n packageVersion: opts.packageVersion,\n session,\n });\n\n return {\n async emitStart() {\n const ci = telemetry.getCiInfo();\n await emitter.send('mcp start', {\n ...ci,\n client: clientName,\n });\n },\n async emitInvoke(tool, outcome, timingMs) {\n await emitter.send(\n 'cmd invoke',\n { outcome, client: clientName },\n timingMs,\n { tool },\n );\n },\n async emitError(kind) {\n await emitter.send('error throw', { kind });\n },\n };\n}\n","import type { ToolClient } from '../tool-client.js';\nimport { flowConfigOf, isCloudId } from '../cloud-flow.js';\nimport { RuntimeRefusal, type FlowRuntime } from './types.js';\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Whether a bare string is shaped like a filesystem path: it names a directory\n * hop, starts with a dot, or carries a file extension. Nothing is ever read\n * either way; the distinction only decides which error a hosted load raises.\n * A path-shaped input is refused outright, while a plain phrase such as an\n * event name is merely unresolvable here, which is what lets `flow_validate`\n * keep its event-name shorthand.\n */\nfunction looksLikePath(value: string): boolean {\n return (\n /[\\\\/]/.test(value) ||\n value.startsWith('.') ||\n /\\.[A-Za-z0-9]+$/.test(value)\n );\n}\n\nexport type ConfigInputKind =\n | 'inline-json'\n | 'cloud-id'\n | 'url'\n | 'local-path'\n | 'bare-string';\n\n/**\n * Classify a config input the way the local loader would resolve it: an\n * http(s) URL, a reserved cloud id, an inline JSON document, a path-shaped\n * string, or a bare string that names none of these. Order matters, a URL is\n * checked before the cloud-id and JSON shapes.\n */\nexport function classifyConfigInput(input: string): ConfigInputKind {\n const trimmed = input.trim();\n if (isHttpUrl(trimmed)) return 'url';\n if (isCloudId(trimmed)) return 'cloud-id';\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) return 'inline-json';\n if (looksLikePath(trimmed)) return 'local-path';\n return 'bare-string';\n}\n\nconst HINT_INLINE_OR_ID =\n 'Pass the flow inline as JSON, or reference a saved flow by its flow_ or cfg_ id.';\n\nfunction refuseLocalPath(): RuntimeRefusal {\n return new RuntimeRefusal(\n 'Local file paths are not available on the hosted walkerOS MCP server.',\n HINT_INLINE_OR_ID,\n );\n}\n\nfunction refuseUrl(): RuntimeRefusal {\n return new RuntimeRefusal(\n 'Fetching URLs is not available on the hosted walkerOS MCP server.',\n HINT_INLINE_OR_ID,\n );\n}\n\nfunction parseInline(trimmed: string): unknown {\n try {\n return JSON.parse(trimmed);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Input appears to be JSON but contains errors: ${message}`);\n }\n}\n\n/**\n * The least-privilege runtime for a shared, network-reached process: the app's\n * OAuth door, in-app chat, and any third-party HTTP host.\n *\n * It never touches the filesystem or the network on the caller's behalf. A\n * saved `flow_`/`cfg_` id is resolved through the access-scoped tool client, a\n * document is parsed inline, and everything else is refused. `bundle`,\n * `simulate` and `push` are deliberately absent: compiling or importing a\n * caller's flow pulls that caller's code (inline or by package name) into this\n * process, and no input shape makes that safe here.\n */\nexport function createHostedRuntime(\n client: Pick<ToolClient, 'getFlow'>,\n): FlowRuntime {\n return {\n async load(input) {\n const trimmed = input.trim();\n if (trimmed === '') throw new Error('Input is required');\n switch (classifyConfigInput(trimmed)) {\n case 'url':\n throw refuseUrl();\n case 'cloud-id':\n return flowConfigOf(await client.getFlow({ flowId: trimmed }));\n case 'inline-json':\n return parseInline(trimmed);\n case 'local-path':\n throw refuseLocalPath();\n case 'bare-string':\n // Not a refusal: nothing was withheld, the input simply names nothing\n // this runtime can resolve.\n throw new Error(\n `Cannot resolve \"${trimmed}\" on the hosted walkerOS MCP server. ${HINT_INLINE_OR_ID}`,\n );\n }\n },\n };\n}\n","import {\n listProjects,\n getProject,\n createProject,\n updateProject,\n deleteProject,\n setDefaultProject,\n resolveProjectId,\n listAllFlows,\n listFlows,\n getFlow,\n createFlow,\n updateFlow,\n deleteFlow,\n duplicateFlow,\n listPreviews,\n getPreview,\n createPreview,\n deletePreview,\n regrantPreview,\n listSecrets,\n createSecret,\n updateSecret,\n deleteSecret,\n deploy,\n listDeployments,\n getDeploymentBySlug,\n deleteDeployment,\n listJourneys,\n startObserveSession,\n getObserveSession,\n endObserveSession,\n listReleases,\n getRelease,\n listStepHistory,\n setReleaseRationale,\n listThreads,\n createThread,\n addThreadMessage,\n listKnowledge,\n listFrames,\n listPageFrames,\n getFrame,\n startDeviceAuthorization,\n completeDeviceLogin,\n whoami,\n credentialSource,\n resolveAppUrl,\n logout,\n feedback,\n getFeedbackPreference,\n setFeedbackPreference,\n fetchHealth,\n fetchOpenApi,\n compareContract,\n} from '@walkeros/cli';\nimport type {\n ContractComparison,\n DeviceAuthorization,\n DeviceLoginResult,\n ListFlowsOptions,\n DeployOptions,\n ListDeploymentsOptions,\n ListPreviewsOptions,\n GetPreviewOptions,\n CreatePreviewOptions,\n DeletePreviewOptions,\n ListSecretsOptions,\n CreateSecretOptions,\n UpdateSecretOptions,\n DeleteSecretOptions,\n FeedbackOptions,\n} from '@walkeros/cli';\n\nimport { normalizeBaseUrl } from './base-url.js';\nimport type {\n ToolClient,\n JourneysResult,\n RegrantPreviewOptions,\n ObserveSessionResult,\n ObserveSessionRef,\n StartObserveSessionOptions,\n ReleaseRef,\n ReleaseIndexWire,\n ReleaseDetailWire,\n StepHistoryWire,\n VersionAnnotationWire,\n ThreadAnchorType,\n ThreadStatus,\n HubThreadWire,\n ListThreadsWire,\n ListKnowledgeWire,\n FrameWire,\n FrameListWire,\n FrameLeanListWire,\n} from './tool-client.js';\n\n// __VERSION__ is this package's version, replaced at build time by tsup's\n// `define` (see tsup.config.ts). In tests, it is set on globalThis (see\n// src/__tests__/support/version.ts).\ndeclare const __VERSION__: string;\n\n/**\n * Default ToolClient implementation backed by @walkeros/cli. Every method\n * delegates to the CLI's programmatic API, which in turn talks to the\n * walkerOS app over HTTPS via openapi-fetch. Token resolution and the\n * base URL come from the CLI's config file and environment\n * (WALKEROS_TOKEN, WALKEROS_APP_URL), so no constructor args are required.\n */\nexport class HttpToolClient implements ToolClient {\n async listProjects(options?: {\n cursor?: string;\n limit?: number;\n }): Promise<unknown> {\n return listProjects(options);\n }\n async getProject(options: { projectId?: string }): Promise<unknown> {\n return getProject(options);\n }\n async createProject(options: { name: string }): Promise<unknown> {\n return createProject(options);\n }\n async updateProject(options: {\n projectId?: string;\n name: string;\n }): Promise<unknown> {\n return updateProject(options);\n }\n async deleteProject(options: { projectId?: string }): Promise<unknown> {\n return deleteProject(options);\n }\n /** Refuses while `WALKEROS_PROJECT_ID` names another project (see the CLI). */\n setDefaultProject(projectId: string): void {\n setDefaultProject(projectId);\n }\n /**\n * `WALKEROS_PROJECT_ID`, then the CLI config's default, through the same\n * resolution the CLI's own commands use. Read here, at the door that owns\n * this process's environment, never in the shared tool layer: a hosted door\n * runs in a server process whose variables are no person's selection.\n */\n getDefaultProject(): string | null {\n return resolveProjectId();\n }\n\n async listAllFlows(options?: {\n sort?: string;\n order?: 'asc' | 'desc';\n includeDeleted?: boolean;\n cursor?: string;\n limit?: number;\n }): Promise<unknown> {\n return listAllFlows(options as Parameters<typeof listAllFlows>[0]);\n }\n async listFlows(options: ListFlowsOptions): Promise<unknown> {\n return listFlows(options);\n }\n async getFlow(options: {\n flowId: string;\n projectId?: string;\n fields?: string[];\n }): Promise<unknown> {\n return getFlow(options);\n }\n async createFlow(options: {\n name: string;\n content: Record<string, unknown>;\n projectId?: string;\n }): Promise<unknown> {\n return createFlow(options);\n }\n async updateFlow(options: {\n flowId: string;\n projectId?: string;\n name?: string;\n content?: Record<string, unknown>;\n mergePatch?: boolean;\n }): Promise<unknown> {\n return updateFlow(options);\n }\n async deleteFlow(options: {\n flowId: string;\n projectId?: string;\n }): Promise<unknown> {\n return deleteFlow(options);\n }\n async duplicateFlow(options: {\n flowId: string;\n name?: string;\n projectId?: string;\n }): Promise<unknown> {\n return duplicateFlow(options);\n }\n\n async listPreviews(options: ListPreviewsOptions): Promise<unknown> {\n return listPreviews(options);\n }\n async getPreview(options: GetPreviewOptions): Promise<unknown> {\n return getPreview(options);\n }\n async createPreview(\n options: CreatePreviewOptions & { siteUrl?: string },\n ): Promise<unknown> {\n // flow-manage passes `siteUrl` (the shared handler's field); the CLI's\n // createPreview mints an origin-bound grant when given `url`. Bridge the two\n // so a preview_create with a site URL over the HTTP client mints a real\n // grant instead of returning a null activationUrl.\n return createPreview({ ...options, url: options.url ?? options.siteUrl });\n }\n async deletePreview(options: DeletePreviewOptions): Promise<unknown> {\n return deletePreview(options);\n }\n async regrantPreview(options: RegrantPreviewOptions): Promise<unknown> {\n return regrantPreview(options);\n }\n\n async listSecrets(options: ListSecretsOptions): Promise<unknown> {\n return listSecrets(options);\n }\n async createSecret(options: CreateSecretOptions): Promise<unknown> {\n return createSecret(options);\n }\n async updateSecret(options: UpdateSecretOptions): Promise<unknown> {\n return updateSecret(options);\n }\n async deleteSecret(options: DeleteSecretOptions): Promise<unknown> {\n return deleteSecret(options);\n }\n\n async deploy(options: DeployOptions): Promise<unknown> {\n return deploy(options);\n }\n async listDeployments(options: ListDeploymentsOptions): Promise<unknown> {\n return listDeployments(options);\n }\n async getDeploymentBySlug(options: {\n slug: string;\n projectId?: string;\n }): Promise<unknown> {\n return getDeploymentBySlug(options);\n }\n async deleteDeployment(options: {\n slug: string;\n projectId?: string;\n }): Promise<unknown> {\n return deleteDeployment(options);\n }\n\n async listJourneys(options: {\n flowId: string;\n projectId?: string;\n traceId?: string;\n limit?: number;\n }): Promise<JourneysResult> {\n return listJourneys(options);\n }\n\n /**\n * Observe session lifecycle over the CLI's authenticated boundary. The trio\n * routes through the same `apiFetch` as every other method here, so token\n * resolution, base URL, and `ApiError` shaping (which\n * `isAuthenticationError` reads) stay identical to the rest of the client.\n */\n async startObserveSession(\n options: StartObserveSessionOptions,\n ): Promise<ObserveSessionResult> {\n return startObserveSession(options);\n }\n async getObserveSession(\n options: ObserveSessionRef,\n ): Promise<ObserveSessionResult> {\n return getObserveSession(options);\n }\n async endObserveSession(options: ObserveSessionRef): Promise<void> {\n return endObserveSession(options);\n }\n\n async listReleases(options: {\n projectId: string;\n flowId: string;\n limit?: number;\n offset?: number;\n }): Promise<ReleaseIndexWire> {\n return listReleases(options);\n }\n async getRelease(options: {\n projectId: string;\n flowId: string;\n ref: ReleaseRef;\n }): Promise<ReleaseDetailWire> {\n return getRelease(options);\n }\n async listStepHistory(options: {\n projectId: string;\n flowId: string;\n step: string;\n flow?: string;\n limit?: number;\n }): Promise<StepHistoryWire> {\n return listStepHistory(options);\n }\n async setReleaseRationale(options: {\n projectId: string;\n flowId: string;\n versionId: string;\n text: string;\n }): Promise<VersionAnnotationWire> {\n return setReleaseRationale(options);\n }\n async listThreads(options: {\n projectId: string;\n flowId: string;\n anchorType?: ThreadAnchorType;\n anchorKey?: string;\n status?: ThreadStatus;\n includeMessages: boolean;\n limit?: number;\n }): Promise<ListThreadsWire> {\n return listThreads(options);\n }\n async createThread(options: {\n projectId: string;\n flowId: string;\n anchorType: ThreadAnchorType;\n anchorKey: string;\n anchorLabel?: string;\n text: string;\n }): Promise<HubThreadWire> {\n return createThread(options);\n }\n async addThreadMessage(options: {\n projectId: string;\n flowId: string;\n threadId: string;\n text: string;\n }): Promise<HubThreadWire> {\n return addThreadMessage(options);\n }\n async listKnowledge(options: {\n projectId: string;\n pageKey?: string;\n frameId?: string;\n markId?: string;\n includeMessages: boolean;\n limit?: number;\n }): Promise<ListKnowledgeWire> {\n return listKnowledge(options);\n }\n\n async listFrames(options: { projectId: string }): Promise<FrameLeanListWire> {\n return listFrames(options);\n }\n async listPageFrames(options: {\n projectId: string;\n pageKey: string;\n }): Promise<FrameListWire> {\n return listPageFrames(options);\n }\n async getFrame(options: {\n projectId: string;\n frameId: string;\n }): Promise<FrameWire> {\n return getFrame(options);\n }\n\n async requestDeviceCode(): Promise<DeviceAuthorization> {\n return startDeviceAuthorization(resolveAppUrl());\n }\n async pollForToken(\n deviceCode: string,\n options?: { timeoutMs?: number },\n ): Promise<DeviceLoginResult> {\n return completeDeviceLogin(deviceCode, options);\n }\n async whoami(): Promise<unknown> {\n return whoami();\n }\n credentialSource(): 'env' | 'config' | null {\n return credentialSource();\n }\n /**\n * Revoke and drop the stored session, then clear a `WALKEROS_TOKEN` from\n * this process: the local door owns its environment, so a later call in the\n * same session no longer authenticates with it.\n */\n async logout(): Promise<{\n deleted: boolean;\n superseded: boolean;\n envCleared: boolean;\n }> {\n const result = await logout();\n const envCleared = Boolean(process.env.WALKEROS_TOKEN);\n delete process.env.WALKEROS_TOKEN;\n return { ...result, envCleared };\n }\n\n /**\n * The app this local door talks to: `WALKEROS_APP_URL`, then the CLI config\n * file, then the built-in default, which is exactly the chain every other\n * method here already resolves its base URL through. Normalized, because\n * neither the env var nor the config file is obliged to omit a trailing\n * slash and the interface promises a base without one.\n */\n appBaseUrl(): string {\n return normalizeBaseUrl(resolveAppUrl());\n }\n\n /**\n * Unauthenticated reachability probe of the app's PUBLIC health route\n * (`GET /api/health`) at `appBaseUrl()`, through the CLI's `fetchHealth`.\n * Sends no credential, so diagnostics works logged-out. Resolves\n * `{ reachable: false, error }` only on a real network/timeout failure.\n */\n async checkHealth(): Promise<{\n reachable: boolean;\n status?: string;\n version?: string;\n error?: string;\n }> {\n const health = await fetchHealth(this.appBaseUrl());\n return {\n reachable: health.reachable,\n ...(health.status !== undefined && { status: health.status }),\n ...(health.appVersion !== undefined && { version: health.appVersion }),\n ...(health.error !== undefined && { error: health.error }),\n };\n }\n\n /**\n * The contract verdict for this MCP against `appBaseUrl()`, per operation,\n * naming `@walkeros/mcp` as the client.\n */\n async checkContract(): Promise<ContractComparison> {\n return compareContract({\n baseUrl: this.appBaseUrl(),\n client: { type: 'mcp', version: __VERSION__ },\n });\n }\n\n /** The live public OpenAPI document of `appBaseUrl()`, without a credential. */\n async openapiDocument(): Promise<unknown> {\n const result = await fetchOpenApi(this.appBaseUrl());\n if (!result.ok) throw new Error(`GET ${result.url}: ${result.error}`);\n return result.document;\n }\n\n async submitFeedback(text: string, options?: FeedbackOptions): Promise<void> {\n await feedback(text, options);\n }\n getFeedbackPreference(): boolean | undefined {\n return getFeedbackPreference();\n }\n setFeedbackPreference(anonymous: boolean): void {\n setFeedbackPreference(anonymous);\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n collectKnownSecrets,\n loadConfig,\n loadJsonConfig,\n bundle,\n push,\n simulateSource,\n simulateTransformer,\n simulateCollector,\n simulateDestination,\n} from '@walkeros/cli';\nimport { isObject } from '@walkeros/core';\nimport { isFlowJson } from '../tools/narrow.js';\nimport type { Flow, WalkerOS } from '@walkeros/core';\nimport { schemas } from '@walkeros/core/dev';\nimport { getOrBuildBundle } from './bundle-cache.js';\nimport type { FlowRuntime } from './types.js';\n\n/**\n * The full-capability runtime for the user's own machine (stdio, the developer\n * CLI). It wraps the `@walkeros/cli` loaders and runners exactly as the tools\n * called them before the runtime seam existed, so local behaviour is unchanged:\n * a config may be a file path, an http(s) URL or inline JSON, and bundling,\n * simulation and push run in this process.\n *\n * This is the only module in the package that may bind those cli functions;\n * the tools reach them through the `FlowRuntime` interface and nothing else.\n */\nexport function createLocalRuntime(): FlowRuntime {\n return {\n load: (input) => loadJsonConfig(input),\n\n baseDir(input) {\n const file = path.resolve(input);\n return fs.existsSync(file) && fs.statSync(file).isFile()\n ? path.dirname(file)\n : undefined;\n },\n\n bundle: (input, opts) =>\n bundle(input, {\n flowName: opts.flowName,\n stats: opts.stats,\n buildOverrides: opts.output ? { output: opts.output } : undefined,\n }),\n\n async simulate(input, opts) {\n // Reuse a prebuilt bundle across calls with the same resolved config. The\n // simulate fns take their fast `mode: 'prebuilt'` branch when given a\n // bundlePath, skipping the per-call rebuild. On any bundle failure fall\n // back to undefined so the simulate fn rebuilds and surfaces its own error.\n let bundlePath: string | undefined;\n try {\n bundlePath = await getOrBuildBundle(input);\n } catch {\n bundlePath = undefined;\n }\n const common = { bundlePath, flow: opts.flow, silent: true };\n const config = opts.config ?? input;\n\n switch (opts.stepType) {\n case 'source':\n return simulateSource(config, opts.event, {\n sourceId: opts.stepId,\n ...common,\n consent: opts.state?.consent,\n });\n case 'transformer':\n return simulateTransformer(config, partialEvent(opts.event), {\n transformerId: opts.stepId,\n ...common,\n ingest: opts.ingest,\n consent: opts.state?.consent,\n });\n case 'collector':\n return simulateCollector(config, partialEvent(opts.event), {\n collectorName: opts.stepId,\n ...common,\n state: opts.state,\n ingest: opts.ingest,\n });\n case 'destination':\n return simulateDestination(config, eventObject(opts.event), {\n destinationId: opts.stepId,\n ...common,\n ingest: opts.ingest,\n consent: opts.state?.consent,\n command: opts.command,\n });\n }\n },\n\n knownSecrets: async (input) =>\n collectKnownSecrets(await loadJsonConfig<Flow.Json>(input)),\n\n async loadRun(input) {\n // One read, detected the way push detects its input: content that\n // parses as JSON is a config, anything else a prebuilt bundle, which\n // carries no config and so no secrets to resolve.\n const content = await loadConfig(input, { json: false });\n const config =\n typeof content === 'string' ? parseJson(content) : undefined;\n if (!isFlowJson(config)) return { knownSecrets: [] };\n return { config, knownSecrets: collectKnownSecrets(config) };\n },\n\n push: (input, event, opts) =>\n push(input, event, {\n json: true,\n flow: opts.flow,\n platform: opts.platform,\n ...(opts.config !== undefined && { raw: opts.config }),\n }),\n };\n}\n\n/**\n * The event a transformer or collector step runs on, checked against the\n * partial event schema the CLI applies. The value passes through as given.\n */\nfunction partialEvent(value: unknown): WalkerOS.DeepPartialEvent {\n if (isPartialEvent(value)) return value;\n const parsed = schemas.PartialEventSchema.safeParse(value);\n throw new Error(parsed.error?.message ?? 'Invalid event');\n}\n\nfunction isPartialEvent(value: unknown): value is WalkerOS.DeepPartialEvent {\n return schemas.PartialEventSchema.safeParse(value).success;\n}\n\n/** A destination step's event, or a command's data: an object. */\nfunction eventObject(value: unknown): Record<string, unknown> {\n if (isObject(value)) return value;\n throw new Error('event must be an object.');\n}\n\nfunction parseJson(content: string): unknown {\n try {\n return JSON.parse(content);\n } catch {\n return undefined;\n }\n}\n","import { createHash } from 'node:crypto';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport { rmSync } from 'node:fs';\nimport { bundle } from '@walkeros/cli';\n\n/**\n * Content-addressed cache of prebuilt simulate bundles for the MCP\n * `flow_simulate` tool. Each `flow_simulate` call otherwise re-bundles the\n * whole flow (`mode: 'build'`), which dominates latency. By keying a prebuilt\n * ESM by the hash of the *resolved* config content, repeated simulations of the\n * same flow reuse one bundle and a changed flow rebuilds.\n *\n * The CLI simulate functions accept a `bundlePath`; passing it takes their\n * `mode: 'prebuilt'` branch and skips the bundle step entirely.\n */\n\ninterface CacheEntry {\n bundlePath: string;\n dir: string;\n}\n\n/** LRU bound: enough to cover a few flows iterated in one session without\n * leaking temp dirs. Oldest entry is evicted (and its dir removed) on insert. */\nconst MAX_ENTRIES = 8;\n\n/** Insertion-ordered map gives us LRU for free: delete+set on access moves the\n * key to the end; the first key is the least-recently used. */\nconst cache = new Map<string, CacheEntry>();\n\n/** In-flight builds, deduped by key so two concurrent identical simulate calls\n * bundle once instead of racing to write the same artifact. */\nconst inFlight = new Map<string, Promise<string>>();\n\nlet cleanupRegistered = false;\n\nfunction hashConfig(resolvedConfig: string): string {\n return createHash('sha256').update(resolvedConfig).digest('hex');\n}\n\n/**\n * Inline JSON config content is cacheable: its full content is the cache key,\n * so an edit always re-keys. A file path or URL is NOT: `resolveConfigPath`\n * returns it unchanged, so the key would be the path string and an edit to the\n * file behind it would silently reuse a stale bundle. Such inputs skip the\n * cache and take the simulate fns' build path (which re-reads the file).\n *\n * The discriminator matches how the CLI simulate fns treat `configPath`: a\n * string that parses as JSON is inline config; anything else is a path/URL.\n */\nfunction isInlineJsonConfig(resolvedConfig: string): boolean {\n const trimmed = resolvedConfig.trimStart();\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return false;\n try {\n JSON.parse(resolvedConfig);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction registerProcessCleanup(): void {\n if (cleanupRegistered) return;\n cleanupRegistered = true;\n const cleanup = () => {\n for (const entry of cache.values()) {\n // Synchronous best-effort removal on exit; async fs is not safe here.\n try {\n rmSync(entry.dir, { recursive: true, force: true });\n } catch {\n // Temp dir already gone or unwritable; nothing to recover.\n }\n }\n cache.clear();\n };\n process.once('exit', cleanup);\n}\n\nasync function evictIfNeeded(): Promise<void> {\n while (cache.size > MAX_ENTRIES) {\n const oldestKey = cache.keys().next().value;\n if (oldestKey === undefined) break;\n const evicted = cache.get(oldestKey);\n cache.delete(oldestKey);\n if (evicted) await rm(evicted.dir, { recursive: true, force: true });\n }\n}\n\n/**\n * Build the resolved config into a prebuilt simulate ESM and return its path,\n * reusing a cached bundle when the same resolved config was bundled before.\n *\n * `resolvedConfig` is the exact string the simulate functions would otherwise\n * receive as `configPath` (inline JSON for cloud ids after id resolution, or a\n * file path / URL / inline JSON otherwise). Keying on it means a cloud id whose\n * underlying content changes between calls rebuilds correctly.\n *\n * Returns `undefined` for file-path / URL configs (see `isInlineJsonConfig`):\n * those bypass the cache so an edited file is never served from a stale bundle.\n * The caller then passes the original configPath with no bundlePath, taking the\n * simulate fns' build path exactly as before.\n *\n * The producer mirrors the CLI build-mode bundle: target `simulate`\n * (skipWrapper + withDev, /dev graph inlined) written as ESM. The flow's own\n * platform is preserved via the bundler's platform defaults; only the output\n * format is pinned to ESM so the CLI can import it directly.\n */\nexport async function getOrBuildBundle(\n resolvedConfig: string,\n): Promise<string | undefined> {\n if (!isInlineJsonConfig(resolvedConfig)) return undefined;\n\n registerProcessCleanup();\n const key = hashConfig(resolvedConfig);\n\n const cached = cache.get(key);\n if (cached) {\n // Refresh LRU position.\n cache.delete(key);\n cache.set(key, cached);\n return cached.bundlePath;\n }\n\n const pending = inFlight.get(key);\n if (pending) return pending;\n\n const build = (async () => {\n const dir = path.join(\n os.tmpdir(),\n `walkeros-mcp-bundle-${key.slice(0, 16)}`,\n );\n await rm(dir, { recursive: true, force: true });\n await mkdir(dir, { recursive: true });\n const bundlePath = path.join(dir, 'flow.mjs');\n\n // Touch the file first so a producer that only mutates (rather than writes)\n // still leaves a real artifact; the bundler overwrites it with the real ESM.\n await writeFile(bundlePath, '', 'utf-8');\n\n // Load-bearing: `bundle()` derives platform from the flow config and\n // intentionally ignores `preset.platform` (the 'simulate' preset is node),\n // so a web flow still bundles browser-platform, equivalent to build-mode.\n // If `bundle()` ever honors `preset.platform`, web simulations via this\n // cache would silently bundle for node and diverge.\n await bundle(resolvedConfig, {\n target: 'simulate',\n silent: true,\n buildOverrides: { output: bundlePath, format: 'esm', minify: false },\n });\n\n cache.set(key, { bundlePath, dir });\n await evictIfNeeded();\n return bundlePath;\n })();\n\n inFlight.set(key, build);\n try {\n return await build;\n } finally {\n inFlight.delete(key);\n }\n}\n\n/** Test-only: clear the cache and remove all temp dirs. */\nexport async function __resetBundleCacheForTests(): Promise<void> {\n inFlight.clear();\n const dirs = Array.from(cache.values(), (e) => e.dir);\n cache.clear();\n await Promise.all(\n dirs.map((dir) => rm(dir, { recursive: true, force: true })),\n );\n}\n"],"mappings":";;;AAAA,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;;;ACDjC,SAAS,iBAAiB;;;ACA1B,SAAS,gBAAgB;AAEzB,SAAS,eAAe;AAExB,SAAS,WAAW,gBAAgB;;;ACJpC,SAAS,SAAS;AAGlB,IAAM,sBAAsB;AAAA,EAC1B,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO;AAAA,EAClB,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC5B,MAAM,EACH,OAAO,EACP,SAAS,EACT,SAAS,iDAAiD;AAAA,EAC7D,SAAS,EACN,OAAO,EACP,SAAS,EACT,SAAS,gDAAgD;AAC9D;AAEO,IAAM,sBAAsB;AAAA,EACjC,OAAO,EAAE,QAAQ,EAAE,SAAS,2BAA2B;AAAA,EACvD,MAAM,EACH,MAAM;AAAA,IACL,EAAE,KAAK,CAAC,YAAY,SAAS,SAAS,QAAQ,SAAS,CAAC;AAAA,IACxD,EAAE,OAAO,EAAE,MAAM,4CAA4C;AAAA,EAC/D,CAAC,EACA,SAAS,oBAAoB;AAAA,EAChC,QAAQ,EAAE,MAAM,EAAE,OAAO,mBAAmB,CAAC,EAAE,SAAS,mBAAmB;AAAA,EAC3E,UAAU,EACP;AAAA,IACC,EAAE,OAAO;AAAA,MACP,GAAG;AAAA,MACH,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,IAClC,CAAC;AAAA,EACH,EACC,SAAS,qBAAqB;AAAA,EACjC,SAAS,EACN,OAAO;AAAA,IACN,OAAO,EACJ,OAAO;AAAA,MACN,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,MACzB,OAAO,EACJ,OAAO;AAAA,QACN,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,KAAK,EAAE,OAAO;AAAA,QACd,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QACzB,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,MACnC,CAAC,EACA,SAAS;AAAA,MACZ,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,MAC1B,SAAS,EAAE,QAAQ,IAAI,EAAE,SAAS;AAAA,IACpC,CAAC,EACA,SAAS,EACT,SAAS,sBAAsB;AAAA,IAClC,SAAS,EACN;AAAA,MACC,EAAE,OAAO;AAAA,QACP,MAAM,EAAE,OAAO;AAAA,QACf,OAAO,EAAE,OAAO;AAAA,QAChB,QAAQ,EAAE,OAAO;AAAA,QACjB,MAAM,EAAE,OAAO;AAAA,MACjB,CAAC;AAAA,IACH,EACC,SAAS,EACT,SAAS,mDAAmD;AAAA,IAC/D,UAAU,EACP,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC,EAC3D,SAAS,EACT,SAAS,kDAAkD;AAAA,EAChE,CAAC,EACA,SAAS,EAAE,QAAQ,CAAC,EACpB,SAAS,+BAA+B;AAAA,EAC3C,QAAQ,EACL,OAAO;AAAA,IACN,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACnC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,CAAC,EACA,SAAS,EACT,SAAS,sBAAsB;AACpC;AAEO,IAAM,oBAAoB;AAAA,EAC/B,SAAS,EAAE,QAAQ,EAAE,SAAS,4BAA4B;AAAA,EAC1D,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EACtE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EACtE,UAAU,EACP;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM,EAAE,OAAO;AAAA,IACjB,CAAC;AAAA,EACH,EACC,SAAS,EACT,SAAS,0CAA0C;AAAA,EACtD,sBAAsB,EACnB,QAAQ,EACR,SAAS,EACT,SAAS,oCAAoC;AAAA,EAChD,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gBAAgB;AAC1D;AAEO,IAAM,sBAAsB;AAAA,EACjC,SAAS,EAAE,QAAQ,EAAE,SAAS,8BAA8B;AAAA,EAC5D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,EAC/D,SAAS,EAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,EACtD,cAAc,EACX;AAAA,IACC,EAAE,OAAO;AAAA,IACT,EAAE,OAAO;AAAA,MACP,UAAU,EACP,QAAQ,EACR,SAAS,wCAAwC;AAAA,MACpD,OAAO,EAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MACrD,SAAS,EACN,QAAQ,EACR,SAAS,EACT,SAAS,qDAAqD;AAAA,IACnE,CAAC;AAAA,EACH,EACC,SAAS,EACT,SAAS,yBAAyB;AAAA,EACrC,gBAAgB,EACb,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EACvC,SAAS,EACT,SAAS,sCAAsC;AAAA,EAClD,OAAO,EACJ,MAAM,EAAE,QAAQ,CAAC,EACjB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAAS,EACN,OAAO;AAAA,IACN,QAAQ,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC;AAAA,IACrC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACrD,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACpD,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACxC,CAAC,EACA,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AACtE;AAEO,IAAM,kBAAkB;AAAA,EAC7B,SAAS,EAAE,QAAQ,EAAE,SAAS,wBAAwB;AAAA,EACtD,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC3E,UAAU,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAC7D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8BAA8B;AACtE;AAGO,IAAM,0BAA0B;AAAA,EACrC,MAAM,EAAE,OAAO,EAAE,SAAS,WAAW;AAAA,EACrC,OAAO,EAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,EACrD,UAAU,EACP;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM,EAAE,OAAO,EAAE,SAAS,0CAA0C;AAAA,MACpE,UAAU,EACP,KAAK,CAAC,UAAU,eAAe,aAAa,CAAC,EAC7C,SAAS,WAAW;AAAA,MACvB,UAAU,EAAE,OAAO,EAAE,SAAS,WAAW;AAAA,MACzC,aAAa,EAAE,OAAO,EAAE,SAAS,cAAc;AAAA,MAC/C,QAAQ,EACL,KAAK,CAAC,UAAU,SAAS,CAAC,EAC1B;AAAA,QACC;AAAA,MACF;AAAA,MACF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,MACnE,aAAa,EACV,OAAO,EACP,SAAS,EACT,SAAS,kCAAkC;AAAA,MAC9C,QAAQ,EACL,QAAQ,EACR,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,OAAO,EAAE,QAAQ,EAAE,SAAS,wCAAwC;AAAA,MACpE,QAAQ,EAAE,QAAQ,EAAE,SAAS,yCAAyC;AAAA,MACtE,YAAY,EACT,QAAQ,EACR,SAAS,iDAAiD;AAAA,MAC7D,YAAY,EACT,QAAQ,EACR,SAAS,0CAA0C;AAAA,MACtD,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,MACtD,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC3D,SAAS,EACN,QAAQ,EACR,SAAS,EACT,SAAS,wCAAwC;AAAA,MACpD,SAAS,EACN,OAAO;AAAA,QACN,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,MAChC,CAAC,EACA,SAAS,EACT,SAAS,wCAAwC;AAAA,IACtD,CAAC;AAAA,EACH,EACC,SAAS,eAAe;AAC7B;;;ACtFO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAC/B;AAAA,EAET,YAAY,SAAiB,MAAc;AACzC,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,YAAY,OAAgB,UAA0B;AACpE,SAAO,iBAAiB,iBAAiB,MAAM,OAAO;AACxD;AASO,IAAM,sBACX;AAGK,SAAS,qBACd,WACgB;AAChB,QAAM,OACJ,cAAc,WACV,aACA,cAAc,aACZ,eACA;AACR,SAAO,IAAI;AAAA,IACT,GAAG,IAAI;AAAA,IACP;AAAA,EACF;AACF;;;AC3JA,SAAS,gBAA+B;AASjC,IAAM,mBAAmB;AAEzB,SAAS,UAAU,OAAwB;AAChD,SAAO,iBAAiB,KAAK,KAAK;AACpC;AAOO,SAAS,aAAa,MAAmC;AAC9D,SAAO,SAAS,IAAI,KAAK,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AAClE;;;AHGA,eAAe,kBACb,SACA,OACA,MACkB;AAClB,MAAI,CAAC,SAAS,MAAM,KAAK,MAAM,GAAI,OAAM,IAAI,MAAM,GAAG,IAAI,cAAc;AACxE,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,gBAAgB,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG;AACvE,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,KAAK;AAAA,EACjC,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB,UAAU,OAAO,EAAG,OAAM;AACjE,QAAI,eAAe;AACjB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,YAAM,IAAI,MAAM,mBAAmB,IAAI,KAAK,OAAO,EAAE;AAAA,IACvD;AACA,QAAI,SAAS,QAAS,QAAO,EAAE,MAAM,QAAQ;AAC7C,UAAM;AAAA,EACR;AACF;AAEA,IAAM,QAAQ;AACd,IAAM,cACJ;AAMF,IAAM,cAAc,QAAQ;AAE5B,IAAM,cAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,2BAA2B,SAAgC;AACzE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,SAAS,CAAC,UAAU,wBAAwB,SAAS,KAAK;AAAA,EAC5D;AACF;AAEA,eAAe,wBAAwB,SAAsB,OAAgB;AAC3E,QAAM,SAAS,QAAQ,oBAAoB,UAAU,SAAS,CAAC,CAAC;AAChE,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,SAAS,OAAO,OAAO,sCAAsC;AAAA,EACtE;AACA,QAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,MAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,OAAO;AACX,MAAI;AAIF,UAAM,WAAW,MAAM,kBAAkB,SAAS,eAAe,IAAI;AACrE,UAAM,YAAY,QAAQ,UAAU,aAAa;AACjD,UAAM,SAAyB,MAAM,SAAS,MAAM,UAAU;AAAA,MAC5D;AAAA,MACA,MAAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACnC,CAAC;AAED,UAAM,UAAU,OAAO,QAAQ,WAAW,CAAC;AAC3C,UAAM,OAAO,QAAQ,WACjB,CAAC,wCAAwC,0BAA0B,IACnE,CAAC,mBAAmB;AACxB,UAAM,QACJ,CAAC,OAAO,SAAS,OAAO,OAAO,WAAW,IACtC;AAAA,MACE,MAAM;AAAA,QACJ,WAAW,OAAO,SAAS,MAAM,mBAAmB,QAAQ,MAAM;AAAA,MACpE;AAAA,IACF,IACA,CAAC,OAAO,QACN;AAAA,MACE,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF,IACA,QAAQ,SAAS,IACf;AAAA,MACE,MAAM;AAAA,QACJ,2BAA2B,QAAQ,MAAM;AAAA,QACzC,GAAG;AAAA,MACL;AAAA,IACF,IACA,EAAE,KAAK;AAGjB,WAAO,UAAU,QAAQ,KAAK;AAAA,EAChC,SAAS,OAAO;AACd,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,yBACd,QACA,SACA;AACA,QAAM,OAAO,2BAA2B,OAAO;AAC/C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,wBAAwB,SAAS,IAAI;AAAA,EACjD;AACF;;;AI9JA,SAAS,WAAAC,gBAAe;AAExB,SAAS,aAAAC,YAAW,YAAAC,iBAAgB;;;ACFpC,SAAS,KAAAC,UAA2B;AACpC,SAAS,YAAAC,iBAAgB;AAUlB,SAAS,mBAAmB,OAA2B;AAC5D,SAAO,MAAM,OACV,IAAI,CAAC,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM,OAAO,EAAE,EACrE,KAAK,IAAI;AACd;AAOO,SAAS,eACd,OACA,KAGoD;AACpD,QAAM,SAASD,GAAE,OAAO,KAAK,EAAE,UAAU,OAAO,CAAC,CAAC;AAClD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAOC,UAAS,IAAI,MAAM,mBAAmB,OAAO,KAAK,CAAC,CAAC;AAAA,IAC7D;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;;;AC1BA,eAAsB,kBACpB,QACA,YACiB;AACjB,MAAI,CAAC,UAAU,UAAU,EAAG,QAAO;AAEnC,QAAM,OAAO,MAAM,OAAO,QAAQ,EAAE,QAAQ,WAAW,CAAC;AACxD,SAAO,KAAK,UAAU,aAAa,IAAI,CAAC;AAC1C;;;AFHA,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAIF,IAAMC,eAAc;AAAA,EAClB,GAAGC,SAAQ;AACb;AAEA,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,yBACd,QACA,SACU;AACV,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,sBAAsB,QAAQ,SAAS,KAAK;AAAA,EAClE;AACF;AAEA,eAAe,sBACb,QACA,SACA,OACA;AACA,QAAM,SAAS,eAAeF,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,YAAY,MAAM,OAAO,OAAO,IAAI,OAAO;AAGnD,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,UAAU,qBAAqB,QAAQ;AAC7C,WAAOG,UAAS,SAAS,QAAQ,IAAI;AAAA,EACvC;AACA,MAAI;AAEF,UAAM,qBAAqB,MAAM,kBAAkB,QAAQ,UAAU;AACrE,UAAM,SAAS,MAAM,QAAQ,OAAO,oBAAoB;AAAA,MACtD,UAAU;AAAA,MACV,OAAO,SAAS;AAAA,MAChB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,QAAQ;AACX,aAAOC;AAAA,QACL,EAAE,SAAS,OAAO,SAAS,4BAA4B;AAAA,QACvD;AAAA,UACE,UAAU;AAAA,YACR;AAAA,UACF;AAAA,UACA,MAAM,CAAC,+CAA+C;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAEA,WAAOA;AAAA,MACL,EAAE,SAAS,MAAM,GAAG,OAAO;AAAA,MAC3B;AAAA,QACE,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,YAAY,OAAO,+CAA+C;AAAA,IACpE;AAAA,EACF;AACF;AAEO,SAAS,uBACd,QACA,QACA,SACA;AACA,QAAM,OAAO,yBAAyB,QAAQ,OAAO;AACrD,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,sBAAsB,QAAQ,SAAS,IAAI;AAAA,EACvD;AACF;;;AGpHA,SAAS,KAAAE,UAAS;AAClB,SAAS,WAAAC,gBAAe;AAExB,SAAS,cAAc,aAAAC,YAAW,YAAAC,iBAAgB;;;ACE3C,IAAM,4BACX;;;ACLF,SAAS,YAAAC,WAAoB,aAAAC,kBAAiB;AAC9C,SAAS,WAAW,oBAAoB;AAUjC,SAAS,SACd,QACA,OACyB;AACzB,QAAM,SAAS,YAAY,UAAU,QAAQ,EAAE,MAAM,CAAC,CAAC;AACvD,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,uCAAuC;AACpE,SAAO;AACT;AAaO,SAAS,cACd,UACA,OAC6B;AAC7B,MAAI;AACJ,MAAI;AACF,QAAI,SAAS;AACX,0BAAoB,SAAS,SAAS,mBAAmB,KAAK;AAAA,EAClE,QAAQ;AACN,wBAAoB;AAAA,EACtB;AACA,MAAI,mBAAmB;AACrB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,iBAAiB,EAAE,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,SAAS,QAAQ,IAAI,CAAC,UAAU;AAAA,MACvC,GAAG;AAAA,MACH,MAAM,aAAa,KAAK,MAAM,EAAE,MAAM,CAAC;AAAA,IACzC,EAAE;AAAA,IACF,mBAAmB,EAAE,OAAO,mCAAmC;AAAA,EACjE;AACF;AASO,SAAS,mBACd,QACA,OAC8B;AAC9B,QAAM,OAAO,UAAU,QAAQ,EAAE,OAAO,OAAO,EAAE,CAAC;AAClD,QAAM,SAAS,YAAY,IAAI;AAC/B,MAAI;AACF,WAAOA,WAAU;AAAA,MACf,GAAG;AAAA,MACH,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,IACnB,CAAC;AACH,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,IAChC,mBAAmB,EAAE,SAAS,OAAO,SAAS,UAAU,OAAO,SAAS;AAAA,EAC1E;AACF;AAEA,SAAS,YAAY,MAAmD;AACtE,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,WAAOD,UAAS,MAAM,IAAI,SAAS;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,QACpB,SACA,OACoB;AACpB,MAAI,QAAQ,QAAS,QAAO,QAAQ,QAAQ,KAAK;AACjD,SAAO;AAAA,IACL,cAAc,QAAQ,eAAe,MAAM,QAAQ,aAAa,KAAK,IAAI,CAAC;AAAA,EAC5E;AACF;;;AFjFA,IAAM,aAA0C;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,WAAW,OAA0C;AAC5D,SAAO,WAAW,KAAK,CAAC,MAAM,MAAM,KAAK;AAC3C;AAEA,IAAME,SAAQ;AACd,IAAM,WAA+D;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAMC,eAAc;AAAA,EAClB,YAAYC,SAAQ,mBAAmB;AAAA,EACvC,OAAOC,GACJ,MAAM,CAACA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,GAAGA,GAAE,OAAO,CAAC,CAAC,EACrD,SAAS,EACT;AAAA,IACC;AAAA,EAOF;AAAA,EACF,MAAMD,SAAQ,mBAAmB;AAAA,EACjC,UAAUA,SAAQ,mBAAmB;AAAA;AAAA;AAAA,EAGrC,MAAMC,GACH,OAAO,EACP;AAAA,IACC;AAAA,EAEF;AAAA,EACF,SAASA,GACN,QAAQ,EACR,SAAS,EACT,SAAS,uDAAuD;AAAA,EACnE,QAAQA,GACL,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAC9B,SAAS,EACT;AAAA,IACC;AAAA,EAIF;AAAA,EACF,OAAOA,GACJ,OAAO;AAAA,IACN,SAASA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACpD,MAAMA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACjD,SAASA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACpD,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,CAAC,EACA,SAAS,EACT;AAAA,IACC;AAAA,EAIF;AAAA,EACF,SAASA,GACN,KAAK,QAAQ,EACb,SAAS,EACT;AAAA,IACC;AAAA,EAEF;AACJ;AAEA,IAAMC,eAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,2BACd,QACA,SACU;AACV,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAa;AAAA,IACb,aAAAC;AAAA,IACA,aAAAG;AAAA,IACA,SAAS,CAAC,UAAU,wBAAwB,QAAQ,SAAS,KAAK;AAAA,EACpE;AACF;AAGA,SAAS,aACP,OACiC;AACjC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAM,WAAW,aAAa,KAAK;AACnC,QAAI,aAAa,OAAW,YAAW,GAAG,IAAI;AAAA,EAChD;AACA,SAAO;AACT;AAEA,eAAe,wBACb,QACA,SACA,OACA;AACA,QAAM,SAAS,eAAeH,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,OAAO;AAIX,MAAI,CAAC,QAAQ,UAAU;AACrB,UAAM,UAAU,qBAAqB,UAAU;AAC/C,WAAOI,UAAS,SAAS,QAAQ,IAAI;AAAA,EACvC;AACA,MAAI,QAAkB,CAAC;AACvB,MAAI;AACF,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,gBAAyB;AAC7B,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI;AACF,wBAAgB,KAAK,MAAM,KAAK;AAAA,MAClC,QAAQ;AACN,cAAM,IAAI;AAAA,UACR,2CAA2C,MAAM,UAAU,GAAG,EAAE;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,QAAI,aAAa,IAAI;AACnB,YAAM,IAAI;AAAA,QACR,wBAAwB,IAAI;AAAA,MAC9B;AAAA,IACF;AACA,UAAM,WAAW,KAAK,UAAU,GAAG,QAAQ;AAC3C,UAAM,SAAS,KAAK,UAAU,WAAW,CAAC;AAE1C,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,sBAAsB,QAAQ;AAAA,MAChC;AAAA,IACF;AAEA,QAAI,YAAY,UAAa,aAAa,eAAe;AACvD,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAGA,UAAM,qBAAqB,MAAM,kBAAkB,QAAQ,UAAU;AAGrE,UAAM,MAAM,MAAM,QAAQ,SAAS,kBAAkB;AACrD,YAAQ,IAAI;AAEZ,UAAM,SAA4B,MAAM,QAAQ;AAAA,MAC9C;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,OAAO,SAAS;AAAA,UACd,SAAS,MAAM;AAAA,UACf,MAAM,aAAa,MAAM,IAAI;AAAA,UAC7B,SAAS,aAAa,MAAM,OAAO;AAAA,UACnC,QAAQ,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA,QAAQ,IAAI;AAAA,MACd;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,OAAO;AACxB,UAAMC,gBAAe,OAAO,OAAO;AAInC,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,aAAa,OAAO,OAAO;AACjC,YAAM,eAAe,OAAO,MAAM;AAAA,QAChC,CAAC,SAAS,KAAK,OAAO;AAAA,MACxB,EAAE;AACF,YAAM,UACJ,mBAAmB,UAAU,SAAS,eAAe,IAAI,MAAM,EAAE,QACzD,YAAY,WAAW,iBAAiB,IAAI,MAAM,EAAE;AAC9D,YAAM,aAAa,UACf,OAAO,QACP,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,OAAO,KAAK;AAEnD,aAAOC;AAAA,QACL;AAAA,UACE;AAAA,YACE;AAAA,YACA,OAAOD;AAAA,YACP;AAAA,YACA,gBAAgB,OAAO;AAAA,YACvB,GAAI,WAAW,SAAS,IAAI,EAAE,OAAO,WAAW,IAAI,CAAC;AAAA,YACrD,UAAU,OAAO;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UACE,MACE,aAAa,eAAe,IACxB;AAAA,YACE;AAAA,UACF,IACA;AAAA,YACE;AAAA,UACF;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,eAAe;AACjC,aAAOC;AAAA,QACL;AAAA,UACE;AAAA,YACE;AAAA,YACA,OAAOD;AAAA,YACP,SAAS;AAAA,YACT,gBAAgB,OAAO;AAAA,YACvB,UAAU,OAAO;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM,CAAC,yCAAyC;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,aAAa;AAC/B,aAAOC;AAAA,QACL;AAAA,UACE;AAAA,YACE;AAAA,YACA,OAAOD;AAAA,YACP,SAAS;AAAA,YACT,gBAAgB,OAAO;AAAA,YACvB,UAAU,OAAO;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM,CAAC,4DAA4D;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eAAmD,CAAC;AAC1D,UAAM,YAAY,OAAO,MAAM;AAC/B,UAAM,cAAkC;AAAA,MACtC,UAAU,YAAY;AAAA,MACtB,OAAO;AAAA,IACT;AACA,QAAI,WAAW,YAAY,GAAG;AAC5B,kBAAY,UAAU,OAAO;AAAA,IAC/B;AACA,iBAAa,OAAO,IAAI,IAAI;AAE5B,UAAM,YAAY,OAAO,KAAK,YAAY,EAAE;AAC5C,UAAM,gBAAgB,OAAO,OAAO,YAAY,EAAE;AAAA,MAChD,CAAC,MAAM,EAAE;AAAA,IACX,EAAE;AAEF,UAAM,WAAqB,CAAC;AAC5B,QAAI,kBAAkB,KAAK,QAAS,UAAS,KAAK,YAAY,MAAM,CAAC;AAErE,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,OAAOA;AAAA,MACP,SAAS,GAAG,aAAa,IAAI,SAAS;AAAA,MACtC;AAAA,MACA,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MACpD,UAAU,OAAO;AAAA,IACnB;AAEA,WAAOC,WAAU,SAAS,WAAW,KAAK,GAAG;AAAA,MAC3C,MAAM,CAAC,yCAAyC;AAAA,MAChD,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,OAAO;AACb,WAAO,cAAcF,UAAS,OAAO,YAAY,OAAO,IAAI,CAAC,GAAG,KAAK;AAAA,EACvE;AACF;AAEA,SAAS,OAAO,SAA+C;AAC7D,QAAM,OAAO,OAAO,QAAQ,WAAW,CAAC,CAAC,EACtC,OAAO,CAAC,CAAC,EAAE,OAAO,MAAM,OAAO,EAC/B,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AACrB,SAAO,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI;AAC7C;AAGA,SAAS,YAAY,QAAmC;AACtD,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,SAAS,WAAW,WAAW;AACjC,UAAMG,WAAU,QAAQ,WAAW,CAAC;AACpC,UAAM,QAAQA,SAAQ,SAASA,SAAQ,KAAK,IAAI,IAAI;AACpD,UAAM,SAASA,SAAQ,SAAS,SAAS,IACrC,gEACA,oCAAoC,KAAK;AAC7C,WAAO,yBAAyB,KAAK,iCAAiC,MAAM;AAAA,EAC9E;AACA,MAAI,SAAS,WAAW,WAAW;AACjC,WACE,0BAA0B,OAAO,QAAQ,QAAQ,CAAC,aAAa,OAAO,QAAQ,OAAO,CAAC;AAAA,EAG1F;AACA,SACE;AAKJ;AAEO,SAAS,yBACd,QACA,QACA,SACA;AACA,QAAM,OAAO,2BAA2B,QAAQ,OAAO;AACvD,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,wBAAwB,QAAQ,SAAS,IAAI;AAAA,EACzD;AACF;;;AGzZA,SAAS,KAAAC,UAAS;AAElB,SAAS,WAAAC,gBAAe;AAGxB,SAAS,YAAAC,iBAAgB;AAYzB,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAIF,IAAMC,eAAc;AAAA,EAClB,YAAYC,SAAQ,eAAe;AAAA,EACnC,OAAOC,GACJ,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAC9B;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMD,SAAQ,eAAe;AAAA,EAC7B,UAAUA,SAAQ,eAAe;AACnC;AAEA,IAAME,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,uBAAuB,SAAgC;AACrE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOL;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAG;AAAA,IACA,SAAS,CAAC,UAAU,oBAAoB,SAAS,KAAK;AAAA,EACxD;AACF;AAEA,eAAe,oBACb,SACA,OACyB;AACzB,QAAM,SAAS,eAAeH,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,YAAY,OAAO,MAAM,SAAS,IAAI,OAAO;AAGrD,MAAI,CAAC,QAAQ,MAAM;AACjB,UAAM,UAAU,qBAAqB,MAAM;AAC3C,WAAOI,UAAS,SAAS,QAAQ,IAAI;AAAA,EACvC;AAKA,MAAI,QAAkB,CAAC;AACvB,MAAI;AACF,UAAM,MAAM,MAAM,QAAQ,SAAS,UAAU;AAC7C,YAAQ,IAAI;AACZ,UAAM,SAAqB,MAAM,QAAQ,KAAK,YAAY,OAAO;AAAA,MAC/D;AAAA,MACA;AAAA,MACA,QAAQ,IAAI;AAAA,IACd,CAAC;AAED,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO;AAAA,QACLA;AAAA,UACE,IAAI,MAAM,OAAO,SAAS,aAAa;AAAA,UACvC;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,mBAAmB,QAAQ,KAAK;AAAA,EACzC,SAAS,OAAO;AACd,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB,QAAmB,SAAsB;AAC5E,QAAM,OAAO,uBAAuB,OAAO;AAC3C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,oBAAoB,SAAS,IAAI;AAAA,EAC7C;AACF;;;ACtHA,SAAS,KAAAC,UAAS;AAElB,SAAS,cAAc,aAAAC,YAAW,YAAAC,iBAAgB;AAElD,SAAS,mBAAmB,yBAAyB;;;ACJrD,SAAS,kBAAkB;AAO3B,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAM,YAAY,IAAI,KAAK;AAEpB,IAAM,gBAAgB;AActB,SAAS,oBAAwC;AACtD,SAAO,QAAQ,IAAI,oBAAoB;AACzC;AA6BA,IAAI;AAEG,SAAS,uBAAyD;AACvE,SAAO;AACT;AAMA,IAAM,QAAQ,oBAAI,IAA4D;AAMvE,SAAS,kBAAkB,UAA8B;AAC9D,MAAI,YAAY,KAAM,QAAO,CAAC;AAC9B,MAAI,OAAO,aAAa,UAAU;AAChC,WAAO,aAAa,cAAc,CAAC,OAAO,QAAQ,IAAI,CAAC,QAAQ;AAAA,EACjE;AACA,MAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,WAAO,SAAS,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,EAClE;AACA,SAAO,CAAC;AACV;AAUA,eAAsB,aAAa,SAIR;AACzB,QAAM,YAAY,SAAS,WAAW;AACtC,QAAM,WAAqB,CAAC;AAE5B,QAAM,SAAS,MAAM,IAAI,SAAS;AAClC,MAAI,UAAU,KAAK,IAAI,IAAI,OAAO,YAAY,WAAW;AACvD,oBAAgB;AAAA,MACd,QAAQ,SAAS,UAAU,QAAQ;AAAA,MACnC,OAAO,OAAO,QAAQ;AAAA,MACtB,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,IACtB;AACA,WAAO,EAAE,SAAS,aAAa,OAAO,SAAS,OAAO,GAAG,SAAS;AAAA,EACpE;AAEA,MAAI;AAGJ,MAAI,WAA0B,SAAS,UAAU,QAAQ;AACzD,MAAI,SAAS,SAAS;AACpB,QAAI;AACF,eAAS,MAAM,iBAAiB,QAAQ,SAAS,OAAO;AAAA,IAC1D,QAAQ;AACN,eAAS;AAAA,QACP;AAAA,MACF;AACA,iBAAW;AACX,UAAI;AACF,iBAAS,MAAM,aAAa;AAAA,MAC9B,QAAQ;AACN,wBAAgB;AAAA,UACd,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,SAAS;AAAA,UACT,WAAW,KAAK,IAAI;AAAA,QACtB;AACA,eAAO,EAAE,SAAS,CAAC,GAAG,SAAS;AAAA,MACjC;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI;AACF,eAAS,MAAM,aAAa;AAAA,IAC9B,QAAQ;AACN,sBAAgB;AAAA,QACd,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS;AAAA,QACT,WAAW,KAAK,IAAI;AAAA,MACtB;AACA,aAAO,EAAE,SAAS,CAAC,GAAG,SAAS;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,YAAY,OAAO,QAAQ;AAClD,MAAI,UAAU,GAAG;AACf,aAAS;AAAA,MACP,GAAG,OAAO;AAAA,IACZ;AAAA,EACF;AAEA,kBAAgB;AAAA,IACd,QAAQ;AAAA,IACR,OAAO,OAAO,QAAQ;AAAA,IACtB,SAAS,CAAC,OAAO;AAAA,IACjB,WAAW,KAAK,IAAI;AAAA,EACtB;AAIA,MAAI,OAAO,QAAQ,SAAS,KAAK,OAAO,UAAU;AAChD,UAAM,IAAI,WAAW,EAAE,SAAS,OAAO,SAAS,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EACzE;AAEA,SAAO,EAAE,SAAS,aAAa,OAAO,SAAS,OAAO,GAAG,SAAS;AACpE;AAEA,eAAe,iBACb,SACA,SACuB;AACvB,QAAM,MAAM,MAAM,WAAW,qBAAqB;AAAA,IAChD,MAAM;AAAA,IACN;AAAA,IACA,OAAO;AAAA,MACL,MAAM,SAAS,QAAQ;AAAA,MACvB,UAAU,SAAS,YAAY;AAAA,IACjC;AAAA,IACA,QAAQ,YAAY,QAAQ,IAAK;AAAA,IACjC,SAAS,EAAE,qBAAqB,cAAc;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,yBAAyB,IAAI,MAAM,EAAE;AAElE,QAAM,OAA+C,MAAM,IAAI,KAAK;AACpE,QAAM,UAA0B,KAAK;AACrC,SAAO,EAAE,SAAS,UAAU,QAAQ,SAAS,GAAG,WAAW,QAAQ,OAAO;AAC5E;AAEA,eAAe,eAAsC;AACnD,QAAM,MAAM,MAAM,MAAM,GAAG,cAAc,6BAA6B;AAAA,IACpE,QAAQ,YAAY,QAAQ,GAAK;AAAA,IACjC,SAAS,EAAE,qBAAqB,cAAc;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,sBAAsB,IAAI,MAAM,EAAE;AAE/D,QAAM,OAAQ,MAAM,IAAI,KAAK;AAM7B,QAAM,YAAY,KAAK,QAAQ;AAE/B,QAAM,cAAc,MAAM,QAAQ;AAAA,IAChC,KAAK,QAAQ,IAAI,CAAC,QAAQ,eAAe,IAAI,OAAO,CAAC;AAAA,EACvD;AAEA,QAAM,UAAU,YACb;AAAA,IACC,CAAC,MACC,EAAE,WAAW;AAAA,EACjB,EACC,IAAI,CAAC,MAAM,EAAE,KAAK,EAClB,OAAO,CAAC,UAAiC,UAAU,MAAS;AAI/D,QAAM,WAAW,cAAc,KAAK,QAAQ,WAAW;AACvD,SAAO,EAAE,SAAS,UAAU,UAAU;AACxC;AAEA,eAAe,eAAe,KAIQ;AACpC,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,aAAa,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,kBAAkB;AAAA,MACjE;AAAA,QACE,QAAQ,YAAY,QAAQ,GAAI;AAAA,QAChC,SAAS,EAAE,qBAAqB,cAAc;AAAA,MAChD;AAAA,IACF;AACA,QAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,QAAQ,OAAO,KAAK,SAAS,SAAU,QAAO;AAEnD,WAAO;AAAA,MACL,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,MACb,aAAa,IAAI;AAAA,MACjB,MAAM,KAAK;AAAA,MACX,UAAU,kBAAkB,KAAK,QAAQ;AAAA,IAC3C;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,aACP,SACA,SACgB;AAChB,MAAI,UAAU;AACd,MAAI,SAAS,MAAM;AACjB,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,IAAI;AAAA,EACzD;AACA,MAAI,SAAS,UAAU;AAErB,cAAU,QAAQ;AAAA,MAChB,CAAC,MAAM,EAAE,SAAS,WAAW,KAAK,EAAE,SAAS,SAAS,QAAQ,QAAS;AAAA,IACzE;AAAA,EACF;AACA,SAAO;AACT;;;ACzQA,SAAS,WAAAC,gBAAuB;AAGzB,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,YAAY,OAAgB,KAAiC;AAC3E,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,QAAQ,MAAM,GAAG;AACvB,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAGO,SAAS,YACd,OACA,KACqC;AACrC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,QAAQ,MAAM,GAAG;AACvB,SAAO,SAAS,KAAK,IAAI,QAAQ;AACnC;AAGO,SAAS,SAAS,OAAyC;AAChE,SAAO,SAAS,KAAK,IAAI,QAAQ,CAAC;AACpC;AAOO,SAAS,WAAW,OAAoC;AAC7D,SAAO,SAAS,KAAK,KAAK,SAAS,MAAM,KAAK;AAChD;AAYO,SAAS,eACd,OAGY;AACZ,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,WAA4C,CAAC;AACnD,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACnD,UAAM,SAASA,SAAQ,YAAY,kBAAkB,UAAU,OAAO;AACtE,QAAI,OAAO,QAAS,UAAS,IAAI,IAAI,OAAO;AAAA,QACvC,SAAQ,KAAK,IAAI;AAAA,EACxB;AACA,SAAO,EAAE,UAAU,QAAQ;AAC7B;;;AFnDO,IAAM,sBAAsB;AAEnC,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAQF,IAAMC,eAAc;AAAA,EAClB,YAAYC,GACT,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EACvE,MAAMA,GACH,OAAO,EACP,SAAS,EACT,SAAS,sDAAsD;AAAA,EAClE,MAAMA,GACH,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,eAAeA,GACZ,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,2BAA2B,SAAgC;AACzE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,wBAAwB,SAAS,KAAK;AAAA,EAC5D;AACF;AAEA,eAAe,wBAAwB,SAAsB,OAAgB;AAC3E,QAAM,SAAS,eAAeF,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,YAAY,MAAM,MAAM,MAAM,cAAc,IAAI,OAAO;AAC/D,MAAI;AACF,UAAM,YAAY,MAAM,QAAQ,KAAK,UAAU;AAC/C,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAGA,UAAM,YAAY,OAAO,KAAK,UAAU,SAAS,CAAC,CAAC;AACnD,UAAM,WACJ,SAAS,UAAU,WAAW,IAAI,UAAU,CAAC,IAAI;AAEnD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,4DAA4D,UAAU,KAAK,IAAI,CAAC;AAAA,MAClF;AAAA,IACF;AAEA,UAAM,eAAe,UAAU,MAAM,QAAQ;AAC7C,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,SAAS,QAAQ,aAAa;AAAA,IAChD;AAqBA,UAAM,WAA0B,CAAC;AAEjC,UAAM,UAAU,CACd,cACA,MACA,MACA,WACkB;AAClB,YAAM,QAAuB,CAAC;AAC9B,iBAAW,CAAC,QAAQ,EAAE,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,YAAI,CAAC,iBAAiB,GAAG,WAAW,MAAO;AAC3C,cAAM,KAAK;AAAA,UACT,MAAM,GAAG,IAAI,IAAI,IAAI;AAAA,UACrB,UAAU;AAAA,UACV,UAAU;AAAA,UACV,aAAa;AAAA,UACb;AAAA,UACA,OAAO,GAAG;AAAA,UACV,aAAa,GAAG;AAAA,UAChB,QAAQ,GAAG;AAAA,UACX,OAAO,GAAG,OAAO;AAAA,UACjB,QAAQ,GAAG,QAAQ;AAAA,UACnB,YAAY,GAAG,YAAY;AAAA,UAC3B,YAAY,GAAG,YAAY;AAAA,UAC3B,GAAI,OACA;AAAA,YACE,IAAI,GAAG;AAAA,YACP,KAAK,GAAG;AAAA,YACR,SAAS,GAAG;AAAA,YACZ,SAAS,GAAG;AAAA,UACd,IACA,CAAC;AAAA,QACP,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAKA,UAAM,UAAU,kBAAkB;AAClC,UAAM,cAAc,OAClB,gBACyC;AACzC,UAAI;AACF,eAAO,MAAM,aAAa,aAAa;AAAA,UACrC;AAAA,UACA,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAIA,UAAM,iBAAiB,oBAAI,IAGzB;AACF,QAAI,kBAAkB;AACtB,UAAM,kBAA4B,CAAC;AACnC,UAAM,aAAa,CACjB,gBACyC;AACzC,YAAM,WAAW,eAAe,IAAI,WAAW;AAC/C,UAAI,SAAU,QAAO;AACrB,UAAI,eAAe,QAAQ,qBAAqB;AAC9C,0BAAkB;AAClB,eAAO,QAAQ,QAAQ,MAAS;AAAA,MAClC;AACA,YAAM,SAAS,YAAY,WAAW;AACtC,qBAAe,IAAI,aAAa,MAAM;AACtC,aAAO;AAAA,IACT;AAKA,UAAM,kBAAkB,CACtB,MACA,eACsC;AACtC,YAAM,WAAW;AAAA,QACf,EAAE,UAAU,KAAK,UAAU,gBAAgB,KAAK,eAAe;AAAA,QAC/D;AAAA,MACF;AACA,aAAO,eAAe,UAAU,IAAI;AAAA,IACtC;AAEA,UAAM,YAAY;AAAA,MAChB,EAAE,KAAK,WAAoB,MAAM,SAAkB;AAAA,MACnD,EAAE,KAAK,gBAAyB,MAAM,cAAuB;AAAA,MAC7D,EAAE,KAAK,gBAAyB,MAAM,cAAuB;AAAA,IAC/D;AAEA,eAAW,EAAE,KAAK,KAAK,KAAK,WAAW;AACrC,YAAM,OAAO,aAAa,GAAG,KAAK,CAAC;AACnC,iBAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAE9C,YAAI,QAAQ,GAAG,IAAI,IAAI,IAAI,OAAO,KAAM;AAGxC,YAAI,IAAI,UAAU;AAChB,mBAAS,KAAK,GAAG,QAAQ,IAAI,UAAU,MAAM,MAAM,QAAQ,CAAC;AAC5D;AAAA,QACF;AAIA,YAAI,CAAC,IAAI,QAAS;AAClB,cAAM,OAAO,MAAM,WAAW,IAAI,OAAO;AACzC,YAAI,CAAC,KAAM;AACX,cAAM,EAAE,WAAW,IAAI,kBAAkB,cAAc,MAAM,IAAI;AACjE,cAAM,kBAAkB,gBAAgB,MAAM,UAAU;AACxD,YAAI,CAAC,gBAAiB;AACtB,iBAAS;AAAA,UACP,GAAG,QAAQ,gBAAgB,UAAU,MAAM,MAAM,SAAS;AAAA,QAC5D;AACA,mBAAW,eAAe,gBAAgB;AACxC,0BAAgB,KAAK,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AAAA,MACzD;AAAA,IACF;AAEA,UAAM,SAAS;AAAA,MACb,MAAM;AAAA,MACN,OAAO,SAAS;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,WAAqB,CAAC;AAC5B,QAAI,SAAS,WAAW,GAAG;AACzB,eAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AACA,QAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAS;AAAA,QACP,WAAW,gBAAgB,MAAM,kEAAkE,gBAAgB,KAAK,IAAI,CAAC;AAAA,MAC/H;AAAA,IACF;AACA,QAAI,iBAAiB;AACnB,eAAS;AAAA,QACP,iDAAiD,mBAAmB;AAAA,MACtE;AAAA,IACF;AACA,UAAM,QAAiD;AAAA,MACrD,MAAM;AAAA,QACJ,QAAQ,WACJ,sDACA;AAAA,MACN;AAAA,MACA,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IAC5C;AACA,WAAOG,WAAU,QAAQ,KAAK;AAAA,EAChC,SAAS,OAAO;AACd,WAAOC;AAAA,MACL;AAAA,MACA,YAAY,OAAO,mDAA8C;AAAA,IACnE;AAAA,EACF;AACF;AAEO,SAAS,yBACd,QACA,SACA;AACA,QAAM,OAAO,2BAA2B,OAAO;AAC/C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,wBAAwB,SAAS,IAAI;AAAA,EACjD;AACF;;;AG5SA,SAAS,KAAAC,UAAS;AAElB,SAAS,gBAAAC,eAAc,aAAAC,YAAW,YAAAC,iBAAgB;AAClD,SAAS,yBAAyB;AAmBlC,IAAM,eAAe;AACrB,IAAM,qBACJ;AAIF,IAAM,oBAAoB;AAAA,EACxB,SAASC,GACN,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,GACH,KAAK,CAAC,UAAU,eAAe,eAAe,OAAO,CAAC,EACtD,SAAS,EACT,SAAS,sCAAsC;AAAA,EAClD,UAAUA,GACP,KAAK,CAAC,OAAO,QAAQ,CAAC,EACtB,SAAS,EACT,SAAS,+DAA+D;AAAA,EAC3E,SAASA,GACN,OAAO,EACP,SAAS,EACT,SAAS,uDAAuD;AACrE;AAEA,IAAM,oBAAoB;AAAA,EACxB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,8BAAwC;AACtD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS,CAAC,UAAU,yBAAyB,KAAK;AAAA,EACpD;AACF;AAEA,eAAe,yBAAyB,OAAgB;AACtD,QAAM,SAAS,eAAe,mBAAmB,KAAK;AACtD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,SAAS,aAAa,MAAM,UAAU,QAAQ,IAAI,OAAO;AACjE,QAAM,UAAU,kBAAkB;AAGlC,MAAI,CAAC,aAAa;AAChB,UAAM,EAAE,SAAS,SAAS,IAAI,MAAM,aAAa;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,SAAS,EAAE,SAAS,SAAS,OAAO,QAAQ,OAAO;AACzD,WAAOC,WAAU,QAAQ;AAAA,MACvB,MAAM,CAAC,0CAA0C;AAAA,MACjD,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAGA,MAAI;AACF,UAAM,OAAO,MAAMC,cAAa,aAAa;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,SAAS;AAAA,MACb,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,UAAU,kBAAkB,KAAK,QAAQ;AAAA,MACzC,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK;AAAA,IACzB;AAEA,WAAOD,WAAU,QAAQ;AAAA,MACvB,MAAM,CAAC,0CAA0C;AAAA,IACnD,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAOE;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BAA0B,QAAmB;AAC3D,QAAM,OAAO,4BAA4B;AACzC,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,yBAAyB,IAAI;AAAA,EACzC;AACF;AAIA,IAAM,YAAY;AAClB,IAAM,kBACJ;AAIF,IAAM,iBAAiB;AAAA,EACrB,SAASH,GACN,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC3E,SAASA,GACN,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,EACjC,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAM,iBAAiB;AAAA,EACrB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,2BAAqC;AACnD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS,CAAC,UAAU,sBAAsB,KAAK;AAAA,EACjD;AACF;AAEA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,kBACP,MAC6C;AAC7C,SAAO,mBAAmB,KAAK,CAAC,aAAa,aAAa,IAAI;AAChE;AAMA,SAAS,aACP,MACAI,UACyB;AACzB,QAAM,SAAkC,CAAC;AAEzC,MAAI,kBAAkB,IAAI,GAAG;AAC3B,UAAM,WAAW,YAAYA,UAAS,UAAU;AAChD,UAAM,cAAc,YAAYA,UAAS,aAAa;AACtD,WAAO,SAAS,kBAAkB,MAAM;AAAA,MACtC,GAAGA;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQA,QAAO,GAAG;AAClD,QAAI,QAAQ,WAAY,QAAO,GAAG,IAAI;AAAA,EACxC;AACA,SAAO;AACT;AAEA,eAAe,sBAAsB,OAAgB;AACnD,QAAM,SAAS,eAAe,gBAAgB,KAAK;AACnD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,SAAS,aAAa,SAAS,QAAQ,IAAI,OAAO;AAC1D,QAAM,UAAU,kBAAkB;AAElC,MAAI;AACF,UAAM,OAAO,MAAMF,cAAa,aAAa;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,SAAkC;AAAA,MACtC,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,UAAU,kBAAkB,KAAK,QAAQ;AAAA,MACzC,SAAS,aAAa,KAAK,MAAM,KAAK,OAAO;AAAA,IAC/C;AAGA,QAAI,KAAK,eAAe;AACtB,aAAO,gBAAgB,OAAO;AAAA,QAC5B,OAAO,QAAQ,KAAK,aAAa,EAAE,IAAI,CAAC,CAAC,MAAME,QAAO,MAAM;AAAA,UAC1D;AAAA,UACA,aAAa,KAAK,MAAMA,QAAO;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,KAAK,OAAO;AACd,UAAI,YAAY,WAAW,YAAY,OAAO;AAC5C,eAAO,QAAQ,KAAK;AAAA,MACtB,OAAO;AACL,cAAM,cAAgD,CAAC;AACvD,mBAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,KAAK,GAAG;AACpD,gBAAM,OAAO,YAAY,MAAM,MAAM;AACrC,cAAI,SAAS,OAAW,aAAY,GAAG,IAAI,EAAE,KAAK;AAAA,QACpD;AACA,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,YAAY,cAAc,YAAY,OAAO;AAC/C,aAAO,WAAW,KAAK;AAEvB,UAAI,KAAK,eAAgB,QAAO,iBAAiB,KAAK;AAAA,IACxD,OAAO;AACL,aAAO,mBAAmB,KAAK;AAAA,IACjC;AAEA,WAAOH,WAAU,MAAM;AAAA,EACzB,SAAS,OAAO;AACd,WAAOE;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,6BAA6B,QAAmB;AAC9D,QAAM,OAAO,yBAAyB;AACtC,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,sBAAsB,IAAI;AAAA,EACtC;AACF;;;ACjSA,SAAS,KAAAE,UAAS;AAElB,SAAS,aAAAC,YAAW,YAAAC,iBAAgB;;;AC2B7B,SAAS,sBAAsB,OAAyB;AAC7D,MAAI,EAAE,iBAAiB,OAAQ,QAAO;AACtC,MAAI,YAAY,SAAS,MAAM,WAAW,IAAK,QAAO;AACtD,SAAO,UAAU,SAAS,MAAM,SAAS;AAC3C;AAQO,SAAS,gBAAgB,OAAyB;AACvD,MAAI,EAAE,iBAAiB,OAAQ,QAAO;AACtC,MAAI,YAAY,SAAS,MAAM,WAAW,IAAK,QAAO;AACtD,SACE,UAAU,UACT,MAAM,SAAS,eAAe,MAAM,SAAS;AAElD;AAEO,IAAM,YACX;;;AC1CK,SAAS,aAAa,GAAmB;AAC9C,QAAM,iBACJ,EAAE,WAAW,aAAa,KAC1B,EAAE,SAAS,cAAc,KACzB,EAAE,MAAM,IAAI,GAAG,EAAE,QAAQ,cAAc,MAAM;AAC/C,MAAI,eAAgB,QAAO;AAC3B,QAAM,cAAc,EAAE,QAAQ,kBAAkB,eAAe;AAC/D,SAAO,cAAc,WAAW;AAClC;AAQA,IAAM,oBAAyC,oBAAI,IAAI;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,SAAS,iBAAiB,OAAyB;AACxD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AACpE,WAAO;AACT,QAAM,SAAmC,OAAO,QAAQ,KAAK;AAC7D,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,QAAQ;AACjC,QAAI,GAAG,IACL,kBAAkB,IAAI,GAAG,KAAK,OAAO,UAAU,WAC3C,aAAa,KAAK,IAClB;AAAA,EACR;AACA,SAAO;AACT;AAwBO,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,IAAM,iBAAiB,CAAC,QAC7B,gBAAgB,IAAI,GAAG;AAclB,SAAS,oBAAuB,OAAU,MAAyB;AACxE,SAAO,KAAK,OAAO,IAAI;AACzB;AAQO,SAAS,mBAAsB,OAAa;AACjD,SAAO,YAAY,KAAK;AAC1B;AAEA,SAAS,YAAY,OAAyB;AAC5C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,WAAW;AACtD,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,UAAI,kBAAkB,IAAI,CAAC,KAAK,OAAO,MAAM,UAAU;AACrD,YAAI,CAAC,IAAI,aAAa,CAAC;AAAA,MACzB,OAAO;AACL,YAAI,CAAC,IAAI,YAAY,CAAC;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,KAAK,OAAgB,MAA+B;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO,aAAa,KAAK;AACxD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC;AAC/D,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,UAAI,MAAM,OAAO,CAAC,KAAK,OAAO,MAAM,UAAU;AAC5C,YAAI,CAAC,IAAI;AAAA,MACX,OAAO;AACL,YAAI,CAAC,IAAI,KAAK,GAAG,IAAI;AAAA,MACvB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AC7IO,IAAM,2BACX;AASK,SAAS,sBACd,QACA,WACoB;AACpB,SAAO,aAAa,OAAO,kBAAkB,KAAK;AACpD;;;AHRA,IAAM,eAAe;AAAA,EACnB,SAAS;AAAA,EACT,OAAO;AAAA,IACL,SAAS;AAAA,MACP,QAAQ,EAAE,UAAU,OAAO,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE;AAAA,MACpD,SAAS,CAAC;AAAA,MACV,cAAc,CAAC;AAAA,IACjB;AAAA,EACF;AACF;AAEA,IAAM,kBAAkB;AAAA,EACtB,SAAS;AAAA,EACT,OAAO;AAAA,IACL,SAAS;AAAA,MACP,QAAQ,EAAE,UAAU,UAAU,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE;AAAA,MACvD,SAAS,CAAC;AAAA,MACV,cAAc,CAAC;AAAA,IACjB;AAAA,EACF;AACF;AAEA,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAKF,IAAMC,eAAc;AAAA,EAClB,QAAQC,GACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EAEF;AAAA,EACF,UAAUA,GACP,KAAK,CAAC,OAAO,QAAQ,CAAC,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EAEF;AACJ;AAEA,IAAM,eAAe;AAAA,EACnB,SAASA,GAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,EAClD,OAAOA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS,cAAc;AAClE;AAEA,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,uBACd,QACA,SACU;AACV,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,oBAAoB,QAAQ,SAAS,KAAK;AAAA,EAChE;AACF;AAEA,eAAe,oBACb,QACA,SACA,OACA;AACA,QAAM,SAAS,eAAeF,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,QAAQ,SAAS,IAAI,OAAO;AAKpC,MAAI,UAAU,UAAU,MAAM,GAAG;AAC/B,UAAM,oBAAoB,sBAAsB,QAAQ,MAAS;AACjE,QAAI,CAAC,mBAAmB;AACtB,aAAOG,UAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,IACrD;AACA,QAAI;AACF,YAAM,OAAO,MAAM,OAAO,QAAQ;AAAA,QAChC,QAAQ;AAAA,QACR,WAAW;AAAA,MACb,CAAC;AACD,aAAOC;AAAA,QACL,oBAAoB,aAAa,IAAI,GAAG,EAAE,MAAM,eAAe,CAAC;AAAA,QAChE;AAAA,UACE,MAAM,CAAC,8BAA8B,+BAA+B;AAAA,QACtE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAOD;AAAA,QACL;AAAA,QACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,QAAI,QAAQ;AAGV,YAAM,SAAS,MAAM,QAAQ,KAAK,MAAM;AACxC,aAAOC,WAAU,oBAAoB,QAAQ,EAAE,MAAM,eAAe,CAAC,GAAG;AAAA,QACtE,MAAM,CAAC,8BAA8B,+BAA+B;AAAA,MACtE,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,UAAU;AACb,aAAOD;AAAA,QACL,IAAI;AAAA,UACF;AAAA,QAEF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,aAAa,QAAQ,eAAe;AACrD,WAAOC,WAAU,UAAU;AAAA,MACzB,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,QAAI,iBAAiB,eAAgB,QAAOD,UAAS,OAAO,MAAM,IAAI;AACtE,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,QAAI,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,QAAQ;AACpD,aAAOA,UAAS,OAAO,mDAA8C;AACvE,WAAOA,UAAS,KAAK;AAAA,EACvB;AACF;AAEO,SAAS,qBACd,QACA,QACA,SACA;AACA,QAAM,OAAO,uBAAuB,QAAQ,OAAO;AACnD,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA;AAAA,MAElB;AAAA,MACA,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,oBAAoB,QAAQ,SAAS,IAAI;AAAA,EACrD;AACF;;;AIlLA,SAAS,KAAAE,UAAS;AAElB,SAAS,aAAAC,YAAW,YAAAC,kBAAgB;AAQpC,IAAMC,SAAQ;AACd,IAAMC,eAAc;AAEpB,IAAMC,eAAc;AAAA,EAClB,MAAMC,GAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,EAC9C,WAAWA,GACR,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,uBAAuB,QAA8B;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,oBAAoB,QAAQ,KAAK;AAAA,EACvD;AACF;AAEA,eAAe,oBAAoB,QAAoB,OAAgB;AACrE,QAAM,SAAS,eAAeF,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,MAAM,WAAW,kBAAkB,IAAI,OAAO;AACtD,MAAI;AACF,QAAI,YAAY,OAAO,sBAAsB;AAE7C,QAAI,cAAc,UAAa,sBAAsB,QAAW;AAC9D,aAAOG;AAAA,QACL,EAAE,cAAc,KAAK;AAAA,QACrB;AAAA,UACE,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,cAAc,UAAa,sBAAsB,QAAW;AAC9D,kBAAY;AACZ,aAAO,sBAAsB,SAAS;AAAA,IACxC;AAEA,UAAM,cAAc,qBAAqB,aAAa;AAEtD,UAAM,OAAO,eAAe,MAAM;AAAA,MAChC,WAAW;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAED,WAAOA,WAAU,EAAE,IAAI,KAAK,CAAC;AAAA,EAC/B,SAAS,OAAO;AACd,WAAOC,WAAS,KAAK;AAAA,EACvB;AACF;AAEO,SAAS,qBAAqB,QAAmB,QAAoB;AAC1E,QAAM,OAAO,uBAAuB,MAAM;AAC1C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,oBAAoB,QAAQ,IAAI;AAAA,EAC5C;AACF;;;ACzFA,SAAS,aAAAC,kBAAiB;AAC1B;AAAA,EACE,WAAW;AAAA,EACX;AAAA,EACA;AAAA,OACK;;;ACmBA,SAAS,iBAAiB,KAAqB;AACpD,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,GAAG;AAAA,EACtB,QAAQ;AACN,WAAO,qBAAqB,GAAG;AAAA,EACjC;AAEA,SAAO,SAAS;AAChB,SAAO,OAAO;AACd,SAAO,qBAAqB,OAAO,SAAS,CAAC;AAC/C;AAEA,SAAS,qBAAqB,OAAuB;AACnD,SAAO,MAAM,QAAQ,QAAQ,EAAE;AACjC;;;AD1BA,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAOF,IAAMC,eAAc,CAAC;AAErB,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,0BACd,QACA,gBACU;AACV,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOH;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAC;AAAA,IACA,SAAS,MAAM,uBAAuB,QAAQ,cAAc;AAAA,EAC9D;AACF;AAEA,eAAe,uBACb,QACA,gBACA;AAKA,QAAM,WAAW,OAAO,WAAW;AAWnC,QAAM,YAAY,kBAAkB;AACpC,QAAM,eACJ,cAAc,UAAa,iBAAiB,SAAS,MAAM,WACvD,QACA;AAON,QAAM,cAKD,OAAO,cACR,OAAO,YAAY,EAAE,MAAM,CAAC,WAAoB;AAAA,IAC9C,WAAW;AAAA,IACX,OAAO,aAAa,KAAK;AAAA,EAC3B,EAAE,IACF,QAAQ,QAAQ,EAAE,WAAW,MAAM,CAAC;AAMxC,QAAM,gBAA6C,OAAO,gBACtD,OACG,cAAc,EACd;AAAA,IAAM,CAAC,UACN;AAAA,MACE;AAAA,MACA;AAAA,MACA,0BAA0B,aAAa,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF,IACF,QAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEJ,QAAM,CAAC,QAAQ,QAAQ,IAAI,MAAM,QAAQ,IAAI,CAAC,aAAa,aAAa,CAAC;AAEzE,QAAM,cAAc,qBAAqB;AAEzC,QAAM,WAAqB,CAAC;AAC5B,MAAI,cAAc,QAAW;AAC3B,aAAS,KAAK,6CAA6C,YAAY,EAAE;AAAA,EAC3E;AACA,MAAI,CAAC,OAAO,aAAa;AACvB,aAAS,KAAK,gCAAgC;AAAA,EAChD,WAAW,CAAC,OAAO,WAAW;AAC5B,UAAM,MAAM,aAAa,mBAAmB,EAAE,SAAS,SAAS,CAAC;AACjE,aAAS,KAAK,OAAO,GAAG,YAAY,OAAO,SAAS,aAAa,EAAE;AAAA,EACrE;AAEA,QAAM,SAAS;AAAA,IACb,KAAK,EAAE,SAAS,eAAe;AAAA,IAC/B,KAAK,EAAE,SAAS,YAAY;AAAA,IAC5B,QAAQ,EAAE,UAAU,QAAQ,aAAa;AAAA,IACzC,KAAK;AAAA,MACH,WAAW,OAAO;AAAA,MAClB,GAAI,OAAO,WAAW,UAAa,EAAE,QAAQ,OAAO,OAAO;AAAA,MAC3D,GAAI,OAAO,YAAY,UAAa,EAAE,SAAS,OAAO,QAAQ;AAAA,IAChE;AAAA,IACA,UAAU,EAAE,gBAAgB,sBAAsB,GAAG,SAAS;AAAA,IAC9D,SAAS,cACL;AAAA,MACE,YAAY,YAAY;AAAA,MACxB,WAAW,YAAY;AAAA,MACvB,SAAS,YAAY;AAAA,IACvB,IACA,EAAE,YAAY,QAAW,WAAW,QAAW,SAAS,OAAU;AAAA,EACxE;AAEA,SAAOC,WAAU,QAAQ,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,MAAS;AACzE;AAEA,SAAS,aAAa,OAAwB;AAC5C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAGA,SAAS,gBACP,QACA,gBACA,QACoB;AACpB,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,wBACd,QACA,QACA,gBACA;AACA,QAAM,OAAO,0BAA0B,QAAQ,cAAc;AAC7D,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,MAAM,uBAAuB,QAAQ,cAAc;AAAA,EACrD;AACF;;;AEzLA,SAAS,KAAAC,UAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AAQpC,IAAMC,SAAQ;AACd,IAAMC,eACJ;AAIF,IAAM,qBACJ;AAGF,IAAM,sBACJ;AAQF,IAAM,sBAGF;AAAA,EACF,QACE;AAAA,EACF,KAAK;AAAA,EACL,MAAM;AACR;AAEA,IAAMC,eAAc;AAAA,EAClB,QAAQC,GACL,KAAK,CAAC,UAAU,SAAS,QAAQ,CAAC,EAClC,SAAS,kCAAkC;AAAA,EAC9C,YAAYA,GACT,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,eAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,mBAAmB,QAA8B;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,gBAAgB,QAAQ,KAAK;AAAA,EACnD;AACF;AAEA,eAAe,gBAAgB,QAAoB,OAAgB;AACjE,QAAM,SAAS,eAAeF,cAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,QAAQ,WAAW,IAAI,OAAO;AACtC,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK,UAAU;AACb,YAAI,CAAC,OAAO,iBAAiB,GAAG;AAC9B,iBAAOG;AAAA,YACL,EAAE,eAAe,MAAM;AAAA,YACvB,EAAE,MAAM,CAAC,8CAA8C,EAAE;AAAA,UAC3D;AAAA,QACF;AAGA,cAAM,OAAO,MAAM,OAAO,OAAO;AACjC,eAAOA,YAAU;AAAA,UACf,eAAe;AAAA,UACf,GAAG,mBAAmB,SAAS,IAAI,CAAC;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,SAAS;AACZ,YAAI,OAAO,iBAAiB,MAAM,QAAQ;AACxC,iBAAOA;AAAA,YACL,EAAE,eAAe,MAAM,SAAS,mBAAmB;AAAA,YACnD;AAAA,cACE,MAAM;AAAA,gBACJ;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,YAAI,YAAY;AACd,gBAAM,OAAO,MAAM,OAAO,aAAa,YAAY;AAAA,YACjD,WAAW;AAAA,UACb,CAAC;AAED,cAAI,KAAK,WAAW,MAAM;AACxB,mBAAOA;AAAA,cACL,EAAE,eAAe,KAAK;AAAA,cACtB;AAAA,gBACE,MAAM;AAAA,kBACJ;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAKA,cAAI,KAAK,WAAW,aAAa,KAAK,WAAW,aAAa;AAC5D,mBAAOA,YAAU;AAAA,cACf,eAAe;AAAA,cACf,QAAQ;AAAA,cACR,SACE,KAAK,WAAW,cACZ,gGACA;AAAA,cACN;AAAA,YACF,CAAC;AAAA,UACH;AAEA,cAAI,KAAK,WAAW;AAClB,mBAAOC,WAAS,IAAI,MAAM,2BAA2B,CAAC;AACxD,cAAI,KAAK,WAAW;AAClB,mBAAOA;AAAA,cACL,IAAI;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAEF,iBAAOA,WAAS,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,QACvC;AAEA,cAAM,OAAO,MAAM,OAAO,kBAAkB;AAC5C,cAAM,WAAW,KAAK;AAEtB,eAAOD,YAAU;AAAA,UACf,eAAe;AAAA,UACf,QAAQ;AAAA,UACR;AAAA,UACA,SAAS,gCAAgC,QAAQ;AAAA,UACjD,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,YAAI,OAAO,iBAAiB,MAAM,QAAQ;AACxC,iBAAOC,WAAS,IAAI,MAAM,mBAAmB,CAAC;AAAA,QAChD;AACA,cAAM,EAAE,SAAS,WAAW,IAAI,MAAM,OAAO,OAAO;AAGpD,cAAM,YAAY,OAAO,iBAAiB;AAC1C,YAAI,cAAc,MAAM;AACtB,iBAAOD,YAAU;AAAA,YACf,WAAW;AAAA,YACX,SAAS,oBAAoB,SAAS;AAAA,UACxC,CAAC;AAAA,QACH;AACA,YAAI;AACJ,YAAI,WAAW,YAAY;AACzB,oBACE;AAAA,QACJ,WAAW,SAAS;AAClB,oBAAU;AAAA,QACZ,WAAW,YAAY;AACrB,oBACE;AAAA,QACJ,OAAO;AACL,oBAAU;AAAA,QACZ;AACA,eAAOA,YAAU;AAAA,UACf,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,MAAM;AAAA,QAC3B;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOC,WAAS,KAAK;AAAA,EACvB;AACF;AAEO,SAAS,iBAAiB,QAAmB,QAAoB;AACtE,QAAM,OAAO,mBAAmB,MAAM;AACtC,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,gBAAgB,QAAQ,IAAI;AAAA,EACxC;AACF;;;ACpNA,SAAS,KAAAC,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;;;ACe7B,SAAS,oBACd,UACA,QACA,OACA,KACe;AACf,QAAM,OAAO,IAAI,MAAM;AACvB,MAAI,CAAC,KAAM,QAAO;AAClB,aAAW,SAAS,KAAK,YAAY,CAAC,GAAG;AACvC,QACE,MAAM,KAAK,MAAM,UACjB,MAAM,KAAK,MAAM,QACjB,MAAM,KAAK,MAAM,IACjB;AACA,aAAO,QAAQ,UAAU,QAAQ,OAAO,KAAK,IAAI;AAAA,IACnD;AAAA,EACF;AACA,aAAW,SAAS,KAAK,SAAS,CAAC,GAAG;AACpC,UAAM,YAAY,MAAM;AAAA,MACtB,CAAC,MAAM,MAAM,CAAC,MAAM,UAAa,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,MAAM;AAAA,IACrE;AACA,QAAI,CAAC,WAAW;AACd,aAAO,GAAG,QAAQ,YAAY,MAAM,sBAAsB,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,MAAM,KAAK,OAAO,EAAE;AAAA,IAChH;AAAA,EACF;AACA,SAAO;AACT;AAWO,SAAS,YACd,OACA,OACA,QACyB;AACzB,MAAI,UAAU,UAAa,UAAU,QAAQ,UAAU;AACrD,UAAM,IAAI,MAAM,GAAG,KAAK,oBAAoB,MAAM,UAAU;AAChE;AAEA,SAAS,QACP,MACA,QACA,OACA,MACQ;AAGR,SAAO,GAAG,KAAK,oBAAoB,MAAM,WAAW,OAAO,MAAM,OAAO,EAAE;AAC5E;AAEO,IAAM,2BAAiD;AAAA,EAC5D,KAAK;AAAA,IACH,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE;AAAA,EAC7B,cAAc;AAAA,IACZ,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,aAAa,EAAE,UAAU,CAAC,UAAU,WAAW,EAAE;AAAA,EACjD,gBAAgB;AAAA,IACd,UAAU,CAAC,QAAQ;AAAA,IACnB,OAAO,CAAC,CAAC,YAAY,gBAAgB,CAAC;AAAA,EACxC;AAAA,EACA,gBAAgB,EAAE,UAAU,CAAC,UAAU,WAAW,EAAE;AAAA,EACpD,iBAAiB,EAAE,UAAU,CAAC,UAAU,WAAW,EAAE;AACvD;AAEO,IAAM,6BAAmD;AAAA,EAC9D,QAAQ;AAAA,IACN,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AACF;AAEO,IAAM,6BAAmD;AAAA,EAC9D,MAAM;AAAA,IACJ,UAAU,CAAC,QAAQ;AAAA,IACnB,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH,UAAU,CAAC,UAAU,QAAQ,OAAO;AAAA,IACpC,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,UAAU,YAAY,OAAO;AAAA,IACxC,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,UAAU,UAAU;AAAA,IAC/B,MAAM;AAAA,EACR;AACF;AAEO,IAAM,8BAAoD;AAAA,EAC/D,KAAK;AAAA,IACH,UAAU,CAAC,WAAW;AAAA,IACtB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,aAAa,MAAM;AAAA,IAC9B,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,UAAU,CAAC,WAAW;AAAA,IACtB,MAAM;AAAA,EACR;AAAA,EACA,aAAa;AAAA,IACX,UAAU,CAAC,WAAW;AAAA,IACtB,MAAM;AAAA,EACR;AAAA,EACA,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE;AAC/B;AAEO,IAAM,4BAAkD;AAAA,EAC7D,MAAM;AAAA,IACJ,UAAU,CAAC,SAAS;AAAA,IACpB,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH,UAAU,CAAC,SAAS;AAAA,IACpB,MAAM;AAAA,EACR;AACF;;;ADxJA,IAAMC,UAAQ;AACd,IAAMC,eACJ;AAEF,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,KAAK,CAAC,QAAQ,OAAO,UAAU,UAAU,UAAU,aAAa,CAAC,EACjE,SAAS,sCAAsC;AAAA,EAClD,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,gDAAgD;AAAA,EAC5D,MAAMA,IACH,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAOA,IACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,6DAA6D;AAC3E;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,4BAA4B,QAA8B;AACxE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,yBAAyB,QAAQ,KAAK;AAAA,EAC5D;AACF;AAEA,eAAe,yBAAyB,QAAoB,OAAgB;AAC1E,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,QAAQ,WAAW,MAAM,QAAQ,MAAM,IAAI,OAAO;AAC1D,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,UAAU;AAAA,IACV,EAAE,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACA,MAAI,gBAAiB,QAAOG,WAAS,IAAI,MAAM,eAAe,CAAC;AAC/D,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK,QAAQ;AACX,cAAM,WAAW,MAAM,OAAO,aAAa,EAAE,QAAQ,MAAM,CAAC;AAC5D,cAAM,SAAS,SAAS,QAAQ,IAAI,SAAS,WAAW;AACxD,cAAM,QAAQ,MAAM,QAAQ,QAAQ,IAChC,WACA,MAAM,QAAQ,MAAM,IAClB,SACA,CAAC;AACP,YAAI,MAAM,WAAW,GAAG;AACtB,iBAAOC;AAAA,YACL,EAAE,UAAU,CAAC,EAAE;AAAA,YACf;AAAA,cACE,MAAM;AAAA,gBACJ;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,eAAOA,YAAU;AAAA,UACf,GAAG,SAAS,QAAQ;AAAA,UACpB,UAAU,MAAM,IAAI,gBAAgB;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,OAAO;AACV,cAAM,UAAU,MAAM,OAAO,WAAW,EAAE,UAAU,CAAC;AACrD,eAAOA,YAAU,iBAAiB,OAAO,CAAC;AAAA,MAC5C;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,MAAM,QAAQ,QAAQ;AAClC,cAAM,UAAU,MAAM,OAAO,cAAc,EAAE,KAAK,CAAC;AACnD,eAAOA,YAAU,iBAAiB,OAAO,GAAG;AAAA,UAC1C,MAAM;AAAA,YACJ;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,MAAM,QAAQ,QAAQ;AAClC,cAAM,UAAU,MAAM,OAAO,cAAc,EAAE,WAAW,KAAK,CAAC;AAC9D,eAAOA,YAAU,iBAAiB,OAAO,CAAC;AAAA,MAC5C;AAAA,MAEA,KAAK,UAAU;AACb,cAAM,UAAU,MAAM,OAAO,cAAc,EAAE,UAAU,CAAC;AACxD,eAAOA,YAAU,OAAO;AAAA,MAC1B;AAAA,MAEA,KAAK,eAAe;AAClB,oBAAY,WAAW,aAAa,aAAa;AACjD,eAAO,kBAAkB,SAAS;AAClC,eAAOA;AAAA,UACL,EAAE,kBAAkB,UAAU;AAAA,UAC9B;AAAA,YACE,MAAM;AAAA,cACJ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,MAAM;AAAA,QAC3B;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,0BACd,QACA,QACA;AACA,QAAM,OAAO,4BAA4B,MAAM;AAC/C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,yBAAyB,QAAQ,IAAI;AAAA,EACjD;AACF;;;AE9KA,SAAS,KAAAE,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;;;ACqC7B,SAAS,iBAAiB,SAA4B;AAC3D,QAAM,aAAmC,EAAE,MAAM,eAAe,GAAG,QAAQ;AAC3E,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,YAAY,MAAM,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,IACA,mBAAmB;AAAA,EAGrB;AACF;;;ACiCA,IAAM,kBAAkB;AAGxB,SAAS,eAAe,OAA0B;AAChD,SAAO,MAAM,MAAM,CAAC,SAAS,SAAS,EAAE;AAC1C;AAEA,SAAS,SAAS,QAA4C;AAC5D,QAAM,EAAE,SAAS,WAAW,OAAO,IAAI;AACvC,MAAI,CAAC,YAAY,SAAS,WAAW,MAAM,EAAG,QAAO;AACrD,SAAO,GAAG,OAAO,aAAa,mBAAmB,SAAS,CAAC,UAAU,mBAAmB,MAAM,CAAC;AACjG;AAMA,SAAS,SACP,QACA,MACA,SAAiC,CAAC,GACd;AACpB,QAAM,OAAO,SAAS,MAAM;AAC5B,MAAI,SAAS,OAAW,QAAO;AAC/B,QAAM,QAAQ,IAAI,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC;AACrD,SAAO,GAAG,IAAI,IAAI,MAAM,SAAS,CAAC;AACpC;AAEO,IAAM,QAAQ;AAAA;AAAA,EAEnB,KAAK,QAA4C;AAC/C,WAAO,SAAS,MAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,KAAK,QAA4C;AAC/C,UAAM,EAAE,MAAM,KAAK,IAAI;AACvB,QAAI,SAAS,GAAI,QAAO;AACxB,QAAI,SAAS,cAAc,KAAK,WAAW,eAAe;AACxD,aAAO,SAAS,QAAQ,UAAU;AACpC,QAAI,OAAO,SAAS,YAAY,SAAS,GAAI,QAAO;AACpD,WAAO,SAAS,QAAQ,QAAQ,EAAE,MAAM,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,QAAQ,QAA4C;AAClD,WAAO,SAAS,QAAQ,UAAU;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,OAAO,QAA8C;AACnD,QAAI,OAAO,eAAe,UAAW,QAAO;AAC5C,WAAO,SAAS,QAAQ,UAAU;AAAA,EACpC;AAAA;AAAA,EAGA,WAAW,QAAkD;AAC3D,UAAM,EAAE,SAAS,WAAW,aAAa,IAAI;AAC7C,QAAI,CAAC,YAAY,SAAS,WAAW,YAAY,EAAG,QAAO;AAC3D,WAAO,GAAG,OAAO,aAAa,mBAAmB,SAAS,CAAC,gBAAgB,mBAAmB,YAAY,CAAC;AAAA,EAC7G;AACF;;;AFvKA,SAAS,aAAa,SAAoC;AACxD,QAAM,QAAQ,YAAY,SAAS,OAAO;AAC1C,aAAW,QAAQ,OAAO,OAAO,SAAS,CAAC,CAAC,GAAG;AAC7C,UAAM,WAAW,YAAY,YAAY,MAAM,QAAQ,GAAG,UAAU;AACpE,QAAI,aAAa,SAAS,aAAa,SAAU,QAAO;AAAA,EAC1D;AACA,SAAO;AACT;AAqBA,SAAS,YACP,QACA,WACA,QACoB;AACpB,MAAI,WAAW,OAAW,QAAO;AACjC,SAAO,MAAM,KAAK,EAAE,SAAS,OAAO,WAAW,GAAG,WAAW,OAAO,CAAC;AACvE;AAQA,SAAS,aAAa,MAAwB;AAC5C,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,EAAE,OAAO,KAAK,IAAI,gBAAgB,EAAE;AACpE,QAAM,QAAQ,SAAS,IAAI,IAAI,KAAK,QAAQ;AAC5C,SAAO,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,IACxC,EAAE,GAAG,MAAM,OAAO,MAAM,IAAI,gBAAgB,EAAE,IAC9C,mBAAmB,IAAI;AAC7B;AAQA,SAAS,cAAc,OAAyB;AAC9C,QAAM,OAAO,iBAAiB,KAAK;AACnC,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,QAAM,EAAE,SAAS,MAAM,IAAI;AAC3B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,YAAY,UAAa,EAAE,SAAS,iBAAiB,OAAO,EAAE;AAAA,IAClE,GAAI,MAAM,QAAQ,KAAK,KAAK,EAAE,OAAO,MAAM,IAAI,gBAAgB,EAAE;AAAA,EACnE;AACF;AAUA,SAAS,WAAW,MAA+B;AACjD,QAAM,SAAkC,EAAE,GAAG,SAAS,IAAI,EAAE;AAC5D,QAAM,OAAO,YAAY,QAAQ,MAAM;AACvC,MAAI,SAAS,OAAW,QAAO,OAAO,aAAa,IAAI;AACvD,MAAI,OAAO,WAAW,QAAW;AAC/B,WAAO,SAAS,oBAAoB,OAAO,QAAQ;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,YAAY,QAAQ,IAAI;AAAA,IAC5B,MAAM,YAAY,QAAQ,MAAM;AAAA,IAChC,QAAQ,YAAY,QAAQ,QAAQ;AAAA,EACtC;AACF;AAEA,IAAMC,UAAQ;AACd,IAAMC,gBACJ;AAEF,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,KAAK;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACA,SAAS,mCAAmC;AAAA,EAC/C,QAAQA,IACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAOA,IAAE,OAAO,GAAGA,IAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SAAS,gDAAgD;AAAA,EAC5D,OAAOA,IACJ,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,MAAMA,IAAE,OAAO,CAAC,EAChB,SAAS,EACT,SAAS,4DAA4D;AAAA,EACxE,MAAMA,IACH,KAAK,CAAC,QAAQ,cAAc,YAAY,CAAC,EACzC,SAAS,EACT,SAAS,sBAAsB;AAAA,EAClC,OAAOA,IAAE,KAAK,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EACzE,gBAAgBA,IACb,QAAQ,EACR,SAAS,EACT,SAAS,6CAA6C;AAAA,EACzD,QAAQA,IACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAOA,IACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,6DAA6D;AAAA,EACzE,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAUA,IACP,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,gBAAgBA,IACb,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,mBAAmB,QAAQ;AAAA,IAC1BA,IAAE,OAAO,EAAE,MAAMA,IAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,IACrCA,IAAE,OAAO;AAAA,MACP,MAAMA,IAAE,QAAQ,oBAAoB;AAAA,MACpC,qBAAqBA,IAAE,OAAO;AAAA,IAChC,CAAC;AAAA,EACH,CAAC,EACA,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,MAAMA,IAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAWA,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,cAAc,MAAwC;AAC7D,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO,CAAC;AAC7B,QAAM,MAA+B,CAAC;AACtC,aAAW,SAAS,wBAAwB;AAC1C,QAAI,KAAK,KAAK,MAAM,OAAW,KAAI,KAAK,IAAI,KAAK,KAAK;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAwC;AACjE,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO,EAAE,UAAU,CAAC,EAAE;AAC3C,SAAO;AAAA,IACL,UAAU,MAAM,QAAQ,KAAK,QAAQ,IACjC,KAAK,SAAS,IAAI,aAAa,IAC/B,CAAC;AAAA,IACL,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,EAC1D;AACF;AAWA,eAAe,qBACb,QACA,QACA,WACwB;AACxB,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,aAAa;AAAA,MACvC;AAAA,MACA,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,MAC3C,OAAO;AAAA,IACT,CAAC;AACD,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,yBAAyB,QAA8B;AACrE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,sBAAsB,QAAQ,KAAK;AAAA,EACzD;AACF;AAEA,eAAe,sBAAsB,QAAoB,OAAgB;AACvE,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,OAAO;AACX,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,UAAU;AAAA,IACV,EAAE,QAAQ,WAAW,MAAM,WAAW,UAAU,eAAe;AAAA,IAC/D;AAAA,EACF;AACA,MAAI,gBAAiB,QAAOG,WAAS,IAAI,MAAM,eAAe,CAAC;AAC/D,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK,QAAQ;AACX,YAAI,WAAW;AACb,gBAAMC,QAAO,MAAM,OAAO,UAAU;AAAA,YAClC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AACD,iBAAOC,YAAU,aAAaD,KAAI,CAAC;AAAA,QACrC;AACA,cAAM,OAAO,MAAM,OAAO,aAAa;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAGD,cAAM,OAAO,MAAM,QAAQ,IAAI,IAC3B,KAAK,IAAI,aAAa,IACtB,mBAAmB,IAAI;AAC3B,eAAOC;AAAA,UACL,EAAE,UAAU,KAAK;AAAA,UACjB;AAAA,YACE,MAAM;AAAA,cACJ;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,KAAK,OAAO;AACV,oBAAY,QAAQ,UAAU,KAAK;AACnC,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,OAAO,MAAM,OAAO,QAAQ;AAAA,UAChC;AAAA,UACA,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AACD,cAAM,OAAO,WAAW,IAAI;AAC5B,cAAM,SAAS,YAAY,QAAQ,mBAAmB,KAAK,EAAE;AAC7D,eAAO,iBAAiB;AAAA,UACtB,QAAQ,KAAK;AAAA,UACb,YAAY,KAAK,QAAQ;AAAA,UACzB,UAAU,aAAa,KAAK,MAAM;AAAA,UAClC,YAAY,KAAK,UAAU,CAAC;AAAA,UAC5B,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,UACrC,aAAa;AAAA,YACX;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,iBAAiB,KAAK,EAAE;AAAA,cAChC,UAAU;AAAA,YACZ;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,qCAAqC,KAAK,EAAE;AAAA,YACtD;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,MAAM,QAAQ,QAAQ;AAClC,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,UAAU,MAAM,OAAO,WAAW;AAAA,UACtC;AAAA,UACA,SAAS,WAAW,CAAC;AAAA,UACrB,WAAW;AAAA,QACb,CAAC;AACD,cAAM,cAAc,WAAW,OAAO;AACtC,cAAM,gBAAgB;AAAA,UACpB;AAAA,UACA;AAAA,UACA,YAAY;AAAA,QACd;AACA,eAAO,iBAAiB;AAAA,UACtB,QAAQ,YAAY;AAAA,UACpB,YAAY,YAAY,QAAQ;AAAA,UAChC,UAAU,aAAa,YAAY,MAAM;AAAA,UACzC,YAAY,YAAY,UAAU,CAAC;AAAA,UACnC,GAAI,kBAAkB,UAAa,EAAE,QAAQ,cAAc;AAAA,UAC3D,aAAa;AAAA,YACX;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,iBAAiB,YAAY,EAAE;AAAA,cACvC,UAAU;AAAA,YACZ;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,eAAe,YAAY,EAAE;AAAA,YACvC;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AACtC,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,UAAU,MAAM,OAAO,WAAW;AAAA,UACtC;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA,YAAY,SAAS;AAAA,QACvB,CAAC;AACD,cAAM,cAAc,WAAW,OAAO;AACtC,eAAO,iBAAiB;AAAA,UACtB,QAAQ,YAAY;AAAA,UACpB,YAAY,YAAY,QAAQ;AAAA,UAChC,UAAU,aAAa,YAAY,MAAM;AAAA,UACzC,YAAY,YAAY,UAAU,CAAC;AAAA,UACnC,aAAa;AAAA,YACX;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,iBAAiB,YAAY,EAAE;AAAA,cACvC,UAAU;AAAA,YACZ;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,eAAe,YAAY,EAAE;AAAA,YACvC;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AACtC,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,UAAU,MAAM,OAAO,WAAW;AAAA,UACtC;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACD,eAAOE,YAAU,OAAO;AAAA,MAC1B;AAAA,MAEA,KAAK,aAAa;AAChB,oBAAY,QAAQ,UAAU,WAAW;AACzC,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,aAAa,MAAM,OAAO,cAAc;AAAA,UAC5C;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACD,eAAOE,YAAU,WAAW,UAAU,EAAE,MAAM;AAAA,MAChD;AAAA,MAEA,KAAK,gBAAgB;AACnB,oBAAY,QAAQ,UAAU,cAAc;AAC5C,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,OAAO,MAAM,OAAO,aAAa;AAAA,UACrC,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AACD,eAAOE,YAAU,kBAAkB,IAAI,CAAC;AAAA,MAC1C;AAAA,MAEA,KAAK,eAAe;AAClB,oBAAY,QAAQ,UAAU,aAAa;AAC3C,oBAAY,WAAW,aAAa,aAAa;AACjD,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,OAAO,MAAM,OAAO,WAAW;AAAA,UACnC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAOE,YAAU,cAAc,IAAI,CAAC;AAAA,MACtC;AAAA,MAEA,KAAK,kBAAkB;AACrB,oBAAY,QAAQ,UAAU,gBAAgB;AAC9C,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AAKA,cAAM,UAAU,MAAM,OAAO,cAAc;AAAA,UACzC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,UAC3B,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC/B,CAAC;AACD,eAAOE,YAAU,cAAc,OAAO,GAAG;AAAA,UACvC,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,kBAAkB;AACrB,oBAAY,QAAQ,UAAU,gBAAgB;AAC9C,oBAAY,WAAW,aAAa,gBAAgB;AACpD,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,cAAM,OAAO,MAAM,OAAO,cAAc;AAAA,UACtC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF,CAAC;AAID,eAAOE;AAAA,UACL,QAAQ,OAAO,SAAS,WACpB,OACA,EAAE,SAAS,MAAM,UAAU;AAAA,QACjC;AAAA,MACF;AAAA,MAEA,KAAK,mBAAmB;AACtB,oBAAY,QAAQ,UAAU,iBAAiB;AAC/C,oBAAY,WAAW,aAAa,iBAAiB;AACrD,cAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,YAAI,CAAC,mBAAmB;AACtB,iBAAOF,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,QACrD;AACA,YAAI,CAAC,OAAO,gBAAgB;AAC1B,iBAAOA;AAAA,YACL,IAAI,MAAM,iDAAiD;AAAA,UAC7D;AAAA,QACF;AAOA,cAAM,kBACJ,aACC,MAAM,qBAAqB,QAAQ,QAAQ,iBAAiB;AAI/D,cAAM,OAAO,MAAM,OAAO,eAAe;AAAA,UACvC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA,SAAS,WAAW,CAAC;AAAA,UACrB,GAAI,kBAAkB,EAAE,WAAW,gBAAgB,IAAI,CAAC;AAAA,QAC1D,CAAC;AACD,eAAOE,YAAU,cAAc,IAAI,GAAG;AAAA,UACpC,MAAM;AAAA,YACJ,kBACI,+MACA;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,MAAM;AAAA,QAC3B;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOF;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,uBAAuB,QAAmB,QAAoB;AAC5E,QAAM,OAAO,yBAAyB,MAAM;AAC5C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,sBAAsB,QAAQ,IAAI;AAAA,EAC9C;AACF;;;AGxpBA,SAAS,KAAAG,WAAS;AAGlB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;;;ACkC7B,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACxC,OAAO;AAAA,EAChB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EACzC,OAAO;AAAA,EACP;AAAA,EACT,YAAY,SAAiB,SAAyC;AACpE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAYA,eAAsB,sBAAsB,MAKxB;AAClB,QAAM,UAAU,MAAM,KAAK,KAAK;AAAA,IAC9B,WAAW,KAAK;AAAA,IAChB,QAAQ,KAAK;AAAA,EACf,CAAC;AAED,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI;AAAA,MACR,iCAAiC,KAAK,MAAM;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,QAAW;AAC3B,UAAM,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACpD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR,2BAA2B,KAAK,IAAI,YAAY,KAAK,MAAM;AAAA,MAC7D;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,QAAQ,CAAC,EAAE;AAAA,EACpB;AAEA,QAAM,IAAI;AAAA,IACR,QAAQ,KAAK,MAAM,QAAQ,QAAQ,MAAM;AAAA,IACzC,QAAQ,IAAI,CAAC,OAAO;AAAA,MAClB,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,WAAW,EAAE;AAAA,IACf,EAAE;AAAA,EACJ;AACF;;;ADtFA,IAAMC,UAAQ;AACd,IAAMC,gBACJ;AAUF,IAAM,sBAAsB;AAAA,EAC1B,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AACV;AAEA,IAAM,mBAAmB;AAAA,EACvB,KAAK;AAAA,EACL,QAAQ;AACV;AAGA,SAAS,UAA4B,SAAyC;AAC5E,SAAO,OAAO,KAAK,OAAO,EAAE;AAAA,IAAO,CAAC,QAClC,OAAO,OAAO,SAAS,GAAG;AAAA,EAC5B;AACF;AAEA,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,KAAK,CAAC,UAAU,QAAQ,OAAO,QAAQ,CAAC,EACxC,SAAS,8BAA8B;AAAA,EAC1C,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,EACtE,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC1E,MAAMA,IACH,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,KAAK,UAAU,gBAAgB,CAAC,EAChC,SAAS,EACT,SAAS,kCAAkC;AAAA,EAC9C,QAAQA,IACL,KAAK,UAAU,mBAAmB,CAAC,EACnC,SAAS,EACT,SAAS,yBAAyB;AAAA,EACrC,MAAMA,IACH,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAUA,IACP,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAOA,IACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,6DAA6D;AAC3E;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAYA,SAAS,kBAAkB,MAAmC;AAC5D,MAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI;AACjE,WAAO;AACT,QAAM,SAAkC,EAAE,GAAG,KAAK;AAClD,aAAW,OAAO,CAAC,MAAM,cAAc,GAAG;AACxC,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,OAAO,UAAU,YAAY,UAAU,GAAI,QAAO;AAAA,EACxD;AACA,SAAO;AACT;AAUA,SAAS,cACP,QACA,WACA,MACoB;AACpB,QAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,MAAI,sBAAsB,OAAW,QAAO;AAC5C,QAAM,eAAe,kBAAkB,IAAI;AAC3C,MAAI,iBAAiB,OAAW,QAAO;AACvC,SAAO,MAAM,WAAW;AAAA,IACtB,SAAS,OAAO,WAAW;AAAA,IAC3B,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAgBA,SAAS,WAAW,MAAe,QAAqC;AACtE,MACE,WAAW,UACX,SAAS,QACT,OAAO,SAAS,YAChB,MAAM,QAAQ,IAAI,GAClB;AACA,WAAO;AAAA,EACT;AACA,SAAO,EAAE,GAAG,MAAM,OAAO;AAC3B;AAGA,SAAS,sBAAsB,OAAgD;AAC7E,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO,CAAC;AAC9B,QAAM,OAAO,YAAY,OAAO,MAAM;AACtC,QAAM,OAAO,YAAY,OAAO,MAAM;AACtC,QAAM,SAAS,YAAY,OAAO,QAAQ;AAC1C,QAAM,YAAY,YAAY,OAAO,WAAW;AAChD,SAAO,SAAS,UACd,SAAS,UACT,WAAW,UACX,cAAc,SACZ,CAAC,EAAE,GAAG,OAAO,MAAM,MAAM,QAAQ,UAAU,CAAC,IAC5C,CAAC;AACP;AAEA,SAAS,gBACP,QACA,WAC4B;AAC5B,SAAO,OAAO,MAAM;AAClB,UAAM,OAAO,MAAM,OAAO,gBAAgB;AAAA,MACxC,WAAW,aAAa,EAAE,aAAa;AAAA,MACvC,QAAQ,EAAE;AAAA,IACZ,CAAC;AACD,UAAM,cAAc,SAAS,IAAI,IAAI,KAAK,cAAc;AACxD,WAAO,MAAM,QAAQ,WAAW,IAC5B,YAAY,QAAQ,qBAAqB,IACzC,CAAC;AAAA,EACP;AACF;AAEO,SAAS,2BAA2B,QAA8B;AACvE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,wBAAwB,QAAQ,KAAK;AAAA,EAC3D;AACF;AAEA,eAAe,wBAAwB,QAAoB,OAAgB;AACzE,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,OAAO;AACX,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,UAAU;AAAA,IACV,EAAE,QAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AACA,MAAI,gBAAiB,QAAOG,WAAS,IAAI,MAAM,eAAe,CAAC;AAC/D,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AAOtC,cAAM,SAAS,MAAM,OAAO,OAAO;AAAA,UACjC;AAAA,UACA;AAAA,UACA,MAAM,QAAQ;AAAA,UACd;AAAA,QACF,CAAC;AAKD,cAAM,SAAS,cAAc,QAAQ,WAAW,MAAM;AACtD,eAAOC,YAAU,WAAW,mBAAmB,MAAM,GAAG,MAAM,GAAG;AAAA,UAC/D,MAAM;AAAA,YACJ;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,QAAQ;AACX,cAAM,OAAO,MAAM,OAAO,gBAAgB;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAOA,YAAU,mBAAmB,IAAI,CAAC;AAAA,MAC3C;AAAA,MAEA,KAAK,OAAO;AACV,oBAAY,QAAQ,UAAU,KAAK;AACnC,cAAM,eAAe,MAAM,sBAAsB;AAAA,UAC/C,WAAW,aAAa;AAAA,UACxB;AAAA,UACA;AAAA,UACA,MAAM,gBAAgB,QAAQ,SAAS;AAAA,QACzC,CAAC;AACD,cAAM,OAAO,MAAM,OAAO,oBAAoB;AAAA,UAC5C,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AACD,cAAM,SAAS,cAAc,QAAQ,WAAW,IAAI;AACpD,eAAOA,YAAU,WAAW,mBAAmB,IAAI,GAAG,MAAM,CAAC;AAAA,MAC/D;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AACtC,cAAM,eAAe,MAAM,sBAAsB;AAAA,UAC/C,WAAW,aAAa;AAAA,UACxB;AAAA,UACA;AAAA,UACA,MAAM,gBAAgB,QAAQ,SAAS;AAAA,QACzC,CAAC;AACD,cAAM,OAAO,MAAM,OAAO,iBAAiB;AAAA,UACzC,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AACD,eAAOA;AAAA,UACL,mBAAmB;AAAA,YACjB,SAAS;AAAA,YACT,GAAG,SAAS,IAAI;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,MAAM;AAAA,QAC3B;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,QAAmB,QAAoB;AACxE,QAAM,OAAO,2BAA2B,MAAM;AAC9C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,wBAAwB,QAAQ,IAAI;AAAA,EAChD;AACF;;;AE9VA,SAAS,KAAAE,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AAgBpC,IAAMC,UAAQ;AACd,IAAMC,gBACJ;AAMF,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,KAAK,CAAC,QAAQ,OAAO,UAAU,QAAQ,CAAC,EACxC,SAAS,qCAAqC;AAAA,EACjD,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,OAAO,EACP;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO,EACP;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAOA,IACJ,OAAO,EACP,IAAI,CAAC,EACL,IAAI,KAAK,EACT,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAUA,IACP,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAEO,SAAS,2BAA2B,QAA8B;AACvE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,wBAAwB,QAAQ,KAAK;AAAA,EAC3D;AACF;AAEA,eAAe,wBAAwB,QAAoB,OAAgB;AACzE,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,QAAQ,WAAW,QAAQ,MAAM,OAAO,SAAS,IAAI,OAAO;AACpE,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,UAAU;AAAA,IACV,EAAE,QAAQ,MAAM,OAAO,SAAS;AAAA,IAChC;AAAA,EACF;AACA,MAAI,gBAAiB,QAAOG,WAAS,IAAI,MAAM,eAAe,CAAC;AAC/D,MAAI;AACF,UAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,QAAI,CAAC;AACH,aAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAErD,YAAQ,QAAQ;AAAA,MACd,KAAK,QAAQ;AACX,oBAAY,QAAQ,UAAU,MAAM;AACpC,cAAM,OAAO,MAAM,OAAO,YAAY;AAAA,UACpC,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AACD,eAAOC,YAAU,MAAM;AAAA,UACrB,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,OAAO;AACV,oBAAY,QAAQ,UAAU,KAAK;AACnC,oBAAY,MAAM,QAAQ,KAAK;AAC/B,oBAAY,OAAO,SAAS,KAAK;AACjC,cAAM,UAAU,MAAM,OAAO,aAAa;AAAA,UACxC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAED,eAAOA,YAAU,SAAS;AAAA,UACxB,MAAM,CAAC,wCAAwC,IAAI,GAAG;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AACtC,oBAAY,UAAU,YAAY,QAAQ;AAC1C,oBAAY,OAAO,SAAS,QAAQ;AACpC,cAAM,UAAU,MAAM,OAAO,aAAa;AAAA,UACxC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAOA,YAAU,OAAO;AAAA,MAC1B;AAAA,MAEA,KAAK,UAAU;AACb,oBAAY,QAAQ,UAAU,QAAQ;AACtC,oBAAY,UAAU,YAAY,QAAQ;AAC1C,cAAM,UAAU,MAAM,OAAO,aAAa;AAAA,UACxC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAOA;AAAA,UACL,WAAW,OAAO,YAAY,WAC1B,UACA,EAAE,SAAS,MAAM,SAAS;AAAA,QAChC;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,MAAM;AAAA,QAC3B;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,yBACd,QACA,QACA;AACA,QAAM,OAAO,2BAA2B,MAAM;AAC9C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,wBAAwB,QAAQ,IAAI;AAAA,EAChD;AACF;;;AC5LA,SAAS,KAAAE,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AASpC,IAAMC,UAAQ;AACd,IAAMC,gBACJ;AAQF,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,OAAO,EACP,SAAS,yDAAyD;AAAA,EACrE,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,EACtE,SAASA,IACN,OAAO,EACP,SAAS,EACT,SAAS,6CAA6C;AAAA,EACzD,OAAOA,IACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AA+BA,SAAS,sBAAsB,UAAgC;AAC7D,SAAO,SAAS,IAAI,CAAC,aAAa;AAAA,IAChC,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,QAAQ;AAAA,MACX,GAAI,QAAQ,MAAM,SAAS,UAAa;AAAA,QACtC,MAAM,oBAAoB,QAAQ,MAAM,IAAI;AAAA,MAC9C;AAAA,IACF;AAAA,IACA,MAAM,QAAQ,KAAK,IAAI,iBAAiB;AAAA,EAC1C,EAAE;AACJ;AAEA,SAAS,kBAAkB,KAA6B;AACtD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,IAAI,OAAO,UAAa,EAAE,IAAI,oBAAoB,IAAI,EAAE,EAAE;AAAA,IAC9D,GAAI,IAAI,QAAQ,UAAa,EAAE,KAAK,oBAAoB,IAAI,GAAG,EAAE;AAAA,IACjE,GAAI,IAAI,UAAU,UAAa,EAAE,OAAO,oBAAoB,IAAI,KAAK,EAAE;AAAA,IACvE,GAAI,IAAI,UAAU,UAAa,EAAE,OAAO,oBAAoB,IAAI,KAAK,EAAE;AAAA,IACvE,GAAI,IAAI,SAAS,UAAa,EAAE,MAAM,oBAAoB,IAAI,IAAI,EAAE;AAAA,IACpE,GAAI,IAAI,aAAa,UAAa;AAAA,MAChC,UAAU,IAAI,SAAS,IAAI,oBAAoB;AAAA,IACjD;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,QAAsC;AAClE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,OAAO,QAAQ,UAAa,EAAE,KAAK,oBAAoB,OAAO,GAAG,EAAE;AAAA,IACvE,GAAI,OAAO,UAAU,UAAa;AAAA,MAChC,OAAO,oBAAoB,OAAO,KAAK;AAAA,IACzC;AAAA,IACA,GAAI,OAAO,UAAU,UAAa;AAAA,MAChC,OAAO,oBAAoB,OAAO,KAAK;AAAA,IACzC;AAAA,EACF;AACF;AAEO,SAAS,8BAA8B,QAA8B;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,2BAA2B,QAAQ,KAAK;AAAA,EAC9D;AACF;AAEA,eAAe,2BAA2B,QAAoB,OAAgB;AAC5E,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM,EAAE,QAAQ,WAAW,SAAS,MAAM,IAAI,OAAO;AACrD,MAAI,CAAC,QAAQ;AACX,WAAOG,WAAS,IAAI,MAAM,0CAA0C,CAAC;AAAA,EACvE;AACA,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,aAAa;AAAA,MACvC;AAAA,MACA,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,MAC3C,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,MACvC,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,IACrC,CAAC;AASD,UAAM,OAAO;AAAA,MACX,WAAW,OAAO;AAAA,MAClB,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO;AAAA,MACpB,UAAU,sBAAsB,OAAO,QAAQ;AAAA,MAC/C,MAAM,OAAO;AAAA,MACb,GAAI,OAAO,iBAAiB,UAAa;AAAA,QACvC,cAAc,OAAO;AAAA,MACvB;AAAA,IACF;AACA,WAAOC,YAAU,MAAM;AAAA,MACrB,MACE,OAAO,cAAc,OACjB;AAAA,QACE;AAAA,MACF,IACA;AAAA,QACE;AAAA,MACF;AAAA,IACR,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,4BACd,QACA,QACA;AACA,QAAM,OAAO,8BAA8B,MAAM;AACjD,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,2BAA2B,QAAQ,IAAI;AAAA,EACnD;AACF;;;ACpMA,SAAS,KAAAE,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;;;ACC7B,IAAM,wBAAwB;AAKrC,SAAS,OAAO,OAAoC;AAClD,MAAI,EAAE,iBAAiB,UAAU,EAAE,UAAU,OAAQ,QAAO;AAC5D,QAAM,OAAO,MAAM;AACnB,SAAO,OAAO,SAAS,WAAW,OAAO;AAC3C;AAMO,SAAS,gBAAgB,OAAyB;AACvD,SAAO,OAAO,KAAK,MAAM;AAC3B;AAOO,SAAS,kBAAkB,SAA+B;AAC/D,SAAO,QAAQ,OAAO,oEAAoE,OAAO;AACnG;AAQO,SAAS,UACd,OACA,SACA,cACoB;AACpB,MAAI,gBAAgB,KAAK,EAAG,QAAO,kBAAkB,OAAO;AAC5D,MAAI,sBAAsB,KAAK,EAAG,QAAO;AACzC,MAAI,OAAO,KAAK,MAAM,YAAa,QAAO;AAC1C,SAAO;AACT;;;AD3BA,IAAMC,UAAQ;AAKP,IAAMC,gBACX;AAYK,IAAM,sBACX;AACK,IAAM,uBACX;AACK,IAAM,YACX;AACK,IAAM,YAAY;AAClB,IAAM,kBACX;AACK,IAAM,aACX;AACK,IAAM,iBACX;AAEF,IAAMC,gBAAc;AAAA,EAClB,QAAQC,IACL,KAAK,CAAC,SAAS,UAAU,MAAM,CAAC,EAChC;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,EAC/D,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,EACtE,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO;AAAA,IACN,WAAWA,IACR,QAAQ,IAAI,EACZ,SAAS,EACT;AAAA,MACC;AAAA,IACF;AAAA,IACF,SAASA,IACN,OAAO,EACP,SAAS,EACT;AAAA,MACC;AAAA,IACF;AAAA,EACJ,CAAC,EACA,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,MAAMA,IAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAOA,IACJ,KAAK,CAAC,OAAO,YAAY,OAAO,CAAC,EACjC,SAAS,EACT,SAAS,6DAA6D;AAAA,EACzE,SAASA,IACN,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAiBA,SAAS,aAAa,MAAgC;AACpD,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO,CAAC;AAC7B,QAAM,WAAW,KAAK;AACtB,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO,CAAC;AACtC,QAAM,UAA2B,CAAC;AAClC,aAAW,SAAS,UAAU;AAC5B,UAAM,OAAO,YAAY,OAAO,MAAM;AACtC,UAAM,WAAW,YAAY,OAAO,UAAU;AAC9C,QAAI,SAAS,OAAW;AACxB,QAAI,aAAa,SAAS,aAAa,SAAU;AACjD,YAAQ,KAAK,EAAE,MAAM,SAAS,CAAC;AAAA,EACjC;AACA,SAAO;AACT;AAUA,SAAS,oBACP,UACA,MACQ;AACR,MAAI,MAAM,YAAY,QAAW;AAC/B,UAAM,QAAQ,SAAS,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK,OAAO;AAClE,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,oCAAoC,KAAK,OAAO,iBAAiB,iBAAiB,QAAQ,CAAC;AAAA,MAC7F;AAAA,IACF;AACA,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,MAAM,cAAc,MAAM;AAC5B,UAAM,UAAU,SAAS,OAAO,CAAC,UAAU,MAAM,aAAa,QAAQ;AACtE,UAAM,OAAO,QAAQ,CAAC;AACtB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR,+FAA+F,iBAAiB,QAAQ,CAAC;AAAA,MAC3H;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,IAAI;AAAA,QACR,iFAAiF,iBAAiB,QAAQ,CAAC;AAAA,MAC7G;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAEA,QAAM,OAAO,SAAS,OAAO,CAAC,UAAU,MAAM,aAAa,KAAK;AAChE,QAAM,UAAU,KAAK,CAAC;AACtB,MAAI,WAAW,KAAK,WAAW,EAAG,QAAO,QAAQ;AACjD,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,IAAI;AAAA,MACR,8EAA8E,iBAAiB,QAAQ,CAAC;AAAA,IAC1G;AAAA,EACF;AAEA,QAAM,eAAe,SAAS,CAAC;AAC/B,MAAI,gBAAgB,SAAS,WAAW,EAAG,QAAO,aAAa;AAC/D,QAAM,IAAI;AAAA,IACR,gFAAgF,iBAAiB,QAAQ,CAAC;AAAA,EAC5G;AACF;AAEA,SAAS,iBAAiB,UAAmC;AAC3D,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,SAAO,SACJ,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,KAAK,MAAM,QAAQ,GAAG,EAClD,KAAK,IAAI;AACd;AAOA,SAAS,OAAO,SAA+B;AAC7C,SAAO;AAAA,IACL,SAAS;AAAA,MACP,UAAU,QAAQ,QAAQ;AAAA,MAC1B,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ,KAAK,iBAAiB;AAAA,MAC7C,gBAAgB,QAAQ,KAAK,kBAAkB;AAAA,IACjD;AAAA,IACA,WAAW;AAAA,MACT,UAAU,QAAQ,WAAW;AAAA,MAC7B,cAAc,QAAQ;AAAA,MACtB,UAAU,QAAQ,QAAQ,YAAY;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,UAAU,SAA+B;AAChD,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,cAAc,QAAQ;AAAA,IACtB,WAAW,QAAQ;AAAA,IACnB,iBAAiB,QAAQ;AAAA,IACzB,MAAM,OAAO,OAAO;AAAA,EACtB;AACF;AAEO,IAAM,4BACX;AAOF,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,OAAgB;AAC3C,UAAM,SAAS,EAAE,MAAM,CAAC;AACxB,SAAK,OAAO;AACZ,SAAK,OAAO,gBAAgB,OAAO,MAAM;AACzC,SAAK,UAAU,eAAe,OAAO,SAAS;AAAA,EAChD;AACF;AAEA,SAAS,gBAAgB,QAAiB,KAAiC;AACzE,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,EAAE,OAAO;AAC5D,WAAO;AACT,QAAM,QAAQ,QAAQ,IAAI,QAAQ,GAAG;AACrC,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,eAAe,QAAiB,KAAoC;AAC3E,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,EAAE,OAAO;AAC5D,WAAO;AACT,QAAM,QAAQ,QAAQ,IAAI,QAAQ,GAAG;AACrC,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ;AACxC;AAWA,eAAe,iBACb,QACA,SACwB;AACxB,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,aAAa;AAAA,MACvC,QAAQ,QAAQ;AAAA,MAChB,GAAI,QAAQ,cAAc,UAAa,EAAE,WAAW,QAAQ,UAAU;AAAA,MACtE,OAAO;AAAA,IACT,CAAC;AACD,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AAKd,QACE,sBAAsB,KAAK,KAC3B,gBAAgB,KAAK,KACrB,gBAAgB,KAAK;AAErB,YAAM;AACR,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAIpE,UAAM,IAAI;AAAA,MACR,GAAG,yBAAyB,KAAK,MAAM;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,6BAA6B,QAA8B;AACzE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAaC;AAAA,IACb,aAAAC;AAAA,IACA,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,0BAA0B,QAAQ,KAAK;AAAA,EAC7D;AACF;AAEA,eAAe,0BAA0B,QAAoB,OAAgB;AAC3E,QAAM,SAAS,eAAeF,eAAa,KAAK;AAChD,MAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,OAAO;AAEX,MAAI,CAAC,QAAQ;AACX,WAAOG,WAAS,IAAI,MAAM,yCAAyC,CAAC;AAAA,EACtE;AACA,QAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,MAAI,CAAC,mBAAmB;AACtB,WAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,EACrD;AAEA,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK,SAAS;AACZ,YAAI,CAAC,OAAO,qBAAqB;AAC/B,iBAAOA;AAAA,YACL,IAAI,MAAM,wDAAwD;AAAA,UACpE;AAAA,QACF;AACA,cAAM,WAAW;AAAA,UACf,MAAM,OAAO,QAAQ;AAAA,YACnB;AAAA,YACA,WAAW;AAAA,YACX,QAAQ,CAAC,UAAU;AAAA,UACrB,CAAC;AAAA,QACH;AACA,cAAM,eAAe,oBAAoB,UAAU,IAAI;AACvD,cAAM,UAAU,MAAM,OAAO,oBAAoB;AAAA,UAC/C,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,UACvC,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,UACnC,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,QACzC,CAAC;AACD,eAAOC,YAAU,UAAU,OAAO,GAAG;AAAA,UACnC,MAAM,CAAC,qBAAqB,sBAAsB,SAAS;AAAA,QAC7D,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,UAAU;AACb,YAAI,CAAC,OAAO,mBAAmB;AAC7B,iBAAOD;AAAA,YACL,IAAI;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,oBACJ,aACC,MAAM,iBAAiB,QAAQ;AAAA,UAC9B;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACH,YAAI,CAAC,mBAAmB;AACtB,iBAAOC;AAAA,YACL,EAAE,WAAW,MAAM,OAAO;AAAA,YAC1B,EAAE,MAAM,CAAC,gBAAgB,mBAAmB,EAAE;AAAA,UAChD;AAAA,QACF;AACA,cAAM,UAAU,MAAM,OAAO,kBAAkB;AAAA,UAC7C,WAAW;AAAA,UACX;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACD,eAAOA,YAAU,UAAU,OAAO,GAAG;AAAA,UACnC,MACE,QAAQ,oBAAoB,IACxB,CAAC,iBAAiB,WAAW,SAAS,IACtC,CAAC,WAAW,SAAS;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,MAEA,KAAK,QAAQ;AACX,YAAI,CAAC,OAAO,mBAAmB;AAC7B,iBAAOD;AAAA,YACL,IAAI,MAAM,uDAAuD;AAAA,UACnE;AAAA,QACF;AACA,cAAM,oBACJ,aACC,MAAM,iBAAiB,QAAQ;AAAA,UAC9B;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACH,YAAI,CAAC,mBAAmB;AACtB,iBAAOC;AAAA,YACL,EAAE,WAAW,MAAM,QAAQ,OAAO,MAAM;AAAA,YACxC,EAAE,MAAM,CAAC,cAAc,EAAE;AAAA,UAC3B;AAAA,QACF;AACA,cAAM,OAAO,kBAAkB;AAAA,UAC7B,WAAW;AAAA,UACX;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AACD,eAAOA;AAAA,UACL,EAAE,WAAW,mBAAmB,QAAQ,OAAO,KAAK;AAAA,UACpD,EAAE,MAAM,CAAC,UAAU,EAAE;AAAA,QACvB;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI;AAAA,UACR,mBAAmB,OAAO,MAAM,CAAC;AAAA,QACnC;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAOD;AAAA,MACL;AAAA,MACA,sBAAsB,KAAK,IAAI,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEO,SAAS,2BACd,QACA,QACA;AACA,QAAM,OAAO,6BAA6B,MAAM;AAChD,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,0BAA0B,QAAQ,IAAI;AAAA,EAClD;AACF;;;AEhdA,SAAS,KAAAE,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AAsDpC,IAAM,6BAA6B;AACnC,IAAM,wBAAwB;AAC9B,IAAM,0BAA0B;AAChC,IAAM,yBAAyB;AAC/B,IAAM,2BAA2B;AACjC,IAAM,mBAAmB;AACzB,IAAM,4BAA4B;AAClC,IAAM,wBAAwB;AAC9B,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,kBAAkB,CAAC,QAAQ,UAAU;AAE3C,IAAMC,UAAQ;AAMP,IAAM,yBACX;AAcF,IAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAgBA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWO,IAAM,0BAA0B;AAAA,EACrC,QAAQC,IACL,KAAK,SAAS;AAAA,IACb,OAAO,MAAM,+BAA+B,QAAQ,KAAK,IAAI,CAAC;AAAA,EAChE,CAAC,EACA,SAAS,oDAAoD;AAAA,EAChE,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAWA,IACR,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,eAAeA,IACZ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,MAAMA,IACH,OAAO,EAKP,KAAK,EACL,IAAI,CAAC,EACL,IAAI,0BAA0B,EAC9B,SAAS,EACT;AAAA,IACC,wBAAwB,0BAA0B;AAAA,EACpD;AAAA,EACF,OAAOA,IACJ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT;AAAA,IACC,0GAA0G,sBAAsB,6JAA6J,wBAAwB,oJAAoJ,yBAAyB;AAAA,EACpe;AAAA,EACF,QAAQA,IACL,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,SAAS,EACT,SAAS,2CAA2C;AAAA,EACvD,YAAYA,IACT,KAAK,iBAAiB,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAWA,IACR,OAAO,EACP,IAAI,CAAC,EACL,IAAI,qBAAqB,EACzB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,aAAaA,IACV,OAAO,EACP,IAAI,CAAC,EACL,IAAI,uBAAuB,EAC3B,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAUA,IACP,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,KAAK,eAAe,EACpB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAO,EACP,IAAI,CAAC,EACL,IAAI,qBAAqB,EACzB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAO,EACP,MAAM,gBAAgB,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,QAAQA,IACL,OAAO,EACP,IAAI,CAAC,EACL,IAAI,kBAAkB,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMC,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAOO,IAAM,uBACX;AACK,IAAM,gCACX;AACK,IAAM,wBACX;AACK,IAAM,uBACX;AACK,IAAM,sBACX;AACK,IAAM,2BACX;AACK,IAAM,uBACX;AACK,IAAM,oBACX;AACK,IAAM,wBACX;AACK,IAAM,6BACX;AACK,IAAM,yBACX;AACK,IAAM,+BAA+B,gEAAgE,yBAAyB;AAC9H,IAAM,6BACX;AACK,IAAM,+BACX;AACK,IAAM,yBACX;AACK,IAAM,8BACX;AACK,IAAM,yBACX;AACK,IAAM,0BACX;AACK,IAAM,2BACX;AACK,IAAM,0BACX;AACK,IAAM,qBACX;AACK,IAAM,uBACX;AACK,IAAM,2BACX;AACK,IAAM,iCACX;AACK,IAAM,2BACX;AACK,IAAM,2BACX;AACK,IAAM,4BACX;AACK,IAAM,+BACX;AACK,IAAM,sBACX;AACK,IAAM,qBACX;AAYF,IAAM,iBAAiBD,IAAE,OAAO,uBAAuB;AAYhD,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YACkB,MAChB,SACA;AACA,UAAM,OAAO;AAHG;AAIhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAMpB;AAEA,SAAS,aACP,OACA,MACA,QACG;AACH,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,IAAI,4BAA4B,MAAM;AAAA,IAC3C;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,WAAW,OAAiB,QAA4B;AAC/D,MAAI,MAAM,cAAc,OAAW,QAAO,EAAE,WAAW,MAAM,UAAU;AACvE,MAAI,MAAM,kBAAkB,QAAW;AACrC,WAAO,EAAE,eAAe,MAAM,cAAc;AAAA,EAC9C;AACA,QAAM,IAAI;AAAA,IACR;AAAA,IACA,sDAAsD,MAAM;AAAA,EAC9D;AACF;AAOA,SAAS,oBAAoB,YAAmC;AAC9D,SAAO;AAAA,IACL,WAAW,WAAW;AAAA,IACtB,WACE,WAAW,cAAc,OAAO,OAAO,aAAa,WAAW,SAAS;AAAA,IAC1E,kBACE,WAAW,qBAAqB,OAC5B,OACA,aAAa,WAAW,gBAAgB;AAAA,IAC9C,QAAQ,WAAW;AAAA,IACnB,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW;AAAA,EACxB;AACF;AAOA,SAAS,qBAAqB,SAA0B;AACtD,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ,QAAQ,IAAI,CAAC,WAAW;AAAA,MACvC,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,MACrB,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,IAChB,EAAE;AAAA,IACF,SAAS,QAAQ;AAAA,IACjB,WAAW,QAAQ;AAAA,IACnB,kBAAkB,QAAQ;AAAA;AAAA;AAAA,IAG1B,GAAI,QAAQ,eAAe,UAAa,EAAE,YAAY,QAAQ,WAAW;AAAA,EAC3E;AACF;AAOA,SAAS,gBAAgB,QAAuB;AAC9C,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,IAClB,aAAa,aAAa,OAAO,WAAW;AAAA,IAC5C,QAAQ,OAAO;AAAA;AAAA;AAAA,IAGf,qBAAqB,OAAO;AAAA,IAC5B,yBAAyB,OAAO;AAAA,IAChC,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,cAAc,OAAO;AAAA,IACrB,GAAI,OAAO,aAAa,SACpB;AAAA;AAAA;AAAA,MAGE,iBAAiB,OAAO,oBAAoB;AAAA,MAC5C,UAAU,OAAO,SAAS,IAAI,CAAC,aAAa;AAAA,QAC1C,QAAQ,QAAQ;AAAA,QAChB,MAAM,aAAa,QAAQ,IAAI;AAAA,QAC/B,WAAW,QAAQ;AAAA,MACrB,EAAE;AAAA,IACJ,IACA,CAAC;AAAA,EACP;AACF;AAeA,SAAS,mBAAmB,OAA2B;AACrD,QAAM,SAAS;AAAA,IACb,IAAI,MAAM;AAAA,IACV,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM;AAAA,IACjB,aAAa,aAAa,MAAM,WAAW;AAAA,IAC3C,SAAS,MAAM;AAAA;AAAA,IAEf,WAAW,MAAM,cAAc,OAAO,OAAO,aAAa,MAAM,SAAS;AAAA;AAAA,IAEzE,QAAQ,MAAM;AAAA,IACd,YAAY,MAAM;AAAA;AAAA,IAElB,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,QAAQ;AAAA,MACN,MAAM,MAAM,OAAO;AAAA,MACnB,IAAI,MAAM,OAAO;AAAA,MACjB,OAAO,aAAa,MAAM,OAAO,KAAK;AAAA,IACxC;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM;AAAA,EACnB;AAEA,MAAI,MAAM,SAAS,eAAe;AAChC,WAAO,EAAE,GAAG,QAAQ,MAAM,MAAM,MAAM,MAAM,aAAa,MAAM,IAAI,EAAE;AAAA,EACvE;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,MAAM;AAAA,IACZ,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM;AAAA,IACjB,cAAc,MAAM;AAAA,IACpB,GAAI,MAAM,aAAa,SACnB;AAAA;AAAA;AAAA,MAGE,iBAAiB,MAAM,oBAAoB;AAAA,MAC3C,UAAU,MAAM,SAAS,IAAI,CAAC,aAAa;AAAA,QACzC,QAAQ,QAAQ;AAAA,QAChB,MAAM,aAAa,QAAQ,IAAI;AAAA,QAC/B,WAAW,QAAQ;AAAA,MACrB,EAAE;AAAA,IACJ,IACA,CAAC;AAAA,EACP;AACF;AAEA,eAAe,eACb,QACA,WACA,QACA,OACA;AACA,QAAM,EAAE,UAAU,MAAM,IAAI,MAAM,OAAO,aAAa;AAAA,IACpD;AAAA,IACA;AAAA,IACA,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,WAAW,UAAa,EAAE,QAAQ,MAAM,OAAO;AAAA,EAC3D,CAAC;AAOD,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC3B,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAOE;AAAA,IACL;AAAA,MACE,UAAU,SAAS,IAAI,CAAC,aAAa;AAAA;AAAA;AAAA,QAGnC,WAAW,QAAQ;AAAA,QACnB,eAAe,QAAQ;AAAA,QACvB,YAAY,QAAQ;AAAA,QACpB,gBAAgB,QAAQ;AAAA;AAAA;AAAA;AAAA,QAIxB,mBAAmB,QAAQ;AAAA,QAC3B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ,YACf;AAAA,UACE,cAAc,QAAQ,UAAU;AAAA,UAChC,qBAAqB,QAAQ,UAAU;AAAA,UACvC,WACE,QAAQ,UAAU,cAAc,OAC5B,OACA,aAAa,QAAQ,UAAU,SAAS;AAAA,QAChD,IACA;AAAA,MACN,EAAE;AAAA,MACF;AAAA,MACA,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACvC;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,iBACb,QACA,WACA,QACA,OACA;AACA,QAAM,UAAU,MAAM,OAAO,WAAW;AAAA,IACtC;AAAA,IACA;AAAA,IACA,KAAK,WAAW,OAAO,aAAa;AAAA,EACtC,CAAC;AAOD,QAAM,mBACJ,QAAQ,SAAS,QAAQ,QAAQ,KAAK;AACxC,QAAM,aACJ,QAAQ,SAAS,QAAQ,QAAQ,KAAK,SAAS,MAAM,CAAC;AAExD,SAAOA;AAAA,IACL;AAAA,MACE,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,MACvB,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ,YACf,oBAAoB,QAAQ,SAAS,IACrC;AAAA,MACJ,MAAM,QAAQ,OACV;AAAA,QACE,eAAe,QAAQ,KAAK;AAAA,QAC5B,mBAAmB,QAAQ,KAAK;AAAA;AAAA;AAAA,QAGhC,MACE,QAAQ,KAAK,SAAS,KAAK,OAAO,aAAa,QAAQ,KAAK,IAAI;AAAA;AAAA,QAElE;AAAA,QACA,MAAM,aACF,kJACA;AAAA,MACN,IACA;AAAA,MACJ,iBAAiB,QAAQ,OACrB,OACA;AAAA,IACN;AAAA,IACA;AAAA,MACE,MAAM,aACF,CAAC,oBAAoB,IACrB,QAAQ,WAAW,YACjB,CAAC,mBAAmB,IACpB,CAAC,wBAAwB;AAAA,IACjC;AAAA,EACF;AACF;AAEA,eAAe,kBACb,QACA,WACA,QACA,OACA;AACA,QAAM,OAAO,aAAa,MAAM,MAAM,QAAQ,cAAc;AAE5D,QAAM,UAAU,MAAM,OAAO,gBAAgB;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,MAAM,SAAS,UAAa,EAAE,MAAM,MAAM,KAAK;AAAA,IACnD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,EACxD,CAAC;AAED,QAAM,OAAO,QAAQ,mBACjB,CAAC,oBAAoB,IACrB,QAAQ,QAAQ,WAAW,IACzB,CAAC,iBAAiB,IAClB,CAAC,qBAAqB;AAkB5B,QAAM,SAAS,QAAQ,QAAQ,CAAC;AAChC,QAAM,aAAa,WAAW,UAAa,OAAO,WAAW;AAC7D,QAAM,SAAS,aACX,MAAM,KAAK;AAAA,IACT,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ;AAAA,EAChB,CAAC,IACD;AAEJ,SAAOA;AAAA,IACL;AAAA,MACE,GAAG,qBAAqB,OAAO;AAAA,MAC/B,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACvC;AAAA,IACA,EAAE,KAAK;AAAA,EACT;AACF;AAQA,eAAe,eACb,QACA,WACA,QACA,OACA,QAC4B;AAC5B,SAAO,OAAO,WAAW;AAAA,IACvB;AAAA,IACA;AAAA,IACA,KAAK,WAAW,OAAO,MAAM;AAAA,EAC/B,CAAC;AACH;AAEA,eAAe,mBACb,QACA,WACA,QACA,OACA;AACA,QAAM,OAAO,aAAa,MAAM,MAAM,QAAQ,eAAe;AAC7D,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,aAAa,MAAM,OAAO,oBAAoB;AAAA,IAClD;AAAA,IACA;AAAA,IACA,WAAW,QAAQ;AAAA,IACnB;AAAA,EACF,CAAC;AAED,SAAOA;AAAA,IACL;AAAA,MACE,WAAW,WAAW;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,WAAW,oBAAoB,UAAU;AAAA,IAC3C;AAAA,IACA,EAAE,MAAM,CAAC,4BAA4B,sBAAsB,EAAE;AAAA,EAC/D;AACF;AAoBA,eAAe,cACb,QACA,WACA,QACA,OACA,QACgC;AAChC,QAAM,OAAO,MAAM,cAAc;AAEjC,MAAI,SAAS,WAAW;AACtB,QAAI,MAAM,cAAc,UAAa,MAAM,kBAAkB,QAAW;AACtE,UAAI,MAAM,cAAc,OAAW,QAAO;AAG1C,YAAM,QAAQ,MAAM,OAAO,WAAW;AAAA,QACpC;AAAA,QACA;AAAA,QACA,KAAK,EAAE,WAAW,MAAM,UAAU;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,WAAW,MAAM;AAAA,QACjB,aAAa,IAAI,MAAM,aAAa;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,WAAW,QAAQ;AAAA,MACnB,aAAa,IAAI,QAAQ,aAAa;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,MAAM,cAAc,OAAW,QAAO;AAC1C,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,WAAW,MAAM;AAAA,IACjB,aAAa,MAAM,eAAe,MAAM;AAAA,EAC1C;AACF;AAEA,eAAe,cACb,QACA,WACA,QACA,OACA;AACA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAKA,QAAM,EAAE,SAAS,eAAe,IAAI,MAAM,OAAO,YAAY;AAAA,IAC3D;AAAA,IACA;AAAA,IACA,iBAAiB,WAAW;AAAA,IAC5B,GAAI,WAAW,OACX,EAAE,YAAY,OAAO,YAAY,WAAW,OAAO,UAAU,IAC7D,CAAC;AAAA,IACL,GAAI,MAAM,WAAW,UAAa,EAAE,QAAQ,MAAM,OAAO;AAAA,IACzD,GAAI,MAAM,UAAU,UAAa;AAAA,MAC/B,OAAO,KAAK,IAAI,MAAM,OAAO,gBAAgB;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,QAAM,YAAY,QAAQ,KAAK,CAAC,WAAW,OAAO,oBAAoB,IAAI;AAK1E,QAAM,WAAW,iBAAiB,CAAC,4BAA4B,IAAI,CAAC;AAEpE,QAAM,OACJ,QAAQ,WAAW,IACf;AAAA,IACE,WAAW,OACP,6BACA;AAAA,EACN,IACA,WAAW,OACT,CAAC,GAAG,UAAU,sBAAsB,IACpC;AAAA,IACE,GAAG;AAAA,IACH,GAAI,YAAY,CAAC,2BAA2B,IAAI,CAAC;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AAMR,QAAM,aAAa,EAAE,SAAS,OAAO,WAAW,GAAG,WAAW,OAAO;AACrE,QAAM,SACJ,WAAW,OACP,MAAM,QAAQ,UAAU,IACxB,MAAM,OAAO,EAAE,GAAG,YAAY,YAAY,OAAO,WAAW,CAAC;AAEnE,SAAOA;AAAA,IACL;AAAA,MACE,SAAS,QAAQ,IAAI,eAAe;AAAA,MACpC;AAAA,MACA,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACvC;AAAA,IACA,EAAE,KAAK;AAAA,EACT;AACF;AAEA,eAAe,cACb,QACA,WACA,QACA,OACA;AACA,QAAM,OAAO,aAAa,MAAM,MAAM,QAAQ,UAAU;AAExD,MAAI,MAAM,aAAa,QAAW;AAChC,UAAMC,UAAS,MAAM,OAAO,iBAAiB;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AACD,WAAOD;AAAA,MACL,EAAE,QAAQ,gBAAgBC,OAAM,EAAE;AAAA,MAClC;AAAA,QACE,MAAM;AAAA,UACJ;AAAA,UACAA,QAAO,WAAW,aACd,0BACA;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,OAAO,aAAa;AAAA,IACvC;AAAA,IACA;AAAA,IACA,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA;AAAA;AAAA,IAGlB,GAAI,OAAO,eAAe,aAAa,EAAE,aAAa,OAAO,YAAY;AAAA,IACzE;AAAA,EACF,CAAC;AAED,SAAOD;AAAA,IACL,EAAE,QAAQ,gBAAgB,MAAM,EAAE;AAAA,IAClC,EAAE,MAAM,CAAC,sBAAsB,wBAAwB,EAAE;AAAA,EAC3D;AACF;AAEA,eAAe,gBACb,QACA,WACA,OACA;AAIA,QAAM,UAAU,MAAM,WAAW;AAIjC,QAAM,EAAE,SAAS,eAAe,IAAI,MAAM,OAAO,cAAc;AAAA,IAC7D;AAAA,IACA,iBAAiB;AAAA,IACjB,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,WAAW,UAAa,EAAE,QAAQ,MAAM,OAAO;AAAA,IACzD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,EACxD,CAAC;AAED,QAAM,YAAY,QAAQ;AAAA,IACxB,CAAC,UAAU,MAAM,SAAS,YAAY,MAAM,oBAAoB;AAAA,EAClE;AAEA,QAAM,WAAW,iBAAiB,CAAC,8BAA8B,IAAI,CAAC;AAEtE,QAAM,OACJ,QAAQ,WAAW,IACf,CAAC,wBAAwB,IACzB;AAAA,IACE,GAAG;AAAA,IACH,GAAI,UACA,YACE,CAAC,2BAA2B,IAC5B,CAAC,IACH,CAAC,wBAAwB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEN,SAAOA;AAAA,IACL,EAAE,SAAS,QAAQ,IAAI,kBAAkB,GAAG,eAAe;AAAA,IAC3D,EAAE,KAAK;AAAA,EACT;AACF;AAEA,eAAsB,iBAAiB,QAAoB,UAAmB;AAC5E,MAAI;AAKF,UAAM,SAAS,eAAe,UAAU,YAAY,CAAC,CAAC;AACtD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,aAAa,iBAAiB,mBAAmB,OAAO,KAAK,CAAC;AAAA,IAC1E;AACA,UAAM,QAAkB,OAAO;AAC/B,UAAM,EAAE,OAAO,IAAI;AAEnB,UAAM,YAAY,sBAAsB,QAAQ,MAAM,SAAS;AAC/D,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,aAAa,iBAAiB,wBAAwB;AAAA,IAClE;AAEA,QAAI,WAAW,aAAa;AAI1B,UAAI,MAAM,WAAW,QAAW;AAC9B,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO,MAAM,gBAAgB,QAAQ,WAAW,KAAK;AAAA,IACvD;AAEA,UAAM,SAAS,aAAa,MAAM,QAAQ,UAAU,MAAM;AAE1D,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,MAAM,eAAe,QAAQ,WAAW,QAAQ,KAAK;AAAA,MAC9D,KAAK;AACH,eAAO,MAAM,iBAAiB,QAAQ,WAAW,QAAQ,KAAK;AAAA,MAChE,KAAK;AACH,eAAO,MAAM,kBAAkB,QAAQ,WAAW,QAAQ,KAAK;AAAA,MACjE,KAAK;AACH,eAAO,MAAM,mBAAmB,QAAQ,WAAW,QAAQ,KAAK;AAAA,MAClE,KAAK;AACH,eAAO,MAAM,cAAc,QAAQ,WAAW,QAAQ,KAAK;AAAA,MAC7D,KAAK;AACH,eAAO,MAAM,cAAc,QAAQ,WAAW,QAAQ,KAAK;AAAA,IAC/D;AAAA,EACF,SAAS,OAAO;AAGd,WAAOE,WAAS,OAAO,UAAU,OAAO,OAAO,kBAAkB,CAAC;AAAA,EACpE;AACF;AAMO,SAAS,wBAAwB,QAA8B;AACpE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOL;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,iBAAiB,QAAQ,KAAK;AAAA,EACpD;AACF;AAEO,SAAS,sBAAsB,QAAmB,QAAoB;AAC3E,QAAM,OAAO,wBAAwB,MAAM;AAC3C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,iBAAiB,QAAQ,IAAI;AAAA,EACzC;AACF;;;ACrlCA,SAAS,KAAAI,WAAS;AAElB,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AA0CpC,IAAMC,oBAAmB;AACzB,IAAM,qBAAqB;AAE3B,IAAMC,UAAQ;AAMP,IAAM,2BACX;AAYK,IAAM,4BAA4B;AAAA,EACvC,QAAQC,IACL,KAAK,CAAC,QAAQ,QAAQ,KAAK,CAAC,EAC5B;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAO,EACP,IAAI,CAAC,EACL,IAAI,kBAAkB,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,IACN,OAAO,EACP,MAAMF,iBAAgB,EACtB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,IAAMG,gBAAc;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAOO,IAAM,8BACX;AACK,IAAM,qCACX;AACK,IAAM,sBACX;AACK,IAAM,wBACX;AACK,IAAM,4BACX;AACK,IAAM,0BACX;AACK,IAAM,0BACX;AACK,IAAM,uBACX;AAUF,IAAM,oBAAoB,CAAC,QACzB,QAAQ,UAAU,QAAQ;AAW5B,SAAS,cAAc,OAAsB;AAC3C,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,aAAa,MAAM,IAAI;AAAA,IAC7B,UAAU,MAAM;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,QAAQ,oBAAoB,MAAM,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAAA,IACrE,QAAQ,MAAM;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,YAAY,MAAM,WAAW,IAAI,CAAC,eAAe;AAAA,MAC/C,IAAI,UAAU;AAAA,MACd,MAAM,UAAU;AAAA,IAClB,EAAE;AAAA,IACF,MAAM,MAAM;AAAA,IACZ,YAAY,MAAM,aACd;AAAA,MACE,SAAS,MAAM,WAAW;AAAA,MAC1B,YAAY,MAAM,WAAW;AAAA,MAC7B,MAAM,MAAM,WAAW;AAAA,MACvB,KAAK,MAAM,WAAW;AAAA,MACtB,cAAc,MAAM,WAAW;AAAA,IACjC,IACA;AAAA,IACJ,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,WAAW,MAAM;AAAA,IACjB,WAAW,MAAM;AAAA,IACjB,WAAW,MAAM;AAAA,EACnB;AACF;AAEA,SAASC,UAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAkDA,IAAM,iBACJ;AAIF,IAAM,mBAAmB;AAIzB,IAAM,oBAAoB;AAE1B,IAAM,UAAU,CAAC,UACf,MAAM,UAAU,oBAAoB,eAAe,KAAK,KAAK;AAE/D,IAAM,aAAa,CAAC,UAA2B,kBAAkB,KAAK,KAAK;AAG3E,IAAM,gBAAiE,oBAAI,IAAI;AAAA;AAAA;AAAA,EAG7E,CAAC,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,EAId,CAAC,YAAY,OAAO;AAAA;AAAA;AAAA,EAGpB,CAAC,aAAa,UAAU;AAC1B,CAAC;AAKD,IAAM,iBAAkE,oBAAI;AAAA,EAC1E,CAAC,CAAC,aAAa,UAAU,CAAC;AAC5B;AAKA,IAAM,mBAAmB;AAIzB,IAAM,UAAU,CAAC,QACf,iBAAiB,KAAK,GAAG,IAAI,MAAM,aAAa,GAAG;AAIrD,SAAS,SAAS,OAAyB;AACzC,MAAI,OAAO,UAAU,SAAU,QAAO,aAAa,KAAK;AACxD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,QAAQ;AACnD,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,QAAQ,GAAG,CAAC,IAAI,SAAS,KAAK;AAAA,EACpC;AACA,SAAO;AACT;AAGA,SAAS,UAAU,OAAyD;AAC1E,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,QAAQ,UAAU,MAAM,QAAQ,KAAK,GAAG;AAC1C,UAAI,GAAG,IAAI,MAAM,IAAI,CAAC,QAAQ,cAAc,KAAK,aAAa,CAAC;AAAA,IACjE,WAAW,QAAQ,QAAQ;AACzB,UAAI,GAAG,IAAI,cAAc,OAAO,cAAc;AAAA,IAChD,OAAO;AACL,UAAI,QAAQ,GAAG,CAAC,IAAI,SAAS,KAAK;AAAA,IACpC;AAAA,EACF;AACA,SAAO;AACT;AASA,SAAS,cACP,OACA,WACS;AACT,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO,SAAS,KAAK;AAC3C,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAM,YAAY,UAAU,IAAI,GAAG;AACnC,QAAI,QAAQ,GAAG,CAAC,IACd,cAAc,UAAa,OAAO,UAAU,YAAY,UAAU,KAAK,IACnE,QACA,SAAS,KAAK;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAkB;AACxC,SAAO;AAAA,IACL,GAAG,cAAc,KAAK;AAAA,IACtB,OAAO,UAAU,MAAM,KAAK;AAAA,EAC9B;AACF;AAQA,IAAM,mBAAmBF,IAAE,OAAO,yBAAyB;AAW3D,eAAe,mBACb,QACA,UAC4B;AAG5B,QAAM,SAAS,iBAAiB,UAAU,YAAY,CAAC,CAAC;AACxD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAOG,WAAS,IAAI,MAAM,mBAAmB,OAAO,KAAK,CAAC,CAAC;AAAA,EAC7D;AACA,QAAM,EAAE,QAAQ,WAAW,SAAS,QAAQ,IAAI,OAAO;AACvD,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,EAAE,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AACA,MAAI,gBAAiB,QAAOA,WAAS,IAAI,MAAM,eAAe,CAAC;AAE/D,MAAI;AACF,UAAM,oBAAoB,sBAAsB,QAAQ,SAAS;AACjE,QAAI,CAAC,mBAAmB;AACtB,aAAOA,WAAS,IAAI,MAAM,wBAAwB,CAAC;AAAA,IACrD;AAEA,YAAQ,QAAQ;AAAA,MACd,KAAK,QAAQ;AACX,cAAM,EAAE,OAAO,IAAI,MAAM,OAAO,WAAW;AAAA,UACzC,WAAW;AAAA,QACb,CAAC;AACD,eAAOC;AAAA,UACL,EAAE,QAAQ,OAAO,IAAI,aAAa,EAAE;AAAA,UACpC;AAAA,YACE,MACE,OAAO,WAAW,IACd,CAAC,mBAAmB,IACpB;AAAA,cACE;AAAA,cACA;AAAA,YACF;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AACX,oBAAY,SAAS,WAAW,MAAM;AACtC,cAAM,EAAE,OAAO,IAAI,MAAM,OAAO,eAAe;AAAA,UAC7C,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AACD,eAAOA;AAAA,UACL,EAAE,SAAS,QAAQ,OAAO,IAAI,cAAc,EAAE;AAAA,UAC9C;AAAA,YACE,MACE,OAAO,WAAW,IACd,CAAC,uBAAuB,IACxB,CAAC,uBAAuB,yBAAyB;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,oBAAY,SAAS,WAAW,KAAK;AACrC,cAAM,QAAQ,MAAM,OAAO,SAAS;AAAA,UAClC,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AACD,eAAOA;AAAA,UACL,EAAE,OAAO,eAAe,KAAK,EAAE;AAAA,UAC/B;AAAA,YACE,MACE,MAAM,YAAY,OACd,CAAC,yBAAyB,yBAAyB,IACnD,CAAC,yBAAyB;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAGd,WAAOD,WAAS,OAAO,UAAU,OAAO,UAAU,oBAAoB,CAAC;AAAA,EACzE;AACF;AAMO,SAAS,0BAA0B,QAA8B;AACtE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOJ;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAAE;AAAA,IACA,SAAS,CAAC,UAAU,mBAAmB,QAAQ,KAAK;AAAA,EACtD;AACF;AAEO,SAAS,wBAAwB,QAAmB,QAAoB;AAC7E,QAAM,OAAO,0BAA0B,MAAM;AAC7C,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,MACE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,SAAS,mBAAmB,QAAQ,IAAI;AAAA,EAC3C;AACF;;;AC3cA,SAAS,wBAAwB;AAEjC,SAAS,0BAA0B;AAG5B,SAAS,+BAA+B,QAAmB;AAChE,QAAM,WAAW,IAAI,iBAAiB,mCAAmC;AAAA,IACvE,MAAM,YAAY;AAChB,YAAM,EAAE,QAAQ,IAAI,MAAM,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAC;AACvE,aAAO;AAAA,QACL,WAAW,QAAQ,IAAI,CAAC,SAAS;AAAA,UAC/B,KAAK,qBAAqB,mBAAmB,IAAI,IAAI,CAAC;AAAA,UACtD,MAAM,IAAI;AAAA,UACV,aAAa,2BAA2B,IAAI,IAAI;AAAA,UAChD,UAAU;AAAA,QACZ,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,KAAK,EAAE,YAAY,MAAM;AAC9B,YAAM,OAAO,MAAM;AAAA,QACjB,mBAAmB,WAAqB;AAAA,MAC1C;AACA,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,KAAK,IAAI,SAAS;AAAA,YAClB,UAAU;AAAA,YACV,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACnCA,SAAS,WAAAI,gBAAe;AAIxB,IAAM,cAAc;AAGpB,eAAe,YACb,QAC6C;AAC7C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,EACF;AACA,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,gBAAgB;AAC9C,WAAO;AAAA,MACL,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,MACtC,UAAU;AAAA,IACZ;AAAA,EACF,SAAS,OAAO;AACd,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,WAAO;AAAA,MACL,MAAM,iCAAiC,MAAM;AAAA,MAC7C,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEO,SAAS,2BACd,QACA,QACA;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK,UAAUC,SAAQ,kBAAkB,MAAM,CAAC;AAAA,UACtD,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK,UAAUA,SAAQ,iBAAiB,MAAM,CAAC;AAAA,UACrD,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK;AAAA,YACT;AAAA,cACE,OAAOA,SAAQ;AAAA,cACf,aAAaA,SAAQ;AAAA,cACrB,MAAMA,SAAQ;AAAA,cACd,QAAQA,SAAQ;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK,UAAUA,SAAQ,mBAAmB,MAAM,CAAC;AAAA,UACvD,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK;AAAA,YACT;AAAA,cACE,eACE;AAAA,cACF,UAAU;AAAA,gBACR,aACE;AAAA,gBACF,uBACE;AAAA,gBACF,aACE;AAAA,gBACF,qBACE;AAAA,gBACF,kBACE;AAAA,gBACF,uBACE;AAAA,gBACF,gBACE;AAAA,gBACF,kBACE;AAAA,gBACF,gBACE;AAAA,cACJ;AAAA,cACA,SAAS;AAAA,gBACP,UAAU;AAAA,kBACR;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,gBACA,SAAS;AAAA,kBACP,WAAW;AAAA,oBACT,QAAQ;AAAA,oBACR,SAAS,EAAE,IAAI,UAAU;AAAA,kBAC3B;AAAA,kBACA,OAAO;AAAA,oBACL,YAAY;AAAA,sBACV,cAAc;AAAA,wBACZ,KAAK;AAAA,0BACH,QAAQ;AAAA,4BACN,KAAK;AAAA,4BACL,QAAQ;AAAA,0BACV;AAAA,wBACF;AAAA,sBACF;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,MAAM,KAAK,UAAUA,SAAQ,oBAAoB,MAAM,CAAC;AAAA,UACxD,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,YAAY;AACV,UAAI;AACJ,UAAI;AACF,cAAM,EAAE,aAAa,IAAI,MAAM,OAAO,IAAI;AAC1C,cAAM,EAAE,cAAc,IAAI,MAAM,OAAO,QAAQ;AAC/C,cAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,cAAM,cACJA,SAAQ,QAAQ,2CAA2C;AAC7D,kBAAU,aAAa,aAAa,OAAO;AAAA,MAC7C,QAAQ;AACN,kBAAU,KAAK,UAAU,EAAE,OAAO,oBAAoB,CAAC;AAAA,MACzD;AACA,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,KAAK;AAAA,YACL,MAAM;AAAA,YACN,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,UAAU,CAAC,EAAE,KAAK,aAAa,GAAI,MAAM,YAAY,MAAM,EAAG,CAAC;AAAA,IACjE;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,YAAY;AACV,YAAM,EAAE,QAAQ,IAAI,MAAM,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAC;AACvE,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,KAAK;AAAA,YACL,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,YACrC,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvSA,SAAS,KAAAC,WAAS;AAGX,SAAS,sBAAsB,QAAmB;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAEF,YAAY;AAAA,QACV,UAAUA,IACP,OAAO,EACP,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,QACF,UAAUA,IACP,OAAO,EACP,SAAS,EACT,SAAS,sCAAsC;AAAA,MACpD;AAAA,IACF;AAAA,IACA,OAAO,EAAE,UAAU,SAAS,OAAO;AAAA,MACjC,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,cACJ,iBAAiB,YAAY,KAAK,mBAAmB,WAAW,OAAO,QAAQ,KAAK,EAAE;AAAA,cACtF;AAAA,cACA;AAAA,cACA,MAAM,WAAW,KAAK,wEAAwE;AAAA,cAC9F;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cAKA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,EAAE,KAAK,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACnEA,SAAS,KAAAC,WAAS;AAGX,SAAS,2BAA2B,QAAmB;AAC5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,YAAY;AAAA,QACV,UAAUA,IACP,OAAO,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,MACvE;AAAA,IACF;AAAA,IACA,OAAO,EAAE,SAAS,OAAO;AAAA,MACvB,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,cACJ,yBAAyB,WAAW,aAAa,QAAQ,WAAW,EAAE;AAAA,cACtE;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM,WAAW,6BAA6B,QAAQ,0BAA0B,GAAG;AAAA,cACnF;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,EAAE,KAAK,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AChDA,SAAS,KAAAC,WAAS;AAGX,SAAS,6BAA6B,QAAmB;AAC9D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,YAAY;AAAA,QACV,WAAWA,IACR,OAAO,EACP,SAAS,EACT;AAAA,UACC;AAAA,QAEF;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO,EAAE,UAAU,OAAO;AAAA,MACxB,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,cACJ,WAAW,cAAc,gBAAgB,sCAAsC,cAAc,kBAAkB,+CAA+C,wBAAwB;AAAA,cACtL;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc,kBACV,8IACA,cAAc,gBACZ,uHACA;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,EAAE,KAAK,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACrDO,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAnC,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AA4C1B,eAAsB,iBACpB,MACqB;AACrB,QAAM,aAAa,KAAK,YAAY,QAAQ;AAC5C,QAAM,UAAU,WAAW;AAE3B,QAAM,UAAU,MAAM,UAAU,cAAc;AAAA,IAC5C,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,gBAAgB,KAAK;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,MAAM,YAAY;AAChB,YAAM,KAAK,UAAU,UAAU;AAC/B,YAAM,QAAQ,KAAK,aAAa;AAAA,QAC9B,GAAG;AAAA,QACH,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,IACA,MAAM,WAAW,MAAM,SAAS,UAAU;AACxC,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,SAAS,QAAQ,WAAW;AAAA,QAC9B;AAAA,QACA,EAAE,KAAK;AAAA,MACT;AAAA,IACF;AAAA,IACA,MAAM,UAAU,MAAM;AACpB,YAAM,QAAQ,KAAK,eAAe,EAAE,KAAK,CAAC;AAAA,IAC5C;AAAA,EACF;AACF;;;AC5EA,SAAS,UAAU,OAAwB;AACzC,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,WAAO,IAAI,aAAa,WAAW,IAAI,aAAa;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAUA,SAAS,cAAc,OAAwB;AAC7C,SACE,QAAQ,KAAK,KAAK,KAClB,MAAM,WAAW,GAAG,KACpB,kBAAkB,KAAK,KAAK;AAEhC;AAeO,SAAS,oBAAoB,OAAgC;AAClE,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,UAAU,OAAO,EAAG,QAAO;AAC/B,MAAI,UAAU,OAAO,EAAG,QAAO;AAC/B,MAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG,EAAG,QAAO;AAC/D,MAAI,cAAc,OAAO,EAAG,QAAO;AACnC,SAAO;AACT;AAEA,IAAM,oBACJ;AAEF,SAAS,kBAAkC;AACzC,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAA4B;AACnC,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,SAA0B;AAC7C,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,IAAI,MAAM,iDAAiD,OAAO,EAAE;AAAA,EAC5E;AACF;AAaO,SAAS,oBACd,QACa;AACb,SAAO;AAAA,IACL,MAAM,KAAK,OAAO;AAChB,YAAM,UAAU,MAAM,KAAK;AAC3B,UAAI,YAAY,GAAI,OAAM,IAAI,MAAM,mBAAmB;AACvD,cAAQ,oBAAoB,OAAO,GAAG;AAAA,QACpC,KAAK;AACH,gBAAM,UAAU;AAAA,QAClB,KAAK;AACH,iBAAO,aAAa,MAAM,OAAO,QAAQ,EAAE,QAAQ,QAAQ,CAAC,CAAC;AAAA,QAC/D,KAAK;AACH,iBAAO,YAAY,OAAO;AAAA,QAC5B,KAAK;AACH,gBAAM,gBAAgB;AAAA,QACxB,KAAK;AAGH,gBAAM,IAAI;AAAA,YACR,mBAAmB,OAAO,wCAAwC,iBAAiB;AAAA,UACrF;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;;;A5ClDA,IAAI;AAEG,SAAS,yBAAiD;AAC/D,SAAO;AACT;AA2BA,SAAS,iCAAiC,QAAyB;AACjE,QAAM,WAAW;AAGjB,QAAM,QAAQ,SAAS;AACvB,MAAI,CAAC,MAAO;AACZ,aAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACpD,UAAM,WAAW,KAAK;AACtB,SAAK,UAAU,UAAU,SAAsC;AAC7D,YAAM,QAAQ,KAAK,IAAI;AACvB,UAAI;AACF,cAAM,SAAS,MAAM,SAAS,GAAG,IAAI;AACrC,cAAM,UAAU;AAChB,YAAI,SAAS;AACX,kBACG,WAAW,UAAU,WAAW,KAAK,IAAI,IAAI,KAAK,EAClD,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACnB;AACA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,UAAU;AAChB,YAAI,SAAS;AACX,kBACG,WAAW,UAAU,SAAS,KAAK,IAAI,IAAI,KAAK,EAChD,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACnB;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,wBAAwB,MAAsC;AAC5E,QAAM,iBAAiB,KAAK,WAAW;AACvC,QAAM,UAAU,KAAK,WAAW,oBAAoB,KAAK,MAAM;AAC/D,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,EAAE,cAAc,oBAAoB;AAAA,EACtC;AAEA,mBAAiB,QAAQ,KAAK,MAAM;AACpC,4BAA0B,QAAQ,KAAK,MAAM;AAC7C,yBAAuB,QAAQ,KAAK,MAAM;AAC1C,qBAAmB,QAAQ,KAAK,MAAM;AACtC,2BAAyB,QAAQ,KAAK,MAAM;AAC5C,6BAA2B,QAAQ,KAAK,MAAM;AAC9C,8BAA4B,QAAQ,KAAK,MAAM;AAC/C,wBAAsB,QAAQ,KAAK,MAAM;AACzC,0BAAwB,QAAQ,KAAK,MAAM;AAC3C,uBAAqB,QAAQ,KAAK,MAAM;AACxC,0BAAwB,QAAQ,KAAK,QAAQ,cAAc;AAE3D,2BAAyB,QAAQ,OAAO;AACxC,yBAAuB,QAAQ,KAAK,QAAQ,OAAO;AACnD,2BAAyB,QAAQ,KAAK,QAAQ,OAAO;AACrD,uBAAqB,QAAQ,OAAO;AACpC,2BAAyB,QAAQ,OAAO;AACxC,uBAAqB,QAAQ,KAAK,QAAQ,OAAO;AAEjD,4BAA0B,MAAM;AAChC,+BAA6B,MAAM;AAEnC,iCAA+B,MAAM;AACrC,6BAA2B,QAAQ,KAAK,MAAM;AAC9C,wBAAsB,MAAM;AAC5B,6BAA2B,MAAM;AACjC,+BAA6B,MAAM;AAEnC,mCAAiC,MAAM;AAOvC,QAAM,qBAAqB,OAAO,OAAO;AACzC,SAAO,OAAO,gBAAgB,MAAM;AAClC,QAAI;AACF,2BAAqB;AAAA,IACvB,QAAQ;AAAA,IAER;AACA,UAAM,aAAa,OAAO,OAAO,iBAAiB;AAClD,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA;AAAA,IACF,CAAC,EACE,KAAK,OAAO,YAAY;AACvB,uBAAiB;AACjB,YAAM,QAAQ,UAAU;AAAA,IAC1B,CAAC,EACA,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EACL;AAEA,SAAO;AACT;;;A6ClMA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAsDA,IAAM,iBAAN,MAA2C;AAAA,EAChD,MAAM,aAAa,SAGE;AACnB,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,WAAW,SAAmD;AAClE,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,cAAc,SAA6C;AAC/D,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA,EACA,MAAM,cAAc,SAGC;AACnB,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA,EACA,MAAM,cAAc,SAAmD;AACrE,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA;AAAA,EAEA,kBAAkB,WAAyB;AACzC,sBAAkB,SAAS;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAAmC;AACjC,WAAO,iBAAiB;AAAA,EAC1B;AAAA,EAEA,MAAM,aAAa,SAME;AACnB,WAAO,aAAa,OAA6C;AAAA,EACnE;AAAA,EACA,MAAM,UAAU,SAA6C;AAC3D,WAAO,UAAU,OAAO;AAAA,EAC1B;AAAA,EACA,MAAM,QAAQ,SAIO;AACnB,WAAO,QAAQ,OAAO;AAAA,EACxB;AAAA,EACA,MAAM,WAAW,SAII;AACnB,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,WAAW,SAMI;AACnB,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,WAAW,SAGI;AACnB,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,cAAc,SAIC;AACnB,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,SAAgD;AACjE,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,WAAW,SAA8C;AAC7D,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,cACJ,SACkB;AAKlB,WAAO,cAAc,EAAE,GAAG,SAAS,KAAK,QAAQ,OAAO,QAAQ,QAAQ,CAAC;AAAA,EAC1E;AAAA,EACA,MAAM,cAAc,SAAiD;AACnE,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA,EACA,MAAM,eAAe,SAAkD;AACrE,WAAO,eAAe,OAAO;AAAA,EAC/B;AAAA,EAEA,MAAM,YAAY,SAA+C;AAC/D,WAAO,YAAY,OAAO;AAAA,EAC5B;AAAA,EACA,MAAM,aAAa,SAAgD;AACjE,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,aAAa,SAAgD;AACjE,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,aAAa,SAAgD;AACjE,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAO,SAA0C;AACrD,WAAO,OAAO,OAAO;AAAA,EACvB;AAAA,EACA,MAAM,gBAAgB,SAAmD;AACvE,WAAO,gBAAgB,OAAO;AAAA,EAChC;AAAA,EACA,MAAM,oBAAoB,SAGL;AACnB,WAAO,oBAAoB,OAAO;AAAA,EACpC;AAAA,EACA,MAAM,iBAAiB,SAGF;AACnB,WAAO,iBAAiB,OAAO;AAAA,EACjC;AAAA,EAEA,MAAM,aAAa,SAKS;AAC1B,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBACJ,SAC+B;AAC/B,WAAO,oBAAoB,OAAO;AAAA,EACpC;AAAA,EACA,MAAM,kBACJ,SAC+B;AAC/B,WAAO,kBAAkB,OAAO;AAAA,EAClC;AAAA,EACA,MAAM,kBAAkB,SAA2C;AACjE,WAAO,kBAAkB,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,aAAa,SAKW;AAC5B,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,WAAW,SAIc;AAC7B,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,gBAAgB,SAMO;AAC3B,WAAO,gBAAgB,OAAO;AAAA,EAChC;AAAA,EACA,MAAM,oBAAoB,SAKS;AACjC,WAAO,oBAAoB,OAAO;AAAA,EACpC;AAAA,EACA,MAAM,YAAY,SAQW;AAC3B,WAAO,YAAY,OAAO;AAAA,EAC5B;AAAA,EACA,MAAM,aAAa,SAOQ;AACzB,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EACA,MAAM,iBAAiB,SAKI;AACzB,WAAO,iBAAiB,OAAO;AAAA,EACjC;AAAA,EACA,MAAM,cAAc,SAOW;AAC7B,WAAO,cAAc,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAM,WAAW,SAA4D;AAC3E,WAAO,WAAW,OAAO;AAAA,EAC3B;AAAA,EACA,MAAM,eAAe,SAGM;AACzB,WAAO,eAAe,OAAO;AAAA,EAC/B;AAAA,EACA,MAAM,SAAS,SAGQ;AACrB,WAAO,SAAS,OAAO;AAAA,EACzB;AAAA,EAEA,MAAM,oBAAkD;AACtD,WAAO,yBAAyB,cAAc,CAAC;AAAA,EACjD;AAAA,EACA,MAAM,aACJ,YACA,SAC4B;AAC5B,WAAO,oBAAoB,YAAY,OAAO;AAAA,EAChD;AAAA,EACA,MAAM,SAA2B;AAC/B,WAAO,OAAO;AAAA,EAChB;AAAA,EACA,mBAA4C;AAC1C,WAAO,iBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAIH;AACD,UAAM,SAAS,MAAM,OAAO;AAC5B,UAAM,aAAa,QAAQ,QAAQ,IAAI,cAAc;AACrD,WAAO,QAAQ,IAAI;AACnB,WAAO,EAAE,GAAG,QAAQ,WAAW;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,aAAqB;AACnB,WAAO,iBAAiB,cAAc,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAKH;AACD,UAAM,SAAS,MAAM,YAAY,KAAK,WAAW,CAAC;AAClD,WAAO;AAAA,MACL,WAAW,OAAO;AAAA,MAClB,GAAI,OAAO,WAAW,UAAa,EAAE,QAAQ,OAAO,OAAO;AAAA,MAC3D,GAAI,OAAO,eAAe,UAAa,EAAE,SAAS,OAAO,WAAW;AAAA,MACpE,GAAI,OAAO,UAAU,UAAa,EAAE,OAAO,OAAO,MAAM;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAA6C;AACjD,WAAO,gBAAgB;AAAA,MACrB,SAAS,KAAK,WAAW;AAAA,MACzB,QAAQ,EAAE,MAAM,OAAO,SAAS,QAAY;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBAAoC;AACxC,UAAM,SAAS,MAAM,aAAa,KAAK,WAAW,CAAC;AACnD,QAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,OAAO,OAAO,GAAG,KAAK,OAAO,KAAK,EAAE;AACpE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,eAAe,MAAc,SAA0C;AAC3E,UAAM,SAAS,MAAM,OAAO;AAAA,EAC9B;AAAA,EACA,wBAA6C;AAC3C,WAAO,sBAAsB;AAAA,EAC/B;AAAA,EACA,sBAAsB,WAA0B;AAC9C,0BAAsB,SAAS;AAAA,EACjC;AACF;;;ACvcA,YAAY,QAAQ;AACpB,YAAYC,WAAU;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAAC,iBAAgB;AAGzB,SAAS,WAAAC,gBAAe;;;AChBxB,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,OAAO,IAAI,iBAAiB;AACrC,SAAS,cAAc;AACvB,SAAS,cAAc;AAoBvB,IAAM,cAAc;AAIpB,IAAMC,SAAQ,oBAAI,IAAwB;AAI1C,IAAM,WAAW,oBAAI,IAA6B;AAElD,IAAI,oBAAoB;AAExB,SAAS,WAAW,gBAAgC;AAClD,SAAO,WAAW,QAAQ,EAAE,OAAO,cAAc,EAAE,OAAO,KAAK;AACjE;AAYA,SAAS,mBAAmB,gBAAiC;AAC3D,QAAM,UAAU,eAAe,UAAU;AACzC,MAAI,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,GAAG,EAAG,QAAO;AACjE,MAAI;AACF,SAAK,MAAM,cAAc;AACzB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAA+B;AACtC,MAAI,kBAAmB;AACvB,sBAAoB;AACpB,QAAM,UAAU,MAAM;AACpB,eAAW,SAASA,OAAM,OAAO,GAAG;AAElC,UAAI;AACF,eAAO,MAAM,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MACpD,QAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAAA,OAAM,MAAM;AAAA,EACd;AACA,UAAQ,KAAK,QAAQ,OAAO;AAC9B;AAEA,eAAe,gBAA+B;AAC5C,SAAOA,OAAM,OAAO,aAAa;AAC/B,UAAM,YAAYA,OAAM,KAAK,EAAE,KAAK,EAAE;AACtC,QAAI,cAAc,OAAW;AAC7B,UAAM,UAAUA,OAAM,IAAI,SAAS;AACnC,IAAAA,OAAM,OAAO,SAAS;AACtB,QAAI,QAAS,OAAM,GAAG,QAAQ,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACrE;AACF;AAqBA,eAAsB,iBACpB,gBAC6B;AAC7B,MAAI,CAAC,mBAAmB,cAAc,EAAG,QAAO;AAEhD,yBAAuB;AACvB,QAAM,MAAM,WAAW,cAAc;AAErC,QAAM,SAASA,OAAM,IAAI,GAAG;AAC5B,MAAI,QAAQ;AAEV,IAAAA,OAAM,OAAO,GAAG;AAChB,IAAAA,OAAM,IAAI,KAAK,MAAM;AACrB,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,UAAU,SAAS,IAAI,GAAG;AAChC,MAAI,QAAS,QAAO;AAEpB,QAAM,SAAS,YAAY;AACzB,UAAM,MAAM,KAAK;AAAA,MACf,GAAG,OAAO;AAAA,MACV,uBAAuB,IAAI,MAAM,GAAG,EAAE,CAAC;AAAA,IACzC;AACA,UAAM,GAAG,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC9C,UAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACpC,UAAM,aAAa,KAAK,KAAK,KAAK,UAAU;AAI5C,UAAM,UAAU,YAAY,IAAI,OAAO;AAOvC,UAAM,OAAO,gBAAgB;AAAA,MAC3B,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,gBAAgB,EAAE,QAAQ,YAAY,QAAQ,OAAO,QAAQ,MAAM;AAAA,IACrE,CAAC;AAED,IAAAA,OAAM,IAAI,KAAK,EAAE,YAAY,IAAI,CAAC;AAClC,UAAM,cAAc;AACpB,WAAO;AAAA,EACT,GAAG;AAEH,WAAS,IAAI,KAAK,KAAK;AACvB,MAAI;AACF,WAAO,MAAM;AAAA,EACf,UAAE;AACA,aAAS,OAAO,GAAG;AAAA,EACrB;AACF;;;ADpIO,SAAS,qBAAkC;AAChD,SAAO;AAAA,IACL,MAAM,CAAC,UAAU,eAAe,KAAK;AAAA,IAErC,QAAQ,OAAO;AACb,YAAM,OAAY,cAAQ,KAAK;AAC/B,aAAU,cAAW,IAAI,KAAQ,YAAS,IAAI,EAAE,OAAO,IAC9C,cAAQ,IAAI,IACjB;AAAA,IACN;AAAA,IAEA,QAAQ,CAAC,OAAO,SACdC,QAAO,OAAO;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,gBAAgB,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI;AAAA,IAC1D,CAAC;AAAA,IAEH,MAAM,SAAS,OAAO,MAAM;AAK1B,UAAI;AACJ,UAAI;AACF,qBAAa,MAAM,iBAAiB,KAAK;AAAA,MAC3C,QAAQ;AACN,qBAAa;AAAA,MACf;AACA,YAAM,SAAS,EAAE,YAAY,MAAM,KAAK,MAAM,QAAQ,KAAK;AAC3D,YAAM,SAAS,KAAK,UAAU;AAE9B,cAAQ,KAAK,UAAU;AAAA,QACrB,KAAK;AACH,iBAAO,eAAe,QAAQ,KAAK,OAAO;AAAA,YACxC,UAAU,KAAK;AAAA,YACf,GAAG;AAAA,YACH,SAAS,KAAK,OAAO;AAAA,UACvB,CAAC;AAAA,QACH,KAAK;AACH,iBAAO,oBAAoB,QAAQ,aAAa,KAAK,KAAK,GAAG;AAAA,YAC3D,eAAe,KAAK;AAAA,YACpB,GAAG;AAAA,YACH,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK,OAAO;AAAA,UACvB,CAAC;AAAA,QACH,KAAK;AACH,iBAAO,kBAAkB,QAAQ,aAAa,KAAK,KAAK,GAAG;AAAA,YACzD,eAAe,KAAK;AAAA,YACpB,GAAG;AAAA,YACH,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,UACf,CAAC;AAAA,QACH,KAAK;AACH,iBAAO,oBAAoB,QAAQ,YAAY,KAAK,KAAK,GAAG;AAAA,YAC1D,eAAe,KAAK;AAAA,YACpB,GAAG;AAAA,YACH,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK,OAAO;AAAA,YACrB,SAAS,KAAK;AAAA,UAChB,CAAC;AAAA,MACL;AAAA,IACF;AAAA,IAEA,cAAc,OAAO,UACnB,oBAAoB,MAAM,eAA0B,KAAK,CAAC;AAAA,IAE5D,MAAM,QAAQ,OAAO;AAInB,YAAM,UAAU,MAAM,WAAW,OAAO,EAAE,MAAM,MAAM,CAAC;AACvD,YAAM,SACJ,OAAO,YAAY,WAAW,UAAU,OAAO,IAAI;AACrD,UAAI,CAAC,WAAW,MAAM,EAAG,QAAO,EAAE,cAAc,CAAC,EAAE;AACnD,aAAO,EAAE,QAAQ,cAAc,oBAAoB,MAAM,EAAE;AAAA,IAC7D;AAAA,IAEA,MAAM,CAAC,OAAO,OAAO,SACnB,KAAK,OAAO,OAAO;AAAA,MACjB,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,GAAI,KAAK,WAAW,UAAa,EAAE,KAAK,KAAK,OAAO;AAAA,IACtD,CAAC;AAAA,EACL;AACF;AAMA,SAAS,aAAa,OAA2C;AAC/D,MAAI,eAAe,KAAK,EAAG,QAAO;AAClC,QAAM,SAASC,SAAQ,mBAAmB,UAAU,KAAK;AACzD,QAAM,IAAI,MAAM,OAAO,OAAO,WAAW,eAAe;AAC1D;AAEA,SAAS,eAAe,OAAoD;AAC1E,SAAOA,SAAQ,mBAAmB,UAAU,KAAK,EAAE;AACrD;AAGA,SAAS,YAAY,OAAyC;AAC5D,MAAIC,UAAS,KAAK,EAAG,QAAO;AAC5B,QAAM,IAAI,MAAM,0BAA0B;AAC5C;AAEA,SAAS,UAAU,SAA0B;AAC3C,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;A/CtIA,iBAAiB,EAAE,MAAM,OAAO,SAAS,QAAY,CAAC;AAOtD,QAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,QAAM,UAAU,uBAAuB;AACvC,MAAI,SAAS;AACX,YAAQ,UAAU,UAAU,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC9C;AACA,UAAQ,MAAM,0CAA0C,GAAG;AAC7D,CAAC;AAED,QAAQ,GAAG,sBAAsB,CAAC,WAAW;AAC3C,QAAM,UAAU,uBAAuB;AACvC,MAAI,SAAS;AACX,YAAQ,UAAU,oBAAoB,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACxD;AACA,UAAQ,MAAM,2CAA2C,MAAM;AACjE,CAAC;AAED,eAAe,OAAO;AAGpB,QAAM,SAAS,wBAAwB;AAAA,IACrC,QAAQ,IAAI,eAAe;AAAA,IAC3B,SAAS;AAAA,IACT,SAAS,mBAAmB;AAAA,EAC9B,CAAC;AACD,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAC9B,UAAQ,MAAM,2CAA2C;AAC3D;AAEA,KAAK,EAAE,MAAM,OAAO,UAAU;AAI5B,MAAI;AACF,UAAM,UAAU,MAAM,iBAAiB;AAAA,MACrC,YAAY;AAAA,MACZ,gBAAgB;AAAA,IAClB,CAAC;AACD,UAAM,QAAQ,UAAU,SAAS;AAAA,EACnC,QAAQ;AAAA,EAER;AACA,UAAQ,MAAM,oCAAoC,KAAK;AACvD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["path","schemas","mcpResult","mcpError","z","mcpError","TITLE","DESCRIPTION","inputSchema","schemas","annotations","mcpError","mcpResult","z","schemas","mcpResult","mcpError","isObject","mcpResult","TITLE","inputSchema","schemas","z","annotations","mcpError","errorMessage","mcpResult","require","z","schemas","mcpError","TITLE","DESCRIPTION","inputSchema","schemas","z","annotations","mcpError","z","mcpResult","mcpError","schemas","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","z","fetchPackage","mcpResult","mcpError","z","mcpResult","fetchPackage","mcpError","schemas","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","mcpResult","TITLE","DESCRIPTION","inputSchema","annotations","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpResult","mcpError","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","data","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","DESCRIPTION","inputSchema","z","annotations","mcpError","mcpResult","z","mcpResult","mcpError","TITLE","z","annotations","mcpResult","thread","mcpError","z","mcpResult","mcpError","FRAME_ID_PATTERN","TITLE","z","annotations","isRecord","mcpError","mcpResult","schemas","schemas","require","z","z","z","path","bundle","isObject","schemas","cache","bundle","schemas","isObject"]}