@featureflip/mcp 0.1.10 → 0.1.12

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/README.md CHANGED
@@ -41,9 +41,9 @@ claude mcp add featureflip -e FEATUREFLIP_TOKEN=ffp_your_token -- npx -y @featur
41
41
  ## Tools
42
42
 
43
43
  CRUD: `list_projects`, `list_environments`, `list_flags`, `get_flag`, `create_flag`, `update_flag`,
44
- `delete_flag`, `archive_flag`, `restore_flag`, `set_flag_expiry`, `set_flag_owner`, `toggle_flag`,
45
- `update_flag_environment_config`, `get_targeting`, `update_targeting`, `manage_variation`, `list_segments`,
46
- `get_segment`
44
+ `delete_flag`, `archive_flag`, `restore_flag`, `set_flag_expiry`, `set_flag_owner`, `set_flag_permanent`,
45
+ `toggle_flag`, `update_flag_environment_config`, `get_targeting`, `update_targeting`, `manage_variation`,
46
+ `list_segments`, `get_segment`
47
47
 
48
48
  Webhooks (Admin token required): `list_webhooks`, `list_webhook_deliveries`, `manage_webhook`, `deliver_webhook`
49
49
 
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as e, i as t, n, o as r, s as i, t as a } from "./org-C5dAa5In.js";
1
+ import { a as e, i as t, n, o as r, s as i, t as a } from "./org-Dq8g_Duu.js";
2
2
  import { serveStdio as o } from "@modelcontextprotocol/server/stdio";
3
3
  //#region src/unconfigured.ts
4
4
  var s = class extends i {
@@ -195,6 +195,8 @@ export interface paths {
195
195
  /** @description OK */
196
196
  200: {
197
197
  headers: {
198
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
199
+ ETag?: string;
198
200
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
199
201
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
200
202
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -251,7 +253,10 @@ export interface paths {
251
253
  put: {
252
254
  parameters: {
253
255
  query?: never;
254
- header?: never;
256
+ header?: {
257
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
258
+ "If-Match"?: string;
259
+ };
255
260
  path: {
256
261
  org: string;
257
262
  project: string;
@@ -270,6 +275,8 @@ export interface paths {
270
275
  /** @description No Content */
271
276
  204: {
272
277
  headers: {
278
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
279
+ ETag?: string;
273
280
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
274
281
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
275
282
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -313,6 +320,18 @@ export interface paths {
313
320
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
314
321
  };
315
322
  };
323
+ /** @description The resource changed since the If-Match ETag. */
324
+ 412: {
325
+ headers: {
326
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
327
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
328
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
329
+ [name: string]: unknown;
330
+ };
331
+ content: {
332
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
333
+ };
334
+ };
316
335
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
317
336
  429: {
318
337
  headers: {
@@ -445,6 +464,7 @@ export interface paths {
445
464
  * Decode's "garbage input degrades gracefully" precedent)
446
465
  * rather than a 400, since it's a non-critical list filter, not a mutation. `owner` filters
447
466
  * by owner: an email (an active member, case-insensitive) or `none` for unowned flags.
467
+ * `permanent` filters to permanent (`true`) or temporary (`false`) flags.
448
468
  */
449
469
  get: {
450
470
  parameters: {
@@ -456,6 +476,7 @@ export interface paths {
456
476
  limit?: number;
457
477
  cursor?: string;
458
478
  owner?: string;
479
+ permanent?: boolean;
459
480
  };
460
481
  header?: never;
461
482
  path: {
@@ -750,6 +771,8 @@ export interface paths {
750
771
  /** @description OK */
751
772
  200: {
752
773
  headers: {
774
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
775
+ ETag?: string;
753
776
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
754
777
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
755
778
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -808,7 +831,10 @@ export interface paths {
808
831
  put: {
809
832
  parameters: {
810
833
  query?: never;
811
- header?: never;
834
+ header?: {
835
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
836
+ "If-Match"?: string;
837
+ };
812
838
  path: {
813
839
  org: string;
814
840
  project: string;
@@ -827,6 +853,8 @@ export interface paths {
827
853
  /** @description No Content */
828
854
  204: {
829
855
  headers: {
856
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
857
+ ETag?: string;
830
858
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
831
859
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
832
860
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -870,6 +898,18 @@ export interface paths {
870
898
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
871
899
  };
872
900
  };
901
+ /** @description The resource changed since the If-Match ETag. */
902
+ 412: {
903
+ headers: {
904
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
905
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
906
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
907
+ [name: string]: unknown;
908
+ };
909
+ content: {
910
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
911
+ };
912
+ };
873
913
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
874
914
  429: {
875
915
  headers: {
@@ -1001,7 +1041,8 @@ export interface paths {
1001
1041
  * date (`2026-12-01`), which means the end of that day in UTC, the same as picking it in the
1002
1042
  * dashboard, or a full ISO-8601 timestamp, which is stored exactly. It must be in the future
1003
1043
  * (400 `EXPIRY_IN_PAST`), so today's date is accepted, and the flag-expiration feature must
1004
- * be enabled (400 `FEATURE_NOT_ENABLED`).
1044
+ * be enabled (400 `FEATURE_NOT_ENABLED`). A permanent flag can't have a date
1045
+ * (400 `PERMANENT_FLAG_HAS_EXPIRY`).
1005
1046
  */
1006
1047
  put: {
1007
1048
  parameters: {
@@ -1375,6 +1416,193 @@ export interface paths {
1375
1416
  patch?: never;
1376
1417
  trace?: never;
1377
1418
  };
1419
+ "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/permanent": {
1420
+ parameters: {
1421
+ query?: never;
1422
+ header?: never;
1423
+ path?: never;
1424
+ cookie?: never;
1425
+ };
1426
+ get?: never;
1427
+ /**
1428
+ * Marks the flag permanent: a kill switch, ops toggle or entitlement gate that is meant to stay.
1429
+ * @description A permanent flag is never offered as a removal candidate and never reported past expiry.
1430
+ * Requires at least Member. The flag can't have an expiry date (400 `PERMANENT_FLAG_HAS_EXPIRY`;
1431
+ * remove the date first) and the flag-permanence feature must be enabled (400 `FEATURE_NOT_ENABLED`).
1432
+ */
1433
+ put: {
1434
+ parameters: {
1435
+ query?: never;
1436
+ header?: never;
1437
+ path: {
1438
+ org: string;
1439
+ project: string;
1440
+ flag: string;
1441
+ };
1442
+ cookie?: never;
1443
+ };
1444
+ requestBody?: never;
1445
+ responses: {
1446
+ /** @description No Content */
1447
+ 204: {
1448
+ headers: {
1449
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1450
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1451
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1452
+ [name: string]: unknown;
1453
+ };
1454
+ content?: never;
1455
+ };
1456
+ /** @description Bad Request */
1457
+ 400: {
1458
+ headers: {
1459
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1460
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1461
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1462
+ [name: string]: unknown;
1463
+ };
1464
+ content: {
1465
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1466
+ };
1467
+ };
1468
+ /** @description Authentication is required, or the supplied API token is invalid or expired. */
1469
+ 401: {
1470
+ headers: {
1471
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1472
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1473
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1474
+ [name: string]: unknown;
1475
+ };
1476
+ content: {
1477
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1478
+ };
1479
+ };
1480
+ /** @description Forbidden */
1481
+ 403: {
1482
+ headers: {
1483
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1484
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1485
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1486
+ [name: string]: unknown;
1487
+ };
1488
+ content: {
1489
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1490
+ };
1491
+ };
1492
+ /** @description Not Found */
1493
+ 404: {
1494
+ headers: {
1495
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1496
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1497
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1498
+ [name: string]: unknown;
1499
+ };
1500
+ content: {
1501
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1502
+ };
1503
+ };
1504
+ /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
1505
+ 429: {
1506
+ headers: {
1507
+ /** @description Number of seconds to wait before retrying the request. */
1508
+ "Retry-After"?: number;
1509
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1510
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1511
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1512
+ [name: string]: unknown;
1513
+ };
1514
+ content: {
1515
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1516
+ };
1517
+ };
1518
+ };
1519
+ };
1520
+ post?: never;
1521
+ /**
1522
+ * Makes the flag temporary again.
1523
+ * @description Requires at least Member. Always allowed, even when the
1524
+ * flag-permanence feature is disabled.
1525
+ */
1526
+ delete: {
1527
+ parameters: {
1528
+ query?: never;
1529
+ header?: never;
1530
+ path: {
1531
+ org: string;
1532
+ project: string;
1533
+ flag: string;
1534
+ };
1535
+ cookie?: never;
1536
+ };
1537
+ requestBody?: never;
1538
+ responses: {
1539
+ /** @description No Content */
1540
+ 204: {
1541
+ headers: {
1542
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1543
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1544
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1545
+ [name: string]: unknown;
1546
+ };
1547
+ content?: never;
1548
+ };
1549
+ /** @description Authentication is required, or the supplied API token is invalid or expired. */
1550
+ 401: {
1551
+ headers: {
1552
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1553
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1554
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1555
+ [name: string]: unknown;
1556
+ };
1557
+ content: {
1558
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1559
+ };
1560
+ };
1561
+ /** @description Forbidden */
1562
+ 403: {
1563
+ headers: {
1564
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1565
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1566
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1567
+ [name: string]: unknown;
1568
+ };
1569
+ content: {
1570
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1571
+ };
1572
+ };
1573
+ /** @description Not Found */
1574
+ 404: {
1575
+ headers: {
1576
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1577
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1578
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1579
+ [name: string]: unknown;
1580
+ };
1581
+ content: {
1582
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1583
+ };
1584
+ };
1585
+ /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
1586
+ 429: {
1587
+ headers: {
1588
+ /** @description Number of seconds to wait before retrying the request. */
1589
+ "Retry-After"?: number;
1590
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1591
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1592
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1593
+ [name: string]: unknown;
1594
+ };
1595
+ content: {
1596
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
1597
+ };
1598
+ };
1599
+ };
1600
+ };
1601
+ options?: never;
1602
+ head?: never;
1603
+ patch?: never;
1604
+ trace?: never;
1605
+ };
1378
1606
  "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/removal-pr": {
1379
1607
  parameters: {
1380
1608
  query?: never;
@@ -1885,6 +2113,8 @@ export interface paths {
1885
2113
  /** @description OK */
1886
2114
  200: {
1887
2115
  headers: {
2116
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2117
+ ETag?: string;
1888
2118
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1889
2119
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1890
2120
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -1943,7 +2173,10 @@ export interface paths {
1943
2173
  put: {
1944
2174
  parameters: {
1945
2175
  query?: never;
1946
- header?: never;
2176
+ header?: {
2177
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
2178
+ "If-Match"?: string;
2179
+ };
1947
2180
  path: {
1948
2181
  org: string;
1949
2182
  project: string;
@@ -1963,6 +2196,8 @@ export interface paths {
1963
2196
  /** @description No Content */
1964
2197
  204: {
1965
2198
  headers: {
2199
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2200
+ ETag?: string;
1966
2201
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1967
2202
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1968
2203
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -2018,6 +2253,18 @@ export interface paths {
2018
2253
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2019
2254
  };
2020
2255
  };
2256
+ /** @description The resource changed since the If-Match ETag. */
2257
+ 412: {
2258
+ headers: {
2259
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2260
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2261
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
2262
+ [name: string]: unknown;
2263
+ };
2264
+ content: {
2265
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2266
+ };
2267
+ };
2021
2268
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
2022
2269
  429: {
2023
2270
  headers: {
@@ -2185,6 +2432,8 @@ export interface paths {
2185
2432
  /** @description OK */
2186
2433
  200: {
2187
2434
  headers: {
2435
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2436
+ ETag?: string;
2188
2437
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2189
2438
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2190
2439
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -2243,7 +2492,10 @@ export interface paths {
2243
2492
  put: {
2244
2493
  parameters: {
2245
2494
  query?: never;
2246
- header?: never;
2495
+ header?: {
2496
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
2497
+ "If-Match"?: string;
2498
+ };
2247
2499
  path: {
2248
2500
  org: string;
2249
2501
  project: string;
@@ -2263,6 +2515,8 @@ export interface paths {
2263
2515
  /** @description No Content */
2264
2516
  204: {
2265
2517
  headers: {
2518
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2519
+ ETag?: string;
2266
2520
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2267
2521
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2268
2522
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -2318,6 +2572,18 @@ export interface paths {
2318
2572
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2319
2573
  };
2320
2574
  };
2575
+ /** @description The resource changed since the If-Match ETag. */
2576
+ 412: {
2577
+ headers: {
2578
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2579
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2580
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
2581
+ [name: string]: unknown;
2582
+ };
2583
+ content: {
2584
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2585
+ };
2586
+ };
2321
2587
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
2322
2588
  429: {
2323
2589
  headers: {
@@ -2485,6 +2751,8 @@ export interface paths {
2485
2751
  /** @description OK */
2486
2752
  200: {
2487
2753
  headers: {
2754
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2755
+ ETag?: string;
2488
2756
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2489
2757
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2490
2758
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -2541,7 +2809,10 @@ export interface paths {
2541
2809
  put: {
2542
2810
  parameters: {
2543
2811
  query?: never;
2544
- header?: never;
2812
+ header?: {
2813
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
2814
+ "If-Match"?: string;
2815
+ };
2545
2816
  path: {
2546
2817
  org: string;
2547
2818
  project: string;
@@ -2562,6 +2833,8 @@ export interface paths {
2562
2833
  /** @description No Content */
2563
2834
  204: {
2564
2835
  headers: {
2836
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
2837
+ ETag?: string;
2565
2838
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2566
2839
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2567
2840
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -2617,6 +2890,18 @@ export interface paths {
2617
2890
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2618
2891
  };
2619
2892
  };
2893
+ /** @description The resource changed since the If-Match ETag. */
2894
+ 412: {
2895
+ headers: {
2896
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
2897
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
2898
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
2899
+ [name: string]: unknown;
2900
+ };
2901
+ content: {
2902
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
2903
+ };
2904
+ };
2620
2905
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
2621
2906
  429: {
2622
2907
  headers: {
@@ -4400,6 +4685,8 @@ export interface paths {
4400
4685
  /** @description OK */
4401
4686
  200: {
4402
4687
  headers: {
4688
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
4689
+ ETag?: string;
4403
4690
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
4404
4691
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
4405
4692
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -4456,7 +4743,10 @@ export interface paths {
4456
4743
  put: {
4457
4744
  parameters: {
4458
4745
  query?: never;
4459
- header?: never;
4746
+ header?: {
4747
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
4748
+ "If-Match"?: string;
4749
+ };
4460
4750
  path: {
4461
4751
  org: string;
4462
4752
  project: string;
@@ -4475,6 +4765,8 @@ export interface paths {
4475
4765
  /** @description No Content */
4476
4766
  204: {
4477
4767
  headers: {
4768
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
4769
+ ETag?: string;
4478
4770
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
4479
4771
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
4480
4772
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -4530,6 +4822,18 @@ export interface paths {
4530
4822
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
4531
4823
  };
4532
4824
  };
4825
+ /** @description The resource changed since the If-Match ETag. */
4826
+ 412: {
4827
+ headers: {
4828
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
4829
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
4830
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
4831
+ [name: string]: unknown;
4832
+ };
4833
+ content: {
4834
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
4835
+ };
4836
+ };
4533
4837
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
4534
4838
  429: {
4535
4839
  headers: {
@@ -4945,6 +5249,8 @@ export interface paths {
4945
5249
  /** @description OK */
4946
5250
  200: {
4947
5251
  headers: {
5252
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
5253
+ ETag?: string;
4948
5254
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
4949
5255
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
4950
5256
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -5014,7 +5320,10 @@ export interface paths {
5014
5320
  put: {
5015
5321
  parameters: {
5016
5322
  query?: never;
5017
- header?: never;
5323
+ header?: {
5324
+ /** @description Optional. The ETag from a GET of this resource. The write applies only if the resource still has that ETag; otherwise 412 `precondition_failed`. `*` or no header applies the write unconditionally. */
5325
+ "If-Match"?: string;
5326
+ };
5018
5327
  path: {
5019
5328
  org: string;
5020
5329
  id: string;
@@ -5032,6 +5341,8 @@ export interface paths {
5032
5341
  /** @description No Content */
5033
5342
  204: {
5034
5343
  headers: {
5344
+ /** @description Strong ETag of the resource. Send it back as If-Match on a PUT. */
5345
+ ETag?: string;
5035
5346
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
5036
5347
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
5037
5348
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
@@ -5087,6 +5398,18 @@ export interface paths {
5087
5398
  "application/json": components["schemas"]["PublicApiErrorEnvelope"];
5088
5399
  };
5089
5400
  };
5401
+ /** @description The resource changed since the If-Match ETag. */
5402
+ 412: {
5403
+ headers: {
5404
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
5405
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
5406
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
5407
+ [name: string]: unknown;
5408
+ };
5409
+ content: {
5410
+ "application/json": components["schemas"]["PublicApiErrorEnvelope"];
5411
+ };
5412
+ };
5090
5413
  /** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
5091
5414
  429: {
5092
5415
  headers: {
@@ -5964,7 +6287,10 @@ export interface components {
5964
6287
  * (400 `EXPIRY_IN_PAST` / `FEATURE_NOT_ENABLED`). OwnerEmail optionally names
5965
6288
  * the owner (an active member, matched case-insensitively; requires the flag-ownership feature —
5966
6289
  * 400 `OWNER_NOT_MEMBER` / `FEATURE_NOT_ENABLED`). Omitted, the owner is the caller when
5967
- * the caller is a member, so a service token creates an unowned flag.
6290
+ * the caller is a member, so a service token creates an unowned flag. IsPermanent marks
6291
+ * the flag permanent (a kill switch, ops toggle or entitlement that is meant to stay; never reported for
6292
+ * cleanup). It requires the flag-permanence feature and can't be combined with ExpiresAtUtc
6293
+ * (400 `FEATURE_NOT_ENABLED` / `PERMANENT_FLAG_HAS_EXPIRY`).
5968
6294
  * @example {
5969
6295
  * "key": "new-checkout-flow",
5970
6296
  * "name": "New Checkout Flow",
@@ -6006,6 +6332,7 @@ export interface components {
6006
6332
  /** Format: date-time */
6007
6333
  expiresAtUtc?: string | null;
6008
6334
  ownerEmail?: string | null;
6335
+ isPermanent?: boolean;
6009
6336
  };
6010
6337
  /**
6011
6338
  * @description Request body for `POST /api/v1/orgs/{org}/projects`. Named distinctly from the
@@ -6316,6 +6643,7 @@ export interface components {
6316
6643
  expiresAtUtc?: string | null;
6317
6644
  owner?: components["schemas"]["PublicFlagOwner"];
6318
6645
  removalPrUrl?: string | null;
6646
+ isPermanent?: boolean;
6319
6647
  };
6320
6648
  /**
6321
6649
  * @description A page of results plus an opaque cursor for the next page, or null when this is the last
@@ -6443,6 +6771,7 @@ export interface components {
6443
6771
  expiresAtUtc?: string | null;
6444
6772
  owner?: components["schemas"]["PublicFlagOwner"];
6445
6773
  removalPrUrl?: string | null;
6774
+ isPermanent?: boolean;
6446
6775
  /** @description Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it. */
6447
6776
  _actions?: {
6448
6777
  [key: string]: components["schemas"]["ActionCapability"];