@cleocode/contracts 2026.6.13 → 2026.6.15
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/__tests__/operation-def.test.js +4 -1
- package/dist/__tests__/operation-def.test.js.map +1 -1
- package/dist/__tests__/provider-def.test.d.ts +12 -0
- package/dist/__tests__/provider-def.test.d.ts.map +1 -0
- package/dist/__tests__/provider-def.test.js +84 -0
- package/dist/__tests__/provider-def.test.js.map +1 -0
- package/dist/__tests__/service-provider.test.d.ts +17 -0
- package/dist/__tests__/service-provider.test.d.ts.map +1 -0
- package/dist/__tests__/service-provider.test.js +108 -0
- package/dist/__tests__/service-provider.test.js.map +1 -0
- package/dist/boundary.d.ts +52 -0
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +23 -0
- package/dist/boundary.js.map +1 -1
- package/dist/branch-lock.d.ts +4 -0
- package/dist/branch-lock.d.ts.map +1 -1
- package/dist/branch-lock.js.map +1 -1
- package/dist/conduit.d.ts +171 -0
- package/dist/conduit.d.ts.map +1 -1
- package/dist/config/index.d.ts +23 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +22 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config.d.ts +109 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts +21 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts.map +1 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +84 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -0
- package/dist/dispatch/identity.d.ts +1 -1
- package/dist/dispatch/identity.d.ts.map +1 -1
- package/dist/dispatch/identity.js +20 -0
- package/dist/dispatch/identity.js.map +1 -1
- package/dist/dispatch/operation-def.d.ts +20 -0
- package/dist/dispatch/operation-def.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +1030 -46
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/index.d.ts +17 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/lease-ipc/__tests__/freeze.test.js +92 -0
- package/dist/lease-ipc/__tests__/freeze.test.js.map +1 -1
- package/dist/lease-ipc/index.d.ts +2 -2
- package/dist/lease-ipc/index.d.ts.map +1 -1
- package/dist/lease-ipc/index.js +1 -1
- package/dist/lease-ipc/index.js.map +1 -1
- package/dist/lease-ipc/messages.d.ts +167 -3
- package/dist/lease-ipc/messages.d.ts.map +1 -1
- package/dist/lease-ipc/messages.js +93 -0
- package/dist/lease-ipc/messages.js.map +1 -1
- package/dist/llm/catalog-schema.d.ts +242 -0
- package/dist/llm/catalog-schema.d.ts.map +1 -0
- package/dist/llm/catalog-schema.js +153 -0
- package/dist/llm/catalog-schema.js.map +1 -0
- package/dist/llm/catalog-schema.json +139 -0
- package/dist/llm/index.d.ts +15 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +14 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/oauth.d.ts +16 -2
- package/dist/llm/oauth.d.ts.map +1 -1
- package/dist/llm/onboarding.d.ts +126 -0
- package/dist/llm/onboarding.d.ts.map +1 -0
- package/dist/llm/onboarding.js +34 -0
- package/dist/llm/onboarding.js.map +1 -0
- package/dist/llm/provider-def.d.ts +254 -0
- package/dist/llm/provider-def.d.ts.map +1 -0
- package/dist/llm/provider-def.js +93 -0
- package/dist/llm/provider-def.js.map +1 -0
- package/dist/llm/system-resolver.d.ts +42 -0
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/operations/admin.d.ts +124 -1
- package/dist/operations/admin.d.ts.map +1 -1
- package/dist/operations/entities.d.ts +110 -0
- package/dist/operations/entities.d.ts.map +1 -0
- package/dist/operations/entities.js +695 -0
- package/dist/operations/entities.js.map +1 -0
- package/dist/operations/llm.d.ts +16 -1
- package/dist/operations/llm.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +230 -0
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/service.d.ts +68 -0
- package/dist/operations/service.d.ts.map +1 -0
- package/dist/operations/service.js +336 -0
- package/dist/operations/service.js.map +1 -0
- package/dist/operations/tasks.d.ts +109 -0
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/operations/worktree.d.ts +11 -1
- package/dist/operations/worktree.d.ts.map +1 -1
- package/dist/playbook.d.ts +56 -0
- package/dist/playbook.d.ts.map +1 -1
- package/dist/release/plan.d.ts +5 -5
- package/dist/spawn.d.ts +70 -0
- package/dist/spawn.d.ts.map +1 -1
- package/dist/spawn.js +1 -0
- package/dist/spawn.js.map +1 -1
- package/dist/vault/service-provider.d.ts +343 -0
- package/dist/vault/service-provider.d.ts.map +1 -0
- package/dist/vault/service-provider.js +857 -0
- package/dist/vault/service-provider.js.map +1 -0
- package/dist/workgraph.d.ts +12 -12
- package/package.json +10 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/operation-def.test.ts +6 -1
- package/src/__tests__/provider-def.test.ts +93 -0
- package/src/__tests__/service-provider.test.ts +129 -0
- package/src/boundary.ts +69 -0
- package/src/branch-lock.ts +4 -0
- package/src/conduit.ts +200 -0
- package/src/config/index.ts +35 -0
- package/src/config.ts +116 -1
- package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +99 -0
- package/src/dispatch/identity.ts +20 -0
- package/src/dispatch/operation-def.ts +21 -0
- package/src/dispatch/operations-registry.ts +1062 -36
- package/src/index.ts +147 -2
- package/src/lease-ipc/__tests__/freeze.test.ts +96 -0
- package/src/lease-ipc/index.ts +12 -0
- package/src/lease-ipc/messages.ts +117 -0
- package/src/llm/catalog-schema.json +139 -0
- package/src/llm/catalog-schema.ts +184 -0
- package/src/llm/index.ts +29 -0
- package/src/llm/oauth.ts +16 -2
- package/src/llm/onboarding.ts +131 -0
- package/src/llm/provider-def.ts +291 -0
- package/src/llm/system-resolver.ts +45 -0
- package/src/operations/admin.ts +144 -0
- package/src/operations/entities.ts +758 -0
- package/src/operations/llm.ts +16 -0
- package/src/operations/output-contracts-data.ts +264 -0
- package/src/operations/service.ts +360 -0
- package/src/operations/tasks.ts +119 -0
- package/src/operations/worktree.ts +11 -0
- package/src/playbook.ts +56 -0
- package/src/spawn.ts +79 -0
- package/src/vault/service-provider.ts +1137 -0
|
@@ -0,0 +1,857 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal service-vault — declarative service-provider registry (types + DATA).
|
|
3
|
+
*
|
|
4
|
+
* EP-UNIVERSAL-SERVICE-VAULT (epic T11765 · saga SG-VAULT-CORE T10409 · M2 W1a ·
|
|
5
|
+
* task T11937). The **service** half of the universal vault: machine-wide OAuth /
|
|
6
|
+
* API credentials for third-party SERVICES (github, google, notion, figma, …) —
|
|
7
|
+
* distinct from the LLM-provider credential pool (`accounts`, T11709) which holds
|
|
8
|
+
* model-API keys. A {@link ServiceProviderDef} is a purely declarative description
|
|
9
|
+
* of one connectable service: its stable key, display label, auth shape, and the
|
|
10
|
+
* default OAuth endpoints/scopes the (later) OAuth dance (T11939) will drive.
|
|
11
|
+
*
|
|
12
|
+
* ## Why this lives in `@cleocode/contracts` (Gate 10 purity)
|
|
13
|
+
*
|
|
14
|
+
* This module is **types + frozen DATA only**. {@link SERVICE_PROVIDERS} is a
|
|
15
|
+
* `const` record literal (no bodied function, no zod schema, no type guard) — it
|
|
16
|
+
* is configuration data, exactly like a routing table, so it satisfies the
|
|
17
|
+
* contracts-purity gate (`lint-no-runtime-in-contracts`). The runtime that
|
|
18
|
+
* CONSUMES the registry (the store, the trust gate, the OAuth flow) lives in
|
|
19
|
+
* `@cleocode/core`; this file never imports from core and carries no side effects.
|
|
20
|
+
*
|
|
21
|
+
* ## Pattern, not census (T11937 vs T11938)
|
|
22
|
+
*
|
|
23
|
+
* Only **github** and **google** are seeded here, deliberately — they prove the
|
|
24
|
+
* declarative pattern (one PKCE provider with a fixed loopback, one classic
|
|
25
|
+
* web-OAuth provider) before the fan-out to ~40 services in the follow-up
|
|
26
|
+
* (T11938). Adding a service is a single DATA entry; no code change.
|
|
27
|
+
*
|
|
28
|
+
* @module contracts/vault/service-provider
|
|
29
|
+
* @task T11937
|
|
30
|
+
* @epic T11765
|
|
31
|
+
* @saga T10409
|
|
32
|
+
* @see ../llm/oauth.js — `ProviderOAuthConfig` / `OAuthMode` (reused here)
|
|
33
|
+
* @see ../llm/sealed-credential.js — `SealedCredential` (the egress handle a resolved service credential is wrapped in)
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Auth shape a service uses to obtain credentials.
|
|
37
|
+
*
|
|
38
|
+
* - `oauth2` — classic OAuth 2.0 Authorization Code grant (e.g. github web flow).
|
|
39
|
+
* - `oauth2-pkce` — OAuth 2.0 Authorization Code + PKCE (RFC 7636), for CLI /
|
|
40
|
+
* headless flows (e.g. google installed-app flow).
|
|
41
|
+
* - `api-key` — a long-lived API token pasted/imported directly (no OAuth dance).
|
|
42
|
+
*
|
|
43
|
+
* The value drives which fields of {@link ServiceProviderDef.oauth} are required
|
|
44
|
+
* and which OAuth code path (T11939) runs for the service.
|
|
45
|
+
*
|
|
46
|
+
* @task T11937
|
|
47
|
+
*/
|
|
48
|
+
export const SERVICE_AUTH_KINDS = ['oauth2', 'oauth2-pkce', 'api-key'];
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Refresh configuration (T11938 BREADTH · T11939 W2 — driven by this DATA)
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
/**
|
|
53
|
+
* Discriminant naming the refresh GRANT a provider uses (T11938 AC3).
|
|
54
|
+
*
|
|
55
|
+
* The OAuth flow (T11939) branches on this value to pick the refresh code path:
|
|
56
|
+
*
|
|
57
|
+
* - `refresh-token` — the standard OAuth 2.0 `grant_type=refresh_token` exchange
|
|
58
|
+
* (RFC 6749 §6), shaped by {@link RefreshConfig.bodyFormat} /
|
|
59
|
+
* {@link RefreshConfig.clientAuth}. The common case (google, atlassian, …).
|
|
60
|
+
* - `github-app` — a GitHub App installation token: sign an RS256 JWT with the
|
|
61
|
+
* app private key, then POST `/app/installations/{id}/access_tokens`.
|
|
62
|
+
* - `service-account-jwt` — a Google service-account: sign an RS256 JWT and
|
|
63
|
+
* exchange it via `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`.
|
|
64
|
+
* - `client-credentials` — the OAuth 2.0 `grant_type=client_credentials` grant
|
|
65
|
+
* (RFC 6749 §4.4), Basic-auth client id/secret (e.g. MongoDB Atlas SAs).
|
|
66
|
+
*
|
|
67
|
+
* @task T11938
|
|
68
|
+
*/
|
|
69
|
+
export const REFRESH_KINDS = [
|
|
70
|
+
'refresh-token',
|
|
71
|
+
'github-app',
|
|
72
|
+
'service-account-jwt',
|
|
73
|
+
'client-credentials',
|
|
74
|
+
];
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Shared refresh configs (T11938) — frozen DATA reused across provider families.
|
|
77
|
+
// Mirror onecli `apps.rs` statics (GOOGLE_REFRESH, ATLASSIAN_REFRESH, …). These
|
|
78
|
+
// are `const` object literals (no runtime helper) so contracts-purity (Gate 10)
|
|
79
|
+
// stays green.
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/** Shared refresh config for every Google OAuth API (form body, client-id/secret in body). */
|
|
82
|
+
const GOOGLE_REFRESH = {
|
|
83
|
+
kind: 'refresh-token',
|
|
84
|
+
tokenUrl: 'https://oauth2.googleapis.com/token',
|
|
85
|
+
bodyFormat: 'form',
|
|
86
|
+
clientAuth: 'body',
|
|
87
|
+
};
|
|
88
|
+
/** Shared refresh config for the Atlassian OAuth APIs (Jira, Confluence) — JSON body. */
|
|
89
|
+
const ATLASSIAN_REFRESH = {
|
|
90
|
+
kind: 'refresh-token',
|
|
91
|
+
tokenUrl: 'https://auth.atlassian.com/oauth/token',
|
|
92
|
+
bodyFormat: 'json',
|
|
93
|
+
clientAuth: 'body',
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* The full service-provider census — **~40 declarative entries** (T11938 BREADTH).
|
|
97
|
+
*
|
|
98
|
+
* Spread into {@link SERVICE_PROVIDERS} after the github/google seeds. Each entry
|
|
99
|
+
* is PURE DATA cannibalized from onecli `apps.rs::APP_PROVIDERS` (host rules,
|
|
100
|
+
* refresh shape, display name) — no code, no runtime helper. Three special-case
|
|
101
|
+
* refresh GRANTS are declared as {@link RefreshKind} discriminants (T11938 AC3):
|
|
102
|
+
* `github-app` (GitHub App), `client-credentials` (MongoDB Atlas SAs). The OAuth
|
|
103
|
+
* flow (T11939) branches on `refresh.kind` to drive the right grant.
|
|
104
|
+
*
|
|
105
|
+
* Default OAuth `clientId`s are PLACEHOLDER public client ids (BYOC-overridden at
|
|
106
|
+
* flow time from `service_configs`); they are not secrets.
|
|
107
|
+
*
|
|
108
|
+
* @task T11938
|
|
109
|
+
*/
|
|
110
|
+
const SERVICE_PROVIDERS_BREADTH = {
|
|
111
|
+
// ── GitHub App (installation token via signed RS256 JWT — special refresh) ──
|
|
112
|
+
'github-app': {
|
|
113
|
+
provider: 'github-app',
|
|
114
|
+
displayName: 'GitHub App',
|
|
115
|
+
authKind: 'oauth2',
|
|
116
|
+
description: 'GitHub App installation access — short-lived installation tokens.',
|
|
117
|
+
defaultScopes: '',
|
|
118
|
+
refresh: {
|
|
119
|
+
kind: 'github-app',
|
|
120
|
+
tokenUrl: 'https://api.github.com/app/installations',
|
|
121
|
+
},
|
|
122
|
+
hostRules: [
|
|
123
|
+
{ host: 'api.github.com', strategy: 'bearer' },
|
|
124
|
+
{ host: 'github.com', strategy: 'basic-x-access-token' },
|
|
125
|
+
{ host: 'raw.githubusercontent.com', strategy: 'bearer' },
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
// ── Google API family (all share GOOGLE_REFRESH + the google PKCE oauth) ──
|
|
129
|
+
gmail: {
|
|
130
|
+
provider: 'gmail',
|
|
131
|
+
displayName: 'Gmail',
|
|
132
|
+
authKind: 'oauth2-pkce',
|
|
133
|
+
description: 'Read, search, and send mail via the Gmail API.',
|
|
134
|
+
defaultScopes: 'https://www.googleapis.com/auth/gmail.modify',
|
|
135
|
+
oauth: {
|
|
136
|
+
mode: 'pkce',
|
|
137
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
138
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
139
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
140
|
+
scope: 'https://www.googleapis.com/auth/gmail.modify',
|
|
141
|
+
redirectUri: 'http://127.0.0.1:7878/service/gmail/callback',
|
|
142
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
143
|
+
},
|
|
144
|
+
refresh: GOOGLE_REFRESH,
|
|
145
|
+
hostRules: [
|
|
146
|
+
{ host: 'gmail.googleapis.com', strategy: 'bearer' },
|
|
147
|
+
{ host: 'www.googleapis.com', pathPrefix: '/gmail/', strategy: 'bearer' },
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
'google-calendar': {
|
|
151
|
+
provider: 'google-calendar',
|
|
152
|
+
displayName: 'Google Calendar',
|
|
153
|
+
authKind: 'oauth2-pkce',
|
|
154
|
+
description: 'Manage calendars and events via the Google Calendar API.',
|
|
155
|
+
defaultScopes: 'https://www.googleapis.com/auth/calendar',
|
|
156
|
+
oauth: {
|
|
157
|
+
mode: 'pkce',
|
|
158
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
159
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
160
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
161
|
+
scope: 'https://www.googleapis.com/auth/calendar',
|
|
162
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-calendar/callback',
|
|
163
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
164
|
+
},
|
|
165
|
+
refresh: GOOGLE_REFRESH,
|
|
166
|
+
hostRules: [{ host: 'www.googleapis.com', pathPrefix: '/calendar/', strategy: 'bearer' }],
|
|
167
|
+
},
|
|
168
|
+
'google-drive': {
|
|
169
|
+
provider: 'google-drive',
|
|
170
|
+
displayName: 'Google Drive',
|
|
171
|
+
authKind: 'oauth2-pkce',
|
|
172
|
+
description: 'List, read, and write files via the Google Drive API.',
|
|
173
|
+
defaultScopes: 'https://www.googleapis.com/auth/drive',
|
|
174
|
+
oauth: {
|
|
175
|
+
mode: 'pkce',
|
|
176
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
177
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
178
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
179
|
+
scope: 'https://www.googleapis.com/auth/drive',
|
|
180
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-drive/callback',
|
|
181
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
182
|
+
},
|
|
183
|
+
refresh: GOOGLE_REFRESH,
|
|
184
|
+
hostRules: [
|
|
185
|
+
{ host: 'www.googleapis.com', pathPrefix: '/drive/', strategy: 'bearer' },
|
|
186
|
+
{ host: 'www.googleapis.com', pathPrefix: '/upload/drive/', strategy: 'bearer' },
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
'google-docs': {
|
|
190
|
+
provider: 'google-docs',
|
|
191
|
+
displayName: 'Google Docs',
|
|
192
|
+
authKind: 'oauth2-pkce',
|
|
193
|
+
description: 'Read and edit documents via the Google Docs API.',
|
|
194
|
+
defaultScopes: 'https://www.googleapis.com/auth/documents',
|
|
195
|
+
oauth: {
|
|
196
|
+
mode: 'pkce',
|
|
197
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
198
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
199
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
200
|
+
scope: 'https://www.googleapis.com/auth/documents',
|
|
201
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-docs/callback',
|
|
202
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
203
|
+
},
|
|
204
|
+
refresh: GOOGLE_REFRESH,
|
|
205
|
+
hostRules: [{ host: 'docs.googleapis.com', strategy: 'bearer' }],
|
|
206
|
+
},
|
|
207
|
+
'google-sheets': {
|
|
208
|
+
provider: 'google-sheets',
|
|
209
|
+
displayName: 'Google Sheets',
|
|
210
|
+
authKind: 'oauth2-pkce',
|
|
211
|
+
description: 'Read and write spreadsheets via the Google Sheets API.',
|
|
212
|
+
defaultScopes: 'https://www.googleapis.com/auth/spreadsheets',
|
|
213
|
+
oauth: {
|
|
214
|
+
mode: 'pkce',
|
|
215
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
216
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
217
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
218
|
+
scope: 'https://www.googleapis.com/auth/spreadsheets',
|
|
219
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-sheets/callback',
|
|
220
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
221
|
+
},
|
|
222
|
+
refresh: GOOGLE_REFRESH,
|
|
223
|
+
hostRules: [{ host: 'sheets.googleapis.com', strategy: 'bearer' }],
|
|
224
|
+
},
|
|
225
|
+
'google-slides': {
|
|
226
|
+
provider: 'google-slides',
|
|
227
|
+
displayName: 'Google Slides',
|
|
228
|
+
authKind: 'oauth2-pkce',
|
|
229
|
+
description: 'Read and edit presentations via the Google Slides API.',
|
|
230
|
+
defaultScopes: 'https://www.googleapis.com/auth/presentations',
|
|
231
|
+
oauth: {
|
|
232
|
+
mode: 'pkce',
|
|
233
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
234
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
235
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
236
|
+
scope: 'https://www.googleapis.com/auth/presentations',
|
|
237
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-slides/callback',
|
|
238
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
239
|
+
},
|
|
240
|
+
refresh: GOOGLE_REFRESH,
|
|
241
|
+
hostRules: [{ host: 'slides.googleapis.com', strategy: 'bearer' }],
|
|
242
|
+
},
|
|
243
|
+
'google-tasks': {
|
|
244
|
+
provider: 'google-tasks',
|
|
245
|
+
displayName: 'Google Tasks',
|
|
246
|
+
authKind: 'oauth2-pkce',
|
|
247
|
+
description: 'Manage task lists via the Google Tasks API.',
|
|
248
|
+
defaultScopes: 'https://www.googleapis.com/auth/tasks',
|
|
249
|
+
oauth: {
|
|
250
|
+
mode: 'pkce',
|
|
251
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
252
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
253
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
254
|
+
scope: 'https://www.googleapis.com/auth/tasks',
|
|
255
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-tasks/callback',
|
|
256
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
257
|
+
},
|
|
258
|
+
refresh: GOOGLE_REFRESH,
|
|
259
|
+
hostRules: [{ host: 'tasks.googleapis.com', strategy: 'bearer' }],
|
|
260
|
+
},
|
|
261
|
+
'google-forms': {
|
|
262
|
+
provider: 'google-forms',
|
|
263
|
+
displayName: 'Google Forms',
|
|
264
|
+
authKind: 'oauth2-pkce',
|
|
265
|
+
description: 'Read forms and responses via the Google Forms API.',
|
|
266
|
+
defaultScopes: 'https://www.googleapis.com/auth/forms.body',
|
|
267
|
+
oauth: {
|
|
268
|
+
mode: 'pkce',
|
|
269
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
270
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
271
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
272
|
+
scope: 'https://www.googleapis.com/auth/forms.body',
|
|
273
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-forms/callback',
|
|
274
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
275
|
+
},
|
|
276
|
+
refresh: GOOGLE_REFRESH,
|
|
277
|
+
hostRules: [{ host: 'forms.googleapis.com', strategy: 'bearer' }],
|
|
278
|
+
},
|
|
279
|
+
'google-classroom': {
|
|
280
|
+
provider: 'google-classroom',
|
|
281
|
+
displayName: 'Google Classroom',
|
|
282
|
+
authKind: 'oauth2-pkce',
|
|
283
|
+
description: 'Manage courses and coursework via the Google Classroom API.',
|
|
284
|
+
defaultScopes: 'https://www.googleapis.com/auth/classroom.courses',
|
|
285
|
+
oauth: {
|
|
286
|
+
mode: 'pkce',
|
|
287
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
288
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
289
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
290
|
+
scope: 'https://www.googleapis.com/auth/classroom.courses',
|
|
291
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-classroom/callback',
|
|
292
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
293
|
+
},
|
|
294
|
+
refresh: GOOGLE_REFRESH,
|
|
295
|
+
hostRules: [{ host: 'classroom.googleapis.com', strategy: 'bearer' }],
|
|
296
|
+
},
|
|
297
|
+
'google-admin': {
|
|
298
|
+
provider: 'google-admin',
|
|
299
|
+
displayName: 'Google Admin',
|
|
300
|
+
authKind: 'oauth2-pkce',
|
|
301
|
+
description: 'Directory and admin operations via the Google Admin SDK.',
|
|
302
|
+
defaultScopes: 'https://www.googleapis.com/auth/admin.directory.user',
|
|
303
|
+
oauth: {
|
|
304
|
+
mode: 'pkce',
|
|
305
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
306
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
307
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
308
|
+
scope: 'https://www.googleapis.com/auth/admin.directory.user',
|
|
309
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-admin/callback',
|
|
310
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
311
|
+
},
|
|
312
|
+
refresh: GOOGLE_REFRESH,
|
|
313
|
+
hostRules: [{ host: 'admin.googleapis.com', strategy: 'bearer' }],
|
|
314
|
+
},
|
|
315
|
+
'google-analytics': {
|
|
316
|
+
provider: 'google-analytics',
|
|
317
|
+
displayName: 'Google Analytics',
|
|
318
|
+
authKind: 'oauth2-pkce',
|
|
319
|
+
description: 'Query reports via the Google Analytics Data API.',
|
|
320
|
+
defaultScopes: 'https://www.googleapis.com/auth/analytics.readonly',
|
|
321
|
+
oauth: {
|
|
322
|
+
mode: 'pkce',
|
|
323
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
324
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
325
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
326
|
+
scope: 'https://www.googleapis.com/auth/analytics.readonly',
|
|
327
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-analytics/callback',
|
|
328
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
329
|
+
},
|
|
330
|
+
refresh: GOOGLE_REFRESH,
|
|
331
|
+
hostRules: [{ host: 'analyticsdata.googleapis.com', strategy: 'bearer' }],
|
|
332
|
+
},
|
|
333
|
+
'google-search-console': {
|
|
334
|
+
provider: 'google-search-console',
|
|
335
|
+
displayName: 'Google Search Console',
|
|
336
|
+
authKind: 'oauth2-pkce',
|
|
337
|
+
description: 'Query search analytics via the Google Search Console API.',
|
|
338
|
+
defaultScopes: 'https://www.googleapis.com/auth/webmasters.readonly',
|
|
339
|
+
oauth: {
|
|
340
|
+
mode: 'pkce',
|
|
341
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
342
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
343
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
344
|
+
scope: 'https://www.googleapis.com/auth/webmasters.readonly',
|
|
345
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-search-console/callback',
|
|
346
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
347
|
+
},
|
|
348
|
+
refresh: GOOGLE_REFRESH,
|
|
349
|
+
hostRules: [
|
|
350
|
+
{ host: 'searchconsole.googleapis.com', strategy: 'bearer' },
|
|
351
|
+
{ host: 'www.googleapis.com', pathPrefix: '/webmasters/', strategy: 'bearer' },
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
'google-meet': {
|
|
355
|
+
provider: 'google-meet',
|
|
356
|
+
displayName: 'Google Meet',
|
|
357
|
+
authKind: 'oauth2-pkce',
|
|
358
|
+
description: 'Manage meeting spaces and conference records via the Google Meet API.',
|
|
359
|
+
defaultScopes: 'https://www.googleapis.com/auth/meetings.space.created',
|
|
360
|
+
oauth: {
|
|
361
|
+
mode: 'pkce',
|
|
362
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
363
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
364
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
365
|
+
scope: 'https://www.googleapis.com/auth/meetings.space.created',
|
|
366
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-meet/callback',
|
|
367
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
368
|
+
},
|
|
369
|
+
refresh: GOOGLE_REFRESH,
|
|
370
|
+
hostRules: [{ host: 'meet.googleapis.com', strategy: 'bearer' }],
|
|
371
|
+
},
|
|
372
|
+
'google-photos': {
|
|
373
|
+
provider: 'google-photos',
|
|
374
|
+
displayName: 'Google Photos',
|
|
375
|
+
authKind: 'oauth2-pkce',
|
|
376
|
+
description: 'Read media items and albums via the Google Photos Library API.',
|
|
377
|
+
defaultScopes: 'https://www.googleapis.com/auth/photoslibrary.readonly',
|
|
378
|
+
oauth: {
|
|
379
|
+
mode: 'pkce',
|
|
380
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
381
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
382
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
383
|
+
scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
|
|
384
|
+
redirectUri: 'http://127.0.0.1:7878/service/google-photos/callback',
|
|
385
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
386
|
+
},
|
|
387
|
+
refresh: GOOGLE_REFRESH,
|
|
388
|
+
hostRules: [{ host: 'photoslibrary.googleapis.com', strategy: 'bearer' }],
|
|
389
|
+
},
|
|
390
|
+
youtube: {
|
|
391
|
+
provider: 'youtube',
|
|
392
|
+
displayName: 'YouTube',
|
|
393
|
+
authKind: 'oauth2-pkce',
|
|
394
|
+
description: 'Manage channels, videos, and playlists via the YouTube Data API.',
|
|
395
|
+
defaultScopes: 'https://www.googleapis.com/auth/youtube',
|
|
396
|
+
oauth: {
|
|
397
|
+
mode: 'pkce',
|
|
398
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
399
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
400
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
401
|
+
scope: 'https://www.googleapis.com/auth/youtube',
|
|
402
|
+
redirectUri: 'http://127.0.0.1:7878/service/youtube/callback',
|
|
403
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
404
|
+
},
|
|
405
|
+
refresh: GOOGLE_REFRESH,
|
|
406
|
+
hostRules: [{ host: 'www.googleapis.com', pathPrefix: '/youtube/', strategy: 'bearer' }],
|
|
407
|
+
},
|
|
408
|
+
'vertex-ai': {
|
|
409
|
+
provider: 'vertex-ai',
|
|
410
|
+
displayName: 'Vertex AI',
|
|
411
|
+
authKind: 'oauth2-pkce',
|
|
412
|
+
description: 'Call Google Cloud Vertex AI model endpoints.',
|
|
413
|
+
defaultScopes: 'https://www.googleapis.com/auth/cloud-platform',
|
|
414
|
+
oauth: {
|
|
415
|
+
mode: 'pkce',
|
|
416
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
417
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
418
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
419
|
+
scope: 'https://www.googleapis.com/auth/cloud-platform',
|
|
420
|
+
redirectUri: 'http://127.0.0.1:7878/service/vertex-ai/callback',
|
|
421
|
+
extraAuthParams: { access_type: 'offline', prompt: 'consent' },
|
|
422
|
+
},
|
|
423
|
+
refresh: GOOGLE_REFRESH,
|
|
424
|
+
hostRules: [
|
|
425
|
+
{ host: 'aiplatform.googleapis.com', strategy: 'bearer' },
|
|
426
|
+
{ host: 'oauth2.googleapis.com', strategy: 'bearer' },
|
|
427
|
+
],
|
|
428
|
+
metadataHeaders: [{ metadataKey: 'projectId', headerName: 'x-goog-user-project' }],
|
|
429
|
+
},
|
|
430
|
+
// ── Atlassian family (JSON refresh body) ──
|
|
431
|
+
jira: {
|
|
432
|
+
provider: 'jira',
|
|
433
|
+
displayName: 'Jira',
|
|
434
|
+
authKind: 'oauth2',
|
|
435
|
+
description: 'Issues, projects, and workflows via the Jira Cloud REST API.',
|
|
436
|
+
defaultScopes: 'read:jira-work write:jira-work offline_access',
|
|
437
|
+
oauth: {
|
|
438
|
+
mode: 'pkce',
|
|
439
|
+
clientId: 'cleo-atlassian-client-id',
|
|
440
|
+
authorizationEndpoint: 'https://auth.atlassian.com/authorize',
|
|
441
|
+
tokenEndpoint: 'https://auth.atlassian.com/oauth/token',
|
|
442
|
+
scope: 'read:jira-work write:jira-work offline_access',
|
|
443
|
+
redirectUri: 'http://127.0.0.1:7878/service/jira/callback',
|
|
444
|
+
extraAuthParams: { audience: 'api.atlassian.com', prompt: 'consent' },
|
|
445
|
+
},
|
|
446
|
+
refresh: ATLASSIAN_REFRESH,
|
|
447
|
+
hostRules: [{ host: 'api.atlassian.com', strategy: 'bearer' }],
|
|
448
|
+
},
|
|
449
|
+
confluence: {
|
|
450
|
+
provider: 'confluence',
|
|
451
|
+
displayName: 'Confluence',
|
|
452
|
+
authKind: 'oauth2',
|
|
453
|
+
description: 'Spaces, pages, and content via the Confluence Cloud REST API.',
|
|
454
|
+
defaultScopes: 'read:confluence-content.all write:confluence-content offline_access',
|
|
455
|
+
oauth: {
|
|
456
|
+
mode: 'pkce',
|
|
457
|
+
clientId: 'cleo-atlassian-client-id',
|
|
458
|
+
authorizationEndpoint: 'https://auth.atlassian.com/authorize',
|
|
459
|
+
tokenEndpoint: 'https://auth.atlassian.com/oauth/token',
|
|
460
|
+
scope: 'read:confluence-content.all write:confluence-content offline_access',
|
|
461
|
+
redirectUri: 'http://127.0.0.1:7878/service/confluence/callback',
|
|
462
|
+
extraAuthParams: { audience: 'api.atlassian.com', prompt: 'consent' },
|
|
463
|
+
},
|
|
464
|
+
refresh: ATLASSIAN_REFRESH,
|
|
465
|
+
hostRules: [{ host: 'api.atlassian.com', strategy: 'bearer' }],
|
|
466
|
+
},
|
|
467
|
+
// ── Notion (JSON body + Basic-auth client credentials) ──
|
|
468
|
+
notion: {
|
|
469
|
+
provider: 'notion',
|
|
470
|
+
displayName: 'Notion',
|
|
471
|
+
authKind: 'oauth2',
|
|
472
|
+
description: 'Databases, pages, and blocks via the Notion API.',
|
|
473
|
+
defaultScopes: '',
|
|
474
|
+
oauth: {
|
|
475
|
+
mode: 'pkce',
|
|
476
|
+
clientId: 'cleo-notion-client-id',
|
|
477
|
+
authorizationEndpoint: 'https://api.notion.com/v1/oauth/authorize',
|
|
478
|
+
tokenEndpoint: 'https://api.notion.com/v1/oauth/token',
|
|
479
|
+
scope: '',
|
|
480
|
+
redirectUri: 'http://127.0.0.1:7878/service/notion/callback',
|
|
481
|
+
extraAuthParams: { owner: 'user' },
|
|
482
|
+
},
|
|
483
|
+
refresh: {
|
|
484
|
+
kind: 'refresh-token',
|
|
485
|
+
tokenUrl: 'https://api.notion.com/v1/oauth/token',
|
|
486
|
+
bodyFormat: 'json',
|
|
487
|
+
clientAuth: 'basic-auth',
|
|
488
|
+
},
|
|
489
|
+
hostRules: [{ host: 'api.notion.com', strategy: 'bearer' }],
|
|
490
|
+
},
|
|
491
|
+
// ── Dropbox (form body) ──
|
|
492
|
+
dropbox: {
|
|
493
|
+
provider: 'dropbox',
|
|
494
|
+
displayName: 'Dropbox',
|
|
495
|
+
authKind: 'oauth2',
|
|
496
|
+
description: 'Files, folders, and sharing via the Dropbox API.',
|
|
497
|
+
defaultScopes: 'files.content.read files.content.write account_info.read',
|
|
498
|
+
oauth: {
|
|
499
|
+
mode: 'pkce',
|
|
500
|
+
clientId: 'cleo-dropbox-client-id',
|
|
501
|
+
authorizationEndpoint: 'https://www.dropbox.com/oauth2/authorize',
|
|
502
|
+
tokenEndpoint: 'https://api.dropboxapi.com/oauth2/token',
|
|
503
|
+
scope: 'files.content.read files.content.write account_info.read',
|
|
504
|
+
redirectUri: 'http://127.0.0.1:7878/service/dropbox/callback',
|
|
505
|
+
extraAuthParams: { token_access_type: 'offline' },
|
|
506
|
+
},
|
|
507
|
+
refresh: {
|
|
508
|
+
kind: 'refresh-token',
|
|
509
|
+
tokenUrl: 'https://api.dropboxapi.com/oauth2/token',
|
|
510
|
+
bodyFormat: 'form',
|
|
511
|
+
clientAuth: 'body',
|
|
512
|
+
},
|
|
513
|
+
hostRules: [
|
|
514
|
+
{ host: 'api.dropboxapi.com', strategy: 'bearer' },
|
|
515
|
+
{ host: 'content.dropboxapi.com', strategy: 'bearer' },
|
|
516
|
+
],
|
|
517
|
+
},
|
|
518
|
+
// ── LinkedIn (form body) ──
|
|
519
|
+
linkedin: {
|
|
520
|
+
provider: 'linkedin',
|
|
521
|
+
displayName: 'LinkedIn',
|
|
522
|
+
authKind: 'oauth2',
|
|
523
|
+
description: 'Profile, posts, and shares via the LinkedIn API.',
|
|
524
|
+
defaultScopes: 'r_liteprofile r_emailaddress w_member_social',
|
|
525
|
+
oauth: {
|
|
526
|
+
mode: 'pkce',
|
|
527
|
+
clientId: 'cleo-linkedin-client-id',
|
|
528
|
+
authorizationEndpoint: 'https://www.linkedin.com/oauth/v2/authorization',
|
|
529
|
+
tokenEndpoint: 'https://www.linkedin.com/oauth/v2/accessToken',
|
|
530
|
+
scope: 'r_liteprofile r_emailaddress w_member_social',
|
|
531
|
+
redirectUri: 'http://127.0.0.1:7878/service/linkedin/callback',
|
|
532
|
+
},
|
|
533
|
+
refresh: {
|
|
534
|
+
kind: 'refresh-token',
|
|
535
|
+
tokenUrl: 'https://www.linkedin.com/oauth/v2/accessToken',
|
|
536
|
+
bodyFormat: 'form',
|
|
537
|
+
clientAuth: 'body',
|
|
538
|
+
},
|
|
539
|
+
hostRules: [{ host: 'api.linkedin.com', strategy: 'bearer' }],
|
|
540
|
+
},
|
|
541
|
+
// ── Todoist (form body) ──
|
|
542
|
+
todoist: {
|
|
543
|
+
provider: 'todoist',
|
|
544
|
+
displayName: 'Todoist',
|
|
545
|
+
authKind: 'oauth2',
|
|
546
|
+
description: 'Tasks, projects, and labels via the Todoist REST API.',
|
|
547
|
+
defaultScopes: 'data:read_write',
|
|
548
|
+
oauth: {
|
|
549
|
+
mode: 'pkce',
|
|
550
|
+
clientId: 'cleo-todoist-client-id',
|
|
551
|
+
authorizationEndpoint: 'https://todoist.com/oauth/authorize',
|
|
552
|
+
tokenEndpoint: 'https://api.todoist.com/oauth/access_token',
|
|
553
|
+
scope: 'data:read_write',
|
|
554
|
+
redirectUri: 'http://127.0.0.1:7878/service/todoist/callback',
|
|
555
|
+
},
|
|
556
|
+
refresh: {
|
|
557
|
+
kind: 'refresh-token',
|
|
558
|
+
tokenUrl: 'https://api.todoist.com/oauth/access_token',
|
|
559
|
+
bodyFormat: 'form',
|
|
560
|
+
clientAuth: 'body',
|
|
561
|
+
},
|
|
562
|
+
hostRules: [{ host: 'api.todoist.com', strategy: 'bearer' }],
|
|
563
|
+
},
|
|
564
|
+
// ── Supabase Management API (form body + Basic-auth client credentials) ──
|
|
565
|
+
supabase: {
|
|
566
|
+
provider: 'supabase',
|
|
567
|
+
displayName: 'Supabase',
|
|
568
|
+
authKind: 'oauth2',
|
|
569
|
+
description: 'Projects and configuration via the Supabase Management API.',
|
|
570
|
+
defaultScopes: 'all',
|
|
571
|
+
oauth: {
|
|
572
|
+
mode: 'pkce',
|
|
573
|
+
clientId: 'cleo-supabase-client-id',
|
|
574
|
+
authorizationEndpoint: 'https://api.supabase.com/v1/oauth/authorize',
|
|
575
|
+
tokenEndpoint: 'https://api.supabase.com/v1/oauth/token',
|
|
576
|
+
scope: 'all',
|
|
577
|
+
redirectUri: 'http://127.0.0.1:7878/service/supabase/callback',
|
|
578
|
+
},
|
|
579
|
+
refresh: {
|
|
580
|
+
kind: 'refresh-token',
|
|
581
|
+
tokenUrl: 'https://api.supabase.com/v1/oauth/token',
|
|
582
|
+
bodyFormat: 'form',
|
|
583
|
+
clientAuth: 'basic-auth',
|
|
584
|
+
},
|
|
585
|
+
hostRules: [{ host: 'api.supabase.com', strategy: 'bearer' }],
|
|
586
|
+
},
|
|
587
|
+
// ── MongoDB Atlas (client_credentials grant — special refresh) ──
|
|
588
|
+
'mongodb-atlas': {
|
|
589
|
+
provider: 'mongodb-atlas',
|
|
590
|
+
displayName: 'MongoDB Atlas',
|
|
591
|
+
authKind: 'oauth2',
|
|
592
|
+
description: 'Clusters and projects via the MongoDB Atlas Administration API.',
|
|
593
|
+
defaultScopes: '',
|
|
594
|
+
refresh: {
|
|
595
|
+
kind: 'client-credentials',
|
|
596
|
+
tokenUrl: 'https://cloud.mongodb.com/api/oauth/token',
|
|
597
|
+
},
|
|
598
|
+
hostRules: [{ host: 'cloud.mongodb.com', strategy: 'bearer' }],
|
|
599
|
+
},
|
|
600
|
+
// ── monday.com (api-key — no OAuth refresh) ──
|
|
601
|
+
monday: {
|
|
602
|
+
provider: 'monday',
|
|
603
|
+
displayName: 'monday.com',
|
|
604
|
+
authKind: 'oauth2',
|
|
605
|
+
description: 'Boards, items, and updates via the monday.com GraphQL API.',
|
|
606
|
+
defaultScopes: 'me:read boards:read boards:write',
|
|
607
|
+
oauth: {
|
|
608
|
+
mode: 'pkce',
|
|
609
|
+
clientId: 'cleo-monday-client-id',
|
|
610
|
+
authorizationEndpoint: 'https://auth.monday.com/oauth2/authorize',
|
|
611
|
+
tokenEndpoint: 'https://auth.monday.com/oauth2/token',
|
|
612
|
+
scope: 'me:read boards:read boards:write',
|
|
613
|
+
redirectUri: 'http://127.0.0.1:7878/service/monday/callback',
|
|
614
|
+
},
|
|
615
|
+
hostRules: [{ host: 'api.monday.com', strategy: 'bearer' }],
|
|
616
|
+
},
|
|
617
|
+
// ── Resend (api-key) ──
|
|
618
|
+
resend: {
|
|
619
|
+
provider: 'resend',
|
|
620
|
+
displayName: 'Resend',
|
|
621
|
+
authKind: 'api-key',
|
|
622
|
+
description: 'Send transactional email via the Resend API (API-key auth).',
|
|
623
|
+
defaultScopes: 'full_access',
|
|
624
|
+
hostRules: [{ host: 'api.resend.com', strategy: 'bearer' }],
|
|
625
|
+
},
|
|
626
|
+
// ── Cloudflare (api-key) ──
|
|
627
|
+
cloudflare: {
|
|
628
|
+
provider: 'cloudflare',
|
|
629
|
+
displayName: 'Cloudflare',
|
|
630
|
+
authKind: 'api-key',
|
|
631
|
+
description: 'Zones, DNS, and Workers via the Cloudflare API (API-token auth).',
|
|
632
|
+
defaultScopes: '',
|
|
633
|
+
hostRules: [{ host: 'api.cloudflare.com', strategy: 'bearer' }],
|
|
634
|
+
},
|
|
635
|
+
// ── Fly.io (api-key) ──
|
|
636
|
+
flyio: {
|
|
637
|
+
provider: 'flyio',
|
|
638
|
+
displayName: 'Fly.io',
|
|
639
|
+
authKind: 'api-key',
|
|
640
|
+
description: 'Machines and apps via the Fly.io Machines API (API-token auth).',
|
|
641
|
+
defaultScopes: '',
|
|
642
|
+
hostRules: [
|
|
643
|
+
{ host: 'api.machines.dev', strategy: 'bearer' },
|
|
644
|
+
{ host: 'api.fly.io', strategy: 'bearer' },
|
|
645
|
+
],
|
|
646
|
+
},
|
|
647
|
+
// ── AWS (api-key/SigV4 — credential headers; no token refresh) ──
|
|
648
|
+
aws: {
|
|
649
|
+
provider: 'aws',
|
|
650
|
+
displayName: 'AWS',
|
|
651
|
+
authKind: 'api-key',
|
|
652
|
+
description: 'AWS service APIs signed with SigV4 (access-key credentials).',
|
|
653
|
+
defaultScopes: '',
|
|
654
|
+
hostRules: [{ host: 'amazonaws.com', strategy: 'header' }],
|
|
655
|
+
credentialHeaders: [{ credentialField: 'accessKeyId', headerName: 'x-amz-access-key-id' }],
|
|
656
|
+
},
|
|
657
|
+
// ── Figma (form body refresh) ──
|
|
658
|
+
figma: {
|
|
659
|
+
provider: 'figma',
|
|
660
|
+
displayName: 'Figma',
|
|
661
|
+
authKind: 'oauth2',
|
|
662
|
+
description: 'Files, projects, and comments via the Figma REST API.',
|
|
663
|
+
defaultScopes: 'file_read',
|
|
664
|
+
oauth: {
|
|
665
|
+
mode: 'pkce',
|
|
666
|
+
clientId: 'cleo-figma-client-id',
|
|
667
|
+
authorizationEndpoint: 'https://www.figma.com/oauth',
|
|
668
|
+
tokenEndpoint: 'https://api.figma.com/v1/oauth/token',
|
|
669
|
+
scope: 'file_read',
|
|
670
|
+
redirectUri: 'http://127.0.0.1:7878/service/figma/callback',
|
|
671
|
+
},
|
|
672
|
+
refresh: {
|
|
673
|
+
kind: 'refresh-token',
|
|
674
|
+
tokenUrl: 'https://api.figma.com/v1/oauth/refresh',
|
|
675
|
+
bodyFormat: 'form',
|
|
676
|
+
clientAuth: 'body',
|
|
677
|
+
},
|
|
678
|
+
hostRules: [{ host: 'api.figma.com', strategy: 'bearer' }],
|
|
679
|
+
},
|
|
680
|
+
// ── Linear (form body refresh) ──
|
|
681
|
+
linear: {
|
|
682
|
+
provider: 'linear',
|
|
683
|
+
displayName: 'Linear',
|
|
684
|
+
authKind: 'oauth2',
|
|
685
|
+
description: 'Issues, projects, and cycles via the Linear GraphQL API.',
|
|
686
|
+
defaultScopes: 'read write',
|
|
687
|
+
oauth: {
|
|
688
|
+
mode: 'pkce',
|
|
689
|
+
clientId: 'cleo-linear-client-id',
|
|
690
|
+
authorizationEndpoint: 'https://linear.app/oauth/authorize',
|
|
691
|
+
tokenEndpoint: 'https://api.linear.app/oauth/token',
|
|
692
|
+
scope: 'read write',
|
|
693
|
+
redirectUri: 'http://127.0.0.1:7878/service/linear/callback',
|
|
694
|
+
},
|
|
695
|
+
refresh: {
|
|
696
|
+
kind: 'refresh-token',
|
|
697
|
+
tokenUrl: 'https://api.linear.app/oauth/token',
|
|
698
|
+
bodyFormat: 'form',
|
|
699
|
+
clientAuth: 'body',
|
|
700
|
+
},
|
|
701
|
+
hostRules: [{ host: 'api.linear.app', strategy: 'bearer' }],
|
|
702
|
+
},
|
|
703
|
+
// ── Slack (form body refresh; token rotation) ──
|
|
704
|
+
slack: {
|
|
705
|
+
provider: 'slack',
|
|
706
|
+
displayName: 'Slack',
|
|
707
|
+
authKind: 'oauth2',
|
|
708
|
+
description: 'Channels, messages, and users via the Slack Web API.',
|
|
709
|
+
defaultScopes: 'channels:read chat:write users:read',
|
|
710
|
+
oauth: {
|
|
711
|
+
mode: 'pkce',
|
|
712
|
+
clientId: 'cleo-slack-client-id',
|
|
713
|
+
authorizationEndpoint: 'https://slack.com/oauth/v2/authorize',
|
|
714
|
+
tokenEndpoint: 'https://slack.com/api/oauth.v2.access',
|
|
715
|
+
scope: 'channels:read chat:write users:read',
|
|
716
|
+
redirectUri: 'http://127.0.0.1:7878/service/slack/callback',
|
|
717
|
+
},
|
|
718
|
+
refresh: {
|
|
719
|
+
kind: 'refresh-token',
|
|
720
|
+
tokenUrl: 'https://slack.com/api/oauth.v2.access',
|
|
721
|
+
bodyFormat: 'form',
|
|
722
|
+
clientAuth: 'body',
|
|
723
|
+
},
|
|
724
|
+
hostRules: [{ host: 'slack.com', strategy: 'bearer' }],
|
|
725
|
+
},
|
|
726
|
+
// ── Discord (form body refresh) ──
|
|
727
|
+
discord: {
|
|
728
|
+
provider: 'discord',
|
|
729
|
+
displayName: 'Discord',
|
|
730
|
+
authKind: 'oauth2',
|
|
731
|
+
description: 'Guilds, channels, and messages via the Discord API.',
|
|
732
|
+
defaultScopes: 'identify guilds',
|
|
733
|
+
oauth: {
|
|
734
|
+
mode: 'pkce',
|
|
735
|
+
clientId: 'cleo-discord-client-id',
|
|
736
|
+
authorizationEndpoint: 'https://discord.com/oauth2/authorize',
|
|
737
|
+
tokenEndpoint: 'https://discord.com/api/oauth2/token',
|
|
738
|
+
scope: 'identify guilds',
|
|
739
|
+
redirectUri: 'http://127.0.0.1:7878/service/discord/callback',
|
|
740
|
+
},
|
|
741
|
+
refresh: {
|
|
742
|
+
kind: 'refresh-token',
|
|
743
|
+
tokenUrl: 'https://discord.com/api/oauth2/token',
|
|
744
|
+
bodyFormat: 'form',
|
|
745
|
+
clientAuth: 'body',
|
|
746
|
+
},
|
|
747
|
+
hostRules: [{ host: 'discord.com', strategy: 'bearer' }],
|
|
748
|
+
},
|
|
749
|
+
// ── Sentry (form body refresh) ──
|
|
750
|
+
sentry: {
|
|
751
|
+
provider: 'sentry',
|
|
752
|
+
displayName: 'Sentry',
|
|
753
|
+
authKind: 'oauth2',
|
|
754
|
+
description: 'Issues, events, and releases via the Sentry API.',
|
|
755
|
+
defaultScopes: 'org:read project:read event:read',
|
|
756
|
+
oauth: {
|
|
757
|
+
mode: 'pkce',
|
|
758
|
+
clientId: 'cleo-sentry-client-id',
|
|
759
|
+
authorizationEndpoint: 'https://sentry.io/oauth/authorize/',
|
|
760
|
+
tokenEndpoint: 'https://sentry.io/oauth/token/',
|
|
761
|
+
scope: 'org:read project:read event:read',
|
|
762
|
+
redirectUri: 'http://127.0.0.1:7878/service/sentry/callback',
|
|
763
|
+
},
|
|
764
|
+
refresh: {
|
|
765
|
+
kind: 'refresh-token',
|
|
766
|
+
tokenUrl: 'https://sentry.io/oauth/token/',
|
|
767
|
+
bodyFormat: 'form',
|
|
768
|
+
clientAuth: 'body',
|
|
769
|
+
},
|
|
770
|
+
hostRules: [{ host: 'sentry.io', strategy: 'bearer' }],
|
|
771
|
+
},
|
|
772
|
+
// ── Vercel (api-key — no OAuth refresh) ──
|
|
773
|
+
vercel: {
|
|
774
|
+
provider: 'vercel',
|
|
775
|
+
displayName: 'Vercel',
|
|
776
|
+
authKind: 'api-key',
|
|
777
|
+
description: 'Deployments, projects, and domains via the Vercel REST API.',
|
|
778
|
+
defaultScopes: '',
|
|
779
|
+
hostRules: [{ host: 'api.vercel.com', strategy: 'bearer' }],
|
|
780
|
+
},
|
|
781
|
+
};
|
|
782
|
+
/**
|
|
783
|
+
* The seeded service-provider registry — **github + google + the ~40-service
|
|
784
|
+
* census** (T11937 seeds + T11938 breadth).
|
|
785
|
+
*
|
|
786
|
+
* Keyed by {@link ServiceProviderDef.provider}. This is the SSoT the store reads
|
|
787
|
+
* when validating a `connect` and the OAuth flow (T11939) reads for default
|
|
788
|
+
* endpoints/scopes. The two seeds prove the two OAuth shapes:
|
|
789
|
+
*
|
|
790
|
+
* - **github** — classic OAuth 2.0 web flow (`authKind: 'oauth2'`), fixed
|
|
791
|
+
* loopback redirect; user grants `repo`/`read:user` scopes.
|
|
792
|
+
* - **google** — installed-app OAuth 2.0 + PKCE (`authKind: 'oauth2-pkce'`),
|
|
793
|
+
* loopback redirect; user grants offline-access + the requested API scopes.
|
|
794
|
+
*
|
|
795
|
+
* The `clientId` values are PLACEHOLDER public client ids for CLEO's first-party
|
|
796
|
+
* OAuth apps — the real ids are wired (or BYOC-overridden) when the OAuth dance
|
|
797
|
+
* lands in T11939. They are NOT secrets (a public OAuth client id is, by design,
|
|
798
|
+
* embeddable in a distributed CLI).
|
|
799
|
+
*
|
|
800
|
+
* Fan-out to the full ~40-service census is the follow-up (T11938): add a DATA
|
|
801
|
+
* entry here, nothing else.
|
|
802
|
+
*
|
|
803
|
+
* @task T11937
|
|
804
|
+
*/
|
|
805
|
+
export const SERVICE_PROVIDERS = {
|
|
806
|
+
github: {
|
|
807
|
+
provider: 'github',
|
|
808
|
+
displayName: 'GitHub',
|
|
809
|
+
authKind: 'oauth2',
|
|
810
|
+
description: 'Repositories, issues, pull requests, and Actions on GitHub.',
|
|
811
|
+
defaultScopes: 'repo read:user read:org',
|
|
812
|
+
oauth: {
|
|
813
|
+
mode: 'pkce',
|
|
814
|
+
// PLACEHOLDER public client id for CLEO's first-party GitHub OAuth app —
|
|
815
|
+
// real id (or a BYOC override from service_configs) wired in T11939.
|
|
816
|
+
clientId: 'cleo-github-client-id',
|
|
817
|
+
authorizationEndpoint: 'https://github.com/login/oauth/authorize',
|
|
818
|
+
tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
|
819
|
+
scope: 'repo read:user read:org',
|
|
820
|
+
redirectUri: 'http://127.0.0.1:7878/service/github/callback',
|
|
821
|
+
},
|
|
822
|
+
hostRules: [
|
|
823
|
+
{ host: 'api.github.com', strategy: 'bearer' },
|
|
824
|
+
{ host: 'github.com', strategy: 'basic-x-access-token' },
|
|
825
|
+
{ host: 'raw.githubusercontent.com', strategy: 'bearer' },
|
|
826
|
+
],
|
|
827
|
+
},
|
|
828
|
+
google: {
|
|
829
|
+
provider: 'google',
|
|
830
|
+
displayName: 'Google',
|
|
831
|
+
authKind: 'oauth2-pkce',
|
|
832
|
+
description: 'Gmail, Drive, Calendar, and other Google APIs.',
|
|
833
|
+
defaultScopes: 'openid email profile https://www.googleapis.com/auth/drive.readonly',
|
|
834
|
+
oauth: {
|
|
835
|
+
mode: 'pkce',
|
|
836
|
+
// PLACEHOLDER public client id for CLEO's first-party Google installed-app
|
|
837
|
+
// OAuth client — real id (or a BYOC override) wired in T11939.
|
|
838
|
+
clientId: 'cleo-google-client-id.apps.googleusercontent.com',
|
|
839
|
+
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
840
|
+
tokenEndpoint: 'https://oauth2.googleapis.com/token',
|
|
841
|
+
scope: 'openid email profile https://www.googleapis.com/auth/drive.readonly',
|
|
842
|
+
redirectUri: 'http://127.0.0.1:7878/service/google/callback',
|
|
843
|
+
extraAuthParams: {
|
|
844
|
+
// Google requires these to return a refresh token on the first consent.
|
|
845
|
+
access_type: 'offline',
|
|
846
|
+
prompt: 'consent',
|
|
847
|
+
},
|
|
848
|
+
},
|
|
849
|
+
refresh: GOOGLE_REFRESH,
|
|
850
|
+
hostRules: [
|
|
851
|
+
{ host: 'www.googleapis.com', strategy: 'bearer' },
|
|
852
|
+
{ host: 'accounts.google.com', strategy: 'bearer' },
|
|
853
|
+
],
|
|
854
|
+
},
|
|
855
|
+
...SERVICE_PROVIDERS_BREADTH,
|
|
856
|
+
};
|
|
857
|
+
//# sourceMappingURL=service-provider.js.map
|