@tai42/api-client 16.0.0 → 16.0.1

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 (370) hide show
  1. package/dist/client/agents-client.d.ts +26 -0
  2. package/dist/client/agents-client.d.ts.map +1 -0
  3. package/dist/client/agents-client.js +19 -0
  4. package/dist/client/agents-client.js.map +1 -0
  5. package/dist/client/auth-client.d.ts +205 -0
  6. package/dist/client/auth-client.d.ts.map +1 -0
  7. package/dist/client/auth-client.js +59 -0
  8. package/dist/client/auth-client.js.map +1 -0
  9. package/dist/client/backend-client.d.ts +39 -0
  10. package/dist/client/backend-client.d.ts.map +1 -0
  11. package/dist/client/backend-client.js +22 -0
  12. package/dist/client/backend-client.js.map +1 -0
  13. package/dist/client/backup-client.d.ts +56 -0
  14. package/dist/client/backup-client.d.ts.map +1 -0
  15. package/dist/client/backup-client.js +12 -0
  16. package/dist/client/backup-client.js.map +1 -0
  17. package/dist/client/capabilities-client.d.ts +35 -0
  18. package/dist/client/capabilities-client.d.ts.map +1 -0
  19. package/dist/client/capabilities-client.js +19 -0
  20. package/dist/client/capabilities-client.js.map +1 -0
  21. package/dist/client/channels-client.d.ts +7 -0
  22. package/dist/client/channels-client.d.ts.map +1 -0
  23. package/dist/client/channels-client.js +10 -0
  24. package/dist/client/channels-client.js.map +1 -0
  25. package/dist/client/config-client.d.ts +59 -0
  26. package/dist/client/config-client.d.ts.map +1 -0
  27. package/dist/client/config-client.js +18 -0
  28. package/dist/client/config-client.js.map +1 -0
  29. package/dist/client/connectors-client.d.ts +225 -0
  30. package/dist/client/connectors-client.d.ts.map +1 -0
  31. package/dist/client/connectors-client.js +31 -0
  32. package/dist/client/connectors-client.js.map +1 -0
  33. package/dist/client/conversations-client.d.ts +399 -0
  34. package/dist/client/conversations-client.d.ts.map +1 -0
  35. package/dist/client/conversations-client.js +120 -0
  36. package/dist/client/conversations-client.js.map +1 -0
  37. package/dist/client/hooks-client.d.ts +113 -0
  38. package/dist/client/hooks-client.d.ts.map +1 -0
  39. package/dist/client/hooks-client.js +25 -0
  40. package/dist/client/hooks-client.js.map +1 -0
  41. package/dist/{client.d.ts → client/index.d.ts} +2235 -2666
  42. package/dist/client/index.d.ts.map +1 -0
  43. package/dist/client/index.js +79 -0
  44. package/dist/client/index.js.map +1 -0
  45. package/dist/client/interactions-client.d.ts +52 -0
  46. package/dist/client/interactions-client.d.ts.map +1 -0
  47. package/dist/client/interactions-client.js +84 -0
  48. package/dist/client/interactions-client.js.map +1 -0
  49. package/dist/client/login-client.d.ts +56 -0
  50. package/dist/client/login-client.d.ts.map +1 -0
  51. package/dist/client/login-client.js +103 -0
  52. package/dist/client/login-client.js.map +1 -0
  53. package/dist/client/manifest-client.d.ts +354 -0
  54. package/dist/client/manifest-client.d.ts.map +1 -0
  55. package/dist/client/manifest-client.js +76 -0
  56. package/dist/client/manifest-client.js.map +1 -0
  57. package/dist/client/marketplace-client.d.ts +274 -0
  58. package/dist/client/marketplace-client.d.ts.map +1 -0
  59. package/dist/client/marketplace-client.js +46 -0
  60. package/dist/client/marketplace-client.js.map +1 -0
  61. package/dist/client/mcp-config-schema-client.d.ts +5 -0
  62. package/dist/client/mcp-config-schema-client.d.ts.map +1 -0
  63. package/dist/client/mcp-config-schema-client.js +9 -0
  64. package/dist/client/mcp-config-schema-client.js.map +1 -0
  65. package/dist/client/notifications-client.d.ts +27 -0
  66. package/dist/client/notifications-client.d.ts.map +1 -0
  67. package/dist/client/notifications-client.js +11 -0
  68. package/dist/client/notifications-client.js.map +1 -0
  69. package/dist/client/observability-client.d.ts +103 -0
  70. package/dist/client/observability-client.d.ts.map +1 -0
  71. package/dist/client/observability-client.js +43 -0
  72. package/dist/client/observability-client.js.map +1 -0
  73. package/dist/client/plugins-client.d.ts +17 -0
  74. package/dist/client/plugins-client.d.ts.map +1 -0
  75. package/dist/client/plugins-client.js +9 -0
  76. package/dist/client/plugins-client.js.map +1 -0
  77. package/dist/client/policy-client.d.ts +37 -0
  78. package/dist/client/policy-client.d.ts.map +1 -0
  79. package/dist/client/policy-client.js +26 -0
  80. package/dist/client/policy-client.js.map +1 -0
  81. package/dist/client/presets-client.d.ts +335 -0
  82. package/dist/client/presets-client.d.ts.map +1 -0
  83. package/dist/client/presets-client.js +38 -0
  84. package/dist/client/presets-client.js.map +1 -0
  85. package/dist/client/profiles-client.d.ts +102 -0
  86. package/dist/client/profiles-client.d.ts.map +1 -0
  87. package/dist/client/profiles-client.js +37 -0
  88. package/dist/client/profiles-client.js.map +1 -0
  89. package/dist/client/schedules-client.d.ts +28 -0
  90. package/dist/client/schedules-client.d.ts.map +1 -0
  91. package/dist/client/schedules-client.js +13 -0
  92. package/dist/client/schedules-client.js.map +1 -0
  93. package/dist/client/settings-schema-client.d.ts +23 -0
  94. package/dist/client/settings-schema-client.d.ts.map +1 -0
  95. package/dist/client/settings-schema-client.js +9 -0
  96. package/dist/client/settings-schema-client.js.map +1 -0
  97. package/dist/client/states-client.d.ts +471 -0
  98. package/dist/client/states-client.d.ts.map +1 -0
  99. package/dist/client/states-client.js +144 -0
  100. package/dist/client/states-client.js.map +1 -0
  101. package/dist/client/storage-client.d.ts +40 -0
  102. package/dist/client/storage-client.d.ts.map +1 -0
  103. package/dist/client/storage-client.js +43 -0
  104. package/dist/client/storage-client.js.map +1 -0
  105. package/dist/client/sub-mcp-client.d.ts +17 -0
  106. package/dist/client/sub-mcp-client.d.ts.map +1 -0
  107. package/dist/client/sub-mcp-client.js +14 -0
  108. package/dist/client/sub-mcp-client.js.map +1 -0
  109. package/dist/client/system-client.d.ts +11 -0
  110. package/dist/client/system-client.d.ts.map +1 -0
  111. package/dist/client/system-client.js +13 -0
  112. package/dist/client/system-client.js.map +1 -0
  113. package/dist/client/templates-client.d.ts +29 -0
  114. package/dist/client/templates-client.d.ts.map +1 -0
  115. package/dist/client/templates-client.js +21 -0
  116. package/dist/client/templates-client.js.map +1 -0
  117. package/dist/client/tool-extensions-client.d.ts +54 -0
  118. package/dist/client/tool-extensions-client.d.ts.map +1 -0
  119. package/dist/client/tool-extensions-client.js +21 -0
  120. package/dist/client/tool-extensions-client.js.map +1 -0
  121. package/dist/client/tool-meta-client.d.ts +69 -0
  122. package/dist/client/tool-meta-client.d.ts.map +1 -0
  123. package/dist/client/tool-meta-client.js +38 -0
  124. package/dist/client/tool-meta-client.js.map +1 -0
  125. package/dist/client/tools-client.d.ts +83 -0
  126. package/dist/client/tools-client.d.ts.map +1 -0
  127. package/dist/client/tools-client.js +38 -0
  128. package/dist/client/tools-client.js.map +1 -0
  129. package/dist/client/transport.d.ts +13 -0
  130. package/dist/client/transport.d.ts.map +1 -0
  131. package/dist/client/transport.js +10 -0
  132. package/dist/client/transport.js.map +1 -0
  133. package/dist/client/trigger-links-client.d.ts +44 -0
  134. package/dist/client/trigger-links-client.d.ts.map +1 -0
  135. package/dist/client/trigger-links-client.js +30 -0
  136. package/dist/client/trigger-links-client.js.map +1 -0
  137. package/dist/client/web-entry-gate-client.d.ts +34 -0
  138. package/dist/client/web-entry-gate-client.d.ts.map +1 -0
  139. package/dist/client/web-entry-gate-client.js +25 -0
  140. package/dist/client/web-entry-gate-client.js.map +1 -0
  141. package/dist/http.d.ts.map +1 -1
  142. package/dist/http.js +33 -17
  143. package/dist/http.js.map +1 -1
  144. package/dist/schemas/api-keys.d.ts +34 -0
  145. package/dist/schemas/api-keys.d.ts.map +1 -0
  146. package/dist/schemas/api-keys.js +22 -0
  147. package/dist/schemas/api-keys.js.map +1 -0
  148. package/dist/schemas/auth-routes.d.ts +78 -0
  149. package/dist/schemas/auth-routes.d.ts.map +1 -0
  150. package/dist/schemas/auth-routes.js +42 -0
  151. package/dist/schemas/auth-routes.js.map +1 -0
  152. package/dist/schemas/backup.d.ts +78 -0
  153. package/dist/schemas/backup.d.ts.map +1 -0
  154. package/dist/schemas/backup.js +33 -0
  155. package/dist/schemas/backup.js.map +1 -0
  156. package/dist/schemas/capabilities.d.ts +99 -0
  157. package/dist/schemas/capabilities.d.ts.map +1 -0
  158. package/dist/schemas/capabilities.js +74 -0
  159. package/dist/schemas/capabilities.js.map +1 -0
  160. package/dist/schemas/channels.d.ts +7 -0
  161. package/dist/schemas/channels.d.ts.map +1 -0
  162. package/dist/schemas/channels.js +9 -0
  163. package/dist/schemas/channels.js.map +1 -0
  164. package/dist/schemas/config.d.ts +17 -0
  165. package/dist/schemas/config.d.ts.map +1 -0
  166. package/dist/schemas/config.js +17 -0
  167. package/dist/schemas/config.js.map +1 -0
  168. package/dist/schemas/connectors.d.ts +383 -0
  169. package/dist/schemas/connectors.d.ts.map +1 -0
  170. package/dist/schemas/connectors.js +122 -0
  171. package/dist/schemas/connectors.js.map +1 -0
  172. package/dist/schemas/conversations.d.ts +600 -0
  173. package/dist/schemas/conversations.d.ts.map +1 -0
  174. package/dist/schemas/conversations.js +208 -0
  175. package/dist/schemas/conversations.js.map +1 -0
  176. package/dist/schemas/extensions.d.ts +44 -0
  177. package/dist/schemas/extensions.d.ts.map +1 -0
  178. package/dist/schemas/extensions.js +29 -0
  179. package/dist/schemas/extensions.js.map +1 -0
  180. package/dist/schemas/fleet.d.ts +271 -0
  181. package/dist/schemas/fleet.d.ts.map +1 -0
  182. package/dist/schemas/fleet.js +132 -0
  183. package/dist/schemas/fleet.js.map +1 -0
  184. package/dist/schemas/hooks.d.ts +120 -0
  185. package/dist/schemas/hooks.d.ts.map +1 -0
  186. package/dist/schemas/hooks.js +44 -0
  187. package/dist/schemas/hooks.js.map +1 -0
  188. package/dist/schemas/index.d.ts +38 -0
  189. package/dist/schemas/index.d.ts.map +1 -0
  190. package/dist/schemas/index.js +38 -0
  191. package/dist/schemas/index.js.map +1 -0
  192. package/dist/schemas/interactions.d.ts +156 -0
  193. package/dist/schemas/interactions.d.ts.map +1 -0
  194. package/dist/schemas/interactions.js +124 -0
  195. package/dist/schemas/interactions.js.map +1 -0
  196. package/dist/schemas/login.d.ts +86 -0
  197. package/dist/schemas/login.d.ts.map +1 -0
  198. package/dist/schemas/login.js +54 -0
  199. package/dist/schemas/login.js.map +1 -0
  200. package/dist/schemas/manifest-mcp.d.ts +125 -0
  201. package/dist/schemas/manifest-mcp.d.ts.map +1 -0
  202. package/dist/schemas/manifest-mcp.js +61 -0
  203. package/dist/schemas/manifest-mcp.js.map +1 -0
  204. package/dist/schemas/marketplace.d.ts +708 -0
  205. package/dist/schemas/marketplace.d.ts.map +1 -0
  206. package/dist/schemas/marketplace.js +387 -0
  207. package/dist/schemas/marketplace.js.map +1 -0
  208. package/dist/schemas/notifications.d.ts +61 -0
  209. package/dist/schemas/notifications.d.ts.map +1 -0
  210. package/dist/schemas/notifications.js +38 -0
  211. package/dist/schemas/notifications.js.map +1 -0
  212. package/dist/schemas/observability.d.ts +114 -0
  213. package/dist/schemas/observability.d.ts.map +1 -0
  214. package/dist/schemas/observability.js +74 -0
  215. package/dist/schemas/observability.js.map +1 -0
  216. package/dist/schemas/policy.d.ts +58 -0
  217. package/dist/schemas/policy.d.ts.map +1 -0
  218. package/dist/schemas/policy.js +32 -0
  219. package/dist/schemas/policy.js.map +1 -0
  220. package/dist/schemas/presets.d.ts +258 -0
  221. package/dist/schemas/presets.d.ts.map +1 -0
  222. package/dist/schemas/presets.js +95 -0
  223. package/dist/schemas/presets.js.map +1 -0
  224. package/dist/schemas/profiles.d.ts +180 -0
  225. package/dist/schemas/profiles.d.ts.map +1 -0
  226. package/dist/schemas/profiles.js +100 -0
  227. package/dist/schemas/profiles.js.map +1 -0
  228. package/dist/schemas/roles.d.ts +125 -0
  229. package/dist/schemas/roles.d.ts.map +1 -0
  230. package/dist/schemas/roles.js +46 -0
  231. package/dist/schemas/roles.js.map +1 -0
  232. package/dist/schemas/schedules.d.ts +25 -0
  233. package/dist/schemas/schedules.d.ts.map +1 -0
  234. package/dist/schemas/schedules.js +24 -0
  235. package/dist/schemas/schedules.js.map +1 -0
  236. package/dist/schemas/served.d.ts +626 -0
  237. package/dist/schemas/served.d.ts.map +1 -0
  238. package/dist/schemas/served.js +28 -0
  239. package/dist/schemas/served.js.map +1 -0
  240. package/dist/schemas/settings-schema.d.ts +23 -0
  241. package/dist/schemas/settings-schema.d.ts.map +1 -0
  242. package/dist/schemas/settings-schema.js +25 -0
  243. package/dist/schemas/settings-schema.js.map +1 -0
  244. package/dist/schemas/shared.d.ts +20 -0
  245. package/dist/schemas/shared.d.ts.map +1 -0
  246. package/dist/schemas/shared.js +20 -0
  247. package/dist/schemas/shared.js.map +1 -0
  248. package/dist/schemas/states.d.ts +499 -0
  249. package/dist/schemas/states.d.ts.map +1 -0
  250. package/dist/schemas/states.js +220 -0
  251. package/dist/schemas/states.js.map +1 -0
  252. package/dist/schemas/storage.d.ts +37 -0
  253. package/dist/schemas/storage.d.ts.map +1 -0
  254. package/dist/schemas/storage.js +24 -0
  255. package/dist/schemas/storage.js.map +1 -0
  256. package/dist/schemas/studio-plugins.d.ts +30 -0
  257. package/dist/schemas/studio-plugins.d.ts.map +1 -0
  258. package/dist/schemas/studio-plugins.js +20 -0
  259. package/dist/schemas/studio-plugins.js.map +1 -0
  260. package/dist/schemas/sub-mcp.d.ts +29 -0
  261. package/dist/schemas/sub-mcp.d.ts.map +1 -0
  262. package/dist/schemas/sub-mcp.js +22 -0
  263. package/dist/schemas/sub-mcp.js.map +1 -0
  264. package/dist/schemas/system-kinds.d.ts +122 -0
  265. package/dist/schemas/system-kinds.d.ts.map +1 -0
  266. package/dist/schemas/system-kinds.js +40 -0
  267. package/dist/schemas/system-kinds.js.map +1 -0
  268. package/dist/schemas/templates.d.ts +26 -0
  269. package/dist/schemas/templates.d.ts.map +1 -0
  270. package/dist/schemas/templates.js +11 -0
  271. package/dist/schemas/templates.js.map +1 -0
  272. package/dist/schemas/tool-meta.d.ts +64 -0
  273. package/dist/schemas/tool-meta.d.ts.map +1 -0
  274. package/dist/schemas/tool-meta.js +44 -0
  275. package/dist/schemas/tool-meta.js.map +1 -0
  276. package/dist/schemas/tools.d.ts +62 -0
  277. package/dist/schemas/tools.d.ts.map +1 -0
  278. package/dist/schemas/tools.js +53 -0
  279. package/dist/schemas/tools.js.map +1 -0
  280. package/dist/schemas/trigger-links.d.ts +71 -0
  281. package/dist/schemas/trigger-links.d.ts.map +1 -0
  282. package/dist/schemas/trigger-links.js +46 -0
  283. package/dist/schemas/trigger-links.js.map +1 -0
  284. package/dist/schemas/web-entry.d.ts +45 -0
  285. package/dist/schemas/web-entry.d.ts.map +1 -0
  286. package/dist/schemas/web-entry.js +36 -0
  287. package/dist/schemas/web-entry.js.map +1 -0
  288. package/dist/tool-runs.d.ts +4 -4
  289. package/package.json +1 -1
  290. package/src/client/agents-client.ts +23 -0
  291. package/src/client/auth-client.ts +144 -0
  292. package/src/client/backend-client.ts +25 -0
  293. package/src/client/backup-client.ts +16 -0
  294. package/src/client/capabilities-client.ts +22 -0
  295. package/src/client/channels-client.ts +11 -0
  296. package/src/client/config-client.ts +21 -0
  297. package/src/client/connectors-client.ts +52 -0
  298. package/src/client/conversations-client.ts +240 -0
  299. package/src/client/hooks-client.ts +44 -0
  300. package/src/client/index.ts +122 -0
  301. package/src/client/interactions-client.ts +89 -0
  302. package/src/client/login-client.ts +109 -0
  303. package/src/client/manifest-client.ts +118 -0
  304. package/src/client/marketplace-client.ts +122 -0
  305. package/src/client/mcp-config-schema-client.ts +11 -0
  306. package/src/client/notifications-client.ts +13 -0
  307. package/src/client/observability-client.ts +82 -0
  308. package/src/client/plugins-client.ts +11 -0
  309. package/src/client/policy-client.ts +41 -0
  310. package/src/client/presets-client.ts +124 -0
  311. package/src/client/profiles-client.ts +51 -0
  312. package/src/client/schedules-client.ts +22 -0
  313. package/src/client/settings-schema-client.ts +11 -0
  314. package/src/client/states-client.ts +292 -0
  315. package/src/client/storage-client.ts +63 -0
  316. package/src/client/sub-mcp-client.ts +17 -0
  317. package/src/client/system-client.ts +16 -0
  318. package/src/client/templates-client.ts +28 -0
  319. package/src/client/tool-extensions-client.ts +24 -0
  320. package/src/client/tool-meta-client.ts +65 -0
  321. package/src/client/tools-client.ts +66 -0
  322. package/src/client/transport.ts +18 -0
  323. package/src/client/trigger-links-client.ts +51 -0
  324. package/src/client/web-entry-gate-client.ts +45 -0
  325. package/src/http.ts +48 -24
  326. package/src/schemas/api-keys.ts +26 -0
  327. package/src/schemas/auth-routes.ts +48 -0
  328. package/src/schemas/backup.ts +42 -0
  329. package/src/schemas/capabilities.ts +87 -0
  330. package/src/schemas/channels.ts +11 -0
  331. package/src/schemas/config.ts +17 -0
  332. package/src/schemas/connectors.ts +138 -0
  333. package/src/schemas/conversations.ts +256 -0
  334. package/src/schemas/extensions.ts +34 -0
  335. package/src/schemas/fleet.ts +153 -0
  336. package/src/schemas/hooks.ts +56 -0
  337. package/src/schemas/index.ts +37 -0
  338. package/src/schemas/interactions.ts +146 -0
  339. package/src/schemas/login.ts +62 -0
  340. package/src/schemas/manifest-mcp.ts +69 -0
  341. package/src/schemas/marketplace.ts +447 -0
  342. package/src/schemas/notifications.ts +42 -0
  343. package/src/schemas/observability.ts +86 -0
  344. package/src/schemas/policy.ts +37 -0
  345. package/src/schemas/presets.ts +113 -0
  346. package/src/schemas/profiles.ts +119 -0
  347. package/src/schemas/roles.ts +57 -0
  348. package/src/schemas/schedules.ts +27 -0
  349. package/src/schemas/served.ts +49 -0
  350. package/src/schemas/settings-schema.ts +31 -0
  351. package/src/schemas/shared.ts +21 -0
  352. package/src/schemas/states.ts +272 -0
  353. package/src/schemas/storage.ts +31 -0
  354. package/src/schemas/studio-plugins.ts +21 -0
  355. package/src/schemas/sub-mcp.ts +24 -0
  356. package/src/schemas/system-kinds.ts +46 -0
  357. package/src/schemas/templates.ts +11 -0
  358. package/src/schemas/tool-meta.ts +51 -0
  359. package/src/schemas/tools.ts +61 -0
  360. package/src/schemas/trigger-links.ts +54 -0
  361. package/src/schemas/web-entry.ts +46 -0
  362. package/dist/client.d.ts.map +0 -1
  363. package/dist/client.js +0 -920
  364. package/dist/client.js.map +0 -1
  365. package/dist/schemas.d.ts +0 -5172
  366. package/dist/schemas.d.ts.map +0 -1
  367. package/dist/schemas.js +0 -2268
  368. package/dist/schemas.js.map +0 -1
  369. package/src/client.ts +0 -1771
  370. package/src/schemas.ts +0 -2760
@@ -0,0 +1,11 @@
1
+ /** Studio front-end plugin registry sub-client. */
2
+ import * as s from '../schemas';
3
+ import type { Transport } from './transport';
4
+
5
+ export function pluginsClient(t: Transport) {
6
+ const { req } = t;
7
+ return {
8
+ listStudioPlugins: (signal?: AbortSignal) =>
9
+ req('/api/plugins', s.studioPluginRegistry, { signal }),
10
+ };
11
+ }
@@ -0,0 +1,41 @@
1
+ /** Access-policy validation, versioning and rollback sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ /**
7
+ * Body for the fail-closed jq guard (POST `/api/auth/validate-condition`). The guard
8
+ * compile-checks the inline jq `condition` the author typed. `sample_context` is a
9
+ * `JqAuthContext`-shaped sample; when present the guard also evaluates the condition
10
+ * against it and returns the boolean `result` (else `result` is `null`).
11
+ */
12
+ export interface ValidateConditionBody {
13
+ readonly condition?: string;
14
+ readonly sample_context?: Record<string, unknown>;
15
+ }
16
+
17
+ export function policyClient(t: Transport) {
18
+ const { req } = t;
19
+ return {
20
+ // The fail-closed jq guard: compiles (and, with `sample_context`, evaluates) a
21
+ // condition without persisting anything, so a broken condition is caught at
22
+ // author time instead of locking a key out at enforcement. A broken condition
23
+ // is a 400 the transport throws — never a false-positive `ok`.
24
+ validateCondition: (body: ValidateConditionBody) =>
25
+ req('/api/auth/validate-condition', s.validateConditionResult, { method: 'POST', body }),
26
+ // The user's append-only policy version history (each row's `is_current`
27
+ // derived from the active pointer). SECRET-ADJACENT — the body carries the raw
28
+ // condition, so its fixtures are hand-authored.
29
+ listPolicyVersions: (userId: string, signal?: AbortSignal) =>
30
+ req(`/api/auth/api-keys/${encodeSegment(userId)}/policy/versions`, s.policyVersionList, {
31
+ signal,
32
+ }),
33
+ // Re-point the enforced policy to a prior version; returns the re-pointed
34
+ // active version. Enforcement follows on cache invalidation.
35
+ rollbackPolicy: (userId: string, version: number) =>
36
+ req(`/api/auth/api-keys/${encodeSegment(userId)}/policy/rollback`, s.policyRollback, {
37
+ method: 'POST',
38
+ body: { version },
39
+ }),
40
+ };
41
+ }
@@ -0,0 +1,124 @@
1
+ /** Preset CRUD, versioning and validation sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ /**
7
+ * Body for creating a preset (POST `/api/presets`). `description` is the bound
8
+ * tool's LLM-facing docstring — REQUIRED non-empty on every create path (the door
9
+ * rejects an empty one with a 422); it is never the tool_meta `display_name`.
10
+ * `extensions` is the combos list — the create flow OMITS it when there are no
11
+ * combos (the route rejects an explicit `extensions: []`). `output_schema` is the
12
+ * optional author-set output JSON Schema; `input_schema` is the optional author-set
13
+ * input JSON Schema, read by the router as a top-level version field. Each combo
14
+ * element is a bare extension name or a `{ name, config }` mapping. Categorization
15
+ * tags live in the tool_meta overlay, written after a successful create — never in
16
+ * this body.
17
+ */
18
+ export interface CreatePresetBody {
19
+ readonly name: string;
20
+ readonly base_tool: string;
21
+ readonly description: string;
22
+ readonly fixed_kwargs?: Record<string, unknown>;
23
+ readonly extensions?: readonly s.PresetExtensionElement[][];
24
+ readonly output_schema?: Record<string, unknown> | null;
25
+ readonly input_schema?: Record<string, unknown> | null;
26
+ // The optional door-layer state binding applied around every run of this preset.
27
+ readonly state_binding?: s.StateBinding | null;
28
+ }
29
+
30
+ /**
31
+ * Body for saving a new preset version (POST `/api/presets/{name}/versions`). At
32
+ * least one field must be provided (an empty body is a loud 400). Each field's
33
+ * sentinel is uniform: omitted carries the active version's value forward; an
34
+ * explicit `[]` clears `extensions`, and an explicit `null` clears `output_schema`
35
+ * or `input_schema`. `input_schema` is the optional author-set input JSON Schema and
36
+ * follows the same carry-forward sentinel as `output_schema`. `state_binding` is the
37
+ * optional door-layer binding and follows the same sentinel: omitted carries the active
38
+ * one forward, an explicit `null` clears it. `description` carries forward when omitted;
39
+ * an explicit non-empty string sets it (the API rejects an explicit empty one).
40
+ * Categorization tags are not a version field — they live in the tool_meta overlay.
41
+ */
42
+ export interface SavePresetVersionBody {
43
+ readonly fixed_kwargs?: Record<string, unknown>;
44
+ readonly description?: string;
45
+ readonly extensions?: readonly s.PresetExtensionElement[][];
46
+ readonly output_schema?: Record<string, unknown> | null;
47
+ readonly input_schema?: Record<string, unknown> | null;
48
+ readonly state_binding?: s.StateBinding | null;
49
+ }
50
+
51
+ /**
52
+ * Body for the dry-run validate door (POST `/api/presets/validate`). `name` is
53
+ * required and selects the verdict mode server-side: CREATE when no preset named
54
+ * `name` exists (then `base_tool` is required), VERSION when one does (the version
55
+ * fields are read under save-version semantics). The draft is sent exactly as the
56
+ * matching write would send it.
57
+ */
58
+ export interface ValidatePresetBody {
59
+ readonly name: string;
60
+ readonly base_tool?: string;
61
+ readonly description?: string;
62
+ readonly fixed_kwargs?: Record<string, unknown>;
63
+ readonly extensions?: readonly s.PresetExtensionElement[][];
64
+ readonly output_schema?: Record<string, unknown> | null;
65
+ readonly input_schema?: Record<string, unknown> | null;
66
+ // The optional door-layer state binding to dry-run — validated (never mounted) by the
67
+ // same checks the write would run. In VERSION mode it follows the save-version sentinel:
68
+ // omitted carries the active binding forward, an explicit `null` clears it.
69
+ readonly state_binding?: s.StateBinding | null;
70
+ }
71
+
72
+ export function presetsClient(t: Transport) {
73
+ const { req } = t;
74
+ return {
75
+ // Every preset is store-backed and versioned; the list is the single
76
+ // management population (the presets plus the conflicted quarantined rows).
77
+ listPresets: (signal?: AbortSignal) => req('/api/presets', s.presetList, { signal }),
78
+ createPreset: (body: CreatePresetBody) =>
79
+ req('/api/presets', s.presetRecord, { method: 'POST', body }),
80
+ getPreset: (name: string, signal?: AbortSignal) =>
81
+ req(`/api/presets/${encodeSegment(name)}`, s.presetDetail, { signal }),
82
+ listPresetVersions: (name: string, signal?: AbortSignal) =>
83
+ req(`/api/presets/${encodeSegment(name)}/versions`, s.presetVersionList, { signal }),
84
+ getPresetVersion: (name: string, version: number, signal?: AbortSignal) =>
85
+ req(
86
+ `/api/presets/${encodeSegment(name)}/versions/${encodeSegment(version)}`,
87
+ s.presetVersion,
88
+ { signal },
89
+ ),
90
+ savePresetVersion: (name: string, body: SavePresetVersionBody) =>
91
+ req(`/api/presets/${encodeSegment(name)}/versions`, s.presetVersion, {
92
+ method: 'POST',
93
+ body,
94
+ }),
95
+ rollbackPreset: (name: string, version: number) =>
96
+ req(`/api/presets/${encodeSegment(name)}/rollback`, s.presetRollback, {
97
+ method: 'POST',
98
+ body: { version },
99
+ }),
100
+ deletePreset: (name: string) =>
101
+ req(`/api/presets/${encodeSegment(name)}`, s.presetDeleted, { method: 'DELETE' }),
102
+ renamePreset: (name: string, newName: string) =>
103
+ req(`/api/presets/${encodeSegment(name)}/rename`, s.presetRenamed, {
104
+ method: 'POST',
105
+ body: { new_name: newName },
106
+ }),
107
+ // The presets whose active composition names this one as a tool — the referees
108
+ // a rename would strand. A rename preflight reads this to warn before the 409.
109
+ getPresetReferees: (name: string, signal?: AbortSignal) =>
110
+ req(`/api/presets/${encodeSegment(name)}/referees`, s.presetReferees, { signal }),
111
+ // The dry-run verdict for a draft (create OR version, mode-resolved server-side):
112
+ // `valid` plus the server's verbatim `error` message. Both verdicts are HTTP 200.
113
+ validatePreset: (body: ValidatePresetBody) =>
114
+ req('/api/presets/validate', s.presetValidation, { method: 'POST', body }),
115
+ // Replace one version's `tags` annotation — labels on an immutable body, so no
116
+ // rebind. Returns the re-annotated identity + new tag list.
117
+ setPresetVersionTags: (name: string, version: number, tags: readonly string[]) =>
118
+ req(
119
+ `/api/presets/${encodeSegment(name)}/versions/${encodeSegment(version)}/tags`,
120
+ s.presetVersionTags,
121
+ { method: 'PUT', body: { tags } },
122
+ ),
123
+ };
124
+ }
@@ -0,0 +1,51 @@
1
+ /** Settings-profile CRUD, versioning and apply sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ export function profilesClient(t: Transport) {
7
+ const { req } = t;
8
+ return {
9
+ // The admin-only `/api/config/profiles/*` surface. Bodies/diff/versions carry
10
+ // REAL secret values (secret/fenced routes); masking is CLIENT-SIDE.
11
+ listSettingsProfiles: (signal?: AbortSignal) =>
12
+ req('/api/config/profiles', s.settingsProfileList, { signal }),
13
+ getSettingsProfile: (name: string, signal?: AbortSignal) =>
14
+ req(`/api/config/profiles/${encodeSegment(name)}`, s.settingsProfileBody, { signal }),
15
+ putSettingsProfile: (name: string, body: s.SettingsProfileBody) =>
16
+ req(`/api/config/profiles/${encodeSegment(name)}`, s.settingsProfileSaved, {
17
+ method: 'PUT',
18
+ body,
19
+ }),
20
+ deleteSettingsProfile: (name: string) =>
21
+ req(`/api/config/profiles/${encodeSegment(name)}`, s.settingsProfileDeleted, {
22
+ method: 'DELETE',
23
+ }),
24
+ // Diff of the SAVED profile vs the stored env — server-computed, no request body.
25
+ diffSettingsProfile: (name: string) =>
26
+ req(`/api/config/profiles/${encodeSegment(name)}/diff`, s.settingsProfileDiff, {
27
+ method: 'POST',
28
+ }),
29
+ // Apply the SAVED profile (full-replace of the profile-managed band). Fenced,
30
+ // destructive → the dedicated `profile_apply_response` report.
31
+ applySettingsProfile: (name: string) =>
32
+ req(`/api/config/profiles/${encodeSegment(name)}/apply`, s.profileApplyResponse, {
33
+ method: 'POST',
34
+ }),
35
+ listSettingsProfileVersions: (name: string, signal?: AbortSignal) =>
36
+ req(`/api/config/profiles/${encodeSegment(name)}/versions`, s.settingsProfileVersionList, {
37
+ signal,
38
+ }),
39
+ getSettingsProfileVersion: (name: string, version: number, signal?: AbortSignal) =>
40
+ req(
41
+ `/api/config/profiles/${encodeSegment(name)}/versions/${encodeSegment(version)}`,
42
+ s.settingsProfileVersion,
43
+ { signal },
44
+ ),
45
+ rollbackSettingsProfile: (name: string, version: number) =>
46
+ req(`/api/config/profiles/${encodeSegment(name)}/rollback`, s.settingsProfileRollback, {
47
+ method: 'POST',
48
+ body: { version },
49
+ }),
50
+ };
51
+ }
@@ -0,0 +1,22 @@
1
+ /** Schedule listing and mutation sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ export function schedulesClient(t: Transport) {
7
+ const { req } = t;
8
+ return {
9
+ listSchedules: (signal?: AbortSignal) => req('/api/schedules', s.scheduleList, { signal }),
10
+ getServerDateTime: (signal?: AbortSignal) =>
11
+ req('/api/schedules/server-datetime', s.serverDateTime, { signal }),
12
+ addSchedule: (body: {
13
+ tool_name: string;
14
+ tool_kwargs: Record<string, unknown>;
15
+ schedule_kwargs: Record<string, unknown>;
16
+ // The optional door-layer state binding applied around every fire of this schedule.
17
+ state_binding?: s.StateBinding | null;
18
+ }) => req('/api/schedules', s.jsonValue, { method: 'POST', body }),
19
+ deleteSchedule: (name: string) =>
20
+ req(`/api/schedules/${encodeSegment(name)}`, s.jsonValue, { method: 'DELETE' }),
21
+ };
22
+ }
@@ -0,0 +1,11 @@
1
+ /** Settings-form schema read sub-client. */
2
+ import * as s from '../schemas';
3
+ import type { Transport } from './transport';
4
+
5
+ export function settingsSchemaClient(t: Transport) {
6
+ const { req } = t;
7
+ return {
8
+ getSettingsSchema: (signal?: AbortSignal) =>
9
+ req('/api/config/settings-schema', s.settingsSchema, { signal }),
10
+ };
11
+ }
@@ -0,0 +1,292 @@
1
+ /** State declaration, record, template and consumer sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ /**
7
+ * The client-facing write body for a state declaration (`PUT /api/states/{name}`), the
8
+ * wire shape of `tai42_contract.states.StateDeclaration` minus the platform-computed
9
+ * `effective_schema`/`regimes` (those are read-only, refused on a write). `schema` is the
10
+ * `TemplatedText | dict` union: an inline JSON-schema object, or a stored template reference
11
+ * (`id` + render `kwargs`) the platform renders to the schema. `retention_days` is `null` to
12
+ * keep records forever.
13
+ */
14
+ export interface StateDeclarationBody {
15
+ readonly name: string;
16
+ readonly description?: string;
17
+ readonly schema: s.TemplatedText | Record<string, unknown>;
18
+ readonly subject_kinds: readonly string[];
19
+ readonly default_subject_kind: string;
20
+ readonly retention_days?: number | null;
21
+ }
22
+
23
+ /**
24
+ * A state-template document write body (`PUT /api/state-templates/{name}`, the platform half).
25
+ * `schema` is the `TemplatedText | dict` union — an inline fragment schema, or a stored
26
+ * template reference the platform renders to the fragment.
27
+ */
28
+ export interface StateTemplateBody {
29
+ readonly name: string;
30
+ readonly description?: string;
31
+ readonly parameters?: Record<string, unknown>;
32
+ readonly schema: s.TemplatedText | Record<string, unknown>;
33
+ readonly regimes?: Record<string, unknown>[];
34
+ readonly declarations?: Record<string, unknown> | null;
35
+ readonly trace?: Record<string, unknown>;
36
+ }
37
+
38
+ /** A template attach / re-attach body (`PUT|PATCH /api/states/{name}/attachments/{template}`). */
39
+ export interface StateAttachmentBody {
40
+ readonly path?: string[];
41
+ readonly parameters?: Record<string, unknown>;
42
+ readonly declarations?: Record<string, unknown>;
43
+ // Reconcile directive for a re-attach that would orphan open records: retry with
44
+ // `{ orphans: "close", resolution: "<name>" }` to close them (the server refuses
45
+ // without it). Omitted on a first attach.
46
+ readonly options?: Record<string, unknown>;
47
+ }
48
+
49
+ /** The four-part subject a record route addresses in its path. */
50
+ export interface StateSubjectRef {
51
+ readonly target_kind: string;
52
+ readonly target_name: string;
53
+ readonly kind: string;
54
+ readonly key: string;
55
+ }
56
+
57
+ /** A keyset page request: an optional size and the opaque cursor a prior page returned. */
58
+ export interface StatePageQuery {
59
+ readonly limit?: number;
60
+ readonly cursor?: string;
61
+ }
62
+
63
+ /**
64
+ * The subject-addressed record path: `/api/states/{name}/records/{target_kind}/
65
+ * {target_name}/{kind}/{key}` — four path segments, each percent-encoded, so a key
66
+ * carrying a slash or a colon never escapes its segment.
67
+ */
68
+ function stateRecordPath(name: string, subject: StateSubjectRef): string {
69
+ return (
70
+ `/api/states/${encodeSegment(name)}/records/` +
71
+ `${encodeSegment(subject.target_kind)}/${encodeSegment(subject.target_name)}/` +
72
+ `${encodeSegment(subject.kind)}/${encodeSegment(subject.key)}`
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Encode a template jq's declared params as JSON query values: the record `template-jq`
78
+ * route reads each `?<param>=<json>` as a JSON-decoded argument, so a string, number,
79
+ * array or object round-trips faithfully. An `undefined` value is dropped (an
80
+ * omitted optional param).
81
+ */
82
+ function encodeJqParams(params?: Record<string, unknown>): Record<string, string> | undefined {
83
+ if (params === undefined) return undefined;
84
+ const query: Record<string, string> = {};
85
+ for (const [key, value] of Object.entries(params)) {
86
+ if (value === undefined) continue;
87
+ query[key] = JSON.stringify(value);
88
+ }
89
+ return query;
90
+ }
91
+
92
+ /** State declaration CRUD: list, read, upsert, delete and stats of a state document. */
93
+ function stateDeclarationMethods(t: Transport) {
94
+ const { req } = t;
95
+ return {
96
+ // A state is a declared JSON document, one per subject. The list is the
97
+ // management population; a single state read composes the declaration with its
98
+ // effective schema, regimes and attachments. Every record route addresses its subject
99
+ // as four percent-encoded path segments (see `stateRecordPath`).
100
+ listStates: (signal?: AbortSignal) => req('/api/states', s.stateList, { signal }),
101
+ getState: (name: string, signal?: AbortSignal) =>
102
+ req(`/api/states/${encodeSegment(name)}`, s.stateDetail, { signal }),
103
+ // A plain declaration upsert — no `replace` flag. With records present the server
104
+ // accepts additive schema changes and refuses with a 409 any change that removes or
105
+ // alters an existing field, or a subject-kind removal that would strand records.
106
+ putState: (name: string, body: StateDeclarationBody) =>
107
+ req(`/api/states/${encodeSegment(name)}`, s.stateDetail, {
108
+ method: 'PUT',
109
+ body,
110
+ }),
111
+ deleteState: (name: string) =>
112
+ req(`/api/states/${encodeSegment(name)}`, s.stateDeleted, { method: 'DELETE' }),
113
+ getStateStats: (name: string, signal?: AbortSignal) =>
114
+ req(`/api/states/${encodeSegment(name)}/stats`, s.stateStats, { signal }),
115
+ };
116
+ }
117
+
118
+ /** Template attachments on a state: list, read, attach, re-attach and detach. */
119
+ function stateAttachmentMethods(t: Transport) {
120
+ const { req } = t;
121
+ return {
122
+ listStateAttachments: (name: string, signal?: AbortSignal) =>
123
+ req(`/api/states/${encodeSegment(name)}/attachments`, s.stateAttachmentList, { signal }),
124
+ getStateAttachment: (name: string, template: string, signal?: AbortSignal) =>
125
+ req(
126
+ `/api/states/${encodeSegment(name)}/attachments/${encodeSegment(template)}`,
127
+ s.stateAttachment,
128
+ { signal },
129
+ ),
130
+ attachStateTemplate: (name: string, template: string, body: StateAttachmentBody) =>
131
+ req(
132
+ `/api/states/${encodeSegment(name)}/attachments/${encodeSegment(template)}`,
133
+ s.stateAttached,
134
+ { method: 'PUT', body },
135
+ ),
136
+ patchStateAttachment: (name: string, template: string, body: StateAttachmentBody) =>
137
+ req(
138
+ `/api/states/${encodeSegment(name)}/attachments/${encodeSegment(template)}`,
139
+ s.stateAttachmentUpdated,
140
+ { method: 'PATCH', body },
141
+ ),
142
+ detachStateTemplate: (name: string, template: string) =>
143
+ req(
144
+ `/api/states/${encodeSegment(name)}/attachments/${encodeSegment(template)}`,
145
+ s.stateDetached,
146
+ { method: 'DELETE' },
147
+ ),
148
+ };
149
+ }
150
+
151
+ /** Record reads and writes: subject listing, content search, and per-subject CRUD. */
152
+ function stateRecordMethods(t: Transport) {
153
+ const { req } = t;
154
+ return {
155
+ listStateSubjects: (
156
+ name: string,
157
+ params: { kind?: string } & StatePageQuery,
158
+ signal?: AbortSignal,
159
+ ) =>
160
+ req(`/api/states/${encodeSegment(name)}/subjects`, s.subjectPage, {
161
+ signal,
162
+ query: { kind: params.kind, limit: params.limit, cursor: params.cursor },
163
+ }),
164
+ // The content search body is a single JSONB containment document (`filters`); the
165
+ // server refuses an empty one, so the UI validates a non-empty object first.
166
+ searchStateRecords: (
167
+ name: string,
168
+ body: { filters: Record<string, unknown> } & StatePageQuery,
169
+ signal?: AbortSignal,
170
+ ) =>
171
+ req(`/api/states/${encodeSegment(name)}/records/search`, s.recordSearchPage, {
172
+ method: 'POST',
173
+ body,
174
+ signal,
175
+ }),
176
+ // A subject with no document yet reads as `null` (a 200 `{data: null}`, the record
177
+ // page's Create path) — never an error, so the schema is nullable.
178
+ getStateRecord: (name: string, subject: StateSubjectRef, signal?: AbortSignal) =>
179
+ req(stateRecordPath(name, subject), s.stateRecord.nullable(), { signal }),
180
+ putStateRecord: (name: string, subject: StateSubjectRef, data: Record<string, unknown>) =>
181
+ req(stateRecordPath(name, subject), s.stateRecord, { method: 'PUT', body: data }),
182
+ patchStateRecord: (name: string, subject: StateSubjectRef, data: Record<string, unknown>) =>
183
+ req(stateRecordPath(name, subject), s.stateRecord, { method: 'PATCH', body: data }),
184
+ applyStateRecord: (
185
+ name: string,
186
+ subject: StateSubjectRef,
187
+ ops: readonly Record<string, unknown>[],
188
+ ) =>
189
+ req(`${stateRecordPath(name, subject)}/deltas`, s.applyResult, {
190
+ method: 'POST',
191
+ body: { ops },
192
+ }),
193
+ };
194
+ }
195
+
196
+ /** Record operations on a subject: template-jq eval/apply, delete, fold, write log, consumers. */
197
+ function stateRecordOpMethods(t: Transport) {
198
+ const { req } = t;
199
+ return {
200
+ // Evaluate a template jq over the subject: each declared param is JSON-encoded into
201
+ // the query string (`?<param>=<json>`); the response is `{name, purpose, value}`. An
202
+ // `attachment.name` jq is percent-encoded as one path segment.
203
+ evalTemplateJq: (
204
+ name: string,
205
+ subject: StateSubjectRef,
206
+ jqName: string,
207
+ params?: Record<string, unknown>,
208
+ signal?: AbortSignal,
209
+ ) =>
210
+ req(
211
+ `${stateRecordPath(name, subject)}/template-jq/${encodeSegment(jqName)}`,
212
+ s.templateJqResult,
213
+ { signal, query: encodeJqParams(params) },
214
+ ),
215
+ // Apply an `update`-purpose template jq to the subject: `input` is the jq's argument,
216
+ // `op_id` its idempotency key (a replay is a no-op). The jq lands its op batch through
217
+ // the apply chokepoint. An `attachment.name` jq is percent-encoded as one path segment.
218
+ applyTemplateJq: (
219
+ name: string,
220
+ subject: StateSubjectRef,
221
+ jqName: string,
222
+ body?: { input?: unknown; op_id?: string },
223
+ ) =>
224
+ req(
225
+ `${stateRecordPath(name, subject)}/template-jq/${encodeSegment(jqName)}`,
226
+ s.templateJqApplyResult,
227
+ { method: 'POST', body: body ?? {} },
228
+ ),
229
+ deleteStateRecord: (name: string, subject: StateSubjectRef) =>
230
+ req(stateRecordPath(name, subject), s.recordErased, { method: 'DELETE' }),
231
+ // `mode` is required server-side (`switch` drops, `merge` combines); the fold returns
232
+ // a report, not the surviving record.
233
+ foldStateRecord: (
234
+ name: string,
235
+ subject: StateSubjectRef,
236
+ into: StateSubjectRef,
237
+ mode: 'switch' | 'merge',
238
+ ) =>
239
+ req(`${stateRecordPath(name, subject)}/fold`, s.stateFoldReport, {
240
+ method: 'POST',
241
+ body: { into, mode },
242
+ }),
243
+ listStateWrites: (
244
+ name: string,
245
+ subject: StateSubjectRef,
246
+ params?: StatePageQuery,
247
+ signal?: AbortSignal,
248
+ ) =>
249
+ req(`${stateRecordPath(name, subject)}/writes`, s.writesPage, {
250
+ signal,
251
+ query: { limit: params?.limit, cursor: params?.cursor },
252
+ }),
253
+ stateConsumers: (name: string, signal?: AbortSignal) =>
254
+ req(`/api/states/${encodeSegment(name)}/consumers`, s.stateConsumers, { signal }),
255
+ };
256
+ }
257
+
258
+ /** State-template documents and retention: list, read, upsert, delete, prune. */
259
+ function stateTemplateMethods(t: Transport) {
260
+ const { req } = t;
261
+ return {
262
+ listStateTemplates: (signal?: AbortSignal) =>
263
+ req('/api/state-templates', s.stateTemplateList, { signal }),
264
+ getStateTemplate: (name: string, signal?: AbortSignal) =>
265
+ req(`/api/state-templates/${encodeSegment(name)}`, s.stateTemplateDocument, { signal }),
266
+ putStateTemplate: (name: string, body: StateTemplateBody, replace?: boolean) =>
267
+ req(`/api/state-templates/${encodeSegment(name)}`, s.stateTemplateDocument, {
268
+ method: 'PUT',
269
+ body,
270
+ query: replace === true ? { replace: 'true' } : undefined,
271
+ }),
272
+ deleteStateTemplate: (name: string) =>
273
+ req(`/api/state-templates/${encodeSegment(name)}`, s.stateTemplateDeleted, {
274
+ method: 'DELETE',
275
+ }),
276
+ pruneStateRetention: () =>
277
+ req('/api/state-retention/prune', s.stateRetentionPruned, { method: 'POST', body: {} }),
278
+ };
279
+ }
280
+
281
+ export function statesClient(t: Transport) {
282
+ // Declaration emit prepends each spread group's members, so the groups are
283
+ // spread in reverse of their public order to keep the surface declaration →
284
+ // attachments → records → record-ops → templates.
285
+ return {
286
+ ...stateTemplateMethods(t),
287
+ ...stateRecordOpMethods(t),
288
+ ...stateRecordMethods(t),
289
+ ...stateAttachmentMethods(t),
290
+ ...stateDeclarationMethods(t),
291
+ };
292
+ }
@@ -0,0 +1,63 @@
1
+ /** Storage resource CRUD sub-client. */
2
+ import * as s from '../schemas';
3
+ import { apiDownload, isUnsafePathSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ /**
7
+ * Body for a storage upload (POST `/api/storage/resources`). Exactly ONE of
8
+ * `content_text` (stored verbatim) or `content_base64` (a base64 string decoded to
9
+ * bytes) supplies the content for `id`; uploading an existing id overwrites it
10
+ * (provider passthrough semantics).
11
+ */
12
+ export interface StorageUploadBody {
13
+ readonly id: string;
14
+ readonly content_text?: string;
15
+ readonly content_base64?: string;
16
+ }
17
+
18
+ /**
19
+ * Encode a possibly-nested storage id / directory path for use in a URL path,
20
+ * percent-encoding each segment while preserving the `/` separators. A storage id
21
+ * can be a nested path (e.g. `a/b c.txt`); encoding each segment independently keeps
22
+ * the slashes structural and escapes everything else (spaces, `#`, `?`, …).
23
+ *
24
+ * Dot segments (`.`, `..`), empty segments (a leading/trailing/doubled `/`, or an
25
+ * empty id) are REJECTED loudly rather than encoded: the browser's WHATWG URL parser
26
+ * removes dot-segments from a relative request path before it is sent — collapsing
27
+ * `..` even when percent-encoded — so such an id can never be faithfully transmitted.
28
+ * Left to encode, it would silently retarget the request at an unrelated same-origin
29
+ * route. The server enforces the same relative-path rule; failing fast here keeps a
30
+ * malformed id from ever leaving the client.
31
+ */
32
+ function encodePath(id: string): string {
33
+ const segments = id.split('/');
34
+ if (segments.some(isUnsafePathSegment)) {
35
+ throw new Error("storage path must be a relative path with no empty, '.', or '..' segment");
36
+ }
37
+ return segments.map(encodeURIComponent).join('/');
38
+ }
39
+
40
+ export function storageClient(t: Transport) {
41
+ const { config, req } = t;
42
+ return {
43
+ // The content store a storage-provider plugin exposes. Dead by default:
44
+ // `getStorageInfo` reports `present: false` (a 200 empty state) and every other
45
+ // door answers a loud 501 when no provider is installed. Ids may be nested
46
+ // paths, so each is `encodePath`-encoded (per-segment, `/` preserved).
47
+ getStorageInfo: (signal?: AbortSignal) => req('/api/storage', s.storageInfo, { signal }),
48
+ listStorageResources: (signal?: AbortSignal) =>
49
+ req('/api/storage/resources', s.storageResourceList, { signal }),
50
+ statStorageResource: (id: string, signal?: AbortSignal) =>
51
+ req(`/api/storage/resources/${encodePath(id)}/stat`, s.storageResourceStat, { signal }),
52
+ downloadStorageResource: (id: string, signal?: AbortSignal): Promise<Blob> =>
53
+ apiDownload(config, `/api/storage/resources/${encodePath(id)}/content`, { signal }),
54
+ uploadStorageResource: (body: StorageUploadBody) =>
55
+ req('/api/storage/resources', s.storageResourceStored, { method: 'POST', body }),
56
+ deleteStorageResource: (id: string) =>
57
+ req(`/api/storage/resources/${encodePath(id)}`, s.storageResourceDeleted, {
58
+ method: 'DELETE',
59
+ }),
60
+ deleteStorageDir: (path: string) =>
61
+ req(`/api/storage/dirs/${encodePath(path)}`, s.storageDirDeleted, { method: 'DELETE' }),
62
+ };
63
+ }
@@ -0,0 +1,17 @@
1
+ /** Sub-MCP mount registry sub-client. */
2
+ import * as s from '../schemas';
3
+ import { encodeSegment } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ export function subMcpClient(t: Transport) {
7
+ const { req } = t;
8
+ return {
9
+ listSubMcp: (signal?: AbortSignal) => req('/api/sub-mcp', s.subMcpList, { signal }),
10
+ // `transport` is optional at the client boundary (the server defaults it to
11
+ // `http`); when omitted, JSON.stringify drops the undefined key from the body.
12
+ createSubMcp: (slug: string, tools: string[], transport?: string) =>
13
+ req('/api/sub-mcp', s.subMcpCreated, { method: 'POST', body: { slug, tools, transport } }),
14
+ deleteSubMcp: (slug: string) =>
15
+ req(`/api/sub-mcp/${encodeSegment(slug)}`, s.subMcpRemoved, { method: 'DELETE' }),
16
+ };
17
+ }
@@ -0,0 +1,16 @@
1
+ /** System health and pluggable-kind status sub-client. */
2
+ import * as s from '../schemas';
3
+ import { apiText } from '../http';
4
+ import type { Transport } from './transport';
5
+
6
+ export function systemClient(t: Transport) {
7
+ const { config, req } = t;
8
+ return {
9
+ getHealth: (signal?: AbortSignal) => apiText(config, '/health', { signal }),
10
+
11
+ // The pluggable-kind status table (`GET /api/system/kinds`) — a JSON `{data}`
12
+ // envelope, one row per kind with its active/default/off state.
13
+ getSystemKinds: (signal?: AbortSignal) =>
14
+ req('/api/system/kinds', s.kindStatusList, { signal }),
15
+ };
16
+ }