@antasphere/chassis-server 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/LICENSE +82 -0
- package/dist/accounts/deletion.d.ts +163 -0
- package/dist/accounts/deletion.d.ts.map +1 -0
- package/dist/accounts/deletion.js +360 -0
- package/dist/accounts/deletion.js.map +1 -0
- package/dist/accounts/erasure-log.d.ts +66 -0
- package/dist/accounts/erasure-log.d.ts.map +1 -0
- package/dist/accounts/erasure-log.js +117 -0
- package/dist/accounts/erasure-log.js.map +1 -0
- package/dist/accounts/index.d.ts +6 -0
- package/dist/accounts/index.d.ts.map +1 -0
- package/dist/accounts/index.js +6 -0
- package/dist/accounts/index.js.map +1 -0
- package/dist/accounts/mint-refusal.d.ts +47 -0
- package/dist/accounts/mint-refusal.d.ts.map +1 -0
- package/dist/accounts/mint-refusal.js +59 -0
- package/dist/accounts/mint-refusal.js.map +1 -0
- package/dist/accounts/signup-duplicate.d.ts +14 -0
- package/dist/accounts/signup-duplicate.d.ts.map +1 -0
- package/dist/accounts/signup-duplicate.js +25 -0
- package/dist/accounts/signup-duplicate.js.map +1 -0
- package/dist/accounts/superadmin.d.ts +27 -0
- package/dist/accounts/superadmin.d.ts.map +1 -0
- package/dist/accounts/superadmin.js +46 -0
- package/dist/accounts/superadmin.js.map +1 -0
- package/dist/api/apikeys.d.ts +14 -0
- package/dist/api/apikeys.d.ts.map +1 -0
- package/dist/api/apikeys.js +124 -0
- package/dist/api/apikeys.js.map +1 -0
- package/dist/api/audit.d.ts +4 -0
- package/dist/api/audit.d.ts.map +1 -0
- package/dist/api/audit.js +75 -0
- package/dist/api/audit.js.map +1 -0
- package/dist/api/break-glass.d.ts +48 -0
- package/dist/api/break-glass.d.ts.map +1 -0
- package/dist/api/break-glass.js +217 -0
- package/dist/api/break-glass.js.map +1 -0
- package/dist/api/cli-auth.d.ts +84 -0
- package/dist/api/cli-auth.d.ts.map +1 -0
- package/dist/api/cli-auth.js +177 -0
- package/dist/api/cli-auth.js.map +1 -0
- package/dist/api/create-api.d.ts +123 -0
- package/dist/api/create-api.d.ts.map +1 -0
- package/dist/api/create-api.js +1165 -0
- package/dist/api/create-api.js.map +1 -0
- package/dist/api/demo-passes.d.ts +45 -0
- package/dist/api/demo-passes.d.ts.map +1 -0
- package/dist/api/demo-passes.js +143 -0
- package/dist/api/demo-passes.js.map +1 -0
- package/dist/api/errors.d.ts +5 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +5 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/export.d.ts +63 -0
- package/dist/api/export.d.ts.map +1 -0
- package/dist/api/export.js +393 -0
- package/dist/api/export.js.map +1 -0
- package/dist/api/files.d.ts +40 -0
- package/dist/api/files.d.ts.map +1 -0
- package/dist/api/files.js +150 -0
- package/dist/api/files.js.map +1 -0
- package/dist/api/index.d.ts +17 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +17 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/invitations.d.ts +50 -0
- package/dist/api/invitations.d.ts.map +1 -0
- package/dist/api/invitations.js +313 -0
- package/dist/api/invitations.js.map +1 -0
- package/dist/api/members.d.ts +25 -0
- package/dist/api/members.d.ts.map +1 -0
- package/dist/api/members.js +522 -0
- package/dist/api/members.js.map +1 -0
- package/dist/api/onboarding.d.ts +26 -0
- package/dist/api/onboarding.d.ts.map +1 -0
- package/dist/api/onboarding.js +23 -0
- package/dist/api/onboarding.js.map +1 -0
- package/dist/api/openapi-doc.d.ts +21 -0
- package/dist/api/openapi-doc.d.ts.map +1 -0
- package/dist/api/openapi-doc.js +25 -0
- package/dist/api/openapi-doc.js.map +1 -0
- package/dist/api/projects.d.ts +24 -0
- package/dist/api/projects.d.ts.map +1 -0
- package/dist/api/projects.js +624 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/api/scope-routes.d.ts +12 -0
- package/dist/api/scope-routes.d.ts.map +1 -0
- package/dist/api/scope-routes.js +2 -0
- package/dist/api/scope-routes.js.map +1 -0
- package/dist/api/sso-connect.d.ts +70 -0
- package/dist/api/sso-connect.d.ts.map +1 -0
- package/dist/api/sso-connect.js +164 -0
- package/dist/api/sso-connect.js.map +1 -0
- package/dist/api/sso-logout.d.ts +41 -0
- package/dist/api/sso-logout.d.ts.map +1 -0
- package/dist/api/sso-logout.js +34 -0
- package/dist/api/sso-logout.js.map +1 -0
- package/dist/api/teams.d.ts +43 -0
- package/dist/api/teams.d.ts.map +1 -0
- package/dist/api/teams.js +447 -0
- package/dist/api/teams.js.map +1 -0
- package/dist/api/workspaces.d.ts +114 -0
- package/dist/api/workspaces.d.ts.map +1 -0
- package/dist/api/workspaces.js +462 -0
- package/dist/api/workspaces.js.map +1 -0
- package/dist/apikeys/index.d.ts +3 -0
- package/dist/apikeys/index.d.ts.map +1 -0
- package/dist/apikeys/index.js +3 -0
- package/dist/apikeys/index.js.map +1 -0
- package/dist/apikeys/peppers.d.ts +53 -0
- package/dist/apikeys/peppers.d.ts.map +1 -0
- package/dist/apikeys/peppers.js +97 -0
- package/dist/apikeys/peppers.js.map +1 -0
- package/dist/apikeys/service.d.ts +56 -0
- package/dist/apikeys/service.d.ts.map +1 -0
- package/dist/apikeys/service.js +196 -0
- package/dist/apikeys/service.js.map +1 -0
- package/dist/app.d.ts +65 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +142 -0
- package/dist/app.js.map +1 -0
- package/dist/audit/filters.d.ts +38 -0
- package/dist/audit/filters.d.ts.map +1 -0
- package/dist/audit/filters.js +97 -0
- package/dist/audit/filters.js.map +1 -0
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +3 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/service.d.ts +65 -0
- package/dist/audit/service.d.ts.map +1 -0
- package/dist/audit/service.js +103 -0
- package/dist/audit/service.js.map +1 -0
- package/dist/boot.d.ts +8 -0
- package/dist/boot.d.ts.map +1 -0
- package/dist/boot.js +822 -0
- package/dist/boot.js.map +1 -0
- package/dist/constant-time.d.ts +3 -0
- package/dist/constant-time.d.ts.map +1 -0
- package/dist/constant-time.js +10 -0
- package/dist/constant-time.js.map +1 -0
- package/dist/email/driver.d.ts +16 -0
- package/dist/email/driver.d.ts.map +1 -0
- package/dist/email/driver.js +136 -0
- package/dist/email/driver.js.map +1 -0
- package/dist/email/index.d.ts +4 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +4 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/shell.d.ts +72 -0
- package/dist/email/shell.d.ts.map +1 -0
- package/dist/email/shell.js +146 -0
- package/dist/email/shell.js.map +1 -0
- package/dist/email/templates.d.ts +83 -0
- package/dist/email/templates.d.ts.map +1 -0
- package/dist/email/templates.js +96 -0
- package/dist/email/templates.js.map +1 -0
- package/dist/entitlements/check.d.ts +140 -0
- package/dist/entitlements/check.d.ts.map +1 -0
- package/dist/entitlements/check.js +276 -0
- package/dist/entitlements/check.js.map +1 -0
- package/dist/entitlements/clock-skew.d.ts +27 -0
- package/dist/entitlements/clock-skew.d.ts.map +1 -0
- package/dist/entitlements/clock-skew.js +58 -0
- package/dist/entitlements/clock-skew.js.map +1 -0
- package/dist/entitlements/gate.d.ts +113 -0
- package/dist/entitlements/gate.d.ts.map +1 -0
- package/dist/entitlements/gate.js +430 -0
- package/dist/entitlements/gate.js.map +1 -0
- package/dist/entitlements/hub-machine-token.d.ts +83 -0
- package/dist/entitlements/hub-machine-token.d.ts.map +1 -0
- package/dist/entitlements/hub-machine-token.js +175 -0
- package/dist/entitlements/hub-machine-token.js.map +1 -0
- package/dist/entitlements/hub-subject.d.ts +32 -0
- package/dist/entitlements/hub-subject.d.ts.map +1 -0
- package/dist/entitlements/hub-subject.js +68 -0
- package/dist/entitlements/hub-subject.js.map +1 -0
- package/dist/entitlements/index.d.ts +9 -0
- package/dist/entitlements/index.d.ts.map +1 -0
- package/dist/entitlements/index.js +9 -0
- package/dist/entitlements/index.js.map +1 -0
- package/dist/entitlements/poster.d.ts +81 -0
- package/dist/entitlements/poster.d.ts.map +1 -0
- package/dist/entitlements/poster.js +169 -0
- package/dist/entitlements/poster.js.map +1 -0
- package/dist/entitlements/profiles.d.ts +121 -0
- package/dist/entitlements/profiles.d.ts.map +1 -0
- package/dist/entitlements/profiles.js +212 -0
- package/dist/entitlements/profiles.js.map +1 -0
- package/dist/entitlements/slot.d.ts +33 -0
- package/dist/entitlements/slot.d.ts.map +1 -0
- package/dist/entitlements/slot.js +75 -0
- package/dist/entitlements/slot.js.map +1 -0
- package/dist/env.d.ts +293 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +383 -0
- package/dist/env.js.map +1 -0
- package/dist/files/http.d.ts +23 -0
- package/dist/files/http.d.ts.map +1 -0
- package/dist/files/http.js +66 -0
- package/dist/files/http.js.map +1 -0
- package/dist/files/index.d.ts +5 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +5 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/serve.d.ts +43 -0
- package/dist/files/serve.d.ts.map +1 -0
- package/dist/files/serve.js +71 -0
- package/dist/files/serve.js.map +1 -0
- package/dist/files/service.d.ts +69 -0
- package/dist/files/service.d.ts.map +1 -0
- package/dist/files/service.js +188 -0
- package/dist/files/service.js.map +1 -0
- package/dist/files/spool.d.ts +21 -0
- package/dist/files/spool.d.ts.map +1 -0
- package/dist/files/spool.js +47 -0
- package/dist/files/spool.js.map +1 -0
- package/dist/identity/better-auth.d.ts +3927 -0
- package/dist/identity/better-auth.d.ts.map +1 -0
- package/dist/identity/better-auth.js +896 -0
- package/dist/identity/better-auth.js.map +1 -0
- package/dist/identity/demo-pass-plugin.d.ts +29 -0
- package/dist/identity/demo-pass-plugin.d.ts.map +1 -0
- package/dist/identity/demo-pass-plugin.js +88 -0
- package/dist/identity/demo-pass-plugin.js.map +1 -0
- package/dist/identity/demo-pass-rules.d.ts +84 -0
- package/dist/identity/demo-pass-rules.d.ts.map +1 -0
- package/dist/identity/demo-pass-rules.js +223 -0
- package/dist/identity/demo-pass-rules.js.map +1 -0
- package/dist/identity/demo-pass.d.ts +159 -0
- package/dist/identity/demo-pass.d.ts.map +1 -0
- package/dist/identity/demo-pass.js +319 -0
- package/dist/identity/demo-pass.js.map +1 -0
- package/dist/identity/hub-grant.d.ts +182 -0
- package/dist/identity/hub-grant.d.ts.map +1 -0
- package/dist/identity/hub-grant.js +594 -0
- package/dist/identity/hub-grant.js.map +1 -0
- package/dist/identity/hub-jwt.d.ts +22 -0
- package/dist/identity/hub-jwt.d.ts.map +1 -0
- package/dist/identity/hub-jwt.js +77 -0
- package/dist/identity/hub-jwt.js.map +1 -0
- package/dist/identity/hub-live-gate.d.ts +17 -0
- package/dist/identity/hub-live-gate.d.ts.map +1 -0
- package/dist/identity/hub-live-gate.js +146 -0
- package/dist/identity/hub-live-gate.js.map +1 -0
- package/dist/identity/hub-logout.d.ts +88 -0
- package/dist/identity/hub-logout.d.ts.map +1 -0
- package/dist/identity/hub-logout.js +158 -0
- package/dist/identity/hub-logout.js.map +1 -0
- package/dist/identity/hub-projection.d.ts +103 -0
- package/dist/identity/hub-projection.d.ts.map +1 -0
- package/dist/identity/hub-projection.js +130 -0
- package/dist/identity/hub-projection.js.map +1 -0
- package/dist/identity/hub-reconcile.d.ts +151 -0
- package/dist/identity/hub-reconcile.d.ts.map +1 -0
- package/dist/identity/hub-reconcile.js +400 -0
- package/dist/identity/hub-reconcile.js.map +1 -0
- package/dist/identity/hub-sso.d.ts +363 -0
- package/dist/identity/hub-sso.d.ts.map +1 -0
- package/dist/identity/hub-sso.js +536 -0
- package/dist/identity/hub-sso.js.map +1 -0
- package/dist/identity/hub-user-client.d.ts +222 -0
- package/dist/identity/hub-user-client.d.ts.map +1 -0
- package/dist/identity/hub-user-client.js +406 -0
- package/dist/identity/hub-user-client.js.map +1 -0
- package/dist/identity/index.d.ts +13 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +13 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/oauth-jwt.d.ts +32 -0
- package/dist/identity/oauth-jwt.d.ts.map +1 -0
- package/dist/identity/oauth-jwt.js +122 -0
- package/dist/identity/oauth-jwt.js.map +1 -0
- package/dist/identity/resolve-membership.d.ts +28 -0
- package/dist/identity/resolve-membership.d.ts.map +1 -0
- package/dist/identity/resolve-membership.js +69 -0
- package/dist/identity/resolve-membership.js.map +1 -0
- package/dist/identity/signing-key.d.ts +49 -0
- package/dist/identity/signing-key.d.ts.map +1 -0
- package/dist/identity/signing-key.js +144 -0
- package/dist/identity/signing-key.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/invitations/index.d.ts +2 -0
- package/dist/invitations/index.d.ts.map +1 -0
- package/dist/invitations/index.js +2 -0
- package/dist/invitations/index.js.map +1 -0
- package/dist/invitations/service.d.ts +36 -0
- package/dist/invitations/service.d.ts.map +1 -0
- package/dist/invitations/service.js +122 -0
- package/dist/invitations/service.js.map +1 -0
- package/dist/jobs/index.d.ts +3 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +3 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/pgboss.d.ts +119 -0
- package/dist/jobs/pgboss.d.ts.map +1 -0
- package/dist/jobs/pgboss.js +521 -0
- package/dist/jobs/pgboss.js.map +1 -0
- package/dist/jobs/timers.d.ts +127 -0
- package/dist/jobs/timers.d.ts.map +1 -0
- package/dist/jobs/timers.js +228 -0
- package/dist/jobs/timers.js.map +1 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +64 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/errors.d.ts +37 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +77 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/http.d.ts +35 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +80 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/inputs.d.ts +19 -0
- package/dist/mcp/inputs.d.ts.map +1 -0
- package/dist/mcp/inputs.js +28 -0
- package/dist/mcp/inputs.js.map +1 -0
- package/dist/mcp/projects.d.ts +31 -0
- package/dist/mcp/projects.d.ts.map +1 -0
- package/dist/mcp/projects.js +315 -0
- package/dist/mcp/projects.js.map +1 -0
- package/dist/mcp/server.d.ts +52 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +93 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/teams.d.ts +7 -0
- package/dist/mcp/teams.d.ts.map +1 -0
- package/dist/mcp/teams.js +62 -0
- package/dist/mcp/teams.js.map +1 -0
- package/dist/mcp/tool-kit.d.ts +67 -0
- package/dist/mcp/tool-kit.d.ts.map +1 -0
- package/dist/mcp/tool-kit.js +74 -0
- package/dist/mcp/tool-kit.js.map +1 -0
- package/dist/members/removal.d.ts +95 -0
- package/dist/members/removal.d.ts.map +1 -0
- package/dist/members/removal.js +143 -0
- package/dist/members/removal.js.map +1 -0
- package/dist/middleware/auth-body.d.ts +25 -0
- package/dist/middleware/auth-body.d.ts.map +1 -0
- package/dist/middleware/auth-body.js +55 -0
- package/dist/middleware/auth-body.js.map +1 -0
- package/dist/middleware/auth-context.d.ts +170 -0
- package/dist/middleware/auth-context.d.ts.map +1 -0
- package/dist/middleware/auth-context.js +251 -0
- package/dist/middleware/auth-context.js.map +1 -0
- package/dist/middleware/body-cap.d.ts +17 -0
- package/dist/middleware/body-cap.d.ts.map +1 -0
- package/dist/middleware/body-cap.js +31 -0
- package/dist/middleware/body-cap.js.map +1 -0
- package/dist/middleware/body-refusal.d.ts +20 -0
- package/dist/middleware/body-refusal.d.ts.map +1 -0
- package/dist/middleware/body-refusal.js +5 -0
- package/dist/middleware/body-refusal.js.map +1 -0
- package/dist/middleware/cross-site.d.ts +61 -0
- package/dist/middleware/cross-site.d.ts.map +1 -0
- package/dist/middleware/cross-site.js +59 -0
- package/dist/middleware/cross-site.js.map +1 -0
- package/dist/middleware/hub-managed.d.ts +45 -0
- package/dist/middleware/hub-managed.d.ts.map +1 -0
- package/dist/middleware/hub-managed.js +56 -0
- package/dist/middleware/hub-managed.js.map +1 -0
- package/dist/middleware/idempotency.d.ts +14 -0
- package/dist/middleware/idempotency.d.ts.map +1 -0
- package/dist/middleware/idempotency.js +222 -0
- package/dist/middleware/idempotency.js.map +1 -0
- package/dist/middleware/index.d.ts +12 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +12 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/json-depth.d.ts +32 -0
- package/dist/middleware/json-depth.d.ts.map +1 -0
- package/dist/middleware/json-depth.js +80 -0
- package/dist/middleware/json-depth.js.map +1 -0
- package/dist/middleware/no-store.d.ts +21 -0
- package/dist/middleware/no-store.d.ts.map +1 -0
- package/dist/middleware/no-store.js +32 -0
- package/dist/middleware/no-store.js.map +1 -0
- package/dist/middleware/oauth-public.d.ts +16 -0
- package/dist/middleware/oauth-public.d.ts.map +1 -0
- package/dist/middleware/oauth-public.js +50 -0
- package/dist/middleware/oauth-public.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +182 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +277 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +10 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +42 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/middleware/scopes.d.ts +33 -0
- package/dist/middleware/scopes.d.ts.map +1 -0
- package/dist/middleware/scopes.js +139 -0
- package/dist/middleware/scopes.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +53 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +96 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/observability/index.d.ts +3 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +3 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/metrics.d.ts +17 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +82 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/otel.d.ts +20 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +54 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/pagination.d.ts +57 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +90 -0
- package/dist/pagination.js.map +1 -0
- package/dist/platform/edition.d.ts +57 -0
- package/dist/platform/edition.d.ts.map +1 -0
- package/dist/platform/edition.js +90 -0
- package/dist/platform/edition.js.map +1 -0
- package/dist/platform/entitlements.d.ts +26 -0
- package/dist/platform/entitlements.d.ts.map +1 -0
- package/dist/platform/entitlements.js +28 -0
- package/dist/platform/entitlements.js.map +1 -0
- package/dist/platform/events.d.ts +87 -0
- package/dist/platform/events.d.ts.map +1 -0
- package/dist/platform/events.js +32 -0
- package/dist/platform/events.js.map +1 -0
- package/dist/platform/index.d.ts +8 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +8 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/local-identity.d.ts +39 -0
- package/dist/platform/local-identity.d.ts.map +1 -0
- package/dist/platform/local-identity.js +87 -0
- package/dist/platform/local-identity.js.map +1 -0
- package/dist/platform/registry.d.ts +23 -0
- package/dist/platform/registry.d.ts.map +1 -0
- package/dist/platform/registry.js +5 -0
- package/dist/platform/registry.js.map +1 -0
- package/dist/platform/usage.d.ts +11 -0
- package/dist/platform/usage.d.ts.map +1 -0
- package/dist/platform/usage.js +12 -0
- package/dist/platform/usage.js.map +1 -0
- package/dist/platform/workspaces.d.ts +25 -0
- package/dist/platform/workspaces.d.ts.map +1 -0
- package/dist/platform/workspaces.js +44 -0
- package/dist/platform/workspaces.js.map +1 -0
- package/dist/projects/access.d.ts +40 -0
- package/dist/projects/access.d.ts.map +1 -0
- package/dist/projects/access.js +133 -0
- package/dist/projects/access.js.map +1 -0
- package/dist/projects/index.d.ts +2 -0
- package/dist/projects/index.d.ts.map +1 -0
- package/dist/projects/index.js +2 -0
- package/dist/projects/index.js.map +1 -0
- package/dist/route-label.d.ts +23 -0
- package/dist/route-label.d.ts.map +1 -0
- package/dist/route-label.js +29 -0
- package/dist/route-label.js.map +1 -0
- package/dist/routes/health.d.ts +30 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +54 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +3 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/wellknown.d.ts +11 -0
- package/dist/routes/wellknown.d.ts.map +1 -0
- package/dist/routes/wellknown.js +45 -0
- package/dist/routes/wellknown.js.map +1 -0
- package/dist/secret.d.ts +30 -0
- package/dist/secret.d.ts.map +1 -0
- package/dist/secret.js +97 -0
- package/dist/secret.js.map +1 -0
- package/dist/setup-transport.d.ts +23 -0
- package/dist/setup-transport.d.ts.map +1 -0
- package/dist/setup-transport.js +52 -0
- package/dist/setup-transport.js.map +1 -0
- package/dist/state.d.ts +21 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +4 -0
- package/dist/state.js.map +1 -0
- package/dist/storage/driver.d.ts +38 -0
- package/dist/storage/driver.d.ts.map +1 -0
- package/dist/storage/driver.js +14 -0
- package/dist/storage/driver.js.map +1 -0
- package/dist/storage/factory.d.ts +4 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +20 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +4 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local.d.ts +21 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +88 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/s3.d.ts +29 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +82 -0
- package/dist/storage/s3.js.map +1 -0
- package/dist/testing/fake-hub.d.ts +425 -0
- package/dist/testing/fake-hub.d.ts.map +1 -0
- package/dist/testing/fake-hub.js +1074 -0
- package/dist/testing/fake-hub.js.map +1 -0
- package/dist/testing/helpers.d.ts +124 -0
- package/dist/testing/helpers.d.ts.map +1 -0
- package/dist/testing/helpers.js +174 -0
- package/dist/testing/helpers.js.map +1 -0
- package/dist/testing/index.d.ts +12 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/setup-origins.d.ts +21 -0
- package/dist/testing/setup-origins.d.ts.map +1 -0
- package/dist/testing/setup-origins.js +57 -0
- package/dist/testing/setup-origins.js.map +1 -0
- package/dist/testing/sso-helpers.d.ts +43 -0
- package/dist/testing/sso-helpers.d.ts.map +1 -0
- package/dist/testing/sso-helpers.js +159 -0
- package/dist/testing/sso-helpers.js.map +1 -0
- package/dist/tool-definition.d.ts +382 -0
- package/dist/tool-definition.d.ts.map +1 -0
- package/dist/tool-definition.js +46 -0
- package/dist/tool-definition.js.map +1 -0
- package/dist/util/index.d.ts +8 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +8 -0
- package/dist/util/index.js.map +1 -0
- package/package.json +161 -0
- package/src/accounts/deletion.ts +389 -0
- package/src/accounts/erasure-log.ts +140 -0
- package/src/accounts/index.ts +5 -0
- package/src/accounts/mint-refusal.ts +67 -0
- package/src/accounts/signup-duplicate.ts +21 -0
- package/src/accounts/superadmin.ts +46 -0
- package/src/api/apikeys.ts +147 -0
- package/src/api/audit.ts +83 -0
- package/src/api/break-glass.ts +294 -0
- package/src/api/cli-auth.ts +308 -0
- package/src/api/create-api.ts +1403 -0
- package/src/api/demo-passes.ts +207 -0
- package/src/api/errors.ts +13 -0
- package/src/api/export.ts +482 -0
- package/src/api/files.ts +200 -0
- package/src/api/index.ts +29 -0
- package/src/api/invitations.ts +396 -0
- package/src/api/members.ts +617 -0
- package/src/api/onboarding.ts +50 -0
- package/src/api/openapi-doc.ts +34 -0
- package/src/api/projects.ts +788 -0
- package/src/api/scope-routes.ts +12 -0
- package/src/api/sso-connect.ts +246 -0
- package/src/api/sso-logout.ts +76 -0
- package/src/api/teams.ts +575 -0
- package/src/api/workspaces.ts +649 -0
- package/src/apikeys/index.ts +2 -0
- package/src/apikeys/peppers.ts +118 -0
- package/src/apikeys/service.ts +223 -0
- package/src/app.ts +228 -0
- package/src/audit/filters.ts +101 -0
- package/src/audit/index.ts +9 -0
- package/src/audit/service.ts +154 -0
- package/src/boot.ts +953 -0
- package/src/constant-time.ts +9 -0
- package/src/email/driver.ts +139 -0
- package/src/email/index.ts +26 -0
- package/src/email/shell.ts +201 -0
- package/src/email/templates.ts +184 -0
- package/src/entitlements/check.ts +435 -0
- package/src/entitlements/clock-skew.ts +58 -0
- package/src/entitlements/gate.ts +636 -0
- package/src/entitlements/hub-machine-token.ts +205 -0
- package/src/entitlements/hub-subject.ts +77 -0
- package/src/entitlements/index.ts +37 -0
- package/src/entitlements/poster.ts +265 -0
- package/src/entitlements/profiles.ts +303 -0
- package/src/entitlements/slot.ts +105 -0
- package/src/env.ts +456 -0
- package/src/files/http.ts +77 -0
- package/src/files/index.ts +4 -0
- package/src/files/serve.ts +115 -0
- package/src/files/service.ts +209 -0
- package/src/files/spool.ts +58 -0
- package/src/identity/better-auth.ts +1103 -0
- package/src/identity/demo-pass-plugin.ts +121 -0
- package/src/identity/demo-pass-rules.ts +229 -0
- package/src/identity/demo-pass.ts +390 -0
- package/src/identity/hub-grant.ts +704 -0
- package/src/identity/hub-jwt.ts +78 -0
- package/src/identity/hub-live-gate.ts +167 -0
- package/src/identity/hub-logout.ts +174 -0
- package/src/identity/hub-projection.ts +251 -0
- package/src/identity/hub-reconcile.ts +572 -0
- package/src/identity/hub-sso.ts +696 -0
- package/src/identity/hub-user-client.ts +554 -0
- package/src/identity/index.ts +56 -0
- package/src/identity/oauth-jwt.ts +128 -0
- package/src/identity/resolve-membership.ts +104 -0
- package/src/identity/signing-key.ts +164 -0
- package/src/index.ts +65 -0
- package/src/invitations/index.ts +1 -0
- package/src/invitations/service.ts +171 -0
- package/src/jobs/index.ts +25 -0
- package/src/jobs/pgboss.ts +594 -0
- package/src/jobs/timers.ts +287 -0
- package/src/logger.ts +67 -0
- package/src/mcp/errors.ts +111 -0
- package/src/mcp/http.ts +129 -0
- package/src/mcp/index.ts +28 -0
- package/src/mcp/inputs.ts +33 -0
- package/src/mcp/projects.ts +480 -0
- package/src/mcp/server.ts +174 -0
- package/src/mcp/teams.ts +97 -0
- package/src/mcp/tool-kit.ts +148 -0
- package/src/members/removal.ts +216 -0
- package/src/middleware/auth-body.ts +58 -0
- package/src/middleware/auth-context.ts +384 -0
- package/src/middleware/body-cap.ts +33 -0
- package/src/middleware/body-refusal.ts +23 -0
- package/src/middleware/cross-site.ts +122 -0
- package/src/middleware/hub-managed.ts +61 -0
- package/src/middleware/idempotency.ts +264 -0
- package/src/middleware/index.ts +33 -0
- package/src/middleware/json-depth.ts +74 -0
- package/src/middleware/no-store.ts +30 -0
- package/src/middleware/oauth-public.ts +54 -0
- package/src/middleware/rate-limit.ts +432 -0
- package/src/middleware/request-id.ts +54 -0
- package/src/middleware/scopes.ts +150 -0
- package/src/middleware/security-headers.ts +129 -0
- package/src/observability/index.ts +2 -0
- package/src/observability/metrics.ts +102 -0
- package/src/observability/otel.ts +79 -0
- package/src/pagination.ts +118 -0
- package/src/platform/edition.ts +140 -0
- package/src/platform/entitlements.ts +47 -0
- package/src/platform/events.ts +71 -0
- package/src/platform/index.ts +7 -0
- package/src/platform/local-identity.ts +90 -0
- package/src/platform/registry.ts +28 -0
- package/src/platform/usage.ts +13 -0
- package/src/platform/workspaces.ts +41 -0
- package/src/projects/access.ts +160 -0
- package/src/projects/index.ts +7 -0
- package/src/route-label.ts +29 -0
- package/src/routes/health.ts +79 -0
- package/src/routes/index.ts +2 -0
- package/src/routes/wellknown.ts +67 -0
- package/src/secret.ts +115 -0
- package/src/setup-transport.ts +46 -0
- package/src/state.ts +23 -0
- package/src/storage/driver.ts +48 -0
- package/src/storage/factory.ts +34 -0
- package/src/storage/index.ts +3 -0
- package/src/storage/local.ts +93 -0
- package/src/storage/s3.ts +109 -0
- package/src/testing/fake-hub.ts +1316 -0
- package/src/testing/helpers.ts +254 -0
- package/src/testing/index.ts +11 -0
- package/src/testing/setup-origins.ts +58 -0
- package/src/testing/sso-helpers.ts +178 -0
- package/src/tool-definition.ts +463 -0
- package/src/util/index.ts +17 -0
- package/test/fixtures/onboarding-backfill.sql +13 -0
- package/test/fixtures/operator-user-id-backfill.sql +18 -0
- package/test/host/dr-lib.sh +253 -0
- package/test/host/drizzle/0000_chassis_baseline.sql +438 -0
- package/test/host/drizzle/0001_last_owner_guard.sql +42 -0
- package/test/host/drizzle/meta/0000_snapshot.json +3566 -0
- package/test/host/drizzle/meta/_journal.json +20 -0
- package/test/host/drizzle.config.ts +17 -0
- package/test/host/identity.ts +41 -0
- package/test/host/minimal-host.ts +35 -0
- package/test/host/minimal-tool.ts +123 -0
- package/test/integration/account-oracle-uniformity.test.ts +284 -0
- package/test/integration/account-recovery.test.ts +236 -0
- package/test/integration/account.test.ts +120 -0
- package/test/integration/api-quota.test.ts +208 -0
- package/test/integration/apikey-expiry.test.ts +178 -0
- package/test/integration/apikey-pepper-rotation.test.ts +190 -0
- package/test/integration/boot-posture.test.ts +169 -0
- package/test/integration/break-glass.test.ts +484 -0
- package/test/integration/cloud-lifecycle.test.ts +233 -0
- package/test/integration/credential-boundaries.test.ts +195 -0
- package/test/integration/default-workspace.test.ts +414 -0
- package/test/integration/demo-pass-rules.test.ts +332 -0
- package/test/integration/demo-pass.test.ts +1222 -0
- package/test/integration/dr-verify-real-dump.test.ts +154 -0
- package/test/integration/edition.test.ts +868 -0
- package/test/integration/email-change.test.ts +394 -0
- package/test/integration/empty-tool.test.ts +267 -0
- package/test/integration/entitlements-null-hook.test.ts +187 -0
- package/test/integration/entitlements.test.ts +693 -0
- package/test/integration/export-entries.test.ts +321 -0
- package/test/integration/files.test.ts +320 -0
- package/test/integration/first-boot-claim.test.ts +131 -0
- package/test/integration/gdpr.test.ts +532 -0
- package/test/integration/helpers.ts +29 -0
- package/test/integration/hub-grant.test.ts +505 -0
- package/test/integration/hub-live-gate.test.ts +612 -0
- package/test/integration/hub-managed-membership.test.ts +559 -0
- package/test/integration/hub-org-selector.test.ts +281 -0
- package/test/integration/hub-reconcile.test.ts +646 -0
- package/test/integration/hub-sso.test.ts +704 -0
- package/test/integration/hub-teams.test.ts +771 -0
- package/test/integration/idempotency.test.ts +261 -0
- package/test/integration/invite-verification.test.ts +210 -0
- package/test/integration/last-owner-race.test.ts +263 -0
- package/test/integration/m9-fixes.test.ts +290 -0
- package/test/integration/mcp-projects.test.ts +463 -0
- package/test/integration/member-removal-race.test.ts +466 -0
- package/test/integration/member-removal.test.ts +794 -0
- package/test/integration/oauth-mcp.test.ts +477 -0
- package/test/integration/oauth-workspace.test.ts +371 -0
- package/test/integration/observability.test.ts +183 -0
- package/test/integration/onboarding.test.ts +268 -0
- package/test/integration/orphan-purge.test.ts +451 -0
- package/test/integration/pagination.test.ts +344 -0
- package/test/integration/platform-core.test.ts +305 -0
- package/test/integration/platform.test.ts +246 -0
- package/test/integration/pool-survives-restart.test.ts +80 -0
- package/test/integration/projects-cloud.test.ts +193 -0
- package/test/integration/projects.test.ts +1310 -0
- package/test/integration/security-fixes.test.ts +190 -0
- package/test/integration/setup-transport.test.ts +118 -0
- package/test/integration/signin-wall.test.ts +103 -0
- package/test/integration/signing-key-rotation.test.ts +349 -0
- package/test/integration/sso-helpers.ts +15 -0
- package/test/integration/sso-logout.test.ts +283 -0
- package/test/integration/teams-cloud.test.ts +194 -0
- package/test/integration/teams.test.ts +551 -0
- package/test/integration/timers.test.ts +377 -0
- package/test/integration/two-factor.test.ts +301 -0
- package/test/integration/usage-window.test.ts +161 -0
- package/test/integration/workspace-create-cloud.test.ts +523 -0
- package/test/integration/workspace-create.test.ts +510 -0
- package/test/integration/workspace-scoping.test.ts +530 -0
- package/test/integration/zz-adv-replay-owner.test.ts +205 -0
- package/test/unit/apikey-peppers.test.ts +110 -0
- package/test/unit/apikey-prefix.test.ts +34 -0
- package/test/unit/audit-filters.test.ts +135 -0
- package/test/unit/auth-origins.test.ts +92 -0
- package/test/unit/body-cap.test.ts +84 -0
- package/test/unit/clock-skew.test.ts +68 -0
- package/test/unit/cross-site.test.ts +166 -0
- package/test/unit/declared-credits.test.ts +13 -0
- package/test/unit/demo-pass-rules.test.ts +192 -0
- package/test/unit/email-driver.test.ts +127 -0
- package/test/unit/end-pool.test.ts +181 -0
- package/test/unit/entitlement-check.test.ts +492 -0
- package/test/unit/entitlement-gate.test.ts +1333 -0
- package/test/unit/entitlement-profiles.test.ts +289 -0
- package/test/unit/erasure-log.test.ts +72 -0
- package/test/unit/error-mapping.test.ts +89 -0
- package/test/unit/export-entries.test.ts +85 -0
- package/test/unit/export-sanitize.test.ts +27 -0
- package/test/unit/files-head-route.test.ts +155 -0
- package/test/unit/files-http.test.ts +97 -0
- package/test/unit/head-rewrite.test.ts +72 -0
- package/test/unit/hub-create-org.test.ts +181 -0
- package/test/unit/hub-jwt.test.ts +93 -0
- package/test/unit/hub-sso-params.test.ts +39 -0
- package/test/unit/hub-subject.test.ts +83 -0
- package/test/unit/idempotency-crypto.test.ts +45 -0
- package/test/unit/json-depth.test.ts +88 -0
- package/test/unit/logger-redaction.test.ts +66 -0
- package/test/unit/mcp-errors.test.ts +110 -0
- package/test/unit/mcp-inputs.test.ts +106 -0
- package/test/unit/mcp-project-hints.test.ts +26 -0
- package/test/unit/no-store.test.ts +49 -0
- package/test/unit/no-tool-migration-filename.test.ts +70 -0
- package/test/unit/observability.test.ts +64 -0
- package/test/unit/openapi-doc.test.ts +93 -0
- package/test/unit/rate-limit-consume-on.test.ts +76 -0
- package/test/unit/rate-limit.test.ts +39 -0
- package/test/unit/readyz-storage.test.ts +157 -0
- package/test/unit/request-quota.test.ts +146 -0
- package/test/unit/scopes.test.ts +66 -0
- package/test/unit/security-headers.test.ts +131 -0
- package/test/unit/serve-content-type.test.ts +74 -0
- package/test/unit/setup-transport.test.ts +29 -0
- package/test/unit/storage-local.test.ts +53 -0
- package/test/unit/superadmin.test.ts +32 -0
- package/test/unit/timers.test.ts +287 -0
- package/test/unit/tool-definition-guards.test.ts +166 -0
- package/test/unit/tool-entitlements-guard.test.ts +168 -0
- package/test/unit/usage-poster.test.ts +542 -0
- package/test/unit/usage-window.test.ts +48 -0
- package/test/unit/workspace-create-audit.test.ts +48 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { mcpInputs } from './inputs.js';
|
|
3
|
+
import { jsonText, mergeErrorHints, wrapToolErrors } from './errors.js';
|
|
4
|
+
import { projectErrorHints, registerProjectTools } from './projects.js';
|
|
5
|
+
import { registerTeamTools } from './teams.js';
|
|
6
|
+
import { callApi, createScopeCheck, forWorkspace, pageQuery } from './tool-kit.js';
|
|
7
|
+
/**
|
|
8
|
+
* The ONE composition of an instance's hint table: the domain hints, then
|
|
9
|
+
* every chassis group (the projects today), then the tool's own last, so a
|
|
10
|
+
* tool may re-word a chassis code and never the reverse. A tool set that
|
|
11
|
+
* wraps its own errors reads the same composition (never a copy), so a
|
|
12
|
+
* chassis group added here reaches the tool's tools without a second edit.
|
|
13
|
+
*/
|
|
14
|
+
export function composeErrorHints(toolHints, toolPrefix) {
|
|
15
|
+
return mergeErrorHints({ ...projectErrorHints(toolPrefix), ...toolHints });
|
|
16
|
+
}
|
|
17
|
+
export function buildMcpServer(ctx, info, tool, identity) {
|
|
18
|
+
// `<prefix>whoami` (the contract of `toolPrefix`), registered below: the other chassis tools point at it.
|
|
19
|
+
const whoami = `${identity.toolPrefix}whoami`;
|
|
20
|
+
const checkScope = createScopeCheck(tool.scopes);
|
|
21
|
+
const hints = composeErrorHints(tool.errorHints, identity.toolPrefix);
|
|
22
|
+
const server = new McpServer({ name: identity.serverName, version: info.version }, {
|
|
23
|
+
instructions: tool.instructions(info)
|
|
24
|
+
});
|
|
25
|
+
// The shared inputs (`inputs.ts`): the ones a tool's own set declares its tools with.
|
|
26
|
+
const { workspaceInput, cursorInput, limitInput } = mcpInputs(identity);
|
|
27
|
+
// ── Pattern 1: READ tool — the end-to-end whoami proof ────────────────────
|
|
28
|
+
server.registerTool('get_me', {
|
|
29
|
+
description: 'Who is connected: the user this MCP connection acts as, with all their organizations. ' +
|
|
30
|
+
'Returns { user: { id, email, name }, workspace, role, via, scopes, workspaces }. ' +
|
|
31
|
+
`Everything done through this server happens as this user. (Alias of ${whoami}.)`,
|
|
32
|
+
inputSchema: { workspace: workspaceInput },
|
|
33
|
+
annotations: { readOnlyHint: true }
|
|
34
|
+
}, async ({ workspace }) => {
|
|
35
|
+
const denied = checkScope(ctx.principal, tool.scopes.read);
|
|
36
|
+
if (denied)
|
|
37
|
+
return denied;
|
|
38
|
+
const c = forWorkspace(ctx, workspace);
|
|
39
|
+
return wrapToolErrors(async () => jsonText(await callApi(c, '/api/v1/me')), hints);
|
|
40
|
+
});
|
|
41
|
+
// ── Pattern 2: LIST tool with cursor pagination passed through ────────────
|
|
42
|
+
server.registerTool('list_files', {
|
|
43
|
+
description: "List a workspace's files, newest first. Returns { files: [{ id, sha256, sizeBytes, " +
|
|
44
|
+
'contentType, originalName, createdBy, createdAt }], nextCursor }. When nextCursor is ' +
|
|
45
|
+
'non-null, call again with cursor set to it for the next page. Download or upload happen ' +
|
|
46
|
+
'through the API, not through tools.',
|
|
47
|
+
inputSchema: {
|
|
48
|
+
workspace: workspaceInput,
|
|
49
|
+
limit: limitInput,
|
|
50
|
+
cursor: cursorInput
|
|
51
|
+
},
|
|
52
|
+
annotations: { readOnlyHint: true }
|
|
53
|
+
}, async ({ workspace, limit, cursor }) => {
|
|
54
|
+
const denied = checkScope(ctx.principal, tool.scopes.read);
|
|
55
|
+
if (denied)
|
|
56
|
+
return denied;
|
|
57
|
+
const c = forWorkspace(ctx, workspace);
|
|
58
|
+
return wrapToolErrors(async () => jsonText(await callApi(c, pageQuery('/api/v1/files', { cursor, limit }))), hints);
|
|
59
|
+
});
|
|
60
|
+
// ── Identity under the tool's own prefix ───────────────────────────────────
|
|
61
|
+
// Registered by the chassis (it reads `/me`, nothing of a domain) so that the
|
|
62
|
+
// name every `workspace` argument and `get_me` point at always exists. Third,
|
|
63
|
+
// right before the tool's set: `tools/list` keeps its order.
|
|
64
|
+
server.registerTool(whoami, {
|
|
65
|
+
description: 'Who is connected: the user this MCP connection acts as, plus ALL their organizations ' +
|
|
66
|
+
'(workspaces) with per-entry role/default/suspended flags. Returns { user: { id, email, ' +
|
|
67
|
+
'name }, workspace, role, via, scopes, workspaces: [...], activeWorkspaceId }. The ' +
|
|
68
|
+
'credential is the USER; the organization is a PER-CALL parameter: every tool accepts an ' +
|
|
69
|
+
'optional `workspace` (an id from `workspaces[]`) — omitted, the entry flagged `default: ' +
|
|
70
|
+
'true` is used (else the oldest membership). Call this first to discover the ids.',
|
|
71
|
+
inputSchema: { workspace: workspaceInput },
|
|
72
|
+
annotations: { readOnlyHint: true }
|
|
73
|
+
}, async ({ workspace }) => {
|
|
74
|
+
const denied = checkScope(ctx.principal, tool.scopes.read);
|
|
75
|
+
if (denied)
|
|
76
|
+
return denied;
|
|
77
|
+
const c = forWorkspace(ctx, workspace);
|
|
78
|
+
return wrapToolErrors(async () => jsonText(await callApi(c, '/api/v1/me')), hints);
|
|
79
|
+
});
|
|
80
|
+
// ── Projects: a chassis concept, so a chassis tool set ─────────────────────
|
|
81
|
+
// A project is a subgroup of a workspace with its own members and roles —
|
|
82
|
+
// the chassis owns it, and therefore owns the eleven tools over it. Registered
|
|
83
|
+
// under the tool's prefix, after whoami and before the tool's own set, so
|
|
84
|
+
// `tools/list` keeps one stable order across every instance.
|
|
85
|
+
registerProjectTools(server, ctx, identity, tool.scopes, checkScope, hints);
|
|
86
|
+
// Teams (PRDCT-2813): a chassis concept too, read-only over MCP, right after
|
|
87
|
+
// the projects they can be members of.
|
|
88
|
+
registerTeamTools(server, ctx, identity, tool.scopes, checkScope, hints);
|
|
89
|
+
// The product surface: the tool's own set, after the chassis tools.
|
|
90
|
+
tool.registerTools(server, ctx);
|
|
91
|
+
return server;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type ErrorHints } from './errors.js';
|
|
3
|
+
import { type McpScopes, type McpToolContext, type ScopeCheck } from './tool-kit.js';
|
|
4
|
+
import type { McpIdentity } from './server.js';
|
|
5
|
+
/** Register the two team reads on a server, after the project tools. */
|
|
6
|
+
export declare function registerTeamTools(server: McpServer, ctx: McpToolContext, identity: McpIdentity, scopes: McpScopes, checkScope: ScopeCheck<string>, hints: ErrorHints): void;
|
|
7
|
+
//# sourceMappingURL=teams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/mcp/teams.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAA4B,KAAK,UAAU,EAAuB,MAAM,aAAa,CAAC;AAC7F,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA8B/C,wEAAwE;AACxE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,EAC9B,KAAK,EAAE,UAAU,GAChB,IAAI,CA8CN"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { mcpInputs } from './inputs.js';
|
|
3
|
+
import { jsonText, wrapToolErrors } from './errors.js';
|
|
4
|
+
import { callApi, forWorkspace, pageQuery } from './tool-kit.js';
|
|
5
|
+
/**
|
|
6
|
+
* The two TEAM reads (PRDCT-2813), registered by the chassis right after the
|
|
7
|
+
* project tools: a team is a chassis concept (a named group of a workspace's
|
|
8
|
+
* own members, on both editions), so the tools over it are the chassis'. Thin
|
|
9
|
+
* shims over the instance's own /api/v1/teams called IN-PROCESS with the
|
|
10
|
+
* caller's bearer forwarded verbatim, like every other chassis tool.
|
|
11
|
+
*
|
|
12
|
+
* READS ONLY, by design: shaping a team (creating it, seating people) is a
|
|
13
|
+
* person's act on the People page, or on the Antasphere account site for a
|
|
14
|
+
* workspace it manages; an agent puts a team on a project through
|
|
15
|
+
* `<toolPrefix>add_project_member` with `teamId`. Nothing here names a tool,
|
|
16
|
+
* a brand or a domain.
|
|
17
|
+
*/
|
|
18
|
+
/** What a team IS, opening both descriptions. */
|
|
19
|
+
const WHAT_IS_A_TEAM = 'A team is a named group of the organization’s own members (for example "Design" or "Sales"). ' +
|
|
20
|
+
'A team can be put on a project with a role, and every member of the team then holds that role ' +
|
|
21
|
+
'on the project.';
|
|
22
|
+
/** Where teams come from and where they are shaped. */
|
|
23
|
+
const WHERE_TEAMS_LIVE = 'In an organization managed by the Antasphere account site, the teams come from there and are ' +
|
|
24
|
+
'read-only here. Creating a team or adding people to one is done by a person on the People page, ' +
|
|
25
|
+
'or on the Antasphere account site for an organization it manages, never through these tools.';
|
|
26
|
+
const teamIdInput = z.uuid().describe('The team id, from the teams list (never the team name or slug).');
|
|
27
|
+
/** Register the two team reads on a server, after the project tools. */
|
|
28
|
+
export function registerTeamTools(server, ctx, identity, scopes, checkScope, hints) {
|
|
29
|
+
const { workspaceInput, cursorInput, limitInput } = mcpInputs(identity);
|
|
30
|
+
const prefix = identity.toolPrefix;
|
|
31
|
+
const read = (workspace, path) => {
|
|
32
|
+
const denied = checkScope(ctx.principal, scopes.read);
|
|
33
|
+
if (denied)
|
|
34
|
+
return Promise.resolve(denied);
|
|
35
|
+
const c = forWorkspace(ctx, workspace);
|
|
36
|
+
return wrapToolErrors(async () => jsonText(await callApi(c, path)), hints);
|
|
37
|
+
};
|
|
38
|
+
server.registerTool(`${prefix}list_teams`, {
|
|
39
|
+
description: `List the teams of an organization, newest first. ${WHAT_IS_A_TEAM} ${WHERE_TEAMS_LIVE} ` +
|
|
40
|
+
'Returns { teams: [{ id, slug, name, membersCount, isMember, hubTeamId, createdAt, ' +
|
|
41
|
+
'updatedAt }], nextCursor } — `isMember` says whether YOU are in the team, and `hubTeamId` ' +
|
|
42
|
+
'is set when the team comes from the Antasphere account site. Pass a team `id` as `teamId` ' +
|
|
43
|
+
`to ${prefix}list_team_members or ${prefix}add_project_member. When nextCursor is non-null, ` +
|
|
44
|
+
'call again with cursor set to it.',
|
|
45
|
+
inputSchema: { workspace: workspaceInput, limit: limitInput, cursor: cursorInput },
|
|
46
|
+
annotations: { readOnlyHint: true }
|
|
47
|
+
}, async ({ workspace, limit, cursor }) => read(workspace, pageQuery('/api/v1/teams', { cursor, limit })));
|
|
48
|
+
server.registerTool(`${prefix}list_team_members`, {
|
|
49
|
+
description: `List the members of one team. ${WHAT_IS_A_TEAM} ${WHERE_TEAMS_LIVE} Returns { members: ` +
|
|
50
|
+
'[{ userId, email, name, role, isActive, addedAt }], nextCursor } — `role` is the person’s ' +
|
|
51
|
+
'role in the ORGANIZATION (a team has no roles of its own). When nextCursor is non-null, call ' +
|
|
52
|
+
'again with cursor set to it.',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
workspace: workspaceInput,
|
|
55
|
+
teamId: teamIdInput,
|
|
56
|
+
limit: limitInput,
|
|
57
|
+
cursor: cursorInput
|
|
58
|
+
},
|
|
59
|
+
annotations: { readOnlyHint: true }
|
|
60
|
+
}, async ({ workspace, teamId, limit, cursor }) => read(workspace, pageQuery(`/api/v1/teams/${teamId}/members`, { cursor, limit })));
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=teams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/mcp/teams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAwC,MAAM,aAAa,CAAC;AAC7F,OAAO,EACL,OAAO,EACP,YAAY,EACZ,SAAS,EAIV,MAAM,eAAe,CAAC;AAGvB;;;;;;;;;;;;GAYG;AAEH,iDAAiD;AACjD,MAAM,cAAc,GAClB,+FAA+F;IAC/F,gGAAgG;IAChG,iBAAiB,CAAC;AAEpB,uDAAuD;AACvD,MAAM,gBAAgB,GACpB,+FAA+F;IAC/F,kGAAkG;IAClG,8FAA8F,CAAC;AAEjG,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC,CAAC;AAEzG,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,GAAmB,EACnB,QAAqB,EACrB,MAAiB,EACjB,UAA8B,EAC9B,KAAiB;IAEjB,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;IAEnC,MAAM,IAAI,GAAG,CAAC,SAA6B,EAAE,IAAY,EAA2B,EAAE;QACpF,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,MAAM;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7E,CAAC,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,GAAG,MAAM,YAAY,EACrB;QACE,WAAW,EACT,oDAAoD,cAAc,IAAI,gBAAgB,GAAG;YACzF,oFAAoF;YACpF,4FAA4F;YAC5F,4FAA4F;YAC5F,MAAM,MAAM,wBAAwB,MAAM,mDAAmD;YAC7F,mCAAmC;QACrC,WAAW,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE;QAClF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CACvG,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,GAAG,MAAM,mBAAmB,EAC5B;QACE,WAAW,EACT,iCAAiC,cAAc,IAAI,gBAAgB,sBAAsB;YACzF,4FAA4F;YAC5F,+FAA+F;YAC/F,8BAA8B;QAChC,WAAW,EAAE;YACX,SAAS,EAAE,cAAc;YACzB,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,WAAW;SACpB;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAC7C,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,iBAAiB,MAAM,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CACnF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type Principal } from '@antasphere/chassis-contract';
|
|
2
|
+
import { type ToolTextResult } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Shared plumbing for MCP tools (used by the chassis examples in server.ts
|
|
5
|
+
* and the tool's own set). Every call goes through the
|
|
6
|
+
* instance's own /api/v1 IN-PROCESS with the caller's Authorization header
|
|
7
|
+
* forwarded verbatim — MCP is just another API client, no privileged path.
|
|
8
|
+
*/
|
|
9
|
+
export interface McpToolContext {
|
|
10
|
+
/** In-process fetch against the root app (path → Response). */
|
|
11
|
+
fetchApi: (path: string, init?: RequestInit) => Promise<Response>;
|
|
12
|
+
/** The verified caller (OAuth token or API key principal). */
|
|
13
|
+
principal: Principal;
|
|
14
|
+
/** Forwarded verbatim on every in-process API call. */
|
|
15
|
+
authorizationHeader: string;
|
|
16
|
+
/**
|
|
17
|
+
* The instance's public origin (`PUBLIC_BASE_URL`), for the one thing a
|
|
18
|
+
* tool composes for a human rather than for the API: the page of the tool's
|
|
19
|
+
* resource that a push answers with (PRDCT-2280). Never used to reach the API.
|
|
20
|
+
*/
|
|
21
|
+
publicBaseUrl: string;
|
|
22
|
+
/**
|
|
23
|
+
* Target workspace of THIS tool call (user-scoped credential model): set
|
|
24
|
+
* from the tool's optional `workspace` argument via {@link forWorkspace},
|
|
25
|
+
* it rides the in-process re-entry as the X-Workspace-Id header, where
|
|
26
|
+
* the API's own resolvers authorize it against the caller's live
|
|
27
|
+
* memberships — a tool argument can never grant what the credential's
|
|
28
|
+
* user does not hold. Absent = the caller's default workspace.
|
|
29
|
+
*/
|
|
30
|
+
workspaceId?: string | undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The per-call workspace seam: every workspace-scoped tool passes its
|
|
34
|
+
* optional `workspace` argument through here so the selection travels on
|
|
35
|
+
* the ONE header the whole platform authorizes.
|
|
36
|
+
*/
|
|
37
|
+
export declare function forWorkspace(ctx: McpToolContext, workspace: string | undefined): McpToolContext;
|
|
38
|
+
/**
|
|
39
|
+
* Tool-level scope pre-check — UX only: the API's fail-closed allowlist
|
|
40
|
+
* (middleware/scopes.ts) is the enforcement point; this just gives the model
|
|
41
|
+
* a clean, actionable error instead of a raw 403.
|
|
42
|
+
*/
|
|
43
|
+
export type ScopeCheck<TScope extends string> = (principal: Principal, scope: TScope) => ToolTextResult | null;
|
|
44
|
+
/** The tool's two MCP scope names: what a read tool and a write tool pre-check. */
|
|
45
|
+
export interface McpScopes<TRead extends string = string, TWrite extends string = string> {
|
|
46
|
+
read: TRead;
|
|
47
|
+
write: TWrite;
|
|
48
|
+
}
|
|
49
|
+
export declare function createScopeCheck<TRead extends string, TWrite extends string>(scopes: McpScopes<TRead, TWrite>): ScopeCheck<TRead | TWrite>;
|
|
50
|
+
/**
|
|
51
|
+
* In-process API call returning the raw Response (asset downloads, multipart
|
|
52
|
+
* uploads). A non-2xx answer is parsed into an ApiToolError so wrapToolErrors
|
|
53
|
+
* renders the code + `Next:` hint.
|
|
54
|
+
*/
|
|
55
|
+
export declare function fetchApiRaw(ctx: McpToolContext, path: string, init?: RequestInit): Promise<Response>;
|
|
56
|
+
/** In-process JSON API call: parses the body, maps non-2xx to ApiToolError. */
|
|
57
|
+
export declare function callApi(ctx: McpToolContext, path: string, init?: RequestInit): Promise<unknown>;
|
|
58
|
+
/**
|
|
59
|
+
* Append cursor/limit list params to a path, after the route's own filters
|
|
60
|
+
* (`extra`, e.g. the `type` of the tool's resource list); an undefined filter is
|
|
61
|
+
* left out.
|
|
62
|
+
*/
|
|
63
|
+
export declare function pageQuery(base: string, params: {
|
|
64
|
+
cursor?: string | undefined;
|
|
65
|
+
limit?: number | undefined;
|
|
66
|
+
}, extra?: Record<string, string | undefined>): string;
|
|
67
|
+
//# sourceMappingURL=tool-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-kit.d.ts","sourceRoot":"","sources":["../../src/mcp/tool-kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE,8DAA8D;IAC9D,SAAS,EAAE,SAAS,CAAC;IACrB,uDAAuD;IACvD,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAE/F;AAUD;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,MAAM,SAAS,MAAM,IAAI,CAC9C,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,KACV,cAAc,GAAG,IAAI,CAAC;AAE3B,mFAAmF;AACnF,MAAM,WAAW,SAAS,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM;IACtF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,SAAS,MAAM,EAC1E,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAC/B,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC,CAW5B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CAiBnB;AAED,+EAA+E;AAC/E,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBzG;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACnE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,GAC7C,MAAM,CASR"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ACTIVE_WORKSPACE_HEADER } from '@antasphere/chassis-contract';
|
|
2
|
+
import { ApiToolError, deny } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* The per-call workspace seam: every workspace-scoped tool passes its
|
|
5
|
+
* optional `workspace` argument through here so the selection travels on
|
|
6
|
+
* the ONE header the whole platform authorizes.
|
|
7
|
+
*/
|
|
8
|
+
export function forWorkspace(ctx, workspace) {
|
|
9
|
+
return workspace ? { ...ctx, workspaceId: workspace } : ctx;
|
|
10
|
+
}
|
|
11
|
+
/** The re-entry headers: caller's bearer + the per-call workspace selector. */
|
|
12
|
+
function apiHeaders(ctx) {
|
|
13
|
+
return {
|
|
14
|
+
authorization: ctx.authorizationHeader,
|
|
15
|
+
...(ctx.workspaceId ? { [ACTIVE_WORKSPACE_HEADER]: ctx.workspaceId } : {})
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function createScopeCheck(scopes) {
|
|
19
|
+
return (principal, scope) => {
|
|
20
|
+
if (principal.scopes && !principal.scopes.has(scope)) {
|
|
21
|
+
return deny(`Missing scope "${scope}": this connection was not granted ` +
|
|
22
|
+
(scope === scopes.write ? 'permission to create or edit data.' : 'permission to read data.') +
|
|
23
|
+
' Reconnect the MCP server and approve the permission on the consent screen.');
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* In-process API call returning the raw Response (asset downloads, multipart
|
|
30
|
+
* uploads). A non-2xx answer is parsed into an ApiToolError so wrapToolErrors
|
|
31
|
+
* renders the code + `Next:` hint.
|
|
32
|
+
*/
|
|
33
|
+
export async function fetchApiRaw(ctx, path, init = {}) {
|
|
34
|
+
const res = await ctx.fetchApi(path, {
|
|
35
|
+
...init,
|
|
36
|
+
headers: { ...(init.headers ?? {}), ...apiHeaders(ctx) }
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const body = (await res.json().catch(() => null));
|
|
40
|
+
throw new ApiToolError(res.status, body?.error?.code ?? null, body?.error?.message ?? `unexpected response from ${path}`, body?.error?.details);
|
|
41
|
+
}
|
|
42
|
+
return res;
|
|
43
|
+
}
|
|
44
|
+
/** In-process JSON API call: parses the body, maps non-2xx to ApiToolError. */
|
|
45
|
+
export async function callApi(ctx, path, init = {}) {
|
|
46
|
+
const res = await ctx.fetchApi(path, {
|
|
47
|
+
...init,
|
|
48
|
+
headers: { ...(init.headers ?? {}), ...apiHeaders(ctx) }
|
|
49
|
+
});
|
|
50
|
+
const body = (await res.json().catch(() => null));
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
throw new ApiToolError(res.status, body?.error?.code ?? null, body?.error?.message ?? `unexpected response from ${path}`, body?.error?.details);
|
|
53
|
+
}
|
|
54
|
+
return body;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Append cursor/limit list params to a path, after the route's own filters
|
|
58
|
+
* (`extra`, e.g. the `type` of the tool's resource list); an undefined filter is
|
|
59
|
+
* left out.
|
|
60
|
+
*/
|
|
61
|
+
export function pageQuery(base, params, extra = {}) {
|
|
62
|
+
const query = new URLSearchParams();
|
|
63
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
64
|
+
if (value !== undefined)
|
|
65
|
+
query.set(key, value);
|
|
66
|
+
}
|
|
67
|
+
if (params.cursor)
|
|
68
|
+
query.set('cursor', params.cursor);
|
|
69
|
+
if (params.limit !== undefined)
|
|
70
|
+
query.set('limit', String(params.limit));
|
|
71
|
+
const qs = query.toString();
|
|
72
|
+
return qs ? `${base}?${qs}` : base;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=tool-kit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-kit.js","sourceRoot":"","sources":["../../src/mcp/tool-kit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type DbConn } from '@antasphere/chassis-db';
|
|
2
|
+
/**
|
|
3
|
+
* The membership an ADD hangs a right on, re-read inside the add's own
|
|
4
|
+
* transaction and held FOR SHARE until it commits: true when the row is
|
|
5
|
+
* there, in that workspace, and active. Every add of something a removal
|
|
6
|
+
* takes (a project grant, a team seat, a demo pass) calls this before its
|
|
7
|
+
* insert, and refuses on false the way it refuses an inactive member.
|
|
8
|
+
*
|
|
9
|
+
* Why the lock (the end-to-end verification, finding 5): the add's first read
|
|
10
|
+
* is outside any transaction, and the insert's foreign key check takes only a
|
|
11
|
+
* KEY SHARE lock, which a removal's `UPDATE workspace_members` does not wait
|
|
12
|
+
* for. An add that read the row active, then waited on another lock (the
|
|
13
|
+
* project row, the team row), inserted after a removal had committed, on the
|
|
14
|
+
* now inactive row, and the right came back with the person at their
|
|
15
|
+
* re-invitation. Held FOR SHARE, the row makes the removal's update wait for
|
|
16
|
+
* the add to commit (the removal's second pass then takes what the add
|
|
17
|
+
* wrote, `deleteMembershipGrants`'s caller); an add that arrives after the
|
|
18
|
+
* update re-reads the row off and inserts nothing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function holdLiveMembership(tx: DbConn, workspaceId: string, who: {
|
|
21
|
+
memberId: string;
|
|
22
|
+
} | {
|
|
23
|
+
userId: string;
|
|
24
|
+
}): Promise<boolean>;
|
|
25
|
+
/** One membership a removal switched off. */
|
|
26
|
+
export interface RemovedMembership {
|
|
27
|
+
/** The `workspace_members` row. */
|
|
28
|
+
memberId: string;
|
|
29
|
+
workspaceId: string;
|
|
30
|
+
userId: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The tool's half of a removal (the `membershipRemoval` slot): what the TOOL
|
|
34
|
+
* hangs on a person in a workspace outside the chassis tables (an invite
|
|
35
|
+
* waiting for them, a grant on one of its resources). It runs in the
|
|
36
|
+
* removal's own transaction and answers what it ended, by name, for the
|
|
37
|
+
* audit record.
|
|
38
|
+
*/
|
|
39
|
+
export type MembershipRemovalHook = (tx: DbConn, removed: readonly RemovedMembership[]) => Promise<Record<string, number>>;
|
|
40
|
+
export interface RemovalCounts {
|
|
41
|
+
projectGrants: number;
|
|
42
|
+
teamSeats: number;
|
|
43
|
+
/** Open workspace invitations revoked: the ones FOR the person and the ones they ISSUED. */
|
|
44
|
+
invitations: number;
|
|
45
|
+
/** Live demo passes revoked, their sessions ended: the ones opening the person and the ones they MINTED. */
|
|
46
|
+
demoPasses: number;
|
|
47
|
+
/** What the tool's hook ended, under the names it gave; empty without a hook. */
|
|
48
|
+
tool: Record<string, number>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* What a REMOVAL takes away beside the membership itself, stated once for
|
|
52
|
+
* both editions (PRDCT-2816): the person's project grants, their team seats
|
|
53
|
+
* (which is also every grant they held through a team), the open workspace
|
|
54
|
+
* invitations that name them or that they issued, and what the tool hangs
|
|
55
|
+
* on them in that workspace (`toolHook`).
|
|
56
|
+
*
|
|
57
|
+
* The demo passes are doors too (round 3, F1): a pass the person MINTED
|
|
58
|
+
* signs a demo person in, who could reactivate them; a pass minted FOR them
|
|
59
|
+
* works again the day they are re-invited, in whoever's hands it is. Both
|
|
60
|
+
* are revoked with the sessions they opened, the pass service's own way.
|
|
61
|
+
*
|
|
62
|
+
* ORDER (round 3, F2): the caller runs this BEFORE it switches the membership
|
|
63
|
+
* row off, inside the same transaction. An invitation's accept locks the
|
|
64
|
+
* invitation, then the membership row; a removal that locked the membership
|
|
65
|
+
* first and the invitation second met it head on and one of the two died
|
|
66
|
+
* of a deadlock. Same order on both sides, no deadlock.
|
|
67
|
+
*
|
|
68
|
+
* The invitations are doors, not rights (the verifier's round 2, N1 and N2).
|
|
69
|
+
* An invitation FOR the person that was open at the removal reactivates the
|
|
70
|
+
* row at the role it names: the person would come back alone, as admin if it
|
|
71
|
+
* says so. An invitation the person ISSUED is a way back in under another
|
|
72
|
+
* address. Both are revoked; an invitation made after the removal is the
|
|
73
|
+
* workspace's own act and brings the person back.
|
|
74
|
+
*
|
|
75
|
+
* A removal switches the membership row off and never deletes it (a re-add
|
|
76
|
+
* reactivates the very same row), so the foreign keys' cascade never fires:
|
|
77
|
+
* without these deletes, a person removed and added back later would find
|
|
78
|
+
* every old grant and seat waiting, and a door left open for them (a pending
|
|
79
|
+
* invite of the tool's) would let them switch the row back on themselves. A
|
|
80
|
+
* removal is a removal: only an act of the workspace brings the person back,
|
|
81
|
+
* and they come back with nothing. A PAUSE (`PATCH /members/{id}` with
|
|
82
|
+
* `isActive: false`) keeps everything, on purpose.
|
|
83
|
+
*
|
|
84
|
+
* The two callers: the hub reconcile's sweep (cloud, the hub removed the
|
|
85
|
+
* person) and `POST /members/{id}/remove` (a workspace managed here). Run it
|
|
86
|
+
* in the transaction that switches the rows off.
|
|
87
|
+
*
|
|
88
|
+
* Idempotent, so a caller may run it twice in one transaction: the deletes
|
|
89
|
+
* are by membership, the revokes filter on what is still open. The removal
|
|
90
|
+
* route does (a second pass after the row is off, `mergeRemovalCounts`).
|
|
91
|
+
*/
|
|
92
|
+
export declare function deleteMembershipGrants(tx: DbConn, removed: readonly RemovedMembership[], toolHook?: MembershipRemovalHook): Promise<RemovalCounts>;
|
|
93
|
+
/** Two passes of `deleteMembershipGrants` as one record: every count summed, the tool's by name. */
|
|
94
|
+
export declare function mergeRemovalCounts(a: RemovalCounts, b: RemovalCounts): RemovalCounts;
|
|
95
|
+
//# sourceMappingURL=removal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removal.d.ts","sourceRoot":"","sources":["../../src/members/removal.ts"],"names":[],"mappings":"AACA,OAAO,EAWL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,SAAS,iBAAiB,EAAE,KAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,WAAW,EAAE,MAAM,CAAC;IACpB,4GAA4G;IAC5G,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAwExB;AAED,oGAAoG;AACpG,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,aAAa,CAUpF"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { and, eq, inArray, isNull, or, sql } from 'drizzle-orm';
|
|
2
|
+
import { demoPasses, demoPassSessions, invitations, oauthAccessToken, oauthRefreshToken, projectMembers, session as sessionTable, user as userTable, workspaceMembers, workspaceTeamMembers } from '@antasphere/chassis-db';
|
|
3
|
+
/**
|
|
4
|
+
* The membership an ADD hangs a right on, re-read inside the add's own
|
|
5
|
+
* transaction and held FOR SHARE until it commits: true when the row is
|
|
6
|
+
* there, in that workspace, and active. Every add of something a removal
|
|
7
|
+
* takes (a project grant, a team seat, a demo pass) calls this before its
|
|
8
|
+
* insert, and refuses on false the way it refuses an inactive member.
|
|
9
|
+
*
|
|
10
|
+
* Why the lock (the end-to-end verification, finding 5): the add's first read
|
|
11
|
+
* is outside any transaction, and the insert's foreign key check takes only a
|
|
12
|
+
* KEY SHARE lock, which a removal's `UPDATE workspace_members` does not wait
|
|
13
|
+
* for. An add that read the row active, then waited on another lock (the
|
|
14
|
+
* project row, the team row), inserted after a removal had committed, on the
|
|
15
|
+
* now inactive row, and the right came back with the person at their
|
|
16
|
+
* re-invitation. Held FOR SHARE, the row makes the removal's update wait for
|
|
17
|
+
* the add to commit (the removal's second pass then takes what the add
|
|
18
|
+
* wrote, `deleteMembershipGrants`'s caller); an add that arrives after the
|
|
19
|
+
* update re-reads the row off and inserts nothing.
|
|
20
|
+
*/
|
|
21
|
+
export async function holdLiveMembership(tx, workspaceId, who) {
|
|
22
|
+
const [row] = await tx
|
|
23
|
+
.select({ id: workspaceMembers.id })
|
|
24
|
+
.from(workspaceMembers)
|
|
25
|
+
.where(and('memberId' in who ? eq(workspaceMembers.id, who.memberId) : eq(workspaceMembers.userId, who.userId), eq(workspaceMembers.workspaceId, workspaceId), eq(workspaceMembers.isActive, true)))
|
|
26
|
+
.for('share')
|
|
27
|
+
.limit(1);
|
|
28
|
+
return row !== undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What a REMOVAL takes away beside the membership itself, stated once for
|
|
32
|
+
* both editions (PRDCT-2816): the person's project grants, their team seats
|
|
33
|
+
* (which is also every grant they held through a team), the open workspace
|
|
34
|
+
* invitations that name them or that they issued, and what the tool hangs
|
|
35
|
+
* on them in that workspace (`toolHook`).
|
|
36
|
+
*
|
|
37
|
+
* The demo passes are doors too (round 3, F1): a pass the person MINTED
|
|
38
|
+
* signs a demo person in, who could reactivate them; a pass minted FOR them
|
|
39
|
+
* works again the day they are re-invited, in whoever's hands it is. Both
|
|
40
|
+
* are revoked with the sessions they opened, the pass service's own way.
|
|
41
|
+
*
|
|
42
|
+
* ORDER (round 3, F2): the caller runs this BEFORE it switches the membership
|
|
43
|
+
* row off, inside the same transaction. An invitation's accept locks the
|
|
44
|
+
* invitation, then the membership row; a removal that locked the membership
|
|
45
|
+
* first and the invitation second met it head on and one of the two died
|
|
46
|
+
* of a deadlock. Same order on both sides, no deadlock.
|
|
47
|
+
*
|
|
48
|
+
* The invitations are doors, not rights (the verifier's round 2, N1 and N2).
|
|
49
|
+
* An invitation FOR the person that was open at the removal reactivates the
|
|
50
|
+
* row at the role it names: the person would come back alone, as admin if it
|
|
51
|
+
* says so. An invitation the person ISSUED is a way back in under another
|
|
52
|
+
* address. Both are revoked; an invitation made after the removal is the
|
|
53
|
+
* workspace's own act and brings the person back.
|
|
54
|
+
*
|
|
55
|
+
* A removal switches the membership row off and never deletes it (a re-add
|
|
56
|
+
* reactivates the very same row), so the foreign keys' cascade never fires:
|
|
57
|
+
* without these deletes, a person removed and added back later would find
|
|
58
|
+
* every old grant and seat waiting, and a door left open for them (a pending
|
|
59
|
+
* invite of the tool's) would let them switch the row back on themselves. A
|
|
60
|
+
* removal is a removal: only an act of the workspace brings the person back,
|
|
61
|
+
* and they come back with nothing. A PAUSE (`PATCH /members/{id}` with
|
|
62
|
+
* `isActive: false`) keeps everything, on purpose.
|
|
63
|
+
*
|
|
64
|
+
* The two callers: the hub reconcile's sweep (cloud, the hub removed the
|
|
65
|
+
* person) and `POST /members/{id}/remove` (a workspace managed here). Run it
|
|
66
|
+
* in the transaction that switches the rows off.
|
|
67
|
+
*
|
|
68
|
+
* Idempotent, so a caller may run it twice in one transaction: the deletes
|
|
69
|
+
* are by membership, the revokes filter on what is still open. The removal
|
|
70
|
+
* route does (a second pass after the row is off, `mergeRemovalCounts`).
|
|
71
|
+
*/
|
|
72
|
+
export async function deleteMembershipGrants(tx, removed, toolHook) {
|
|
73
|
+
if (removed.length === 0) {
|
|
74
|
+
return { projectGrants: 0, teamSeats: 0, invitations: 0, demoPasses: 0, tool: {} };
|
|
75
|
+
}
|
|
76
|
+
const ids = removed.map((row) => row.memberId);
|
|
77
|
+
const grants = await tx
|
|
78
|
+
.delete(projectMembers)
|
|
79
|
+
.where(inArray(projectMembers.memberId, ids))
|
|
80
|
+
.returning({ id: projectMembers.id });
|
|
81
|
+
const seats = await tx
|
|
82
|
+
.delete(workspaceTeamMembers)
|
|
83
|
+
.where(inArray(workspaceTeamMembers.memberId, ids))
|
|
84
|
+
.returning({ id: workspaceTeamMembers.id });
|
|
85
|
+
let revokedInvitations = 0;
|
|
86
|
+
let revokedPasses = 0;
|
|
87
|
+
for (const { workspaceId, userId } of removed) {
|
|
88
|
+
const passes = await tx
|
|
89
|
+
.update(demoPasses)
|
|
90
|
+
.set({ revokedAt: sql `now()` })
|
|
91
|
+
.where(and(eq(demoPasses.workspaceId, workspaceId), isNull(demoPasses.revokedAt), or(eq(demoPasses.userId, userId), eq(demoPasses.createdBy, userId))))
|
|
92
|
+
.returning({ id: demoPasses.id });
|
|
93
|
+
if (passes.length > 0) {
|
|
94
|
+
const passIds = passes.map((p) => p.id);
|
|
95
|
+
const sessions = (await tx
|
|
96
|
+
.select({ sessionId: demoPassSessions.sessionId })
|
|
97
|
+
.from(demoPassSessions)
|
|
98
|
+
.where(inArray(demoPassSessions.passId, passIds))).map((s) => s.sessionId);
|
|
99
|
+
if (sessions.length > 0) {
|
|
100
|
+
await tx.delete(oauthAccessToken).where(inArray(oauthAccessToken.sessionId, sessions));
|
|
101
|
+
await tx.delete(oauthRefreshToken).where(inArray(oauthRefreshToken.sessionId, sessions));
|
|
102
|
+
await tx.delete(demoPassSessions).where(inArray(demoPassSessions.sessionId, sessions));
|
|
103
|
+
await tx.delete(sessionTable).where(inArray(sessionTable.id, sessions));
|
|
104
|
+
}
|
|
105
|
+
revokedPasses += passes.length;
|
|
106
|
+
}
|
|
107
|
+
const [person] = await tx
|
|
108
|
+
.select({ email: userTable.email })
|
|
109
|
+
.from(userTable)
|
|
110
|
+
.where(eq(userTable.id, userId))
|
|
111
|
+
.limit(1);
|
|
112
|
+
const rows = await tx
|
|
113
|
+
.update(invitations)
|
|
114
|
+
.set({ revokedAt: sql `now()` })
|
|
115
|
+
.where(and(eq(invitations.workspaceId, workspaceId), isNull(invitations.acceptedAt), isNull(invitations.revokedAt), person
|
|
116
|
+
? or(eq(invitations.invitedBy, userId), sql `lower(${invitations.email}) = lower(${person.email})`)
|
|
117
|
+
: eq(invitations.invitedBy, userId)))
|
|
118
|
+
.returning({ id: invitations.id });
|
|
119
|
+
revokedInvitations += rows.length;
|
|
120
|
+
}
|
|
121
|
+
const tool = toolHook ? await toolHook(tx, removed) : {};
|
|
122
|
+
return {
|
|
123
|
+
projectGrants: grants.length,
|
|
124
|
+
teamSeats: seats.length,
|
|
125
|
+
invitations: revokedInvitations,
|
|
126
|
+
demoPasses: revokedPasses,
|
|
127
|
+
tool
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** Two passes of `deleteMembershipGrants` as one record: every count summed, the tool's by name. */
|
|
131
|
+
export function mergeRemovalCounts(a, b) {
|
|
132
|
+
const tool = { ...a.tool };
|
|
133
|
+
for (const [key, n] of Object.entries(b.tool))
|
|
134
|
+
tool[key] = (tool[key] ?? 0) + n;
|
|
135
|
+
return {
|
|
136
|
+
projectGrants: a.projectGrants + b.projectGrants,
|
|
137
|
+
teamSeats: a.teamSeats + b.teamSeats,
|
|
138
|
+
invitations: a.invitations + b.invitations,
|
|
139
|
+
demoPasses: a.demoPasses + b.demoPasses,
|
|
140
|
+
tool
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=removal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removal.js","sourceRoot":"","sources":["../../src/members/removal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Pre-validates JSON bodies bound for the Better Auth mount (AF-1 + the
|
|
4
|
+
* update-user half of SL-B4, PRDCT-1358).
|
|
5
|
+
*
|
|
6
|
+
* The load-bearing half is NUL: Better Auth's free-text sinks (`/update-user`'s
|
|
7
|
+
* `name`) are outside the contract, so a NUL rode through to Postgres (SQLSTATE
|
|
8
|
+
* 22021) and surfaced as Better Auth's OWN 500 — a response `app.onError` never
|
|
9
|
+
* sees, so the app-level 22021 backstop cannot reach `/auth/*`. Refusing it
|
|
10
|
+
* here, before the mount, is the only complete place.
|
|
11
|
+
*
|
|
12
|
+
* The malformed/empty-JSON half is defence in depth and a wire-shape
|
|
13
|
+
* normalizer: on the pinned Better Auth (better-call ≥ 1.3.7) a JSON parse
|
|
14
|
+
* error already answers 400 (`BAD_REQUEST`), not a 500 — but with better-call's
|
|
15
|
+
* own error code, not this API's. Answering `invalid_json` here keeps the auth
|
|
16
|
+
* surface's parse errors in the same envelope as every other route, and guards
|
|
17
|
+
* a future dependency change that reverts to a 500.
|
|
18
|
+
*
|
|
19
|
+
* A body under a JSON content-type must parse and carry no NUL anywhere;
|
|
20
|
+
* non-JSON content types pass untouched (the OAuth token endpoint is
|
|
21
|
+
* form-encoded), as do bodyless requests. The body is read from a clone — the
|
|
22
|
+
* mount consumes the original.
|
|
23
|
+
*/
|
|
24
|
+
export declare function authBodyGuard(): MiddlewareHandler;
|
|
25
|
+
//# sourceMappingURL=auth-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-body.d.ts","sourceRoot":"","sources":["../../src/middleware/auth-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAO9C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CA4BjD"}
|