theokit 0.74.4 → 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.
- package/dist/{actions-virtual-module-MIQJEHKJ.js → actions-virtual-module-MIQPBAZW.js} +5 -5
- package/dist/{actions-virtual-module-4J7Z37Y4.js → actions-virtual-module-QEI6QPK4.js} +5 -5
- package/dist/adapters/agent-mount.js +1 -1
- package/dist/{agent-QJINXU6U.js → agent-IIF6JUWX.js} +3 -3
- package/dist/{app-typed-client-AZMUYIYV.js → app-typed-client-CHSITA46.js} +5 -5
- package/dist/{app-typed-client-DSS23KDC.js → app-typed-client-XQJXF646.js} +5 -5
- package/dist/{build-AKN2NCFW.js → build-QIO4VAW2.js} +22 -87
- package/dist/build-QIO4VAW2.js.map +1 -0
- package/dist/{chunk-25OXNMVO.js → chunk-2BMJQMTH.js} +5 -5
- package/dist/{chunk-44E7XIZC.js → chunk-3MKRDJQ2.js} +2 -2
- package/dist/{chunk-4ERYQBL6.js → chunk-4Z5XO4O4.js} +2 -2
- package/dist/{chunk-SHFZKJCU.js → chunk-6RVWPEKK.js} +15 -10
- package/dist/{chunk-SHFZKJCU.js.map → chunk-6RVWPEKK.js.map} +1 -1
- package/dist/{chunk-V7ISZGNS.js → chunk-7HGZ3CKL.js} +2 -2
- package/dist/{chunk-6R5F5YF2.js → chunk-A6UFN6QQ.js} +16 -11
- package/dist/{chunk-6R5F5YF2.js.map → chunk-A6UFN6QQ.js.map} +1 -1
- package/dist/{chunk-5KRMDP46.js → chunk-AHYOVVJ7.js} +13 -3
- package/dist/chunk-AHYOVVJ7.js.map +1 -0
- package/dist/{chunk-WR5B2XNT.js → chunk-FNAEKJHO.js} +2 -2
- package/dist/{chunk-HKF6YNY4.js → chunk-FU3LEX2I.js} +26 -12
- package/dist/chunk-FU3LEX2I.js.map +1 -0
- package/dist/{chunk-VD3BCME6.js → chunk-I5PDEWZZ.js} +2 -2
- package/dist/chunk-IWIRHUNV.js +96 -0
- package/dist/chunk-IWIRHUNV.js.map +1 -0
- package/dist/{chunk-U5PWXS3J.js → chunk-O5JZ6ROY.js} +13 -3
- package/dist/chunk-O5JZ6ROY.js.map +1 -0
- package/dist/{chunk-VOXLI66L.js → chunk-OZB2TKGJ.js} +2 -2
- package/dist/{chunk-ET2TAY3Z.js → chunk-RAUYMVUO.js} +279 -15
- package/dist/chunk-RAUYMVUO.js.map +1 -0
- package/dist/{chunk-7FIK5NKN.js → chunk-RKRFJRJ3.js} +15 -10
- package/dist/{chunk-7FIK5NKN.js.map → chunk-RKRFJRJ3.js.map} +1 -1
- package/dist/{chunk-DA3GGICE.js → chunk-RQKMY3JW.js} +2 -2
- package/dist/{chunk-D5KBBTVD.js → chunk-RY6D4EXL.js} +20 -13
- package/dist/chunk-RY6D4EXL.js.map +1 -0
- package/dist/cli/index.js +10 -10
- package/dist/{dev-LMZGOV4M.js → dev-J2XZIENF.js} +8 -8
- package/dist/{dev-emit-T3X6RR7M.js → dev-emit-AXTJK56H.js} +3 -3
- package/dist/{dev-emit-ZK5GCHXN.js → dev-emit-XAPVJBM4.js} +3 -3
- package/dist/{generate-EN6EDITF.js → generate-RW3NO3NR.js} +239 -141
- package/dist/generate-RW3NO3NR.js.map +1 -0
- package/dist/index.js +5 -5
- package/dist/{info-XURFOBRF.js → info-6NAUW5XY.js} +3 -3
- package/dist/{internal-api-XPT4GLYX.js → internal-api-A5HA7TYF.js} +5 -5
- package/dist/{internal-api-ATSPOXI2.js → internal-api-R7TTYMCY.js} +5 -5
- package/dist/{load-config-2DXLI7NW.js → load-config-CLFWJOXN.js} +3 -3
- package/dist/{mcp-4CXNOZA4.js → mcp-MWTG3LRA.js} +4 -4
- package/dist/{openapi-UJSUQPNT.js → openapi-RVFUXXCR.js} +5 -5
- package/dist/{preview-WTPUW47O.js → preview-ML4CFUD6.js} +3 -3
- package/dist/{routes-ENMU4GAN.js → routes-SMNSI2ZX.js} +3 -3
- package/dist/server/agent/index.d.ts +99 -6
- package/dist/server/agent/index.js +9 -1
- package/dist/server/cron/index.js +2 -2
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +15 -7
- package/dist/server/index.js.map +1 -1
- package/dist/server/jobs/index.js +2 -2
- package/dist/server/scan/index.js +4 -4
- package/dist/{server-boundary-K4YQXDQT.js → server-boundary-HYLYGFZY.js} +5 -5
- package/dist/{server-boundary-JM72DQLA.js → server-boundary-ZT6HN7ON.js} +5 -5
- package/dist/{start-GAULIE5E.js → start-L5TGWGLU.js} +7 -7
- package/dist/vite-plugin/index.js +5 -5
- package/dist/{vite-plugin-NXWE2AVM.js → vite-plugin-OJND2LU5.js} +8 -8
- package/package.json +2 -2
- package/dist/build-AKN2NCFW.js.map +0 -1
- package/dist/chunk-5KRMDP46.js.map +0 -1
- package/dist/chunk-D5KBBTVD.js.map +0 -1
- package/dist/chunk-ET2TAY3Z.js.map +0 -1
- package/dist/chunk-HKF6YNY4.js.map +0 -1
- package/dist/chunk-U5PWXS3J.js.map +0 -1
- package/dist/generate-EN6EDITF.js.map +0 -1
- /package/dist/{actions-virtual-module-MIQJEHKJ.js.map → actions-virtual-module-MIQPBAZW.js.map} +0 -0
- /package/dist/{actions-virtual-module-4J7Z37Y4.js.map → actions-virtual-module-QEI6QPK4.js.map} +0 -0
- /package/dist/{agent-QJINXU6U.js.map → agent-IIF6JUWX.js.map} +0 -0
- /package/dist/{app-typed-client-AZMUYIYV.js.map → app-typed-client-CHSITA46.js.map} +0 -0
- /package/dist/{app-typed-client-DSS23KDC.js.map → app-typed-client-XQJXF646.js.map} +0 -0
- /package/dist/{chunk-25OXNMVO.js.map → chunk-2BMJQMTH.js.map} +0 -0
- /package/dist/{chunk-44E7XIZC.js.map → chunk-3MKRDJQ2.js.map} +0 -0
- /package/dist/{chunk-4ERYQBL6.js.map → chunk-4Z5XO4O4.js.map} +0 -0
- /package/dist/{chunk-V7ISZGNS.js.map → chunk-7HGZ3CKL.js.map} +0 -0
- /package/dist/{chunk-WR5B2XNT.js.map → chunk-FNAEKJHO.js.map} +0 -0
- /package/dist/{chunk-VD3BCME6.js.map → chunk-I5PDEWZZ.js.map} +0 -0
- /package/dist/{chunk-VOXLI66L.js.map → chunk-OZB2TKGJ.js.map} +0 -0
- /package/dist/{chunk-DA3GGICE.js.map → chunk-RQKMY3JW.js.map} +0 -0
- /package/dist/{dev-LMZGOV4M.js.map → dev-J2XZIENF.js.map} +0 -0
- /package/dist/{dev-emit-T3X6RR7M.js.map → dev-emit-AXTJK56H.js.map} +0 -0
- /package/dist/{dev-emit-ZK5GCHXN.js.map → dev-emit-XAPVJBM4.js.map} +0 -0
- /package/dist/{info-XURFOBRF.js.map → info-6NAUW5XY.js.map} +0 -0
- /package/dist/{internal-api-XPT4GLYX.js.map → internal-api-A5HA7TYF.js.map} +0 -0
- /package/dist/{internal-api-ATSPOXI2.js.map → internal-api-R7TTYMCY.js.map} +0 -0
- /package/dist/{load-config-2DXLI7NW.js.map → load-config-CLFWJOXN.js.map} +0 -0
- /package/dist/{mcp-4CXNOZA4.js.map → mcp-MWTG3LRA.js.map} +0 -0
- /package/dist/{openapi-UJSUQPNT.js.map → openapi-RVFUXXCR.js.map} +0 -0
- /package/dist/{preview-WTPUW47O.js.map → preview-ML4CFUD6.js.map} +0 -0
- /package/dist/{routes-ENMU4GAN.js.map → routes-SMNSI2ZX.js.map} +0 -0
- /package/dist/{server-boundary-K4YQXDQT.js.map → server-boundary-HYLYGFZY.js.map} +0 -0
- /package/dist/{server-boundary-JM72DQLA.js.map → server-boundary-ZT6HN7ON.js.map} +0 -0
- /package/dist/{start-GAULIE5E.js.map → start-L5TGWGLU.js.map} +0 -0
- /package/dist/{vite-plugin-NXWE2AVM.js.map → vite-plugin-OJND2LU5.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/scan/agent-scan.ts","../src/server/scan/detect-agent-policy.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `<projectRoot>/agents/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nimport { declaresAgentPolicy } from './detect-agent-policy.js'\nimport { MissingAgentPolicyError } from './errors.js'\nimport { createFileStampCache } from './file-stamp-cache.js'\n\nconst AGENT_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n// Convention § 5: a co-located test file is not an agent.\nconst TEST_FILE = /\\.(test|spec)$/\n\n/**\n * Folder-semantic discovery (Eve-style \"file = identity\"): an agent may be a self-contained folder that\n * co-locates its composition — `agents/<name>/{index.ts, tools/, skills/, prompts/, lib/}`. Files INSIDE\n * these conventional sub-folders are that concern (a tool, a skill, a prompt, a helper), NOT a routed\n * agent, so the scanner skips any file whose path passes through one of them. Only `<name>.ts` or\n * `<name>/index.ts` is served at `/api/agents/<name>`. A flat file literally named `tools.ts` is still a\n * valid agent (the reserved names only apply to intermediate DIRECTORIES, never the agent file itself).\n */\nconst AGENT_SUBFOLDERS = new Set([\n 'tools',\n 'skills',\n 'prompts',\n 'lib',\n 'hooks',\n 'channels',\n 'connections',\n 'subagents',\n 'schedules',\n 'sandbox',\n 'workflows',\n 'evals',\n 'memory',\n])\n\n/**\n * A discovered agent file. `name` is the client-facing key; `agentPath` is the mounted\n * SSE route (M0/M1 `UIMessageStream`).\n */\nexport interface AgentNode {\n filePath: string\n agentPath: string\n name: string\n}\n\n/**\n * M2 — scan the TOP-LEVEL `agents/` convention (sibling of `server/`, per the LOCKED naming\n * decision). Mirrors `scanWebSocketRoutes`: one file → one endpoint, `index` stripped.\n */\n/**\n * Resolved paths already reported, so a per-request scan says it once — B-249, NFR-001.\n *\n * Keyed by the RESOLVED path rather than by the process: a test harness legitimately scans two\n * roots, and each distinct mistake deserves its own line. Same shape as `warnedAboutLegacySalt` in\n * `packages/http/src/action-encryption.ts`, and for the same reason: `scanAgents` runs per request\n * on a scanned deploy target, so an unbounded warning is a log flood on the exact path an anonymous\n * caller can drive.\n */\nconst reportedMissingDirs = new Set<string>()\n\nexport function scanAgents(projectRoot: string, configured?: string): AgentNode[] {\n const agentsDirName = configured ?? 'agents'\n // `agentsDirName` (config `agentsDir`, default \"agents\") — the dir holding `<name>.ts` agent\n // definitions, relative to the project root. May be nested (e.g. \"core/agents\"). (#95 follow-up)\n const agentsDir = join(projectRoot, agentsDirName)\n if (!existsSync(agentsDir) || !statSync(agentsDir).isDirectory()) {\n // B-249 — the same `[]` as before, and no longer the same silence.\n //\n // A configured value that resolves to nothing produced a result byte-identical to \"this app\n // declares no agents\", so a deployed `/api/agents/<name>` answered 404 with an empty log and an\n // operator had no reason to suspect configuration. The loudest way in is an ABSOLUTE path —\n // this parameter is a NAME joined onto the root, so `join()` silently yields\n // `<root><abs>` — but a typo, a missing nesting level and a directory a build did not copy all\n // land in exactly the same place, and one rule covers all four.\n //\n // Silent when NOTHING was configured: a project with no agents is the ordinary case, and a gate\n // that fires on ordinary work is a gate somebody disables. The parameter is OPTIONAL rather\n // than defaulted for exactly that reason — a default erases the difference between \"nobody\n // configured this\" and \"somebody configured 'agents'\", and only the first should stay quiet.\n //\n // The return value does not move (FR-003) and the contract stays relative (FR-004): reporting a\n // path that does not exist tells the operator what went wrong without widening a documented\n // public contract, which is a decision for a plan rather than a repair.\n if (configured !== undefined && !reportedMissingDirs.has(agentsDir)) {\n reportedMissingDirs.add(agentsDir)\n console.warn(\n `[theokit] agentsDir ${JSON.stringify(agentsDirName)} resolves to ${JSON.stringify(agentsDir)}, ` +\n `which is not a directory, so NO agents were found and every /api/agents/* route will 404. ` +\n `The value is a path relative to the project root ${JSON.stringify(projectRoot)} — an ` +\n `absolute path is joined onto it and cannot resolve.`,\n )\n }\n return []\n }\n\n const results: AgentNode[] = []\n walkSourceFiles(agentsDir, { extensions: AGENT_EXTENSIONS }, (absPath) => {\n const name = agentNameOf(agentsDir, absPath)\n if (name === undefined) return\n const agentPath = `/api/agents/${name}`\n assertAgentDeclaresPolicy(absPath, agentPath)\n results.push({\n filePath: absPath,\n agentPath,\n name,\n })\n })\n return results\n}\n\n/**\n * The name the agent at `absPath` is served under, or `undefined` when the file is not an agent:\n * a test file, a file under a composition sub-folder, or a bare `index`. The one definition of\n * \"which file is agent `<name>`\", shared by `scanAgents` and `findAgentFile`.\n */\nfunction agentNameOf(agentsDir: string, absPath: string): string | undefined {\n let rel = relative(agentsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n if (TEST_FILE.test(rel)) return undefined\n // Eve-style: a file living under a composition sub-folder (tools/, skills/, prompts/, …) is that\n // concern, not a routed agent. Check the intermediate DIRECTORIES only — the agent file itself may\n // be named anything.\n const dirs = rel.split('/').slice(0, -1)\n if (dirs.some((segment) => AGENT_SUBFOLDERS.has(segment))) return undefined\n // Unlike routes/ws, an agent needs an explicit name — a bare `agents/index.ts`\n // (name `''` → `/api/agents/`) is nonsensical for a typed `useAgent(name)` binding.\n // `agents/foo/index.ts` still collapses to `foo` (a named nested agent).\n if (rel.endsWith('/index')) rel = rel.slice(0, -6)\n if (rel === 'index' || rel === '') return undefined\n return rel\n}\n\n/**\n * The file `scanAgents` would serve as agent `name` under the absolute directory `agentsDir`, or\n * `undefined` when there is none. Unlike `scanAgents` it does not refuse an agent that declares no\n * policy: a caller asking where one agent lives (the schedule generator) is not mounting it, and\n * the build still refuses the undeclared one when it scans.\n */\nexport function findAgentFile(agentsDir: string, name: string): string | undefined {\n if (!existsSync(agentsDir) || !statSync(agentsDir).isDirectory()) return undefined\n let found: string | undefined\n walkSourceFiles(agentsDir, { extensions: AGENT_EXTENSIONS }, (absPath) => {\n if (found === undefined && agentNameOf(agentsDir, absPath) === name) found = absPath\n })\n return found\n}\n\n/**\n * Cache of the policy-declaration answer, keyed by path + mtime + size.\n *\n * `theokit dev` re-scans the agents directory on EVERY request, so parsing each agent file with the\n * TypeScript AST per request would turn a build-time check into per-request latency. Keying on the\n * file's own mtime and size means an edit invalidates the entry without anyone remembering to, and\n * a `theokit build` (one process, one scan) never notices the cache exists.\n */\nconst policyDeclarationCache = createFileStampCache<boolean>()\n\n/** Test seam — the module-level cache would otherwise outlive a fixture directory. */\nexport function _resetAgentPolicyCacheForTests(): void {\n policyDeclarationCache.clear()\n}\n\n/**\n * Refuse an agent file that declares no access policy (usetheokit/theokit#365).\n *\n * The refusal lives in the scanner, next to the reserved-name and empty-name refusals, because this\n * is the one place every entry point passes through: `theokit build`, `theokit start`, `theokit dev`\n * and the manifest generator all reach agents by calling `scanAgents`.\n *\n * The blast radius stops at the file system, exactly as it does for routes. A module handed to\n * `mountAgent` in memory — a test, an embedder, an `@Expose`d controller method — never passed a\n * scanner, and `admitAgentRequest` still treats an undeclared policy as \"not declared\" rather than\n * as denial. Absence is refused where an application DECLARES its agents, not where a caller passes\n * one.\n */\nfunction assertAgentDeclaresPolicy(filePath: string, agentPath: string): void {\n // The stamping and the `has`-vs-truthy subtlety moved into `createFileStampCache` (#417), where\n // the route scanner shares them rather than growing a second copy keyed \"the same way\".\n const declared = policyDeclarationCache.get(filePath, () =>\n declaresAgentPolicy(filePath, readFileSync(filePath, 'utf8')),\n )\n if (!declared) throw new MissingAgentPolicyError({ file: filePath, agentPath })\n}\n","/**\n * Does this agent file declare an access policy? (usetheokit/theokit#365)\n *\n * The sibling of `detect-route-policy.ts`, and deliberately the same instrument: the TypeScript\n * AST rather than a regex, because `// policy: ...` in a comment and the word `policy` in a doc\n * block are both things an agent file legitimately contains, and neither declares anything.\n *\n * ## What it looks for, and why it is simpler than the route detector\n *\n * A route file declares one policy PER exported HTTP method, so the route detector has to return a\n * set and reason about which method carried which config. An agent file is one agent, so the\n * question is a single yes or no: is there a top-level export named `policy`?\n *\n * ```ts\n * export const policy = 'public'\n * export const policy = ({ subject, params }) => requireOwner(subject, ownerOf(params.sessionId))\n * const policy = ...; export { policy }\n * export { agentPolicy as policy } from './shared' // ← also counts; see below\n * ```\n *\n * ## Where this is deliberately laxer than the route detector\n *\n * The route detector refuses `export { GET } from './shared'`, on the reasoning that it cannot see\n * whether the re-exported value declares a policy. Here there is nothing to look inside: the export\n * IS the policy, so a re-export names one as surely as a local const does. The value's SHAPE is\n * checked at runtime by `readAgentPolicy`, which throws on anything that is neither `'public'` nor\n * a function — so a wrong type fails loudly rather than being served open.\n */\nimport { createRequire } from 'node:module'\n\nimport type * as TS from 'typescript'\n\n/**\n * The compiler, loaded on first use and never at import time.\n *\n * This was module scope, and a Cloudflare deploy found what that costs: `theokit/server/scan` is\n * imported by the generated worker (through `agent-scan.ts`), Cloudflare EXECUTES the module during\n * validation, and there `import.meta.url` is undefined — so `createRequire` threw before the worker\n * ever answered a request (B-263, error 10021). `wrangler deploy --dry-run` had returned exit 0 on\n * the same bundle minutes earlier: it bundles and does not execute.\n *\n * The second reason is independent of Workers and would hold anyway: this is a BUILD-TIME AST\n * scanner, and nothing that merely imports the module should pay for the TypeScript compiler.\n *\n * Cached, so scanning many files still loads it once.\n */\nlet compiler: typeof TS | undefined\n\nfunction ts_(): typeof TS {\n compiler ??= createRequire(import.meta.url)('typescript') as typeof TS\n return compiler\n}\n\nconst POLICY_EXPORT = 'policy'\n\nfunction hasExportModifier(modifiers: readonly TS.Modifier[] | undefined): boolean {\n if (!modifiers) return false\n for (const m of modifiers) {\n if (m.kind === ts_().SyntaxKind.ExportKeyword) return true\n }\n return false\n}\n\n/** `export const policy = ...` (also `let`/`var`, which are legal if unusual). */\nfunction variableStatementDeclaresPolicy(stmt: TS.VariableStatement): boolean {\n if (!hasExportModifier(ts_().getModifiers(stmt))) return false\n return stmt.declarationList.declarations.some(\n (decl) => ts_().isIdentifier(decl.name) && decl.name.text === POLICY_EXPORT,\n )\n}\n\n/** `export { policy }`, `export { p as policy }`, `export { p as policy } from './shared'`. */\nfunction exportDeclarationDeclaresPolicy(stmt: TS.ExportDeclaration): boolean {\n if (!stmt.exportClause || !ts_().isNamedExports(stmt.exportClause)) return false\n return stmt.exportClause.elements.some((spec) => spec.name.text === POLICY_EXPORT)\n}\n\n/** `export function policy() {}` — a function declaration is a policy as much as a const is. */\nfunction functionDeclarationDeclaresPolicy(stmt: TS.FunctionDeclaration): boolean {\n return hasExportModifier(ts_().getModifiers(stmt)) && stmt.name?.text === POLICY_EXPORT\n}\n\n/**\n * True when the file has a top-level export named `policy`.\n *\n * `content` is passed in rather than read here so the caller reads each file once — the same\n * contract `detectRoutePolicyKinds` follows.\n */\nexport function declaresAgentPolicy(filePath: string, content: string): boolean {\n const sourceFile = ts_().createSourceFile(\n filePath,\n content,\n ts_().ScriptTarget.Latest,\n /* setParentNodes */ false,\n ts_().ScriptKind.TS,\n )\n for (const stmt of sourceFile.statements) {\n if (ts_().isVariableStatement(stmt) && variableStatementDeclaresPolicy(stmt)) return true\n if (ts_().isExportDeclaration(stmt) && exportDeclarationDeclaresPolicy(stmt)) return true\n if (ts_().isFunctionDeclaration(stmt) && functionDeclarationDeclaresPolicy(stmt)) return true\n }\n return false\n}\n"],"mappings":";;;;;;;;;AAIA,SAAS,YAAY,cAAc,gBAAgB;AACnD,SAAS,SAAS,MAAM,gBAAgB;;;ACuBxC,SAAS,qBAAqB;AAkB9B,IAAI;AAEJ,SAAS,MAAiB;AACxB,eAAa,cAAc,YAAY,GAAG,EAAE,YAAY;AACxD,SAAO;AACT;AAEA,IAAM,gBAAgB;AAEtB,SAAS,kBAAkB,WAAwD;AACjF,MAAI,CAAC,UAAW,QAAO;AACvB,aAAW,KAAK,WAAW;AACzB,QAAI,EAAE,SAAS,IAAI,EAAE,WAAW,cAAe,QAAO;AAAA,EACxD;AACA,SAAO;AACT;AAGA,SAAS,gCAAgC,MAAqC;AAC5E,MAAI,CAAC,kBAAkB,IAAI,EAAE,aAAa,IAAI,CAAC,EAAG,QAAO;AACzD,SAAO,KAAK,gBAAgB,aAAa;AAAA,IACvC,CAAC,SAAS,IAAI,EAAE,aAAa,KAAK,IAAI,KAAK,KAAK,KAAK,SAAS;AAAA,EAChE;AACF;AAGA,SAAS,gCAAgC,MAAqC;AAC5E,MAAI,CAAC,KAAK,gBAAgB,CAAC,IAAI,EAAE,eAAe,KAAK,YAAY,EAAG,QAAO;AAC3E,SAAO,KAAK,aAAa,SAAS,KAAK,CAAC,SAAS,KAAK,KAAK,SAAS,aAAa;AACnF;AAGA,SAAS,kCAAkC,MAAuC;AAChF,SAAO,kBAAkB,IAAI,EAAE,aAAa,IAAI,CAAC,KAAK,KAAK,MAAM,SAAS;AAC5E;AAQO,SAAS,oBAAoB,UAAkB,SAA0B;AAC9E,QAAM,aAAa,IAAI,EAAE;AAAA,IACvB;AAAA,IACA;AAAA,IACA,IAAI,EAAE,aAAa;AAAA;AAAA,IACE;AAAA,IACrB,IAAI,EAAE,WAAW;AAAA,EACnB;AACA,aAAW,QAAQ,WAAW,YAAY;AACxC,QAAI,IAAI,EAAE,oBAAoB,IAAI,KAAK,gCAAgC,IAAI,EAAG,QAAO;AACrF,QAAI,IAAI,EAAE,oBAAoB,IAAI,KAAK,gCAAgC,IAAI,EAAG,QAAO;AACrF,QAAI,IAAI,EAAE,sBAAsB,IAAI,KAAK,kCAAkC,IAAI,EAAG,QAAO;AAAA,EAC3F;AACA,SAAO;AACT;;;ADzFA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAE/D,IAAM,YAAY;AAUlB,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;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;AAyBD,IAAM,sBAAsB,oBAAI,IAAY;AAErC,SAAS,WAAW,aAAqB,YAAkC;AAChF,QAAM,gBAAgB,cAAc;AAGpC,QAAM,YAAY,KAAK,aAAa,aAAa;AACjD,MAAI,CAAC,WAAW,SAAS,KAAK,CAAC,SAAS,SAAS,EAAE,YAAY,GAAG;AAkBhE,QAAI,eAAe,UAAa,CAAC,oBAAoB,IAAI,SAAS,GAAG;AACnE,0BAAoB,IAAI,SAAS;AACjC,cAAQ;AAAA,QACN,uBAAuB,KAAK,UAAU,aAAa,CAAC,gBAAgB,KAAK,UAAU,SAAS,CAAC,gJAEvC,KAAK,UAAU,WAAW,CAAC;AAAA,MAEnF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAuB,CAAC;AAC9B,kBAAgB,WAAW,EAAE,YAAY,iBAAiB,GAAG,CAAC,YAAY;AACxE,UAAM,OAAO,YAAY,WAAW,OAAO;AAC3C,QAAI,SAAS,OAAW;AACxB,UAAM,YAAY,eAAe,IAAI;AACrC,8BAA0B,SAAS,SAAS;AAC5C,YAAQ,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AAOA,SAAS,YAAY,WAAmB,SAAqC;AAC3E,MAAI,MAAM,SAAS,WAAW,OAAO;AACrC,QAAM,IAAI,QAAQ,OAAO,GAAG;AAC5B,QAAM,IAAI,MAAM,GAAG,CAAC,QAAQ,GAAG,EAAE,MAAM;AACvC,MAAI,UAAU,KAAK,GAAG,EAAG,QAAO;AAIhC,QAAM,OAAO,IAAI,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE;AACvC,MAAI,KAAK,KAAK,CAAC,YAAY,iBAAiB,IAAI,OAAO,CAAC,EAAG,QAAO;AAIlE,MAAI,IAAI,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE;AACjD,MAAI,QAAQ,WAAW,QAAQ,GAAI,QAAO;AAC1C,SAAO;AACT;AAQO,SAAS,cAAc,WAAmB,MAAkC;AACjF,MAAI,CAAC,WAAW,SAAS,KAAK,CAAC,SAAS,SAAS,EAAE,YAAY,EAAG,QAAO;AACzE,MAAI;AACJ,kBAAgB,WAAW,EAAE,YAAY,iBAAiB,GAAG,CAAC,YAAY;AACxE,QAAI,UAAU,UAAa,YAAY,WAAW,OAAO,MAAM,KAAM,SAAQ;AAAA,EAC/E,CAAC;AACD,SAAO;AACT;AAUA,IAAM,yBAAyB,qBAA8B;AAoB7D,SAAS,0BAA0B,UAAkB,WAAyB;AAG5E,QAAM,WAAW,uBAAuB;AAAA,IAAI;AAAA,IAAU,MACpD,oBAAoB,UAAU,aAAa,UAAU,MAAM,CAAC;AAAA,EAC9D;AACA,MAAI,CAAC,SAAU,OAAM,IAAI,wBAAwB,EAAE,MAAM,UAAU,UAAU,CAAC;AAChF;","names":[]}
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
parseAgentRequestBody,
|
|
27
27
|
readAgentPolicy,
|
|
28
28
|
subjectFromContext
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-RQKMY3JW.js";
|
|
30
30
|
import {
|
|
31
31
|
getApprovalRegistry
|
|
32
32
|
} from "./chunk-BINRCILF.js";
|
|
@@ -901,4 +901,4 @@ export {
|
|
|
901
901
|
applyNonceToInlineScripts,
|
|
902
902
|
setupSsrDevMiddleware
|
|
903
903
|
};
|
|
904
|
-
//# sourceMappingURL=chunk-
|
|
904
|
+
//# sourceMappingURL=chunk-I5PDEWZZ.js.map
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "tsx/esm";
|
|
3
|
+
import {
|
|
4
|
+
compareByCodeUnit,
|
|
5
|
+
walkSourceFiles
|
|
6
|
+
} from "./chunk-Z7CJHDLS.js";
|
|
7
|
+
import {
|
|
8
|
+
importUserModule
|
|
9
|
+
} from "./chunk-O5JZ6ROY.js";
|
|
10
|
+
|
|
11
|
+
// src/server/cron/cron-scan.ts
|
|
12
|
+
import { existsSync } from "fs";
|
|
13
|
+
import { basename, resolve } from "path";
|
|
14
|
+
var DuplicateCronNameError = class extends Error {
|
|
15
|
+
constructor(cronName, filePaths) {
|
|
16
|
+
super(
|
|
17
|
+
`Duplicate cron name "${cronName}" defined in: ${filePaths.join(", ")}. Cron names must be unique across server/crons/ and agents/schedules/.`
|
|
18
|
+
);
|
|
19
|
+
this.cronName = cronName;
|
|
20
|
+
this.filePaths = filePaths;
|
|
21
|
+
this.name = "DuplicateCronNameError";
|
|
22
|
+
}
|
|
23
|
+
cronName;
|
|
24
|
+
filePaths;
|
|
25
|
+
code = "DUPLICATE_CRON_NAME";
|
|
26
|
+
};
|
|
27
|
+
var CRON_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".mjs"]);
|
|
28
|
+
function isCronDefinition(value) {
|
|
29
|
+
if (typeof value !== "object" || value === null) return false;
|
|
30
|
+
const def = value;
|
|
31
|
+
return typeof def.name === "string" && typeof def.schedule === "string" && typeof def.handler === "function" && (def.concurrency === "forbid" || def.concurrency === "allow");
|
|
32
|
+
}
|
|
33
|
+
function cronScanDirs(cwd, serverDir, agentsDir) {
|
|
34
|
+
return {
|
|
35
|
+
crons: resolve(cwd, serverDir, "crons"),
|
|
36
|
+
schedules: resolve(cwd, agentsDir, "schedules")
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function isDiscoverableCronFile(fileName) {
|
|
40
|
+
return !fileName.startsWith("_") && !fileName.startsWith(".");
|
|
41
|
+
}
|
|
42
|
+
function listCronFiles(dirs) {
|
|
43
|
+
const filePaths = [];
|
|
44
|
+
for (const dir of dirs) {
|
|
45
|
+
if (!existsSync(dir)) continue;
|
|
46
|
+
walkSourceFiles(dir, { extensions: CRON_EXTENSIONS }, (p) => {
|
|
47
|
+
if (isDiscoverableCronFile(basename(p))) filePaths.push(p);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return filePaths;
|
|
51
|
+
}
|
|
52
|
+
async function scanCronDirs(dirs) {
|
|
53
|
+
const filePaths = listCronFiles(dirs);
|
|
54
|
+
const nodes = [];
|
|
55
|
+
for (const filePath of filePaths) {
|
|
56
|
+
let mod;
|
|
57
|
+
try {
|
|
58
|
+
mod = await importUserModule(filePath);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
61
|
+
throw new Error(`Failed to import cron file "${filePath}": ${reason}`);
|
|
62
|
+
}
|
|
63
|
+
const exported = mod.default;
|
|
64
|
+
if (!isCronDefinition(exported)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Cron file "${filePath}" is missing a valid default export. Expected \`export default defineCron(name, { schedule, handler })\`.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
nodes.push({
|
|
70
|
+
name: exported.name,
|
|
71
|
+
filePath,
|
|
72
|
+
schedule: exported.schedule,
|
|
73
|
+
concurrency: exported.concurrency
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const byName = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const node of nodes) {
|
|
78
|
+
const bucket = byName.get(node.name) ?? [];
|
|
79
|
+
bucket.push(node.filePath);
|
|
80
|
+
byName.set(node.name, bucket);
|
|
81
|
+
}
|
|
82
|
+
for (const [name, paths] of byName) {
|
|
83
|
+
if (paths.length > 1) {
|
|
84
|
+
throw new DuplicateCronNameError(name, paths);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return nodes.sort((a, b) => compareByCodeUnit(a.name, b.name));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export {
|
|
91
|
+
cronScanDirs,
|
|
92
|
+
isDiscoverableCronFile,
|
|
93
|
+
listCronFiles,
|
|
94
|
+
scanCronDirs
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=chunk-IWIRHUNV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/cron/cron-scan.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: caller-controlled directory paths only. No HTTP\n * input ever reaches these fs calls.\n */\nimport { existsSync } from 'node:fs'\nimport { basename, resolve } from 'node:path'\n\nimport { importUserModule } from '../../config/import-user-module.js'\nimport { compareByCodeUnit } from '../_internal/compare-by-code-unit.js'\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nimport type { CronConcurrencyPolicy, CronDefinition } from './cron-types.js'\n\n/**\n * One discovered cron from build-time scan. The handler is intentionally\n * NOT included — manifest is platform-neutral and consumed by adapters\n * that emit static config. Runtime dispatch loads the handler at fire time.\n */\nexport interface CronNode {\n readonly name: string\n readonly filePath: string\n readonly schedule: string\n readonly concurrency: CronConcurrencyPolicy\n}\n\nexport class DuplicateCronNameError extends Error {\n readonly code = 'DUPLICATE_CRON_NAME'\n constructor(\n public readonly cronName: string,\n public readonly filePaths: readonly string[],\n ) {\n super(\n `Duplicate cron name \"${cronName}\" defined in: ${filePaths.join(', ')}. ` +\n 'Cron names must be unique across server/crons/ and agents/schedules/.',\n )\n this.name = 'DuplicateCronNameError'\n }\n}\n\nconst CRON_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs'])\n\ninterface CronModule {\n default?: unknown\n}\n\nfunction isCronDefinition(value: unknown): value is CronDefinition {\n if (typeof value !== 'object' || value === null) return false\n const def = value as Record<string, unknown>\n return (\n typeof def.name === 'string' &&\n typeof def.schedule === 'string' &&\n typeof def.handler === 'function' &&\n (def.concurrency === 'forbid' || def.concurrency === 'allow')\n )\n}\n\n/**\n * The two homes `theokit build` scans for crons, absolute: `<serverDir>/crons` (a backend trigger)\n * and `<agentsDir>/schedules` (a scheduled agent run). One definition, read by the build and by the\n * schedule generator, so a generated schedule lands where the build looks.\n */\nexport function cronScanDirs(\n cwd: string,\n serverDir: string,\n agentsDir: string,\n): { readonly crons: string; readonly schedules: string } {\n return {\n crons: resolve(cwd, serverDir, 'crons'),\n schedules: resolve(cwd, agentsDir, 'schedules'),\n }\n}\n\n/**\n * Whether the scanner treats a file named `fileName` as a cron. Private helpers (`_helper.ts`) and\n * dotfiles (`.DS_Store`, or `.ts` from an empty name) are skipped.\n */\nexport function isDiscoverableCronFile(fileName: string): boolean {\n return !fileName.startsWith('_') && !fileName.startsWith('.')\n}\n\n/**\n * The cron files {@link scanCronDirs} would import from `dirs`, without importing them. Missing\n * dirs are skipped.\n */\nexport function listCronFiles(dirs: readonly string[]): string[] {\n const filePaths: string[] = []\n for (const dir of dirs) {\n if (!existsSync(dir)) continue\n walkSourceFiles(dir, { extensions: CRON_EXTENSIONS }, (p) => {\n if (isDiscoverableCronFile(basename(p))) filePaths.push(p)\n })\n }\n return filePaths\n}\n\n/**\n * Scan a directory for cron definition files and return the discovered\n * `CronNode[]` sorted by name. Throws `DuplicateCronNameError` on name\n * collision and `Error` on missing default export.\n *\n * Sequential by design — module imports are awaited one-by-one to keep\n * error messages anchored to the file that failed.\n */\nexport async function scanCrons(cronsDir: string): Promise<CronNode[]> {\n return scanCronDirs([cronsDir])\n}\n\n/**\n * Scan MULTIPLE cron directories and merge the results with a UNIFIED\n * duplicate-name guard across all of them. The framework discovers crons in\n * two conventional homes: `server/crons/` (a backend trigger) and\n * `agents/schedules/` (a scheduled agent run — kept in the agent domain). Both\n * feed the same manifest + deploy translation; a name may not collide across\n * the two dirs. Missing dirs are skipped (no error). Nodes are returned sorted\n * by name for a stable manifest.\n */\nexport async function scanCronDirs(dirs: readonly string[]): Promise<CronNode[]> {\n const filePaths = listCronFiles(dirs)\n\n const nodes: CronNode[] = []\n for (const filePath of filePaths) {\n let mod: CronModule\n try {\n mod = await importUserModule(filePath)\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to import cron file \"${filePath}\": ${reason}`)\n }\n const exported = mod.default\n if (!isCronDefinition(exported)) {\n throw new Error(\n `Cron file \"${filePath}\" is missing a valid default export. ` +\n 'Expected `export default defineCron(name, { schedule, handler })`.',\n )\n }\n nodes.push({\n name: exported.name,\n filePath,\n schedule: exported.schedule,\n concurrency: exported.concurrency,\n })\n }\n\n // Dup-name detection (unified across every scanned dir).\n const byName = new Map<string, string[]>()\n for (const node of nodes) {\n const bucket = byName.get(node.name) ?? []\n bucket.push(node.filePath)\n byName.set(node.name, bucket)\n }\n for (const [name, paths] of byName) {\n if (paths.length > 1) {\n throw new DuplicateCronNameError(name, paths)\n }\n }\n\n return nodes.sort((a, b) => compareByCodeUnit(a.name, b.name))\n}\n"],"mappings":";;;;;;;;;;;AAIA,SAAS,kBAAkB;AAC3B,SAAS,UAAU,eAAe;AAoB3B,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAEhD,YACkB,UACA,WAChB;AACA;AAAA,MACE,wBAAwB,QAAQ,iBAAiB,UAAU,KAAK,IAAI,CAAC;AAAA,IAEvE;AANgB;AACA;AAMhB,SAAK,OAAO;AAAA,EACd;AAAA,EARkB;AAAA,EACA;AAAA,EAHT,OAAO;AAWlB;AAEA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAM9D,SAAS,iBAAiB,OAAyC;AACjE,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,SAAS,YACpB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,YAAY,eACtB,IAAI,gBAAgB,YAAY,IAAI,gBAAgB;AAEzD;AAOO,SAAS,aACd,KACA,WACA,WACwD;AACxD,SAAO;AAAA,IACL,OAAO,QAAQ,KAAK,WAAW,OAAO;AAAA,IACtC,WAAW,QAAQ,KAAK,WAAW,WAAW;AAAA,EAChD;AACF;AAMO,SAAS,uBAAuB,UAA2B;AAChE,SAAO,CAAC,SAAS,WAAW,GAAG,KAAK,CAAC,SAAS,WAAW,GAAG;AAC9D;AAMO,SAAS,cAAc,MAAmC;AAC/D,QAAM,YAAsB,CAAC;AAC7B,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,WAAW,GAAG,EAAG;AACtB,oBAAgB,KAAK,EAAE,YAAY,gBAAgB,GAAG,CAAC,MAAM;AAC3D,UAAI,uBAAuB,SAAS,CAAC,CAAC,EAAG,WAAU,KAAK,CAAC;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAuBA,eAAsB,aAAa,MAA8C;AAC/E,QAAM,YAAY,cAAc,IAAI;AAEpC,QAAM,QAAoB,CAAC;AAC3B,aAAW,YAAY,WAAW;AAChC,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,iBAAiB,QAAQ;AAAA,IACvC,SAAS,KAAK;AACZ,YAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,YAAM,IAAI,MAAM,+BAA+B,QAAQ,MAAM,MAAM,EAAE;AAAA,IACvE;AACA,UAAM,WAAW,IAAI;AACrB,QAAI,CAAC,iBAAiB,QAAQ,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,cAAc,QAAQ;AAAA,MAExB;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,MAAM,SAAS;AAAA,MACf;AAAA,MACA,UAAU,SAAS;AAAA,MACnB,aAAa,SAAS;AAAA,IACxB,CAAC;AAAA,EACH;AAGA,QAAM,SAAS,oBAAI,IAAsB;AACzC,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC;AACzC,WAAO,KAAK,KAAK,QAAQ;AACzB,WAAO,IAAI,KAAK,MAAM,MAAM;AAAA,EAC9B;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAClC,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,IAAI,uBAAuB,MAAM,KAAK;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,CAAC,GAAG,MAAM,kBAAkB,EAAE,MAAM,EAAE,IAAI,CAAC;AAC/D;","names":[]}
|
|
@@ -28,12 +28,22 @@ async function importUserModule(absoluteFilePath, parentURL = import.meta.url) {
|
|
|
28
28
|
return await import(fileURL);
|
|
29
29
|
} catch (err) {
|
|
30
30
|
if (!isLoaderInteropError(err)) throw err;
|
|
31
|
-
const
|
|
32
|
-
return await
|
|
31
|
+
const scopedImport = await tsxNamespace();
|
|
32
|
+
return await scopedImport(fileURL, parentURL);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
var namespacedImport;
|
|
36
|
+
function tsxNamespace() {
|
|
37
|
+
namespacedImport ??= (async () => {
|
|
38
|
+
const namespace = `theokit-user-modules-${process.pid}`;
|
|
39
|
+
const [esm, cjs] = await Promise.all([import("tsx/esm/api"), import("tsx/cjs/api")]);
|
|
40
|
+
cjs.register({ namespace });
|
|
41
|
+
return esm.register({ namespace }).import;
|
|
42
|
+
})();
|
|
43
|
+
return namespacedImport;
|
|
44
|
+
}
|
|
35
45
|
|
|
36
46
|
export {
|
|
37
47
|
importUserModule
|
|
38
48
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
49
|
+
//# sourceMappingURL=chunk-O5JZ6ROY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/import-user-module.ts"],"sourcesContent":["/**\n * Helper for loading user-authored TypeScript modules at runtime.\n *\n * Why this exists: theokit framework code (`load-config.ts`, `job-scan.ts`,\n * `cron-scan.ts`, `integrate-ui.ts`, `static.ts`) dynamically imports\n * `.ts` files from user space (`theo.config.ts`, `server/jobs/*.ts`,\n * `static-paths.ts`, etc.). Two execution environments must work:\n *\n * 1. **Production CLI** — `dist/cli/index.js` starts with\n * `import \"tsx/esm\"` which registers a global Node ESM loader hook.\n * Subsequent `await import('foo.ts')` calls are intercepted by the\n * hook, transformed in-place, and returned as ESM namespaces.\n *\n * 2. **Vitest tests** — Vitest runs framework code through Vite's SSR\n * pipeline. Dynamic imports inside framework modules are hijacked\n * by Vite's `loadAndTransform`, which cannot resolve absolute paths\n * outside the Vite project root (e.g., `/tmp/test-fixture/foo.ts`).\n * Even with `server.deps.external` configured to hand the path\n * back to Node, the registered tsx/esm loader hits a `require()`\n * ESM cycle error on Node 22 because the calling stack contains\n * both the loader's own evaluation context AND the importer.\n *\n * A namespaced `register()` from `tsx/esm/api` is the escape hatch for\n * exactly this scenario: it transforms the source file via tsx's\n * standalone pipeline and evaluates the result inside its namespace,\n * bypassing both Vite SSR and any registered global hook.\n *\n * The namespace is registered ONCE per process and reused. `tsImport()`\n * registers a new one on every call and never removes it, so the loader\n * hooks pile up; on Node 22.12 the fourth or fifth load in a process\n * stalled forever. Reusing one namespace means a file already loaded is\n * served from the module cache, which is what the native `import()` above\n * does too.\n *\n * Strategy:\n * - Try native `await import()` first (zero overhead in production\n * where tsx hook is registered).\n * - On failure with the well-known cycle/resolution errors, fall back\n * to `tsImport()`. Other errors (genuine syntax errors, missing\n * module, etc.) propagate unchanged.\n *\n * Idempotent and side-effect-free.\n */\nimport { pathToFileURL } from 'node:url'\n\nconst CYCLE_PATTERNS = [\n // Node 22 strict ESM cycle detection when a registered loader hook\n // re-enters its own evaluation context.\n 'require() ES Module',\n 'in a cycle',\n // Vite SSR throws this when it cannot resolve an out-of-root URL.\n 'Failed to load url',\n 'Does the file exist?',\n // Node native ESM resolver throws this for `.ts` files when no\n // tsx loader is registered globally (the common test-worker case).\n 'Cannot find module',\n // ERR_UNKNOWN_FILE_EXTENSION for `.ts` files.\n 'Unknown file extension',\n]\n\nfunction isLoaderInteropError(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n const msg = err.message\n return CYCLE_PATTERNS.some((p) => msg.includes(p))\n}\n\n/**\n * Load a user-authored TS/JS module at the given absolute file path.\n * `parentURL` defaults to the URL of this module file.\n *\n * @returns module namespace object (matches `await import(...)` return)\n */\nexport async function importUserModule(\n absoluteFilePath: string,\n parentURL: string = import.meta.url,\n): Promise<Record<string, unknown>> {\n const fileURL = pathToFileURL(absoluteFilePath).href\n try {\n return (await import(fileURL)) as Record<string, unknown>\n } catch (err) {\n if (!isLoaderInteropError(err)) throw err\n // Fallback: tsx programmatic API. Imports are scoped to one namespace, no\n // global hook mutation, no Vite SSR interference. Slower than a registered\n // loader, but only used as a last resort.\n //\n // No tsconfig is passed — tsx's default bundler-style resolver handles\n // `.js → .ts` fallback for relative imports under the user's module.\n // Passing an explicit tsconfig sometimes shadows the default and\n // breaks the `.js → .ts` rewrite chain inside the namespaced loader\n // (verified empirically in cron-scan/job-scan vitest workers).\n const scopedImport = await tsxNamespace()\n return (await scopedImport(fileURL, parentURL)) as Record<string, unknown>\n }\n}\n\ntype ScopedImport = (specifier: string, parentURL: string) => Promise<unknown>\n\nlet namespacedImport: Promise<ScopedImport> | undefined\n\n/**\n * The one tsx namespace this process loads user modules through. Registered on first use, with\n * the CommonJS hook beside the ESM one, the same pair `tsImport()` registers per call.\n */\nfunction tsxNamespace(): Promise<ScopedImport> {\n namespacedImport ??= (async () => {\n const namespace = `theokit-user-modules-${process.pid}`\n const [esm, cjs] = await Promise.all([import('tsx/esm/api'), import('tsx/cjs/api')])\n cjs.register({ namespace })\n return esm.register({ namespace }).import\n })()\n return namespacedImport\n}\n"],"mappings":";;;;AA2CA,SAAS,qBAAqB;AAE9B,IAAM,iBAAiB;AAAA;AAAA;AAAA,EAGrB;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA;AACF;AAEA,SAAS,qBAAqB,KAAuB;AACnD,MAAI,EAAE,eAAe,OAAQ,QAAO;AACpC,QAAM,MAAM,IAAI;AAChB,SAAO,eAAe,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;AACnD;AAQA,eAAsB,iBACpB,kBACA,YAAoB,YAAY,KACE;AAClC,QAAM,UAAU,cAAc,gBAAgB,EAAE;AAChD,MAAI;AACF,WAAQ,MAAM,OAAO;AAAA,EACvB,SAAS,KAAK;AACZ,QAAI,CAAC,qBAAqB,GAAG,EAAG,OAAM;AAUtC,UAAM,eAAe,MAAM,aAAa;AACxC,WAAQ,MAAM,aAAa,SAAS,SAAS;AAAA,EAC/C;AACF;AAIA,IAAI;AAMJ,SAAS,eAAsC;AAC7C,wBAAsB,YAAY;AAChC,UAAM,YAAY,wBAAwB,QAAQ,GAAG;AACrD,UAAM,CAAC,KAAK,GAAG,IAAI,MAAM,QAAQ,IAAI,CAAC,OAAO,aAAa,GAAG,OAAO,aAAa,CAAC,CAAC;AACnF,QAAI,SAAS,EAAE,UAAU,CAAC;AAC1B,WAAO,IAAI,SAAS,EAAE,UAAU,CAAC,EAAE;AAAA,EACrC,GAAG;AACH,SAAO;AACT;","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-3QPVEJ7D.js";
|
|
6
6
|
import {
|
|
7
7
|
importUserModule
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-O5JZ6ROY.js";
|
|
9
9
|
import {
|
|
10
10
|
theoConfigSchema
|
|
11
11
|
} from "./chunk-NX3P5MLH.js";
|
|
@@ -110,4 +110,4 @@ export {
|
|
|
110
110
|
deepMerge,
|
|
111
111
|
loadConfig
|
|
112
112
|
};
|
|
113
|
-
//# sourceMappingURL=chunk-
|
|
113
|
+
//# sourceMappingURL=chunk-OZB2TKGJ.js.map
|
|
@@ -33,35 +33,277 @@ function createWorkflowTool(workflow, config) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// src/server/agent/acp-tool.ts
|
|
36
|
+
import { resolve } from "node:path";
|
|
37
|
+
import { AcpClient, AcpConnectionClosedError, AcpProtocolError } from "@theokit/agents";
|
|
38
|
+
|
|
39
|
+
// src/server/agent/node-acp-transport.ts
|
|
36
40
|
import { spawn } from "node:child_process";
|
|
37
|
-
|
|
41
|
+
var AcpTransportClosedError = class extends Error {
|
|
42
|
+
constructor(command, reason, options) {
|
|
43
|
+
super(`[theokit] createACPTool: the agent process "${command}" ${reason}`, options);
|
|
44
|
+
this.command = command;
|
|
45
|
+
this.reason = reason;
|
|
46
|
+
}
|
|
47
|
+
command;
|
|
48
|
+
reason;
|
|
49
|
+
name = "AcpTransportClosedError";
|
|
50
|
+
};
|
|
51
|
+
var SIGTERM_GRACE_MS = 2e3;
|
|
52
|
+
var SIGKILL_WAIT_MS = 2e3;
|
|
53
|
+
var GROUP_POLL_MS = 20;
|
|
54
|
+
var OWN_PROCESS_GROUP = process.platform !== "win32";
|
|
38
55
|
var NodeAcpTransport = class {
|
|
39
|
-
// stdin=pipe, stdout=pipe, stderr=inherit → the third stream is null.
|
|
40
|
-
proc;
|
|
41
56
|
constructor(command, args = [], cwd) {
|
|
42
|
-
this.
|
|
57
|
+
this.command = command;
|
|
58
|
+
this.proc = spawn(command, args, {
|
|
59
|
+
cwd,
|
|
60
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
61
|
+
detached: OWN_PROCESS_GROUP
|
|
62
|
+
});
|
|
63
|
+
this.proc.stdout.setEncoding("utf8");
|
|
64
|
+
this.exited = new Promise((resolve2) => {
|
|
65
|
+
this.proc.once("exit", () => {
|
|
66
|
+
resolve2();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
this.proc.on("error", (err) => {
|
|
70
|
+
this.end(`failed: ${err.message}`, err);
|
|
71
|
+
});
|
|
72
|
+
this.proc.stdin.on("error", (err) => {
|
|
73
|
+
this.end(`closed its stdin: ${err.message}`, err);
|
|
74
|
+
});
|
|
75
|
+
this.proc.on("close", (code, signal) => {
|
|
76
|
+
this.end(code === null ? `exited on signal ${String(signal)}` : `exited with code ${code}`);
|
|
77
|
+
});
|
|
43
78
|
}
|
|
79
|
+
command;
|
|
80
|
+
// stdin=pipe, stdout=pipe, stderr=inherit → the third stream is null.
|
|
81
|
+
proc;
|
|
82
|
+
closed;
|
|
83
|
+
listeners = [];
|
|
84
|
+
/** Settles when the process has exited (or never started). */
|
|
85
|
+
exited;
|
|
44
86
|
send(line) {
|
|
45
|
-
this.proc.stdin.write(line);
|
|
87
|
+
if (this.closed === void 0) this.proc.stdin.write(line);
|
|
46
88
|
}
|
|
47
89
|
subscribe(onData) {
|
|
48
|
-
this.proc.stdout.on("data",
|
|
49
|
-
|
|
90
|
+
this.proc.stdout.on("data", onData);
|
|
91
|
+
}
|
|
92
|
+
onClose(listener) {
|
|
93
|
+
if (this.closed !== void 0) listener(this.closed);
|
|
94
|
+
else this.listeners.push(listener);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* End the channel and the process, and settle once the process and its group have exited:
|
|
98
|
+
* SIGTERM first, then SIGKILL for anything still running after {@link SIGTERM_GRACE_MS}.
|
|
99
|
+
*/
|
|
100
|
+
async close() {
|
|
101
|
+
this.end("was closed by the caller");
|
|
102
|
+
try {
|
|
103
|
+
if (!this.running() && !this.groupAlive()) return;
|
|
104
|
+
this.signal("SIGTERM");
|
|
105
|
+
if (await this.goneWithin(SIGTERM_GRACE_MS)) return;
|
|
106
|
+
this.signal("SIGKILL");
|
|
107
|
+
await this.goneWithin(SIGKILL_WAIT_MS);
|
|
108
|
+
} finally {
|
|
109
|
+
this.proc.stdin.destroy();
|
|
110
|
+
this.proc.stdout.destroy();
|
|
111
|
+
this.proc.unref();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Whether the process started and has not exited yet. */
|
|
115
|
+
running() {
|
|
116
|
+
return this.proc.pid !== void 0 && this.proc.exitCode === null && this.proc.signalCode === null;
|
|
117
|
+
}
|
|
118
|
+
/** Whether a process of the agent's group is still running (always `false` without a group). */
|
|
119
|
+
groupAlive() {
|
|
120
|
+
const pid = this.proc.pid;
|
|
121
|
+
if (!OWN_PROCESS_GROUP || pid === void 0) return false;
|
|
122
|
+
try {
|
|
123
|
+
process.kill(-pid, 0);
|
|
124
|
+
return true;
|
|
125
|
+
} catch (err) {
|
|
126
|
+
return err.code === "EPERM";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** Send `signal` to the agent's process group, or to the spawned process without one. */
|
|
130
|
+
signal(signal) {
|
|
131
|
+
const pid = this.proc.pid;
|
|
132
|
+
if (!OWN_PROCESS_GROUP || pid === void 0) {
|
|
133
|
+
this.proc.kill(signal);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
process.kill(-pid, signal);
|
|
138
|
+
} catch (err) {
|
|
139
|
+
if (err.code !== "ESRCH") throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** Wait up to `ms` for the process and every process of its group to exit; `true` when they did. */
|
|
143
|
+
async goneWithin(ms) {
|
|
144
|
+
const deadline = Date.now() + ms;
|
|
145
|
+
if (!await this.exitsWithin(ms)) return false;
|
|
146
|
+
while (this.groupAlive()) {
|
|
147
|
+
if (Date.now() >= deadline) return false;
|
|
148
|
+
await new Promise((resolve2) => setTimeout(resolve2, GROUP_POLL_MS));
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
/** Wait up to `ms` for the process to exit; `true` when it did. */
|
|
153
|
+
async exitsWithin(ms) {
|
|
154
|
+
let timer;
|
|
155
|
+
const elapsed = new Promise((resolve2) => {
|
|
156
|
+
timer = setTimeout(() => {
|
|
157
|
+
resolve2(false);
|
|
158
|
+
}, ms);
|
|
50
159
|
});
|
|
160
|
+
try {
|
|
161
|
+
return await Promise.race([this.exited.then(() => true), elapsed]);
|
|
162
|
+
} finally {
|
|
163
|
+
clearTimeout(timer);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Record the first way the channel ended and tell every listener; later endings are ignored. */
|
|
167
|
+
end(reason, cause) {
|
|
168
|
+
if (this.closed !== void 0) return;
|
|
169
|
+
const error = new AcpTransportClosedError(this.command, reason, { cause });
|
|
170
|
+
this.closed = error;
|
|
171
|
+
for (const listener of this.listeners.splice(0)) listener(error);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// src/server/agent/acp-tool.ts
|
|
176
|
+
var AcpRequestTimeoutError = class extends Error {
|
|
177
|
+
constructor(command, method, timeoutMs) {
|
|
178
|
+
super(
|
|
179
|
+
`[theokit] createACPTool: the agent "${command}" did not answer ${method} within ${String(timeoutMs)}ms`
|
|
180
|
+
);
|
|
181
|
+
this.command = command;
|
|
182
|
+
this.method = method;
|
|
183
|
+
this.timeoutMs = timeoutMs;
|
|
51
184
|
}
|
|
52
|
-
|
|
53
|
-
|
|
185
|
+
command;
|
|
186
|
+
method;
|
|
187
|
+
timeoutMs;
|
|
188
|
+
name = "AcpRequestTimeoutError";
|
|
189
|
+
};
|
|
190
|
+
var STOP_REASON_MEANING = {
|
|
191
|
+
max_tokens: "it reached its token limit",
|
|
192
|
+
max_turn_requests: "it reached its limit of model requests in one turn",
|
|
193
|
+
refusal: "it refused to continue",
|
|
194
|
+
cancelled: "it cancelled the turn"
|
|
195
|
+
};
|
|
196
|
+
var AcpTurnStoppedError = class extends Error {
|
|
197
|
+
constructor(command, stopReason, partialText) {
|
|
198
|
+
const meaning = STOP_REASON_MEANING[stopReason] ?? "a stop reason this client does not know";
|
|
199
|
+
super(
|
|
200
|
+
`[theokit] createACPTool: the agent "${command}" stopped the turn before finishing it, with stopReason "${stopReason}" (${meaning}); the ${String(partialText.length)} characters it streamed are on the error's partialText`
|
|
201
|
+
);
|
|
202
|
+
this.command = command;
|
|
203
|
+
this.stopReason = stopReason;
|
|
204
|
+
this.partialText = partialText;
|
|
54
205
|
}
|
|
206
|
+
command;
|
|
207
|
+
stopReason;
|
|
208
|
+
partialText;
|
|
209
|
+
name = "AcpTurnStoppedError";
|
|
55
210
|
};
|
|
211
|
+
var DEFAULT_ACP_TIMEOUT_MS = 6e5;
|
|
56
212
|
function defaultTransport(config) {
|
|
57
213
|
return new NodeAcpTransport(config.command, config.args, config.cwd);
|
|
58
214
|
}
|
|
215
|
+
var ACP_PROTOCOL_VERSION = 1;
|
|
216
|
+
function isRecord(value) {
|
|
217
|
+
return typeof value === "object" && value !== null;
|
|
218
|
+
}
|
|
219
|
+
function toAcpPermissionResponse(params, decision) {
|
|
220
|
+
const options = isRecord(params) && Array.isArray(params.options) ? params.options : [];
|
|
221
|
+
const wanted = decision.granted ? ["allow_once"] : ["reject_once", "reject_always"];
|
|
222
|
+
for (const kind of wanted) {
|
|
223
|
+
const option = options.find((o) => isRecord(o) && o.kind === kind);
|
|
224
|
+
if (isRecord(option) && typeof option.optionId === "string") {
|
|
225
|
+
return { outcome: { outcome: "selected", optionId: option.optionId } };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return { outcome: { outcome: "cancelled" } };
|
|
229
|
+
}
|
|
230
|
+
function agentTextChunk(params, sessionId) {
|
|
231
|
+
if (!isRecord(params) || params.sessionId !== sessionId || !isRecord(params.update))
|
|
232
|
+
return void 0;
|
|
233
|
+
const { sessionUpdate, content } = params.update;
|
|
234
|
+
if (sessionUpdate !== "agent_message_chunk" || !isRecord(content)) return void 0;
|
|
235
|
+
return content.type === "text" && typeof content.text === "string" ? content.text : void 0;
|
|
236
|
+
}
|
|
237
|
+
function stepFailure(method, cause) {
|
|
238
|
+
if (cause instanceof AcpConnectionClosedError) {
|
|
239
|
+
return cause.cause instanceof Error ? cause.cause : cause;
|
|
240
|
+
}
|
|
241
|
+
if (cause instanceof AcpProtocolError) return cause;
|
|
242
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
243
|
+
return new Error(`[theokit] createACPTool: the agent refused ${method}: ${reason}`, { cause });
|
|
244
|
+
}
|
|
245
|
+
async function step(turn, method, params) {
|
|
246
|
+
turn.signal?.throwIfAborted();
|
|
247
|
+
let timer;
|
|
248
|
+
try {
|
|
249
|
+
return await new Promise((resolve2, reject) => {
|
|
250
|
+
turn.abort = reject;
|
|
251
|
+
timer = setTimeout(() => {
|
|
252
|
+
reject(new AcpRequestTimeoutError(turn.command, method, turn.timeoutMs));
|
|
253
|
+
}, turn.timeoutMs);
|
|
254
|
+
turn.client.request(method, params).then(resolve2).catch((cause) => {
|
|
255
|
+
reject(stepFailure(method, cause));
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
} finally {
|
|
259
|
+
clearTimeout(timer);
|
|
260
|
+
turn.abort = void 0;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function sessionIdOf(created) {
|
|
264
|
+
if (isRecord(created) && typeof created.sessionId === "string") return created.sessionId;
|
|
265
|
+
throw new Error(
|
|
266
|
+
`[theokit] createACPTool: the agent refused session/new: returned no sessionId (got ${JSON.stringify(created)})`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
function stopReasonOf(result) {
|
|
270
|
+
if (isRecord(result) && typeof result.stopReason === "string") return result.stopReason;
|
|
271
|
+
throw new Error(
|
|
272
|
+
`[theokit] createACPTool: the agent refused session/prompt: returned no stopReason (got ${JSON.stringify(result)})`
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
async function runTurn(turn, cwd, message) {
|
|
276
|
+
const updates = [];
|
|
277
|
+
turn.client.onNotification("session/update", (params) => {
|
|
278
|
+
updates.push(params);
|
|
279
|
+
});
|
|
280
|
+
await step(turn, "initialize", {
|
|
281
|
+
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
282
|
+
clientCapabilities: {}
|
|
283
|
+
});
|
|
284
|
+
const sessionId = sessionIdOf(await step(turn, "session/new", { cwd, mcpServers: [] }));
|
|
285
|
+
const result = await step(turn, "session/prompt", {
|
|
286
|
+
sessionId,
|
|
287
|
+
prompt: [{ type: "text", text: message }]
|
|
288
|
+
});
|
|
289
|
+
const stopReason = stopReasonOf(result);
|
|
290
|
+
const texts = updates.map((params) => agentTextChunk(params, sessionId));
|
|
291
|
+
const reply = texts.filter((text) => text !== void 0).join("");
|
|
292
|
+
if (stopReason !== "end_turn") throw new AcpTurnStoppedError(turn.command, stopReason, reply);
|
|
293
|
+
return reply;
|
|
294
|
+
}
|
|
59
295
|
function createACPTool(config) {
|
|
60
296
|
if (typeof config.onPermissionRequest !== "function") {
|
|
61
297
|
throw new Error(
|
|
62
298
|
"[theokit] createACPTool requires onPermissionRequest (security by default \u2014 no default-allow)"
|
|
63
299
|
);
|
|
64
300
|
}
|
|
301
|
+
const timeoutMs = config.timeoutMs ?? DEFAULT_ACP_TIMEOUT_MS;
|
|
302
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
303
|
+
throw new RangeError(
|
|
304
|
+
`[theokit] createACPTool: timeoutMs must be a positive finite number of milliseconds (got ${String(timeoutMs)})`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
65
307
|
const makeTransport = config.transportFactory ?? defaultTransport;
|
|
66
308
|
return {
|
|
67
309
|
name: config.name,
|
|
@@ -73,12 +315,30 @@ function createACPTool(config) {
|
|
|
73
315
|
},
|
|
74
316
|
required: ["message"]
|
|
75
317
|
},
|
|
76
|
-
handler: async (input) => {
|
|
318
|
+
handler: async (input, ctx) => {
|
|
77
319
|
const message = typeof input.message === "string" ? input.message : "";
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
320
|
+
const signal = ctx?.signal;
|
|
321
|
+
signal?.throwIfAborted();
|
|
322
|
+
const transport = makeTransport(config);
|
|
323
|
+
let onAbort;
|
|
324
|
+
try {
|
|
325
|
+
const turn = {
|
|
326
|
+
client: new AcpClient(transport),
|
|
327
|
+
command: config.command,
|
|
328
|
+
timeoutMs,
|
|
329
|
+
signal
|
|
330
|
+
};
|
|
331
|
+
onAbort = () => turn.abort?.(signal?.reason);
|
|
332
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
333
|
+
turn.client.onRequest(
|
|
334
|
+
"session/request_permission",
|
|
335
|
+
async (params) => toAcpPermissionResponse(params, await config.onPermissionRequest(params))
|
|
336
|
+
);
|
|
337
|
+
return await runTurn(turn, resolve(config.cwd ?? process.cwd()), message);
|
|
338
|
+
} finally {
|
|
339
|
+
if (onAbort !== void 0) signal?.removeEventListener("abort", onAbort);
|
|
340
|
+
await transport.close?.();
|
|
341
|
+
}
|
|
82
342
|
}
|
|
83
343
|
};
|
|
84
344
|
}
|
|
@@ -295,7 +555,11 @@ async function serveMcpStdio(mod, name, appResources, streams) {
|
|
|
295
555
|
|
|
296
556
|
export {
|
|
297
557
|
createWorkflowTool,
|
|
558
|
+
AcpTransportClosedError,
|
|
298
559
|
NodeAcpTransport,
|
|
560
|
+
AcpRequestTimeoutError,
|
|
561
|
+
AcpTurnStoppedError,
|
|
562
|
+
DEFAULT_ACP_TIMEOUT_MS,
|
|
299
563
|
createACPTool,
|
|
300
564
|
createVendorAgentTool,
|
|
301
565
|
CodeModePermissionDeniedError,
|
|
@@ -308,4 +572,4 @@ export {
|
|
|
308
572
|
streamAgentTurnInProcess,
|
|
309
573
|
InProcessApprovalRequiredError
|
|
310
574
|
};
|
|
311
|
-
//# sourceMappingURL=chunk-
|
|
575
|
+
//# sourceMappingURL=chunk-RAUYMVUO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/agent/workflow-tool.ts","../src/server/agent/acp-tool.ts","../src/server/agent/node-acp-transport.ts","../src/server/agent/vendor-agent-tool.ts","../src/server/agent/code-mode.ts","../src/server/agent/channel-webhook.ts","../src/server/agent/index.ts","../src/server/agent/mcp-stdio.ts"],"mappings":"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","names":["resolve","resolve","tool"]}
|