theokit 0.74.5 → 0.75.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.
Files changed (98) hide show
  1. package/dist/{actions-virtual-module-MIQJEHKJ.js → actions-virtual-module-MIQPBAZW.js} +5 -5
  2. package/dist/{actions-virtual-module-4J7Z37Y4.js → actions-virtual-module-QEI6QPK4.js} +5 -5
  3. package/dist/adapters/agent-mount.js +1 -1
  4. package/dist/{agent-XPZUWTHR.js → agent-IIF6JUWX.js} +3 -3
  5. package/dist/{app-typed-client-AZMUYIYV.js → app-typed-client-CHSITA46.js} +5 -5
  6. package/dist/{app-typed-client-DSS23KDC.js → app-typed-client-XQJXF646.js} +5 -5
  7. package/dist/{build-F3O5LJHY.js → build-QIO4VAW2.js} +22 -87
  8. package/dist/build-QIO4VAW2.js.map +1 -0
  9. package/dist/{chunk-PZLH4WGU.js → chunk-2BMJQMTH.js} +5 -5
  10. package/dist/{chunk-44E7XIZC.js → chunk-3MKRDJQ2.js} +2 -2
  11. package/dist/{chunk-4ERYQBL6.js → chunk-4Z5XO4O4.js} +2 -2
  12. package/dist/{chunk-FPC6ZEEU.js → chunk-6RVWPEKK.js} +10 -10
  13. package/dist/{chunk-V7ISZGNS.js → chunk-7HGZ3CKL.js} +2 -2
  14. package/dist/{chunk-6R5F5YF2.js → chunk-A6UFN6QQ.js} +16 -11
  15. package/dist/{chunk-6R5F5YF2.js.map → chunk-A6UFN6QQ.js.map} +1 -1
  16. package/dist/{chunk-5KRMDP46.js → chunk-AHYOVVJ7.js} +13 -3
  17. package/dist/chunk-AHYOVVJ7.js.map +1 -0
  18. package/dist/{chunk-WR5B2XNT.js → chunk-FNAEKJHO.js} +2 -2
  19. package/dist/{chunk-HKF6YNY4.js → chunk-FU3LEX2I.js} +26 -12
  20. package/dist/chunk-FU3LEX2I.js.map +1 -0
  21. package/dist/{chunk-VD3BCME6.js → chunk-I5PDEWZZ.js} +2 -2
  22. package/dist/chunk-IWIRHUNV.js +96 -0
  23. package/dist/chunk-IWIRHUNV.js.map +1 -0
  24. package/dist/{chunk-U5PWXS3J.js → chunk-O5JZ6ROY.js} +13 -3
  25. package/dist/chunk-O5JZ6ROY.js.map +1 -0
  26. package/dist/{chunk-VOXLI66L.js → chunk-OZB2TKGJ.js} +2 -2
  27. package/dist/{chunk-ET2TAY3Z.js → chunk-RAUYMVUO.js} +279 -15
  28. package/dist/chunk-RAUYMVUO.js.map +1 -0
  29. package/dist/{chunk-XUAWD5HK.js → chunk-RKRFJRJ3.js} +10 -10
  30. package/dist/{chunk-DA3GGICE.js → chunk-RQKMY3JW.js} +2 -2
  31. package/dist/{chunk-D5KBBTVD.js → chunk-RY6D4EXL.js} +20 -13
  32. package/dist/chunk-RY6D4EXL.js.map +1 -0
  33. package/dist/cli/index.js +10 -10
  34. package/dist/{dev-TW6QD7F3.js → dev-J2XZIENF.js} +8 -8
  35. package/dist/{dev-emit-T3X6RR7M.js → dev-emit-AXTJK56H.js} +3 -3
  36. package/dist/{dev-emit-ZK5GCHXN.js → dev-emit-XAPVJBM4.js} +3 -3
  37. package/dist/{generate-EN6EDITF.js → generate-RW3NO3NR.js} +239 -141
  38. package/dist/generate-RW3NO3NR.js.map +1 -0
  39. package/dist/index.js +5 -5
  40. package/dist/{info-XURFOBRF.js → info-6NAUW5XY.js} +3 -3
  41. package/dist/{internal-api-XPT4GLYX.js → internal-api-A5HA7TYF.js} +5 -5
  42. package/dist/{internal-api-ATSPOXI2.js → internal-api-R7TTYMCY.js} +5 -5
  43. package/dist/{load-config-2DXLI7NW.js → load-config-CLFWJOXN.js} +3 -3
  44. package/dist/{mcp-LMV3NQEP.js → mcp-MWTG3LRA.js} +4 -4
  45. package/dist/{openapi-UJSUQPNT.js → openapi-RVFUXXCR.js} +5 -5
  46. package/dist/{preview-AMNBV2DP.js → preview-ML4CFUD6.js} +3 -3
  47. package/dist/{routes-ENMU4GAN.js → routes-SMNSI2ZX.js} +3 -3
  48. package/dist/server/agent/index.d.ts +99 -6
  49. package/dist/server/agent/index.js +9 -1
  50. package/dist/server/cron/index.js +2 -2
  51. package/dist/server/index.d.ts +1 -1
  52. package/dist/server/index.js +15 -7
  53. package/dist/server/index.js.map +1 -1
  54. package/dist/server/jobs/index.js +2 -2
  55. package/dist/server/scan/index.js +4 -4
  56. package/dist/{server-boundary-K4YQXDQT.js → server-boundary-HYLYGFZY.js} +5 -5
  57. package/dist/{server-boundary-JM72DQLA.js → server-boundary-ZT6HN7ON.js} +5 -5
  58. package/dist/{start-GAULIE5E.js → start-L5TGWGLU.js} +7 -7
  59. package/dist/vite-plugin/index.js +5 -5
  60. package/dist/{vite-plugin-4ZMBW3KV.js → vite-plugin-OJND2LU5.js} +8 -8
  61. package/package.json +2 -2
  62. package/dist/build-F3O5LJHY.js.map +0 -1
  63. package/dist/chunk-5KRMDP46.js.map +0 -1
  64. package/dist/chunk-D5KBBTVD.js.map +0 -1
  65. package/dist/chunk-ET2TAY3Z.js.map +0 -1
  66. package/dist/chunk-HKF6YNY4.js.map +0 -1
  67. package/dist/chunk-U5PWXS3J.js.map +0 -1
  68. package/dist/generate-EN6EDITF.js.map +0 -1
  69. /package/dist/{actions-virtual-module-MIQJEHKJ.js.map → actions-virtual-module-MIQPBAZW.js.map} +0 -0
  70. /package/dist/{actions-virtual-module-4J7Z37Y4.js.map → actions-virtual-module-QEI6QPK4.js.map} +0 -0
  71. /package/dist/{agent-XPZUWTHR.js.map → agent-IIF6JUWX.js.map} +0 -0
  72. /package/dist/{app-typed-client-AZMUYIYV.js.map → app-typed-client-CHSITA46.js.map} +0 -0
  73. /package/dist/{app-typed-client-DSS23KDC.js.map → app-typed-client-XQJXF646.js.map} +0 -0
  74. /package/dist/{chunk-PZLH4WGU.js.map → chunk-2BMJQMTH.js.map} +0 -0
  75. /package/dist/{chunk-44E7XIZC.js.map → chunk-3MKRDJQ2.js.map} +0 -0
  76. /package/dist/{chunk-4ERYQBL6.js.map → chunk-4Z5XO4O4.js.map} +0 -0
  77. /package/dist/{chunk-FPC6ZEEU.js.map → chunk-6RVWPEKK.js.map} +0 -0
  78. /package/dist/{chunk-V7ISZGNS.js.map → chunk-7HGZ3CKL.js.map} +0 -0
  79. /package/dist/{chunk-WR5B2XNT.js.map → chunk-FNAEKJHO.js.map} +0 -0
  80. /package/dist/{chunk-VD3BCME6.js.map → chunk-I5PDEWZZ.js.map} +0 -0
  81. /package/dist/{chunk-VOXLI66L.js.map → chunk-OZB2TKGJ.js.map} +0 -0
  82. /package/dist/{chunk-XUAWD5HK.js.map → chunk-RKRFJRJ3.js.map} +0 -0
  83. /package/dist/{chunk-DA3GGICE.js.map → chunk-RQKMY3JW.js.map} +0 -0
  84. /package/dist/{dev-TW6QD7F3.js.map → dev-J2XZIENF.js.map} +0 -0
  85. /package/dist/{dev-emit-T3X6RR7M.js.map → dev-emit-AXTJK56H.js.map} +0 -0
  86. /package/dist/{dev-emit-ZK5GCHXN.js.map → dev-emit-XAPVJBM4.js.map} +0 -0
  87. /package/dist/{info-XURFOBRF.js.map → info-6NAUW5XY.js.map} +0 -0
  88. /package/dist/{internal-api-XPT4GLYX.js.map → internal-api-A5HA7TYF.js.map} +0 -0
  89. /package/dist/{internal-api-ATSPOXI2.js.map → internal-api-R7TTYMCY.js.map} +0 -0
  90. /package/dist/{load-config-2DXLI7NW.js.map → load-config-CLFWJOXN.js.map} +0 -0
  91. /package/dist/{mcp-LMV3NQEP.js.map → mcp-MWTG3LRA.js.map} +0 -0
  92. /package/dist/{openapi-UJSUQPNT.js.map → openapi-RVFUXXCR.js.map} +0 -0
  93. /package/dist/{preview-AMNBV2DP.js.map → preview-ML4CFUD6.js.map} +0 -0
  94. /package/dist/{routes-ENMU4GAN.js.map → routes-SMNSI2ZX.js.map} +0 -0
  95. /package/dist/{server-boundary-K4YQXDQT.js.map → server-boundary-HYLYGFZY.js.map} +0 -0
  96. /package/dist/{server-boundary-JM72DQLA.js.map → server-boundary-ZT6HN7ON.js.map} +0 -0
  97. /package/dist/{start-GAULIE5E.js.map → start-L5TGWGLU.js.map} +0 -0
  98. /package/dist/{vite-plugin-4ZMBW3KV.js.map → vite-plugin-OJND2LU5.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/generate.ts","../src/cli/commands/generate-containment.ts","../src/cli/commands/generate-policy-placeholder.ts","../src/cli/commands/generate-resource.ts","../src/cli/commands/generate-schedule.ts","../src/server/cron/define-cron.ts","../src/cli/commands/generate-types.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\n\nimport { pathTraversalRefusal } from './generate-containment.js'\nimport {\n UNDECIDED_POLICY_IDENT,\n undecidedPolicyDeclaration,\n} from './generate-policy-placeholder.js'\nimport { generateResource } from './generate-resource.js'\nimport { resolveScheduleTarget } from './generate-schedule.js'\nimport {\n VALID_TYPES,\n type GeneratorType,\n type GenerateOptions,\n type GenerateResult,\n type GenerateStatus,\n} from './generate-types.js'\n\nexport {}\n\nfunction toKebabCase(name: string): boolean {\n return /^[a-z][a-z0-9/-]*$/.test(name)\n}\n\n/**\n * Reserved JS identifier names that conflict with object prototype machinery\n * or would shadow built-in module shapes if used as action/route names.\n * Mirrors action-scan's RESERVED_NAMES (T1.4).\n */\nconst RESERVED_BASENAMES = new Set([\n 'index',\n 'constructor',\n '__proto__',\n 'prototype',\n 'hasOwnProperty',\n])\n\n/**\n * Validate that a name segment doesn't hit the reserved-identifier list.\n * Checks the BASENAME (last `/` segment) — nested `admin/constructor` still\n * rejected because the file `constructor.ts` would be the conflict.\n */\nfunction hasReservedSegment(name: string): boolean {\n const basename = name.includes('/') ? (name.split('/').pop() ?? name) : name\n return RESERVED_BASENAMES.has(basename)\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 toCamelCase(name: string): string {\n const pascal = toPascalCase(name)\n return pascal.charAt(0).toLowerCase() + pascal.slice(1)\n}\n\nfunction generateRouteTemplate(name: string): string {\n return [\n `import { route, type AccessDecision } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${name}.ts`,\n 'a stub today is a real handler tomorrow',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .handler(({ ctx }) => {`,\n ` return { message: 'TODO: implement ${name} GET' }`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateControllerTemplate(name: string): string {\n const className = toPascalCase(name) + 'Controller'\n const baseName = name.split('/').pop() ?? name\n return [\n `// AUTO-GENERATED by \\`theokit generate controller ${name}\\``,\n `import { Controller, Get } from '@theokit/http'`,\n ``,\n `@Controller('${baseName}')`,\n `export class ${className} {`,\n ` @Get()`,\n ` findAll(): string {`,\n ` return 'This action returns all ${baseName}'`,\n ` }`,\n `}`,\n ``,\n ].join('\\n')\n}\n\nfunction generateActionTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { action } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const ${camel} = action()`,\n ` .input(z.object({}))`,\n ` .handler(({ input, ctx }) => {`,\n ` return { message: 'TODO: implement ${name}' }`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\n/**\n * Co-located test template for `theokit generate action <name>` (T5.2 +\n * plan Q4 scenario 1: roundtrip serialize). Skeleton uses vitest BDD shape\n * per testing.md.\n */\nfunction generateAgentTemplate(name: string): string {\n return [\n `import { AgentBuilder } from '@theokit/agents'`,\n `import { z } from 'zod'`,\n ``,\n `// Zero-config: this file is auto-served at POST /api/agents/${name}.`,\n `// Add tools with tool('name')...build() and chain them via .tool(...).`,\n `export default AgentBuilder.create()`,\n ` .input(z.object({ message: z.string() }))`,\n ` .model('openai/gpt-4o-mini')`,\n ` .system('You are a helpful ${name} assistant.')`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateToolboxTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { tool } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const ${camel}Hello = tool('${name}_hello')`,\n ` .describe('Say hello')`,\n ` .input(z.object({ name: z.string() }))`,\n ` .execute(({ name }) => \\`Hello, \\${name}!\\`)`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateWorkflowTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { Workflow, fn } from '@theokit/sdk/workflow'`,\n ``,\n `/**`,\n ` * A minimal workflow — a typed, multi-step pipeline (@theokit/sdk). Each \\`fn(...)\\` step is a pure`,\n ` * function; a step can also run an agent via \\`agentStep(name, agent, mapInput)\\`. Import + run it from`,\n ` * a route, action, cron job, or tool:`,\n ` *`,\n ` * const run = await ${camel}Workflow.run({ name: 'Ada' })`,\n ` * console.log(run.status, run.output) // 'completed' 'Hello, Ada!'`,\n ` */`,\n `export const ${camel}Workflow = Workflow.create({ name: '${name}' })`,\n ` .then(fn('normalize', (input: { name: string }) => ({ name: input.name.trim() })))`,\n ` .then(fn('greet', (step: { name: string }) => \\`Hello, \\${step.name}!\\`))`,\n ` .commit()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateEvalTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { Eval, Scorers } from '@theokit/sdk/eval'`,\n ``,\n `/**`,\n ` * An eval for your agent (@theokit/sdk) — runs the model over a dataset and scores each output.`,\n ` * To score the REAL agent, mirror its config: point \\`agent.model\\` (and, ideally, a \\`systemPrompt\\`)`,\n ` * at the same values your \\`agents/chat.ts\\` uses. Run it (needs a provider key in the environment):`,\n ` *`,\n ` * const run = await ${camel}Eval.run()`,\n ` * console.log(run.aggregate.meanScore)`,\n ` */`,\n `export const ${camel}Eval = Eval.create({`,\n ` name: '${name}',`,\n ` dataset: [{ input: 'Say ok', expected: 'ok' }],`,\n ` scorers: [Scorers.containsExpected({ caseSensitive: false })],`,\n ` // Mirror your agent: same model (+ systemPrompt) so this evaluates the agent your users talk to.`,\n ` agent: { apiKey: process.env.OPENROUTER_API_KEY ?? '', model: { id: 'openai/gpt-4o-mini' } },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateSandboxTemplate(name: string): string {\n const camel = toCamelCase(name)\n const base = name.split('/').pop() ?? name\n const snake = base.replace(/-/g, '_')\n return [\n `import { tool } from 'theokit/server'`,\n `import { LocalSandbox } from '@theokit/sdk/sandbox'`,\n `import { z } from 'zod'`,\n ``,\n `/**`,\n ` * A sandbox-backed agent tool. \\`LocalSandbox\\` (@theokit/sdk) runs a shell command with a timeout +`,\n ` * output cap, isolated from your app process — so the agent can run commands SAFELY. This IS an agent`,\n ` * capability: connect it to your agent with \\`.tool(...)\\`:`,\n ` *`,\n ` * // agents/chat.ts`,\n ` * import { ${camel}Tool } from './sandbox/${base}.js'`,\n ` * AgentBuilder.create().model(...).tool(${camel}Tool).build()`,\n ` */`,\n `export const ${camel}Tool = tool('${snake}')`,\n ` .describe('Run a shell command in an isolated sandbox and return its output.')`,\n ` .input(z.object({ command: z.string().describe('The shell command to run, e.g. \"ls -la\"') }))`,\n ` .execute(async ({ command }) => {`,\n ` const sandbox = new LocalSandbox({ timeoutMs: 5_000 })`,\n ` const { stdout, stderr, exitCode } = await sandbox.execute(command)`,\n ` return exitCode === 0 ? stdout : \\`exit \\${exitCode}: \\${stderr}\\``,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateMemoryTemplate(_name: string): string {\n return [\n `/**`,\n ` * Conversation memory — nothing to wire.`,\n ` *`,\n ` * Since @theokit/sdk 4.0, every agent session persists AUTOMATICALLY to a native Claude-shaped`,\n ` * transcript. TheoKit roots it at your app under \\`.data/agent-sessions/projects/<cwd>/<agentId>.jsonl\\`,`,\n ` * keyed by the conversation's session id — a same-session follow-up request resumes prior turns with`,\n ` * zero setup. There is no storage adapter to construct or pass to the agent anymore.`,\n ` *`,\n ` * Keep these transcripts out of git — add \\`.data/\\` to your \\`.gitignore\\`.`,\n ` *`,\n ` * Advanced: to change WHERE sessions are written (e.g. \\`~/.claude\\` so the Claude Code CLI can`,\n ` * \\`--continue\\` them), set the SDK's \\`local.baseDir\\` where you create the agent. Most apps never need to.`,\n ` */`,\n `export {}`,\n ``,\n ].join('\\n')\n}\n\n/** Where a single-file kind is written, relative to the project root, and what it says. */\ninterface SingleFileKind {\n path: (name: string) => string\n template: (name: string) => string\n}\n\n/**\n * The single-file kinds. `resource` writes several files and `schedule` reads its directory from\n * the project config, so neither is here.\n */\nconst SINGLE_FILE_KINDS: Partial<Record<GeneratorType, SingleFileKind>> = {\n // Agent-capability generators. These live UNDER `agents/` — they are facets of the agent domain,\n // not standalone top-level concerns — and the folder-semantic scanner treats each as composition\n // (never a phantom route).\n workflow: { path: (name) => `agents/workflows/${name}.ts`, template: generateWorkflowTemplate },\n eval: { path: (name) => `agents/evals/${name}.ts`, template: generateEvalTemplate },\n sandbox: { path: (name) => `agents/sandbox/${name}.ts`, template: generateSandboxTemplate },\n memory: { path: (name) => `agents/memory/${name}.ts`, template: generateMemoryTemplate },\n route: { path: (name) => `server/routes/${name}.ts`, template: generateRouteTemplate },\n action: { path: (name) => `server/actions/${name}.ts`, template: generateActionTemplate },\n page: { path: (name) => `app/${name}/page.tsx`, template: generatePageTemplate },\n ws: { path: (name) => `server/ws/${name}.ts`, template: generateWsTemplate },\n controller: {\n path: (name) => `server/controllers/${name}.controller.ts`,\n template: generateControllerTemplate,\n },\n agent: { path: (name) => `server/agents/${name}.agent.ts`, template: generateAgentTemplate },\n toolbox: {\n path: (name) => `server/toolboxes/${name}.tools.ts`,\n template: generateToolboxTemplate,\n },\n}\n\nfunction resolveTemplate(\n cwd: string,\n kind: GeneratorType,\n name: string,\n): { filePath: string; content: string } | null {\n const spec = SINGLE_FILE_KINDS[kind]\n if (spec === undefined) return null\n return { filePath: resolve(cwd, spec.path(name)), content: spec.template(name) }\n}\n\nfunction generateActionTestTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { describe, it, expect } from 'vitest'`,\n ``,\n `import { ${camel} } from './${name.split('/').pop()}.js'`,\n ``,\n `describe('${name} action', () => {`,\n ` it('should accept a valid input shape', () => {`,\n ` expect(${camel}.input).toBeDefined()`,\n ` expect(typeof ${camel}.handler).toBe('function')`,\n ` })`,\n ``,\n ` it('should reject invalid input via zod schema', () => {`,\n ` const parsed = ${camel}.input.safeParse({ __invalid: true })`,\n ` // Empty object schema accepts {}; tighten this assertion when adding fields.`,\n ` expect(parsed.success).toBe(true)`,\n ` })`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generatePageTemplate(name: string): string {\n const pascal = toPascalCase(name)\n return [`export default function ${pascal}Page() {`, ` return <h1>${pascal}</h1>`, `}`, ``].join(\n '\\n',\n )\n}\n\nfunction generateWsTemplate(_name: string): string {\n return [\n `import { defineWebSocket } from 'theokit/server'`,\n ``,\n `export default defineWebSocket({`,\n ` onMessage(ws, data) {`,\n ` ws.send(\\`echo: \\${data}\\`)`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n/** A file to write: where it goes and what it says. */\ninterface Target {\n filePath: string\n content: string\n}\n\n/** Whether `value` names a generator kind. */\nfunction isGeneratorType(value: string): value is GeneratorType {\n return (VALID_TYPES as readonly string[]).includes(value)\n}\n\n/**\n * The refusal for options `generate` cannot act on: not a project, an unknown kind, a name that is\n * not kebab-case, or a reserved basename. `undefined` when the options are acceptable.\n */\nfunction refuseOptions({ cwd, type, name }: GenerateOptions): GenerateResult | undefined {\n if (!existsSync(resolve(cwd, 'theo.config.ts')) && !existsSync(resolve(cwd, 'theo.config.js'))) {\n return {\n status: 'not_a_project',\n message: 'Not a Theo project. cwd has no theo.config.ts or theo.config.js',\n }\n }\n\n if (!isGeneratorType(type)) {\n return {\n status: 'invalid_kind',\n message: `Invalid generator type \"${type}\". Available: ${VALID_TYPES.join(', ')}`,\n }\n }\n\n if (!name || !toKebabCase(name)) {\n return {\n status: 'invalid_name',\n message: `Invalid name \"${name}\". Use kebab-case: lowercase letters, numbers, hyphens. Example: my-route`,\n }\n }\n\n // EC-2-related: reject reserved JS identifier basenames (would shadow\n // built-in prototype machinery in virtual module emit or scan).\n if (hasReservedSegment(name)) {\n return {\n status: 'invalid_name',\n message: `Reserved name \"${name}\" — basename collides with built-in identifier (index/constructor/__proto__/prototype/hasOwnProperty).`,\n }\n }\n return undefined\n}\n\n/** Where a single-file kind goes and what it says, or the refusal that explains why it cannot. */\nasync function resolveTarget(\n cwd: string,\n type: GeneratorType,\n name: string,\n): Promise<Target | GenerateResult> {\n // A schedule's directory comes from the project config, so resolving it is async and may refuse.\n if (type === 'schedule') return resolveScheduleTarget(cwd, name)\n const target = resolveTemplate(cwd, type, name)\n if (target === null) return { status: 'invalid_kind', message: `Unknown type: ${type}` }\n return target\n}\n\n/** Write `target` unless it escapes the project or already exists. */\nfunction writeTarget(\n cwd: string,\n type: GeneratorType,\n name: string,\n { filePath, content }: Target,\n): GenerateResult {\n // EC-4: confirm the resolved filePath stays inside cwd. `toKebabCase` rejects most traversal\n // vectors in the name, but a directory read from config (`agentsDir`) can still point outside.\n const escaped = pathTraversalRefusal(cwd, filePath)\n if (escaped !== undefined) return escaped\n\n if (existsSync(filePath)) {\n return { status: 'already_exists', filePath, kind: type, name }\n }\n\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content)\n\n // T5.2 + plan Q4: emit co-located test file alongside actions (only\n // for action type; routes/pages/ws keep prior single-file behavior).\n // Skip if existing test file present (preserve user-customized tests).\n if (type === 'action') {\n const testPath = filePath.replace(/\\.ts$/, '.test.ts')\n if (!existsSync(testPath)) {\n writeFileSync(testPath, generateActionTestTemplate(name))\n }\n }\n\n return { status: 'created', filePath, kind: type, name }\n}\n\n/**\n * Programmatic generate. Returns a structured result instead of throwing —\n * Studio (`theokit_generate` tool) consumes this directly. The CLI wrapper\n * below maps the structured result to console output + exit code semantics.\n */\nexport async function generate(opts: GenerateOptions): Promise<GenerateResult> {\n const refused = refuseOptions(opts)\n if (refused !== undefined) return refused\n const { cwd, name } = opts\n // refuseOptions refused every value that is not a generator kind.\n const kind = opts.type as GeneratorType\n\n // Resource generates multiple files — handle separately\n if (kind === 'resource') {\n return generateResource(cwd, name, opts.fields ?? [])\n }\n\n const resolved = await resolveTarget(cwd, kind, name)\n if ('status' in resolved) return resolved\n return writeTarget(cwd, kind, name, resolved)\n}\n\n/** The statuses the CLI reports by throwing, and the message each throws. */\nconst CLI_REFUSALS: Record<\n Exclude<GenerateStatus, 'created' | 'already_exists'>,\n (result: GenerateResult, name: string) => string\n> = {\n not_a_project: () => 'Not a Theo project. Run this from a project root with theo.config.ts',\n invalid_kind: (result) => result.message ?? 'Invalid kind',\n // `generate` returns invalid_name for a malformed name, a reserved name and a path that\n // resolves outside the project; each message says which, so the CLI must not replace it.\n invalid_name: (result, name) => result.message ?? `Invalid name \"${name}\"`,\n invalid_config: (result) => result.message ?? 'Invalid theo.config.ts',\n agent_not_found: (result) => result.message ?? 'No chat agent found',\n}\n\n/**\n * CLI entry point — preserves the original surface (throws + console.log).\n * Wraps the programmatic `generate` function.\n */\nexport async function generateCommand(\n type: string,\n name: string,\n fields?: string[],\n): Promise<void> {\n const result = await generate({ cwd: process.cwd(), type, name, fields })\n if (result.status === 'already_exists') {\n console.log(`\\n ⚠ ${result.filePath} already exists. Skipping.\\n`)\n } else if (result.status === 'created') {\n console.log(`\\n ✓ Created ${type}: ${result.filePath}\\n`)\n } else {\n throw new Error(CLI_REFUSALS[result.status](result, name))\n }\n}\n","/**\n * The one rule every generator applies before writing: the file stays inside the project. Shared\n * by `generate` and the schedule generator, which checks it before looking for the chat agent so an\n * `agentsDir` outside the project is refused as traversal, never reported as a missing agent there.\n */\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\n\nimport type { GenerateResult } from './generate-types.js'\n\n/**\n * Whether `filePath` lies strictly inside `cwd`. Decided by `path.relative`, never by a string\n * prefix: `/tmp/x/app-outside/...` starts with `/tmp/x/app` and is still outside it. A null byte,\n * an absolute path and a `..` escape are all outside.\n */\nfunction isPathInside(cwd: string, filePath: string): boolean {\n if (filePath.includes('\\x00')) return false\n const fromRoot = relative(resolve(cwd), filePath)\n return fromRoot !== '' && !isAbsolute(fromRoot) && fromRoot.split(sep)[0] !== '..'\n}\n\n/** The refusal for a `filePath` outside the project at `cwd`, or `undefined` when it is inside. */\nexport function pathTraversalRefusal(cwd: string, filePath: string): GenerateResult | undefined {\n if (isPathInside(cwd, filePath)) return undefined\n return {\n status: 'invalid_name',\n message: `Path traversal denied: \"${filePath}\" is outside the project root ${resolve(cwd)}.`,\n }\n}\n","/**\n * The access policy a generated route carries until its author decides one.\n *\n * ADR 0001 made an undeclared `policy` a build error because \"a route that nobody had thought\n * about was indistinguishable from a route deliberately left open\". The generators then wrote\n * `'public'` — including on five methods that read and write a database table — so a generated\n * file was the not-thought-about case wearing the deliberate value, which is the precise state\n * the gate exists to make impossible (usetheokit/theokit#416). `theo build` accepted it, because\n * `assertEveryMethodDeclaresPolicy` asks whether a policy was declared, not which one.\n *\n * A generated route now REFUSES. The author still has to write the answer down — the gate's whole\n * purpose — but the value standing in until they do is the safe one rather than the open one.\n *\n * ## Why an AccessDecision and not `() => false`\n *\n * `evaluateRoutePolicy` maps a bare `false` to \"access denied by route policy\", which tells the\n * reader nothing about where to go. The contract already says a denial \"carries its reason so the\n * caller can say it\", so the refusal names its own file: the first `curl` against a forgotten\n * route prints the path to edit.\n *\n * ## Why a named const rather than a lambda per method\n *\n * Five methods would mean five copies, and deleting four of them is the kind of chore that leaves\n * the fifth behind. One const is one thing to replace, and `grep -rn undecidedPolicy` counts the\n * routes still awaiting a decision — which is the number ADR 0001 wanted to make greppable, and\n * which `grep -c \"policy('public')\"` could not give once generated placeholders were mixed in with\n * real decisions.\n */\n\n/** The identifier the generated methods reference. Exported so callers cannot misspell it. */\nexport const UNDECIDED_POLICY_IDENT = 'undecidedPolicy'\n\n/**\n * Lines declaring the placeholder, to splice into a generated module.\n *\n * @param routePath - the generated file's own path, repo-relative, so the refusal can name it\n * @param what - what the route does, in one clause, for the TODO comment\n */\nexport function undecidedPolicyDeclaration(routePath: string, what: string): string[] {\n return [\n `// TODO(policy): every route declares who may call it (ADR 0001). Generated as a REFUSAL`,\n `// rather than 'public', because the generator cannot know your access model —`,\n `// ${what}.`,\n `// Replace this with 'public' if the route is genuinely open, or with a check such as`,\n `// \\`({ subject, params }) => requireOwner(subject, ownerOf(params.id))\\`, then delete the const.`,\n `const ${UNDECIDED_POLICY_IDENT} = (): AccessDecision => ({`,\n ` allowed: false,`,\n ` reason:`,\n ` '${routePath} still carries the policy the generator wrote, which refuses everyone. ' +`,\n ` 'Declare who may call this route (ADR 0001).',`,\n `})`,\n ]\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\n\nimport {\n UNDECIDED_POLICY_IDENT,\n undecidedPolicyDeclaration,\n} from './generate-policy-placeholder.js'\nimport type { GenerateResult } from './generate-types.js'\n\n// --- Field parsing ---\n\nconst ALLOWED_FIELD_TYPES = new Set(['string', 'text', 'number', 'boolean'])\nconst RESERVED_FIELDS = new Set(['id', 'createdAt', 'created_at'])\n\ninterface ResourceField {\n name: string\n type: 'string' | 'text' | 'number' | 'boolean'\n drizzleColumn: string\n zodType: string\n}\n\nfunction parseResourceFields(args: string[]): ResourceField[] {\n if (args.length === 0) {\n throw new Error(\n 'Resource requires at least one field. Example: theokit generate resource posts title:string',\n )\n }\n return args.map((arg) => {\n const parts = arg.split(':')\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(`Invalid field \"${arg}\". Use name:type format (e.g. title:string)`)\n }\n const [name, type] = parts\n if (!ALLOWED_FIELD_TYPES.has(type)) {\n throw new Error(\n `Unknown field type \"${type}\" in \"${arg}\". Valid types: ${[...ALLOWED_FIELD_TYPES].join(', ')}`,\n )\n }\n if (RESERVED_FIELDS.has(name)) {\n throw new Error(`Field \"${name}\" is reserved (auto-generated by the framework)`)\n }\n const fieldType = type as ResourceField['type']\n return {\n name,\n type: fieldType,\n drizzleColumn: mapDrizzleColumn(name, fieldType),\n zodType: mapZodType(fieldType),\n }\n })\n}\n\n// --- Column / type mapping ---\n\nfunction mapDrizzleColumn(name: string, type: ResourceField['type']): string {\n switch (type) {\n case 'string':\n case 'text':\n return `text('${name}').notNull()`\n case 'number':\n return `integer('${name}').notNull()`\n case 'boolean':\n return `integer('${name}', { mode: 'boolean' }).notNull().default(false)`\n }\n}\n\nfunction mapZodType(type: ResourceField['type']): string {\n switch (type) {\n case 'string':\n case 'text':\n return 'z.string()'\n case 'number':\n return 'z.number()'\n case 'boolean':\n return 'z.boolean()'\n }\n}\n\n// --- Template generators ---\n\nfunction generateSchemaEntry(resourceName: string, fields: ResourceField[]): string {\n const cols = [\n ` id: integer('id').primaryKey({ autoIncrement: true }),`,\n ...fields.map((f) => ` ${f.name}: ${f.drizzleColumn},`),\n ` createdAt: text('created_at')`,\n ` .notNull()`,\n ` .$defaultFn(() => new Date().toISOString().split('T')[0]),`,\n ]\n return [\n ``,\n `export const ${resourceName} = sqliteTable('${resourceName}', {`,\n ...cols,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateRouteIndex(resourceName: string, fields: ResourceField[]): string {\n const bodyFields = fields.map((f) => ` ${f.name}: ${f.zodType},`).join('\\n')\n return [\n `import { route, type AccessDecision } from 'theokit/server/define'`,\n `import { z } from 'zod'`,\n `import { db } from '../../db/index.js'`,\n `import { ${resourceName} } from '../../db/schema.js'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${resourceName}/index.ts`,\n 'these methods read and write a table',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .handler(() => db.select().from(${resourceName}).all())`,\n ` .build()`,\n ``,\n `export const POST = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .body(`,\n ` z.object({`,\n bodyFields,\n ` }),`,\n ` )`,\n ` .status(201)`,\n ` .handler(({ body }) => {`,\n ` const result = db.insert(${resourceName}).values(body).returning().get()`,\n ` return result`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateRouteId(resourceName: string, fields: ResourceField[]): string {\n const updateFields = fields.map((f) => ` ${f.name}: ${f.zodType}.optional(),`).join('\\n')\n return [\n `import { route, type AccessDecision } from 'theokit/server/define'`,\n `import { z } from 'zod'`,\n `import { db } from '../../db/index.js'`,\n `import { ${resourceName} } from '../../db/schema.js'`,\n `import { eq } from 'drizzle-orm'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${resourceName}/[id].ts`,\n 'these methods read, update and delete rows of a table',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .handler(({ params }) => {`,\n ` const item = db.select().from(${resourceName}).where(eq(${resourceName}.id, params.id)).get()`,\n ` if (!item) return new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })`,\n ` return item`,\n ` })`,\n ` .build()`,\n ``,\n `export const PUT = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .body(`,\n ` z.object({`,\n updateFields,\n ` }),`,\n ` )`,\n ` .handler(({ params, body }) => {`,\n ` const result = db.update(${resourceName}).set(body).where(eq(${resourceName}.id, params.id)).returning().get()`,\n ` if (!result) return new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })`,\n ` return result`,\n ` })`,\n ` .build()`,\n ``,\n `export const DELETE = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .status(204)`,\n ` .handler(({ params }) => {`,\n ` db.delete(${resourceName}).where(eq(${resourceName}.id, params.id)).run()`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateTestTemplate(resourceName: string): string {\n return [\n `import { describe, it, expect } from 'vitest'`,\n ``,\n `describe('${resourceName} API', () => {`,\n ` it('should have a schema defined', async () => {`,\n ` const schema = await import('../server/db/schema.js')`,\n ` expect(schema.${resourceName}).toBeDefined()`,\n ` })`,\n ``,\n ` it('should have route handlers', async () => {`,\n ` const index = await import('../server/routes/${resourceName}/index.js')`,\n ` expect(index.GET).toBeDefined()`,\n ` expect(index.POST).toBeDefined()`,\n ` })`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n// --- Orchestrator ---\n\nexport function generateResource(cwd: string, name: string, fieldArgs: string[]): GenerateResult {\n let fields: ResourceField[]\n try {\n fields = parseResourceFields(fieldArgs)\n } catch (err) {\n return { status: 'invalid_name', message: err instanceof Error ? err.message : String(err) }\n }\n\n const schemaPath = resolve(cwd, 'server/db/schema.ts')\n const routeIndexPath = resolve(cwd, `server/routes/${name}/index.ts`)\n const routeIdPath = resolve(cwd, `server/routes/${name}/[id].ts`)\n const testPath = resolve(cwd, `tests/${name}.test.ts`)\n\n if (!existsSync(schemaPath)) {\n return {\n status: 'not_a_project',\n message:\n 'server/db/schema.ts not found. Run this from a TheoKit project with database setup.',\n }\n }\n\n if (existsSync(routeIndexPath)) {\n return { status: 'already_exists', filePath: routeIndexPath, kind: 'resource', name }\n }\n\n const existingSchema = readFileSync(schemaPath, 'utf-8')\n if (existingSchema.includes(`export const ${name} =`)) {\n return {\n status: 'already_exists',\n filePath: schemaPath,\n kind: 'resource',\n name,\n message: `Table \"${name}\" already exists in schema.ts`,\n }\n }\n\n // 1. Append schema entry\n appendFileSync(schemaPath, generateSchemaEntry(name, fields))\n\n // 2. Create route files\n mkdirSync(dirname(routeIndexPath), { recursive: true })\n writeFileSync(routeIndexPath, generateRouteIndex(name, fields))\n writeFileSync(routeIdPath, generateRouteId(name, fields))\n\n // 3. Create test file\n mkdirSync(dirname(testPath), { recursive: true })\n if (!existsSync(testPath)) {\n writeFileSync(testPath, generateTestTemplate(name))\n }\n\n return { status: 'created', filePath: routeIndexPath, kind: 'resource', name }\n}\n","/**\n * The `theokit generate schedule` generator.\n *\n * A schedule must land where `theokit build` scans (`<agentsDir>/schedules`), so its directory is\n * read from the project config through `loadConfig`, the same reader the build uses. When the\n * config cannot be read the generator refuses by name instead of guessing a directory.\n *\n * A schedule runs the app's `chat` agent, so a project without one is refused too: a schedule\n * importing a module that does not exist would make `theokit build` fail on it.\n *\n * The schedule declares `defineCron('<last segment of the name>')`, so that segment is checked with\n * `defineCron`'s own rule and the scanner's own discovery: a name the build would reject, skip, or\n * find already used by another cron file is refused as `invalid_name` before anything is written.\n */\nimport { basename, dirname, extname, relative, resolve, sep } from 'node:path'\n\nimport { loadConfig } from '../../config/load-config.js'\nimport { cronScanDirs, isDiscoverableCronFile, listCronFiles } from '../../server/cron/cron-scan.js'\nimport { CRON_NAME_RULE, isValidCronName } from '../../server/cron/define-cron.js'\nimport { findAgentFile } from '../../server/scan/agent-scan.js'\n\nimport { pathTraversalRefusal } from './generate-containment.js'\nimport type { GenerateResult } from './generate-types.js'\n\n/** Where the schedule goes and what it says, or the refusal that explains why it cannot be written. */\nexport async function resolveScheduleTarget(\n cwd: string,\n name: string,\n): Promise<{ filePath: string; content: string } | GenerateResult> {\n const malformed = cronNameRefusal(name)\n if (malformed !== undefined) return malformed\n let config: Awaited<ReturnType<typeof loadConfig>>\n try {\n config = await loadConfig(cwd)\n } catch (err) {\n return {\n status: 'invalid_config',\n message: `Cannot read ${resolve(cwd, 'theo.config.ts')}: ${(err as Error).message}`,\n }\n }\n const { agentsDir, serverDir } = config\n const agentsRoot = resolve(cwd, agentsDir)\n const cronDirs = cronScanDirs(cwd, serverDir, agentsDir)\n const filePath = resolve(cronDirs.schedules, `${name}.ts`)\n // Before the agent lookup: a chat agent missing from a directory outside the project is not\n // something to create, and the refusal must name the escape, not the missing file.\n const escaped = pathTraversalRefusal(cwd, filePath)\n if (escaped !== undefined) return escaped\n // The agent scanner's own rule, so the file found is the one the build serves as `chat`.\n const chatPath = findAgentFile(agentsRoot, 'chat')\n if (chatPath === undefined) {\n return {\n status: 'agent_not_found',\n message:\n `No \"chat\" agent in ${agentsRoot} (the build serves it from chat.{ts,tsx,js,jsx} or ` +\n 'chat/index.{ts,tsx,js,jsx}). A schedule runs the chat agent; create it first.',\n }\n }\n // The build scans both homes with one duplicate-name guard (build.ts, emitCronArtifacts).\n const taken = cronNameTaken(name, filePath, [cronDirs.crons, cronDirs.schedules])\n if (taken !== undefined) return taken\n return { filePath, content: generateScheduleTemplate(name, importSpecifier(filePath, chatPath)) }\n}\n\n/** The cron name a schedule called `name` declares: its last `/` segment. */\nexport function cronNameOf(name: string): string {\n return name.split('/').pop() ?? name\n}\n\n/** A refusal when the build would skip the file or `defineCron` would reject its name. */\nfunction cronNameRefusal(name: string): GenerateResult | undefined {\n const cronName = cronNameOf(name)\n if (!isDiscoverableCronFile(`${cronName}.ts`)) {\n return {\n status: 'invalid_name',\n message: `Invalid schedule name \"${name}\": the build does not discover a cron file named \"${cronName}.ts\".`,\n }\n }\n if (!isValidCronName(cronName)) {\n return {\n status: 'invalid_name',\n message: `Invalid schedule name \"${name}\": its cron name \"${cronName}\" is one defineCron rejects. ${CRON_NAME_RULE}`,\n }\n }\n return undefined\n}\n\n/**\n * A refusal when another cron file already carries this schedule's cron name. The generator names\n * a cron after its file, so a file of the same name in either cron home is the clash the build's\n * duplicate-name guard would fail on. The target itself is left to the `already_exists` answer.\n *\n * Compared by FILE name, while the build compares the name each file passes to `defineCron`, which\n * it learns only by importing the file. A hand-written `foo.ts` declaring `defineCron('bar')` is\n * not seen here, so schedule `bar` is written and the build then fails with\n * `DuplicateCronNameError`; and a `bar.ts` declaring another name refuses schedule `bar` although\n * the build would accept it. Importing every cron file to read its name would run user code at\n * generate time, which this generator does not do.\n */\nfunction cronNameTaken(\n name: string,\n filePath: string,\n cronDirs: readonly string[],\n): GenerateResult | undefined {\n const cronName = cronNameOf(name)\n const clash = listCronFiles(cronDirs).find(\n (path) => path !== filePath && basename(path, extname(path)) === cronName,\n )\n if (clash === undefined) return undefined\n return {\n status: 'invalid_name',\n message: `Invalid schedule name \"${name}\": the cron name \"${cronName}\" is already used by ${clash}. Cron names must be unique across server/crons/ and agents/schedules/.`,\n }\n}\n\n/**\n * The ESM specifier the schedule at `fromFile` uses to import `toFile` (`../chat.js`). A TypeScript\n * source is imported by its `.js` name, as TypeScript and tsx resolve it; a `.js` or `.jsx` file\n * keeps its own extension.\n */\nexport function importSpecifier(fromFile: string, toFile: string): string {\n const path = relative(dirname(fromFile), toFile)\n .split(sep)\n .join('/')\n .replace(/\\.tsx?$/, '.js')\n return path.startsWith('.') ? path : `./${path}`\n}\n\nfunction generateScheduleTemplate(name: string, chatSpecifier: string): string {\n const base = cronNameOf(name)\n return [\n `import { defineCron } from 'theokit/server/cron'`,\n `import { resolveProvider } from 'theokit/server/agent'`,\n `import { streamAgentTurnInProcess } from '@theokit/agents'`,\n ``,\n `import chat from '${chatSpecifier}'`,\n ``,\n `/**`,\n ` * A scheduled agent run, a first-class TheoKit cron. \\`theokit build\\` discovers it and translates the`,\n ` * schedule to your deploy target's native cron; \\`theokit start\\` runs it in-process.`,\n ` *`,\n ` * Each fire is one model run of your \\`chat\\` agent, so it spends tokens. Nobody is present to approve`,\n ` * a gated tool, so the run uses the \\`auto-reject\\` posture: every approval is answered \"no\" and the`,\n ` * gated tool does not run.`,\n ` *`,\n ` * Schedules are UTC (https://crontab.guru). \\`signal\\` aborts when the scheduler stops.`,\n ` */`,\n `export default defineCron('${base}', {`,\n ` schedule: '0 9 * * *', // every day at 09:00 UTC`,\n ` async handler({ traceId, scheduledAt, signal }) {`,\n ` let outcome = 'ok'`,\n ` try {`,\n ` const agent = chat as { model?: string; plugins?: readonly unknown[] }`,\n ` const { apiKey } = resolveProvider(agent.model, { plugins: agent.plugins })`,\n ` const run = streamAgentTurnInProcess(chat, apiKey, {`,\n ` message: \\`Scheduled run \"${base}\" at \\${scheduledAt.toISOString()}\\`,`,\n ` signal,`,\n ` approvals: {`,\n ` kind: 'auto-reject',`,\n ` reason: 'unattended schedule \"${base}\": nobody is present to approve',`,\n ` },`,\n ` })`,\n ` for await (const chunk of run) {`,\n ` // The SDK can report a failed run as a chunk rather than a rejection.`,\n ` if (chunk.type === 'error') {`,\n ` throw new Error(\\`[${base}] agent run failed: \\${chunk.errorText ?? 'no error text'}\\`)`,\n ` }`,\n ` }`,\n ` } catch (err) {`,\n ` outcome = \\`failed: \\${err instanceof Error ? err.message : String(err)}\\``,\n ` throw err`,\n ` } finally {`,\n ` // One traced line per fire, failed fires included: the scheduler's own error line has no trace id.`,\n ` console.log(\\`[${base}] fire \\${outcome} at \\${scheduledAt.toISOString()} (trace \\${traceId})\\`)`,\n ` }`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n","import type { CronDefinition, CronOptions } from './cron-types.js'\nimport { validateCronSchedule } from './cron-validate.js'\n\nconst NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/\n\n/** What {@link isValidCronName} requires, in words, for an error message. */\nexport const CRON_NAME_RULE =\n 'Must be 1-64 chars, lowercase alphanumeric + hyphen, starting with [a-z0-9].'\n\n/** Whether `defineCron` accepts `name`. The generator asks this before writing a cron. */\nexport function isValidCronName(name: string): boolean {\n return typeof name === 'string' && NAME_RE.test(name)\n}\n\nfunction validateName(name: string): void {\n if (!isValidCronName(name)) {\n throw new Error(`defineCron: invalid name \"${name}\". ${CRON_NAME_RULE}`)\n }\n}\n\n/**\n * Declare a time-triggered handler. Pure identity helper — no\n * registration side effect; the build-time scanner (T1.3) discovers\n * definitions by walking `server/crons/` and emits a manifest the\n * adapters translate at deploy.\n *\n * @example\n * ```ts\n * // server/crons/morning-summary.ts\n * export default defineCron('morning-summary', {\n * schedule: '0 9 * * *', // 09:00 UTC\n * async handler({ traceId, scheduledAt, signal }) {\n * // ...\n * },\n * })\n * ```\n */\nexport function defineCron(name: string, options: CronOptions): CronDefinition {\n validateName(name)\n validateCronSchedule(options.schedule)\n return {\n name,\n schedule: options.schedule,\n handler: options.handler,\n concurrency: options.concurrency ?? 'forbid',\n }\n}\n","/**\n * Shared types for the `theokit generate` CLI command family.\n *\n * Extracted to break the circular dependency between generate.ts ↔ generate-resource.ts\n * (architecture-remediation plan T1.1, 2026-06-12).\n */\n\nexport const VALID_TYPES = [\n 'route',\n 'action',\n 'page',\n 'ws',\n 'controller',\n 'agent',\n 'toolbox',\n 'workflow',\n 'eval',\n 'sandbox',\n 'schedule',\n 'memory',\n 'resource',\n] as const\nexport type GeneratorType = (typeof VALID_TYPES)[number]\n\nexport interface GenerateOptions {\n cwd: string\n type: string\n name: string\n fields?: string[]\n}\n\nexport type GenerateStatus =\n | 'created'\n | 'already_exists'\n | 'invalid_kind'\n | 'invalid_name'\n | 'not_a_project'\n | 'invalid_config'\n | 'agent_not_found'\n\nexport interface GenerateResult {\n status: GenerateStatus\n filePath?: string\n kind?: GeneratorType\n name?: string\n message?: string\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,cAAAA,aAAY,aAAAC,YAAW,iBAAAC,sBAAqB;AACrD,SAAS,WAAAC,UAAS,WAAAC,gBAAe;;;ACIjC,SAAS,YAAY,UAAU,SAAS,WAAW;AASnD,SAAS,aAAa,KAAa,UAA2B;AAC5D,MAAI,SAAS,SAAS,IAAM,EAAG,QAAO;AACtC,QAAM,WAAW,SAAS,QAAQ,GAAG,GAAG,QAAQ;AAChD,SAAO,aAAa,MAAM,CAAC,WAAW,QAAQ,KAAK,SAAS,MAAM,GAAG,EAAE,CAAC,MAAM;AAChF;AAGO,SAAS,qBAAqB,KAAa,UAA8C;AAC9F,MAAI,aAAa,KAAK,QAAQ,EAAG,QAAO;AACxC,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS,2BAA2B,QAAQ,iCAAiC,QAAQ,GAAG,CAAC;AAAA,EAC3F;AACF;;;ACGO,IAAM,yBAAyB;AAQ/B,SAAS,2BAA2B,WAAmB,MAAwB;AACpF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,IAAI;AAAA,IACV;AAAA,IACA;AAAA,IACA,SAAS,sBAAsB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,QAAQ,SAAS;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;;;ACpDA,SAAS,gBAAgB,YAAY,WAAW,cAAc,qBAAqB;AACnF,SAAS,WAAAC,UAAS,eAAe;AAUjC,IAAM,sBAAsB,oBAAI,IAAI,CAAC,UAAU,QAAQ,UAAU,SAAS,CAAC;AAC3E,IAAM,kBAAkB,oBAAI,IAAI,CAAC,MAAM,aAAa,YAAY,CAAC;AASjE,SAAS,oBAAoB,MAAiC;AAC5D,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,QAAI,MAAM,WAAW,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;AAChD,YAAM,IAAI,MAAM,kBAAkB,GAAG,6CAA6C;AAAA,IACpF;AACA,UAAM,CAAC,MAAM,IAAI,IAAI;AACrB,QAAI,CAAC,oBAAoB,IAAI,IAAI,GAAG;AAClC,YAAM,IAAI;AAAA,QACR,uBAAuB,IAAI,SAAS,GAAG,mBAAmB,CAAC,GAAG,mBAAmB,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/F;AAAA,IACF;AACA,QAAI,gBAAgB,IAAI,IAAI,GAAG;AAC7B,YAAM,IAAI,MAAM,UAAU,IAAI,iDAAiD;AAAA,IACjF;AACA,UAAM,YAAY;AAClB,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,eAAe,iBAAiB,MAAM,SAAS;AAAA,MAC/C,SAAS,WAAW,SAAS;AAAA,IAC/B;AAAA,EACF,CAAC;AACH;AAIA,SAAS,iBAAiB,MAAc,MAAqC;AAC3E,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO,SAAS,IAAI;AAAA,IACtB,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,IACzB,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,EAC3B;AACF;AAEA,SAAS,WAAW,MAAqC;AACvD,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAIA,SAAS,oBAAoB,cAAsB,QAAiC;AAClF,QAAM,OAAO;AAAA,IACX;AAAA,IACA,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,aAAa,GAAG;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,YAAY,mBAAmB,YAAY;AAAA,IAC3D,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,mBAAmB,cAAsB,QAAiC;AACjF,QAAM,aAAa,OAAO,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,OAAO,GAAG,EAAE,KAAK,IAAI;AAC9E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,YAAY;AAAA,IACxB;AAAA,IACA,GAAG;AAAA,MACD,iBAAiB,YAAY;AAAA,MAC7B;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC,qCAAqC,YAAY;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gCAAgC,YAAY;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,gBAAgB,cAAsB,QAAiC;AAC9E,QAAM,eAAe,OAAO,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,OAAO,cAAc,EAAE,KAAK,IAAI;AAC3F,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,YAAY;AAAA,IACxB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,MACD,iBAAiB,YAAY;AAAA,MAC7B;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC;AAAA,IACA;AAAA,IACA,qCAAqC,YAAY,cAAc,YAAY;AAAA,IAC3E;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gCAAgC,YAAY,wBAAwB,YAAY;AAAA,IAChF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,YAAY,cAAc,YAAY;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,qBAAqB,cAA8B;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa,YAAY;AAAA,IACzB;AAAA,IACA;AAAA,IACA,qBAAqB,YAAY;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA,oDAAoD,YAAY;AAAA,IAChE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAIO,SAAS,iBAAiB,KAAa,MAAc,WAAqC;AAC/F,MAAI;AACJ,MAAI;AACF,aAAS,oBAAoB,SAAS;AAAA,EACxC,SAAS,KAAK;AACZ,WAAO,EAAE,QAAQ,gBAAgB,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,EAC7F;AAEA,QAAM,aAAaC,SAAQ,KAAK,qBAAqB;AACrD,QAAM,iBAAiBA,SAAQ,KAAK,iBAAiB,IAAI,WAAW;AACpE,QAAM,cAAcA,SAAQ,KAAK,iBAAiB,IAAI,UAAU;AAChE,QAAM,WAAWA,SAAQ,KAAK,SAAS,IAAI,UAAU;AAErD,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SACE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,WAAW,cAAc,GAAG;AAC9B,WAAO,EAAE,QAAQ,kBAAkB,UAAU,gBAAgB,MAAM,YAAY,KAAK;AAAA,EACtF;AAEA,QAAM,iBAAiB,aAAa,YAAY,OAAO;AACvD,MAAI,eAAe,SAAS,gBAAgB,IAAI,IAAI,GAAG;AACrD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN;AAAA,MACA,SAAS,UAAU,IAAI;AAAA,IACzB;AAAA,EACF;AAGA,iBAAe,YAAY,oBAAoB,MAAM,MAAM,CAAC;AAG5D,YAAU,QAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,gBAAc,gBAAgB,mBAAmB,MAAM,MAAM,CAAC;AAC9D,gBAAc,aAAa,gBAAgB,MAAM,MAAM,CAAC;AAGxD,YAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,kBAAc,UAAU,qBAAqB,IAAI,CAAC;AAAA,EACpD;AAEA,SAAO,EAAE,QAAQ,WAAW,UAAU,gBAAgB,MAAM,YAAY,KAAK;AAC/E;;;ACjPA,SAAS,UAAU,WAAAC,UAAS,SAAS,YAAAC,WAAU,WAAAC,UAAS,OAAAC,YAAW;;;ACXnE,IAAM,UAAU;AAGT,IAAM,iBACX;AAGK,SAAS,gBAAgB,MAAuB;AACrD,SAAO,OAAO,SAAS,YAAY,QAAQ,KAAK,IAAI;AACtD;;;ADaA,eAAsB,sBACpB,KACA,MACiE;AACjE,QAAM,YAAY,gBAAgB,IAAI;AACtC,MAAI,cAAc,OAAW,QAAO;AACpC,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,WAAW,GAAG;AAAA,EAC/B,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,eAAeC,SAAQ,KAAK,gBAAgB,CAAC,KAAM,IAAc,OAAO;AAAA,IACnF;AAAA,EACF;AACA,QAAM,EAAE,WAAW,UAAU,IAAI;AACjC,QAAM,aAAaA,SAAQ,KAAK,SAAS;AACzC,QAAM,WAAW,aAAa,KAAK,WAAW,SAAS;AACvD,QAAM,WAAWA,SAAQ,SAAS,WAAW,GAAG,IAAI,KAAK;AAGzD,QAAM,UAAU,qBAAqB,KAAK,QAAQ;AAClD,MAAI,YAAY,OAAW,QAAO;AAElC,QAAM,WAAW,cAAc,YAAY,MAAM;AACjD,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SACE,sBAAsB,UAAU;AAAA,IAEpC;AAAA,EACF;AAEA,QAAM,QAAQ,cAAc,MAAM,UAAU,CAAC,SAAS,OAAO,SAAS,SAAS,CAAC;AAChF,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,EAAE,UAAU,SAAS,yBAAyB,MAAM,gBAAgB,UAAU,QAAQ,CAAC,EAAE;AAClG;AAGO,SAAS,WAAW,MAAsB;AAC/C,SAAO,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AAClC;AAGA,SAAS,gBAAgB,MAA0C;AACjE,QAAM,WAAW,WAAW,IAAI;AAChC,MAAI,CAAC,uBAAuB,GAAG,QAAQ,KAAK,GAAG;AAC7C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,0BAA0B,IAAI,qDAAqD,QAAQ;AAAA,IACtG;AAAA,EACF;AACA,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,0BAA0B,IAAI,qBAAqB,QAAQ,gCAAgC,cAAc;AAAA,IACpH;AAAA,EACF;AACA,SAAO;AACT;AAcA,SAAS,cACP,MACA,UACA,UAC4B;AAC5B,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,QAAQ,cAAc,QAAQ,EAAE;AAAA,IACpC,CAAC,SAAS,SAAS,YAAY,SAAS,MAAM,QAAQ,IAAI,CAAC,MAAM;AAAA,EACnE;AACA,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS,0BAA0B,IAAI,qBAAqB,QAAQ,wBAAwB,KAAK;AAAA,EACnG;AACF;AAOO,SAAS,gBAAgB,UAAkB,QAAwB;AACxE,QAAM,OAAOC,UAASC,SAAQ,QAAQ,GAAG,MAAM,EAC5C,MAAMC,IAAG,EACT,KAAK,GAAG,EACR,QAAQ,WAAW,KAAK;AAC3B,SAAO,KAAK,WAAW,GAAG,IAAI,OAAO,KAAK,IAAI;AAChD;AAEA,SAAS,yBAAyB,MAAc,eAA+B;AAC7E,QAAM,OAAO,WAAW,IAAI;AAC5B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB,aAAa;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,8BAA8B,IAAI;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qCAAqC,IAAI;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA,2CAA2C,IAAI;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gCAAgC,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,wBAAwB,IAAI;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;;;AE5KO,IAAM,cAAc;AAAA,EACzB;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;;;ANDA,SAAS,YAAY,MAAuB;AAC1C,SAAO,qBAAqB,KAAK,IAAI;AACvC;AAOA,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOD,SAAS,mBAAmB,MAAuB;AACjD,QAAMC,YAAW,KAAK,SAAS,GAAG,IAAK,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,OAAQ;AACxE,SAAO,mBAAmB,IAAIA,SAAQ;AACxC;AAEA,SAAS,aAAa,MAAsB;AAC1C,SAAO,KACJ,MAAM,MAAM,EACZ,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EACjD,KAAK,EAAE;AACZ;AAEA,SAAS,YAAY,MAAsB;AACzC,QAAM,SAAS,aAAa,IAAI;AAChC,SAAO,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AACxD;AAEA,SAAS,sBAAsB,MAAsB;AACnD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,MACD,iBAAiB,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC;AAAA,IACA,0CAA0C,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,2BAA2B,MAAsB;AACxD,QAAM,YAAY,aAAa,IAAI,IAAI;AACvC,QAAM,WAAW,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AAC1C,SAAO;AAAA,IACL,sDAAsD,IAAI;AAAA,IAC1D;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ;AAAA,IACxB,gBAAgB,SAAS;AAAA,IACzB;AAAA,IACA;AAAA,IACA,uCAAuC,QAAQ;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,uBAAuB,MAAsB;AACpD,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK;AAAA,IACrB;AAAA,IACA;AAAA,IACA,0CAA0C,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAOA,SAAS,sBAAsB,MAAsB;AACnD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,gEAAgE,IAAI;AAAA,IACpE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gCAAgC,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,wBAAwB,MAAsB;AACrD,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK,iBAAiB,IAAI;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,yBAAyB,MAAsB;AACtD,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,0BAA0B,KAAK;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK,uCAAuC,IAAI;AAAA,IAChE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,qBAAqB,MAAsB;AAClD,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,0BAA0B,KAAK;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK;AAAA,IACrB,YAAY,IAAI;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,wBAAwB,MAAsB;AACrD,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AACtC,QAAM,QAAQ,KAAK,QAAQ,MAAM,GAAG;AACpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,KAAK,0BAA0B,IAAI;AAAA,IACpD,8CAA8C,KAAK;AAAA,IACnD;AAAA,IACA,gBAAgB,KAAK,gBAAgB,KAAK;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,uBAAuB,OAAuB;AACrD,SAAO;AAAA,IACL;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,EAAE,KAAK,IAAI;AACb;AAYA,IAAM,oBAAoE;AAAA;AAAA;AAAA;AAAA,EAIxE,UAAU,EAAE,MAAM,CAAC,SAAS,oBAAoB,IAAI,OAAO,UAAU,yBAAyB;AAAA,EAC9F,MAAM,EAAE,MAAM,CAAC,SAAS,gBAAgB,IAAI,OAAO,UAAU,qBAAqB;AAAA,EAClF,SAAS,EAAE,MAAM,CAAC,SAAS,kBAAkB,IAAI,OAAO,UAAU,wBAAwB;AAAA,EAC1F,QAAQ,EAAE,MAAM,CAAC,SAAS,iBAAiB,IAAI,OAAO,UAAU,uBAAuB;AAAA,EACvF,OAAO,EAAE,MAAM,CAAC,SAAS,iBAAiB,IAAI,OAAO,UAAU,sBAAsB;AAAA,EACrF,QAAQ,EAAE,MAAM,CAAC,SAAS,kBAAkB,IAAI,OAAO,UAAU,uBAAuB;AAAA,EACxF,MAAM,EAAE,MAAM,CAAC,SAAS,OAAO,IAAI,aAAa,UAAU,qBAAqB;AAAA,EAC/E,IAAI,EAAE,MAAM,CAAC,SAAS,aAAa,IAAI,OAAO,UAAU,mBAAmB;AAAA,EAC3E,YAAY;AAAA,IACV,MAAM,CAAC,SAAS,sBAAsB,IAAI;AAAA,IAC1C,UAAU;AAAA,EACZ;AAAA,EACA,OAAO,EAAE,MAAM,CAAC,SAAS,iBAAiB,IAAI,aAAa,UAAU,sBAAsB;AAAA,EAC3F,SAAS;AAAA,IACP,MAAM,CAAC,SAAS,oBAAoB,IAAI;AAAA,IACxC,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,gBACP,KACA,MACA,MAC8C;AAC9C,QAAM,OAAO,kBAAkB,IAAI;AACnC,MAAI,SAAS,OAAW,QAAO;AAC/B,SAAO,EAAE,UAAUC,SAAQ,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,KAAK,SAAS,IAAI,EAAE;AACjF;AAEA,SAAS,2BAA2B,MAAsB;AACxD,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,KAAK,cAAc,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,IACpD;AAAA,IACA,aAAa,IAAI;AAAA,IACjB;AAAA,IACA,cAAc,KAAK;AAAA,IACnB,qBAAqB,KAAK;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,KAAK;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,qBAAqB,MAAsB;AAClD,QAAM,SAAS,aAAa,IAAI;AAChC,SAAO,CAAC,2BAA2B,MAAM,YAAY,gBAAgB,MAAM,SAAS,KAAK,EAAE,EAAE;AAAA,IAC3F;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,OAAuB;AACjD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AASA,SAAS,gBAAgB,OAAuC;AAC9D,SAAQ,YAAkC,SAAS,KAAK;AAC1D;AAMA,SAAS,cAAc,EAAE,KAAK,MAAM,KAAK,GAAgD;AACvF,MAAI,CAACC,YAAWD,SAAQ,KAAK,gBAAgB,CAAC,KAAK,CAACC,YAAWD,SAAQ,KAAK,gBAAgB,CAAC,GAAG;AAC9F,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB,IAAI,GAAG;AAC1B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,2BAA2B,IAAI,iBAAiB,YAAY,KAAK,IAAI,CAAC;AAAA,IACjF;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,CAAC,YAAY,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,iBAAiB,IAAI;AAAA,IAChC;AAAA,EACF;AAIA,MAAI,mBAAmB,IAAI,GAAG;AAC5B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,kBAAkB,IAAI;AAAA,IACjC;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAe,cACb,KACA,MACA,MACkC;AAElC,MAAI,SAAS,WAAY,QAAO,sBAAsB,KAAK,IAAI;AAC/D,QAAM,SAAS,gBAAgB,KAAK,MAAM,IAAI;AAC9C,MAAI,WAAW,KAAM,QAAO,EAAE,QAAQ,gBAAgB,SAAS,iBAAiB,IAAI,GAAG;AACvF,SAAO;AACT;AAGA,SAAS,YACP,KACA,MACA,MACA,EAAE,UAAU,QAAQ,GACJ;AAGhB,QAAM,UAAU,qBAAqB,KAAK,QAAQ;AAClD,MAAI,YAAY,OAAW,QAAO;AAElC,MAAIC,YAAW,QAAQ,GAAG;AACxB,WAAO,EAAE,QAAQ,kBAAkB,UAAU,MAAM,MAAM,KAAK;AAAA,EAChE;AAEA,EAAAC,WAAUC,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,EAAAC,eAAc,UAAU,OAAO;AAK/B,MAAI,SAAS,UAAU;AACrB,UAAM,WAAW,SAAS,QAAQ,SAAS,UAAU;AACrD,QAAI,CAACH,YAAW,QAAQ,GAAG;AACzB,MAAAG,eAAc,UAAU,2BAA2B,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,WAAW,UAAU,MAAM,MAAM,KAAK;AACzD;AAOA,eAAsB,SAAS,MAAgD;AAC7E,QAAM,UAAU,cAAc,IAAI;AAClC,MAAI,YAAY,OAAW,QAAO;AAClC,QAAM,EAAE,KAAK,KAAK,IAAI;AAEtB,QAAM,OAAO,KAAK;AAGlB,MAAI,SAAS,YAAY;AACvB,WAAO,iBAAiB,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,EACtD;AAEA,QAAM,WAAW,MAAM,cAAc,KAAK,MAAM,IAAI;AACpD,MAAI,YAAY,SAAU,QAAO;AACjC,SAAO,YAAY,KAAK,MAAM,MAAM,QAAQ;AAC9C;AAGA,IAAM,eAGF;AAAA,EACF,eAAe,MAAM;AAAA,EACrB,cAAc,CAAC,WAAW,OAAO,WAAW;AAAA;AAAA;AAAA,EAG5C,cAAc,CAAC,QAAQ,SAAS,OAAO,WAAW,iBAAiB,IAAI;AAAA,EACvE,gBAAgB,CAAC,WAAW,OAAO,WAAW;AAAA,EAC9C,iBAAiB,CAAC,WAAW,OAAO,WAAW;AACjD;AAMA,eAAsB,gBACpB,MACA,MACA,QACe;AACf,QAAM,SAAS,MAAM,SAAS,EAAE,KAAK,QAAQ,IAAI,GAAG,MAAM,MAAM,OAAO,CAAC;AACxE,MAAI,OAAO,WAAW,kBAAkB;AACtC,YAAQ,IAAI;AAAA,WAAS,OAAO,QAAQ;AAAA,CAA8B;AAAA,EACpE,WAAW,OAAO,WAAW,WAAW;AACtC,YAAQ,IAAI;AAAA,mBAAiB,IAAI,KAAK,OAAO,QAAQ;AAAA,CAAI;AAAA,EAC3D,OAAO;AACL,UAAM,IAAI,MAAM,aAAa,OAAO,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3D;AACF;","names":["existsSync","mkdirSync","writeFileSync","resolve","dirname","resolve","resolve","dirname","relative","resolve","sep","resolve","relative","dirname","sep","basename","resolve","existsSync","mkdirSync","dirname","writeFileSync"]}
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  scanRoutes,
9
9
  theoConfigSchema,
10
10
  theoPlugin
11
- } from "./chunk-FPC6ZEEU.js";
11
+ } from "./chunk-6RVWPEKK.js";
12
12
  import "./chunk-7NRFZBAL.js";
13
13
  import "./chunk-SSYDEKWF.js";
14
14
  import "./chunk-D7STTNQN.js";
@@ -32,9 +32,9 @@ import "./chunk-CHTAWXC2.js";
32
32
  import "./chunk-AVQU5CQF.js";
33
33
  import "./chunk-VSLTKX5L.js";
34
34
  import "./chunk-SFGGRC35.js";
35
- import "./chunk-4ERYQBL6.js";
36
- import "./chunk-V7ISZGNS.js";
37
- import "./chunk-6R5F5YF2.js";
35
+ import "./chunk-4Z5XO4O4.js";
36
+ import "./chunk-7HGZ3CKL.js";
37
+ import "./chunk-A6UFN6QQ.js";
38
38
  import "./chunk-DV34VG3N.js";
39
39
  import "./chunk-V6Y2SMRG.js";
40
40
  import "./chunk-ACKBVBUI.js";
@@ -44,7 +44,7 @@ import "./chunk-ICXXHV4V.js";
44
44
  import "./chunk-YSJOZEI6.js";
45
45
  import "./chunk-Z4PJMZLM.js";
46
46
  import "./chunk-UMNXCU3K.js";
47
- import "./chunk-5KRMDP46.js";
47
+ import "./chunk-AHYOVVJ7.js";
48
48
  import "./chunk-SOYOYGWY.js";
49
49
  import "./chunk-ZWN3AODA.js";
50
50
  import "./chunk-XTHN6JBX.js";
@@ -5,9 +5,9 @@ import {
5
5
  } from "./chunk-47MM2JUK.js";
6
6
  import {
7
7
  loadConfig
8
- } from "./chunk-VOXLI66L.js";
8
+ } from "./chunk-OZB2TKGJ.js";
9
9
  import "./chunk-3QPVEJ7D.js";
10
- import "./chunk-U5PWXS3J.js";
10
+ import "./chunk-O5JZ6ROY.js";
11
11
  import "./chunk-NX3P5MLH.js";
12
12
  import "./chunk-L4V5V2TI.js";
13
13
  import "./chunk-D2R5SJEL.js";
@@ -103,4 +103,4 @@ export {
103
103
  buildInfo,
104
104
  infoCommand
105
105
  };
106
- //# sourceMappingURL=info-XURFOBRF.js.map
106
+ //# sourceMappingURL=info-6NAUW5XY.js.map
@@ -46,7 +46,7 @@ import {
46
46
  } from "./chunk-SFGGRC35.js";
47
47
  import {
48
48
  createViteLoader
49
- } from "./chunk-4ERYQBL6.js";
49
+ } from "./chunk-4Z5XO4O4.js";
50
50
  import {
51
51
  ACTION_SCHEMAS_DIR,
52
52
  generateManifest,
@@ -55,10 +55,10 @@ import {
55
55
  scanServerActionsEnriched,
56
56
  scanServerRoutes,
57
57
  scanWebSocketRoutes
58
- } from "./chunk-V7ISZGNS.js";
58
+ } from "./chunk-7HGZ3CKL.js";
59
59
  import {
60
60
  scanAgents
61
- } from "./chunk-6R5F5YF2.js";
61
+ } from "./chunk-A6UFN6QQ.js";
62
62
  import "./chunk-DV34VG3N.js";
63
63
  import "./chunk-V6Y2SMRG.js";
64
64
  import "./chunk-ACKBVBUI.js";
@@ -71,7 +71,7 @@ import {
71
71
  generateNonce
72
72
  } from "./chunk-Z4PJMZLM.js";
73
73
  import "./chunk-UMNXCU3K.js";
74
- import "./chunk-5KRMDP46.js";
74
+ import "./chunk-AHYOVVJ7.js";
75
75
  import "./chunk-SOYOYGWY.js";
76
76
  import "./chunk-ZWN3AODA.js";
77
77
  import "./chunk-XTHN6JBX.js";
@@ -108,4 +108,4 @@ export {
108
108
  scanWebSocketRoutes,
109
109
  sendError
110
110
  };
111
- //# sourceMappingURL=internal-api-XPT4GLYX.js.map
111
+ //# sourceMappingURL=internal-api-A5HA7TYF.js.map
@@ -16,7 +16,7 @@ import {
16
16
  handleCspReport,
17
17
  handleCsrfReadiness,
18
18
  mountAgent
19
- } from "./chunk-DA3GGICE.js";
19
+ } from "./chunk-RQKMY3JW.js";
20
20
  import {
21
21
  resolveProvider
22
22
  } from "./chunk-BINRCILF.js";
@@ -38,10 +38,10 @@ import {
38
38
  import "./chunk-7UZZHCRN.js";
39
39
  import {
40
40
  generateManifest
41
- } from "./chunk-WR5B2XNT.js";
41
+ } from "./chunk-FNAEKJHO.js";
42
42
  import {
43
43
  scanAgents
44
- } from "./chunk-HKF6YNY4.js";
44
+ } from "./chunk-FU3LEX2I.js";
45
45
  import {
46
46
  ACTION_SCHEMAS_DIR,
47
47
  matchRoute,
@@ -51,7 +51,7 @@ import {
51
51
  scanWebSocketRoutes
52
52
  } from "./chunk-4WP7A7RX.js";
53
53
  import "./chunk-Z7CJHDLS.js";
54
- import "./chunk-U5PWXS3J.js";
54
+ import "./chunk-O5JZ6ROY.js";
55
55
  import "./chunk-D2R5SJEL.js";
56
56
  import "./chunk-VQIUTCK2.js";
57
57
  export {
@@ -87,4 +87,4 @@ export {
87
87
  scanWebSocketRoutes,
88
88
  sendError
89
89
  };
90
- //# sourceMappingURL=internal-api-ATSPOXI2.js.map
90
+ //# sourceMappingURL=internal-api-R7TTYMCY.js.map
@@ -3,9 +3,9 @@ import "tsx/esm";
3
3
  import {
4
4
  deepMerge,
5
5
  loadConfig
6
- } from "./chunk-VOXLI66L.js";
6
+ } from "./chunk-OZB2TKGJ.js";
7
7
  import "./chunk-3QPVEJ7D.js";
8
- import "./chunk-U5PWXS3J.js";
8
+ import "./chunk-O5JZ6ROY.js";
9
9
  import "./chunk-NX3P5MLH.js";
10
10
  import "./chunk-L4V5V2TI.js";
11
11
  import "./chunk-D2R5SJEL.js";
@@ -13,4 +13,4 @@ export {
13
13
  deepMerge,
14
14
  loadConfig
15
15
  };
16
- //# sourceMappingURL=load-config-2DXLI7NW.js.map
16
+ //# sourceMappingURL=load-config-CLFWJOXN.js.map
@@ -2,7 +2,7 @@
2
2
  import "tsx/esm";
3
3
  import {
4
4
  createAgentSsrLoader
5
- } from "./chunk-PZLH4WGU.js";
5
+ } from "./chunk-2BMJQMTH.js";
6
6
  import {
7
7
  extractAppResources,
8
8
  handleMcpJsonRpc
@@ -10,7 +10,7 @@ import {
10
10
  import "./chunk-BINRCILF.js";
11
11
  import {
12
12
  scanAgents
13
- } from "./chunk-HKF6YNY4.js";
13
+ } from "./chunk-FU3LEX2I.js";
14
14
  import "./chunk-Z7CJHDLS.js";
15
15
  import "./chunk-3QPVEJ7D.js";
16
16
 
@@ -46,7 +46,7 @@ async function serveMcpStdio(mod, name, appResources, streams) {
46
46
  // src/cli/commands/mcp.ts
47
47
  async function mcpCommand(name, deps = {}) {
48
48
  const projectRoot = deps.projectRoot ?? process.cwd();
49
- const agentsDir = deps.agentsDir ?? (await (await import("./load-config-2DXLI7NW.js")).loadConfig(projectRoot)).agentsDir;
49
+ const agentsDir = deps.agentsDir ?? (await (await import("./load-config-CLFWJOXN.js")).loadConfig(projectRoot)).agentsDir;
50
50
  const agent = scanAgents(projectRoot, agentsDir).find((a) => a.name === name);
51
51
  if (!agent) {
52
52
  const names = scanAgents(projectRoot, agentsDir).map((a) => a.name).join(", ");
@@ -75,4 +75,4 @@ async function mcpCommand(name, deps = {}) {
75
75
  export {
76
76
  mcpCommand
77
77
  };
78
- //# sourceMappingURL=mcp-LMV3NQEP.js.map
78
+ //# sourceMappingURL=mcp-MWTG3LRA.js.map
@@ -6,15 +6,15 @@ import {
6
6
  } from "./chunk-47VNWTL4.js";
7
7
  import {
8
8
  generateManifest
9
- } from "./chunk-WR5B2XNT.js";
10
- import "./chunk-HKF6YNY4.js";
9
+ } from "./chunk-FNAEKJHO.js";
10
+ import "./chunk-FU3LEX2I.js";
11
11
  import "./chunk-4WP7A7RX.js";
12
12
  import "./chunk-Z7CJHDLS.js";
13
13
  import {
14
14
  loadConfig
15
- } from "./chunk-VOXLI66L.js";
15
+ } from "./chunk-OZB2TKGJ.js";
16
16
  import "./chunk-3QPVEJ7D.js";
17
- import "./chunk-U5PWXS3J.js";
17
+ import "./chunk-O5JZ6ROY.js";
18
18
  import "./chunk-NX3P5MLH.js";
19
19
  import "./chunk-L4V5V2TI.js";
20
20
  import "./chunk-D2R5SJEL.js";
@@ -84,4 +84,4 @@ function emitOpenApiInMemory(manifest, config) {
84
84
  export {
85
85
  openapiCommand
86
86
  };
87
- //# sourceMappingURL=openapi-UJSUQPNT.js.map
87
+ //# sourceMappingURL=openapi-RVFUXXCR.js.map
@@ -4,8 +4,8 @@ import "tsx/esm";
4
4
  // src/cli/commands/preview.ts
5
5
  async function defaultSteps() {
6
6
  const [{ buildCommand }, { startCommand }] = await Promise.all([
7
- import("./build-F3O5LJHY.js"),
8
- import("./start-GAULIE5E.js")
7
+ import("./build-QIO4VAW2.js"),
8
+ import("./start-L5TGWGLU.js")
9
9
  ]);
10
10
  return {
11
11
  build: (opts) => buildCommand(opts),
@@ -20,4 +20,4 @@ async function previewCommand(options = {}, steps) {
20
20
  export {
21
21
  previewCommand
22
22
  };
23
- //# sourceMappingURL=preview-AMNBV2DP.js.map
23
+ //# sourceMappingURL=preview-ML4CFUD6.js.map
@@ -11,9 +11,9 @@ import {
11
11
  import "./chunk-Z7CJHDLS.js";
12
12
  import {
13
13
  loadConfig
14
- } from "./chunk-VOXLI66L.js";
14
+ } from "./chunk-OZB2TKGJ.js";
15
15
  import "./chunk-3QPVEJ7D.js";
16
- import "./chunk-U5PWXS3J.js";
16
+ import "./chunk-O5JZ6ROY.js";
17
17
  import "./chunk-NX3P5MLH.js";
18
18
  import "./chunk-L4V5V2TI.js";
19
19
  import "./chunk-D2R5SJEL.js";
@@ -64,4 +64,4 @@ async function routesCommand() {
64
64
  export {
65
65
  routesCommand
66
66
  };
67
- //# sourceMappingURL=routes-ENMU4GAN.js.map
67
+ //# sourceMappingURL=routes-SMNSI2ZX.js.map
@@ -1,8 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { C as CustomTool } from '../../define-agent-tool-aYYLpMeo.js';
3
+ import { CustomTool as CustomTool$1 } from '@theokit/sdk';
3
4
  import { AcpTransport } from '@theokit/agents';
4
5
  export { AgentModule, InProcessApprovalRequest, InProcessApprovalRequiredError, InProcessAwaitApproval, StreamAgentTurnDeps, StreamAgentTurnInProcessInput, streamAgentTurnInProcess } from '@theokit/agents';
5
- import { CustomTool as CustomTool$1 } from '@theokit/sdk';
6
6
  import { V as VerifyFn, S as SubscribeFn } from '../../whatsapp-D_Fnl1LX.js';
7
7
  export { P as ProviderDescriptor, R as ResolvedProvider, l as listProviders, a as registerProvider, b as resetProviderRegistry, r as resolveProvider, t as tryResolveProvider } from '../../provider-resolver-Cc9C3-Rb.js';
8
8
 
@@ -43,13 +43,98 @@ interface WorkflowToolConfig {
43
43
  */
44
44
  declare function createWorkflowTool(workflow: WorkflowLike, config: WorkflowToolConfig): CustomTool;
45
45
 
46
- /** Stdio transport backed by a spawned subprocess (the default for {@link createACPTool}). */
47
- declare class NodeAcpTransport implements AcpTransport {
46
+ /** The agent process could not start, failed, or exited before the call finished. */
47
+ declare class AcpTransportClosedError extends Error {
48
+ /** The agent executable, as configured. */
49
+ readonly command: string;
50
+ /** What happened to the process, e.g. `exited with code 3` or `failed: spawn x ENOENT`. */
51
+ readonly reason: string;
52
+ readonly name = "AcpTransportClosedError";
53
+ constructor(
54
+ /** The agent executable, as configured. */
55
+ command: string,
56
+ /** What happened to the process, e.g. `exited with code 3` or `failed: spawn x ENOENT`. */
57
+ reason: string, options?: {
58
+ cause?: unknown;
59
+ });
60
+ }
61
+ /**
62
+ * A transport `createACPTool` can release. `close` is called once when the call ends, and the
63
+ * call waits for it when it returns a promise. `onClose`, inherited from {@link AcpTransport},
64
+ * reports a channel that closed on its own (the process failed or exited), which rejects the request
65
+ * in flight with the error it reports: {@link NodeAcpTransport} reports an
66
+ * {@link AcpTransportClosedError}. Both are optional so a plain {@link AcpTransport} still works.
67
+ */
68
+ interface AcpToolTransport extends AcpTransport {
69
+ close?(): void | Promise<void>;
70
+ }
71
+ /** Stdio transport backed by a spawned subprocess (the default for `createACPTool`). */
72
+ declare class NodeAcpTransport implements AcpToolTransport {
73
+ private readonly command;
48
74
  private readonly proc;
75
+ private closed;
76
+ private readonly listeners;
77
+ /** Settles when the process has exited (or never started). */
78
+ private readonly exited;
49
79
  constructor(command: string, args?: string[], cwd?: string);
50
80
  send(line: string): void;
51
81
  subscribe(onData: (chunk: string) => void): void;
52
- close(): void;
82
+ onClose(listener: (error: AcpTransportClosedError) => void): void;
83
+ /**
84
+ * End the channel and the process, and settle once the process and its group have exited:
85
+ * SIGTERM first, then SIGKILL for anything still running after {@link SIGTERM_GRACE_MS}.
86
+ */
87
+ close(): Promise<void>;
88
+ /** Whether the process started and has not exited yet. */
89
+ private running;
90
+ /** Whether a process of the agent's group is still running (always `false` without a group). */
91
+ private groupAlive;
92
+ /** Send `signal` to the agent's process group, or to the spawned process without one. */
93
+ private signal;
94
+ /** Wait up to `ms` for the process and every process of its group to exit; `true` when they did. */
95
+ private goneWithin;
96
+ /** Wait up to `ms` for the process to exit; `true` when it did. */
97
+ private exitsWithin;
98
+ /** Record the first way the channel ended and tell every listener; later endings are ignored. */
99
+ private end;
100
+ }
101
+
102
+ /** The agent did not answer one request of the turn within the configured timeout. */
103
+ declare class AcpRequestTimeoutError extends Error {
104
+ /** The agent executable, as configured. */
105
+ readonly command: string;
106
+ /** The ACP method left unanswered, e.g. `session/prompt`. */
107
+ readonly method: string;
108
+ /** The timeout that elapsed, in milliseconds. */
109
+ readonly timeoutMs: number;
110
+ readonly name = "AcpRequestTimeoutError";
111
+ constructor(
112
+ /** The agent executable, as configured. */
113
+ command: string,
114
+ /** The ACP method left unanswered, e.g. `session/prompt`. */
115
+ method: string,
116
+ /** The timeout that elapsed, in milliseconds. */
117
+ timeoutMs: number);
118
+ }
119
+ /**
120
+ * The agent ended the turn with a `stopReason` other than `end_turn`: it stopped before finishing,
121
+ * so the text it streamed is not its answer. That text is kept as `partialText`.
122
+ */
123
+ declare class AcpTurnStoppedError extends Error {
124
+ /** The agent executable, as configured. */
125
+ readonly command: string;
126
+ /** The `stopReason` of the `session/prompt` result, e.g. `max_tokens`. */
127
+ readonly stopReason: string;
128
+ /** The text the agent streamed for the session before it stopped. */
129
+ readonly partialText: string;
130
+ readonly name = "AcpTurnStoppedError";
131
+ constructor(
132
+ /** The agent executable, as configured. */
133
+ command: string,
134
+ /** The `stopReason` of the `session/prompt` result, e.g. `max_tokens`. */
135
+ stopReason: string,
136
+ /** The text the agent streamed for the session before it stopped. */
137
+ partialText: string);
53
138
  }
54
139
  interface AcpToolConfig {
55
140
  /** Executable for the coding agent (e.g. `claude`, `amp`, `codex`). */
@@ -71,9 +156,17 @@ interface AcpToolConfig {
71
156
  } | Promise<{
72
157
  granted: boolean;
73
158
  }>;
159
+ /**
160
+ * How long one request of the turn (`initialize`, `session/new`, `session/prompt`) may wait for
161
+ * the agent's answer, in milliseconds. Defaults to {@link DEFAULT_ACP_TIMEOUT_MS}. A request
162
+ * past it rejects the call with {@link AcpRequestTimeoutError} and the agent process is closed.
163
+ */
164
+ timeoutMs?: number;
74
165
  /** Injected transport factory (defaults to spawning via {@link NodeAcpTransport}) — for tests. */
75
- transportFactory?: (config: AcpToolConfig) => AcpTransport;
166
+ transportFactory?: (config: AcpToolConfig) => AcpToolTransport;
76
167
  }
168
+ /** Default per-request timeout: ten minutes, room for a long coding turn without hanging forever. */
169
+ declare const DEFAULT_ACP_TIMEOUT_MS = 600000;
77
170
  /** Wrap a coding agent as a `CustomTool`. Fails fast if `onPermissionRequest` is missing. */
78
171
  declare function createACPTool(config: AcpToolConfig): CustomTool$1;
79
172
 
@@ -336,4 +429,4 @@ interface StdioStreams {
336
429
  */
337
430
  declare function serveMcpStdio(mod: unknown, name: string, appResources: readonly AppResource[], streams: StdioStreams): Promise<void>;
338
431
 
339
- export { type AcpToolConfig, type AppResource, type AppResourceInput, type ChannelMessage, type ChannelWebhookConfig, type CodeModeApi, type CodeModeConfig, type CodeModePermission, CodeModePermissionDeniedError, type McpResourceContents, type McpResourceDescriptor, NodeAcpTransport, type Sandbox, type StdioStreams, type VendorAgentClient, type VendorAgentToolConfig, type WorkflowLike, type WorkflowToolConfig, buildResourceDescriptors, createACPTool, createCodeMode, createVendorAgentTool, createWorkflowTool, defineAppResource, extractAppResources, handleChannelWebhook, handleMcpStdioLine, isChannelPath, parseChannelPath, readAppResource, serveMcpStdio };
432
+ export { AcpRequestTimeoutError, type AcpToolConfig, type AcpToolTransport, AcpTransportClosedError, AcpTurnStoppedError, type AppResource, type AppResourceInput, type ChannelMessage, type ChannelWebhookConfig, type CodeModeApi, type CodeModeConfig, type CodeModePermission, CodeModePermissionDeniedError, DEFAULT_ACP_TIMEOUT_MS, type McpResourceContents, type McpResourceDescriptor, NodeAcpTransport, type Sandbox, type StdioStreams, type VendorAgentClient, type VendorAgentToolConfig, type WorkflowLike, type WorkflowToolConfig, buildResourceDescriptors, createACPTool, createCodeMode, createVendorAgentTool, createWorkflowTool, defineAppResource, extractAppResources, handleChannelWebhook, handleMcpStdioLine, isChannelPath, parseChannelPath, readAppResource, serveMcpStdio };
@@ -1,5 +1,9 @@
1
1
  import {
2
+ AcpRequestTimeoutError,
3
+ AcpTransportClosedError,
4
+ AcpTurnStoppedError,
2
5
  CodeModePermissionDeniedError,
6
+ DEFAULT_ACP_TIMEOUT_MS,
3
7
  InProcessApprovalRequiredError,
4
8
  NodeAcpTransport,
5
9
  createACPTool,
@@ -12,7 +16,7 @@ import {
12
16
  parseChannelPath,
13
17
  serveMcpStdio,
14
18
  streamAgentTurnInProcess
15
- } from "../../chunk-ET2TAY3Z.js";
19
+ } from "../../chunk-RAUYMVUO.js";
16
20
  import "../../chunk-DVUJLMTF.js";
17
21
  import {
18
22
  buildResourceDescriptors,
@@ -29,7 +33,11 @@ import {
29
33
  } from "../../chunk-ICXXHV4V.js";
30
34
  import "../../chunk-XTHN6JBX.js";
31
35
  export {
36
+ AcpRequestTimeoutError,
37
+ AcpTransportClosedError,
38
+ AcpTurnStoppedError,
32
39
  CodeModePermissionDeniedError,
40
+ DEFAULT_ACP_TIMEOUT_MS,
33
41
  InProcessApprovalRequiredError,
34
42
  NodeAcpTransport,
35
43
  buildResourceDescriptors,
@@ -14,10 +14,10 @@ import {
14
14
  translateCronToVercel,
15
15
  validateCronSchedule,
16
16
  writeCronManifest
17
- } from "../../chunk-D5KBBTVD.js";
17
+ } from "../../chunk-RY6D4EXL.js";
18
18
  import "../../chunk-IDEZ7FU2.js";
19
19
  import "../../chunk-UMNXCU3K.js";
20
- import "../../chunk-5KRMDP46.js";
20
+ import "../../chunk-AHYOVVJ7.js";
21
21
  import "../../chunk-SOYOYGWY.js";
22
22
  import "../../chunk-ZWN3AODA.js";
23
23
  import "../../chunk-XTHN6JBX.js";
@@ -11,7 +11,7 @@ export { A as ActionError, a as ActionErrorCode, b as ActionInputError, e as Act
11
11
  export { ACTION_SCHEMAS_DIR, ActionNode, ActionScanError, LoadedManifest, ManifestAction, ManifestAgent, ManifestRoute, ManifestWebSocket, TheoManifest, WebSocketRouteNode, _resetRouteScanCacheForTests, compareRouteSpecificity, generateManifest, loadManifest, scanMiddlewares, scanServerActions, scanServerActionsEnriched, scanServerRoutes, scanWebSocketRoutes, writeManifest } from './scan/index.js';
12
12
  export { S as ServerRouteNode, c as compilePattern, m as matchRoute } from '../match-DaKsL73w.js';
13
13
  export { L as LoadModule, c as createProductionLoader, a as createViteLoader } from '../module-loader-DCip7NoL.js';
14
- export { AcpToolConfig, AppResource, AppResourceInput, ChannelMessage, ChannelWebhookConfig, CodeModeApi, CodeModeConfig, CodeModePermission, CodeModePermissionDeniedError, McpResourceContents, McpResourceDescriptor, NodeAcpTransport, Sandbox, StdioStreams, VendorAgentClient, VendorAgentToolConfig, WorkflowLike, WorkflowToolConfig, buildResourceDescriptors, createACPTool, createCodeMode, createVendorAgentTool, createWorkflowTool, defineAppResource, extractAppResources, handleChannelWebhook, handleMcpStdioLine, isChannelPath, parseChannelPath, readAppResource, serveMcpStdio } from './agent/index.js';
14
+ export { AcpRequestTimeoutError, AcpToolConfig, AcpToolTransport, AcpTransportClosedError, AcpTurnStoppedError, AppResource, AppResourceInput, ChannelMessage, ChannelWebhookConfig, CodeModeApi, CodeModeConfig, CodeModePermission, CodeModePermissionDeniedError, DEFAULT_ACP_TIMEOUT_MS, McpResourceContents, McpResourceDescriptor, NodeAcpTransport, Sandbox, StdioStreams, VendorAgentClient, VendorAgentToolConfig, WorkflowLike, WorkflowToolConfig, buildResourceDescriptors, createACPTool, createCodeMode, createVendorAgentTool, createWorkflowTool, defineAppResource, extractAppResources, handleChannelWebhook, handleMcpStdioLine, isChannelPath, parseChannelPath, readAppResource, serveMcpStdio } from './agent/index.js';
15
15
  export { AgentModule, InProcessApprovalRequest, InProcessApprovalRequiredError, InProcessAwaitApproval, StreamAgentTurnDeps, StreamAgentTurnInProcessInput, streamAgentTurnInProcess } from '@theokit/agents';
16
16
  export { P as ProviderDescriptor, R as ResolvedProvider, l as listProviders, a as registerProvider, b as resetProviderRegistry, r as resolveProvider, t as tryResolveProvider } from '../provider-resolver-Cc9C3-Rb.js';
17
17
  export { AuthRequiredError, Authenticated, BackupCode, BackupCodeOptions, MIN_SECRET_LENGTH, OidcMetadata, PkceChallenge, PreviewMarker, PreviewMarkerConfig, SecretWeakness, SecretWeaknessCode, SessionConfig, SessionManager, SessionManagerWeb, SessionMeta, SessionReader, ThrottleOptions, ThrottleState, TotpAlgorithm, TotpOptions, TotpUriOptions, VerifyTotpOptions, _resetKeyCacheForTests, assertProductionSecret, checkThrottle, clearOidcCache, createPreviewMarker, createSessionManager, createSessionManagerWeb, decrypt, discoverOidcProvider, encrypt, generateBackupCodes, generateOAuthState, generatePkceChallenge, generateTotp, generateTotpSecret, inspectSecret, pkceChallengeFromVerifier, recordAttempt, requireAuth, rotateIfNeeded, rotateIfNeededWeb, totpUri, verifyBackupCode, verifyOAuthState, verifyTotp } from './auth/index.js';