@cosmicdrift/kumiko-framework 0.387.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/AGENTS.md +6 -1
  2. package/agents/examples/anonymous-access.md +1 -1
  3. package/agents/examples/apex-landing.md +204 -0
  4. package/agents/examples/api-worker-split.md +64 -0
  5. package/agents/examples/app-config.md +14 -0
  6. package/agents/examples/auth-mfa.md +115 -0
  7. package/agents/examples/env-composition.md +28 -1
  8. package/agents/examples/legal-pages.md +1 -1
  9. package/agents/examples/prod-boot-options.md +16 -0
  10. package/agents/examples/rate-limiting.md +48 -0
  11. package/agents/examples/record-detail-layout.md +692 -0
  12. package/agents/examples/seed-migration.md +212 -0
  13. package/agents/examples/wizard-form.md +941 -0
  14. package/agents/examples/writeform-section.md +548 -0
  15. package/agents/features.md +19 -2
  16. package/agents/widgets.md +1 -0
  17. package/dist/api/client-error-route.js +8 -2
  18. package/dist/api/index.d.ts +3 -1
  19. package/dist/api/index.js +3 -1
  20. package/dist/api/request-context.d.ts +1 -1
  21. package/dist/api/request-context.js +1 -1
  22. package/dist/api/server-boot-checks.d.ts +10 -0
  23. package/dist/api/server-boot-checks.js +157 -0
  24. package/dist/api/server-event-dispatcher.d.ts +26 -0
  25. package/dist/api/server-event-dispatcher.js +208 -0
  26. package/dist/api/server-extra-routes.d.ts +11 -0
  27. package/dist/api/server-extra-routes.js +203 -0
  28. package/dist/api/server-middleware.d.ts +20 -0
  29. package/dist/api/server-middleware.js +211 -0
  30. package/dist/api/server-routes.d.ts +19 -0
  31. package/dist/api/server-routes.js +293 -0
  32. package/dist/api/server-websocket-routes.d.ts +4 -0
  33. package/dist/api/server-websocket-routes.js +108 -0
  34. package/dist/api/server-wiring.d.ts +32 -0
  35. package/dist/api/server-wiring.js +236 -0
  36. package/dist/api/server.d.ts +10 -15
  37. package/dist/api/server.js +48 -1251
  38. package/dist/api/session-cookies.js +4 -4
  39. package/dist/api/sse-route.js +16 -12
  40. package/dist/crypto/owner-transition-rekey.d.ts +5 -1
  41. package/dist/crypto/owner-transition-rekey.js +1 -1
  42. package/dist/crypto/pii-field-encryption.d.ts +5 -1
  43. package/dist/crypto/pii-field-encryption.js +3 -1
  44. package/dist/db/aggregate-sql.d.ts +21 -0
  45. package/dist/db/aggregate-sql.js +155 -0
  46. package/dist/db/closed-connection.d.ts +9 -0
  47. package/dist/db/closed-connection.js +95 -0
  48. package/dist/db/dialect.js +1 -1
  49. package/dist/db/distinct-on.d.ts +1 -1
  50. package/dist/db/driver-row-coercion.d.ts +2 -0
  51. package/dist/db/driver-row-coercion.js +186 -0
  52. package/dist/db/driver-value-preparation.d.ts +16 -0
  53. package/dist/db/driver-value-preparation.js +99 -0
  54. package/dist/db/entity-field-encryption.d.ts +1 -0
  55. package/dist/db/entity-field-encryption.js +1 -1
  56. package/dist/db/entity-table-meta.js +103 -110
  57. package/dist/db/event-store-executor-context.d.ts +2 -1
  58. package/dist/db/event-store-executor-read-aggregate.d.ts +8 -0
  59. package/dist/db/event-store-executor-read-aggregate.js +112 -0
  60. package/dist/db/event-store-executor-read-filter.d.ts +31 -0
  61. package/dist/db/event-store-executor-read-filter.js +203 -0
  62. package/dist/db/event-store-executor-read-paging.d.ts +14 -0
  63. package/dist/db/event-store-executor-read-paging.js +99 -0
  64. package/dist/db/event-store-executor-read-rows.d.ts +6 -0
  65. package/dist/db/event-store-executor-read-rows.js +32 -0
  66. package/dist/db/event-store-executor-read-search.d.ts +28 -0
  67. package/dist/db/event-store-executor-read-search.js +221 -0
  68. package/dist/db/event-store-executor-read-sort.d.ts +41 -0
  69. package/dist/db/event-store-executor-read-sort.js +130 -0
  70. package/dist/db/event-store-executor-read-where.d.ts +24 -0
  71. package/dist/db/event-store-executor-read-where.js +81 -0
  72. package/dist/db/event-store-executor-read.d.ts +2 -9
  73. package/dist/db/event-store-executor-read.js +48 -701
  74. package/dist/db/event-store-executor-write-steps.d.ts +20 -0
  75. package/dist/db/event-store-executor-write-steps.js +100 -0
  76. package/dist/db/event-store-executor-write.js +395 -499
  77. package/dist/db/index.d.ts +6 -2
  78. package/dist/db/index.js +5 -1
  79. package/dist/db/list-aggregate-labels.d.ts +14 -0
  80. package/dist/db/list-aggregate-labels.js +26 -0
  81. package/dist/db/migrate-generator.js +71 -86
  82. package/dist/db/migrate-runner.js +4 -1
  83. package/dist/db/query.d.ts +2 -15
  84. package/dist/db/query.js +8 -761
  85. package/dist/db/reference-data.js +6 -1
  86. package/dist/db/table-builder.js +113 -166
  87. package/dist/db/table-info.d.ts +10 -0
  88. package/dist/db/table-info.js +45 -0
  89. package/dist/db/temporal-value-guards.d.ts +6 -0
  90. package/dist/db/temporal-value-guards.js +15 -0
  91. package/dist/db/tenant-db-runner.d.ts +1 -0
  92. package/dist/db/tenant-db-runner.js +3 -0
  93. package/dist/db/tenant-db.js +39 -9
  94. package/dist/db/where-clause.d.ts +6 -0
  95. package/dist/db/where-clause.js +236 -0
  96. package/dist/derivatives/delete-stored-file.js +2 -1
  97. package/dist/engine/boot-validator/boot-check.js +1 -1
  98. package/dist/engine/boot-validator/detail-screens.js +2 -2
  99. package/dist/engine/boot-validator/entity-handler.d.ts +1 -0
  100. package/dist/engine/boot-validator/entity-handler.js +17 -0
  101. package/dist/engine/boot-validator/form-derivations.js +35 -1
  102. package/dist/engine/boot-validator/i18n-keys.js +5 -3
  103. package/dist/engine/boot-validator/index.js +2 -0
  104. package/dist/engine/boot-validator/pii-retention.js +233 -155
  105. package/dist/engine/boot-validator/screens-actions.d.ts +1 -0
  106. package/dist/engine/boot-validator/screens-actions.js +8 -1
  107. package/dist/engine/boot-validator/screens-dashboard.js +2 -5
  108. package/dist/engine/boot-validator/screens-forms.js +2 -6
  109. package/dist/engine/boot-validator/screens-kind-config-edit.d.ts +3 -0
  110. package/dist/engine/boot-validator/screens-kind-config-edit.js +88 -0
  111. package/dist/engine/boot-validator/screens-kind-entity-edit.d.ts +3 -0
  112. package/dist/engine/boot-validator/screens-kind-entity-edit.js +55 -0
  113. package/dist/engine/boot-validator/screens-kind-entity-list.d.ts +3 -0
  114. package/dist/engine/boot-validator/screens-kind-entity-list.js +228 -0
  115. package/dist/engine/boot-validator/screens-kind-projection-detail.d.ts +3 -0
  116. package/dist/engine/boot-validator/screens-kind-projection-detail.js +235 -0
  117. package/dist/engine/boot-validator/screens-kind-projection-list.d.ts +3 -0
  118. package/dist/engine/boot-validator/screens-kind-projection-list.js +52 -0
  119. package/dist/engine/boot-validator/screens-kind-secret-mint.d.ts +3 -0
  120. package/dist/engine/boot-validator/screens-kind-secret-mint.js +28 -0
  121. package/dist/engine/boot-validator/screens-kind-shared.d.ts +37 -0
  122. package/dist/engine/boot-validator/screens-kind-shared.js +142 -0
  123. package/dist/engine/boot-validator/screens-lists.d.ts +2 -1
  124. package/dist/engine/boot-validator/screens-lists.js +12 -9
  125. package/dist/engine/boot-validator/screens.d.ts +0 -2
  126. package/dist/engine/boot-validator/screens.js +99 -860
  127. package/dist/engine/build-app-schema.js +56 -96
  128. package/dist/engine/define-feature.js +9 -2
  129. package/dist/engine/define-handler.js +1 -0
  130. package/dist/engine/entity-handlers.d.ts +13 -0
  131. package/dist/engine/entity-handlers.js +10 -21
  132. package/dist/engine/entity-list-runtime-options.d.ts +8 -0
  133. package/dist/engine/entity-list-runtime-options.js +18 -0
  134. package/dist/engine/feature-ast/extractors/handlers.js +1 -0
  135. package/dist/engine/feature-ast/extractors/round2.js +25 -6
  136. package/dist/engine/feature-ast/patch.js +4 -182
  137. package/dist/engine/feature-ast/pattern-change-schema.d.ts +3 -0
  138. package/dist/engine/feature-ast/pattern-change-schema.js +1 -0
  139. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +7 -0
  140. package/dist/engine/feature-ast/pattern-id-matchers.js +210 -0
  141. package/dist/engine/feature-ast/patterns.d.ts +9 -0
  142. package/dist/engine/feature-ast/patterns.js +43 -51
  143. package/dist/engine/feature-ast/render.js +48 -87
  144. package/dist/engine/feature-entity-handlers.js +3 -0
  145. package/dist/engine/form-derivations.js +18 -7
  146. package/dist/engine/handler-field-references.js +1 -1
  147. package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
  148. package/dist/engine/project-app-schema-for-roles.js +6 -4
  149. package/dist/engine/registry-ingest.js +1 -1
  150. package/dist/engine/schema-builder.js +228 -212
  151. package/dist/engine/screen-helpers.js +1 -1
  152. package/dist/engine/screen-kind.d.ts +7 -0
  153. package/dist/engine/screen-kind.js +1 -0
  154. package/dist/engine/strip-disabled-features-from-app-schema.js +51 -14
  155. package/dist/engine/validate-projection-allowlist.js +2 -1
  156. package/dist/entrypoint/index.d.ts +4 -1
  157. package/dist/entrypoint/index.js +7 -1
  158. package/dist/errors/docs-url.d.ts +1 -1
  159. package/dist/errors/docs-url.js +22 -2
  160. package/dist/es-ops/context.js +1 -1
  161. package/dist/event-store/admin-api.js +1 -1
  162. package/dist/event-store/event-store.js +10 -4
  163. package/dist/files/bind-pending-file-refs.js +3 -3
  164. package/dist/files/create-file-ref-from-bytes.js +4 -1
  165. package/dist/files/file-handle.js +2 -3
  166. package/dist/files/file-routes.js +11 -8
  167. package/dist/files/resolve-content-type.js +43 -0
  168. package/dist/files/upload-ledger.js +7 -0
  169. package/dist/i18n/required-surface-keys.js +182 -206
  170. package/dist/internal/stack-support.d.ts +2 -1
  171. package/dist/internal/stack-support.js +1 -1
  172. package/dist/jobs/job-runner-context.d.ts +32 -0
  173. package/dist/jobs/job-runner-context.js +305 -0
  174. package/dist/jobs/job-runner-execution.d.ts +7 -0
  175. package/dist/jobs/job-runner-execution.js +160 -0
  176. package/dist/jobs/job-runner-gates.d.ts +19 -0
  177. package/dist/jobs/job-runner-gates.js +198 -0
  178. package/dist/jobs/job-runner-helpers.d.ts +17 -3
  179. package/dist/jobs/job-runner-helpers.js +61 -2
  180. package/dist/jobs/job-runner-scope.d.ts +44 -0
  181. package/dist/jobs/job-runner-scope.js +102 -0
  182. package/dist/jobs/job-runner-types.d.ts +12 -0
  183. package/dist/jobs/job-runner.d.ts +0 -1
  184. package/dist/jobs/job-runner.js +47 -657
  185. package/dist/observability/escape-hatch-report.d.ts +3 -0
  186. package/dist/observability/escape-hatch-report.js +12 -1
  187. package/dist/pipeline/cascade-handler.js +165 -138
  188. package/dist/pipeline/dispatch-query.js +10 -3
  189. package/dist/pipeline/dispatch-shared.d.ts +13 -3
  190. package/dist/pipeline/dispatch-shared.js +58 -710
  191. package/dist/pipeline/dispatch-write.js +296 -189
  192. package/dist/pipeline/event-dispatcher-admin.js +2 -1
  193. package/dist/pipeline/event-dispatcher-delivery.js +3 -5
  194. package/dist/pipeline/handler-context-auth.d.ts +9 -0
  195. package/dist/pipeline/handler-context-auth.js +54 -0
  196. package/dist/pipeline/handler-context-config.d.ts +14 -0
  197. package/dist/pipeline/handler-context-config.js +113 -0
  198. package/dist/pipeline/handler-context-db.d.ts +24 -0
  199. package/dist/pipeline/handler-context-db.js +149 -0
  200. package/dist/pipeline/handler-context-dispatch.d.ts +21 -0
  201. package/dist/pipeline/handler-context-dispatch.js +89 -0
  202. package/dist/pipeline/handler-context-events.d.ts +43 -0
  203. package/dist/pipeline/handler-context-events.js +237 -0
  204. package/dist/pipeline/handler-context-notify.d.ts +12 -0
  205. package/dist/pipeline/handler-context-notify.js +55 -0
  206. package/dist/pipeline/handler-context-observability.d.ts +7 -0
  207. package/dist/pipeline/handler-context-observability.js +21 -0
  208. package/dist/pipeline/handler-context-scope.d.ts +48 -0
  209. package/dist/pipeline/handler-context-scope.js +88 -0
  210. package/dist/pipeline/notify-scope.js +12 -1
  211. package/dist/pipeline/pre-handler-gates.js +20 -4
  212. package/dist/pipeline/pre-transaction-reservations.d.ts +1 -0
  213. package/dist/pipeline/pre-transaction-reservations.js +9 -3
  214. package/dist/pipeline/projection-rebuild.js +2 -1
  215. package/dist/schema-cli/apply-command.d.ts +2 -0
  216. package/dist/schema-cli/apply-command.js +97 -0
  217. package/dist/schema-cli/baseline-command.d.ts +2 -0
  218. package/dist/schema-cli/baseline-command.js +33 -0
  219. package/dist/schema-cli/generate-command.d.ts +2 -0
  220. package/dist/schema-cli/generate-command.js +90 -0
  221. package/dist/schema-cli/shared.d.ts +39 -0
  222. package/dist/schema-cli/shared.js +95 -0
  223. package/dist/schema-cli/status-command.d.ts +2 -0
  224. package/dist/schema-cli/status-command.js +73 -0
  225. package/dist/schema-cli/validate-boot-input.d.ts +5 -0
  226. package/dist/schema-cli/validate-boot-input.js +130 -0
  227. package/dist/schema-cli/validate-command.d.ts +2 -0
  228. package/dist/schema-cli/validate-command.js +130 -0
  229. package/dist/schema-cli.d.ts +2 -18
  230. package/dist/schema-cli.js +47 -604
  231. package/dist/search/meilisearch-adapter.js +2 -1
  232. package/dist/upgrade-cli.js +149 -121
  233. package/package.json +4 -4
  234. package/src/changes.json +310 -0
  235. package/src/scripts/codemod/feature-layout.ts +10 -2
  236. package/src/scripts/codemod/object-form.ts +41 -4
  237. package/src/scripts/codemod/package-merge.ts +58 -8
  238. package/src/scripts/codemod/pii-personal-migration.ts +175 -145
  239. package/src/scripts/codemod/testing-injection.ts +122 -42
  240. package/src/scripts/codemod/testing-move.ts +29 -7
@@ -0,0 +1,130 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { diffReplayAgainstSnapshot, generateMigration, readMigrationSqlTexts, replayMigrationsDir, } from "../db/index.js";
4
+ import { validateBoot } from "../engine/boot-validator.js";
5
+ import { describeThrown, loadPreviousSnapshot, loadSchemaModOrReport, nextSequenceNumber, SNAPSHOT_FILENAME, } from "./shared.js";
6
+ import { featureDefinitionsOf, parseValidateBootOptions, withFileStoragePresence, } from "./validate-boot-input.js";
7
+ // 1. Schema drift — compute the diff, never write.
8
+ function checkSchemaDrift(ctx, schemaMod, prevSnapshot) {
9
+ const { out, migrationsDir } = ctx;
10
+ const drift = generateMigration({
11
+ metas: schemaMod.entityMetas,
12
+ prevSnapshot,
13
+ name: "validate",
14
+ sequenceNumber: nextSequenceNumber(migrationsDir),
15
+ priorMigrationsSql: readMigrationSqlTexts(migrationsDir),
16
+ });
17
+ const pendingTables = [
18
+ ...drift.diff.newTables.map((t) => t.tableName),
19
+ ...drift.diff.changedTables.map((t) => t.tableName),
20
+ ...drift.diff.droppedTables,
21
+ ...drift.retiredDrops.map((t) => t.tableName),
22
+ ];
23
+ if (pendingTables.length === 0) {
24
+ out.log(" ✓ schema: migrations match the entity definitions");
25
+ return true;
26
+ }
27
+ out.err(" ✗ schema drift: entity definitions are ahead of kumiko/migrations.");
28
+ out.err(` pending — new: ${drift.diff.newTables.length}, changed: ${drift.diff.changedTables.length}, dropped: ${drift.diff.droppedTables.length}`);
29
+ out.err(` tables: ${pendingTables.join(", ")}`);
30
+ out.err(" Fix: `kumiko-schema generate <name>`, then commit the migration.");
31
+ return false;
32
+ }
33
+ // 2. Boot validity — needs the composed feature set.
34
+ function checkBootValidity(out, schemaMod) {
35
+ let bootFeatures;
36
+ try {
37
+ bootFeatures = featureDefinitionsOf(schemaMod.features);
38
+ }
39
+ catch (e) {
40
+ out.err(` ✗ boot: ${describeThrown(e)}`);
41
+ return false;
42
+ }
43
+ if (bootFeatures === undefined) {
44
+ out.log(" · boot: skipped — add `export const FEATURES = composeFeatures(APP_FEATURES, { includeBundled: true })` to kumiko/schema.ts to enable validateBoot.");
45
+ return true;
46
+ }
47
+ try {
48
+ validateBoot(bootFeatures, {
49
+ ...parseValidateBootOptions(schemaMod.validateBootOptions),
50
+ env: withFileStoragePresence(process.env),
51
+ });
52
+ out.log(" ✓ boot: feature configuration is valid");
53
+ return true;
54
+ }
55
+ catch (e) {
56
+ out.err(` ✗ boot: ${describeThrown(e)}`);
57
+ return false;
58
+ }
59
+ }
60
+ function reportMigrationContentMismatches(out, mismatches) {
61
+ out.err(" ✗ migration-content drift: committed *.sql files don't produce .snapshot.json.");
62
+ for (const m of mismatches) {
63
+ out.err(` ${m.tableName} (${m.kind}): ${m.detail}`);
64
+ }
65
+ if (mismatches.some((m) => m.kind === "unexpected-table")) {
66
+ out.err(" Fix (unexpected-table): build a meta via `defineUnmanagedTable()` " +
67
+ "from `@cosmicdrift/kumiko-framework/db`, then `r.storeTable(meta, { reason: ... })` " +
68
+ "inside a feature — this adds it to ENTITY_METAS immediately; the .snapshot.json " +
69
+ "only picks it up on the NEXT `kumiko-schema generate` run, which you still need " +
70
+ "to run and commit. `table()` returns a query handle, not a storeTable()-compatible " +
71
+ "meta — don't pass its result to storeTable(). See the bundled `jobs` feature's " +
72
+ "job-run-log store table for the pattern.");
73
+ }
74
+ if (mismatches.some((m) => m.kind !== "unexpected-table")) {
75
+ out.err(" Fix (missing-table/column-drift): a migration file's body doesn't match " +
76
+ "what it (or the snapshot) claims — hand-fix the file, or ship a corrective " +
77
+ "migration if it's already applied in prod.");
78
+ }
79
+ }
80
+ // 3. Migration-content drift — replay the committed *.sql files and
81
+ // diff the reconstructed schema against .snapshot.json.
82
+ function checkMigrationContentDrift(ctx, prevSnapshot) {
83
+ const { out, migrationsDir } = ctx;
84
+ if (!existsSync(migrationsDir) || prevSnapshot === null)
85
+ return true;
86
+ try {
87
+ const replayed = replayMigrationsDir(migrationsDir);
88
+ const mismatches = diffReplayAgainstSnapshot(replayed, prevSnapshot);
89
+ if (mismatches.length === 0) {
90
+ out.log(" ✓ migrations: table/column names match .snapshot.json");
91
+ return true;
92
+ }
93
+ reportMigrationContentMismatches(out, mismatches);
94
+ return false;
95
+ }
96
+ catch (e) {
97
+ // replayMigrationsDir fail-loud's on a table-DDL statement it can't
98
+ // parse — that must surface as a normal ✗ line like every other
99
+ // check here, not a raw stack trace that kills the process before
100
+ // any later check (or the Fix: help) ever runs.
101
+ out.err(` ✗ migration-content: ${describeThrown(e)}`);
102
+ out.err(" Fix: a statement in a migration file isn't recognizable to the replay parser — extend the parser's recognized patterns, or reword the migration to one it understands.");
103
+ return false;
104
+ }
105
+ }
106
+ // Static, DB-free boot-blocking checks for CI — catches "this won't boot"
107
+ // before deploy. Three layers, no database:
108
+ // 1. schema drift: would `generate` write a migration? (= an entity was
109
+ // added/changed but never generated → missing table → prod 500)
110
+ // 2. boot validity: validateBoot over the composed FEATURES (QN/screen/
111
+ // nav/role refs). Runs only if kumiko/schema.ts exports FEATURES;
112
+ // honours its optional VALIDATE_BOOT_OPTIONS export.
113
+ // 3. migration-content drift: replay every committed *.sql file and
114
+ // diff the result against .snapshot.json — catches a migration
115
+ // file whose SQL body doesn't match what its own snapshot entry
116
+ // claims (e.g. an accidental copy-paste from an earlier file).
117
+ // Layer 1 alone misses this: it only compares ENTITY_METAS to the
118
+ // snapshot, never the snapshot to the SQL that's supposed to have
119
+ // produced it.
120
+ // The DB-level gate (assertKumikoSchemaCurrent) stays at boot/deploy.
121
+ export async function runValidateCommand(ctx) {
122
+ const schemaMod = await loadSchemaModOrReport(ctx);
123
+ if (schemaMod === undefined)
124
+ return 1;
125
+ const prevSnapshot = loadPreviousSnapshot(join(ctx.migrationsDir, SNAPSHOT_FILENAME));
126
+ const schemaOk = checkSchemaDrift(ctx, schemaMod, prevSnapshot);
127
+ const bootOk = checkBootValidity(ctx.out, schemaMod);
128
+ const migrationsOk = checkMigrationContentDrift(ctx, prevSnapshot);
129
+ return schemaOk && bootOk && migrationsOk ? 0 : 1;
130
+ }
@@ -1,21 +1,5 @@
1
- import type { FeatureDefinition } from "./engine/types/feature.ts";
2
- export type SchemaCliOut = {
3
- readonly log: (line: string) => void;
4
- readonly err: (line: string) => void;
5
- };
6
- export type RunSchemaCliOptions = {
7
- readonly features?: undefined;
8
- readonly kmsSlots?: undefined;
9
- } | {
10
- /** Composed app features. When given, `apply` rebuilds the projections whose
11
- * tables a freshly applied migration changed (via its `.rebuild.json`
12
- * marker). Omitted (dev `kumiko schema`) → no rebuild, migrations only. */
13
- readonly features: readonly FeatureDefinition[];
14
- /** Schema-declared Key Manager slots, `kmsSlotsOf(composedEnv.schema)`, or
15
- * `[]` when the app wires none. This CLI parses no env schema, so the
16
- * rebuild's KMS wiring cannot derive them itself. */
17
- readonly kmsSlots: readonly string[];
18
- };
1
+ import type { RunSchemaCliOptions, SchemaCliOut } from "./schema-cli/shared.ts";
2
+ export type { RunSchemaCliOptions, SchemaCliOut } from "./schema-cli/shared.ts";
19
3
  /**
20
4
  * Runs a schema-CLI subcommand. `appCwd` is the app workspace root (where
21
5
  * `kumiko/schema.ts` + `kumiko/migrations/` live). Returns a process exit code.