@tai42/api-client 15.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} +2199 -2508
- 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/generated/served-schemas.d.ts +748 -0
- package/dist/generated/served-schemas.d.ts.map +1 -0
- package/dist/generated/served-schemas.js +60 -0
- package/dist/generated/served-schemas.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/index.d.ts +1 -1
- package/dist/index.d.ts.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/templated-text.d.ts +30 -0
- package/dist/templated-text.d.ts.map +1 -0
- package/dist/templated-text.js +30 -0
- package/dist/templated-text.js.map +1 -0
- package/dist/tool-runs.d.ts +4 -4
- package/package.json +6 -2
- 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/generated/served-schemas.ts +126 -0
- package/src/http.ts +48 -24
- package/src/index.ts +1 -0
- 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/src/templated-text.ts +35 -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 -5152
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -2556
- package/dist/schemas.js.map +0 -1
- package/src/client.ts +0 -1765
- package/src/schemas.ts +0 -3067
|
@@ -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
|
+
}
|