@cosmicdrift/kumiko-framework 0.389.0 → 0.390.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 (616) hide show
  1. package/AGENTS.md +9 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/inbound-mail-triage.md +1 -0
  13. package/agents/examples/lane-routing.md +2 -1
  14. package/agents/examples/legal-pages.md +2 -2
  15. package/agents/examples/lifecycle-hooks.md +3 -3
  16. package/agents/examples/managed-config.md +4 -4
  17. package/agents/examples/managed-pages.md +1 -1
  18. package/agents/examples/relations.md +19 -4
  19. package/agents/examples/search.md +4 -4
  20. package/agents/examples/secrets-demo.md +9 -6
  21. package/agents/examples/state-machine.md +2 -2
  22. package/agents/examples/tenant-settings.md +1 -1
  23. package/agents/examples/user-data-rights.md +3 -6
  24. package/agents/examples/workflow-engine.md +53 -47
  25. package/agents/examples.md +4 -4
  26. package/agents/features.md +1 -1
  27. package/dist/api/auth-middleware.js +1 -1
  28. package/dist/api/auth-routes-invite.js +2 -1
  29. package/dist/api/entity-read-access.d.ts +3 -1
  30. package/dist/api/export/export-columns.d.ts +3 -1
  31. package/dist/api/export/export-route.js +3 -2
  32. package/dist/api/export/export-screen.d.ts +2 -1
  33. package/dist/api/extra-route.d.ts +3 -1
  34. package/dist/api/index.d.ts +23 -27
  35. package/dist/api/index.js +13 -15
  36. package/dist/api/jwt.js +1 -1
  37. package/dist/api/observability-middleware.d.ts +1 -1
  38. package/dist/api/observability-middleware.js +2 -1
  39. package/dist/api/request-context-internals.d.ts +31 -0
  40. package/dist/api/request-context-internals.js +11 -0
  41. package/dist/api/request-context-scopes.d.ts +14 -0
  42. package/dist/api/request-context-scopes.js +69 -0
  43. package/dist/api/request-context.d.ts +1 -40
  44. package/dist/api/request-context.js +22 -51
  45. package/dist/api/request-id-middleware.d.ts +1 -1
  46. package/dist/api/route-registrars.d.ts +2 -1
  47. package/dist/api/route-registrars.js +1 -1
  48. package/dist/api/routes.js +7 -3
  49. package/dist/api/server-boot-checks.d.ts +1 -1
  50. package/dist/api/server-boot-checks.js +2 -2
  51. package/dist/api/server-event-dispatcher.d.ts +6 -1
  52. package/dist/api/server-event-dispatcher.js +3 -4
  53. package/dist/api/server-extra-routes.d.ts +1 -1
  54. package/dist/api/server-extra-routes.js +2 -1
  55. package/dist/api/server-middleware.js +3 -1
  56. package/dist/api/server-routes.d.ts +2 -1
  57. package/dist/api/server-wiring.js +6 -4
  58. package/dist/api/server.d.ts +2 -1
  59. package/dist/api/sse-route.d.ts +2 -1
  60. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  61. package/dist/api/tenant-scoped-secrets.js +13 -0
  62. package/dist/api/websocket-route.d.ts +1 -1
  63. package/dist/auth/index.d.ts +0 -1
  64. package/dist/auth/roles.d.ts +0 -5
  65. package/dist/compliance/duration-spec.d.ts +0 -1
  66. package/dist/compliance/duration-spec.js +0 -5
  67. package/dist/compliance/index.d.ts +4 -4
  68. package/dist/compliance/index.js +2 -2
  69. package/dist/compliance/profiles.d.ts +0 -15
  70. package/dist/compliance/profiles.js +0 -23
  71. package/dist/config/index.d.ts +10 -10
  72. package/dist/config/index.js +13 -1
  73. package/dist/config/internals.d.ts +9 -0
  74. package/dist/config/internals.js +1 -0
  75. package/dist/consumer-cli-internals.d.ts +4 -0
  76. package/dist/consumer-cli-internals.js +1 -0
  77. package/dist/consumer-cli.d.ts +1 -4
  78. package/dist/consumer-cli.js +5 -1
  79. package/dist/crypto/event-pii.js +1 -1
  80. package/dist/crypto/index.d.ts +8 -9
  81. package/dist/crypto/index.js +7 -8
  82. package/dist/crypto/pg-kms-adapter.js +6 -1
  83. package/dist/db/apply-entity-event.d.ts +1 -1
  84. package/dist/db/apply-entity-event.js +15 -47
  85. package/dist/db/blind-index-cleanup.js +91 -77
  86. package/dist/db/collect-table-metas.js +1 -1
  87. package/dist/db/compound-types.d.ts +1 -1
  88. package/dist/db/compound-types.js +0 -7
  89. package/dist/db/config-seed.d.ts +2 -1
  90. package/dist/db/config-seed.js +6 -1
  91. package/dist/db/connection.d.ts +3 -1
  92. package/dist/db/connection.js +15 -5
  93. package/dist/db/cross-tenant-reads.d.ts +1 -1
  94. package/dist/db/cross-tenant-reads.js +1 -1
  95. package/dist/db/dialect.d.ts +0 -5
  96. package/dist/db/dialect.js +0 -3
  97. package/dist/db/eagerload.d.ts +2 -1
  98. package/dist/db/entity-field-encryption.d.ts +1 -1
  99. package/dist/db/entity-table-meta.d.ts +1 -1
  100. package/dist/db/event-store-executor-context.d.ts +3 -1
  101. package/dist/db/event-store-executor-context.js +4 -3
  102. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  103. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  104. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  105. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  106. package/dist/db/event-store-executor-read.js +2 -2
  107. package/dist/db/event-store-executor-write-atomic.js +8 -7
  108. package/dist/db/event-store-executor-write-steps.d.ts +3 -2
  109. package/dist/db/event-store-executor-write.js +7 -4
  110. package/dist/db/event-store-executor.d.ts +1 -1
  111. package/dist/db/executor-managed-tables.d.ts +7 -1
  112. package/dist/db/executor-managed-tables.js +11 -2
  113. package/dist/db/index.d.ts +29 -28
  114. package/dist/db/index.js +22 -20
  115. package/dist/db/known-table-names.d.ts +6 -0
  116. package/dist/db/known-table-names.js +21 -0
  117. package/dist/db/list-aggregate-labels.d.ts +1 -1
  118. package/dist/db/located-timestamp.d.ts +1 -1
  119. package/dist/db/located-timestamp.js +0 -5
  120. package/dist/db/migrate-generator.d.ts +17 -1
  121. package/dist/db/migrate-generator.js +50 -20
  122. package/dist/db/migrate-primary-key.d.ts +12 -0
  123. package/dist/db/migrate-primary-key.js +45 -0
  124. package/dist/db/migrate-rls-diff.d.ts +20 -0
  125. package/dist/db/migrate-rls-diff.js +61 -0
  126. package/dist/db/migrate-runner.js +4 -0
  127. package/dist/db/money.d.ts +1 -1
  128. package/dist/db/money.js +1 -1
  129. package/dist/db/parent-ref-clause.d.ts +2 -1
  130. package/dist/db/pg-error.d.ts +2 -0
  131. package/dist/db/pg-error.js +11 -0
  132. package/dist/db/queries/ddl.d.ts +3 -0
  133. package/dist/db/queries/ddl.js +34 -1
  134. package/dist/db/queries/event-store.js +4 -2
  135. package/dist/db/queries/event-tenants.d.ts +2 -0
  136. package/dist/db/queries/event-tenants.js +17 -0
  137. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  138. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  139. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  140. package/dist/db/queries/rls-boot-catalog.js +39 -0
  141. package/dist/db/queries/rls-catalog.d.ts +6 -0
  142. package/dist/db/queries/rls-catalog.js +82 -0
  143. package/dist/db/queries/rls-scope.d.ts +3 -0
  144. package/dist/db/queries/rls-scope.js +17 -0
  145. package/dist/db/queries/rls-shape.d.ts +10 -0
  146. package/dist/db/queries/rls-shape.js +42 -0
  147. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  148. package/dist/db/queries/session-advisory-lock.js +23 -0
  149. package/dist/db/queries/shadow-swap.d.ts +1 -2
  150. package/dist/db/queries/shadow-swap.js +9 -25
  151. package/dist/db/queries/test-stack.d.ts +4 -1
  152. package/dist/db/queries/test-stack.js +83 -2
  153. package/dist/db/query.js +11 -7
  154. package/dist/db/reference-data.d.ts +1 -1
  155. package/dist/db/reference-data.js +6 -1
  156. package/dist/db/render-ddl.d.ts +6 -2
  157. package/dist/db/render-ddl.js +7 -7
  158. package/dist/db/render-rls-ddl.d.ts +35 -0
  159. package/dist/db/render-rls-ddl.js +127 -0
  160. package/dist/db/replay-migration-sql.d.ts +3 -1
  161. package/dist/db/replay-migration-sql.js +22 -5
  162. package/dist/db/replay-rls.d.ts +25 -0
  163. package/dist/db/replay-rls.js +156 -0
  164. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  165. package/dist/db/row-level-security-boot-check.js +85 -0
  166. package/dist/db/row-level-security-connection.d.ts +3 -0
  167. package/dist/db/row-level-security-connection.js +213 -0
  168. package/dist/db/row-level-security-scope.d.ts +33 -0
  169. package/dist/db/row-level-security-scope.js +127 -0
  170. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  171. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  172. package/dist/db/sql-identifier.d.ts +1 -0
  173. package/dist/db/sql-identifier.js +3 -0
  174. package/dist/db/table-builder.d.ts +2 -1
  175. package/dist/db/table-builder.js +1 -1
  176. package/dist/db/table-info.js +1 -1
  177. package/dist/db/table-push.d.ts +11 -2
  178. package/dist/db/table-push.js +15 -2
  179. package/dist/db/tenant-db-runner.d.ts +3 -1
  180. package/dist/db/tenant-db-runner.js +4 -3
  181. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  182. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  183. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  184. package/dist/db/tenant-db-statement-runner.js +48 -0
  185. package/dist/db/tenant-db.d.ts +17 -12
  186. package/dist/db/tenant-db.js +49 -120
  187. package/dist/db/tenant-id-filter.d.ts +3 -0
  188. package/dist/db/tenant-id-filter.js +30 -0
  189. package/dist/db/transaction-serialization.d.ts +6 -0
  190. package/dist/db/transaction-serialization.js +60 -0
  191. package/dist/derivatives/delete-stored-file.js +1 -1
  192. package/dist/derivatives/index.d.ts +2 -5
  193. package/dist/derivatives/index.js +2 -3
  194. package/dist/engine/access.d.ts +2 -1
  195. package/dist/engine/access.js +1 -1
  196. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  197. package/dist/engine/boot-validator/entity-handler.js +1 -1
  198. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
  199. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
  200. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
  201. package/dist/engine/boot-validator/nav.d.ts +3 -1
  202. package/dist/engine/boot-validator/nav.js +1 -1
  203. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  204. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  205. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  206. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  207. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  209. package/dist/engine/boot-validator/screens.d.ts +2 -1
  210. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  211. package/dist/engine/bridge-stub.d.ts +5 -2
  212. package/dist/engine/bridge-stub.js +39 -24
  213. package/dist/engine/config-helpers.d.ts +2 -2
  214. package/dist/engine/config-helpers.js +0 -9
  215. package/dist/engine/constants.d.ts +0 -10
  216. package/dist/engine/constants.js +0 -8
  217. package/dist/engine/create-app.js +1 -1
  218. package/dist/engine/define-feature.d.ts +2 -1
  219. package/dist/engine/define-feature.js +1 -2
  220. package/dist/engine/define-handler.d.ts +1 -1
  221. package/dist/engine/define-step.d.ts +0 -1
  222. package/dist/engine/define-step.js +0 -3
  223. package/dist/engine/embedded-derived.d.ts +1 -1
  224. package/dist/engine/entity-handlers.d.ts +2 -1
  225. package/dist/engine/entity-handlers.js +7 -7
  226. package/dist/engine/entity-list-runtime-options.js +3 -1
  227. package/dist/engine/entity-list-searchability.d.ts +2 -1
  228. package/dist/engine/event-def.d.ts +2 -1
  229. package/dist/engine/event-helpers.d.ts +3 -1
  230. package/dist/engine/event-helpers.js +3 -3
  231. package/dist/engine/extension-names.d.ts +2 -8
  232. package/dist/engine/extension-names.js +2 -2
  233. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  234. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  235. package/dist/engine/extensions/user-data.d.ts +0 -8
  236. package/dist/engine/factories.d.ts +2 -1
  237. package/dist/engine/feature-builder-state.d.ts +8 -1
  238. package/dist/engine/feature-changelog.d.ts +1 -1
  239. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  240. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  241. package/dist/engine/feature-manifest.js +1 -1
  242. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  243. package/dist/engine/feature-ui-extensions.js +6 -4
  244. package/dist/engine/field-access.d.ts +2 -1
  245. package/dist/engine/handler-field-references.d.ts +0 -4
  246. package/dist/engine/index.d.ts +57 -54
  247. package/dist/engine/index.js +22 -27
  248. package/dist/engine/instruction-fields.d.ts +1 -1
  249. package/dist/engine/personal-data-fields.d.ts +1 -1
  250. package/dist/engine/qualified-name.d.ts +0 -1
  251. package/dist/engine/read-claim.d.ts +2 -1
  252. package/dist/engine/registry-facade.js +0 -3
  253. package/dist/engine/registry-ingest.d.ts +2 -1
  254. package/dist/engine/registry-ingest.js +1 -2
  255. package/dist/engine/registry-state.d.ts +12 -2
  256. package/dist/engine/registry-state.js +2 -3
  257. package/dist/engine/registry-validate.d.ts +3 -1
  258. package/dist/engine/registry-validate.js +7 -7
  259. package/dist/engine/run-in.d.ts +1 -1
  260. package/dist/engine/run-in.js +0 -1
  261. package/dist/engine/schema-builder.d.ts +1 -1
  262. package/dist/engine/schema-builder.js +1 -1
  263. package/dist/engine/screen-filter-ops.d.ts +2 -1
  264. package/dist/engine/screen-filter-ops.js +0 -5
  265. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  266. package/dist/engine/soft-delete-cleanup.js +4 -4
  267. package/dist/engine/state-machine.js +2 -1
  268. package/dist/engine/steps/_read-source.js +1 -1
  269. package/dist/engine/steps/aggregate-append-event.js +2 -2
  270. package/dist/engine/steps/call-feature.js +2 -2
  271. package/dist/engine/steps/mail-send.js +1 -1
  272. package/dist/engine/steps/retry.js +1 -1
  273. package/dist/engine/steps/wait-for-event.js +1 -1
  274. package/dist/engine/steps/wait.js +1 -1
  275. package/dist/engine/steps/webhook-send.js +1 -1
  276. package/dist/engine/template-variables.d.ts +2 -1
  277. package/dist/engine/transfer-adjacency.d.ts +1 -1
  278. package/dist/engine/types/index.d.ts +8 -31
  279. package/dist/engine/types/index.js +2 -10
  280. package/dist/engine/validation.d.ts +2 -1
  281. package/dist/entrypoint/index.d.ts +7 -35
  282. package/dist/entrypoint/index.js +7 -1
  283. package/dist/entrypoint/internals.d.ts +40 -0
  284. package/dist/entrypoint/internals.js +1 -0
  285. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  286. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  287. package/dist/env/dry-run-internals.d.ts +10 -0
  288. package/dist/env/dry-run-internals.js +1 -0
  289. package/dist/env/dry-run.d.ts +1 -10
  290. package/dist/env/dry-run.js +2 -1
  291. package/dist/env/index.d.ts +1 -85
  292. package/dist/env/index.js +6 -50
  293. package/dist/env/internals.d.ts +87 -0
  294. package/dist/env/internals.js +53 -0
  295. package/dist/errors/classes.js +2 -2
  296. package/dist/errors/index.d.ts +5 -14
  297. package/dist/errors/index.js +4 -9
  298. package/dist/errors/member-resolution.js +1 -1
  299. package/dist/errors/reasons.d.ts +0 -1
  300. package/dist/errors/reasons.js +7 -7
  301. package/dist/errors/serialize.d.ts +0 -18
  302. package/dist/errors/serialize.js +0 -27
  303. package/dist/es-ops/index.d.ts +4 -4
  304. package/dist/es-ops/index.js +2 -2
  305. package/dist/es-ops/operations-schema.d.ts +1 -1
  306. package/dist/es-ops/types.d.ts +4 -5
  307. package/dist/event-store/admin-api-internals.d.ts +14 -0
  308. package/dist/event-store/admin-api-internals.js +1 -0
  309. package/dist/event-store/admin-api.d.ts +1 -14
  310. package/dist/event-store/admin-api.js +11 -6
  311. package/dist/event-store/archive.js +4 -2
  312. package/dist/event-store/errors.js +2 -2
  313. package/dist/event-store/event-store.js +41 -34
  314. package/dist/event-store/events-schema.js +4 -1
  315. package/dist/event-store/index.d.ts +11 -13
  316. package/dist/event-store/index.js +7 -9
  317. package/dist/event-store/rebuild-dead-letter.js +4 -2
  318. package/dist/event-store/snapshot.js +4 -3
  319. package/dist/event-store/stream-scope.d.ts +2 -0
  320. package/dist/event-store/stream-scope.js +6 -0
  321. package/dist/event-store/upcaster-dead-letter.js +4 -2
  322. package/dist/event-store/upcaster.d.ts +2 -1
  323. package/dist/files/action-form-upload.d.ts +2 -1
  324. package/dist/files/action-form-upload.js +1 -1
  325. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  326. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  327. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  328. package/dist/files/bind-pending-file-refs.js +2 -1
  329. package/dist/files/bind-referenced-files.write.js +1 -1
  330. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  331. package/dist/files/create-file-ref-from-bytes.js +3 -3
  332. package/dist/files/create-file-ref.d.ts +3 -2
  333. package/dist/files/create-file-ref.js +2 -2
  334. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  335. package/dist/files/dispose-removed-file-refs.js +1 -1
  336. package/dist/files/feature.js +2 -2
  337. package/dist/files/file-handle.js +1 -1
  338. package/dist/files/file-routes.d.ts +1 -1
  339. package/dist/files/file-routes.js +12 -2
  340. package/dist/files/index.d.ts +11 -13
  341. package/dist/files/index.js +5 -7
  342. package/dist/files/load-save-file-refs.d.ts +2 -1
  343. package/dist/files/load-save-file-refs.js +1 -1
  344. package/dist/files/provider-resolver.d.ts +5 -4
  345. package/dist/files/provider-resolver.js +4 -4
  346. package/dist/files/storage-tracking.js +4 -2
  347. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  348. package/dist/files/sweep-orphaned-uploads.js +1 -1
  349. package/dist/i18n/index.d.ts +2 -8
  350. package/dist/i18n/index.js +1 -1
  351. package/dist/i18n/internals.d.ts +7 -0
  352. package/dist/i18n/internals.js +1 -0
  353. package/dist/i18n/required-surface-keys.d.ts +4 -1
  354. package/dist/internal/row-level-security.d.ts +3 -0
  355. package/dist/internal/row-level-security.js +3 -0
  356. package/dist/internal/stack-support.d.ts +1 -1
  357. package/dist/internal/stack-support.js +1 -1
  358. package/dist/internal/testing.d.ts +1 -0
  359. package/dist/internal/testing.js +9 -5
  360. package/dist/jobs/index.d.ts +1 -1
  361. package/dist/jobs/job-append-event.d.ts +12 -0
  362. package/dist/jobs/job-append-event.js +30 -0
  363. package/dist/jobs/job-runner-context.d.ts +2 -2
  364. package/dist/jobs/job-runner-context.js +46 -16
  365. package/dist/jobs/job-runner-execution.d.ts +1 -1
  366. package/dist/jobs/job-runner-execution.js +6 -4
  367. package/dist/jobs/job-runner-gates.d.ts +1 -1
  368. package/dist/jobs/job-runner-gates.js +0 -1
  369. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  370. package/dist/jobs/job-runner-helpers.js +10 -1
  371. package/dist/jobs/job-runner-scope.d.ts +5 -2
  372. package/dist/jobs/job-runner-types.d.ts +2 -1
  373. package/dist/jobs/job-runner.js +19 -6
  374. package/dist/jobs/max-per-tenant.d.ts +1 -1
  375. package/dist/logging/index.d.ts +1 -2
  376. package/dist/logging/index.js +1 -1
  377. package/dist/logging/pino-logger.js +1 -1
  378. package/dist/logging/utils.d.ts +1 -0
  379. package/dist/logging/utils.js +6 -0
  380. package/dist/migrations/index.d.ts +3 -3
  381. package/dist/migrations/index.js +3 -3
  382. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  383. package/dist/migrations/pending-rebuilds.js +1 -1
  384. package/dist/migrations/pii-event-backfill.js +4 -1
  385. package/dist/observability/escape-hatch-report.d.ts +2 -1
  386. package/dist/observability/index.d.ts +7 -15
  387. package/dist/observability/index.js +4 -12
  388. package/dist/observability/metric-validator.js +1 -1
  389. package/dist/observability/metrics-handle.d.ts +0 -1
  390. package/dist/observability/metrics-handle.js +2 -15
  391. package/dist/observability/recording-tracer.d.ts +1 -2
  392. package/dist/observability/recording-tracer.js +0 -6
  393. package/dist/observability/sensitive-filter.d.ts +0 -2
  394. package/dist/observability/sensitive-filter.js +0 -29
  395. package/dist/pipeline/active-membership.d.ts +2 -1
  396. package/dist/pipeline/active-membership.js +6 -2
  397. package/dist/pipeline/append-event-core.d.ts +2 -1
  398. package/dist/pipeline/append-event-core.js +2 -2
  399. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  400. package/dist/pipeline/attach-outside-transaction.js +13 -0
  401. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  402. package/dist/pipeline/cascade-handler.d.ts +2 -1
  403. package/dist/pipeline/cascade-handler.js +3 -2
  404. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  405. package/dist/pipeline/config-accessor-factory.js +1 -1
  406. package/dist/pipeline/context-services.d.ts +56 -0
  407. package/dist/pipeline/context-services.js +73 -0
  408. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  409. package/dist/pipeline/dispatch-batch.js +31 -18
  410. package/dist/pipeline/dispatch-query.js +5 -4
  411. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  412. package/dist/pipeline/dispatch-scope.js +27 -0
  413. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  414. package/dist/pipeline/dispatch-shared.js +75 -198
  415. package/dist/pipeline/dispatch-stream.js +8 -4
  416. package/dist/pipeline/dispatch-write.d.ts +2 -1
  417. package/dist/pipeline/dispatch-write.js +10 -8
  418. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  419. package/dist/pipeline/dispatcher-utils.js +8 -2
  420. package/dist/pipeline/dispatcher.d.ts +3 -2
  421. package/dist/pipeline/dispatcher.js +4 -3
  422. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  423. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  424. package/dist/pipeline/event-dispatcher-delivery.js +4 -2
  425. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  426. package/dist/pipeline/event-dispatcher.js +7 -3
  427. package/dist/pipeline/event-retention.js +59 -56
  428. package/dist/pipeline/handler-access-error.js +2 -1
  429. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  430. package/dist/pipeline/handler-context-auth.js +7 -4
  431. package/dist/pipeline/handler-context-config.d.ts +2 -5
  432. package/dist/pipeline/handler-context-config.js +2 -2
  433. package/dist/pipeline/handler-context-db.d.ts +32 -7
  434. package/dist/pipeline/handler-context-db.js +26 -17
  435. package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
  436. package/dist/pipeline/handler-context-dispatch.js +9 -8
  437. package/dist/pipeline/handler-context-events.d.ts +22 -36
  438. package/dist/pipeline/handler-context-events.js +36 -31
  439. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  440. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  441. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  442. package/dist/pipeline/handler-context-notify.js +1 -1
  443. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  444. package/dist/pipeline/handler-context-observability.js +7 -5
  445. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  446. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  447. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  448. package/dist/pipeline/handler-context-scope.js +18 -20
  449. package/dist/pipeline/index.d.ts +9 -21
  450. package/dist/pipeline/index.js +5 -7
  451. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  452. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  453. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  454. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  455. package/dist/pipeline/member-read-only-transaction.js +11 -3
  456. package/dist/pipeline/member-reader.d.ts +1 -1
  457. package/dist/pipeline/member-reader.js +2 -2
  458. package/dist/pipeline/msp-rebuild.js +5 -3
  459. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  460. package/dist/pipeline/notify-scope.d.ts +2 -1
  461. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  462. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  463. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  464. package/dist/pipeline/projection-rebuild.js +12 -5
  465. package/dist/pipeline/projection-state.d.ts +0 -6
  466. package/dist/pipeline/projection-state.js +0 -5
  467. package/dist/pipeline/projections-runner.d.ts +2 -1
  468. package/dist/pipeline/projections-runner.js +10 -6
  469. package/dist/pipeline/system-hooks.d.ts +3 -1
  470. package/dist/pipeline/system-hooks.js +6 -4
  471. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  472. package/dist/pipeline/system-identity-switch.js +51 -36
  473. package/dist/pipeline/typed-append-event.d.ts +2 -0
  474. package/dist/pipeline/typed-append-event.js +4 -0
  475. package/dist/pipeline/write-origin.js +2 -2
  476. package/dist/pipeline/write-result-masking.d.ts +1 -1
  477. package/dist/random/index.d.ts +1 -2
  478. package/dist/random/index.js +1 -2
  479. package/dist/rate-limit/bucket.d.ts +2 -1
  480. package/dist/rate-limit/middleware.js +2 -1
  481. package/dist/redis/index.d.ts +3 -4
  482. package/dist/redis/index.js +2 -2
  483. package/dist/schema-cli/apply-command.js +5 -2
  484. package/dist/schema-cli/baseline-command.js +7 -2
  485. package/dist/schema-cli/generate-command.js +7 -9
  486. package/dist/schema-cli/shared.d.ts +4 -0
  487. package/dist/schema-cli/shared.js +21 -2
  488. package/dist/schema-cli/status-command.js +8 -2
  489. package/dist/schema-cli/validate-command.js +52 -4
  490. package/dist/schema-cli.d.ts +0 -1
  491. package/dist/search/configure-tenant-index.d.ts +1 -3
  492. package/dist/search/configure-tenant-index.js +0 -4
  493. package/dist/search/index.d.ts +1 -4
  494. package/dist/search/index.js +0 -2
  495. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  496. package/dist/search/meilisearch-adapter-internals.js +9 -0
  497. package/dist/search/meilisearch-adapter.d.ts +1 -8
  498. package/dist/search/meilisearch-adapter.js +6 -7
  499. package/dist/search/meilisearch-peer.d.ts +2 -0
  500. package/dist/search/meilisearch-peer.js +5 -0
  501. package/dist/search/reindex-entity.js +93 -87
  502. package/dist/secrets/index.d.ts +3 -4
  503. package/dist/secrets/index.js +2 -3
  504. package/dist/seeding/index.d.ts +2 -2
  505. package/dist/seeding/index.js +1 -2
  506. package/dist/time/index.d.ts +2 -2
  507. package/dist/time/index.js +1 -1
  508. package/dist/time/tz-context.d.ts +0 -5
  509. package/dist/time/tz-context.js +0 -9
  510. package/dist/ui-types/index.d.ts +8 -11
  511. package/dist/ui-types/index.js +3 -3
  512. package/dist/upgrade-changelog.d.ts +3 -2
  513. package/dist/upgrade-changelog.js +12 -8
  514. package/dist/upgrade-cli-internals.d.ts +8 -0
  515. package/dist/upgrade-cli-internals.js +63 -0
  516. package/dist/upgrade-cli.d.ts +1 -9
  517. package/dist/upgrade-cli.js +10 -64
  518. package/dist/utils/import-optional-peer.d.ts +6 -0
  519. package/dist/utils/import-optional-peer.js +19 -0
  520. package/dist/utils/index.d.ts +1 -4
  521. package/dist/utils/index.js +1 -4
  522. package/package.json +22 -18
  523. package/src/changes.json +206 -0
  524. package/dist/crypto/request-kms-cache.d.ts +0 -8
  525. package/dist/crypto/request-kms-cache.js +0 -21
  526. package/dist/engine/codemod/index.d.ts +0 -2
  527. package/dist/engine/codemod/index.js +0 -1
  528. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  529. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  530. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  531. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  532. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  533. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  534. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  535. package/dist/engine/feature-ast/extractors/events.js +0 -275
  536. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  537. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  538. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  539. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  540. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  541. package/dist/engine/feature-ast/extractors/index.js +0 -13
  542. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  543. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  544. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  545. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  546. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  547. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  548. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
  549. package/dist/engine/feature-ast/extractors/round1.js +0 -87
  550. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  551. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  552. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  553. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  554. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  555. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  556. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  557. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  558. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  559. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  560. package/dist/engine/feature-ast/index.d.ts +0 -16
  561. package/dist/engine/feature-ast/index.js +0 -10
  562. package/dist/engine/feature-ast/parse.d.ts +0 -31
  563. package/dist/engine/feature-ast/parse.js +0 -485
  564. package/dist/engine/feature-ast/patch.d.ts +0 -212
  565. package/dist/engine/feature-ast/patch.js +0 -611
  566. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  567. package/dist/engine/feature-ast/patcher.js +0 -281
  568. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
  569. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
  570. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  571. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
  572. package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
  573. package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
  574. package/dist/engine/feature-ast/patterns.d.ts +0 -322
  575. package/dist/engine/feature-ast/patterns.js +0 -107
  576. package/dist/engine/feature-ast/render.d.ts +0 -47
  577. package/dist/engine/feature-ast/render.js +0 -666
  578. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  579. package/dist/engine/feature-ast/source-location.js +0 -27
  580. package/dist/engine/pattern-library/index.d.ts +0 -2
  581. package/dist/engine/pattern-library/index.js +0 -3
  582. package/dist/engine/pattern-library/library.d.ts +0 -14
  583. package/dist/engine/pattern-library/library.js +0 -94
  584. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  585. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  586. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  587. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  588. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  589. package/dist/engine/pattern-library/shared-fields.js +0 -88
  590. package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
  591. package/dist/engine/pattern-library/static-schemas.js +0 -487
  592. package/dist/engine/pattern-library/types.d.ts +0 -158
  593. package/dist/engine/pattern-library/types.js +0 -36
  594. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  595. package/dist/engine/resolve-config-or-param.js +0 -76
  596. package/src/scripts/codemod/README.md +0 -187
  597. package/src/scripts/codemod/codemod-support.ts +0 -334
  598. package/src/scripts/codemod/collect-source-files.ts +0 -48
  599. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  600. package/src/scripts/codemod/db-factory.ts +0 -810
  601. package/src/scripts/codemod/feature-factory.ts +0 -429
  602. package/src/scripts/codemod/feature-layout.ts +0 -424
  603. package/src/scripts/codemod/import-extensions.ts +0 -118
  604. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  605. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  606. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  607. package/src/scripts/codemod/object-form.ts +0 -746
  608. package/src/scripts/codemod/package-merge.ts +0 -299
  609. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  610. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  611. package/src/scripts/codemod/s3-imports.ts +0 -236
  612. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  613. package/src/scripts/codemod/testing-injection.ts +0 -215
  614. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  615. package/src/scripts/codemod/testing-move.ts +0 -542
  616. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -1,611 +0,0 @@
1
- // Patch operations: apply add/replace/remove/update changes to a feature-file's
2
- // SourceFile in-place, working at the r.*-call granularity. Custom code
3
- // (helpers, comments, imports, anything between calls) survives every
4
- // patch unchanged — the patcher only touches the spans it owns.
5
- //
6
- // **Identity model — Natural-Key:** patterns are addressed by the
7
- // human-readable name they carry: entity-name, handler-name, nav-id,
8
- // hook-target+type, etc. Reorders and re-renderings don't break IDs;
9
- // renames are explicit (remove old → add new). For the few singleton
10
- // patterns (toggleable, requires, systemScope) the kind itself is the
11
- // key — a feature has at most one of each.
12
- //
13
- // **Position semantics:**
14
- // - addPattern → appended at the end of the setup callback
15
- // - replacePattern → in place, same indentation as the original call
16
- // - removePattern → call + leading blank-line whitespace gone
17
- // - updatePattern → only the named header properties of a handler's
18
- // inline object literal change; everything else, comments included,
19
- // stays byte-identical (no re-render)
20
- //
21
- // **Renderer-driven output.** Every pattern lands in canonical Object-
22
- // Form (single-arg literal, see render.ts). Existing patterns in legacy
23
- // positional form get converted on replace; new patterns start
24
- // canonical. Schema-Version-Header is the renderer's responsibility.
25
- //
26
- // **Comment-Preservation — known limitation.** Inline comments INSIDE a
27
- // pattern (e.g. `// reason: legacy field` on an entity field property)
28
- // are LOST on replace, because the renderer regenerates the call from
29
- // the parsed FeaturePattern, which doesn't carry comment-trivia.
30
- // Comments BETWEEN patterns (helper-functions, top-of-feature notes,
31
- // imports) survive every patch — only comments authored on lines the
32
- // patcher rewrites are dropped. Tracked as a future-work item: see
33
- // roadmap C-Notes for the canonical-comment-attach Pattern that would
34
- // preserve prefixed `// kumiko-comment:` markers across roundtrips.
35
- import { SyntaxKind, } from "ts-morph";
36
- import { readPropertyKey } from "./extractors/shared.js";
37
- import { callMatchesId } from "./pattern-id-matchers.js";
38
- import { indent, PATTERN_INDENT, renderPattern, renderValue } from "./render.js";
39
- /**
40
- * Apply a sequence of changes to the source file in-place. The list is
41
- * processed in order; replace/remove failures (id not found) throw so
42
- * callers can react explicitly — silent no-ops would mask design bugs
43
- * in the Designer/AI generator. Adds always succeed.
44
- *
45
- * The function does NOT save the file — `sourceFile.saveSync()` (or the
46
- * caller's persistence layer) is expected to follow.
47
- */
48
- export function applyChanges(sourceFile, changes) {
49
- for (const change of changes) {
50
- switch (change.op) {
51
- case "add":
52
- addPattern(sourceFile, change.pattern);
53
- break;
54
- case "replace":
55
- replacePattern(sourceFile, change.id, change.pattern);
56
- break;
57
- case "remove":
58
- removePattern(sourceFile, change.id);
59
- break;
60
- case "update":
61
- updatePattern(sourceFile, change);
62
- break;
63
- default: {
64
- const _exhaustive = change;
65
- throw new Error(`applyChanges: unknown op ${String(_exhaustive)}`);
66
- }
67
- }
68
- }
69
- }
70
- // =============================================================================
71
- // Add
72
- // =============================================================================
73
- /**
74
- * Low-level escape hatch: append a hand-built FeaturePattern at the end
75
- * of the setup callback's body. **Prefer the typed `add{Kind}` methods
76
- * on `createFeaturePatcher(sf)`** — they take natural args, build the
77
- * FeaturePattern internally, and avoid SourceLocation boilerplate.
78
- *
79
- * Use this directly when:
80
- * - Migrating a parsed pattern from another file (already-built
81
- * FeaturePattern object on hand)
82
- * - The pattern kind isn't yet covered by a typed `add{Kind}`
83
- *
84
- * The pattern is rendered (canonical Object-Form) and inserted as the
85
- * last statement, separated from the previous one by a blank line —
86
- * biome-stable formatting that matches the renderFeatureFile output.
87
- */
88
- export function addPattern(sourceFile, pattern) {
89
- if (isAiStepId(pattern)) {
90
- throw new Error(`addPattern: ${pattern.kind} steps must be inserted into a defineWorkflow steps array, not the setup body`);
91
- }
92
- const setup = findSetupCallback(sourceFile);
93
- if (!setup) {
94
- throw new Error("addPattern: no defineFeature(name, (r) => { ... }) call found");
95
- }
96
- const body = setup.body;
97
- const rendered = indent(renderPattern(pattern), PATTERN_INDENT);
98
- // Find the closing brace of the body to insert just before it. The body
99
- // is a Block; its last child is the close-brace, so the safe insertion
100
- // point is the position of the close-brace (insertText pushes it down).
101
- const closeBracePos = body.getEnd() - 1; // `}`
102
- const lastStatement = lastNonTriviaChild(body);
103
- // If the body has at least one statement, prefix with a blank line so
104
- // every pattern is visually separated. For an empty setup callback,
105
- // skip the leading newline so the first statement isn't preceded by a
106
- // gratuitous blank line.
107
- const needsLeadingBlank = lastStatement !== undefined;
108
- const text = needsLeadingBlank ? `\n${rendered}\n` : `${rendered}\n`;
109
- sourceFile.insertText(closeBracePos, text);
110
- }
111
- // =============================================================================
112
- // Replace
113
- // =============================================================================
114
- /**
115
- * Find the call matching `id` and replace the entire CallExpression text
116
- * with the rendered version of `pattern`. The replacement is reindented
117
- * to match the original call's column so existing helpers/comments
118
- * around it stay aligned. Throws when no call matches — callers must
119
- * handle that case explicitly.
120
- */
121
- export function replacePattern(sourceFile, id, pattern) {
122
- const call = findCallForId(sourceFile, id);
123
- if (!call) {
124
- throw new Error(`replacePattern: no call found for ${describeId(id)}`);
125
- }
126
- // Whole call-statement spans from the CallExpression's start through
127
- // its enclosing ExpressionStatement (which carries the trailing `;`).
128
- const enclosingStatement = call.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
129
- const startNode = isAiStepId(id) ? call : (enclosingStatement ?? call);
130
- const startPos = startNode.getStart();
131
- // AI steps live in array literals — replace only the CallExpression so the
132
- // surrounding comma stays (comma-eating belongs to removePattern alone).
133
- const endPos = isAiStepId(id) ? call.getEnd() : startNode.getEnd();
134
- // Detect column of the original call's first non-whitespace character;
135
- // the rendered pattern starts at column 0 and gets indented to match.
136
- const startLineCol = sourceFile.getLineAndColumnAtPos(startPos);
137
- const originalIndent = " ".repeat(Math.max(0, startLineCol.column - 1));
138
- const rendered = indent(renderPattern(pattern), originalIndent).trimStart();
139
- sourceFile.replaceText([startPos, endPos], rendered);
140
- }
141
- // =============================================================================
142
- // Remove
143
- // =============================================================================
144
- /**
145
- * Find the call matching `id` and remove it together with its trailing
146
- * newline. Comments belonging to the pattern are unaffected only when
147
- * they live BEFORE the call as line-leading trivia — those leading
148
- * comments are kept (they may belong to surrounding code, the patcher
149
- * can't disambiguate without semantic markers). Inline comments on the
150
- * same line as the call are removed with the call.
151
- */
152
- export function removePattern(sourceFile, id) {
153
- const call = findCallForId(sourceFile, id);
154
- if (!call) {
155
- throw new Error(`removePattern: no call found for ${describeId(id)}`);
156
- }
157
- if (isAiStepId(id)) {
158
- const { start, end } = aiStepPatchSpan(sourceFile, call);
159
- sourceFile.replaceText([start, end], "");
160
- }
161
- else {
162
- const enclosingStatement = call.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
163
- const target = enclosingStatement ?? call;
164
- // Erase from the start of the line containing the statement (so leading
165
- // indentation goes with it) through the trailing newline, including the
166
- // *leading* blank line that addPattern emits — keeps blank-line counts
167
- // stable under add → remove cycles. We don't touch leading comments.
168
- const startPos = lineStart(sourceFile, target.getStart());
169
- const endPos = lineEnd(sourceFile, target.getEnd());
170
- // Collapse a preceding blank line if there is one (avoids a double
171
- // blank line between the now-adjacent statements).
172
- const collapseStart = collapsePrecedingBlankLine(sourceFile, startPos);
173
- sourceFile.replaceText([collapseStart, endPos + 1], "");
174
- }
175
- }
176
- // =============================================================================
177
- // Update — patch a subset of a handler pattern's header fields in place
178
- // =============================================================================
179
- const WRITE_HANDLER_HEADER_KEY_FLAGS = {
180
- access: true,
181
- description: true,
182
- agent: true,
183
- rateLimit: true,
184
- additionalRateLimits: true,
185
- unsafeSkipTransitionGuard: true,
186
- escapeHatch: true,
187
- };
188
- const QUERY_HANDLER_HEADER_KEY_FLAGS = {
189
- access: true,
190
- description: true,
191
- agent: true,
192
- rateLimit: true,
193
- escapeHatch: true,
194
- };
195
- const STREAM_HANDLER_HEADER_KEY_FLAGS = {
196
- access: true,
197
- rateLimit: true,
198
- escapeHatch: true,
199
- };
200
- const HEADER_KEY_FLAGS_BY_HANDLER_KIND = {
201
- writeHandler: WRITE_HANDLER_HEADER_KEY_FLAGS,
202
- queryHandler: QUERY_HANDLER_HEADER_KEY_FLAGS,
203
- streamHandler: STREAM_HANDLER_HEADER_KEY_FLAGS,
204
- };
205
- function lastProperty(obj) {
206
- return obj.getProperties().at(-1);
207
- }
208
- // ts-morph's getProperty(name) keeps the quotes of string-literal keys, so `"description": x` would never match `description`.
209
- function findPropertyByKey(obj, key) {
210
- return obj.getProperties().find((prop) => {
211
- const assign = prop.asKind(SyntaxKind.PropertyAssignment);
212
- if (assign)
213
- return readPropertyKey(assign) === key;
214
- return prop.asKind(SyntaxKind.ShorthandPropertyAssignment)?.getName() === key;
215
- });
216
- }
217
- // Replaces the value of an already-present key; undefined when the key is missing.
218
- function buildInPlaceSetEdit(obj, key, value) {
219
- const sourceFile = obj.getSourceFile();
220
- const existing = findPropertyByKey(obj, key);
221
- const assign = existing?.asKind(SyntaxKind.PropertyAssignment);
222
- if (assign) {
223
- const init = assign.getInitializer();
224
- if (init) {
225
- // Column of the *property*, not the initializer — the initializer's
226
- // further-right column would misalign a multi-line rendered value.
227
- const col = sourceFile.getLineAndColumnAtPos(assign.getStart()).column;
228
- return { start: init.getStart(), end: init.getEnd(), text: renderValue(value, col - 1) };
229
- }
230
- }
231
- const shorthand = existing?.asKind(SyntaxKind.ShorthandPropertyAssignment);
232
- if (shorthand) {
233
- const col = sourceFile.getLineAndColumnAtPos(shorthand.getStart()).column;
234
- return {
235
- start: shorthand.getStart(),
236
- end: shorthand.getEnd(),
237
- text: `${key}: ${renderValue(value, col - 1)}`,
238
- };
239
- }
240
- return undefined;
241
- }
242
- // All missing keys go into ONE edit: separate edits would share the same
243
- // anchor position and depend on apply order and trailing-comma luck.
244
- function buildAppendEdit(obj, entries) {
245
- const sourceFile = obj.getSourceFile();
246
- const last = lastProperty(obj);
247
- const fullText = sourceFile.getFullText();
248
- const isSingleLineLiteral = !obj.getText().includes("\n");
249
- if (!last) {
250
- // Empty literal — insert right after the opening brace.
251
- const openBrace = obj.getFirstChildByKindOrThrow(SyntaxKind.OpenBraceToken);
252
- const joined = entries.map(([key, value]) => `${key}: ${renderValue(value, 0)}`).join(", ");
253
- return { start: openBrace.getEnd(), end: openBrace.getEnd(), text: ` ${joined} ` };
254
- }
255
- if (isSingleLineLiteral) {
256
- let pos = last.getEnd();
257
- const hasComma = fullText[pos] === ",";
258
- if (hasComma)
259
- pos++;
260
- const joined = entries.map(([key, value]) => `${key}: ${renderValue(value, 0)}`).join(", ");
261
- return { start: pos, end: pos, text: `${hasComma ? "" : ","} ${joined}` };
262
- }
263
- const col = sourceFile.getLineAndColumnAtPos(last.getStart()).column;
264
- const indentStr = " ".repeat(col - 1);
265
- const valueEnd = last.getEnd();
266
- const hasComma = fullText[valueEnd] === ",";
267
- const contentStart = hasComma ? valueEnd + 1 : valueEnd;
268
- const lineEndPos = lineEnd(sourceFile, contentStart);
269
- // Rest of the line after the value/comma — normally empty, or a trailing comment.
270
- const restOfLine = fullText.slice(contentStart, lineEndPos);
271
- const restIsBlankOrComment = restOfLine.trim().length === 0 || restOfLine.trim().startsWith("//");
272
- if (!restIsBlankOrComment) {
273
- // Last property shares its line with other content (e.g. `});`) —
274
- // appending here would land after it. Narrower than replace; bail.
275
- throw new Error("updatePattern: cannot append a header field — the handler literal's last property shares a line with other code; use replace");
276
- }
277
- const appended = entries
278
- .map(([key, value]) => `\n${indentStr}${key}: ${renderValue(value, col - 1)},`)
279
- .join("");
280
- // Reconstruct the comma here (not inserted after the value) so it lands
281
- // right after the value, never inside a trailing `//` comment.
282
- return { start: valueEnd, end: lineEndPos, text: `,${restOfLine}${appended}` };
283
- }
284
- // Whole-line delete: property was alone on its line (with its indentation
285
- // and trailing newline) — used when nothing else shares that line.
286
- function buildWholeLineUnsetEdit(sourceFile, lineStartPos, afterPos) {
287
- const text = sourceFile.getFullText();
288
- let end = afterPos;
289
- while (end < text.length && text[end] !== "\n")
290
- end++;
291
- if (end < text.length)
292
- end++;
293
- return { start: lineStartPos, end, text: "" };
294
- }
295
- // Inline delete: property shares its line with other content — remove only
296
- // the property plus its trailing comma+space, or (last on the line, no
297
- // trailing comma) the preceding comma+space.
298
- function buildInlineUnsetEdit(text, propStart, afterPos, hasTrailingComma) {
299
- let start = propStart;
300
- let end = afterPos;
301
- if (hasTrailingComma && text[end] === " ")
302
- end++;
303
- if (!hasTrailingComma) {
304
- let precedingStart = propStart;
305
- while (precedingStart > 0 && text[precedingStart - 1] === " ")
306
- precedingStart--;
307
- if (text[precedingStart - 1] === ",")
308
- start = precedingStart - 1;
309
- }
310
- return { start, end, text: "" };
311
- }
312
- function buildUnsetEdit(obj, key) {
313
- const prop = findPropertyByKey(obj, key);
314
- if (!prop)
315
- return undefined; // no-op: nothing to remove, unset is idempotent
316
- const sourceFile = obj.getSourceFile();
317
- const text = sourceFile.getFullText();
318
- const propStart = prop.getStart();
319
- const lineStartPos = lineStart(sourceFile, propStart);
320
- const beforeOnLine = text.slice(lineStartPos, propStart);
321
- let afterPos = prop.getEnd();
322
- const hasTrailingComma = text[afterPos] === ",";
323
- if (hasTrailingComma)
324
- afterPos++;
325
- let probe = afterPos;
326
- while (probe < text.length && (text[probe] === " " || text[probe] === "\t"))
327
- probe++;
328
- const restOfLine = text.slice(probe, lineEnd(sourceFile, probe));
329
- // Whole-line delete only when the property is alone on its line — else
330
- // this would eat sibling properties or the enclosing call's `});`.
331
- const aloneOnLine = beforeOnLine.trim().length === 0 &&
332
- (restOfLine.trim().length === 0 || restOfLine.trim().startsWith("//"));
333
- if (aloneOnLine)
334
- return buildWholeLineUnsetEdit(sourceFile, lineStartPos, afterPos);
335
- return buildInlineUnsetEdit(text, propStart, afterPos, hasTrailingComma);
336
- }
337
- function resolveUpdatableHandlerLiteral(sourceFile, change) {
338
- const call = findCallForId(sourceFile, change.id);
339
- if (!call) {
340
- throw new Error(`updatePattern: no call found for ${describeId(change.id)}`);
341
- }
342
- const args = call.getArguments();
343
- if (args.length !== 1) {
344
- throw new Error(`updatePattern: ${describeId(change.id)} uses the positional call form; update requires the object form; use replace`);
345
- }
346
- const arg0 = args[0];
347
- if (!arg0) {
348
- throw new Error(`updatePattern: no call found for ${describeId(change.id)}`);
349
- }
350
- const obj = arg0.asKind(SyntaxKind.ObjectLiteralExpression);
351
- if (!obj) {
352
- throw new Error(`updatePattern: ${describeId(change.id)} is not an inline object literal; use replace`);
353
- }
354
- if (obj.getProperties().some((prop) => prop.isKind(SyntaxKind.SpreadAssignment))) {
355
- throw new Error("updatePattern: cannot update a handler literal containing a spread; use replace");
356
- }
357
- return obj;
358
- }
359
- /**
360
- * Apply a `HandlerHeaderUpdate` to the header fields named in `set`/`unset`
361
- * only, via targeted text edits — `schemaSource`, `handlerBody`, comments,
362
- * and every unnamed field stay byte-identical (narrower than replacePattern).
363
- */
364
- export function updatePattern(sourceFile, change) {
365
- const obj = resolveUpdatableHandlerLiteral(sourceFile, change);
366
- const headerFlags = HEADER_KEY_FLAGS_BY_HANDLER_KIND[change.id.kind];
367
- const setEntries = Object.entries(change.set).filter(([, v]) => v !== undefined);
368
- for (const [key] of setEntries) {
369
- if (!Object.hasOwn(headerFlags, key)) {
370
- throw new Error(`updatePattern: "${key}" is not a header field of ${change.id.kind}`);
371
- }
372
- }
373
- // Widen to `string`: this is a runtime boundary, re-check even though the
374
- // static type already excludes "access" from `unset`.
375
- const unsetKeyList = change.unset ?? [];
376
- const setKeySet = new Set(setEntries.map(([key]) => key));
377
- for (const key of unsetKeyList) {
378
- if (!Object.hasOwn(headerFlags, key)) {
379
- throw new Error(`updatePattern: "${key}" is not a header field of ${change.id.kind}`);
380
- }
381
- if (key === "access") {
382
- throw new Error("updatePattern: access is required and cannot be unset");
383
- }
384
- if (setKeySet.has(key)) {
385
- throw new Error(`updatePattern: "${key}" is in both set and unset`);
386
- }
387
- }
388
- // Dedupe: two identical `unset` entries would otherwise produce two
389
- // overlapping deletes, the second eating text past the first's shrink.
390
- const unsetKeys = new Set(unsetKeyList);
391
- const originalText = sourceFile.getFullText();
392
- try {
393
- // Unsets run first and the set edits are built against the re-parsed
394
- // result: an append anchor and an inline unset can otherwise share the
395
- // same comma and overlap.
396
- applyEditsDescending(sourceFile, [...unsetKeys]
397
- .map((key) => buildUnsetEdit(obj, key))
398
- .filter((edit) => edit !== undefined));
399
- const settable = unsetKeys.size > 0 ? resolveUpdatableHandlerLiteral(sourceFile, change) : obj;
400
- const inPlaceEdits = [];
401
- const missingEntries = [];
402
- for (const [key, value] of setEntries) {
403
- const edit = buildInPlaceSetEdit(settable, key, value);
404
- if (edit)
405
- inPlaceEdits.push(edit);
406
- else
407
- missingEntries.push([key, value]);
408
- }
409
- applyEditsDescending(sourceFile, [
410
- ...inPlaceEdits,
411
- ...(missingEntries.length > 0 ? [buildAppendEdit(settable, missingEntries)] : []),
412
- ]);
413
- }
414
- catch (error) {
415
- sourceFile.replaceWithText(originalText);
416
- throw error;
417
- }
418
- }
419
- // Apply from the highest offset down so an earlier edit's positions,
420
- // captured against the pre-edit text, stay valid.
421
- function applyEditsDescending(sourceFile, edits) {
422
- const sorted = edits.slice().sort((a, b) => b.start - a.start);
423
- for (let i = 1; i < sorted.length; i++) {
424
- const previous = sorted[i - 1];
425
- const current = sorted[i];
426
- if (previous && current && current.end > previous.start) {
427
- throw new Error("updatePattern: internal error, text edits overlap");
428
- }
429
- }
430
- for (const edit of sorted)
431
- sourceFile.replaceText([edit.start, edit.end], edit.text);
432
- }
433
- function isAiStepId(idOrPattern) {
434
- return (idOrPattern.kind === "ai.generate" ||
435
- idOrPattern.kind === "ai.extract" ||
436
- idOrPattern.kind === "ai.classify");
437
- }
438
- function aiStepPatchSpan(sourceFile, call) {
439
- const start = call.getStart();
440
- let end = call.getEnd();
441
- const text = sourceFile.getFullText();
442
- while (end < text.length && (text[end] === " " || text[end] === " "))
443
- end++;
444
- if (text[end] === ",")
445
- end++;
446
- while (end < text.length && (text[end] === " " || text[end] === " "))
447
- end++;
448
- if (end < text.length && text[end] === "\n")
449
- end++;
450
- return { start, end };
451
- }
452
- function findSetupCallback(sourceFile) {
453
- for (const stmt of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
454
- if (stmt.getExpression().getText() !== "defineFeature")
455
- continue;
456
- const setupArg = stmt.getArguments()[1];
457
- if (!setupArg)
458
- continue;
459
- const arrow = setupArg.asKind(SyntaxKind.ArrowFunction);
460
- if (!arrow)
461
- continue;
462
- return { call: stmt, body: arrow.getBody() };
463
- }
464
- return undefined;
465
- }
466
- /**
467
- * Singleton kinds: a feature has at most one of each. The Boot-Validator
468
- * rejects features that declare two `r.requires(...)` etc. — the patcher
469
- * asserts the same invariant so a corrupt source file produces an
470
- * explicit error here, not a silent first-match win.
471
- *
472
- * Exported so the pattern-library tests + downstream consumers
473
- * (Designer, AI-Builder) share one source-of-truth — duplicating this
474
- * set would let the library's `singleton: true` flags drift silently
475
- * from the patcher's enforcement.
476
- */
477
- export const SINGLETON_KINDS = new Set([
478
- "requires",
479
- "optionalRequires",
480
- "readsConfig",
481
- "systemScope",
482
- "toggleable",
483
- "describe",
484
- "uiHints",
485
- "adoptsBundledLists",
486
- "config",
487
- "translations",
488
- "authClaims",
489
- // Tree-Actions slot — at-most-one per feature, mirrors the registrar's
490
- // only-once-guard in define-feature.ts.
491
- "treeActions",
492
- ]);
493
- /**
494
- * Return the CallExpression in the setup callback whose call shape
495
- * matches the given id. Reads the call arguments structurally — same
496
- * paths the parser walks, no re-parsing through extractors.ts (would
497
- * be redundant work).
498
- *
499
- * For singleton kinds (requires, toggleable, etc.) the patcher
500
- * additionally asserts that the file contains AT MOST one matching
501
- * call. Two calls of the same singleton kind would let the first-match
502
- * silently win; we'd rather throw so Designer/AI surfacing the corrupt
503
- * feature can fix it explicitly.
504
- */
505
- function findCallForId(sourceFile, id) {
506
- if (isAiStepId(id)) {
507
- return findAiStepCall(sourceFile, id);
508
- }
509
- const setup = findSetupCallback(sourceFile);
510
- if (!setup)
511
- return undefined;
512
- const registrarParam = setup.call
513
- .getArguments()[1]
514
- ?.asKind(SyntaxKind.ArrowFunction)
515
- ?.getParameters()[0]
516
- ?.getName();
517
- if (!registrarParam)
518
- return undefined;
519
- const matches = [];
520
- for (const call of setup.body.getDescendantsOfKind(SyntaxKind.CallExpression)) {
521
- const propAccess = call.getExpression().asKind(SyntaxKind.PropertyAccessExpression);
522
- if (!propAccess)
523
- continue;
524
- if (propAccess.getExpression().getText() !== registrarParam)
525
- continue;
526
- if (propAccess.getName() !== id.kind)
527
- continue;
528
- if (callMatchesId(call, id.kind, id))
529
- matches.push(call);
530
- }
531
- if (SINGLETON_KINDS.has(id.kind) && matches.length > 1) {
532
- throw new Error(`findCallForId: ${id.kind} is a singleton but ${matches.length} calls were found — feature file is corrupt`);
533
- }
534
- return matches[0];
535
- }
536
- const AI_STEP_FACTORY = {
537
- "ai.generate": "aiGenerateStep",
538
- "ai.extract": "aiExtractStep",
539
- "ai.classify": "aiClassifyStep",
540
- };
541
- function findAiStepCall(sourceFile, id) {
542
- if (!isAiStepId(id))
543
- return undefined;
544
- const factory = AI_STEP_FACTORY[id.kind];
545
- const matches = [];
546
- for (const call of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
547
- if (call.getExpression().getText() !== factory)
548
- continue;
549
- if (callMatchesId(call, id.kind, id))
550
- matches.push(call);
551
- }
552
- if (matches.length > 1) {
553
- throw new Error(`findAiStepCall: ambiguous ${id.kind} stepKey=${JSON.stringify("stepKey" in id ? id.stepKey : undefined)} — ${matches.length} matches; disambiguate or include workflowName in PatternId`);
554
- }
555
- return matches[0];
556
- }
557
- // =============================================================================
558
- // Format helpers — line boundaries / blank-line collapse
559
- // (indent / PATTERN_INDENT live in render.ts and are imported above.)
560
- // =============================================================================
561
- function lastNonTriviaChild(body) {
562
- // Block nodes have child[0] = `{`, last = `}`. Find the last
563
- // SyntaxList element that's an actual statement — that signals
564
- // whether the body is empty for blank-line decisions.
565
- if (!body.isKind(SyntaxKind.Block))
566
- return undefined;
567
- const statements = body.getStatements();
568
- return statements[statements.length - 1];
569
- }
570
- function lineStart(sourceFile, pos) {
571
- const text = sourceFile.getFullText();
572
- let i = pos;
573
- while (i > 0 && text[i - 1] !== "\n")
574
- i--;
575
- return i;
576
- }
577
- function lineEnd(sourceFile, pos) {
578
- const text = sourceFile.getFullText();
579
- let i = pos;
580
- while (i < text.length && text[i] !== "\n")
581
- i++;
582
- return i;
583
- }
584
- function collapsePrecedingBlankLine(sourceFile, startPos) {
585
- // If the line preceding `startPos` is empty (only whitespace), include
586
- // it in the deletion range so add → remove leaves a clean file.
587
- const text = sourceFile.getFullText();
588
- if (startPos < 2)
589
- return startPos;
590
- const i = startPos - 1; // \n at end of previous line
591
- if (text[i] !== "\n")
592
- return startPos;
593
- let j = i - 1;
594
- while (j >= 0 && text[j] !== "\n" && (text[j] === " " || text[j] === "\t"))
595
- j--;
596
- if (j < 0 || text[j] === "\n") {
597
- // Found an empty (whitespace-only) preceding line — include its
598
- // newline in the deletion span.
599
- return j + 1;
600
- }
601
- return startPos;
602
- }
603
- // Used only in error messages — stringifies kind + identifying fields
604
- // in a `kind(field=value, ...)` shape for at-a-glance debugging.
605
- function describeId(id) {
606
- const fields = Object.entries(id)
607
- .filter(([key]) => key !== "kind")
608
- .map(([key, value]) => `${key}=${String(value)}`)
609
- .join(", ");
610
- return `${id.kind}(${fields})`;
611
- }