@lunora/codegen 1.0.0-alpha.249 → 1.0.0-alpha.250

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AdvisorExportSink, AdvisorGeoIndexUsage, AdvisorNotifyCall, AdvisorNotifyConfig, Finding, LintContext, AdvisorProcedureProtection } from '@lunora/advisor';
2
2
  export type { Finding } from '@lunora/advisor';
3
- import { Project, Node } from 'ts-morph';
3
+ import { SourceFile, Project, Node } from 'ts-morph';
4
4
  import { LunoraError } from '@lunora/errors';
5
5
  export { MESSAGE_SOLUTIONS as LUNORA_SOLUTION_RULES, type Solution as LunoraSolution, type SolutionRule as LunoraSolutionRule, findSolutionByMessage as findLunoraSolution } from '@lunora/errors';
6
6
  import { Schema } from '@lunora/server';
@@ -2409,18 +2409,20 @@ declare const lintSchema: (options: LintSchemaOptions) => Finding[];
2409
2409
  */
2410
2410
  declare const formatAdvisories: (findings: ReadonlyArray<Finding>) => string;
2411
2411
  /**
2412
- * The canonical capability list. **Order is load-bearing** for the `emit-app.ts`
2413
- * long-tail: the fluent methods are emitted in the order the `appMethod`-bearing
2414
- * rows appear here, so this array is ordered to reproduce the original
2415
- * `LONG_TAIL` sequence (ai, analytics, browser, hyperdrive, images, kv, payment,
2416
- * r2sql, vectors). The `serverCtxField` rows are referenced by name in the ctx
2417
- * interface templates, so their order here is not output-affecting.
2412
+ * The canonical capability list. **Order is load-bearing** — every consumer
2413
+ * emits in row order (see the module doc). The `appMethod` rows reproduce the
2414
+ * original `LONG_TAIL` builder sequence (ai, aiSearch, analytics, artifacts, browser, hyperdrive,
2415
+ * images, kv, payment, x402, r2sql, vectors), and the same order places the
2416
+ * `ctx.*` fields and the ShardDO wiring.
2418
2417
  */
2419
2418
  declare const CAPABILITY_ROWS: readonly [{
2420
2419
  readonly contextProperty: "access";
2421
2420
  readonly key: "access";
2422
2421
  readonly moduleSpecifier: "@lunora/cloudflare-access";
2423
2422
  readonly requiredPackage: "@lunora/cloudflare-access";
2423
+ readonly serverCtxField: "\n /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */\n readonly access: import(\"@lunora/cloudflare-access/context\").AccessFacade;";
2424
+ readonly shardBinding: "bespoke";
2425
+ readonly tier: "every";
2424
2426
  }, {
2425
2427
  readonly appMethod: {
2426
2428
  readonly configKey: "ai";
@@ -2431,6 +2433,29 @@ declare const CAPABILITY_ROWS: readonly [{
2431
2433
  readonly key: "ai";
2432
2434
  readonly moduleSpecifier: "@lunora/ai";
2433
2435
  readonly requiredPackage: "@lunora/ai";
2436
+ readonly shardBinding: "bespoke";
2437
+ readonly tier: "action";
2438
+ }, {
2439
+ readonly appMethod: {
2440
+ readonly configKey: "aiSearch";
2441
+ readonly doc: "Override the AI Search namespace binding backing `ctx.aiSearch` (defaults to `env.AI_SEARCH`).";
2442
+ readonly method: "aiSearch";
2443
+ };
2444
+ readonly contextProperty: "aiSearch";
2445
+ readonly key: "aiSearch";
2446
+ readonly moduleSpecifier: "@lunora/bindings/ai-search";
2447
+ readonly requiredPackage: "@lunora/bindings";
2448
+ readonly serverCtxField: "\n /** Cloudflare AI Search namespace (`ai_search_namespaces`): `.get(name)` an instance, then `search` / `chatCompletions`. Billed, non-deterministic network I/O — available only in actions. */\n readonly aiSearch: import(\"@lunora/bindings/ai-search\").AiSearch;";
2449
+ readonly shardBinding: {
2450
+ readonly binding: {
2451
+ readonly envName: "AI_SEARCH";
2452
+ };
2453
+ readonly clientType: "AiSearch";
2454
+ readonly missingMessage: "ctx.aiSearch: no AI Search binding found. Add an \\`ai_search_namespaces\\` binding (env.AI_SEARCH) to wrangler.jsonc, or point \\`defineApp().aiSearch((env) => …)\\` at yours.";
2455
+ readonly stubMethods: readonly ["chatCompletions", "create", "delete", "get", "list", "search"];
2456
+ readonly syncStubMethods: readonly ["get"];
2457
+ };
2458
+ readonly tier: "action";
2434
2459
  }, {
2435
2460
  readonly appMethod: {
2436
2461
  readonly configKey: "analytics";
@@ -2441,10 +2466,47 @@ declare const CAPABILITY_ROWS: readonly [{
2441
2466
  readonly key: "analytics";
2442
2467
  readonly moduleSpecifier: "@lunora/bindings/analytics";
2443
2468
  readonly requiredPackage: "@lunora/bindings";
2444
- readonly serverCtxField: {
2445
- 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;";
2446
- readonly tier: "every";
2469
+ readonly serverCtxField: "\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;";
2470
+ readonly shardBinding: {
2471
+ readonly binding: {
2472
+ readonly bindingType: "AnalyticsEngineDatasetLike";
2473
+ readonly envName: "ANALYTICS";
2474
+ readonly factory: {
2475
+ readonly name: "createAnalytics";
2476
+ };
2477
+ };
2478
+ readonly clientType: "AnalyticsClient";
2479
+ readonly missingMessage: "ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().";
2480
+ readonly stubMethods: readonly ["track", "writeDataPoint"];
2481
+ readonly syncStubMethods: readonly ["track", "writeDataPoint"];
2482
+ };
2483
+ readonly tier: "every";
2484
+ }, {
2485
+ readonly appMethod: {
2486
+ readonly configKey: "artifacts";
2487
+ readonly doc: "Override the Artifacts binding backing `ctx.artifacts` (defaults to `env.ARTIFACTS`).";
2488
+ readonly method: "artifacts";
2489
+ };
2490
+ readonly contextProperty: "artifacts";
2491
+ readonly key: "artifacts";
2492
+ readonly moduleSpecifier: "@lunora/bindings/artifacts";
2493
+ readonly requiredPackage: "@lunora/bindings";
2494
+ readonly serverCtxField: "\n /** Cloudflare Artifacts repos (create/import/fork, Git tokens, read commits and files). Non-deterministic — available only in actions. Writes go through `git push` with a token, not this client. */\n readonly artifacts: import(\"@lunora/bindings/artifacts\").ArtifactsClient;";
2495
+ readonly shardBinding: {
2496
+ readonly binding: {
2497
+ readonly bindingType: "ArtifactsBindingLike";
2498
+ readonly envName: "ARTIFACTS";
2499
+ readonly factory: {
2500
+ readonly name: "createArtifacts";
2501
+ readonly option: "binding";
2502
+ };
2503
+ };
2504
+ readonly clientType: "ArtifactsClient";
2505
+ readonly missingMessage: "ctx.artifacts: no Artifacts binding found. Add an \\`artifacts\\` binding ({ binding: \\\"ARTIFACTS\\\", namespace }) to wrangler.jsonc, or point ctx.artifacts at another binding with defineApp().artifacts((env) => env.<BINDING>).";
2506
+ readonly stubMethods: readonly ["authenticatedRemote", "create", "delete", "import", "info", "list", "withRepo"];
2507
+ readonly syncStubMethods: readonly ["authenticatedRemote"];
2447
2508
  };
2509
+ readonly tier: "action";
2448
2510
  }, {
2449
2511
  readonly appMethod: {
2450
2512
  readonly configKey: "browser";
@@ -2455,10 +2517,13 @@ declare const CAPABILITY_ROWS: readonly [{
2455
2517
  readonly key: "browser";
2456
2518
  readonly moduleSpecifier: "@lunora/browser";
2457
2519
  readonly requiredPackage: "@lunora/browser";
2458
- readonly serverCtxField: {
2459
- readonly field: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
2460
- readonly tier: "action";
2520
+ readonly serverCtxField: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
2521
+ readonly shardBinding: {
2522
+ readonly clientType: "Browser";
2523
+ readonly missingMessage: "ctx.browser: provide a \\`browser\\` config thunk, e.g. \\`browser: (env) => createBrowser({ binding: env.BROWSER, launch })\\` with \\`import { launch } from '@cloudflare/playwright'\\`. Session reuse (connect/sessions) additionally needs those two exports passed the same way.";
2524
+ readonly stubMethods: readonly ["cancelCrawl", "connect", "content", "crawl", "crawlResult", "launch", "pdf", "quickAction", "scrape", "screenshot", "sessions"];
2461
2525
  };
2526
+ readonly tier: "action";
2462
2527
  }, {
2463
2528
  readonly contextProperty: "containers";
2464
2529
  readonly key: "container";
@@ -2477,10 +2542,13 @@ declare const CAPABILITY_ROWS: readonly [{
2477
2542
  readonly key: "hyperdrive";
2478
2543
  readonly moduleSpecifier: "@lunora/hyperdrive";
2479
2544
  readonly requiredPackage: "@lunora/hyperdrive";
2480
- readonly serverCtxField: {
2481
- 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;";
2482
- readonly tier: "action";
2545
+ readonly serverCtxField: "\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;";
2546
+ readonly shardBinding: {
2547
+ readonly clientType: "SqlClient";
2548
+ readonly missingMessage: "ctx.sql: provide a \\`sql\\` config thunk that builds a SqlClient from your driver, e.g. \\`sql: (env) => fromPostgresJs(postgres(env.HYPERDRIVE.connectionString))\\`.";
2549
+ readonly stubMethods: readonly ["query"];
2483
2550
  };
2551
+ readonly tier: "action";
2484
2552
  }, {
2485
2553
  readonly appMethod: {
2486
2554
  readonly configKey: "images";
@@ -2491,10 +2559,21 @@ declare const CAPABILITY_ROWS: readonly [{
2491
2559
  readonly key: "images";
2492
2560
  readonly moduleSpecifier: "@lunora/bindings/images";
2493
2561
  readonly requiredPackage: "@lunora/bindings";
2494
- readonly serverCtxField: {
2495
- readonly field: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
2496
- readonly tier: "action";
2562
+ readonly serverCtxField: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
2563
+ readonly shardBinding: {
2564
+ readonly binding: {
2565
+ readonly bindingType: "ImagesBindingLike";
2566
+ readonly envName: "IMAGES";
2567
+ readonly factory: {
2568
+ readonly name: "createImages";
2569
+ readonly option: "binding";
2570
+ };
2571
+ };
2572
+ readonly clientType: "Images";
2573
+ readonly missingMessage: "ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().";
2574
+ readonly stubMethods: readonly ["info", "transform"];
2497
2575
  };
2576
+ readonly tier: "action";
2498
2577
  }, {
2499
2578
  readonly appMethod: {
2500
2579
  readonly configKey: "kv";
@@ -2505,10 +2584,22 @@ declare const CAPABILITY_ROWS: readonly [{
2505
2584
  readonly key: "kv";
2506
2585
  readonly moduleSpecifier: "@lunora/bindings/kv";
2507
2586
  readonly requiredPackage: "@lunora/bindings";
2508
- readonly serverCtxField: {
2509
- readonly field: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
2510
- readonly tier: "every";
2587
+ readonly serverCtxField: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
2588
+ readonly shardBinding: {
2589
+ readonly binding: {
2590
+ readonly bindingType: "KVNamespaceLike";
2591
+ readonly envName: "KV";
2592
+ readonly factory: {
2593
+ readonly name: "createKv";
2594
+ readonly option: "namespace";
2595
+ };
2596
+ readonly unvouchableReads: readonly ["get", "getRaw", "getWithMetadata", "list"];
2597
+ };
2598
+ readonly clientType: "Kv";
2599
+ readonly missingMessage: "ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().";
2600
+ readonly stubMethods: readonly ["delete", "get", "getRaw", "getWithMetadata", "list", "put"];
2511
2601
  };
2602
+ readonly tier: "every";
2512
2603
  }, {
2513
2604
  readonly key: "mail";
2514
2605
  readonly moduleSpecifier: "@lunora/mail";
@@ -2541,10 +2632,21 @@ declare const CAPABILITY_ROWS: readonly [{
2541
2632
  readonly key: "pipelines";
2542
2633
  readonly moduleSpecifier: "@lunora/bindings/pipelines";
2543
2634
  readonly requiredPackage: "@lunora/bindings";
2544
- readonly serverCtxField: {
2545
- 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;";
2546
- readonly tier: "action";
2635
+ readonly serverCtxField: "\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;";
2636
+ readonly shardBinding: {
2637
+ readonly binding: {
2638
+ readonly bindingType: "PipelineBindingLike";
2639
+ readonly envName: "PIPELINES";
2640
+ readonly factory: {
2641
+ readonly name: "createPipelines";
2642
+ readonly option: "binding";
2643
+ };
2644
+ };
2645
+ readonly clientType: "PipelineClient";
2646
+ readonly missingMessage: "ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().";
2647
+ readonly stubMethods: readonly ["send"];
2547
2648
  };
2649
+ readonly tier: "action";
2548
2650
  }, {
2549
2651
  readonly appMethod: {
2550
2652
  readonly configKey: "r2sql";
@@ -2555,10 +2657,9 @@ declare const CAPABILITY_ROWS: readonly [{
2555
2657
  readonly key: "r2sql";
2556
2658
  readonly moduleSpecifier: "@lunora/bindings/r2sql";
2557
2659
  readonly requiredPackage: "@lunora/bindings";
2558
- readonly serverCtxField: {
2559
- 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;";
2560
- readonly tier: "action";
2561
- };
2660
+ readonly serverCtxField: "\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;";
2661
+ readonly shardBinding: "bespoke";
2662
+ readonly tier: "action";
2562
2663
  }, {
2563
2664
  readonly contextProperty: "scheduler";
2564
2665
  readonly key: "scheduler";
@@ -2583,6 +2684,51 @@ declare const CAPABILITY_ROWS: readonly [{
2583
2684
  }];
2584
2685
  /** The literal union of every capability id — the single source of truth for `FeatureUsage`'s keys (so they cannot drift). */
2585
2686
  type CapabilityKey = (typeof CAPABILITY_ROWS)[number]["key"];
2687
+ /**
2688
+ * Code-usage signals for every optional, package-backed feature, in a single
2689
+ * pass over the `lunora/` source set. Each flag is `true` when a source imports
2690
+ * the feature's `@lunora/*` package or reads its generated `ctx.*` helper. This
2691
+ * is the one detection path for all of them — it subsumes the old standalone
2692
+ * `discoverAiUsage` / `discoverPaymentUsage` probes (which were line-for-line
2693
+ * copies of this same import-or-`ctx.X` check).
2694
+ *
2695
+ * The key set is derived from the {@link CAPABILITIES} table (its
2696
+ * {@link CapabilityKey} union), so a capability added there is automatically
2697
+ * probed here — the two can't drift. `ai` and `payments` gate whether codegen
2698
+ * wires the SDK into the generated worker (so a non-AI app never imports
2699
+ * `@lunora/ai`); the rest additionally feed the studio's nav gating via
2700
+ * `buildStudioFeatures`. `mail` is import-only — it has no `ctx.mail`
2701
+ * helper (mail is reached through its own client), so only a `@lunora/mail`
2702
+ * import flips it here; a worker-entry wiring outside `lunora/` is caught
2703
+ * instead by the package-dependency signal in `buildStudioFeatures`.
2704
+ */
2705
+ type FeatureUsage = Record<CapabilityKey, boolean>;
2706
+ /**
2707
+ * The set of `ctx` helper names the source reaches — a direct `ctx.PROPERTY`
2708
+ * access, or a destructuring of the property off the context (`const { kv } =
2709
+ * ctx`, `async ({ ctx: { kv } }) => …`).
2710
+ *
2711
+ * The context is resolved by BINDING, not by the identifier text `ctx`. A
2712
+ * handler receives it as a property of one destructured argument, so the local
2713
+ * name it lands under is the handler's to pick: `{ ctx }`, `{ ctx: context }`
2714
+ * and `{ ctx: { secrets } }` are the same read. Matching the text `ctx`
2715
+ * recognised only the first — and for `secrets`, which has no import arm and no
2716
+ * {@link CAPABILITIES} row, nothing else covered the other two, so a renamed or
2717
+ * destructured read built green on a host that rates the Secrets Store
2718
+ * unsupported and threw on first use.
2719
+ *
2720
+ * Three descendant walks (bindings, then accesses and `const … = ctx` patterns),
2721
+ * collected once per file: each context-bearing {@link CAPABILITIES} entry then
2722
+ * just tests membership in this set, so detection is O(files × nodes) rather
2723
+ * than O(files × features × nodes).
2724
+ */
2725
+ declare const contextPropertiesRead: (sourceFile: SourceFile) => Set<string>;
2726
+ /**
2727
+ * Detect code-usage of every package-backed feature across the function files
2728
+ * under `lunora/`, in a single pass. The result feeds both worker gating (`ai` /
2729
+ * `payments`) and — via `buildStudioFeatures` — the studio nav.
2730
+ */
2731
+ declare const discoverFeatureUsage: (project: Project, lunoraDirectory: string) => FeatureUsage;
2586
2732
  /** The default codegen target — today's behavior, byte-identical goldens. */
2587
2733
  declare const DEFAULT_TARGET = "cloudflare";
2588
2734
  /**
@@ -3378,6 +3524,13 @@ declare const emitWranglerCronTriggers: (crons: ReadonlyArray<CronJobIR>) => str
3378
3524
  interface EmitServerOptions {
3379
3525
  /** Agents declared via `defineAgent` exports — wires the typed `ctx.agents` producers onto Mutation/Action contexts. */
3380
3526
  agents?: ReadonlyArray<AgentIR>;
3527
+ /**
3528
+ * The package-backed capabilities the app uses (post platform gate). Each
3529
+ * used row of the `CAPABILITIES` table with a `serverCtxField` lands on the
3530
+ * ctx interfaces its `tier` names; `ai` / `payments` / `x402` gate their
3531
+ * bespoke ActionCtx fields off the same set.
3532
+ */
3533
+ capabilities?: ReadonlySet<CapabilityKey>;
3381
3534
  containers?: ReadonlyArray<ContainerIR>;
3382
3535
  /**
3383
3536
  * The single `defineEnv(...)` contract declared in `lunora/env.ts`. When
@@ -3388,37 +3541,12 @@ interface EmitServerOptions {
3388
3541
  env?: EnvIR;
3389
3542
  /** Absolute `_generated/` directory, so an RPC service's entry module is imported by a path relative to it. Required with `services`. */
3390
3543
  generatedDirectory?: string;
3391
- /**
3392
- * A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access
3393
- * facade (`@lunora/cloudflare-access/context`) onto every ctx. Distinct from
3394
- * `emitApp`'s `hasAccess` (which gates the worker's `.access()` resolveIdentity
3395
- * method); this one gates the per-request `ctx.access` read surface.
3396
- */
3397
- hasAccessFacade?: boolean;
3398
- hasAi?: boolean;
3399
- /** A `lunora/` source uses `@lunora/bindings/analytics` / `ctx.analytics` — wires the write helper onto every ctx. */
3400
- hasAnalytics?: boolean;
3401
- /** A `lunora/` source uses `@lunora/browser` / `ctx.browser` — wires `ctx.browser` onto ActionCtx only. */
3402
- hasBrowser?: boolean;
3403
3544
  /** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
3404
3545
  hasFlags?: boolean;
3405
- /** A `lunora/` source uses `@lunora/hyperdrive` / `ctx.sql` — wires `ctx.sql` onto ActionCtx only. */
3406
- hasHyperdrive?: boolean;
3407
- /** A `lunora/` source uses `@lunora/bindings/images` / `ctx.images` — wires `ctx.images` onto ActionCtx only. */
3408
- hasImages?: boolean;
3409
- /** A `lunora/` source uses `@lunora/bindings/kv` / `ctx.kv` — wires `ctx.kv` onto every ctx. */
3410
- hasKv?: boolean;
3411
3546
  /** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
3412
3547
  hasNotify?: boolean;
3413
- hasPayments?: boolean;
3414
- /** A `lunora/` source uses `@lunora/bindings/pipelines` / `ctx.pipelines` — wires `ctx.pipelines` onto ActionCtx only. */
3415
- hasPipelines?: boolean;
3416
- /** A `lunora/` source uses `@lunora/bindings/r2sql` / `ctx.r2sql` — wires `ctx.r2sql` onto ActionCtx only. */
3417
- hasR2sql?: boolean;
3418
3548
  /** The target platform supports a vector store. `false` withholds `ctx.vectors` even when the schema declares an index. */
3419
3549
  hasVectors?: boolean;
3420
- /** A `lunora/` source uses `@lunora/x402/pay` / `ctx.x402` — wires the agent-wallet pay rail onto ActionCtx only. */
3421
- hasX402?: boolean;
3422
3550
  /**
3423
3551
  * The single `defineIdentity(...)` claim contract declared in
3424
3552
  * `lunora/identity.ts` (Plan 080). When present, `ctx.auth.getIdentity()`,
@@ -3440,13 +3568,15 @@ interface EmitServerOptions {
3440
3568
  useUmbrella?: boolean;
3441
3569
  workflows?: ReadonlyArray<WorkflowIR>;
3442
3570
  }
3443
- declare const emitServer: ({ agents, containers, env, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasVectors, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasX402, identity, queues, schema, generatedDirectory, services, storageRuleBuckets, topics, useUmbrella, workflows }?: EmitServerOptions) => string;
3571
+ declare const emitServer: ({ agents, capabilities, containers, env, hasVectors, hasFlags, hasNotify, identity, queues, schema, generatedDirectory, services, storageRuleBuckets, topics, useUmbrella, workflows }?: EmitServerOptions) => string;
3444
3572
  interface EmitShardOptions {
3445
3573
  advisories?: ReadonlyArray<Finding>;
3446
3574
  /** Every declared procedure — the health map's denominator, served via `getAdvisorProcedures`. */
3447
3575
  advisorProcedures?: ReadonlyArray<AdvisorProcedureProtection>;
3448
3576
  /** Agents declared via `defineAgent` exports in `lunora/agents.ts` — wires the typed `ctx.agents` producers. */
3449
3577
  agents?: ReadonlyArray<AgentIR>;
3578
+ /** The package-backed capabilities the app uses (post platform gate) — each row of the `CAPABILITIES` table it names is wired per its `shardBinding` / `tier`. */
3579
+ capabilities?: ReadonlySet<CapabilityKey>;
3450
3580
  containers?: ReadonlyArray<ContainerIR>;
3451
3581
  /** The single `defineEnv(...)` contract declared in `lunora/env.ts` — applies the accessor to the worker `env` to populate `ctx.env`. */
3452
3582
  env?: EnvIR;
@@ -3455,28 +3585,10 @@ interface EmitShardOptions {
3455
3585
  key: string;
3456
3586
  type: "boolean" | "number" | "object" | "string";
3457
3587
  }>;
3458
- /** A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access facade onto every ctx. */
3459
- hasAccessFacade?: boolean;
3460
- hasAi?: boolean;
3461
- /** A `lunora/` source reads `ctx.analytics` — wires the Analytics Engine write helper onto every ctx. */
3462
- hasAnalytics?: boolean;
3463
- /** A `lunora/` source reads `ctx.browser` — wires `ctx.browser` onto the ActionCtx only. */
3464
- hasBrowser?: boolean;
3465
3588
  /** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
3466
3589
  hasFlags?: boolean;
3467
- /** A `lunora/` source reads `ctx.sql` (Hyperdrive) — wires `ctx.sql` onto the ActionCtx only. */
3468
- hasHyperdrive?: boolean;
3469
- /** A `lunora/` source reads `ctx.images` — wires `ctx.images` onto the ActionCtx only. */
3470
- hasImages?: boolean;
3471
- /** A `lunora/` source reads `ctx.kv` — wires `ctx.kv` onto every ctx. */
3472
- hasKv?: boolean;
3473
3590
  /** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
3474
3591
  hasNotify?: boolean;
3475
- hasPayments?: boolean;
3476
- /** A `lunora/` source reads `ctx.pipelines` — wires `ctx.pipelines` onto the ActionCtx only. */
3477
- hasPipelines?: boolean;
3478
- /** A `lunora/` source reads `ctx.r2sql` (R2 SQL) — wires `ctx.r2sql` onto the ActionCtx only. */
3479
- hasR2sql?: boolean;
3480
3592
  /**
3481
3593
  * The target platform supports a vector store. `false` withholds the whole
3482
3594
  * Vectorize wiring — the `@lunora/bindings/vectors` imports, the
@@ -3485,8 +3597,6 @@ interface EmitShardOptions {
3485
3597
  * `emitApp` withhold from the type surface for the same verdict.
3486
3598
  */
3487
3599
  hasVectors?: boolean;
3488
- /** A `lunora/` source reads `ctx.x402` — wires the agent-wallet pay rail onto the ActionCtx only. */
3489
- hasX402?: boolean;
3490
3600
  maskMetadata?: MaskMetadataIR;
3491
3601
  /** Custom mutators declared via `defineMutator` in `lunora/mutators.ts` — wires the `isCustomMutator` push-protocol override. */
3492
3602
  mutators?: ReadonlyArray<MutatorIR>;
@@ -3514,7 +3624,7 @@ interface EmitShardOptions {
3514
3624
  useUmbrella?: boolean;
3515
3625
  workflows?: ReadonlyArray<WorkflowIR>;
3516
3626
  }
3517
- declare const emitShard: ({ advisories, advisorProcedures, agents, containers, env, flagKeys, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasVectors, hasX402, maskMetadata, mutators, queues, rlsMetadata, schema, schemaSnapshot, shapes, storageRules, studioFeatures, services, topics, useUmbrella, workflows }: EmitShardOptions) => string;
3627
+ declare const emitShard: ({ advisories, advisorProcedures, agents, capabilities, containers, env, flagKeys, hasFlags, hasNotify, hasVectors, maskMetadata, mutators, queues, rlsMetadata, schema, schemaSnapshot, shapes, storageRules, studioFeatures, services, topics, useUmbrella, workflows }: EmitShardOptions) => string;
3518
3628
  /**
3519
3629
  * Emit `_generated/containers.ts` — one container-enabled Durable Object class
3520
3630
  * per `defineContainer` export, each a thin subclass of `LunoraContainer`
@@ -3546,6 +3656,16 @@ declare const emitAgents: (agents: ReadonlyArray<AgentIR>) => string;
3546
3656
  declare const GENERATED_HEADER = "// GENERATED by @lunora/codegen — do not edit.\n// Run `lunora codegen` to regenerate.\n\n";
3547
3657
  /** Which capability methods the generated `defineApp` builder exposes — one flag per package-backed feature the app actually uses. */
3548
3658
  interface EmitAppOptions {
3659
+ /**
3660
+ * The package-backed capabilities the app uses (post platform gate). Every
3661
+ * used row of the `CAPABILITIES` table with an `appMethod` gets its fluent
3662
+ * `defineApp` method (`.ai()`, `.kv()`, `.payment()`, …), which sets the
3663
+ * matching `createShardDO` config key. Usage-driven on purpose: each method's
3664
+ * parameter reads `ShardConfig[configKey]`, and the shard emits that config
3665
+ * field on the same usage signal. `vectors` is the exception — its method
3666
+ * follows {@link EmitAppOptions.hasVectors} + `vectorIndexCount`, not usage.
3667
+ */
3668
+ capabilities: ReadonlySet<CapabilityKey>;
3549
3669
  /**
3550
3670
  * Inbound-email agents (`defineAgent({ onEmail })`) → wire the worker's
3551
3671
  * top-level `email()` handler to `dispatchAgentEmail(...)` (from
@@ -3558,32 +3678,20 @@ interface EmitAppOptions {
3558
3678
  }>;
3559
3679
  /** App depends on `@lunora/cloudflare-access` → emit `.access()` (wire the Cloudflare Access `resolveIdentity`, composed ahead of `@lunora/auth` when both are present). */
3560
3680
  hasAccess: boolean;
3561
- /** App uses `@lunora/ai` / `ctx.ai` → emit `.ai()` (override the Workers AI binding backing `ctx.ai`). */
3562
- hasAi: boolean;
3563
- /** App uses `@lunora/bindings/analytics` / `ctx.analytics` → emit `.analytics()` (override the dataset backing `ctx.analytics`). */
3564
- hasAnalytics: boolean;
3565
3681
  /** App depends on `@lunora/auth` → emit `.auth()` + the lazy build/migrate dance. */
3566
3682
  hasAuth: boolean;
3567
- /** App uses `@lunora/browser` / `ctx.browser` → emit `.browser()`. */
3568
- hasBrowser: boolean;
3569
3683
  /** App depends on a worker-composition framework adapter (`@lunora/astro`/`@lunora/svelte`/`@lunora/vue`), or hand-composes one in `src/worker.ts` → emit `.buildFrameworkWorker(host)`. */
3570
3684
  hasFramework: boolean;
3571
3685
  /** Schema declares **D1-backed** `.global()` tables → emit `.global()` (D1 ctx-db + studio introspector + cross-shard relations). */
3572
3686
  hasGlobal: boolean;
3573
- /** App uses `@lunora/hyperdrive` / `ctx.sql` → emit `.hyperdrive()`. */
3574
- hasHyperdrive: boolean;
3575
3687
  /** Schema declares **Hyperdrive-backed** `.global({ backend: "hyperdrive" })` tables → emit `.hyperdriveGlobal()` (reactive Postgres/MySQL ctx-db over Hyperdrive). */
3576
3688
  hasHyperdriveGlobal: boolean;
3577
- /** App uses `@lunora/bindings/images` / `ctx.images` → emit `.images()`. */
3578
- hasImages: boolean;
3579
- /** App uses `@lunora/bindings/kv` / `ctx.kv` → emit `.kv()`. Usage-only, because the method's parameter type reads `ShardConfig["kv"]`, and that config field is emitted on the same usage signal. */
3580
- hasKv: boolean;
3581
3689
  /**
3582
3690
  * Wire the studio's zero-config KV introspector. Gated on `studioFeatures.kv`
3583
- * (usage OR a declared `@lunora/bindings` dependency), NOT on {@link EmitAppOptions.hasKv},
3691
+ * (usage OR a declared `@lunora/bindings` dependency), NOT on the `kv` capability,
3584
3692
  * so a visible KV tab always has a working backend — never the reverse.
3585
3693
  *
3586
- * Kept separate from `hasKv` deliberately: the two were accidentally equal
3694
+ * Kept separate from the `kv` usage flag deliberately: the two were accidentally equal
3587
3695
  * while the dependency arm in `discover/studio-features.ts` matched a subpath
3588
3696
  * and could never fire. Fixing that arm made them diverge, and the shared flag
3589
3697
  * emitted a `.kv()` builder whose `ShardConfig["kv"]` type did not exist.
@@ -3591,12 +3699,8 @@ interface EmitAppOptions {
3591
3699
  hasKvIntrospector: boolean;
3592
3700
  /** App declares `lunora/notify.ts` (`@lunora/notify`) → wire `options.notifySubscriptionStore` so the studio Notifications page can read registered devices. */
3593
3701
  hasNotify: boolean;
3594
- /** App uses `@lunora/payment` / `ctx.payments` → emit `.payment()`. */
3595
- hasPayments: boolean;
3596
3702
  /** App declares push queues (`defineQueue`) → wire `LUNORA_QUEUE_REGISTRY` into the worker's `queue()` consumer entry. */
3597
3703
  hasQueue: boolean;
3598
- /** App uses `@lunora/bindings/r2sql` / `ctx.r2sql` → emit `.r2sql()`. */
3599
- hasR2sql: boolean;
3600
3704
  /** App imports `@lunora/scheduler` / declares crons → emit `.scheduler()`. */
3601
3705
  hasScheduler: boolean;
3602
3706
  /**
@@ -3624,8 +3728,6 @@ interface EmitAppOptions {
3624
3728
  hasVectors?: boolean;
3625
3729
  /** App declares Cloudflare Workflows (`defineWorkflow`) → wire `options.workflowsClient` so the studio's workflow-instance proxy can reach the CF REST API. */
3626
3730
  hasWorkflow: boolean;
3627
- /** App uses `@lunora/x402/pay` / `ctx.x402` → emit `.x402()` (wire the agent-wallet pay rail). */
3628
- hasX402: boolean;
3629
3731
  /** The single `defineIdentity(...)` contract in `lunora/identity.ts` (Plan 080) → import it as a VALUE and wire `options.identity`, so the runtime trust boundary validates every resolved identity before it becomes `ctx.auth`. `undefined` ⇒ no wiring, byte-identical output. */
3630
3732
  identity?: IdentityIR;
3631
3733
  /** Schema declares `.jurisdiction("…")` → pin every DO the worker reaches (shards, fan-out, scheduler, containers, voice sessions, DO-backed auth, `@lunora/mail` shard RPC) to the Cloudflare data-residency jurisdiction. */
@@ -4329,4 +4431,4 @@ declare const secretKindOf: (value: string) => string | undefined;
4329
4431
  /** A redacted preview of a secret value — first 4 chars plus its length, never the full value. */
4330
4432
  declare const redact: (value: string) => string;
4331
4433
  declare const VERSION = "0.0.0";
4332
- export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type ContainerImageIR, type ContainerNamedImageIR, type ContextPropertyCallIR, type CronJobIR, DEFAULT_TARGET, type DefaultScheduledContainerIR, type DriftChange, type DriftRemediation, type DriftScope, type DurableObjectScheduledContainerIR, 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, type LoadedProjectConfig, type LunoraProjectConfig, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcDocument, type OpenRpcEmitInput, type OpenRpcMethod, PROJECT_CONFIG_FILENAMES, type PlatformDiagnostic, type ProjectConfigLiterals, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, type RuntimeVerb, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SDK_LANGUAGES, SDK_TARGETS, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type SdkFiles, type SdkMethod, type SdkNamespace, type SdkRenderInput, type SdkResult, type SdkTarget, type ServiceBindingIR, type ServiceLiteral, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, type TopicIR, 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, discoverHyperdriveCalls, 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, emitScheduler, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, errorAdvisoryNames, errorPlatformDiagnosticNames, evaluateSchemaDrift, findProjectConfigFile, findTsconfig, fingerprintSchemaSources, formatAdvisories, generateSdk, isD1GlobalTable, isHyperdriveGlobalTable, isTypedSchema, lintSchema, listLunoraSourceFiles, loadProjectConfig, parseSchemaSnapshot, platformMatrixIds, readPackageDependencies, readProjectConfigLiterals, readProjectTarget, readServiceBindings, redact, refreshCodegenProject, resolveCodegenTarget, resolveServiceBindings, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, sortedUniqueNames, toAdvisorContext, validatorIrToJsonSchema };
4434
+ export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type ContainerImageIR, type ContainerNamedImageIR, type ContextPropertyCallIR, type CronJobIR, DEFAULT_TARGET, type DefaultScheduledContainerIR, type DriftChange, type DriftRemediation, type DriftScope, type DurableObjectScheduledContainerIR, type EmitAppOptions, FLAGS_FILENAME, type FeatureUsage, type FieldSnapshot, type FlagsIR, type FunctionIR, GENERATED_HEADER, type HttpRouteIR, type IndexIR, type IndexSnapshot, type InsertWriteIR, LUNORA_ERROR_CODES, type LintSchemaOptions, type LoadedProjectConfig, type LunoraProjectConfig, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcDocument, type OpenRpcEmitInput, type OpenRpcMethod, PROJECT_CONFIG_FILENAMES, type PlatformDiagnostic, type ProjectConfigLiterals, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, type RuntimeVerb, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SDK_LANGUAGES, SDK_TARGETS, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type SdkFiles, type SdkMethod, type SdkNamespace, type SdkRenderInput, type SdkResult, type SdkTarget, type ServiceBindingIR, type ServiceLiteral, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, type TopicIR, VERSION, type ValidatorIR, type VectorIndexIR, WORKFLOWS_FILENAME, type WorkflowIR, type WranglerVariableIR, buildOpenApiDocument, buildOpenRpcDocument, buildSchemaSnapshot, contextPropertiesRead, createCodegenProject, describeErrorLevelFindings, diagnosticAt, diffSchemaSnapshots, discoverAgents, discoverAuthApiCalls, discoverContainers, discoverCrons, discoverFeatureUsage, discoverFlags, discoverFunctions, discoverHttpRoutes, discoverHyperdriveCalls, 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, emitScheduler, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, errorAdvisoryNames, errorPlatformDiagnosticNames, evaluateSchemaDrift, findProjectConfigFile, findTsconfig, fingerprintSchemaSources, formatAdvisories, generateSdk, isD1GlobalTable, isHyperdriveGlobalTable, isTypedSchema, lintSchema, listLunoraSourceFiles, loadProjectConfig, parseSchemaSnapshot, platformMatrixIds, readPackageDependencies, readProjectConfigLiterals, readProjectTarget, readServiceBindings, redact, refreshCodegenProject, resolveCodegenTarget, resolveServiceBindings, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, sortedUniqueNames, toAdvisorContext, validatorIrToJsonSchema };