@jini-ai/cms 0.1.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 (527) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +84 -0
  3. package/dist/content-types/agent-tools.d.ts +65 -0
  4. package/dist/content-types/agent-tools.d.ts.map +1 -0
  5. package/dist/content-types/agent-tools.js +172 -0
  6. package/dist/content-types/agent-tools.js.map +1 -0
  7. package/dist/content-types/cleanup.d.ts +118 -0
  8. package/dist/content-types/cleanup.d.ts.map +1 -0
  9. package/dist/content-types/cleanup.js +65 -0
  10. package/dist/content-types/cleanup.js.map +1 -0
  11. package/dist/content-types/errors.d.ts +90 -0
  12. package/dist/content-types/errors.d.ts.map +1 -0
  13. package/dist/content-types/errors.js +119 -0
  14. package/dist/content-types/errors.js.map +1 -0
  15. package/dist/content-types/field-defs.d.ts +25 -0
  16. package/dist/content-types/field-defs.d.ts.map +1 -0
  17. package/dist/content-types/field-defs.js +155 -0
  18. package/dist/content-types/field-defs.js.map +1 -0
  19. package/dist/content-types/index-provisioning.d.ts +94 -0
  20. package/dist/content-types/index-provisioning.d.ts.map +1 -0
  21. package/dist/content-types/index-provisioning.js +133 -0
  22. package/dist/content-types/index-provisioning.js.map +1 -0
  23. package/dist/content-types/index.d.ts +63 -0
  24. package/dist/content-types/index.d.ts.map +1 -0
  25. package/dist/content-types/index.js +36 -0
  26. package/dist/content-types/index.js.map +1 -0
  27. package/dist/content-types/lifecycle-dispatch.d.ts +38 -0
  28. package/dist/content-types/lifecycle-dispatch.d.ts.map +1 -0
  29. package/dist/content-types/lifecycle-dispatch.js +28 -0
  30. package/dist/content-types/lifecycle-dispatch.js.map +1 -0
  31. package/dist/content-types/lifecycle.d.ts +104 -0
  32. package/dist/content-types/lifecycle.d.ts.map +1 -0
  33. package/dist/content-types/lifecycle.js +143 -0
  34. package/dist/content-types/lifecycle.js.map +1 -0
  35. package/dist/content-types/list.d.ts +44 -0
  36. package/dist/content-types/list.d.ts.map +1 -0
  37. package/dist/content-types/list.js +13 -0
  38. package/dist/content-types/list.js.map +1 -0
  39. package/dist/content-types/repo.memory.d.ts +72 -0
  40. package/dist/content-types/repo.memory.d.ts.map +1 -0
  41. package/dist/content-types/repo.memory.js +71 -0
  42. package/dist/content-types/repo.memory.js.map +1 -0
  43. package/dist/content-types/tool-registrations.d.ts +65 -0
  44. package/dist/content-types/tool-registrations.d.ts.map +1 -0
  45. package/dist/content-types/tool-registrations.js +180 -0
  46. package/dist/content-types/tool-registrations.js.map +1 -0
  47. package/dist/content-types/types.d.ts +78 -0
  48. package/dist/content-types/types.d.ts.map +1 -0
  49. package/dist/content-types/types.js +32 -0
  50. package/dist/content-types/types.js.map +1 -0
  51. package/dist/content-types/write-service.d.ts +141 -0
  52. package/dist/content-types/write-service.d.ts.map +1 -0
  53. package/dist/content-types/write-service.js +180 -0
  54. package/dist/content-types/write-service.js.map +1 -0
  55. package/dist/core/commands/change-set.d.ts +98 -0
  56. package/dist/core/commands/change-set.d.ts.map +1 -0
  57. package/dist/core/commands/change-set.js +2 -0
  58. package/dist/core/commands/change-set.js.map +1 -0
  59. package/dist/core/commands/command.d.ts +168 -0
  60. package/dist/core/commands/command.d.ts.map +1 -0
  61. package/dist/core/commands/command.js +173 -0
  62. package/dist/core/commands/command.js.map +1 -0
  63. package/dist/core/index.d.ts +45 -0
  64. package/dist/core/index.d.ts.map +1 -0
  65. package/dist/core/index.js +43 -0
  66. package/dist/core/index.js.map +1 -0
  67. package/dist/core/ports.d.ts +139 -0
  68. package/dist/core/ports.d.ts.map +1 -0
  69. package/dist/core/ports.js +2 -0
  70. package/dist/core/ports.js.map +1 -0
  71. package/dist/core/tools/registration-kit.d.ts +308 -0
  72. package/dist/core/tools/registration-kit.d.ts.map +1 -0
  73. package/dist/core/tools/registration-kit.js +381 -0
  74. package/dist/core/tools/registration-kit.js.map +1 -0
  75. package/dist/entries/agent-tools.d.ts +78 -0
  76. package/dist/entries/agent-tools.d.ts.map +1 -0
  77. package/dist/entries/agent-tools.js +158 -0
  78. package/dist/entries/agent-tools.js.map +1 -0
  79. package/dist/entries/errors.d.ts +43 -0
  80. package/dist/entries/errors.d.ts.map +1 -0
  81. package/dist/entries/errors.js +59 -0
  82. package/dist/entries/errors.js.map +1 -0
  83. package/dist/entries/field-validation.d.ts +70 -0
  84. package/dist/entries/field-validation.d.ts.map +1 -0
  85. package/dist/entries/field-validation.js +87 -0
  86. package/dist/entries/field-validation.js.map +1 -0
  87. package/dist/entries/index.d.ts +55 -0
  88. package/dist/entries/index.d.ts.map +1 -0
  89. package/dist/entries/index.js +38 -0
  90. package/dist/entries/index.js.map +1 -0
  91. package/dist/entries/lifecycle-dispatch.d.ts +15 -0
  92. package/dist/entries/lifecycle-dispatch.d.ts.map +1 -0
  93. package/dist/entries/lifecycle-dispatch.js +16 -0
  94. package/dist/entries/lifecycle-dispatch.js.map +1 -0
  95. package/dist/entries/list.d.ts +47 -0
  96. package/dist/entries/list.d.ts.map +1 -0
  97. package/dist/entries/list.js +12 -0
  98. package/dist/entries/list.js.map +1 -0
  99. package/dist/entries/repo.memory.d.ts +64 -0
  100. package/dist/entries/repo.memory.d.ts.map +1 -0
  101. package/dist/entries/repo.memory.js +73 -0
  102. package/dist/entries/repo.memory.js.map +1 -0
  103. package/dist/entries/tool-registrations.d.ts +52 -0
  104. package/dist/entries/tool-registrations.d.ts.map +1 -0
  105. package/dist/entries/tool-registrations.js +141 -0
  106. package/dist/entries/tool-registrations.js.map +1 -0
  107. package/dist/entries/types.d.ts +55 -0
  108. package/dist/entries/types.d.ts.map +1 -0
  109. package/dist/entries/types.js +2 -0
  110. package/dist/entries/types.js.map +1 -0
  111. package/dist/entries/write-service.d.ts +202 -0
  112. package/dist/entries/write-service.d.ts.map +1 -0
  113. package/dist/entries/write-service.js +204 -0
  114. package/dist/entries/write-service.js.map +1 -0
  115. package/dist/identity/admin-crud-service.d.ts +252 -0
  116. package/dist/identity/admin-crud-service.d.ts.map +1 -0
  117. package/dist/identity/admin-crud-service.js +437 -0
  118. package/dist/identity/admin-crud-service.js.map +1 -0
  119. package/dist/identity/agent-tool-input.d.ts +58 -0
  120. package/dist/identity/agent-tool-input.d.ts.map +1 -0
  121. package/dist/identity/agent-tool-input.js +126 -0
  122. package/dist/identity/agent-tool-input.js.map +1 -0
  123. package/dist/identity/agent-tools.d.ts +101 -0
  124. package/dist/identity/agent-tools.d.ts.map +1 -0
  125. package/dist/identity/agent-tools.js +290 -0
  126. package/dist/identity/agent-tools.js.map +1 -0
  127. package/dist/identity/auth-service.d.ts +87 -0
  128. package/dist/identity/auth-service.d.ts.map +1 -0
  129. package/dist/identity/auth-service.js +141 -0
  130. package/dist/identity/auth-service.js.map +1 -0
  131. package/dist/identity/authorize.d.ts +90 -0
  132. package/dist/identity/authorize.d.ts.map +1 -0
  133. package/dist/identity/authorize.js +94 -0
  134. package/dist/identity/authorize.js.map +1 -0
  135. package/dist/identity/grant-service.d.ts +198 -0
  136. package/dist/identity/grant-service.d.ts.map +1 -0
  137. package/dist/identity/grant-service.js +361 -0
  138. package/dist/identity/grant-service.js.map +1 -0
  139. package/dist/identity/hasher.d.ts +39 -0
  140. package/dist/identity/hasher.d.ts.map +1 -0
  141. package/dist/identity/hasher.js +39 -0
  142. package/dist/identity/hasher.js.map +1 -0
  143. package/dist/identity/index.d.ts +59 -0
  144. package/dist/identity/index.d.ts.map +1 -0
  145. package/dist/identity/index.js +51 -0
  146. package/dist/identity/index.js.map +1 -0
  147. package/dist/identity/password-policy.d.ts +58 -0
  148. package/dist/identity/password-policy.d.ts.map +1 -0
  149. package/dist/identity/password-policy.js +67 -0
  150. package/dist/identity/password-policy.js.map +1 -0
  151. package/dist/identity/permission-migrations.d.ts +86 -0
  152. package/dist/identity/permission-migrations.d.ts.map +1 -0
  153. package/dist/identity/permission-migrations.js +67 -0
  154. package/dist/identity/permission-migrations.js.map +1 -0
  155. package/dist/identity/permissions.d.ts +35 -0
  156. package/dist/identity/permissions.d.ts.map +1 -0
  157. package/dist/identity/permissions.js +603 -0
  158. package/dist/identity/permissions.js.map +1 -0
  159. package/dist/identity/ports.d.ts +201 -0
  160. package/dist/identity/ports.d.ts.map +1 -0
  161. package/dist/identity/ports.js +2 -0
  162. package/dist/identity/ports.js.map +1 -0
  163. package/dist/identity/repo.memory.d.ts +164 -0
  164. package/dist/identity/repo.memory.d.ts.map +1 -0
  165. package/dist/identity/repo.memory.js +224 -0
  166. package/dist/identity/repo.memory.js.map +1 -0
  167. package/dist/identity/seed.d.ts +42 -0
  168. package/dist/identity/seed.d.ts.map +1 -0
  169. package/dist/identity/seed.js +277 -0
  170. package/dist/identity/seed.js.map +1 -0
  171. package/dist/identity/tool-registrations.d.ts +50 -0
  172. package/dist/identity/tool-registrations.d.ts.map +1 -0
  173. package/dist/identity/tool-registrations.js +419 -0
  174. package/dist/identity/tool-registrations.js.map +1 -0
  175. package/dist/identity/types.d.ts +185 -0
  176. package/dist/identity/types.d.ts.map +1 -0
  177. package/dist/identity/types.js +64 -0
  178. package/dist/identity/types.js.map +1 -0
  179. package/dist/identity/username.d.ts +12 -0
  180. package/dist/identity/username.d.ts.map +1 -0
  181. package/dist/identity/username.js +14 -0
  182. package/dist/identity/username.js.map +1 -0
  183. package/dist/media/agent-tools.d.ts +66 -0
  184. package/dist/media/agent-tools.d.ts.map +1 -0
  185. package/dist/media/agent-tools.js +131 -0
  186. package/dist/media/agent-tools.js.map +1 -0
  187. package/dist/media/blob-gc-lock.d.ts +37 -0
  188. package/dist/media/blob-gc-lock.d.ts.map +1 -0
  189. package/dist/media/blob-gc-lock.js +55 -0
  190. package/dist/media/blob-gc-lock.js.map +1 -0
  191. package/dist/media/blob-gc.d.ts +246 -0
  192. package/dist/media/blob-gc.d.ts.map +1 -0
  193. package/dist/media/blob-gc.js +254 -0
  194. package/dist/media/blob-gc.js.map +1 -0
  195. package/dist/media/blob-key.d.ts +28 -0
  196. package/dist/media/blob-key.d.ts.map +1 -0
  197. package/dist/media/blob-key.js +11 -0
  198. package/dist/media/blob-key.js.map +1 -0
  199. package/dist/media/blob-store.fs.d.ts +23 -0
  200. package/dist/media/blob-store.fs.d.ts.map +1 -0
  201. package/dist/media/blob-store.fs.js +48 -0
  202. package/dist/media/blob-store.fs.js.map +1 -0
  203. package/dist/media/blob-store.memory.d.ts +22 -0
  204. package/dist/media/blob-store.memory.d.ts.map +1 -0
  205. package/dist/media/blob-store.memory.js +23 -0
  206. package/dist/media/blob-store.memory.js.map +1 -0
  207. package/dist/media/content-type-sniffer.d.ts +49 -0
  208. package/dist/media/content-type-sniffer.d.ts.map +1 -0
  209. package/dist/media/content-type-sniffer.js +141 -0
  210. package/dist/media/content-type-sniffer.js.map +1 -0
  211. package/dist/media/image-transformer.d.ts +45 -0
  212. package/dist/media/image-transformer.d.ts.map +1 -0
  213. package/dist/media/image-transformer.js +23 -0
  214. package/dist/media/image-transformer.js.map +1 -0
  215. package/dist/media/image-transformer.sharp.d.ts +26 -0
  216. package/dist/media/image-transformer.sharp.d.ts.map +1 -0
  217. package/dist/media/image-transformer.sharp.js +91 -0
  218. package/dist/media/image-transformer.sharp.js.map +1 -0
  219. package/dist/media/index.d.ts +43 -0
  220. package/dist/media/index.d.ts.map +1 -0
  221. package/dist/media/index.js +31 -0
  222. package/dist/media/index.js.map +1 -0
  223. package/dist/media/media-service.d.ts +244 -0
  224. package/dist/media/media-service.d.ts.map +1 -0
  225. package/dist/media/media-service.js +345 -0
  226. package/dist/media/media-service.js.map +1 -0
  227. package/dist/media/ports.d.ts +142 -0
  228. package/dist/media/ports.d.ts.map +1 -0
  229. package/dist/media/ports.js +2 -0
  230. package/dist/media/ports.js.map +1 -0
  231. package/dist/media/rendition-service.d.ts +66 -0
  232. package/dist/media/rendition-service.d.ts.map +1 -0
  233. package/dist/media/rendition-service.js +135 -0
  234. package/dist/media/rendition-service.js.map +1 -0
  235. package/dist/media/repo.memory.d.ts +107 -0
  236. package/dist/media/repo.memory.d.ts.map +1 -0
  237. package/dist/media/repo.memory.js +131 -0
  238. package/dist/media/repo.memory.js.map +1 -0
  239. package/dist/media/tool-registrations.d.ts +42 -0
  240. package/dist/media/tool-registrations.d.ts.map +1 -0
  241. package/dist/media/tool-registrations.js +121 -0
  242. package/dist/media/tool-registrations.js.map +1 -0
  243. package/dist/media/transform-lock.d.ts +36 -0
  244. package/dist/media/transform-lock.d.ts.map +1 -0
  245. package/dist/media/transform-lock.js +50 -0
  246. package/dist/media/transform-lock.js.map +1 -0
  247. package/dist/media/transform-registry.d.ts +103 -0
  248. package/dist/media/transform-registry.d.ts.map +1 -0
  249. package/dist/media/transform-registry.js +87 -0
  250. package/dist/media/transform-registry.js.map +1 -0
  251. package/dist/media/transform-types.d.ts +82 -0
  252. package/dist/media/transform-types.d.ts.map +1 -0
  253. package/dist/media/transform-types.js +47 -0
  254. package/dist/media/transform-types.js.map +1 -0
  255. package/dist/media/types.d.ts +150 -0
  256. package/dist/media/types.d.ts.map +1 -0
  257. package/dist/media/types.js +26 -0
  258. package/dist/media/types.js.map +1 -0
  259. package/dist/navigation/agent-tools.d.ts +90 -0
  260. package/dist/navigation/agent-tools.d.ts.map +1 -0
  261. package/dist/navigation/agent-tools.js +225 -0
  262. package/dist/navigation/agent-tools.js.map +1 -0
  263. package/dist/navigation/contracts.d.ts +98 -0
  264. package/dist/navigation/contracts.d.ts.map +1 -0
  265. package/dist/navigation/contracts.js +70 -0
  266. package/dist/navigation/contracts.js.map +1 -0
  267. package/dist/navigation/index.d.ts +39 -0
  268. package/dist/navigation/index.d.ts.map +1 -0
  269. package/dist/navigation/index.js +30 -0
  270. package/dist/navigation/index.js.map +1 -0
  271. package/dist/navigation/menu-service.d.ts +256 -0
  272. package/dist/navigation/menu-service.d.ts.map +1 -0
  273. package/dist/navigation/menu-service.js +382 -0
  274. package/dist/navigation/menu-service.js.map +1 -0
  275. package/dist/navigation/ports.d.ts +147 -0
  276. package/dist/navigation/ports.d.ts.map +1 -0
  277. package/dist/navigation/ports.js +2 -0
  278. package/dist/navigation/ports.js.map +1 -0
  279. package/dist/navigation/read-model.d.ts +11 -0
  280. package/dist/navigation/read-model.d.ts.map +1 -0
  281. package/dist/navigation/read-model.js +27 -0
  282. package/dist/navigation/read-model.js.map +1 -0
  283. package/dist/navigation/reconcile.d.ts +57 -0
  284. package/dist/navigation/reconcile.d.ts.map +1 -0
  285. package/dist/navigation/reconcile.js +33 -0
  286. package/dist/navigation/reconcile.js.map +1 -0
  287. package/dist/navigation/repo.memory.d.ts +137 -0
  288. package/dist/navigation/repo.memory.d.ts.map +1 -0
  289. package/dist/navigation/repo.memory.js +95 -0
  290. package/dist/navigation/repo.memory.js.map +1 -0
  291. package/dist/navigation/resolver.d.ts +110 -0
  292. package/dist/navigation/resolver.d.ts.map +1 -0
  293. package/dist/navigation/resolver.js +131 -0
  294. package/dist/navigation/resolver.js.map +1 -0
  295. package/dist/navigation/tool-registrations.d.ts +43 -0
  296. package/dist/navigation/tool-registrations.d.ts.map +1 -0
  297. package/dist/navigation/tool-registrations.js +126 -0
  298. package/dist/navigation/tool-registrations.js.map +1 -0
  299. package/dist/navigation/types.d.ts +207 -0
  300. package/dist/navigation/types.d.ts.map +1 -0
  301. package/dist/navigation/types.js +14 -0
  302. package/dist/navigation/types.js.map +1 -0
  303. package/dist/presentation/index.d.ts +15 -0
  304. package/dist/presentation/index.d.ts.map +1 -0
  305. package/dist/presentation/index.js +15 -0
  306. package/dist/presentation/index.js.map +1 -0
  307. package/dist/presentation/presentation.d.ts +72 -0
  308. package/dist/presentation/presentation.d.ts.map +1 -0
  309. package/dist/presentation/presentation.js +51 -0
  310. package/dist/presentation/presentation.js.map +1 -0
  311. package/dist/presentation/repo.memory.d.ts +9 -0
  312. package/dist/presentation/repo.memory.d.ts.map +1 -0
  313. package/dist/presentation/repo.memory.js +21 -0
  314. package/dist/presentation/repo.memory.js.map +1 -0
  315. package/dist/server/index.d.ts +28 -0
  316. package/dist/server/index.d.ts.map +1 -0
  317. package/dist/server/index.js +28 -0
  318. package/dist/server/index.js.map +1 -0
  319. package/dist/settings/agent-tools.d.ts +83 -0
  320. package/dist/settings/agent-tools.d.ts.map +1 -0
  321. package/dist/settings/agent-tools.js +200 -0
  322. package/dist/settings/agent-tools.js.map +1 -0
  323. package/dist/settings/agent-writable-preferences.d.ts +67 -0
  324. package/dist/settings/agent-writable-preferences.d.ts.map +1 -0
  325. package/dist/settings/agent-writable-preferences.js +144 -0
  326. package/dist/settings/agent-writable-preferences.js.map +1 -0
  327. package/dist/settings/change-feed.d.ts +74 -0
  328. package/dist/settings/change-feed.d.ts.map +1 -0
  329. package/dist/settings/change-feed.js +61 -0
  330. package/dist/settings/change-feed.js.map +1 -0
  331. package/dist/settings/definitions-dispatch.d.ts +51 -0
  332. package/dist/settings/definitions-dispatch.d.ts.map +1 -0
  333. package/dist/settings/definitions-dispatch.js +86 -0
  334. package/dist/settings/definitions-dispatch.js.map +1 -0
  335. package/dist/settings/dictionaries/index.d.ts +45 -0
  336. package/dist/settings/dictionaries/index.d.ts.map +1 -0
  337. package/dist/settings/dictionaries/index.js +69 -0
  338. package/dist/settings/dictionaries/index.js.map +1 -0
  339. package/dist/settings/dictionaries/settings-dialog.ar.d.ts +3 -0
  340. package/dist/settings/dictionaries/settings-dialog.ar.d.ts.map +1 -0
  341. package/dist/settings/dictionaries/settings-dialog.ar.js +28 -0
  342. package/dist/settings/dictionaries/settings-dialog.ar.js.map +1 -0
  343. package/dist/settings/dictionaries/settings-dialog.bn.d.ts +3 -0
  344. package/dist/settings/dictionaries/settings-dialog.bn.d.ts.map +1 -0
  345. package/dist/settings/dictionaries/settings-dialog.bn.js +28 -0
  346. package/dist/settings/dictionaries/settings-dialog.bn.js.map +1 -0
  347. package/dist/settings/dictionaries/settings-dialog.de.d.ts +3 -0
  348. package/dist/settings/dictionaries/settings-dialog.de.d.ts.map +1 -0
  349. package/dist/settings/dictionaries/settings-dialog.de.js +28 -0
  350. package/dist/settings/dictionaries/settings-dialog.de.js.map +1 -0
  351. package/dist/settings/dictionaries/settings-dialog.es.d.ts +3 -0
  352. package/dist/settings/dictionaries/settings-dialog.es.d.ts.map +1 -0
  353. package/dist/settings/dictionaries/settings-dialog.es.js +28 -0
  354. package/dist/settings/dictionaries/settings-dialog.es.js.map +1 -0
  355. package/dist/settings/dictionaries/settings-dialog.fa.d.ts +3 -0
  356. package/dist/settings/dictionaries/settings-dialog.fa.d.ts.map +1 -0
  357. package/dist/settings/dictionaries/settings-dialog.fa.js +28 -0
  358. package/dist/settings/dictionaries/settings-dialog.fa.js.map +1 -0
  359. package/dist/settings/dictionaries/settings-dialog.fr.d.ts +3 -0
  360. package/dist/settings/dictionaries/settings-dialog.fr.d.ts.map +1 -0
  361. package/dist/settings/dictionaries/settings-dialog.fr.js +28 -0
  362. package/dist/settings/dictionaries/settings-dialog.fr.js.map +1 -0
  363. package/dist/settings/dictionaries/settings-dialog.hi.d.ts +3 -0
  364. package/dist/settings/dictionaries/settings-dialog.hi.d.ts.map +1 -0
  365. package/dist/settings/dictionaries/settings-dialog.hi.js +28 -0
  366. package/dist/settings/dictionaries/settings-dialog.hi.js.map +1 -0
  367. package/dist/settings/dictionaries/settings-dialog.hu.d.ts +3 -0
  368. package/dist/settings/dictionaries/settings-dialog.hu.d.ts.map +1 -0
  369. package/dist/settings/dictionaries/settings-dialog.hu.js +28 -0
  370. package/dist/settings/dictionaries/settings-dialog.hu.js.map +1 -0
  371. package/dist/settings/dictionaries/settings-dialog.id.d.ts +3 -0
  372. package/dist/settings/dictionaries/settings-dialog.id.d.ts.map +1 -0
  373. package/dist/settings/dictionaries/settings-dialog.id.js +28 -0
  374. package/dist/settings/dictionaries/settings-dialog.id.js.map +1 -0
  375. package/dist/settings/dictionaries/settings-dialog.it.d.ts +3 -0
  376. package/dist/settings/dictionaries/settings-dialog.it.d.ts.map +1 -0
  377. package/dist/settings/dictionaries/settings-dialog.it.js +28 -0
  378. package/dist/settings/dictionaries/settings-dialog.it.js.map +1 -0
  379. package/dist/settings/dictionaries/settings-dialog.ja.d.ts +3 -0
  380. package/dist/settings/dictionaries/settings-dialog.ja.d.ts.map +1 -0
  381. package/dist/settings/dictionaries/settings-dialog.ja.js +28 -0
  382. package/dist/settings/dictionaries/settings-dialog.ja.js.map +1 -0
  383. package/dist/settings/dictionaries/settings-dialog.ko.d.ts +3 -0
  384. package/dist/settings/dictionaries/settings-dialog.ko.d.ts.map +1 -0
  385. package/dist/settings/dictionaries/settings-dialog.ko.js +28 -0
  386. package/dist/settings/dictionaries/settings-dialog.ko.js.map +1 -0
  387. package/dist/settings/dictionaries/settings-dialog.pl.d.ts +3 -0
  388. package/dist/settings/dictionaries/settings-dialog.pl.d.ts.map +1 -0
  389. package/dist/settings/dictionaries/settings-dialog.pl.js +28 -0
  390. package/dist/settings/dictionaries/settings-dialog.pl.js.map +1 -0
  391. package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts +3 -0
  392. package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts.map +1 -0
  393. package/dist/settings/dictionaries/settings-dialog.pt-BR.js +28 -0
  394. package/dist/settings/dictionaries/settings-dialog.pt-BR.js.map +1 -0
  395. package/dist/settings/dictionaries/settings-dialog.ru.d.ts +3 -0
  396. package/dist/settings/dictionaries/settings-dialog.ru.d.ts.map +1 -0
  397. package/dist/settings/dictionaries/settings-dialog.ru.js +28 -0
  398. package/dist/settings/dictionaries/settings-dialog.ru.js.map +1 -0
  399. package/dist/settings/dictionaries/settings-dialog.th.d.ts +3 -0
  400. package/dist/settings/dictionaries/settings-dialog.th.d.ts.map +1 -0
  401. package/dist/settings/dictionaries/settings-dialog.th.js +28 -0
  402. package/dist/settings/dictionaries/settings-dialog.th.js.map +1 -0
  403. package/dist/settings/dictionaries/settings-dialog.tr.d.ts +3 -0
  404. package/dist/settings/dictionaries/settings-dialog.tr.d.ts.map +1 -0
  405. package/dist/settings/dictionaries/settings-dialog.tr.js +28 -0
  406. package/dist/settings/dictionaries/settings-dialog.tr.js.map +1 -0
  407. package/dist/settings/dictionaries/settings-dialog.uk.d.ts +3 -0
  408. package/dist/settings/dictionaries/settings-dialog.uk.d.ts.map +1 -0
  409. package/dist/settings/dictionaries/settings-dialog.uk.js +28 -0
  410. package/dist/settings/dictionaries/settings-dialog.uk.js.map +1 -0
  411. package/dist/settings/dictionaries/settings-dialog.ur.d.ts +3 -0
  412. package/dist/settings/dictionaries/settings-dialog.ur.d.ts.map +1 -0
  413. package/dist/settings/dictionaries/settings-dialog.ur.js +28 -0
  414. package/dist/settings/dictionaries/settings-dialog.ur.js.map +1 -0
  415. package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts +3 -0
  416. package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts.map +1 -0
  417. package/dist/settings/dictionaries/settings-dialog.zh-CN.js +28 -0
  418. package/dist/settings/dictionaries/settings-dialog.zh-CN.js.map +1 -0
  419. package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts +3 -0
  420. package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts.map +1 -0
  421. package/dist/settings/dictionaries/settings-dialog.zh-TW.js +28 -0
  422. package/dist/settings/dictionaries/settings-dialog.zh-TW.js.map +1 -0
  423. package/dist/settings/ensure-definitions.d.ts +88 -0
  424. package/dist/settings/ensure-definitions.d.ts.map +1 -0
  425. package/dist/settings/ensure-definitions.js +91 -0
  426. package/dist/settings/ensure-definitions.js.map +1 -0
  427. package/dist/settings/errors.d.ts +36 -0
  428. package/dist/settings/errors.d.ts.map +1 -0
  429. package/dist/settings/errors.js +40 -0
  430. package/dist/settings/errors.js.map +1 -0
  431. package/dist/settings/index.d.ts +37 -0
  432. package/dist/settings/index.d.ts.map +1 -0
  433. package/dist/settings/index.js +36 -0
  434. package/dist/settings/index.js.map +1 -0
  435. package/dist/settings/ports.d.ts +117 -0
  436. package/dist/settings/ports.d.ts.map +1 -0
  437. package/dist/settings/ports.js +2 -0
  438. package/dist/settings/ports.js.map +1 -0
  439. package/dist/settings/purge-service.d.ts +53 -0
  440. package/dist/settings/purge-service.d.ts.map +1 -0
  441. package/dist/settings/purge-service.js +105 -0
  442. package/dist/settings/purge-service.js.map +1 -0
  443. package/dist/settings/repo.memory.d.ts +119 -0
  444. package/dist/settings/repo.memory.d.ts.map +1 -0
  445. package/dist/settings/repo.memory.js +199 -0
  446. package/dist/settings/repo.memory.js.map +1 -0
  447. package/dist/settings/settings.d.ts +124 -0
  448. package/dist/settings/settings.d.ts.map +1 -0
  449. package/dist/settings/settings.js +238 -0
  450. package/dist/settings/settings.js.map +1 -0
  451. package/dist/settings/tool-registrations.d.ts +56 -0
  452. package/dist/settings/tool-registrations.d.ts.map +1 -0
  453. package/dist/settings/tool-registrations.js +240 -0
  454. package/dist/settings/tool-registrations.js.map +1 -0
  455. package/dist/settings/types.d.ts +125 -0
  456. package/dist/settings/types.d.ts.map +1 -0
  457. package/dist/settings/types.js +3 -0
  458. package/dist/settings/types.js.map +1 -0
  459. package/dist/settings/ui-tab-definitions.d.ts +41 -0
  460. package/dist/settings/ui-tab-definitions.d.ts.map +1 -0
  461. package/dist/settings/ui-tab-definitions.js +148 -0
  462. package/dist/settings/ui-tab-definitions.js.map +1 -0
  463. package/dist/settings/write-service.d.ts +314 -0
  464. package/dist/settings/write-service.d.ts.map +1 -0
  465. package/dist/settings/write-service.js +677 -0
  466. package/dist/settings/write-service.js.map +1 -0
  467. package/dist/taxonomy/agent-tools.d.ts +76 -0
  468. package/dist/taxonomy/agent-tools.d.ts.map +1 -0
  469. package/dist/taxonomy/agent-tools.js +178 -0
  470. package/dist/taxonomy/agent-tools.js.map +1 -0
  471. package/dist/taxonomy/content-lookup.d.ts +45 -0
  472. package/dist/taxonomy/content-lookup.d.ts.map +1 -0
  473. package/dist/taxonomy/content-lookup.js +9 -0
  474. package/dist/taxonomy/content-lookup.js.map +1 -0
  475. package/dist/taxonomy/index.d.ts +38 -0
  476. package/dist/taxonomy/index.d.ts.map +1 -0
  477. package/dist/taxonomy/index.js +38 -0
  478. package/dist/taxonomy/index.js.map +1 -0
  479. package/dist/taxonomy/list.d.ts +39 -0
  480. package/dist/taxonomy/list.d.ts.map +1 -0
  481. package/dist/taxonomy/list.js +19 -0
  482. package/dist/taxonomy/list.js.map +1 -0
  483. package/dist/taxonomy/merge-term.d.ts +94 -0
  484. package/dist/taxonomy/merge-term.d.ts.map +1 -0
  485. package/dist/taxonomy/merge-term.js +65 -0
  486. package/dist/taxonomy/merge-term.js.map +1 -0
  487. package/dist/taxonomy/repo.memory.d.ts +160 -0
  488. package/dist/taxonomy/repo.memory.d.ts.map +1 -0
  489. package/dist/taxonomy/repo.memory.js +171 -0
  490. package/dist/taxonomy/repo.memory.js.map +1 -0
  491. package/dist/taxonomy/validation-chain.d.ts +114 -0
  492. package/dist/taxonomy/validation-chain.d.ts.map +1 -0
  493. package/dist/taxonomy/validation-chain.js +152 -0
  494. package/dist/taxonomy/validation-chain.js.map +1 -0
  495. package/dist/taxonomy/write-service.d.ts +387 -0
  496. package/dist/taxonomy/write-service.d.ts.map +1 -0
  497. package/dist/taxonomy/write-service.js +350 -0
  498. package/dist/taxonomy/write-service.js.map +1 -0
  499. package/dist/workspace/agent-tools.d.ts +67 -0
  500. package/dist/workspace/agent-tools.d.ts.map +1 -0
  501. package/dist/workspace/agent-tools.js +103 -0
  502. package/dist/workspace/agent-tools.js.map +1 -0
  503. package/dist/workspace/create.d.ts +116 -0
  504. package/dist/workspace/create.d.ts.map +1 -0
  505. package/dist/workspace/create.js +69 -0
  506. package/dist/workspace/create.js.map +1 -0
  507. package/dist/workspace/delete.d.ts +50 -0
  508. package/dist/workspace/delete.d.ts.map +1 -0
  509. package/dist/workspace/delete.js +24 -0
  510. package/dist/workspace/delete.js.map +1 -0
  511. package/dist/workspace/index.d.ts +27 -0
  512. package/dist/workspace/index.d.ts.map +1 -0
  513. package/dist/workspace/index.js +27 -0
  514. package/dist/workspace/index.js.map +1 -0
  515. package/dist/workspace/repo.memory.d.ts +34 -0
  516. package/dist/workspace/repo.memory.d.ts.map +1 -0
  517. package/dist/workspace/repo.memory.js +50 -0
  518. package/dist/workspace/repo.memory.js.map +1 -0
  519. package/dist/workspace/tool-registrations.d.ts +38 -0
  520. package/dist/workspace/tool-registrations.d.ts.map +1 -0
  521. package/dist/workspace/tool-registrations.js +71 -0
  522. package/dist/workspace/tool-registrations.js.map +1 -0
  523. package/dist/workspace/update.d.ts +52 -0
  524. package/dist/workspace/update.d.ts.map +1 -0
  525. package/dist/workspace/update.js +41 -0
  526. package/dist/workspace/update.js.map +1 -0
  527. package/package.json +149 -0
@@ -0,0 +1,141 @@
1
+ import type { ClockPort } from "../core/ports.js";
2
+ import { type ActorIdentityInput, type ActorPrincipalKind, type ContentTypeFieldDef, type ContentTypeRecord, type Result } from "./types.js";
3
+ /**
4
+ * @file Write-service — `registerContentType`/`updateContentTypeFields`, the single write
5
+ * chokepoint for the `content_types` registry.
6
+ *
7
+ * Purpose:
8
+ * The ONLY path that creates or full-replaces a content type's field schema. Every export here:
9
+ * `authorize()` first (fail-closed) -> the fixed definition-time guard sequence (CIC U-002-B1) ->
10
+ * same-transaction row + revision write (+ watermark stamp when supplied) -> index provisioning.
11
+ *
12
+ * `registerContentType`'s CIC U-002-B1 guard order is binding, not incidental: key grammar ->
13
+ * reserved-key -> field-name grammar -> field-kind -> queryable-cap, evaluation stops at the
14
+ * first failure. `updateContentTypeFields`'s CIC U-004-B1 additionally requires `expectedVersion`
15
+ * to be checked BEFORE the `fields_empty` floor and before any per-field guard, so a stale
16
+ * `expectedVersion` combined with `fields: []` reports `VERSION_CONFLICT`, never
17
+ * `VALIDATION_ERROR(fields_empty)`.
18
+ *
19
+ * How it relates to the project:
20
+ * `deps.watermark` (REQ-01/INV-08) and the actor-identity delegation fields
21
+ * (`delegatedByWorkspaceId`/`delegatedById`, REQ-16) are both optional/additive — every
22
+ * pre-existing call site that omits them is unaffected; `watermark-stamping.integration.test.ts`
23
+ * exercises both.
24
+ *
25
+ * Architectural role:
26
+ * `features/content-types` domain logic. Depends only on `core/ports` and this package's own
27
+ * `errors.ts`/`index-provisioning.ts`/`types.ts` — no adapter, no other feature.
28
+ */
29
+ /** Matches every other feature's chokepoint `AuthorizeFn` shape structurally — no shared import, kept decoupled. */
30
+ export type AuthorizeFn = (params: {
31
+ principalId: string;
32
+ permission: string;
33
+ workspaceId: string;
34
+ }) => Promise<{
35
+ allowed: boolean;
36
+ reason: string;
37
+ }>;
38
+ export interface ContentTypeRevisionInput {
39
+ contentTypeKey: string;
40
+ workspaceId: string;
41
+ op: "register" | "field-change";
42
+ stateJson: ContentTypeRecord;
43
+ actorId: string;
44
+ /**
45
+ * Audit provenance — the actor CLASS behind `actorId` (`'user'` for a human admin request,
46
+ * `'agent'` for a write made through the assistant's tool surface, `'system'` for an internal
47
+ * boot-time registration). `null` when the caller did not supply one; see
48
+ * `ActorIdentityInput.principalKind` for why `actorId` alone cannot answer the audit question.
49
+ */
50
+ principalKind: ActorPrincipalKind | null;
51
+ delegatedByWorkspaceId: string | null;
52
+ delegatedById: string | null;
53
+ recordedAt: string;
54
+ }
55
+ export interface ContentTypeRepoPort {
56
+ save(row: ContentTypeRecord): Promise<void>;
57
+ appendRevision(revision: ContentTypeRevisionInput): Promise<void>;
58
+ findByKey(params: {
59
+ workspaceId: string;
60
+ key: string;
61
+ }): Promise<ContentTypeRecord | null>;
62
+ transaction<T>(fn: () => Promise<T>): Promise<T>;
63
+ }
64
+ export interface IndexProvisionerPort {
65
+ provisionIndexesForNewContentType(input: {
66
+ workspaceId: string;
67
+ contentTypeKey: string;
68
+ fields: ContentTypeFieldDef[];
69
+ }): Promise<void>;
70
+ applyFieldIndexTransitions(input: {
71
+ workspaceId: string;
72
+ contentTypeKey: string;
73
+ transitions: Array<{
74
+ fieldName: string;
75
+ action: "provision" | "teardown" | "reprovision";
76
+ }>;
77
+ }): Promise<void>;
78
+ }
79
+ export interface OutboxPort {
80
+ enqueue(event: {
81
+ name: string;
82
+ payload: Record<string, unknown>;
83
+ }): Promise<void>;
84
+ }
85
+ /** Optional (REQ-01/INV-08) — advances `database_write_watermark` by exactly 1 when supplied. */
86
+ export interface WatermarkPort {
87
+ stampWatermark(input: {
88
+ workspaceId: string;
89
+ }): Promise<number>;
90
+ }
91
+ export interface ContentTypeWriteServiceDeps {
92
+ repo: ContentTypeRepoPort;
93
+ clock: ClockPort;
94
+ ids: {
95
+ newId: () => string;
96
+ };
97
+ authorize: AuthorizeFn;
98
+ indexProvisioner: IndexProvisionerPort;
99
+ outbox: OutboxPort;
100
+ watermark?: WatermarkPort;
101
+ }
102
+ export interface RegisterContentTypeRequired {
103
+ deps: ContentTypeWriteServiceDeps;
104
+ input: ActorIdentityInput & {
105
+ workspaceId: string;
106
+ key: string;
107
+ label: string;
108
+ fields: ContentTypeFieldDef[];
109
+ };
110
+ }
111
+ /**
112
+ * REQ-01..08 — registers a new content type. Guard order is CIC U-002-B1, fixed and stop-at-first-
113
+ * failure: key grammar -> reserved-key -> field-name grammar -> field-kind -> queryable-cap.
114
+ *
115
+ * @complexity O(f) in the number of submitted fields (two guard passes over `fields`).
116
+ * @overallScore 100
117
+ */
118
+ export declare function registerContentType(required: RegisterContentTypeRequired): Promise<Result<{
119
+ contentType: ContentTypeRecord;
120
+ }, Error>>;
121
+ export interface UpdateContentTypeFieldsRequired {
122
+ deps: ContentTypeWriteServiceDeps;
123
+ input: ActorIdentityInput & {
124
+ workspaceId: string;
125
+ key: string;
126
+ fields: ContentTypeFieldDef[];
127
+ expectedVersion: number;
128
+ };
129
+ }
130
+ /**
131
+ * REQ-26 — full-replace of a content type's field schema. CIC U-004-B1: `expectedVersion` is
132
+ * checked BEFORE the `fields_empty` floor and before any per-field guard, so a stale version
133
+ * combined with an empty array reports `VERSION_CONFLICT`, never `VALIDATION_ERROR`.
134
+ *
135
+ * @complexity O(f) in the number of submitted fields.
136
+ * @overallScore 100
137
+ */
138
+ export declare function updateContentTypeFields(required: UpdateContentTypeFieldsRequired): Promise<Result<{
139
+ contentType: ContentTypeRecord;
140
+ }, Error>>;
141
+ //# sourceMappingURL=write-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-service.d.ts","sourceRoot":"","sources":["../../src/content-types/write-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ import { ContentTypeNotFoundError, ForbiddenError, InvalidFieldKindError, InvalidFieldNameGrammarError, InvalidKeyGrammarError, QueryableFieldCapExceededError, ReservedContentTypeKeyError, ValidationError, VersionConflictError, } from "./errors.js";
2
+ import { resolveFieldIndexTransition, validateIdentifierGrammar } from "./index-provisioning.js";
3
+ import { isContentTypeFieldKind, } from "./types.js";
4
+ /** Reserved forever for the legacy `posts` table — an operator Collection can never take these keys. */
5
+ const RESERVED_CONTENT_TYPE_KEYS = new Set(["post", "page"]);
6
+ /** Per-type cap on `queryable` fields (queryable-index sprawl mitigation). */
7
+ const QUERYABLE_FIELD_CAP = 20;
8
+ function countQueryableFields(fields) {
9
+ return fields.filter((f) => f.queryable).length;
10
+ }
11
+ /**
12
+ * REQ-01..08 — registers a new content type. Guard order is CIC U-002-B1, fixed and stop-at-first-
13
+ * failure: key grammar -> reserved-key -> field-name grammar -> field-kind -> queryable-cap.
14
+ *
15
+ * @complexity O(f) in the number of submitted fields (two guard passes over `fields`).
16
+ * @overallScore 100
17
+ */
18
+ export async function registerContentType(required) {
19
+ const { deps, input } = required;
20
+ const authResult = await deps.authorize({
21
+ principalId: input.actorId,
22
+ permission: "admin.collections.manage",
23
+ workspaceId: input.workspaceId,
24
+ });
25
+ if (!authResult.allowed) {
26
+ return { ok: false, error: new ForbiddenError(`principal '${input.actorId}' cannot register a content type (${authResult.reason})`) };
27
+ }
28
+ // Guard 1: key grammar.
29
+ if (!validateIdentifierGrammar(input.key)) {
30
+ return { ok: false, error: new InvalidKeyGrammarError(`content-type key '${input.key}' fails the identifier grammar gate ^[a-z][a-z0-9_]{0,63}$`) };
31
+ }
32
+ // Guard 2: reserved key.
33
+ if (RESERVED_CONTENT_TYPE_KEYS.has(input.key)) {
34
+ return { ok: false, error: new ReservedContentTypeKeyError(`key '${input.key}' is permanently reserved for the legacy 'posts' table`) };
35
+ }
36
+ // Guard 3: field-name grammar (every field, before any kind/cap check).
37
+ for (const field of input.fields) {
38
+ if (!validateIdentifierGrammar(field.name)) {
39
+ return { ok: false, error: new InvalidFieldNameGrammarError(`field name '${field.name}' fails the identifier grammar gate`) };
40
+ }
41
+ }
42
+ // Guard 4: field-kind, closed enum.
43
+ for (const field of input.fields) {
44
+ if (!isContentTypeFieldKind(field.kind)) {
45
+ return { ok: false, error: new InvalidFieldKindError(`field '${field.name}' has kind '${field.kind}', not one of the closed field-kind enum`) };
46
+ }
47
+ }
48
+ // Guard 5: queryable-field cap, submitted array alone.
49
+ if (countQueryableFields(input.fields) > QUERYABLE_FIELD_CAP) {
50
+ return { ok: false, error: new QueryableFieldCapExceededError(`content type '${input.key}' submits more than ${QUERYABLE_FIELD_CAP} queryable fields`) };
51
+ }
52
+ const now = deps.clock.nowIso();
53
+ const contentType = {
54
+ workspaceId: input.workspaceId,
55
+ key: input.key,
56
+ label: input.label,
57
+ fields: input.fields,
58
+ status: "active",
59
+ version: 1,
60
+ tombstonedAt: null,
61
+ };
62
+ await deps.repo.transaction(async () => {
63
+ await deps.repo.save(contentType);
64
+ await deps.repo.appendRevision({
65
+ contentTypeKey: input.key,
66
+ workspaceId: input.workspaceId,
67
+ op: "register",
68
+ stateJson: contentType,
69
+ actorId: input.actorId,
70
+ principalKind: input.principalKind ?? null,
71
+ delegatedByWorkspaceId: input.delegatedByWorkspaceId ?? null,
72
+ delegatedById: input.delegatedById ?? null,
73
+ recordedAt: now,
74
+ });
75
+ if (deps.watermark)
76
+ await deps.watermark.stampWatermark({ workspaceId: input.workspaceId });
77
+ });
78
+ await deps.indexProvisioner.provisionIndexesForNewContentType({
79
+ workspaceId: input.workspaceId,
80
+ contentTypeKey: input.key,
81
+ fields: input.fields,
82
+ });
83
+ return { ok: true, value: { contentType } };
84
+ }
85
+ /**
86
+ * REQ-26 — full-replace of a content type's field schema. CIC U-004-B1: `expectedVersion` is
87
+ * checked BEFORE the `fields_empty` floor and before any per-field guard, so a stale version
88
+ * combined with an empty array reports `VERSION_CONFLICT`, never `VALIDATION_ERROR`.
89
+ *
90
+ * @complexity O(f) in the number of submitted fields.
91
+ * @overallScore 100
92
+ */
93
+ export async function updateContentTypeFields(required) {
94
+ const { deps, input } = required;
95
+ const authResult = await deps.authorize({
96
+ principalId: input.actorId,
97
+ permission: "admin.collections.manage",
98
+ workspaceId: input.workspaceId,
99
+ });
100
+ if (!authResult.allowed) {
101
+ return { ok: false, error: new ForbiddenError(`principal '${input.actorId}' cannot update content type '${input.key}' (${authResult.reason})`) };
102
+ }
103
+ const current = await deps.repo.findByKey({ workspaceId: input.workspaceId, key: input.key });
104
+ if (!current) {
105
+ return { ok: false, error: new ContentTypeNotFoundError(`content type '${input.key}' was not found in workspace '${input.workspaceId}'`) };
106
+ }
107
+ // U-004-B1: expectedVersion checked FIRST — before fields_empty, before any per-field guard.
108
+ if (input.expectedVersion !== current.version) {
109
+ return { ok: false, error: new VersionConflictError(`expected version ${input.expectedVersion} for content type '${input.key}', found ${current.version}`) };
110
+ }
111
+ if (input.fields.length === 0) {
112
+ return { ok: false, error: new ValidationError(`content type '${input.key}' update submitted an empty fields array`, "fields_empty") };
113
+ }
114
+ for (const field of input.fields) {
115
+ if (!validateIdentifierGrammar(field.name)) {
116
+ return { ok: false, error: new InvalidFieldNameGrammarError(`field name '${field.name}' fails the identifier grammar gate`) };
117
+ }
118
+ }
119
+ for (const field of input.fields) {
120
+ if (!isContentTypeFieldKind(field.kind)) {
121
+ return { ok: false, error: new InvalidFieldKindError(`field '${field.name}' has kind '${field.kind}', not one of the closed field-kind enum`) };
122
+ }
123
+ }
124
+ if (countQueryableFields(input.fields) > QUERYABLE_FIELD_CAP) {
125
+ return { ok: false, error: new QueryableFieldCapExceededError(`content type '${input.key}' submits more than ${QUERYABLE_FIELD_CAP} queryable fields`) };
126
+ }
127
+ const before = current.fields;
128
+ const after = input.fields;
129
+ const now = deps.clock.nowIso();
130
+ const updated = { ...current, fields: after, version: current.version + 1 };
131
+ await deps.repo.transaction(async () => {
132
+ await deps.repo.save(updated);
133
+ await deps.repo.appendRevision({
134
+ contentTypeKey: input.key,
135
+ workspaceId: input.workspaceId,
136
+ op: "field-change",
137
+ stateJson: updated,
138
+ actorId: input.actorId,
139
+ principalKind: input.principalKind ?? null,
140
+ delegatedByWorkspaceId: input.delegatedByWorkspaceId ?? null,
141
+ delegatedById: input.delegatedById ?? null,
142
+ recordedAt: now,
143
+ });
144
+ if (deps.watermark)
145
+ await deps.watermark.stampWatermark({ workspaceId: input.workspaceId });
146
+ });
147
+ await deps.indexProvisioner.applyFieldIndexTransitions({
148
+ workspaceId: input.workspaceId,
149
+ contentTypeKey: input.key,
150
+ transitions: computeFullReplaceTransitions(before, after),
151
+ });
152
+ return { ok: true, value: { contentType: updated } };
153
+ }
154
+ /**
155
+ * CIC U-003-B1 composition — resolves an index transition for every field name present on either
156
+ * side of a full-replace update (union of before/after names), one before/after comparison per
157
+ * name, and returns only the actionable (non-`"none"`) transitions.
158
+ *
159
+ * @complexity O(f) in the number of distinct field names across both arrays.
160
+ * @overallScore 100
161
+ */
162
+ function computeFullReplaceTransitions(before, after) {
163
+ const beforeByName = new Map(before.map((f) => [f.name, f]));
164
+ const afterByName = new Map(after.map((f) => [f.name, f]));
165
+ const allNames = new Set([...beforeByName.keys(), ...afterByName.keys()]);
166
+ const transitions = [];
167
+ for (const name of allNames) {
168
+ const b = beforeByName.get(name);
169
+ const a = afterByName.get(name);
170
+ const transition = resolveFieldIndexTransition({
171
+ before: b ? { kind: b.kind, queryable: b.queryable } : undefined,
172
+ after: a ? { kind: a.kind, queryable: a.queryable } : undefined,
173
+ });
174
+ if (transition.action !== "none") {
175
+ transitions.push({ fieldName: name, action: transition.action });
176
+ }
177
+ }
178
+ return transitions;
179
+ }
180
+ //# sourceMappingURL=write-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-service.js","sourceRoot":"","sources":["../../src/content-types/write-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import type { DomainEvent, ISODateTime, JsonObject, UUID } from "../ports.js";
2
+ /**
3
+ * @file Change-set vocabulary and persistence contract.
4
+ *
5
+ * Purpose:
6
+ * Defines the durable rows that make every mutation auditable and revertible,
7
+ * for human and AI actors alike.
8
+ *
9
+ * How it relates to the project:
10
+ * - `command.ts` records one change set per executed command.
11
+ * - `revert.ts` walks items in reverse to undo an applied change set.
12
+ * - `repo.memory.ts` provides the in-memory adapter for local dev/tests.
13
+ *
14
+ * Architectural role:
15
+ * This is the storage shape required to land with the first persistent
16
+ * schema. SQLite/Postgres adapters must satisfy `ChangeSetRepoPort` unchanged.
17
+ *
18
+ * `insert()`'s optional third argument lets the caller pass the fully-formed outbox event through
19
+ * the SAME call, so a durable adapter can co-persist it inside the same transaction as the header
20
+ * + items. This does NOT bring the domain write (`mutation.execute()`) into the transaction — that
21
+ * remains covered by `executeCommand()`'s existing compensating-rollback path. See
22
+ * `docs/decisions/change-set-outbox-transaction-boundary.md` for the full rationale, including why
23
+ * this shape was chosen over threading a transaction handle through `OutboxPort`/`mutation.execute()`.
24
+ */
25
+ export type ChangeSetStatus = "proposed" | "applied" | "reverted" | "discarded";
26
+ export type ChangeSetOperation = "create" | "update" | "delete" | "activate";
27
+ /** Durable header row for one reviewable, revertible unit of change. */
28
+ export interface ChangeSetRecord {
29
+ id: UUID;
30
+ workspaceId: UUID;
31
+ /** Principal (user or agent) that caused the change. */
32
+ actorId?: UUID;
33
+ status: ChangeSetStatus;
34
+ /** Human-readable description shown in audit/review UIs. */
35
+ summary: string;
36
+ /** Client-supplied key that makes retried commands safe to reject. */
37
+ idempotencyKey?: string | undefined;
38
+ /** Link back to the chat message / plan step that motivated the change. */
39
+ intentRef?: string | undefined;
40
+ createdAt: ISODateTime;
41
+ appliedAt?: ISODateTime;
42
+ revertedAt?: ISODateTime;
43
+ }
44
+ /** One entity mutation inside a change set. */
45
+ export interface ChangeSetItemRecord {
46
+ id: UUID;
47
+ changeSetId: UUID;
48
+ /** Entity type key used to resolve an inverse applier, e.g. `post`. */
49
+ entityType: string;
50
+ entityId: UUID;
51
+ operation: ChangeSetOperation;
52
+ /** Revision pointers for revisioned entity types. */
53
+ beforeRevisionId?: UUID | undefined;
54
+ afterRevisionId?: UUID | undefined;
55
+ /**
56
+ * Inline inverse for non-revisioned entities. An item with neither revision
57
+ * pointers nor an inverse payload cannot be reverted — and such
58
+ * entities must not be mutated by agents.
59
+ */
60
+ inversePayload?: JsonObject | undefined;
61
+ /**
62
+ * Entity version *after* the mutation (REQ-08 guard input). Revert refuses
63
+ * unless the entity's current version still equals this — otherwise the entity
64
+ * has moved on since. Undefined for entity types without a version.
65
+ */
66
+ entityVersionAtApply?: number | undefined;
67
+ /** Apply order; revert walks positions in reverse. */
68
+ position: number;
69
+ }
70
+ /** Change set header plus its ordered items. */
71
+ export interface ChangeSetWithItems {
72
+ changeSet: ChangeSetRecord;
73
+ items: ChangeSetItemRecord[];
74
+ }
75
+ /** Persistence contract for change sets. */
76
+ export interface ChangeSetRepoPort {
77
+ /**
78
+ * `event`, when present, must be durably recorded atomically with `record`/`items` (BR-04 —
79
+ * see this file's header). A SQLite adapter co-persists it inside the same transaction; the
80
+ * in-memory adapter forwards it to its injected event bus/outbox. Omit `event` for a change set
81
+ * that has no associated domain event to deliver.
82
+ */
83
+ insert(record: ChangeSetRecord, items: ChangeSetItemRecord[], event?: DomainEvent): Promise<void>;
84
+ findById(required: {
85
+ workspaceId: UUID;
86
+ id: UUID;
87
+ }): Promise<ChangeSetWithItems | null>;
88
+ findByIdempotencyKey(required: {
89
+ workspaceId: UUID;
90
+ idempotencyKey: string;
91
+ }): Promise<ChangeSetRecord | null>;
92
+ listByWorkspace(required: {
93
+ workspaceId: UUID;
94
+ }): Promise<ChangeSetRecord[]>;
95
+ /** Persist status transitions (applied -> reverted, proposed -> discarded, …). */
96
+ save(record: ChangeSetRecord): Promise<void>;
97
+ }
98
+ //# sourceMappingURL=change-set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-set.d.ts","sourceRoot":"","sources":["../../../src/core/commands/change-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE7E,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,IAAI,CAAC;IAClB,wDAAwD;IACxD,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,eAAe,CAAC;IACxB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,IAAI,CAAC;IAClB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,kBAAkB,CAAC;IAC9B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACpC,eAAe,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACnC;;;;OAIG;IACH,cAAc,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,QAAQ,CAAC,QAAQ,EAAE;QAAE,WAAW,EAAE,IAAI,CAAC;QAAC,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACxF,oBAAoB,CAAC,QAAQ,EAAE;QAC7B,WAAW,EAAE,IAAI,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACpC,eAAe,CAAC,QAAQ,EAAE;QAAE,WAAW,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7E,kFAAkF;IAClF,IAAI,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=change-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-set.js","sourceRoot":"","sources":["../../../src/core/commands/change-set.ts"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ import type { ClockPort, IdGeneratorPort, JsonObject, OutboxPort, UUID } from "../ports.js";
2
+ import type { ChangeSetOperation, ChangeSetRepoPort } from "./change-set.js";
3
+ /**
4
+ * @file The single mutation write path.
5
+ *
6
+ * Purpose:
7
+ * Every admin mutation — human save or AI tool call — runs through
8
+ * `executeCommand`, which captures the inverse, executes the feature call, and
9
+ * records an auto-applied single-item change set. Audit trail by construction.
10
+ *
11
+ * How it relates to the project:
12
+ * - Wraps `features/*` mutation functions; never contains domain logic itself.
13
+ * - Persists via `ChangeSetRepoPort`; announces via the outbox when provided.
14
+ * - `revert.ts` consumes the recorded inverse payloads to undo change sets.
15
+ *
16
+ * Architectural role:
17
+ * The gate that makes "auditable and undoable" a property of the system rather
18
+ * than a per-feature effort. Proposed (unapplied) multi-item change sets for
19
+ * agent plans build on this same envelope later.
20
+ */
21
+ /** Principal executing a command. Agents act on behalf of a user. */
22
+ export interface CommandActor {
23
+ id: UUID;
24
+ kind: "user" | "agent";
25
+ /** User the agent is acting for; unset for direct human commands. */
26
+ onBehalfOfId?: UUID | undefined;
27
+ }
28
+ /** Cross-cutting command metadata; the mutation itself lives in `CommandMutation`. */
29
+ export interface CommandEnvelope {
30
+ workspaceId: UUID;
31
+ actor: CommandActor;
32
+ /** Human-readable description recorded on the change set. */
33
+ summary: string;
34
+ /** Supplied by retry-capable callers (agents must always send one). */
35
+ idempotencyKey?: string | undefined;
36
+ /** Chat message / plan step that motivated this command. */
37
+ intentRef?: string | undefined;
38
+ /**
39
+ * The permission this mutation requires, e.g.
40
+ * `"content.write"`. Must be supplied together with `ExecuteCommandDeps.authorize`
41
+ * — see that field's doc for the migration story. Optional only so gateway
42
+ * callers not yet migrated to real identity/authorize wiring keep compiling.
43
+ */
44
+ permission?: string | undefined;
45
+ }
46
+ /** The entity write a command performs, with its inverse capture. */
47
+ export interface CommandMutation<TResult> {
48
+ entityType: string;
49
+ entityId: UUID;
50
+ operation: ChangeSetOperation;
51
+ /**
52
+ * Snapshot whatever is needed to undo this mutation, read *before* execute.
53
+ * Return null when no inverse exists — the change set is then recorded but
54
+ * cannot be reverted (and agents must not be offered this mutation).
55
+ */
56
+ captureInverse(): Promise<JsonObject | null>;
57
+ /** The actual feature call. Runs only after inverse capture succeeds. */
58
+ execute(): Promise<TResult>;
59
+ /**
60
+ * Read the entity's version from the execute result (the version *after* the
61
+ * mutation, REQ-08 / AC-02). Stamped onto the item as the revert guard input.
62
+ * Omit for entity types without a version.
63
+ */
64
+ captureEntityVersion?(result: TResult): number | null;
65
+ /**
66
+ * Compensating rollback for the memory adapter's all-or-nothing guarantee
67
+ * (REQ-01 / BR-04 / EC-08 / AC-17). If the change-set record fails to persist
68
+ * *after* `execute()` has applied the feature mutation, the gateway calls this
69
+ * to undo the mutation — restoring the entity to its exact pre-`execute` state
70
+ * (verbatim, including `version`) so no "mutation without a record" survives
71
+ * (INV-01). On the SQLite adapter (RT-004) a real transaction replaces this and
72
+ * `rollback` becomes a no-op/omitted. Omit only for a mutation whose record step
73
+ * cannot fail independently of its feature write (none in v1).
74
+ */
75
+ rollback?(): Promise<void>;
76
+ }
77
+ /**
78
+ * The shape of the `authorize()` gate, kept generic here so
79
+ * `core/commands` never imports the `identity` library (that would invert the
80
+ * dependency direction — `features`/libraries depend on `core`, not the
81
+ * reverse; see `identity/authorize.ts`'s file header). Composition roots
82
+ * (`server/app.ts` / `server/deps.ts`) bind a closure over the real
83
+ * `identity.authorize()` and its repos, and pass that closure as
84
+ * `ExecuteCommandDeps.authorize`.
85
+ */
86
+ export type AuthorizeFn = (params: {
87
+ principalId: UUID;
88
+ permission: string;
89
+ workspaceId: UUID;
90
+ entityType?: string | undefined;
91
+ entityId?: UUID | undefined;
92
+ }) => Promise<{
93
+ allowed: boolean;
94
+ reason: string;
95
+ }>;
96
+ /** Dependencies for executeCommand. */
97
+ export interface ExecuteCommandDeps {
98
+ clock: ClockPort;
99
+ idGen: IdGeneratorPort;
100
+ changeSets: ChangeSetRepoPort;
101
+ /** When provided, `change-set.applied` is enqueued for async consumers. */
102
+ outbox?: OutboxPort | undefined;
103
+ /**
104
+ * Authorization gate. Must be supplied together with
105
+ * `CommandEnvelope.permission` — omitting one while supplying the other is a
106
+ * wiring bug (see `executeCommand`'s guard) rather than something that
107
+ * should silently allow or silently skip. Omitting BOTH is the legacy
108
+ * pre-identity path, kept so gateway callers not yet migrated to real
109
+ * identity/authorize wiring keep compiling and passing (see the Programmer
110
+ * handoff for which routes remain unconverted this pass).
111
+ */
112
+ authorize?: AuthorizeFn | undefined;
113
+ }
114
+ /** Required parameters for executeCommand. */
115
+ export interface ExecuteCommandRequired<TResult> {
116
+ deps: ExecuteCommandDeps;
117
+ command: CommandEnvelope;
118
+ mutation: CommandMutation<TResult>;
119
+ }
120
+ /** Optional parameters for executeCommand. Reserved for future use. */
121
+ export interface ExecuteCommandOptional {
122
+ }
123
+ /**
124
+ * Thrown when a command's idempotency key was already used in the workspace.
125
+ * Callers should re-read current state instead of retrying the mutation.
126
+ */
127
+ export declare class DuplicateCommandError extends Error {
128
+ readonly changeSetId: UUID;
129
+ constructor(message: string, changeSetId: UUID);
130
+ }
131
+ /**
132
+ * Thrown when `authorize()` denies the caller. Routes map
133
+ * this to 403 `FORBIDDEN`. Raised before the idempotency check (INV-04) — a
134
+ * replayed command id from a denied caller therefore never produces
135
+ * `DuplicateCommandError` either (EC-08).
136
+ */
137
+ export declare class ForbiddenError extends Error {
138
+ readonly permission: string;
139
+ readonly reason: string;
140
+ constructor(message: string, permission: string, reason: string);
141
+ }
142
+ /**
143
+ * Execute a mutation through the command gateway.
144
+ *
145
+ * Order matters: idempotency check → inverse capture → execute → record.
146
+ * If execute throws, nothing is recorded; if inverse capture throws, the
147
+ * mutation never runs.
148
+ *
149
+ * The feature mutation and its change-set record commit as one unit of work
150
+ * (REQ-01): if `changeSets.insert` fails after `execute` has applied the
151
+ * mutation, the gateway rolls the mutation back via `mutation.rollback` and
152
+ * re-throws, so no change set and no outbox event survive (EC-08 / AC-17,
153
+ * INV-01).
154
+ *
155
+ * The `change-set.applied` event is passed as `changeSets.insert()`'s third argument, not a
156
+ * separate `deps.outbox.enqueue()` call afterward — a durable adapter co-persists it inside the
157
+ * same transaction as the change-set record, so it can never land without a durable delivery
158
+ * record (or vice versa). This still does NOT cover the domain mutation itself
159
+ * (`mutation.execute()` stays outside any shared transaction, covered only by the compensating
160
+ * rollback above), and it covers only this producer. See
161
+ * `docs/decisions/change-set-outbox-transaction-boundary.md` for the full rationale, including the
162
+ * other direct `OutboxPort.enqueue()` producers this decision deliberately leaves untouched.
163
+ */
164
+ export declare function executeCommand<TResult>(required: ExecuteCommandRequired<TResult>, _optional?: ExecuteCommandOptional): Promise<{
165
+ result: TResult;
166
+ changeSetId: UUID;
167
+ }>;
168
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/core/commands/command.ts"],"names":[],"mappings":"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"}