@thinkai/tai-api-contract 2.2.8 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/openapi.d.ts +331 -5
- package/dist/generated/openapi.d.ts.map +1 -1
- package/openapi/openapi.yaml +312 -6
- package/package.json +1 -1
- package/src/generated/openapi.ts +331 -5
package/src/generated/openapi.ts
CHANGED
|
@@ -159,7 +159,7 @@ export interface paths {
|
|
|
159
159
|
get?: never;
|
|
160
160
|
/**
|
|
161
161
|
* Replace workspace data sources
|
|
162
|
-
* @description Replace the workspace's `sources` array. Cursor entries are validated strictly (`token` 1-256 chars, no whitespace, no `env:` prefix; optional
|
|
162
|
+
* @description Replace the workspace's `sources` array. Cursor entries are validated strictly (`token` 1-256 chars, no whitespace, no `env:` prefix; optional deprecated `baseUrl` is accepted for backwards compatibility and ignored at runtime; verification and future refresh use the fixed Cursor Admin API host. Other types pass through with only a non-empty `type` requirement so existing github / jira / sonarqube / bitbucket callers are not regressed.
|
|
163
163
|
* Every secret-keyed top-level string field (`token`, `password`, `api_key`, `secret`, `private_key`, `client_secret`) is encrypted at rest with AES-256-GCM under `SOURCES_TOKEN_ENC_KEY` before persistence; `env:`-prefixed values pass through unchanged. `GET /workspaces/{workspaceId}/config` continues to redact every secret-keyed field to `***` regardless of whether the stored value is encrypted, plaintext, or `env:` ref.
|
|
164
164
|
* Requires editor or admin workspace role.
|
|
165
165
|
* **Typical outcomes:** Valid typed sources → `200` with `{ ok: true, workspaceId }`. Missing required fields for a given `type` (e.g. GitHub without `repo` or `token`) → `400` with `error` text. Unknown `type` strings (non-cursor) currently pass through to storage (lenient compatibility); only `cursor` entries get strict field validation. Cursor sources enforce strict token shape (no whitespace, no `env:` prefix).
|
|
@@ -184,7 +184,7 @@ export interface paths {
|
|
|
184
184
|
/**
|
|
185
185
|
* Test one source connection (does not persist)
|
|
186
186
|
* @description Verify a source's credentials without persisting them. Always returns 200 — upstream auth, rate-limit, and network failures surface as `{ success: false, error }` so the SPA can render an inline error.
|
|
187
|
-
* Currently only `type: cursor` is verified end-to-end (
|
|
187
|
+
* Currently only `type: cursor` is verified end-to-end (Cursor Admin API, HTTP Basic against `https://api.cursor.com`; optional `baseUrl` in the body is deprecated and ignored). Other types report `{ success: false, error: "unsupported_type" }`. Documented `error` codes for cursor: `invalid_token`, `rate_limited`, `network_error`.
|
|
188
188
|
* **Typical outcomes:** Malformed body, missing `type`, invalid `type`, or missing required fields for the declared type → `400` with `{ error: "..." }`. Well-formed body with bad credentials or unreachable service → `200` with `{ success: false, error: "..." }` (Cursor verifier and non-cursor paths as documented above).
|
|
189
189
|
*/
|
|
190
190
|
post: operations["postTenantSourceTest"];
|
|
@@ -293,6 +293,94 @@ export interface paths {
|
|
|
293
293
|
patch?: never;
|
|
294
294
|
trace?: never;
|
|
295
295
|
};
|
|
296
|
+
"/workspaces/{workspaceId}/integrations/ai-tool/{provider}/refresh": {
|
|
297
|
+
parameters: {
|
|
298
|
+
query?: never;
|
|
299
|
+
header?: never;
|
|
300
|
+
path?: never;
|
|
301
|
+
cookie?: never;
|
|
302
|
+
};
|
|
303
|
+
get?: never;
|
|
304
|
+
put?: never;
|
|
305
|
+
/**
|
|
306
|
+
* Refresh AI tool integration snapshots
|
|
307
|
+
* @description Provider-agnostic refresh. Returns 409 when an advisory-lock refresh is already in progress. On upstream auth/rate/network failures, returns `200` with `{ ok:false, error }` so the SPA can render inline error.
|
|
308
|
+
*/
|
|
309
|
+
post: operations["refreshWorkspaceAiTool"];
|
|
310
|
+
delete?: never;
|
|
311
|
+
options?: never;
|
|
312
|
+
head?: never;
|
|
313
|
+
patch?: never;
|
|
314
|
+
trace?: never;
|
|
315
|
+
};
|
|
316
|
+
"/workspaces/{workspaceId}/integrations/ai-tool/{provider}/seats": {
|
|
317
|
+
parameters: {
|
|
318
|
+
query?: never;
|
|
319
|
+
header?: never;
|
|
320
|
+
path?: never;
|
|
321
|
+
cookie?: never;
|
|
322
|
+
};
|
|
323
|
+
/** List latest AI-tool seats */
|
|
324
|
+
get: operations["getWorkspaceAiToolSeats"];
|
|
325
|
+
put?: never;
|
|
326
|
+
post?: never;
|
|
327
|
+
delete?: never;
|
|
328
|
+
options?: never;
|
|
329
|
+
head?: never;
|
|
330
|
+
patch?: never;
|
|
331
|
+
trace?: never;
|
|
332
|
+
};
|
|
333
|
+
"/workspaces/{workspaceId}/integrations/ai-tool/{provider}/daily-usage": {
|
|
334
|
+
parameters: {
|
|
335
|
+
query?: never;
|
|
336
|
+
header?: never;
|
|
337
|
+
path?: never;
|
|
338
|
+
cookie?: never;
|
|
339
|
+
};
|
|
340
|
+
/** List AI-tool daily usage */
|
|
341
|
+
get: operations["getWorkspaceAiToolDailyUsage"];
|
|
342
|
+
put?: never;
|
|
343
|
+
post?: never;
|
|
344
|
+
delete?: never;
|
|
345
|
+
options?: never;
|
|
346
|
+
head?: never;
|
|
347
|
+
patch?: never;
|
|
348
|
+
trace?: never;
|
|
349
|
+
};
|
|
350
|
+
"/workspaces/{workspaceId}/integrations/ai-tool/{provider}/spend": {
|
|
351
|
+
parameters: {
|
|
352
|
+
query?: never;
|
|
353
|
+
header?: never;
|
|
354
|
+
path?: never;
|
|
355
|
+
cookie?: never;
|
|
356
|
+
};
|
|
357
|
+
/** List AI-tool spend */
|
|
358
|
+
get: operations["getWorkspaceAiToolSpend"];
|
|
359
|
+
put?: never;
|
|
360
|
+
post?: never;
|
|
361
|
+
delete?: never;
|
|
362
|
+
options?: never;
|
|
363
|
+
head?: never;
|
|
364
|
+
patch?: never;
|
|
365
|
+
trace?: never;
|
|
366
|
+
};
|
|
367
|
+
"/workspaces/{workspaceId}/integrations/ai-tool/{provider}/status": {
|
|
368
|
+
parameters: {
|
|
369
|
+
query?: never;
|
|
370
|
+
header?: never;
|
|
371
|
+
path?: never;
|
|
372
|
+
cookie?: never;
|
|
373
|
+
};
|
|
374
|
+
/** Get last refresh status */
|
|
375
|
+
get: operations["getWorkspaceAiToolRefreshStatus"];
|
|
376
|
+
put?: never;
|
|
377
|
+
post?: never;
|
|
378
|
+
delete?: never;
|
|
379
|
+
options?: never;
|
|
380
|
+
head?: never;
|
|
381
|
+
patch?: never;
|
|
382
|
+
trace?: never;
|
|
383
|
+
};
|
|
296
384
|
"/integrations/github/callback": {
|
|
297
385
|
parameters: {
|
|
298
386
|
query?: never;
|
|
@@ -750,15 +838,15 @@ export interface components {
|
|
|
750
838
|
} & {
|
|
751
839
|
[key: string]: unknown;
|
|
752
840
|
};
|
|
753
|
-
/** @description Cursor (AI Tools) source entry for `PUT /workspaces/{workspaceId}/sources` and `POST /workspaces/{workspaceId}/sources/test`. The `token` field carries a literal Cursor API key on writes; reads from `GET /workspaces/{workspaceId}/config` redact it to `***`. */
|
|
841
|
+
/** @description Cursor (AI Tools) source entry for `PUT /workspaces/{workspaceId}/sources` and `POST /workspaces/{workspaceId}/sources/test`. The `token` field carries a literal Cursor API key on writes; reads from `GET /workspaces/{workspaceId}/config` redact it to `***`. Runtime calls use the Cursor Admin API at `https://api.cursor.com` (HTTP Basic); do not rely on `baseUrl`. */
|
|
754
842
|
CursorSourceDto: {
|
|
755
843
|
/** @enum {string} */
|
|
756
844
|
type: "cursor";
|
|
757
845
|
/** @description Cursor API key (literal). Whitespace and `env:` prefix are rejected. */
|
|
758
846
|
token: string;
|
|
759
847
|
/**
|
|
760
|
-
*
|
|
761
|
-
* @description
|
|
848
|
+
* @deprecated
|
|
849
|
+
* @description Deprecated. Historically suggested an API base URL; the server ignores this field and always uses the Cursor Admin API host. Kept so older clients can submit payloads unchanged.
|
|
762
850
|
* @default https://api.cursor.com
|
|
763
851
|
*/
|
|
764
852
|
baseUrl: string;
|
|
@@ -773,6 +861,55 @@ export interface components {
|
|
|
773
861
|
success: boolean;
|
|
774
862
|
error?: string;
|
|
775
863
|
};
|
|
864
|
+
AiToolSeatDto: {
|
|
865
|
+
externalId: string;
|
|
866
|
+
email: string;
|
|
867
|
+
displayName?: string | null;
|
|
868
|
+
role?: string | null;
|
|
869
|
+
isRemoved: boolean;
|
|
870
|
+
payload?: {
|
|
871
|
+
[key: string]: unknown;
|
|
872
|
+
};
|
|
873
|
+
};
|
|
874
|
+
AiToolDailyUsageRowDto: {
|
|
875
|
+
/** Format: date */
|
|
876
|
+
day: string;
|
|
877
|
+
externalId: string;
|
|
878
|
+
email?: string | null;
|
|
879
|
+
isActive: boolean;
|
|
880
|
+
mostUsedModel?: string | null;
|
|
881
|
+
payload?: {
|
|
882
|
+
[key: string]: unknown;
|
|
883
|
+
};
|
|
884
|
+
};
|
|
885
|
+
AiToolSpendRowDto: {
|
|
886
|
+
/** Format: int64 */
|
|
887
|
+
billingCycleStartMs: number;
|
|
888
|
+
externalId: string;
|
|
889
|
+
email?: string | null;
|
|
890
|
+
/** Format: int64 */
|
|
891
|
+
spendCents: number;
|
|
892
|
+
payload?: {
|
|
893
|
+
[key: string]: unknown;
|
|
894
|
+
};
|
|
895
|
+
};
|
|
896
|
+
AiToolRefreshStatusDto: {
|
|
897
|
+
/** Format: date-time */
|
|
898
|
+
lastAttemptAt: string;
|
|
899
|
+
/** Format: date-time */
|
|
900
|
+
lastSuccessAt?: string | null;
|
|
901
|
+
lastErrorKind?: string | null;
|
|
902
|
+
lastErrorMessage?: string | null;
|
|
903
|
+
/** Format: int64 */
|
|
904
|
+
durationMs?: number | null;
|
|
905
|
+
counts: {
|
|
906
|
+
[key: string]: unknown;
|
|
907
|
+
};
|
|
908
|
+
};
|
|
909
|
+
AiToolRefreshResponseDto: {
|
|
910
|
+
ok: boolean;
|
|
911
|
+
error?: string | null;
|
|
912
|
+
};
|
|
776
913
|
/** @description Nested metric groups; see TypeScript `DashboardProductivityMetricsDto` in @thinkai/tai-api-contract. */
|
|
777
914
|
DashboardProductivityMetricsDto: {
|
|
778
915
|
[key: string]: unknown;
|
|
@@ -1245,6 +1382,11 @@ export type TenantSourceEntryDto = components['schemas']['TenantSourceEntryDto']
|
|
|
1245
1382
|
export type CursorSourceDto = components['schemas']['CursorSourceDto'];
|
|
1246
1383
|
export type WorkspaceConfigDto = components['schemas']['WorkspaceConfigDto'];
|
|
1247
1384
|
export type TestConnectionResponseDto = components['schemas']['TestConnectionResponseDto'];
|
|
1385
|
+
export type AiToolSeatDto = components['schemas']['AiToolSeatDto'];
|
|
1386
|
+
export type AiToolDailyUsageRowDto = components['schemas']['AiToolDailyUsageRowDto'];
|
|
1387
|
+
export type AiToolSpendRowDto = components['schemas']['AiToolSpendRowDto'];
|
|
1388
|
+
export type AiToolRefreshStatusDto = components['schemas']['AiToolRefreshStatusDto'];
|
|
1389
|
+
export type AiToolRefreshResponseDto = components['schemas']['AiToolRefreshResponseDto'];
|
|
1248
1390
|
export type DashboardProductivityMetricsDto = components['schemas']['DashboardProductivityMetricsDto'];
|
|
1249
1391
|
export type DashboardProductivityDto = components['schemas']['DashboardProductivityDto'];
|
|
1250
1392
|
export type DashboardProductivityHistoryDto = components['schemas']['DashboardProductivityHistoryDto'];
|
|
@@ -2027,6 +2169,190 @@ export interface operations {
|
|
|
2027
2169
|
};
|
|
2028
2170
|
};
|
|
2029
2171
|
};
|
|
2172
|
+
refreshWorkspaceAiTool: {
|
|
2173
|
+
parameters: {
|
|
2174
|
+
query?: never;
|
|
2175
|
+
header?: never;
|
|
2176
|
+
path: {
|
|
2177
|
+
workspaceId: components["parameters"]["WorkspaceId"];
|
|
2178
|
+
provider: "cursor";
|
|
2179
|
+
};
|
|
2180
|
+
cookie?: never;
|
|
2181
|
+
};
|
|
2182
|
+
requestBody?: never;
|
|
2183
|
+
responses: {
|
|
2184
|
+
/** @description Refresh result */
|
|
2185
|
+
200: {
|
|
2186
|
+
headers: {
|
|
2187
|
+
[name: string]: unknown;
|
|
2188
|
+
};
|
|
2189
|
+
content: {
|
|
2190
|
+
"application/json": components["schemas"]["AiToolRefreshResponseDto"];
|
|
2191
|
+
};
|
|
2192
|
+
};
|
|
2193
|
+
401: components["responses"]["Unauthorized"];
|
|
2194
|
+
403: components["responses"]["Forbidden"];
|
|
2195
|
+
/** @description Provider source missing for this workspace */
|
|
2196
|
+
404: {
|
|
2197
|
+
headers: {
|
|
2198
|
+
[name: string]: unknown;
|
|
2199
|
+
};
|
|
2200
|
+
content: {
|
|
2201
|
+
/**
|
|
2202
|
+
* @example {
|
|
2203
|
+
* "ok": false,
|
|
2204
|
+
* "error": "no_source"
|
|
2205
|
+
* }
|
|
2206
|
+
*/
|
|
2207
|
+
"application/json": components["schemas"]["AiToolRefreshResponseDto"];
|
|
2208
|
+
};
|
|
2209
|
+
};
|
|
2210
|
+
/** @description Refresh already in progress */
|
|
2211
|
+
409: {
|
|
2212
|
+
headers: {
|
|
2213
|
+
[name: string]: unknown;
|
|
2214
|
+
};
|
|
2215
|
+
content: {
|
|
2216
|
+
/**
|
|
2217
|
+
* @example {
|
|
2218
|
+
* "ok": false,
|
|
2219
|
+
* "error": "already_in_progress"
|
|
2220
|
+
* }
|
|
2221
|
+
*/
|
|
2222
|
+
"application/json": components["schemas"]["AiToolRefreshResponseDto"];
|
|
2223
|
+
};
|
|
2224
|
+
};
|
|
2225
|
+
};
|
|
2226
|
+
};
|
|
2227
|
+
getWorkspaceAiToolSeats: {
|
|
2228
|
+
parameters: {
|
|
2229
|
+
query?: never;
|
|
2230
|
+
header?: never;
|
|
2231
|
+
path: {
|
|
2232
|
+
workspaceId: components["parameters"]["WorkspaceId"];
|
|
2233
|
+
provider: "cursor";
|
|
2234
|
+
};
|
|
2235
|
+
cookie?: never;
|
|
2236
|
+
};
|
|
2237
|
+
requestBody?: never;
|
|
2238
|
+
responses: {
|
|
2239
|
+
/** @description Seats */
|
|
2240
|
+
200: {
|
|
2241
|
+
headers: {
|
|
2242
|
+
[name: string]: unknown;
|
|
2243
|
+
};
|
|
2244
|
+
content: {
|
|
2245
|
+
"application/json": {
|
|
2246
|
+
seats: components["schemas"]["AiToolSeatDto"][];
|
|
2247
|
+
};
|
|
2248
|
+
};
|
|
2249
|
+
};
|
|
2250
|
+
401: components["responses"]["Unauthorized"];
|
|
2251
|
+
403: components["responses"]["Forbidden"];
|
|
2252
|
+
};
|
|
2253
|
+
};
|
|
2254
|
+
getWorkspaceAiToolDailyUsage: {
|
|
2255
|
+
parameters: {
|
|
2256
|
+
query?: {
|
|
2257
|
+
from?: string;
|
|
2258
|
+
to?: string;
|
|
2259
|
+
externalId?: string;
|
|
2260
|
+
};
|
|
2261
|
+
header?: never;
|
|
2262
|
+
path: {
|
|
2263
|
+
workspaceId: components["parameters"]["WorkspaceId"];
|
|
2264
|
+
provider: "cursor";
|
|
2265
|
+
};
|
|
2266
|
+
cookie?: never;
|
|
2267
|
+
};
|
|
2268
|
+
requestBody?: never;
|
|
2269
|
+
responses: {
|
|
2270
|
+
/** @description Usage rows */
|
|
2271
|
+
200: {
|
|
2272
|
+
headers: {
|
|
2273
|
+
[name: string]: unknown;
|
|
2274
|
+
};
|
|
2275
|
+
content: {
|
|
2276
|
+
"application/json": {
|
|
2277
|
+
rows: components["schemas"]["AiToolDailyUsageRowDto"][];
|
|
2278
|
+
};
|
|
2279
|
+
};
|
|
2280
|
+
};
|
|
2281
|
+
401: components["responses"]["Unauthorized"];
|
|
2282
|
+
403: components["responses"]["Forbidden"];
|
|
2283
|
+
};
|
|
2284
|
+
};
|
|
2285
|
+
getWorkspaceAiToolSpend: {
|
|
2286
|
+
parameters: {
|
|
2287
|
+
query?: {
|
|
2288
|
+
cycleStartMs?: number;
|
|
2289
|
+
};
|
|
2290
|
+
header?: never;
|
|
2291
|
+
path: {
|
|
2292
|
+
workspaceId: components["parameters"]["WorkspaceId"];
|
|
2293
|
+
provider: "cursor";
|
|
2294
|
+
};
|
|
2295
|
+
cookie?: never;
|
|
2296
|
+
};
|
|
2297
|
+
requestBody?: never;
|
|
2298
|
+
responses: {
|
|
2299
|
+
/** @description Spend rows */
|
|
2300
|
+
200: {
|
|
2301
|
+
headers: {
|
|
2302
|
+
[name: string]: unknown;
|
|
2303
|
+
};
|
|
2304
|
+
content: {
|
|
2305
|
+
"application/json": {
|
|
2306
|
+
rows: components["schemas"]["AiToolSpendRowDto"][];
|
|
2307
|
+
};
|
|
2308
|
+
};
|
|
2309
|
+
};
|
|
2310
|
+
401: components["responses"]["Unauthorized"];
|
|
2311
|
+
403: components["responses"]["Forbidden"];
|
|
2312
|
+
};
|
|
2313
|
+
};
|
|
2314
|
+
getWorkspaceAiToolRefreshStatus: {
|
|
2315
|
+
parameters: {
|
|
2316
|
+
query?: never;
|
|
2317
|
+
header?: never;
|
|
2318
|
+
path: {
|
|
2319
|
+
workspaceId: components["parameters"]["WorkspaceId"];
|
|
2320
|
+
provider: "cursor";
|
|
2321
|
+
};
|
|
2322
|
+
cookie?: never;
|
|
2323
|
+
};
|
|
2324
|
+
requestBody?: never;
|
|
2325
|
+
responses: {
|
|
2326
|
+
/** @description Refresh status */
|
|
2327
|
+
200: {
|
|
2328
|
+
headers: {
|
|
2329
|
+
[name: string]: unknown;
|
|
2330
|
+
};
|
|
2331
|
+
content: {
|
|
2332
|
+
"application/json": {
|
|
2333
|
+
status: components["schemas"]["AiToolRefreshStatusDto"];
|
|
2334
|
+
};
|
|
2335
|
+
};
|
|
2336
|
+
};
|
|
2337
|
+
401: components["responses"]["Unauthorized"];
|
|
2338
|
+
403: components["responses"]["Forbidden"];
|
|
2339
|
+
/** @description No refresh status yet (or provider source missing) */
|
|
2340
|
+
404: {
|
|
2341
|
+
headers: {
|
|
2342
|
+
[name: string]: unknown;
|
|
2343
|
+
};
|
|
2344
|
+
content: {
|
|
2345
|
+
/**
|
|
2346
|
+
* @example {
|
|
2347
|
+
* "ok": false,
|
|
2348
|
+
* "error": "no_source"
|
|
2349
|
+
* }
|
|
2350
|
+
*/
|
|
2351
|
+
"application/json": components["schemas"]["AiToolRefreshResponseDto"];
|
|
2352
|
+
};
|
|
2353
|
+
};
|
|
2354
|
+
};
|
|
2355
|
+
};
|
|
2030
2356
|
getGithubInstallCallback: {
|
|
2031
2357
|
parameters: {
|
|
2032
2358
|
query: {
|