@runcofactor/cli 0.28.0 → 0.29.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.
Files changed (115) hide show
  1. package/dist/{account-6FPITX2M.js → account-QWQP6YCY.js} +3 -3
  2. package/dist/{alert-PWERXHCP.js → alert-65FH7P74.js} +4 -4
  3. package/dist/{api-catalog-HCSSHOFY.js → api-catalog-WM6R37CA.js} +3 -3
  4. package/dist/{attachment-A7JAZWWH.js → attachment-FTQTZUTA.js} +3 -3
  5. package/dist/{augmentor-MIEBKJUK.js → augmentor-IQMT6NFX.js} +3 -3
  6. package/dist/{chunk-3VHY375S.js → chunk-3VIBXXNX.js} +2 -2
  7. package/dist/{chunk-IFZ72FZV.js → chunk-3X3TSH2B.js} +2 -2
  8. package/dist/{chunk-ZP3RP4IK.js → chunk-6AJLNMHB.js} +2 -2
  9. package/dist/{chunk-44NI5IDC.js → chunk-6QGUAITE.js} +15 -1
  10. package/dist/{chunk-44NI5IDC.js.map → chunk-6QGUAITE.js.map} +1 -1
  11. package/dist/{chunk-5N4OZPFQ.js → chunk-DECTGV4O.js} +2 -2
  12. package/dist/{chunk-6BAMC77N.js → chunk-E22PSTUP.js} +2 -2
  13. package/dist/{chunk-4ZNTGBJR.js → chunk-EHKHZ5UR.js} +23 -23
  14. package/dist/chunk-EHKHZ5UR.js.map +1 -0
  15. package/dist/{chunk-DHL4O7MG.js → chunk-MBMFYGKN.js} +2 -2
  16. package/dist/{chunk-YBX5BIKL.js → chunk-PK5UICGR.js} +2 -2
  17. package/dist/{chunk-4SV3CGNM.js → chunk-SFRUUIIC.js} +2 -2
  18. package/dist/{chunk-LSL2M7O6.js → chunk-WTMSRIDK.js} +2 -2
  19. package/dist/{credential-KSLGCJU7.js → credential-CKO4ZBMU.js} +3 -3
  20. package/dist/{credential-template-WECUNR4X.js → credential-template-XOZ2FJ6Z.js} +3 -3
  21. package/dist/{dist-5PKCAL5N.js → dist-YPK2RMUK.js} +3 -3
  22. package/dist/{docs-PRUI4LAD.js → docs-WZCQ6GP7.js} +3 -3
  23. package/dist/{environment-ATT4UQCY.js → environment-KO3JUX3V.js} +3 -3
  24. package/dist/{feature-flag-MWIHVJER.js → feature-flag-4YPPF27F.js} +63 -5
  25. package/dist/feature-flag-4YPPF27F.js.map +1 -0
  26. package/dist/index.js +38 -38
  27. package/dist/{init-QBMKWGHZ.js → init-RXWDJV5I.js} +3 -3
  28. package/dist/{install-BHYIXK6G.js → install-Z7EGAEEW.js} +3 -3
  29. package/dist/{issues-JO3OVOV7.js → issues-XOU54YKP.js} +3 -3
  30. package/dist/{knobs-4LLJ4LCU.js → knobs-7MB2O5SW.js} +3 -3
  31. package/dist/{list-JVJSIK52.js → list-5CJZY5BC.js} +3 -3
  32. package/dist/{local-VCZGHODB.js → local-XLBE4JIT.js} +5 -5
  33. package/dist/{login-UBNUPK2H.js → login-6GDATX4X.js} +3 -3
  34. package/dist/{mcp-2BBNDVZI.js → mcp-52UNMEF3.js} +4 -4
  35. package/dist/{metrics-4YOSDGIG.js → metrics-4Z5IJZ7U.js} +3 -3
  36. package/dist/{product-T2PVBVZ4.js → product-N2R3MWZS.js} +3 -3
  37. package/dist/{prompts-MI4QK2ZM.js → prompts-X6FNI6NZ.js} +3 -3
  38. package/dist/{property-EKASZCO7.js → property-VUKL5IFR.js} +3 -3
  39. package/dist/{record-Z4NY75FM.js → record-AVGKVJK7.js} +4 -4
  40. package/dist/{release-Z7WKFMBS.js → release-4QOZ4IP6.js} +3 -3
  41. package/dist/{sandbox-YOODBA5Q.js → sandbox-4ZR6XRIQ.js} +14 -3
  42. package/dist/sandbox-4ZR6XRIQ.js.map +1 -0
  43. package/dist/{scenarios-ABYCUJ4O.js → scenarios-UZBDO3XR.js} +3 -3
  44. package/dist/{schedule-ZRHOCT5Q.js → schedule-XCSZ6NLT.js} +4 -4
  45. package/dist/{session-T7BV73AC.js → session-QXHDS5GP.js} +5 -5
  46. package/dist/{skill-VLCWQJHG.js → skill-FXNE77RE.js} +166 -159
  47. package/dist/skill-FXNE77RE.js.map +1 -0
  48. package/dist/{spec-QPWXRPAG.js → spec-TOUOP4TC.js} +3 -3
  49. package/dist/{src-BH5O6Z3E.js → src-YZGG5ZSL.js} +3 -3
  50. package/dist/{start-5BADZ65B.js → start-JDLIIBPC.js} +3 -3
  51. package/dist/{tag-CIR6U5LL.js → tag-LSS3IOUA.js} +4 -4
  52. package/dist/{task-4YKONXJI.js → task-KCNDIT4A.js} +3 -3
  53. package/dist/{test-suite-PRJ2PGMN.js → test-suite-MOVN2XL5.js} +5 -5
  54. package/dist/{trace-XVB47RLY.js → trace-7OZNMAKV.js} +4 -4
  55. package/dist/{triage-L5WR65KW.js → triage-BRSUW4Z7.js} +4 -4
  56. package/dist/{utilities-LBKWREPU.js → utilities-TXQGGH37.js} +3 -3
  57. package/dist/{workflow-GCZCXPGA.js → workflow-2TVSFQXK.js} +310 -302
  58. package/dist/workflow-2TVSFQXK.js.map +1 -0
  59. package/dist/{workflow-cache-XWTLXIHE.js → workflow-cache-LRH5CAPS.js} +6 -6
  60. package/dist/{workflow-debug-XHR4552F.js → workflow-debug-IWXZXSL2.js} +5 -5
  61. package/dist/{workflow-proposals-VWLKW352.js → workflow-proposals-76D2MM6G.js} +3 -3
  62. package/package.json +1 -1
  63. package/dist/chunk-4ZNTGBJR.js.map +0 -1
  64. package/dist/feature-flag-MWIHVJER.js.map +0 -1
  65. package/dist/sandbox-YOODBA5Q.js.map +0 -1
  66. package/dist/skill-VLCWQJHG.js.map +0 -1
  67. package/dist/workflow-GCZCXPGA.js.map +0 -1
  68. /package/dist/{account-6FPITX2M.js.map → account-QWQP6YCY.js.map} +0 -0
  69. /package/dist/{alert-PWERXHCP.js.map → alert-65FH7P74.js.map} +0 -0
  70. /package/dist/{api-catalog-HCSSHOFY.js.map → api-catalog-WM6R37CA.js.map} +0 -0
  71. /package/dist/{attachment-A7JAZWWH.js.map → attachment-FTQTZUTA.js.map} +0 -0
  72. /package/dist/{augmentor-MIEBKJUK.js.map → augmentor-IQMT6NFX.js.map} +0 -0
  73. /package/dist/{chunk-3VHY375S.js.map → chunk-3VIBXXNX.js.map} +0 -0
  74. /package/dist/{chunk-IFZ72FZV.js.map → chunk-3X3TSH2B.js.map} +0 -0
  75. /package/dist/{chunk-ZP3RP4IK.js.map → chunk-6AJLNMHB.js.map} +0 -0
  76. /package/dist/{chunk-5N4OZPFQ.js.map → chunk-DECTGV4O.js.map} +0 -0
  77. /package/dist/{chunk-6BAMC77N.js.map → chunk-E22PSTUP.js.map} +0 -0
  78. /package/dist/{chunk-DHL4O7MG.js.map → chunk-MBMFYGKN.js.map} +0 -0
  79. /package/dist/{chunk-YBX5BIKL.js.map → chunk-PK5UICGR.js.map} +0 -0
  80. /package/dist/{chunk-4SV3CGNM.js.map → chunk-SFRUUIIC.js.map} +0 -0
  81. /package/dist/{chunk-LSL2M7O6.js.map → chunk-WTMSRIDK.js.map} +0 -0
  82. /package/dist/{credential-KSLGCJU7.js.map → credential-CKO4ZBMU.js.map} +0 -0
  83. /package/dist/{credential-template-WECUNR4X.js.map → credential-template-XOZ2FJ6Z.js.map} +0 -0
  84. /package/dist/{dist-5PKCAL5N.js.map → dist-YPK2RMUK.js.map} +0 -0
  85. /package/dist/{docs-PRUI4LAD.js.map → docs-WZCQ6GP7.js.map} +0 -0
  86. /package/dist/{environment-ATT4UQCY.js.map → environment-KO3JUX3V.js.map} +0 -0
  87. /package/dist/{init-QBMKWGHZ.js.map → init-RXWDJV5I.js.map} +0 -0
  88. /package/dist/{install-BHYIXK6G.js.map → install-Z7EGAEEW.js.map} +0 -0
  89. /package/dist/{issues-JO3OVOV7.js.map → issues-XOU54YKP.js.map} +0 -0
  90. /package/dist/{knobs-4LLJ4LCU.js.map → knobs-7MB2O5SW.js.map} +0 -0
  91. /package/dist/{list-JVJSIK52.js.map → list-5CJZY5BC.js.map} +0 -0
  92. /package/dist/{local-VCZGHODB.js.map → local-XLBE4JIT.js.map} +0 -0
  93. /package/dist/{login-UBNUPK2H.js.map → login-6GDATX4X.js.map} +0 -0
  94. /package/dist/{mcp-2BBNDVZI.js.map → mcp-52UNMEF3.js.map} +0 -0
  95. /package/dist/{metrics-4YOSDGIG.js.map → metrics-4Z5IJZ7U.js.map} +0 -0
  96. /package/dist/{product-T2PVBVZ4.js.map → product-N2R3MWZS.js.map} +0 -0
  97. /package/dist/{prompts-MI4QK2ZM.js.map → prompts-X6FNI6NZ.js.map} +0 -0
  98. /package/dist/{property-EKASZCO7.js.map → property-VUKL5IFR.js.map} +0 -0
  99. /package/dist/{record-Z4NY75FM.js.map → record-AVGKVJK7.js.map} +0 -0
  100. /package/dist/{release-Z7WKFMBS.js.map → release-4QOZ4IP6.js.map} +0 -0
  101. /package/dist/{scenarios-ABYCUJ4O.js.map → scenarios-UZBDO3XR.js.map} +0 -0
  102. /package/dist/{schedule-ZRHOCT5Q.js.map → schedule-XCSZ6NLT.js.map} +0 -0
  103. /package/dist/{session-T7BV73AC.js.map → session-QXHDS5GP.js.map} +0 -0
  104. /package/dist/{spec-QPWXRPAG.js.map → spec-TOUOP4TC.js.map} +0 -0
  105. /package/dist/{src-BH5O6Z3E.js.map → src-YZGG5ZSL.js.map} +0 -0
  106. /package/dist/{start-5BADZ65B.js.map → start-JDLIIBPC.js.map} +0 -0
  107. /package/dist/{tag-CIR6U5LL.js.map → tag-LSS3IOUA.js.map} +0 -0
  108. /package/dist/{task-4YKONXJI.js.map → task-KCNDIT4A.js.map} +0 -0
  109. /package/dist/{test-suite-PRJ2PGMN.js.map → test-suite-MOVN2XL5.js.map} +0 -0
  110. /package/dist/{trace-XVB47RLY.js.map → trace-7OZNMAKV.js.map} +0 -0
  111. /package/dist/{triage-L5WR65KW.js.map → triage-BRSUW4Z7.js.map} +0 -0
  112. /package/dist/{utilities-LBKWREPU.js.map → utilities-TXQGGH37.js.map} +0 -0
  113. /package/dist/{workflow-cache-XWTLXIHE.js.map → workflow-cache-LRH5CAPS.js.map} +0 -0
  114. /package/dist/{workflow-debug-XHR4552F.js.map → workflow-debug-IWXZXSL2.js.map} +0 -0
  115. /package/dist/{workflow-proposals-VWLKW352.js.map → workflow-proposals-76D2MM6G.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  apiRequest,
4
4
  fetchProperties,
5
5
  getApplicationArg
6
- } from "./chunk-LSL2M7O6.js";
6
+ } from "./chunk-WTMSRIDK.js";
7
7
  import {
8
8
  apiFetch,
9
9
  exitOnFailure
@@ -14,7 +14,7 @@ import {
14
14
  resolveConfig
15
15
  } from "./chunk-YBYOOXMK.js";
16
16
  import "./chunk-S3Q7MDCS.js";
17
- import "./chunk-4ZNTGBJR.js";
17
+ import "./chunk-EHKHZ5UR.js";
18
18
  import "./chunk-ZSOAFMES.js";
19
19
  import "./chunk-ICKB3EOT.js";
20
20
 
@@ -470,4 +470,4 @@ async function runCredential(argv) {
470
470
  export {
471
471
  runCredential
472
472
  };
473
- //# sourceMappingURL=credential-KSLGCJU7.js.map
473
+ //# sourceMappingURL=credential-CKO4ZBMU.js.map
@@ -3,7 +3,7 @@ import {
3
3
  apiRequest,
4
4
  fetchProperties,
5
5
  getApplicationArg
6
- } from "./chunk-LSL2M7O6.js";
6
+ } from "./chunk-WTMSRIDK.js";
7
7
  import "./chunk-H3LWYSKY.js";
8
8
  import {
9
9
  getArgValue,
@@ -11,7 +11,7 @@ import {
11
11
  resolveConfig
12
12
  } from "./chunk-YBYOOXMK.js";
13
13
  import "./chunk-S3Q7MDCS.js";
14
- import "./chunk-4ZNTGBJR.js";
14
+ import "./chunk-EHKHZ5UR.js";
15
15
  import "./chunk-ZSOAFMES.js";
16
16
  import "./chunk-ICKB3EOT.js";
17
17
 
@@ -431,4 +431,4 @@ async function runCredentialTemplate(argv) {
431
431
  export {
432
432
  runCredentialTemplate
433
433
  };
434
- //# sourceMappingURL=credential-template-WECUNR4X.js.map
434
+ //# sourceMappingURL=credential-template-XOZ2FJ6Z.js.map
@@ -162,9 +162,9 @@ import {
162
162
  withRecoveryNotice,
163
163
  withRecoveryNoticeMCP,
164
164
  withToolTimeout
165
- } from "./chunk-IFZ72FZV.js";
165
+ } from "./chunk-3X3TSH2B.js";
166
166
  import "./chunk-S3Q7MDCS.js";
167
- import "./chunk-4ZNTGBJR.js";
167
+ import "./chunk-EHKHZ5UR.js";
168
168
  import "./chunk-2EHYDUHX.js";
169
169
  import "./chunk-ICKB3EOT.js";
170
170
  export {
@@ -332,4 +332,4 @@ export {
332
332
  withRecoveryNoticeMCP,
333
333
  withToolTimeout
334
334
  };
335
- //# sourceMappingURL=dist-5PKCAL5N.js.map
335
+ //# sourceMappingURL=dist-YPK2RMUK.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
2
2
  import {
3
3
  apiRequest
4
- } from "./chunk-LSL2M7O6.js";
4
+ } from "./chunk-WTMSRIDK.js";
5
5
  import "./chunk-H3LWYSKY.js";
6
6
  import {
7
7
  getArgValue,
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  getSubDir
13
13
  } from "./chunk-S3Q7MDCS.js";
14
- import "./chunk-4ZNTGBJR.js";
14
+ import "./chunk-EHKHZ5UR.js";
15
15
  import "./chunk-ZSOAFMES.js";
16
16
  import "./chunk-ICKB3EOT.js";
17
17
 
@@ -448,4 +448,4 @@ async function runDocs(argv) {
448
448
  export {
449
449
  runDocs
450
450
  };
451
- //# sourceMappingURL=docs-PRUI4LAD.js.map
451
+ //# sourceMappingURL=docs-WZCQ6GP7.js.map
@@ -2,7 +2,7 @@ import { createRequire as __cr } from "module"; import { fileURLToPath as __fup
2
2
  import {
3
3
  apiRequest,
4
4
  fetchProperties
5
- } from "./chunk-LSL2M7O6.js";
5
+ } from "./chunk-WTMSRIDK.js";
6
6
  import "./chunk-H3LWYSKY.js";
7
7
  import {
8
8
  getArgValue,
@@ -10,7 +10,7 @@ import {
10
10
  resolveConfig
11
11
  } from "./chunk-YBYOOXMK.js";
12
12
  import "./chunk-S3Q7MDCS.js";
13
- import "./chunk-4ZNTGBJR.js";
13
+ import "./chunk-EHKHZ5UR.js";
14
14
  import "./chunk-ZSOAFMES.js";
15
15
  import "./chunk-ICKB3EOT.js";
16
16
 
@@ -218,4 +218,4 @@ async function runEnvironment(argv) {
218
218
  export {
219
219
  runEnvironment
220
220
  };
221
- //# sourceMappingURL=environment-ATT4UQCY.js.map
221
+ //# sourceMappingURL=environment-KO3JUX3V.js.map
@@ -5,7 +5,7 @@ import {
5
5
  getTargetOrg,
6
6
  parseLifecycleStage,
7
7
  toLifecycleLabel
8
- } from "./chunk-LSL2M7O6.js";
8
+ } from "./chunk-WTMSRIDK.js";
9
9
  import "./chunk-H3LWYSKY.js";
10
10
  import {
11
11
  getArgValue,
@@ -13,7 +13,7 @@ import {
13
13
  resolveConfig
14
14
  } from "./chunk-YBYOOXMK.js";
15
15
  import "./chunk-S3Q7MDCS.js";
16
- import "./chunk-4ZNTGBJR.js";
16
+ import "./chunk-EHKHZ5UR.js";
17
17
  import "./chunk-ZSOAFMES.js";
18
18
  import "./chunk-ICKB3EOT.js";
19
19
 
@@ -64,6 +64,16 @@ async function handleList(argv, apiUrl, token) {
64
64
  const product = flag.productCardId ? ` product=${flag.productTitle ?? flag.productCardId}` : "";
65
65
  const rollout = flag.rolloutPercentage === null || flag.rolloutPercentage === void 0 ? "" : ` rollout=${flag.rolloutPercentage}%`;
66
66
  console.log(` ${flag.name} ${flag.description ?? ""} (${lifecycle}${finalValue})${bake}${rollout} [orgs=${orgCount}, users=${userCount}]${product}${stale}`);
67
+ for (const org of flag.organizations ?? []) {
68
+ const parts = [];
69
+ if (org.rolloutPercentageOverride !== null && org.rolloutPercentageOverride !== void 0) {
70
+ parts.push(`rollout override ${org.rolloutPercentageOverride}%`);
71
+ }
72
+ if (org.excludeFromAnalysis) parts.push("excluded from analysis");
73
+ if (parts.length) {
74
+ console.log(` \u21B3 ${org.orgName}: ${parts.join(", ")}`);
75
+ }
76
+ }
67
77
  }
68
78
  }
69
79
  async function handleCreate(argv, apiUrl, token) {
@@ -204,18 +214,63 @@ async function handleEnable(argv, apiUrl, token) {
204
214
  console.error("Usage: canary feature-flag enable <name> (--target-org <orgId> | --user <userId>)");
205
215
  process.exit(1);
206
216
  }
217
+ const overrideRaw = getArgValue(argv, "--rollout-override");
218
+ const excludeFromAnalysis = hasFlag(argv, "--exclude-from-analysis");
219
+ const includeInAnalysis = hasFlag(argv, "--include-in-analysis");
220
+ if (excludeFromAnalysis && includeInAnalysis) {
221
+ console.error("Error: Provide either --exclude-from-analysis or --include-in-analysis, not both.");
222
+ process.exit(1);
223
+ }
224
+ const rolloutConfigProvided = overrideRaw !== void 0 || excludeFromAnalysis || includeInAnalysis;
225
+ if (userId && rolloutConfigProvided) {
226
+ console.error("Error: --rollout-override / --exclude-from-analysis apply to org gates only (use --target-org).");
227
+ process.exit(1);
228
+ }
229
+ let rolloutPercentageOverride;
230
+ if (overrideRaw !== void 0) {
231
+ if (overrideRaw === "clear") {
232
+ rolloutPercentageOverride = null;
233
+ } else {
234
+ const parsed = Number.parseInt(overrideRaw, 10);
235
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 100) {
236
+ console.error("Error: --rollout-override must be an integer 0-100 or 'clear'.");
237
+ process.exit(1);
238
+ }
239
+ rolloutPercentageOverride = parsed;
240
+ }
241
+ }
242
+ let excludeFlag;
243
+ if (excludeFromAnalysis) excludeFlag = true;
244
+ else if (includeInAnalysis) excludeFlag = false;
207
245
  if (orgId) {
246
+ const body = {};
247
+ if (rolloutPercentageOverride !== void 0) {
248
+ body.rolloutPercentageOverride = rolloutPercentageOverride;
249
+ }
250
+ if (excludeFlag !== void 0) body.excludeFromAnalysis = excludeFlag;
208
251
  const result = await apiRequest(
209
252
  apiUrl,
210
253
  token,
211
254
  "POST",
212
- `/superadmin/feature-flags/${encodeURIComponent(name)}/organizations/${encodeURIComponent(orgId)}`
255
+ `/superadmin/feature-flags/${encodeURIComponent(name)}/organizations/${encodeURIComponent(orgId)}`,
256
+ body
213
257
  );
214
258
  if (!result.ok) {
215
259
  console.error(`Error: ${result.error}`);
216
260
  process.exit(1);
217
261
  }
218
- console.log(`Enabled ${name} for org ${orgId}`);
262
+ const suffix = [];
263
+ if (rolloutPercentageOverride !== void 0) {
264
+ suffix.push(
265
+ rolloutPercentageOverride === null ? "rollout override cleared" : `rollout override ${rolloutPercentageOverride}%`
266
+ );
267
+ }
268
+ if (excludeFlag !== void 0) {
269
+ suffix.push(excludeFlag ? "excluded from analysis" : "included in analysis");
270
+ }
271
+ console.log(
272
+ `Enabled ${name} for org ${orgId}${suffix.length ? ` (${suffix.join(", ")})` : ""}`
273
+ );
219
274
  } else {
220
275
  const result = await apiRequest(
221
276
  apiUrl,
@@ -626,6 +681,9 @@ function printFeatureFlagHelp() {
626
681
  " delete <name> Delete a flag and all its gates",
627
682
  " enable <name> (--target-org <orgId> | --user <userId>)",
628
683
  " Enable a flag for an org or user",
684
+ " [--rollout-override <0-100|clear>] [--exclude-from-analysis | --include-in-analysis]",
685
+ " Per-org (--target-org) rollout override + A-B analysis exclusion;",
686
+ " may also update an already-enabled org in place",
629
687
  " disable <name> (--target-org <orgId> | --user <userId>)",
630
688
  " Disable a flag for an org or user (kept as 'was enabled' history)",
631
689
  " lifecycle <name> --stage <stage> [--final-value true|false]",
@@ -712,4 +770,4 @@ async function runFeatureFlag(argv) {
712
770
  export {
713
771
  runFeatureFlag
714
772
  };
715
- //# sourceMappingURL=feature-flag-MWIHVJER.js.map
773
+ //# sourceMappingURL=feature-flag-4YPPF27F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/feature-flag.ts"],"sourcesContent":["/**\n * CLI Feature Flag Management\n *\n * Allows superadmins to manage feature flags via the CLI.\n */\n\nimport process from \"node:process\";\nimport { readFileSync } from \"node:fs\";\nimport { resolveConfig, getArgValue, hasFlag } from \"./auth.js\";\nimport {\n type LifecycleStage,\n toLifecycleLabel,\n parseLifecycleStage,\n apiRequest,\n fetchList,\n getTargetOrg,\n} from \"./cli-helpers.js\";\n\n/** Resolve a `--plan @file.md` (read file) or inline string value. */\nfunction readContent(value: string): string {\n if (value.startsWith(\"@\")) {\n return readFileSync(value.slice(1), \"utf8\");\n }\n return value;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_REVIEW_INTERVAL_DAYS = 7;\nconst DEFAULT_MAX_WINDOW_DAYS = 30;\n\n/** Bake age (days) + burning state from a flag's bake metadata. */\nfunction bakeStatus(flag: {\n bakeStartedAt?: string | null;\n bakeMaxWindowDays?: number | null;\n}): { ageDays: number; burning: boolean } {\n if (!flag.bakeStartedAt) return { ageDays: 0, burning: false };\n const startedMs = new Date(flag.bakeStartedAt).getTime();\n const ageMs = Date.now() - startedMs;\n const maxWindow = flag.bakeMaxWindowDays ?? DEFAULT_MAX_WINDOW_DAYS;\n return { ageDays: Math.floor(ageMs / DAY_MS), burning: ageMs > maxWindow * DAY_MS };\n}\n\n/** ` baking 4d 🔥` style suffix for list rows. */\nfunction formatBakeSuffix(flag: {\n bakeStartedAt?: string | null;\n bakeMaxWindowDays?: number | null;\n}): string {\n const { ageDays, burning } = bakeStatus(flag);\n return ` baked=${ageDays}d${burning ? \" 🔥BURNING\" : \"\"}`;\n}\n\ntype FeatureFlag = {\n id: string;\n name: string;\n description: string | null;\n lifecycleStage: LifecycleStage;\n finalValue: boolean | null;\n bakeMonitoringPlan?: string | null;\n bakeStartedAt?: string | null;\n bakeReviewIntervalDays?: number | null;\n bakeMaxWindowDays?: number | null;\n createdAt: string;\n lastToggledAt: string;\n isStale: boolean;\n rolloutPercentage?: number | null;\n productCardId: string | null;\n productTitle: string | null;\n organizations?: Array<{\n gateId: string;\n orgId: string;\n orgName: string;\n createdAt: string;\n rolloutPercentageOverride?: number | null;\n excludeFromAnalysis?: boolean;\n }>;\n users?: Array<{\n gateId: string;\n userId: string;\n userEmail: string | null;\n createdAt: string;\n }>;\n};\n\ntype FlagApiResponse = {\n ok: boolean;\n error?: string;\n flag?: FeatureFlag;\n};\n\ntype ProductCard = {\n id: string;\n title: string;\n stage: string;\n orgId: string;\n orgName: string;\n};\n\nfunction fetchFlags(apiUrl: string, token: string): Promise<FeatureFlag[]> {\n return fetchList<FeatureFlag>(apiUrl, token, \"/superadmin/feature-flags\", \"flags\");\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, \"--json\");\n const flags = await fetchFlags(apiUrl, token);\n\n if (jsonOutput) {\n console.log(JSON.stringify(flags, null, 2));\n return;\n }\n\n if (flags.length === 0) {\n console.log(\"No feature flags found.\");\n return;\n }\n\n for (const flag of flags) {\n const orgCount = flag.organizations?.length ?? 0;\n const userCount = flag.users?.length ?? 0;\n const lifecycle = `lifecycle=${toLifecycleLabel(flag.lifecycleStage)}`;\n // baking and internal are gate-driven like active — no final value.\n const finalValue =\n flag.lifecycleStage === \"active\" ||\n flag.lifecycleStage === \"baking\" ||\n flag.lifecycleStage === \"internal\"\n ? \"\"\n : ` final=${flag.finalValue === true ? \"true\" : \"false\"}`;\n const bake = flag.lifecycleStage === \"baking\" ? formatBakeSuffix(flag) : \"\";\n const stale = flag.isStale ? \" [STALE]\" : \"\";\n const product = flag.productCardId\n ? ` product=${flag.productTitle ?? flag.productCardId}`\n : \"\";\n const rollout =\n flag.rolloutPercentage === null || flag.rolloutPercentage === undefined\n ? \"\"\n : ` rollout=${flag.rolloutPercentage}%`;\n console.log(` ${flag.name} ${flag.description ?? \"\"} (${lifecycle}${finalValue})${bake}${rollout} [orgs=${orgCount}, users=${userCount}]${product}${stale}`);\n\n // Surface per-org rollout overrides / analysis exclusions (only the gates\n // that deviate from the flag default, to keep the listing quiet).\n for (const org of flag.organizations ?? []) {\n const parts: string[] = [];\n if (org.rolloutPercentageOverride !== null && org.rolloutPercentageOverride !== undefined) {\n parts.push(`rollout override ${org.rolloutPercentageOverride}%`);\n }\n if (org.excludeFromAnalysis) parts.push(\"excluded from analysis\");\n if (parts.length) {\n console.log(` ↳ ${org.orgName}: ${parts.join(\", \")}`);\n }\n }\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag create <name> [--description <text>] [--product <productCardId>]\");\n process.exit(1);\n }\n\n const description = getArgValue(argv, \"--description\") ?? null;\n const productCardId = getArgValue(argv, \"--product\") ?? null;\n const result = await apiRequest<FlagApiResponse>(apiUrl, token, \"POST\", \"/superadmin/feature-flags\", {\n name,\n description,\n productCardId,\n });\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Created feature flag: ${name}${productCardId ? ` (product ${productCardId})` : \"\"}`);\n}\n\nasync function handleProduct(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n const productCardId = getArgValue(argv, \"--product\");\n const clear = hasFlag(argv, \"--clear\");\n\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag product <name> (--product <productCardId> | --clear)\");\n process.exit(1);\n }\n\n if ((productCardId && clear) || (!productCardId && !clear)) {\n console.error(\"Error: Provide either --product <productCardId> or --clear.\");\n process.exit(1);\n }\n\n const result = await apiRequest<FlagApiResponse & { flag?: { productTitle?: string | null } }>(\n apiUrl, token, \"POST\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/product`,\n { productCardId: clear ? null : productCardId }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(\n clear\n ? `Cleared product link for ${name}`\n : `Linked ${name} to product ${result.flag?.productTitle ?? productCardId}`\n );\n}\n\nasync function handleRollout(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n const raw = getArgValue(argv, \"--percentage\");\n const clear = hasFlag(argv, \"--clear\");\n\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag rollout <name> (--percentage <0-100> | --clear)\");\n process.exit(1);\n }\n\n if ((raw !== undefined && clear) || (raw === undefined && !clear)) {\n console.error(\"Error: Provide either --percentage <0-100> or --clear.\");\n process.exit(1);\n }\n\n let rolloutPercentage: number | null = null;\n if (!clear) {\n rolloutPercentage = Number.parseInt(raw as string, 10);\n if (!Number.isInteger(rolloutPercentage) || rolloutPercentage < 0 || rolloutPercentage > 100) {\n console.error(\"Error: --percentage must be an integer 0-100.\");\n process.exit(1);\n }\n }\n\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"POST\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/rollout`,\n { rolloutPercentage }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(\n clear\n ? `Cleared rollout for ${name} (legacy gate=on behavior)`\n : `Set ${name} rollout to ${rolloutPercentage}% treatment`\n );\n}\n\nasync function handleProducts(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, \"--json\");\n const search = getArgValue(argv, \"--search\");\n const path = search\n ? `/superadmin/product-cards?search=${encodeURIComponent(search)}`\n : \"/superadmin/product-cards\";\n const products = await fetchList<ProductCard>(apiUrl, token, path, \"products\");\n\n if (jsonOutput) {\n console.log(JSON.stringify(products, null, 2));\n return;\n }\n\n if (products.length === 0) {\n console.log(\"No product cards found.\");\n return;\n }\n\n for (const product of products) {\n console.log(` ${product.id} ${product.title} (stage=${product.stage}, org=${product.orgName})`);\n }\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag delete <name>\");\n process.exit(1);\n }\n\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"DELETE\", `/superadmin/feature-flags/${encodeURIComponent(name)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Deleted feature flag: ${name}`);\n}\n\nasync function handleEnable(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n const orgId = getTargetOrg(argv);\n const userId = getArgValue(argv, \"--user\");\n\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag enable <name> (--target-org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId && userId) {\n console.error(\"Error: Provide either --target-org or --user, not both.\");\n process.exit(1);\n }\n\n if (!orgId && !userId) {\n console.error(\"Error: Provide either --target-org <orgId> or --user <userId>.\");\n console.error(\"Usage: canary feature-flag enable <name> (--target-org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n // Per-org rollout config (org gates only). --rollout-override <0-100|clear>\n // sets a per-org override of the flag's global %; --exclude-from-analysis /\n // --include-in-analysis toggle whether this org's runs count in the A-B stats.\n const overrideRaw = getArgValue(argv, \"--rollout-override\");\n const excludeFromAnalysis = hasFlag(argv, \"--exclude-from-analysis\");\n const includeInAnalysis = hasFlag(argv, \"--include-in-analysis\");\n\n if (excludeFromAnalysis && includeInAnalysis) {\n console.error(\"Error: Provide either --exclude-from-analysis or --include-in-analysis, not both.\");\n process.exit(1);\n }\n\n const rolloutConfigProvided =\n overrideRaw !== undefined || excludeFromAnalysis || includeInAnalysis;\n if (userId && rolloutConfigProvided) {\n console.error(\"Error: --rollout-override / --exclude-from-analysis apply to org gates only (use --target-org).\");\n process.exit(1);\n }\n\n let rolloutPercentageOverride: number | null | undefined;\n if (overrideRaw !== undefined) {\n if (overrideRaw === \"clear\") {\n rolloutPercentageOverride = null;\n } else {\n const parsed = Number.parseInt(overrideRaw, 10);\n if (!Number.isInteger(parsed) || parsed < 0 || parsed > 100) {\n console.error(\"Error: --rollout-override must be an integer 0-100 or 'clear'.\");\n process.exit(1);\n }\n rolloutPercentageOverride = parsed;\n }\n }\n\n let excludeFlag: boolean | undefined;\n if (excludeFromAnalysis) excludeFlag = true;\n else if (includeInAnalysis) excludeFlag = false;\n\n if (orgId) {\n const body: Record<string, unknown> = {};\n if (rolloutPercentageOverride !== undefined) {\n body.rolloutPercentageOverride = rolloutPercentageOverride;\n }\n if (excludeFlag !== undefined) body.excludeFromAnalysis = excludeFlag;\n\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"POST\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/organizations/${encodeURIComponent(orgId)}`,\n body\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n const suffix: string[] = [];\n if (rolloutPercentageOverride !== undefined) {\n suffix.push(\n rolloutPercentageOverride === null\n ? \"rollout override cleared\"\n : `rollout override ${rolloutPercentageOverride}%`\n );\n }\n if (excludeFlag !== undefined) {\n suffix.push(excludeFlag ? \"excluded from analysis\" : \"included in analysis\");\n }\n console.log(\n `Enabled ${name} for org ${orgId}${suffix.length ? ` (${suffix.join(\", \")})` : \"\"}`\n );\n } else {\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"POST\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/users/${encodeURIComponent(userId!)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Enabled ${name} for user ${userId}`);\n }\n}\n\nasync function handleDisable(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n const orgId = getTargetOrg(argv);\n const userId = getArgValue(argv, \"--user\");\n\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag disable <name> (--target-org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId && userId) {\n console.error(\"Error: Provide either --target-org or --user, not both.\");\n process.exit(1);\n }\n\n if (!orgId && !userId) {\n console.error(\"Error: Provide either --target-org <orgId> or --user <userId>.\");\n console.error(\"Usage: canary feature-flag disable <name> (--target-org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId) {\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"DELETE\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/organizations/${encodeURIComponent(orgId)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Disabled ${name} for org ${orgId}`);\n } else {\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"DELETE\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/users/${encodeURIComponent(userId!)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Disabled ${name} for user ${userId}`);\n }\n}\n\nasync function handleLifecycle(argv: string[], apiUrl: string, token: string): Promise<void> {\n const name = argv[0];\n\n if (!name || name.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error(\"Usage: canary feature-flag lifecycle <name> --stage <active|baking|internal|deprecated|ready_for_cleanup> [--final-value true|false] [--plan @file|\\\"text\\\"] [--review-interval <days>] [--max-window <days>]\");\n process.exit(1);\n }\n\n const stage = parseLifecycleStage(argv);\n const rawFinalValue = getArgValue(argv, \"--final-value\");\n const clearFinalValue = hasFlag(argv, \"--clear-final-value\");\n\n // active, baking and internal are gate-driven (no final value); deprecated\n // and ready_for_cleanup carry a forced final value.\n const gateDriven = stage === \"active\" || stage === \"baking\" || stage === \"internal\";\n\n if (rawFinalValue !== undefined && clearFinalValue) {\n console.error(\"Error: use either --final-value or --clear-final-value, not both.\");\n process.exit(1);\n }\n\n let finalValue: boolean | undefined = undefined;\n\n if (gateDriven) {\n if (rawFinalValue !== undefined) {\n console.error(`Error: ${stage} stage does not accept --final-value.`);\n process.exit(1);\n }\n finalValue = undefined;\n } else {\n if (clearFinalValue) {\n console.error(\"Error: --clear-final-value can only be used with --stage active.\");\n process.exit(1);\n }\n if (!rawFinalValue) {\n console.error(\"Error: --final-value true|false is required for deprecated or ready_for_cleanup.\");\n process.exit(1);\n }\n if (rawFinalValue !== \"true\" && rawFinalValue !== \"false\") {\n console.error(\"Error: --final-value must be true or false.\");\n process.exit(1);\n }\n finalValue = rawFinalValue === \"true\";\n }\n\n // Oven (baking) options: monitoring plan + review cadence.\n let monitoringPlan: string | undefined;\n let reviewIntervalDays: number | undefined;\n let maxWindowDays: number | undefined;\n if (stage === \"baking\") {\n const rawPlan = getArgValue(argv, \"--plan\");\n if (rawPlan !== undefined) monitoringPlan = readContent(rawPlan);\n const rawInterval = getArgValue(argv, \"--review-interval\");\n if (rawInterval !== undefined) {\n reviewIntervalDays = Number.parseInt(rawInterval, 10);\n if (!Number.isInteger(reviewIntervalDays) || reviewIntervalDays <= 0) {\n console.error(\"Error: --review-interval must be a positive integer (days).\");\n process.exit(1);\n }\n }\n const rawWindow = getArgValue(argv, \"--max-window\");\n if (rawWindow !== undefined) {\n maxWindowDays = Number.parseInt(rawWindow, 10);\n if (!Number.isInteger(maxWindowDays) || maxWindowDays <= 0) {\n console.error(\"Error: --max-window must be a positive integer (days).\");\n process.exit(1);\n }\n }\n }\n\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"POST\",\n `/superadmin/feature-flags/${encodeURIComponent(name)}/lifecycle`,\n { stage, finalValue, monitoringPlan, reviewIntervalDays, maxWindowDays }\n );\n\n if (!result.ok || !result.flag) {\n console.error(`Error: ${result.error ?? \"Failed to update lifecycle\"}`);\n process.exit(1);\n }\n\n if (result.flag.lifecycleStage === \"baking\") {\n const { ageDays } = bakeStatus(result.flag);\n console.log(\n `Put ${name} in the oven: stage=baking, baked=${ageDays}d, review every ${result.flag.bakeReviewIntervalDays ?? DEFAULT_REVIEW_INTERVAL_DAYS}d, burns after ${result.flag.bakeMaxWindowDays ?? DEFAULT_MAX_WINDOW_DAYS}d.`\n );\n return;\n }\n\n const final =\n result.flag.lifecycleStage === \"active\" || result.flag.lifecycleStage === \"internal\"\n ? \"(none)\"\n : result.flag.finalValue === true\n ? \"true\"\n : \"false\";\n console.log(`Updated lifecycle for ${name}: stage=${toLifecycleLabel(result.flag.lifecycleStage)}, final=${final}`);\n}\n\ntype OvenFlag = {\n id: string;\n name: string;\n description: string | null;\n productCardId: string | null;\n productTitle: string | null;\n bakeMonitoringPlan: string | null;\n bakeStartedAt: string | null;\n bakeReviewIntervalDays: number;\n bakeMaxWindowDays: number;\n bakeAgeDays: number;\n burning: boolean;\n};\n\nasync function handleOven(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, \"--json\");\n const flags = await fetchList<OvenFlag>(apiUrl, token, \"/superadmin/feature-flags/oven\", \"flags\");\n\n if (jsonOutput) {\n console.log(JSON.stringify(flags, null, 2));\n return;\n }\n\n if (flags.length === 0) {\n console.log(\"The oven is empty — no flags are baking.\");\n return;\n }\n\n console.log(`In the oven (${flags.length}):`);\n for (const flag of flags) {\n const burn = flag.burning ? \" 🔥BURNING\" : \"\";\n const product = flag.productCardId ? ` product=${flag.productTitle ?? flag.productCardId}` : \"\";\n console.log(\n ` ${flag.name} baked=${flag.bakeAgeDays}d (review ${flag.bakeReviewIntervalDays}d / burns ${flag.bakeMaxWindowDays}d)${burn}${product}`\n );\n if (flag.bakeMonitoringPlan) {\n const firstLine = flag.bakeMonitoringPlan.split(\"\\n\")[0]?.slice(0, 100) ?? \"\";\n console.log(` plan: ${firstLine}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Announcements — messages attached to a flag, shown when the flag is on/GA'd.\n// A same-domain flag sub-attribute (like `product` / `rollout`), reached as\n// `feature-flag announcement <sub> …`.\n// ---------------------------------------------------------------------------\n\ntype AnnouncementConfig = {\n uiComponent: string;\n title: string;\n body: string;\n ctaLabel?: string;\n ctaHref?: string;\n dismissLabel?: string;\n};\n\ntype Announcement = {\n id: string;\n flagName: string;\n uiComponent: string;\n config: AnnouncementConfig;\n seenScope: \"user\" | \"org\";\n active: boolean;\n expiresAt: string | null;\n createdAt: string;\n updatedAt: string;\n viewCount?: number;\n};\n\ntype AnnouncementApiResponse = {\n ok: boolean;\n error?: string;\n announcement?: Announcement;\n};\n\n/** Resolve `--ttl 7d|12h|30m` into an absolute ISO expiry, or undefined. */\nfunction parseTtlToIso(ttl: string): string {\n const match = /^(\\d+)([dhm])$/.exec(ttl.trim());\n if (!match) {\n console.error(\"Error: --ttl must look like 7d, 12h, or 30m.\");\n process.exit(1);\n }\n const n = Number.parseInt(match[1], 10);\n const unitMs = match[2] === \"d\" ? 86_400_000 : match[2] === \"h\" ? 3_600_000 : 60_000;\n return new Date(Date.now() + n * unitMs).toISOString();\n}\n\nasync function handleAnnouncementCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const flag = argv[0];\n if (!flag || flag.startsWith(\"--\")) {\n console.error(\"Error: Missing flag name.\");\n console.error('Usage: canary feature-flag announcement create <flag> --title <t> --body @file|\"text\" [--scope user|org] [--ttl 7d|--expires <iso>] [--cta-label <l> --cta-href <url>] [--dismiss-label <l>] [--inactive]');\n process.exit(1);\n }\n\n const title = getArgValue(argv, \"--title\");\n const rawBody = getArgValue(argv, \"--body\");\n if (!title || !rawBody) {\n console.error(\"Error: --title and --body are required.\");\n process.exit(1);\n }\n const body = readContent(rawBody);\n\n const scope = getArgValue(argv, \"--scope\");\n if (scope !== undefined && scope !== \"user\" && scope !== \"org\") {\n console.error(\"Error: --scope must be user or org.\");\n process.exit(1);\n }\n\n const ctaLabel = getArgValue(argv, \"--cta-label\");\n const ctaHref = getArgValue(argv, \"--cta-href\");\n if ((ctaLabel && !ctaHref) || (!ctaLabel && ctaHref)) {\n console.error(\"Error: --cta-label and --cta-href must be provided together.\");\n process.exit(1);\n }\n const dismissLabel = getArgValue(argv, \"--dismiss-label\");\n const component = getArgValue(argv, \"--component\") ?? \"interstitial_dialog\";\n\n const ttl = getArgValue(argv, \"--ttl\");\n const expires = getArgValue(argv, \"--expires\");\n if (ttl && expires) {\n console.error(\"Error: provide either --ttl or --expires, not both.\");\n process.exit(1);\n }\n const expiresAt = ttl ? parseTtlToIso(ttl) : (expires ?? null);\n\n const config: AnnouncementConfig = {\n uiComponent: component,\n title,\n body,\n ...(ctaLabel && ctaHref ? { ctaLabel, ctaHref } : {}),\n ...(dismissLabel ? { dismissLabel } : {}),\n };\n\n const result = await apiRequest<AnnouncementApiResponse>(\n apiUrl, token, \"POST\", \"/superadmin/announcements\",\n {\n flagName: flag,\n config,\n seenScope: scope,\n active: hasFlag(argv, \"--inactive\") ? false : undefined,\n expiresAt,\n }\n );\n\n if (!result.ok || !result.announcement) {\n console.error(`Error: ${result.error ?? \"Failed to create announcement\"}`);\n process.exit(1);\n }\n\n console.log(\n `Created announcement ${result.announcement.id} for ${flag} (scope=${result.announcement.seenScope}${expiresAt ? `, expires ${expiresAt}` : \"\"})`\n );\n}\n\nasync function handleAnnouncementList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, \"--json\");\n const flag = argv[0] && !argv[0].startsWith(\"--\") ? argv[0] : undefined;\n const path = flag\n ? `/superadmin/announcements?flagName=${encodeURIComponent(flag)}`\n : \"/superadmin/announcements\";\n const announcements = await fetchList<Announcement>(apiUrl, token, path, \"announcements\");\n\n if (jsonOutput) {\n console.log(JSON.stringify(announcements, null, 2));\n return;\n }\n\n if (announcements.length === 0) {\n console.log(\"No announcements found.\");\n return;\n }\n\n const now = Date.now();\n for (const a of announcements) {\n const expired = a.expiresAt ? new Date(a.expiresAt).getTime() <= now : false;\n const state = !a.active ? \"inactive\" : expired ? \"expired\" : \"live\";\n const expiry = a.expiresAt ? ` expires=${a.expiresAt}` : \"\";\n console.log(\n ` ${a.id} flag=${a.flagName} [${state}] scope=${a.seenScope} views=${a.viewCount ?? 0}${expiry}`\n );\n console.log(` ${a.config.title}`);\n }\n}\n\nasync function handleAnnouncementSetActive(argv: string[], apiUrl: string, token: string, active: boolean): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith(\"--\")) {\n console.error(`Error: Missing announcement id.\\nUsage: canary feature-flag announcement ${active ? \"activate\" : \"deactivate\"} <id>`);\n process.exit(1);\n }\n const result = await apiRequest<AnnouncementApiResponse>(\n apiUrl, token, \"POST\", `/superadmin/announcements/${encodeURIComponent(id)}/active`, { active }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`${active ? \"Activated\" : \"Deactivated\"} announcement ${id}`);\n}\n\nasync function handleAnnouncementExpire(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith(\"--\")) {\n console.error(\"Error: Missing announcement id.\\nUsage: canary feature-flag announcement expire <id>\");\n process.exit(1);\n }\n const result = await apiRequest<AnnouncementApiResponse>(\n apiUrl, token, \"POST\", `/superadmin/announcements/${encodeURIComponent(id)}`,\n { expiresAt: new Date().toISOString() }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`Expired announcement ${id} (no longer shows)`);\n}\n\nasync function handleAnnouncementViews(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith(\"--\")) {\n console.error(\"Error: Missing announcement id.\\nUsage: canary feature-flag announcement views <id>\");\n process.exit(1);\n }\n const jsonOutput = hasFlag(argv, \"--json\");\n const result = await apiRequest<{\n ok: boolean;\n error?: string;\n count?: number;\n views?: Array<{ userId: string; userEmail: string | null; orgId: string; seenAt: string }>;\n }>(apiUrl, token, \"GET\", `/superadmin/announcements/${encodeURIComponent(id)}/views`);\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const views = result.views ?? [];\n console.log(`${result.count ?? views.length} view(s) for ${id}:`);\n for (const v of views) {\n console.log(` ${v.userEmail ?? v.userId} org=${v.orgId} ${v.seenAt}`);\n }\n}\n\nasync function handleAnnouncementDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith(\"--\")) {\n console.error(\"Error: Missing announcement id.\\nUsage: canary feature-flag announcement delete <id>\");\n process.exit(1);\n }\n const result = await apiRequest<AnnouncementApiResponse>(\n apiUrl, token, \"DELETE\", `/superadmin/announcements/${encodeURIComponent(id)}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`Deleted announcement ${id}`);\n}\n\nfunction printAnnouncementHelp(): void {\n console.log(\n [\n \"Usage: canary feature-flag announcement <sub-command> [options]\",\n \"\",\n \"Attach an announcement (interstitial dialog) to a flag. Shows to users for\",\n \"whom the flag is turned on or GA'd, until they've seen it or the TTL passes.\",\n \"\",\n \"Sub-commands:\",\n ' create <flag> --title <t> --body @file|\"text\" [--scope user|org] [--ttl 7d|--expires <iso>]',\n \" [--cta-label <l> --cta-href <url>] [--dismiss-label <l>] [--inactive]\",\n \" list [<flag>] [--json] List announcements (optionally for one flag) + view counts\",\n \" activate <id> Turn the kill-switch on\",\n \" deactivate <id> Turn the kill-switch off (stops showing)\",\n \" expire <id> Set expiry to now (stops showing, keeps history)\",\n \" views <id> [--json] Show the recorded view log\",\n \" delete <id> Delete an announcement (and its views)\",\n \"\",\n \"Options:\",\n \" --scope user|org Seen de-dup: per-user (default) or per-org (first viewer suppresses for all)\",\n \" --ttl 7d|12h|30m Relative expiry (mutually exclusive with --expires)\",\n \" --expires <iso> Absolute ISO 8601 expiry\",\n \" --inactive Create paused (won't show until activated)\",\n ].join(\"\\n\")\n );\n}\n\nasync function runAnnouncement(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [sub, ...rest] = argv;\n if (!sub || sub === \"help\" || hasFlag(argv, \"--help\", \"-h\")) {\n printAnnouncementHelp();\n return;\n }\n switch (sub) {\n case \"create\":\n await handleAnnouncementCreate(rest, apiUrl, token);\n break;\n case \"list\":\n await handleAnnouncementList(rest, apiUrl, token);\n break;\n case \"activate\":\n await handleAnnouncementSetActive(rest, apiUrl, token, true);\n break;\n case \"deactivate\":\n await handleAnnouncementSetActive(rest, apiUrl, token, false);\n break;\n case \"expire\":\n await handleAnnouncementExpire(rest, apiUrl, token);\n break;\n case \"views\":\n await handleAnnouncementViews(rest, apiUrl, token);\n break;\n case \"delete\":\n await handleAnnouncementDelete(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown announcement sub-command: ${sub}`);\n printAnnouncementHelp();\n process.exit(1);\n }\n}\n\nfunction printFeatureFlagHelp(): void {\n console.log(\n [\n \"Usage: canary feature-flag <sub-command> [options]\",\n \"\",\n \"Sub-commands:\",\n \" list List all feature flags\",\n \" create <name> [--description <text>] [--product <productCardId>]\",\n \" Create a new flag (optionally linked to a product)\",\n \" delete <name> Delete a flag and all its gates\",\n \" enable <name> (--target-org <orgId> | --user <userId>)\",\n \" Enable a flag for an org or user\",\n \" [--rollout-override <0-100|clear>] [--exclude-from-analysis | --include-in-analysis]\",\n \" Per-org (--target-org) rollout override + A-B analysis exclusion;\",\n \" may also update an already-enabled org in place\",\n \" disable <name> (--target-org <orgId> | --user <userId>)\",\n \" Disable a flag for an org or user (kept as 'was enabled' history)\",\n \" lifecycle <name> --stage <stage> [--final-value true|false]\",\n \" Mark lifecycle + final value\",\n \" --stage baking --plan @file [--review-interval <days>] [--max-window <days>]\",\n \" Put a flag in the oven (requires a linked product card)\",\n \" product <name> (--product <productCardId> | --clear)\",\n \" Link/unlink a flag to a product board item\",\n \" rollout <name> (--percentage <0-100> | --clear)\",\n \" Set the A-B / rollout treatment % (per-run coin flip; clear = legacy gate=on)\",\n \" products [--search <text>] List product board items (find product card ids)\",\n \" oven [--json] List flags currently baking (age + burning state)\",\n \" announcement <sub> ... Manage a flag's announcement message (see `announcement help`)\",\n \"\",\n \"Stages: active, baking, internal, deprecated, ready_for_cleanup\",\n \" internal: long-lived internal-only product (gated to internal orgs only; drives the Internal board column)\",\n \"\",\n \"Options:\",\n \" --target-org <orgId> Target organization (cross-org superadmin action)\",\n \" --user <userId> Target user\",\n \" --product <productCardId> Product board item (cards.id) to link\",\n \" --percentage <0-100> Treatment-assignment % (rollout sub-command); ramp up to roll out gradually\",\n \" --clear Clear the product link / rollout % (product or rollout sub-command)\",\n \" --search <text> Filter product cards by title (products sub-command only)\",\n \" --final-value <true|false> Final value for deprecated/ready_for_cleanup\",\n \" --clear-final-value Clear final value (only valid with --stage active)\",\n \" --plan @file|\\\"text\\\" Monitoring/telemetry plan (required to enter baking)\",\n \" --review-interval <days> Days between oven-check reviews (baking; default 7)\",\n \" --max-window <days> Days before a baking flag 'burns' (default 30)\",\n \" --env <env> Target environment (prod, dev, local)\",\n \" --json Output as JSON (list only)\",\n \" --api-url <url> API URL override (takes precedence over --env)\",\n \" --token <key> API token override\",\n ].join(\"\\n\")\n );\n}\n\nexport async function runFeatureFlag(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === \"help\" || hasFlag(argv, \"--help\", \"-h\")) {\n printFeatureFlagHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case \"list\":\n await handleList(rest, apiUrl, token);\n break;\n case \"create\":\n await handleCreate(rest, apiUrl, token);\n break;\n case \"delete\":\n await handleDelete(rest, apiUrl, token);\n break;\n case \"enable\":\n await handleEnable(rest, apiUrl, token);\n break;\n case \"disable\":\n await handleDisable(rest, apiUrl, token);\n break;\n case \"lifecycle\":\n await handleLifecycle(rest, apiUrl, token);\n break;\n case \"product\":\n await handleProduct(rest, apiUrl, token);\n break;\n case \"rollout\":\n await handleRollout(rest, apiUrl, token);\n break;\n case \"products\":\n await handleProducts(rest, apiUrl, token);\n break;\n case \"oven\":\n await handleOven(rest, apiUrl, token);\n break;\n case \"announcement\":\n await runAnnouncement(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printFeatureFlagHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}