@lunora/codegen 1.0.0-alpha.42 → 1.0.0-alpha.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/index.d.mts +155 -11
  2. package/dist/index.d.ts +155 -11
  3. package/dist/index.mjs +19 -18
  4. package/dist/packem_shared/AGENTS_FILENAME-BksnAJgx.mjs +116 -0
  5. package/dist/packem_shared/{FLAGS_FILENAME-fEZtzWXi.mjs → FLAGS_FILENAME-Dg4mKUuz.mjs} +1 -1
  6. package/dist/packem_shared/GENERATED_HEADER-7W9f2IG3.mjs +4 -0
  7. package/dist/packem_shared/{OPENRPC_VERSION-CzhfvCIQ.mjs → OPENRPC_VERSION-Cyttekkt.mjs} +1 -1
  8. package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-Cl1EBMdR.mjs → SCHEMA_SNAPSHOT_FILENAME-CMjGZSa1.mjs} +80 -21
  9. package/dist/packem_shared/{buildOpenApiDocument-bg-NnLka.mjs → buildOpenApiDocument-saZ_-kl4.mjs} +1 -1
  10. package/dist/packem_shared/{discoverAuthApiCalls-WMx8L2FG.mjs → discoverAuthApiCalls-Dx3K42rk.mjs} +1 -1
  11. package/dist/packem_shared/{discoverCrons-D-jrpm97.mjs → discoverCrons-_aosTRLr.mjs} +36 -21
  12. package/dist/packem_shared/{discoverFunctions-CZ91aenA.mjs → discoverFunctions-BJ-qR7Rg.mjs} +1 -1
  13. package/dist/packem_shared/{discoverHttpRoutes-DNZLDCmm.mjs → discoverHttpRoutes-daCzuTe8.mjs} +9 -1
  14. package/dist/packem_shared/{discoverInserts-DFRJhmCv.mjs → discoverInserts-DI4q5NxE.mjs} +1 -1
  15. package/dist/packem_shared/{discoverMaskProcedures-B5iFnZ-X.mjs → discoverMaskProcedures-BcTOEKNU.mjs} +1 -1
  16. package/dist/packem_shared/{discoverMigrations-CdKtMlBc.mjs → discoverMigrations-VNUFvCwr.mjs} +1 -1
  17. package/dist/packem_shared/{discoverNondeterministicCalls-C_PrQPkA.mjs → discoverNondeterministicCalls-S0N2xLCq.mjs} +1 -1
  18. package/dist/packem_shared/{discoverQueries-B8W9UPrt.mjs → discoverQueries-CJnnnLpd.mjs} +1 -1
  19. package/dist/packem_shared/{discoverR2sqlCalls-Bm7Rfnf4.mjs → discoverR2sqlCalls-pnpicWfz.mjs} +1 -1
  20. package/dist/packem_shared/{discoverRlsMetadata-B4GL4ZKm.mjs → discoverRlsMetadata-DppniPUH.mjs} +1 -1
  21. package/dist/packem_shared/{discoverStorageRulesMetadata-nosjYcvN.mjs → discoverStorageRulesMetadata-CnHl2rXD.mjs} +1 -1
  22. package/dist/packem_shared/{emit-31Yg1Ee5.mjs → emit-C_29WVlW.mjs} +328 -31
  23. package/dist/packem_shared/{emitApp-DCP7Pr6M.mjs → emitApp-C9oljiZd.mjs} +25 -2
  24. package/package.json +9 -8
  25. package/dist/packem_shared/GENERATED_HEADER-D6RK1WF1.mjs +0 -3
package/dist/index.mjs CHANGED
@@ -1,29 +1,30 @@
1
1
  export { formatAdvisories, lintSchema } from './packem_shared/formatAdvisories-DRhEiJUz.mjs';
2
2
  export { CodegenDiagnosticError, diagnosticAt } from './packem_shared/CodegenDiagnosticError-DyQ5FwkM.mjs';
3
- export { default as discoverAuthApiCalls } from './packem_shared/discoverAuthApiCalls-WMx8L2FG.mjs';
3
+ export { AGENTS_FILENAME, discoverAgents } from './packem_shared/AGENTS_FILENAME-BksnAJgx.mjs';
4
+ export { default as discoverAuthApiCalls } from './packem_shared/discoverAuthApiCalls-Dx3K42rk.mjs';
4
5
  export { CONTAINERS_FILENAME, discoverContainers } from './packem_shared/CONTAINERS_FILENAME-DjpXMqhp.mjs';
5
- export { default as discoverCrons } from './packem_shared/discoverCrons-D-jrpm97.mjs';
6
- export { FLAGS_FILENAME, discoverFlags } from './packem_shared/FLAGS_FILENAME-fEZtzWXi.mjs';
7
- export { discoverFunctions } from './packem_shared/discoverFunctions-CZ91aenA.mjs';
8
- export { default as discoverHttpRoutes } from './packem_shared/discoverHttpRoutes-DNZLDCmm.mjs';
9
- export { default as discoverInserts } from './packem_shared/discoverInserts-DFRJhmCv.mjs';
10
- export { default as discoverMaskProcedures } from './packem_shared/discoverMaskProcedures-B5iFnZ-X.mjs';
11
- export { default as discoverMigrations } from './packem_shared/discoverMigrations-CdKtMlBc.mjs';
6
+ export { default as discoverCrons } from './packem_shared/discoverCrons-_aosTRLr.mjs';
7
+ export { FLAGS_FILENAME, discoverFlags } from './packem_shared/FLAGS_FILENAME-Dg4mKUuz.mjs';
8
+ export { discoverFunctions } from './packem_shared/discoverFunctions-BJ-qR7Rg.mjs';
9
+ export { default as discoverHttpRoutes } from './packem_shared/discoverHttpRoutes-daCzuTe8.mjs';
10
+ export { default as discoverInserts } from './packem_shared/discoverInserts-DI4q5NxE.mjs';
11
+ export { default as discoverMaskProcedures } from './packem_shared/discoverMaskProcedures-BcTOEKNU.mjs';
12
+ export { default as discoverMigrations } from './packem_shared/discoverMigrations-VNUFvCwr.mjs';
12
13
  export { MUTATORS_FILENAME, discoverMutators } from './packem_shared/MUTATORS_FILENAME-BZOfUhlY.mjs';
13
- export { default as discoverNondeterministicCalls } from './packem_shared/discoverNondeterministicCalls-C_PrQPkA.mjs';
14
- export { default as discoverQueries } from './packem_shared/discoverQueries-B8W9UPrt.mjs';
14
+ export { default as discoverNondeterministicCalls } from './packem_shared/discoverNondeterministicCalls-S0N2xLCq.mjs';
15
+ export { default as discoverQueries } from './packem_shared/discoverQueries-CJnnnLpd.mjs';
15
16
  export { QUEUES_FILENAME, discoverQueues } from './packem_shared/QUEUES_FILENAME-Xv6Vy-Ku.mjs';
16
- export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-Bm7Rfnf4.mjs';
17
- export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-B4GL4ZKm.mjs';
17
+ export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-pnpicWfz.mjs';
18
+ export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-DppniPUH.mjs';
18
19
  export { default as discoverSchema } from './packem_shared/discoverSchema-DFWVgU5o.mjs';
19
20
  export { SHAPES_FILENAME, discoverShapes } from './packem_shared/SHAPES_FILENAME-DOhPGi-6.mjs';
20
- export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-nosjYcvN.mjs';
21
+ export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-CnHl2rXD.mjs';
21
22
  export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-B2By8S4s.mjs';
22
- export { G as GENERATED_HEADER, e as emitApi, a as emitCollections, b as emitContainers, c as emitCrons, d as emitDataModel, f as emitDrizzleSchema, g as emitFunctions, h as emitServer, i as emitShard, j as emitVectors, k as emitWorkflows, l as emitWranglerCronTriggers } from './packem_shared/emit-31Yg1Ee5.mjs';
23
- export { emitApp } from './packem_shared/emitApp-DCP7Pr6M.mjs';
24
- export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-bg-NnLka.mjs';
25
- export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-CzhfvCIQ.mjs';
26
- export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-Cl1EBMdR.mjs';
23
+ export { G as GENERATED_HEADER, e as emitAgents, a as emitApi, b as emitCollections, c as emitContainers, d as emitCrons, f as emitDataModel, g as emitDrizzleSchema, h as emitFunctions, i as emitServer, j as emitShard, k as emitVectors, l as emitWorkflows, m as emitWranglerCronTriggers } from './packem_shared/emit-C_29WVlW.mjs';
24
+ export { emitApp } from './packem_shared/emitApp-C9oljiZd.mjs';
25
+ export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-saZ_-kl4.mjs';
26
+ export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-Cyttekkt.mjs';
27
+ export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-CMjGZSa1.mjs';
27
28
  export { SCHEMA_SNAPSHOT_VERSION, SchemaSnapshotParseError, buildSchemaSnapshot, diffSchemaSnapshots, evaluateSchemaDrift, parseSchemaSnapshot, serializeSchemaSnapshot } from './packem_shared/SCHEMA_SNAPSHOT_VERSION-D0ARY6rL.mjs';
28
29
  export { schemaFromIr } from './packem_shared/schemaFromIr-DTYsLBaA.mjs';
29
30
  export { LUNORA_ERROR_CODES, validatorIrToJsonSchema } from './packem_shared/LUNORA_ERROR_CODES-DvTLozCu.mjs';
@@ -0,0 +1,116 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { agentDefaultName, agentClassName, agentBindingName, voiceBindingName, voiceClassName } from '@lunora/agent/naming';
4
+ import { SyntaxKind, Node } from 'ts-morph';
5
+ import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
6
+
7
+ const AGENTS_FILENAME = "agents.ts";
8
+ const isDefineAgent = (identifier) => {
9
+ const symbol = identifier.getSymbol();
10
+ if (!symbol) {
11
+ return identifier.getText() === "defineAgent";
12
+ }
13
+ for (const declaration of symbol.getDeclarations()) {
14
+ if (!Node.isImportSpecifier(declaration)) {
15
+ continue;
16
+ }
17
+ if (declaration.getImportDeclaration().getModuleSpecifierValue() !== "@lunora/agent") {
18
+ return false;
19
+ }
20
+ return declaration.getNameNode().getText() === "defineAgent";
21
+ }
22
+ return false;
23
+ };
24
+ const stringProperty = (expression, exportName, property) => {
25
+ if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
26
+ return expression.getLiteralValue();
27
+ }
28
+ throw diagnosticAt(
29
+ expression,
30
+ `agent "${exportName}": \`${property}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`
31
+ );
32
+ };
33
+ const booleanProperty = (expression, exportName, property) => {
34
+ if (expression.getKind() === SyntaxKind.TrueKeyword) {
35
+ return true;
36
+ }
37
+ if (expression.getKind() === SyntaxKind.FalseKeyword) {
38
+ return false;
39
+ }
40
+ throw diagnosticAt(
41
+ expression,
42
+ `agent "${exportName}": \`${property}\` must be a static boolean literal — it is deploy configuration codegen writes into the ctx.agents wiring spec`
43
+ );
44
+ };
45
+ const agentFromCall = (call, exportName) => {
46
+ const argument = call.getArguments()[0];
47
+ if (!argument || !Node.isObjectLiteralExpression(argument)) {
48
+ throw diagnosticAt(call, `agent "${exportName}": defineAgent must be passed an inline object literal`);
49
+ }
50
+ const ir = {
51
+ bindingName: agentBindingName(exportName),
52
+ className: agentClassName(exportName),
53
+ exportName,
54
+ name: agentDefaultName(exportName)
55
+ };
56
+ const nameProperty = argument.getProperty("name");
57
+ if (nameProperty && Node.isPropertyAssignment(nameProperty)) {
58
+ ir.name = stringProperty(nameProperty.getInitializerOrThrow(), exportName, "name");
59
+ }
60
+ const publicRunProperty = argument.getProperty("publicRun");
61
+ if (publicRunProperty && Node.isPropertyAssignment(publicRunProperty) && booleanProperty(publicRunProperty.getInitializerOrThrow(), exportName, "publicRun")) {
62
+ ir.publicRun = true;
63
+ }
64
+ const voiceProperty = argument.getProperty("voice");
65
+ if (voiceProperty && Node.isPropertyAssignment(voiceProperty)) {
66
+ const voiceInitializer = voiceProperty.getInitializerOrThrow();
67
+ if (!Node.isObjectLiteralExpression(voiceInitializer)) {
68
+ throw diagnosticAt(
69
+ voiceInitializer,
70
+ `agent "${exportName}": \`voice\` must be an inline object literal — its presence tells codegen to emit the voice-session Durable Object`
71
+ );
72
+ }
73
+ ir.voice = true;
74
+ ir.voiceBindingName = voiceBindingName(exportName);
75
+ ir.voiceClassName = voiceClassName(exportName);
76
+ }
77
+ if (argument.getProperty("onEmail")) {
78
+ ir.onEmail = true;
79
+ }
80
+ return ir;
81
+ };
82
+ const agentsFromSource = (source) => {
83
+ const agents = [];
84
+ for (const declaration of source.getVariableDeclarations()) {
85
+ if (!declaration.isExported()) {
86
+ continue;
87
+ }
88
+ const initializer = declaration.getInitializer();
89
+ if (initializer?.getKind() !== SyntaxKind.CallExpression) {
90
+ continue;
91
+ }
92
+ const call = initializer;
93
+ const callee = call.getExpression();
94
+ if (!Node.isIdentifier(callee) || !isDefineAgent(callee)) {
95
+ continue;
96
+ }
97
+ const nameNode = declaration.getNameNode();
98
+ if (!Node.isIdentifier(nameNode)) {
99
+ throw diagnosticAt(nameNode, "defineAgent exports must be plain named exports (no destructuring)");
100
+ }
101
+ agents.push(agentFromCall(call, nameNode.getText()));
102
+ }
103
+ return agents;
104
+ };
105
+ const discoverAgents = (project, lunoraDirectory) => {
106
+ const agentsPath = join(lunoraDirectory, AGENTS_FILENAME);
107
+ if (!existsSync(agentsPath)) {
108
+ return [];
109
+ }
110
+ const source = project.getSourceFile(agentsPath) ?? project.addSourceFileAtPath(agentsPath);
111
+ const agents = agentsFromSource(source);
112
+ agents.sort((a, b) => a.exportName.localeCompare(b.exportName));
113
+ return agents;
114
+ };
115
+
116
+ export { AGENTS_FILENAME, discoverAgents };
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { SyntaxKind, Node } from 'ts-morph';
4
- import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BJ-qR7Rg.mjs';
5
5
 
6
6
  const FLAGS_FILENAME = "flags.ts";
7
7
  const FLAG_TYPES = /* @__PURE__ */ new Set(["boolean", "number", "object", "string"]);
@@ -0,0 +1,4 @@
1
+ import '@lunora/agent/component';
2
+ import '@lunora/errors';
3
+ export { G as GENERATED_HEADER, n as buildStorageColumns, e as emitAgents, a as emitApi, b as emitCollections, c as emitContainers, d as emitCrons, f as emitDataModel, g as emitDrizzleSchema, h as emitFunctions, o as emitQueues, p as emitSeed, i as emitServer, j as emitShard, k as emitVectors, l as emitWorkflows, m as emitWranglerCronTriggers } from './emit-C_29WVlW.mjs';
4
+ import './paths-BRd6JHuF.mjs';
@@ -1,4 +1,4 @@
1
- import { G as GENERATED_HEADER } from './emit-31Yg1Ee5.mjs';
1
+ import { G as GENERATED_HEADER } from './emit-C_29WVlW.mjs';
2
2
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
3
3
  import { argsObjectSchema, LUNORA_ERROR_CODES } from './LUNORA_ERROR_CODES-DvTLozCu.mjs';
4
4
 
@@ -4,32 +4,33 @@ import { performance } from 'node:perf_hooks';
4
4
  import { LunoraError } from '@lunora/errors';
5
5
  import { Node, SyntaxKind, Project } from 'ts-morph';
6
6
  import { lintSchema } from './formatAdvisories-DRhEiJUz.mjs';
7
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, inlineHandler as inlineHandler$1, procedureHandler, chainUsesWrappedCall, isDatabaseAccessor, chainHasStep, discoverFunctions } from './discoverFunctions-CZ91aenA.mjs';
8
- import discoverAuthApiCalls from './discoverAuthApiCalls-WMx8L2FG.mjs';
7
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, inlineHandler as inlineHandler$1, procedureHandler, chainUsesWrappedCall, isDatabaseAccessor, chainHasStep, discoverFunctions } from './discoverFunctions-BJ-qR7Rg.mjs';
8
+ import { discoverAgents } from './AGENTS_FILENAME-BksnAJgx.mjs';
9
+ import discoverAuthApiCalls from './discoverAuthApiCalls-Dx3K42rk.mjs';
9
10
  import { discoverContainers } from './CONTAINERS_FILENAME-DjpXMqhp.mjs';
10
- import discoverCrons from './discoverCrons-D-jrpm97.mjs';
11
+ import discoverCrons from './discoverCrons-_aosTRLr.mjs';
11
12
  import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
12
- import { C as CAPABILITIES, m as buildStorageColumns, d as emitDataModel, e as emitApi, h as emitServer, g as emitFunctions, i as emitShard, a as emitCollections, b as emitContainers, k as emitWorkflows, n as emitQueues, c as emitCrons, j as emitVectors, f as emitDrizzleSchema, o as emitSeed, l as emitWranglerCronTriggers } from './emit-31Yg1Ee5.mjs';
13
- import { discoverFlagKeys } from './FLAGS_FILENAME-fEZtzWXi.mjs';
14
- import discoverHttpRoutes from './discoverHttpRoutes-DNZLDCmm.mjs';
15
- import discoverInserts from './discoverInserts-DFRJhmCv.mjs';
16
- import discoverMaskProcedures, { discoverMaskStrategies, discoverMaskMetadata } from './discoverMaskProcedures-B5iFnZ-X.mjs';
17
- import discoverMigrations from './discoverMigrations-CdKtMlBc.mjs';
13
+ import { C as CAPABILITIES, n as buildStorageColumns, f as emitDataModel, a as emitApi, i as emitServer, h as emitFunctions, j as emitShard, b as emitCollections, c as emitContainers, l as emitWorkflows, e as emitAgents, o as emitQueues, d as emitCrons, k as emitVectors, g as emitDrizzleSchema, p as emitSeed, m as emitWranglerCronTriggers } from './emit-C_29WVlW.mjs';
14
+ import { discoverFlagKeys } from './FLAGS_FILENAME-Dg4mKUuz.mjs';
15
+ import discoverHttpRoutes from './discoverHttpRoutes-daCzuTe8.mjs';
16
+ import discoverInserts from './discoverInserts-DI4q5NxE.mjs';
17
+ import discoverMaskProcedures, { discoverMaskStrategies, discoverMaskMetadata } from './discoverMaskProcedures-BcTOEKNU.mjs';
18
+ import discoverMigrations from './discoverMigrations-VNUFvCwr.mjs';
18
19
  import { MUTATORS_FILENAME, isDefineMutatorCallee, discoverMutators } from './MUTATORS_FILENAME-BZOfUhlY.mjs';
19
- import discoverNondeterministicCalls from './discoverNondeterministicCalls-C_PrQPkA.mjs';
20
- import discoverQueries from './discoverQueries-B8W9UPrt.mjs';
20
+ import discoverNondeterministicCalls from './discoverNondeterministicCalls-S0N2xLCq.mjs';
21
+ import discoverQueries from './discoverQueries-CJnnnLpd.mjs';
21
22
  import { discoverQueues } from './QUEUES_FILENAME-Xv6Vy-Ku.mjs';
22
- import discoverR2sqlCalls from './discoverR2sqlCalls-Bm7Rfnf4.mjs';
23
- import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-B4GL4ZKm.mjs';
23
+ import discoverR2sqlCalls from './discoverR2sqlCalls-pnpicWfz.mjs';
24
+ import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-DppniPUH.mjs';
24
25
  import discoverSchema from './discoverSchema-DFWVgU5o.mjs';
25
26
  import { secretKindOf, redact } from './redact-oTmsol5A.mjs';
26
27
  import { discoverShapes } from './SHAPES_FILENAME-DOhPGi-6.mjs';
27
- import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-nosjYcvN.mjs';
28
+ import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-CnHl2rXD.mjs';
28
29
  import { e as enclosingExportName$2 } from './discover-ast-CT6BgBr4.mjs';
29
30
  import { discoverWorkflows } from './WORKFLOWS_FILENAME-B2By8S4s.mjs';
30
- import { emitApp } from './emitApp-DCP7Pr6M.mjs';
31
- import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-bg-NnLka.mjs';
32
- import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-CzhfvCIQ.mjs';
31
+ import { emitApp } from './emitApp-C9oljiZd.mjs';
32
+ import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-saZ_-kl4.mjs';
33
+ import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-Cyttekkt.mjs';
33
34
  import { buildSchemaSnapshot, serializeSchemaSnapshot } from './SCHEMA_SNAPSHOT_VERSION-D0ARY6rL.mjs';
34
35
 
35
36
  const HTTP_VERBS$1 = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
@@ -2698,6 +2699,41 @@ const discoverRelationLoads = (project, lunoraDirectory) => {
2698
2699
  return rows;
2699
2700
  };
2700
2701
 
2702
+ const SANDBOX_MODULE_SPECIFIERS = /* @__PURE__ */ new Set(["@lunora/agent", "@lunora/agent/sandbox"]);
2703
+ const scanImportDeclaration = (declaration) => {
2704
+ const found = { usesSandboxBrowser: false, usesSandboxContainer: false };
2705
+ if (!SANDBOX_MODULE_SPECIFIERS.has(declaration.getModuleSpecifierValue()) || declaration.isTypeOnly()) {
2706
+ return found;
2707
+ }
2708
+ for (const named of declaration.getNamedImports()) {
2709
+ if (named.isTypeOnly()) {
2710
+ continue;
2711
+ }
2712
+ const name = named.getNameNode().getText();
2713
+ if (name === "browserTool") {
2714
+ found.usesSandboxBrowser = true;
2715
+ } else if (name === "containerTool") {
2716
+ found.usesSandboxContainer = true;
2717
+ }
2718
+ }
2719
+ return found;
2720
+ };
2721
+ const discoverSandboxUsage = (project, lunoraDirectory) => {
2722
+ const usage = { usesSandboxBrowser: false, usesSandboxContainer: false };
2723
+ for (const filePath of listLunoraSourceFiles(lunoraDirectory)) {
2724
+ const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
2725
+ for (const declaration of sourceFile.getImportDeclarations()) {
2726
+ const found = scanImportDeclaration(declaration);
2727
+ usage.usesSandboxBrowser ||= found.usesSandboxBrowser;
2728
+ usage.usesSandboxContainer ||= found.usesSandboxContainer;
2729
+ }
2730
+ if (usage.usesSandboxBrowser && usage.usesSandboxContainer) {
2731
+ break;
2732
+ }
2733
+ }
2734
+ return usage;
2735
+ };
2736
+
2701
2737
  const literalValueOf = (node) => {
2702
2738
  if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {
2703
2739
  return node.getLiteralText();
@@ -3166,7 +3202,8 @@ const runCodegen = (options) => {
3166
3202
  const env = discoverEnv(project, lunoraDirectory);
3167
3203
  const workflows = discoverWorkflows(project, lunoraDirectory);
3168
3204
  const queues = discoverQueues(project, lunoraDirectory);
3169
- const crons = discoverCrons(project, lunoraDirectory, workflows);
3205
+ const agents = discoverAgents(project, lunoraDirectory);
3206
+ const crons = discoverCrons(project, lunoraDirectory, workflows, agents);
3170
3207
  const containers = discoverContainers(project, lunoraDirectory);
3171
3208
  const advisories = options.lint === false ? [] : lintSchema({
3172
3209
  adminRoutes: discoverAdminRoutes(project, lunoraDirectory),
@@ -3229,7 +3266,9 @@ const runCodegen = (options) => {
3229
3266
  const hasFlags = existsSync(join(lunoraDirectory, "flags.ts"));
3230
3267
  const flagKeys = hasFlags ? discoverFlagKeys(project, lunoraDirectory) : [];
3231
3268
  const hasHyperdrive = featureUsage.hyperdrive;
3232
- const hasBrowser = featureUsage.browser;
3269
+ const sandboxUsage = discoverSandboxUsage(project, lunoraDirectory);
3270
+ const usesSandbox = sandboxUsage.usesSandboxBrowser || sandboxUsage.usesSandboxContainer;
3271
+ const hasBrowser = featureUsage.browser || sandboxUsage.usesSandboxBrowser;
3233
3272
  const hasImages = featureUsage.images;
3234
3273
  const hasAnalytics = featureUsage.analytics;
3235
3274
  const hasPipelines = featureUsage.pipelines;
@@ -3249,8 +3288,9 @@ const runCodegen = (options) => {
3249
3288
  const useUmbrella = dependencies.has("lunorash");
3250
3289
  const emitStartedAt = timingEnabled ? performance.now() : 0;
3251
3290
  const dataModelContent = emitDataModel(schema, useUmbrella);
3252
- const apiContent = emitApi(functions, workflows, useUmbrella);
3291
+ const apiContent = emitApi({ agents, functions, httpRoutes, useUmbrella, workflows });
3253
3292
  const serverContent = emitServer({
3293
+ agents,
3254
3294
  containers,
3255
3295
  env,
3256
3296
  hasAccessFacade,
@@ -3272,9 +3312,10 @@ const runCodegen = (options) => {
3272
3312
  useUmbrella,
3273
3313
  workflows
3274
3314
  });
3275
- const functionsContent = emitFunctions(functions, migrations, useUmbrella, mutators, shapes);
3315
+ const functionsContent = emitFunctions({ agents, functions, migrations, mutators, shapes, useUmbrella, usesSandbox });
3276
3316
  const shardContent = emitShard({
3277
3317
  advisories,
3318
+ agents,
3278
3319
  containers,
3279
3320
  env,
3280
3321
  flagKeys,
@@ -3304,6 +3345,7 @@ const runCodegen = (options) => {
3304
3345
  const collectionsContent = emitCollections(shapes, dependencies.has("@lunora/db"), useUmbrella);
3305
3346
  const containersContent = emitContainers(containers, schema.jurisdiction);
3306
3347
  const workflowsContent = emitWorkflows(workflows);
3348
+ const agentsContent = emitAgents(agents);
3307
3349
  const queuesContent = emitQueues(queues);
3308
3350
  const cronsContent = emitCrons(crons);
3309
3351
  const vectorsContent = emitVectors(schema.vectorIndexes);
@@ -3313,6 +3355,13 @@ const runCodegen = (options) => {
3313
3355
  const wantsOpenApi = apiSpec === "openapi" || apiSpec === "both";
3314
3356
  const wantsOpenRpc = apiSpec === "openrpc" || apiSpec === "both";
3315
3357
  const appContent = emitApp({
3358
+ // Inbound-email agents (`defineAgent({ onEmail })`) → wire the worker's
3359
+ // top-level `email()` handler to each agent's `AGENT_*` Workflow binding so
3360
+ // received mail starts a durable run. Empty for email-free (and agent-free)
3361
+ // projects, so the emitted app.ts stays byte-identical.
3362
+ emailAgents: agents.filter((agent) => agent.onEmail === true).map((agent) => {
3363
+ return { bindingName: agent.bindingName, exportName: agent.exportName };
3364
+ }),
3316
3365
  hasAccess: dependencies.has("@lunora/cloudflare-access"),
3317
3366
  hasAi,
3318
3367
  hasAnalytics,
@@ -3349,6 +3398,13 @@ const runCodegen = (options) => {
3349
3398
  // Schema `.jurisdiction("…")` → pin the generated worker's DOs to the region.
3350
3399
  jurisdiction: schema.jurisdiction,
3351
3400
  useUmbrella,
3401
+ // Voice-enabled agents (`defineAgent({ voice: … })`) → wire the worker's
3402
+ // `/_lunora/voice/<exportName>` route to each agent's `VOICE_*` DO
3403
+ // namespace. Empty for voice-free (and agent-free) projects, so the
3404
+ // emitted app.ts stays byte-identical.
3405
+ voiceAgents: agents.filter((agent) => agent.voice === true && agent.voiceBindingName !== void 0).map((agent) => {
3406
+ return { bindingName: agent.voiceBindingName, exportName: agent.exportName };
3407
+ }),
3352
3408
  wantsOpenApi,
3353
3409
  wantsOpenRpc
3354
3410
  });
@@ -3384,6 +3440,7 @@ const runCodegen = (options) => {
3384
3440
  writeIfChanged(join(outputDirectory, "drizzle.shard.ts"), drizzleFiles.shard);
3385
3441
  writeIfPresent(join(outputDirectory, "containers.ts"), containersContent);
3386
3442
  writeIfPresent(join(outputDirectory, "workflows.ts"), workflowsContent);
3443
+ writeIfPresent(join(outputDirectory, "agents.ts"), agentsContent);
3387
3444
  writeIfPresent(join(outputDirectory, "queues.ts"), queuesContent);
3388
3445
  writeIfPresent(join(outputDirectory, "seed.ts"), seedContent);
3389
3446
  writeIfPresent(join(outputDirectory, "collections.ts"), collectionsContent);
@@ -3404,9 +3461,11 @@ const runCodegen = (options) => {
3404
3461
  }
3405
3462
  return {
3406
3463
  advisories,
3464
+ agents,
3407
3465
  containers,
3408
3466
  cronTriggers: emitWranglerCronTriggers(crons),
3409
3467
  generated: {
3468
+ agents: agentsContent,
3410
3469
  api: apiContent,
3411
3470
  app: appContent,
3412
3471
  collections: collectionsContent,
@@ -1,4 +1,4 @@
1
- import { G as GENERATED_HEADER } from './emit-31Yg1Ee5.mjs';
1
+ import { G as GENERATED_HEADER } from './emit-C_29WVlW.mjs';
2
2
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
3
3
  import { LUNORA_ERROR_CODES, objectSchema, argsObjectSchema, validatorIrToJsonSchema } from './LUNORA_ERROR_CODES-DvTLozCu.mjs';
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
3
  import { T as TS_EXTENSION_RE, e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
4
- import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BJ-qR7Rg.mjs';
5
5
 
6
6
  const isAuthApiCall = (call) => {
7
7
  const callee = call.getExpression();
@@ -2,7 +2,7 @@ import { LunoraError } from '@lunora/errors';
2
2
  import { isValidCronExpression, compileCronSchedule, CRON_SCHEDULE_KINDS } from '@lunora/scheduler';
3
3
  import { SyntaxKind, Node } from 'ts-morph';
4
4
  import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
5
- import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
5
+ import { listLunoraSourceFiles } from './discoverFunctions-BJ-qR7Rg.mjs';
6
6
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
7
7
 
8
8
  const CRON_METHODS = /* @__PURE__ */ new Set([...CRON_SCHEDULE_KINDS, "cron"]);
@@ -128,24 +128,38 @@ const functionPathFromArgument = (call, index, jobName) => {
128
128
  const workflowTarget = (workflow) => {
129
129
  return { workflow: { binding: workflow.bindingName, exportName: workflow.exportName } };
130
130
  };
131
- const resolveTarget = (call, index, jobName, workflowsByName) => {
131
+ const agentTarget = (agent) => {
132
+ return { workflow: { binding: agent.bindingName, exportName: agent.exportName } };
133
+ };
134
+ const resolveReferenceAccess = (argument, receiverName, byName, jobName, kind, build) => {
135
+ const receiver = argument.getExpression();
136
+ if (!Node.isIdentifier(receiver) || receiver.getText() !== receiverName) {
137
+ return void 0;
138
+ }
139
+ const definition = byName.get(argument.getName());
140
+ if (definition) {
141
+ return build(definition);
142
+ }
143
+ throw diagnosticAt(
144
+ argument,
145
+ `Cron job "${jobName}" targets ${receiverName}.${argument.getName()}, but no such ${kind} is declared in lunora/${kind}s.ts.`,
146
+ {
147
+ code: "CRON_NON_STATIC_FN",
148
+ name: "LunoraError",
149
+ status: 500
150
+ }
151
+ );
152
+ };
153
+ const resolveTarget = (call, index, jobName, workflowsByName, agentsByName) => {
132
154
  const argument = call.getArguments()[index];
133
155
  if (argument && Node.isPropertyAccessExpression(argument)) {
134
- const receiver = argument.getExpression();
135
- if (Node.isIdentifier(receiver) && receiver.getText() === "workflows") {
136
- const workflow = workflowsByName.get(argument.getName());
137
- if (workflow) {
138
- return workflowTarget(workflow);
139
- }
140
- throw diagnosticAt(
141
- argument,
142
- `Cron job "${jobName}" targets workflows.${argument.getName()}, but no such workflow is declared in lunora/workflows.ts.`,
143
- {
144
- code: "CRON_NON_STATIC_FN",
145
- name: "LunoraError",
146
- status: 500
147
- }
148
- );
156
+ const workflowReference = resolveReferenceAccess(argument, "workflows", workflowsByName, jobName, "workflow", workflowTarget);
157
+ if (workflowReference) {
158
+ return workflowReference;
159
+ }
160
+ const agentReference = resolveReferenceAccess(argument, "agents", agentsByName, jobName, "agent", agentTarget);
161
+ if (agentReference) {
162
+ return agentReference;
149
163
  }
150
164
  return { functionPath: functionPathFromArgument(call, index, jobName) };
151
165
  }
@@ -166,7 +180,7 @@ const resolveTarget = (call, index, jobName, workflowsByName) => {
166
180
  }
167
181
  return { functionPath: functionPathFromArgument(call, index, jobName) };
168
182
  };
169
- const cronFromCall = (call, callee, builderNames, workflowsByName) => {
183
+ const cronFromCall = (call, callee, builderNames, workflowsByName, agentsByName) => {
170
184
  const method = callee.getName();
171
185
  if (!CRON_METHODS.has(method)) {
172
186
  return void 0;
@@ -211,7 +225,7 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
211
225
  }
212
226
  cron = compileCronSchedule(method, objectLiteralValue(scheduleArgument, name));
213
227
  }
214
- const target = resolveTarget(call, 2, name, workflowsByName);
228
+ const target = resolveTarget(call, 2, name, workflowsByName, agentsByName);
215
229
  const argumentsNode = call.getArguments()[3];
216
230
  const args = argumentsNode && Node.isObjectLiteralExpression(argumentsNode) ? objectLiteralValue(argumentsNode, name) : {};
217
231
  return { args, cron, name, ...target };
@@ -227,10 +241,11 @@ const assertUniqueNames = (crons) => {
227
241
  seen.add(cron.name);
228
242
  }
229
243
  };
230
- const discoverCrons = (project, lunoraDirectory, workflows = []) => {
244
+ const discoverCrons = (project, lunoraDirectory, workflows = [], agents = []) => {
231
245
  const filePaths = listLunoraSourceFiles(lunoraDirectory);
232
246
  const crons = [];
233
247
  const workflowsByName = new Map(workflows.map((workflow) => [workflow.exportName, workflow]));
248
+ const agentsByName = new Map(agents.map((agent) => [agent.exportName, agent]));
234
249
  for (const filePath of filePaths) {
235
250
  const source = project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
236
251
  const builderNames = collectCronBuilderNames(source);
@@ -242,7 +257,7 @@ const discoverCrons = (project, lunoraDirectory, workflows = []) => {
242
257
  if (!Node.isPropertyAccessExpression(callee)) {
243
258
  continue;
244
259
  }
245
- const cron = cronFromCall(call, callee, builderNames, workflowsByName);
260
+ const cron = cronFromCall(call, callee, builderNames, workflowsByName, agentsByName);
246
261
  if (cron) {
247
262
  crons.push(cron);
248
263
  }
@@ -515,4 +515,4 @@ const discoverFunctions = (project, lunoraDirectory) => {
515
515
  return functions;
516
516
  };
517
517
 
518
- export { chainHasStep, chainUsesWrappedCall, classifyProcedureCall, discoverFunctions, inlineHandler, isDatabaseAccessor, listLunoraSourceFiles, lunoraRelativePath, procedureHandler };
518
+ export { chainHasStep, chainUsesWrappedCall, classifyProcedureCall, discoverFunctions, inlineHandler, isDatabaseAccessor, listLunoraSourceFiles, lunoraRelativePath, procedureHandler, unwrapHandlerReturn };
@@ -1,6 +1,6 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { Node } from 'ts-morph';
3
- import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
3
+ import { listLunoraSourceFiles, unwrapHandlerReturn } from './discoverFunctions-BJ-qR7Rg.mjs';
4
4
  import { p as parseValidator, a as parseObjectShape } from './parse-validator-BSJo1HGP.mjs';
5
5
 
6
6
  const TS_EXTENSION_RE = /\.ts$/u;
@@ -72,6 +72,13 @@ const walkRouteChain = (terminalCall, terminalStep) => {
72
72
  state.path = root.path;
73
73
  return state;
74
74
  };
75
+ const chunkTypeFromStreamTerminal = (call) => {
76
+ const handler = call.getArguments()[0];
77
+ if (!handler || !(Node.isArrowFunction(handler) || Node.isFunctionExpression(handler))) {
78
+ return "unknown";
79
+ }
80
+ return unwrapHandlerReturn(handler);
81
+ };
75
82
  const routeFromTerminal = (call, callee, exportName, filePath) => {
76
83
  const step = callee.getName();
77
84
  if (!TERMINAL_STEPS.has(step)) {
@@ -90,6 +97,7 @@ const routeFromTerminal = (call, callee, exportName, filePath) => {
90
97
  path: state.path,
91
98
  searchParams: state.searchParams,
92
99
  stream: state.stream,
100
+ ...state.stream ? { chunkType: chunkTypeFromStreamTerminal(call) } : {},
93
101
  ...state.output ? { output: state.output } : {}
94
102
  };
95
103
  };
@@ -1,6 +1,6 @@
1
1
  import { SyntaxKind, Node } from 'ts-morph';
2
2
  import { e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
3
- import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-CZ91aenA.mjs';
3
+ import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BJ-qR7Rg.mjs';
4
4
 
5
5
  const isDatabaseInsertCall = (call) => {
6
6
  const callee = call.getExpression();
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const isMaskCall = (node) => {
5
5
  if (!Node.isCallExpression(node)) {
@@ -1,7 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
3
  import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
4
- import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BJ-qR7Rg.mjs';
5
5
 
6
6
  const TS_EXTENSION_RE = /\.ts$/u;
7
7
  const isDefineMigration = (identifier) => {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const PROPERTY_CALLS = {
5
5
  "crypto.getRandomValues": "crypto.getRandomValues",
@@ -1,5 +1,5 @@
1
1
  import { SyntaxKind, Node } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const INDEX_METHODS = /* @__PURE__ */ new Set(["withIndex", "withSearchIndex"]);
5
5
  const isDatabaseQueryCall = (call) => {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const handlerOf = (call, receiver) => {
5
5
  if (receiver) {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const isRlsCall = (node) => {
5
5
  if (!Node.isCallExpression(node)) {
@@ -1,5 +1,5 @@
1
1
  import { Node } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const STORAGE_OPERATIONS = /* @__PURE__ */ new Set(["delete", "list", "read", "write"]);
5
5
  const isStorageRulesCall = (node) => {