effect-codemode 0.0.1 → 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/testing.ts", "../src/bridge.ts", "../src/sanitize.ts", "../src/typegen.ts", "../src/types.ts", "../src/codemode.ts", "../src/executor.ts", "../src/executor-base.ts", "../src/registry.ts"],
4
+ "sourcesContent": [
5
+ "import { Effect, Layer } from \"effect\"\n\nimport type { CodemodeTool } from \"./codemode\"\nimport { createCodemodeTool } from \"./codemode\"\nimport { CodeExecutor } from \"./executor\"\nimport { CodemodeRegistry } from \"./registry\"\nimport { generateDeclarations, type ToolDescriptor as TypegenDescriptor } from \"./typegen\"\nimport type { ToolDescriptor } from \"./types\"\nimport { toTypegenDescriptor } from \"./types\"\n\n/**\n * Shared helper: build a registry from group layers, snapshot it, and merge\n * all available tools. Returns the merged tools, status text, and group names.\n *\n * Used by both `buildTestTool` and `buildInspector` to avoid duplication.\n */\nfunction snapshotGroups(groups: ReadonlyArray<Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>>) {\n return Effect.gen(function* () {\n // Create a fresh registry\n const registryImpl = yield* CodemodeRegistry.make\n\n // Build and run all group layers against this registry\n const registryLayer = Layer.succeed(CodemodeRegistry, registryImpl)\n const mergedGroups =\n groups.length === 1\n ? groups[0]!\n : Layer.mergeAll(\n ...(groups as [\n Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>,\n Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>,\n ...Array<Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>>,\n ]),\n )\n const fullLayer = Layer.provide(mergedGroups, registryLayer)\n\n // Build the layer to trigger group registrations\n yield* Layer.build(fullLayer).pipe(Effect.scoped)\n\n // Read the snapshot\n const { available, failed } = yield* registryImpl.snapshot\n\n // Merge all available tools\n const allTools: Record<string, ToolDescriptor> = {}\n for (const group of available) {\n for (const [key, tool] of Object.entries(group.tools)) {\n allTools[key] = { ...tool, service: group.name }\n }\n }\n\n // Build status text\n const statusParts: string[] = []\n for (const g of available) {\n statusParts.push(` ${g.name}: available`)\n }\n for (const f of failed) {\n statusParts.push(` ${f.name}: unavailable (${f.error})`)\n }\n const statusText = statusParts.join(\"\\n\")\n const groupNames = available.map((g) => g.name)\n\n return { allTools, statusText, groupNames }\n })\n}\n\n/**\n * Build a CodemodeTool from group layers synchronously. Intended for use in tests\n * where you want to exercise the full pipeline without starting an MCP server.\n *\n * ```ts\n * import { buildTestTool } from \"effect-codemode/test\"\n * const codemode = buildTestTool(TodoToolsLive, UserToolsLive)\n * const result = await codemode.execute(`Effect.gen(function* () { ... })`)\n * ```\n */\nexport function buildTestTool(\n ...groups: ReadonlyArray<Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>>\n): CodemodeTool {\n return Effect.runSync(\n Effect.gen(function* () {\n const { allTools, statusText, groupNames } = yield* snapshotGroups(groups)\n\n // Get a runtime and executor\n const rt = yield* Effect.runtime<never>()\n const exec = yield* Effect.provide(CodeExecutor, CodeExecutor.Default)\n\n return createCodemodeTool(allTools, rt, exec, statusText, [], groupNames)\n }),\n )\n}\n\n/**\n * Return just the TypeScript declarations string for the given group layers.\n * No runtime or executor is created — only resolves tools and generates declarations.\n *\n * ```ts\n * import { buildInspector } from \"effect-codemode/test\"\n * const declarations = buildInspector(TodoToolsLive, UserToolsLive)\n * ```\n */\nexport function buildInspector(\n ...groups: ReadonlyArray<Layer.Layer<CodemodeRegistry, unknown, CodemodeRegistry>>\n): string {\n return Effect.runSync(\n Effect.gen(function* () {\n const { allTools } = yield* snapshotGroups(groups)\n\n // Generate declarations\n const typegenTools: Record<string, TypegenDescriptor> = {}\n for (const [key, tool] of Object.entries(allTools)) {\n typegenTools[key] = toTypegenDescriptor(tool)\n }\n return generateDeclarations(typegenTools)\n }),\n )\n}\n\n// Backward-compatible aliases\nexport { buildTestTool as test, buildInspector as inspect }\n",
6
+ "import { Effect, Exit, Runtime, Schedule, Schema } from \"effect\"\n\nimport { sanitizeToolName } from \"./sanitize\"\nimport type { ToolDescriptor, ToolInvocation, ToolMiddleware } from \"./types\"\n\n// Well-known Effect type ID symbols\nconst OptionTypeId = Symbol.for(\"effect/Option\")\nconst EitherTypeId = Symbol.for(\"effect/Either\")\n\n/**\n * Recursively unwraps Effect tagged types (Option, Either) into plain\n * JSON-friendly values. Uses a WeakSet to safely handle circular references.\n *\n * - Option<A>: Some → unwrapped value, None → null\n * - Either<L, R>: Right → unwrapped right value, Left → { _tag: \"Left\", left: ... }\n * - Arrays: each element recursively unwrapped\n * - Plain objects: each value recursively unwrapped\n */\nexport const unwrapEffectTypes = (value: unknown, seen?: WeakSet<object>): unknown => {\n // Primitives pass through\n if (value === null || value === undefined || typeof value !== \"object\") {\n return value\n }\n\n const obj = value as Record<string | symbol, unknown>\n const tracking = seen ?? new WeakSet<object>()\n\n // Circular reference guard\n if (tracking.has(obj)) {\n return \"[Circular]\"\n }\n tracking.add(obj)\n\n // Option: { [OptionTypeId]: ..., _tag: \"Some\" | \"None\" }\n if (OptionTypeId in obj) {\n if (obj[\"_tag\"] === \"None\") {\n return null\n }\n if (obj[\"_tag\"] === \"Some\") {\n return unwrapEffectTypes(obj[\"value\"], tracking)\n }\n }\n\n // Either: { [EitherTypeId]: ..., _tag: \"Right\" | \"Left\" }\n if (EitherTypeId in obj) {\n if (obj[\"_tag\"] === \"Right\") {\n return unwrapEffectTypes(obj[\"right\"], tracking)\n }\n if (obj[\"_tag\"] === \"Left\") {\n return { _tag: \"Left\", left: unwrapEffectTypes(obj[\"left\"], tracking) }\n }\n }\n\n // Arrays\n if (Array.isArray(obj)) {\n return obj.map((item) => unwrapEffectTypes(item, tracking))\n }\n\n // Plain objects — recurse over own enumerable string keys\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(obj)) {\n result[key] = unwrapEffectTypes(obj[key], tracking)\n }\n return result\n}\n\n/**\n * Maximum number of retry attempts for rate-limited requests.\n */\nconst MAX_RETRIES = 3\n\n/**\n * Returns whether an error looks like a rate limit error:\n * - Effect TaggedError with _tag \"RateLimitError\"\n * - Any error object with a status of 429\n */\nconst isRateLimitError = (err: unknown): err is { _tag: string; retryAfter?: number; status?: number } => {\n if (typeof err !== \"object\" || err === null) return false\n const obj = err as Record<string, unknown>\n if (obj[\"_tag\"] === \"RateLimitError\") return true\n if (obj[\"status\"] === 429) return true\n return false\n}\n\n/**\n * Waits for a backoff duration. Uses `retryAfter` from the error if available,\n * otherwise exponential backoff: 1s, 2s, 4s.\n */\nconst backoff = (attempt: number, retryAfterSeconds?: number): Promise<void> => {\n const ms = retryAfterSeconds !== undefined ? retryAfterSeconds * 1000 : Math.pow(2, attempt) * 1000\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Composes an array of middleware into a single wrapper around a base Effect.\n * Middleware are applied in order: the first middleware in the array is the\n * outermost wrapper. Each middleware receives `next` which is the rest of the\n * chain (subsequent middleware + the base effect).\n */\nconst applyMiddleware = (\n middlewares: ReadonlyArray<ToolMiddleware>,\n invocation: ToolInvocation,\n base: Effect.Effect<unknown, unknown>,\n): Effect.Effect<unknown, unknown> => {\n // Build the chain from right to left: last middleware wraps the base first\n let current = base\n for (let i = middlewares.length - 1; i >= 0; i--) {\n const mw = middlewares[i]!\n const next = current\n current = mw(invocation, next)\n }\n return current\n}\n\nexport interface EffectToAsyncFnOptions {\n /** Whether to validate output against the tool's outputSchema (default: true) */\n readonly validateOutput?: boolean | undefined\n /** Middleware to wrap around each tool execution */\n readonly middleware?: ReadonlyArray<ToolMiddleware> | undefined\n}\n\n/**\n * Converts a single Effect-based tool into a plain async function\n * using a captured Effect Runtime. Unwraps Effect types (Option, Either)\n * from the return value and retries on rate limit errors.\n */\nexport const effectToAsyncFn = <R>(\n tool: ToolDescriptor,\n runtime: Runtime.Runtime<R>,\n options?: EffectToAsyncFnOptions,\n): ((rawInput: unknown) => Promise<unknown>) => {\n const shouldValidateOutput = options?.validateOutput !== false\n\n const middlewares = options?.middleware ?? []\n\n return async (rawInput: unknown): Promise<unknown> => {\n // Decode input through the tool's schema\n const decoded = Schema.decodeUnknownSync(tool.inputSchema as Schema.Schema<unknown, unknown, never>)(rawInput)\n\n let lastError: unknown\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n // Back off before retrying (skip on first attempt)\n if (attempt > 0) {\n const retryAfter = isRateLimitError(lastError) ? lastError.retryAfter : undefined\n await backoff(attempt - 1, retryAfter)\n }\n\n // Build the Effect with middleware applied\n let effect = tool.execute(decoded) as Effect.Effect<unknown, unknown, R>\n\n if (middlewares.length > 0) {\n const invocation: ToolInvocation = { name: tool.name, input: decoded }\n const provided = Effect.provide(effect, runtime.context) as Effect.Effect<unknown, unknown>\n effect = applyMiddleware(middlewares, invocation, provided) as Effect.Effect<unknown, unknown, R>\n }\n\n // Run the Effect program using the captured runtime\n const exit = await Runtime.runPromiseExit(runtime)(effect)\n\n if (Exit.isSuccess(exit)) {\n const unwrapped = unwrapEffectTypes(exit.value)\n\n // Lenient output validation: warn on mismatch but still return raw result\n if (shouldValidateOutput && tool.outputSchema) {\n try {\n Schema.decodeUnknownSync(tool.outputSchema as Schema.Schema<unknown, unknown, never>, {\n onExcessProperty: \"preserve\",\n })(unwrapped)\n } catch (e) {\n console.warn(\n `[codemode] Output validation warning for tool \"${tool.name}\":`,\n e instanceof Error ? e.message : String(e),\n )\n }\n }\n\n return unwrapped\n }\n\n // On failure, extract a useful error\n const cause = exit.cause\n const failure = cause._tag === \"Fail\" ? cause.error : cause\n const error: Record<string, unknown> = {\n _tag:\n typeof failure === \"object\" && failure !== null && \"_tag\" in failure\n ? (failure as { _tag: string })._tag\n : \"ExecutionError\",\n message:\n typeof failure === \"object\" && failure !== null && \"message\" in failure\n ? (failure as { message: string }).message\n : String(failure),\n }\n\n // Flatten all error fields to top level (matches generated type shape)\n if (typeof failure === \"object\" && failure !== null) {\n for (const [k, v] of Object.entries(failure)) {\n if (k !== \"_tag\" && k !== \"message\") {\n error[k] = v\n }\n }\n }\n\n // Retry on rate limit errors, throw immediately on anything else\n if (isRateLimitError(error) && attempt < MAX_RETRIES) {\n lastError = error\n continue\n }\n\n throw error\n }\n\n // Should be unreachable, but satisfies the type checker\n throw lastError\n }\n}\n\n/**\n * Builds a table of plain async functions from an array of tool descriptors\n * and a captured Effect Runtime.\n */\nexport const buildFnTable = <R>(\n tools: ReadonlyArray<ToolDescriptor>,\n runtime: Runtime.Runtime<R>,\n options?: EffectToAsyncFnOptions,\n): Record<string, (...args: Array<unknown>) => Promise<unknown>> => {\n const table: Record<string, (...args: Array<unknown>) => Promise<unknown>> = {}\n\n for (const tool of tools) {\n const fn = effectToAsyncFn(tool, runtime, options)\n const key = sanitizeToolName(tool.name)\n // Wrap to accept spread args — the first arg is the input object\n table[key] = async (...args: Array<unknown>) => fn(args[0])\n }\n\n return table\n}\n\n/**\n * Converts a single Effect-based tool into a function that returns an Effect.\n * The returned Effect decodes input, calls the service, unwraps Effect types,\n * and keeps errors in the Effect error channel (no throwing).\n *\n * Rate limit errors are retried using Effect.retry with exponential backoff.\n */\nexport const effectToEffectFn = <R>(\n tool: ToolDescriptor,\n runtime: Runtime.Runtime<R>,\n options?: EffectToAsyncFnOptions,\n): ((rawInput: unknown) => Effect.Effect<unknown, unknown>) => {\n const shouldValidateOutput = options?.validateOutput !== false\n const middlewares = options?.middleware ?? []\n\n return (rawInput: unknown): Effect.Effect<unknown, unknown> => {\n const decoded = Schema.decodeUnknownSync(tool.inputSchema as Schema.Schema<unknown, unknown, never>)(rawInput)\n\n const baseEffect: Effect.Effect<unknown, unknown> = Effect.flatMap(\n Effect.provide(tool.execute(decoded), runtime.context) as Effect.Effect<unknown, unknown>,\n (value) => {\n const unwrapped = unwrapEffectTypes(value)\n\n if (shouldValidateOutput && tool.outputSchema) {\n try {\n Schema.decodeUnknownSync(tool.outputSchema as Schema.Schema<unknown, unknown, never>, {\n onExcessProperty: \"preserve\",\n })(unwrapped)\n } catch (e) {\n console.warn(\n `[codemode] Output validation warning for tool \"${tool.name}\":`,\n e instanceof Error ? e.message : String(e),\n )\n }\n }\n\n return Effect.succeed(unwrapped)\n },\n )\n\n // Apply middleware chain around the base effect\n const withMiddleware =\n middlewares.length > 0\n ? applyMiddleware(middlewares, { name: tool.name, input: decoded }, baseEffect)\n : baseEffect\n\n // Retry rate limit errors with exponential backoff (1s, 2s, 4s)\n const retrySchedule = Schedule.exponential(\"1 second\").pipe(Schedule.compose(Schedule.recurs(MAX_RETRIES)))\n\n return withMiddleware.pipe(\n Effect.retry({\n schedule: retrySchedule,\n while: (err) => isRateLimitError(err),\n }),\n )\n }\n}\n\n/**\n * Builds a table of Effect-returning functions from an array of tool\n * descriptors and a captured Effect Runtime.\n *\n * Each function in the table takes an input and returns an\n * `Effect<unknown, unknown>` — errors stay in the Effect error channel.\n */\nexport const buildEffectFnTable = <R>(\n tools: ReadonlyArray<ToolDescriptor>,\n runtime: Runtime.Runtime<R>,\n options?: EffectToAsyncFnOptions,\n): Record<string, (...args: Array<unknown>) => Effect.Effect<unknown, unknown>> => {\n const table: Record<string, (...args: Array<unknown>) => Effect.Effect<unknown, unknown>> = {}\n\n for (const tool of tools) {\n const fn = effectToEffectFn(tool, runtime, options)\n const key = sanitizeToolName(tool.name)\n table[key] = (...args: Array<unknown>) => fn(args[0])\n }\n\n return table\n}\n",
7
+ "/**\n * Sanitizes a tool name so it can be used as a valid JavaScript identifier.\n *\n * - Replaces `-`, `.`, and spaces with `_`\n * - Strips remaining non-identifier characters\n * - Prefixes digit-leading names with `_`\n * - Appends `_` to JS reserved words\n */\n\nconst JS_RESERVED = new Set([\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"let\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"undefined\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n \"await\",\n \"static\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n])\n\nexport function sanitizeToolName(name: string): string {\n // Replace common separators with underscores\n let result = name.replace(/[-.\\s]/g, \"_\")\n\n // Strip any remaining characters that aren't valid in identifiers\n result = result.replace(/[^a-zA-Z0-9_$]/g, \"\")\n\n // Empty after stripping — fallback\n if (result.length === 0) return \"_\"\n\n // Prefix digit-leading names\n if (/^\\d/.test(result)) {\n result = `_${result}`\n }\n\n // Append underscore to reserved words\n if (JS_RESERVED.has(result)) {\n result = `${result}_`\n }\n\n return result\n}\n",
8
+ "import { Option } from \"effect\"\nimport * as SchemaAST from \"effect/SchemaAST\"\n\nimport { sanitizeToolName } from \"./sanitize\"\n\n/**\n * Describes an error type for typegen.\n * - `string` form: just the tag name (e.g. \"NotFoundError\") — generates a minimal type with `_tag` and `message`.\n * - `object` form: tag name plus the full SchemaAST — generates a complete type with all fields.\n */\nexport type ErrorDescriptor =\n | string\n | {\n readonly tag: string\n readonly ast: SchemaAST.AST\n }\n\nexport interface ToolDescriptor {\n readonly name: string\n readonly description: string\n readonly inputSchema: SchemaAST.AST\n readonly outputSchema?: SchemaAST.AST | undefined\n readonly errors?: ReadonlyArray<ErrorDescriptor> | undefined\n}\n\n/**\n * Walk an Effect SchemaAST and produce a TypeScript type string.\n */\nexport function astToTypeScript(ast: SchemaAST.AST, seen = new Set<SchemaAST.AST>()): string {\n switch (ast._tag) {\n case \"StringKeyword\":\n return \"string\"\n case \"NumberKeyword\":\n return \"number\"\n case \"BooleanKeyword\":\n return \"boolean\"\n case \"BigIntKeyword\":\n return \"bigint\"\n case \"UndefinedKeyword\":\n return \"undefined\"\n case \"VoidKeyword\":\n return \"void\"\n case \"NeverKeyword\":\n return \"never\"\n case \"UnknownKeyword\":\n return \"unknown\"\n case \"AnyKeyword\":\n return \"any\"\n case \"ObjectKeyword\":\n return \"object\"\n case \"SymbolKeyword\":\n return \"symbol\"\n case \"UniqueSymbol\":\n return `typeof ${String(ast.symbol)}`\n\n case \"Literal\": {\n if (ast.literal === null) return \"null\"\n if (typeof ast.literal === \"string\") return JSON.stringify(ast.literal)\n return String(ast.literal)\n }\n\n case \"Enums\":\n return ast.enums.map(([_, v]) => JSON.stringify(v)).join(\" | \") || \"never\"\n\n case \"TemplateLiteral\": {\n const spans = ast.spans\n .map((s) => {\n const t =\n s.type._tag === \"StringKeyword\"\n ? \"string\"\n : s.type._tag === \"NumberKeyword\"\n ? \"number\"\n : astToTypeScript(s.type as SchemaAST.AST, seen)\n return `\\${${t}}${s.literal}`\n })\n .join(\"\")\n return `\\`${ast.head}${spans}\\``\n }\n\n case \"Union\":\n return ast.types.map((t) => astToTypeScript(t, seen)).join(\" | \")\n\n case \"TupleType\": {\n const elems = ast.elements.map((e) => {\n const t = astToTypeScript(e.type, seen)\n return e.isOptional ? `${t}?` : t\n })\n if (ast.rest.length > 0) {\n const restType = astToTypeScript(ast.rest[0]!.type, seen)\n if (ast.elements.length === 0) return `Array<${restType}>`\n elems.push(`...Array<${restType}>`)\n }\n return `[${elems.join(\", \")}]`\n }\n\n case \"TypeLiteral\": {\n if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {\n return \"{}\"\n }\n const props = ast.propertySignatures.map((ps) => {\n const key =\n typeof ps.name === \"string\"\n ? /^[a-zA-Z_$][\\w$]*$/.test(ps.name)\n ? ps.name\n : JSON.stringify(ps.name)\n : `[${String(ps.name)}]`\n const opt = ps.isOptional ? \"?\" : \"\"\n return ` ${key}${opt}: ${astToTypeScript(ps.type, seen)}`\n })\n const idxSigs = ast.indexSignatures.map((is) => {\n const param = astToTypeScript(is.parameter, seen)\n return ` [key: ${param}]: ${astToTypeScript(is.type, seen)}`\n })\n return `{\\n${[...props, ...idxSigs].join(\"\\n\")}\\n}`\n }\n\n case \"Refinement\":\n return astToTypeScript(ast.from, seen)\n\n case \"Transformation\":\n return astToTypeScript(ast.to, seen)\n\n case \"Suspend\": {\n const id = Option.getOrUndefined(SchemaAST.getIdentifierAnnotation(ast))\n if (id) return id\n if (seen.has(ast)) return \"unknown\"\n seen.add(ast)\n return astToTypeScript(ast.f(), seen)\n }\n\n case \"Declaration\": {\n const id = Option.getOrUndefined(SchemaAST.getIdentifierAnnotation(ast))\n return id ?? \"unknown\"\n }\n\n default:\n return \"unknown\"\n }\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .split(/[-_]/)\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(\"\")\n}\n\nfunction fieldDescription(ast: SchemaAST.AST): string | undefined {\n const direct = Option.getOrUndefined(SchemaAST.getDescriptionAnnotation(ast))\n if (direct) return direct\n // For optional fields: Union(T, UndefinedKeyword) — check non-undefined members\n if (ast._tag === \"Union\") {\n for (const member of ast.types) {\n if (member._tag === \"UndefinedKeyword\") continue\n const desc = Option.getOrUndefined(SchemaAST.getDescriptionAnnotation(member))\n if (desc) return desc\n }\n }\n return undefined\n}\n\nfunction resolveTypeLiteral(ast: SchemaAST.AST): SchemaAST.AST {\n if (ast._tag === \"Transformation\") return ast.to\n return ast\n}\n\nfunction buildJSDoc(description: string, inputAst?: SchemaAST.AST, errors?: ReadonlyArray<ErrorDescriptor>): string {\n const lines: string[] = [`/** ${description}`]\n if (inputAst) {\n const resolved = resolveTypeLiteral(inputAst)\n if (resolved._tag === \"TypeLiteral\") {\n for (const ps of resolved.propertySignatures) {\n const desc = fieldDescription(ps.type)\n if (desc) lines.push(` * @param ${String(ps.name)} - ${desc}`)\n }\n }\n }\n if (errors && errors.length > 0) {\n for (const err of errors) {\n const tag = errorTag(err)\n lines.push(` * @error ${tag} — catchable with Effect.catchTag(\"${tag}\", ...)`)\n }\n }\n lines.push(\" */\")\n return lines.join(\"\\n\")\n}\n\n/**\n * Extract the tag name from an ErrorDescriptor.\n */\nfunction errorTag(error: ErrorDescriptor): string {\n return typeof error === \"string\" ? error : error.tag\n}\n\n/**\n * Build a TypeScript type declaration for an error.\n *\n * When a rich AST is available, generates the full type with all fields.\n * Otherwise, falls back to the minimal `{ _tag, message }` shape.\n */\nfunction buildErrorType(error: ErrorDescriptor): string {\n const tag = errorTag(error)\n if (typeof error === \"string\") {\n return `type ${tag} = { readonly _tag: \"${tag}\"; readonly message: string }`\n }\n // Rich error: walk the AST to generate all fields\n const typeString = astToTypeScript(error.ast)\n return `type ${tag} = ${typeString}`\n}\n\n/**\n * Resolve the best name for a shared output schema.\n *\n * Prefers the SchemaAST identifier annotation (e.g. \"Issue\", \"User\").\n * Falls back to the PascalCase name derived from the first tool that uses it.\n */\nfunction resolveSharedOutputName(ast: SchemaAST.AST | undefined, firstToolKey: string): string {\n if (ast) {\n // Check the outer AST node first\n const id = Option.getOrUndefined(SchemaAST.getIdentifierAnnotation(ast))\n if (id) return id\n // For Transformations, also check the decoded (to) side\n if (ast._tag === \"Transformation\") {\n const toId = Option.getOrUndefined(SchemaAST.getIdentifierAnnotation(ast.to))\n if (toId) return toId\n }\n }\n return `${toPascalCase(sanitizeToolName(firstToolKey))}Output`\n}\n\n/**\n * Generate TypeScript declarations for a set of tool descriptors.\n *\n * Methods return `Effect<Output, ErrorType>` for use in Effect.gen programs.\n * Error types are generated as tagged union members.\n *\n * When multiple tools share an identical output schema, the type is emitted\n * once (using the schema's identifier annotation if available) and referenced\n * by name in each method signature.\n */\nexport function generateDeclarations(tools: Record<string, ToolDescriptor>): string {\n const entries = Object.entries(tools)\n\n // --- Phase 1: compute output type strings and group duplicates -----------\n // Map from generated type string -> { name, keys[] }\n const outputTypeStringToGroup = new Map<string, { name: string; keys: string[] }>()\n // Map from tool key -> the output type name to use in its signature\n const toolOutputTypeName = new Map<string, string>()\n\n for (const [key, tool] of entries) {\n const typeString = tool.outputSchema ? astToTypeScript(tool.outputSchema) : \"unknown\"\n\n const existing = outputTypeStringToGroup.get(typeString)\n if (existing) {\n existing.keys.push(key)\n } else {\n outputTypeStringToGroup.set(typeString, { name: \"\", keys: [key] })\n }\n }\n\n // Assign names: shared groups get a shared name, singletons get PerToolOutput\n for (const [_typeString, group] of outputTypeStringToGroup) {\n if (group.keys.length > 1) {\n // Shared — use identifier annotation or derive from first tool\n const firstTool = tools[group.keys[0]!]!\n group.name = resolveSharedOutputName(firstTool.outputSchema, group.keys[0]!)\n } else {\n // Singleton — use the classic per-tool naming\n const key = group.keys[0]!\n group.name = `${toPascalCase(sanitizeToolName(key))}Output`\n }\n for (const key of group.keys) {\n toolOutputTypeName.set(key, group.name)\n }\n }\n\n // --- Phase 2: emit declarations ------------------------------------------\n const parts: string[] = []\n const methods: string[] = []\n const emittedErrors = new Set<string>()\n const emittedOutputTypes = new Set<string>()\n\n for (const [key, tool] of entries) {\n const safeName = sanitizeToolName(key)\n const pascal = toPascalCase(safeName)\n const inputType = `${pascal}Input`\n const outputType = toolOutputTypeName.get(key)!\n\n parts.push(`type ${inputType} = ${astToTypeScript(tool.inputSchema)}`)\n\n // Only emit each output type declaration once\n if (!emittedOutputTypes.has(outputType)) {\n emittedOutputTypes.add(outputType)\n const typeString = tool.outputSchema ? astToTypeScript(tool.outputSchema) : \"unknown\"\n parts.push(`type ${outputType} = ${typeString}`)\n }\n\n // Collect error types for this tool\n if (tool.errors && tool.errors.length > 0) {\n for (const err of tool.errors) {\n const tag = errorTag(err)\n if (!emittedErrors.has(tag)) {\n emittedErrors.add(tag)\n parts.push(buildErrorType(err))\n }\n }\n }\n\n // Build Effect return type: Effect<Output, Error1 | Error2> or Effect<Output, never>\n const errorType = tool.errors && tool.errors.length > 0 ? tool.errors.map((e) => errorTag(e)).join(\" | \") : \"never\"\n\n const jsdoc = buildJSDoc(tool.description, tool.inputSchema, tool.errors)\n methods.push(` ${jsdoc}\\n ${safeName}(input: ${inputType}): Effect<${outputType}, ${errorType}>`)\n }\n\n parts.push(\"\")\n parts.push(`declare const codemode: {\\n${methods.join(\"\\n\")}\\n}`)\n\n return parts.join(\"\\n\\n\")\n}\n",
9
+ "import { Effect, Schema } from \"effect\"\nimport * as SchemaAST from \"effect/SchemaAST\"\n\nimport type { ErrorDescriptor, ToolDescriptor as TypegenDescriptor } from \"./typegen\"\n\n/**\n * Describes a tool that can be bridged from an Effect service to a plain async function.\n */\nexport interface ToolDescriptor {\n readonly name: string\n readonly description: string\n readonly example?: string | undefined\n readonly inputSchema: Schema.Schema.Any\n readonly outputSchema?: Schema.Schema.Any | undefined\n readonly errors?: ReadonlyArray<ErrorDescriptor> | undefined\n readonly service?: string | undefined\n readonly requiresConfirmation?: boolean | undefined\n readonly middleware?: ReadonlyArray<ToolMiddleware> | undefined\n readonly execute: (input: unknown) => Effect.Effect<unknown, unknown, unknown>\n}\n\n/**\n * Context passed to each middleware function, describing the tool being invoked.\n */\nexport interface ToolInvocation {\n readonly name: string\n readonly input: unknown\n}\n\n/**\n * A middleware function that wraps tool execution.\n *\n * Receives the tool invocation context and a `next` Effect representing\n * the downstream execution (either the next middleware or the tool itself).\n * Must return an Effect that produces the tool result.\n *\n * ```ts\n * const logging: ToolMiddleware = (tool, next) =>\n * Effect.gen(function* () {\n * console.log(`Calling ${tool.name}`)\n * const result = yield* next\n * console.log(`Done ${tool.name}`)\n * return result\n * })\n * ```\n */\nexport type ToolMiddleware = (\n tool: ToolInvocation,\n next: Effect.Effect<unknown, unknown>,\n) => Effect.Effect<unknown, unknown>\n\n/**\n * Result of executing user-provided code in the sandbox.\n */\nexport interface ExecuteResult {\n readonly result: unknown\n readonly error?: string\n readonly logs: string[]\n}\n\n/**\n * Interface for code execution engines.\n */\nexport interface ExecutorOptions {\n /** Called for each console.log/warn/error/info/debug from sandbox code — use for streaming progress */\n readonly onLog?: (level: string, message: string) => void\n /** Whether to allow network access (fetch, URL, Request, Headers, Response) in the sandbox. Defaults to true. */\n readonly allowNetwork?: boolean\n /** Maximum execution time in milliseconds. */\n readonly timeoutMs?: number | undefined\n}\n\nexport interface Executor {\n readonly execute: (\n code: string,\n fns: Record<string, (...args: Array<unknown>) => unknown>,\n options?: ExecutorOptions,\n ) => Promise<ExecuteResult>\n}\n\n/**\n * Convert a tool descriptor (Schema.Schema.Any) to typegen format (SchemaAST.AST).\n */\nexport function toTypegenDescriptor(tool: ToolDescriptor): TypegenDescriptor {\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: (tool.inputSchema as { ast: SchemaAST.AST }).ast,\n outputSchema: tool.outputSchema ? (tool.outputSchema as { ast: SchemaAST.AST }).ast : undefined,\n errors: tool.errors,\n }\n}\n",
10
+ "import { Runtime } from \"effect\"\n\nimport { buildEffectFnTable } from \"./bridge\"\nimport { generateDeclarations, type ToolDescriptor as TypegenDescriptor } from \"./typegen\"\nimport type { ExecuteResult, Executor, ExecutorOptions, ToolDescriptor, ToolMiddleware } from \"./types\"\nimport { toTypegenDescriptor } from \"./types\"\n\nexport interface CodemodeTool {\n /** The tool name for MCP registration */\n readonly name: string\n /** Full description including generated TS declarations */\n readonly description: string\n /** The generated TypeScript declarations (for debugging/display) */\n readonly declarations: string\n /** Execute LLM-generated code, optionally streaming console output */\n readonly execute: (code: string, options?: ExecutorOptions) => Promise<ExecuteResult>\n}\n\n/**\n * Pick up to `max` representative examples from tool shapes, spanning different groups.\n */\nfunction buildExamplesBlock(tools: Record<string, ToolDescriptor>, max: number = 3): string {\n const withExamples = Object.entries(tools).filter(([_, t]) => t.example)\n if (withExamples.length === 0) return \"\"\n\n // Try to pick from different services for diversity\n const seen = new Set<string>()\n const picked: Array<[string, ToolDescriptor]> = []\n\n for (const [key, tool] of withExamples) {\n const svc = tool.service ?? \"unknown\"\n if (!seen.has(svc) && picked.length < max) {\n seen.add(svc)\n picked.push([key, tool])\n }\n }\n\n // Fill remaining slots if we have room\n for (const entry of withExamples) {\n if (picked.length >= max) break\n if (!picked.includes(entry)) {\n picked.push(entry)\n }\n }\n\n const lines = picked.map(([key, tool]) => `**${key}:**\\n\\`\\`\\`typescript\\n${tool.example}\\n\\`\\`\\``)\n\n return `\\n\\nExamples:\\n\\n${lines.join(\"\\n\\n\")}`\n}\n\nconst COMPACT_THRESHOLD = 7\n\n/**\n * Creates the codemode tool by wiring together:\n * - Type generation (for the LLM prompt)\n * - The fn table (Effect services -> plain async functions)\n * - The executor (sandbox)\n *\n * Accepts sandbox tools only — confirmation tools should be split out before calling.\n */\nexport function createCodemodeTool<R>(\n sandboxTools: Record<string, ToolDescriptor>,\n runtime: Runtime.Runtime<R>,\n executor: Executor,\n serviceStatuses?: string,\n middleware?: ReadonlyArray<ToolMiddleware>,\n groupNames?: ReadonlyArray<string>,\n): CodemodeTool {\n // Generate TypeScript declarations for the LLM (sandbox tools only)\n const typegenTools: Record<string, TypegenDescriptor> = {}\n for (const [key, tool] of Object.entries(sandboxTools)) {\n typegenTools[key] = toTypegenDescriptor(tool)\n }\n const declarations = generateDeclarations(typegenTools)\n\n // Build Effect-returning function table from sandbox tools only\n const tools = Object.values(sandboxTools)\n const fns = buildEffectFnTable(tools, runtime, { middleware })\n\n const statusBlock = serviceStatuses ? `\\nService status:\\n${serviceStatuses}\\n` : \"\"\n\n // Dynamic service list from group names or fallback\n const serviceList = groupNames && groupNames.length > 0 ? groupNames.join(\", \") : \"configured services\"\n\n // Dynamic examples from tool shapes\n const examplesBlock = buildExamplesBlock(sandboxTools)\n\n const toolCount = Object.keys(sandboxTools).length\n const isCompact = toolCount > COMPACT_THRESHOLD\n\n let apiBlock: string\n if (isCompact) {\n // Compact: one-line summaries with instruction to use search_tools for full types\n const catalog = Object.entries(sandboxTools)\n .map(([key, tool]) => ` ${key}(input): ${tool.description}`)\n .join(\"\\n\")\n apiBlock = `Available API (${toolCount} tools — use \\`search_tools\\` for full type signatures):\n\n${catalog}`\n } else {\n // Full declarations inline\n apiBlock = `Available API:\n\n\\`\\`\\`typescript\n${declarations}\n\\`\\`\\``\n }\n\n const description = `Execute TypeScript code using Effect to orchestrate operations across ${serviceList}.\n\nThe sandbox has \\`Effect\\`, \\`pipe\\`, \\`Duration\\`, \\`Schedule\\`, \\`Option\\`, \\`Either\\`, \\`Match\\`, \\`Schema\\`, \\`Arr\\` (Effect's Array module), \\`Ref\\`, \\`Stream\\`, \\`Chunk\\`, \\`Data\\`, \\`Order\\`, and \\`Predicate\\` available as globals.\nEach method on \\`codemode\\` returns an \\`Effect\\` — use \\`yield*\\` inside \\`Effect.gen\\` to unwrap values.\nReturn an Effect as the final value and the runtime will execute it.\n${statusBlock}\n\n${apiBlock}\n\nWrite an \\`Effect.gen\\` program that calls methods on the \\`codemode\\` object using \\`yield*\\`.\nReturn a value from the generator to send results back.\n${examplesBlock}\n\n**Error handling with catchTag** — gracefully catch service-specific errors:\n\\`\\`\\`typescript\nEffect.gen(function* () {\n return yield* codemode.some_tool({ id: \"nonexistent\" })\n}).pipe(\n Effect.catchTag(\"NotFoundError\", (e) => Effect.succeed({ error: e.message }))\n)\n\\`\\`\\`\n\n**Retry with backoff** — retry a flaky operation:\n\\`\\`\\`typescript\nEffect.gen(function* () {\n return yield* codemode.some_tool({ id: \"ID\" })\n}).pipe(\n Effect.retry({ times: 3, schedule: Schedule.exponential(\"1 second\") })\n)\n\\`\\`\\`\n\n**Timeout** — bail if an operation takes too long:\n\\`\\`\\`typescript\nEffect.gen(function* () {\n return yield* codemode.some_tool({})\n}).pipe(\n Effect.timeout(\"10 seconds\")\n)\n\\`\\`\\`\n\n**Backward compatibility** — async/await still works:\n\\`\\`\\`typescript\nasync () => {\n const result = await Effect.runPromise(codemode.some_tool({}))\n return result\n}\n\\`\\`\\``\n\n return {\n name: \"execute_code\",\n description,\n declarations,\n execute: (code: string, options?: ExecutorOptions) => executor.execute(code, fns, options),\n }\n}\n",
11
+ "import * as vm from \"node:vm\"\n\nimport { Context, Layer } from \"effect\"\n\nimport { createBaseExecutor, normalizeCode } from \"./executor-base\"\nimport type { Executor } from \"./types\"\n\n// Re-export normalizeCode so existing imports from \"./executor\" still work\nexport { normalizeCode } from \"./executor-base\"\n\n/**\n * Direct executor: uses `new Function()` with a curated set of globals.\n */\nconst createDirectExecutor = (): Executor =>\n createBaseExecutor(async (wrappedCode, globals) => {\n const paramNames = Object.keys(globals)\n const paramValues = Object.values(globals)\n const fn = new Function(...paramNames, wrappedCode)\n return fn(...paramValues)\n })\n\n/**\n * VM executor: uses node:vm for stronger isolation than new Function().\n *\n * normalizeCode produces function-body code (with `return` statements),\n * but vm.Script runs as a program where top-level `return` is illegal.\n * Strip the leading `return ` so the expression is evaluated directly.\n */\nconst createVmExecutor = (): Executor =>\n createBaseExecutor(async (wrappedCode, globals) => {\n // normalizeCode outputs \"return <expr>\" — strip \"return \" for vm script context\n const scriptCode = wrappedCode.startsWith(\"return \")\n ? wrappedCode.slice(7)\n : wrappedCode\n const context = vm.createContext(globals)\n const script = new vm.Script(scriptCode)\n return script.runInContext(context, { timeout: 35_000 }) as Promise<unknown>\n })\n\n/**\n * Effect service for code execution.\n *\n * Provides multiple Layer implementations following the @effect/platform pattern:\n * - `CodeExecutor.Direct` — uses `new Function()` (fast, less isolated)\n * - `CodeExecutor.Vm` — uses `node:vm` (stronger isolation)\n * - `CodeExecutor.Default` — alias for `Vm`\n */\nexport class CodeExecutor extends Context.Tag(\"@effect-codemode/Executor\")<CodeExecutor, Executor>() {\n static readonly Direct = Layer.succeed(CodeExecutor, createDirectExecutor())\n static readonly Vm = Layer.succeed(CodeExecutor, createVmExecutor())\n static readonly Default = CodeExecutor.Vm\n}\n",
12
+ "import * as acorn from \"acorn\"\nimport {\n Array as Arr,\n Chunk,\n Data,\n Duration,\n Effect,\n Either,\n Match,\n Option,\n Order,\n Predicate,\n Ref,\n Schedule,\n Schema,\n Stream,\n pipe,\n} from \"effect\"\n\nimport type { ExecuteResult, Executor, ExecutorOptions } from \"./types\"\n\n// Well-known Effect type ID symbol for runtime detection\nconst EffectTypeId = Symbol.for(\"effect/Effect\")\n\nconst DEFAULT_TIMEOUT_MS = 30_000\n\n// Bun.Transpiler for stripping TypeScript syntax — zero dependencies, ~120μs per transform.\n// Resolves at module load: uses Bun.Transpiler when running on Bun, identity function otherwise.\n//\n// IMPORTANT: Bun.Transpiler performs dead-code elimination, which removes bare expressions\n// like `() => 42`, `42`, and `async () => { ... }` that aren't assigned or called.\n// To prevent this, we first try wrapping the code as `export default (code)` which forces\n// the transpiler to preserve the expression. Falls back to raw transpile for multi-statement code.\nconst stripTypeScript: (code: string) => string = (() => {\n const g = globalThis as Record<string, unknown>\n if (typeof g[\"Bun\"] === \"object\" && g[\"Bun\"] !== null) {\n const BunNs = g[\"Bun\"] as { Transpiler: new (opts: { loader: string }) => { transformSync: (code: string) => string } }\n const transpiler = new BunNs.Transpiler({ loader: \"ts\" })\n const WRAP_PREFIX = \"var __codemode__ = \"\n return (code: string) => {\n // Try 1: wrap as var assignment to prevent DCE on single expressions\n try {\n const wrapped = `${WRAP_PREFIX}${code}`\n const result = transpiler.transformSync(wrapped).trim()\n if (result.startsWith(WRAP_PREFIX)) {\n let body = result.slice(WRAP_PREFIX.length)\n if (body.endsWith(\";\")) body = body.slice(0, -1)\n return body.trim()\n }\n } catch {\n // Not a single expression — fall through to raw transpile\n }\n // Try 2: raw transpile for multi-statement code\n try {\n return transpiler.transformSync(code).trim()\n } catch {\n return code\n }\n }\n }\n return (code: string) => code\n})()\n\n// Grab references to globals that will be injected into the sandbox.\n// These are available in Bun but TypeScript may not know about them\n// without DOM lib or bun-types.\nconst _globals = globalThis as Record<string, unknown>\nconst _fetch = _globals[\"fetch\"] as typeof fetch\nconst _setTimeout = _globals[\"setTimeout\"] as (cb: () => void, ms: number) => number\nconst _clearTimeout = _globals[\"clearTimeout\"] as (id: number) => void\nconst _URL = _globals[\"URL\"] as typeof URL\nconst _Response = _globals[\"Response\"] as typeof Response\nconst _Request = _globals[\"Request\"] as typeof Request\nconst _Headers = _globals[\"Headers\"] as typeof Headers\nconst _Promise = _globals[\"Promise\"] as typeof Promise\n\n/**\n * Run an array of async functions concurrently, like Promise.all but\n * available to sandbox code without needing access to the Promise global.\n */\nfunction parallel<T>(fns: ReadonlyArray<() => Promise<T>>): Promise<Array<T>> {\n return _Promise.all(fns.map((fn) => fn()))\n}\n\n/**\n * Sleep for a given number of milliseconds.\n */\nfunction sleep(ms: number): Promise<void> {\n return new _Promise<void>((resolve) => _setTimeout(resolve, ms))\n}\n\n/**\n * Test whether a value is an Effect by checking for the well-known type ID symbol.\n */\nfunction isEffect(value: unknown): value is Effect.Effect<unknown, unknown> {\n return typeof value === \"object\" && value !== null && EffectTypeId in value\n}\n\n/**\n * Normalize user-provided code into a form suitable for `new Function()`.\n *\n * Uses acorn to parse the code as a module and determines the best wrapping:\n * 1. Single ExpressionStatement that is an ArrowFunctionExpression -> call it directly\n * 2. Body ends with an ExpressionStatement -> splice `return` before it, wrap in async IIFE\n * 3. Otherwise -> wrap entire body in async IIFE\n *\n * Falls back to the regex heuristic if acorn parsing fails.\n */\nexport function normalizeCode(code: string): string {\n // Strip TypeScript syntax (type annotations, as casts, interfaces, etc.)\n const trimmed = code.trim()\n const stripped = stripTypeScript(trimmed)\n // Guard: if the transpiler eliminated all code (DCE), fall back to the original\n const jsCode = stripped || trimmed\n try {\n const ast = acorn.parse(jsCode, { ecmaVersion: 2022, sourceType: \"module\" })\n const body = ast.body\n\n if (body.length === 0) {\n return `return (async () => { ${jsCode} })()`\n }\n\n // Case 1: single expression that is an arrow function -> call it\n const first = body[0]!\n if (body.length === 1 && first.type === \"ExpressionStatement\") {\n const expr = first.expression\n if (expr.type === \"ArrowFunctionExpression\") {\n // Use AST positions to extract just the expression (no trailing semicolons)\n const arrowExpr = jsCode.slice(expr.start, expr.end)\n return `return (${arrowExpr})()`\n }\n }\n\n // Case 2: last statement is an expression -> inject return\n const last = body[body.length - 1]!\n if (last.type === \"ExpressionStatement\") {\n const before = jsCode.slice(0, last.start)\n const expr = jsCode.slice(last.start, last.end)\n // Strip trailing semicolons from the expression for clean `return expr`\n const cleanExpr = expr.replace(/;\\s*$/, \"\")\n return `return (async () => { ${before}return ${cleanExpr} })()`\n }\n\n // Case 3: general statements (variable decls, if/for, etc.)\n return `return (async () => { ${jsCode} })()`\n } catch {\n // Acorn parse failed — fall back to regex heuristic\n return normalizeCodeFallback(jsCode)\n }\n}\n\n/**\n * Regex-based fallback: detect arrow functions or wrap as IIFE.\n */\nfunction normalizeCodeFallback(code: string): string {\n if (isArrowFallback(code)) {\n return `return (${code})()`\n }\n return `return (async () => { ${code} })()`\n}\n\nfunction isArrowFallback(code: string): boolean {\n if (/^async\\s*\\(/.test(code)) return true\n if (/^async\\s+[a-zA-Z_$]\\w*\\s*=>/.test(code)) return true\n if (code.startsWith(\"(\")) {\n let depth = 0\n for (let i = 0; i < code.length; i++) {\n if (code[i] === \"(\") depth++\n else if (code[i] === \")\") {\n depth--\n if (depth === 0) {\n const rest = code.slice(i + 1).trimStart()\n return rest.startsWith(\"=>\")\n }\n }\n }\n }\n if (/^[a-zA-Z_$]\\w*\\s*=>/.test(code)) return true\n return false\n}\n\nconst networkBlockedFn = () => {\n throw new Error(\"Network access is disabled (allowNetwork: false)\")\n}\n\n// A class that throws on construction — needed because `new fn()` fails with\n// \"is not a constructor\" when fn is a plain function in some runtimes.\n// oxlint-disable-next-line no-extraneous-class\nconst NetworkBlockedClass = new Proxy(class {}, {\n construct() {\n throw new Error(\"Network access is disabled (allowNetwork: false)\")\n },\n apply() {\n throw new Error(\"Network access is disabled (allowNetwork: false)\")\n },\n})\n\n/**\n * Build the sandbox globals object: console capture, network control, Effect modules, and tool fns.\n */\nexport function buildSandboxGlobals(\n fns: Record<string, (...args: Array<unknown>) => unknown>,\n options: ExecutorOptions | undefined,\n logs: string[],\n): Record<string, unknown> {\n const onLog = options?.onLog\n\n const emit = (level: string, msg: string) => {\n logs.push(level === \"log\" ? msg : `[${level}] ${msg}`)\n onLog?.(level, msg)\n }\n\n const capturedConsole = {\n log: (...args: Array<unknown>) => emit(\"log\", args.map(String).join(\" \")),\n warn: (...args: Array<unknown>) => emit(\"warn\", args.map(String).join(\" \")),\n error: (...args: Array<unknown>) => emit(\"error\", args.map(String).join(\" \")),\n info: (...args: Array<unknown>) => emit(\"info\", args.map(String).join(\" \")),\n debug: (...args: Array<unknown>) => emit(\"debug\", args.map(String).join(\" \")),\n }\n\n const allowNetwork = options?.allowNetwork !== false\n\n const globals: Record<string, unknown> = {\n codemode: Object.freeze(fns),\n console: Object.freeze(capturedConsole),\n fetch: allowNetwork ? _fetch : networkBlockedFn,\n setTimeout: _setTimeout,\n clearTimeout: _clearTimeout,\n URL: allowNetwork ? _URL : NetworkBlockedClass,\n Response: allowNetwork ? _Response : NetworkBlockedClass,\n Request: allowNetwork ? _Request : NetworkBlockedClass,\n Headers: allowNetwork ? _Headers : NetworkBlockedClass,\n Promise: _Promise,\n parallel,\n sleep,\n // Effect runtime globals — sandbox code can write Effect.gen programs\n Effect,\n pipe,\n Duration,\n Schedule,\n Option,\n Either,\n Match,\n Schema,\n Arr,\n Ref,\n Stream,\n Chunk,\n Data,\n Order,\n Predicate,\n }\n\n return globals\n}\n\n/**\n * Create an executor from a `runCode` function that handles the actual code execution mechanism.\n *\n * The `runCode` function receives the normalized code and sandbox globals, and must return\n * a Promise of the raw result (before Effect detection). The shared infrastructure handles\n * console capture, global injection, network blocking, Effect detection, timeout, and error handling.\n */\nexport function createBaseExecutor(\n runCode: (wrappedCode: string, globals: Record<string, unknown>) => Promise<unknown>,\n): Executor {\n return {\n execute: async (\n code: string,\n fns: Record<string, (...args: Array<unknown>) => unknown>,\n options?: ExecutorOptions,\n ): Promise<ExecuteResult> => {\n const logs: string[] = []\n const globals = buildSandboxGlobals(fns, options, logs)\n\n try {\n const trimmed = code.trim()\n const wrappedCode = normalizeCode(trimmed)\n const timeout = (options as Record<string, unknown> | undefined)?.[\"timeoutMs\"] as number | undefined ?? DEFAULT_TIMEOUT_MS\n\n let result = await _Promise.race([\n runCode(wrappedCode, globals),\n new _Promise<never>((_, reject) =>\n _setTimeout(() => reject(new Error(`Execution timed out after ${timeout}ms`)), timeout),\n ),\n ])\n\n // If the result is an Effect, run it to get the final value\n if (isEffect(result)) {\n result = await Effect.runPromise(result)\n }\n\n return { result, logs }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { result: undefined, error: message, logs }\n }\n },\n }\n}\n",
13
+ "import { Context, Effect, Layer, Ref } from \"effect\"\n\nimport type { ToolDescriptor, ToolMiddleware } from \"./types\"\n\n/**\n * Internal service that accumulates tool registrations from groups.\n * Not part of the public API.\n *\n * Groups register during Layer construction (via `Layer.effectDiscard` in `.toLayer()`).\n * `serve()` reads the snapshot after all group layers have been built.\n */\nexport class CodemodeRegistry extends Context.Tag(\"@effect-codemode/Registry\")<\n CodemodeRegistry,\n {\n readonly registerGroup: (\n name: string,\n tools: Record<string, ToolDescriptor>,\n middleware?: ReadonlyArray<ToolMiddleware>,\n ) => Effect.Effect<void>\n readonly registerFailure: (name: string, error: string) => Effect.Effect<void>\n readonly registerMiddleware: (mw: ToolMiddleware) => Effect.Effect<void>\n readonly snapshot: Effect.Effect<{\n available: Array<{\n name: string\n tools: Record<string, ToolDescriptor>\n middleware: ReadonlyArray<ToolMiddleware>\n }>\n failed: Array<{ name: string; error: string }>\n globalMiddleware: ReadonlyArray<ToolMiddleware>\n }>\n }\n>() {\n /**\n * Create a live registry backed by Ref.\n * Used internally by serve().\n */\n static make = Effect.gen(function* () {\n const groupsRef = yield* Ref.make<\n Array<{\n name: string\n tools: Record<string, ToolDescriptor>\n middleware: ReadonlyArray<ToolMiddleware>\n }>\n >([])\n const failedRef = yield* Ref.make<Array<{ name: string; error: string }>>([])\n const globalMiddlewareRef = yield* Ref.make<ReadonlyArray<ToolMiddleware>>([])\n\n return CodemodeRegistry.of({\n registerGroup: (name, tools, middleware) =>\n Ref.update(groupsRef, (groups) => [...groups, { name, tools, middleware: middleware ?? [] }]),\n registerFailure: (name, error) => Ref.update(failedRef, (failed) => [...failed, { name, error }]),\n registerMiddleware: (mw) => Ref.update(globalMiddlewareRef, (mws) => [...mws, mw]),\n snapshot: Effect.all({\n available: Ref.get(groupsRef),\n failed: Ref.get(failedRef),\n globalMiddleware: Ref.get(globalMiddlewareRef),\n }),\n })\n })\n\n static layer = Layer.effect(CodemodeRegistry, CodemodeRegistry.make)\n}\n"
14
+ ],
15
+ "mappings": ";AAAA,mBAAS,kBAAQ;;;ACAjB;;;ACSA,IAAM,cAAc,IAAI,IAAI;AAAA,EAC1B;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;AACF,CAAC;AAEM,SAAS,gBAAgB,CAAC,MAAsB;AAErD,MAAI,SAAS,KAAK,QAAQ,WAAW,GAAG;AAGxC,WAAS,OAAO,QAAQ,mBAAmB,EAAE;AAG7C,MAAI,OAAO,WAAW;AAAG,WAAO;AAGhC,MAAI,MAAM,KAAK,MAAM,GAAG;AACtB,aAAS,IAAI;AAAA,EACf;AAGA,MAAI,YAAY,IAAI,MAAM,GAAG;AAC3B,aAAS,GAAG;AAAA,EACd;AAEA,SAAO;AAAA;;;ADzET,IAAM,eAAe,OAAO,IAAI,eAAe;AAC/C,IAAM,eAAe,OAAO,IAAI,eAAe;AAWxC,IAAM,oBAAoB,CAAC,OAAgB,SAAoC;AAEpF,MAAI,UAAU,QAAQ,UAAU,oBAAoB,UAAU,UAAU;AACtE,WAAO;AAAA,EACT;AAEA,QAAM,MAAM;AACZ,QAAM,WAAW,QAAQ,IAAI;AAG7B,MAAI,SAAS,IAAI,GAAG,GAAG;AACrB,WAAO;AAAA,EACT;AACA,WAAS,IAAI,GAAG;AAGhB,MAAI,gBAAgB,KAAK;AACvB,QAAI,IAAI,YAAY,QAAQ;AAC1B,aAAO;AAAA,IACT;AACA,QAAI,IAAI,YAAY,QAAQ;AAC1B,aAAO,kBAAkB,IAAI,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,gBAAgB,KAAK;AACvB,QAAI,IAAI,YAAY,SAAS;AAC3B,aAAO,kBAAkB,IAAI,UAAU,QAAQ;AAAA,IACjD;AACA,QAAI,IAAI,YAAY,QAAQ;AAC1B,aAAO,EAAE,MAAM,QAAQ,MAAM,kBAAkB,IAAI,SAAS,QAAQ,EAAE;AAAA,IACxE;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,CAAC,SAAS,kBAAkB,MAAM,QAAQ,CAAC;AAAA,EAC5D;AAGA,QAAM,SAAkC,CAAC;AACzC,aAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,WAAO,OAAO,kBAAkB,IAAI,MAAM,QAAQ;AAAA,EACpD;AACA,SAAO;AAAA;AAMT,IAAM,cAAc;AAOpB,IAAM,mBAAmB,CAAC,QAAgF;AACxG,aAAW,QAAQ,YAAY,QAAQ;AAAM,WAAO;AACpD,QAAM,MAAM;AACZ,MAAI,IAAI,YAAY;AAAkB,WAAO;AAC7C,MAAI,IAAI,cAAc;AAAK,WAAO;AAClC,SAAO;AAAA;AAOT,IAAM,UAAU,CAAC,SAAiB,sBAA8C;AAC9E,QAAM,KAAK,sBAAsB,YAAY,oBAAoB,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI;AAC/F,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA;AASzD,IAAM,kBAAkB,CACtB,aACA,YACA,SACoC;AAEpC,MAAI,UAAU;AACd,WAAS,IAAI,YAAY,SAAS,EAAG,KAAK,GAAG,KAAK;AAChD,UAAM,KAAK,YAAY;AACvB,UAAM,OAAO;AACb,cAAU,GAAG,YAAY,IAAI;AAAA,EAC/B;AACA,SAAO;AAAA;AAeF,IAAM,kBAAkB,CAC7B,MACA,SACA,YAC8C;AAC9C,QAAM,uBAAuB,SAAS,mBAAmB;AAEzD,QAAM,cAAc,SAAS,cAAc,CAAC;AAE5C,SAAO,OAAO,aAAwC;AAEpD,UAAM,UAAU,OAAO,kBAAkB,KAAK,WAAqD,EAAE,QAAQ;AAE7G,QAAI;AAEJ,aAAS,UAAU,EAAG,WAAW,aAAa,WAAW;AAEvD,UAAI,UAAU,GAAG;AACf,cAAM,aAAa,iBAAiB,SAAS,IAAI,UAAU,aAAa;AACxE,cAAM,QAAQ,UAAU,GAAG,UAAU;AAAA,MACvC;AAGA,UAAI,SAAS,KAAK,QAAQ,OAAO;AAEjC,UAAI,YAAY,SAAS,GAAG;AAC1B,cAAM,aAA6B,EAAE,MAAM,KAAK,MAAM,OAAO,QAAQ;AACrE,cAAM,WAAW,OAAO,QAAQ,QAAQ,QAAQ,OAAO;AACvD,iBAAS,gBAAgB,aAAa,YAAY,QAAQ;AAAA,MAC5D;AAGA,YAAM,OAAO,MAAM,QAAQ,eAAe,OAAO,EAAE,MAAM;AAEzD,UAAI,KAAK,UAAU,IAAI,GAAG;AACxB,cAAM,YAAY,kBAAkB,KAAK,KAAK;AAG9C,YAAI,wBAAwB,KAAK,cAAc;AAC7C,cAAI;AACF,mBAAO,kBAAkB,KAAK,cAAwD;AAAA,cACpF,kBAAkB;AAAA,YACpB,CAAC,EAAE,SAAS;AAAA,mBACL,GAAP;AACA,oBAAQ,KACN,kDAAkD,KAAK,UACvD,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA;AAAA,QAEJ;AAEA,eAAO;AAAA,MACT;AAGA,YAAM,QAAQ,KAAK;AACnB,YAAM,UAAU,MAAM,SAAS,SAAS,MAAM,QAAQ;AACtD,YAAM,QAAiC;AAAA,QACrC,aACS,YAAY,YAAY,YAAY,QAAQ,UAAU,UACxD,QAA6B,OAC9B;AAAA,QACN,gBACS,YAAY,YAAY,YAAY,QAAQ,aAAa,UAC3D,QAAgC,UACjC,OAAO,OAAO;AAAA,MACtB;AAGA,iBAAW,YAAY,YAAY,YAAY,MAAM;AACnD,oBAAY,GAAG,MAAM,OAAO,QAAQ,OAAO,GAAG;AAC5C,cAAI,MAAM,UAAU,MAAM,WAAW;AACnC,kBAAM,KAAK;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAGA,UAAI,iBAAiB,KAAK,KAAK,UAAU,aAAa;AACpD,oBAAY;AACZ;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAGA,UAAM;AAAA;AAAA;AAgCH,IAAM,mBAAmB,CAC9B,MACA,SACA,YAC6D;AAC7D,QAAM,uBAAuB,SAAS,mBAAmB;AACzD,QAAM,cAAc,SAAS,cAAc,CAAC;AAE5C,SAAO,CAAC,aAAuD;AAC7D,UAAM,UAAU,OAAO,kBAAkB,KAAK,WAAqD,EAAE,QAAQ;AAE7G,UAAM,aAA8C,OAAO,QACzD,OAAO,QAAQ,KAAK,QAAQ,OAAO,GAAG,QAAQ,OAAO,GACrD,CAAC,UAAU;AACT,YAAM,YAAY,kBAAkB,KAAK;AAEzC,UAAI,wBAAwB,KAAK,cAAc;AAC7C,YAAI;AACF,iBAAO,kBAAkB,KAAK,cAAwD;AAAA,YACpF,kBAAkB;AAAA,UACpB,CAAC,EAAE,SAAS;AAAA,iBACL,GAAP;AACA,kBAAQ,KACN,kDAAkD,KAAK,UACvD,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA;AAAA,MAEJ;AAEA,aAAO,OAAO,QAAQ,SAAS;AAAA,KAEnC;AAGA,UAAM,iBACJ,YAAY,SAAS,IACjB,gBAAgB,aAAa,EAAE,MAAM,KAAK,MAAM,OAAO,QAAQ,GAAG,UAAU,IAC5E;AAGN,UAAM,gBAAgB,SAAS,YAAY,UAAU,EAAE,KAAK,SAAS,QAAQ,SAAS,OAAO,WAAW,CAAC,CAAC;AAE1G,WAAO,eAAe,KACpB,OAAO,MAAM;AAAA,MACX,UAAU;AAAA,MACV,OAAO,CAAC,QAAQ,iBAAiB,GAAG;AAAA,IACtC,CAAC,CACH;AAAA;AAAA;AAWG,IAAM,qBAAqB,CAChC,OACA,SACA,YACiF;AACjF,QAAM,QAAsF,CAAC;AAE7F,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,iBAAiB,MAAM,SAAS,OAAO;AAClD,UAAM,MAAM,iBAAiB,KAAK,IAAI;AACtC,UAAM,OAAO,IAAI,SAAyB,GAAG,KAAK,EAAE;AAAA,EACtD;AAEA,SAAO;AAAA;;;AE5TT;AACA;AA2BO,SAAS,eAAe,CAAC,KAAoB,OAAO,IAAI,KAA8B;AAC3F,UAAQ,IAAI;AAAA,SACL;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO;AAAA,SACJ;AACH,aAAO,UAAU,OAAO,IAAI,MAAM;AAAA,SAE/B,WAAW;AACd,UAAI,IAAI,YAAY;AAAM,eAAO;AACjC,iBAAW,IAAI,YAAY;AAAU,eAAO,KAAK,UAAU,IAAI,OAAO;AACtE,aAAO,OAAO,IAAI,OAAO;AAAA,IAC3B;AAAA,SAEK;AACH,aAAO,IAAI,MAAM,IAAI,EAAE,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK;AAAA,SAEhE,mBAAmB;AACtB,YAAM,QAAQ,IAAI,MACf,IAAI,CAAC,MAAM;AACV,cAAM,IACJ,EAAE,KAAK,SAAS,kBACZ,WACA,EAAE,KAAK,SAAS,kBACd,WACA,gBAAgB,EAAE,MAAuB,IAAI;AACrD,eAAO,MAAM,KAAK,EAAE;AAAA,OACrB,EACA,KAAK,EAAE;AACV,aAAO,KAAK,IAAI,OAAO;AAAA,IACzB;AAAA,SAEK;AACH,aAAO,IAAI,MAAM,IAAI,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,EAAE,KAAK,KAAK;AAAA,SAE7D,aAAa;AAChB,YAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,MAAM;AACpC,cAAM,IAAI,gBAAgB,EAAE,MAAM,IAAI;AACtC,eAAO,EAAE,aAAa,GAAG,OAAO;AAAA,OACjC;AACD,UAAI,IAAI,KAAK,SAAS,GAAG;AACvB,cAAM,WAAW,gBAAgB,IAAI,KAAK,GAAI,MAAM,IAAI;AACxD,YAAI,IAAI,SAAS,WAAW;AAAG,iBAAO,SAAS;AAC/C,cAAM,KAAK,YAAY,WAAW;AAAA,MACpC;AACA,aAAO,IAAI,MAAM,KAAK,IAAI;AAAA,IAC5B;AAAA,SAEK,eAAe;AAClB,UAAI,IAAI,mBAAmB,WAAW,KAAK,IAAI,gBAAgB,WAAW,GAAG;AAC3E,eAAO;AAAA,MACT;AACA,YAAM,QAAQ,IAAI,mBAAmB,IAAI,CAAC,OAAO;AAC/C,cAAM,aACG,GAAG,SAAS,WACf,qBAAqB,KAAK,GAAG,IAAI,IAC/B,GAAG,OACH,KAAK,UAAU,GAAG,IAAI,IACxB,IAAI,OAAO,GAAG,IAAI;AACxB,cAAM,MAAM,GAAG,aAAa,MAAM;AAClC,eAAO,KAAK,MAAM,QAAQ,gBAAgB,GAAG,MAAM,IAAI;AAAA,OACxD;AACD,YAAM,UAAU,IAAI,gBAAgB,IAAI,CAAC,OAAO;AAC9C,cAAM,QAAQ,gBAAgB,GAAG,WAAW,IAAI;AAChD,eAAO,WAAW,WAAW,gBAAgB,GAAG,MAAM,IAAI;AAAA,OAC3D;AACD,aAAO;AAAA,EAAM,CAAC,GAAG,OAAO,GAAG,OAAO,EAAE,KAAK;AAAA,CAAI;AAAA;AAAA,IAC/C;AAAA,SAEK;AACH,aAAO,gBAAgB,IAAI,MAAM,IAAI;AAAA,SAElC;AACH,aAAO,gBAAgB,IAAI,IAAI,IAAI;AAAA,SAEhC,WAAW;AACd,YAAM,KAAK,OAAO,eAAyB,kCAAwB,GAAG,CAAC;AACvE,UAAI;AAAI,eAAO;AACf,UAAI,KAAK,IAAI,GAAG;AAAG,eAAO;AAC1B,WAAK,IAAI,GAAG;AACZ,aAAO,gBAAgB,IAAI,EAAE,GAAG,IAAI;AAAA,IACtC;AAAA,SAEK,eAAe;AAClB,YAAM,KAAK,OAAO,eAAyB,kCAAwB,GAAG,CAAC;AACvE,aAAO,MAAM;AAAA,IACf;AAAA;AAGE,aAAO;AAAA;AAAA;AAIb,SAAS,YAAY,CAAC,MAAsB;AAC1C,SAAO,KACJ,MAAM,MAAM,EACZ,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EACjD,KAAK,EAAE;AAAA;AAGZ,SAAS,gBAAgB,CAAC,KAAwC;AAChE,QAAM,SAAS,OAAO,eAAyB,mCAAyB,GAAG,CAAC;AAC5E,MAAI;AAAQ,WAAO;AAEnB,MAAI,IAAI,SAAS,SAAS;AACxB,eAAW,UAAU,IAAI,OAAO;AAC9B,UAAI,OAAO,SAAS;AAAoB;AACxC,YAAM,OAAO,OAAO,eAAyB,mCAAyB,MAAM,CAAC;AAC7E,UAAI;AAAM,eAAO;AAAA,IACnB;AAAA,EACF;AACA;AAAA;AAGF,SAAS,kBAAkB,CAAC,KAAmC;AAC7D,MAAI,IAAI,SAAS;AAAkB,WAAO,IAAI;AAC9C,SAAO;AAAA;AAGT,SAAS,UAAU,CAAC,aAAqB,UAA0B,QAAiD;AAClH,QAAM,QAAkB,CAAC,OAAO,aAAa;AAC7C,MAAI,UAAU;AACZ,UAAM,WAAW,mBAAmB,QAAQ;AAC5C,QAAI,SAAS,SAAS,eAAe;AACnC,iBAAW,MAAM,SAAS,oBAAoB;AAC5C,cAAM,OAAO,iBAAiB,GAAG,IAAI;AACrC,YAAI;AAAM,gBAAM,KAAK,aAAa,OAAO,GAAG,IAAI,OAAO,MAAM;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU,OAAO,SAAS,GAAG;AAC/B,eAAW,OAAO,QAAQ;AACxB,YAAM,MAAM,SAAS,GAAG;AACxB,YAAM,KAAK,aAAa,yCAAwC,YAAY;AAAA,IAC9E;AAAA,EACF;AACA,QAAM,KAAK,KAAK;AAChB,SAAO,MAAM,KAAK;AAAA,CAAI;AAAA;AAMxB,SAAS,QAAQ,CAAC,OAAgC;AAChD,gBAAc,UAAU,WAAW,QAAQ,MAAM;AAAA;AASnD,SAAS,cAAc,CAAC,OAAgC;AACtD,QAAM,MAAM,SAAS,KAAK;AAC1B,aAAW,UAAU,UAAU;AAC7B,WAAO,QAAQ,2BAA2B;AAAA,EAC5C;AAEA,QAAM,aAAa,gBAAgB,MAAM,GAAG;AAC5C,SAAO,QAAQ,SAAS;AAAA;AAS1B,SAAS,uBAAuB,CAAC,KAAgC,cAA8B;AAC7F,MAAI,KAAK;AAEP,UAAM,KAAK,OAAO,eAAyB,kCAAwB,GAAG,CAAC;AACvE,QAAI;AAAI,aAAO;AAEf,QAAI,IAAI,SAAS,kBAAkB;AACjC,YAAM,OAAO,OAAO,eAAyB,kCAAwB,IAAI,EAAE,CAAC;AAC5E,UAAI;AAAM,eAAO;AAAA,IACnB;AAAA,EACF;AACA,SAAO,GAAG,aAAa,iBAAiB,YAAY,CAAC;AAAA;AAahD,SAAS,oBAAoB,CAAC,OAA+C;AAClF,QAAM,UAAU,OAAO,QAAQ,KAAK;AAIpC,QAAM,0BAA0B,IAAI;AAEpC,QAAM,qBAAqB,IAAI;AAE/B,cAAY,KAAK,SAAS,SAAS;AACjC,UAAM,aAAa,KAAK,eAAe,gBAAgB,KAAK,YAAY,IAAI;AAE5E,UAAM,WAAW,wBAAwB,IAAI,UAAU;AACvD,QAAI,UAAU;AACZ,eAAS,KAAK,KAAK,GAAG;AAAA,IACxB,OAAO;AACL,8BAAwB,IAAI,YAAY,EAAE,MAAM,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;AAAA;AAAA,EAErE;AAGA,cAAY,aAAa,UAAU,yBAAyB;AAC1D,QAAI,MAAM,KAAK,SAAS,GAAG;AAEzB,YAAM,YAAY,MAAM,MAAM,KAAK;AACnC,YAAM,OAAO,wBAAwB,UAAU,cAAc,MAAM,KAAK,EAAG;AAAA,IAC7E,OAAO;AAEL,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,OAAO,GAAG,aAAa,iBAAiB,GAAG,CAAC;AAAA;AAEpD,eAAW,OAAO,MAAM,MAAM;AAC5B,yBAAmB,IAAI,KAAK,MAAM,IAAI;AAAA,IACxC;AAAA,EACF;AAGA,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAC3B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,qBAAqB,IAAI;AAE/B,cAAY,KAAK,SAAS,SAAS;AACjC,UAAM,WAAW,iBAAiB,GAAG;AACrC,UAAM,SAAS,aAAa,QAAQ;AACpC,UAAM,YAAY,GAAG;AACrB,UAAM,aAAa,mBAAmB,IAAI,GAAG;AAE7C,UAAM,KAAK,QAAQ,eAAe,gBAAgB,KAAK,WAAW,GAAG;AAGrE,SAAK,mBAAmB,IAAI,UAAU,GAAG;AACvC,yBAAmB,IAAI,UAAU;AACjC,YAAM,aAAa,KAAK,eAAe,gBAAgB,KAAK,YAAY,IAAI;AAC5E,YAAM,KAAK,QAAQ,gBAAgB,YAAY;AAAA,IACjD;AAGA,QAAI,KAAK,UAAU,KAAK,OAAO,SAAS,GAAG;AACzC,iBAAW,OAAO,KAAK,QAAQ;AAC7B,cAAM,MAAM,SAAS,GAAG;AACxB,aAAK,cAAc,IAAI,GAAG,GAAG;AAC3B,wBAAc,IAAI,GAAG;AACrB,gBAAM,KAAK,eAAe,GAAG,CAAC;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,UAAU,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI;AAE5G,UAAM,QAAQ,WAAW,KAAK,aAAa,KAAK,aAAa,KAAK,MAAM;AACxE,YAAQ,KAAK,KAAK;AAAA,IAAY,mBAAmB,sBAAsB,eAAe,YAAY;AAAA,EACpG;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK;AAAA,EAA8B,QAAQ,KAAK;AAAA,CAAI;AAAA,EAAM;AAEhE,SAAO,MAAM,KAAK;AAAA;AAAA,CAAM;AAAA;;;AC3OnB,SAAS,mBAAmB,CAAC,MAAyC;AAC3E,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,aAAc,KAAK,YAAuC;AAAA,IAC1D,cAAc,KAAK,eAAgB,KAAK,aAAwC,MAAM;AAAA,IACtF,QAAQ,KAAK;AAAA,EACf;AAAA;;;ACrEF,SAAS,kBAAkB,CAAC,OAAuC,MAAc,GAAW;AAC1F,QAAM,eAAe,OAAO,QAAQ,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO;AACvE,MAAI,aAAa,WAAW;AAAG,WAAO;AAGtC,QAAM,OAAO,IAAI;AACjB,QAAM,SAA0C,CAAC;AAEjD,cAAY,KAAK,SAAS,cAAc;AACtC,UAAM,MAAM,KAAK,WAAW;AAC5B,SAAK,KAAK,IAAI,GAAG,KAAK,OAAO,SAAS,KAAK;AACzC,WAAK,IAAI,GAAG;AACZ,aAAO,KAAK,CAAC,KAAK,IAAI,CAAC;AAAA,IACzB;AAAA,EACF;AAGA,aAAW,SAAS,cAAc;AAChC,QAAI,OAAO,UAAU;AAAK;AAC1B,SAAK,OAAO,SAAS,KAAK,GAAG;AAC3B,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,QAAQ,OAAO,IAAI,EAAE,KAAK,UAAU,KAAK;AAAA;AAAA,EAA6B,KAAK;AAAA,OAAiB;AAElG,SAAO;AAAA;AAAA;AAAA;AAAA,EAAoB,MAAM,KAAK;AAAA;AAAA,CAAM;AAAA;AAG9C,IAAM,oBAAoB;AAUnB,SAAS,kBAAqB,CACnC,cACA,SACA,UACA,iBACA,YACA,YACc;AAEd,QAAM,eAAkD,CAAC;AACzD,cAAY,KAAK,SAAS,OAAO,QAAQ,YAAY,GAAG;AACtD,iBAAa,OAAO,oBAAoB,IAAI;AAAA,EAC9C;AACA,QAAM,eAAe,qBAAqB,YAAY;AAGtD,QAAM,QAAQ,OAAO,OAAO,YAAY;AACxC,QAAM,MAAM,mBAAmB,OAAO,SAAS,EAAE,WAAW,CAAC;AAE7D,QAAM,cAAc,kBAAkB;AAAA;AAAA,EAAsB;AAAA,IAAsB;AAGlF,QAAM,cAAc,cAAc,WAAW,SAAS,IAAI,WAAW,KAAK,IAAI,IAAI;AAGlF,QAAM,gBAAgB,mBAAmB,YAAY;AAErD,QAAM,YAAY,OAAO,KAAK,YAAY,EAAE;AAC5C,QAAM,YAAY,YAAY;AAE9B,MAAI;AACJ,MAAI,WAAW;AAEb,UAAM,UAAU,OAAO,QAAQ,YAAY,EACxC,IAAI,EAAE,KAAK,UAAU,KAAK,eAAe,KAAK,aAAa,EAC3D,KAAK;AAAA,CAAI;AACZ,eAAW,kBAAkB;AAAA;AAAA,EAE/B;AAAA,EACA,OAAO;AAEL,eAAW;AAAA;AAAA;AAAA,EAGb;AAAA;AAAA;AAIA,QAAM,cAAc,yEAAyE;AAAA;AAAA;AAAA;AAAA;AAAA,EAK7F;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAIA;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;AAqCA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS,CAAC,MAAc,YAA8B,SAAS,QAAQ,MAAM,KAAK,OAAO;AAAA,EAC3F;AAAA;;;ACjKF;AAEA;;;ACFA;AACA;AAAA,WACE;AAAA;AAAA;AAAA;AAAA,YAIA;AAAA;AAAA;AAAA,YAGA;AAAA;AAAA;AAAA;AAAA,cAIA;AAAA,YACA;AAAA;AAAA;AAAA;AAQF,IAAM,eAAe,OAAO,IAAI,eAAe;AAE/C,IAAM,qBAAqB;AAS3B,IAAM,mBAA6C,MAAM;AACvD,QAAM,IAAI;AACV,aAAW,EAAE,WAAW,YAAY,EAAE,WAAW,MAAM;AACrD,UAAM,QAAQ,EAAE;AAChB,UAAM,aAAa,IAAI,MAAM,WAAW,EAAE,QAAQ,KAAK,CAAC;AACxD,UAAM,cAAc;AACpB,WAAO,CAAC,SAAiB;AAEvB,UAAI;AACF,cAAM,UAAU,GAAG,cAAc;AACjC,cAAM,SAAS,WAAW,cAAc,OAAO,EAAE,KAAK;AACtD,YAAI,OAAO,WAAW,WAAW,GAAG;AAClC,cAAI,OAAO,OAAO,MAAM,YAAY,MAAM;AAC1C,cAAI,KAAK,SAAS,GAAG;AAAG,mBAAO,KAAK,MAAM,GAAG,EAAE;AAC/C,iBAAO,KAAK,KAAK;AAAA,QACnB;AAAA,cACA;AAAA;AAIF,UAAI;AACF,eAAO,WAAW,cAAc,IAAI,EAAE,KAAK;AAAA,cAC3C;AACA,eAAO;AAAA;AAAA;AAAA,EAGb;AACA,SAAO,CAAC,SAAiB;AAAA,GACxB;AAKH,IAAM,WAAW;AACjB,IAAM,SAAS,SAAS;AACxB,IAAM,cAAc,SAAS;AAC7B,IAAM,gBAAgB,SAAS;AAC/B,IAAM,OAAO,SAAS;AACtB,IAAM,YAAY,SAAS;AAC3B,IAAM,WAAW,SAAS;AAC1B,IAAM,WAAW,SAAS;AAC1B,IAAM,WAAW,SAAS;AAM1B,SAAS,QAAW,CAAC,KAAyD;AAC5E,SAAO,SAAS,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;AAAA;AAM3C,SAAS,KAAK,CAAC,IAA2B;AACxC,SAAO,IAAI,SAAe,CAAC,YAAY,YAAY,SAAS,EAAE,CAAC;AAAA;AAMjE,SAAS,QAAQ,CAAC,OAA0D;AAC1E,gBAAc,UAAU,YAAY,UAAU,QAAQ,gBAAgB;AAAA;AAajE,SAAS,aAAa,CAAC,MAAsB;AAElD,QAAM,UAAU,KAAK,KAAK;AAC1B,QAAM,WAAW,gBAAgB,OAAO;AAExC,QAAM,SAAS,YAAY;AAC3B,MAAI;AACF,UAAM,MAAY,YAAM,QAAQ,EAAE,aAAa,MAAM,YAAY,SAAS,CAAC;AAC3E,UAAM,OAAO,IAAI;AAEjB,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO,yBAAyB;AAAA,IAClC;AAGA,UAAM,QAAQ,KAAK;AACnB,QAAI,KAAK,WAAW,KAAK,MAAM,SAAS,uBAAuB;AAC7D,YAAM,OAAO,MAAM;AACnB,UAAI,KAAK,SAAS,2BAA2B;AAE3C,cAAM,YAAY,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG;AACnD,eAAO,WAAW;AAAA,MACpB;AAAA,IACF;AAGA,UAAM,OAAO,KAAK,KAAK,SAAS;AAChC,QAAI,KAAK,SAAS,uBAAuB;AACvC,YAAM,SAAS,OAAO,MAAM,GAAG,KAAK,KAAK;AACzC,YAAM,OAAO,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG;AAE9C,YAAM,YAAY,KAAK,QAAQ,SAAS,EAAE;AAC1C,aAAO,yBAAyB,gBAAgB;AAAA,IAClD;AAGA,WAAO,yBAAyB;AAAA,UAChC;AAEA,WAAO,sBAAsB,MAAM;AAAA;AAAA;AAOvC,SAAS,qBAAqB,CAAC,MAAsB;AACnD,MAAI,gBAAgB,IAAI,GAAG;AACzB,WAAO,WAAW;AAAA,EACpB;AACA,SAAO,yBAAyB;AAAA;AAGlC,SAAS,eAAe,CAAC,MAAuB;AAC9C,MAAI,cAAc,KAAK,IAAI;AAAG,WAAO;AACrC,MAAI,8BAA8B,KAAK,IAAI;AAAG,WAAO;AACrD,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,QAAI,QAAQ;AACZ,aAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAI,KAAK,OAAO;AAAK;AAAA,eACZ,KAAK,OAAO,KAAK;AACxB;AACA,YAAI,UAAU,GAAG;AACf,gBAAM,OAAO,KAAK,MAAM,IAAI,CAAC,EAAE,UAAU;AACzC,iBAAO,KAAK,WAAW,IAAI;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,sBAAsB,KAAK,IAAI;AAAG,WAAO;AAC7C,SAAO;AAAA;AAGT,IAAM,mBAAmB,MAAM;AAC7B,QAAM,IAAI,MAAM,kDAAkD;AAAA;AAMpE,IAAM,sBAAsB,IAAI,MAAM,MAAM;AAAC,GAAG;AAAA,EAC9C,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,kDAAkD;AAAA;AAAA,EAEpE,KAAK,GAAG;AACN,UAAM,IAAI,MAAM,kDAAkD;AAAA;AAEtE,CAAC;AAKM,SAAS,mBAAmB,CACjC,KACA,SACA,MACyB;AACzB,QAAM,QAAQ,SAAS;AAEvB,QAAM,OAAO,CAAC,OAAe,QAAgB;AAC3C,SAAK,KAAK,UAAU,QAAQ,MAAM,IAAI,UAAU,KAAK;AACrD,YAAQ,OAAO,GAAG;AAAA;AAGpB,QAAM,kBAAkB;AAAA,IACtB,KAAK,IAAI,SAAyB,KAAK,OAAO,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,IACxE,MAAM,IAAI,SAAyB,KAAK,QAAQ,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,IAC1E,OAAO,IAAI,SAAyB,KAAK,SAAS,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,IAC5E,MAAM,IAAI,SAAyB,KAAK,QAAQ,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,IAC1E,OAAO,IAAI,SAAyB,KAAK,SAAS,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9E;AAEA,QAAM,eAAe,SAAS,iBAAiB;AAE/C,QAAM,UAAmC;AAAA,IACvC,UAAU,OAAO,OAAO,GAAG;AAAA,IAC3B,SAAS,OAAO,OAAO,eAAe;AAAA,IACtC,OAAO,eAAe,SAAS;AAAA,IAC/B,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,KAAK,eAAe,OAAO;AAAA,IAC3B,UAAU,eAAe,YAAY;AAAA,IACrC,SAAS,eAAe,WAAW;AAAA,IACnC,SAAS,eAAe,WAAW;AAAA,IACnC,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IAEA;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;AAEA,SAAO;AAAA;AAUF,SAAS,kBAAkB,CAChC,SACU;AACV,SAAO;AAAA,IACL,SAAS,OACP,MACA,KACA,YAC2B;AAC3B,YAAM,OAAiB,CAAC;AACxB,YAAM,UAAU,oBAAoB,KAAK,SAAS,IAAI;AAEtD,UAAI;AACF,cAAM,UAAU,KAAK,KAAK;AAC1B,cAAM,cAAc,cAAc,OAAO;AACzC,cAAM,UAAW,UAAkD,gBAAsC;AAEzG,YAAI,SAAS,MAAM,SAAS,KAAK;AAAA,UAC/B,QAAQ,aAAa,OAAO;AAAA,UAC5B,IAAI,SAAgB,CAAC,GAAG,WACtB,YAAY,MAAM,OAAO,IAAI,MAAM,6BAA6B,WAAW,CAAC,GAAG,OAAO,CACxF;AAAA,QACF,CAAC;AAGD,YAAI,SAAS,MAAM,GAAG;AACpB,mBAAS,MAAM,QAAO,WAAW,MAAM;AAAA,QACzC;AAEA,eAAO,EAAE,QAAQ,KAAK;AAAA,eACf,KAAP;AACA,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,QAAQ,WAAW,OAAO,SAAS,KAAK;AAAA;AAAA;AAAA,EAGvD;AAAA;;;AD7RF,IAAM,uBAAuB,MAC3B,mBAAmB,OAAO,aAAa,YAAY;AACjD,QAAM,aAAa,OAAO,KAAK,OAAO;AACtC,QAAM,cAAc,OAAO,OAAO,OAAO;AACzC,QAAM,KAAK,IAAI,SAAS,GAAG,YAAY,WAAW;AAClD,SAAO,GAAG,GAAG,WAAW;AAAA,CACzB;AASH,IAAM,mBAAmB,MACvB,mBAAmB,OAAO,aAAa,YAAY;AAEjD,QAAM,aAAa,YAAY,WAAW,SAAS,IAC/C,YAAY,MAAM,CAAC,IACnB;AACJ,QAAM,UAAa,iBAAc,OAAO;AACxC,QAAM,SAAS,IAAO,UAAO,UAAU;AACvC,SAAO,OAAO,aAAa,SAAS,EAAE,SAAS,MAAO,CAAC;AAAA,CACxD;AAUI;AAAA,MAAM,qBAAqB,QAAQ,IAAI,2BAA2B,EAA0B,EAAE;AAAA,SACnF,SAAS,MAAM,QAAQ,cAAc,qBAAqB,CAAC;AAAA,SAC3D,KAAK,MAAM,QAAQ,cAAc,iBAAiB,CAAC;AAAA,SACnD,UAAU,aAAa;AACzC;;;AEnDA,oBAAS,oBAAS,kBAAQ,eAAO;AAW1B;AAAA,MAAM,yBAAyB,SAAQ,IAAI,2BAA2B,EAoB3E,EAAE;AAAA,SAKK,OAAO,QAAO,cAAc,GAAG;AACpC,UAAM,YAAY,OAAO,KAAI,KAM3B,CAAC,CAAC;AACJ,UAAM,YAAY,OAAO,KAAI,KAA6C,CAAC,CAAC;AAC5E,UAAM,sBAAsB,OAAO,KAAI,KAAoC,CAAC,CAAC;AAE7E,WAAO,iBAAiB,GAAG;AAAA,MACzB,eAAe,CAAC,MAAM,OAAO,eAC3B,KAAI,OAAO,WAAW,CAAC,WAAW,CAAC,GAAG,QAAQ,EAAE,MAAM,OAAO,YAAY,cAAc,CAAC,EAAE,CAAC,CAAC;AAAA,MAC9F,iBAAiB,CAAC,MAAM,UAAU,KAAI,OAAO,WAAW,CAAC,WAAW,CAAC,GAAG,QAAQ,EAAE,MAAM,MAAM,CAAC,CAAC;AAAA,MAChG,oBAAoB,CAAC,OAAO,KAAI,OAAO,qBAAqB,CAAC,QAAQ,CAAC,GAAG,KAAK,EAAE,CAAC;AAAA,MACjF,UAAU,QAAO,IAAI;AAAA,QACnB,WAAW,KAAI,IAAI,SAAS;AAAA,QAC5B,QAAQ,KAAI,IAAI,SAAS;AAAA,QACzB,kBAAkB,KAAI,IAAI,mBAAmB;AAAA,MAC/C,CAAC;AAAA,IACH,CAAC;AAAA,GACF;AAAA,SAEM,QAAQ,OAAM,OAAO,kBAAkB,iBAAiB,IAAI;AACrE;;;AR7CA,SAAS,cAAc,CAAC,QAAiF;AACvG,SAAO,QAAO,cAAc,GAAG;AAE7B,UAAM,eAAe,OAAO,iBAAiB;AAG7C,UAAM,gBAAgB,OAAM,QAAQ,kBAAkB,YAAY;AAClE,UAAM,eACJ,OAAO,WAAW,IACd,OAAO,KACP,OAAM,SACJ,GAAI,MAKN;AACN,UAAM,YAAY,OAAM,QAAQ,cAAc,aAAa;AAG3D,WAAO,OAAM,MAAM,SAAS,EAAE,KAAK,QAAO,MAAM;AAGhD,YAAQ,WAAW,WAAW,OAAO,aAAa;AAGlD,UAAM,WAA2C,CAAC;AAClD,eAAW,SAAS,WAAW;AAC7B,kBAAY,KAAK,SAAS,OAAO,QAAQ,MAAM,KAAK,GAAG;AACrD,iBAAS,OAAO,KAAK,MAAM,SAAS,MAAM,KAAK;AAAA,MACjD;AAAA,IACF;AAGA,UAAM,cAAwB,CAAC;AAC/B,eAAW,KAAK,WAAW;AACzB,kBAAY,KAAK,KAAK,EAAE,iBAAiB;AAAA,IAC3C;AACA,eAAW,KAAK,QAAQ;AACtB,kBAAY,KAAK,KAAK,EAAE,sBAAsB,EAAE,QAAQ;AAAA,IAC1D;AACA,UAAM,aAAa,YAAY,KAAK;AAAA,CAAI;AACxC,UAAM,aAAa,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI;AAE9C,WAAO,EAAE,UAAU,YAAY,WAAW;AAAA,GAC3C;AAAA;AAaI,SAAS,aAAa,IACxB,QACW;AACd,SAAO,QAAO,QACZ,QAAO,cAAc,GAAG;AACtB,YAAQ,UAAU,YAAY,eAAe,OAAO,eAAe,MAAM;AAGzE,UAAM,KAAK,OAAO,QAAO,QAAe;AACxC,UAAM,OAAO,OAAO,QAAO,QAAQ,cAAc,aAAa,OAAO;AAErE,WAAO,mBAAmB,UAAU,IAAI,MAAM,YAAY,CAAC,GAAG,UAAU;AAAA,GACzE,CACH;AAAA;AAYK,SAAS,cAAc,IACzB,QACK;AACR,SAAO,QAAO,QACZ,QAAO,cAAc,GAAG;AACtB,YAAQ,aAAa,OAAO,eAAe,MAAM;AAGjD,UAAM,eAAkD,CAAC;AACzD,gBAAY,KAAK,SAAS,OAAO,QAAQ,QAAQ,GAAG;AAClD,mBAAa,OAAO,oBAAoB,IAAI;AAAA,IAC9C;AACA,WAAO,qBAAqB,YAAY;AAAA,GACzC,CACH;AAAA;",
16
+ "debugId": "5529472230DF2A5864756E2164756E21",
17
+ "names": []
18
+ }
package/dist/tool.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { Schema } from "effect";
2
+ import type { ToolMiddleware } from "./types";
3
+ /**
4
+ * Structural constraint for a Schema.TaggedError class.
5
+ *
6
+ * We avoid using `Schema.TaggedErrorClass<any, string, any>` directly because
7
+ * its `Invariant<Self>` wrapper in the Schema TypeId causes variance issues
8
+ * under strict tsconfig (e.g. `exactOptionalPropertyTypes`). Instead, we match
9
+ * the structural shape: a constructor with a static `_tag` property.
10
+ */
11
+ export interface TaggedErrorClassLike {
12
+ readonly _tag: string;
13
+ new (...args: ReadonlyArray<never>): {
14
+ readonly _tag: string;
15
+ };
16
+ }
17
+ /**
18
+ * A pure shape descriptor for a tool — name, description, input/output schemas,
19
+ * error types, and flags. No execute function.
20
+ *
21
+ * Analogous to `Rpc.make()` in `@effect/rpc`.
22
+ */
23
+ export interface ToolShape<Name extends string, I, O, Errors extends ReadonlyArray<TaggedErrorClassLike>> {
24
+ readonly _tag: "ToolShape";
25
+ readonly name: Name;
26
+ readonly description: string;
27
+ readonly input: Schema.Schema.Any & {
28
+ readonly Type: I;
29
+ };
30
+ readonly output: (Schema.Schema.Any & {
31
+ readonly Type: O;
32
+ }) | undefined;
33
+ readonly errors: Errors;
34
+ readonly requiresConfirmation: boolean;
35
+ readonly example: string | undefined;
36
+ readonly middleware: ReadonlyArray<ToolMiddleware>;
37
+ }
38
+ /**
39
+ * Configuration for defining a tool shape.
40
+ */
41
+ export interface ToolConfig<I, O, Errors extends ReadonlyArray<TaggedErrorClassLike>> {
42
+ readonly description: string;
43
+ readonly input: Schema.Schema.Any & {
44
+ readonly Type: I;
45
+ };
46
+ readonly output?: (Schema.Schema.Any & {
47
+ readonly Type: O;
48
+ }) | undefined;
49
+ readonly errors?: Errors;
50
+ readonly requiresConfirmation?: boolean;
51
+ readonly example?: string;
52
+ readonly middleware?: ReadonlyArray<ToolMiddleware>;
53
+ }
54
+ /**
55
+ * Create a tool shape — a pure data descriptor with no implementation.
56
+ *
57
+ * Tool names are validated and sanitized at definition time using `sanitizeToolName`.
58
+ *
59
+ * ```ts
60
+ * const TodoGet = Codemode.tool("todo_get", {
61
+ * description: "Get a todo by ID",
62
+ * input: Schema.Struct({ id: Schema.String }),
63
+ * output: Todo,
64
+ * errors: [NotFoundError],
65
+ * })
66
+ * ```
67
+ */
68
+ export declare function tool<Name extends string, I, O = never, Errors extends ReadonlyArray<TaggedErrorClassLike> = []>(name: Name, config: ToolConfig<I, O, Errors>): ToolShape<Name, I, O, Errors>;
69
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,KAAK,GAAG,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC/D;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,SAAS,aAAa,CAAC,oBAAoB,CAAC;IACtG,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAA;IACxD,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAA;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,SAAS,aAAa,CAAC,oBAAoB,CAAC;IAClF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAA;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAA;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;CACpD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,SAAS,aAAa,CAAC,oBAAoB,CAAC,GAAG,EAAE,EAC7G,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,GAC/B,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAc/B"}
@@ -0,0 +1,10 @@
1
+ import type { Sink } from "effect/Sink";
2
+ import type { Stream } from "effect/Stream";
3
+ /**
4
+ * Stdio transport — provides McpServer via stdin/stdout.
5
+ */
6
+ export declare const StdioTransport: (stdin: Stream<Uint8Array<ArrayBufferLike>, unknown, unknown>, stdout: Sink<unknown, string | Uint8Array<ArrayBufferLike>, unknown, unknown, unknown>, options?: {
7
+ name?: string;
8
+ version?: string;
9
+ } | undefined) => import("effect/Layer").Layer<import("@effect/ai/McpServer").McpServer | import("@effect/ai/McpSchema").McpServerClient, never, unknown>;
10
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,cAAc;;;yJAUvB,CAAA"}
@@ -0,0 +1,33 @@
1
+ import * as SchemaAST from "effect/SchemaAST";
2
+ /**
3
+ * Describes an error type for typegen.
4
+ * - `string` form: just the tag name (e.g. "NotFoundError") — generates a minimal type with `_tag` and `message`.
5
+ * - `object` form: tag name plus the full SchemaAST — generates a complete type with all fields.
6
+ */
7
+ export type ErrorDescriptor = string | {
8
+ readonly tag: string;
9
+ readonly ast: SchemaAST.AST;
10
+ };
11
+ export interface ToolDescriptor {
12
+ readonly name: string;
13
+ readonly description: string;
14
+ readonly inputSchema: SchemaAST.AST;
15
+ readonly outputSchema?: SchemaAST.AST | undefined;
16
+ readonly errors?: ReadonlyArray<ErrorDescriptor> | undefined;
17
+ }
18
+ /**
19
+ * Walk an Effect SchemaAST and produce a TypeScript type string.
20
+ */
21
+ export declare function astToTypeScript(ast: SchemaAST.AST, seen?: Set<SchemaAST.AST>): string;
22
+ /**
23
+ * Generate TypeScript declarations for a set of tool descriptors.
24
+ *
25
+ * Methods return `Effect<Output, ErrorType>` for use in Effect.gen programs.
26
+ * Error types are generated as tagged union members.
27
+ *
28
+ * When multiple tools share an identical output schema, the type is emitted
29
+ * once (using the schema's identifier annotation if available) and referenced
30
+ * by name in each method signature.
31
+ */
32
+ export declare function generateDeclarations(tools: Record<string, ToolDescriptor>): string;
33
+ //# sourceMappingURL=typegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../src/typegen.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAA;AAI7C;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB,MAAM,GACN;IACE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAA;CAC5B,CAAA;AAEL,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,CAAA;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAA;CAC7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,qBAA2B,GAAG,MAAM,CA8G3F;AA4FD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,MAAM,CA+ElF"}
@@ -0,0 +1,69 @@
1
+ import { Effect, Schema } from "effect";
2
+ import type { ErrorDescriptor, ToolDescriptor as TypegenDescriptor } from "./typegen";
3
+ /**
4
+ * Describes a tool that can be bridged from an Effect service to a plain async function.
5
+ */
6
+ export interface ToolDescriptor {
7
+ readonly name: string;
8
+ readonly description: string;
9
+ readonly example?: string | undefined;
10
+ readonly inputSchema: Schema.Schema.Any;
11
+ readonly outputSchema?: Schema.Schema.Any | undefined;
12
+ readonly errors?: ReadonlyArray<ErrorDescriptor> | undefined;
13
+ readonly service?: string | undefined;
14
+ readonly requiresConfirmation?: boolean | undefined;
15
+ readonly middleware?: ReadonlyArray<ToolMiddleware> | undefined;
16
+ readonly execute: (input: unknown) => Effect.Effect<unknown, unknown, unknown>;
17
+ }
18
+ /**
19
+ * Context passed to each middleware function, describing the tool being invoked.
20
+ */
21
+ export interface ToolInvocation {
22
+ readonly name: string;
23
+ readonly input: unknown;
24
+ }
25
+ /**
26
+ * A middleware function that wraps tool execution.
27
+ *
28
+ * Receives the tool invocation context and a `next` Effect representing
29
+ * the downstream execution (either the next middleware or the tool itself).
30
+ * Must return an Effect that produces the tool result.
31
+ *
32
+ * ```ts
33
+ * const logging: ToolMiddleware = (tool, next) =>
34
+ * Effect.gen(function* () {
35
+ * console.log(`Calling ${tool.name}`)
36
+ * const result = yield* next
37
+ * console.log(`Done ${tool.name}`)
38
+ * return result
39
+ * })
40
+ * ```
41
+ */
42
+ export type ToolMiddleware = (tool: ToolInvocation, next: Effect.Effect<unknown, unknown>) => Effect.Effect<unknown, unknown>;
43
+ /**
44
+ * Result of executing user-provided code in the sandbox.
45
+ */
46
+ export interface ExecuteResult {
47
+ readonly result: unknown;
48
+ readonly error?: string;
49
+ readonly logs: string[];
50
+ }
51
+ /**
52
+ * Interface for code execution engines.
53
+ */
54
+ export interface ExecutorOptions {
55
+ /** Called for each console.log/warn/error/info/debug from sandbox code — use for streaming progress */
56
+ readonly onLog?: (level: string, message: string) => void;
57
+ /** Whether to allow network access (fetch, URL, Request, Headers, Response) in the sandbox. Defaults to true. */
58
+ readonly allowNetwork?: boolean;
59
+ /** Maximum execution time in milliseconds. */
60
+ readonly timeoutMs?: number | undefined;
61
+ }
62
+ export interface Executor {
63
+ readonly execute: (code: string, fns: Record<string, (...args: Array<unknown>) => unknown>, options?: ExecutorOptions) => Promise<ExecuteResult>;
64
+ }
65
+ /**
66
+ * Convert a tool descriptor (Schema.Schema.Any) to typegen format (SchemaAST.AST).
67
+ */
68
+ export declare function toTypegenDescriptor(tool: ToolDescriptor): TypegenDescriptor;
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAGvC,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAErF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,CAAA;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAA;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,SAAS,CAAA;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;CAC/E;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,KAClC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAEpC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yGAAuG;IACvG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD,iHAAiH;IACjH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,EACzD,OAAO,CAAC,EAAE,eAAe,KACtB,OAAO,CAAC,aAAa,CAAC,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,CAQ3E"}
package/package.json CHANGED
@@ -1,19 +1,53 @@
1
1
  {
2
2
  "name": "effect-codemode",
3
- "version": "0.0.1",
3
+ "version": "0.1.0-beta.0",
4
4
  "description": "Effect-native codemode for MCP — give LLMs a typed Effect SDK instead of individual tool calls",
5
+ "keywords": [
6
+ "ai",
7
+ "codemode",
8
+ "effect",
9
+ "effect-ts",
10
+ "llm",
11
+ "mcp",
12
+ "model-context-protocol",
13
+ "tool-calling",
14
+ "typescript"
15
+ ],
5
16
  "license": "MIT",
6
- "author": "aulneau",
7
17
  "repository": {
8
18
  "type": "git",
9
19
  "url": "https://github.com/aulneau/effect-codemode"
10
20
  },
11
- "keywords": [
12
- "effect",
13
- "mcp",
14
- "codemode",
15
- "ai",
16
- "llm",
17
- "typescript"
18
- ]
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "type": "module",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ },
31
+ "./test": {
32
+ "types": "./dist/testing.d.ts",
33
+ "import": "./dist/testing.js"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "build": "rm -rf dist && tsgo -p tsconfig.build.json && bun build ./src/index.ts ./src/testing.ts --outdir ./dist --root ./src --packages=external --format esm --sourcemap=external"
38
+ },
39
+ "dependencies": {
40
+ "@effect/ai": "^0.33.2",
41
+ "@effect/platform": "^0.94.5",
42
+ "@effect/rpc": "^0.73.2",
43
+ "acorn": "^8.16.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/acorn": "^6.0.4",
47
+ "bun-types": "^1.3.9",
48
+ "effect": "3.19.14"
49
+ },
50
+ "peerDependencies": {
51
+ "effect": "^3.19.0"
52
+ }
19
53
  }