@kindgi/api 0.1.4 → 0.1.5
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-binding.d.ts +13 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/agent-pins.d.ts.map +1 -1
- package/dist/agent-pins.js +18 -2
- package/dist/agent-pins.js.map +1 -1
- package/dist/app.d.ts +110 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +163 -35
- package/dist/app.js.map +1 -1
- package/dist/block-publish.d.ts +56 -0
- package/dist/block-publish.d.ts.map +1 -0
- package/dist/block-publish.js +132 -0
- package/dist/block-publish.js.map +1 -0
- package/dist/caller.d.ts +24 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +47 -0
- package/dist/caller.js.map +1 -0
- package/dist/capability-binding.d.ts +11 -0
- package/dist/capability-binding.d.ts.map +1 -1
- package/dist/cost-binding.d.ts +19 -0
- package/dist/cost-binding.d.ts.map +1 -1
- package/dist/cost-binding.js.map +1 -1
- package/dist/derive-agent-version.d.ts +7 -0
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +4 -0
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +75 -7
- package/dist/errors.js.map +1 -1
- package/dist/eval-case-binding.d.ts +16 -4
- package/dist/eval-case-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.d.ts +31 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +7 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/eval-sample.d.ts +11 -0
- package/dist/eval-sample.d.ts.map +1 -0
- package/dist/eval-sample.js +34 -0
- package/dist/eval-sample.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +13 -0
- package/dist/eval-suite-binding.d.ts.map +1 -1
- package/dist/eval-suite-binding.js.map +1 -1
- package/dist/flow-binding.d.ts +18 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/flow-pins.d.ts.map +1 -1
- package/dist/flow-pins.js +18 -2
- package/dist/flow-pins.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +25 -0
- package/dist/gate.js.map +1 -1
- package/dist/handler-binding.d.ts +32 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/hitl-binding.d.ts +23 -0
- package/dist/hitl-binding.d.ts.map +1 -1
- package/dist/identity-directory-binding.d.ts +82 -4
- package/dist/identity-directory-binding.d.ts.map +1 -1
- package/dist/identity-provider-binding.d.ts +197 -17
- package/dist/identity-provider-binding.d.ts.map +1 -1
- package/dist/improvement-pass-binding.d.ts +196 -0
- package/dist/improvement-pass-binding.d.ts.map +1 -0
- package/dist/improvement-pass-binding.js +9 -0
- package/dist/improvement-pass-binding.js.map +1 -0
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +25 -4
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +43 -6
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/judgment-binding.d.ts +25 -1
- package/dist/judgment-binding.d.ts.map +1 -1
- package/dist/mcp-endpoint-binding.d.ts +7 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -1
- package/dist/memory-binding.d.ts +124 -17
- package/dist/memory-binding.d.ts.map +1 -1
- package/dist/memory-erasure-binding.d.ts +145 -0
- package/dist/memory-erasure-binding.d.ts.map +1 -0
- package/dist/memory-erasure-binding.js +4 -0
- package/dist/memory-erasure-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +66 -13
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +150 -50
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/authorize.d.ts +9 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +122 -4
- package/dist/middleware/authorize.js.map +1 -1
- package/dist/middleware/error-mapper.d.ts +5 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -1
- package/dist/middleware/error-mapper.js +14 -1
- package/dist/middleware/error-mapper.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +70 -5
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +174 -41
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/key-project.d.ts +17 -0
- package/dist/middleware/key-project.d.ts.map +1 -0
- package/dist/middleware/key-project.js +75 -0
- package/dist/middleware/key-project.js.map +1 -0
- package/dist/middleware/principal.d.ts.map +1 -1
- package/dist/middleware/principal.js +9 -5
- package/dist/middleware/principal.js.map +1 -1
- package/dist/middleware/project-ref.d.ts.map +1 -1
- package/dist/middleware/project-ref.js +3 -0
- package/dist/middleware/project-ref.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +5 -2
- package/dist/openapi/generate.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +919 -140
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +90 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2081 -359
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/person-grants-binding.d.ts +77 -0
- package/dist/person-grants-binding.d.ts.map +1 -0
- package/dist/person-grants-binding.js +4 -0
- package/dist/person-grants-binding.js.map +1 -0
- package/dist/proposal-service.d.ts +121 -0
- package/dist/proposal-service.d.ts.map +1 -0
- package/dist/proposal-service.js +447 -0
- package/dist/proposal-service.js.map +1 -0
- package/dist/proposal-status.d.ts +60 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +109 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/provider-binding.d.ts +10 -0
- package/dist/provider-binding.d.ts.map +1 -1
- package/dist/publish-refused.d.ts +28 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +24 -3
- package/dist/publish-refused.js.map +1 -1
- package/dist/routes/adapters.d.ts +2 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +3 -1
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agent-releases.d.ts +55 -3
- package/dist/routes/agent-releases.d.ts.map +1 -1
- package/dist/routes/agent-releases.js +85 -55
- package/dist/routes/agent-releases.js.map +1 -1
- package/dist/routes/agents.d.ts +12 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +100 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts +15 -3
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +133 -122
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/artifacts.d.ts +25 -3
- package/dist/routes/artifacts.d.ts.map +1 -1
- package/dist/routes/artifacts.js +116 -7
- package/dist/routes/artifacts.js.map +1 -1
- package/dist/routes/auth.d.ts +25 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +655 -281
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +2 -42
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/capabilities.d.ts +2 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +6 -1
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +9 -10
- package/dist/routes/compliance.d.ts.map +1 -1
- package/dist/routes/compliance.js +42 -61
- package/dist/routes/compliance.js.map +1 -1
- package/dist/routes/conversations.d.ts +8 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +87 -8
- package/dist/routes/conversations.js.map +1 -1
- package/dist/routes/cost.d.ts +12 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +74 -3
- package/dist/routes/cost.js.map +1 -1
- package/dist/routes/denied.d.ts +11 -0
- package/dist/routes/denied.d.ts.map +1 -0
- package/dist/routes/denied.js +17 -0
- package/dist/routes/denied.js.map +1 -0
- package/dist/routes/deployments.d.ts +10 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +171 -13
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +69 -1
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-overrides.d.ts +18 -0
- package/dist/routes/eval-overrides.d.ts.map +1 -0
- package/dist/routes/eval-overrides.js +81 -0
- package/dist/routes/eval-overrides.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +10 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +66 -7
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-suites.d.ts.map +1 -1
- package/dist/routes/eval-suites.js +28 -2
- package/dist/routes/eval-suites.js.map +1 -1
- package/dist/routes/event-triggers.d.ts +5 -1
- package/dist/routes/event-triggers.d.ts.map +1 -1
- package/dist/routes/event-triggers.js +26 -3
- package/dist/routes/event-triggers.js.map +1 -1
- package/dist/routes/export-signing-keys.d.ts +12 -0
- package/dist/routes/export-signing-keys.d.ts.map +1 -0
- package/dist/routes/export-signing-keys.js +24 -0
- package/dist/routes/export-signing-keys.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +9 -1
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/gate-policies.d.ts +4 -1
- package/dist/routes/gate-policies.d.ts.map +1 -1
- package/dist/routes/gate-policies.js +29 -5
- package/dist/routes/gate-policies.js.map +1 -1
- package/dist/routes/guardrails.d.ts +16 -14
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +39 -3
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/identity.d.ts +20 -4
- package/dist/routes/identity.d.ts.map +1 -1
- package/dist/routes/identity.js +246 -6
- package/dist/routes/identity.js.map +1 -1
- package/dist/routes/improvement-passes.d.ts +52 -0
- package/dist/routes/improvement-passes.d.ts.map +1 -0
- package/dist/routes/improvement-passes.js +449 -0
- package/dist/routes/improvement-passes.js.map +1 -0
- package/dist/routes/judged-suites.d.ts +50 -0
- package/dist/routes/judged-suites.d.ts.map +1 -1
- package/dist/routes/judged-suites.js +66 -27
- package/dist/routes/judged-suites.js.map +1 -1
- package/dist/routes/judgment-context.d.ts +18 -2
- package/dist/routes/judgment-context.d.ts.map +1 -1
- package/dist/routes/judgment-context.js +63 -5
- package/dist/routes/judgment-context.js.map +1 -1
- package/dist/routes/judgment-flow-context.d.ts.map +1 -1
- package/dist/routes/judgment-flow-context.js +14 -2
- package/dist/routes/judgment-flow-context.js.map +1 -1
- package/dist/routes/judgments.d.ts.map +1 -1
- package/dist/routes/judgments.js +8 -1
- package/dist/routes/judgments.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +26 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/memory-access.d.ts +43 -0
- package/dist/routes/memory-access.d.ts.map +1 -0
- package/dist/routes/memory-access.js +114 -0
- package/dist/routes/memory-access.js.map +1 -0
- package/dist/routes/memory-erasures.d.ts +25 -0
- package/dist/routes/memory-erasures.d.ts.map +1 -0
- package/dist/routes/memory-erasures.js +214 -0
- package/dist/routes/memory-erasures.js.map +1 -0
- package/dist/routes/memory-parse.d.ts +38 -0
- package/dist/routes/memory-parse.d.ts.map +1 -0
- package/dist/routes/memory-parse.js +199 -0
- package/dist/routes/memory-parse.js.map +1 -0
- package/dist/routes/memory.d.ts +9 -4
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +226 -234
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/observations.d.ts +4 -1
- package/dist/routes/observations.d.ts.map +1 -1
- package/dist/routes/observations.js +8 -2
- package/dist/routes/observations.js.map +1 -1
- package/dist/routes/pagination.d.ts +7 -0
- package/dist/routes/pagination.d.ts.map +1 -1
- package/dist/routes/pagination.js +10 -0
- package/dist/routes/pagination.js.map +1 -1
- package/dist/routes/policies.d.ts +2 -1
- package/dist/routes/policies.d.ts.map +1 -1
- package/dist/routes/policies.js +3 -1
- package/dist/routes/policies.js.map +1 -1
- package/dist/routes/project-mismatch.d.ts +22 -0
- package/dist/routes/project-mismatch.d.ts.map +1 -0
- package/dist/routes/project-mismatch.js +34 -0
- package/dist/routes/project-mismatch.js.map +1 -0
- package/dist/routes/projects.d.ts +15 -4
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +100 -9
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/proposals.d.ts +25 -17
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +340 -507
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/provenance.d.ts +17 -3
- package/dist/routes/provenance.d.ts.map +1 -1
- package/dist/routes/provenance.js +79 -103
- package/dist/routes/provenance.js.map +1 -1
- package/dist/routes/providers.d.ts +17 -1
- package/dist/routes/providers.d.ts.map +1 -1
- package/dist/routes/providers.js +110 -3
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/public-run-tokens.d.ts.map +1 -1
- package/dist/routes/public-run-tokens.js +3 -0
- package/dist/routes/public-run-tokens.js.map +1 -1
- package/dist/routes/readable-projects.d.ts +26 -0
- package/dist/routes/readable-projects.d.ts.map +1 -0
- package/dist/routes/readable-projects.js +39 -0
- package/dist/routes/readable-projects.js.map +1 -0
- package/dist/routes/runs.d.ts +10 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +92 -42
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/schedules.d.ts +21 -13
- package/dist/routes/schedules.d.ts.map +1 -1
- package/dist/routes/schedules.js +416 -55
- package/dist/routes/schedules.js.map +1 -1
- package/dist/routes/segments.d.ts +2 -0
- package/dist/routes/segments.d.ts.map +1 -1
- package/dist/routes/segments.js +5 -0
- package/dist/routes/segments.js.map +1 -1
- package/dist/routes/service-accounts.d.ts +17 -0
- package/dist/routes/service-accounts.d.ts.map +1 -0
- package/dist/routes/service-accounts.js +212 -0
- package/dist/routes/service-accounts.js.map +1 -0
- package/dist/routes/sign-in-options.d.ts +50 -0
- package/dist/routes/sign-in-options.d.ts.map +1 -0
- package/dist/routes/sign-in-options.js +98 -0
- package/dist/routes/sign-in-options.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +2 -1
- package/dist/routes/signing-keys.d.ts.map +1 -1
- package/dist/routes/signing-keys.js +3 -1
- package/dist/routes/signing-keys.js.map +1 -1
- package/dist/routes/tenant-access.d.ts +13 -0
- package/dist/routes/tenant-access.d.ts.map +1 -0
- package/dist/routes/tenant-access.js +26 -0
- package/dist/routes/tenant-access.js.map +1 -0
- package/dist/routes/tenant.d.ts.map +1 -1
- package/dist/routes/tenant.js +4 -0
- package/dist/routes/tenant.js.map +1 -1
- package/dist/routes/token-sign-in.d.ts +36 -0
- package/dist/routes/token-sign-in.d.ts.map +1 -0
- package/dist/routes/token-sign-in.js +101 -0
- package/dist/routes/token-sign-in.js.map +1 -0
- package/dist/routes/tokens.d.ts +15 -5
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +162 -43
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +9 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/trigger-access.d.ts +29 -0
- package/dist/routes/trigger-access.d.ts.map +1 -0
- package/dist/routes/trigger-access.js +33 -0
- package/dist/routes/trigger-access.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +2 -1
- package/dist/routes/webhook-endpoints.d.ts.map +1 -1
- package/dist/routes/webhook-endpoints.js +11 -3
- package/dist/routes/webhook-endpoints.js.map +1 -1
- package/dist/routes/webhooks.d.ts +5 -1
- package/dist/routes/webhooks.d.ts.map +1 -1
- package/dist/routes/webhooks.js +25 -2
- package/dist/routes/webhooks.js.map +1 -1
- package/dist/run-failure.d.ts +21 -0
- package/dist/run-failure.d.ts.map +1 -0
- package/dist/run-failure.js +29 -0
- package/dist/run-failure.js.map +1 -0
- package/dist/service-account-binding.d.ts +108 -0
- package/dist/service-account-binding.d.ts.map +1 -0
- package/dist/service-account-binding.js +4 -0
- package/dist/service-account-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +61 -13
- package/dist/session-store-binding.d.ts.map +1 -1
- package/dist/signed-export.d.ts +89 -0
- package/dist/signed-export.d.ts.map +1 -0
- package/dist/signed-export.js +149 -0
- package/dist/signed-export.js.map +1 -0
- package/dist/supervisor-binding.d.ts +186 -413
- package/dist/supervisor-binding.d.ts.map +1 -1
- package/dist/testing/app-bindings.d.ts +33 -0
- package/dist/testing/app-bindings.d.ts.map +1 -0
- package/dist/testing/app-bindings.js +112 -0
- package/dist/testing/app-bindings.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub-binding.d.ts +34 -0
- package/dist/testing/stub-binding.d.ts.map +1 -0
- package/dist/testing/stub-binding.js +42 -0
- package/dist/testing/stub-binding.js.map +1 -0
- package/dist/testing/trigger-registry.d.ts +21 -0
- package/dist/testing/trigger-registry.d.ts.map +1 -0
- package/dist/testing/trigger-registry.js +206 -0
- package/dist/testing/trigger-registry.js.map +1 -0
- package/dist/token-admin.d.ts +46 -8
- package/dist/token-admin.d.ts.map +1 -1
- package/dist/token-admin.js.map +1 -1
- package/dist/tool-binding.d.ts +13 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/dist/trigger-binding.d.ts +2 -2
- package/dist/trigger-binding.d.ts.map +1 -1
- package/dist/trigger-binding.js +1 -1
- package/dist/trigger-binding.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.d.ts +19 -3
- package/dist/webhook-endpoint-binding.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.js +1 -1
- package/dist/webhook-endpoint-binding.js.map +1 -1
- package/openapi.json +15387 -8789
- package/package.json +26 -22
- package/src/agent-binding.ts +14 -0
- package/src/agent-pins.ts +18 -2
- package/src/app.ts +366 -80
- package/src/block-publish.ts +181 -0
- package/src/caller.ts +62 -0
- package/src/capability-binding.ts +12 -0
- package/src/cost-binding.ts +19 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +75 -7
- package/src/eval-case-binding.ts +17 -1
- package/src/eval-run-binding.ts +31 -0
- package/src/eval-run-dispatcher.ts +7 -0
- package/src/eval-sample.ts +42 -0
- package/src/eval-suite-binding.ts +14 -0
- package/src/flow-binding.ts +19 -0
- package/src/flow-pins.ts +18 -2
- package/src/gate.ts +26 -0
- package/src/handler-binding.ts +36 -1
- package/src/hitl-binding.ts +24 -0
- package/src/identity-directory-binding.ts +85 -4
- package/src/identity-provider-binding.ts +216 -21
- package/src/improvement-pass-binding.ts +193 -0
- package/src/index.ts +153 -31
- package/src/judged-dispatcher.ts +78 -11
- package/src/judgment-binding.ts +25 -1
- package/src/mcp-endpoint-binding.ts +7 -0
- package/src/memory-binding.ts +121 -17
- package/src/memory-erasure-binding.ts +156 -0
- package/src/middleware/auth.ts +228 -62
- package/src/middleware/authorize.ts +155 -3
- package/src/middleware/error-mapper.ts +15 -1
- package/src/middleware/idempotency.ts +230 -43
- package/src/middleware/key-project.ts +86 -0
- package/src/middleware/principal.ts +9 -5
- package/src/middleware/project-ref.ts +3 -0
- package/src/openapi/generate.ts +11 -2
- package/src/openapi/operations.ts +1060 -143
- package/src/openapi/schemas.ts +2387 -469
- package/src/person-grants-binding.ts +76 -0
- package/src/proposal-service.ts +640 -0
- package/src/proposal-status.ts +176 -0
- package/src/provider-binding.ts +10 -0
- package/src/publish-refused.ts +56 -9
- package/src/routes/adapters.ts +4 -0
- package/src/routes/agent-releases.ts +121 -69
- package/src/routes/agents.ts +128 -1
- package/src/routes/approvals.ts +164 -154
- package/src/routes/artifacts.ts +181 -11
- package/src/routes/auth.ts +804 -336
- package/src/routes/blocks.ts +2 -53
- package/src/routes/capabilities.ts +10 -1
- package/src/routes/compliance.ts +60 -99
- package/src/routes/conversations.ts +101 -7
- package/src/routes/cost.ts +110 -4
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +210 -17
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +89 -6
- package/src/routes/eval-suites.ts +32 -2
- package/src/routes/event-triggers.ts +27 -3
- package/src/routes/export-signing-keys.ts +31 -0
- package/src/routes/flows.ts +12 -1
- package/src/routes/gate-policies.ts +37 -6
- package/src/routes/guardrails.ts +61 -2
- package/src/routes/identity.ts +328 -10
- package/src/routes/improvement-passes.ts +541 -0
- package/src/routes/judged-suites.ts +113 -43
- package/src/routes/judgment-context.ts +76 -5
- package/src/routes/judgment-flow-context.ts +16 -2
- package/src/routes/judgments.ts +17 -3
- package/src/routes/mcp.ts +29 -1
- package/src/routes/memory-access.ts +160 -0
- package/src/routes/memory-erasures.ts +240 -0
- package/src/routes/memory-parse.ts +250 -0
- package/src/routes/memory.ts +244 -286
- package/src/routes/observations.ts +15 -2
- package/src/routes/pagination.ts +12 -0
- package/src/routes/policies.ts +7 -1
- package/src/routes/project-mismatch.ts +56 -0
- package/src/routes/projects.ts +107 -13
- package/src/routes/proposals.ts +370 -611
- package/src/routes/provenance.ts +99 -133
- package/src/routes/providers.ts +142 -3
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/readable-projects.ts +66 -0
- package/src/routes/runs.ts +119 -39
- package/src/routes/schedules.ts +472 -60
- package/src/routes/segments.ts +11 -0
- package/src/routes/service-accounts.ts +262 -0
- package/src/routes/sign-in-options.ts +168 -0
- package/src/routes/signing-keys.ts +7 -1
- package/src/routes/tenant-access.ts +37 -0
- package/src/routes/tenant.ts +6 -0
- package/src/routes/token-sign-in.ts +161 -0
- package/src/routes/tokens.ts +172 -46
- package/src/routes/tools.ts +12 -1
- package/src/routes/trigger-access.ts +72 -0
- package/src/routes/webhook-endpoints.ts +15 -3
- package/src/routes/webhooks.ts +26 -2
- package/src/run-failure.ts +42 -0
- package/src/service-account-binding.ts +113 -0
- package/src/session-store-binding.ts +65 -13
- package/src/signed-export.ts +250 -0
- package/src/supervisor-binding.ts +169 -409
- package/src/testing/app-bindings.ts +142 -0
- package/src/testing/index.ts +21 -0
- package/src/testing/stub-binding.ts +53 -0
- package/src/testing/trigger-registry.ts +259 -0
- package/src/token-admin.ts +40 -8
- package/src/tool-binding.ts +14 -0
- package/src/trigger-binding.ts +8 -1
- package/src/types.ts +16 -0
- package/src/webhook-endpoint-binding.ts +18 -3
package/src/flow-binding.ts
CHANGED
|
@@ -72,6 +72,8 @@ export interface FlowRegistryBinding {
|
|
|
72
72
|
* well-formed `Flow`. Bindings MAY reject with `already-registered`
|
|
73
73
|
* when the same `(flowId, version)` is re-published; the route maps
|
|
74
74
|
* that to `409`.
|
|
75
|
+
* A version of a flow whose versions live in another project is
|
|
76
|
+
* `project-mismatch` (flows never move between projects; `409 flow-project-mismatch`).
|
|
75
77
|
*/
|
|
76
78
|
publish(input: FlowPublishInput): Promise<FlowPublishOutcome>;
|
|
77
79
|
/**
|
|
@@ -93,6 +95,11 @@ export interface FlowRegistryBinding {
|
|
|
93
95
|
export type FlowVersionRecord = Flow & {
|
|
94
96
|
/** ISO-8601; present only on an unregistered version. */
|
|
95
97
|
readonly unregisteredAt?: string;
|
|
98
|
+
/**
|
|
99
|
+
* The project the version belongs to, when the store records it: a
|
|
100
|
+
* deploy into another project is refused even when it writes nothing.
|
|
101
|
+
*/
|
|
102
|
+
readonly projectId?: ProjectId;
|
|
96
103
|
};
|
|
97
104
|
|
|
98
105
|
export interface FlowListInput {
|
|
@@ -209,6 +216,18 @@ export type FlowPublishOutcome =
|
|
|
209
216
|
readonly flowId: FlowId;
|
|
210
217
|
readonly version: string;
|
|
211
218
|
readonly projectId: ProjectId;
|
|
219
|
+
}
|
|
220
|
+
| {
|
|
221
|
+
/**
|
|
222
|
+
* The flow's versions live in another project: a flow belongs to
|
|
223
|
+
* the project its first version was published into, and never
|
|
224
|
+
* moves. Nothing is written (the route answers `409 flow-project-mismatch`).
|
|
225
|
+
*/
|
|
226
|
+
readonly kind: 'project-mismatch';
|
|
227
|
+
readonly flowId: FlowId;
|
|
228
|
+
readonly version: string;
|
|
229
|
+
/** The project the flow belongs to. */
|
|
230
|
+
readonly projectId: ProjectId;
|
|
212
231
|
};
|
|
213
232
|
|
|
214
233
|
export type FlowUnregisterOutcome = {
|
package/src/flow-pins.ts
CHANGED
|
@@ -113,17 +113,33 @@ export async function publishDeployedFlow(
|
|
|
113
113
|
input: PublishDeployedFlowInput,
|
|
114
114
|
): Promise<DeployedVersionOutcome> {
|
|
115
115
|
const { flows, tenantId, projectId, flow, pins, enqueueTuples } = input;
|
|
116
|
+
const existing = await allFlowVersions(flows, tenantId, flow.id);
|
|
117
|
+
// A flow never moves, even by a deploy that writes nothing (an unchanged
|
|
118
|
+
// or reused version): one of another project is refused. A registry
|
|
119
|
+
// that doesn't record the project refuses only a write.
|
|
120
|
+
const held = existing[0];
|
|
121
|
+
if (held !== undefined) {
|
|
122
|
+
const record = await flows.getVersion({ tenantId, flowId: flow.id, version: held.version });
|
|
123
|
+
if (record?.projectId !== undefined && record.projectId !== projectId) {
|
|
124
|
+
throw new PublishRefused('flow', `${flow.id}@${flow.version}`, {
|
|
125
|
+
kind: 'project-mismatch',
|
|
126
|
+
flowId: flow.id,
|
|
127
|
+
version: flow.version,
|
|
128
|
+
projectId: record.projectId,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
116
132
|
return deployVersion<Flow>({
|
|
117
133
|
label: `flow "${flow.id as unknown as string}"`,
|
|
118
134
|
definition: flow,
|
|
119
135
|
pins,
|
|
120
136
|
pinsDigest: flowPinsDigest(pins),
|
|
121
|
-
existing
|
|
137
|
+
existing,
|
|
122
138
|
publish: async (version) => {
|
|
123
139
|
const outcome = await flows.publish({ tenantId, projectId, flow: version, enqueueTuples });
|
|
124
140
|
if (outcome.kind === 'ok') return 'ok';
|
|
125
141
|
if (outcome.kind === 'already-registered') return 'taken';
|
|
126
|
-
throw new PublishRefused('flow', `${flow.id}@${version.version}`, outcome
|
|
142
|
+
throw new PublishRefused('flow', `${flow.id}@${version.version}`, outcome);
|
|
127
143
|
},
|
|
128
144
|
});
|
|
129
145
|
}
|
package/src/gate.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { ReviewerRole } from '@kindgi/authz';
|
|
5
5
|
import type { LiveScope } from '@kindgi/types';
|
|
6
6
|
|
|
7
|
+
import type { EvalSample } from './eval-run-binding.js';
|
|
7
8
|
import type { GateMetricName, GateMetricSpec, GatePolicySpec } from './gate-policy-binding.js';
|
|
8
9
|
import type { ComparisonMetric, JudgedComparisonSummary } from './judged-dispatcher.js';
|
|
9
10
|
|
|
@@ -114,6 +115,7 @@ export function evaluateGate(input: GateInput): GateResult {
|
|
|
114
115
|
checks.push(freshnessCheck(spec.comparison.maxAgeHours, summary, input.now));
|
|
115
116
|
}
|
|
116
117
|
if (spec.comparison?.suite !== undefined) checks.push(suiteCheck(spec.comparison.suite, summary));
|
|
118
|
+
if (summary.sample !== undefined) checks.push(sampleCheck(summary.sample));
|
|
117
119
|
checks.push(sameContentsCheck(input));
|
|
118
120
|
checks.push(baselineCheck(summary, input));
|
|
119
121
|
checks.push(scopeCheck(summary, input));
|
|
@@ -204,6 +206,23 @@ function suiteCheck(
|
|
|
204
206
|
};
|
|
205
207
|
}
|
|
206
208
|
|
|
209
|
+
/**
|
|
210
|
+
* A comparison on part of the test set: the hold-out part proves a
|
|
211
|
+
* candidate; the search part chose it, so its numbers flatter it.
|
|
212
|
+
*/
|
|
213
|
+
function sampleCheck(sample: EvalSample): GateCheck {
|
|
214
|
+
const passed = sample.part === 'hold-out';
|
|
215
|
+
return {
|
|
216
|
+
name: 'comparison.sample',
|
|
217
|
+
passed,
|
|
218
|
+
message: passed
|
|
219
|
+
? `The comparison ran the hold-out part of the test set (seed ${sample.seed}).`
|
|
220
|
+
: 'The comparison ran the search part of the test set, which chose this candidate: compare on the hold-out part, or the whole test set.',
|
|
221
|
+
value: sample.part,
|
|
222
|
+
threshold: 'hold-out',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
207
226
|
function sameContentsCheck(input: GateInput): GateCheck {
|
|
208
227
|
const { promotion, summary } = input;
|
|
209
228
|
const candidate = summary?.candidate;
|
|
@@ -217,6 +236,13 @@ function sameContentsCheck(input: GateInput): GateCheck {
|
|
|
217
236
|
};
|
|
218
237
|
}
|
|
219
238
|
const compared = `${candidate.agentId} ${candidate.version}`;
|
|
239
|
+
if (candidate.overrides !== undefined) {
|
|
240
|
+
return {
|
|
241
|
+
name,
|
|
242
|
+
passed: false,
|
|
243
|
+
message: `The comparison ran ${compared} with other content for ${[...(candidate.overrides.settings ?? []), ...(candidate.overrides.prompts ?? [])].join(', ')} than it pins (an improvement pass's search): compare the published version.`,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
220
246
|
if (candidate.agentId !== promotion.agentId || candidate.version !== promotion.version) {
|
|
221
247
|
return {
|
|
222
248
|
name,
|
package/src/handler-binding.ts
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import type { AgentId } from '@kindgi/agents';
|
|
5
|
+
import type { Principal } from '@kindgi/authz';
|
|
5
6
|
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
7
|
+
import type { RunIdempotencyKey, RunTriggerRef } from '@kindgi/runtime';
|
|
6
8
|
import type { FlowId, ProjectId, RunId, ScopeSegment, Semver, TenantId } from '@kindgi/types';
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -67,6 +69,12 @@ export interface RunTrace {
|
|
|
67
69
|
export interface ResumeRunBindingInput {
|
|
68
70
|
readonly tenantId: TenantId;
|
|
69
71
|
readonly runId: RunId;
|
|
72
|
+
/**
|
|
73
|
+
* The trace context of the request resuming the run (a reviewer's
|
|
74
|
+
* decision): the resumed work runs under it, and the run keeps its own
|
|
75
|
+
* trace id from the request that started it. Absent: as before.
|
|
76
|
+
*/
|
|
77
|
+
readonly trace?: RunTrace;
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
export interface InvokeAgentBindingInput {
|
|
@@ -107,6 +115,19 @@ export interface InvokeAgentBindingInput {
|
|
|
107
115
|
* can't run in the background may treat `false` like `true`.
|
|
108
116
|
*/
|
|
109
117
|
readonly wait?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Start the run at most once per key (`RunIdempotencyKey`): a key a run
|
|
120
|
+
* already has starts nothing and answers that run, with `existing`.
|
|
121
|
+
*/
|
|
122
|
+
readonly idempotencyKey?: RunIdempotencyKey;
|
|
123
|
+
/** Set when a trigger starts the run; the run records it (`RunTriggerRef`). */
|
|
124
|
+
readonly trigger?: RunTriggerRef;
|
|
125
|
+
/**
|
|
126
|
+
* Who started the run (the authenticated caller), when known: whom the
|
|
127
|
+
* turn acts for, e.g. whose own memory its retrievals may read. Set by
|
|
128
|
+
* the route, never from the body. On its own it enforces nothing.
|
|
129
|
+
*/
|
|
130
|
+
readonly principal?: Principal;
|
|
110
131
|
/** The trace context of the request starting the run: the binding records its `traceId` on the run. */
|
|
111
132
|
readonly trace?: RunTrace;
|
|
112
133
|
}
|
|
@@ -128,14 +149,28 @@ export interface InvokeFlowBindingInput {
|
|
|
128
149
|
* can't run in the background may treat `false` like `true`.
|
|
129
150
|
*/
|
|
130
151
|
readonly wait?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Start the run at most once per key (`RunIdempotencyKey`): a key a run
|
|
154
|
+
* already has starts nothing and answers that run, with `existing`.
|
|
155
|
+
*/
|
|
156
|
+
readonly idempotencyKey?: RunIdempotencyKey;
|
|
157
|
+
/** Set when a trigger starts the run; the run records it (`RunTriggerRef`). */
|
|
158
|
+
readonly trigger?: RunTriggerRef;
|
|
131
159
|
/** Agents and tools to run at other exact versions than the flow version's pins (`RunFlowInput.versions`). */
|
|
132
160
|
readonly versions?: FlowVersionOverrides;
|
|
161
|
+
/** Who started the run, as for `InvokeAgentBindingInput.principal`: its agent steps act for them. */
|
|
162
|
+
readonly principal?: Principal;
|
|
133
163
|
/** The trace context of the request starting the run, as for an agent run. */
|
|
134
164
|
readonly trace?: RunTrace;
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
export type RunHandlerOutcome =
|
|
138
|
-
| {
|
|
168
|
+
| {
|
|
169
|
+
readonly kind: 'ok';
|
|
170
|
+
readonly runId: RunId;
|
|
171
|
+
/** The `idempotencyKey` named a run that already existed: nothing new started. */
|
|
172
|
+
readonly existing?: true;
|
|
173
|
+
}
|
|
139
174
|
| { readonly kind: 'err'; readonly error: RunHandlerFailure };
|
|
140
175
|
|
|
141
176
|
/**
|
package/src/hitl-binding.ts
CHANGED
|
@@ -88,17 +88,41 @@ export interface ListApprovalsBindingInput {
|
|
|
88
88
|
readonly status?: ApprovalStatus;
|
|
89
89
|
readonly requiredRole?: ReviewerRole;
|
|
90
90
|
readonly since?: Timestamp;
|
|
91
|
+
/** A bare time: approvals created before it. Milliseconds, no tie-breaker; `after` replaces it. */
|
|
91
92
|
readonly cursor?: Cursor;
|
|
92
93
|
/**
|
|
93
94
|
* Only approvals whose `waitTokenId` is one of these: the approvals a
|
|
94
95
|
* run's open waits belong to (T272). Absent: no filter.
|
|
95
96
|
*/
|
|
96
97
|
readonly waitTokenIds?: readonly string[];
|
|
98
|
+
/**
|
|
99
|
+
* Only approvals after this one in the list's order (`createdAt` desc,
|
|
100
|
+
* then `id` desc): where a page that ended on it continues. Its
|
|
101
|
+
* `createdAt` is the binding's `exactCreatedAt` for it.
|
|
102
|
+
*/
|
|
103
|
+
readonly after?: ApprovalPosition;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Where a page of approvals ends: an approval's `createdAt` as stored
|
|
108
|
+
* (Postgres keeps microseconds), and its id. A JS `Date` keeps
|
|
109
|
+
* milliseconds: a position built from one skips the approvals created
|
|
110
|
+
* earlier in the same millisecond.
|
|
111
|
+
*/
|
|
112
|
+
export interface ApprovalPosition {
|
|
113
|
+
readonly createdAt: string;
|
|
114
|
+
readonly id: ApprovalId;
|
|
97
115
|
}
|
|
98
116
|
|
|
99
117
|
export interface ListApprovalsBindingResult {
|
|
100
118
|
readonly approvals: readonly Approval[];
|
|
101
119
|
readonly nextCursor?: Cursor;
|
|
120
|
+
/**
|
|
121
|
+
* Each listed approval's `createdAt` as stored (microseconds), by id:
|
|
122
|
+
* with the id, the `after` that continues past it. Absent from a binding
|
|
123
|
+
* that doesn't give it; a caller then continues by `cursor`.
|
|
124
|
+
*/
|
|
125
|
+
readonly exactCreatedAt?: Readonly<Record<string, string>>;
|
|
102
126
|
}
|
|
103
127
|
|
|
104
128
|
export interface SubmitReviewBindingInput {
|
|
@@ -13,16 +13,16 @@ import type { Cursor, TenantId, Timestamp, UserId } from '@kindgi/types';
|
|
|
13
13
|
* tenant" / "show me a user's profile" / "revoke all a user's active
|
|
14
14
|
* sessions" question this binding covers.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* bespoke store behind this binding.
|
|
16
|
+
* The framework does NOT own user persistence. Deployments plug in an
|
|
17
|
+
* LDAP / SCIM / IdP-mirror / bespoke store behind this binding.
|
|
19
18
|
*
|
|
20
19
|
* Same caller-plugged pattern as every other admin-plane binding
|
|
21
20
|
* (`PolicyRegistryBinding`, `ProviderRegistryBinding`, ...).
|
|
22
21
|
*
|
|
23
22
|
* The directory is flat. Groups / roles / RBAC / invitations /
|
|
24
23
|
* audit history / LDAP+SCIM sync / impersonation are not part of this
|
|
25
|
-
* binding.
|
|
24
|
+
* binding. Adding a person (`createUser`) is optional: a directory that
|
|
25
|
+
* mirrors an identity provider leaves it out.
|
|
26
26
|
*/
|
|
27
27
|
export interface IdentityDirectoryBinding {
|
|
28
28
|
/**
|
|
@@ -30,6 +30,14 @@ export interface IdentityDirectoryBinding {
|
|
|
30
30
|
* the route surfaces `null` as `404 identity-user-not-found`.
|
|
31
31
|
*/
|
|
32
32
|
getUser(input: IdentityGetUserInput): Promise<UserRecord | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Optional. The person still in the tenant whose `primaryEmail` is
|
|
35
|
+
* `email`, compared as the directory compares emails when it adds a
|
|
36
|
+
* person (case-insensitively, for the runtime's); `null` when none.
|
|
37
|
+
* When present, `POST /v1/projects/{projectId}/memberships` takes an
|
|
38
|
+
* `email` as well as a `userId`.
|
|
39
|
+
*/
|
|
40
|
+
findUserByEmail?(input: IdentityFindUserByEmailInput): Promise<UserRecord | null>;
|
|
33
41
|
/**
|
|
34
42
|
* Cursor-paginated list of users in the tenant. Optional `query`
|
|
35
43
|
* is a prefix match on `displayName` — the natural filter shape
|
|
@@ -55,19 +63,88 @@ export interface IdentityDirectoryBinding {
|
|
|
55
63
|
* delegate to `SessionStoreBinding.revokeAllForUser`.
|
|
56
64
|
*/
|
|
57
65
|
revokeAllSessions(input: IdentityRevokeSessionsInput): Promise<RevokeSessionsResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Optional. Add a person to the tenant as a tenant member, written to
|
|
68
|
+
* the authorization store before it returns: they can read the
|
|
69
|
+
* tenant's settings, not its projects. A tenant admin then gives them a
|
|
70
|
+
* role and mints their first API key. When present,
|
|
71
|
+
* `POST /v1/identity/users` mounts (tenant admins only). An email
|
|
72
|
+
* another person of the tenant has is refused.
|
|
73
|
+
*/
|
|
74
|
+
createUser?(input: IdentityCreateUserInput): Promise<IdentityCreateUserResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Optional. Unregister a person (remove them from the tenant), in one
|
|
77
|
+
* step: they're marked unregistered (their record stays, with
|
|
78
|
+
* `unregisteredAt`, so their history still says who they were), every
|
|
79
|
+
* API key and session of theirs is revoked, and every grant and
|
|
80
|
+
* membership they hold is taken from the authorization store, all before
|
|
81
|
+
* it returns. Their email is then free: adding it again makes a new
|
|
82
|
+
* person. Unregistering someone already unregistered changes nothing.
|
|
83
|
+
* Refused for yourself, the deployment's seed user, and the tenant's
|
|
84
|
+
* only tenant admin. When present,
|
|
85
|
+
* `POST /v1/identity/users/{userId}/unregister` mounts (tenant admins
|
|
86
|
+
* only).
|
|
87
|
+
*/
|
|
88
|
+
unregisterUser?(input: IdentityUnregisterUserInput): Promise<IdentityUnregisterUserResult>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface IdentityUnregisterUserInput {
|
|
92
|
+
readonly tenantId: TenantId;
|
|
93
|
+
readonly userId: UserId;
|
|
94
|
+
/** Who unregisters them: `user:<id>` or `service_account:<id>`. */
|
|
95
|
+
readonly unregisteredBy?: string;
|
|
58
96
|
}
|
|
59
97
|
|
|
98
|
+
/** Why a person can't be unregistered. */
|
|
99
|
+
export type IdentityUnregisterUserRefusal = 'yourself' | 'seed-user' | 'last-tenant-admin';
|
|
100
|
+
|
|
101
|
+
export type IdentityUnregisterUserResult =
|
|
102
|
+
| {
|
|
103
|
+
readonly kind: 'unregistered';
|
|
104
|
+
/** The person, with `unregisteredAt`. */
|
|
105
|
+
readonly user: UserRecord;
|
|
106
|
+
/** What unregistering took away (each 0 when they were already unregistered). */
|
|
107
|
+
readonly keysRevoked: number;
|
|
108
|
+
readonly sessionsRevoked: number;
|
|
109
|
+
readonly grantsRemoved: number;
|
|
110
|
+
}
|
|
111
|
+
| { readonly kind: 'not-found' }
|
|
112
|
+
| {
|
|
113
|
+
readonly kind: 'refused';
|
|
114
|
+
readonly reason: IdentityUnregisterUserRefusal;
|
|
115
|
+
readonly message: string;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export interface IdentityCreateUserInput {
|
|
119
|
+
readonly tenantId: TenantId;
|
|
120
|
+
readonly displayName: string;
|
|
121
|
+
readonly primaryEmail?: string;
|
|
122
|
+
/** Who added them: `user:<id>` or `service_account:<id>`. */
|
|
123
|
+
readonly createdBy?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type IdentityCreateUserResult =
|
|
127
|
+
| { readonly kind: 'created'; readonly user: UserRecord }
|
|
128
|
+
| { readonly kind: 'email-taken'; readonly userId: UserId };
|
|
129
|
+
|
|
60
130
|
export interface IdentityGetUserInput {
|
|
61
131
|
readonly tenantId: TenantId;
|
|
62
132
|
readonly userId: UserId;
|
|
63
133
|
}
|
|
64
134
|
|
|
135
|
+
export interface IdentityFindUserByEmailInput {
|
|
136
|
+
readonly tenantId: TenantId;
|
|
137
|
+
readonly email: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
65
140
|
export interface IdentityListUsersInput {
|
|
66
141
|
readonly tenantId: TenantId;
|
|
67
142
|
readonly limit: number;
|
|
68
143
|
readonly cursor?: Cursor;
|
|
69
144
|
/** Prefix match on `UserRecord.displayName`. Undefined = no filter. */
|
|
70
145
|
readonly query?: string;
|
|
146
|
+
/** Unregistered people too (`unregisteredAt` set). Default: only the people still here. */
|
|
147
|
+
readonly includeUnregistered?: boolean;
|
|
71
148
|
}
|
|
72
149
|
|
|
73
150
|
export interface IdentityListSessionsInput {
|
|
@@ -78,6 +155,8 @@ export interface IdentityListSessionsInput {
|
|
|
78
155
|
export interface IdentityRevokeSessionsInput {
|
|
79
156
|
readonly tenantId: TenantId;
|
|
80
157
|
readonly userId: UserId;
|
|
158
|
+
/** Who asked (`user:<id>`, `service_account:<id>`), for the audit trail. */
|
|
159
|
+
readonly revokedBy?: string;
|
|
81
160
|
}
|
|
82
161
|
|
|
83
162
|
/**
|
|
@@ -94,6 +173,8 @@ export interface UserRecord {
|
|
|
94
173
|
readonly displayName?: string;
|
|
95
174
|
readonly createdAt: Timestamp;
|
|
96
175
|
readonly lastActiveAt?: Timestamp;
|
|
176
|
+
/** When they were removed from the tenant (`unregisterUser`); absent while they're here. */
|
|
177
|
+
readonly unregisteredAt?: Timestamp;
|
|
97
178
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
98
179
|
}
|
|
99
180
|
|
|
@@ -4,35 +4,216 @@
|
|
|
4
4
|
import type { TenantId } from '@kindgi/types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Caller-plugged catalog of
|
|
8
|
-
*
|
|
9
|
-
* `ProviderRegistryBinding` (model providers)
|
|
10
|
-
* NOT own provider persistence, and secrets never
|
|
7
|
+
* Caller-plugged catalog of the identity providers a tenant signs in
|
|
8
|
+
* with: OIDC and SAML identity providers (sign-in), and plain OAuth 2.0
|
|
9
|
+
* providers. Same pattern as `ProviderRegistryBinding` (model providers):
|
|
10
|
+
* the API package does NOT own provider persistence, and secrets never
|
|
11
|
+
* cross the wire.
|
|
11
12
|
*
|
|
12
|
-
* A
|
|
13
|
-
*
|
|
14
|
-
* secrets-manager path, KMS handle,
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* never surfaces on any HTTP response.
|
|
13
|
+
* A provider carries only REFERENCES to its secrets (`clientSecretRef`,
|
|
14
|
+
* `spSigningKeyRef`, `spDecryptionKeyRef`): opaque pointers the deployment
|
|
15
|
+
* resolves server-side (env-var lookup, secrets-manager path, KMS handle,
|
|
16
|
+
* etc.). The secrets themselves are used inside the deployment's boundary
|
|
17
|
+
* and never surface on any HTTP response.
|
|
18
18
|
*
|
|
19
|
-
* PKCE is mandatory (S256)
|
|
20
|
-
* rejected at boot; the framework does NOT emit `code_challenge_method`
|
|
21
|
-
* negotiation.
|
|
19
|
+
* PKCE is mandatory (S256) for the OAuth flows.
|
|
22
20
|
*/
|
|
23
21
|
export interface IdentityProviderBinding {
|
|
24
22
|
list(input: IdentityProviderListInput): Promise<IdentityProviderPage>;
|
|
25
23
|
get(input: IdentityProviderGetInput): Promise<ProviderConfig | null>;
|
|
26
24
|
register(input: IdentityProviderRegisterInput): Promise<IdentityProviderRegisterOutcome>;
|
|
27
25
|
unregister(input: IdentityProviderUnregisterInput): Promise<IdentityProviderUnregisterOutcome>;
|
|
26
|
+
/**
|
|
27
|
+
* The ways a person can sign in, before anyone is signed in
|
|
28
|
+
* (`GET /v1/auth/sign-in-options`, unauthenticated). Answer by the email
|
|
29
|
+
* DOMAIN only, never by whether a person exists:
|
|
30
|
+
* - with `emailDomain`: the providers whose `domains` include it, from
|
|
31
|
+
* the one tenant the domain is verified for (the deployment decides
|
|
32
|
+
* how: e.g. the only tenant it serves, or one its operator named);
|
|
33
|
+
* none when the domain isn't verified for any tenant;
|
|
34
|
+
* - without: the route doesn't ask. Sign-in is email first, so nothing
|
|
35
|
+
* is offered before an email.
|
|
36
|
+
* Absent → the route answers an empty list.
|
|
37
|
+
*/
|
|
38
|
+
readonly signInOptions?: (input: SignInOptionsInput) => Promise<readonly SignInOption[]>;
|
|
39
|
+
/**
|
|
40
|
+
* What to give the identity provider so it can send people back
|
|
41
|
+
* (`signIn`), for a provider registered now or later under this
|
|
42
|
+
* `providerId`: the same before registration, after it, and after an
|
|
43
|
+
* unregister and a new registration, so an admin can set up the
|
|
44
|
+
* identity provider's side first. `undefined` when this deployment
|
|
45
|
+
* doesn't sign in with that `kind`.
|
|
46
|
+
* Absent → `GET /v1/auth/providers/:providerId/sign-in` isn't mounted.
|
|
47
|
+
*/
|
|
48
|
+
readonly signInUrls?: (
|
|
49
|
+
input: IdentityProviderSignInUrlsInput,
|
|
50
|
+
) => Promise<ProviderSignIn | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Replace a registered provider's configuration, keeping its `signIn`
|
|
53
|
+
* (the identity provider's side doesn't change). Validated as a new
|
|
54
|
+
* registration is.
|
|
55
|
+
* Absent → `PATCH /v1/auth/providers/:providerId` isn't mounted.
|
|
56
|
+
*/
|
|
57
|
+
readonly update?: (input: IdentityProviderUpdateInput) => Promise<IdentityProviderUpdateOutcome>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface IdentityProviderSignInUrlsInput {
|
|
61
|
+
readonly tenantId: TenantId;
|
|
62
|
+
readonly providerId: string;
|
|
63
|
+
readonly kind: IdentityProviderKind;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface IdentityProviderUpdateInput {
|
|
67
|
+
readonly tenantId: TenantId;
|
|
68
|
+
/** The whole new configuration (the route merges the changes in). */
|
|
69
|
+
readonly config: ProviderConfig;
|
|
28
70
|
}
|
|
29
71
|
|
|
30
|
-
export type
|
|
72
|
+
export type IdentityProviderUpdateOutcome =
|
|
73
|
+
| { readonly kind: 'ok'; readonly provider: ProviderConfig }
|
|
74
|
+
| {
|
|
75
|
+
/** As on registration: 422 `identity-provider-invalid`, with `message`. */
|
|
76
|
+
readonly kind: 'invalid';
|
|
77
|
+
readonly message: string;
|
|
78
|
+
}
|
|
79
|
+
| { readonly kind: 'not-found' };
|
|
31
80
|
|
|
32
|
-
export interface
|
|
33
|
-
/**
|
|
81
|
+
export interface SignInOptionsInput {
|
|
82
|
+
/** Lowercase, from the email the person typed. */
|
|
83
|
+
readonly emailDomain?: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** One way to sign in, as a sign-in page shows it. */
|
|
87
|
+
export interface SignInOption {
|
|
88
|
+
readonly providerId: string;
|
|
89
|
+
/** "Sign in with …". */
|
|
90
|
+
readonly displayName: string;
|
|
91
|
+
/** Where the browser goes to start signing in with this provider. */
|
|
92
|
+
readonly signInUrl: string;
|
|
93
|
+
/**
|
|
94
|
+
* Whose it is: a workspace's own identity provider (`tenant`), or one
|
|
95
|
+
* the deployment offers everyone it has added ("Continue with Google",
|
|
96
|
+
* `deployment`). A sign-in page shows a workspace's own first. Absent:
|
|
97
|
+
* `tenant`.
|
|
98
|
+
*/
|
|
99
|
+
readonly owner?: 'tenant' | 'deployment';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* - `oidc`: an OpenID Connect identity provider people sign in with
|
|
104
|
+
* (Okta, Entra ID, Google, Keycloak…): an `issuer`, the endpoints come
|
|
105
|
+
* from its discovery document.
|
|
106
|
+
* - `saml`: a SAML 2.0 identity provider people sign in with.
|
|
107
|
+
* - `oauth2`: a plain OAuth 2.0 provider that isn't OpenID Connect (e.g.
|
|
108
|
+
* GitHub), with its endpoints given. Pick `oidc` for any provider that
|
|
109
|
+
* speaks OpenID Connect.
|
|
110
|
+
*/
|
|
111
|
+
export type IdentityProviderKind = 'oauth2' | 'oidc' | 'saml';
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* An identity provider's configuration: one shape per `kind`. Narrow on
|
|
115
|
+
* `kind` before reading kind-specific fields (`clientId`,
|
|
116
|
+
* `tokenEndpoint`, `idpMetadataXml`…).
|
|
117
|
+
*/
|
|
118
|
+
export type ProviderConfig = OAuth2ProviderConfig | OidcProviderConfig | SamlProviderConfig;
|
|
119
|
+
|
|
120
|
+
/** What every kind of identity provider has. */
|
|
121
|
+
export interface ProviderConfigBase {
|
|
122
|
+
/** Stable string chosen by the tenant (e.g. `acme-sso`, `globex-oidc`). */
|
|
34
123
|
readonly providerId: string;
|
|
35
124
|
readonly kind: IdentityProviderKind;
|
|
125
|
+
/** The name a sign-in page shows ("Sign in with …"). Default: `providerId`. */
|
|
126
|
+
readonly displayName?: string;
|
|
127
|
+
/**
|
|
128
|
+
* The email domains whose people sign in with this provider (lowercase,
|
|
129
|
+
* e.g. `acme.com`): how an email-first sign-in page finds it.
|
|
130
|
+
*/
|
|
131
|
+
readonly domains?: readonly string[];
|
|
132
|
+
/**
|
|
133
|
+
* Who may sign in the first time: `invite` (default) only people a
|
|
134
|
+
* tenant admin added; `domain` also anyone from one of `domains`, once
|
|
135
|
+
* the deployment has verified them.
|
|
136
|
+
*/
|
|
137
|
+
readonly join?: 'invite' | 'domain';
|
|
138
|
+
/**
|
|
139
|
+
* What to give the identity provider so it can send people back: set
|
|
140
|
+
* by the deployment on what it returns; ignored on registration.
|
|
141
|
+
*/
|
|
142
|
+
readonly signIn?: ProviderSignIn;
|
|
143
|
+
readonly metadata?: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Where the identity provider sends people back to. */
|
|
147
|
+
export type ProviderSignIn =
|
|
148
|
+
| {
|
|
149
|
+
/** OIDC / OAuth 2.0: the redirect URI to allow on the provider's client. */
|
|
150
|
+
readonly redirectUri: string;
|
|
151
|
+
}
|
|
152
|
+
| {
|
|
153
|
+
/** SAML: the service provider's entity ID, as the IdP knows it. */
|
|
154
|
+
readonly spEntityId: string;
|
|
155
|
+
/** SAML: the assertion consumer service URL (HTTP-POST binding). */
|
|
156
|
+
readonly acsUrl: string;
|
|
157
|
+
/** SAML: the service provider's metadata, for IdPs that import it. */
|
|
158
|
+
readonly spMetadataUrl: string;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** An OpenID Connect identity provider (sign-in). */
|
|
162
|
+
export interface OidcProviderConfig extends ProviderConfigBase {
|
|
163
|
+
readonly kind: 'oidc';
|
|
164
|
+
/** The issuer; its `/.well-known/openid-configuration` gives the endpoints. */
|
|
165
|
+
readonly issuer: string;
|
|
166
|
+
readonly clientId: string;
|
|
167
|
+
/** Opaque pointer resolved server-side. Never a plaintext secret. */
|
|
168
|
+
readonly clientSecretRef: string;
|
|
169
|
+
/** Default `openid email profile`. */
|
|
170
|
+
readonly scopes?: readonly string[];
|
|
171
|
+
/** From discovery when absent; returned once the deployment has them. */
|
|
172
|
+
readonly authorizationEndpoint?: string;
|
|
173
|
+
readonly tokenEndpoint?: string;
|
|
174
|
+
readonly userinfoEndpoint?: string;
|
|
175
|
+
readonly jwksEndpoint?: string;
|
|
176
|
+
readonly allowedRedirectUris?: readonly string[];
|
|
177
|
+
readonly claimMapping?: ClaimMappingSpec;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** A SAML 2.0 identity provider (sign-in). */
|
|
181
|
+
export interface SamlProviderConfig extends ProviderConfigBase {
|
|
182
|
+
readonly kind: 'saml';
|
|
183
|
+
/** The IdP's metadata XML. Or give `idpEntityId` + `idpSsoUrl` + `idpCertificates`. */
|
|
184
|
+
readonly idpMetadataXml?: string;
|
|
185
|
+
readonly idpEntityId?: string;
|
|
186
|
+
/** The IdP's single sign-on URL (HTTP-Redirect binding). */
|
|
187
|
+
readonly idpSsoUrl?: string;
|
|
188
|
+
/** The IdP's signing certificates (PEM); several during a rollover. */
|
|
189
|
+
readonly idpCertificates?: readonly string[];
|
|
190
|
+
/**
|
|
191
|
+
* Opaque pointer to the service provider's signing key (PEM), for IdPs
|
|
192
|
+
* that require signed AuthnRequests. Never a plaintext key.
|
|
193
|
+
*/
|
|
194
|
+
readonly spSigningKeyRef?: string;
|
|
195
|
+
/** Opaque pointer to the key that decrypts encrypted assertions. Never a plaintext key. */
|
|
196
|
+
readonly spDecryptionKeyRef?: string;
|
|
197
|
+
/** Require signed assertions. Default `true`. */
|
|
198
|
+
readonly wantAssertionsSigned?: boolean;
|
|
199
|
+
/** Assertion attribute names. Defaults: `userId` = the NameID, `email` = `email`. */
|
|
200
|
+
readonly attributeMapping?: SamlAttributeMapping;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface SamlAttributeMapping {
|
|
204
|
+
readonly userId?: string;
|
|
205
|
+
readonly email?: string;
|
|
206
|
+
readonly displayName?: string;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* A plain OAuth 2.0 provider that isn't OpenID Connect (e.g. GitHub), run
|
|
211
|
+
* by this package's own OAuth flow (`/v1/auth/login` + callback, with the
|
|
212
|
+
* deployment's `exchangeCode`). For a provider that speaks OpenID Connect,
|
|
213
|
+
* use `oidc`.
|
|
214
|
+
*/
|
|
215
|
+
export interface OAuth2ProviderConfig extends ProviderConfigBase {
|
|
216
|
+
readonly kind: 'oauth2';
|
|
36
217
|
readonly clientId: string;
|
|
37
218
|
/**
|
|
38
219
|
* Opaque pointer resolved server-side. Never a plaintext secret. The
|
|
@@ -69,7 +250,6 @@ export interface ProviderConfig {
|
|
|
69
250
|
* own `ExchangeCodeFn` MAY honor this field the same way.
|
|
70
251
|
*/
|
|
71
252
|
readonly claimMapping?: ClaimMappingSpec;
|
|
72
|
-
readonly metadata?: Record<string, unknown>;
|
|
73
253
|
}
|
|
74
254
|
|
|
75
255
|
/**
|
|
@@ -140,10 +320,25 @@ export interface IdentityProviderRegisterInput {
|
|
|
140
320
|
readonly config: ProviderConfig;
|
|
141
321
|
}
|
|
142
322
|
|
|
143
|
-
export type IdentityProviderRegisterOutcome =
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
323
|
+
export type IdentityProviderRegisterOutcome =
|
|
324
|
+
| {
|
|
325
|
+
readonly kind: 'ok';
|
|
326
|
+
readonly providerId: string;
|
|
327
|
+
/**
|
|
328
|
+
* The provider as stored: discovered endpoints, `signIn`. Absent from
|
|
329
|
+
* older bindings; the route then answers with `providerId` alone.
|
|
330
|
+
*/
|
|
331
|
+
readonly provider?: ProviderConfig;
|
|
332
|
+
}
|
|
333
|
+
| {
|
|
334
|
+
/**
|
|
335
|
+
* The deployment couldn't use the configuration: the issuer's
|
|
336
|
+
* discovery failed, the SAML metadata didn't parse, a host it may
|
|
337
|
+
* not reach. 422 `identity-provider-invalid`, with `message`.
|
|
338
|
+
*/
|
|
339
|
+
readonly kind: 'invalid';
|
|
340
|
+
readonly message: string;
|
|
341
|
+
};
|
|
147
342
|
|
|
148
343
|
export interface IdentityProviderUnregisterInput {
|
|
149
344
|
readonly tenantId: TenantId;
|