theokit 0.54.0 → 0.55.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-FGJR3I7V.js → actions-virtual-module-PREAJNIS.js} +3 -3
- package/dist/{actions-virtual-module-M4MTKOAX.js → actions-virtual-module-TZFLCIIR.js} +2 -2
- package/dist/{agent-TKCC4WZ6.js → agent-2AELELAC.js} +2 -2
- package/dist/{app-typed-client-6MNNVMJU.js → app-typed-client-KSFGMOQ6.js} +3 -3
- package/dist/{app-typed-client-22BZ3KDX.js → app-typed-client-NEKRXPAQ.js} +2 -2
- package/dist/{build-JH53TZJI.js → build-ESSQS5F5.js} +4 -3
- package/dist/build-ESSQS5F5.js.map +1 -0
- package/dist/{chunk-SIGUGCBS.js → chunk-2PSKQWGM.js} +2 -2
- package/dist/{chunk-DAE7BJ7H.js → chunk-3DRALT3J.js} +2 -2
- package/dist/{chunk-IHAQUUT2.js → chunk-DADMEW4G.js} +1 -1
- package/dist/chunk-DADMEW4G.js.map +1 -0
- package/dist/{chunk-S6RWUH3J.js → chunk-F6P6S5YS.js} +7 -7
- package/dist/{chunk-AI7GBBRB.js → chunk-GWE4MUKQ.js} +2 -2
- package/dist/{chunk-FVFYACYK.js → chunk-ITSNTHWN.js} +1 -1
- package/dist/chunk-ITSNTHWN.js.map +1 -0
- package/dist/{chunk-6VYF5PMG.js → chunk-QZUIF64G.js} +2 -2
- package/dist/{chunk-HLDXHDCB.js → chunk-VRELW5NF.js} +7 -7
- package/dist/cli/index.js +6 -6
- package/dist/client/index.d.ts +26 -4
- package/dist/client/index.js.map +1 -1
- package/dist/{config-support-WQHQIJTA.js → config-support-O4REYSK5.js} +32 -1
- package/dist/{config-support-WQHQIJTA.js.map → config-support-O4REYSK5.js.map} +1 -1
- package/dist/{dev-6KDYNF5E.js → dev-MWGPBGQP.js} +4 -4
- package/dist/index.js +3 -3
- package/dist/{internal-api-VUDJUWYE.js → internal-api-J3BYA3VU.js} +3 -3
- package/dist/{internal-api-TA37BXH7.js → internal-api-XSUP3NDI.js} +2 -2
- package/dist/{mcp-2RQCKWQR.js → mcp-6IPY275L.js} +2 -2
- package/dist/{preview-J57QZNTO.js → preview-KPAKWBRW.js} +3 -3
- package/dist/server/http/index.js +2 -2
- package/dist/server/index.js +2 -2
- package/dist/{server-boundary-4UIGB3G5.js → server-boundary-7ZO4FZIV.js} +3 -3
- package/dist/{server-boundary-A2PUD4JV.js → server-boundary-PGPFBJBH.js} +2 -2
- package/dist/{start-3F4LVHWS.js → start-F3T2ZPPI.js} +3 -3
- package/dist/vite-plugin/index.js +3 -3
- package/dist/{vite-plugin-VYNUCEI2.js → vite-plugin-5O3D472R.js} +4 -4
- package/package.json +1 -1
- package/dist/build-JH53TZJI.js.map +0 -1
- package/dist/chunk-FVFYACYK.js.map +0 -1
- package/dist/chunk-IHAQUUT2.js.map +0 -1
- /package/dist/{actions-virtual-module-FGJR3I7V.js.map → actions-virtual-module-PREAJNIS.js.map} +0 -0
- /package/dist/{actions-virtual-module-M4MTKOAX.js.map → actions-virtual-module-TZFLCIIR.js.map} +0 -0
- /package/dist/{agent-TKCC4WZ6.js.map → agent-2AELELAC.js.map} +0 -0
- /package/dist/{app-typed-client-6MNNVMJU.js.map → app-typed-client-KSFGMOQ6.js.map} +0 -0
- /package/dist/{app-typed-client-22BZ3KDX.js.map → app-typed-client-NEKRXPAQ.js.map} +0 -0
- /package/dist/{chunk-SIGUGCBS.js.map → chunk-2PSKQWGM.js.map} +0 -0
- /package/dist/{chunk-DAE7BJ7H.js.map → chunk-3DRALT3J.js.map} +0 -0
- /package/dist/{chunk-S6RWUH3J.js.map → chunk-F6P6S5YS.js.map} +0 -0
- /package/dist/{chunk-AI7GBBRB.js.map → chunk-GWE4MUKQ.js.map} +0 -0
- /package/dist/{chunk-6VYF5PMG.js.map → chunk-QZUIF64G.js.map} +0 -0
- /package/dist/{chunk-HLDXHDCB.js.map → chunk-VRELW5NF.js.map} +0 -0
- /package/dist/{dev-6KDYNF5E.js.map → dev-MWGPBGQP.js.map} +0 -0
- /package/dist/{internal-api-VUDJUWYE.js.map → internal-api-J3BYA3VU.js.map} +0 -0
- /package/dist/{internal-api-TA37BXH7.js.map → internal-api-XSUP3NDI.js.map} +0 -0
- /package/dist/{mcp-2RQCKWQR.js.map → mcp-6IPY275L.js.map} +0 -0
- /package/dist/{preview-J57QZNTO.js.map → preview-KPAKWBRW.js.map} +0 -0
- /package/dist/{server-boundary-4UIGB3G5.js.map → server-boundary-7ZO4FZIV.js.map} +0 -0
- /package/dist/{server-boundary-A2PUD4JV.js.map → server-boundary-PGPFBJBH.js.map} +0 -0
- /package/dist/{start-3F4LVHWS.js.map → start-F3T2ZPPI.js.map} +0 -0
- /package/dist/{vite-plugin-VYNUCEI2.js.map → vite-plugin-5O3D472R.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-3DRALT3J.js";
|
|
2
2
|
import "./chunk-WX6NHGKS.js";
|
|
3
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-ITSNTHWN.js";
|
|
4
4
|
import "./chunk-ZDUO4IYN.js";
|
|
5
5
|
import "./chunk-47FFT43U.js";
|
|
6
6
|
import "./chunk-NTDN54XO.js";
|
|
@@ -234,4 +234,4 @@ export const actions = manifest
|
|
|
234
234
|
export {
|
|
235
235
|
actionsVirtualModule
|
|
236
236
|
};
|
|
237
|
-
//# sourceMappingURL=actions-virtual-module-
|
|
237
|
+
//# sourceMappingURL=actions-virtual-module-PREAJNIS.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "tsx/esm";
|
|
3
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-DADMEW4G.js";
|
|
4
4
|
import "./chunk-5YPXXSYY.js";
|
|
5
5
|
import "./chunk-MWWFXYW3.js";
|
|
6
6
|
import "./chunk-RPET332G.js";
|
|
@@ -218,4 +218,4 @@ export const actions = manifest
|
|
|
218
218
|
export {
|
|
219
219
|
actionsVirtualModule
|
|
220
220
|
};
|
|
221
|
-
//# sourceMappingURL=actions-virtual-module-
|
|
221
|
+
//# sourceMappingURL=actions-virtual-module-TZFLCIIR.js.map
|
|
@@ -3,7 +3,7 @@ import "tsx/esm";
|
|
|
3
3
|
import {
|
|
4
4
|
agentCommand,
|
|
5
5
|
createAgentSsrLoader
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2PSKQWGM.js";
|
|
7
7
|
import "./chunk-5YPXXSYY.js";
|
|
8
8
|
import "./chunk-5NNFO7R7.js";
|
|
9
9
|
import "./chunk-Z7CJHDLS.js";
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
agentCommand,
|
|
13
13
|
createAgentSsrLoader
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=agent-
|
|
15
|
+
//# sourceMappingURL=agent-2AELELAC.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
scanControllerModules
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3DRALT3J.js";
|
|
4
4
|
import "./chunk-WX6NHGKS.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-ITSNTHWN.js";
|
|
6
6
|
import "./chunk-ZDUO4IYN.js";
|
|
7
7
|
import "./chunk-47FFT43U.js";
|
|
8
8
|
import "./chunk-NTDN54XO.js";
|
|
@@ -427,4 +427,4 @@ export {
|
|
|
427
427
|
generateClientDts,
|
|
428
428
|
shouldReemitForFile
|
|
429
429
|
};
|
|
430
|
-
//# sourceMappingURL=app-typed-client-
|
|
430
|
+
//# sourceMappingURL=app-typed-client-KSFGMOQ6.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "tsx/esm";
|
|
3
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-DADMEW4G.js";
|
|
4
4
|
import "./chunk-5YPXXSYY.js";
|
|
5
5
|
import {
|
|
6
6
|
scanControllerModules
|
|
@@ -411,4 +411,4 @@ export {
|
|
|
411
411
|
generateClientDts,
|
|
412
412
|
shouldReemitForFile
|
|
413
413
|
};
|
|
414
|
-
//# sourceMappingURL=app-typed-client-
|
|
414
|
+
//# sourceMappingURL=app-typed-client-NEKRXPAQ.js.map
|
|
@@ -554,7 +554,7 @@ async function buildCommand(options) {
|
|
|
554
554
|
`);
|
|
555
555
|
}
|
|
556
556
|
async function runAdapterBuild(target, config, cwd) {
|
|
557
|
-
const { theoPluginAsync } = await import("./vite-plugin-
|
|
557
|
+
const { theoPluginAsync } = await import("./vite-plugin-5O3D472R.js");
|
|
558
558
|
const { default: react } = await import("@vitejs/plugin-react");
|
|
559
559
|
const ctx = {
|
|
560
560
|
// `react()` may return Plugin or Plugin[] depending on version; spread the
|
|
@@ -605,7 +605,8 @@ async function runAdapterBuild(target, config, cwd) {
|
|
|
605
605
|
};
|
|
606
606
|
const { resolveAdapter } = await import("./registry-KBZDCFVQ.js");
|
|
607
607
|
const adapter = await resolveAdapter(target);
|
|
608
|
-
const { warnUnappliedConfig } = await import("./config-support-
|
|
608
|
+
const { warnUnappliedConfig, assertRateLimitEnforceable } = await import("./config-support-O4REYSK5.js");
|
|
609
|
+
assertRateLimitEnforceable(config, adapter, target);
|
|
609
610
|
warnUnappliedConfig(config, adapter, target, (message) => {
|
|
610
611
|
console.log(message);
|
|
611
612
|
});
|
|
@@ -675,4 +676,4 @@ function relativize3(absPath, root) {
|
|
|
675
676
|
export {
|
|
676
677
|
buildCommand
|
|
677
678
|
};
|
|
678
|
-
//# sourceMappingURL=build-
|
|
679
|
+
//# sourceMappingURL=build-ESSQS5F5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/build.ts","../src/adapters/types.ts","../src/server/cron/adapter-translators.ts","../src/server/_internal/atomic-write.ts","../src/server/cron/cron-manifest.ts","../src/server/cron/cron-scan.ts","../src/server/jobs/job-manifest.ts","../src/server/jobs/job-scan.ts","../src/cli/cleanup/cleanup.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, relative, resolve, sep } from 'node:path'\n\n// T1.1 (architecture-medium-deferrals) — nodeAdapter no longer static-imported.\n// All adapters dispatch via `adapterRegistry` (lazy-imported within runAdapterBuild).\nimport { VALID_TARGETS, type BuildTarget, type AdapterBuildContext } from '../../adapters/types.js'\nimport { loadConfig } from '../../config/load-config.js'\nimport { loadEnv } from '../../config/load-env.js'\nimport { validateProjectStructure } from '../../config/validate-structure.js'\nimport {\n ExistingConfigUnparseableError,\n translateCronToAws,\n translateCronToCloudflare,\n translateCronToDeno,\n translateCronToVercel,\n} from '../../server/cron/adapter-translators.js'\nimport { writeCronManifest } from '../../server/cron/cron-manifest.js'\nimport { scanCronDirs } from '../../server/cron/cron-scan.js'\nimport { writeJobManifest } from '../../server/jobs/job-manifest.js'\nimport { scanJobs } from '../../server/jobs/job-scan.js'\nimport { scanAgents } from '../../server/scan/agent-scan.js'\nimport { generateManifest, writeManifest } from '../../server/scan/manifest.js'\nimport { scanServerRoutes } from '../../server/scan/scan.js'\nimport { scanWebSocketRoutes } from '../../server/scan/ws-scan.js'\nimport {\n buildManifest as buildServicesManifest,\n writeManifest as writeServicesManifest,\n} from '../../services/index.js'\n// G2 T2.2 — OpenAPI emit. Opt-in via `config.openapi`. Dual output:\n// 1. <distDir>/openapi.json (pre-Vite, dev surface + manifests sibling)\n// 2. dist/openapi.json (post-Vite, build artifact)\n// The dist emit awaits runAdapterBuild — if Vite fails, the second emit\n// never runs (EC-2 absorbed: no stale dist artifact).\nimport { emitOpenApi } from '../../vite-plugin/openapi-emit/emit.js'\nimport { loadRoutesForOpenApi } from '../../vite-plugin/openapi-emit/load-routes.js'\nimport { cleanOutDir } from '../cleanup/cleanup.js'\nimport { preflightNodeAndBindings } from '../preflight-node-version.js'\n\nimport { describeControllerArtifacts, emitControllerArtifacts } from './build/emit-controllers.js'\n\n// Adapters that do NOT support cron triggers natively. Build still\n// succeeds with crons declared, but emits a warning + skip note.\nconst CRON_NA_TARGETS = new Set<BuildTarget>(['bun', 'netlify', 'static'])\n\n// DERIVED, never restated. A hand-written list here went stale and told users\n// that three working targets were unsupported: it named node/vercel/cloudflare\n// while aws-lambda, deno-deploy and theo-cloud also translate crons. Deriving\n// from the two constants means adding a target cannot desynchronise the message.\nconst CRON_SUPPORTED_TARGETS = VALID_TARGETS.filter((t) => !CRON_NA_TARGETS.has(t))\n\nexport async function buildCommand(options?: { target?: string }): Promise<void> {\n const cwd = process.cwd()\n // Preflight (FIRST — BEFORE anything that touches native bindings).\n preflightNodeAndBindings(cwd)\n // Phase 1 (T1.2) — Load .env BEFORE config load.\n loadEnv({ cwd, mode: 'production' })\n\n const config = await loadConfig(cwd)\n // #95 — honor config.appDir so a custom frontend dir (e.g. apps/web) passes the structure gate.\n validateProjectStructure(cwd, config.appDir)\n\n // T2.2 — Clean .theokit/ at build start (Astro pattern). Skip .git*.\n const distDirAbs = resolve(cwd, config.distDir)\n await cleanOutDir({ dir: distDirAbs })\n\n const target = (options?.target ?? 'node') as BuildTarget\n\n if (!VALID_TARGETS.includes(target)) {\n throw new Error(\n `Invalid build target \"${target}\". Available targets: ${VALID_TARGETS.join(', ')}`,\n )\n }\n\n // EC-201 — cross-reference note when config.adapters[] diverges from\n // the --target flag. --target is authoritative per ADR D2.\n const configAdapters = (config as { adapters?: readonly string[] }).adapters\n if (configAdapters && configAdapters.length > 0) {\n const otherAdapters = configAdapters.filter((a) => a !== target)\n if (otherAdapters.length > 0) {\n console.log(\n `\\n Note: theo.config.ts.adapters lists [${otherAdapters.join(', ')}]; ` +\n `this build translates for ${target} only. ` +\n `Run \\`theokit build --target=<adapter>\\` separately for each (cross-reference).`,\n )\n }\n }\n\n console.log(`\\n Building for ${target}...\\n`)\n\n // Manifests emit BEFORE adapter bundling (Vite). Why: manifests are\n // fast + deterministic + don't depend on Vite. If Vite fails (missing\n // dep, malformed entry), the user still gets manifests for diagnostics.\n const serverDir = resolve(cwd, config.serverDir)\n const distDir = distDirAbs\n // #95 follow-up — pass projectRoot (cwd) + config.agentsDir so agents scan honors a custom dir.\n const manifest = generateManifest(serverDir, cwd, config.agentsDir)\n writeManifest(manifest, distDir)\n\n const totalEndpoints =\n manifest.routes.length + manifest.actions.length + manifest.websockets.length\n console.log(\n ` ✓ Manifest: ${manifest.routes.length} routes, ${manifest.actions.length} actions, ${manifest.websockets.length} ws (${totalEndpoints} total)`,\n )\n\n // T1.1 — cron scan + manifest + per-target adapter translation\n await emitCronArtifacts({ cwd, serverDir, agentsDir: config.agentsDir, distDir, target })\n\n // T1.2 — job scan + manifest (no per-target translation needed)\n await emitJobArtifacts({ cwd, serverDir, distDir })\n\n // theokit#123 — compile `server/controllers/**` so `theokit start` can serve them.\n //\n // #122 made controllers first-class in dev, where Vite's swc transform compiles them on the fly.\n // Production has neither, so an uncompiled `.controller.ts` cannot load and its routes 404'd —\n // working in dev and failing in prod, which is the worst place for a gap to live.\n //\n // Deliberately NOT folded into `generateManifest` (ADR-5): the manifest is the deploy-adapter\n // contract, and a parallel route source in it would ripple through every adapter. This writes a\n // separate artifact only the Node start path reads. No controllers ⇒ no artifact at all.\n const controllerManifest = await emitControllerArtifacts({ serverDir, distDir })\n if (controllerManifest !== null) {\n console.log(` ${describeControllerArtifacts(controllerManifest)}`)\n }\n\n // Wave 2 (T1.2) — services manifest at <cwd>/.theokit/services.json. Always\n // emit (empty array when services: {} is empty) so adapters can rely on\n // the file existing. Topological order preserved by buildServicesManifest.\n //\n // Plan v1.2 T2.1 — when theo.config.ts declares `name`, emit services.json\n // v2 with that project identifier. Falling back to v1 (no project field)\n // keeps TheoCloud's deprecation warning path intact (services-bundle).\n const projectName = config.name\n const servicesManifest = buildServicesManifest(config.services, projectName)\n writeServicesManifest(cwd, servicesManifest)\n if (servicesManifest.services.length > 0) {\n const versionLabel = `v${String(servicesManifest.version)}`\n const projectLabel =\n servicesManifest.version === 2 ? ` project=\"${servicesManifest.project}\"` : ''\n console.log(\n ` ✓ Services manifest (${versionLabel}${projectLabel}): ${String(servicesManifest.services.length)} service(s) ` +\n `(${servicesManifest.services.map((s) => s.name).join(', ')})`,\n )\n } else if (servicesManifest.version === 1) {\n console.log(\n ' ⚠ services.json emitted as v1 (no `name` in theo.config.ts). ' +\n 'TheoCloud will accept this with a deprecation warning; sunset in theokit 0.6.0. ' +\n 'Run `theokit migrate services-json-v1-to-v2` to upgrade.',\n )\n }\n\n // G2 T2.2 — OpenAPI dev-surface emit (pre-Vite, sibling of manifests).\n // Opt-in: only when config.openapi is defined. Best-effort: a route load\n // failure produces a warning, not a build abort.\n if (config.openapi !== undefined) {\n const hydrated = await loadRoutesForOpenApi({ serverDir, routes: manifest.routes })\n const devResult = emitOpenApi({\n manifest: hydrated,\n config: { ...config.openapi, outDir: distDir },\n })\n console.log(` ✓ OpenAPI: ${String(hydrated.length)} ops → ${devResult.path}`)\n }\n\n // Now run the adapter-specific bundling (Vite + adapter-specific work).\n await runAdapterBuild(target, config, cwd)\n\n // G2 T2.2 — OpenAPI build-artifact emit (post-Vite, EC-2 gated on success).\n // If runAdapterBuild threw, execution never reaches this point — no stale\n // dist/openapi.json is written.\n if (config.openapi !== undefined) {\n const distOut = resolve(cwd, 'dist')\n const hydrated = await loadRoutesForOpenApi({ serverDir, routes: manifest.routes })\n const distResult = emitOpenApi({\n manifest: hydrated,\n config: { ...config.openapi, outDir: distOut },\n })\n console.log(` ✓ OpenAPI (dist): ${distResult.path}`)\n }\n\n const ssrNote = config.ssr ? ' (SSR)' : ''\n console.log(`\\n ✓ Build complete → ${target}${ssrNote}\\n`)\n}\n\nasync function runAdapterBuild(\n target: BuildTarget,\n config: Awaited<ReturnType<typeof loadConfig>>,\n cwd: string,\n): Promise<void> {\n // T1.1 (architecture-cleanup) — CLI composes the Vite Plugin[] and INJECTS it into\n // the adapter via ctx.makeVitePlugins. This inverts the previous `adapters → vite-plugin`\n // edge — adapters no longer import from vite-plugin/ directly.\n //\n // theoPlugin AND `@vitejs/plugin-react` are dynamically imported so the deps are\n // materialized only when needed (adapter is `node`). This keeps the CLI's startup\n // path independent of optional build-time deps (so e.g. `theokit build --target=static`\n // does not need react installed). dep-cruiser's per-module rule allows `cli → vite-plugin`.\n //\n // 0.2.2 regression fix: switched sync `theoPlugin()` → `theoPluginAsync()` so the\n // returned Plugin[] includes the @theo/actions virtual module + typed-client +\n // services + @theokit/ui auto-chain. Without async, build-time Rollup couldn't\n // resolve `@theo/actions` even though dev-time Vite (which already used async)\n // could. See https://github.com/usetheo/theokit/commits — 0.2.2 changelog.\n const { theoPluginAsync } = await import('../../vite-plugin/index.js')\n const { default: react } = await import('@vitejs/plugin-react')\n const ctx: AdapterBuildContext = {\n // `react()` may return Plugin or Plugin[] depending on version; spread the\n // async chain so the contract returns a flat Plugin[] (AdapterBuildContext\n // type updated to `Plugin[] | Promise<Plugin[]>`).\n // #95 — inject the config dirs so the client build's router/entry + typed-client codegen honor\n // custom appDir/serverDir/agentsDir (e.g. \"apps/web\" / \"core\" / \"core/agents\").\n makeVitePlugins: async (opts) =>\n [\n react(),\n ...(await theoPluginAsync({\n ...opts,\n appDir: config.appDir,\n serverDir: config.serverDir,\n agentsDir: config.agentsDir,\n })),\n ].flat(),\n\n // #369 — the same inversion, for the same reason. A Worker has no filesystem, so the Cloudflare\n // entry bakes its routes at build time; importing the scanner from `adapters/` would add the\n // `adapters → server` edge that `adapters-may-only-depend-on-core-router-services` refuses. The\n // CLI already imports both sides, so it composes the scan and hands over the result.\n //\n // Paths are made relative to the project root here, where `cwd` is known: that string is both\n // the emitted import specifier and the key the executor looks a module up by, and the scanners\n // return absolute paths.\n scanRoutes: (serverDir) => {\n const abs = resolve(cwd, serverDir)\n const toProjectRelative = (p: string): string => relative(cwd, p).split(sep).join('/')\n return {\n routes: scanServerRoutes(abs).map((route) => ({\n filePath: toProjectRelative(route.filePath),\n routePath: route.routePath,\n methods: route.methods ?? [],\n })),\n wsRoutes: scanWebSocketRoutes(abs).map((ws) =>\n toProjectRelative(typeof ws === 'string' ? ws : ws.filePath),\n ),\n // #367 — agents are a DIFFERENT scan served by a DIFFERENT function, which is why no\n // adapter had ever heard of them: the entries route `/api/` through `scanServerRoutes` +\n // `executeRoute` alone, so `/api/agents/<name>` matched nothing and 404'd on every target.\n // Scanned here, beside the routes, because the same inversion argument applies verbatim.\n agents: scanAgents(dirname(abs), config.agentsDir).map((agent) => ({\n filePath: toProjectRelative(agent.filePath),\n agentPath: agent.agentPath,\n name: agent.name,\n })),\n }\n },\n }\n\n // T1.1 (architecture-medium-deferrals, ADR D1) — Adapter Registry replaces\n // the previous 9-case switch. New adapters add 1 line in `adapters/registry.ts`;\n // CLI is closed for modification (OCP).\n const { resolveAdapter } = await import('../../adapters/registry.js')\n const adapter = await resolveAdapter(target)\n\n // #409 / #410 — a config key that validates and is then never read makes the\n // deployed app behave as if the operator had not written it, with nothing\n // anywhere saying so. Name it before the build output scrolls past.\n const { warnUnappliedConfig, assertRateLimitEnforceable } =\n await import('../../adapters/config-support.js')\n\n // #461 — one of those keys does not get a warning. A dropped `cors` degrades where someone can\n // see it; a dropped RATE LIMIT looks exactly like success until the abuse it was meant to stop.\n // #321 and #322 are that lesson twice. So this target/config combination is refused by name,\n // BEFORE the build writes anything — the same answer `MissingRoutePolicyError` gives an\n // undeclared route policy, and the public-bind refusal gives an unauthenticated write.\n assertRateLimitEnforceable(config, adapter, target)\n\n warnUnappliedConfig(config, adapter, target, (message) => {\n console.log(message)\n })\n\n await adapter.build(config, cwd, ctx)\n}\n\nasync function emitCronArtifacts(opts: {\n cwd: string\n serverDir: string\n agentsDir: string\n distDir: string\n target: BuildTarget\n}): Promise<void> {\n // Crons live in two conventional homes: `server/crons/` (a backend trigger) and\n // `agents/schedules/` (a scheduled agent run, kept in the agent domain). Both feed one manifest.\n const cronsDir = resolve(opts.serverDir, 'crons')\n const agentsSchedulesDir = resolve(opts.cwd, opts.agentsDir, 'schedules')\n\n const cronNodes = await scanCronDirs([cronsDir, agentsSchedulesDir])\n const manifestPath = resolve(opts.distDir, 'crons.json')\n writeCronManifest(manifestPath, cronNodes, opts.cwd)\n\n console.log(` ✓ Crons: ${cronNodes.length} declared`)\n\n if (cronNodes.length === 0) return\n\n // EC-201: target-specific translation. N/A targets emit a warning + skip.\n if (CRON_NA_TARGETS.has(opts.target)) {\n console.log(\n ` ⚠ Cron not supported by target \"${opts.target}\" — declared crons skipped. ` +\n `Supported targets: ${CRON_SUPPORTED_TARGETS.join(', ')}.`,\n )\n return\n }\n\n const manifestEntries = cronNodes.map((n) => ({\n name: n.name,\n filePath: relativize(n.filePath, opts.cwd),\n schedule: n.schedule,\n concurrency: n.concurrency,\n }))\n\n try {\n switch (opts.target) {\n case 'vercel':\n translateCronToVercel(resolve(opts.cwd, 'vercel.json'), manifestEntries)\n console.log(` ✓ Cron → vercel.json crons[] (${cronNodes.length} entries)`)\n break\n case 'cloudflare':\n translateCronToCloudflare(resolve(opts.cwd, 'wrangler.toml'), manifestEntries)\n console.log(` ✓ Cron → wrangler.toml [triggers] (${cronNodes.length})`)\n break\n case 'aws-lambda':\n translateCronToAws(resolve(opts.cwd, 'serverless.yml'), manifestEntries)\n console.log(` ✓ Cron → serverless.yml functions (${cronNodes.length})`)\n break\n case 'deno-deploy':\n translateCronToDeno(resolve(opts.distDir, 'crons-entry.ts'), manifestEntries)\n console.log(` ✓ Cron → ${opts.distDir}/crons-entry.ts (Deno.cron)`)\n break\n case 'node':\n console.log(` ✓ Cron → in-process scheduler (theokit start)`)\n break\n }\n } catch (err) {\n if (err instanceof ExistingConfigUnparseableError) throw err\n throw err\n }\n}\n\nasync function emitJobArtifacts(opts: {\n cwd: string\n serverDir: string\n distDir: string\n}): Promise<void> {\n const jobsDir = resolve(opts.serverDir, 'jobs')\n\n const jobNodes = existsSync(jobsDir) ? await scanJobs(jobsDir) : []\n const manifestPath = resolve(opts.distDir, 'jobs.json')\n writeJobManifest(manifestPath, jobNodes, opts.cwd)\n console.log(` ✓ Jobs: ${jobNodes.length} declared`)\n}\n\nfunction relativize(absPath: string, root: string): string {\n if (absPath.startsWith(root)) {\n const trimmed = absPath.slice(root.length)\n return trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n }\n return absPath\n}\n","import type { Plugin } from 'vite'\n\nimport type { TheoConfig } from '../config/schema.js'\n\nimport type { DeployedAgent } from './deployed-agents.js'\n\n/**\n * Build context injected by the CLI into adapter.build.\n *\n * - `makeVitePlugins` — optional factory provided by CLI for adapters\n * that drive `viteBuild()` directly (currently: `nodeAdapter`).\n * When omitted, adapters that need Vite must fail with an actionable\n * error. This inverts the previous direct edge `adapters → vite-plugin`\n * per ADR-0001 v3 (T1.1 of the architecture-cleanup plan).\n *\n * The factory MAY return a Promise — `theokit build` uses\n * `theoPluginAsync` to wire the full Plugin[] chain (actions virtual\n * module + typed client + services + @theokit/ui auto-chain) so adapters\n * MUST `await` the result. See `cli/commands/build.ts` for the canonical\n * invocation.\n */\n/** One server route, flattened to what an adapter can bake into an emitted entry (#369). */\nexport interface AdapterRoute {\n /** Path relative to the project root — both the import specifier and the executor's lookup key. */\n filePath: string\n routePath: string\n methods: readonly string[]\n}\n\nexport interface AdapterBuildContext {\n makeVitePlugins?: (opts: { root: string; ssr?: boolean }) => Plugin[] | Promise<Plugin[]>\n /**\n * Scan the project's routes, INJECTED for the same reason `makeVitePlugins` is (#369).\n *\n * A Worker has no filesystem, so the Cloudflare entry has to bake its routes at build time\n * instead of scanning for them at request time. Importing the scanner here would put an\n * `adapters → server` edge in the graph — the layering inversion ADR-0001 v3 removed for\n * `vite-plugin`, and the one `adapters-may-only-depend-on-core-router-services` refuses. The CLI\n * already imports both sides, so it composes this and passes it in.\n */\n scanRoutes?: (serverDir: string) => {\n routes: AdapterRoute[]\n wsRoutes: string[]\n /**\n * The app's agents (#367). A different scan from the routes, served by a different function —\n * which is precisely why no adapter had ever heard of them and every deployed\n * `/api/agents/<name>` was a 404.\n */\n agents?: DeployedAgent[]\n }\n}\n\n/**\n * A configuration key that a request handler applies at runtime. Build-time\n * keys are deliberately absent: a runtime cannot silently drop them.\n */\nexport type ConfigConcern =\n | 'rateLimit'\n | 'cors'\n | 'csrf'\n | 'disallowed'\n | 'serialization'\n | 'plugins'\n | 'securityHeaders'\n\nexport interface DeployAdapter {\n name: string\n /**\n * #382 — does the handler this adapter emits hand its runtime a response\n * whose body is still being written?\n *\n * The claim is deliberately narrow, and it is the only part we can verify\n * without a real deployment: `true` means the emitted contract carries a\n * live body (a `Response` over a `ReadableStream`, or a chunk-by-chunk drain\n * into the runtime's own writable) rather than a fully materialized string\n * or buffer. It does NOT claim the platform was observed flushing early —\n * that needs a deploy, and none of these targets has one in CI.\n *\n * Omitted means no, on purpose: a new adapter should have to state that it\n * streams, because the failure mode of the opposite default is a target\n * silently listed for something nobody exercised.\n *\n * `aws-lambda` is the one target that answers no by construction — its v2\n * result object carries `body` as a string, so the response cannot exist\n * before the run ends. Making it stream means `awslambda.streamifyResponse`\n * plus a Function URL in `RESPONSE_STREAM` invoke mode, which this adapter\n * does not emit and which would break every API Gateway deployment of it.\n */\n streamsResponses?: boolean\n /**\n * Which configuration keys the handler this adapter emits actually applies.\n *\n * Same contract as `streamsResponses`, for the same reason: omitted means\n * **none**, on purpose. A new adapter should have to state what it honours,\n * because the failure mode of the opposite default is a target that parses a\n * rate limit, validates it, and refuses nothing — with no line anywhere\n * saying so.\n *\n * `'runtime-not-emitted-here'` is a third answer, not a synonym for none: it\n * belongs to an adapter that emits no request handler at all, so this build\n * genuinely cannot say what the runtime applies. Reporting such a target as\n * dropping configuration would be asserting rather than measuring.\n *\n * The declaration is a claim, and nothing here can verify it — a wrong claim\n * reads exactly like a right one. What it buys is that dropping a concern\n * becomes a visible edit instead of an omission.\n */\n /**\n * #367 — can the handler this adapter emits serve an AGENT?\n *\n * Same contract as `streamsResponses` and `appliesConfig`, for the same reason: omitted means\n * **no**, on purpose. The gap this answers went unnoticed because nothing in this layer had ever\n * heard of agents — `grep -rc \"agent\"` over the 14 adapter files returned nothing — so an agent\n * was served by no pipeline at all outside a machine running `theokit start`, in a framework\n * whose stated reason to exist is that the agent ships through the same pipeline as the page.\n *\n * `true` claims the emitted entry routes `/api/agents/<name>` to `mountAgent`. It is a claim\n * nothing here can verify, exactly like the other two; what it buys is that a target which drops\n * agents has to say so rather than be silently assumed to serve them.\n */\n servesAgents?: boolean\n appliesConfig?: readonly ConfigConcern[] | 'runtime-not-emitted-here'\n build(config: TheoConfig, cwd: string, ctx?: AdapterBuildContext): Promise<void>\n}\n\nexport type BuildTarget =\n | 'node'\n | 'vercel'\n | 'cloudflare'\n | 'static'\n | 'bun'\n | 'deno-deploy'\n | 'netlify'\n | 'aws-lambda'\n | 'theo-cloud'\n\nexport const VALID_TARGETS: BuildTarget[] = [\n 'node',\n 'vercel',\n 'cloudflare',\n 'static',\n 'bun',\n 'deno-deploy',\n 'netlify',\n 'aws-lambda',\n 'theo-cloud',\n]\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time adapter translators: caller-controlled paths only.\n */\nimport { existsSync, readFileSync } from 'node:fs'\n\nimport { writeAtomic } from '../_internal/atomic-write.js'\n\nimport type { CronManifestEntry } from './cron-manifest.js'\n\n/**\n * Thrown when an existing platform-config file (vercel.json, wrangler.toml,\n * serverless.yml) cannot be parsed. Caller must fix the file before\n * re-running `theokit build`. We NEVER silently overwrite a user's config.\n */\nexport class ExistingConfigUnparseableError extends Error {\n readonly code = 'EXISTING_CONFIG_UNPARSEABLE'\n constructor(\n public readonly filePath: string,\n public readonly parseError: string,\n ) {\n super(\n `Existing config \"${filePath}\" could not be parsed: ${parseError}. ` +\n 'Fix or remove the file before re-running build — TheoKit never silently overwrites user configuration.',\n )\n this.name = 'ExistingConfigUnparseableError'\n }\n}\n\n// ──────────────────────────────────────────────────────────\n// Vercel — vercel.json crons[]\n// ──────────────────────────────────────────────────────────\n\ninterface VercelJson {\n crons?: { path: string; schedule: string }[]\n [key: string]: unknown\n}\n\n/**\n * Translate a TheoKit cron manifest into `vercel.json crons[]`.\n *\n * EC-105: existing fields (functions, headers, redirects, rewrites, env,\n * etc.) are preserved verbatim — ONLY the `crons[]` slice is replaced.\n */\nexport function translateCronToVercel(\n vercelJsonPath: string,\n crons: readonly CronManifestEntry[],\n): void {\n let existing: VercelJson = {}\n if (existsSync(vercelJsonPath)) {\n const raw = readFileSync(vercelJsonPath, 'utf8')\n try {\n existing = JSON.parse(raw) as VercelJson\n } catch (err) {\n throw new ExistingConfigUnparseableError(\n vercelJsonPath,\n err instanceof Error ? err.message : String(err),\n )\n }\n }\n const merged: VercelJson = {\n ...existing,\n crons: crons.map((c) => ({\n path: `/api/__crons/${c.name}`,\n schedule: c.schedule,\n })),\n }\n writeAtomic(vercelJsonPath, JSON.stringify(merged, null, 2))\n}\n\n// ──────────────────────────────────────────────────────────\n// Cloudflare — wrangler.toml [triggers] crons\n// ──────────────────────────────────────────────────────────\n\n/**\n * Translate a TheoKit cron manifest into `wrangler.toml [triggers] crons`.\n *\n * EC-105: regex-based mutation that preserves comments + other sections\n * verbatim. Replaces only the `[triggers]` block (or appends if absent).\n */\nexport function translateCronToCloudflare(\n wranglerTomlPath: string,\n crons: readonly CronManifestEntry[],\n): void {\n const schedules = crons.map((c) => `\"${c.schedule}\"`).join(', ')\n const triggersBlock = `[triggers]\\ncrons = [${schedules}]\\n`\n\n if (!existsSync(wranglerTomlPath)) {\n writeAtomic(wranglerTomlPath, triggersBlock)\n return\n }\n\n const existing = readFileSync(wranglerTomlPath, 'utf8')\n\n // Replace existing [triggers] section if present. Strategy: split into\n // line array, find the [triggers] header line, drop subsequent lines\n // until the next section header (line starting with `[`) or EOF.\n const lines = existing.split('\\n')\n const triggersIdx = lines.findIndex((l) => l.trim() === '[triggers]')\n\n let next: string\n if (triggersIdx !== -1) {\n let endIdx = lines.length\n for (let i = triggersIdx + 1; i < lines.length; i++) {\n if (lines[i].trim().startsWith('[')) {\n endIdx = i\n break\n }\n }\n const before = lines.slice(0, triggersIdx).join('\\n')\n const after = lines.slice(endIdx).join('\\n')\n next = `${before}\\n${triggersBlock.trimEnd()}\\n${after}`.replace(/\\n{3,}/g, '\\n\\n')\n } else {\n next = existing.endsWith('\\n')\n ? `${existing}\\n${triggersBlock}`\n : `${existing}\\n\\n${triggersBlock}`\n }\n writeAtomic(wranglerTomlPath, next)\n}\n\n// ──────────────────────────────────────────────────────────\n// AWS Lambda — serverless.yml functions.<fn>.events: schedule\n// ──────────────────────────────────────────────────────────\n\n/**\n * Convert TheoKit's 5-field UTC cron to AWS EventBridge's 6-field format.\n * EventBridge requires `?` in EITHER day-of-month OR day-of-week (not both `*`).\n *\n * Algorithm:\n * - If DOM is \"*\" and DOW is \"*\" → insert ? in DOW (default)\n * - If DOM is \"*\" and DOW is specific → insert ? in DOM\n * - If DOM is specific and DOW is \"*\" → insert ? in DOW\n * - Append \"*\" year field at end.\n */\nexport function convertToAwsCron(schedule: string): string {\n const parts = schedule.trim().split(/\\s+/)\n if (parts.length !== 5) {\n throw new Error(`Invalid 5-field schedule for AWS conversion: \"${schedule}\"`)\n }\n const [minute, hour, dom, month, dow] = parts\n let awsDom = dom\n let awsDow = dow\n if (dom === '*' && dow === '*') {\n awsDow = '?'\n } else if (dom === '*') {\n awsDom = '?'\n } else if (dow === '*') {\n awsDow = '?'\n }\n return `cron(${minute} ${hour} ${awsDom} ${month} ${awsDow} *)`\n}\n\n/**\n * Translate a TheoKit cron manifest into a `serverless.yml` functions\n * map with `events: - schedule: cron(...)` entries.\n *\n * EC-105: appends to `functions:` block, preserving all existing\n * functions/sections. Cron functions are named `cron_<name>` to avoid\n * collision with user-declared functions.\n */\nexport function translateCronToAws(\n serverlessYmlPath: string,\n crons: readonly CronManifestEntry[],\n): void {\n const cronFunctionsYaml = crons\n .map(\n (c) => ` cron_${c.name}:\n handler: .theokit/server/crons/${c.name}.handler\n events:\n - schedule: ${convertToAwsCron(c.schedule)}`,\n )\n .join('\\n')\n\n const block = `\\nfunctions:\\n${cronFunctionsYaml}\\n`\n\n if (!existsSync(serverlessYmlPath)) {\n // Minimal serverless.yml scaffold\n writeAtomic(\n serverlessYmlPath,\n `service: theokit-app\\nprovider:\\n name: aws\\n runtime: nodejs22.x\\n${block}`,\n )\n return\n }\n\n const existing = readFileSync(serverlessYmlPath, 'utf8')\n\n // Look for an existing top-level `functions:` block; if present, append our\n // cron entries under it (don't replace user-declared functions).\n const functionsRe = /^functions:\\s*\\n/m\n let next: string\n if (functionsRe.test(existing)) {\n next = existing.replace(functionsRe, (match) => `${match}${cronFunctionsYaml}\\n`)\n } else {\n next = existing.endsWith('\\n') ? `${existing}${block}` : `${existing}\\n${block}`\n }\n writeAtomic(serverlessYmlPath, next)\n}\n\n// ──────────────────────────────────────────────────────────\n// Deno Deploy — Deno.cron registrations\n// ──────────────────────────────────────────────────────────\n\n/**\n * Emit a Deno entry file that registers each cron via `Deno.cron`.\n *\n * Unlike Vercel/CF/AWS, Deno.cron is an in-process runtime API — the\n * entry file is a managed artifact (overwritten each build), not a user\n * config (so EC-105 doesn't apply here).\n */\nexport function translateCronToDeno(entryPath: string, crons: readonly CronManifestEntry[]): void {\n const lines = crons.map(\n (c) =>\n `Deno.cron(\"${c.name}\", \"${c.schedule}\", async () => {\n const mod = await import(\"../${c.filePath}\");\n const def = mod.default;\n await def.handler({\n traceId: crypto.randomUUID().replace(/-/g, \"\"),\n scheduledAt: new Date(),\n signal: AbortSignal.timeout(60_000),\n });\n});`,\n )\n const content = `// AUTOGENERATED by TheoKit cron build — DO NOT EDIT.\n// Source: server/crons/*.ts → .theokit/crons.json → this file.\n${lines.join('\\n\\n')}\n`\n writeAtomic(entryPath, content)\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time atomic write: caller-controlled paths only. No HTTP input\n * reaches these fs calls.\n */\n// T5a.1b — Web Crypto migration. Build-time only; node:fs + node:path stay\n// because this is a manifest-write leaf (e.g. .theokit/jobs.json) and per\n// ADR-0028 the runtime-portable boundary is the request handler, not the\n// scanner. Only node:crypto is swapped out — Web Crypto's\n// getRandomValues works in every supported runtime.\nimport { mkdirSync, renameSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\n/**\n * Write `content` to `path` atomically via the tmp + rename pattern.\n *\n * Two concurrent calls to `writeAtomic(path, ...)` are guaranteed to\n * leave `path` containing valid content from ONE of the calls (never\n * truncated, never interleaved). POSIX rename is atomic on the same\n * filesystem.\n *\n * EC-106 (jobs-crons-webhooks-cost-tracking-plan) — shared helper for\n * `.theokit/crons.json` and `.theokit/jobs.json` manifest writes so a\n * concurrent dev-server scan + build manifest emit never produces\n * partial JSON.\n *\n * @param path destination path\n * @param content bytes (UTF-8 string) to write\n */\nexport function writeAtomic(path: string, content: string): void {\n mkdirSync(dirname(path), { recursive: true })\n // Include a random suffix so two concurrent writes don't trample each\n // other's tmp file. Web Crypto getRandomValues is non-blocking +\n // collision-safe for the tiny entropy we need (8 hex chars = 32 bits).\n // Hex-encoded manually to avoid Buffer (runtime-agnostic per ADR-0028).\n const randBuf = new Uint8Array(4)\n globalThis.crypto.getRandomValues(randBuf)\n let suffix = ''\n for (const b of randBuf) suffix += b.toString(16).padStart(2, '0')\n const tmp = `${path}.tmp-${process.pid}-${suffix}`\n writeFileSync(tmp, content, 'utf8')\n renameSync(tmp, path)\n}\n","import { writeAtomic } from '../_internal/atomic-write.js'\n\nimport type { CronNode } from './cron-scan.js'\n\nexport const CRON_MANIFEST_SCHEMA_VERSION = 1 as const\n\nexport interface CronManifestEntry {\n readonly name: string\n readonly filePath: string\n readonly schedule: string\n readonly concurrency: 'forbid' | 'allow'\n}\n\nexport interface CronManifest {\n readonly schemaVersion: typeof CRON_MANIFEST_SCHEMA_VERSION\n readonly generatedAt: string\n readonly crons: readonly CronManifestEntry[]\n}\n\n/**\n * Build a `CronManifest` from scanned `CronNode[]`. Filepaths are kept\n * relative to the caller's project root for portability.\n */\nexport function buildCronManifest(nodes: readonly CronNode[], projectRoot?: string): CronManifest {\n const crons: CronManifestEntry[] = nodes.map((n) => ({\n name: n.name,\n filePath: projectRoot ? relativize(n.filePath, projectRoot) : n.filePath,\n schedule: n.schedule,\n concurrency: n.concurrency,\n }))\n return {\n schemaVersion: CRON_MANIFEST_SCHEMA_VERSION,\n generatedAt: new Date().toISOString(),\n crons,\n }\n}\n\n/**\n * Write the cron manifest to `path` atomically (EC-106).\n *\n * Accepts either a pre-built `CronManifest` OR an array of `CronNode[]`\n * (which gets converted via `buildCronManifest`). The atomic-write\n * helper guarantees `path` always contains valid JSON, even under\n * concurrent writes (e.g., dev-server rescan + build).\n */\nexport function writeCronManifest(\n path: string,\n input: readonly CronNode[] | CronManifest,\n projectRoot?: string,\n): void {\n const manifest: CronManifest = isManifest(input) ? input : buildCronManifest(input, projectRoot)\n writeAtomic(path, JSON.stringify(manifest, null, 2))\n}\n\nfunction isManifest(value: unknown): value is CronManifest {\n return typeof value === 'object' && value !== null && 'schemaVersion' in value && 'crons' in value\n}\n\nfunction relativize(absPath: string, root: string): string {\n if (absPath.startsWith(root)) {\n const trimmed = absPath.slice(root.length)\n return trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n }\n return absPath\n}\n","/* 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 } 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 * 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: string[] = []\n for (const dir of dirs) {\n if (!existsSync(dir)) continue\n walkSourceFiles(dir, { extensions: CRON_EXTENSIONS }, (p) => {\n const base = basename(p)\n // Skip private helpers (`_helper.ts`) and OS junk (`.DS_Store`).\n if (base.startsWith('_') || base.startsWith('.')) return\n filePaths.push(p)\n })\n }\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","import { writeAtomic } from '../_internal/atomic-write.js'\n\nimport type { JobNode } from './job-scan.js'\n\nexport const JOB_MANIFEST_SCHEMA_VERSION = 1 as const\n\nexport interface JobManifestEntry {\n readonly name: string\n readonly filePath: string\n readonly maxAttempts: number\n readonly hasInputSchema: boolean\n}\n\nexport interface JobManifest {\n readonly schemaVersion: typeof JOB_MANIFEST_SCHEMA_VERSION\n readonly generatedAt: string\n readonly jobs: readonly JobManifestEntry[]\n}\n\nexport function buildJobManifest(nodes: readonly JobNode[], projectRoot?: string): JobManifest {\n const jobs: JobManifestEntry[] = nodes.map((n) => ({\n name: n.name,\n filePath: projectRoot ? relativize(n.filePath, projectRoot) : n.filePath,\n maxAttempts: n.maxAttempts,\n hasInputSchema: n.hasInputSchema,\n }))\n return {\n schemaVersion: JOB_MANIFEST_SCHEMA_VERSION,\n generatedAt: new Date().toISOString(),\n jobs,\n }\n}\n\nexport function writeJobManifest(\n path: string,\n input: readonly JobNode[] | JobManifest,\n projectRoot?: string,\n): void {\n const manifest: JobManifest = isManifest(input) ? input : buildJobManifest(input, projectRoot)\n writeAtomic(path, JSON.stringify(manifest, null, 2))\n}\n\nfunction isManifest(value: unknown): value is JobManifest {\n return typeof value === 'object' && value !== null && 'schemaVersion' in value && 'jobs' in value\n}\n\nfunction relativize(absPath: string, root: string): string {\n if (absPath.startsWith(root)) {\n const trimmed = absPath.slice(root.length)\n return trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n }\n return absPath\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: caller-controlled directory paths only.\n */\nimport { existsSync } from 'node:fs'\nimport { basename } 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 { JobDefinition } from './job-types.js'\n\nexport interface JobNode {\n readonly name: string\n readonly filePath: string\n readonly maxAttempts: number\n readonly hasInputSchema: boolean\n}\n\nexport class DuplicateJobNameError extends Error {\n readonly code = 'DUPLICATE_JOB_NAME'\n constructor(\n public readonly jobName: string,\n public readonly filePaths: readonly string[],\n ) {\n super(\n `Duplicate job name \"${jobName}\" defined in: ${filePaths.join(', ')}. ` +\n 'Job names must be unique across server/jobs/.',\n )\n this.name = 'DuplicateJobNameError'\n }\n}\n\nconst JOB_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs'])\n\ninterface JobModule {\n default?: unknown\n}\n\nfunction isJobDefinition(value: unknown): value is JobDefinition {\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.handler === 'function' &&\n typeof def.maxAttempts === 'number' &&\n typeof def.hasInputSchema === 'boolean'\n )\n}\n\nexport async function scanJobs(jobsDir: string): Promise<JobNode[]> {\n if (!existsSync(jobsDir)) return []\n\n const filePaths: string[] = []\n walkSourceFiles(jobsDir, { extensions: JOB_EXTENSIONS }, (p) => {\n const base = basename(p)\n if (base.startsWith('_') || base.startsWith('.')) return\n filePaths.push(p)\n })\n\n const nodes: JobNode[] = []\n for (const filePath of filePaths) {\n let mod: JobModule\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 job file \"${filePath}\": ${reason}`)\n }\n const exported = mod.default\n if (!isJobDefinition(exported)) {\n throw new Error(\n `Job file \"${filePath}\" is missing a valid default export. ` +\n 'Expected `export default defineJob(name, { handler })`.',\n )\n }\n nodes.push({\n name: exported.name,\n filePath,\n maxAttempts: exported.maxAttempts,\n hasInputSchema: exported.hasInputSchema,\n })\n }\n\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 DuplicateJobNameError(name, paths)\n }\n }\n\n return nodes.sort((a, b) => compareByCodeUnit(a.name, b.name))\n}\n","/**\n * State cleanup utilities (Phase 2 of\n *\n * - `cleanOutDir` — Astro pattern: empty a directory except a skip list,\n * used at `theokit build` start.\n * - `gcAgentRegistry` — Nuxt LRU pattern: delete oldest agent dirs when\n * count exceeds cap, used at `theokit dev` startup.\n *\n * EC-3 (MUST FIX, CRITICAL): cleanOutDir refuses to wipe anything outside\n * the current cwd. Prevents catastrophic `distDir: '/'` data loss.\n * EC-9 (SHOULD TEST): gcAgentRegistry handles dirs with mtime=0 (Docker overlay).\n * EC-11 (SHOULD TEST): cleanOutDir normalizes trailing-slash in skip basenames.\n * EC-12 (SHOULD TEST): cleanOutDir catches EROFS and continues.\n */\n\nimport { promises as fs } from 'node:fs'\nimport { basename, resolve as resolvePath, sep } from 'node:path'\n\nimport type {\n CleanOutDirOptions,\n CleanOutDirResult,\n GcAgentRegistryOptions,\n GcAgentRegistryResult,\n} from './cleanup-types.js'\n\nconst DEFAULT_SKIP = ['.git', '.gitkeep', '.gitignore']\n// DEFAULT_MAX_AGENTS removed in Phase 7 — gcAgentRegistry is a tombstone.\n\nfunction normalizeSkipName(name: string): string {\n // EC-11 — strip trailing slash + leading `./`\n return basename(name.replace(/\\/$/, ''))\n}\n\n/**\n * Empty a directory, preserving entries in the skip list.\n *\n * Throws if `opts.dir` is not inside `process.cwd()` (EC-3 path safety).\n * Returns `{deleted:0, kept:0}` when the directory does not exist.\n */\nexport async function cleanOutDir(opts: CleanOutDirOptions): Promise<CleanOutDirResult> {\n const resolvedDir = resolvePath(opts.dir)\n const resolvedCwd = resolvePath(process.cwd())\n\n // EC-3 — path safety guard. CRITICAL.\n if (resolvedDir === resolvedCwd) {\n throw new Error(\n `cleanOutDir refused to wipe ${resolvedDir} — must be a child of cwd, not cwd itself`,\n )\n }\n if (!resolvedDir.startsWith(resolvedCwd + sep)) {\n throw new Error(\n `cleanOutDir refused to wipe ${resolvedDir} — must be inside cwd (${resolvedCwd})`,\n )\n }\n\n const skip = new Set((opts.skip ?? DEFAULT_SKIP).map(normalizeSkipName))\n\n let entries: { name: string }[]\n try {\n entries = await fs.readdir(resolvedDir, { withFileTypes: true })\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') return { deleted: 0, kept: 0 }\n throw err\n }\n\n let deleted = 0\n let kept = 0\n for (const entry of entries) {\n const name = entry.name\n if (skip.has(name)) {\n kept++\n continue\n }\n const fullPath = resolvePath(resolvedDir, name)\n try {\n await fs.rm(fullPath, { recursive: true, force: true, maxRetries: 3 })\n deleted++\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') {\n deleted++ // already gone\n continue\n }\n // EC-12 — EROFS or other rm failure: warn + continue, don't crash.\n console.warn(\n `[theokit] cleanOutDir could not remove ${fullPath} (${code ?? 'unknown'}); skipping`,\n )\n kept++\n }\n }\n\n return { deleted, kept }\n}\n\n/**\n * Phase 7 — TOMBSTONE for backward-compat. The SDK v1.1.0's `Agent.registry`\n * handles GC natively; this function is a no-op + emits a deprecation warning\n * ONCE per process (EC-10).\n *\n * Will be deleted entirely in TheoKit 0.4.0. Marked deprecated via runtime\n * warning rather than `@deprecated` JSDoc tag to avoid the eslint\n * sonarjs/deprecation flagging our own internal symbols.\n */\nlet warnedOnce = false\nexport async function gcAgentRegistry(\n _opts: GcAgentRegistryOptions,\n): Promise<GcAgentRegistryResult> {\n if (!warnedOnce) {\n warnedOnce = true\n console.warn(\n '[theokit] gcAgentRegistry is deprecated; SDK Agent.registry handles GC natively (configure via theo.config.ts > agents.registry)',\n )\n }\n return Promise.resolve({ deleted: 0, kept: 0 })\n}\n\n/**\n * @internal — testing helper. Resets the module-scoped warnedOnce flag.\n */\nexport function __resetGcDeprecationWarnedForTests(): void {\n warnedOnce = false\n}\n"],"mappings":"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","names":["existsSync","dirname","sep","existsSync","existsSync","relativize","isManifest","existsSync","basename","existsSync","basename","basename","writeManifest","sep","dirname","relativize","existsSync"]}
|
|
@@ -178,7 +178,7 @@ async function agentCommand(name, message, deps = {}) {
|
|
|
178
178
|
async function createAgentSsrLoader(projectRoot) {
|
|
179
179
|
const { createServer } = await import("vite");
|
|
180
180
|
const react = (await import("@vitejs/plugin-react")).default;
|
|
181
|
-
const { theoPluginAsync } = await import("./vite-plugin-
|
|
181
|
+
const { theoPluginAsync } = await import("./vite-plugin-5O3D472R.js");
|
|
182
182
|
const { loadConfig } = await import("./load-config-BKUAMGO5.js");
|
|
183
183
|
const config = await loadConfig(projectRoot);
|
|
184
184
|
const theoPlugins = await theoPluginAsync({
|
|
@@ -212,4 +212,4 @@ export {
|
|
|
212
212
|
agentCommand,
|
|
213
213
|
createAgentSsrLoader
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-2PSKQWGM.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
dispatchCsrfWarn,
|
|
3
3
|
incomingMessageToWebRequest,
|
|
4
4
|
sendError
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ITSNTHWN.js";
|
|
6
6
|
import {
|
|
7
7
|
enforceCsrf
|
|
8
8
|
} from "./chunk-P6OS7652.js";
|
|
@@ -108,4 +108,4 @@ export {
|
|
|
108
108
|
scanControllerModules,
|
|
109
109
|
dispatchControllerRequest
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-3DRALT3J.js.map
|