@lunora/config 1.0.0-alpha.13 → 1.0.0-alpha.131

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 (93) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +2 -2
  3. package/__assets__/package-og.svg +1 -1
  4. package/dist/cloudflare/index.d.mts +790 -0
  5. package/dist/cloudflare/index.d.ts +790 -0
  6. package/dist/cloudflare/index.mjs +1 -0
  7. package/dist/index.d.mts +702 -855
  8. package/dist/index.d.ts +702 -855
  9. package/dist/index.mjs +1 -22
  10. package/dist/packem_shared/ACCENT-CLeV5v0K.mjs +7 -0
  11. package/dist/packem_shared/AGENT_MODE_ENV-B54hVQ_w.mjs +1 -0
  12. package/dist/packem_shared/AGENT_RULES_DIR-hP9TiDNx.mjs +1 -0
  13. package/dist/packem_shared/ALLOW_FORWARDED_ENV-DGdbCDre.mjs +1 -0
  14. package/dist/packem_shared/BINDING_MANIFEST_VERSION-DOlqQgYt.mjs +1 -0
  15. package/dist/packem_shared/CLOUDFLARE_DRIVER-B_MaIVFz.mjs +1 -0
  16. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-cfA_ogWA.mjs +1 -0
  17. package/dist/packem_shared/DEV_DAEMON_ENV-D9Z83rlU.mjs +4 -0
  18. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-BL0hrPx3.mjs +6 -0
  19. package/dist/packem_shared/LINKED_PROJECT_DIR-CMzUvj-1.mjs +2 -0
  20. package/dist/packem_shared/LUNORA_CONFIG_FILE-11ax8L-y.mjs +1 -0
  21. package/dist/packem_shared/LUNORA_EVENT_SOURCE-ZclWASXS.mjs +1 -0
  22. package/dist/packem_shared/LUNORA_IGNORED_PATHS-DIdyP0js.mjs +19 -0
  23. package/dist/packem_shared/LunoraReporter-BnXUqh8t.mjs +6 -0
  24. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-BgmvEPA-.mjs +1 -0
  25. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CUYWD0Mh.mjs +1 -0
  26. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-ws6iE0y-.mjs +1 -0
  27. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-BN97lRmC.mjs +1 -0
  28. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-BNB1ogaj.mjs +1 -0
  29. package/dist/packem_shared/SEED_ENDPOINT-BaYShU8q.mjs +1 -0
  30. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs +1 -0
  31. package/dist/packem_shared/WRANGLER_FILES-Bi_18Pj6.mjs +1 -0
  32. package/dist/packem_shared/applyAdditiveEdit-Cff30cSa.mjs +6 -0
  33. package/dist/packem_shared/assetContentType-DNZyUOuF.mjs +1 -0
  34. package/dist/packem_shared/buildPackageSecretsBlock-D2oDEMcf.mjs +18 -0
  35. package/dist/packem_shared/classifyPolicyEdit-BzC_MfYK.mjs +24 -0
  36. package/dist/packem_shared/cloudflare-driver-BHtz6vmK.mjs +1 -0
  37. package/dist/packem_shared/collectExportGaps-ajyIOfom.mjs +1 -0
  38. package/dist/packem_shared/collectWranglerSecretVariables-DZE0RIsW.mjs +1 -0
  39. package/dist/packem_shared/createConfirm-C5G4-dT6.mjs +7 -0
  40. package/dist/packem_shared/detectFramework-VTQfCNXy.mjs +1 -0
  41. package/dist/packem_shared/discover-info-DRQ0Ote0.mjs +1 -0
  42. package/dist/packem_shared/discoverAgentInfo-C8LTinx8.mjs +1 -0
  43. package/dist/packem_shared/discoverContainerInfo-C1zY2O8F.mjs +1 -0
  44. package/dist/packem_shared/discoverSchemaInfo-C8X9mo-i.mjs +1 -0
  45. package/dist/packem_shared/discoverWorkflowInfo-DHzCyLRj.mjs +1 -0
  46. package/dist/packem_shared/inferLunoraBindings-_ESCdL9P.mjs +1 -0
  47. package/dist/packem_shared/jsonc-edit-BZVpxVA0.mjs +1 -0
  48. package/dist/packem_shared/parseDevVariable-B193_28t.mjs +1 -0
  49. package/dist/packem_shared/parseSchema-BQjgz6bk.mjs +1 -0
  50. package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.mts → policy-scaffold.d-fV3db0S_.d.mts} +23 -23
  51. package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.ts → policy-scaffold.d-fV3db0S_.d.ts} +23 -23
  52. package/dist/packem_shared/reconcileWranglerCompatibilityDate-BXNiEQ7p.mjs +1 -0
  53. package/dist/packem_shared/reconcileWranglerCrons-BmQa_kGL.mjs +1 -0
  54. package/dist/packem_shared/renderStudioHtml-B2AkxcW1.mjs +15 -0
  55. package/dist/packem_shared/schema-info.d-DS0bUsWE.d.mts +375 -0
  56. package/dist/packem_shared/schema-info.d-DS0bUsWE.d.ts +375 -0
  57. package/dist/packem_shared/serveJsonHandler-DQ-Yqa4J.mjs +1 -0
  58. package/dist/packem_shared/streamContainerLogs-BPYBNrWS.mjs +2 -0
  59. package/dist/packem_shared/wranglerToAlchemy-BXagFk92.mjs +6 -0
  60. package/dist/packem_shared/write-atomic-Cdr2oQb-.mjs +1 -0
  61. package/dist/studio-host/index.d.mts +166 -92
  62. package/dist/studio-host/index.d.ts +166 -92
  63. package/dist/studio-host/index.mjs +1 -7
  64. package/package.json +15 -8
  65. package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
  66. package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
  67. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
  68. package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
  69. package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
  70. package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
  71. package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
  72. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
  73. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
  74. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
  75. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-DRSNSOOp.mjs +0 -476
  76. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
  77. package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
  78. package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
  79. package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
  80. package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
  81. package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
  82. package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
  83. package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
  84. package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
  85. package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
  86. package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
  87. package/dist/packem_shared/inferLunoraBindings-DIku9mTN.mjs +0 -302
  88. package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
  89. package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
  90. package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
  91. package/dist/packem_shared/reconcileWranglerBindings-DTHmqTbL.mjs +0 -277
  92. package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
  93. package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
@@ -2,14 +2,14 @@
2
2
  interface ScaffoldPolicyEdit {
3
3
  readonly kind: "scaffoldPolicy";
4
4
  /**
5
- * Base name for the generated file and its exported policy-set identifier,
6
- * e.g. `invoices` → `lunora/invoices.policies.ts` exporting `invoicesPolicies`.
7
- */
5
+ * Base name for the generated file and its exported policy-set identifier,
6
+ * e.g. `invoices` → `lunora/invoices.policies.ts` exporting `invoicesPolicies`.
7
+ */
8
8
  readonly name: string;
9
9
  /** Logical table the scaffolded policy guards (used in the stub body). */
10
10
  readonly table: string;
11
11
  }
12
- /** Append `.use(rls(<policies>))` to an existing procedure's builder chain. */
12
+ /** Append `.use(rls(<policies>))` to an existing procedure's builder chain. */
13
13
  interface WireRlsEdit {
14
14
  /** Exported procedure name to wire, e.g. `listInvoices`. */
15
15
  readonly exportName: string;
@@ -20,10 +20,10 @@ interface WireRlsEdit {
20
20
  /** Additive scaffolder edits — the only requests the scaffolder applies. */
21
21
  type AdditivePolicyEdit = ScaffoldPolicyEdit | WireRlsEdit;
22
22
  /**
23
- * Destructive scaffolder requests — never applied. Rewriting an existing `when`
24
- * body changes evaluation semantics silently, so it is refused (STOP condition
25
- * in plan 025); carried as data so the editor can describe the request.
26
- */
23
+ * Destructive scaffolder requests — never applied. Rewriting an existing `when`
24
+ * body changes evaluation semantics silently, so it is refused (STOP condition
25
+ * in plan 025); carried as data so the editor can describe the request.
26
+ */
27
27
  interface DestructivePolicyEdit {
28
28
  readonly exportName?: string;
29
29
  readonly kind: "rewritePolicyWhen";
@@ -32,10 +32,10 @@ interface DestructivePolicyEdit {
32
32
  /** Any request the scaffolder can receive. */
33
33
  type PolicyEdit = AdditivePolicyEdit | DestructivePolicyEdit;
34
34
  /**
35
- * Classify a scaffolder request. Additive requests ({@link AdditivePolicyEdit})
36
- * apply directly; everything else (rewriting an existing predicate) changes
37
- * evaluation semantics and is destructive.
38
- */
35
+ * Classify a scaffolder request. Additive requests ({@link AdditivePolicyEdit})
36
+ * apply directly; everything else (rewriting an existing predicate) changes
37
+ * evaluation semantics and is destructive.
38
+ */
39
39
  declare const classifyPolicyEdit: (edit: PolicyEdit) => "additive" | "destructive";
40
40
  /** Failure reasons a scaffolder request can report. */
41
41
  type PolicyScaffoldFailureReason = "already-wired" | "destructive" | "invalid-identifier" | "unknown-procedure" | "unsupported-procedure-shape";
@@ -57,18 +57,18 @@ type WireResult = {
57
57
  text: string;
58
58
  };
59
59
  /**
60
- * Generate the source of a new policy/role/permission stub file. The `when`
61
- * predicate is a `() => false` skeleton with a TODO — the scaffolder never
62
- * authors real logic, the developer fills it in. Pure (no I/O); the handler
63
- * writes the returned source and refuses to overwrite an existing file.
64
- */
60
+ * Generate the source of a new policy/role/permission stub file. The `when`
61
+ * predicate is a `() => false` skeleton with a TODO — the scaffolder never
62
+ * authors real logic, the developer fills it in. Pure (no I/O); the handler
63
+ * writes the returned source and refuses to overwrite an existing file.
64
+ */
65
65
  declare const scaffoldPolicyFile: (edit: ScaffoldPolicyEdit) => ScaffoldFileResult;
66
66
  /**
67
- * Append `.use(rls(&lt;policies>))` to a procedure's builder chain, preserving the
68
- * terminal `.query(handler)` (and its handler body) byte-for-byte. Only the
69
- * **builder** form can be wired; the bare-factory form (`query({ handler })`)
70
- * has no chain and is reported `unsupported-procedure-shape` so the editor can
71
- * tell the developer to convert it rather than silently rewriting their code.
72
- */
67
+ * Append `.use(rls(<policies>))` to a procedure's builder chain, preserving the
68
+ * terminal `.query(handler)` (and its handler body) byte-for-byte. Only the
69
+ * **builder** form can be wired; the bare-factory form (`query({ handler })`)
70
+ * has no chain and is reported `unsupported-procedure-shape` so the editor can
71
+ * tell the developer to convert it rather than silently rewriting their code.
72
+ */
73
73
  declare const wireRlsIntoProcedure: (source: string, edit: WireRlsEdit) => WireResult;
74
74
  export { AdditivePolicyEdit as A, DestructivePolicyEdit as D, PolicyEdit as P, ScaffoldPolicyEdit as S, WireRlsEdit as W, PolicyScaffoldFailureReason as a, ScaffoldFileResult as b, WireResult as c, classifyPolicyEdit as d, scaffoldPolicyFile as s, wireRlsIntoProcedure as w };
@@ -2,14 +2,14 @@
2
2
  interface ScaffoldPolicyEdit {
3
3
  readonly kind: "scaffoldPolicy";
4
4
  /**
5
- * Base name for the generated file and its exported policy-set identifier,
6
- * e.g. `invoices` → `lunora/invoices.policies.ts` exporting `invoicesPolicies`.
7
- */
5
+ * Base name for the generated file and its exported policy-set identifier,
6
+ * e.g. `invoices` → `lunora/invoices.policies.ts` exporting `invoicesPolicies`.
7
+ */
8
8
  readonly name: string;
9
9
  /** Logical table the scaffolded policy guards (used in the stub body). */
10
10
  readonly table: string;
11
11
  }
12
- /** Append `.use(rls(&lt;policies>))` to an existing procedure's builder chain. */
12
+ /** Append `.use(rls(<policies>))` to an existing procedure's builder chain. */
13
13
  interface WireRlsEdit {
14
14
  /** Exported procedure name to wire, e.g. `listInvoices`. */
15
15
  readonly exportName: string;
@@ -20,10 +20,10 @@ interface WireRlsEdit {
20
20
  /** Additive scaffolder edits — the only requests the scaffolder applies. */
21
21
  type AdditivePolicyEdit = ScaffoldPolicyEdit | WireRlsEdit;
22
22
  /**
23
- * Destructive scaffolder requests — never applied. Rewriting an existing `when`
24
- * body changes evaluation semantics silently, so it is refused (STOP condition
25
- * in plan 025); carried as data so the editor can describe the request.
26
- */
23
+ * Destructive scaffolder requests — never applied. Rewriting an existing `when`
24
+ * body changes evaluation semantics silently, so it is refused (STOP condition
25
+ * in plan 025); carried as data so the editor can describe the request.
26
+ */
27
27
  interface DestructivePolicyEdit {
28
28
  readonly exportName?: string;
29
29
  readonly kind: "rewritePolicyWhen";
@@ -32,10 +32,10 @@ interface DestructivePolicyEdit {
32
32
  /** Any request the scaffolder can receive. */
33
33
  type PolicyEdit = AdditivePolicyEdit | DestructivePolicyEdit;
34
34
  /**
35
- * Classify a scaffolder request. Additive requests ({@link AdditivePolicyEdit})
36
- * apply directly; everything else (rewriting an existing predicate) changes
37
- * evaluation semantics and is destructive.
38
- */
35
+ * Classify a scaffolder request. Additive requests ({@link AdditivePolicyEdit})
36
+ * apply directly; everything else (rewriting an existing predicate) changes
37
+ * evaluation semantics and is destructive.
38
+ */
39
39
  declare const classifyPolicyEdit: (edit: PolicyEdit) => "additive" | "destructive";
40
40
  /** Failure reasons a scaffolder request can report. */
41
41
  type PolicyScaffoldFailureReason = "already-wired" | "destructive" | "invalid-identifier" | "unknown-procedure" | "unsupported-procedure-shape";
@@ -57,18 +57,18 @@ type WireResult = {
57
57
  text: string;
58
58
  };
59
59
  /**
60
- * Generate the source of a new policy/role/permission stub file. The `when`
61
- * predicate is a `() => false` skeleton with a TODO — the scaffolder never
62
- * authors real logic, the developer fills it in. Pure (no I/O); the handler
63
- * writes the returned source and refuses to overwrite an existing file.
64
- */
60
+ * Generate the source of a new policy/role/permission stub file. The `when`
61
+ * predicate is a `() => false` skeleton with a TODO — the scaffolder never
62
+ * authors real logic, the developer fills it in. Pure (no I/O); the handler
63
+ * writes the returned source and refuses to overwrite an existing file.
64
+ */
65
65
  declare const scaffoldPolicyFile: (edit: ScaffoldPolicyEdit) => ScaffoldFileResult;
66
66
  /**
67
- * Append `.use(rls(&lt;policies>))` to a procedure's builder chain, preserving the
68
- * terminal `.query(handler)` (and its handler body) byte-for-byte. Only the
69
- * **builder** form can be wired; the bare-factory form (`query({ handler })`)
70
- * has no chain and is reported `unsupported-procedure-shape` so the editor can
71
- * tell the developer to convert it rather than silently rewriting their code.
72
- */
67
+ * Append `.use(rls(<policies>))` to a procedure's builder chain, preserving the
68
+ * terminal `.query(handler)` (and its handler body) byte-for-byte. Only the
69
+ * **builder** form can be wired; the bare-factory form (`query({ handler })`)
70
+ * has no chain and is reported `unsupported-procedure-shape` so the editor can
71
+ * tell the developer to convert it rather than silently rewriting their code.
72
+ */
73
73
  declare const wireRlsIntoProcedure: (source: string, edit: WireRlsEdit) => WireResult;
74
74
  export { AdditivePolicyEdit as A, DestructivePolicyEdit as D, PolicyEdit as P, ScaffoldPolicyEdit as S, WireRlsEdit as W, PolicyScaffoldFailureReason as a, ScaffoldFileResult as b, WireResult as c, classifyPolicyEdit as d, scaffoldPolicyFile as s, wireRlsIntoProcedure as w };
@@ -0,0 +1 @@
1
+ import{writeFileSync as d}from"node:fs";import{modify as l,applyEdits as c}from"jsonc-parser";import{r as s}from"./jsonc-edit-BZVpxVA0.mjs";import{isCacheEnabled as f,WORKERS_CACHE_MIN_DATE as r}from"./WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs";import{findWranglerFile as g,readWranglerJsonc as m}from"./WRANGLER_FILES-Bi_18Pj6.mjs";const b=i=>{const e=g(i);if(!e)return{changed:!1,date:void 0,reason:"wrangler.jsonc not found"};const{parsed:t,text:n}=m(e);if(t===void 0)return{changed:!1,date:void 0,reason:`failed to parse ${e} as JSONC`,wranglerPath:e};const a=t.compatibility_date??"";if(!f(t))return{changed:!1,date:a||void 0,reason:"cache not enabled",wranglerPath:e};if(a>=r)return{changed:!1,date:a,reason:`compatibility_date already >= ${r}`,wranglerPath:e};const o=l(n,["compatibility_date"],r,s);return o.length===0?{changed:!1,date:a||void 0,reason:"no structural edit produced",wranglerPath:e}:(d(e,c(n,o),"utf8"),{changed:!0,date:r,wranglerPath:e})};export{b as reconcileWranglerCompatibilityDate};
@@ -0,0 +1 @@
1
+ import{writeFileSync as g}from"node:fs";import{modify as c,applyEdits as l}from"jsonc-parser";import{findWranglerFile as d,readWranglerJsonc as f}from"./WRANGLER_FILES-Bi_18Pj6.mjs";const h=(t,e)=>t.length===e.length&&t.every((r,n)=>r===e[n]),m=(t,e)=>{const r=d(t);if(!r)return{changed:!1,reason:"wrangler.jsonc not found"};const{parsed:n,text:a}=f(r);if(n===void 0)return{changed:!1,reason:`failed to parse ${r} as JSONC`,wranglerPath:r};const o=Array.isArray(n.triggers?.crons)?n.triggers.crons.filter(i=>typeof i=="string"):[];if(h(o,e))return{changed:!1,reason:"triggers.crons already in sync",wranglerPath:r};const s=c(a,["triggers","crons"],[...e],{formattingOptions:{insertSpaces:!0,tabSize:4}});return s.length===0?{changed:!1,reason:"no structural edit produced",wranglerPath:r}:(g(r,l(a,s),"utf8"),{changed:!0,wranglerPath:r})};export{m as reconcileWranglerCrons};
@@ -0,0 +1,15 @@
1
+ const i=e=>JSON.stringify(e).replaceAll("<",String.raw`\u003c`),_=e=>e.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;"),l=e=>{const t=[`window.__LUNORA_BASE_PATH__=${i(e.basePath)};`];return e.adminToken!==void 0&&e.adminToken!==""&&t.push(`window.__LUNORA_ADMIN_TOKEN__=${i(e.adminToken)};`),e.dataEditable===!0&&t.push("window.__LUNORA_DATA_EDITABLE__=true;"),e.runAsIdentity===!0&&t.push("window.__LUNORA_RUN_AS_IDENTITY__=true;"),e.schemaEditable===!0&&t.push("window.__LUNORA_SCHEMA_EDITABLE__=true;"),e.rulesInstalled===!1&&t.push("window.__LUNORA_RULES_INSTALLED__=false;"),`<!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Lunora Studio</title>
7
+ <script>${t.join("")}<\/script>
8
+ <link rel="stylesheet" href="${_(e.styleHref)}" />
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="${_(e.scriptSrc)}"><\/script>
13
+ </body>
14
+ </html>
15
+ `};export{l as default};
@@ -0,0 +1,375 @@
1
+ import { AgentIR, ContainerIR, QueueIR, WorkflowIR } from '@lunora/codegen';
2
+ /**
3
+ * `DeployDriver` — the provider-neutral seam between what an app needs and
4
+ * how a host provides it (plan 114, §5.3).
5
+ *
6
+ * Configuration inference is two jobs welded together today. Deciding that an
7
+ * app needs a shard namespace, a queue, and an object-storage bucket is
8
+ * host-neutral: it falls out of the app's schema and imports, and every target
9
+ * reaches the same conclusion. Writing `durable_objects.bindings[]` into a
10
+ * `wrangler.jsonc` is not — it is one host's encoding of that conclusion.
11
+ *
12
+ * The split here names both halves. {@link ResourceGraph} is the neutral answer
13
+ * to "what does this app need?"; a {@link DeployDriver} turns that graph into
14
+ * one host's configuration and owns the host's toolchain surface. A second
15
+ * target implements the driver rather than forking the inference.
16
+ *
17
+ * Only the Cloudflare driver exists today (`cloudflare-driver.ts`), and it is
18
+ * deliberately thin: it delegates to the same `inferLunoraBindings` /
19
+ * `reconcileWrangler*` functions the CLI called directly before, so routing a
20
+ * command through the driver is behavior-preserving by construction.
21
+ *
22
+ * The second half is the **toolchain surface**: which command a host runs to
23
+ * deploy, serve, tail, or set a secret. A driver only *describes* that command
24
+ * ({@link ToolchainCommand}); it never spawns. The CLI keeps ownership of
25
+ * running it — package-manager resolution (`pnpm exec` / `npx --` / `bun x`)
26
+ * and the injected spawner its tests substitute — so the driver stays free of
27
+ * process concerns and remains trivially testable as a pure function.
28
+ *
29
+ * Each request type below is deliberately neutral: `preview`, `environment`,
30
+ * `temporary` are concepts, not wrangler flags. A second host maps the same
31
+ * request onto its own CLI without the caller changing.
32
+ */
33
+ /** A durable, single-writer shard namespace (a Durable Object namespace on Cloudflare). */
34
+ interface ShardNamespaceResource {
35
+ /** The implementing class name the host binds to. */
36
+ className: string;
37
+ /** Whether the worker entry re-exports the class — an unexported class cannot be bound. */
38
+ exported: boolean;
39
+ /** The binding name the app reaches it through (e.g. `SHARD`). */
40
+ name: string;
41
+ }
42
+ /** A named resource the app declares and the host must provision (queue, workflow, container). */
43
+ interface NamedResource {
44
+ /** Whether the declaration is re-exported from the worker entry, where that applies. */
45
+ exported?: boolean;
46
+ /** The declared name. */
47
+ name: string;
48
+ }
49
+ /**
50
+ * The provider-neutral statement of what an app needs, derived from its schema
51
+ * and imports. Every field is a *requirement*, not a host encoding: a driver
52
+ * decides what `objectStorage: true` means for its target.
53
+ */
54
+ interface ResourceGraph {
55
+ /** Container images the app declares. */
56
+ containers: ReadonlyArray<NamedResource>;
57
+ /** Cron expressions the app schedules. */
58
+ crons: ReadonlyArray<string>;
59
+ /**
60
+ * The app declares a `.global()` table, so it needs a replicated SQL store
61
+ * (D1 on Cloudflare; Aurora/RDS elsewhere).
62
+ */
63
+ globalDatabase: boolean;
64
+ /** The app reads or writes a key-value store. */
65
+ keyValueStore: boolean;
66
+ /** The app needs object storage (R2 on Cloudflare; S3-compatible elsewhere). */
67
+ objectStorage: boolean;
68
+ /** Queues the app declares. */
69
+ queues: ReadonlyArray<NamedResource>;
70
+ /** Shard namespaces the app needs. */
71
+ shardNamespaces: ReadonlyArray<ShardNamespaceResource>;
72
+ /**
73
+ * Human-readable provenance for each requirement — why inference concluded
74
+ * the app needs it. Surfaced in CLI logs; never load-bearing.
75
+ */
76
+ signals: ReadonlyArray<string>;
77
+ /** Workflows the app declares. */
78
+ workflows: ReadonlyArray<NamedResource>;
79
+ }
80
+ /** The outcome of writing a {@link ResourceGraph} into a host's configuration. */
81
+ interface ProvisionResult {
82
+ /** Short labels for each resource written, for logging. */
83
+ added: ReadonlyArray<string>;
84
+ /** Whether the host's configuration file was rewritten. */
85
+ changed: boolean;
86
+ /** Resolved configuration path, when the host has one. */
87
+ configPath?: string;
88
+ /** Non-fatal hints for requirements the driver cannot auto-provision. */
89
+ warnings: ReadonlyArray<string>;
90
+ }
91
+ /**
92
+ * A host CLI invocation, described but not run.
93
+ *
94
+ * `tool` is the binary name only (`"wrangler"`); the caller resolves how to
95
+ * execute it through the project's package manager. Keeping that split means a
96
+ * driver never has to know whether the project uses pnpm, npm, yarn, or bun.
97
+ */
98
+ interface ToolchainCommand {
99
+ /** Arguments for {@link ToolchainCommand.tool}. */
100
+ args: ReadonlyArray<string>;
101
+ /** The host CLI binary, e.g. `"wrangler"`. */
102
+ tool: string;
103
+ }
104
+ /** Neutral options for a deploy. */
105
+ interface DeployRequest {
106
+ /** Validate and bundle without publishing — nothing ships. */
107
+ dryRun?: boolean;
108
+ /** Deploy this entry file instead of the host config's default (framework composition). */
109
+ entry?: string;
110
+ /** Named deployment environment, when the host supports them. */
111
+ environment?: string;
112
+ /** Write the built bundle (and any build metadata) to this directory. */
113
+ outDir?: string;
114
+ /** Upload a preview/versioned artifact instead of taking production traffic. */
115
+ preview?: boolean;
116
+ /** Deploy to a short-lived, unauthenticated account where the host offers one. */
117
+ temporary?: boolean;
118
+ }
119
+ /** Neutral options for a local dev server. */
120
+ interface DevRequest {
121
+ /** Host config file to run against, when the flow uses a generated one. */
122
+ configPath?: string;
123
+ /** Named environment. */
124
+ environment?: string;
125
+ /** Extra host-specific flags the caller has already resolved. */
126
+ extraArgs?: ReadonlyArray<string>;
127
+ }
128
+ /** Neutral options for tailing live logs. */
129
+ interface TailRequest {
130
+ /** Named environment. */
131
+ environment?: string;
132
+ /** Output format the host tail supports (`"json"`, `"pretty"`, …). */
133
+ format?: string;
134
+ /** Free-text filter. */
135
+ search?: string;
136
+ /** Status filter (`"error"`, `"ok"`, …). */
137
+ status?: string;
138
+ /** Tail a short-lived account's deployment. */
139
+ temporary?: boolean;
140
+ /** Tail a specific deployed worker/service by name, when the host addresses them individually. */
141
+ worker?: string;
142
+ }
143
+ /** Neutral options for reading or writing deployment secrets. */
144
+ interface SecretRequest {
145
+ /** Named environment. */
146
+ environment?: string;
147
+ /** The secret's name — required for `put`, unused for `list`. */
148
+ key?: string;
149
+ /** Operate against a short-lived account. */
150
+ temporary?: boolean;
151
+ }
152
+ /**
153
+ * The host's command-line surface. Optional as a whole: a host with no CLI (a
154
+ * hypothetical API-driven target) implements `infer`/`provision` only, and the
155
+ * caller falls back to its own handling.
156
+ */
157
+ interface DriverToolchain {
158
+ /** The command that deploys the app. */
159
+ deploy: (request: DeployRequest) => ToolchainCommand;
160
+ /** The command that runs a local dev server. */
161
+ dev: (request: DevRequest) => ToolchainCommand;
162
+ /** The command that lists remote secret names. */
163
+ secretList: (request: SecretRequest) => ToolchainCommand;
164
+ /** The command that writes one secret. Its value is passed on stdin, never argv. */
165
+ secretPut: (request: SecretRequest) => ToolchainCommand;
166
+ /** The command that tails live logs. */
167
+ tail: (request: TailRequest) => ToolchainCommand;
168
+ }
169
+ /** Options every driver method receives. */
170
+ interface DriverContext {
171
+ /** Cron expressions codegen discovered, threaded in because they come from the app's code rather than its config. */
172
+ crons?: ReadonlyArray<string>;
173
+ /** Project root containing the `lunora/` directory. */
174
+ projectRoot: string;
175
+ }
176
+ /**
177
+ * A deploy target's implementation: report what the app needs, and encode it
178
+ * into that host's configuration.
179
+ *
180
+ * **Why `provision` does not take a {@link ResourceGraph}.** The obvious
181
+ * signature is `provision(graph, context)`, and it is wrong. Writing real host
182
+ * configuration needs the host's own encodings — binding names, DO class
183
+ * wiring, migration tags — which the neutral graph deliberately discards. A
184
+ * driver handed only the graph would have to re-derive them, so passing it
185
+ * would be decorative. `infer` is therefore the *reporting* surface (a portable
186
+ * picture of the app's requirements, for logs, diagnostics, and cross-target
187
+ * comparison) and `provision` is the *doing* surface, which owns its own
188
+ * inference end-to-end.
189
+ *
190
+ * That asymmetry is a genuine finding about this seam, not a shortcut: it says
191
+ * the neutral graph is not a sufficient intermediate representation for config
192
+ * emission. If a future target needs one, the graph must grow a host-extension
193
+ * escape hatch rather than pretend it already carries the detail.
194
+ */
195
+ interface DeployDriver {
196
+ /** The target id this driver serves (`"cloudflare"`, …) — matches codegen's `target`. */
197
+ readonly id: string;
198
+ /**
199
+ * Read the app and report what it needs, in provider-neutral terms. Pure
200
+ * with respect to the project: it never writes configuration.
201
+ */
202
+ infer: (context: DriverContext) => Promise<ResourceGraph>;
203
+ /** Human-readable target name, for logs. */
204
+ readonly name: string;
205
+ /**
206
+ * Write the app's requirements into the host's configuration, adding what is
207
+ * missing and leaving existing entries alone. Must be idempotent:
208
+ * provisioning an already-provisioned project reports `changed: false`, and
209
+ * must fold a failed step into a warning rather than throwing.
210
+ */
211
+ provision: (context: DriverContext) => Promise<ProvisionResult>;
212
+ /**
213
+ * The host's command-line surface, or `undefined` for a host that has none.
214
+ * Pure: these build argv, they never spawn.
215
+ */
216
+ readonly toolchain?: DriverToolchain;
217
+ }
218
+ interface DurableObjectSpec {
219
+ binding: string;
220
+ className: string;
221
+ }
222
+ /**
223
+ * A `defineContainer` declaration plus whether its generated DO class is
224
+ * exported by the worker entry. Only exported containers are safe to
225
+ * provision — wrangler rejects a `containers[].class_name` (and its Durable
226
+ * Object binding) that the worker doesn't export.
227
+ */
228
+ interface InferredContainer extends ContainerIR {
229
+ exported: boolean;
230
+ }
231
+ /**
232
+ * A `defineWorkflow` declaration plus whether its generated
233
+ * `WorkflowEntrypoint` class is exported by the worker entry. Only exported
234
+ * workflows are safe to provision — wrangler rejects a `workflows[].class_name`
235
+ * the worker doesn't export. Workflows are NOT Durable Objects, so this never
236
+ * implies a `durable_objects` binding or migration.
237
+ */
238
+ interface InferredWorkflow extends WorkflowIR {
239
+ exported: boolean;
240
+ }
241
+ /**
242
+ * A `defineAgent` declaration plus whether its generated agent
243
+ * `WorkflowEntrypoint` class (e.g. `SupportAgentWorkflow`) is exported by the
244
+ * worker entry. An agent compiles onto a Cloudflare Workflow, so — exactly like
245
+ * {@link InferredWorkflow} — only exported agents are safe to provision
246
+ * (wrangler rejects a `workflows[].class_name` the worker doesn't export), and
247
+ * an agent is NOT a Durable Object (no `durable_objects` binding or migration).
248
+ */
249
+ interface InferredAgent extends AgentIR {
250
+ exported: boolean;
251
+ }
252
+ /**
253
+ * A queue declared in `lunora/queues.ts`. Unlike workflows, a queue needs no
254
+ * worker-entry class export (its `queue()` handler rides `createWorker`), so
255
+ * there is no `exported` flag — every declared queue is reconcilable into the
256
+ * wrangler `queues.producers[]` / `queues.consumers[]`.
257
+ */
258
+ type InferredQueue = QueueIR;
259
+ interface InferredBindings {
260
+ /** Agents declared in `lunora/agents.ts` (exported or not — see {@link InferredAgent.exported}); reconciled into `workflows[]`. */
261
+ agents: InferredAgent[];
262
+ /** Containers declared in `lunora/containers.ts` (exported or not — see {@link InferredContainer.exported}). */
263
+ containers: InferredContainer[];
264
+ /** Durable Objects the worker entry exports → safe to bind. */
265
+ durableObjects: DurableObjectSpec[];
266
+ /**
267
+ * The wrangler `flagship[].binding` name implied by `lunora/flags.ts` when it
268
+ * uses the Flagship provider in binding mode — `undefined` for HTTP-mode
269
+ * Flagship, a custom OpenFeature provider, or no flags. The binding needs an
270
+ * un-mintable `app_id`, so it is reconciled as a hint, not auto-written.
271
+ */
272
+ flagshipBinding?: string;
273
+ /** Schema declares a `.global()` table → needs the `DB` D1 binding. */
274
+ needsD1: boolean;
275
+ /** Queues declared in `lunora/queues.ts` → reconciled into `queues.producers[]` / `queues.consumers[]`. */
276
+ queues: InferredQueue[];
277
+ /** Human-readable provenance for each inferred binding / hint, for logging. */
278
+ signals: string[];
279
+ /** `@lunora/ai` is imported or `env.AI` is used → needs the `ai` Workers AI binding. */
280
+ usesAi: boolean;
281
+ /** `@lunora/bindings/analytics` is imported → self-describing `analytics_engine_datasets` binding (auto-writeable). */
282
+ usesAnalytics: boolean;
283
+ /** `@lunora/auth` is imported (sessions may be D1- or `SessionDO`-backed). */
284
+ usesAuth: boolean;
285
+ /** `@lunora/browser` is imported → self-describing `browser` binding (auto-writeable). */
286
+ usesBrowser: boolean;
287
+ /** `lunora/flags.ts` declares a feature-flag provider (any OpenFeature provider — Flagship or custom). */
288
+ usesFlags: boolean;
289
+ /** `@lunora/hyperdrive` is imported (binding needs an un-mintable remote `id`; hint-only). */
290
+ usesHyperdrive: boolean;
291
+ /** `@lunora/bindings/images` is imported → self-describing `images` binding (auto-writeable). */
292
+ usesImages: boolean;
293
+ /** `@lunora/bindings/kv` is imported (namespace binding name + id are user-defined; hint-only). */
294
+ usesKv: boolean;
295
+ /** `@lunora/mail` is imported (Resend API key must be set in `.dev.vars`; no binding). */
296
+ usesMail: boolean;
297
+ /** `@lunora/payment` is imported (provider secrets must be set in `.dev.vars`; no binding). */
298
+ usesPayment: boolean;
299
+ /** `ctx.pipelines` is used (binding needs an un-mintable remote pipeline name; hint-only). */
300
+ usesPipelines: boolean;
301
+ /** `@lunora/scheduler` is imported. */
302
+ usesScheduler: boolean;
303
+ /** `@lunora/storage` is imported (R2 bucket binding name is user-defined). */
304
+ usesStorage: boolean;
305
+ /** `@lunora/x402/charge` is imported — the charge rail settles USDC to a recipient address (a public `[vars]` entry, user-named; hint-only). */
306
+ usesX402Charge: boolean;
307
+ /** `@lunora/x402/pay` is imported — the agent-wallet pay rail signs from a Secrets Store binding paired with a spend policy (ActionCtx-only; hint-only). */
308
+ usesX402Pay: boolean;
309
+ /** Workflows declared in `lunora/workflows.ts` (exported or not — see {@link InferredWorkflow.exported}). */
310
+ workflows: InferredWorkflow[];
311
+ }
312
+ interface InferOptions {
313
+ projectRoot: string;
314
+ /** Directories (relative to root) to scan. Defaults to `lunora` + `src`. */
315
+ scanDirs?: ReadonlyArray<string>;
316
+ /** Lunora source directory holding `schema.ts`. Defaults to `lunora`. */
317
+ schemaDir?: string;
318
+ }
319
+ /**
320
+ * Scan a Lunora project and report which Cloudflare bindings its code implies.
321
+ * Read-only: performs no writes. Binding provisioning is driven by the worker
322
+ * entry's Durable Object exports plus the schema's D1 need; capability imports
323
+ * surface as hints.
324
+ */
325
+ declare const inferLunoraBindings: (options: InferOptions) => Promise<InferredBindings>;
326
+ /**
327
+ * Derive the list of `@lunora/*` package names that are actively used by a
328
+ * project, based on its already-resolved {@link InferredBindings}.
329
+ *
330
+ * This is the canonical bridge between binding inference and the package-aware
331
+ * `.dev.vars.example` scaffolding in `scaffold-dev-variables.ts`. The result is
332
+ * a stable, predictable slice of {@link CAPABILITY_SOURCES} source values,
333
+ * filtered to the flags that are `true` in `bindings` — in CAPABILITY_SOURCES
334
+ * declaration order.
335
+ */
336
+ declare const packageNamesFromBindings: (bindings: InferredBindings) => string[];
337
+ /** One filterable Vectorize metadata property a schema declares. */
338
+ interface VectorMetadataDeclaration {
339
+ /** The vector index the property belongs to. */
340
+ index: string;
341
+ /**
342
+ * The validator kind behind the column, or `undefined` when the column
343
+ * isn't in the owning table's shape. Callers map it to the Vectorize
344
+ * metadata type; a kind that can't be filtered on is reported, not indexed.
345
+ */
346
+ kind: string | undefined;
347
+ /** Column mirrored into vector metadata. */
348
+ property: string;
349
+ }
350
+ interface SchemaInfo {
351
+ /** Whether the lunora schema declares any `.global()` table. */
352
+ hasGlobalTable: boolean;
353
+ /** Names of vector indexes declared via `.vectorize()` / `defineVectorIndex()`. */
354
+ vectorIndexNames?: ReadonlyArray<string>;
355
+ /**
356
+ * Metadata properties declared filterable on a vector index. Cloudflare
357
+ * needs an explicit metadata index per property before a `filter` can match
358
+ * anything, so deploy provisions these and doctor reports them.
359
+ */
360
+ vectorMetadata?: ReadonlyArray<VectorMetadataDeclaration>;
361
+ }
362
+ interface DiscoverSchemaInfoResult {
363
+ /** Parse error message, when the schema exists but could not be analyzed. */
364
+ error?: string;
365
+ /** Schema facts, or `undefined` when no `schema.ts` exists or parsing failed. */
366
+ info: SchemaInfo | undefined;
367
+ }
368
+ /**
369
+ * Discover {@link SchemaInfo} for a project. Returns `{ info: undefined }` when
370
+ * the project declares no `schema.ts` (not an error), or `{ info: undefined,
371
+ * error }` when a present schema could not be parsed — callers decide whether a
372
+ * parse failure is a warning (validator) or simply ignorable (inference).
373
+ */
374
+ declare const discoverSchemaInfo: (projectRoot: string, schemaDirectory: string) => DiscoverSchemaInfoResult;
375
+ export { DeployDriver as D, InferredBindings as I, NamedResource as N, ProvisionResult as P, ResourceGraph as R, SchemaInfo as S, TailRequest as T, DeployRequest as a, DevRequest as b, DiscoverSchemaInfoResult as c, DriverContext as d, DriverToolchain as e, InferOptions as f, InferredAgent as g, InferredContainer as h, InferredWorkflow as i, SecretRequest as j, ShardNamespaceResource as k, ToolchainCommand as l, discoverSchemaInfo as m, inferLunoraBindings as n, packageNamesFromBindings as p };