@lunora/codegen 1.0.0-alpha.82 → 1.0.0-alpha.84

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 (42) hide show
  1. package/dist/index.d.mts +584 -549
  2. package/dist/index.d.ts +584 -549
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/DEFAULT_TARGET-CH5disA3.mjs +1 -0
  5. package/dist/packem_shared/{FLAGS_FILENAME-UPE377GV.mjs → FLAGS_FILENAME-BiJh08O0.mjs} +1 -1
  6. package/dist/packem_shared/GENERATED_HEADER-oy7DTIDi.mjs +1 -0
  7. package/dist/packem_shared/{MUTATORS_FILENAME-CsAoG-d2.mjs → MUTATORS_FILENAME-9652koWz.mjs} +1 -1
  8. package/dist/packem_shared/{NOTIFY_FILENAME-zA5OFFbv.mjs → NOTIFY_FILENAME-DeIlwPBu.mjs} +1 -1
  9. package/dist/packem_shared/{OPENRPC_VERSION-IKkrtXye.mjs → OPENRPC_VERSION-K3RTK2CP.mjs} +1 -1
  10. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DHVrsPNK.mjs +9 -0
  11. package/dist/packem_shared/{SHAPES_FILENAME-DyVUZzIk.mjs → SHAPES_FILENAME-Cwn4I4UB.mjs} +1 -1
  12. package/dist/packem_shared/{buildOpenApiDocument-XeZ1ycwi.mjs → buildOpenApiDocument-Blf3mpIz.mjs} +1 -1
  13. package/dist/packem_shared/describeErrorLevelFindings-IhNx9gPr.mjs +1 -0
  14. package/dist/packem_shared/discover-queries-B4Lw0cEr.mjs +1 -0
  15. package/dist/packem_shared/{discoverAuthApiCalls-CYdI8pkP.mjs → discoverAuthApiCalls-CVTXSguP.mjs} +1 -1
  16. package/dist/packem_shared/discoverCrons-CZ0_RXUc.mjs +1 -0
  17. package/dist/packem_shared/discoverFunctions-9GMvSwz7.mjs +1 -0
  18. package/dist/packem_shared/{discoverHttpRoutes-DmTedJlp.mjs → discoverHttpRoutes-VyBQ9CbN.mjs} +1 -1
  19. package/dist/packem_shared/{discoverInserts-CssZuKb6.mjs → discoverInserts-BGlOx2Cg.mjs} +1 -1
  20. package/dist/packem_shared/discoverMaskProcedures-DpAT4zsu.mjs +1 -0
  21. package/dist/packem_shared/{discoverMigrations-qyXaVjw1.mjs → discoverMigrations-CcOvlTA7.mjs} +1 -1
  22. package/dist/packem_shared/{discoverNondeterministicCalls-GNP4oKrf.mjs → discoverNondeterministicCalls-CVY5_-x1.mjs} +1 -1
  23. package/dist/packem_shared/discoverQueries-BFFoJLOQ.mjs +1 -0
  24. package/dist/packem_shared/{discoverR2sqlCalls-B7uqLnVS.mjs → discoverR2sqlCalls-BKn9ogOI.mjs} +1 -1
  25. package/dist/packem_shared/{discoverRlsMetadata-Bt0QK8VM.mjs → discoverRlsMetadata-B2iTIbm0.mjs} +1 -1
  26. package/dist/packem_shared/{discoverSandboxUsage-Bb2JzaIW.mjs → discoverSandboxUsage-rkLj3ZC0.mjs} +1 -1
  27. package/dist/packem_shared/discoverSchema-1zm6abY5.mjs +1 -0
  28. package/dist/packem_shared/{discoverStorageRulesMetadata-VJ_uXOFe.mjs → discoverStorageRulesMetadata-AD_GPKdF.mjs} +1 -1
  29. package/dist/packem_shared/{emit-05q6XTbd.mjs → emit-B7IUlWwi.mjs} +265 -215
  30. package/dist/packem_shared/{emitApp-C2DhPKWE.mjs → emitApp-jRD2D9kI.mjs} +111 -37
  31. package/dist/packem_shared/parse-validator-DCrBLhq7.mjs +1 -0
  32. package/package.json +10 -10
  33. package/dist/packem_shared/DEFAULT_TARGET-BYPEwgZu.mjs +0 -1
  34. package/dist/packem_shared/GENERATED_HEADER-Cphn03Kf.mjs +0 -1
  35. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DBD0oti8.mjs +0 -12
  36. package/dist/packem_shared/discover-queries-Ctpk9SA-.mjs +0 -1
  37. package/dist/packem_shared/discoverCrons-CwtPaymU.mjs +0 -1
  38. package/dist/packem_shared/discoverFunctions-CVYkUBTm.mjs +0 -1
  39. package/dist/packem_shared/discoverMaskProcedures-DQ-4yUUK.mjs +0 -1
  40. package/dist/packem_shared/discoverQueries-2A0lbpxV.mjs +0 -1
  41. package/dist/packem_shared/discoverSchema-CaTD2Sdx.mjs +0 -1
  42. package/dist/packem_shared/parse-validator-_jDrFxwt.mjs +0 -1
package/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { AdvisorExportSink, AdvisorGeoIndexUsage, AdvisorNotifyCall, AdvisorNotifyConfig, Finding, LintContext, AdvisorProcedureProtection } from '@lunora/advisor';
2
2
  export type { Finding } from '@lunora/advisor';
3
+ import '@lunora/platform';
4
+ import { Project, Node } from 'ts-morph';
3
5
  import { LunoraError } from '@lunora/errors';
4
6
  export { MESSAGE_SOLUTIONS as LUNORA_SOLUTION_RULES, type Solution as LunoraSolution, type SolutionRule as LunoraSolutionRule, findSolutionByMessage as findLunoraSolution } from '@lunora/errors';
5
- import { Node, Project } from 'ts-morph';
6
7
  import { StudioFeaturesResult } from '@lunora/shard-engine';
7
- import '@lunora/platform';
8
8
  import { Schema } from '@lunora/server';
9
9
  import { JsonSchema } from '@lunora/values';
10
10
  /**
@@ -1140,22 +1140,31 @@ interface HttpRouteIR {
1140
1140
  * pass straight through to the advisor without conversion.
1141
1141
  */
1142
1142
  interface ProcedureMiddlewareIR {
1143
- /** `true` when the handler (or a helper inside it) references `ctx.mail` / `ctx.email`. */
1144
- callsMail: boolean;
1143
+ /**
1144
+ * `true` when the handler body could be read statically — an inline function
1145
+ * expression/arrow, or a same-file identifier resolved to one. `false` for a
1146
+ * genuinely cross-file handler (an imported function, or an identifier that
1147
+ * doesn't resolve in this file), in which case every behavioural fact below
1148
+ * is `undefined` rather than a false "not observed" — the feeder never saw
1149
+ * the body, so it has nothing to report.
1150
+ */
1151
+ analyzableBody: boolean;
1152
+ /** `true` when the handler (or a helper inside it) references `ctx.mail` / `ctx.email`. `undefined` when `analyzableBody` is `false`. */
1153
+ callsMail?: boolean;
1145
1154
  /** `true` when the handler emits a structured observability event (`ctx.log` / `ctx.span` / `ctx.trace`). */
1146
- emitsEvent: boolean;
1155
+ emitsEvent?: boolean;
1147
1156
  /** `true` when a `// lunora-advisor-exempt` directive sits above the export. */
1148
1157
  exempt: boolean;
1149
1158
  /** The `-- reason` from that directive, or `""`. */
1150
1159
  exemptReason: string;
1151
1160
  /** Export binding name of the procedure (e.g. `signUp`). */
1152
1161
  exportName: string;
1153
- /** `true` when the handler fans work out to a privileged, cost-bearing dispatch surface (scheduler `runAfter`/`runAt`, a queue producer send, or a workflow create). Feeds the privileged-fanout lint. */
1154
- fanOut: boolean;
1162
+ /** `true` when the handler fans work out to a privileged, cost-bearing dispatch surface (scheduler `runAfter`/`runAt`, a queue producer send, or a workflow create). Feeds the privileged-fanout lint. `undefined` when `analyzableBody` is `false`. */
1163
+ fanOut?: boolean;
1155
1164
  /** Source file relative to `<projectRoot>/lunora/`, without extension. */
1156
1165
  file: string;
1157
1166
  /** `true` when the handler wraps work in `try`/`catch`. */
1158
- handlesErrors: boolean;
1167
+ handlesErrors?: boolean;
1159
1168
  /**
1160
1169
  * `true` when the procedure declares an email-shaped argument (`email`,
1161
1170
  * `emailAddress`, `userEmail`, …), `false` when it provably declares none,
@@ -1169,19 +1178,19 @@ interface ProcedureMiddlewareIR {
1169
1178
  hasEmailArg?: boolean;
1170
1179
  kind: "action" | "mutation" | "query";
1171
1180
  /** `true` when the handler reaches an outbound surface (`ctx.fetch`, mail, queues, storage, sql, ai, …) that can fail. */
1172
- reachesOutbound: boolean;
1181
+ reachesOutbound?: boolean;
1173
1182
  /** `true` when the handler runs any AI generation, bounded or not. */
1174
- runsAiGeneration: boolean;
1183
+ runsAiGeneration?: boolean;
1175
1184
  /** `true` when the handler throws a bare `new Error(...)` rather than a coded `LunoraError`. */
1176
- throwsBareError: boolean;
1177
- /** `true` when the handler runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound in its config literal. Feeds the `ai_unbounded_generation_public` lint. */
1178
- unboundedAiGeneration: boolean;
1185
+ throwsBareError?: boolean;
1186
+ /** `true` when the handler runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound in its config literal. Feeds the `ai_unbounded_generation_public` lint. `undefined` when `analyzableBody` is `false`. */
1187
+ unboundedAiGeneration?: boolean;
1179
1188
  /** `true` when the chain carries `.use(verifyTurnstile(...))` or a `protectPublic({ captcha })` bundle. */
1180
1189
  usesCaptcha: boolean;
1181
1190
  /** `true` when the chain carries `.use(emailGateMiddleware(...))` (`@lunora/auth`). Feeds the `signup_mutation_without_disposable_gating` lint. */
1182
1191
  usesEmailGate: boolean;
1183
- /** `true` when the handler calls `ctx.db.insertManyUnsafe(...)`, bypassing validators and triggers. Feeds the `insert_many_unsafe_user_data` lint. */
1184
- usesInsertManyUnsafe: boolean;
1192
+ /** `true` when the handler calls `ctx.db.insertManyUnsafe(...)`, bypassing validators and triggers. Feeds the `insert_many_unsafe_user_data` lint. `undefined` when `analyzableBody` is `false`. */
1193
+ usesInsertManyUnsafe?: boolean;
1185
1194
  /** `true` when the chain carries `.use(mask(...))`. */
1186
1195
  usesMask: boolean;
1187
1196
  /** `true` when the chain carries `.use(rateLimit(...))` or a `protectPublic({ rateLimit })` bundle. */
@@ -1190,8 +1199,8 @@ interface ProcedureMiddlewareIR {
1190
1199
  usesRls: boolean;
1191
1200
  /** `"internal"` for `internalQuery` / `internalMutation` / `internalAction`. */
1192
1201
  visibility: "internal" | "public";
1193
- /** `true` when the handler inserts into a user/session/account-shaped table. */
1194
- writesUserTable: boolean;
1202
+ /** `true` when the handler inserts into a user/session/account-shaped table. `undefined` when `analyzableBody` is `false`. */
1203
+ writesUserTable?: boolean;
1195
1204
  }
1196
1205
  /**
1197
1206
  * Per-procedure argument-validator snapshot, produced by the
@@ -1374,6 +1383,14 @@ interface StorageKeyAccessIR {
1374
1383
  line: number;
1375
1384
  /** The bucket method invoked with the arg-derived key, e.g. `get` / `put` / `delete` / `download`. */
1376
1385
  method: string;
1386
+ /**
1387
+ * Visibility of the enclosing procedure. `internal` procedures have no
1388
+ * untrusted caller by construction — see `owner_field_from_args_not_auth`'s
1389
+ * identical split — so `storage_key_from_user_args` drops the finding to
1390
+ * INFO rather than ERROR there. `undefined` when the access sits outside any
1391
+ * registered procedure the feeder could attribute it to.
1392
+ */
1393
+ visibility?: "internal" | "public";
1377
1394
  }
1378
1395
  /**
1379
1396
  * One `ctx.containers.<exportName>.get(name, …)` call whose instance key is derived
@@ -2040,105 +2057,575 @@ declare const lintSchema: (options: LintSchemaOptions) => Finding[];
2040
2057
  */
2041
2058
  declare const formatAdvisories: (findings: ReadonlyArray<Finding>) => string;
2042
2059
  /**
2043
- * An error thrown by codegen discovery when the user's schema or function
2044
- * source has a structural problem that can be pinpointed to a specific source
2045
- * location. A `LunoraError` subclass (`code: "CODEGEN_DIAGNOSTIC"`); the `file`,
2046
- * `line`, and `column` properties (also passed through as the base `loc`) mirror
2047
- * what Vite's error-overlay `loc` field expects so the browser can display the
2048
- * exact spot.
2060
+ * The canonical capability list. **Order is load-bearing** for the `emit-app.ts`
2061
+ * long-tail: the fluent methods are emitted in the order the `appMethod`-bearing
2062
+ * rows appear here, so this array is ordered to reproduce the original
2063
+ * `LONG_TAIL` sequence (ai, analytics, browser, hyperdrive, images, kv, payment,
2064
+ * r2sql, vectors). The `serverCtxField` rows are referenced by name in the ctx
2065
+ * interface templates, so their order here is not output-affecting.
2049
2066
  */
2050
- declare class CodegenDiagnosticError extends LunoraError {
2051
- readonly column: number;
2052
- readonly file: string;
2053
- readonly line: number;
2054
- constructor(message: string, file: string, line: number, column: number);
2055
- }
2067
+ declare const CAPABILITY_ROWS: readonly [{
2068
+ readonly contextProperty: "access";
2069
+ readonly key: "access";
2070
+ readonly moduleSpecifier: "@lunora/cloudflare-access";
2071
+ }, {
2072
+ readonly appMethod: {
2073
+ readonly configKey: "ai";
2074
+ readonly doc: "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).";
2075
+ readonly method: "ai";
2076
+ };
2077
+ readonly contextProperty: "ai";
2078
+ readonly key: "ai";
2079
+ readonly moduleSpecifier: "@lunora/ai";
2080
+ }, {
2081
+ readonly appMethod: {
2082
+ readonly configKey: "analytics";
2083
+ readonly doc: "Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).";
2084
+ readonly method: "analytics";
2085
+ };
2086
+ readonly contextProperty: "analytics";
2087
+ readonly key: "analytics";
2088
+ readonly moduleSpecifier: "@lunora/bindings/analytics";
2089
+ readonly serverCtxField: {
2090
+ readonly field: "\n /** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */\n readonly analytics: import(\"@lunora/bindings/analytics\").AnalyticsClient;";
2091
+ readonly tier: "every";
2092
+ };
2093
+ }, {
2094
+ readonly appMethod: {
2095
+ readonly configKey: "browser";
2096
+ readonly doc: "Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).";
2097
+ readonly method: "browser";
2098
+ };
2099
+ readonly contextProperty: "browser";
2100
+ readonly key: "browser";
2101
+ readonly moduleSpecifier: "@lunora/browser";
2102
+ readonly serverCtxField: {
2103
+ readonly field: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
2104
+ readonly tier: "action";
2105
+ };
2106
+ }, {
2107
+ readonly contextProperty: "containers";
2108
+ readonly key: "container";
2109
+ readonly moduleSpecifier: "@lunora/container";
2110
+ }, {
2111
+ readonly contextProperty: "flags";
2112
+ readonly key: "flags";
2113
+ readonly moduleSpecifier: "@lunora/flags";
2114
+ }, {
2115
+ readonly appMethod: {
2116
+ readonly configKey: "sql";
2117
+ readonly doc: "Wire the Hyperdrive SQL client backing `ctx.sql` — build it with `createHyperdrive` + `fromPostgresJs`/`fromNodePg`/`fromMysql2`.";
2118
+ readonly method: "hyperdrive";
2119
+ };
2120
+ readonly contextProperty: "sql";
2121
+ readonly key: "hyperdrive";
2122
+ readonly moduleSpecifier: "@lunora/hyperdrive";
2123
+ readonly serverCtxField: {
2124
+ readonly field: "\n /**\n * External database access via Hyperdrive. Non-deterministic — available only in actions. Writes here are NOT tracked by Lunora live queries; subscriptions will not re-run on external DB changes.\n */\n readonly sql: import(\"@lunora/hyperdrive\").SqlClient;";
2125
+ readonly tier: "action";
2126
+ };
2127
+ }, {
2128
+ readonly appMethod: {
2129
+ readonly configKey: "images";
2130
+ readonly doc: "Override the Images binding backing `ctx.images` (defaults to `env.IMAGES`).";
2131
+ readonly method: "images";
2132
+ };
2133
+ readonly contextProperty: "images";
2134
+ readonly key: "images";
2135
+ readonly moduleSpecifier: "@lunora/bindings/images";
2136
+ readonly serverCtxField: {
2137
+ readonly field: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
2138
+ readonly tier: "action";
2139
+ };
2140
+ }, {
2141
+ readonly appMethod: {
2142
+ readonly configKey: "kv";
2143
+ readonly doc: "Override the Workers KV binding backing `ctx.kv` (defaults to `env.KV`).";
2144
+ readonly method: "kv";
2145
+ };
2146
+ readonly contextProperty: "kv";
2147
+ readonly key: "kv";
2148
+ readonly moduleSpecifier: "@lunora/bindings/kv";
2149
+ readonly serverCtxField: {
2150
+ readonly field: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
2151
+ readonly tier: "every";
2152
+ };
2153
+ }, {
2154
+ readonly key: "mail";
2155
+ readonly moduleSpecifier: "@lunora/mail";
2156
+ }, {
2157
+ readonly contextProperty: "notify";
2158
+ readonly key: "notify";
2159
+ readonly moduleSpecifier: "@lunora/notify";
2160
+ }, {
2161
+ readonly appMethod: {
2162
+ readonly configKey: "payment";
2163
+ readonly doc: "Wire the payment options backing `ctx.payments`.";
2164
+ readonly method: "payment";
2165
+ };
2166
+ readonly contextProperty: "payments";
2167
+ readonly key: "payments";
2168
+ readonly moduleSpecifier: "@lunora/payment";
2169
+ }, {
2170
+ readonly appMethod: {
2171
+ readonly configKey: "x402";
2172
+ readonly doc: "Wire the x402 agent-wallet pay rail backing `ctx.x402` — a payment-enabled `fetch` that answers `402` challenges under a mandatory spend policy (ActionCtx-only; spends real funds).";
2173
+ readonly method: "x402";
2174
+ };
2175
+ readonly contextProperty: "x402";
2176
+ readonly key: "x402";
2177
+ readonly moduleSpecifier: "@lunora/x402/pay";
2178
+ }, {
2179
+ readonly contextProperty: "pipelines";
2180
+ readonly key: "pipelines";
2181
+ readonly moduleSpecifier: "@lunora/bindings/pipelines";
2182
+ readonly serverCtxField: {
2183
+ readonly field: "\n /** Pipelines ingestion sink (durable, R2-backed). Fire-and-forget and batched; do not read it back in-handler. */\n readonly pipelines: import(\"@lunora/bindings/pipelines\").PipelineClient;";
2184
+ readonly tier: "action";
2185
+ };
2186
+ }, {
2187
+ readonly appMethod: {
2188
+ readonly configKey: "r2sql";
2189
+ readonly doc: "Wire the R2 SQL client backing `ctx.r2sql` — build it with `createR2Sql({ accountId, apiToken, bucket })` (defaults to env `R2_SQL_TOKEN` / `R2_SQL_ACCOUNT_ID` / `R2_SQL_BUCKET`).";
2190
+ readonly method: "r2sql";
2191
+ };
2192
+ readonly contextProperty: "r2sql";
2193
+ readonly key: "r2sql";
2194
+ readonly moduleSpecifier: "@lunora/bindings/r2sql";
2195
+ readonly serverCtxField: {
2196
+ readonly field: "\n /**\n * R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.\n */\n readonly r2sql: import(\"@lunora/bindings/r2sql\").R2SqlClient;";
2197
+ readonly tier: "action";
2198
+ };
2199
+ }, {
2200
+ readonly contextProperty: "scheduler";
2201
+ readonly key: "scheduler";
2202
+ readonly moduleSpecifier: "@lunora/scheduler";
2203
+ }, {
2204
+ readonly contextProperty: "storage";
2205
+ readonly key: "storage";
2206
+ readonly moduleSpecifier: "@lunora/storage";
2207
+ }, {
2208
+ readonly appMethod: {
2209
+ readonly configKey: "vectors";
2210
+ readonly doc: "Wire the Vectorize index map backing `ctx.vectors`.";
2211
+ readonly method: "vectors";
2212
+ };
2213
+ readonly contextProperty: "vectors";
2214
+ readonly key: "vectors";
2215
+ readonly moduleSpecifier: "@lunora/bindings/vectors";
2216
+ }, {
2217
+ readonly contextProperty: "workflows";
2218
+ readonly key: "workflows";
2219
+ readonly moduleSpecifier: "@lunora/workflow";
2220
+ }];
2221
+ /** The literal union of every capability id — the single source of truth for `FeatureUsage`'s keys (so they cannot drift). */
2222
+ type CapabilityKey = (typeof CAPABILITY_ROWS)[number]["key"];
2223
+ /** The default codegen target — today's behavior, byte-identical goldens. */
2224
+ declare const DEFAULT_TARGET = "cloudflare";
2056
2225
  /**
2057
- * Build a {@link CodegenDiagnosticError} whose message includes the source
2058
- * location and whose `file`/`line`/`column` properties are set from the
2059
- * ts-morph `Node`'s position in its source file.
2226
+ * Read `target` from `&lt;projectRoot>/lunora.json`.
2060
2227
  *
2061
- * Message format: `@lunora/codegen: &lt;detail> (&lt;file>:&lt;line>:&lt;column>)`
2228
+ * This lives in `@lunora/codegen` rather than `@lunora/config` — where the rest
2229
+ * of the `lunora.json` reading lives — because `@lunora/config` depends on
2230
+ * `@lunora/codegen`, not the reverse. Putting it there and importing it here
2231
+ * would invert that edge, so config delegates to this instead and there is
2232
+ * still exactly one parser for the key.
2062
2233
  *
2063
- * `meta` is merged onto the returned error for callers that also carry the
2064
- * project-wide `LunoraError` envelope (`code`/`name`/`status`) it never
2065
- * touches `file`/`line`/`column`, and the error stays an instance of
2066
- * {@link CodegenDiagnosticError} so the Vite overlay's `instanceof` location
2067
- * lookup is unaffected.
2234
+ * Best-effort and deliberately unvalidated: a missing file, malformed JSONC, or
2235
+ * a non-string value all collapse to `undefined`, because those are shape
2236
+ * errors rather than a name the user meant. An unrecognized *name* is returned
2237
+ * as-is so the caller's registry lookup rejects it — swallowing a typo into the
2238
+ * default would ship an app to the wrong provider.
2239
+ * @param projectRoot Directory containing `lunora.json`.
2240
+ * @returns the declared target, or `undefined` when none is usable.
2068
2241
  */
2069
- declare const diagnosticAt: (node: Node, detail: string, meta?: Record<string, unknown>) => CodegenDiagnosticError;
2070
- /** The only file agents may be declared in — mirrors `lunora/workflows.ts`. */
2071
- declare const AGENTS_FILENAME = "agents.ts";
2242
+ declare const readProjectTarget: (projectRoot: string) => string | undefined;
2072
2243
  /**
2073
- * Discover every agent the project declares: exported `defineAgent()` calls in
2074
- * `lunora/agents.ts`. Returns `[]` when the file doesn't exist. Only four things
2075
- * are read statically — the optional `name` override (wrangler `workflows[].name`),
2076
- * the optional `publicRun` opt-in (the `agents:agentRun` capability gate), the
2077
- * presence of a `voice` block (which turns on the voice-session Durable Object),
2078
- * and the presence of an `onEmail` mapper (which wires the worker `email()`
2079
- * handler); the rest of the agent config (model / tools / memory / voice models /
2080
- * the `onEmail` closure body) is runtime-only, so codegen never evaluates it.
2244
+ * The target codegen should emit for: an explicit option wins, then
2245
+ * `lunora.json`, then the default.
2246
+ *
2247
+ * `runCodegen` applies this itself so a caller that forgets to pass a target
2248
+ * still emits the surface the project declared. That default matters more than
2249
+ * it looks: a call site that silently omits the target emits the *default*
2250
+ * surface with no diagnostic to notice, and the mismatch only shows up at
2251
+ * runtime on the deployed app.
2252
+ * @param projectRoot Directory containing `lunora.json`.
2253
+ * @param explicit A caller-supplied target, if any.
2254
+ * @returns the resolved target id — not guaranteed to be registered.
2081
2255
  */
2082
- declare const discoverAgents: (project: Project, lunoraDirectory: string) => AgentIR[];
2256
+ declare const resolveCodegenTarget: (projectRoot: string, explicit?: string) => string;
2083
2257
  /**
2084
- * Discover `ctx.authApi.&lt;method>(...)` (and bare `authApi.&lt;method>(...)`) calls
2085
- * under the lunora source directory and attribute each to the exported function
2086
- * (and file) performing it. Calls outside an exported declaration are dropped.
2258
+ * The target ids codegen can gate against.
2259
+ *
2260
+ * `@lunora/config`'s driver registry (`deployTargetIds`) used to assert
2261
+ * equality against this — "two id spaces for one concept" — on the theory that
2262
+ * a target with a matrix but no driver "gates a surface nothing can deploy."
2263
+ * Plan 234 found that reasoning incomplete by registering `node` here: a
2264
+ * codegen-gateable target and a deployable target are genuinely different
2265
+ * questions, and a spike/dev-only host answers the first "yes" and the second
2266
+ * "not yet" without that being a bug in either registry. See
2267
+ * `plans/234-node-host-findings.md` for the finding and `@lunora/config`'s
2268
+ * `project-config.test.ts` for where the now-relaxed invariant lives.
2269
+ * @returns the registered matrix ids, sorted.
2087
2270
  */
2088
- declare const discoverAuthApiCalls: (project: Project, lunoraDirectory: string) => AuthApiCallIR[];
2089
- /** The only file containers may be declared in — mirrors `lunora/crons.ts`. */
2090
- declare const CONTAINERS_FILENAME = "containers.ts";
2271
+ declare const platformMatrixIds: () => ReadonlyArray<string>;
2272
+ /** An advisor-style diagnostic about a target's platform capabilities. */
2273
+ interface PlatformDiagnostic {
2274
+ /** The codegen capability this concerns, when it is feature-specific. */
2275
+ feature?: CapabilityKey;
2276
+ /** Severity. All three names are errors — each drops or misdirects an emitted surface. */
2277
+ level: "error" | "warn";
2278
+ /** Human-readable explanation of the gap. */
2279
+ message: string;
2280
+ /** The lint id: `platform_unsupported_feature`, `platform_undeclared_feature`, or `platform_unknown_target`. */
2281
+ name: "platform_undeclared_feature" | "platform_unknown_target" | "platform_unsupported_feature";
2282
+ /** How to resolve it. */
2283
+ remediation: string;
2284
+ /** The requested deploy target. */
2285
+ target: string;
2286
+ }
2091
2287
  /**
2092
- * Discover every container the project declares: exported `defineContainer()`
2093
- * calls in `lunora/containers.ts`. Returns `[]` when the file doesn't exist.
2094
- * Wrangler-relevant fields (`image`, `instanceType`, `maxInstances`, `name`)
2095
- * must be static literals; runtime-only fields (`env`, `sleepAfter`, …) may be
2096
- * any expression since the generated class imports the definition object.
2097
- */
2098
- declare const discoverContainers: (project: Project, lunoraDirectory: string) => ContainerIR[];
2099
- /**
2100
- * Scan every `.ts` file under `lunoraDir` for `cronJobs()` builder registrations
2101
- * (`crons.interval(...)`, `crons.daily(...)`, `crons.cron(...)`, …) and lift them
2102
- * into {@link CronJobIR}. Schedules are compiled to standard cron expressions;
2103
- * function references are resolved to their `namespace:fn` dispatch path, while a
2104
- * `workflows.NAME` / `agents.NAME` reference (or a bare identifier naming a
2105
- * declared workflow) resolves to a durable workflow start. Names must be unique
2106
- * across the project.
2288
+ * Committed, tracked baseline file holding the blessed structural schema
2289
+ * snapshot the pre-deploy drift gate diffs against. Lives in `lunora/` (NOT the
2290
+ * gitignored `_generated/`) so it is committed alongside `schema.ts`. Leading
2291
+ * dot keeps it tucked away next to the schema it describes.
2107
2292
  */
2108
- declare const discoverCrons: (project: Project, lunoraDirectory: string, workflows?: ReadonlyArray<WorkflowIR>, agents?: ReadonlyArray<AgentIR>) => CronJobIR[];
2109
- /** The only file a feature-flag provider may be declared in — mirrors `lunora/queues.ts`. */
2110
- declare const FLAGS_FILENAME = "flags.ts";
2293
+ declare const SCHEMA_SNAPSHOT_FILENAME = ".lunora-schema.json";
2111
2294
  /**
2112
- * Discover the feature-flag provider a project declares in `lunora/flags.ts`.
2113
- * Returns `undefined` when the file doesn't exist (the app has no flags). The
2114
- * read is metadata-only and lenient: codegen wires `ctx.flags` purely from the
2115
- * file's *existence* (`run-codegen.ts`) and imports the real module for the
2116
- * provider value this IR exists solely so the config layer can reconcile the
2117
- * wrangler `flagship` binding for the Flagship binding-mode provider. Anything
2118
- * it can't read statically degrades to a `custom` provider (no binding), never
2119
- * a thrown error.
2295
+ * Construct the ts-morph `Project` codegen discovers over. Prefers the user's
2296
+ * `tsconfig.json` (when one is found walking up from `lunoraDirectory`) so
2297
+ * cross-file type resolution and path aliases work; falls back to an isolated
2298
+ * project otherwise. This is the exact construction {@link runCodegen} uses
2299
+ * when no `project` is injected exported so a long-lived caller (the Vite
2300
+ * dev-loop) can build one once and reuse it across runs via
2301
+ * {@link refreshCodegenProject} instead of re-parsing the user's whole TS
2302
+ * program on every save.
2120
2303
  */
2121
- declare const discoverFlags: (project: Project, lunoraDirectory: string) => FlagsIR | undefined;
2304
+ declare const createCodegenProject: (lunoraDirectory: string) => Project;
2122
2305
  /**
2123
- * Scan all .ts files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
2124
- * for top-level `export const x = query/mutation/action({...})` registrations.
2306
+ * Synchronise a reused {@link createCodegenProject} Project with the current
2307
+ * on-disk state of `lunoraDirectory`, so the next {@link runCodegen} sees the
2308
+ * same files a freshly-constructed Project would — without re-parsing the whole
2309
+ * TS program. Adds any on-disk source file the Project doesn't yet have, and
2310
+ * `refreshFromFileSystemSync()`es the ones it does (picking up edits); then
2311
+ * removes Project source files under `lunoraDirectory` that no longer exist on
2312
+ * disk (the classic stale-deleted-file cache bug).
2313
+ *
2314
+ * Files outside `lunoraDirectory` (e.g. those pulled in by the user's tsconfig)
2315
+ * are left untouched — they back type resolution and rarely change in the
2316
+ * dev-loop; a tsconfig change invalidates the whole cached Project upstream.
2125
2317
  */
2126
- declare const discoverFunctions: (project: Project, lunoraDirectory: string) => FunctionIR[];
2318
+ declare const refreshCodegenProject: (project: Project, lunoraDirectory: string) => void;
2127
2319
  /**
2128
- * Scan all `.ts` files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
2129
- * for `export const x = httpRoute.&lt;verb>(...)…handler(...)` typed REST routes.
2130
- * These are the headline OpenAPI target: each becomes a real `paths` entry.
2320
+ * Top-level codegen entry. Parses `&lt;projectRoot>/lunora/schema.ts` and every
2321
+ * function file under `&lt;projectRoot>/lunora/`, then writes
2322
+ * `_generated/{api,server,dataModel}.ts` next to them.
2323
+ *
2324
+ * When `LUNORA_CODEGEN_TIMING` is set (truthy), a single diagnostic summary
2325
+ * line is written to stderr with the total wall time and the discovery-vs-emit
2326
+ * split — opt-in instrumentation that is otherwise zero-cost and side-effect-free
2327
+ * on the returned {@link CodegenResult}.
2131
2328
  */
2132
- declare const discoverHttpRoutes: (project: Project, lunoraDirectory: string) => HttpRouteIR[];
2329
+ declare const runCodegen: (options: CodegenOptions) => CodegenResult;
2330
+ interface CodegenOptions {
2331
+ /**
2332
+ * Which machine-readable API spec(s) to emit into `_generated/`.
2333
+ *
2334
+ * `"openapi"` (the default) writes only `openapi.json` (OpenAPI 3.1; covers
2335
+ * both the RPC functions and `httpRouter()` REST routes). `"openrpc"` writes
2336
+ * only `openrpc.json` (OpenRPC 1.x; the RPC functions only — OpenRPC cannot
2337
+ * represent REST routes). `"both"` writes both files; `"none"` writes neither.
2338
+ *
2339
+ * Regardless of the choice, `CodegenResult.generated.openApi` and `.openRpc`
2340
+ * always carry the rendered string (computation is cheap and pure); only the
2341
+ * on-disk write is gated by this option.
2342
+ */
2343
+ apiSpec?: "both" | "none" | "openapi" | "openrpc";
2344
+ /**
2345
+ * When true, run discovery + emit (so any schema/function parse error
2346
+ * surfaces) but skip writing files to `_generated/`. The returned
2347
+ * `outputDirectory` is still the path that *would* have been written.
2348
+ */
2349
+ dryRun?: boolean;
2350
+ /**
2351
+ * Run the static schema advisor (unindexed FKs, …) during codegen.
2352
+ * Defaults to `true`. When `false`, `CodegenResult.advisories` is empty.
2353
+ * Computed regardless of `dryRun`; codegen never prints them — see
2354
+ * {@link CodegenResult.advisories}.
2355
+ */
2356
+ lint?: boolean;
2357
+ /** Override the lunora subdirectory name. Defaults to `"lunora"`. */
2358
+ lunoraDirectory?: string;
2359
+ /**
2360
+ * Reuse a previously-constructed ts-morph {@link Project} instead of building
2361
+ * a fresh one each run. The caller owns refreshing its source files from disk
2362
+ * (see {@link refreshCodegenProject}) — codegen does not re-read changed files
2363
+ * off an injected Project. Built via {@link createCodegenProject} when absent.
2364
+ * Used by the Vite dev-loop to avoid re-parsing the whole TS program on every
2365
+ * save; omit it (CLI one-shot path) to get the default fresh-Project behaviour.
2366
+ */
2367
+ project?: Project;
2368
+ /** Project root containing the `lunora/` directory. */
2369
+ projectRoot: string;
2370
+ /**
2371
+ * The deploy target codegen tailors the emitted `ctx.*` surface to.
2372
+ * Defaults to `"cloudflare"` — whose capability matrix marks every feature
2373
+ * native or emulated, so the default output is unchanged (byte-identical
2374
+ * goldens). A target that marks a used feature unsupported omits its
2375
+ * `ctx.*` surface and reports it in {@link CodegenResult.platformDiagnostics}.
2376
+ * Only `"cloudflare"` is registered until other per-target `@lunora/platform`
2377
+ * matrices land; an unknown target emits the full surface un-gated and a
2378
+ * `platform_unknown_target` diagnostic.
2379
+ */
2380
+ target?: string;
2381
+ /**
2382
+ * Re-bless the committed schema-drift baseline (`lunora/.lunora-schema.json`)
2383
+ * with the current structural snapshot. The baseline is ALWAYS written on
2384
+ * first capture (when the file is absent); set this to overwrite an existing
2385
+ * one — e.g. after the developer has added the data migration that justifies
2386
+ * a breaking change. Ignored when `dryRun` is true.
2387
+ */
2388
+ updateSchemaBaseline?: boolean;
2389
+ /**
2390
+ * Committed `wrangler.jsonc` `vars` entries that hold plaintext secrets — the
2391
+ * `plaintext_secret_in_wrangler_vars` lint input. Produced by `@lunora/config`
2392
+ * (which reads `wrangler.jsonc`) and threaded through by the CLI / Vite plugin;
2393
+ * codegen only forwards it to the advisor. Absent when no wrangler config is
2394
+ * present or the caller doesn't scan it.
2395
+ */
2396
+ wranglerVariables?: ReadonlyArray<WranglerVariableIR>;
2397
+ }
2398
+ interface CodegenResult {
2399
+ /**
2400
+ * The normalized advisor evidence the findings were produced from, so a
2401
+ * caller can score it into a health map (`scoreAdvisor`) without re-running
2402
+ * discovery. `undefined` under `lint: false`.
2403
+ *
2404
+ * Deliberately not scored here: the map carries a `generatedAt` stamp, and
2405
+ * codegen's result stays a pure function of the sources.
2406
+ */
2407
+ advisorContext?: LintContext;
2408
+ /**
2409
+ * Static schema advisor findings (e.g. unindexed foreign keys) produced
2410
+ * this run. Empty when `lint` is `false` or the schema is clean. Codegen
2411
+ * does not print these itself — each caller presents them through its own
2412
+ * channel (the CLI logger, the vite overlay, the studio Advisors table).
2413
+ * `formatAdvisories` is exported for a plain multi-line rendering.
2414
+ */
2415
+ advisories: ReadonlyArray<Finding>;
2416
+ /**
2417
+ * Agents discovered from `defineAgent` exports in `lunora/agents.ts` — the
2418
+ * list the config layer reconciles into wrangler's `workflows[]` array (an
2419
+ * agent compiles onto a Cloudflare Workflow). Agents are NOT Durable Objects,
2420
+ * so this adds no binding or migration. Empty when the project declares none.
2421
+ */
2422
+ agents: ReadonlyArray<AgentIR>;
2423
+ /**
2424
+ * Containers discovered from `defineContainer` exports in
2425
+ * `lunora/containers.ts` — the list the config layer reconciles into
2426
+ * wrangler's `containers[]`, `CONTAINER_*` Durable Object bindings, and
2427
+ * migration classes. Empty when the project declares no containers.
2428
+ */
2429
+ containers: ReadonlyArray<ContainerIR>;
2430
+ /**
2431
+ * Deduplicated cron schedules discovered from `cronJobs()` definitions —
2432
+ * the array the vite plugin reconciles into `wrangler.jsonc`'s
2433
+ * `triggers.crons`. Empty when the project declares no crons.
2434
+ */
2435
+ cronTriggers: ReadonlyArray<string>;
2436
+ generated: {
2437
+ /** WorkflowEntrypoint classes for declared agents (`_generated/agents.ts`); `""` (and not written) when no agents are declared. */
2438
+ agents: string;
2439
+ api: string;
2440
+ /** Fluent worker-composition builder (`_generated/app.ts`) — `defineApp()`. Always written. */
2441
+ app: string;
2442
+ /** Partial-replication collection factories (`_generated/collections.ts`); `""` (and not written) unless the project declares shapes and installs `@lunora/db`. */
2443
+ collections: string;
2444
+ /** Container DO classes (`_generated/containers.ts`); `""` (and not written) when no containers are declared. */
2445
+ containers: string;
2446
+ crons: string;
2447
+ dataModel: string;
2448
+ drizzleGlobal: string;
2449
+ drizzleShard: string;
2450
+ functions: string;
2451
+ /** OpenAPI 3.1.0 document (`_generated/openapi.json`), pretty-printed JSON. */
2452
+ openApi: string;
2453
+ /**
2454
+ * OpenAPI document as an importable TS module (`_generated/openapi.ts`) —
2455
+ * `export const openApiSpec`, the worker imports it for
2456
+ * `createWorker({ openApiSpec })`. Same document as `openApi`. Written
2457
+ * alongside `openapi.json` whenever `apiSpec` includes `openapi`.
2458
+ */
2459
+ openApiModule: string;
2460
+ /** OpenRPC 1.x document (`_generated/openrpc.json`), pretty-printed JSON. Always computed; written only when `apiSpec` includes `openrpc`. */
2461
+ openRpc: string;
2462
+ /**
2463
+ * OpenRPC document as an importable TS module (`_generated/openrpc.ts`) —
2464
+ * `export const openRpcSpec`, for `createWorker({ openRpcSpec })`. Same
2465
+ * document as `openRpc`. Written alongside `openrpc.json` whenever
2466
+ * `apiSpec` includes `openrpc`.
2467
+ */
2468
+ openRpcModule: string;
2469
+ /** Push-consumer queue registry (`_generated/queues.ts`); `""` (and not written) when no push queues are declared. */
2470
+ queues: string;
2471
+ /** Project-bound seed client (`_generated/seed.ts`); `""` (and not written) when `@lunora/seed` is not a declared dependency. */
2472
+ seed: string;
2473
+ server: string;
2474
+ shard: string;
2475
+ /** Static vector-index registry (`_generated/vectors.ts`) — `LUNORA_VECTOR_INDEXES`. Empty array body when the schema declares none. */
2476
+ vectors: string;
2477
+ /** WorkflowEntrypoint classes (`_generated/workflows.ts`); `""` (and not written) when no workflows are declared. */
2478
+ workflows: string;
2479
+ };
2480
+ outputDirectory: string;
2481
+ /**
2482
+ * Portability diagnostics for the requested {@link CodegenOptions.target}:
2483
+ * `ctx.*` features the app uses that the target does not support (omitted
2484
+ * from the emitted surface), or an unknown target. Empty for a
2485
+ * fully-supported app on the default Cloudflare target. Presentation is the
2486
+ * caller's job, like {@link CodegenResult.advisories}.
2487
+ */
2488
+ platformDiagnostics: ReadonlyArray<PlatformDiagnostic>;
2489
+ /**
2490
+ * Queues discovered from `defineQueue` exports in `lunora/queues.ts` — the
2491
+ * list the config layer reconciles into wrangler's `queues.producers[]` /
2492
+ * `queues.consumers[]`. Queues are NOT Durable Objects, so this adds no
2493
+ * binding or migration. Empty when the project declares no queues.
2494
+ */
2495
+ queues: ReadonlyArray<QueueIR>;
2496
+ /**
2497
+ * The CURRENT structural schema snapshot computed this run (tables + field
2498
+ * kinds/optionality + indexes/relations/shard mode + declared migration ids).
2499
+ * The pre-deploy drift gate diffs this against the committed baseline read
2500
+ * from {@link CodegenResult.schemaSnapshotPath}. Always present, even on a
2501
+ * `dryRun`.
2502
+ */
2503
+ schemaSnapshot: SchemaSnapshot;
2504
+ /** Absolute path of the committed baseline file (`lunora/.lunora-schema.json`). */
2505
+ schemaSnapshotPath: string;
2506
+ /**
2507
+ * Workflows discovered from `defineWorkflow` exports in
2508
+ * `lunora/workflows.ts` — the list the config layer reconciles into
2509
+ * wrangler's `workflows[]` array. Workflows are NOT Durable Objects, so this
2510
+ * adds no binding or migration. Empty when the project declares no workflows.
2511
+ */
2512
+ workflows: ReadonlyArray<WorkflowIR>;
2513
+ }
2514
+ /** Deduplicated, sorted names of every ERROR-level advisory in `advisories`. */
2515
+ declare const errorAdvisoryNames: (advisories: ReadonlyArray<Pick<Finding, "level" | "name">>) => ReadonlyArray<string>;
2516
+ /** Deduplicated, sorted names of every error-level platform diagnostic in `platformDiagnostics`. */
2517
+ declare const errorPlatformDiagnosticNames: (platformDiagnostics: ReadonlyArray<Pick<PlatformDiagnostic, "level" | "name">>) => ReadonlyArray<string>;
2133
2518
  /**
2134
- * Discover `ctx.db.insert("table", …)` writes under the lunora source directory
2135
- * and attribute each to the exported function (and file) performing it. Calls
2136
- * with a non-literal table argument, or outside an exported declaration, are
2137
- * dropped (`table === ""` / no enclosing export).
2519
+ * Convenience read combining both categories from a full {@link CodegenResult}
2520
+ * the shape the Vite plugin's `buildBlockingMessage` needs, which (unlike
2521
+ * the CLI's `lunora codegen`/`lunora deploy`) folds ERROR-level advisories and
2522
+ * platform diagnostics into a single blocking message with no strict/CI
2523
+ * opt-out.
2138
2524
  */
2139
- declare const discoverInserts: (project: Project, lunoraDirectory: string) => InsertWriteIR[];
2525
+ declare const describeErrorLevelFindings: (result: Pick<CodegenResult, "advisories" | "platformDiagnostics">) => {
2526
+ advisoryNames: ReadonlyArray<string>;
2527
+ platformDiagnosticNames: ReadonlyArray<string>;
2528
+ };
2140
2529
  /**
2141
- * Discover masking usage for every exported Lunora procedure under the lunora
2530
+ * An error thrown by codegen discovery when the user's schema or function
2531
+ * source has a structural problem that can be pinpointed to a specific source
2532
+ * location. A `LunoraError` subclass (`code: "CODEGEN_DIAGNOSTIC"`); the `file`,
2533
+ * `line`, and `column` properties (also passed through as the base `loc`) mirror
2534
+ * what Vite's error-overlay `loc` field expects so the browser can display the
2535
+ * exact spot.
2536
+ */
2537
+ declare class CodegenDiagnosticError extends LunoraError {
2538
+ readonly column: number;
2539
+ readonly file: string;
2540
+ readonly line: number;
2541
+ constructor(message: string, file: string, line: number, column: number);
2542
+ }
2543
+ /**
2544
+ * Build a {@link CodegenDiagnosticError} whose message includes the source
2545
+ * location and whose `file`/`line`/`column` properties are set from the
2546
+ * ts-morph `Node`'s position in its source file.
2547
+ *
2548
+ * Message format: `@lunora/codegen: &lt;detail> (&lt;file>:&lt;line>:&lt;column>)`
2549
+ *
2550
+ * `meta` is merged onto the returned error for callers that also carry the
2551
+ * project-wide `LunoraError` envelope (`code`/`name`/`status`) — it never
2552
+ * touches `file`/`line`/`column`, and the error stays an instance of
2553
+ * {@link CodegenDiagnosticError} so the Vite overlay's `instanceof` location
2554
+ * lookup is unaffected.
2555
+ */
2556
+ declare const diagnosticAt: (node: Node, detail: string, meta?: Record<string, unknown>) => CodegenDiagnosticError;
2557
+ /** The only file agents may be declared in — mirrors `lunora/workflows.ts`. */
2558
+ declare const AGENTS_FILENAME = "agents.ts";
2559
+ /**
2560
+ * Discover every agent the project declares: exported `defineAgent()` calls in
2561
+ * `lunora/agents.ts`. Returns `[]` when the file doesn't exist. Only four things
2562
+ * are read statically — the optional `name` override (wrangler `workflows[].name`),
2563
+ * the optional `publicRun` opt-in (the `agents:agentRun` capability gate), the
2564
+ * presence of a `voice` block (which turns on the voice-session Durable Object),
2565
+ * and the presence of an `onEmail` mapper (which wires the worker `email()`
2566
+ * handler); the rest of the agent config (model / tools / memory / voice models /
2567
+ * the `onEmail` closure body) is runtime-only, so codegen never evaluates it.
2568
+ */
2569
+ declare const discoverAgents: (project: Project, lunoraDirectory: string) => AgentIR[];
2570
+ /**
2571
+ * Discover `ctx.authApi.&lt;method>(...)` (and bare `authApi.&lt;method>(...)`) calls
2572
+ * under the lunora source directory and attribute each to the exported function
2573
+ * (and file) performing it. Calls outside an exported declaration are dropped.
2574
+ */
2575
+ declare const discoverAuthApiCalls: (project: Project, lunoraDirectory: string) => AuthApiCallIR[];
2576
+ /** The only file containers may be declared in — mirrors `lunora/crons.ts`. */
2577
+ declare const CONTAINERS_FILENAME = "containers.ts";
2578
+ /**
2579
+ * Discover every container the project declares: exported `defineContainer()`
2580
+ * calls in `lunora/containers.ts`. Returns `[]` when the file doesn't exist.
2581
+ * Wrangler-relevant fields (`image`, `instanceType`, `maxInstances`, `name`)
2582
+ * must be static literals; runtime-only fields (`env`, `sleepAfter`, …) may be
2583
+ * any expression since the generated class imports the definition object.
2584
+ */
2585
+ declare const discoverContainers: (project: Project, lunoraDirectory: string) => ContainerIR[];
2586
+ /**
2587
+ * Scan every `.ts` file under `lunoraDir` for `cronJobs()` builder registrations
2588
+ * (`crons.interval(...)`, `crons.daily(...)`, `crons.cron(...)`, …) and lift them
2589
+ * into {@link CronJobIR}. Schedules are compiled to standard cron expressions;
2590
+ * function references are resolved to their `namespace:fn` dispatch path, while a
2591
+ * `workflows.NAME` / `agents.NAME` reference (or a bare identifier naming a
2592
+ * declared workflow) resolves to a durable workflow start. Names must be unique
2593
+ * across the project.
2594
+ */
2595
+ declare const discoverCrons: (project: Project, lunoraDirectory: string, workflows?: ReadonlyArray<WorkflowIR>, agents?: ReadonlyArray<AgentIR>) => CronJobIR[];
2596
+ /** The only file a feature-flag provider may be declared in — mirrors `lunora/queues.ts`. */
2597
+ declare const FLAGS_FILENAME = "flags.ts";
2598
+ /**
2599
+ * Discover the feature-flag provider a project declares in `lunora/flags.ts`.
2600
+ * Returns `undefined` when the file doesn't exist (the app has no flags). The
2601
+ * read is metadata-only and lenient: codegen wires `ctx.flags` purely from the
2602
+ * file's *existence* (`run-codegen.ts`) and imports the real module for the
2603
+ * provider value — this IR exists solely so the config layer can reconcile the
2604
+ * wrangler `flagship` binding for the Flagship binding-mode provider. Anything
2605
+ * it can't read statically degrades to a `custom` provider (no binding), never
2606
+ * a thrown error.
2607
+ */
2608
+ declare const discoverFlags: (project: Project, lunoraDirectory: string) => FlagsIR | undefined;
2609
+ /**
2610
+ * Scan all .ts files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
2611
+ * for top-level `export const x = query/mutation/action({...})` registrations.
2612
+ */
2613
+ declare const discoverFunctions: (project: Project, lunoraDirectory: string) => FunctionIR[];
2614
+ /**
2615
+ * Scan all `.ts` files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
2616
+ * for `export const x = httpRoute.&lt;verb>(...)…handler(...)` typed REST routes.
2617
+ * These are the headline OpenAPI target: each becomes a real `paths` entry.
2618
+ */
2619
+ declare const discoverHttpRoutes: (project: Project, lunoraDirectory: string) => HttpRouteIR[];
2620
+ /**
2621
+ * Discover `ctx.db.insert("table", …)` writes under the lunora source directory
2622
+ * and attribute each to the exported function (and file) performing it. Calls
2623
+ * with a non-literal table argument, or outside an exported declaration, are
2624
+ * dropped (`table === ""` / no enclosing export).
2625
+ */
2626
+ declare const discoverInserts: (project: Project, lunoraDirectory: string) => InsertWriteIR[];
2627
+ /**
2628
+ * Discover masking usage for every exported Lunora procedure under the lunora
2142
2629
  * source directory — the column-level twin of `discoverRlsProcedures`. For each
2143
2630
  * procedure, records whether its builder chain includes `.use(mask(...))`, which
2144
2631
  * `(table, column)` pairs that mask declares, and which tables it reads/writes
@@ -2748,458 +3235,6 @@ declare const emitOpenRpc: (input: OpenRpcEmitInput) => string;
2748
3235
  * the object returned by {@link buildOpenRpcDocument} (reused, never recomputed).
2749
3236
  */
2750
3237
  declare const emitOpenRpcModule: (document_: Record<string, unknown>) => string;
2751
- /**
2752
- * The canonical capability list. **Order is load-bearing** for the `emit-app.ts`
2753
- * long-tail: the fluent methods are emitted in the order the `appMethod`-bearing
2754
- * rows appear here, so this array is ordered to reproduce the original
2755
- * `LONG_TAIL` sequence (ai, analytics, browser, hyperdrive, images, kv, payment,
2756
- * r2sql, vectors). The `serverCtxField` rows are referenced by name in the ctx
2757
- * interface templates, so their order here is not output-affecting.
2758
- */
2759
- declare const CAPABILITY_ROWS: readonly [{
2760
- readonly contextProperty: "access";
2761
- readonly key: "access";
2762
- readonly moduleSpecifier: "@lunora/cloudflare-access";
2763
- }, {
2764
- readonly appMethod: {
2765
- readonly configKey: "ai";
2766
- readonly doc: "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).";
2767
- readonly method: "ai";
2768
- };
2769
- readonly contextProperty: "ai";
2770
- readonly key: "ai";
2771
- readonly moduleSpecifier: "@lunora/ai";
2772
- }, {
2773
- readonly appMethod: {
2774
- readonly configKey: "analytics";
2775
- readonly doc: "Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).";
2776
- readonly method: "analytics";
2777
- };
2778
- readonly contextProperty: "analytics";
2779
- readonly key: "analytics";
2780
- readonly moduleSpecifier: "@lunora/bindings/analytics";
2781
- readonly serverCtxField: {
2782
- readonly field: "\n /** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */\n readonly analytics: import(\"@lunora/bindings/analytics\").AnalyticsClient;";
2783
- readonly tier: "every";
2784
- };
2785
- }, {
2786
- readonly appMethod: {
2787
- readonly configKey: "browser";
2788
- readonly doc: "Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).";
2789
- readonly method: "browser";
2790
- };
2791
- readonly contextProperty: "browser";
2792
- readonly key: "browser";
2793
- readonly moduleSpecifier: "@lunora/browser";
2794
- readonly serverCtxField: {
2795
- readonly field: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
2796
- readonly tier: "action";
2797
- };
2798
- }, {
2799
- readonly contextProperty: "containers";
2800
- readonly key: "container";
2801
- readonly moduleSpecifier: "@lunora/container";
2802
- }, {
2803
- readonly contextProperty: "flags";
2804
- readonly key: "flags";
2805
- readonly moduleSpecifier: "@lunora/flags";
2806
- }, {
2807
- readonly appMethod: {
2808
- readonly configKey: "sql";
2809
- readonly doc: "Wire the Hyperdrive SQL client backing `ctx.sql` — build it with `createHyperdrive` + `fromPostgresJs`/`fromNodePg`/`fromMysql2`.";
2810
- readonly method: "hyperdrive";
2811
- };
2812
- readonly contextProperty: "sql";
2813
- readonly key: "hyperdrive";
2814
- readonly moduleSpecifier: "@lunora/hyperdrive";
2815
- readonly serverCtxField: {
2816
- readonly field: "\n /**\n * External database access via Hyperdrive. Non-deterministic — available only in actions. Writes here are NOT tracked by Lunora live queries; subscriptions will not re-run on external DB changes.\n */\n readonly sql: import(\"@lunora/hyperdrive\").SqlClient;";
2817
- readonly tier: "action";
2818
- };
2819
- }, {
2820
- readonly appMethod: {
2821
- readonly configKey: "images";
2822
- readonly doc: "Override the Images binding backing `ctx.images` (defaults to `env.IMAGES`).";
2823
- readonly method: "images";
2824
- };
2825
- readonly contextProperty: "images";
2826
- readonly key: "images";
2827
- readonly moduleSpecifier: "@lunora/bindings/images";
2828
- readonly serverCtxField: {
2829
- readonly field: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
2830
- readonly tier: "action";
2831
- };
2832
- }, {
2833
- readonly appMethod: {
2834
- readonly configKey: "kv";
2835
- readonly doc: "Override the Workers KV binding backing `ctx.kv` (defaults to `env.KV`).";
2836
- readonly method: "kv";
2837
- };
2838
- readonly contextProperty: "kv";
2839
- readonly key: "kv";
2840
- readonly moduleSpecifier: "@lunora/bindings/kv";
2841
- readonly serverCtxField: {
2842
- readonly field: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
2843
- readonly tier: "every";
2844
- };
2845
- }, {
2846
- readonly key: "mail";
2847
- readonly moduleSpecifier: "@lunora/mail";
2848
- }, {
2849
- readonly contextProperty: "notify";
2850
- readonly key: "notify";
2851
- readonly moduleSpecifier: "@lunora/notify";
2852
- }, {
2853
- readonly appMethod: {
2854
- readonly configKey: "payment";
2855
- readonly doc: "Wire the payment options backing `ctx.payments`.";
2856
- readonly method: "payment";
2857
- };
2858
- readonly contextProperty: "payments";
2859
- readonly key: "payments";
2860
- readonly moduleSpecifier: "@lunora/payment";
2861
- }, {
2862
- readonly appMethod: {
2863
- readonly configKey: "x402";
2864
- readonly doc: "Wire the x402 agent-wallet pay rail backing `ctx.x402` — a payment-enabled `fetch` that answers `402` challenges under a mandatory spend policy (ActionCtx-only; spends real funds).";
2865
- readonly method: "x402";
2866
- };
2867
- readonly contextProperty: "x402";
2868
- readonly key: "x402";
2869
- readonly moduleSpecifier: "@lunora/x402/pay";
2870
- }, {
2871
- readonly contextProperty: "pipelines";
2872
- readonly key: "pipelines";
2873
- readonly moduleSpecifier: "@lunora/bindings/pipelines";
2874
- readonly serverCtxField: {
2875
- readonly field: "\n /** Pipelines ingestion sink (durable, R2-backed). Fire-and-forget and batched; do not read it back in-handler. */\n readonly pipelines: import(\"@lunora/bindings/pipelines\").PipelineClient;";
2876
- readonly tier: "action";
2877
- };
2878
- }, {
2879
- readonly appMethod: {
2880
- readonly configKey: "r2sql";
2881
- readonly doc: "Wire the R2 SQL client backing `ctx.r2sql` — build it with `createR2Sql({ accountId, apiToken, bucket })` (defaults to env `R2_SQL_TOKEN` / `R2_SQL_ACCOUNT_ID` / `R2_SQL_BUCKET`).";
2882
- readonly method: "r2sql";
2883
- };
2884
- readonly contextProperty: "r2sql";
2885
- readonly key: "r2sql";
2886
- readonly moduleSpecifier: "@lunora/bindings/r2sql";
2887
- readonly serverCtxField: {
2888
- readonly field: "\n /**\n * R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.\n */\n readonly r2sql: import(\"@lunora/bindings/r2sql\").R2SqlClient;";
2889
- readonly tier: "action";
2890
- };
2891
- }, {
2892
- readonly contextProperty: "scheduler";
2893
- readonly key: "scheduler";
2894
- readonly moduleSpecifier: "@lunora/scheduler";
2895
- }, {
2896
- readonly contextProperty: "storage";
2897
- readonly key: "storage";
2898
- readonly moduleSpecifier: "@lunora/storage";
2899
- }, {
2900
- readonly appMethod: {
2901
- readonly configKey: "vectors";
2902
- readonly doc: "Wire the Vectorize index map backing `ctx.vectors`.";
2903
- readonly method: "vectors";
2904
- };
2905
- readonly contextProperty: "vectors";
2906
- readonly key: "vectors";
2907
- readonly moduleSpecifier: "@lunora/bindings/vectors";
2908
- }, {
2909
- readonly contextProperty: "workflows";
2910
- readonly key: "workflows";
2911
- readonly moduleSpecifier: "@lunora/workflow";
2912
- }];
2913
- /** The literal union of every capability id — the single source of truth for `FeatureUsage`'s keys (so they cannot drift). */
2914
- type CapabilityKey = (typeof CAPABILITY_ROWS)[number]["key"];
2915
- /** The default codegen target — today's behavior, byte-identical goldens. */
2916
- declare const DEFAULT_TARGET = "cloudflare";
2917
- /**
2918
- * Read `target` from `&lt;projectRoot>/lunora.json`.
2919
- *
2920
- * This lives in `@lunora/codegen` rather than `@lunora/config` — where the rest
2921
- * of the `lunora.json` reading lives — because `@lunora/config` depends on
2922
- * `@lunora/codegen`, not the reverse. Putting it there and importing it here
2923
- * would invert that edge, so config delegates to this instead and there is
2924
- * still exactly one parser for the key.
2925
- *
2926
- * Best-effort and deliberately unvalidated: a missing file, malformed JSONC, or
2927
- * a non-string value all collapse to `undefined`, because those are shape
2928
- * errors rather than a name the user meant. An unrecognized *name* is returned
2929
- * as-is so the caller's registry lookup rejects it — swallowing a typo into the
2930
- * default would ship an app to the wrong provider.
2931
- * @param projectRoot Directory containing `lunora.json`.
2932
- * @returns the declared target, or `undefined` when none is usable.
2933
- */
2934
- declare const readProjectTarget: (projectRoot: string) => string | undefined;
2935
- /**
2936
- * The target codegen should emit for: an explicit option wins, then
2937
- * `lunora.json`, then the default.
2938
- *
2939
- * `runCodegen` applies this itself so a caller that forgets to pass a target
2940
- * still emits the surface the project declared. That default matters more than
2941
- * it looks: a call site that silently omits the target emits the *default*
2942
- * surface with no diagnostic to notice, and the mismatch only shows up at
2943
- * runtime on the deployed app.
2944
- * @param projectRoot Directory containing `lunora.json`.
2945
- * @param explicit A caller-supplied target, if any.
2946
- * @returns the resolved target id — not guaranteed to be registered.
2947
- */
2948
- declare const resolveCodegenTarget: (projectRoot: string, explicit?: string) => string;
2949
- /**
2950
- * The target ids codegen can gate against.
2951
- *
2952
- * Exported so `@lunora/config` can assert that its driver registry and this
2953
- * capability-matrix registry name the same targets. They are two id spaces for one
2954
- * concept: a target that ships a driver but no matrix passes the CLI's
2955
- * validation and then emits an un-gated surface, and one with a matrix but no
2956
- * driver gates a surface nothing can deploy. Today both hold exactly
2957
- * `cloudflare`, which is why nothing has noticed.
2958
- * @returns the registered matrix ids, sorted.
2959
- */
2960
- declare const platformMatrixIds: () => ReadonlyArray<string>;
2961
- /** An advisor-style diagnostic about a target's platform capabilities. */
2962
- interface PlatformDiagnostic {
2963
- /** The codegen capability this concerns, when it is feature-specific. */
2964
- feature?: CapabilityKey;
2965
- /** Severity. `platform_unsupported_feature` and `platform_unknown_target` are both errors — each drops or misdirects an emitted surface. */
2966
- level: "error" | "warn";
2967
- /** Human-readable explanation of the gap. */
2968
- message: string;
2969
- /** The lint id: `platform_unsupported_feature` or `platform_unknown_target`. */
2970
- name: "platform_unknown_target" | "platform_unsupported_feature";
2971
- /** How to resolve it. */
2972
- remediation: string;
2973
- /** The requested deploy target. */
2974
- target: string;
2975
- }
2976
- /**
2977
- * Committed, tracked baseline file holding the blessed structural schema
2978
- * snapshot the pre-deploy drift gate diffs against. Lives in `lunora/` (NOT the
2979
- * gitignored `_generated/`) so it is committed alongside `schema.ts`. Leading
2980
- * dot keeps it tucked away next to the schema it describes.
2981
- */
2982
- declare const SCHEMA_SNAPSHOT_FILENAME = ".lunora-schema.json";
2983
- /**
2984
- * Construct the ts-morph `Project` codegen discovers over. Prefers the user's
2985
- * `tsconfig.json` (when one is found walking up from `lunoraDirectory`) so
2986
- * cross-file type resolution and path aliases work; falls back to an isolated
2987
- * project otherwise. This is the exact construction {@link runCodegen} uses
2988
- * when no `project` is injected — exported so a long-lived caller (the Vite
2989
- * dev-loop) can build one once and reuse it across runs via
2990
- * {@link refreshCodegenProject} instead of re-parsing the user's whole TS
2991
- * program on every save.
2992
- */
2993
- declare const createCodegenProject: (lunoraDirectory: string) => Project;
2994
- /**
2995
- * Synchronise a reused {@link createCodegenProject} Project with the current
2996
- * on-disk state of `lunoraDirectory`, so the next {@link runCodegen} sees the
2997
- * same files a freshly-constructed Project would — without re-parsing the whole
2998
- * TS program. Adds any on-disk source file the Project doesn't yet have, and
2999
- * `refreshFromFileSystemSync()`es the ones it does (picking up edits); then
3000
- * removes Project source files under `lunoraDirectory` that no longer exist on
3001
- * disk (the classic stale-deleted-file cache bug).
3002
- *
3003
- * Files outside `lunoraDirectory` (e.g. those pulled in by the user's tsconfig)
3004
- * are left untouched — they back type resolution and rarely change in the
3005
- * dev-loop; a tsconfig change invalidates the whole cached Project upstream.
3006
- */
3007
- declare const refreshCodegenProject: (project: Project, lunoraDirectory: string) => void;
3008
- /**
3009
- * Top-level codegen entry. Parses `&lt;projectRoot>/lunora/schema.ts` and every
3010
- * function file under `&lt;projectRoot>/lunora/`, then writes
3011
- * `_generated/{api,server,dataModel}.ts` next to them.
3012
- *
3013
- * When `LUNORA_CODEGEN_TIMING` is set (truthy), a single diagnostic summary
3014
- * line is written to stderr with the total wall time and the discovery-vs-emit
3015
- * split — opt-in instrumentation that is otherwise zero-cost and side-effect-free
3016
- * on the returned {@link CodegenResult}.
3017
- */
3018
- declare const runCodegen: (options: CodegenOptions) => CodegenResult;
3019
- interface CodegenOptions {
3020
- /**
3021
- * Which machine-readable API spec(s) to emit into `_generated/`.
3022
- *
3023
- * `"openapi"` (the default) writes only `openapi.json` (OpenAPI 3.1; covers
3024
- * both the RPC functions and `httpRouter()` REST routes). `"openrpc"` writes
3025
- * only `openrpc.json` (OpenRPC 1.x; the RPC functions only — OpenRPC cannot
3026
- * represent REST routes). `"both"` writes both files; `"none"` writes neither.
3027
- *
3028
- * Regardless of the choice, `CodegenResult.generated.openApi` and `.openRpc`
3029
- * always carry the rendered string (computation is cheap and pure); only the
3030
- * on-disk write is gated by this option.
3031
- */
3032
- apiSpec?: "both" | "none" | "openapi" | "openrpc";
3033
- /**
3034
- * When true, run discovery + emit (so any schema/function parse error
3035
- * surfaces) but skip writing files to `_generated/`. The returned
3036
- * `outputDirectory` is still the path that *would* have been written.
3037
- */
3038
- dryRun?: boolean;
3039
- /**
3040
- * Run the static schema advisor (unindexed FKs, …) during codegen.
3041
- * Defaults to `true`. When `false`, `CodegenResult.advisories` is empty.
3042
- * Computed regardless of `dryRun`; codegen never prints them — see
3043
- * {@link CodegenResult.advisories}.
3044
- */
3045
- lint?: boolean;
3046
- /** Override the lunora subdirectory name. Defaults to `"lunora"`. */
3047
- lunoraDirectory?: string;
3048
- /**
3049
- * Reuse a previously-constructed ts-morph {@link Project} instead of building
3050
- * a fresh one each run. The caller owns refreshing its source files from disk
3051
- * (see {@link refreshCodegenProject}) — codegen does not re-read changed files
3052
- * off an injected Project. Built via {@link createCodegenProject} when absent.
3053
- * Used by the Vite dev-loop to avoid re-parsing the whole TS program on every
3054
- * save; omit it (CLI one-shot path) to get the default fresh-Project behaviour.
3055
- */
3056
- project?: Project;
3057
- /** Project root containing the `lunora/` directory. */
3058
- projectRoot: string;
3059
- /**
3060
- * The deploy target codegen tailors the emitted `ctx.*` surface to.
3061
- * Defaults to `"cloudflare"` — whose capability matrix marks every feature
3062
- * native or emulated, so the default output is unchanged (byte-identical
3063
- * goldens). A target that marks a used feature unsupported omits its
3064
- * `ctx.*` surface and reports it in {@link CodegenResult.platformDiagnostics}.
3065
- * Only `"cloudflare"` is registered until other per-target `@lunora/platform`
3066
- * matrices land; an unknown target emits the full surface un-gated and a
3067
- * `platform_unknown_target` diagnostic.
3068
- */
3069
- target?: string;
3070
- /**
3071
- * Re-bless the committed schema-drift baseline (`lunora/.lunora-schema.json`)
3072
- * with the current structural snapshot. The baseline is ALWAYS written on
3073
- * first capture (when the file is absent); set this to overwrite an existing
3074
- * one — e.g. after the developer has added the data migration that justifies
3075
- * a breaking change. Ignored when `dryRun` is true.
3076
- */
3077
- updateSchemaBaseline?: boolean;
3078
- /**
3079
- * Committed `wrangler.jsonc` `vars` entries that hold plaintext secrets — the
3080
- * `plaintext_secret_in_wrangler_vars` lint input. Produced by `@lunora/config`
3081
- * (which reads `wrangler.jsonc`) and threaded through by the CLI / Vite plugin;
3082
- * codegen only forwards it to the advisor. Absent when no wrangler config is
3083
- * present or the caller doesn't scan it.
3084
- */
3085
- wranglerVariables?: ReadonlyArray<WranglerVariableIR>;
3086
- }
3087
- interface CodegenResult {
3088
- /**
3089
- * The normalized advisor evidence the findings were produced from, so a
3090
- * caller can score it into a health map (`scoreAdvisor`) without re-running
3091
- * discovery. `undefined` under `lint: false`.
3092
- *
3093
- * Deliberately not scored here: the map carries a `generatedAt` stamp, and
3094
- * codegen's result stays a pure function of the sources.
3095
- */
3096
- advisorContext?: LintContext;
3097
- /**
3098
- * Static schema advisor findings (e.g. unindexed foreign keys) produced
3099
- * this run. Empty when `lint` is `false` or the schema is clean. Codegen
3100
- * does not print these itself — each caller presents them through its own
3101
- * channel (the CLI logger, the vite overlay, the studio Advisors table).
3102
- * `formatAdvisories` is exported for a plain multi-line rendering.
3103
- */
3104
- advisories: ReadonlyArray<Finding>;
3105
- /**
3106
- * Agents discovered from `defineAgent` exports in `lunora/agents.ts` — the
3107
- * list the config layer reconciles into wrangler's `workflows[]` array (an
3108
- * agent compiles onto a Cloudflare Workflow). Agents are NOT Durable Objects,
3109
- * so this adds no binding or migration. Empty when the project declares none.
3110
- */
3111
- agents: ReadonlyArray<AgentIR>;
3112
- /**
3113
- * Containers discovered from `defineContainer` exports in
3114
- * `lunora/containers.ts` — the list the config layer reconciles into
3115
- * wrangler's `containers[]`, `CONTAINER_*` Durable Object bindings, and
3116
- * migration classes. Empty when the project declares no containers.
3117
- */
3118
- containers: ReadonlyArray<ContainerIR>;
3119
- /**
3120
- * Deduplicated cron schedules discovered from `cronJobs()` definitions —
3121
- * the array the vite plugin reconciles into `wrangler.jsonc`'s
3122
- * `triggers.crons`. Empty when the project declares no crons.
3123
- */
3124
- cronTriggers: ReadonlyArray<string>;
3125
- generated: {
3126
- /** WorkflowEntrypoint classes for declared agents (`_generated/agents.ts`); `""` (and not written) when no agents are declared. */
3127
- agents: string;
3128
- api: string;
3129
- /** Fluent worker-composition builder (`_generated/app.ts`) — `defineApp()`. Always written. */
3130
- app: string;
3131
- /** Partial-replication collection factories (`_generated/collections.ts`); `""` (and not written) unless the project declares shapes and installs `@lunora/db`. */
3132
- collections: string;
3133
- /** Container DO classes (`_generated/containers.ts`); `""` (and not written) when no containers are declared. */
3134
- containers: string;
3135
- crons: string;
3136
- dataModel: string;
3137
- drizzleGlobal: string;
3138
- drizzleShard: string;
3139
- functions: string;
3140
- /** OpenAPI 3.1.0 document (`_generated/openapi.json`), pretty-printed JSON. */
3141
- openApi: string;
3142
- /**
3143
- * OpenAPI document as an importable TS module (`_generated/openapi.ts`) —
3144
- * `export const openApiSpec`, the worker imports it for
3145
- * `createWorker({ openApiSpec })`. Same document as `openApi`. Written
3146
- * alongside `openapi.json` whenever `apiSpec` includes `openapi`.
3147
- */
3148
- openApiModule: string;
3149
- /** OpenRPC 1.x document (`_generated/openrpc.json`), pretty-printed JSON. Always computed; written only when `apiSpec` includes `openrpc`. */
3150
- openRpc: string;
3151
- /**
3152
- * OpenRPC document as an importable TS module (`_generated/openrpc.ts`) —
3153
- * `export const openRpcSpec`, for `createWorker({ openRpcSpec })`. Same
3154
- * document as `openRpc`. Written alongside `openrpc.json` whenever
3155
- * `apiSpec` includes `openrpc`.
3156
- */
3157
- openRpcModule: string;
3158
- /** Push-consumer queue registry (`_generated/queues.ts`); `""` (and not written) when no push queues are declared. */
3159
- queues: string;
3160
- /** Project-bound seed client (`_generated/seed.ts`); `""` (and not written) when `@lunora/seed` is not a declared dependency. */
3161
- seed: string;
3162
- server: string;
3163
- shard: string;
3164
- /** Static vector-index registry (`_generated/vectors.ts`) — `LUNORA_VECTOR_INDEXES`. Empty array body when the schema declares none. */
3165
- vectors: string;
3166
- /** WorkflowEntrypoint classes (`_generated/workflows.ts`); `""` (and not written) when no workflows are declared. */
3167
- workflows: string;
3168
- };
3169
- outputDirectory: string;
3170
- /**
3171
- * Portability diagnostics for the requested {@link CodegenOptions.target}:
3172
- * `ctx.*` features the app uses that the target does not support (omitted
3173
- * from the emitted surface), or an unknown target. Empty for a
3174
- * fully-supported app on the default Cloudflare target. Presentation is the
3175
- * caller's job, like {@link CodegenResult.advisories}.
3176
- */
3177
- platformDiagnostics: ReadonlyArray<PlatformDiagnostic>;
3178
- /**
3179
- * Queues discovered from `defineQueue` exports in `lunora/queues.ts` — the
3180
- * list the config layer reconciles into wrangler's `queues.producers[]` /
3181
- * `queues.consumers[]`. Queues are NOT Durable Objects, so this adds no
3182
- * binding or migration. Empty when the project declares no queues.
3183
- */
3184
- queues: ReadonlyArray<QueueIR>;
3185
- /**
3186
- * The CURRENT structural schema snapshot computed this run (tables + field
3187
- * kinds/optionality + indexes/relations/shard mode + declared migration ids).
3188
- * The pre-deploy drift gate diffs this against the committed baseline read
3189
- * from {@link CodegenResult.schemaSnapshotPath}. Always present, even on a
3190
- * `dryRun`.
3191
- */
3192
- schemaSnapshot: SchemaSnapshot;
3193
- /** Absolute path of the committed baseline file (`lunora/.lunora-schema.json`). */
3194
- schemaSnapshotPath: string;
3195
- /**
3196
- * Workflows discovered from `defineWorkflow` exports in
3197
- * `lunora/workflows.ts` — the list the config layer reconciles into
3198
- * wrangler's `workflows[]` array. Workflows are NOT Durable Objects, so this
3199
- * adds no binding or migration. Empty when the project declares no workflows.
3200
- */
3201
- workflows: ReadonlyArray<WorkflowIR>;
3202
- }
3203
3238
  /**
3204
3239
  * Build a {@link SchemaSnapshot} from a parsed {@link SchemaIR} and the set of
3205
3240
  * declared migration ids. Tables and migration ids are sorted so the emitted
@@ -3291,4 +3326,4 @@ declare const secretKindOf: (value: string) => string | undefined;
3291
3326
  /** A redacted preview of a secret value — first 4 chars plus its length, never the full value. */
3292
3327
  declare const redact: (value: string) => string;
3293
3328
  declare const VERSION = "0.0.0";
3294
- export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type CronJobIR, DEFAULT_TARGET, type DriftChange, type DriftScope, type EmitAppOptions, FLAGS_FILENAME, type FieldSnapshot, type FlagsIR, type FunctionIR, GENERATED_HEADER, type HttpRouteIR, type IndexIR, type IndexSnapshot, type InsertWriteIR, LUNORA_ERROR_CODES, type LintSchemaOptions, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcEmitInput, type PlatformDiagnostic, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type R2sqlCallIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, VERSION, type ValidatorIR, type VectorIndexIR, WORKFLOWS_FILENAME, type WorkflowIR, type WranglerVariableIR, buildOpenApiDocument, buildOpenRpcDocument, buildSchemaSnapshot, createCodegenProject, diagnosticAt, diffSchemaSnapshots, discoverAgents, discoverAuthApiCalls, discoverContainers, discoverCrons, discoverFlags, discoverFunctions, discoverHttpRoutes, discoverInserts, discoverMaskProcedures, discoverMigrations, discoverMutators, discoverNondeterministicCalls, discoverNotifyCalls, discoverNotifyConfig, discoverQueries, discoverQueues, discoverR2sqlCalls, discoverRlsMetadata, discoverRlsProcedures, discoverSandboxUsage, discoverSchema, discoverShapes, discoverStorageRulesMetadata, discoverWorkflows, emitAgents, emitApi, emitApp, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitOpenApi, emitOpenApiModule, emitOpenRpc, emitOpenRpcModule, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, evaluateSchemaDrift, formatAdvisories, lintSchema, parseSchemaSnapshot, platformMatrixIds, readPackageDependencies, readProjectTarget, redact, refreshCodegenProject, resolveCodegenTarget, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, toAdvisorContext, validatorIrToJsonSchema };
3329
+ export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type CronJobIR, DEFAULT_TARGET, type DriftChange, type DriftScope, type EmitAppOptions, FLAGS_FILENAME, type FieldSnapshot, type FlagsIR, type FunctionIR, GENERATED_HEADER, type HttpRouteIR, type IndexIR, type IndexSnapshot, type InsertWriteIR, LUNORA_ERROR_CODES, type LintSchemaOptions, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcEmitInput, type PlatformDiagnostic, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type R2sqlCallIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, VERSION, type ValidatorIR, type VectorIndexIR, WORKFLOWS_FILENAME, type WorkflowIR, type WranglerVariableIR, buildOpenApiDocument, buildOpenRpcDocument, buildSchemaSnapshot, createCodegenProject, describeErrorLevelFindings, diagnosticAt, diffSchemaSnapshots, discoverAgents, discoverAuthApiCalls, discoverContainers, discoverCrons, discoverFlags, discoverFunctions, discoverHttpRoutes, discoverInserts, discoverMaskProcedures, discoverMigrations, discoverMutators, discoverNondeterministicCalls, discoverNotifyCalls, discoverNotifyConfig, discoverQueries, discoverQueues, discoverR2sqlCalls, discoverRlsMetadata, discoverRlsProcedures, discoverSandboxUsage, discoverSchema, discoverShapes, discoverStorageRulesMetadata, discoverWorkflows, emitAgents, emitApi, emitApp, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitOpenApi, emitOpenApiModule, emitOpenRpc, emitOpenRpcModule, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, errorAdvisoryNames, errorPlatformDiagnosticNames, evaluateSchemaDrift, formatAdvisories, lintSchema, parseSchemaSnapshot, platformMatrixIds, readPackageDependencies, readProjectTarget, redact, refreshCodegenProject, resolveCodegenTarget, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, toAdvisorContext, validatorIrToJsonSchema };