@aphexcms/cms-core 9.7.0 → 9.8.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 (326) hide show
  1. package/dist/agent-chat-state.svelte.d.ts +38 -0
  2. package/dist/agent-chat-state.svelte.d.ts.map +1 -0
  3. package/dist/agent-chat-state.svelte.js +86 -0
  4. package/dist/ai/content-workspace-tools.d.ts +3 -0
  5. package/dist/ai/content-workspace-tools.d.ts.map +1 -0
  6. package/dist/ai/content-workspace-tools.js +50 -0
  7. package/dist/ai/default-system-prompt.d.ts +2 -0
  8. package/dist/ai/default-system-prompt.d.ts.map +1 -0
  9. package/dist/ai/default-system-prompt.js +15 -0
  10. package/dist/ai/index.d.ts +2 -0
  11. package/dist/ai/index.d.ts.map +1 -0
  12. package/dist/ai/index.js +4 -0
  13. package/dist/ai/interfaces/ai-provider.d.ts +67 -0
  14. package/dist/ai/interfaces/ai-provider.d.ts.map +1 -0
  15. package/dist/ai/interfaces/ai-provider.js +16 -0
  16. package/dist/ai/run-agent-turn.d.ts +29 -0
  17. package/dist/ai/run-agent-turn.d.ts.map +1 -0
  18. package/dist/ai/run-agent-turn.js +166 -0
  19. package/dist/api/agent-chat.d.ts +27 -0
  20. package/dist/api/agent-chat.d.ts.map +1 -0
  21. package/dist/api/agent-chat.js +64 -0
  22. package/dist/api/documents.d.ts +8 -3
  23. package/dist/api/documents.d.ts.map +1 -1
  24. package/dist/api/documents.js +6 -6
  25. package/dist/api/schemas/agent-chat.d.ts +45 -0
  26. package/dist/api/schemas/agent-chat.d.ts.map +1 -0
  27. package/dist/api/schemas/agent-chat.js +35 -0
  28. package/dist/api/schemas/agent-operations.d.ts +13 -0
  29. package/dist/api/schemas/agent-operations.d.ts.map +1 -0
  30. package/dist/api/schemas/agent-operations.js +15 -0
  31. package/dist/api/schemas/documents.d.ts +22 -0
  32. package/dist/api/schemas/documents.d.ts.map +1 -1
  33. package/dist/api/schemas/documents.js +20 -2
  34. package/dist/chunk-recovery.d.ts +33 -0
  35. package/dist/chunk-recovery.d.ts.map +1 -0
  36. package/dist/chunk-recovery.js +131 -0
  37. package/dist/client/index.d.ts +1 -0
  38. package/dist/client/index.d.ts.map +1 -1
  39. package/dist/client/index.js +1 -0
  40. package/dist/client/ui.d.ts +1 -0
  41. package/dist/client/ui.d.ts.map +1 -1
  42. package/dist/client/ui.js +1 -0
  43. package/dist/components/AdminApp.svelte +37 -3
  44. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  45. package/dist/components/admin/ActivityView.svelte +251 -42
  46. package/dist/components/admin/ActivityView.svelte.d.ts.map +1 -1
  47. package/dist/components/admin/AgentChat.svelte +977 -0
  48. package/dist/components/admin/AgentChat.svelte.d.ts +17 -0
  49. package/dist/components/admin/AgentChat.svelte.d.ts.map +1 -0
  50. package/dist/components/admin/DocumentEditor.svelte +273 -60
  51. package/dist/components/admin/DocumentEditor.svelte.d.ts +6 -0
  52. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  53. package/dist/components/admin/ObjectModal.svelte +4 -2
  54. package/dist/components/admin/fields/ArrayField.svelte +4 -1
  55. package/dist/components/admin/fields/ReferenceField.svelte +12 -1
  56. package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
  57. package/dist/components/index.d.ts +1 -0
  58. package/dist/components/index.d.ts.map +1 -1
  59. package/dist/components/index.js +1 -0
  60. package/dist/components/layout/Sidebar.svelte +26 -2
  61. package/dist/components/layout/Sidebar.svelte.d.ts +1 -0
  62. package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
  63. package/dist/db/interfaces/agent-change-sets.d.ts +17 -0
  64. package/dist/db/interfaces/agent-change-sets.d.ts.map +1 -0
  65. package/dist/db/interfaces/agent-change-sets.js +1 -0
  66. package/dist/db/interfaces/document.d.ts +25 -3
  67. package/dist/db/interfaces/document.d.ts.map +1 -1
  68. package/dist/db/interfaces/document.js +19 -1
  69. package/dist/db/interfaces/index.d.ts +4 -1
  70. package/dist/db/interfaces/index.d.ts.map +1 -1
  71. package/dist/db/interfaces/index.js +1 -1
  72. package/dist/document-refresh.svelte.d.ts +2 -0
  73. package/dist/document-refresh.svelte.d.ts.map +1 -1
  74. package/dist/document-refresh.svelte.js +15 -0
  75. package/dist/document-workspace-registry.svelte.d.ts +15 -0
  76. package/dist/document-workspace-registry.svelte.d.ts.map +1 -0
  77. package/dist/document-workspace-registry.svelte.js +30 -0
  78. package/dist/field-validation/utils.d.ts.map +1 -1
  79. package/dist/field-validation/utils.js +211 -29
  80. package/dist/hooks.d.ts +2 -0
  81. package/dist/hooks.d.ts.map +1 -1
  82. package/dist/hooks.js +2 -0
  83. package/dist/lib/agent-chat-state.svelte.d.ts +38 -0
  84. package/dist/lib/agent-chat-state.svelte.d.ts.map +1 -0
  85. package/dist/lib/agent-chat-state.svelte.js +87 -0
  86. package/dist/lib/agent-chat-state.svelte.js.map +1 -0
  87. package/dist/lib/ai/content-workspace-tools.d.ts +3 -0
  88. package/dist/lib/ai/content-workspace-tools.d.ts.map +1 -0
  89. package/dist/lib/ai/content-workspace-tools.js +51 -0
  90. package/dist/lib/ai/content-workspace-tools.js.map +1 -0
  91. package/dist/lib/ai/default-system-prompt.d.ts +2 -0
  92. package/dist/lib/ai/default-system-prompt.d.ts.map +1 -0
  93. package/dist/lib/ai/default-system-prompt.js +16 -0
  94. package/dist/lib/ai/default-system-prompt.js.map +1 -0
  95. package/dist/lib/ai/index.d.ts +2 -0
  96. package/dist/lib/ai/index.d.ts.map +1 -0
  97. package/dist/lib/ai/index.js +5 -0
  98. package/dist/lib/ai/index.js.map +1 -0
  99. package/dist/lib/ai/interfaces/ai-provider.d.ts +67 -0
  100. package/dist/lib/ai/interfaces/ai-provider.d.ts.map +1 -0
  101. package/dist/lib/ai/interfaces/ai-provider.js +17 -0
  102. package/dist/lib/ai/interfaces/ai-provider.js.map +1 -0
  103. package/dist/lib/ai/run-agent-turn.d.ts +29 -0
  104. package/dist/lib/ai/run-agent-turn.d.ts.map +1 -0
  105. package/dist/lib/ai/run-agent-turn.js +167 -0
  106. package/dist/lib/ai/run-agent-turn.js.map +1 -0
  107. package/dist/lib/api/agent-chat.d.ts +27 -0
  108. package/dist/lib/api/agent-chat.d.ts.map +1 -0
  109. package/dist/lib/api/agent-chat.js +65 -0
  110. package/dist/lib/api/agent-chat.js.map +1 -0
  111. package/dist/lib/api/documents.d.ts +8 -3
  112. package/dist/lib/api/documents.d.ts.map +1 -1
  113. package/dist/lib/api/documents.js +6 -6
  114. package/dist/lib/api/documents.js.map +1 -1
  115. package/dist/lib/api/schemas/agent-chat.d.ts +45 -0
  116. package/dist/lib/api/schemas/agent-chat.d.ts.map +1 -0
  117. package/dist/lib/api/schemas/agent-chat.js +36 -0
  118. package/dist/lib/api/schemas/agent-chat.js.map +1 -0
  119. package/dist/lib/api/schemas/agent-operations.d.ts +13 -0
  120. package/dist/lib/api/schemas/agent-operations.d.ts.map +1 -0
  121. package/dist/lib/api/schemas/agent-operations.js +16 -0
  122. package/dist/lib/api/schemas/agent-operations.js.map +1 -0
  123. package/dist/lib/api/schemas/documents.d.ts +22 -0
  124. package/dist/lib/api/schemas/documents.d.ts.map +1 -1
  125. package/dist/lib/api/schemas/documents.js +20 -2
  126. package/dist/lib/api/schemas/documents.js.map +1 -1
  127. package/dist/lib/chunk-recovery.d.ts +33 -0
  128. package/dist/lib/chunk-recovery.d.ts.map +1 -0
  129. package/dist/lib/chunk-recovery.js +132 -0
  130. package/dist/lib/chunk-recovery.js.map +1 -0
  131. package/dist/lib/client/index.d.ts +1 -0
  132. package/dist/lib/client/index.d.ts.map +1 -1
  133. package/dist/lib/client/index.js +1 -0
  134. package/dist/lib/client/index.js.map +1 -1
  135. package/dist/lib/client/ui.d.ts +1 -0
  136. package/dist/lib/client/ui.d.ts.map +1 -1
  137. package/dist/lib/client/ui.js +1 -0
  138. package/dist/lib/client/ui.js.map +1 -1
  139. package/dist/lib/components/index.d.ts +1 -0
  140. package/dist/lib/components/index.d.ts.map +1 -1
  141. package/dist/lib/components/index.js +1 -0
  142. package/dist/lib/components/index.js.map +1 -1
  143. package/dist/lib/db/interfaces/agent-change-sets.d.ts +17 -0
  144. package/dist/lib/db/interfaces/agent-change-sets.d.ts.map +1 -0
  145. package/dist/lib/db/interfaces/agent-change-sets.js +2 -0
  146. package/dist/lib/db/interfaces/agent-change-sets.js.map +1 -0
  147. package/dist/lib/db/interfaces/document.d.ts +25 -3
  148. package/dist/lib/db/interfaces/document.d.ts.map +1 -1
  149. package/dist/lib/db/interfaces/document.js +19 -1
  150. package/dist/lib/db/interfaces/document.js.map +1 -1
  151. package/dist/lib/db/interfaces/index.d.ts +4 -1
  152. package/dist/lib/db/interfaces/index.d.ts.map +1 -1
  153. package/dist/lib/db/interfaces/index.js +1 -1
  154. package/dist/lib/db/interfaces/index.js.map +1 -1
  155. package/dist/lib/document-refresh.svelte.d.ts +2 -0
  156. package/dist/lib/document-refresh.svelte.d.ts.map +1 -1
  157. package/dist/lib/document-refresh.svelte.js +15 -0
  158. package/dist/lib/document-refresh.svelte.js.map +1 -1
  159. package/dist/lib/document-workspace-registry.svelte.d.ts +15 -0
  160. package/dist/lib/document-workspace-registry.svelte.d.ts.map +1 -0
  161. package/dist/lib/document-workspace-registry.svelte.js +31 -0
  162. package/dist/lib/document-workspace-registry.svelte.js.map +1 -0
  163. package/dist/lib/field-validation/utils.d.ts.map +1 -1
  164. package/dist/lib/field-validation/utils.js +211 -29
  165. package/dist/lib/field-validation/utils.js.map +1 -1
  166. package/dist/lib/hooks.d.ts +2 -0
  167. package/dist/lib/hooks.d.ts.map +1 -1
  168. package/dist/lib/hooks.js +2 -0
  169. package/dist/lib/hooks.js.map +1 -1
  170. package/dist/lib/local-api/collection-api.d.ts +7 -2
  171. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  172. package/dist/lib/local-api/collection-api.js +17 -10
  173. package/dist/lib/local-api/collection-api.js.map +1 -1
  174. package/dist/lib/mcp/tools.d.ts +39 -4
  175. package/dist/lib/mcp/tools.d.ts.map +1 -1
  176. package/dist/lib/mcp/tools.js +546 -362
  177. package/dist/lib/mcp/tools.js.map +1 -1
  178. package/dist/lib/plugins/resolver.d.ts +8 -1
  179. package/dist/lib/plugins/resolver.d.ts.map +1 -1
  180. package/dist/lib/plugins/resolver.js +14 -1
  181. package/dist/lib/plugins/resolver.js.map +1 -1
  182. package/dist/lib/plugins/types.d.ts +23 -2
  183. package/dist/lib/plugins/types.d.ts.map +1 -1
  184. package/dist/lib/plugins/types.js.map +1 -1
  185. package/dist/lib/preview/stega.d.ts +2 -2
  186. package/dist/lib/preview/stega.d.ts.map +1 -1
  187. package/dist/lib/preview/stega.js +52 -29
  188. package/dist/lib/preview/stega.js.map +1 -1
  189. package/dist/lib/schema-utils/validator.d.ts.map +1 -1
  190. package/dist/lib/schema-utils/validator.js +5 -2
  191. package/dist/lib/schema-utils/validator.js.map +1 -1
  192. package/dist/lib/server/api/index.d.ts.map +1 -1
  193. package/dist/lib/server/api/index.js +8 -0
  194. package/dist/lib/server/api/index.js.map +1 -1
  195. package/dist/lib/server/api/routes/agent-change-sets.d.ts +4 -0
  196. package/dist/lib/server/api/routes/agent-change-sets.d.ts.map +1 -0
  197. package/dist/lib/server/api/routes/agent-change-sets.js +132 -0
  198. package/dist/lib/server/api/routes/agent-change-sets.js.map +1 -0
  199. package/dist/lib/server/api/routes/agent-chat.d.ts +14 -0
  200. package/dist/lib/server/api/routes/agent-chat.d.ts.map +1 -0
  201. package/dist/lib/server/api/routes/agent-chat.js +224 -0
  202. package/dist/lib/server/api/routes/agent-chat.js.map +1 -0
  203. package/dist/lib/server/api/routes/document-versions.d.ts.map +1 -1
  204. package/dist/lib/server/api/routes/document-versions.js +16 -2
  205. package/dist/lib/server/api/routes/document-versions.js.map +1 -1
  206. package/dist/lib/server/api/routes/documents-by-id.d.ts.map +1 -1
  207. package/dist/lib/server/api/routes/documents-by-id.js +11 -1
  208. package/dist/lib/server/api/routes/documents-by-id.js.map +1 -1
  209. package/dist/lib/server/api/routes/documents-publish.d.ts.map +1 -1
  210. package/dist/lib/server/api/routes/documents-publish.js +36 -3
  211. package/dist/lib/server/api/routes/documents-publish.js.map +1 -1
  212. package/dist/lib/server/api/routes/jobs.d.ts.map +1 -1
  213. package/dist/lib/server/api/routes/jobs.js +4 -2
  214. package/dist/lib/server/api/routes/jobs.js.map +1 -1
  215. package/dist/lib/server/api/routes/resolve-created-by.d.ts +13 -0
  216. package/dist/lib/server/api/routes/resolve-created-by.d.ts.map +1 -0
  217. package/dist/lib/server/api/routes/resolve-created-by.js +31 -0
  218. package/dist/lib/server/api/routes/resolve-created-by.js.map +1 -0
  219. package/dist/lib/server/index.d.ts +1 -0
  220. package/dist/lib/server/index.d.ts.map +1 -1
  221. package/dist/lib/server/index.js +1 -0
  222. package/dist/lib/server/index.js.map +1 -1
  223. package/dist/lib/services/version-service.d.ts +4 -4
  224. package/dist/lib/services/version-service.d.ts.map +1 -1
  225. package/dist/lib/services/version-service.js +15 -11
  226. package/dist/lib/services/version-service.js.map +1 -1
  227. package/dist/lib/type-gen.d.ts.map +1 -1
  228. package/dist/lib/type-gen.js +11 -0
  229. package/dist/lib/type-gen.js.map +1 -1
  230. package/dist/lib/types/agent-change-sets.d.ts +70 -0
  231. package/dist/lib/types/agent-change-sets.d.ts.map +1 -0
  232. package/dist/lib/types/agent-change-sets.js +7 -0
  233. package/dist/lib/types/agent-change-sets.js.map +1 -0
  234. package/dist/lib/types/agent-stream.d.ts +60 -0
  235. package/dist/lib/types/agent-stream.d.ts.map +1 -0
  236. package/dist/lib/types/agent-stream.js +12 -0
  237. package/dist/lib/types/agent-stream.js.map +1 -0
  238. package/dist/lib/types/agent-tools.d.ts +65 -0
  239. package/dist/lib/types/agent-tools.d.ts.map +1 -0
  240. package/dist/lib/types/agent-tools.js +2 -0
  241. package/dist/lib/types/agent-tools.js.map +1 -0
  242. package/dist/lib/types/config.d.ts +19 -0
  243. package/dist/lib/types/config.d.ts.map +1 -1
  244. package/dist/lib/types/document-workspace.d.ts +53 -0
  245. package/dist/lib/types/document-workspace.d.ts.map +1 -0
  246. package/dist/lib/types/document-workspace.js +15 -0
  247. package/dist/lib/types/document-workspace.js.map +1 -0
  248. package/dist/lib/types/document.d.ts +5 -0
  249. package/dist/lib/types/document.d.ts.map +1 -1
  250. package/dist/lib/types/index.d.ts +2 -0
  251. package/dist/lib/types/index.d.ts.map +1 -1
  252. package/dist/lib/types/index.js +2 -0
  253. package/dist/lib/types/index.js.map +1 -1
  254. package/dist/lib/types/schemas.js +1 -1
  255. package/dist/lib/types/schemas.js.map +1 -1
  256. package/dist/lib/utils/fetch-remote-file.d.ts +11 -0
  257. package/dist/lib/utils/fetch-remote-file.d.ts.map +1 -0
  258. package/dist/lib/utils/fetch-remote-file.js +169 -0
  259. package/dist/lib/utils/fetch-remote-file.js.map +1 -0
  260. package/dist/local-api/collection-api.d.ts +7 -2
  261. package/dist/local-api/collection-api.d.ts.map +1 -1
  262. package/dist/local-api/collection-api.js +17 -10
  263. package/dist/mcp/tools.d.ts +39 -4
  264. package/dist/mcp/tools.d.ts.map +1 -1
  265. package/dist/mcp/tools.js +546 -362
  266. package/dist/plugins/resolver.d.ts +8 -1
  267. package/dist/plugins/resolver.d.ts.map +1 -1
  268. package/dist/plugins/resolver.js +14 -1
  269. package/dist/plugins/types.d.ts +23 -2
  270. package/dist/plugins/types.d.ts.map +1 -1
  271. package/dist/preview/stega.d.ts +2 -2
  272. package/dist/preview/stega.d.ts.map +1 -1
  273. package/dist/preview/stega.js +52 -29
  274. package/dist/schema-utils/validator.d.ts.map +1 -1
  275. package/dist/schema-utils/validator.js +5 -2
  276. package/dist/server/api/index.d.ts.map +1 -1
  277. package/dist/server/api/index.js +8 -0
  278. package/dist/server/api/routes/agent-change-sets.d.ts +4 -0
  279. package/dist/server/api/routes/agent-change-sets.d.ts.map +1 -0
  280. package/dist/server/api/routes/agent-change-sets.js +131 -0
  281. package/dist/server/api/routes/agent-chat.d.ts +14 -0
  282. package/dist/server/api/routes/agent-chat.d.ts.map +1 -0
  283. package/dist/server/api/routes/agent-chat.js +223 -0
  284. package/dist/server/api/routes/document-versions.d.ts.map +1 -1
  285. package/dist/server/api/routes/document-versions.js +16 -2
  286. package/dist/server/api/routes/documents-by-id.d.ts.map +1 -1
  287. package/dist/server/api/routes/documents-by-id.js +11 -1
  288. package/dist/server/api/routes/documents-publish.d.ts.map +1 -1
  289. package/dist/server/api/routes/documents-publish.js +36 -3
  290. package/dist/server/api/routes/jobs.d.ts.map +1 -1
  291. package/dist/server/api/routes/jobs.js +4 -2
  292. package/dist/server/api/routes/resolve-created-by.d.ts +13 -0
  293. package/dist/server/api/routes/resolve-created-by.d.ts.map +1 -0
  294. package/dist/server/api/routes/resolve-created-by.js +30 -0
  295. package/dist/server/index.d.ts +1 -0
  296. package/dist/server/index.d.ts.map +1 -1
  297. package/dist/server/index.js +1 -0
  298. package/dist/services/version-service.d.ts +4 -4
  299. package/dist/services/version-service.d.ts.map +1 -1
  300. package/dist/services/version-service.js +15 -11
  301. package/dist/type-gen.d.ts.map +1 -1
  302. package/dist/type-gen.js +11 -0
  303. package/dist/types/agent-change-sets.d.ts +70 -0
  304. package/dist/types/agent-change-sets.d.ts.map +1 -0
  305. package/dist/types/agent-change-sets.js +6 -0
  306. package/dist/types/agent-stream.d.ts +60 -0
  307. package/dist/types/agent-stream.d.ts.map +1 -0
  308. package/dist/types/agent-stream.js +11 -0
  309. package/dist/types/agent-tools.d.ts +65 -0
  310. package/dist/types/agent-tools.d.ts.map +1 -0
  311. package/dist/types/agent-tools.js +1 -0
  312. package/dist/types/config.d.ts +19 -0
  313. package/dist/types/config.d.ts.map +1 -1
  314. package/dist/types/document-workspace.d.ts +53 -0
  315. package/dist/types/document-workspace.d.ts.map +1 -0
  316. package/dist/types/document-workspace.js +14 -0
  317. package/dist/types/document.d.ts +5 -0
  318. package/dist/types/document.d.ts.map +1 -1
  319. package/dist/types/index.d.ts +2 -0
  320. package/dist/types/index.d.ts.map +1 -1
  321. package/dist/types/index.js +2 -0
  322. package/dist/types/schemas.js +1 -1
  323. package/dist/utils/fetch-remote-file.d.ts +11 -0
  324. package/dist/utils/fetch-remote-file.d.ts.map +1 -0
  325. package/dist/utils/fetch-remote-file.js +168 -0
  326. package/package.json +5 -2
@@ -5,7 +5,7 @@
5
5
  * `config.plugins` and exposed on the engine so both server and admin consult the
6
6
  * same resolved model. Validates duplicate part ids up front — no silent overrides.
7
7
  */
8
- import type { AdminToolPart, CMSPlugin, DocumentActionPart, EventConsumerPart, FieldComponentPart, PartKind, PluginPart, ServerRoutePart, SettingsPart } from './types.js';
8
+ import type { AdminToolPart, AgentToolPart, CMSPlugin, DocumentActionPart, EventConsumerPart, FieldComponentPart, PartKind, PluginPart, ServerRoutePart, SettingsPart } from './types.js';
9
9
  import type { SchemaType } from '../types/schemas.js';
10
10
  import type { JobHandlerMap } from '../jobs/types.js';
11
11
  import { type CapabilityDefinition } from '../types/capabilities.js';
@@ -54,6 +54,13 @@ export interface PartResolver {
54
54
  eventConsumers(): EventConsumerPart[];
55
55
  /** Event consumers subscribed to a given event type — the relay's fan-out list. */
56
56
  consumersForEvent(eventType: string): EventConsumerPart[];
57
+ /**
58
+ * Tools visible to a caller with the given capability set — the advertisement
59
+ * filter. Execution must separately re-check `requiredCapabilities` against the
60
+ * actual invoking caller; never trust that a tool was only reachable because it
61
+ * was listed.
62
+ */
63
+ agentToolsForCapabilities(capabilities: string[], overrideAccess?: boolean): AgentToolPart[];
57
64
  }
58
65
  export declare function createPartResolver(plugins?: CMSPlugin[]): PartResolver;
59
66
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,YAAY,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,yEAAyE;IACzE,WAAW,IAAI,UAAU,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;IAC3D,gDAAgD;IAChD,YAAY,IAAI,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB;oEACgE;IAChE,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,sFAAsF;IACtF,eAAe,CAAC,IAAI,EAAE;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,kBAAkB,EAAE,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,EAAE,CAAC;IAC1F,sEAAsE;IACtE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC9D,+DAA+D;IAC/D,oBAAoB,IAAI,YAAY,EAAE,CAAC;IACvC,8DAA8D;IAC9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAChE;;;;OAIG;IACH,WAAW,IAAI,aAAa,CAAC;IAC7B,gHAAgH;IAChH,cAAc,IAAI,iBAAiB,EAAE,CAAC;IACtC,mFAAmF;IACnF,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;CAC1D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,SAAS,EAAO,GAAG,YAAY,CAwF1E"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,YAAY,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,yEAAyE;IACzE,WAAW,IAAI,UAAU,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;IAC3D,gDAAgD;IAChD,YAAY,IAAI,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB;oEACgE;IAChE,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,sFAAsF;IACtF,eAAe,CAAC,IAAI,EAAE;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,kBAAkB,EAAE,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,EAAE,CAAC;IAC1F,sEAAsE;IACtE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC9D,+DAA+D;IAC/D,oBAAoB,IAAI,YAAY,EAAE,CAAC;IACvC,8DAA8D;IAC9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAChE;;;;OAIG;IACH,WAAW,IAAI,aAAa,CAAC;IAC7B,gHAAgH;IAChH,cAAc,IAAI,iBAAiB,EAAE,CAAC;IACtC,mFAAmF;IACnF,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;IAC1D;;;;;OAKG;IACH,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,aAAa,EAAE,CAAC;CAC7F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,SAAS,EAAO,GAAG,YAAY,CA0G1E"}
@@ -27,6 +27,18 @@ export function createPartResolver(plugins = []) {
27
27
  }
28
28
  settingsIds.add(part.pluginId);
29
29
  }
30
+ // Agent tool parts key on `definition.name` (not a top-level `id`), so guard
31
+ // their uniqueness separately too — two tools sharing a name would collide in
32
+ // whatever registry the agent runtime builds from this list.
33
+ const agentToolNames = new Set();
34
+ for (const part of allParts) {
35
+ if (part.implements !== 'aphex/agent/tool')
36
+ continue;
37
+ if (agentToolNames.has(part.definition.name)) {
38
+ throw new Error(`Duplicate agent tool name "${part.definition.name}". Tool names must be unique across all plugins.`);
39
+ }
40
+ agentToolNames.add(part.definition.name);
41
+ }
30
42
  const getParts = (kind) => allParts.filter((p) => p.implements === kind);
31
43
  const hasCaps = (required, caps, overrideAccess) => overrideAccess || !required || required.length === 0 || required.every((c) => caps.includes(c));
32
44
  return {
@@ -63,6 +75,7 @@ export function createPartResolver(plugins = []) {
63
75
  settingsDeclaration: (pluginId) => getParts('aphex/settings').find((s) => s.pluginId === pluginId),
64
76
  jobHandlers: () => getParts('aphex/job/handler').reduce((acc, part) => ({ ...acc, ...part.handlers }), {}),
65
77
  eventConsumers: () => getParts('aphex/event/consumer'),
66
- consumersForEvent: (eventType) => getParts('aphex/event/consumer').filter((c) => c.events.includes(eventType))
78
+ consumersForEvent: (eventType) => getParts('aphex/event/consumer').filter((c) => c.events.includes(eventType)),
79
+ agentToolsForCapabilities: (capabilities, overrideAccess = false) => getParts('aphex/agent/tool').filter((t) => hasCaps(t.definition.requiredCapabilities, capabilities, overrideAccess))
67
80
  };
68
81
  }
@@ -20,8 +20,9 @@ import type { AdminArea } from '../admin/types.js';
20
20
  import type { CapabilityDefinition } from '../types/capabilities.js';
21
21
  import type { JobHandlerMap } from '../jobs/types.js';
22
22
  import type { EventConsumerHandler } from '../events/consumer.js';
23
+ import type { AgentToolDefinition, AgentToolExecutor } from '../types/agent-tools.js';
23
24
  /** Known extension points. Plugins may also register custom string kinds. */
24
- export type PartKind = 'aphex/schema' | 'aphex/schema/transform' | 'aphex/server/route' | 'aphex/capabilities' | 'aphex/settings' | 'aphex/job/handler' | 'aphex/event/consumer' | 'aphex/document/action' | 'aphex/admin/tool' | 'aphex/field/component';
25
+ export type PartKind = 'aphex/schema' | 'aphex/schema/transform' | 'aphex/server/route' | 'aphex/capabilities' | 'aphex/settings' | 'aphex/job/handler' | 'aphex/event/consumer' | 'aphex/agent/tool' | 'aphex/document/action' | 'aphex/admin/tool' | 'aphex/field/component';
25
26
  /** Contributes content schemas, merged into the app's `schemaTypes`. */
26
27
  export interface SchemaPart {
27
28
  implements: 'aphex/schema';
@@ -163,6 +164,26 @@ export interface EventConsumerPart {
163
164
  /** Retry budget for this consumer's delivery jobs before dead-lettering. Defaults to the queue default (5). */
164
165
  maxAttempts?: number;
165
166
  }
167
+ /**
168
+ * Contributes a tool an AI agent can call (MCP today; a future in-admin agent
169
+ * panel is meant to sit on the same contract — see Milestone 2 of
170
+ * references/content-copilot-phase-1-plan.md). `definition` is the
171
+ * serializable part (name/description/capabilities/zod schema) an LLM/UI
172
+ * needs to know the tool exists; `execute` is the function that actually runs
173
+ * it, receiving `LocalAPIContext`/`CMSInstances` as call-time arguments
174
+ * rather than a static import — the same shape `aphex/event/consumer` already
175
+ * uses to stay barrel-weight-safe in a part that may sit alongside
176
+ * client-shared code.
177
+ *
178
+ * `requiredCapabilities` on the definition is enforced at both advertisement
179
+ * and execution — a tool hidden from an unauthorized caller must also reject
180
+ * direct invocation, never rely on the advertisement filter alone.
181
+ */
182
+ export interface AgentToolPart {
183
+ implements: 'aphex/agent/tool';
184
+ definition: AgentToolDefinition;
185
+ execute: AgentToolExecutor;
186
+ }
166
187
  /**
167
188
  * A minimal, stable context handed to a document-action component. Deliberately
168
189
  * decoupled from editor internals — actions get exactly this and nothing more, so
@@ -259,7 +280,7 @@ export interface FieldComponentPart {
259
280
  input: string;
260
281
  component: Component<FieldComponentProps>;
261
282
  }
262
- export type PluginPart = SchemaPart | SchemaTransformPart | ServerRoutePart | CapabilitiesPart | SettingsPart | JobHandlerPart | EventConsumerPart | DocumentActionPart | AdminToolPart | FieldComponentPart;
283
+ export type PluginPart = SchemaPart | SchemaTransformPart | ServerRoutePart | CapabilitiesPart | SettingsPart | JobHandlerPart | EventConsumerPart | AgentToolPart | DocumentActionPart | AdminToolPart | FieldComponentPart;
263
284
  /** A plugin manifest. Returned by `definePlugin`. */
264
285
  export interface CMSPlugin {
265
286
  /** Package-style name, e.g. `@acme/aphex-plugin-seo`. Used in error messages. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { Field } from '../types/schemas.js';
1
+ import type { Field, SchemaType } from '../types/schemas.js';
2
2
  /**
3
3
  * Remove all stega-encoded data from a string or deep JSON structure.
4
4
  * Use in <svelte:head> (title, meta), alt text, aria-labels — anywhere the raw
@@ -21,5 +21,5 @@ export declare function stegaDecode(value: string): {
21
21
  * Every nested string always encodes the *top-level* field name so that clicking
22
22
  * in the preview navigates to the correct editor field.
23
23
  */
24
- export declare function stegaEncodeDocument(data: Record<string, unknown>, fields: Field[]): Record<string, unknown>;
24
+ export declare function stegaEncodeDocument(data: Record<string, unknown>, fields: Field[], schemas?: SchemaType[]): Record<string, unknown>;
25
25
  //# sourceMappingURL=stega.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stega.d.ts","sourceRoot":"","sources":["../../src/lib/preview/stega.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,qBAAqB,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEzC;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAUP;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,KAAK,EAAE,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
1
+ {"version":3,"file":"stega.d.ts","sourceRoot":"","sources":["../../src/lib/preview/stega.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAiB,MAAM,qBAAqB,CAAC;AAsB5E;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEzC;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAUP;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,UAAU,EAAO,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
@@ -1,4 +1,21 @@
1
1
  import { vercelStegaCombine, vercelStegaClean, vercelStegaDecode } from '@vercel/stega';
2
+ import { getSchemaByName } from '../schema-utils/utils.js';
3
+ /**
4
+ * Resolve the `fields` for an array member / block. Members are usually named type
5
+ * references (`{ type: 'doctorGridBlock' }`) with no inline `fields`, so without the
6
+ * schema registry the encoder can't reach into them and the item's text is never
7
+ * stega-encoded (invisible to click-to-edit). Prefer an inline `fields`, otherwise
8
+ * look the type up in the registry.
9
+ */
10
+ function resolveFields(typeRef, itemType, schemas) {
11
+ if (typeRef?.fields)
12
+ return typeRef.fields;
13
+ const name = itemType ?? typeRef?.type;
14
+ if (!name)
15
+ return undefined;
16
+ const schema = getSchemaByName(schemas, name);
17
+ return schema && 'fields' in schema ? schema.fields : undefined;
18
+ }
2
19
  /**
3
20
  * Remove all stega-encoded data from a string or deep JSON structure.
4
21
  * Use in <svelte:head> (title, meta), alt text, aria-labels — anywhere the raw
@@ -19,14 +36,14 @@ export function stegaDecode(value) {
19
36
  * Every nested string always encodes the *top-level* field name so that clicking
20
37
  * in the preview navigates to the correct editor field.
21
38
  */
22
- export function stegaEncodeDocument(data, fields) {
39
+ export function stegaEncodeDocument(data, fields, schemas = []) {
23
40
  const result = { ...data };
24
41
  for (const field of fields) {
25
42
  const val = result[field.name];
26
43
  if (val == null)
27
44
  continue;
28
45
  // objectPath is undefined at root — each field IS the top-level, no sub-path needed
29
- result[field.name] = encodeFieldValue(val, field, field.name, undefined);
46
+ result[field.name] = encodeFieldValue(val, field, field.name, undefined, schemas);
30
47
  }
31
48
  return result;
32
49
  }
@@ -35,7 +52,7 @@ export function stegaEncodeDocument(data, fields) {
35
52
  // editor knows which field to scroll to; objectPath carries the dotted sub-path
36
53
  // so the editor can drill into nested inputs.
37
54
  // ---------------------------------------------------------------------------
38
- function encodeFieldValue(val, field, topLevel, objectPath) {
55
+ function encodeFieldValue(val, field, topLevel, objectPath, schemas) {
39
56
  if (val == null)
40
57
  return val;
41
58
  const path = objectPath ? `${objectPath}.${field.name}` : field.name;
@@ -56,11 +73,14 @@ function encodeFieldValue(val, field, topLevel, objectPath) {
56
73
  return val;
57
74
  // Only forward objectPath when truly nested (inside an object); top-level
58
75
  // arrays must NOT get an objectPath or the arrayIndex navigation branch is skipped.
59
- return encodeArray(val, field.of, topLevel, objectPath ? path : undefined);
60
- case 'object':
61
- if (typeof val !== 'object' || !field.fields)
76
+ return encodeArray(val, field.of, topLevel, objectPath ? path : undefined, schemas);
77
+ case 'object': {
78
+ // Inline `fields`, or a named object type resolved from the registry.
79
+ const objFields = field.fields ?? resolveFields(field, field.type, schemas);
80
+ if (typeof val !== 'object' || !objFields)
62
81
  return val;
63
- return encodeObject(val, field.fields, topLevel, path);
82
+ return encodeObject(val, objFields, topLevel, path, schemas);
83
+ }
64
84
  // image, file, reference, slug, number, boolean, date, datetime — not text, skip.
65
85
  // Image click-to-edit is handled at render time (the frontend stega-encodes the
66
86
  // *effective* alt — override or asset default — so every image is clickable, not
@@ -69,12 +89,12 @@ function encodeFieldValue(val, field, topLevel, objectPath) {
69
89
  return val;
70
90
  }
71
91
  }
72
- function encodeArray(items, of, topLevel, objectPath) {
92
+ function encodeArray(items, of, topLevel, objectPath, schemas) {
73
93
  const hasBlock = of.some((t) => t.type === 'block');
74
94
  const firstType = of[0]?.type;
75
95
  if (hasBlock) {
76
96
  // Portable text — encode spans within blocks and string fields in custom block types
77
- return encodePortableText(items, of, topLevel);
97
+ return encodePortableText(items, of, topLevel, schemas);
78
98
  }
79
99
  if (firstType === 'string' || firstType === 'text') {
80
100
  // Primitive string array (e.g. tags) — include the item's array index
@@ -87,33 +107,34 @@ function encodeArray(items, of, topLevel, objectPath) {
87
107
  return vercelStegaCombine(item, payload);
88
108
  });
89
109
  }
90
- // Array of inline objects — encode each item's string fields
91
- if (of[0]?.fields) {
92
- return items.map((item, arrayIndex) => {
93
- if (!item || typeof item !== 'object')
94
- return item;
95
- const obj = item;
96
- const typeRef = of.find((t) => t.name === obj._type || t.type === obj._type) ?? of[0];
97
- if (!typeRef?.fields)
98
- return item;
99
- const itemPath = objectPath ? `${objectPath}[${arrayIndex}]` : `[${arrayIndex}]`;
100
- return encodeObject(obj, typeRef.fields, topLevel, itemPath);
101
- });
102
- }
103
- return items;
110
+ // Array of objects — either inline `fields` or named object-type references
111
+ // (`{ type: 'doctorGridBlock' }`) resolved from the schema registry. The latter is
112
+ // the common page-builder case, so resolving is what makes those blocks clickable.
113
+ return items.map((item, arrayIndex) => {
114
+ if (!item || typeof item !== 'object')
115
+ return item;
116
+ const obj = item;
117
+ const itemType = typeof obj._type === 'string' ? obj._type : undefined;
118
+ const typeRef = of.find((t) => t.name === obj._type || t.type === obj._type) ?? of[0];
119
+ const fields = resolveFields(typeRef, itemType, schemas);
120
+ if (!fields)
121
+ return item;
122
+ const itemPath = objectPath ? `${objectPath}[${arrayIndex}]` : `[${arrayIndex}]`;
123
+ return encodeObject(obj, fields, topLevel, itemPath, schemas);
124
+ });
104
125
  }
105
- function encodeObject(obj, fields, topLevel, objectPath) {
126
+ function encodeObject(obj, fields, topLevel, objectPath, schemas) {
106
127
  const result = { ...obj };
107
128
  for (const field of fields) {
108
129
  const val = result[field.name];
109
130
  if (val == null)
110
131
  continue;
111
- result[field.name] = encodeFieldValue(val, field, topLevel, objectPath);
132
+ result[field.name] = encodeFieldValue(val, field, topLevel, objectPath, schemas);
112
133
  }
113
134
  return result;
114
135
  }
115
136
  /** Encode portable text: spans in standard blocks + string fields in custom block types. */
116
- function encodePortableText(blocks, of, topLevel) {
137
+ function encodePortableText(blocks, of, topLevel, schemas) {
117
138
  return blocks.map((block, blockIndex) => {
118
139
  if (!block || typeof block !== 'object')
119
140
  return block;
@@ -142,10 +163,12 @@ function encodePortableText(blocks, of, topLevel) {
142
163
  if (b._type === 'image')
143
164
  return block;
144
165
  // Custom block type (callout, codeBlock, etc.) — encode string fields, carrying
145
- // blockIndex so clicking them opens the block's edit modal in the editor.
166
+ // blockIndex so clicking them opens the block's edit modal in the editor. Fields
167
+ // come from an inline definition or a named object type in the registry.
146
168
  const typeRef = of.find((t) => t.name === b._type || t.type === b._type);
147
- if (typeRef?.fields) {
148
- return encodeCustomBlock(b, typeRef.fields, topLevel, blockIndex);
169
+ const fields = resolveFields(typeRef, typeof b._type === 'string' ? b._type : undefined, schemas);
170
+ if (fields) {
171
+ return encodeCustomBlock(b, fields, topLevel, blockIndex);
149
172
  }
150
173
  return block;
151
174
  });
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAmOpE"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAwOpE"}
@@ -72,8 +72,11 @@ export function validateSchemaReferences(schemas) {
72
72
  errors.push(`Schema "${parentSchema}" uses reserved field name "${field.name}". Reserved names: ${RESERVED_FIELD_NAMES.join(', ')}`);
73
73
  }
74
74
  // Check array field references
75
- if (field.type === 'array' && field.of) {
76
- for (const arrayType of field.of) {
75
+ if (field.type === 'array') {
76
+ if (!field.of || field.of.length === 0) {
77
+ errors.push(`Schema "${parentSchema}" field "${field.name}" is an array with no "of" — declare at least one item type`);
78
+ }
79
+ for (const arrayType of field.of ?? []) {
77
80
  // Reference items inside an array must declare `to` and target known schemas
78
81
  if (arrayType.type === 'reference') {
79
82
  const to = arrayType.to;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAuB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QA6DrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAyB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAqErD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
@@ -21,6 +21,8 @@ import { userPreferencesRouter } from './routes/user-preferences.js';
21
21
  import { userRouter } from './routes/user.js';
22
22
  import { workersRunRouter } from './routes/workers-run.js';
23
23
  import { jobsRouter } from './routes/jobs.js';
24
+ import { agentChatRouter } from './routes/agent-chat.js';
25
+ import { agentChangeSetsRouter } from './routes/agent-change-sets.js';
24
26
  /**
25
27
  * Build the Aphex API Hono app shell.
26
28
  *
@@ -94,6 +96,12 @@ export function mountAphexBuiltins(app) {
94
96
  app.route('/internal/workers', workersRunRouter);
95
97
  // Read-only job/event history (observability). → GET /api/jobs, GET /api/events
96
98
  app.route('/', jobsRouter);
99
+ // In-admin agent streaming chat — 404s unless `aiProvider` is configured.
100
+ // → POST /api/agent/chat
101
+ app.route('/agent', agentChatRouter);
102
+ // Agent audit/undo trail. → GET /api/agent/change-sets, GET /api/agent/change-sets/:id,
103
+ // POST /api/agent/change-sets/:id/undo
104
+ app.route('/agent', agentChangeSetsRouter);
97
105
  // Health check — unauthenticated, used by load balancers and uptime monitors.
98
106
  app.get('/aphex-health', async (c) => {
99
107
  try {
@@ -0,0 +1,4 @@
1
+ import { Hono } from 'hono';
2
+ import type { AphexEnv } from '../index.js';
3
+ export declare const agentChangeSetsRouter: Hono<AphexEnv>;
4
+ //# sourceMappingURL=agent-change-sets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-change-sets.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/agent-change-sets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAqBzC,eAAO,MAAM,qBAAqB,EAAE,IAAI,CAAC,QAAQ,CAiI9C,CAAC"}
@@ -0,0 +1,131 @@
1
+ import { Hono } from 'hono';
2
+ import { z } from 'zod';
3
+ import { authToContext } from '../../../local-api/auth-helpers.js';
4
+ import { hasCapability } from '../../../types/capabilities.js';
5
+ import { RevisionConflictError } from '../../../db/interfaces.js';
6
+ import { cmsLogger } from '../../../utils/logger.js';
7
+ import { withCreatedByNames } from './resolve-created-by.js';
8
+ const listChangeSetsQuery = z.object({
9
+ limit: z.coerce.number().int().min(1).max(200).optional(),
10
+ offset: z.coerce.number().int().min(0).optional()
11
+ });
12
+ /** Map an adapter Page into the ApiResponse `pagination` shape the client expects. */
13
+ function toPagination(page) {
14
+ const pageSize = page.limit || 1;
15
+ return {
16
+ total: page.total,
17
+ page: Math.floor(page.offset / pageSize) + 1,
18
+ pageSize,
19
+ totalPages: Math.max(1, Math.ceil(page.total / pageSize)),
20
+ hasNextPage: page.offset + page.limit < page.total,
21
+ hasPrevPage: page.offset > 0
22
+ };
23
+ }
24
+ export const agentChangeSetsRouter = new Hono()
25
+ // Read-only audit history — visible to anyone who can read content, same posture as
26
+ // GET /api/jobs · /api/events (jobs.ts's requireHistoryAccess).
27
+ .get('/change-sets', async (c) => {
28
+ const auth = c.var.auth;
29
+ if (!auth || auth.type === 'partial_session') {
30
+ return c.json({ success: false, error: 'Authentication required' }, 401);
31
+ }
32
+ if (!hasCapability(auth, 'document.read')) {
33
+ return c.json({ success: false, error: 'Insufficient permissions' }, 403);
34
+ }
35
+ const q = listChangeSetsQuery.safeParse(c.req.query());
36
+ if (!q.success) {
37
+ return c.json({ success: false, error: 'Invalid query parameters', issues: q.error.issues }, 400);
38
+ }
39
+ const { organizationId } = authToContext(auth);
40
+ const page = await c.var.aphexCMS.databaseAdapter.listChangeSets({
41
+ organizationId,
42
+ limit: q.data.limit,
43
+ offset: q.data.offset
44
+ });
45
+ const items = await withCreatedByNames(page.items, c.var.aphexCMS.auth);
46
+ return c.json({ success: true, data: items, pagination: toPagination(page) });
47
+ })
48
+ .get('/change-sets/:id', async (c) => {
49
+ const auth = c.var.auth;
50
+ if (!auth || auth.type === 'partial_session') {
51
+ return c.json({ success: false, error: 'Authentication required' }, 401);
52
+ }
53
+ if (!hasCapability(auth, 'document.read')) {
54
+ return c.json({ success: false, error: 'Insufficient permissions' }, 403);
55
+ }
56
+ const { organizationId } = authToContext(auth);
57
+ const changeSet = await c.var.aphexCMS.databaseAdapter.getChangeSet(organizationId, c.req.param('id'));
58
+ if (!changeSet)
59
+ return c.json({ success: false, error: 'Not found' }, 404);
60
+ const [withName] = await withCreatedByNames([changeSet], c.var.aphexCMS.auth);
61
+ return c.json({ success: true, data: withName });
62
+ })
63
+ // Undo a whole turn: for every operation that mutated a document and has a
64
+ // `versionBefore` (create_document operations don't — see agent-change-sets.ts's doc
65
+ // comment), restore that document to it, in reverse order. Reuses the exact CAS-guarded
66
+ // primitive DocumentEditor's own version-restore already calls — undo is itself just
67
+ // another version-tracked draft write, not bespoke revert logic. A conflict (someone
68
+ // edited the document since the agent touched it) is reported per-operation rather than
69
+ // aborting the rest of the undo.
70
+ .post('/change-sets/:id/undo', async (c) => {
71
+ const auth = c.var.auth;
72
+ if (!auth || auth.type === 'partial_session') {
73
+ return c.json({ success: false, error: 'Authentication required' }, 401);
74
+ }
75
+ if (!hasCapability(auth, 'document.update')) {
76
+ return c.json({ success: false, error: 'Insufficient permissions' }, 403);
77
+ }
78
+ const context = authToContext(auth);
79
+ const { databaseAdapter, localAPI } = c.var.aphexCMS;
80
+ const changeSet = await databaseAdapter.getChangeSet(context.organizationId, c.req.param('id'));
81
+ if (!changeSet)
82
+ return c.json({ success: false, error: 'Not found' }, 404);
83
+ const undoable = changeSet.operations
84
+ .filter((op) => op.success && op.versionBefore !== null)
85
+ .reverse();
86
+ const results = [];
87
+ for (const op of undoable) {
88
+ try {
89
+ const collection = localAPI.getCollection(op.collection);
90
+ if (!collection) {
91
+ results.push({
92
+ operationId: op.id,
93
+ documentId: op.documentId,
94
+ success: false,
95
+ error: `Unknown collection: ${op.collection}`
96
+ });
97
+ continue;
98
+ }
99
+ // Fetch the current revision fresh on every iteration — undoing the previous
100
+ // operation in this same loop changes it, so a value read before the loop
101
+ // started would be stale by the time we get here.
102
+ const current = await collection.findByID(context, op.documentId);
103
+ const restored = await localAPI.versionService.restoreVersion(databaseAdapter, context.organizationId, op.documentId, op.versionBefore, context.user?.id, current?._meta?.revision);
104
+ results.push({
105
+ operationId: op.id,
106
+ documentId: op.documentId,
107
+ success: restored !== null,
108
+ error: restored === null ? 'Version not found or restore failed' : undefined
109
+ });
110
+ }
111
+ catch (err) {
112
+ if (err instanceof RevisionConflictError) {
113
+ results.push({
114
+ operationId: op.id,
115
+ documentId: op.documentId,
116
+ success: false,
117
+ error: `Changed since the agent's edit (conflict): ${err.message}`
118
+ });
119
+ continue;
120
+ }
121
+ cmsLogger.error('[agent-change-sets] undo failed for operation:', op.id, err);
122
+ results.push({
123
+ operationId: op.id,
124
+ documentId: op.documentId,
125
+ success: false,
126
+ error: err instanceof Error ? err.message : 'Unknown error'
127
+ });
128
+ }
129
+ }
130
+ return c.json({ success: true, data: { results } });
131
+ });
@@ -0,0 +1,14 @@
1
+ import { Hono } from 'hono';
2
+ import type { AphexEnv } from '../index.js';
3
+ import type { CMSInstances } from '../../../hooks.js';
4
+ import type { LocalAPIContext } from '../../../local-api/index.js';
5
+ /**
6
+ * Best-effort audit record for one mutating tool call — looks up the two most recent
7
+ * document-version rows to capture `versionBefore`/`versionAfter` (the version an undo would
8
+ * restore to, and the one this write produced), then records the operation. Never throws: a
9
+ * failure to record the audit trail must never break the actual tool call or the SSE stream.
10
+ * Exported for unit testing — not part of the route's own public surface.
11
+ */
12
+ export declare function recordMutatingOperation(aphexCMS: CMSInstances, context: LocalAPIContext, changeSetId: string, toolName: string, args: Record<string, unknown>, success: boolean, error: string | undefined, data: unknown): Promise<void>;
13
+ export declare const agentChatRouter: Hono<AphexEnv>;
14
+ //# sourceMappingURL=agent-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/agent-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAQzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAsBhE;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC5C,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,eAAO,MAAM,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAwB,CAAC"}