@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.
- package/dist/client/agents-client.d.ts +26 -0
- package/dist/client/agents-client.d.ts.map +1 -0
- package/dist/client/agents-client.js +19 -0
- package/dist/client/agents-client.js.map +1 -0
- package/dist/client/auth-client.d.ts +205 -0
- package/dist/client/auth-client.d.ts.map +1 -0
- package/dist/client/auth-client.js +59 -0
- package/dist/client/auth-client.js.map +1 -0
- package/dist/client/backend-client.d.ts +39 -0
- package/dist/client/backend-client.d.ts.map +1 -0
- package/dist/client/backend-client.js +22 -0
- package/dist/client/backend-client.js.map +1 -0
- package/dist/client/backup-client.d.ts +56 -0
- package/dist/client/backup-client.d.ts.map +1 -0
- package/dist/client/backup-client.js +12 -0
- package/dist/client/backup-client.js.map +1 -0
- package/dist/client/capabilities-client.d.ts +35 -0
- package/dist/client/capabilities-client.d.ts.map +1 -0
- package/dist/client/capabilities-client.js +19 -0
- package/dist/client/capabilities-client.js.map +1 -0
- package/dist/client/channels-client.d.ts +7 -0
- package/dist/client/channels-client.d.ts.map +1 -0
- package/dist/client/channels-client.js +10 -0
- package/dist/client/channels-client.js.map +1 -0
- package/dist/client/config-client.d.ts +59 -0
- package/dist/client/config-client.d.ts.map +1 -0
- package/dist/client/config-client.js +18 -0
- package/dist/client/config-client.js.map +1 -0
- package/dist/client/connectors-client.d.ts +225 -0
- package/dist/client/connectors-client.d.ts.map +1 -0
- package/dist/client/connectors-client.js +31 -0
- package/dist/client/connectors-client.js.map +1 -0
- package/dist/client/conversations-client.d.ts +399 -0
- package/dist/client/conversations-client.d.ts.map +1 -0
- package/dist/client/conversations-client.js +120 -0
- package/dist/client/conversations-client.js.map +1 -0
- package/dist/client/hooks-client.d.ts +113 -0
- package/dist/client/hooks-client.d.ts.map +1 -0
- package/dist/client/hooks-client.js +25 -0
- package/dist/client/hooks-client.js.map +1 -0
- package/dist/{client.d.ts → client/index.d.ts} +2235 -2666
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +79 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/interactions-client.d.ts +52 -0
- package/dist/client/interactions-client.d.ts.map +1 -0
- package/dist/client/interactions-client.js +84 -0
- package/dist/client/interactions-client.js.map +1 -0
- package/dist/client/login-client.d.ts +56 -0
- package/dist/client/login-client.d.ts.map +1 -0
- package/dist/client/login-client.js +103 -0
- package/dist/client/login-client.js.map +1 -0
- package/dist/client/manifest-client.d.ts +354 -0
- package/dist/client/manifest-client.d.ts.map +1 -0
- package/dist/client/manifest-client.js +76 -0
- package/dist/client/manifest-client.js.map +1 -0
- package/dist/client/marketplace-client.d.ts +274 -0
- package/dist/client/marketplace-client.d.ts.map +1 -0
- package/dist/client/marketplace-client.js +46 -0
- package/dist/client/marketplace-client.js.map +1 -0
- package/dist/client/mcp-config-schema-client.d.ts +5 -0
- package/dist/client/mcp-config-schema-client.d.ts.map +1 -0
- package/dist/client/mcp-config-schema-client.js +9 -0
- package/dist/client/mcp-config-schema-client.js.map +1 -0
- package/dist/client/notifications-client.d.ts +27 -0
- package/dist/client/notifications-client.d.ts.map +1 -0
- package/dist/client/notifications-client.js +11 -0
- package/dist/client/notifications-client.js.map +1 -0
- package/dist/client/observability-client.d.ts +103 -0
- package/dist/client/observability-client.d.ts.map +1 -0
- package/dist/client/observability-client.js +43 -0
- package/dist/client/observability-client.js.map +1 -0
- package/dist/client/plugins-client.d.ts +17 -0
- package/dist/client/plugins-client.d.ts.map +1 -0
- package/dist/client/plugins-client.js +9 -0
- package/dist/client/plugins-client.js.map +1 -0
- package/dist/client/policy-client.d.ts +37 -0
- package/dist/client/policy-client.d.ts.map +1 -0
- package/dist/client/policy-client.js +26 -0
- package/dist/client/policy-client.js.map +1 -0
- package/dist/client/presets-client.d.ts +335 -0
- package/dist/client/presets-client.d.ts.map +1 -0
- package/dist/client/presets-client.js +38 -0
- package/dist/client/presets-client.js.map +1 -0
- package/dist/client/profiles-client.d.ts +102 -0
- package/dist/client/profiles-client.d.ts.map +1 -0
- package/dist/client/profiles-client.js +37 -0
- package/dist/client/profiles-client.js.map +1 -0
- package/dist/client/schedules-client.d.ts +28 -0
- package/dist/client/schedules-client.d.ts.map +1 -0
- package/dist/client/schedules-client.js +13 -0
- package/dist/client/schedules-client.js.map +1 -0
- package/dist/client/settings-schema-client.d.ts +23 -0
- package/dist/client/settings-schema-client.d.ts.map +1 -0
- package/dist/client/settings-schema-client.js +9 -0
- package/dist/client/settings-schema-client.js.map +1 -0
- package/dist/client/states-client.d.ts +471 -0
- package/dist/client/states-client.d.ts.map +1 -0
- package/dist/client/states-client.js +144 -0
- package/dist/client/states-client.js.map +1 -0
- package/dist/client/storage-client.d.ts +40 -0
- package/dist/client/storage-client.d.ts.map +1 -0
- package/dist/client/storage-client.js +43 -0
- package/dist/client/storage-client.js.map +1 -0
- package/dist/client/sub-mcp-client.d.ts +17 -0
- package/dist/client/sub-mcp-client.d.ts.map +1 -0
- package/dist/client/sub-mcp-client.js +14 -0
- package/dist/client/sub-mcp-client.js.map +1 -0
- package/dist/client/system-client.d.ts +11 -0
- package/dist/client/system-client.d.ts.map +1 -0
- package/dist/client/system-client.js +13 -0
- package/dist/client/system-client.js.map +1 -0
- package/dist/client/templates-client.d.ts +29 -0
- package/dist/client/templates-client.d.ts.map +1 -0
- package/dist/client/templates-client.js +21 -0
- package/dist/client/templates-client.js.map +1 -0
- package/dist/client/tool-extensions-client.d.ts +54 -0
- package/dist/client/tool-extensions-client.d.ts.map +1 -0
- package/dist/client/tool-extensions-client.js +21 -0
- package/dist/client/tool-extensions-client.js.map +1 -0
- package/dist/client/tool-meta-client.d.ts +69 -0
- package/dist/client/tool-meta-client.d.ts.map +1 -0
- package/dist/client/tool-meta-client.js +38 -0
- package/dist/client/tool-meta-client.js.map +1 -0
- package/dist/client/tools-client.d.ts +83 -0
- package/dist/client/tools-client.d.ts.map +1 -0
- package/dist/client/tools-client.js +38 -0
- package/dist/client/tools-client.js.map +1 -0
- package/dist/client/transport.d.ts +13 -0
- package/dist/client/transport.d.ts.map +1 -0
- package/dist/client/transport.js +10 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/client/trigger-links-client.d.ts +44 -0
- package/dist/client/trigger-links-client.d.ts.map +1 -0
- package/dist/client/trigger-links-client.js +30 -0
- package/dist/client/trigger-links-client.js.map +1 -0
- package/dist/client/web-entry-gate-client.d.ts +34 -0
- package/dist/client/web-entry-gate-client.d.ts.map +1 -0
- package/dist/client/web-entry-gate-client.js +25 -0
- package/dist/client/web-entry-gate-client.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +33 -17
- package/dist/http.js.map +1 -1
- package/dist/schemas/api-keys.d.ts +34 -0
- package/dist/schemas/api-keys.d.ts.map +1 -0
- package/dist/schemas/api-keys.js +22 -0
- package/dist/schemas/api-keys.js.map +1 -0
- package/dist/schemas/auth-routes.d.ts +78 -0
- package/dist/schemas/auth-routes.d.ts.map +1 -0
- package/dist/schemas/auth-routes.js +42 -0
- package/dist/schemas/auth-routes.js.map +1 -0
- package/dist/schemas/backup.d.ts +78 -0
- package/dist/schemas/backup.d.ts.map +1 -0
- package/dist/schemas/backup.js +33 -0
- package/dist/schemas/backup.js.map +1 -0
- package/dist/schemas/capabilities.d.ts +99 -0
- package/dist/schemas/capabilities.d.ts.map +1 -0
- package/dist/schemas/capabilities.js +74 -0
- package/dist/schemas/capabilities.js.map +1 -0
- package/dist/schemas/channels.d.ts +7 -0
- package/dist/schemas/channels.d.ts.map +1 -0
- package/dist/schemas/channels.js +9 -0
- package/dist/schemas/channels.js.map +1 -0
- package/dist/schemas/config.d.ts +17 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +17 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/connectors.d.ts +383 -0
- package/dist/schemas/connectors.d.ts.map +1 -0
- package/dist/schemas/connectors.js +122 -0
- package/dist/schemas/connectors.js.map +1 -0
- package/dist/schemas/conversations.d.ts +600 -0
- package/dist/schemas/conversations.d.ts.map +1 -0
- package/dist/schemas/conversations.js +208 -0
- package/dist/schemas/conversations.js.map +1 -0
- package/dist/schemas/extensions.d.ts +44 -0
- package/dist/schemas/extensions.d.ts.map +1 -0
- package/dist/schemas/extensions.js +29 -0
- package/dist/schemas/extensions.js.map +1 -0
- package/dist/schemas/fleet.d.ts +271 -0
- package/dist/schemas/fleet.d.ts.map +1 -0
- package/dist/schemas/fleet.js +132 -0
- package/dist/schemas/fleet.js.map +1 -0
- package/dist/schemas/hooks.d.ts +120 -0
- package/dist/schemas/hooks.d.ts.map +1 -0
- package/dist/schemas/hooks.js +44 -0
- package/dist/schemas/hooks.js.map +1 -0
- package/dist/schemas/index.d.ts +38 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +38 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/interactions.d.ts +156 -0
- package/dist/schemas/interactions.d.ts.map +1 -0
- package/dist/schemas/interactions.js +124 -0
- package/dist/schemas/interactions.js.map +1 -0
- package/dist/schemas/login.d.ts +86 -0
- package/dist/schemas/login.d.ts.map +1 -0
- package/dist/schemas/login.js +54 -0
- package/dist/schemas/login.js.map +1 -0
- package/dist/schemas/manifest-mcp.d.ts +125 -0
- package/dist/schemas/manifest-mcp.d.ts.map +1 -0
- package/dist/schemas/manifest-mcp.js +61 -0
- package/dist/schemas/manifest-mcp.js.map +1 -0
- package/dist/schemas/marketplace.d.ts +708 -0
- package/dist/schemas/marketplace.d.ts.map +1 -0
- package/dist/schemas/marketplace.js +387 -0
- package/dist/schemas/marketplace.js.map +1 -0
- package/dist/schemas/notifications.d.ts +61 -0
- package/dist/schemas/notifications.d.ts.map +1 -0
- package/dist/schemas/notifications.js +38 -0
- package/dist/schemas/notifications.js.map +1 -0
- package/dist/schemas/observability.d.ts +114 -0
- package/dist/schemas/observability.d.ts.map +1 -0
- package/dist/schemas/observability.js +74 -0
- package/dist/schemas/observability.js.map +1 -0
- package/dist/schemas/policy.d.ts +58 -0
- package/dist/schemas/policy.d.ts.map +1 -0
- package/dist/schemas/policy.js +32 -0
- package/dist/schemas/policy.js.map +1 -0
- package/dist/schemas/presets.d.ts +258 -0
- package/dist/schemas/presets.d.ts.map +1 -0
- package/dist/schemas/presets.js +95 -0
- package/dist/schemas/presets.js.map +1 -0
- package/dist/schemas/profiles.d.ts +180 -0
- package/dist/schemas/profiles.d.ts.map +1 -0
- package/dist/schemas/profiles.js +100 -0
- package/dist/schemas/profiles.js.map +1 -0
- package/dist/schemas/roles.d.ts +125 -0
- package/dist/schemas/roles.d.ts.map +1 -0
- package/dist/schemas/roles.js +46 -0
- package/dist/schemas/roles.js.map +1 -0
- package/dist/schemas/schedules.d.ts +25 -0
- package/dist/schemas/schedules.d.ts.map +1 -0
- package/dist/schemas/schedules.js +24 -0
- package/dist/schemas/schedules.js.map +1 -0
- package/dist/schemas/served.d.ts +626 -0
- package/dist/schemas/served.d.ts.map +1 -0
- package/dist/schemas/served.js +28 -0
- package/dist/schemas/served.js.map +1 -0
- package/dist/schemas/settings-schema.d.ts +23 -0
- package/dist/schemas/settings-schema.d.ts.map +1 -0
- package/dist/schemas/settings-schema.js +25 -0
- package/dist/schemas/settings-schema.js.map +1 -0
- package/dist/schemas/shared.d.ts +20 -0
- package/dist/schemas/shared.d.ts.map +1 -0
- package/dist/schemas/shared.js +20 -0
- package/dist/schemas/shared.js.map +1 -0
- package/dist/schemas/states.d.ts +499 -0
- package/dist/schemas/states.d.ts.map +1 -0
- package/dist/schemas/states.js +220 -0
- package/dist/schemas/states.js.map +1 -0
- package/dist/schemas/storage.d.ts +37 -0
- package/dist/schemas/storage.d.ts.map +1 -0
- package/dist/schemas/storage.js +24 -0
- package/dist/schemas/storage.js.map +1 -0
- package/dist/schemas/studio-plugins.d.ts +30 -0
- package/dist/schemas/studio-plugins.d.ts.map +1 -0
- package/dist/schemas/studio-plugins.js +20 -0
- package/dist/schemas/studio-plugins.js.map +1 -0
- package/dist/schemas/sub-mcp.d.ts +29 -0
- package/dist/schemas/sub-mcp.d.ts.map +1 -0
- package/dist/schemas/sub-mcp.js +22 -0
- package/dist/schemas/sub-mcp.js.map +1 -0
- package/dist/schemas/system-kinds.d.ts +122 -0
- package/dist/schemas/system-kinds.d.ts.map +1 -0
- package/dist/schemas/system-kinds.js +40 -0
- package/dist/schemas/system-kinds.js.map +1 -0
- package/dist/schemas/templates.d.ts +26 -0
- package/dist/schemas/templates.d.ts.map +1 -0
- package/dist/schemas/templates.js +11 -0
- package/dist/schemas/templates.js.map +1 -0
- package/dist/schemas/tool-meta.d.ts +64 -0
- package/dist/schemas/tool-meta.d.ts.map +1 -0
- package/dist/schemas/tool-meta.js +44 -0
- package/dist/schemas/tool-meta.js.map +1 -0
- package/dist/schemas/tools.d.ts +62 -0
- package/dist/schemas/tools.d.ts.map +1 -0
- package/dist/schemas/tools.js +53 -0
- package/dist/schemas/tools.js.map +1 -0
- package/dist/schemas/trigger-links.d.ts +71 -0
- package/dist/schemas/trigger-links.d.ts.map +1 -0
- package/dist/schemas/trigger-links.js +46 -0
- package/dist/schemas/trigger-links.js.map +1 -0
- package/dist/schemas/web-entry.d.ts +45 -0
- package/dist/schemas/web-entry.d.ts.map +1 -0
- package/dist/schemas/web-entry.js +36 -0
- package/dist/schemas/web-entry.js.map +1 -0
- package/dist/tool-runs.d.ts +4 -4
- package/package.json +1 -1
- package/src/client/agents-client.ts +23 -0
- package/src/client/auth-client.ts +144 -0
- package/src/client/backend-client.ts +25 -0
- package/src/client/backup-client.ts +16 -0
- package/src/client/capabilities-client.ts +22 -0
- package/src/client/channels-client.ts +11 -0
- package/src/client/config-client.ts +21 -0
- package/src/client/connectors-client.ts +52 -0
- package/src/client/conversations-client.ts +240 -0
- package/src/client/hooks-client.ts +44 -0
- package/src/client/index.ts +122 -0
- package/src/client/interactions-client.ts +89 -0
- package/src/client/login-client.ts +109 -0
- package/src/client/manifest-client.ts +118 -0
- package/src/client/marketplace-client.ts +122 -0
- package/src/client/mcp-config-schema-client.ts +11 -0
- package/src/client/notifications-client.ts +13 -0
- package/src/client/observability-client.ts +82 -0
- package/src/client/plugins-client.ts +11 -0
- package/src/client/policy-client.ts +41 -0
- package/src/client/presets-client.ts +124 -0
- package/src/client/profiles-client.ts +51 -0
- package/src/client/schedules-client.ts +22 -0
- package/src/client/settings-schema-client.ts +11 -0
- package/src/client/states-client.ts +292 -0
- package/src/client/storage-client.ts +63 -0
- package/src/client/sub-mcp-client.ts +17 -0
- package/src/client/system-client.ts +16 -0
- package/src/client/templates-client.ts +28 -0
- package/src/client/tool-extensions-client.ts +24 -0
- package/src/client/tool-meta-client.ts +65 -0
- package/src/client/tools-client.ts +66 -0
- package/src/client/transport.ts +18 -0
- package/src/client/trigger-links-client.ts +51 -0
- package/src/client/web-entry-gate-client.ts +45 -0
- package/src/http.ts +48 -24
- package/src/schemas/api-keys.ts +26 -0
- package/src/schemas/auth-routes.ts +48 -0
- package/src/schemas/backup.ts +42 -0
- package/src/schemas/capabilities.ts +87 -0
- package/src/schemas/channels.ts +11 -0
- package/src/schemas/config.ts +17 -0
- package/src/schemas/connectors.ts +138 -0
- package/src/schemas/conversations.ts +256 -0
- package/src/schemas/extensions.ts +34 -0
- package/src/schemas/fleet.ts +153 -0
- package/src/schemas/hooks.ts +56 -0
- package/src/schemas/index.ts +37 -0
- package/src/schemas/interactions.ts +146 -0
- package/src/schemas/login.ts +62 -0
- package/src/schemas/manifest-mcp.ts +69 -0
- package/src/schemas/marketplace.ts +447 -0
- package/src/schemas/notifications.ts +42 -0
- package/src/schemas/observability.ts +86 -0
- package/src/schemas/policy.ts +37 -0
- package/src/schemas/presets.ts +113 -0
- package/src/schemas/profiles.ts +119 -0
- package/src/schemas/roles.ts +57 -0
- package/src/schemas/schedules.ts +27 -0
- package/src/schemas/served.ts +49 -0
- package/src/schemas/settings-schema.ts +31 -0
- package/src/schemas/shared.ts +21 -0
- package/src/schemas/states.ts +272 -0
- package/src/schemas/storage.ts +31 -0
- package/src/schemas/studio-plugins.ts +21 -0
- package/src/schemas/sub-mcp.ts +24 -0
- package/src/schemas/system-kinds.ts +46 -0
- package/src/schemas/templates.ts +11 -0
- package/src/schemas/tool-meta.ts +51 -0
- package/src/schemas/tools.ts +61 -0
- package/src/schemas/trigger-links.ts +54 -0
- package/src/schemas/web-entry.ts +46 -0
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -920
- package/dist/client.js.map +0 -1
- package/dist/schemas.d.ts +0 -5172
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -2268
- package/dist/schemas.js.map +0 -1
- package/src/client.ts +0 -1771
- package/src/schemas.ts +0 -2760
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Prompt-template listing, render and mutation sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import type { Transport } from './transport';
|
|
4
|
+
|
|
5
|
+
export function templatesClient(t: Transport) {
|
|
6
|
+
const { req } = t;
|
|
7
|
+
return {
|
|
8
|
+
listTemplates: (signal?: AbortSignal) => req('/api/templates', s.templateNames, { signal }),
|
|
9
|
+
getTemplate: (templateId: string) =>
|
|
10
|
+
req('/api/template', s.templateDetail, { method: 'POST', body: { template_id: templateId } }),
|
|
11
|
+
uploadTemplate: (path: string, content: string) =>
|
|
12
|
+
req('/api/upload-template', s.templateUploaded, { method: 'POST', body: { path, content } }),
|
|
13
|
+
deleteTemplate: (path: string) =>
|
|
14
|
+
req('/api/delete-template', s.templateDeleted, { method: 'POST', body: { path } }),
|
|
15
|
+
// Delete every stored template under a directory prefix. Unlike the idempotent
|
|
16
|
+
// single delete, the server 404s a prefix matching nothing and 400s the template
|
|
17
|
+
// root; those surface as loud errors, never a faked success.
|
|
18
|
+
deleteTemplateDir: (path: string) =>
|
|
19
|
+
req('/api/delete-template-dir', s.templateDirDeleted, { method: 'POST', body: { path } }),
|
|
20
|
+
// Render one authored text — inline `content` OR a stored template `id`, plus its
|
|
21
|
+
// render `kwargs` — and parse the rendered output. The value is the shared
|
|
22
|
+
// `TemplatedText` (exactly one source); the route wraps it under `text`.
|
|
23
|
+
renderTemplate: (text: s.TemplatedText) =>
|
|
24
|
+
req('/api/render-template', s.templateRendered, { method: 'POST', body: { text } }),
|
|
25
|
+
clearTemplatesCache: () =>
|
|
26
|
+
req('/api/clear-templates-cache', s.templateCacheCleared, { method: 'POST' }),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Tool extension listing and authoring sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import { encodeSegment } from '../http';
|
|
4
|
+
import type { Transport } from './transport';
|
|
5
|
+
|
|
6
|
+
export function toolExtensionsClient(t: Transport) {
|
|
7
|
+
const { req } = t;
|
|
8
|
+
return {
|
|
9
|
+
listExtensions: (signal?: AbortSignal) => req('/api/extensions', s.extensions, { signal }),
|
|
10
|
+
// A MANIFEST-provided tool's current combos + the extension catalog. (A preset
|
|
11
|
+
// tool's extensions live on the preset spec, read via `getPreset`.)
|
|
12
|
+
getToolExtensions: (name: string, signal?: AbortSignal) =>
|
|
13
|
+
req(`/api/tools/${encodeSegment(name)}/extensions`, s.toolExtensions, { signal }),
|
|
14
|
+
// Author ALL of a MANIFEST tool's combos at once (the full lossless list; `[]`
|
|
15
|
+
// clears). Returns the apply result: the local reload (`status` + `env_keys`) plus
|
|
16
|
+
// the mode-wrapped fleet `fanout` of the reload it broadcast, from which the shared
|
|
17
|
+
// fleet-report handler surfaces any failed propagation.
|
|
18
|
+
setToolExtensions: (name: string, combos: readonly s.PresetExtensionElement[][]) =>
|
|
19
|
+
req(`/api/tools/${encodeSegment(name)}/extensions`, s.toolExtensionsApplyResult, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
body: { combos },
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Tool-organization overlay (folders and meta) sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import { encodeSegment } from '../http';
|
|
4
|
+
import type { Transport } from './transport';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Merge-patch body for a tool's overlay row (PATCH
|
|
8
|
+
* `/api/tool-meta/tools/{tool_name}`). Only the fields PRESENT are written; a
|
|
9
|
+
* present-null clears (`hidden: null` writes the tri-state "defer to the plugin
|
|
10
|
+
* declaration" state, `display_name: null` clears the label, `folder_id: null`
|
|
11
|
+
* unfiles); a present `tags` array replaces the whole set. Absent fields are left
|
|
12
|
+
* untouched — there is no full-row replace, so a display-name+tags editor sends
|
|
13
|
+
* ONLY those two keys with no risk to `folder_id`/`hidden`. At least one field must
|
|
14
|
+
* be present. A blank/whitespace-only `display_name` is rejected by the API (422) —
|
|
15
|
+
* callers map an emptied label to `null`, never `""`. A present `badges` array
|
|
16
|
+
* replaces the whole overlay set (INFORMATIONAL labels, never an enforced gate).
|
|
17
|
+
*/
|
|
18
|
+
export interface ToolMetaPatch {
|
|
19
|
+
readonly display_name?: string | null;
|
|
20
|
+
readonly folder_id?: string | null;
|
|
21
|
+
readonly tags?: readonly string[];
|
|
22
|
+
readonly badges?: readonly string[];
|
|
23
|
+
readonly hidden?: boolean | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function toolMetaClient(t: Transport) {
|
|
27
|
+
const { req } = t;
|
|
28
|
+
return {
|
|
29
|
+
// The folder tree + per-tool overlay rows in one read; the features merge the
|
|
30
|
+
// rows against the live tool list and native tags client-side.
|
|
31
|
+
listToolMeta: (signal?: AbortSignal) => req('/api/tool-meta', s.toolMetaOverlay, { signal }),
|
|
32
|
+
// Merge-patch a tool's overlay row (create it if absent). `patch` carries ONLY
|
|
33
|
+
// the fields to change — a present-null clears, an absent field is untouched,
|
|
34
|
+
// and a present `tags` array replaces the set.
|
|
35
|
+
upsertToolMeta: (toolName: string, patch: ToolMetaPatch) =>
|
|
36
|
+
req(`/api/tool-meta/tools/${encodeSegment(toolName)}`, s.toolMetaRecord, {
|
|
37
|
+
method: 'PATCH',
|
|
38
|
+
body: patch,
|
|
39
|
+
}),
|
|
40
|
+
deleteToolMeta: (toolName: string) =>
|
|
41
|
+
req(`/api/tool-meta/tools/${encodeSegment(toolName)}`, s.toolMetaDeleted, {
|
|
42
|
+
method: 'DELETE',
|
|
43
|
+
}),
|
|
44
|
+
createFolder: (name: string, parentId: string | null = null) =>
|
|
45
|
+
req('/api/tool-meta/folders', s.folderRecord, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
body: { name, parent_id: parentId },
|
|
48
|
+
}),
|
|
49
|
+
renameFolder: (folderId: string, name: string) =>
|
|
50
|
+
req(`/api/tool-meta/folders/${encodeSegment(folderId)}/rename`, s.folderRecord, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
body: { name },
|
|
53
|
+
}),
|
|
54
|
+
// `null` re-parents to the root.
|
|
55
|
+
moveFolder: (folderId: string, parentId: string | null) =>
|
|
56
|
+
req(`/api/tool-meta/folders/${encodeSegment(folderId)}/move`, s.folderRecord, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
body: { parent_id: parentId },
|
|
59
|
+
}),
|
|
60
|
+
deleteFolder: (folderId: string) =>
|
|
61
|
+
req(`/api/tool-meta/folders/${encodeSegment(folderId)}`, s.folderDeleted, {
|
|
62
|
+
method: 'DELETE',
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Tool catalog, run, live-registry admin and tag sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import { encodeSegment } from '../http';
|
|
4
|
+
import { getToolRun, listToolRuns, submitToolRun, type SubmitToolRunArgs } from '../tool-runs';
|
|
5
|
+
import type { Transport } from './transport';
|
|
6
|
+
|
|
7
|
+
export interface RunToolArgs {
|
|
8
|
+
readonly tool: string;
|
|
9
|
+
readonly kwargs?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Identify one app tool for a live-registry op (`POST /api/tools/reload`,
|
|
14
|
+
* `POST /api/tools/remove`): its `kind` (the reloader kind a plugin registered,
|
|
15
|
+
* e.g. `example_tool`) and `name`. `targets` optionally restricts the fleet
|
|
16
|
+
* fan-out to specific workers; omit it to reach every worker.
|
|
17
|
+
*/
|
|
18
|
+
export interface ToolAdminArgs {
|
|
19
|
+
readonly kind: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly targets?: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function toolsClient(t: Transport) {
|
|
25
|
+
const { config, req } = t;
|
|
26
|
+
return {
|
|
27
|
+
listTools: (signal?: AbortSignal) => req('/api/tools', s.toolNames, { signal }),
|
|
28
|
+
getToolSchema: (name: string, signal?: AbortSignal) =>
|
|
29
|
+
req(`/api/tools/${encodeSegment(name)}/schema`, s.toolSchema, { signal }),
|
|
30
|
+
getAllToolSchemas: (signal?: AbortSignal) =>
|
|
31
|
+
req('/api/tools-schema', s.allToolSchemas, { signal }),
|
|
32
|
+
runTool: (args: RunToolArgs, signal?: AbortSignal) =>
|
|
33
|
+
req('/api/run-tool', s.runToolResult, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
// The backend's `/api/run-tool` door reads `{tool_name, arguments}` (the
|
|
36
|
+
// shape `read_tool_call` enforces and the background `/api/tool-runs`
|
|
37
|
+
// submit already sends). The SPA keeps `tool`/`kwargs` as its ergonomic
|
|
38
|
+
// arg names; map them onto the wire fields here.
|
|
39
|
+
body: { tool_name: args.tool, arguments: args.kwargs ?? {} },
|
|
40
|
+
signal,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
// Re-register or remove one app tool by kind+name, applied on this worker and
|
|
44
|
+
// broadcast to the fleet (all workers, or only `targets`); both return the bare
|
|
45
|
+
// per-worker `fleetResult` the shared fleet-report handler renders. Both are
|
|
46
|
+
// fenced + destructive server-side, so a refusal surfaces as a loud error.
|
|
47
|
+
reloadTool: (args: ToolAdminArgs) =>
|
|
48
|
+
req('/api/tools/reload', s.fleetResult, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
body: { kind: args.kind, name: args.name, targets: args.targets ?? null },
|
|
51
|
+
}),
|
|
52
|
+
removeTool: (args: ToolAdminArgs) =>
|
|
53
|
+
req('/api/tools/remove', s.fleetResult, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
body: { kind: args.kind, name: args.name, targets: args.targets ?? null },
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
submitToolRun: (args: SubmitToolRunArgs, signal?: AbortSignal) =>
|
|
59
|
+
submitToolRun(config, args, signal),
|
|
60
|
+
getToolRun: (runId: string, signal?: AbortSignal) => getToolRun(config, runId, signal),
|
|
61
|
+
listToolRuns: (toolName: string, signal?: AbortSignal) =>
|
|
62
|
+
listToolRuns(config, toolName, signal),
|
|
63
|
+
|
|
64
|
+
listToolTags: (signal?: AbortSignal) => req('/api/tools/tags', s.toolTags, { signal }),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The shared transport seam every sub-client method flows through. */
|
|
2
|
+
import type { ApiConfig } from '../http';
|
|
3
|
+
import { apiRequest } from '../http';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build the per-request transport for one client: the bound `config` and the
|
|
7
|
+
* `req` chokepoint that validates every response against its schema.
|
|
8
|
+
*/
|
|
9
|
+
export function makeTransport(config: ApiConfig) {
|
|
10
|
+
const req = <S extends Parameters<typeof apiRequest>[2]>(
|
|
11
|
+
path: string,
|
|
12
|
+
schema: S,
|
|
13
|
+
options?: Parameters<typeof apiRequest>[3],
|
|
14
|
+
) => apiRequest(config, path, schema, options);
|
|
15
|
+
return { config, req };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type Transport = ReturnType<typeof makeTransport>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Trigger-link mint, listing and revoke sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import { encodeSegment } from '../http';
|
|
4
|
+
import type { Transport } from './transport';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Body for minting a trigger link (POST `/api/hooks/trigger-links`). `ttl_seconds`
|
|
8
|
+
* is REQUIRED and nullable — a positive int is a timed link, `null` is a permanent
|
|
9
|
+
* link (`0`/negative is a loud server 400); it is always sent EXPLICITLY (a dropped
|
|
10
|
+
* key 400s server-side). `name` is optional (the server generates one when omitted);
|
|
11
|
+
* `tool_kwargs` is the optional per-link params merged last into every fire.
|
|
12
|
+
*/
|
|
13
|
+
export interface TriggerLinkCreateBody {
|
|
14
|
+
readonly topic: string;
|
|
15
|
+
readonly name?: string;
|
|
16
|
+
readonly execution_key: string;
|
|
17
|
+
// The link is a token door; this is its only auth knob (token → token+api_key).
|
|
18
|
+
readonly require_api_key: boolean;
|
|
19
|
+
readonly ttl_seconds: number | null;
|
|
20
|
+
readonly tool_kwargs?: Record<string, unknown> | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function triggerLinksClient(t: Transport) {
|
|
24
|
+
const { req } = t;
|
|
25
|
+
return {
|
|
26
|
+
// Mint a trigger link for a topic. `ttl_seconds` is sent EXPLICITLY
|
|
27
|
+
// (including `null` for a permanent link) — the server requires the key present
|
|
28
|
+
// and 400s a dropped one; `tool_kwargs` is omitted when undefined. The raw
|
|
29
|
+
// `token` rides the response ONCE (composed into the QR URL client-side).
|
|
30
|
+
createTriggerLink: (body: TriggerLinkCreateBody) =>
|
|
31
|
+
req('/api/hooks/trigger-links', s.triggerLinkCreated, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
body: {
|
|
34
|
+
topic: body.topic,
|
|
35
|
+
name: body.name,
|
|
36
|
+
execution_key: body.execution_key,
|
|
37
|
+
require_api_key: body.require_api_key,
|
|
38
|
+
ttl_seconds: body.ttl_seconds,
|
|
39
|
+
tool_kwargs: body.tool_kwargs,
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
// Every live trigger-link record (hash prefix only — never a raw token).
|
|
43
|
+
listTriggerLinks: (signal?: AbortSignal) =>
|
|
44
|
+
req('/api/hooks/trigger-links', s.triggerLinkList, { signal }),
|
|
45
|
+
// Revoke a link by name (immediate + durable). 404 when the name is unknown.
|
|
46
|
+
deleteTriggerLink: (name: string) =>
|
|
47
|
+
req(`/api/hooks/trigger-links/${encodeSegment(name)}`, s.triggerLinkDeleted, {
|
|
48
|
+
method: 'DELETE',
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** Web-channel entry-gate sub-client. */
|
|
2
|
+
import * as s from '../schemas';
|
|
3
|
+
import { encodeSegment } from '../http';
|
|
4
|
+
import type { Transport } from './transport';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Body for minting a web entry code (POST
|
|
8
|
+
* `/api/channels/web/gates/{identity}/codes`). Both fields are optional-nullable
|
|
9
|
+
* and sent EXPLICITLY: `label` is a human tag (`null` for none); `expires_at` is
|
|
10
|
+
* an ISO-8601 instant the code dies at (`null` for a code that never expires).
|
|
11
|
+
*/
|
|
12
|
+
export interface WebEntryCodeMintBody {
|
|
13
|
+
readonly label: string | null;
|
|
14
|
+
readonly expires_at: string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function webEntryGateClient(t: Transport) {
|
|
18
|
+
const { req } = t;
|
|
19
|
+
return {
|
|
20
|
+
// A web route's entry gate, keyed by its `our_identity`: read the flag + its
|
|
21
|
+
// live codes, flip the flag, mint a code (raw returned ONCE), revoke a code by
|
|
22
|
+
// its hash id. The conversation monitor's first route mutations.
|
|
23
|
+
getWebEntryGate: (identity: string, signal?: AbortSignal) =>
|
|
24
|
+
req(`/api/channels/web/gates/${encodeSegment(identity)}`, s.webEntryGate, { signal }),
|
|
25
|
+
setWebEntryGate: (identity: string, enabled: boolean) =>
|
|
26
|
+
req(`/api/channels/web/gates/${encodeSegment(identity)}`, s.webEntryGateState, {
|
|
27
|
+
method: 'PUT',
|
|
28
|
+
body: { enabled },
|
|
29
|
+
}),
|
|
30
|
+
// Mint a code. `label`/`expires_at` are sent EXPLICITLY (including `null`). The
|
|
31
|
+
// raw `code` rides the reply ONCE (composed into the chat URL client-side).
|
|
32
|
+
mintWebEntryCode: (identity: string, body: WebEntryCodeMintBody) =>
|
|
33
|
+
req(`/api/channels/web/gates/${encodeSegment(identity)}/codes`, s.webEntryCodeMinted, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
body: { label: body.label, expires_at: body.expires_at },
|
|
36
|
+
}),
|
|
37
|
+
// Revoke a code by its hash id (immediate + durable). 404 when the id is unknown.
|
|
38
|
+
revokeWebEntryCode: (identity: string, codeId: string) =>
|
|
39
|
+
req(
|
|
40
|
+
`/api/channels/web/gates/${encodeSegment(identity)}/codes/${encodeSegment(codeId)}`,
|
|
41
|
+
s.webEntryCodeRevoked,
|
|
42
|
+
{ method: 'DELETE' },
|
|
43
|
+
),
|
|
44
|
+
};
|
|
45
|
+
}
|
package/src/http.ts
CHANGED
|
@@ -92,30 +92,18 @@ function retryAfterSeconds(header: string | null): number | undefined {
|
|
|
92
92
|
return Number.isFinite(seconds) && seconds >= 0 ? seconds : undefined;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Read the JSON body of a request response, applying the transport's error
|
|
97
|
+
* policy: a non-2xx status throws (a 409 as `ApiConflictError` carrying the
|
|
98
|
+
* parsed body, every other as `ApiError` with the server message/code and the
|
|
99
|
+
* named `Retry-After` delay), and a body that is not JSON throws `ApiSchemaError`
|
|
100
|
+
* on a 2xx or `ApiError` otherwise. Returns the parsed payload only for a 2xx.
|
|
101
|
+
*/
|
|
102
|
+
async function readJsonPayload(
|
|
103
|
+
response: Response,
|
|
97
104
|
path: string,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
): Promise<z.infer<S>> {
|
|
101
|
-
const doFetch = config.fetch ?? globalThis.fetch;
|
|
102
|
-
const token = config.getToken();
|
|
103
|
-
const headers: Record<string, string> = { ...JSON_HEADERS };
|
|
104
|
-
if (token) headers['x-api-key'] = token;
|
|
105
|
-
|
|
106
|
-
const response = await doFetch(buildUrl(config.baseUrl ?? '', path, options.query), {
|
|
107
|
-
method: options.method ?? 'GET',
|
|
108
|
-
headers,
|
|
109
|
-
body: options.body === undefined ? undefined : JSON.stringify(options.body),
|
|
110
|
-
signal: options.signal,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
if (response.status === 401) throw new ApiUnauthorizedError();
|
|
114
|
-
|
|
115
|
-
// `Retry-After` rides on the error so a retrying caller waits the delay the server
|
|
116
|
-
// named (the gated routes' reloading 503 carries one) instead of guessing.
|
|
117
|
-
const retryAfter = retryAfterSeconds(response.headers.get('Retry-After'));
|
|
118
|
-
|
|
105
|
+
retryAfter: number | undefined,
|
|
106
|
+
): Promise<unknown> {
|
|
119
107
|
let payload: unknown;
|
|
120
108
|
try {
|
|
121
109
|
payload = await response.json();
|
|
@@ -138,15 +126,51 @@ export async function apiRequest<S extends z.ZodType>(
|
|
|
138
126
|
throw new ApiError(text, response.status, code, retryAfter, payload);
|
|
139
127
|
}
|
|
140
128
|
|
|
129
|
+
return payload;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Unwrap the `{ data }` envelope and validate it against `schema`; a missing
|
|
133
|
+
* envelope or a validation failure throws `ApiSchemaError`. */
|
|
134
|
+
function validateEnvelope<S extends z.ZodType>(
|
|
135
|
+
schema: S,
|
|
136
|
+
path: string,
|
|
137
|
+
payload: unknown,
|
|
138
|
+
): z.infer<S> {
|
|
141
139
|
if (!isDataEnvelope(payload)) {
|
|
142
140
|
throw new ApiSchemaError(path, 'response was not a { data } envelope');
|
|
143
141
|
}
|
|
144
|
-
|
|
145
142
|
const parsed = schema.safeParse(payload.data);
|
|
146
143
|
if (!parsed.success) throw new ApiSchemaError(path, parsed.error.issues);
|
|
147
144
|
return parsed.data;
|
|
148
145
|
}
|
|
149
146
|
|
|
147
|
+
export async function apiRequest<S extends z.ZodType>(
|
|
148
|
+
config: ApiConfig,
|
|
149
|
+
path: string,
|
|
150
|
+
schema: S,
|
|
151
|
+
options: RequestOptions = {},
|
|
152
|
+
): Promise<z.infer<S>> {
|
|
153
|
+
const doFetch = config.fetch ?? globalThis.fetch;
|
|
154
|
+
const token = config.getToken();
|
|
155
|
+
const headers: Record<string, string> = { ...JSON_HEADERS };
|
|
156
|
+
if (token) headers['x-api-key'] = token;
|
|
157
|
+
|
|
158
|
+
const response = await doFetch(buildUrl(config.baseUrl ?? '', path, options.query), {
|
|
159
|
+
method: options.method ?? 'GET',
|
|
160
|
+
headers,
|
|
161
|
+
body: options.body === undefined ? undefined : JSON.stringify(options.body),
|
|
162
|
+
signal: options.signal,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (response.status === 401) throw new ApiUnauthorizedError();
|
|
166
|
+
|
|
167
|
+
// `Retry-After` rides on the error so a retrying caller waits the delay the server
|
|
168
|
+
// named (the gated routes' reloading 503 carries one) instead of guessing.
|
|
169
|
+
const retryAfter = retryAfterSeconds(response.headers.get('Retry-After'));
|
|
170
|
+
const payload = await readJsonPayload(response, path, retryAfter);
|
|
171
|
+
return validateEnvelope(schema, path, payload);
|
|
172
|
+
}
|
|
173
|
+
|
|
150
174
|
/**
|
|
151
175
|
* Fetch a plain-text endpoint (the skeleton's `/health` → `"OK"`). No `{ data }`
|
|
152
176
|
* envelope, no zod — the body is returned verbatim. Non-2xx still throws loudly.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** API-key payload and mint/edit/revoke response schemas. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { templatedText } from './served';
|
|
4
|
+
import { jsonValue } from './shared';
|
|
5
|
+
|
|
6
|
+
/** The per-key payloads (`GET /api/auth/tokens-payload`). The stable per-mint
|
|
7
|
+
* `key_fingerprint` is nested under `policy_data`; the picker reads it there. */
|
|
8
|
+
export const tokensPayload = z.array(
|
|
9
|
+
z.object({
|
|
10
|
+
// The value an `execution_key` binding names.
|
|
11
|
+
user_id: z.string().min(1),
|
|
12
|
+
description: z.string(),
|
|
13
|
+
scopes: z.array(z.string()),
|
|
14
|
+
policy_data: jsonValue,
|
|
15
|
+
condition: templatedText.nullable().optional(),
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
export type TokensPayload = z.infer<typeof tokensPayload>;
|
|
19
|
+
|
|
20
|
+
/** Mint reply `{ api_key, key_fingerprint }` narrowed to the raw `sk-…` key,
|
|
21
|
+
* returned once at creation and never again. */
|
|
22
|
+
export const createdApiKey = z
|
|
23
|
+
.object({ api_key: z.string(), key_fingerprint: z.string() })
|
|
24
|
+
.transform((minted) => minted.api_key);
|
|
25
|
+
export const editApiKeyResult = z.object({ user_id: z.string(), updated: z.boolean() });
|
|
26
|
+
export const revokeApiKeyResult = z.object({ user_id: z.string(), revoked: z.boolean() });
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Route catalog, scope mapping and public-route response schemas. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/** `{ url: scope_id }` — every URL currently mapped to a scope. */
|
|
5
|
+
export const authScopes = z.record(z.string(), z.string());
|
|
6
|
+
|
|
7
|
+
export const addUrlToScopeResult = z.object({ scope_id: z.string(), url: z.string() });
|
|
8
|
+
export const removeUrlFromScopeResult = z.object({ url: z.string() });
|
|
9
|
+
export const removeScopeResult = z.object({ scope_id: z.string(), deleted_keys: z.number() });
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A route's authorization ACTION class, joined onto the catalog from the route
|
|
13
|
+
* registry. `read`/`write` routes are GRANTABLE — a role's per-tag level opens
|
|
14
|
+
* them; `fenced`/`secret` routes are ADMIN-ONLY and never grantable (no per-tag
|
|
15
|
+
* level reaches them). `null` marks a path the registry carries no metadata for
|
|
16
|
+
* (an unregistered/ungated path — no feature tags, no action).
|
|
17
|
+
*/
|
|
18
|
+
export const routeAction = z.enum(['read', 'write', 'fenced', 'secret']);
|
|
19
|
+
export type RouteAction = z.infer<typeof routeAction>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* One row of the route catalog (`GET /api/auth/routes`) — a plain HTTP route with
|
|
23
|
+
* its current mapping, JOINED with its route-registry metadata. `mapped` is the
|
|
24
|
+
* scope id, the public marker, or `null` when the path is unmapped (the mapper's
|
|
25
|
+
* "unassigned" bucket source). `methods` is the route's method set with `HEAD`
|
|
26
|
+
* removed. `tags` are the route's feature-group labels, `summary` its one-line
|
|
27
|
+
* description, and `action` its authorization class — the join fields the Roles
|
|
28
|
+
* grant editor reads to derive grantable feature groups and mark the admin-only
|
|
29
|
+
* (fenced/secret) routes it must never offer a grant for. An unregistered path
|
|
30
|
+
* carries `tags: []`, `summary: ''`, `action: null`.
|
|
31
|
+
*/
|
|
32
|
+
export const authRoute = z.object({
|
|
33
|
+
path: z.string(),
|
|
34
|
+
methods: z.array(z.string()),
|
|
35
|
+
mapped: z.string().nullable(),
|
|
36
|
+
tags: z.array(z.string()),
|
|
37
|
+
summary: z.string(),
|
|
38
|
+
action: routeAction.nullable(),
|
|
39
|
+
});
|
|
40
|
+
export type AuthRoute = z.infer<typeof authRoute>;
|
|
41
|
+
export const authRoutes = z.array(authRoute);
|
|
42
|
+
/** `GET /api/auth/public-routes` — the sorted urls pinned to the public marker. */
|
|
43
|
+
export const publicRoutes = z.array(z.string());
|
|
44
|
+
|
|
45
|
+
/** `POST /api/auth/public-routes` — the pinned url. */
|
|
46
|
+
export const pinPublicResult = z.object({ url: z.string() });
|
|
47
|
+
/** `DELETE /api/auth/public-routes` — the unpinned url (404 when not pinned). */
|
|
48
|
+
export const unpinPublicResult = z.object({ url: z.string() });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Backup section, document and import-report response schemas. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { fleetReportFanout } from './fleet';
|
|
4
|
+
|
|
5
|
+
export const backupSections = z.array(z.object({ name: z.string(), secret: z.boolean() }));
|
|
6
|
+
|
|
7
|
+
/** The exported backup document — validated when the UI reads a picked file. */
|
|
8
|
+
export const backupDocument = z.object({
|
|
9
|
+
version: z.literal(1),
|
|
10
|
+
created_at: z.string(),
|
|
11
|
+
sections: z.record(z.string(), z.unknown()),
|
|
12
|
+
errors: z.record(z.string(), z.string()).optional(),
|
|
13
|
+
});
|
|
14
|
+
export type BackupDocument = z.infer<typeof backupDocument>;
|
|
15
|
+
|
|
16
|
+
export const backupImportReport = z.object({
|
|
17
|
+
ok: z.boolean(),
|
|
18
|
+
sections: z.record(
|
|
19
|
+
z.string(),
|
|
20
|
+
z.object({
|
|
21
|
+
created: z.number(),
|
|
22
|
+
updated: z.number(),
|
|
23
|
+
skipped: z.number(),
|
|
24
|
+
errors: z.array(z.string()),
|
|
25
|
+
new_api_keys: z
|
|
26
|
+
.array(
|
|
27
|
+
z.object({
|
|
28
|
+
user_id: z.string(),
|
|
29
|
+
description: z.string(),
|
|
30
|
+
api_key: z.string(),
|
|
31
|
+
}),
|
|
32
|
+
)
|
|
33
|
+
.optional(),
|
|
34
|
+
// The `manifest` and `env` sections apply through the config pipeline, so their
|
|
35
|
+
// report carries the mode-wrapped fleet `fanout` of the restore's reload; other
|
|
36
|
+
// sections omit it. Parsed EXPLICITLY so the shared fleet-report handler can
|
|
37
|
+
// surface a failed restore propagation — otherwise zod would strip it silently.
|
|
38
|
+
fanout: fleetReportFanout.optional(),
|
|
39
|
+
}),
|
|
40
|
+
),
|
|
41
|
+
});
|
|
42
|
+
export type BackupImportReport = z.infer<typeof backupImportReport>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** Caller capability projection and auth-capabilities schemas. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { subMcpMount } from './sub-mcp';
|
|
4
|
+
|
|
5
|
+
/** A concrete route the caller can reach, with the methods that pass its jq fence. */
|
|
6
|
+
export const routeEntry = z.object({
|
|
7
|
+
path: z.string(),
|
|
8
|
+
methods: z.array(z.string()),
|
|
9
|
+
});
|
|
10
|
+
export type RouteEntry = z.infer<typeof routeEntry>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A dynamic route pattern the caller can reach — a mount/pattern surface not
|
|
14
|
+
* enumerable into concrete paths, projected only when its scope AND jq admit it.
|
|
15
|
+
*/
|
|
16
|
+
export const patternEntry = z.object({
|
|
17
|
+
pattern: z.string(),
|
|
18
|
+
scope_id: z.string(),
|
|
19
|
+
});
|
|
20
|
+
export type PatternEntry = z.infer<typeof patternEntry>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A sub-MCP mount the caller can reach, with the tools it exposes and its
|
|
24
|
+
* transport. Shares the {@link subMcpMount} shape with the registry list, adding
|
|
25
|
+
* the `slug` the projection carries inline (the list keys mounts by slug instead).
|
|
26
|
+
*/
|
|
27
|
+
export const subMcpEntry = subMcpMount.extend({ slug: z.string() });
|
|
28
|
+
export type SubMcpEntry = z.infer<typeof subMcpEntry>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `GET /api/auth/me` — the caller's derived capability projection: the concrete
|
|
32
|
+
* (path, method) surface, dynamic patterns, sub-MCP mounts, tools, and agents it
|
|
33
|
+
* can reach RIGHT NOW (derived server-side, never stored). `admin` is the
|
|
34
|
+
* condition-free ownerless `"*"` discriminator (a TOTAL projection); a scoped
|
|
35
|
+
* session carries `admin: false` and a jq-exact `routes` list. `owner_user_id` is
|
|
36
|
+
* the key's owner claim, `null` for an ownerless key. The invariant is
|
|
37
|
+
* projection ⊆ gate: every projected surface is one the server would admit, so
|
|
38
|
+
* the UI can filter on it without ever advertising a door the gate denies.
|
|
39
|
+
*/
|
|
40
|
+
export const meProjection = z.object({
|
|
41
|
+
user_id: z.string(),
|
|
42
|
+
owner_user_id: z.string().nullable(),
|
|
43
|
+
admin: z.boolean(),
|
|
44
|
+
scopes: z.array(z.string()),
|
|
45
|
+
routes: z.array(routeEntry),
|
|
46
|
+
route_patterns: z.array(patternEntry),
|
|
47
|
+
sub_mcp: z.array(subMcpEntry),
|
|
48
|
+
tools: z.array(z.string()),
|
|
49
|
+
agents: z.array(z.string()),
|
|
50
|
+
mintable: z.boolean(),
|
|
51
|
+
});
|
|
52
|
+
export type MeProjection = z.infer<typeof meProjection>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* `POST /api/auth/claim-links` — a one-time claim link minted in the key-create
|
|
56
|
+
* flow. `claim_path` is a fragment-carrier path (`/login#claim=<token>`, never an
|
|
57
|
+
* absolute URL — the Studio composes the origin); `token` is the raw claim token
|
|
58
|
+
* returned exactly ONCE; `expires_at` is an ISO-8601 instant.
|
|
59
|
+
*/
|
|
60
|
+
export const claimLinkCreated = z.object({
|
|
61
|
+
claim_path: z.string(),
|
|
62
|
+
token: z.string(),
|
|
63
|
+
expires_at: z.string(),
|
|
64
|
+
});
|
|
65
|
+
export type ClaimLinkCreated = z.infer<typeof claimLinkCreated>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* `POST /api/auth/logout` — the single authed logout dispatcher's result.
|
|
69
|
+
* `revoked` is `true` when a live accounts session was revoked; a plain `sk-` key
|
|
70
|
+
* has nothing to revoke and answers `404` (a loud absent-session signal), never a
|
|
71
|
+
* `revoked: false` body. Non-strict, so a SUCCESSFUL logout never throws
|
|
72
|
+
* `ApiSchemaError` on an additive field.
|
|
73
|
+
*/
|
|
74
|
+
export const logoutResult = z.object({ revoked: z.boolean() });
|
|
75
|
+
export type LogoutResult = z.infer<typeof logoutResult>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* `GET /api/auth/capabilities` — whether this deployment can MINT API keys
|
|
79
|
+
* locally. `mintable: false` means every configured identity provider is
|
|
80
|
+
* validator-only (keys are issued at an external issuer), so the key-creation
|
|
81
|
+
* UI disables up front instead of surfacing a raw mint failure. Non-strict.
|
|
82
|
+
*/
|
|
83
|
+
export const authCapabilities = z.object({
|
|
84
|
+
mintable: z.boolean(),
|
|
85
|
+
providers: z.array(z.object({ name: z.string(), mintable: z.boolean() })),
|
|
86
|
+
});
|
|
87
|
+
export type AuthCapabilities = z.infer<typeof authCapabilities>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Installed channel-plugin catalog response schema. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// The installed channel-plugin catalog: names registered via the manifest's
|
|
5
|
+
// channel modules. A deployment with none bound answers questions only in this
|
|
6
|
+
// inbox (the Studio default).
|
|
7
|
+
|
|
8
|
+
export const channels = z.object({
|
|
9
|
+
channels: z.array(z.string()),
|
|
10
|
+
});
|
|
11
|
+
export type Channels = z.infer<typeof channels>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Environment-config and config-mode response schemas. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const envConfig = z.object({
|
|
5
|
+
env: z.record(z.string(), z.string()),
|
|
6
|
+
secret_keys: z.array(z.string()),
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* `GET /api/config/mode` — the active config backend mode (`file` / `k8s`). The
|
|
10
|
+
* skeleton emits only `config_mode`; `read_only` is a UI-side gate, tolerated-absent
|
|
11
|
+
* and defaulting to `false` (writable) so a normal response never drifts, while a
|
|
12
|
+
* genuinely read-only deployment can opt in by emitting `read_only: true`.
|
|
13
|
+
*/
|
|
14
|
+
export const configMode = z.object({
|
|
15
|
+
config_mode: z.string(),
|
|
16
|
+
read_only: z.boolean().default(false),
|
|
17
|
+
});
|