@segmentstream/ontology 0.0.0-stage → 0.92.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 (483) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +1655 -2
  4. package/dist/action.d.ts +193 -0
  5. package/dist/action.js +41 -0
  6. package/dist/agent-chat.d.ts +44 -0
  7. package/dist/agent-chat.js +91 -0
  8. package/dist/agent-task-contract.d.ts +64 -0
  9. package/dist/agent-task-contract.js +15 -0
  10. package/dist/agent-task.d.ts +39 -0
  11. package/dist/agent-task.js +112 -0
  12. package/dist/analyze.d.ts +215 -0
  13. package/dist/analyze.js +2438 -0
  14. package/dist/app-feedback.d.ts +167 -0
  15. package/dist/app-feedback.js +176 -0
  16. package/dist/authoring-input.d.ts +3 -0
  17. package/dist/authoring-input.js +107 -0
  18. package/dist/authoring-names.d.ts +4 -0
  19. package/dist/authoring-names.js +13 -0
  20. package/dist/authoring-records.d.ts +35 -0
  21. package/dist/authoring-records.js +264 -0
  22. package/dist/authoring.d.ts +15 -0
  23. package/dist/authoring.js +331 -0
  24. package/dist/bin/check.d.ts +30 -0
  25. package/dist/bin/check.js +99 -0
  26. package/dist/bin/load.d.ts +48 -0
  27. package/dist/bin/load.js +139 -0
  28. package/dist/bin/main.d.ts +31 -0
  29. package/dist/bin/main.js +121 -0
  30. package/dist/bin/migrate.d.ts +57 -0
  31. package/dist/bin/migrate.js +170 -0
  32. package/dist/bin/output.d.ts +31 -0
  33. package/dist/bin/output.js +84 -0
  34. package/dist/bin.d.ts +2 -0
  35. package/dist/bin.js +31 -0
  36. package/dist/blob.d.ts +52 -0
  37. package/dist/blob.js +87 -0
  38. package/dist/channel-session.d.ts +16 -0
  39. package/dist/channel-session.js +16 -0
  40. package/dist/chat.d.ts +43 -0
  41. package/dist/chat.js +34 -0
  42. package/dist/confirmation.d.ts +46 -0
  43. package/dist/confirmation.js +41 -0
  44. package/dist/connection.d.ts +213 -0
  45. package/dist/connection.js +289 -0
  46. package/dist/deployment.d.ts +35 -0
  47. package/dist/deployment.js +76 -0
  48. package/dist/diagnostics.d.ts +27 -0
  49. package/dist/diagnostics.js +106 -0
  50. package/dist/emails.d.ts +70 -0
  51. package/dist/emails.js +221 -0
  52. package/dist/entity.d.ts +331 -0
  53. package/dist/entity.js +153 -0
  54. package/dist/errors.d.ts +154 -0
  55. package/dist/errors.js +109 -0
  56. package/dist/feedback-config.d.ts +24 -0
  57. package/dist/feedback-config.js +126 -0
  58. package/dist/files.d.ts +39 -0
  59. package/dist/files.js +4 -0
  60. package/dist/groups.d.ts +95 -0
  61. package/dist/groups.js +280 -0
  62. package/dist/index.d.ts +109 -0
  63. package/dist/index.js +70 -0
  64. package/dist/internal/diagnostics.js +594 -0
  65. package/dist/legacy.d.ts +160 -0
  66. package/dist/legacy.js +270 -0
  67. package/dist/manifest-compatibility.d.ts +8 -0
  68. package/dist/manifest-compatibility.js +87 -0
  69. package/dist/manifest.d.ts +3329 -0
  70. package/dist/manifest.js +757 -0
  71. package/dist/me.d.ts +46 -0
  72. package/dist/me.js +109 -0
  73. package/dist/metric-filters.d.ts +48 -0
  74. package/dist/metric-filters.js +252 -0
  75. package/dist/metric-routes.d.ts +132 -0
  76. package/dist/metric-routes.js +498 -0
  77. package/dist/metric.d.ts +172 -0
  78. package/dist/metric.js +132 -0
  79. package/dist/migrate/apply.d.ts +94 -0
  80. package/dist/migrate/apply.js +526 -0
  81. package/dist/migrate/errors.d.ts +46 -0
  82. package/dist/migrate/errors.js +38 -0
  83. package/dist/migrate/index.d.ts +10 -0
  84. package/dist/migrate/index.js +7 -0
  85. package/dist/migrate/model.d.ts +2311 -0
  86. package/dist/migrate/model.js +148 -0
  87. package/dist/migrate/plan.d.ts +51 -0
  88. package/dist/migrate/plan.js +1856 -0
  89. package/dist/migrate/preview.d.ts +13 -0
  90. package/dist/migrate/preview.js +65 -0
  91. package/dist/migrate/storage.d.ts +226 -0
  92. package/dist/migrate/storage.js +774 -0
  93. package/dist/model-metrics.d.ts +22 -0
  94. package/dist/model-metrics.js +545 -0
  95. package/dist/names.d.ts +49 -0
  96. package/dist/names.js +110 -0
  97. package/dist/navigation-artifact.d.ts +13 -0
  98. package/dist/navigation-artifact.js +11 -0
  99. package/dist/navigation-catalog.d.ts +55 -0
  100. package/dist/navigation-catalog.js +297 -0
  101. package/dist/nitro-navigation.d.ts +3 -0
  102. package/dist/nitro-navigation.js +64 -0
  103. package/dist/nitro-workflows.d.ts +108 -0
  104. package/dist/nitro-workflows.js +286 -0
  105. package/dist/nitro.d.ts +40 -0
  106. package/dist/nitro.js +50 -0
  107. package/dist/ontology.d.ts +41 -0
  108. package/dist/ontology.js +46 -0
  109. package/dist/permissions.d.ts +198 -0
  110. package/dist/permissions.js +272 -0
  111. package/dist/property.d.ts +188 -0
  112. package/dist/property.js +301 -0
  113. package/dist/query.d.ts +245 -0
  114. package/dist/query.js +615 -0
  115. package/dist/relationship.d.ts +99 -0
  116. package/dist/relationship.js +33 -0
  117. package/dist/render.d.ts +81 -0
  118. package/dist/render.js +512 -0
  119. package/dist/replication/baseline.d.ts +51 -0
  120. package/dist/replication/baseline.js +215 -0
  121. package/dist/replication/bigquery.d.ts +37 -0
  122. package/dist/replication/bigquery.js +211 -0
  123. package/dist/replication/coverage.d.ts +14 -0
  124. package/dist/replication/coverage.js +53 -0
  125. package/dist/replication/evolution.d.ts +25 -0
  126. package/dist/replication/evolution.js +184 -0
  127. package/dist/replication/identities.d.ts +6 -0
  128. package/dist/replication/identities.js +47 -0
  129. package/dist/replication/legacy-baseline.d.ts +27 -0
  130. package/dist/replication/legacy-baseline.js +109 -0
  131. package/dist/replication/legacy-store.d.ts +19 -0
  132. package/dist/replication/legacy-store.js +63 -0
  133. package/dist/replication/lineage.d.ts +36 -0
  134. package/dist/replication/lineage.js +72 -0
  135. package/dist/replication/migrate.d.ts +21 -0
  136. package/dist/replication/migrate.js +84 -0
  137. package/dist/replication/model.d.ts +52 -0
  138. package/dist/replication/model.js +99 -0
  139. package/dist/replication/scans.d.ts +34 -0
  140. package/dist/replication/scans.js +158 -0
  141. package/dist/replication/schema.d.ts +11 -0
  142. package/dist/replication/schema.js +226 -0
  143. package/dist/replication/shadow-schema.d.ts +4 -0
  144. package/dist/replication/shadow-schema.js +61 -0
  145. package/dist/replication/shadow.d.ts +127 -0
  146. package/dist/replication/shadow.js +614 -0
  147. package/dist/replication/source-replacement.d.ts +33 -0
  148. package/dist/replication/source-replacement.js +76 -0
  149. package/dist/replication/store.d.ts +36 -0
  150. package/dist/replication/store.js +382 -0
  151. package/dist/replication/transaction.d.ts +23 -0
  152. package/dist/replication/transaction.js +88 -0
  153. package/dist/role.d.ts +61 -0
  154. package/dist/role.js +76 -0
  155. package/dist/runtime/action-deadlocks.d.ts +21 -0
  156. package/dist/runtime/action-deadlocks.js +130 -0
  157. package/dist/runtime/action-transactions.d.ts +35 -0
  158. package/dist/runtime/action-transactions.js +54 -0
  159. package/dist/runtime/agent-counters.d.ts +26 -0
  160. package/dist/runtime/agent-counters.js +98 -0
  161. package/dist/runtime/agent-tasks.d.ts +63 -0
  162. package/dist/runtime/agent-tasks.js +120 -0
  163. package/dist/runtime/agents.d.ts +15 -0
  164. package/dist/runtime/agents.js +457 -0
  165. package/dist/runtime/batch-diagnostics.d.ts +22 -0
  166. package/dist/runtime/batch-diagnostics.js +89 -0
  167. package/dist/runtime/batch.d.ts +52 -0
  168. package/dist/runtime/batch.js +534 -0
  169. package/dist/runtime/channel-session-revocation.d.ts +3 -0
  170. package/dist/runtime/channel-session-revocation.js +5 -0
  171. package/dist/runtime/channel-sessions.d.ts +4 -0
  172. package/dist/runtime/channel-sessions.js +61 -0
  173. package/dist/runtime/confirmations.d.ts +29 -0
  174. package/dist/runtime/confirmations.js +57 -0
  175. package/dist/runtime/cursor.d.ts +23 -0
  176. package/dist/runtime/cursor.js +100 -0
  177. package/dist/runtime/deployment.d.ts +7 -0
  178. package/dist/runtime/deployment.js +4 -0
  179. package/dist/runtime/errors.d.ts +118 -0
  180. package/dist/runtime/errors.js +109 -0
  181. package/dist/runtime/federation-tables.d.ts +2 -0
  182. package/dist/runtime/federation-tables.js +20 -0
  183. package/dist/runtime/federation.d.ts +42 -0
  184. package/dist/runtime/federation.js +222 -0
  185. package/dist/runtime/files.d.ts +39 -0
  186. package/dist/runtime/files.js +44 -0
  187. package/dist/runtime/generated-actions.d.ts +37 -0
  188. package/dist/runtime/generated-actions.js +307 -0
  189. package/dist/runtime/history.d.ts +91 -0
  190. package/dist/runtime/history.js +77 -0
  191. package/dist/runtime/ids.d.ts +6 -0
  192. package/dist/runtime/ids.js +39 -0
  193. package/dist/runtime/member-tables.d.ts +8 -0
  194. package/dist/runtime/member-tables.js +33 -0
  195. package/dist/runtime/member-writes.d.ts +78 -0
  196. package/dist/runtime/member-writes.js +202 -0
  197. package/dist/runtime/metric-query.d.ts +19 -0
  198. package/dist/runtime/metric-query.js +411 -0
  199. package/dist/runtime/model.d.ts +67 -0
  200. package/dist/runtime/model.js +150 -0
  201. package/dist/runtime/new-user-hook.d.ts +6 -0
  202. package/dist/runtime/new-user-hook.js +37 -0
  203. package/dist/runtime/oauth.d.ts +9 -0
  204. package/dist/runtime/oauth.js +299 -0
  205. package/dist/runtime/pipeline.d.ts +155 -0
  206. package/dist/runtime/pipeline.js +597 -0
  207. package/dist/runtime/postgres-tls.d.ts +10 -0
  208. package/dist/runtime/postgres-tls.js +14 -0
  209. package/dist/runtime/principals.d.ts +302 -0
  210. package/dist/runtime/principals.js +1307 -0
  211. package/dist/runtime/reads.d.ts +55 -0
  212. package/dist/runtime/reads.js +313 -0
  213. package/dist/runtime/records.d.ts +42 -0
  214. package/dist/runtime/records.js +245 -0
  215. package/dist/runtime/resolve-agent-identity.d.ts +6 -0
  216. package/dist/runtime/resolve-agent-identity.js +181 -0
  217. package/dist/runtime/service-binding.d.ts +18 -0
  218. package/dist/runtime/service-binding.js +266 -0
  219. package/dist/runtime/sign-in-links.d.ts +68 -0
  220. package/dist/runtime/sign-in-links.js +147 -0
  221. package/dist/runtime/sql-runtime.d.ts +131 -0
  222. package/dist/runtime/sql-runtime.js +362 -0
  223. package/dist/runtime/statement.d.ts +18 -0
  224. package/dist/runtime/statement.js +31 -0
  225. package/dist/runtime/user-identities.d.ts +66 -0
  226. package/dist/runtime/user-identities.js +106 -0
  227. package/dist/runtime/user-identity-sql.d.ts +86 -0
  228. package/dist/runtime/user-identity-sql.js +297 -0
  229. package/dist/runtime/user-roles.d.ts +16 -0
  230. package/dist/runtime/user-roles.js +32 -0
  231. package/dist/runtime/validation.d.ts +16 -0
  232. package/dist/runtime/validation.js +26 -0
  233. package/dist/runtime/where.d.ts +57 -0
  234. package/dist/runtime/where.js +404 -0
  235. package/dist/runtime/workflow-admission.d.ts +49 -0
  236. package/dist/runtime/workflow-admission.js +92 -0
  237. package/dist/runtime/workflow-argument-codec.d.ts +10 -0
  238. package/dist/runtime/workflow-argument-codec.js +120 -0
  239. package/dist/runtime/workflow-arguments.d.ts +17 -0
  240. package/dist/runtime/workflow-arguments.js +99 -0
  241. package/dist/runtime/workflow-starts.d.ts +203 -0
  242. package/dist/runtime/workflow-starts.js +493 -0
  243. package/dist/runtime/workflow-users.d.ts +9 -0
  244. package/dist/runtime/workflow-users.js +17 -0
  245. package/dist/runtime/workload.d.ts +25 -0
  246. package/dist/runtime/workload.js +24 -0
  247. package/dist/runtime/writes.d.ts +108 -0
  248. package/dist/runtime/writes.js +491 -0
  249. package/dist/runtime-source.d.ts +22 -0
  250. package/dist/runtime-source.js +28 -0
  251. package/dist/runtime.d.ts +310 -0
  252. package/dist/runtime.js +31 -0
  253. package/dist/server.d.ts +23 -0
  254. package/dist/server.js +107 -0
  255. package/dist/service/agent/attachments.d.ts +33 -0
  256. package/dist/service/agent/attachments.js +228 -0
  257. package/dist/service/agent/authentication.d.ts +22 -0
  258. package/dist/service/agent/authentication.js +58 -0
  259. package/dist/service/agent/confirmations.d.ts +5 -0
  260. package/dist/service/agent/confirmations.js +73 -0
  261. package/dist/service/agent/conversation-routes.d.ts +14 -0
  262. package/dist/service/agent/conversation-routes.js +45 -0
  263. package/dist/service/agent/conversations.d.ts +40 -0
  264. package/dist/service/agent/conversations.js +69 -0
  265. package/dist/service/agent/files.d.ts +12 -0
  266. package/dist/service/agent/files.js +69 -0
  267. package/dist/service/agent/protocol.d.ts +90 -0
  268. package/dist/service/agent/protocol.js +114 -0
  269. package/dist/service/agent/server.d.ts +28 -0
  270. package/dist/service/agent/server.js +374 -0
  271. package/dist/service/agent/task-caller.d.ts +21 -0
  272. package/dist/service/agent/task-caller.js +35 -0
  273. package/dist/service/agent/task-start.d.ts +53 -0
  274. package/dist/service/agent/task-start.js +161 -0
  275. package/dist/service/agent/tasks.d.ts +40 -0
  276. package/dist/service/agent/tasks.js +155 -0
  277. package/dist/service/api.d.ts +50 -0
  278. package/dist/service/api.js +288 -0
  279. package/dist/service/authentication.d.ts +227 -0
  280. package/dist/service/authentication.js +767 -0
  281. package/dist/service/caller-context.d.ts +24 -0
  282. package/dist/service/caller-context.js +6 -0
  283. package/dist/service/catalog.d.ts +42 -0
  284. package/dist/service/catalog.js +66 -0
  285. package/dist/service/channel/provider.d.ts +10 -0
  286. package/dist/service/channel/provider.js +1 -0
  287. package/dist/service/channel/providers/telegram.d.ts +18 -0
  288. package/dist/service/channel/providers/telegram.js +108 -0
  289. package/dist/service/channel/sessions.d.ts +5 -0
  290. package/dist/service/channel/sessions.js +53 -0
  291. package/dist/service/channel/sign-in.d.ts +7 -0
  292. package/dist/service/channel/sign-in.js +78 -0
  293. package/dist/service/chat/archive.d.ts +64 -0
  294. package/dist/service/chat/archive.js +62 -0
  295. package/dist/service/chat/attribution.d.ts +26 -0
  296. package/dist/service/chat/attribution.js +28 -0
  297. package/dist/service/chat/delivery.d.ts +18 -0
  298. package/dist/service/chat/delivery.js +251 -0
  299. package/dist/service/chat/diagnostics.d.ts +2 -0
  300. package/dist/service/chat/diagnostics.js +35 -0
  301. package/dist/service/chat/envelope.d.ts +96 -0
  302. package/dist/service/chat/envelope.js +39 -0
  303. package/dist/service/chat/idempotency.d.ts +19 -0
  304. package/dist/service/chat/idempotency.js +37 -0
  305. package/dist/service/chat/providers/telegram.d.ts +36 -0
  306. package/dist/service/chat/providers/telegram.js +133 -0
  307. package/dist/service/chat/reads.d.ts +25 -0
  308. package/dist/service/chat/reads.js +75 -0
  309. package/dist/service/chat/resolve.d.ts +34 -0
  310. package/dist/service/chat/resolve.js +150 -0
  311. package/dist/service/chat/routes.d.ts +23 -0
  312. package/dist/service/chat/routes.js +75 -0
  313. package/dist/service/chat/schemas.d.ts +43 -0
  314. package/dist/service/chat/schemas.js +31 -0
  315. package/dist/service/config.d.ts +218 -0
  316. package/dist/service/config.js +265 -0
  317. package/dist/service/connection-stream.d.ts +10 -0
  318. package/dist/service/connection-stream.js +191 -0
  319. package/dist/service/connections.d.ts +60 -0
  320. package/dist/service/connections.js +271 -0
  321. package/dist/service/decisions.d.ts +35 -0
  322. package/dist/service/decisions.js +63 -0
  323. package/dist/service/descriptions.d.ts +8 -0
  324. package/dist/service/descriptions.js +20 -0
  325. package/dist/service/discovery-schemas.d.ts +92 -0
  326. package/dist/service/discovery-schemas.js +59 -0
  327. package/dist/service/discovery-search.d.ts +30 -0
  328. package/dist/service/discovery-search.js +95 -0
  329. package/dist/service/discovery.d.ts +37 -0
  330. package/dist/service/discovery.js +436 -0
  331. package/dist/service/docs.d.ts +9 -0
  332. package/dist/service/docs.js +197 -0
  333. package/dist/service/errors.d.ts +145 -0
  334. package/dist/service/errors.js +704 -0
  335. package/dist/service/federation-provider.d.ts +36 -0
  336. package/dist/service/federation-provider.js +110 -0
  337. package/dist/service/federation-server.d.ts +20 -0
  338. package/dist/service/federation-server.js +249 -0
  339. package/dist/service/federation-status.d.ts +40 -0
  340. package/dist/service/federation-status.js +151 -0
  341. package/dist/service/handlers.d.ts +18 -0
  342. package/dist/service/handlers.js +287 -0
  343. package/dist/service/mcp/confirmation.d.ts +68 -0
  344. package/dist/service/mcp/confirmation.js +178 -0
  345. package/dist/service/mcp/find-input.d.ts +12 -0
  346. package/dist/service/mcp/find-input.js +122 -0
  347. package/dist/service/mcp/input-schema.d.ts +6 -0
  348. package/dist/service/mcp/input-schema.js +126 -0
  349. package/dist/service/mcp/listing.d.ts +26 -0
  350. package/dist/service/mcp/listing.js +92 -0
  351. package/dist/service/mcp/metric-tools.d.ts +85 -0
  352. package/dist/service/mcp/metric-tools.js +258 -0
  353. package/dist/service/mcp/request-log.d.ts +5 -0
  354. package/dist/service/mcp/request-log.js +53 -0
  355. package/dist/service/mcp/runtime-policy.d.ts +27 -0
  356. package/dist/service/mcp/runtime-policy.js +62 -0
  357. package/dist/service/mcp/server.d.ts +52 -0
  358. package/dist/service/mcp/server.js +861 -0
  359. package/dist/service/mcp/tools.d.ts +99 -0
  360. package/dist/service/mcp/tools.js +938 -0
  361. package/dist/service/member-file-routes.d.ts +22 -0
  362. package/dist/service/member-file-routes.js +52 -0
  363. package/dist/service/member-files.d.ts +245 -0
  364. package/dist/service/member-files.js +258 -0
  365. package/dist/service/metric-query-platform.d.ts +77 -0
  366. package/dist/service/metric-query-platform.js +198 -0
  367. package/dist/service/metric-query-scopes.d.ts +43 -0
  368. package/dist/service/metric-query-scopes.js +147 -0
  369. package/dist/service/metric-query.d.ts +48 -0
  370. package/dist/service/metric-query.js +200 -0
  371. package/dist/service/name-suggestions.d.ts +3 -0
  372. package/dist/service/name-suggestions.js +38 -0
  373. package/dist/service/navigation-schemas.d.ts +80 -0
  374. package/dist/service/navigation-schemas.js +49 -0
  375. package/dist/service/navigation.d.ts +20 -0
  376. package/dist/service/navigation.js +165 -0
  377. package/dist/service/oauth/protocol.d.ts +70 -0
  378. package/dist/service/oauth/protocol.js +157 -0
  379. package/dist/service/oauth/refresh-replay.d.ts +2 -0
  380. package/dist/service/oauth/refresh-replay.js +20 -0
  381. package/dist/service/oauth/server.d.ts +28 -0
  382. package/dist/service/oauth/server.js +769 -0
  383. package/dist/service/operations.d.ts +170 -0
  384. package/dist/service/operations.js +392 -0
  385. package/dist/service/plan.d.ts +57 -0
  386. package/dist/service/plan.js +96 -0
  387. package/dist/service/rate-limit.d.ts +22 -0
  388. package/dist/service/rate-limit.js +52 -0
  389. package/dist/service/record-reads.d.ts +21 -0
  390. package/dist/service/record-reads.js +155 -0
  391. package/dist/service/replication.d.ts +5 -0
  392. package/dist/service/replication.js +39 -0
  393. package/dist/service/runtime-contract.d.ts +508 -0
  394. package/dist/service/runtime-contract.js +18 -0
  395. package/dist/service/runtime-identity.d.ts +71 -0
  396. package/dist/service/runtime-identity.js +122 -0
  397. package/dist/service/schemas.d.ts +961 -0
  398. package/dist/service/schemas.js +639 -0
  399. package/dist/service/service.d.ts +21 -0
  400. package/dist/service/service.js +526 -0
  401. package/dist/service/warehouse-platform.d.ts +17 -0
  402. package/dist/service/warehouse-platform.js +122 -0
  403. package/dist/service/warehouse-query.d.ts +24 -0
  404. package/dist/service/warehouse-query.js +280 -0
  405. package/dist/service/webhooks.d.ts +106 -0
  406. package/dist/service/webhooks.js +233 -0
  407. package/dist/service/workflow-admission-provider.d.ts +31 -0
  408. package/dist/service/workflow-admission-provider.js +205 -0
  409. package/dist/service/workflow-argument-serialization.d.ts +2 -0
  410. package/dist/service/workflow-argument-serialization.js +14 -0
  411. package/dist/service/workflow-callback.d.ts +22 -0
  412. package/dist/service/workflow-callback.js +75 -0
  413. package/dist/service/workflow-deployment.d.ts +8 -0
  414. package/dist/service/workflow-deployment.js +131 -0
  415. package/dist/service/workflow-diagnostics.d.ts +23 -0
  416. package/dist/service/workflow-diagnostics.js +263 -0
  417. package/dist/service/workflow-errors.d.ts +26 -0
  418. package/dist/service/workflow-errors.js +181 -0
  419. package/dist/service/workflow-logging.d.ts +2 -0
  420. package/dist/service/workflow-logging.js +50 -0
  421. package/dist/service/workflow-queue-fence.d.ts +6 -0
  422. package/dist/service/workflow-queue-fence.js +66 -0
  423. package/dist/service/workflows.d.ts +200 -0
  424. package/dist/service/workflows.js +1549 -0
  425. package/dist/sign-in.d.ts +58 -0
  426. package/dist/sign-in.js +57 -0
  427. package/dist/source.d.ts +30 -0
  428. package/dist/source.js +107 -0
  429. package/dist/start-recovery-contract.d.ts +49 -0
  430. package/dist/start-recovery-contract.js +26 -0
  431. package/dist/start-recovery.d.ts +27 -0
  432. package/dist/start-recovery.js +81 -0
  433. package/dist/storage/api.d.ts +4 -0
  434. package/dist/storage/api.js +40 -0
  435. package/dist/storage/attachments.d.ts +146 -0
  436. package/dist/storage/attachments.js +733 -0
  437. package/dist/storage/authorization.d.ts +38 -0
  438. package/dist/storage/authorization.js +83 -0
  439. package/dist/storage/file-access.d.ts +17 -0
  440. package/dist/storage/file-access.js +8 -0
  441. package/dist/storage/limits.d.ts +12 -0
  442. package/dist/storage/limits.js +17 -0
  443. package/dist/storage/maintenance-auth.d.ts +20 -0
  444. package/dist/storage/maintenance-auth.js +24 -0
  445. package/dist/storage/maintenance.d.ts +11 -0
  446. package/dist/storage/maintenance.js +67 -0
  447. package/dist/storage/neon.d.ts +4 -0
  448. package/dist/storage/neon.js +318 -0
  449. package/dist/storage/operator.d.ts +11 -0
  450. package/dist/storage/operator.js +30 -0
  451. package/dist/storage/provider.d.ts +93 -0
  452. package/dist/storage/provider.js +36 -0
  453. package/dist/storage/sessions.d.ts +184 -0
  454. package/dist/storage/sessions.js +688 -0
  455. package/dist/storage/tables.d.ts +54 -0
  456. package/dist/storage/tables.js +205 -0
  457. package/dist/storage/transfers.d.ts +16 -0
  458. package/dist/storage/transfers.js +153 -0
  459. package/dist/storage/writes.d.ts +7 -0
  460. package/dist/storage/writes.js +88 -0
  461. package/dist/telegram.d.ts +35 -0
  462. package/dist/telegram.js +173 -0
  463. package/dist/user-identity.d.ts +28 -0
  464. package/dist/user-identity.js +106 -0
  465. package/dist/user.d.ts +75 -0
  466. package/dist/user.js +111 -0
  467. package/dist/warehouse-backed.d.ts +6 -0
  468. package/dist/warehouse-backed.js +495 -0
  469. package/dist/webhook-token.d.ts +11 -0
  470. package/dist/webhook-token.js +18 -0
  471. package/dist/webhooks.d.ts +40 -0
  472. package/dist/webhooks.js +55 -0
  473. package/dist/wire.d.ts +10 -0
  474. package/dist/wire.js +35 -0
  475. package/dist/workflow-runtime.d.ts +116 -0
  476. package/dist/workflow-runtime.js +109 -0
  477. package/dist/workflow-topics.d.ts +28 -0
  478. package/dist/workflow-topics.js +28 -0
  479. package/dist/workflow.d.ts +284 -0
  480. package/dist/workflow.js +259 -0
  481. package/dist/workflows.d.ts +24 -0
  482. package/dist/workflows.js +18 -0
  483. package/package.json +127 -4
@@ -0,0 +1,222 @@
1
+ import { randomUUID, createHash } from "node:crypto";
2
+ import { Effect, Schema } from "effect";
3
+ import { SqlClient } from "effect/unstable/sql";
4
+ import { makePrincipalUserWriter } from "./sql-runtime.js";
5
+ import { lockSessionMember, resolvePrincipalById, resolvePrincipalByIdentity, } from "./principals.js";
6
+ import { ensureSignInIdentity, liveSignInIdentities, makeIdentityWriter, NEON_AUTH_PROVIDER, OIDC_PROVIDER, USER_IDENTITY_TABLE, userOfAccount, } from "./user-identities.js";
7
+ export const FEDERATION_TOKEN_PREFIX = "ssfs_";
8
+ export const federationDigest = (value) => createHash("sha256").update(value).digest("hex");
9
+ export const FederationSession = Schema.Struct({
10
+ hash: Schema.String,
11
+ userId: Schema.NullOr(Schema.String),
12
+ linkUserId: Schema.optionalKey(Schema.String),
13
+ issuer: Schema.String,
14
+ subject: Schema.String,
15
+ clientId: Schema.String,
16
+ generation: Schema.Int,
17
+ consentId: Schema.String,
18
+ sessionId: Schema.optionalKey(Schema.String),
19
+ environment: Schema.optionalKey(Schema.String),
20
+ deploymentId: Schema.optionalKey(Schema.String),
21
+ manifestDigest: Schema.optionalKey(Schema.String),
22
+ expiresAt: Schema.Number,
23
+ });
24
+ function decodeSession(value) {
25
+ const row = { ...value };
26
+ for (const key of ["sessionId", "environment", "deploymentId", "manifestDigest", "linkUserId"]) {
27
+ if (row[key] === null) {
28
+ delete row[key];
29
+ }
30
+ }
31
+ return Schema.decodeUnknownSync(FederationSession)(row);
32
+ }
33
+ export function sqlFederationStore(ontology, sql) {
34
+ const principal = (id) => resolvePrincipalById(ontology, sql, id).pipe(Effect.catchTag("PrincipalRejected", () => Effect.succeed(undefined)), Effect.orDie);
35
+ // Every binding is a `user_identity` record; `_user_identities` and the user's columns are still
36
+ // written beside it for earlier SDKs. See docs/workspace-user-identities.md.
37
+ const identityWriter = (action) => makeIdentityWriter(ontology, sql, {
38
+ action: `${USER_IDENTITY_TABLE}.${action}`,
39
+ actionId: randomUUID(),
40
+ });
41
+ const identity = (issuer, subject) => Effect.gen(function* () {
42
+ const userId = yield* userOfAccount(sql, { provider: OIDC_PROVIDER, issuer, subject });
43
+ return userId ? yield* principal(userId) : undefined;
44
+ }).pipe(Effect.orDie);
45
+ return {
46
+ identity,
47
+ principal,
48
+ emailIdentity: (subject) => userOfAccount(sql, { provider: NEON_AUTH_PROVIDER, issuer: null, subject }).pipe(Effect.flatMap((userId) => (userId ? principal(userId) : Effect.succeed(undefined))), Effect.orDie),
49
+ // A revoked binding is known too: it never falls back to the email of the account. So is a link
50
+ // an earlier SDK made only in `_user_identities` since the last copy: sign-in fails closed until
51
+ // the next migration copies it, instead of matching another member by email.
52
+ bindingExists: (issuer, subject) => sql
53
+ .unsafe(`SELECT 1 FROM "${USER_IDENTITY_TABLE}" WHERE "provider" = $1 AND "issuer" = $2 ` +
54
+ `AND "subject" = $3 UNION ALL ` +
55
+ `SELECT 1 FROM "_user_identities" WHERE "issuer" = $2 AND "subject" = $3 LIMIT 1`, [OIDC_PROVIDER, issuer, subject])
56
+ .pipe(Effect.map((rows) => rows.length > 0), Effect.orDie),
57
+ enroll: (claims) => sql
58
+ .withTransaction(Effect.gen(function* () {
59
+ yield* sql.unsafe(`SELECT pg_advisory_xact_lock_shared(hashtextextended('segmentstream.ontology.migration', 0))`);
60
+ const [catalog] = yield* sql.unsafe(`SELECT manifest->'sign_in'->'browser'->'methods' AS methods FROM "_ontology" WHERE id`);
61
+ if (Array.isArray(catalog?.methods) && !catalog.methods.includes("segmentstream")) {
62
+ return undefined;
63
+ }
64
+ // Serialize enrollment for a pairwise identity; the primary identity resolver locks invitations.
65
+ yield* sql.unsafe(`SELECT pg_advisory_xact_lock(hashtextextended($1, 0))`, [
66
+ JSON.stringify([claims.issuer, claims.subject]),
67
+ ]);
68
+ const existing = yield* identity(claims.issuer, claims.subject);
69
+ if (existing) {
70
+ return existing;
71
+ }
72
+ // An earlier SDK linked the account since the last copy: never enroll it as someone else.
73
+ const [legacy] = yield* sql.unsafe(`SELECT 1 FROM "_user_identities" WHERE "issuer" = $1 AND "subject" = $2`, [claims.issuer, claims.subject]);
74
+ if (legacy) {
75
+ return undefined;
76
+ }
77
+ if (claims.email) {
78
+ const [invited] = yield* sql.unsafe(`SELECT id::text FROM "user" WHERE lower(email) = lower($1) FOR UPDATE`, [claims.email]);
79
+ if (invited) {
80
+ const [binding] = yield* sql.unsafe(`SELECT 1 FROM "${USER_IDENTITY_TABLE}" WHERE "user_id" = $1::uuid ` +
81
+ `AND "provider" = $2 AND "revoked_at" IS NULL`, [invited.id, OIDC_PROVIDER]);
82
+ if (binding) {
83
+ return undefined;
84
+ }
85
+ }
86
+ }
87
+ const member = yield* resolvePrincipalByIdentity(ontology, {
88
+ identityProvider: `oidc:${claims.issuer}`,
89
+ identitySubject: claims.subject,
90
+ ...(claims.email === undefined ? {} : { email: claims.email }),
91
+ ...(claims.name === undefined ? {} : { name: claims.name }),
92
+ }).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.catchTag("PrincipalRejected", () => Effect.succeed(undefined)));
93
+ if (!member) {
94
+ return undefined;
95
+ }
96
+ // @legacy identities.legacy-stores-dual-write
97
+ yield* sql.unsafe(`INSERT INTO "_user_identities" (issuer, subject, user_id)
98
+ VALUES ($1, $2, $3::uuid) ON CONFLICT (issuer, subject) DO NOTHING`, [claims.issuer, claims.subject, member.id]);
99
+ // Sign-in recorded the identity with the member; this keeps it if the member was found.
100
+ yield* ensureSignInIdentity(identityWriter("enroll"), sql, {
101
+ provider: OIDC_PROVIDER,
102
+ issuer: claims.issuer,
103
+ subject: claims.subject,
104
+ userId: member.id,
105
+ origin: "sign_in",
106
+ });
107
+ return yield* identity(claims.issuer, claims.subject);
108
+ }))
109
+ .pipe(Effect.orDie),
110
+ linkEmail: (userId, subject, email) => sql
111
+ .withTransaction(Effect.gen(function* () {
112
+ yield* sql.unsafe(`SELECT id FROM "user" WHERE id = $1::uuid FOR UPDATE`, [userId]);
113
+ yield* lockSessionMember(sql, userId);
114
+ const proof = yield* principal(userId);
115
+ if (!proof) {
116
+ return undefined;
117
+ }
118
+ const [row] = yield* sql.unsafe(`SELECT email FROM "user" WHERE id = $1::uuid FOR UPDATE`, [userId]);
119
+ if (!email?.trim() ||
120
+ !row?.email?.trim() ||
121
+ email.trim().toLowerCase() !== row.email.trim().toLowerCase()) {
122
+ return "email_identity_mismatch";
123
+ }
124
+ // Email links to a member who signs in with SegmentStream only, or with this account.
125
+ const held = yield* liveSignInIdentities(sql, userId);
126
+ if (held.some((identity) => identity.provider !== OIDC_PROVIDER &&
127
+ !(identity.provider === NEON_AUTH_PROVIDER && identity.subject === subject))) {
128
+ return undefined;
129
+ }
130
+ const owner = yield* userOfAccount(sql, {
131
+ provider: NEON_AUTH_PROVIDER,
132
+ issuer: null,
133
+ subject,
134
+ });
135
+ if (owner !== undefined && owner !== userId) {
136
+ return undefined;
137
+ }
138
+ const actionId = randomUUID();
139
+ yield* makePrincipalUserWriter(ontology, sql, {
140
+ action: "user.link_email",
141
+ actionId,
142
+ }).update(userId, { identity_provider: NEON_AUTH_PROVIDER, identity_subject: subject });
143
+ yield* ensureSignInIdentity(makeIdentityWriter(ontology, sql, {
144
+ action: `${USER_IDENTITY_TABLE}.link_email`,
145
+ actionId,
146
+ }), sql, { provider: NEON_AUTH_PROVIDER, issuer: null, subject, userId, origin: "link" });
147
+ return yield* principal(userId);
148
+ }))
149
+ .pipe(Effect.orDie),
150
+ link: (issuer, subject, proofUserId) => sql
151
+ .withTransaction(Effect.gen(function* () {
152
+ yield* lockSessionMember(sql, proofUserId);
153
+ yield* sql.unsafe(`SELECT id FROM "user" WHERE id = $1::uuid FOR UPDATE`, [
154
+ proofUserId,
155
+ ]);
156
+ const proof = yield* principal(proofUserId);
157
+ if (!proof || proof.kind !== "member") {
158
+ return undefined;
159
+ }
160
+ // The legacy insert waits for a concurrent link of the account, which then holds it.
161
+ // @legacy identities.legacy-stores-dual-write
162
+ yield* sql.unsafe(`INSERT INTO "_user_identities" (issuer, subject, user_id)
163
+ VALUES ($1, $2, $3::uuid) ON CONFLICT (issuer, subject) DO NOTHING`, [issuer, subject, proofUserId]);
164
+ const [bound] = yield* sql.unsafe(`SELECT user_id::text FROM "_user_identities" WHERE issuer = $1 AND subject = $2`, [issuer, subject]);
165
+ if (bound?.user_id === proofUserId) {
166
+ yield* ensureSignInIdentity(identityWriter("link"), sql, {
167
+ provider: OIDC_PROVIDER,
168
+ issuer,
169
+ subject,
170
+ userId: proofUserId,
171
+ origin: "link",
172
+ });
173
+ }
174
+ const linked = yield* identity(issuer, subject);
175
+ return linked?.id === proofUserId ? linked : undefined;
176
+ }))
177
+ .pipe(Effect.orDie),
178
+ save: (session) => sql
179
+ .withTransaction(Effect.gen(function* () {
180
+ if (session.userId !== null) {
181
+ yield* lockSessionMember(sql, session.userId);
182
+ }
183
+ yield* sql.unsafe(`INSERT INTO "_federation_sessions"
184
+ (hash, user_id, issuer, subject, client_id, generation, consent_id, expires_at,
185
+ session_id, environment, deployment_id, manifest_digest, link_user_id)
186
+ VALUES ($1, $2::uuid, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::uuid)`, [
187
+ session.hash,
188
+ session.userId,
189
+ session.issuer,
190
+ session.subject,
191
+ session.clientId,
192
+ session.generation,
193
+ session.consentId,
194
+ session.expiresAt,
195
+ session.sessionId ?? null,
196
+ session.environment ?? null,
197
+ session.deploymentId ?? null,
198
+ session.manifestDigest ?? null,
199
+ session.linkUserId ?? null,
200
+ ]);
201
+ }))
202
+ .pipe(Effect.asVoid, Effect.orDie),
203
+ read: (hash) => sql
204
+ .unsafe(`SELECT hash, user_id::text AS "userId", issuer, subject, client_id AS "clientId",
205
+ generation, consent_id AS "consentId", expires_at::double precision AS "expiresAt",
206
+ session_id AS "sessionId", environment, deployment_id AS "deploymentId",
207
+ manifest_digest AS "manifestDigest", link_user_id::text AS "linkUserId"
208
+ FROM "_federation_sessions" WHERE hash = $1 AND expires_at > extract(epoch FROM now()) * 1000`, [hash])
209
+ .pipe(Effect.map((rows) => (rows[0] ? decodeSession(rows[0]) : undefined)), Effect.orDie),
210
+ consumePending: (hash) => sql
211
+ .unsafe(`DELETE FROM "_federation_sessions"
212
+ WHERE hash = $1 AND user_id IS NULL AND expires_at > extract(epoch FROM now()) * 1000
213
+ RETURNING hash, user_id::text AS "userId", issuer, subject, client_id AS "clientId",
214
+ generation, consent_id AS "consentId", expires_at::double precision AS "expiresAt",
215
+ session_id AS "sessionId", environment, deployment_id AS "deploymentId",
216
+ manifest_digest AS "manifestDigest", link_user_id::text AS "linkUserId"`, [hash])
217
+ .pipe(Effect.map((rows) => (rows[0] ? decodeSession(rows[0]) : undefined)), Effect.orDie),
218
+ remove: (hash) => sql
219
+ .unsafe(`DELETE FROM "_federation_sessions" WHERE hash = $1`, [hash])
220
+ .pipe(Effect.asVoid, Effect.orDie),
221
+ };
222
+ }
@@ -0,0 +1,39 @@
1
+ import { Context, Effect, Schema } from "effect";
2
+ import { NotFound, PermissionDenied } from "../errors.js";
3
+ import type { OntologyManifest } from "../manifest.js";
4
+ import type { OntologyReads, Principal } from "../runtime.js";
5
+ export interface FileReference {
6
+ readonly entity: string;
7
+ readonly id: string;
8
+ readonly property?: string;
9
+ }
10
+ declare const UnsupportedFile_base: Schema.Class<UnsupportedFile, Schema.TaggedStruct<"UnsupportedFile", {
11
+ readonly message: Schema.String;
12
+ }>, import("effect/Cause").YieldableError>;
13
+ export declare class UnsupportedFile extends UnsupportedFile_base {
14
+ }
15
+ /** Resolve only declared file properties, checking permission before reading any record. */
16
+ export declare function resolveFileRecord(input: {
17
+ readonly manifest: OntologyManifest;
18
+ readonly reads: Pick<OntologyReads["Service"], "get">;
19
+ readonly principal: Principal;
20
+ readonly reference: FileReference;
21
+ }): Effect.Effect<{
22
+ entity: string;
23
+ id: string;
24
+ property: string;
25
+ file: {
26
+ readonly id: string;
27
+ readonly filename: string;
28
+ readonly contentType: string;
29
+ readonly size: number;
30
+ readonly createdAt: string;
31
+ };
32
+ }, PermissionDenied | NotFound | UnsupportedFile, never>;
33
+ declare const AgentFileRecords_base: Context.ServiceClass<AgentFileRecords, "@segmentstream/ontology/AgentFileRecords", {
34
+ readonly resolve: (reference: FileReference, principal: Principal) => ReturnType<typeof resolveFileRecord>;
35
+ }>;
36
+ /** File validation in an action's prepare, bound to its ontology and read runtime. */
37
+ export declare class AgentFileRecords extends AgentFileRecords_base {
38
+ }
39
+ export {};
@@ -0,0 +1,44 @@
1
+ import { Context, Effect, Schema } from "effect";
2
+ import { BlobValue } from "../blob.js";
3
+ import { NotFound, PermissionDenied } from "../errors.js";
4
+ import { isAllowed, permissionOf, READ_VERB } from "../permissions.js";
5
+ export class UnsupportedFile extends Schema.TaggedError()("UnsupportedFile", {
6
+ message: Schema.String,
7
+ }) {
8
+ }
9
+ /** Resolve only declared file properties, checking permission before reading any record. */
10
+ export function resolveFileRecord(input) {
11
+ return Effect.gen(function* () {
12
+ const { entity: entityName, id, property: propertyName } = input.reference;
13
+ const permission = permissionOf(entityName, READ_VERB);
14
+ if (!isAllowed(permission, input.principal)) {
15
+ return yield* new PermissionDenied({ permission, message: "The file requires read access." });
16
+ }
17
+ const entity = input.manifest.entities.find((candidate) => candidate.name === entityName);
18
+ if (entity === undefined) {
19
+ return yield* new NotFound({ entity: entityName, id, message: "File record not found." });
20
+ }
21
+ const properties = entity.properties.filter((candidate) => candidate.type === "blob");
22
+ const property = propertyName === undefined
23
+ ? properties.length === 1
24
+ ? properties[0]
25
+ : undefined
26
+ : properties.find((candidate) => candidate.name === propertyName);
27
+ if (property === undefined) {
28
+ return yield* new UnsupportedFile({
29
+ message: "Name a file property; the entity must have exactly one when property is omitted.",
30
+ });
31
+ }
32
+ const record = yield* input.reads.get({ entity: entityName, id });
33
+ const file = record[property.name];
34
+ if (file === null || file === undefined) {
35
+ return yield* new NotFound({ entity: entityName, id, message: "File not found." });
36
+ }
37
+ // Runtime records are decoded already; malformed stored metadata is an operator failure.
38
+ const decoded = yield* Schema.decodeUnknownEffect(BlobValue)(file).pipe(Effect.orDie);
39
+ return { entity: entityName, id, property: property.name, file: decoded };
40
+ });
41
+ }
42
+ /** File validation in an action's prepare, bound to its ontology and read runtime. */
43
+ export class AgentFileRecords extends Context.Service()("@segmentstream/ontology/AgentFileRecords") {
44
+ }
@@ -0,0 +1,37 @@
1
+ import { Schema } from "effect";
2
+ import { type AnyAction } from "../action.js";
3
+ import type { JsonSchemaObject } from "../analyze.js";
4
+ import type { Ontology } from "../ontology.js";
5
+ /** An entity's generated actions by name. */
6
+ export type GeneratedActions = Readonly<Record<string, AnyAction>>;
7
+ /** `upsert_by_email`. */
8
+ export declare function upsertActionName(property: string): string;
9
+ /**
10
+ * The actions generated for an entity: `create`, `update` (without `managed` properties), `delete`,
11
+ * `upsert_by_<property>` per unique property, and `link`/`unlink` when it declares a `rel.many`
12
+ * whose target keeps its generated writes. An entity that declares `writes: "actions"` has none. They
13
+ * are ordinary actions and run through the same pipeline. Their `permission` is unset: each requires
14
+ * the permission named after it (`lead:create`), and `upsert_by_<property>` both `create` and `update`,
15
+ * as `generatedActionPermissions` says. The built-in User has only its member management: `invite`,
16
+ * `grant_roles`, `revoke_roles`, `deactivate` and `reactivate`; members are otherwise created by
17
+ * sign-in and services by the app or the CLI. The built-in agent chat has only `update`, for its
18
+ * unmanaged properties: the agent records chats and their members.
19
+ */
20
+ export declare function generatedActions(ontology: Ontology, entityName: string): GeneratedActions;
21
+ /**
22
+ * Why a generated write is missing when its entity declares `writes: "actions"`, naming the
23
+ * authored actions that write it instead; `undefined` for any other unknown action.
24
+ */
25
+ export declare function writesOnlyThroughActions(ontology: Ontology, entityName: string, actionName: string): string | undefined;
26
+ /** An action's input as JSON Schema (draft 2020-12), as the manifest describes authored actions. */
27
+ export declare function actionInputJsonSchema(input: Schema.Top): JsonSchemaObject;
28
+ /** A generated action, described as the manifest describes authored ones. */
29
+ export interface GeneratedActionManifest {
30
+ readonly name: string;
31
+ readonly description: string;
32
+ /** Every permission the action requires: one, or `create` and `update` for `upsert_by_<property>`. */
33
+ readonly permissions: ReadonlyArray<string>;
34
+ readonly input: JsonSchemaObject;
35
+ }
36
+ /** The generated actions described as the manifest describes authored ones, for catalogs and MCP. */
37
+ export declare function generatedActionManifests(ontology: Ontology, entityName: string): ReadonlyArray<GeneratedActionManifest>;
@@ -0,0 +1,307 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { uploadInput, BLOB_UPLOAD_ANNOTATION } from "../blob.js";
3
+ import { action } from "../action.js";
4
+ import { GENERATED_UPSERT_PREFIX, MEMBER_ROLE } from "../names.js";
5
+ import { generatedActionPermissions } from "../permissions.js";
6
+ import { p, REFERENCE_ANNOTATION } from "../property.js";
7
+ import { isCalendarDate, isInstant } from "../query.js";
8
+ import { OntologyWrites } from "../runtime.js";
9
+ import { User } from "../user.js";
10
+ import { entityModel, ontologyModel, propertyValueSchema, } from "./model.js";
11
+ /** Generated actions, built once per ontology and entity. */
12
+ const builtActions = new WeakMap();
13
+ function article(word) {
14
+ return /^[aeiou]/i.test(word) ? `an ${word}` : `a ${word}`;
15
+ }
16
+ /** `upsert_by_email`. */
17
+ export function upsertActionName(property) {
18
+ return `${GENERATED_UPSERT_PREFIX}${property}`;
19
+ }
20
+ /** A property's value schema, refusing days that do not exist, which PostgreSQL would reject. */
21
+ function propertyInput(field, entity) {
22
+ if (field.storage === "blob") {
23
+ return uploadInput(entity.name, field.name);
24
+ }
25
+ const schema = propertyValueSchema(field.property);
26
+ if (field.storage === "date") {
27
+ return schema.check(Schema.makeFilter((value) => isCalendarDate(value) || "Expected a date that exists"));
28
+ }
29
+ if (field.storage === "timestamp") {
30
+ return schema.check(Schema.makeFilter((value) => isInstant(value) || "Expected an instant that exists"));
31
+ }
32
+ return schema;
33
+ }
34
+ function reference(link, description) {
35
+ return p.ref(link.target, { description });
36
+ }
37
+ function relationshipDescription(entity, link) {
38
+ const declaration = entity.manifest.relationships.find((candidate) => candidate.name === link.name);
39
+ return declaration?.description ?? `The id of a ${link.target} record.`;
40
+ }
41
+ /**
42
+ * Whether a `rel.many` keeps its generated writes: not when its target declares `writes: "actions"`,
43
+ * whose links change only through authored actions on either side.
44
+ */
45
+ function generatedJoin(ontology, link) {
46
+ return ontology.manifest.entities.find((e) => e.name === link.target)?.writes !== "actions";
47
+ }
48
+ /** Input fields for the values of a record: properties, `rel.one` ids and `rel.many` id lists. */
49
+ function valueFields(ontology, entity, { mode }) {
50
+ const fields = {};
51
+ for (const field of entity.fields) {
52
+ if (field.source !== "property") {
53
+ continue;
54
+ }
55
+ const definition = field.property?.definition;
56
+ if (mode === "update" && definition?.managed === true) {
57
+ continue;
58
+ }
59
+ const value = propertyInput(field, entity);
60
+ const required = mode === "create" &&
61
+ !field.nullable &&
62
+ !(definition !== undefined && "default" in definition);
63
+ fields[field.name] = required
64
+ ? value
65
+ : Schema.optionalKey(field.nullable ? Schema.NullOr(value) : value);
66
+ }
67
+ for (const link of entity.links.values()) {
68
+ if (link.via === "key") {
69
+ const target = reference(link, relationshipDescription(entity, link));
70
+ const required = mode === "create" && !link.optional;
71
+ fields[link.name] = required
72
+ ? target
73
+ : Schema.optionalKey(link.optional ? Schema.NullOr(target) : target);
74
+ }
75
+ else if (link.via === "join" &&
76
+ !link.inverse &&
77
+ !entity.resolved.builtIn &&
78
+ generatedJoin(ontology, link)) {
79
+ fields[link.name] = Schema.optionalKey(Schema.Array(reference(link, `The id of a ${link.target} record.`)).annotate({
80
+ description: `${relationshipDescription(entity, link)} The list replaces the current links.`,
81
+ }));
82
+ }
83
+ }
84
+ return fields;
85
+ }
86
+ function joinLinks(ontology, entity) {
87
+ return [...entity.links.values()]
88
+ .filter((link) => link.via === "join" && !link.inverse && generatedJoin(ontology, link))
89
+ .map((link) => link.name);
90
+ }
91
+ /** Values to write, without the keys a generated input adds around them. */
92
+ function valuesOf(input, omit) {
93
+ return Object.fromEntries(Object.entries(input).filter(([key]) => !omit.includes(key)));
94
+ }
95
+ /**
96
+ * The actions generated for an entity: `create`, `update` (without `managed` properties), `delete`,
97
+ * `upsert_by_<property>` per unique property, and `link`/`unlink` when it declares a `rel.many`
98
+ * whose target keeps its generated writes. An entity that declares `writes: "actions"` has none. They
99
+ * are ordinary actions and run through the same pipeline. Their `permission` is unset: each requires
100
+ * the permission named after it (`lead:create`), and `upsert_by_<property>` both `create` and `update`,
101
+ * as `generatedActionPermissions` says. The built-in User has only its member management: `invite`,
102
+ * `grant_roles`, `revoke_roles`, `deactivate` and `reactivate`; members are otherwise created by
103
+ * sign-in and services by the app or the CLI. The built-in agent chat has only `update`, for its
104
+ * unmanaged properties: the agent records chats and their members.
105
+ */
106
+ export function generatedActions(ontology, entityName) {
107
+ const declared = ontology.manifest.entities.find((e) => e.name === entityName);
108
+ // A warehouse-backed entity has no writes; one with `writes: "actions"` only authored ones.
109
+ if (declared?.source !== undefined || declared?.writes === "actions") {
110
+ return {};
111
+ }
112
+ const byEntity = builtActions.get(ontology) ?? new Map();
113
+ const actions = byEntity.get(entityName) ?? buildGeneratedActions(ontology, entityName);
114
+ byEntity.set(entityName, actions);
115
+ builtActions.set(ontology, byEntity);
116
+ return actions;
117
+ }
118
+ const GENERATED_WRITES = new Set(["create", "update", "delete", "link", "unlink"]);
119
+ /**
120
+ * Why a generated write is missing when its entity declares `writes: "actions"`, naming the
121
+ * authored actions that write it instead; `undefined` for any other unknown action.
122
+ */
123
+ export function writesOnlyThroughActions(ontology, entityName, actionName) {
124
+ const declared = ontology.manifest.entities.find((candidate) => candidate.name === entityName);
125
+ const generatedName = GENERATED_WRITES.has(actionName) || actionName.startsWith(GENERATED_UPSERT_PREFIX);
126
+ if (declared?.writes !== "actions" || !generatedName) {
127
+ return undefined;
128
+ }
129
+ const authored = declared.actions.map((action) => action.name);
130
+ return (`${entityName} declares writes: "actions", so it has no generated ${actionName}; only its ` +
131
+ `own actions write its records` +
132
+ (authored.length > 0 ? `: ${authored.join(", ")}.` : ", and it declares none."));
133
+ }
134
+ /** A role a member may be granted: one the ontology declares, never the implicit `member`. */
135
+ function grantableRole(ontology) {
136
+ const declared = ontology.roles
137
+ .map((candidate) => candidate.name)
138
+ .filter((name) => name !== MEMBER_ROLE);
139
+ return declared.length > 0
140
+ ? Schema.Literals(declared)
141
+ : Schema.String.check(Schema.makeFilter(() => "Expected a role of the ontology, which declares none"));
142
+ }
143
+ /** A role to revoke: any assigned role, including one the ontology no longer declares. */
144
+ const revocableRole = Schema.String.check(Schema.makeFilter((role) => role !== MEMBER_ROLE || `${MEMBER_ROLE} is held by every active member and is never revoked`));
145
+ /**
146
+ * The built-in user's actions: inviting a member and changing a member's roles and activation, each
147
+ * through the runtime's member writes, which the `User` handle and the console share. Each returns
148
+ * the user, with its roles. A service is no member: its roles come with its API key.
149
+ */
150
+ function memberActions(ontology, entity) {
151
+ const label = entity.label.toLowerCase();
152
+ const member = (verb) => p.ref(entity.name, { description: `The member to ${verb}.` });
153
+ const roles = Schema.Array(grantableRole(ontology)).annotate({
154
+ description: "Roles the ontology declares. Every member holds member, which is never listed.",
155
+ });
156
+ return {
157
+ invite: action({
158
+ description: `Invite a member: create a ${label} for an email no ${label} has, with roles. ` +
159
+ "The member is linked to it at their first sign-in.",
160
+ input: Schema.Struct({
161
+ email: p.email({ description: "The address the member signs in with." }),
162
+ name: Schema.optionalKey(p.text({ description: "The name shown in the app; the email when omitted." })),
163
+ roles: Schema.optionalKey(roles),
164
+ }),
165
+ hints: { destructive: false, idempotent: false },
166
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.inviteUser({
167
+ email: input.email,
168
+ name: input.name,
169
+ roles: input.roles,
170
+ })),
171
+ }),
172
+ grant_roles: action({
173
+ description: "Grant roles to a member; roles the member holds stay as they are.",
174
+ input: Schema.Struct({ id: member("grant the roles to"), roles }),
175
+ hints: { destructive: false, idempotent: true },
176
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.grantUserRoles({
177
+ id: input.id,
178
+ roles: input.roles,
179
+ })),
180
+ }),
181
+ revoke_roles: action({
182
+ description: "Revoke roles from a member, or every role with all; roles the member does not hold are " +
183
+ "ignored. Give roles or all, not both.",
184
+ input: Schema.Struct({
185
+ id: member("revoke the roles from"),
186
+ roles: Schema.optionalKey(Schema.Array(revocableRole).annotate({ description: "The roles to revoke." })),
187
+ all: Schema.optionalKey(Schema.Literal(true).annotate({ description: "Revoke every role the member holds." })),
188
+ }).check(Schema.makeFilter((input) => (input.roles === undefined) !== (input.all === undefined) ||
189
+ "Expected roles or all: true, not both")),
190
+ hints: { destructive: true, idempotent: true },
191
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.revokeUserRoles({
192
+ id: input.id,
193
+ roles: input.all === true ? "all" : input.roles,
194
+ })),
195
+ }),
196
+ deactivate: action({
197
+ description: "Deactivate a member: they can no longer sign in or run actions, and their sessions end. " +
198
+ "Their roles and history stay.",
199
+ input: Schema.Struct({ id: member("deactivate") }),
200
+ hints: { destructive: true, idempotent: true },
201
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.setUserActive({ id: input.id, active: false })),
202
+ }),
203
+ reactivate: action({
204
+ description: "Reactivate a deactivated member, with the roles they held.",
205
+ input: Schema.Struct({ id: member("reactivate") }),
206
+ hints: { destructive: false, idempotent: true },
207
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.setUserActive({ id: input.id, active: true })),
208
+ }),
209
+ };
210
+ }
211
+ function buildGeneratedActions(ontology, entityName) {
212
+ const entity = entityModel(ontologyModel(ontology), entityName);
213
+ if (entity.resolved.builtIn && entity.name === User.name) {
214
+ return memberActions(ontology, entity);
215
+ }
216
+ if (entity.resolved.builtIn && entity.resolved.permissions.update === undefined) {
217
+ return {};
218
+ }
219
+ const label = entity.label.toLowerCase();
220
+ const id = (verb) => p.ref(entityName, { description: `The ${label} to ${verb}.` });
221
+ const managed = entity.fields
222
+ .filter((field) => field.property?.definition.managed === true)
223
+ .map((field) => field.name);
224
+ const update = action({
225
+ description: `Change ${article(label)}'s properties and relationships; omitted values stay as they are.` +
226
+ (managed.length > 0 ? ` ${managed.join(", ")} change only through other actions.` : ""),
227
+ input: Schema.Struct({
228
+ id: id("change"),
229
+ ...valueFields(ontology, entity, { mode: "update" }),
230
+ }),
231
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.update({
232
+ entity: entityName,
233
+ id: input.id,
234
+ values: valuesOf(input, ["id"]),
235
+ })),
236
+ });
237
+ if (entity.resolved.builtIn) {
238
+ return { update };
239
+ }
240
+ const actions = {
241
+ create: action({
242
+ description: `Create ${article(label)}.`,
243
+ input: Schema.Struct(valueFields(ontology, entity, { mode: "create" })),
244
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.create({ entity: entityName, values: input })),
245
+ }),
246
+ update,
247
+ delete: action({
248
+ description: `Delete ${article(label)}. Records that refer to it are deleted, cleared or protect it, ` +
249
+ "as each relationship's onDelete says.",
250
+ input: Schema.Struct({ id: id("delete") }),
251
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.delete({ entity: entityName, id: input.id })),
252
+ }),
253
+ };
254
+ for (const field of entity.fields) {
255
+ if (field.property?.definition.unique !== true) {
256
+ continue;
257
+ }
258
+ const name = upsertActionName(field.name);
259
+ actions[name] = action({
260
+ description: `Create ${article(label)}, or update the ${label} with the same ${field.name}.`,
261
+ input: Schema.Struct(valueFields(ontology, entity, { mode: "create" })),
262
+ handler: ({ input }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.upsertBy({ entity: entityName, property: field.name, values: input })),
263
+ });
264
+ }
265
+ const many = joinLinks(ontology, entity);
266
+ if (many.length > 0) {
267
+ const input = Schema.Struct({
268
+ relationship: Schema.Literals(many),
269
+ id: p.ref(entityName, { description: `The ${label}.` }),
270
+ target: Schema.String.annotate({
271
+ format: "uuid",
272
+ description: "The id of the related record.",
273
+ }),
274
+ });
275
+ actions.link = action({
276
+ description: `Link ${article(label)} to a record through ${many.join(" or ")}.`,
277
+ input,
278
+ handler: ({ input: { relationship, id: recordId, target } }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.link({ entity: entityName, relationship, id: recordId, targetId: target })),
279
+ });
280
+ actions.unlink = action({
281
+ description: `Remove a link of ${article(label)} through ${many.join(" or ")}.`,
282
+ input,
283
+ handler: ({ input: { relationship, id: recordId, target } }) => Effect.flatMap(OntologyWrites, (runtime) => runtime.unlink({ entity: entityName, relationship, id: recordId, targetId: target })),
284
+ });
285
+ }
286
+ return actions;
287
+ }
288
+ /** An action's input as JSON Schema (draft 2020-12), as the manifest describes authored actions. */
289
+ export function actionInputJsonSchema(input) {
290
+ const document = Schema.toJsonSchemaDocument(input, {
291
+ includeAnnotationKey: (key) => key === REFERENCE_ANNOTATION || key === BLOB_UPLOAD_ANNOTATION,
292
+ onExcessProperty: "error",
293
+ });
294
+ const schema = document.schema;
295
+ return Object.keys(document.definitions).length === 0
296
+ ? schema
297
+ : { ...schema, $defs: document.definitions };
298
+ }
299
+ /** The generated actions described as the manifest describes authored ones, for catalogs and MCP. */
300
+ export function generatedActionManifests(ontology, entityName) {
301
+ return Object.entries(generatedActions(ontology, entityName)).map(([name, generated]) => ({
302
+ name,
303
+ description: generated.description,
304
+ permissions: generatedActionPermissions(entityName, name),
305
+ input: actionInputJsonSchema(generated.input),
306
+ }));
307
+ }