@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,350 @@
1
+ import { ForbiddenError } from "../core/commands/command.js";
2
+ import { validateContentJoin, validateHierarchyAssignment } from "./validation-chain.js";
3
+ /** The hardcoded post/page taxonomy allow-list (permanent, see
4
+ * `docs/decisions/taxonomy-content-type-allow-list.md`) — every taxonomy is applicable to
5
+ * `post`/`page` content; no other content type is eligible for term assignment until this is
6
+ * deliberately extended. */
7
+ export const TAXONOMY_ALLOWED_CONTENT_TYPES = new Set(["post", "page"]);
8
+ export function isContentTypeOnAllowList(contentType) {
9
+ return TAXONOMY_ALLOWED_CONTENT_TYPES.has(contentType);
10
+ }
11
+ export class TaxonomyRecordNotFoundError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "TaxonomyRecordNotFoundError";
15
+ }
16
+ }
17
+ export class TermRecordNotFoundError extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "TermRecordNotFoundError";
21
+ }
22
+ }
23
+ /** Finding 1 fix — the target of an `assignTerms` call does not resolve to any real content row. */
24
+ export class ContentRecordNotFoundError extends Error {
25
+ constructor(message) {
26
+ super(message);
27
+ this.name = "ContentRecordNotFoundError";
28
+ }
29
+ }
30
+ /** `admin.taxonomy.manage` (the flat-string permission convention) — must run before any other
31
+ * side effect of every write-service export in this file. */
32
+ async function authorizeTaxonomyManage(deps, principalId) {
33
+ const result = await deps.authorize({ principalId, permission: "admin.taxonomy.manage" });
34
+ if (!result.allowed) {
35
+ throw new ForbiddenError(`principal '${principalId}' is not authorized for 'admin.taxonomy.manage' (${result.reason})`, "admin.taxonomy.manage", result.reason);
36
+ }
37
+ }
38
+ /** Creates a taxonomy row (hierarchical=true -> "category"-shaped, false -> "tag"-shaped — same
39
+ * shared table). Ordinary mutation, no plan()/confirmation ceremony. */
40
+ export async function createTaxonomy(required, _optional = {}) {
41
+ const { deps, principalId, name, hierarchical } = required;
42
+ await authorizeTaxonomyManage(deps, principalId);
43
+ const now = deps.clock.nowIso();
44
+ const taxonomy = {
45
+ id: deps.idGen.newId(),
46
+ name,
47
+ hierarchical,
48
+ status: "active",
49
+ updatedAt: now,
50
+ version: 1,
51
+ };
52
+ await deps.taxonomies.insert(taxonomy);
53
+ await deps.revisions.insert({
54
+ taxonomyId: taxonomy.id,
55
+ op: "create",
56
+ previousState: null,
57
+ actorId: principalId,
58
+ recordedAt: now,
59
+ });
60
+ deps.stampWatermark();
61
+ await deps.outbox.enqueue({ name: "taxonomy.created", taxonomyId: taxonomy.id, actorId: principalId, occurredAt: now });
62
+ return taxonomy;
63
+ }
64
+ /** AC-03/AC-13/EC-04 — validates `parentId` via `validateHierarchyAssignment` before writing. A
65
+ * freshly-created term has no descendants yet, so it structurally cannot be a cycle source; the
66
+ * cycle check is therefore always a no-op (`() => false`) here, unlike a reparent of an existing
67
+ * term (not yet built — no certified test in this slice exercises it). */
68
+ export async function createTerm(required, _optional = {}) {
69
+ const { deps, principalId, taxonomyId, name, parentId } = required;
70
+ await authorizeTaxonomyManage(deps, principalId);
71
+ const taxonomy = await deps.taxonomies.findById(taxonomyId);
72
+ if (!taxonomy) {
73
+ throw new TaxonomyRecordNotFoundError(`taxonomy '${taxonomyId}' was not found`);
74
+ }
75
+ const candidateParentId = parentId ?? null;
76
+ let resolvedParent = "not-applicable";
77
+ if (candidateParentId !== null) {
78
+ const parentTerm = await deps.terms.findById(candidateParentId);
79
+ resolvedParent = parentTerm ? { id: parentTerm.id, taxonomyId: parentTerm.taxonomyId } : null;
80
+ }
81
+ validateHierarchyAssignment({
82
+ childTaxonomyId: taxonomyId,
83
+ taxonomyIsHierarchical: taxonomy.hierarchical,
84
+ candidateParentId,
85
+ resolvedParent,
86
+ wouldCreateCycle: () => false,
87
+ termId: "__new__",
88
+ });
89
+ const now = deps.clock.nowIso();
90
+ const term = {
91
+ id: deps.idGen.newId(),
92
+ taxonomyId,
93
+ parentId: candidateParentId,
94
+ name,
95
+ status: "active",
96
+ updatedAt: now,
97
+ version: 1,
98
+ };
99
+ await deps.terms.insert(term);
100
+ await deps.revisions.insert({ taxonomyId, op: "create", previousState: null, actorId: principalId, recordedAt: now });
101
+ deps.stampWatermark();
102
+ await deps.outbox.enqueue({ name: "taxonomy.term_created", termId: term.id, actorId: principalId, occurredAt: now });
103
+ return term;
104
+ }
105
+ /** AC-15/AC-19/AC-25/REQ-12/REQ-17 — same-tx rename + revision (carrying the pre-rename state) +
106
+ * watermark + outbox. `authorize()` runs before the term lookup, so a denied caller produces zero
107
+ * side effects of any kind. */
108
+ export async function renameTerm(required, _optional = {}) {
109
+ const { deps, principalId, termId, newName } = required;
110
+ await authorizeTaxonomyManage(deps, principalId);
111
+ const current = await deps.terms.findById(termId);
112
+ if (!current) {
113
+ throw new TermRecordNotFoundError(`term '${termId}' was not found`);
114
+ }
115
+ const now = deps.clock.nowIso();
116
+ const updated = {
117
+ id: current.id,
118
+ taxonomyId: current.taxonomyId,
119
+ parentId: current.parentId ?? null,
120
+ name: newName,
121
+ status: current.status ?? "active",
122
+ updatedAt: now,
123
+ version: (current.version ?? 1) + 1,
124
+ };
125
+ await deps.terms.update(updated);
126
+ await deps.revisions.insert({
127
+ taxonomyId: current.taxonomyId,
128
+ op: "rename",
129
+ previousState: { name: current.name },
130
+ actorId: principalId,
131
+ recordedAt: now,
132
+ });
133
+ deps.stampWatermark();
134
+ await deps.outbox.enqueue({ name: "taxonomy.term_renamed", termId, actorId: principalId, occurredAt: now });
135
+ return updated;
136
+ }
137
+ /** AC-17/AC-20/INV-05/REQ-13/REQ-14 — upserts every `entry_terms` row (idempotent on-conflict per
138
+ * `entry_terms_unique`, EC-09), then stamps the watermark and enqueues the outbox event exactly
139
+ * ONCE per call regardless of `termIds.length` — never once per term. Never produces a
140
+ * `taxonomy_revisions` row (see this file's header for the disclosed narrowing this implements).
141
+ *
142
+ * Finding 1 fix (TM-adr041-043-044-045-audit-001): every `termId` is validated via
143
+ * `validateContentJoin` (allow-list -> workspace -> lens, `validation-chain.ts`'s fixed order)
144
+ * BEFORE any `entry_terms` row is written — every termId must resolve to a real term, and the
145
+ * target content must resolve to a real row whose kind matches the caller-supplied `contentType`.
146
+ * Validation runs for ALL termIds before ANY write, so a failure partway through never leaves a
147
+ * partial assignment. Content is resolved once per call (not once per term) since every term in
148
+ * one call shares the same `(contentType, contentId)` target.
149
+ */
150
+ export async function assignTerms(required, _optional = {}) {
151
+ const { deps, principalId, contentType, contentId, termIds } = required;
152
+ await authorizeTaxonomyManage(deps, principalId);
153
+ const isOnAllowList = isContentTypeOnAllowList(contentType);
154
+ const content = isOnAllowList ? await deps.contentLookup.resolve({ contentType, contentId }) : null;
155
+ if (isOnAllowList && !content) {
156
+ throw new ContentRecordNotFoundError(`content '${contentType}:${contentId}' was not found`);
157
+ }
158
+ for (const termId of termIds) {
159
+ const term = await deps.terms.findById(termId);
160
+ if (!term) {
161
+ throw new TermRecordNotFoundError(`term '${termId}' was not found`);
162
+ }
163
+ validateContentJoin({
164
+ taxonomyId: term.taxonomyId,
165
+ isOnAllowList,
166
+ callerWorkspaceId: deps.workspaceId,
167
+ // `SqliteTermRepo`/`SqliteEntryTermRepo` are workspace-BOUND at construction (single
168
+ // workspace per content.db) — a term/content row that resolves via those adapters at all
169
+ // is, by construction, already in the caller's own workspace. See this file's header.
170
+ resolvedTermWorkspaceId: deps.workspaceId,
171
+ resolvedContentWorkspaceId: content?.workspaceId ?? deps.workspaceId,
172
+ suppliedContentType: contentType,
173
+ resolvedContentKind: content?.kind ?? contentType,
174
+ });
175
+ }
176
+ const now = deps.clock.nowIso();
177
+ for (const termId of termIds) {
178
+ await deps.entryTerms.upsert({ contentType, contentId, termId, addedAt: now });
179
+ }
180
+ deps.stampWatermark();
181
+ await deps.outbox.enqueue({
182
+ name: "taxonomy.terms_assigned",
183
+ contentType,
184
+ contentId,
185
+ termIds,
186
+ actorId: principalId,
187
+ occurredAt: now,
188
+ });
189
+ }
190
+ /** Content-deletion event subscriber. Best-effort (a missed event leaves an orphaned
191
+ * `entry_terms` row that is inert on read; a periodic/boot reconciliation sweep — modeled by
192
+ * re-invoking this same function for the orphan — is the backstop, never a hard failure). A
193
+ * no-op for content with no
194
+ * assigned terms, never an error. */
195
+ export async function onContentDeleted(required, _optional = {}) {
196
+ const { event, entryTerms } = required;
197
+ await entryTerms.deleteByContent({
198
+ workspaceId: event.workspaceId,
199
+ contentType: event.contentType,
200
+ contentId: event.contentId,
201
+ });
202
+ }
203
+ /** `deleteTerm`/`deleteTaxonomy` refuse rather than silently orphan when content is still
204
+ * assigned. Carries `assignedCount` so a caller (route/UI) can render "N items are still
205
+ * assigned" instead of a generic failure. */
206
+ export class TermHasAssignedContentError extends Error {
207
+ assignedCount;
208
+ constructor(message, assignedCount) {
209
+ super(message);
210
+ this.assignedCount = assignedCount;
211
+ this.name = "TermHasAssignedContentError";
212
+ }
213
+ }
214
+ /** See `DeletableTermRepoPort.countChildren`'s doc comment for why this guard exists. Carries
215
+ * `childCount` for the same reason `TermHasAssignedContentError` carries `assignedCount`. */
216
+ export class TermHasChildTermsError extends Error {
217
+ childCount;
218
+ constructor(message, childCount) {
219
+ super(message);
220
+ this.childCount = childCount;
221
+ this.name = "TermHasChildTermsError";
222
+ }
223
+ }
224
+ /** `deleteTaxonomy`'s content-assignment guard — `assignedCount` is the sum across every member
225
+ * term, not a single term's count. */
226
+ export class TaxonomyHasAssignedContentError extends Error {
227
+ assignedCount;
228
+ constructor(message, assignedCount) {
229
+ super(message);
230
+ this.assignedCount = assignedCount;
231
+ this.name = "TaxonomyHasAssignedContentError";
232
+ }
233
+ }
234
+ /**
235
+ * Deletes a single term. Refuses (never cascades) when the term still has children or is still
236
+ * assigned to content — both checks run, and either alone is enough to block, before any write.
237
+ * An unassigned, childless term is destroying nothing recoverable, so this is a direct delete with
238
+ * no plan()/confirmation ceremony (`mergeTerm` earns that ceremony because it migrates data this
239
+ * does not).
240
+ *
241
+ * `authorize()` runs before the transaction opens (a pure permission check, no side effect, so it
242
+ * doesn't need transactional protection); everything from the existence check onward — both
243
+ * guards and the delete itself — runs inside `deps.transaction()` (see that port's doc comment for
244
+ * why). Does NOT cascade-delete the term's `taxonomy_revisions` rows: that table is an append-only
245
+ * audit trail (mirrors `redirect_hits`/`asset_renditions`'s disclosed audit-not-referential-
246
+ * integrity precedent), and erasing a term's history the moment the term itself is deleted would
247
+ * destroy the very "this term existed and was deleted" record this call's own revision insert
248
+ * below creates. Confirmed by grepping `db/schema.ts`: no other table has a `taxonomyId`/`termId`
249
+ * column, so `taxonomy_revisions` is the only thing this decision applies to.
250
+ *
251
+ * @complexity O(1) — one `countChildren` call, one `countByTerm` call, one delete, all inside one
252
+ * transaction.
253
+ * @overallScore 100
254
+ */
255
+ export async function deleteTerm(required, _optional = {}) {
256
+ const { deps, principalId, termId } = required;
257
+ await authorizeTaxonomyManage(deps, principalId);
258
+ return deps.transaction(async () => {
259
+ const current = await deps.terms.findById(termId);
260
+ if (!current) {
261
+ throw new TermRecordNotFoundError(`term '${termId}' was not found`);
262
+ }
263
+ const childCount = await deps.terms.countChildren({ parentId: termId });
264
+ if (childCount > 0) {
265
+ throw new TermHasChildTermsError(`term '${termId}' has ${childCount} child term(s) and cannot be deleted`, childCount);
266
+ }
267
+ const assignedCount = await deps.entryTerms.countByTerm({ termId });
268
+ if (assignedCount > 0) {
269
+ throw new TermHasAssignedContentError(`term '${termId}' is assigned to ${assignedCount} content item(s) and cannot be deleted`, assignedCount);
270
+ }
271
+ await deps.terms.delete(termId);
272
+ const now = deps.clock.nowIso();
273
+ await deps.revisions.insert({
274
+ taxonomyId: current.taxonomyId,
275
+ op: "delete",
276
+ previousState: { termId, name: current.name ?? null },
277
+ actorId: principalId,
278
+ recordedAt: now,
279
+ });
280
+ deps.stampWatermark();
281
+ await deps.outbox.enqueue({
282
+ name: "taxonomy.term_deleted",
283
+ termId,
284
+ taxonomyId: current.taxonomyId,
285
+ actorId: principalId,
286
+ occurredAt: now,
287
+ });
288
+ return { deletedTermId: termId };
289
+ });
290
+ }
291
+ /**
292
+ * Deletes a taxonomy together with its member terms, refusing when ANY member term is still
293
+ * assigned to content (the sum across all member terms, reported as one `assignedCount`). Unlike
294
+ * `deleteTerm`, this does cascade — but only over terms this same call has just confirmed, INSIDE
295
+ * the same transaction, are unassigned, so nothing recoverable is lost. `deleteTerm`'s own "has
296
+ * children" guard does not apply here: a member term's children are, by construction, also members
297
+ * of the same taxonomy (hierarchy never crosses taxonomies — `validateHierarchyAssignment`'s
298
+ * `ParentCrossTaxonomyError` enforces that on the write side), so deleting the full member set in
299
+ * one pass never leaves a `parentId` dangling outside the set being deleted.
300
+ *
301
+ * Same transaction-boundary and `taxonomy_revisions`-retention rationale as `deleteTerm` — see its
302
+ * doc comment. The taxonomy-level version of the same TOCTOU risk: `listByTaxonomy` and every
303
+ * per-term `countByTerm` call must see the SAME committed state the delete loop is about to act
304
+ * on, which is only guaranteed inside one transaction, not across N separate queries beforehand.
305
+ *
306
+ * @complexity O(t) in the taxonomy's own term count — one `countByTerm` per member term to total
307
+ * the guard, then one delete per member term plus one taxonomy delete, all inside one transaction.
308
+ * @overallScore 100
309
+ */
310
+ export async function deleteTaxonomy(required, _optional = {}) {
311
+ const { deps, principalId, taxonomyId } = required;
312
+ await authorizeTaxonomyManage(deps, principalId);
313
+ return deps.transaction(async () => {
314
+ const taxonomy = await deps.taxonomies.findById(taxonomyId);
315
+ if (!taxonomy) {
316
+ throw new TaxonomyRecordNotFoundError(`taxonomy '${taxonomyId}' was not found`);
317
+ }
318
+ const memberTerms = await deps.terms.listByTaxonomy({ taxonomyId });
319
+ let totalAssigned = 0;
320
+ for (const term of memberTerms) {
321
+ totalAssigned += await deps.entryTerms.countByTerm({ termId: term.id });
322
+ }
323
+ if (totalAssigned > 0) {
324
+ throw new TaxonomyHasAssignedContentError(`taxonomy '${taxonomyId}' has ${totalAssigned} content assignment(s) across its terms and cannot be deleted`, totalAssigned);
325
+ }
326
+ for (const term of memberTerms) {
327
+ await deps.terms.delete(term.id);
328
+ }
329
+ await deps.taxonomies.delete(taxonomyId);
330
+ const now = deps.clock.nowIso();
331
+ const deletedTermIds = memberTerms.map((term) => term.id);
332
+ await deps.revisions.insert({
333
+ taxonomyId,
334
+ op: "delete",
335
+ previousState: { deletedTermIds },
336
+ actorId: principalId,
337
+ recordedAt: now,
338
+ });
339
+ deps.stampWatermark();
340
+ await deps.outbox.enqueue({
341
+ name: "taxonomy.deleted",
342
+ taxonomyId,
343
+ deletedTermIds,
344
+ actorId: principalId,
345
+ occurredAt: now,
346
+ });
347
+ return { deletedTaxonomyId: taxonomyId, deletedTermIds };
348
+ });
349
+ }
350
+ //# sourceMappingURL=write-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-service.js","sourceRoot":"","sources":["../../src/taxonomy/write-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @file The Workspace domain's agent-tool catalog, instantiating this package's shared
3
+ * naming/callability convention (the same shape every other domain catalog in this package
4
+ * already uses).
5
+ *
6
+ * Purpose:
7
+ * A static, in-process catalog describing every agent-callable tool this domain exposes and the
8
+ * permission each one carries. This is the highest-stakes domain wired so far: a host's
9
+ * `workspaceId` is fixed at process composition (a v1 install always has exactly one addressable
10
+ * workspace row), so `create`/`delete` are deliberately excluded
11
+ * outright rather than treated as ordinary CRUD:
12
+ * - `CREATE_WORKSPACE` inserts a row no route can ever address afterwards (every other workspace
13
+ * route resolves strictly against the boot-wired `workspaceId`, never a caller-supplied id)
14
+ * — wiring it would let an agent mint permanently orphaned, unreferenceable rows with no
15
+ * corresponding read/delete path back to them. Zero utility, non-zero clutter/spam surface.
16
+ * - `DELETE_WORKSPACE` is INV-03-guarded to always refuse in v1 (there is only ever one row), but
17
+ * the moment that guard's precondition changes (a second addressable workspace exists), the same
18
+ * tool becomes a lever that can remove the only workspace scope a request can reach — whole-scope,
19
+ * no per-domain undo, the same blast-radius class as a forward database migration or a backup
20
+ * restore. Excluded by design, mirroring those two.
21
+ * `UPDATE_WORKSPACE` is the one write kept: a narrow rename of `name`/`slug` on the single existing,
22
+ * already-addressable workspace, no cascading effects (`id`/`createdAt` immutable by convention —
23
+ * see `update.ts`), the same risk class as `identity_role_rename`.
24
+ *
25
+ * How it relates to the package:
26
+ * A host's server-side tool filter consumes this catalog to decide which tool names an
27
+ * agent session may even see; `authorize()` (the single-evaluator rule below) enforces the actual
28
+ * permission checks at call time — this module only declares the catalog shape, it performs no
29
+ * I/O and no enforcement itself.
30
+ *
31
+ * Architectural role:
32
+ * `workspace` domain logic. No dependencies.
33
+ */
34
+ export type AgentToolSideEffect = "none" | "mutates-durable-state" | "mints-token";
35
+ export type AgentToolActorClassRule = "confirmer-must-equal-own-delegatedBy" | "user-only" | "none";
36
+ export interface AgentToolDefinition {
37
+ name: string;
38
+ description: string;
39
+ sideEffects: AgentToolSideEffect;
40
+ authorization: {
41
+ permission: string;
42
+ };
43
+ actorClassRule?: AgentToolActorClassRule;
44
+ /**
45
+ * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
46
+ * by whichever host layer wires these tools (any such layer should refuse to wire a tool lacking
47
+ * one). Optional, matching this package's other domain catalogs — the two entries this dispatch
48
+ * leaves unwired (see file header) carry no schema at all, since one is never published for a
49
+ * tool the model never sees.
50
+ *
51
+ * Deliberately not widened to `| undefined` (unlike most optional fields in this port) — this
52
+ * type flows into `core/tools/registration-kit.ts`'s `WirableToolDefinition`, which declares both
53
+ * this field and `actorClassRule` above without `| undefined`. Widening only this catalog's copy
54
+ * would make it structurally incompatible with that shared interface under
55
+ * `exactOptionalPropertyTypes`, the same reason `navigation`'s and `identity`'s catalogs leave
56
+ * these two fields alone.
57
+ */
58
+ inputSchema?: Readonly<Record<string, unknown>>;
59
+ }
60
+ /**
61
+ * The Workspace domain's fixed agent-tool catalog.
62
+ *
63
+ * @complexity O(1) — a fixed, statically-defined list.
64
+ * @overallScore 100
65
+ */
66
+ export declare function getWorkspaceAgentToolCatalog(): AgentToolDefinition[];
67
+ //# sourceMappingURL=agent-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-tools.d.ts","sourceRoot":"","sources":["../../src/workspace/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,uBAAuB,GAAG,aAAa,CAAC;AAEnF,MAAM,MAAM,uBAAuB,GAAG,sCAAsC,GAAG,WAAW,GAAG,MAAM,CAAC;AAEpG,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,mBAAmB,CAAC;IACjC,aAAa,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD;AA6BD;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,mBAAmB,EAAE,CAsCpE"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @file The Workspace domain's agent-tool catalog, instantiating this package's shared
3
+ * naming/callability convention (the same shape every other domain catalog in this package
4
+ * already uses).
5
+ *
6
+ * Purpose:
7
+ * A static, in-process catalog describing every agent-callable tool this domain exposes and the
8
+ * permission each one carries. This is the highest-stakes domain wired so far: a host's
9
+ * `workspaceId` is fixed at process composition (a v1 install always has exactly one addressable
10
+ * workspace row), so `create`/`delete` are deliberately excluded
11
+ * outright rather than treated as ordinary CRUD:
12
+ * - `CREATE_WORKSPACE` inserts a row no route can ever address afterwards (every other workspace
13
+ * route resolves strictly against the boot-wired `workspaceId`, never a caller-supplied id)
14
+ * — wiring it would let an agent mint permanently orphaned, unreferenceable rows with no
15
+ * corresponding read/delete path back to them. Zero utility, non-zero clutter/spam surface.
16
+ * - `DELETE_WORKSPACE` is INV-03-guarded to always refuse in v1 (there is only ever one row), but
17
+ * the moment that guard's precondition changes (a second addressable workspace exists), the same
18
+ * tool becomes a lever that can remove the only workspace scope a request can reach — whole-scope,
19
+ * no per-domain undo, the same blast-radius class as a forward database migration or a backup
20
+ * restore. Excluded by design, mirroring those two.
21
+ * `UPDATE_WORKSPACE` is the one write kept: a narrow rename of `name`/`slug` on the single existing,
22
+ * already-addressable workspace, no cascading effects (`id`/`createdAt` immutable by convention —
23
+ * see `update.ts`), the same risk class as `identity_role_rename`.
24
+ *
25
+ * How it relates to the package:
26
+ * A host's server-side tool filter consumes this catalog to decide which tool names an
27
+ * agent session may even see; `authorize()` (the single-evaluator rule below) enforces the actual
28
+ * permission checks at call time — this module only declares the catalog shape, it performs no
29
+ * I/O and no enforcement itself.
30
+ *
31
+ * Architectural role:
32
+ * `workspace` domain logic. No dependencies.
33
+ */
34
+ /** No arguments — `workspace_get` takes none; it always reports the caller's own boot-wired workspace. */
35
+ const NO_INPUT_SCHEMA = {
36
+ type: "object",
37
+ additionalProperties: false,
38
+ required: [],
39
+ properties: {},
40
+ };
41
+ /** `workspace_update`'s input — mirrors `update.ts`'s `UpdateWorkspaceInput` minus `id` (the tool
42
+ * always targets the caller's own boot-wired workspace, exactly like an admin route's
43
+ * `:workspaceId` path param, which is checked against the host's own `workspaceId` and never
44
+ * trusted otherwise). At least one of `name`/`slug` must be present — enforced by `updateWorkspace`
45
+ * itself (`WorkspaceValidationError` on an empty update), not expressible in this package's
46
+ * plain-JSON-Schema-subset convention (no domain catalog uses `anyOf`/`oneOf` today). */
47
+ const UPDATE_WORKSPACE_SCHEMA = {
48
+ type: "object",
49
+ additionalProperties: false,
50
+ required: [],
51
+ properties: {
52
+ name: { type: "string", description: "New workspace name. Omit to leave unchanged. At least one of name/slug is required." },
53
+ slug: {
54
+ type: "string",
55
+ description: "New workspace slug (lowercase letters, numbers, dashes only). Omit to leave unchanged. At least one of name/slug is required.",
56
+ },
57
+ },
58
+ };
59
+ /**
60
+ * The Workspace domain's fixed agent-tool catalog.
61
+ *
62
+ * @complexity O(1) — a fixed, statically-defined list.
63
+ * @overallScore 100
64
+ */
65
+ export function getWorkspaceAgentToolCatalog() {
66
+ return [
67
+ {
68
+ name: "workspace_get",
69
+ description: "Reports the caller's own workspace: id, name, slug, and creation time. v1 always has exactly one addressable workspace.",
70
+ sideEffects: "none",
71
+ authorization: { permission: "workspace.manage" },
72
+ inputSchema: NO_INPUT_SCHEMA,
73
+ },
74
+ {
75
+ name: "workspace_update",
76
+ description: "Renames the caller's own workspace: updates name and/or slug. At least one field is required. Does not change the workspace's id or creation time, and has no cascading effects on other domains.",
77
+ sideEffects: "mutates-durable-state",
78
+ authorization: { permission: "workspace.manage" },
79
+ inputSchema: UPDATE_WORKSPACE_SCHEMA,
80
+ },
81
+ {
82
+ // EXCLUDED BY DESIGN, never wired: see this file's header. Inserts a row no other route can
83
+ // ever address (every workspace route resolves strictly against the boot-wired
84
+ // `workspaceId`), so wiring this would only let an agent mint permanently orphaned rows.
85
+ name: "workspace_create",
86
+ description: "Creates a new workspace row. NEVER agent-callable — see file header.",
87
+ sideEffects: "mutates-durable-state",
88
+ authorization: { permission: "workspace.manage" },
89
+ },
90
+ {
91
+ // EXCLUDED BY DESIGN, never wired: see this file's header. INV-03-guarded to always refuse
92
+ // today (v1 has exactly one workspace row), but the lever itself removes the only addressable
93
+ // workspace scope the moment that guard's precondition ever changes — whole-scope,
94
+ // irreversible, no per-domain undo. Same exclusion class as a forward database migration or a
95
+ // backup restore.
96
+ name: "workspace_delete",
97
+ description: "Deletes a workspace row. NEVER agent-callable — see file header.",
98
+ sideEffects: "mutates-durable-state",
99
+ authorization: { permission: "workspace.manage" },
100
+ },
101
+ ];
102
+ }
103
+ //# sourceMappingURL=agent-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-tools.js","sourceRoot":"","sources":["../../src/workspace/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA6BH,0GAA0G;AAC1G,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;CACN,CAAC;AAEX;;;;;yFAKyF;AACzF,MAAM,uBAAuB,GAAG;IAC9B,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE;QACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qFAAqF,EAAE;QAC5H,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,+HAA+H;SAC7I;KACF;CACO,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL;YACE,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,yHAAyH;YACtI,WAAW,EAAE,MAAM;YACnB,aAAa,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE;YACjD,WAAW,EAAE,eAAe;SAC7B;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EACT,mMAAmM;YACrM,WAAW,EAAE,uBAAuB;YACpC,aAAa,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE;YACjD,WAAW,EAAE,uBAAuB;SACrC;QACD;YACE,4FAA4F;YAC5F,+EAA+E;YAC/E,yFAAyF;YACzF,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,sEAAsE;YACnF,WAAW,EAAE,uBAAuB;YACpC,aAAa,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE;SAClD;QACD;YACE,2FAA2F;YAC3F,8FAA8F;YAC9F,mFAAmF;YACnF,8FAA8F;YAC9F,kBAAkB;YAClB,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kEAAkE;YAC/E,WAAW,EAAE,uBAAuB;YACpC,aAAa,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE;SAClD;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,116 @@
1
+ import type { ClockPort, IdGeneratorPort, OutboxPort, UUID } from "../core/ports.js";
2
+ /**
3
+ * @file Workspace creation vertical slice (domain logic).
4
+ *
5
+ * Purpose:
6
+ * Encapsulates business rules for creating a workspace. Also owns the shared
7
+ * `WorkspaceRepoPort` contract and record shape for the whole feature slice
8
+ * (`update.ts`/`delete.ts` import from here rather than duplicating
9
+ * the port) — mirrors `identity/types.ts`+`identity/ports.ts` owning the
10
+ * shared shapes their sibling transition files (`grant-service.ts`) import.
11
+ *
12
+ * How it relates to the package:
13
+ * - Imports abstractions from `../core/ports.js` (no framework/db coupling).
14
+ * - Uses `WorkspaceRepoPort` for persistence and `OutboxPort` for event enqueue.
15
+ * - Is invoked by a host's own admin create-workspace route (moved off the
16
+ * original unauthenticated `POST /workspaces` route in the host's composition root).
17
+ * - Is verified by tests in `./__tests__`.
18
+ *
19
+ * Architectural role:
20
+ * Demonstrates the intended slice pattern:
21
+ * validate -> check constraints -> persist -> enqueue domain event.
22
+ */
23
+ export interface WorkspaceRecord {
24
+ id: UUID;
25
+ name: string;
26
+ slug: string;
27
+ createdAt: string;
28
+ }
29
+ /**
30
+ * Workspace persistence contract for this slice. `findById`/`list`/`update`/`delete` were
31
+ * later additions (both adapters — this package's `repo.memory.ts` and a host's own SQLite
32
+ * adapter — implement all seven methods; `insert`/`findBySlug`'s existing contract is unchanged).
33
+ */
34
+ export interface WorkspaceRepoPort {
35
+ insert(record: WorkspaceRecord): Promise<void>;
36
+ findBySlug(slug: string): Promise<WorkspaceRecord | null>;
37
+ findById(id: UUID): Promise<WorkspaceRecord | null>;
38
+ /** A v1 install always has exactly one row (see `delete.ts`'s header);
39
+ * the port itself is not limited to one. */
40
+ list(): Promise<WorkspaceRecord[]>;
41
+ /** Replaces the full record (id/createdAt immutable by convention — see
42
+ * `update.ts`, which never changes them). */
43
+ update(record: WorkspaceRecord): Promise<void>;
44
+ /** Callers (see `delete.ts`) must apply the last-workspace guard
45
+ * themselves — this port method performs the row deletion only, no business rule. */
46
+ delete(id: UUID): Promise<void>;
47
+ }
48
+ /**
49
+ * Shared `name`/`slug` validation — used by both `createWorkspace` below
50
+ * and `updateWorkspace` (`update.ts`) so the two transitions can never drift on what counts as a
51
+ * valid name/slug. Returns the normalized (trimmed name, trimmed+lowercased slug) pair; throws
52
+ * `WorkspaceValidationError` on either being invalid.
53
+ *
54
+ * @complexity O(1) — two regex/trim checks.
55
+ * @overallScore 100
56
+ */
57
+ export declare function validateWorkspaceNameAndSlug(input: {
58
+ name: string;
59
+ slug: string;
60
+ }): {
61
+ name: string;
62
+ slug: string;
63
+ };
64
+ /** Command payload for workspace creation. */
65
+ export interface CreateWorkspaceInput {
66
+ name: string;
67
+ slug: string;
68
+ }
69
+ /** Dependencies required by the create-workspace slice. */
70
+ export interface CreateWorkspaceDeps {
71
+ idGen: IdGeneratorPort;
72
+ clock: ClockPort;
73
+ repo: WorkspaceRepoPort;
74
+ outbox: OutboxPort;
75
+ }
76
+ /** Required parameters for createWorkspace. */
77
+ export interface CreateWorkspaceRequired {
78
+ deps: CreateWorkspaceDeps;
79
+ input: CreateWorkspaceInput;
80
+ }
81
+ /** Optional parameters for createWorkspace. Reserved for future use. */
82
+ export interface CreateWorkspaceOptional {
83
+ }
84
+ /** Thrown when incoming command data is invalid. */
85
+ export declare class WorkspaceValidationError extends Error {
86
+ }
87
+ /** Thrown when uniqueness constraints are violated. */
88
+ export declare class WorkspaceConflictError extends Error {
89
+ }
90
+ /** Thrown when a `:workspaceId` does not resolve to a row. */
91
+ export declare class WorkspaceNotFoundError extends Error {
92
+ }
93
+ /**
94
+ * Thrown when `deleteWorkspace` (`delete.ts`) would remove the install's
95
+ * last remaining workspace row. Named distinctly from `WorkspaceConflictError` (a 409, same as this
96
+ * maps to) so a caller can tell "duplicate slug" apart from "would brick the install" without
97
+ * string-matching the message — mirrors this codebase's `GrantExceedsIssuerError` being kept distinct
98
+ * from `IdentityForbiddenError` for the identical reason (typed-reason clarity).
99
+ */
100
+ export declare class WorkspaceLastRemainingError extends Error {
101
+ }
102
+ /**
103
+ * Execute create-workspace command.
104
+ *
105
+ * Synchronous path:
106
+ * - validate input
107
+ * - check uniqueness
108
+ * - write workspace record
109
+ *
110
+ * Asynchronous path:
111
+ * - enqueue `workspace.created` domain event to outbox
112
+ */
113
+ export declare function createWorkspace(required: CreateWorkspaceRequired, _optional?: CreateWorkspaceOptional): Promise<{
114
+ id: UUID;
115
+ }>;
116
+ //# sourceMappingURL=create.d.ts.map