@jini-ai/cms 0.3.10 → 0.4.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 (258) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +47 -19
  3. package/dist/content-types/agent-tools.d.ts +3 -56
  4. package/dist/content-types/agent-tools.js +22 -6
  5. package/dist/content-types/cleanup.d.ts +18 -13
  6. package/dist/content-types/cleanup.js +16 -11
  7. package/dist/content-types/errors.d.ts +57 -24
  8. package/dist/content-types/errors.js +56 -39
  9. package/dist/content-types/field-defs.d.ts +8 -4
  10. package/dist/content-types/field-defs.js +19 -14
  11. package/dist/content-types/index-provisioning.d.ts +61 -47
  12. package/dist/content-types/index-provisioning.js +90 -66
  13. package/dist/content-types/index.d.ts +4 -3
  14. package/dist/content-types/lifecycle-dispatch.d.ts +11 -5
  15. package/dist/content-types/lifecycle-dispatch.js +5 -4
  16. package/dist/content-types/lifecycle.d.ts +23 -18
  17. package/dist/content-types/lifecycle.js +71 -64
  18. package/dist/content-types/repo.memory.d.ts +5 -4
  19. package/dist/content-types/repo.memory.js +3 -2
  20. package/dist/content-types/tool-registrations.d.ts +6 -8
  21. package/dist/content-types/tool-registrations.js +24 -28
  22. package/dist/content-types/types.d.ts +17 -13
  23. package/dist/content-types/types.js +11 -5
  24. package/dist/content-types/write-service.d.ts +20 -22
  25. package/dist/content-types/write-service.js +78 -75
  26. package/dist/core/authorization.d.ts +15 -0
  27. package/dist/core/authorization.js +2 -0
  28. package/dist/core/commands/change-set.d.ts +15 -7
  29. package/dist/core/commands/command.d.ts +45 -26
  30. package/dist/core/commands/command.js +73 -63
  31. package/dist/core/entity-liveness.d.ts +11 -7
  32. package/dist/core/entity-liveness.js +5 -4
  33. package/dist/core/index.d.ts +12 -5
  34. package/dist/core/index.js +10 -4
  35. package/dist/core/ports.d.ts +25 -24
  36. package/dist/core/ports.js +1 -0
  37. package/dist/core/tools/args.d.ts +49 -0
  38. package/dist/core/tools/args.js +46 -0
  39. package/dist/core/tools/index.d.ts +3 -0
  40. package/dist/core/tools/index.js +3 -0
  41. package/dist/entries/agent-tools.d.ts +1 -73
  42. package/dist/entries/agent-tools.js +19 -13
  43. package/dist/entries/errors.d.ts +28 -14
  44. package/dist/entries/errors.js +17 -11
  45. package/dist/entries/field-validation.d.ts +5 -3
  46. package/dist/entries/field-validation.js +7 -5
  47. package/dist/entries/index.d.ts +2 -2
  48. package/dist/entries/lifecycle-dispatch.d.ts +5 -2
  49. package/dist/entries/lifecycle-dispatch.js +2 -1
  50. package/dist/entries/list.d.ts +4 -2
  51. package/dist/entries/list.js +4 -3
  52. package/dist/entries/repo.memory.d.ts +12 -10
  53. package/dist/entries/repo.memory.js +11 -10
  54. package/dist/entries/tool-registrations.d.ts +6 -8
  55. package/dist/entries/tool-registrations.js +42 -41
  56. package/dist/entries/types.d.ts +0 -7
  57. package/dist/entries/write-service.d.ts +28 -29
  58. package/dist/entries/write-service.js +114 -105
  59. package/dist/http/settings/cms-adapter.d.ts +20 -0
  60. package/dist/http/settings/cms-adapter.js +124 -0
  61. package/dist/http/settings/contracts.d.ts +135 -0
  62. package/dist/http/settings/contracts.js +2 -0
  63. package/dist/http/settings/http.d.ts +10 -0
  64. package/dist/http/settings/http.js +211 -0
  65. package/dist/http/settings/index.d.ts +5 -0
  66. package/dist/http/settings/index.js +4 -0
  67. package/dist/http/settings/shared.d.ts +68 -0
  68. package/dist/http/settings/shared.js +54 -0
  69. package/dist/http/settings/stream.d.ts +24 -0
  70. package/dist/http/settings/stream.js +147 -0
  71. package/dist/media/agent-tools.d.ts +1 -66
  72. package/dist/media/agent-tools.js +5 -1
  73. package/dist/media/blob-gc-lock.d.ts +6 -2
  74. package/dist/media/blob-gc-lock.js +4 -2
  75. package/dist/media/blob-gc.d.ts +64 -51
  76. package/dist/media/blob-gc.js +62 -52
  77. package/dist/media/blob-key.d.ts +1 -1
  78. package/dist/media/content-type-sniffer.d.ts +3 -1
  79. package/dist/media/content-type-sniffer.js +1 -1
  80. package/dist/media/html-attributes.d.ts +9 -5
  81. package/dist/media/html-attributes.js +8 -6
  82. package/dist/media/image-transformer.js +1 -1
  83. package/dist/media/image-transformer.sharp.d.ts +6 -0
  84. package/dist/media/image-transformer.sharp.js +12 -6
  85. package/dist/media/import/fetch-image.d.ts +24 -0
  86. package/dist/media/import/fetch-image.js +137 -0
  87. package/dist/media/import/index.d.ts +3 -0
  88. package/dist/media/import/index.js +3 -0
  89. package/dist/media/import/ports.d.ts +38 -0
  90. package/dist/media/index.d.ts +7 -1
  91. package/dist/media/index.js +1 -0
  92. package/dist/media/media-service.d.ts +14 -10
  93. package/dist/media/media-service.js +57 -52
  94. package/dist/media/ports.d.ts +3 -2
  95. package/dist/media/rendition-service.d.ts +3 -3
  96. package/dist/media/rendition-service.js +38 -37
  97. package/dist/media/repo.memory.d.ts +18 -7
  98. package/dist/media/repo.memory.js +12 -6
  99. package/dist/media/tool-registrations.d.ts +16 -15
  100. package/dist/media/tool-registrations.js +84 -72
  101. package/dist/media/transform-lock.d.ts +22 -12
  102. package/dist/media/transform-lock.js +14 -13
  103. package/dist/media/transform-registry.d.ts +3 -3
  104. package/dist/media/transform-registry.js +19 -18
  105. package/dist/media/transform-types.d.ts +8 -3
  106. package/dist/media/transform-types.js +10 -5
  107. package/dist/media/types.d.ts +21 -4
  108. package/dist/media/types.js +15 -2
  109. package/dist/navigation/agent-tools.d.ts +1 -80
  110. package/dist/navigation/agent-tools.js +15 -3
  111. package/dist/navigation/contracts.d.ts +1 -1
  112. package/dist/navigation/index.d.ts +2 -2
  113. package/dist/navigation/menu-service.d.ts +57 -40
  114. package/dist/navigation/menu-service.js +80 -69
  115. package/dist/navigation/ports.d.ts +1 -1
  116. package/dist/navigation/read-model.d.ts +3 -1
  117. package/dist/navigation/read-model.js +2 -2
  118. package/dist/navigation/reconcile.d.ts +2 -2
  119. package/dist/navigation/reconcile.js +2 -1
  120. package/dist/navigation/repo.memory.d.ts +7 -3
  121. package/dist/navigation/repo.memory.js +4 -2
  122. package/dist/navigation/resolver.d.ts +4 -1
  123. package/dist/navigation/resolver.js +1 -1
  124. package/dist/navigation/tool-registrations.d.ts +6 -8
  125. package/dist/navigation/tool-registrations.js +44 -42
  126. package/dist/navigation/types.d.ts +1 -1
  127. package/dist/presentation/presentation.d.ts +11 -3
  128. package/dist/presentation/presentation.js +13 -6
  129. package/dist/presentation/repo.memory.d.ts +6 -2
  130. package/dist/presentation/repo.memory.js +3 -2
  131. package/dist/settings/agent-tools.d.ts +2 -75
  132. package/dist/settings/agent-tools.js +49 -45
  133. package/dist/settings/agent-value-write-tools.d.ts +22 -0
  134. package/dist/settings/agent-value-write-tools.js +154 -0
  135. package/dist/settings/agent-writable-preferences.js +8 -20
  136. package/dist/settings/agent-write-denylist.d.ts +19 -0
  137. package/dist/settings/agent-write-denylist.js +15 -0
  138. package/dist/settings/change-feed.d.ts +11 -2
  139. package/dist/settings/change-feed.js +4 -4
  140. package/dist/settings/definitions-dispatch.d.ts +8 -3
  141. package/dist/settings/definitions-dispatch.js +5 -5
  142. package/dist/settings/dictionaries/index.d.ts +5 -2
  143. package/dist/settings/dictionaries/index.js +2 -2
  144. package/dist/settings/dictionaries/settings-dialog.ar.js +0 -1
  145. package/dist/settings/dictionaries/settings-dialog.bn.js +0 -1
  146. package/dist/settings/dictionaries/settings-dialog.de.js +0 -1
  147. package/dist/settings/dictionaries/settings-dialog.es.js +0 -1
  148. package/dist/settings/dictionaries/settings-dialog.fa.js +0 -1
  149. package/dist/settings/dictionaries/settings-dialog.fr.js +0 -1
  150. package/dist/settings/dictionaries/settings-dialog.hi.js +0 -1
  151. package/dist/settings/dictionaries/settings-dialog.hu.js +0 -1
  152. package/dist/settings/dictionaries/settings-dialog.id.js +0 -1
  153. package/dist/settings/dictionaries/settings-dialog.it.js +0 -1
  154. package/dist/settings/dictionaries/settings-dialog.ja.js +0 -1
  155. package/dist/settings/dictionaries/settings-dialog.ko.js +0 -1
  156. package/dist/settings/dictionaries/settings-dialog.pl.js +0 -1
  157. package/dist/settings/dictionaries/settings-dialog.pt-BR.js +0 -1
  158. package/dist/settings/dictionaries/settings-dialog.ru.js +0 -1
  159. package/dist/settings/dictionaries/settings-dialog.th.js +0 -1
  160. package/dist/settings/dictionaries/settings-dialog.tr.js +0 -1
  161. package/dist/settings/dictionaries/settings-dialog.uk.js +0 -1
  162. package/dist/settings/dictionaries/settings-dialog.ur.js +0 -1
  163. package/dist/settings/dictionaries/settings-dialog.zh-CN.js +0 -1
  164. package/dist/settings/dictionaries/settings-dialog.zh-TW.js +0 -1
  165. package/dist/settings/ensure-definitions.d.ts +5 -5
  166. package/dist/settings/errors.d.ts +7 -1
  167. package/dist/settings/errors.js +7 -1
  168. package/dist/settings/index.d.ts +4 -1
  169. package/dist/settings/index.js +1 -0
  170. package/dist/settings/ports.d.ts +6 -5
  171. package/dist/settings/principal-lookup.d.ts +9 -0
  172. package/dist/settings/principal-lookup.js +2 -0
  173. package/dist/settings/purge-service.d.ts +5 -4
  174. package/dist/settings/purge-service.js +3 -2
  175. package/dist/settings/settings.d.ts +22 -7
  176. package/dist/settings/settings.js +47 -26
  177. package/dist/settings/tool-registrations.d.ts +25 -32
  178. package/dist/settings/tool-registrations.js +66 -56
  179. package/dist/settings/types.d.ts +1 -1
  180. package/dist/settings/ui-tab-definitions.d.ts +1 -1
  181. package/dist/settings/write-service.d.ts +32 -26
  182. package/dist/settings/write-service.js +26 -20
  183. package/dist/taxonomy/agent-tools.d.ts +1 -66
  184. package/dist/taxonomy/agent-tools.js +25 -15
  185. package/dist/taxonomy/content-lookup.js +1 -1
  186. package/dist/taxonomy/index.d.ts +2 -2
  187. package/dist/taxonomy/merge-term.d.ts +7 -4
  188. package/dist/taxonomy/merge-term.js +7 -5
  189. package/dist/taxonomy/repo.memory.d.ts +42 -19
  190. package/dist/taxonomy/repo.memory.js +14 -12
  191. package/dist/taxonomy/validation-chain.d.ts +39 -18
  192. package/dist/taxonomy/validation-chain.js +35 -25
  193. package/dist/taxonomy/write-service.d.ts +106 -45
  194. package/dist/taxonomy/write-service.js +221 -179
  195. package/dist/trash/adapters/record-store.d.ts +52 -0
  196. package/dist/trash/adapters/record-store.js +36 -0
  197. package/dist/trash/cursor.d.ts +20 -0
  198. package/dist/trash/cursor.js +36 -0
  199. package/dist/trash/follow-ups.d.ts +76 -0
  200. package/dist/trash/follow-ups.js +46 -0
  201. package/dist/trash/index.d.ts +8 -0
  202. package/dist/trash/index.js +8 -0
  203. package/dist/trash/ports.d.ts +308 -0
  204. package/dist/trash/ports.js +2 -0
  205. package/dist/trash/repo.memory.d.ts +50 -0
  206. package/dist/trash/repo.memory.js +114 -0
  207. package/dist/trash/sweeper.d.ts +77 -0
  208. package/dist/trash/sweeper.js +127 -0
  209. package/dist/trash/write-service.d.ts +100 -0
  210. package/dist/trash/write-service.js +242 -0
  211. package/dist/workspace/agent-tools.d.ts +1 -59
  212. package/dist/workspace/agent-tools.js +27 -12
  213. package/dist/workspace/create.d.ts +31 -6
  214. package/dist/workspace/create.js +18 -5
  215. package/dist/workspace/delete.d.ts +18 -13
  216. package/dist/workspace/delete.js +20 -12
  217. package/dist/workspace/index.d.ts +1 -1
  218. package/dist/workspace/repo.memory.d.ts +19 -4
  219. package/dist/workspace/repo.memory.js +26 -4
  220. package/dist/workspace/tool-registrations.d.ts +2 -2
  221. package/dist/workspace/tool-registrations.js +13 -13
  222. package/dist/workspace/update.d.ts +6 -5
  223. package/dist/workspace/update.js +9 -8
  224. package/package.json +44 -38
  225. package/dist/identity/admin-crud-service.d.ts +0 -280
  226. package/dist/identity/admin-crud-service.js +0 -468
  227. package/dist/identity/agent-tool-input.d.ts +0 -58
  228. package/dist/identity/agent-tool-input.js +0 -126
  229. package/dist/identity/agent-tools.d.ts +0 -101
  230. package/dist/identity/agent-tools.js +0 -290
  231. package/dist/identity/auth-service.d.ts +0 -118
  232. package/dist/identity/auth-service.js +0 -170
  233. package/dist/identity/authorize.d.ts +0 -90
  234. package/dist/identity/authorize.js +0 -94
  235. package/dist/identity/grant-service.d.ts +0 -198
  236. package/dist/identity/grant-service.js +0 -361
  237. package/dist/identity/hasher.d.ts +0 -39
  238. package/dist/identity/hasher.js +0 -39
  239. package/dist/identity/index.d.ts +0 -62
  240. package/dist/identity/index.js +0 -54
  241. package/dist/identity/password-policy.d.ts +0 -57
  242. package/dist/identity/password-policy.js +0 -66
  243. package/dist/identity/permission-migrations.d.ts +0 -86
  244. package/dist/identity/permission-migrations.js +0 -67
  245. package/dist/identity/permissions.d.ts +0 -35
  246. package/dist/identity/permissions.js +0 -603
  247. package/dist/identity/ports.d.ts +0 -201
  248. package/dist/identity/repo.memory.d.ts +0 -164
  249. package/dist/identity/repo.memory.js +0 -224
  250. package/dist/identity/seed.d.ts +0 -54
  251. package/dist/identity/seed.js +0 -429
  252. package/dist/identity/tool-registrations.d.ts +0 -50
  253. package/dist/identity/tool-registrations.js +0 -419
  254. package/dist/identity/types.d.ts +0 -185
  255. package/dist/identity/types.js +0 -64
  256. package/dist/identity/username.d.ts +0 -12
  257. package/dist/identity/username.js +0 -14
  258. /package/dist/{identity → media/import}/ports.js +0 -0
@@ -1,83 +1,4 @@
1
- /**
2
- * @file The Navigation (Menus) agent-tool catalog — this domain's instance of the
3
- * per-domain `agent-tools.ts` convention `forms/agent-tools.ts` and `identity/agent-tools.ts`
4
- * already use.
5
- *
6
- * Purpose:
7
- * A static, in-process catalog describing every agent-callable tool this domain exposes and the
8
- * permission each carries. Every entry maps 1:1 onto a real exported function of
9
- * `navigation/menu-service.ts` (plus two pure reads over `MenuRepoPort`) — this catalog never names
10
- * an operation the domain cannot perform.
11
- *
12
- * Precedent already in this library: `navigation/contracts.ts` declares `NAVIGATION_AI_TOOLS` — a
13
- * design-note list of an intended future AI tool surface (`navigation.search`/`.get`/`.where_used`/
14
- * `.update`/`.assign`) for a DIFFERENT, not-yet-built delivery mechanism (a "change-set review
15
- * layer" HITL gateway; the list itself is unused anywhere in this build today). Two of its five
16
- * names do not correspond to any real, callable capability in this build: `navigation.search` has
17
- * no implementation beyond `MenuRepoPort.list` (folded into `menus_list_menus` below — there is no
18
- * separate text-search capability, matching how `identity_user_list`/`identity_role_list` are
19
- * likewise this library's "search" for their own domains), and `navigation.where_used` has no
20
- * implementation anywhere (`NavWhereUsedResult` is declared in `contracts.ts` but no function in
21
- * `navigation/` computes it — `entry_refs`-backed where-used, unlike `widgets`/`media`, was never
22
- * built for menus). Wrapping either literally would invent backend capability this catalog's own
23
- * discipline forbids; `menus_list_menus` + `menus_get_menu` are this build's honest equivalents of
24
- * "search"/"get".
25
- *
26
- * Deliberate absence (the point of a catalog, not an oversight):
27
- * - There is NO `menus_delete_menu` (nor a separate trash-only tool). `deleteMenu` is ONE function
28
- * that performs BOTH steps of the deletion ladder, keyed off the menu's CURRENT status:
29
- * a first call trashes (safe, unconditional), but a second call against an already-trashed menu
30
- * PURGES it — a hard, irreversible delete, blocked only by a still-bound-location guard that
31
- * itself can be bypassed with `force` (gated behind the separate `admin.menus.delete.force`
32
- * permission). Unlike `widgets`/`media` (which expose trash and purge as two SEPARATE domain
33
- * functions, letting a catalog safely wire trash alone), navigation has no decomposed trash-only
34
- * entrypoint to call — the very same tool call, made twice, silently escalates from a reversible
35
- * soft-delete into a permanent one. That is exactly the shape of risk `identity/agent-tools.ts`
36
- * excludes `resetUserPassword` for: a single lever whose second pull does something categorically
37
- * more dangerous than its first, reachable by an agent re-invoking a tool it already called once
38
- * (e.g. after losing track of a prior call, or via prompt injection through ordinary operator
39
- * content). Left human-UI-only.
40
- *
41
- * How it relates to the project:
42
- * A host's own tool-registration layer maps these entries into `ToolRegistration`s (see
43
- * `tool-registrations.ts`). Unlike Forms/Identity/Widgets, `menu-service.ts`'s functions perform NO
44
- * internal `authorize()` call of their own (confirmed: `CreateMenuDeps`/`UpdateMenuTreeDeps`/
45
- * `AssignLocationDeps` carry no `authorize` field) — every admin HTTP route a host builds is expected
46
- * to check `deps.authorize(...)` inline, before calling the service function (mirrors `media`'s
47
- * identical gap, see `media/agent-tools.ts`'s header). `tool-registrations.ts` therefore performs
48
- * that SAME inline `authorize()` call itself (the identical permission string and `entityType:
49
- * "menu"` the HTTP route uses) rather than relying on a domain-layer gate that does not exist for
50
- * this library.
51
- *
52
- * Architectural role:
53
- * `navigation` domain declaration. Imports only `VALID_TARGET_KINDS`-equivalent constants are not
54
- * exported from `menu-service.ts` as public data (the target-kind allowlist is enforced, not
55
- * published, there), so the target schema below is hand-authored against `types.ts`'s `NavTarget`
56
- * union and cross-checked by this catalog's own contract test rather than imported.
57
- */
58
- export type AgentToolSideEffect = "none" | "mutates-durable-state" | "mints-token";
59
- export type AgentToolActorClassRule = "confirmer-must-equal-own-delegatedBy" | "user-only" | "none";
60
- export interface AgentToolDefinition {
61
- name: string;
62
- description: string;
63
- sideEffects: AgentToolSideEffect;
64
- authorization: {
65
- permission: string;
66
- };
67
- actorClassRule?: AgentToolActorClassRule;
68
- /**
69
- * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
70
- * (a host's own tool-registration layer, which refuses to wire any tool lacking one).
71
- *
72
- * Deliberately not widened to `| undefined` (unlike most optional fields in this port) — this
73
- * type flows into `core/tools/registration-kit.ts`'s `WirableToolDefinition`, which declares both
74
- * this field and `actorClassRule` below without `| undefined`. Widening only this catalog's copy
75
- * would make it structurally incompatible with that shared interface under
76
- * `exactOptionalPropertyTypes`, which is exactly what identity's own `agent-tools.ts` avoids for
77
- * the same reason.
78
- */
79
- inputSchema?: Readonly<Record<string, unknown>>;
80
- }
1
+ import type { AgentToolDefinition } from "@jini-ai/core";
81
2
  /**
82
3
  * The Navigation domain's fixed agent-tool catalog — the 5 operations a host's admin HTTP surface
83
4
  * (`server/routes/admin/menus/*.ts`) exposes that are safe to wrap, out of its 6 total (see file
@@ -56,6 +56,17 @@
56
56
  * union and cross-checked by this catalog's own contract test rather than imported.
57
57
  */
58
58
  import { ALLOWED_HREF_SHAPES_DESCRIPTION } from "./menu-service.js";
59
+ /**
60
+ * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
61
+ * (a host's own tool-registration layer, which refuses to wire any tool lacking one).
62
+ *
63
+ * Deliberately not widened to `| undefined` (unlike most optional fields in this port) — this
64
+ * type flows into `@jini-ai/core`'s `registration-kit.ts`'s `AgentToolDefinition`, which declares both
65
+ * this field and `actorClassRule` below without `| undefined`. Widening only this catalog's copy
66
+ * would make it structurally incompatible with that shared interface under
67
+ * `exactOptionalPropertyTypes`, which is exactly what identity's own `agent-tools.ts` avoids for
68
+ * the same reason.
69
+ */
59
70
  const MENU_ID_SCHEMA = {
60
71
  type: "string",
61
72
  description: "The menu's id, as returned by menus_list_menus, menus_get_menu, or menus_create_menu.",
@@ -152,7 +163,7 @@ const ITEMS_TREE_SCHEMA = {
152
163
  export const menusAgentToolCatalog = [
153
164
  {
154
165
  name: "menus_list_menus",
155
- description: "Lists every menu in the workspace (id, slug, title, status, item tree, locations, version). Read-only.",
166
+ description: "Lists every menu in the workspace (id, slug, title, status, item tree, locations, version). Read-only. To delete a menu, use trash_item with entityType 'menu' (it moves to the Trash and can be restored).",
156
167
  sideEffects: "none",
157
168
  authorization: { permission: "admin.menus.read" },
158
169
  inputSchema: {
@@ -177,7 +188,8 @@ export const menusAgentToolCatalog = [
177
188
  {
178
189
  name: "menus_create_menu",
179
190
  description: "Creates a new menu in 'draft' status with no location assigned yet — it has no effect on the live site until " +
180
- "menus_assign_location binds it somewhere. Rejects a duplicate slug within the workspace.",
191
+ "menus_assign_location binds it somewhere. Rejects a duplicate slug within the workspace. " +
192
+ "To delete a menu, use trash_item with entityType 'menu' (it moves to the Trash and can be restored).",
181
193
  sideEffects: "mutates-durable-state",
182
194
  authorization: { permission: "admin.menus.create" },
183
195
  inputSchema: {
@@ -195,7 +207,7 @@ export const menusAgentToolCatalog = [
195
207
  name: "menus_update_menu_tree",
196
208
  description: "Replaces an existing menu's whole item tree (and optionally its title/slug) in one version-guarded write. " +
197
209
  "Always a whole-tree replace — there is no per-item patch operation, so the submitted tree must include every " +
198
- "item the menu keeps.",
210
+ "item the menu keeps. To delete a menu, use trash_item with entityType 'menu' (it moves to the Trash and can be restored).",
199
211
  sideEffects: "mutates-durable-state",
200
212
  authorization: { permission: "admin.menus.update" },
201
213
  inputSchema: {
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * INTERFACES + DATA CATALOGS ONLY. No feature logic.
12
12
  */
13
- import type { UUID } from "../core/ports.js";
13
+ import type { UUID } from "@jini-ai/core/primitives";
14
14
  import type { NavItemNode, NavLocationKey, NavMenuEntry } from "./types.js";
15
15
  /**
16
16
  * The `admin.menus.*` permission strings (renamed
@@ -9,7 +9,7 @@ export { NAV_MENU_CONTENT_TYPE, NAV_FIELD_NAMESPACE, NAV_DOC_TYPE } from "./type
9
9
  export type { NavLocationBindingRepoPort, NavResolveContext, NavTargetResolver, NavMenuReadModel, NavLocationRegistry, } from "./ports.js";
10
10
  export type { NavigationPermission, CreateMenuInput, UpdateMenuInput, AssignLocationInput, UnassignLocationInput, DeleteMenuInput, NavigationEventName, NavMenuChangedPayload, NavLocationChangedPayload, NavigationHookName, NavigationAiTool, NavWhereUsedResult, } from "./contracts.js";
11
11
  export { NAVIGATION_PERMISSIONS, NAVIGATION_EVENTS, NAVIGATION_HOOKS, NAVIGATION_AI_TOOLS, } from "./contracts.js";
12
- export { createNavMenuReadModel, type NavMenuReadModelDeps } from "./read-model.js";
12
+ export { createNavMenuReadModel, type NavMenuReadModelDeps, type NavMenuReadModelOptions } from "./read-model.js";
13
13
  /**
14
14
  * `MenuRepoPort` is navigation-owned (not part of the frozen `ports.ts` ADR surface — see
15
15
  * `repo.memory.ts`'s file header for why) but is a real public contract: a host's own SQLite
@@ -29,7 +29,7 @@ export { createMenu, updateMenuTree, assignLocation, deleteMenu, validateAndClon
29
29
  export { resolveForLocation, resolveMenuDoc, type ResolveTargetHrefFn, type ResolvedTargetHref, type ResolveForLocationDeps, type ResolveForLocationServiceInput, type ResolveForLocationRequired, type ResolveForLocationOptional, } from "./resolver.js";
30
30
  export { rebuildNavLocationBindings, type RebuildNavLocationBindingsDeps, type RebuildNavLocationBindingsResult, } from "./reconcile.js";
31
31
  /** The agent-tool surface for this domain (see `agent-tools.ts` for what is deliberately omitted). */
32
- export { menusAgentToolCatalog, type AgentToolDefinition as NavigationAgentToolDefinition, type AgentToolSideEffect as NavigationAgentToolSideEffect, type AgentToolActorClassRule as NavigationAgentToolActorClassRule, } from "./agent-tools.js";
32
+ export { menusAgentToolCatalog, } from "./agent-tools.js";
33
33
  /**
34
34
  * The agent-tool wiring for this domain.
35
35
  *
@@ -1,12 +1,22 @@
1
- import type { ClockPort, IdGeneratorPort, OutboxPort, UUID } from "../core/ports.js";
1
+ import type { Clock, IdGenerator, UUID } from "@jini-ai/core/primitives";
2
+ import type { OutboxPort } from "../core/ports.js";
2
3
  import type { MenuRepoPort } from "./repo.memory.js";
3
4
  import type { NavLocationBindingRepoPort } from "./ports.js";
4
5
  import { type NavItemNode, type NavLocationBindingRow, type NavLocationKey, type NavMenuEntry } from "./types.js";
5
6
  export declare class MenuNotFoundError extends Error {
7
+ constructor({ message }: {
8
+ message: string;
9
+ }, optionalArgs?: ErrorOptions);
6
10
  }
7
11
  export declare class MenuValidationError extends Error {
12
+ constructor({ message }: {
13
+ message: string;
14
+ }, optionalArgs?: ErrorOptions);
8
15
  }
9
16
  export declare class MenuConflictError extends Error {
17
+ constructor({ message }: {
18
+ message: string;
19
+ }, optionalArgs?: ErrorOptions);
10
20
  }
11
21
  /**
12
22
  * The 409-style purge rejection: hard delete is blocked while the menu is
@@ -16,7 +26,10 @@ export declare class MenuConflictError extends Error {
16
26
  */
17
27
  export declare class MenuLocationBoundError extends MenuConflictError {
18
28
  readonly boundLocations: readonly NavLocationKey[];
19
- constructor(message: string, boundLocations: readonly NavLocationKey[]);
29
+ constructor(requiredArgs: {
30
+ message: string;
31
+ boundLocations: readonly NavLocationKey[];
32
+ }, optionalArgs?: Record<string, never>);
20
33
  }
21
34
  /** Default max nesting depth (root = depth 1). Configurable. */
22
35
  export declare const DEFAULT_MAX_TREE_DEPTH = 5;
@@ -25,7 +38,7 @@ export declare const DEFAULT_MAX_ITEM_COUNT = 500;
25
38
  /**
26
39
  * The CANONICAL href allowlist for an author-authored link — same accepted shapes (`#…`, same-origin
27
40
  * `/…`, `http(s)://`, `mailto:`) as the host's render-time `safeHref` in `render.ts` and its
28
- * `features/theme/static-render.ts` duplicate. **This is now the single source of truth**: exported
41
+ * `features/theme/static-render.ts` duplicate. **This is now the single source of truth** exported
29
42
  * from this package's public surface (`navigation/index.ts` -> `@jini-ai/cms/navigation`) so the
30
43
  * dependency runs the direction that is actually legal — the host already depends on `@jini-ai/cms`, not
31
44
  * the reverse — rather than each consumer hand-copying the predicate.
@@ -36,14 +49,14 @@ export declare const DEFAULT_MAX_ITEM_COUNT = 500;
36
49
  * `check:boundaries` no-deep-import concern is NOT what blocks it: `render.ts` already imports
37
50
  * `@jini-ai/cms/core` today, and `features/theme` already imports `@jini-ai/cms/core` too, so both
38
51
  * call sites may legally import `@jini-ai/cms/navigation` directly — verified by grep, not assumed).
39
- * Until that follow-up lands, `apps/website/development/scripts/check-menu-href-allowlist-sync.ts`
52
+ * Until that follow-up lands, the host's menu href allowlist sync check
40
53
  * behaviorally gates the three copies against the same adversarial table so a divergence fails CI
41
54
  * instead of drifting silently.
42
55
  *
43
- * Replaced (this change) a `URL_SCHEME_DENYLIST` (`startsWith` on a lowercased, `.trim()`ed string)
56
+ * Replaced (this change) a `URL_SCHEME_DENYLIST` (`startsWith` on a lowercased, `.trim`ed string)
44
57
  * that failed open: the WHATWG `URL` parser strips TAB/LF/CR from ANYWHERE in the input and folds a
45
- * leading backslash to `/` for `http(s)`, so `"java\tscript:alert(1)"`, `" javascript:alert(1)"`,
46
- * `"file:///etc/passwd"`, `"blob:…"`, `"about:blank"`, `"//evil.example"` (protocol-relative), and
58
+ * leading backslash to `/` for `http(s)`, so `"java\tscript:alert"`, `" javascript:alert"`,
59
+ * `"file:// etc/passwd"`, `"blob:…"`, `"about:blank"`, `"//evil.example"` (protocol-relative), and
47
60
  * `"/\evil.example"` all resolved to a dangerous or off-origin target while never matching any
48
61
  * `startsWith` prefix in the old list. An allowlist closes the whole bypass class at once (case,
49
62
  * embedded control characters, and scheme are all irrelevant to an allowlist the same way) rather
@@ -58,11 +71,13 @@ export declare const DEFAULT_MAX_ITEM_COUNT = 500;
58
71
  * hrefs written through the host's admin editor.
59
72
  *
60
73
  * @param rawHref - The href to check, already confirmed non-empty by `validateTarget`. Any string is
61
- * otherwise a valid input — this function performs no other precondition checks.
74
+ * otherwise a valid input — this function performs no other precondition checks.
62
75
  * @returns `true` when `rawHref` passes the allowlist, `false` otherwise.
63
- * @complexity O(1) — a handful of string checks plus one `URL` construction on the `/…` branch.
76
+ * @complexity O — a handful of string checks plus one `URL` construction on the `/…` branch.
64
77
  */
65
- export declare function isAllowedHref(rawHref: string): boolean;
78
+ export declare function isAllowedHref({ rawHref }: {
79
+ rawHref: string;
80
+ }, _optional?: Record<string, never>): boolean;
66
81
  /**
67
82
  * Human-readable description of {@link isAllowedHref}'s accepted shapes — the single source of truth
68
83
  * for both `validateTarget`'s rejection message below and `agent-tools.ts`'s published JSON Schema
@@ -80,31 +95,33 @@ export interface TreeValidationLimits {
80
95
  *
81
96
  * Checks (total/bounded validation + target integrity):
82
97
  * - `items` (and every `children` array) is actually an array, and every node
83
- * in it is a non-null object — untrusted JSON bodies can carry `null`
84
- * entries or a non-array `items`/`children`, which must reject as a
85
- * `MenuValidationError`, not throw an uncaught `TypeError`;
98
+ * in it is a non-null object — untrusted JSON bodies can carry `null`
99
+ * entries or a non-array `items`/`children`, which must reject as a
100
+ * `MenuValidationError`, not throw an uncaught `TypeError`;
86
101
  * - every node has a non-empty `id`, unique across the whole tree (id
87
- * stability is a caller responsibility — see `updateMenuTree` doc for the
88
- * simplification this build accepts);
102
+ * stability is a caller responsibility — see `updateMenuTree` doc for the
103
+ * simplification this build accepts);
89
104
  * - nesting depth stays within `maxDepth`;
90
105
  * - total item count stays within `maxItemCount`;
91
106
  * - every node has a `target` object (a missing/`null` `target` rejects
92
- * rather than crashing) whose `kind` is one of the four v1 kinds — reserved
93
- * kinds (`dynamicQuery`, `content`) are rejected with a clear "not yet"
94
- * error rather than silently accepted;
107
+ * rather than crashing) whose `kind` is one of the four v1 kinds — reserved
108
+ * kinds (`dynamicQuery`, `content`) are rejected with a clear "not yet"
109
+ * error rather than silently accepted;
95
110
  * - `url` targets require a non-empty string `href` and pass an origin/scheme
96
- * ALLOWLIST (`#…`, same-origin `/…`, `http(s)://`, `mailto:` — see
97
- * {@link isAllowedHref}), not a scheme denylist.
111
+ * ALLOWLIST (`#…`, same-origin `/…`, `http(s)://`, `mailto:` — see
112
+ * {@link isAllowedHref}), not a scheme denylist.
98
113
  *
99
114
  * @complexity O(n) over total node count for one full walk; no per-node
100
115
  * backtracking. Space is O(n) for the cloned tree plus O(n) for the id set.
101
116
  * @overallScore 100
102
117
  */
103
- export declare function validateAndCloneTree(items: readonly NavItemNode[], limits?: TreeValidationLimits): NavItemNode[];
118
+ export declare function validateAndCloneTree({ items }: {
119
+ items: readonly NavItemNode[];
120
+ }, limits?: TreeValidationLimits): NavItemNode[];
104
121
  export interface CreateMenuDeps {
105
122
  repo: MenuRepoPort;
106
- clock: ClockPort;
107
- idGen: IdGeneratorPort;
123
+ clock: Clock;
124
+ idGen: IdGenerator;
108
125
  /** Enqueues `navigation.menu.created` after a successful save. */
109
126
  outbox: OutboxPort;
110
127
  }
@@ -142,9 +159,9 @@ export declare function createMenu(required: CreateMenuRequired, optional?: Crea
142
159
  }>;
143
160
  export interface UpdateMenuTreeDeps {
144
161
  repo: MenuRepoPort;
145
- clock: ClockPort;
162
+ clock: Clock;
146
163
  /** Not previously present on this deps bag — needed to mint the outbox event's id. */
147
- idGen: IdGeneratorPort;
164
+ idGen: IdGenerator;
148
165
  /** Enqueues `navigation.menu.updated` after a successful save. */
149
166
  outbox: OutboxPort;
150
167
  }
@@ -176,7 +193,7 @@ export interface UpdateMenuTreeOptional {
176
193
  * previous tree and is deferred — a caller-discipline requirement for now,
177
194
  * not a runtime-enforced invariant.
178
195
  *
179
- * @complexity O(n) in the new tree size for validation; O(1) additional repo
196
+ * @complexity O(n) in the new tree size for validation; O additional repo
180
197
  * calls (one read, at most one slug-uniqueness read, one write).
181
198
  * @overallScore 90
182
199
  * @findings Medium: id-stability across edits (ids not renumbered on survive)
@@ -191,9 +208,9 @@ export declare function updateMenuTree(required: UpdateMenuTreeRequired, optiona
191
208
  export interface AssignLocationDeps {
192
209
  repo: MenuRepoPort;
193
210
  bindingRepo: NavLocationBindingRepoPort;
194
- clock: ClockPort;
211
+ clock: Clock;
195
212
  /** Not previously present on this deps bag — needed to mint outbox event ids. */
196
- idGen: IdGeneratorPort;
213
+ idGen: IdGenerator;
197
214
  /** Enqueues `navigation.location.assigned` (+ `.unassigned` on reassignment). */
198
215
  outbox: OutboxPort;
199
216
  }
@@ -229,7 +246,7 @@ export interface AssignLocationOptional {
229
246
  * transaction machinery — do not copy this sequencing pattern into code that
230
247
  * has real transactions available.
231
248
  *
232
- * @complexity O(1) repo calls (bounded: at most two menu reads/writes plus one
249
+ * @complexity O repo calls (bounded: at most two menu reads/writes plus one
233
250
  * binding upsert), independent of workspace size.
234
251
  * @overallScore 90
235
252
  * @findings Medium: no rollback across the two writes (menu save, then
@@ -246,9 +263,9 @@ export declare function assignLocation(required: AssignLocationRequired, _option
246
263
  export interface DeleteMenuDeps {
247
264
  repo: MenuRepoPort;
248
265
  bindingRepo: NavLocationBindingRepoPort;
249
- clock: ClockPort;
266
+ clock: Clock;
250
267
  /** Not previously present on this deps bag — needed to mint outbox event ids. */
251
- idGen: IdGeneratorPort;
268
+ idGen: IdGenerator;
252
269
  /** Enqueues `navigation.menu.updated` (trash) or `navigation.menu.deleted` (purge); nothing on a blocked purge. */
253
270
  outbox: OutboxPort;
254
271
  }
@@ -267,17 +284,17 @@ export interface DeleteMenuOptional {
267
284
  /**
268
285
  * Deletion ladder (mirrors the media library's):
269
286
  * 1. First call on a non-trashed menu **soft-deletes** it (`status: 'trash'`,
270
- * revisioned) and returns — no purge yet.
271
- * 2. A second call on an already-trashed menu attempts the **hard purge**. If
272
- * the menu is still bound to any location, purge is rejected with
273
- * `MenuLocationBoundError` (409-style) listing the bound keys, unless
274
- * `force` is set — permission-gating that error behind
275
- * `navigation.delete.force` is the caller's (gateway's) job, not this
276
- * function's; this function only enforces the *shape* of the guard.
287
+ * revisioned) and returns — no purge yet.
288
+ * 2. A second call on an already-trashed menu attempts the **hard purge** If
289
+ * the menu is still bound to any location, purge is rejected with
290
+ * `MenuLocationBoundError` (409-style) listing the bound keys, unless
291
+ * `force` is set — permission-gating that error behind
292
+ * `navigation.delete.force` is the caller's (gateway's) job, not this
293
+ * function's; this function only enforces the *shape* of the guard.
277
294
  * 3. On a successful purge, the menu row and all of its location bindings are
278
- * removed.
295
+ * removed.
279
296
  *
280
- * @complexity O(1) repo calls; O(k) bindings scanned where k = locations this
297
+ * @complexity O repo calls; O(k) bindings scanned where k = locations this
281
298
  * menu holds (small, bounded by registered locations).
282
299
  * @overallScore 100
283
300
  */