@opengeni/contracts 0.44.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-authored-durable-text.d.ts +70 -0
- package/dist/agent-config.d.ts +869 -0
- package/dist/agent-instruction-changes.d.ts +110 -0
- package/dist/agent-learning.d.ts +243 -0
- package/dist/agent-topology.d.ts +292 -0
- package/dist/allowance-refusal.d.ts +9 -0
- package/dist/allowance-refusal.js +50 -0
- package/dist/allowance-refusal.js.map +1 -0
- package/dist/analytics-consent-report.d.ts +19 -0
- package/dist/analytics-consent-report.js +10 -0
- package/dist/analytics-consent-report.js.map +1 -0
- package/dist/api-key-presets.d.ts +19 -0
- package/dist/artifact-catalog.d.ts +161 -0
- package/dist/artifacts.d.ts +135 -11
- package/dist/atlassian-native-retirement.d.ts +16 -0
- package/dist/atlassian-native-retirement.js +30 -0
- package/dist/atlassian-native-retirement.js.map +1 -0
- package/dist/atlassian.d.ts +2 -0
- package/dist/atlassian.js +27 -11
- package/dist/browser-storage.d.ts +5 -0
- package/dist/browser-storage.js +9 -0
- package/dist/browser-storage.js.map +1 -0
- package/dist/bundled-skills.d.ts +40 -0
- package/dist/canonical-human-identities.d.ts +157 -0
- package/dist/canonical-human-identities.js +23 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/chunk-2ACYHZFB.js +292 -0
- package/dist/chunk-2ACYHZFB.js.map +1 -0
- package/dist/chunk-2VORLN2R.js +353 -0
- package/dist/chunk-2VORLN2R.js.map +1 -0
- package/dist/{chunk-Y3MLSLB4.js → chunk-3SIZGL3O.js} +42 -30
- package/dist/chunk-3SIZGL3O.js.map +1 -0
- package/dist/chunk-46KLD2UH.js +186 -0
- package/dist/chunk-46KLD2UH.js.map +1 -0
- package/dist/chunk-4JGHSSB7.js +11 -0
- package/dist/chunk-4JGHSSB7.js.map +1 -0
- package/dist/{chunk-52SGB2QO.js → chunk-5IXYF6XN.js} +50 -10
- package/dist/chunk-5IXYF6XN.js.map +1 -0
- package/dist/chunk-BCS7WHCK.js +139 -0
- package/dist/chunk-BCS7WHCK.js.map +1 -0
- package/dist/chunk-EK7NDGFR.js +128 -0
- package/dist/chunk-EK7NDGFR.js.map +1 -0
- package/dist/{chunk-5UDNP7AO.js → chunk-FZ6BXQHL.js} +78 -38
- package/dist/chunk-FZ6BXQHL.js.map +1 -0
- package/dist/chunk-GRG7PHWQ.js +25 -0
- package/dist/chunk-GRG7PHWQ.js.map +1 -0
- package/dist/chunk-JUFK3T4Q.js +80 -0
- package/dist/chunk-JUFK3T4Q.js.map +1 -0
- package/dist/chunk-KHHZTBP7.js +11 -0
- package/dist/chunk-KHHZTBP7.js.map +1 -0
- package/dist/chunk-KR2V42UZ.js +187 -0
- package/dist/chunk-KR2V42UZ.js.map +1 -0
- package/dist/chunk-MZLBPKFE.js +168 -0
- package/dist/chunk-MZLBPKFE.js.map +1 -0
- package/dist/{chunk-H5BVCZKF.js → chunk-NRMCVHAU.js} +6 -5
- package/dist/chunk-NRMCVHAU.js.map +1 -0
- package/dist/{chunk-TZ6YEYN4.js → chunk-NVJMJWLL.js} +3 -1
- package/dist/chunk-NVJMJWLL.js.map +1 -0
- package/dist/chunk-O77VSFYZ.js +70 -0
- package/dist/chunk-O77VSFYZ.js.map +1 -0
- package/dist/chunk-PX3VCKAU.js +29 -0
- package/dist/chunk-PX3VCKAU.js.map +1 -0
- package/dist/chunk-QR5D2IQC.js +61 -0
- package/dist/chunk-QR5D2IQC.js.map +1 -0
- package/dist/chunk-RJ76DRPO.js +117 -0
- package/dist/chunk-RJ76DRPO.js.map +1 -0
- package/dist/chunk-RKX3NQYS.js +28 -0
- package/dist/chunk-RKX3NQYS.js.map +1 -0
- package/dist/{chunk-FJBG5E4O.js → chunk-SIOU2K4U.js} +45 -22
- package/dist/chunk-SIOU2K4U.js.map +1 -0
- package/dist/chunk-TSCDAGET.js +75 -0
- package/dist/chunk-TSCDAGET.js.map +1 -0
- package/dist/{chunk-LSB7GRLG.js → chunk-TXTQIYCV.js} +15 -11
- package/dist/chunk-TXTQIYCV.js.map +1 -0
- package/dist/chunk-X7ETVO4P.js +26544 -0
- package/dist/chunk-X7ETVO4P.js.map +1 -0
- package/dist/{chunk-CADSX6UN.js → chunk-Y3KNXVTD.js} +2 -2
- package/dist/chunk-YBW5JSA3.js +251 -0
- package/dist/chunk-YBW5JSA3.js.map +1 -0
- package/dist/chunk-YRXAWWCU.js +45 -0
- package/dist/chunk-YRXAWWCU.js.map +1 -0
- package/dist/claude-provider-account-authority.d.ts +18 -0
- package/dist/claude-subscription-oauth.d.ts +42 -0
- package/dist/claude-subscription-usage.d.ts +159 -0
- package/dist/client-error-report.d.ts +109 -0
- package/dist/client-error-report.js +87 -0
- package/dist/client-error-report.js.map +1 -0
- package/dist/code-search.d.ts +52 -0
- package/dist/code-search.js +40 -0
- package/dist/code-search.js.map +1 -0
- package/dist/codex-provider-account-authority.d.ts +23 -0
- package/dist/codex-provider-account-authority.js +23 -0
- package/dist/codex-provider-account-authority.js.map +1 -0
- package/dist/company-brain-governed-writes.d.ts +475 -0
- package/dist/company-brain.d.ts +336 -0
- package/dist/company-profile.d.ts +566 -0
- package/dist/connect.d.ts +325 -0
- package/dist/connect.js +191 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-account-label.d.ts +2 -0
- package/dist/connection-account-label.js +35 -0
- package/dist/connection-account-label.js.map +1 -0
- package/dist/connection-authority.d.ts +193 -0
- package/dist/connection-authority.js +50 -0
- package/dist/connection-authority.js.map +1 -0
- package/dist/connector-attachments.d.ts +95 -0
- package/dist/connector-attachments.js +51 -0
- package/dist/connector-attachments.js.map +1 -0
- package/dist/connector-tool-permissions.d.ts +73 -0
- package/dist/direct-model-provider.d.ts +36 -0
- package/dist/editable-artifact-codec-registry.d.ts +16 -7
- package/dist/editable-artifact-codec-registry.js +19 -9
- package/dist/editable-artifact-committed-transaction.d.ts +2 -2
- package/dist/editable-artifact-committed-transaction.js +2 -2
- package/dist/editable-artifact-live.d.ts +11 -12
- package/dist/editable-artifact-live.js +110 -45
- package/dist/editable-artifact-live.js.map +1 -1
- package/dist/editable-artifact-serialized-commit.d.ts +2 -1
- package/dist/editable-artifact-serialized-commit.js +8 -7
- package/dist/editable-artifact-versions.d.ts +20 -5
- package/dist/editable-artifact-versions.js +23 -5
- package/dist/editable-artifacts.d.ts +2 -0
- package/dist/editable-artifacts.js +48 -36
- package/dist/external-identities.d.ts +784 -0
- package/dist/external-identities.js +44 -0
- package/dist/external-identities.js.map +1 -0
- package/dist/feedback.d.ts +51 -0
- package/dist/github-repository-contracts.d.ts +36 -0
- package/dist/github-repository-contracts.js +59 -0
- package/dist/github-repository-contracts.js.map +1 -0
- package/dist/github-repository.d.ts +14 -0
- package/dist/github-repository.js +36 -0
- package/dist/github-repository.js.map +1 -0
- package/dist/google-drive.d.ts +90 -1
- package/dist/google-drive.js +91 -15
- package/dist/google-drive.js.map +1 -1
- package/dist/governed-learning-activation.d.ts +154 -0
- package/dist/governed-learning-evaluator.d.ts +152 -0
- package/dist/host-mcp-bindings.d.ts +326 -0
- package/dist/host-mcp-bindings.js +252 -0
- package/dist/host-mcp-bindings.js.map +1 -0
- package/dist/image-generation.d.ts +1 -0
- package/dist/index.d.ts +27574 -5374
- package/dist/index.js +2531 -177
- package/dist/insights-usage.d.ts +877 -0
- package/dist/insights-usage.js +509 -0
- package/dist/insights-usage.js.map +1 -0
- package/dist/interaction.d.ts +1752 -13
- package/dist/knowledge-entries.d.ts +982 -0
- package/dist/knowledge-preparation.d.ts +237 -0
- package/dist/knowledge.d.ts +740 -0
- package/dist/managed-auth-session-sets.d.ts +241 -0
- package/dist/managed-auth-session-sets.js +191 -0
- package/dist/managed-auth-session-sets.js.map +1 -0
- package/dist/managed-sign-in-methods.d.ts +56 -0
- package/dist/managed-sign-in-methods.js +46 -0
- package/dist/managed-sign-in-methods.js.map +1 -0
- package/dist/mcp-catalog-limits.d.ts +2 -0
- package/dist/mcp-endpoint.d.ts +7 -0
- package/dist/mcp-endpoint.js +9 -0
- package/dist/mcp-endpoint.js.map +1 -0
- package/dist/mcp-oauth.d.ts +71 -0
- package/dist/modal-native-proof-v2.d.ts +587 -0
- package/dist/modal-native-proof-v2.js +37 -0
- package/dist/modal-native-proof-v2.js.map +1 -0
- package/dist/model-availability.d.ts +15 -0
- package/dist/model-connection-access.d.ts +24 -0
- package/dist/model-context-inspector.d.ts +329 -0
- package/dist/model-display.d.ts +38 -0
- package/dist/model-display.js +134 -0
- package/dist/model-display.js.map +1 -0
- package/dist/model-picker-order.d.ts +25 -0
- package/dist/model-picker-order.js +42 -0
- package/dist/model-picker-order.js.map +1 -0
- package/dist/organization-access.d.ts +231 -0
- package/dist/organization-access.js +34 -0
- package/dist/organization-access.js.map +1 -0
- package/dist/organization-integration-policy.d.ts +27 -0
- package/dist/organization-membership-lifecycle.d.ts +1022 -0
- package/dist/organization-model-usage.d.ts +146 -0
- package/dist/organization-model-usage.js +67 -0
- package/dist/organization-model-usage.js.map +1 -0
- package/dist/organization-recovery.d.ts +337 -0
- package/dist/organization-recovery.js +37 -0
- package/dist/organization-recovery.js.map +1 -0
- package/dist/organization-usage.d.ts +138 -0
- package/dist/permissions.d.ts +54 -0
- package/dist/personal-github.d.ts +320 -0
- package/dist/personal-github.js +222 -0
- package/dist/personal-github.js.map +1 -0
- package/dist/plugin-discovery.d.ts +35 -0
- package/dist/plugin-discovery.js +7 -0
- package/dist/plugin-discovery.js.map +1 -0
- package/dist/preference-registry.d.ts +44 -1
- package/dist/product-analytics.d.ts +113 -0
- package/dist/product-lifecycle-facts.d.ts +73 -0
- package/dist/remember.d.ts +350 -0
- package/dist/retained-output.d.ts +8 -0
- package/dist/sandbox-file-artifacts.d.ts +57 -0
- package/dist/sandbox-provider-command.d.ts +113 -0
- package/dist/sandbox-recovery.d.ts +146 -0
- package/dist/sandbox-snapshots.d.ts +39 -0
- package/dist/session-final-reply.d.ts +6 -0
- package/dist/session-final-reply.js +9 -0
- package/dist/session-final-reply.js.map +1 -0
- package/dist/session-goal-reports.d.ts +21 -0
- package/dist/session-history-import.d.ts +947 -0
- package/dist/session-list-entries.d.ts +4 -0
- package/dist/session-list-entries.js +51 -0
- package/dist/session-list-entries.js.map +1 -0
- package/dist/session-mcp-projections.d.ts +215 -0
- package/dist/session-message-search.d.ts +68 -0
- package/dist/session-titles.d.ts +68 -0
- package/dist/session-titles.js +25 -0
- package/dist/session-titles.js.map +1 -0
- package/dist/session-topology-primitives.d.ts +22 -0
- package/dist/signup-attribution.d.ts +39 -0
- package/dist/site-request-headers.test.d.ts +1 -0
- package/dist/site-session-http.d.ts +11 -0
- package/dist/site-session-http.js +11 -0
- package/dist/site-session-http.js.map +1 -0
- package/dist/skill-catalog-context.d.ts +7 -0
- package/dist/skill-files.d.ts +12 -0
- package/dist/skill-metadata.d.ts +9 -0
- package/dist/skill-use.d.ts +61 -0
- package/dist/skills.d.ts +185 -0
- package/dist/slack-bot-scopes.d.ts +46 -21
- package/dist/slack-bot-scopes.js +14 -3
- package/dist/slack-rest-mcp.d.ts +31 -0
- package/dist/slack-rest-mcp.js +19 -0
- package/dist/slack-rest-mcp.js.map +1 -0
- package/dist/slack-task-policy.d.ts +294 -0
- package/dist/spreadsheet-artifact-commands.d.ts +2 -3
- package/dist/spreadsheet-artifact-commands.js +4 -2
- package/dist/spreadsheet-artifact-query.js +3 -2
- package/dist/subscription-account-pools.d.ts +292 -0
- package/dist/task-notes.d.ts +169 -0
- package/dist/tool-catalog.d.ts +286 -0
- package/dist/tool-result-spill.d.ts +16 -0
- package/dist/usage-allowances.d.ts +285 -0
- package/dist/usage-allowances.js +49 -0
- package/dist/usage-allowances.js.map +1 -0
- package/dist/video-generation.d.ts +51 -0
- package/dist/video-generation.js +9 -1
- package/dist/work-claims.d.ts +411 -0
- package/dist/workspace-instruction-policies.d.ts +94 -0
- package/dist/workspace-integration-wire.d.ts +36 -0
- package/dist/workspace-integration-wire.js +23 -0
- package/dist/workspace-integration-wire.js.map +1 -0
- package/dist/workspace-integrations.d.ts +948 -0
- package/dist/workspace-learning-administration.d.ts +289 -0
- package/dist/workspace-learning-policy.d.ts +1 -1
- package/dist/workspace-state.d.ts +85 -416
- package/dist/xai-provider-account-authority.d.ts +26 -0
- package/dist/xai-provider-account-authority.js +9 -0
- package/dist/xai-provider-account-authority.js.map +1 -0
- package/package.json +146 -1
- package/src/agent-authored-durable-text.ts +116 -0
- package/src/agent-config.ts +1527 -0
- package/src/agent-instruction-changes.ts +98 -0
- package/src/agent-learning.ts +161 -0
- package/src/agent-topology.ts +69 -0
- package/src/allowance-refusal.ts +81 -0
- package/src/analytics-consent-report.ts +20 -0
- package/src/api-key-presets.ts +25 -0
- package/src/artifact-catalog.ts +60 -0
- package/src/artifacts.ts +146 -18
- package/src/atlassian-native-retirement.ts +33 -0
- package/src/browser-storage.ts +10 -0
- package/src/bundled-skills.ts +73 -0
- package/src/canonical-human-identities.ts +93 -0
- package/src/claude-provider-account-authority.ts +12 -0
- package/src/claude-subscription-oauth.ts +62 -0
- package/src/claude-subscription-usage.ts +59 -0
- package/src/client-error-report.ts +184 -0
- package/src/code-search.ts +105 -0
- package/src/codex-provider-account-authority.ts +37 -0
- package/src/company-brain-governed-writes.ts +356 -0
- package/src/company-brain.ts +201 -0
- package/src/company-profile.ts +167 -1
- package/src/connect.ts +202 -0
- package/src/connection-account-label.ts +46 -0
- package/src/connection-authority.ts +213 -0
- package/src/connector-attachments.ts +327 -0
- package/src/connector-tool-permissions.ts +60 -0
- package/src/direct-model-provider.ts +98 -0
- package/src/editable-artifact-codec-registry.ts +55 -17
- package/src/editable-artifact-committed-transaction.ts +44 -31
- package/src/editable-artifact-live.ts +123 -57
- package/src/editable-artifact-serialized-commit.ts +2 -1
- package/src/editable-artifact-versions.ts +26 -5
- package/src/editable-artifacts.ts +2 -0
- package/src/external-identities.ts +285 -0
- package/src/feedback.ts +39 -0
- package/src/github-repository-contracts.ts +85 -0
- package/src/github-repository.ts +59 -0
- package/src/google-drive.ts +76 -4
- package/src/governed-learning-activation.ts +191 -0
- package/src/governed-learning-evaluator.ts +176 -0
- package/src/host-mcp-bindings.ts +298 -0
- package/src/image-generation.ts +8 -2
- package/src/index.ts +8019 -1799
- package/src/insights-usage.ts +679 -0
- package/src/interaction.ts +1102 -6
- package/src/knowledge-entries.ts +375 -0
- package/src/knowledge-preparation.ts +50 -0
- package/src/knowledge.ts +335 -0
- package/src/managed-auth-session-sets.ts +253 -0
- package/src/managed-sign-in-methods.ts +37 -0
- package/src/mcp-catalog-limits.ts +2 -0
- package/src/mcp-endpoint.ts +30 -0
- package/src/mcp-oauth.ts +66 -0
- package/src/modal-native-proof-v2.ts +398 -0
- package/src/model-availability.ts +22 -0
- package/src/model-connection-access.ts +17 -0
- package/src/model-context-inspector.ts +139 -0
- package/src/model-display.ts +195 -0
- package/src/model-picker-order.ts +97 -0
- package/src/organization-access.ts +176 -0
- package/src/organization-integration-policy.ts +54 -0
- package/src/organization-membership-lifecycle.ts +559 -0
- package/src/organization-model-usage.ts +72 -0
- package/src/organization-recovery.ts +186 -0
- package/src/organization-usage.ts +79 -0
- package/src/permissions.ts +58 -0
- package/src/personal-github.ts +267 -0
- package/src/plugin-discovery.ts +33 -0
- package/src/preference-registry.ts +20 -1
- package/src/product-analytics.ts +253 -0
- package/src/product-lifecycle-facts.ts +121 -0
- package/src/remember.ts +243 -0
- package/src/retained-output.ts +20 -3
- package/src/sandbox-file-artifacts.ts +73 -0
- package/src/sandbox-provider-command.ts +82 -0
- package/src/sandbox-recovery.ts +116 -0
- package/src/sandbox-snapshots.ts +142 -0
- package/src/session-final-reply.ts +16 -0
- package/src/session-goal-reports.ts +55 -0
- package/src/session-history-import.ts +159 -0
- package/src/session-list-entries.ts +91 -0
- package/src/session-mcp-projections.ts +273 -0
- package/src/session-message-search.ts +54 -0
- package/src/session-titles.ts +467 -0
- package/src/session-topology-primitives.ts +21 -0
- package/src/signup-attribution.ts +81 -0
- package/src/site-request-headers.test.ts +28 -0
- package/src/site-session-http.ts +63 -0
- package/src/skill-catalog-context.ts +50 -0
- package/src/skill-files.ts +52 -0
- package/src/skill-metadata.ts +40 -0
- package/src/skill-use.ts +77 -0
- package/src/skills.ts +136 -0
- package/src/slack-bot-scopes.ts +106 -42
- package/src/slack-rest-mcp.ts +194 -0
- package/src/slack-task-policy.ts +215 -0
- package/src/spreadsheet-artifact-commands.ts +12 -13
- package/src/subscription-account-pools.ts +44 -0
- package/src/task-notes.ts +105 -0
- package/src/tool-catalog.ts +155 -0
- package/src/tool-result-spill.ts +35 -0
- package/src/usage-allowances.ts +187 -0
- package/src/video-generation.ts +43 -6
- package/src/work-claims.ts +266 -0
- package/src/workspace-instruction-policies.ts +31 -0
- package/src/workspace-integration-wire.ts +99 -0
- package/src/workspace-integrations.ts +640 -0
- package/src/workspace-learning-administration.ts +88 -0
- package/src/workspace-learning-policy.ts +4 -3
- package/src/workspace-state.ts +16 -126
- package/src/xai-provider-account-authority.ts +38 -0
- package/dist/chunk-52SGB2QO.js.map +0 -1
- package/dist/chunk-5UDNP7AO.js.map +0 -1
- package/dist/chunk-BVGIYW7D.js +0 -11
- package/dist/chunk-BVGIYW7D.js.map +0 -1
- package/dist/chunk-FJBG5E4O.js.map +0 -1
- package/dist/chunk-H5BVCZKF.js.map +0 -1
- package/dist/chunk-LSB7GRLG.js.map +0 -1
- package/dist/chunk-TZ6YEYN4.js.map +0 -1
- package/dist/chunk-VA22KRHS.js +0 -15177
- package/dist/chunk-VA22KRHS.js.map +0 -1
- package/dist/chunk-Y3MLSLB4.js.map +0 -1
- /package/dist/{chunk-CADSX6UN.js.map → chunk-Y3KNXVTD.js.map} +0 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { TurnInitiator, TurnInitiatorContext } from "./index";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
OPENGENI_WEBHOOK_TEST_EVENT_TYPE,
|
|
6
|
+
WORKSPACE_WEBHOOK_EVENT_TYPES,
|
|
7
|
+
} from "./workspace-integration-wire";
|
|
8
|
+
import {
|
|
9
|
+
UsageAllowancePeriod,
|
|
10
|
+
UsageAllowanceStatus,
|
|
11
|
+
UsageAllowanceWindow,
|
|
12
|
+
} from "./usage-allowances";
|
|
13
|
+
|
|
14
|
+
export * from "./workspace-integration-wire";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Workspace integration primitives for embedding hosts: signed outbound
|
|
18
|
+
* webhooks and one signed HTTP credential provider per workspace. Both
|
|
19
|
+
* directions share one signature scheme so a host verifies every OpenGeni
|
|
20
|
+
* request with the same helper.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export const WorkspaceWebhookEventType = z.enum(WORKSPACE_WEBHOOK_EVENT_TYPES);
|
|
24
|
+
export type WorkspaceWebhookEventType = z.infer<typeof WorkspaceWebhookEventType>;
|
|
25
|
+
|
|
26
|
+
export const WORKSPACE_WEBHOOK_LIMIT_PER_WORKSPACE = 10;
|
|
27
|
+
export const ORGANIZATION_WEBHOOK_LIMIT_PER_ORGANIZATION = 10;
|
|
28
|
+
|
|
29
|
+
/** Scoping convenience, never authority. Null means all non-personal workspaces. */
|
|
30
|
+
export const IntegrationWorkspaceFilter = z
|
|
31
|
+
.object({
|
|
32
|
+
externalSource: z
|
|
33
|
+
.string()
|
|
34
|
+
.min(1)
|
|
35
|
+
.max(200)
|
|
36
|
+
.refine(
|
|
37
|
+
(value) =>
|
|
38
|
+
!value.includes("\0") &&
|
|
39
|
+
!/[\uD800-\uDFFF]/u.test(value) &&
|
|
40
|
+
new TextEncoder().encode(value).byteLength <= 200,
|
|
41
|
+
"External source must be valid PostgreSQL text of at most 200 UTF-8 bytes",
|
|
42
|
+
),
|
|
43
|
+
})
|
|
44
|
+
.strict();
|
|
45
|
+
export type IntegrationWorkspaceFilter = z.infer<typeof IntegrationWorkspaceFilter>;
|
|
46
|
+
|
|
47
|
+
/** Informational attribution only. It never supplies or changes authorization. */
|
|
48
|
+
export const InitiatingHuman = z.object({
|
|
49
|
+
subjectId: z.string(),
|
|
50
|
+
externalIdentity: z.object({ source: z.string(), externalId: z.string() }).nullable(),
|
|
51
|
+
});
|
|
52
|
+
export type InitiatingHuman = z.infer<typeof InitiatingHuman>;
|
|
53
|
+
|
|
54
|
+
const HttpUrl = z
|
|
55
|
+
.string()
|
|
56
|
+
.trim()
|
|
57
|
+
.min(8)
|
|
58
|
+
.max(2048)
|
|
59
|
+
.url()
|
|
60
|
+
.refine((value) => /^https?:\/\//i.test(value), "URL must use http or https");
|
|
61
|
+
|
|
62
|
+
const EventTypes = z
|
|
63
|
+
.array(WorkspaceWebhookEventType)
|
|
64
|
+
.min(1)
|
|
65
|
+
.max(WORKSPACE_WEBHOOK_EVENT_TYPES.length)
|
|
66
|
+
.transform((types) => [...new Set(types)]);
|
|
67
|
+
|
|
68
|
+
export const WorkspaceWebhook = z
|
|
69
|
+
.object({
|
|
70
|
+
id: z.string().uuid(),
|
|
71
|
+
workspaceId: z.string().uuid(),
|
|
72
|
+
url: z.string(),
|
|
73
|
+
eventTypes: z.array(WorkspaceWebhookEventType),
|
|
74
|
+
enabled: z.boolean(),
|
|
75
|
+
description: z.string().nullable(),
|
|
76
|
+
createdAt: z.string(),
|
|
77
|
+
updatedAt: z.string(),
|
|
78
|
+
})
|
|
79
|
+
.strict();
|
|
80
|
+
export type WorkspaceWebhook = z.infer<typeof WorkspaceWebhook>;
|
|
81
|
+
|
|
82
|
+
export const CreateWorkspaceWebhookRequest = z
|
|
83
|
+
.object({
|
|
84
|
+
url: HttpUrl,
|
|
85
|
+
eventTypes: EventTypes,
|
|
86
|
+
enabled: z.boolean().optional(),
|
|
87
|
+
description: z.string().trim().max(500).nullable().optional(),
|
|
88
|
+
})
|
|
89
|
+
.strict();
|
|
90
|
+
export type CreateWorkspaceWebhookRequest = z.input<typeof CreateWorkspaceWebhookRequest>;
|
|
91
|
+
|
|
92
|
+
/** The signing secret is returned exactly once, at creation. */
|
|
93
|
+
export const CreateWorkspaceWebhookResponse = z
|
|
94
|
+
.object({ webhook: WorkspaceWebhook, secret: z.string() })
|
|
95
|
+
.strict();
|
|
96
|
+
export type CreateWorkspaceWebhookResponse = z.infer<typeof CreateWorkspaceWebhookResponse>;
|
|
97
|
+
|
|
98
|
+
export const UpdateWorkspaceWebhookRequest = z
|
|
99
|
+
.object({
|
|
100
|
+
url: HttpUrl.optional(),
|
|
101
|
+
eventTypes: EventTypes.optional(),
|
|
102
|
+
enabled: z.boolean().optional(),
|
|
103
|
+
description: z.string().trim().max(500).nullable().optional(),
|
|
104
|
+
})
|
|
105
|
+
.strict();
|
|
106
|
+
export type UpdateWorkspaceWebhookRequest = z.input<typeof UpdateWorkspaceWebhookRequest>;
|
|
107
|
+
|
|
108
|
+
export const ListWorkspaceWebhooksResponse = z
|
|
109
|
+
.object({ webhooks: z.array(WorkspaceWebhook) })
|
|
110
|
+
.strict();
|
|
111
|
+
export type ListWorkspaceWebhooksResponse = z.infer<typeof ListWorkspaceWebhooksResponse>;
|
|
112
|
+
|
|
113
|
+
/** Organization webhooks fan out session events only; usage events are per-workspace. */
|
|
114
|
+
export const OrganizationWebhookEventType = WorkspaceWebhookEventType.exclude([
|
|
115
|
+
"usage.threshold_reached",
|
|
116
|
+
"usage.exhausted",
|
|
117
|
+
"usage.period_reset",
|
|
118
|
+
]);
|
|
119
|
+
export type OrganizationWebhookEventType = z.infer<typeof OrganizationWebhookEventType>;
|
|
120
|
+
const OrganizationEventTypes = z
|
|
121
|
+
.array(WorkspaceWebhookEventType)
|
|
122
|
+
.min(1)
|
|
123
|
+
.max(WorkspaceWebhookEventType.options.length)
|
|
124
|
+
.refine((types) => types.every((type) => !type.startsWith("usage.")), {
|
|
125
|
+
message:
|
|
126
|
+
"Organization webhooks accept session events only; subscribe to usage events on a workspace webhook.",
|
|
127
|
+
})
|
|
128
|
+
.transform((types) => [...new Set(types)]);
|
|
129
|
+
|
|
130
|
+
export const OrganizationWebhook = WorkspaceWebhook.omit({ workspaceId: true }).extend({
|
|
131
|
+
organizationId: z.string().uuid(),
|
|
132
|
+
eventTypes: z
|
|
133
|
+
.array(WorkspaceWebhookEventType)
|
|
134
|
+
.refine((types) => types.every((type) => !type.startsWith("usage.")), {
|
|
135
|
+
message:
|
|
136
|
+
"Organization webhooks accept session events only; subscribe to usage events on a workspace webhook.",
|
|
137
|
+
}),
|
|
138
|
+
workspaceFilter: IntegrationWorkspaceFilter.nullable(),
|
|
139
|
+
});
|
|
140
|
+
export type OrganizationWebhook = z.infer<typeof OrganizationWebhook>;
|
|
141
|
+
|
|
142
|
+
export const CreateOrganizationWebhookRequest = CreateWorkspaceWebhookRequest.extend({
|
|
143
|
+
eventTypes: OrganizationEventTypes,
|
|
144
|
+
workspaceFilter: IntegrationWorkspaceFilter.nullable(),
|
|
145
|
+
});
|
|
146
|
+
export type CreateOrganizationWebhookRequest = z.input<typeof CreateOrganizationWebhookRequest>;
|
|
147
|
+
|
|
148
|
+
export const UpdateOrganizationWebhookRequest = UpdateWorkspaceWebhookRequest.extend({
|
|
149
|
+
eventTypes: OrganizationEventTypes.optional(),
|
|
150
|
+
/** Explicit on every update: null covers all non-personal workspaces. */
|
|
151
|
+
workspaceFilter: IntegrationWorkspaceFilter.nullable(),
|
|
152
|
+
});
|
|
153
|
+
export type UpdateOrganizationWebhookRequest = z.input<typeof UpdateOrganizationWebhookRequest>;
|
|
154
|
+
|
|
155
|
+
export const CreateOrganizationWebhookResponse = z
|
|
156
|
+
.object({ webhook: OrganizationWebhook, secret: z.string() })
|
|
157
|
+
.strict();
|
|
158
|
+
export type CreateOrganizationWebhookResponse = z.infer<typeof CreateOrganizationWebhookResponse>;
|
|
159
|
+
|
|
160
|
+
export const ListOrganizationWebhooksResponse = z
|
|
161
|
+
.object({ webhooks: z.array(OrganizationWebhook) })
|
|
162
|
+
.strict();
|
|
163
|
+
export type ListOrganizationWebhooksResponse = z.infer<typeof ListOrganizationWebhooksResponse>;
|
|
164
|
+
|
|
165
|
+
export const WorkspaceWebhookDeliveryStatus = z.enum(["pending", "delivered", "failed"]);
|
|
166
|
+
export type WorkspaceWebhookDeliveryStatus = z.infer<typeof WorkspaceWebhookDeliveryStatus>;
|
|
167
|
+
|
|
168
|
+
export const WorkspaceWebhookDelivery = z
|
|
169
|
+
.object({
|
|
170
|
+
id: z.string().uuid(),
|
|
171
|
+
webhookId: z.string().uuid(),
|
|
172
|
+
eventId: z.string().uuid(),
|
|
173
|
+
eventType: z.string(),
|
|
174
|
+
status: WorkspaceWebhookDeliveryStatus,
|
|
175
|
+
attempts: z.number().int(),
|
|
176
|
+
lastStatus: z.number().int().nullable(),
|
|
177
|
+
lastError: z.string().nullable(),
|
|
178
|
+
nextAttemptAt: z.string().nullable(),
|
|
179
|
+
deliveredAt: z.string().nullable(),
|
|
180
|
+
failedAt: z.string().nullable(),
|
|
181
|
+
createdAt: z.string(),
|
|
182
|
+
})
|
|
183
|
+
.strict();
|
|
184
|
+
export type WorkspaceWebhookDelivery = z.infer<typeof WorkspaceWebhookDelivery>;
|
|
185
|
+
|
|
186
|
+
export const ListWorkspaceWebhookDeliveriesResponse = z
|
|
187
|
+
.object({ deliveries: z.array(WorkspaceWebhookDelivery) })
|
|
188
|
+
.strict();
|
|
189
|
+
export type ListWorkspaceWebhookDeliveriesResponse = z.infer<
|
|
190
|
+
typeof ListWorkspaceWebhookDeliveriesResponse
|
|
191
|
+
>;
|
|
192
|
+
|
|
193
|
+
export const OrganizationWebhookDelivery = WorkspaceWebhookDelivery;
|
|
194
|
+
export type OrganizationWebhookDelivery = z.infer<typeof OrganizationWebhookDelivery>;
|
|
195
|
+
export const ListOrganizationWebhookDeliveriesResponse = ListWorkspaceWebhookDeliveriesResponse;
|
|
196
|
+
export type ListOrganizationWebhookDeliveriesResponse = z.infer<
|
|
197
|
+
typeof ListOrganizationWebhookDeliveriesResponse
|
|
198
|
+
>;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* The thin body POSTed to a webhook endpoint. It identifies what changed;
|
|
202
|
+
* receivers read details through the authenticated API.
|
|
203
|
+
*/
|
|
204
|
+
export const SessionWorkspaceWebhookEvent = z.object({
|
|
205
|
+
lane: z.enum(["organization", "workspace"]).default("workspace"),
|
|
206
|
+
id: z.string().uuid(),
|
|
207
|
+
type: z.string(),
|
|
208
|
+
workspaceId: z.string().uuid(),
|
|
209
|
+
/** Present on new deliveries; optional for receivers of pre-upgrade deliveries. */
|
|
210
|
+
workspace: z
|
|
211
|
+
.object({
|
|
212
|
+
id: z.string().uuid(),
|
|
213
|
+
externalSource: z.string().nullable(),
|
|
214
|
+
externalId: z.string().nullable(),
|
|
215
|
+
})
|
|
216
|
+
.optional(),
|
|
217
|
+
sessionId: z.string().uuid(),
|
|
218
|
+
turnId: z.string().uuid().nullable(),
|
|
219
|
+
sequence: z.number().int(),
|
|
220
|
+
occurredAt: z.string(),
|
|
221
|
+
initiatingHuman: InitiatingHuman.nullable().optional(),
|
|
222
|
+
data: z.object({ status: z.string().optional(), reason: z.string().optional() }).passthrough(),
|
|
223
|
+
});
|
|
224
|
+
export type SessionWorkspaceWebhookEvent = z.infer<typeof SessionWorkspaceWebhookEvent>;
|
|
225
|
+
/** Workspace allowance events have no synthetic session or turn identity.
|
|
226
|
+
* Optional null context fields let transport adapters share an envelope. */
|
|
227
|
+
export const WorkspaceUsageWebhookEvent = z.object({
|
|
228
|
+
lane: z.literal("workspace").default("workspace"),
|
|
229
|
+
id: z.string().uuid(),
|
|
230
|
+
type: z.enum(["usage.threshold_reached", "usage.exhausted", "usage.period_reset"]),
|
|
231
|
+
workspaceId: z.string().uuid(),
|
|
232
|
+
workspace: z
|
|
233
|
+
.object({
|
|
234
|
+
id: z.string().uuid(),
|
|
235
|
+
externalSource: z.string().nullable(),
|
|
236
|
+
externalId: z.string().nullable(),
|
|
237
|
+
})
|
|
238
|
+
.optional(),
|
|
239
|
+
sessionId: z.null().optional(),
|
|
240
|
+
turnId: z.null().optional(),
|
|
241
|
+
sequence: z.number().int().nonnegative().optional(),
|
|
242
|
+
occurredAt: z.string(),
|
|
243
|
+
data: z
|
|
244
|
+
.object({
|
|
245
|
+
scope: z.enum(["workspace", "member"]).optional(),
|
|
246
|
+
subjectId: z.string().nullable().optional(),
|
|
247
|
+
threshold: z.number().finite().optional(),
|
|
248
|
+
fraction: z.number().finite().nullable().optional(),
|
|
249
|
+
resetsAt: z.string().nullable().optional(),
|
|
250
|
+
status: UsageAllowanceStatus.optional(),
|
|
251
|
+
period: z.union([UsageAllowanceWindow, UsageAllowancePeriod, z.literal("*")]).optional(),
|
|
252
|
+
})
|
|
253
|
+
.passthrough(),
|
|
254
|
+
});
|
|
255
|
+
export type WorkspaceUsageWebhookEvent = z.infer<typeof WorkspaceUsageWebhookEvent>;
|
|
256
|
+
/**
|
|
257
|
+
* "Send test event": proves the endpoint is reachable and verifies the
|
|
258
|
+
* signature. It names the workspace but no session, turn or sequence.
|
|
259
|
+
*/
|
|
260
|
+
export const WorkspaceTestWebhookEvent = z.object({
|
|
261
|
+
lane: z.enum(["organization", "workspace"]).default("workspace"),
|
|
262
|
+
id: z.string().uuid(),
|
|
263
|
+
type: z.literal(OPENGENI_WEBHOOK_TEST_EVENT_TYPE),
|
|
264
|
+
workspaceId: z.string().uuid(),
|
|
265
|
+
workspace: z
|
|
266
|
+
.object({
|
|
267
|
+
id: z.string().uuid(),
|
|
268
|
+
externalSource: z.string().nullable(),
|
|
269
|
+
externalId: z.string().nullable(),
|
|
270
|
+
})
|
|
271
|
+
.optional(),
|
|
272
|
+
sessionId: z.null().optional(),
|
|
273
|
+
turnId: z.null().optional(),
|
|
274
|
+
occurredAt: z.string(),
|
|
275
|
+
data: z.object({ webhookId: z.string().uuid().optional() }).passthrough(),
|
|
276
|
+
});
|
|
277
|
+
export type WorkspaceTestWebhookEvent = z.infer<typeof WorkspaceTestWebhookEvent>;
|
|
278
|
+
export const WorkspaceWebhookEvent = z.union([
|
|
279
|
+
SessionWorkspaceWebhookEvent,
|
|
280
|
+
WorkspaceUsageWebhookEvent,
|
|
281
|
+
WorkspaceTestWebhookEvent,
|
|
282
|
+
]);
|
|
283
|
+
export type WorkspaceWebhookEvent = z.infer<typeof WorkspaceWebhookEvent>;
|
|
284
|
+
|
|
285
|
+
export const WorkspaceCredentialProvider = z
|
|
286
|
+
.object({
|
|
287
|
+
workspaceId: z.string().uuid(),
|
|
288
|
+
url: z.string(),
|
|
289
|
+
enabled: z.boolean(),
|
|
290
|
+
timeoutMs: z.number().int(),
|
|
291
|
+
createdAt: z.string(),
|
|
292
|
+
updatedAt: z.string(),
|
|
293
|
+
})
|
|
294
|
+
.strict();
|
|
295
|
+
export type WorkspaceCredentialProvider = z.infer<typeof WorkspaceCredentialProvider>;
|
|
296
|
+
|
|
297
|
+
export const PutWorkspaceCredentialProviderRequest = z
|
|
298
|
+
.object({
|
|
299
|
+
url: HttpUrl,
|
|
300
|
+
enabled: z.boolean().optional(),
|
|
301
|
+
timeoutMs: z.number().int().min(1000).max(30000).optional(),
|
|
302
|
+
})
|
|
303
|
+
.strict();
|
|
304
|
+
export type PutWorkspaceCredentialProviderRequest = z.input<
|
|
305
|
+
typeof PutWorkspaceCredentialProviderRequest
|
|
306
|
+
>;
|
|
307
|
+
|
|
308
|
+
/** `secret` is present only when the provider was first created. */
|
|
309
|
+
export const PutWorkspaceCredentialProviderResponse = z
|
|
310
|
+
.object({ provider: WorkspaceCredentialProvider, secret: z.string().optional() })
|
|
311
|
+
.strict();
|
|
312
|
+
export type PutWorkspaceCredentialProviderResponse = z.infer<
|
|
313
|
+
typeof PutWorkspaceCredentialProviderResponse
|
|
314
|
+
>;
|
|
315
|
+
|
|
316
|
+
export const GetWorkspaceCredentialProviderResponse = z
|
|
317
|
+
.object({ provider: WorkspaceCredentialProvider.nullable() })
|
|
318
|
+
.strict();
|
|
319
|
+
export type GetWorkspaceCredentialProviderResponse = z.infer<
|
|
320
|
+
typeof GetWorkspaceCredentialProviderResponse
|
|
321
|
+
>;
|
|
322
|
+
|
|
323
|
+
export const OrganizationCredentialProvider = WorkspaceCredentialProvider.omit({
|
|
324
|
+
workspaceId: true,
|
|
325
|
+
}).extend({
|
|
326
|
+
organizationId: z.string().uuid(),
|
|
327
|
+
workspaceFilter: IntegrationWorkspaceFilter.nullable(),
|
|
328
|
+
});
|
|
329
|
+
export type OrganizationCredentialProvider = z.infer<typeof OrganizationCredentialProvider>;
|
|
330
|
+
|
|
331
|
+
export const PutOrganizationCredentialProviderRequest =
|
|
332
|
+
PutWorkspaceCredentialProviderRequest.extend({
|
|
333
|
+
/** Required; null explicitly covers all non-personal workspaces. PUT replaces configuration. */
|
|
334
|
+
workspaceFilter: IntegrationWorkspaceFilter.nullable(),
|
|
335
|
+
});
|
|
336
|
+
export type PutOrganizationCredentialProviderRequest = z.input<
|
|
337
|
+
typeof PutOrganizationCredentialProviderRequest
|
|
338
|
+
>;
|
|
339
|
+
|
|
340
|
+
export const PutOrganizationCredentialProviderResponse = z
|
|
341
|
+
.object({ provider: OrganizationCredentialProvider, secret: z.string().optional() })
|
|
342
|
+
.strict();
|
|
343
|
+
export type PutOrganizationCredentialProviderResponse = z.infer<
|
|
344
|
+
typeof PutOrganizationCredentialProviderResponse
|
|
345
|
+
>;
|
|
346
|
+
|
|
347
|
+
export const GetOrganizationCredentialProviderResponse = z
|
|
348
|
+
.object({ provider: OrganizationCredentialProvider.nullable() })
|
|
349
|
+
.strict();
|
|
350
|
+
export type GetOrganizationCredentialProviderResponse = z.infer<
|
|
351
|
+
typeof GetOrganizationCredentialProviderResponse
|
|
352
|
+
>;
|
|
353
|
+
|
|
354
|
+
/** Exact accepted-turn provenance, never an authorization grant. */
|
|
355
|
+
export type CredentialProviderInitiatorContext = {
|
|
356
|
+
/** Agent delegation is identified by the newest frozen `via` hop. */
|
|
357
|
+
kind: "human" | "service" | "agent";
|
|
358
|
+
/** Full frozen causal identity, including an accepted service's display label. */
|
|
359
|
+
initiator: TurnInitiator;
|
|
360
|
+
/** Unmodified accepted context, including bounded `via` and coalesced `updateIds`. */
|
|
361
|
+
context: TurnInitiatorContext;
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
/** The body OpenGeni POSTs to a workspace credential provider. */
|
|
365
|
+
export type CredentialProviderRequest = {
|
|
366
|
+
type: "credentials.request";
|
|
367
|
+
lane: "organization" | "workspace";
|
|
368
|
+
/** Selected session-attached remote targets; providers must authorize each exact URL. */
|
|
369
|
+
mcpServers: { id: string; url: string }[];
|
|
370
|
+
/**
|
|
371
|
+
* `test` comes from an administrator's "Test connection": it is not a run,
|
|
372
|
+
* so `sessionId`, `rootSessionId`, `turnId` and `attemptId` are the nil
|
|
373
|
+
* UUID. Answer it as you would a run in this workspace (OpenGeni shows only
|
|
374
|
+
* the names of what you return, never the values), or `not_applicable`.
|
|
375
|
+
*/
|
|
376
|
+
purpose: "provision" | "renewal" | "test";
|
|
377
|
+
forceRefresh: boolean;
|
|
378
|
+
accountId: string;
|
|
379
|
+
workspaceId: string;
|
|
380
|
+
sessionId: string;
|
|
381
|
+
rootSessionId: string;
|
|
382
|
+
parentSessionId: string | null;
|
|
383
|
+
turnId: string;
|
|
384
|
+
attemptId: string;
|
|
385
|
+
initiator: { kind: string; subjectId?: string };
|
|
386
|
+
/** Informational, signed with the body. Optional only for pre-upgrade senders. */
|
|
387
|
+
initiatorContext?: CredentialProviderInitiatorContext;
|
|
388
|
+
initiatingHumanSubjectId: string | null;
|
|
389
|
+
/** Informational, not authority. Optional only for pre-upgrade senders. */
|
|
390
|
+
initiatingHuman?: InitiatingHuman | null;
|
|
391
|
+
sandboxBackend: string;
|
|
392
|
+
sandboxOs: string;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
const ProviderAuthNeeded = z.object({
|
|
396
|
+
reason: z.enum(["missing_connection", "expired", "insufficient_scope", "refresh_failed"]),
|
|
397
|
+
providerDomain: z.string().optional(),
|
|
398
|
+
connectionId: z.string().optional(),
|
|
399
|
+
scopes: z.array(z.string()).optional(),
|
|
400
|
+
resource: z.string().optional(),
|
|
401
|
+
authorizationUrl: z.string().optional(),
|
|
402
|
+
message: z.string().optional(),
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* HTTPS Git credentials the host wants available to `git` in the sandbox.
|
|
407
|
+
* OpenGeni stores them in a renewable file and points a credential helper at
|
|
408
|
+
* it, so a refreshed token applies to the next git command.
|
|
409
|
+
*/
|
|
410
|
+
const ProviderGitCredential = z.object({
|
|
411
|
+
host: z
|
|
412
|
+
.string()
|
|
413
|
+
.trim()
|
|
414
|
+
.min(1)
|
|
415
|
+
.max(253)
|
|
416
|
+
.regex(/^[A-Za-z0-9.-]+(:\d{1,5})?$/, "host must be a bare hostname"),
|
|
417
|
+
username: z.string().min(1).max(256).optional(),
|
|
418
|
+
password: z.string().min(1).max(16384),
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const FORBIDDEN_MCP_HEADERS = new Set([
|
|
422
|
+
"host",
|
|
423
|
+
"connection",
|
|
424
|
+
"keep-alive",
|
|
425
|
+
"proxy-authenticate",
|
|
426
|
+
"proxy-authorization",
|
|
427
|
+
"te",
|
|
428
|
+
"trailer",
|
|
429
|
+
"transfer-encoding",
|
|
430
|
+
"upgrade",
|
|
431
|
+
"content-length",
|
|
432
|
+
"mcp-session-id",
|
|
433
|
+
"mcp-protocol-version",
|
|
434
|
+
"content-type",
|
|
435
|
+
"accept",
|
|
436
|
+
]);
|
|
437
|
+
|
|
438
|
+
/** Exact WHATWG normalization; IDs, URL credentials and fragments are never targets. */
|
|
439
|
+
export function normalizeCredentialProviderMcpUrl(value: string): string {
|
|
440
|
+
const url = new URL(value);
|
|
441
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password || url.hash) {
|
|
442
|
+
throw new Error("MCP credential URL must be an HTTP endpoint without credentials or fragment");
|
|
443
|
+
}
|
|
444
|
+
return url.href;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const ProviderMcpUrl = z
|
|
448
|
+
.string()
|
|
449
|
+
.min(8)
|
|
450
|
+
.max(2048)
|
|
451
|
+
.refine((value) => {
|
|
452
|
+
try {
|
|
453
|
+
normalizeCredentialProviderMcpUrl(value);
|
|
454
|
+
return true;
|
|
455
|
+
} catch {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
}, "MCP credential url must be an HTTP endpoint without credentials or fragment")
|
|
459
|
+
.transform(normalizeCredentialProviderMcpUrl);
|
|
460
|
+
|
|
461
|
+
/** Secret, turn-local headers for one session-attached remote MCP, by normalized URL only. */
|
|
462
|
+
export const CredentialProviderMcpHeaders = z
|
|
463
|
+
.object({
|
|
464
|
+
url: ProviderMcpUrl,
|
|
465
|
+
headers: z.record(z.string(), z.string()),
|
|
466
|
+
expiresAt: z.iso.datetime({ offset: true }).optional(),
|
|
467
|
+
})
|
|
468
|
+
.strict()
|
|
469
|
+
.superRefine((entry, context) => {
|
|
470
|
+
const headers = Object.entries(entry.headers);
|
|
471
|
+
const seen = new Set<string>();
|
|
472
|
+
let bytes = 0;
|
|
473
|
+
if (headers.length === 0 || headers.length > 32) {
|
|
474
|
+
context.addIssue({ code: "custom", message: "MCP headers must contain 1–32 entries" });
|
|
475
|
+
}
|
|
476
|
+
for (const [name, value] of headers) {
|
|
477
|
+
const lower = name.toLowerCase();
|
|
478
|
+
if (
|
|
479
|
+
name.length > 128 ||
|
|
480
|
+
name.length === 0 ||
|
|
481
|
+
/[^!#$%&'*+.^_`|~0-9A-Za-z-]/.test(name) ||
|
|
482
|
+
FORBIDDEN_MCP_HEADERS.has(lower) ||
|
|
483
|
+
seen.has(lower)
|
|
484
|
+
) {
|
|
485
|
+
context.addIssue({ code: "custom", message: "Invalid or duplicate MCP header name" });
|
|
486
|
+
}
|
|
487
|
+
seen.add(lower);
|
|
488
|
+
const valueBytes = new TextEncoder().encode(value).byteLength;
|
|
489
|
+
bytes += name.length + valueBytes;
|
|
490
|
+
if (valueBytes > 16384 || /[^\t\u0020-\u007e\u0080-\u00ff]/.test(value)) {
|
|
491
|
+
context.addIssue({ code: "custom", message: "Invalid or oversized MCP header value" });
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (bytes > 65536) {
|
|
495
|
+
context.addIssue({ code: "custom", message: "MCP header material exceeds 64 KiB" });
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
export type CredentialProviderMcpHeaders = z.infer<typeof CredentialProviderMcpHeaders>;
|
|
499
|
+
|
|
500
|
+
export const CredentialProviderMcpMaterial = z
|
|
501
|
+
.array(CredentialProviderMcpHeaders)
|
|
502
|
+
.max(32)
|
|
503
|
+
.superRefine((entries, context) => {
|
|
504
|
+
if (new Set(entries.map((entry) => entry.url)).size !== entries.length) {
|
|
505
|
+
context.addIssue({ code: "custom", message: "Duplicate MCP server target" });
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
export type CredentialProviderMcpMaterial = z.infer<typeof CredentialProviderMcpMaterial>;
|
|
509
|
+
|
|
510
|
+
/** What a credential provider returns. Scope echoes are added by OpenGeni. */
|
|
511
|
+
export const CredentialProviderResponse = z.discriminatedUnion("status", [
|
|
512
|
+
z.object({
|
|
513
|
+
status: z.literal("ok"),
|
|
514
|
+
environment: z.record(z.string(), z.string()).optional(),
|
|
515
|
+
files: z
|
|
516
|
+
.array(
|
|
517
|
+
z.object({
|
|
518
|
+
path: z.string(),
|
|
519
|
+
content: z.string(),
|
|
520
|
+
mode: z.enum(["0400", "0600"]).optional(),
|
|
521
|
+
}),
|
|
522
|
+
)
|
|
523
|
+
.optional(),
|
|
524
|
+
fileEnvironment: z.record(z.string(), z.string()).optional(),
|
|
525
|
+
git: z.array(ProviderGitCredential).max(16).optional(),
|
|
526
|
+
mcp: CredentialProviderMcpMaterial.optional(),
|
|
527
|
+
expiresAt: z.string().nullable().optional(),
|
|
528
|
+
authNeeded: z.array(ProviderAuthNeeded).optional(),
|
|
529
|
+
}),
|
|
530
|
+
z.object({ status: z.literal("not_applicable") }),
|
|
531
|
+
z.object({ status: z.literal("auth_needed"), authNeeded: z.array(ProviderAuthNeeded).min(1) }),
|
|
532
|
+
]);
|
|
533
|
+
export type CredentialProviderResponse = z.infer<typeof CredentialProviderResponse>;
|
|
534
|
+
|
|
535
|
+
/** Immediate signing-secret rotation; the new secret is returned once. */
|
|
536
|
+
export const RotateWorkspaceCredentialProviderSecretResponse = z
|
|
537
|
+
.object({ provider: WorkspaceCredentialProvider, secret: z.string() })
|
|
538
|
+
.strict();
|
|
539
|
+
export type RotateWorkspaceCredentialProviderSecretResponse = z.infer<
|
|
540
|
+
typeof RotateWorkspaceCredentialProviderSecretResponse
|
|
541
|
+
>;
|
|
542
|
+
export const RotateOrganizationCredentialProviderSecretResponse = z
|
|
543
|
+
.object({ provider: OrganizationCredentialProvider, secret: z.string() })
|
|
544
|
+
.strict();
|
|
545
|
+
export type RotateOrganizationCredentialProviderSecretResponse = z.infer<
|
|
546
|
+
typeof RotateOrganizationCredentialProviderSecretResponse
|
|
547
|
+
>;
|
|
548
|
+
export const RotateWorkspaceWebhookSecretResponse = CreateWorkspaceWebhookResponse;
|
|
549
|
+
export type RotateWorkspaceWebhookSecretResponse = z.infer<
|
|
550
|
+
typeof RotateWorkspaceWebhookSecretResponse
|
|
551
|
+
>;
|
|
552
|
+
export const RotateOrganizationWebhookSecretResponse = CreateOrganizationWebhookResponse;
|
|
553
|
+
export type RotateOrganizationWebhookSecretResponse = z.infer<
|
|
554
|
+
typeof RotateOrganizationWebhookSecretResponse
|
|
555
|
+
>;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* The outcome of one test request to a webhook or credential-provider
|
|
559
|
+
* endpoint. Nothing is stored: the request is sent once, synchronously.
|
|
560
|
+
* Credential values never appear; `credentials` names what a run would get.
|
|
561
|
+
*/
|
|
562
|
+
export const IntegrationEndpointTestResult = z
|
|
563
|
+
.object({
|
|
564
|
+
/** A 2xx answer (for a provider, also a valid response body). */
|
|
565
|
+
ok: z.boolean(),
|
|
566
|
+
/** The HTTP status, or null when the endpoint was not reached. */
|
|
567
|
+
status: z.number().int().nullable(),
|
|
568
|
+
durationMs: z.number().int().nonnegative(),
|
|
569
|
+
/** What went wrong, in one sentence, or null. */
|
|
570
|
+
error: z.string().nullable(),
|
|
571
|
+
/** The exact JSON body OpenGeni signed and sent. */
|
|
572
|
+
request: z.string(),
|
|
573
|
+
/** The start of the endpoint's answer. Omitted for a successful provider answer. */
|
|
574
|
+
responseBody: z.string().nullable(),
|
|
575
|
+
credentials: z
|
|
576
|
+
.object({
|
|
577
|
+
status: z.enum(["ok", "not_applicable", "auth_needed"]),
|
|
578
|
+
environment: z.array(z.string()),
|
|
579
|
+
files: z.array(z.string()),
|
|
580
|
+
git: z.array(z.string()),
|
|
581
|
+
mcp: z.array(z.string()),
|
|
582
|
+
expiresAt: z.string().nullable(),
|
|
583
|
+
authNeeded: z.array(
|
|
584
|
+
z.object({
|
|
585
|
+
reason: z.string(),
|
|
586
|
+
providerDomain: z.string().nullable(),
|
|
587
|
+
message: z.string().nullable(),
|
|
588
|
+
}),
|
|
589
|
+
),
|
|
590
|
+
})
|
|
591
|
+
.strict()
|
|
592
|
+
.nullable(),
|
|
593
|
+
})
|
|
594
|
+
.strict();
|
|
595
|
+
export type IntegrationEndpointTestResult = z.infer<typeof IntegrationEndpointTestResult>;
|
|
596
|
+
|
|
597
|
+
export const TestWorkspaceWebhookResponse = z
|
|
598
|
+
.object({ result: IntegrationEndpointTestResult })
|
|
599
|
+
.strict();
|
|
600
|
+
export type TestWorkspaceWebhookResponse = z.infer<typeof TestWorkspaceWebhookResponse>;
|
|
601
|
+
|
|
602
|
+
/** Tests the provider runs in this workspace would use: its own, else the organization's. */
|
|
603
|
+
export const TestWorkspaceCredentialProviderResponse = z
|
|
604
|
+
.object({
|
|
605
|
+
lane: z.enum(["workspace", "organization"]),
|
|
606
|
+
url: z.string(),
|
|
607
|
+
result: IntegrationEndpointTestResult,
|
|
608
|
+
})
|
|
609
|
+
.strict();
|
|
610
|
+
export type TestWorkspaceCredentialProviderResponse = z.infer<
|
|
611
|
+
typeof TestWorkspaceCredentialProviderResponse
|
|
612
|
+
>;
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Organization registrations that apply to one workspace, for workspace
|
|
616
|
+
* administrators: an enabled organization provider whose filter matches
|
|
617
|
+
* (even when this workspace overrides it) and the enabled organization
|
|
618
|
+
* webhooks that also receive this workspace's events. Never secrets.
|
|
619
|
+
*/
|
|
620
|
+
export const WorkspaceInheritedIntegrationsResponse = z
|
|
621
|
+
.object({
|
|
622
|
+
credentialProvider: z
|
|
623
|
+
.object({ url: z.string(), timeoutMs: z.number().int(), updatedAt: z.string() })
|
|
624
|
+
.strict()
|
|
625
|
+
.nullable(),
|
|
626
|
+
webhooks: z.array(
|
|
627
|
+
z
|
|
628
|
+
.object({
|
|
629
|
+
id: z.string().uuid(),
|
|
630
|
+
url: z.string(),
|
|
631
|
+
eventTypes: z.array(WorkspaceWebhookEventType),
|
|
632
|
+
description: z.string().nullable(),
|
|
633
|
+
})
|
|
634
|
+
.strict(),
|
|
635
|
+
),
|
|
636
|
+
})
|
|
637
|
+
.strict();
|
|
638
|
+
export type WorkspaceInheritedIntegrationsResponse = z.infer<
|
|
639
|
+
typeof WorkspaceInheritedIntegrationsResponse
|
|
640
|
+
>;
|