@runcofactor/cli 0.15.2 → 0.17.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 (141) hide show
  1. package/dist/{account-62I7FG5G.js → account-ZSM2Q3RB.js} +6 -6
  2. package/dist/account-ZSM2Q3RB.js.map +1 -0
  3. package/dist/{api-catalog-CAJUASVC.js → api-catalog-MMPFWS52.js} +5 -5
  4. package/dist/{attachment-RL4AZUJE.js → attachment-NSYL5X3S.js} +5 -5
  5. package/dist/{augmentor-GAF3MFY6.js → augmentor-LSJLMJYP.js} +5 -5
  6. package/dist/{auth-DURHUZDW.js → auth-OYF5A4BY.js} +4 -2
  7. package/dist/{chunk-26U3DGUM.js → chunk-7YJTQCPX.js} +3 -5
  8. package/dist/chunk-7YJTQCPX.js.map +1 -0
  9. package/dist/{chunk-PXFDH6YL.js → chunk-A4ISG3VX.js} +55 -15
  10. package/dist/{chunk-PXFDH6YL.js.map → chunk-A4ISG3VX.js.map} +1 -1
  11. package/dist/{chunk-4NRDONSC.js → chunk-FGB6PS2T.js} +4 -4
  12. package/dist/chunk-FGB6PS2T.js.map +1 -0
  13. package/dist/{chunk-VKBTI5EF.js → chunk-GFP4UEUT.js} +3 -3
  14. package/dist/{chunk-IWKJQZJQ.js → chunk-GZVCNYR4.js} +55 -55
  15. package/dist/chunk-GZVCNYR4.js.map +1 -0
  16. package/dist/{chunk-G5SXUXSU.js → chunk-H7ZML5QL.js} +2 -2
  17. package/dist/{chunk-HKQ5XQAQ.js → chunk-HGPZ2QWV.js} +4 -4
  18. package/dist/{chunk-CJEKEW7R.js → chunk-IHCPMYKU.js} +3 -3
  19. package/dist/{chunk-UZ2ZA5A6.js → chunk-JZWJFG4M.js} +2 -2
  20. package/dist/{chunk-5R4HMSNX.js → chunk-MO5G5TP5.js} +17141 -16812
  21. package/dist/chunk-MO5G5TP5.js.map +1 -0
  22. package/dist/{chunk-CFJXYPTF.js → chunk-PVWG3V62.js} +13 -5
  23. package/dist/chunk-PVWG3V62.js.map +1 -0
  24. package/dist/{chunk-3CZU7XCS.js → chunk-PWZ4ULCB.js} +20 -14
  25. package/dist/chunk-PWZ4ULCB.js.map +1 -0
  26. package/dist/{chunk-ZXRVFFCY.js → chunk-VHVOTGBQ.js} +3 -3
  27. package/dist/{chunk-IGHDIWZU.js → chunk-VYTIJ6HJ.js} +17 -2
  28. package/dist/{chunk-IGHDIWZU.js.map → chunk-VYTIJ6HJ.js.map} +1 -1
  29. package/dist/{credential-JGVSEGVH.js → credential-WOATCWOU.js} +5 -5
  30. package/dist/{credential-template-CWWMOKB2.js → credential-template-Q3DQE2AH.js} +5 -5
  31. package/dist/{debug-workflow-BXRU72YZ.js → debug-workflow-ZNP5XZQF.js} +7 -7
  32. package/dist/{src-CV57ZD6I.js → dist-WW2S733L.js} +7 -9
  33. package/dist/{docs-PVBXPTGR.js → docs-XVU4LA7G.js} +5 -5
  34. package/dist/{doctor-RHMKD4W5.js → doctor-PGNHD3TI.js} +3 -3
  35. package/dist/{environment-WZKIO3R3.js → environment-MRDNWU47.js} +5 -5
  36. package/dist/{feature-flag-K5REGGDY.js → feature-flag-D3DQZ6DX.js} +11 -10
  37. package/dist/feature-flag-D3DQZ6DX.js.map +1 -0
  38. package/dist/index.js +144 -56
  39. package/dist/index.js.map +1 -1
  40. package/dist/{init-FFUZO5D7.js → init-DHWKUYIR.js} +10 -10
  41. package/dist/{install-XRKEQAFZ.js → install-DMEFGQHD.js} +5 -5
  42. package/dist/{issues-I3V6GEXU.js → issues-E4YQ4DVC.js} +5 -5
  43. package/dist/{knobs-6WLJMB44.js → knobs-NA6SPLHX.js} +5 -5
  44. package/dist/{list-PHC7VYNS.js → list-GJNGFQMC.js} +5 -5
  45. package/dist/{local-VGYRSW22.js → local-NSKOZHHA.js} +6 -6
  46. package/dist/{login-QPU2BKG2.js → login-AMSRVPXG.js} +10 -10
  47. package/dist/{mcp-LA452TOA.js → mcp-V4GKEL2J.js} +7 -8
  48. package/dist/{mcp-LA452TOA.js.map → mcp-V4GKEL2J.js.map} +1 -1
  49. package/dist/metrics-DM4YQQZN.js +367 -0
  50. package/dist/metrics-DM4YQQZN.js.map +1 -0
  51. package/dist/{product-RSZV5HMB.js → product-WGOLTBRI.js} +6 -5
  52. package/dist/product-WGOLTBRI.js.map +1 -0
  53. package/dist/{property-YP4GHQAR.js → property-B7QMGLVW.js} +5 -5
  54. package/dist/{psql-XGLBI6T7.js → psql-4JHPJ2CO.js} +3 -3
  55. package/dist/{record-KWKHP2ZY.js → record-LDNKS42Y.js} +6 -6
  56. package/dist/{record-KWKHP2ZY.js.map → record-LDNKS42Y.js.map} +1 -1
  57. package/dist/{redis-VJGCUJPV.js → redis-N44ZZ6VB.js} +3 -3
  58. package/dist/{release-NDRHPW6V.js → release-R7GKLEAI.js} +5 -5
  59. package/dist/{sandbox-OOCANWOG.js → sandbox-PLYUNOFX.js} +6 -6
  60. package/dist/{scenarios-2HRLCGFY.js → scenarios-WUUUKP2S.js} +5 -5
  61. package/dist/{session-M4ULYDYP.js → session-Y6RO7GFC.js} +15 -17
  62. package/dist/{session-M4ULYDYP.js.map → session-Y6RO7GFC.js.map} +1 -1
  63. package/dist/{skill-4DGPRDUC.js → skill-3SP7MAA4.js} +176 -15
  64. package/dist/skill-3SP7MAA4.js.map +1 -0
  65. package/dist/{spec-XZ2TKUFZ.js → spec-ESPA3H26.js} +5 -5
  66. package/dist/{src-HL7HEJIW.js → src-ECFPDE5X.js} +18 -2
  67. package/dist/src-ECFPDE5X.js.map +1 -0
  68. package/dist/{src-7LAXXTVG.js → src-OWPS5DCK.js} +63 -27
  69. package/dist/{src-7LAXXTVG.js.map → src-OWPS5DCK.js.map} +1 -1
  70. package/dist/{src-OU7544PM.js → src-PDYXACRP.js} +2 -2
  71. package/dist/{start-IYKF3C3X.js → start-KDDRLUFN.js} +8 -8
  72. package/dist/{tag-T45MMSCH.js → tag-DAGHQZAR.js} +6 -6
  73. package/dist/{task-MCUHAVTD.js → task-PRR75HI4.js} +5 -5
  74. package/dist/{test-suite-BICBRSBP.js → test-suite-O3UY7EER.js} +7 -7
  75. package/dist/{trace-2BAPMYAS.js → trace-BCSP7PCX.js} +5 -6
  76. package/dist/{triage-M3RZ2ASB.js → triage-2BKUBMMX.js} +6 -6
  77. package/dist/utilities-O3OO64T5.js +441 -0
  78. package/dist/utilities-O3OO64T5.js.map +1 -0
  79. package/dist/{workflow-ZGJU4QCV.js → workflow-76EKT3DS.js} +16 -21
  80. package/dist/workflow-76EKT3DS.js.map +1 -0
  81. package/dist/{workflow-cache-M4N325UT.js → workflow-cache-UDTTNIHT.js} +8 -8
  82. package/dist/{workflow-cache-M4N325UT.js.map → workflow-cache-UDTTNIHT.js.map} +1 -1
  83. package/dist/{workflow-debug-W4USZH35.js → workflow-debug-WO7D32EI.js} +8 -9
  84. package/dist/{workflow-debug-W4USZH35.js.map → workflow-debug-WO7D32EI.js.map} +1 -1
  85. package/dist/{workflow-proposals-5E3DTYZB.js → workflow-proposals-PGURJ6ZI.js} +7 -7
  86. package/package.json +3 -3
  87. package/dist/account-62I7FG5G.js.map +0 -1
  88. package/dist/chunk-26U3DGUM.js.map +0 -1
  89. package/dist/chunk-3CZU7XCS.js.map +0 -1
  90. package/dist/chunk-4NRDONSC.js.map +0 -1
  91. package/dist/chunk-5R4HMSNX.js.map +0 -1
  92. package/dist/chunk-CFJXYPTF.js.map +0 -1
  93. package/dist/chunk-IWKJQZJQ.js.map +0 -1
  94. package/dist/chunk-KRWRUU6R.js +0 -114
  95. package/dist/chunk-KRWRUU6R.js.map +0 -1
  96. package/dist/feature-flag-K5REGGDY.js.map +0 -1
  97. package/dist/pdf-extract-YHE54XU4.js +0 -13
  98. package/dist/product-RSZV5HMB.js.map +0 -1
  99. package/dist/skill-4DGPRDUC.js.map +0 -1
  100. package/dist/src-HL7HEJIW.js.map +0 -1
  101. package/dist/triage-M3RZ2ASB.js.map +0 -1
  102. package/dist/workflow-ZGJU4QCV.js.map +0 -1
  103. /package/dist/{api-catalog-CAJUASVC.js.map → api-catalog-MMPFWS52.js.map} +0 -0
  104. /package/dist/{attachment-RL4AZUJE.js.map → attachment-NSYL5X3S.js.map} +0 -0
  105. /package/dist/{augmentor-GAF3MFY6.js.map → augmentor-LSJLMJYP.js.map} +0 -0
  106. /package/dist/{auth-DURHUZDW.js.map → auth-OYF5A4BY.js.map} +0 -0
  107. /package/dist/{chunk-VKBTI5EF.js.map → chunk-GFP4UEUT.js.map} +0 -0
  108. /package/dist/{chunk-G5SXUXSU.js.map → chunk-H7ZML5QL.js.map} +0 -0
  109. /package/dist/{chunk-HKQ5XQAQ.js.map → chunk-HGPZ2QWV.js.map} +0 -0
  110. /package/dist/{chunk-CJEKEW7R.js.map → chunk-IHCPMYKU.js.map} +0 -0
  111. /package/dist/{chunk-UZ2ZA5A6.js.map → chunk-JZWJFG4M.js.map} +0 -0
  112. /package/dist/{chunk-ZXRVFFCY.js.map → chunk-VHVOTGBQ.js.map} +0 -0
  113. /package/dist/{credential-JGVSEGVH.js.map → credential-WOATCWOU.js.map} +0 -0
  114. /package/dist/{credential-template-CWWMOKB2.js.map → credential-template-Q3DQE2AH.js.map} +0 -0
  115. /package/dist/{debug-workflow-BXRU72YZ.js.map → debug-workflow-ZNP5XZQF.js.map} +0 -0
  116. /package/dist/{pdf-extract-YHE54XU4.js.map → dist-WW2S733L.js.map} +0 -0
  117. /package/dist/{docs-PVBXPTGR.js.map → docs-XVU4LA7G.js.map} +0 -0
  118. /package/dist/{doctor-RHMKD4W5.js.map → doctor-PGNHD3TI.js.map} +0 -0
  119. /package/dist/{environment-WZKIO3R3.js.map → environment-MRDNWU47.js.map} +0 -0
  120. /package/dist/{init-FFUZO5D7.js.map → init-DHWKUYIR.js.map} +0 -0
  121. /package/dist/{install-XRKEQAFZ.js.map → install-DMEFGQHD.js.map} +0 -0
  122. /package/dist/{issues-I3V6GEXU.js.map → issues-E4YQ4DVC.js.map} +0 -0
  123. /package/dist/{knobs-6WLJMB44.js.map → knobs-NA6SPLHX.js.map} +0 -0
  124. /package/dist/{list-PHC7VYNS.js.map → list-GJNGFQMC.js.map} +0 -0
  125. /package/dist/{local-VGYRSW22.js.map → local-NSKOZHHA.js.map} +0 -0
  126. /package/dist/{login-QPU2BKG2.js.map → login-AMSRVPXG.js.map} +0 -0
  127. /package/dist/{property-YP4GHQAR.js.map → property-B7QMGLVW.js.map} +0 -0
  128. /package/dist/{psql-XGLBI6T7.js.map → psql-4JHPJ2CO.js.map} +0 -0
  129. /package/dist/{redis-VJGCUJPV.js.map → redis-N44ZZ6VB.js.map} +0 -0
  130. /package/dist/{release-NDRHPW6V.js.map → release-R7GKLEAI.js.map} +0 -0
  131. /package/dist/{sandbox-OOCANWOG.js.map → sandbox-PLYUNOFX.js.map} +0 -0
  132. /package/dist/{scenarios-2HRLCGFY.js.map → scenarios-WUUUKP2S.js.map} +0 -0
  133. /package/dist/{spec-XZ2TKUFZ.js.map → spec-ESPA3H26.js.map} +0 -0
  134. /package/dist/{src-CV57ZD6I.js.map → src-PDYXACRP.js.map} +0 -0
  135. /package/dist/{start-IYKF3C3X.js.map → start-KDDRLUFN.js.map} +0 -0
  136. /package/dist/{src-OU7544PM.js.map → tag-DAGHQZAR.js.map} +0 -0
  137. /package/dist/{task-MCUHAVTD.js.map → task-PRR75HI4.js.map} +0 -0
  138. /package/dist/{test-suite-BICBRSBP.js.map → test-suite-O3UY7EER.js.map} +0 -0
  139. /package/dist/{tag-T45MMSCH.js.map → trace-BCSP7PCX.js.map} +0 -0
  140. /package/dist/{trace-2BAPMYAS.js.map → triage-2BKUBMMX.js.map} +0 -0
  141. /package/dist/{workflow-proposals-5E3DTYZB.js.map → workflow-proposals-PGURJ6ZI.js.map} +0 -0
@@ -4,16 +4,16 @@ import {
4
4
  fetchList,
5
5
  parseLifecycleStage,
6
6
  toLifecycleLabel
7
- } from "./chunk-CFJXYPTF.js";
8
- import "./chunk-3CZU7XCS.js";
7
+ } from "./chunk-PVWG3V62.js";
8
+ import "./chunk-PWZ4ULCB.js";
9
9
  import {
10
10
  getArgValue,
11
11
  hasFlag,
12
12
  resolveConfig
13
- } from "./chunk-IGHDIWZU.js";
13
+ } from "./chunk-VYTIJ6HJ.js";
14
14
  import "./chunk-32P26BZT.js";
15
15
  import "./chunk-JWHYXEA2.js";
16
- import "./chunk-IWKJQZJQ.js";
16
+ import "./chunk-GZVCNYR4.js";
17
17
  import "./chunk-VKVL7WBN.js";
18
18
 
19
19
  // src/feature-flag.ts
@@ -57,7 +57,7 @@ async function handleList(argv, apiUrl, token) {
57
57
  const orgCount = flag.organizations?.length ?? 0;
58
58
  const userCount = flag.users?.length ?? 0;
59
59
  const lifecycle = `lifecycle=${toLifecycleLabel(flag.lifecycleStage)}`;
60
- const finalValue = flag.lifecycleStage === "active" || flag.lifecycleStage === "baking" ? "" : ` final=${flag.finalValue === true ? "true" : "false"}`;
60
+ const finalValue = flag.lifecycleStage === "active" || flag.lifecycleStage === "baking" || flag.lifecycleStage === "internal" ? "" : ` final=${flag.finalValue === true ? "true" : "false"}`;
61
61
  const bake = flag.lifecycleStage === "baking" ? formatBakeSuffix(flag) : "";
62
62
  const stale = flag.isStale ? " [STALE]" : "";
63
63
  const product = flag.productCardId ? ` product=${flag.productTitle ?? flag.productCardId}` : "";
@@ -240,13 +240,13 @@ async function handleLifecycle(argv, apiUrl, token) {
240
240
  const name = argv[0];
241
241
  if (!name || name.startsWith("--")) {
242
242
  console.error("Error: Missing flag name.");
243
- console.error('Usage: canary feature-flag lifecycle <name> --stage <active|baking|deprecated|ready_for_cleanup> [--final-value true|false] [--plan @file|"text"] [--review-interval <days>] [--max-window <days>]');
243
+ 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>]');
244
244
  process.exit(1);
245
245
  }
246
246
  const stage = parseLifecycleStage(argv);
247
247
  const rawFinalValue = getArgValue(argv, "--final-value");
248
248
  const clearFinalValue = hasFlag(argv, "--clear-final-value");
249
- const gateDriven = stage === "active" || stage === "baking";
249
+ const gateDriven = stage === "active" || stage === "baking" || stage === "internal";
250
250
  if (rawFinalValue !== void 0 && clearFinalValue) {
251
251
  console.error("Error: use either --final-value or --clear-final-value, not both.");
252
252
  process.exit(1);
@@ -314,7 +314,7 @@ async function handleLifecycle(argv, apiUrl, token) {
314
314
  );
315
315
  return;
316
316
  }
317
- const final = result.flag.lifecycleStage === "active" ? "(none)" : result.flag.finalValue === true ? "true" : "false";
317
+ const final = result.flag.lifecycleStage === "active" || result.flag.lifecycleStage === "internal" ? "(none)" : result.flag.finalValue === true ? "true" : "false";
318
318
  console.log(`Updated lifecycle for ${name}: stage=${toLifecycleLabel(result.flag.lifecycleStage)}, final=${final}`);
319
319
  }
320
320
  async function handleOven(argv, apiUrl, token) {
@@ -364,7 +364,8 @@ function printFeatureFlagHelp() {
364
364
  " products [--search <text>] List product board items (find product card ids)",
365
365
  " oven [--json] List flags currently baking (age + burning state)",
366
366
  "",
367
- "Stages: active, baking, deprecated, ready_for_cleanup",
367
+ "Stages: active, baking, internal, deprecated, ready_for_cleanup",
368
+ " internal: long-lived internal-only product (gated to internal orgs only; drives the Internal board column)",
368
369
  "",
369
370
  "Options:",
370
371
  " --org <orgId> Target organization",
@@ -428,4 +429,4 @@ async function runFeatureFlag(argv) {
428
429
  export {
429
430
  runFeatureFlag
430
431
  };
431
- //# sourceMappingURL=feature-flag-K5REGGDY.js.map
432
+ //# sourceMappingURL=feature-flag-D3DQZ6DX.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} 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 productCardId: string | null;\n productTitle: string | null;\n organizations?: Array<{\n gateId: string;\n orgId: string;\n orgName: string;\n createdAt: string;\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 console.log(` ${flag.name} ${flag.description ?? \"\"} (${lifecycle}${finalValue})${bake} [orgs=${orgCount}, users=${userCount}]${product}${stale}`);\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 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 = getArgValue(argv, \"--org\");\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> (--org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId && userId) {\n console.error(\"Error: Provide either --org or --user, not both.\");\n process.exit(1);\n }\n\n if (!orgId && !userId) {\n console.error(\"Error: Provide either --org <orgId> or --user <userId>.\");\n console.error(\"Usage: canary feature-flag enable <name> (--org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId) {\n const result = await apiRequest<FlagApiResponse>(\n apiUrl, token, \"POST\",\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(`Enabled ${name} for org ${orgId}`);\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 = getArgValue(argv, \"--org\");\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> (--org <orgId> | --user <userId>)\");\n process.exit(1);\n }\n\n if (orgId && userId) {\n console.error(\"Error: Provide either --org or --user, not both.\");\n process.exit(1);\n }\n\n if (!orgId && !userId) {\n console.error(\"Error: Provide either --org <orgId> or --user <userId>.\");\n console.error(\"Usage: canary feature-flag disable <name> (--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\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> (--org <orgId> | --user <userId>)\",\n \" Enable a flag for an org or user\",\n \" disable <name> (--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 \" products [--search <text>] List product board items (find product card ids)\",\n \" oven [--json] List flags currently baking (age + burning state)\",\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 \" --org <orgId> Target organization\",\n \" --user <userId> Target user\",\n \" --product <productCardId> Product board item (cards.id) to link\",\n \" --clear Clear the product link (product sub-command only)\",\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 \"products\":\n await handleProducts(rest, apiUrl, token);\n break;\n case \"oven\":\n await handleOven(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":[]}
package/dist/index.js CHANGED
@@ -1,28 +1,30 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  runRemoteTest
4
- } from "./chunk-CJEKEW7R.js";
4
+ } from "./chunk-IHCPMYKU.js";
5
+ import "./chunk-VHVOTGBQ.js";
6
+ import "./chunk-PVWG3V62.js";
7
+ import {
8
+ debug,
9
+ fetchOrExit,
10
+ isSuperadminToken
11
+ } from "./chunk-PWZ4ULCB.js";
5
12
  import {
6
13
  runLogin
7
- } from "./chunk-G5SXUXSU.js";
14
+ } from "./chunk-H7ZML5QL.js";
8
15
  import {
9
16
  checkForUpdate
10
17
  } from "./chunk-AQPJQ5AE.js";
11
- import "./chunk-ZXRVFFCY.js";
12
- import "./chunk-CFJXYPTF.js";
13
- import {
14
- fetchOrExit,
15
- isSuperadminToken
16
- } from "./chunk-3CZU7XCS.js";
17
18
  import {
18
19
  envToProfile,
19
20
  getArgValue,
20
21
  hasFlag,
21
22
  readAllStoredTokens,
22
23
  readStoredAuth,
24
+ resolveAuthSource,
23
25
  resolveConfig,
24
26
  resolveOptionalConfig
25
- } from "./chunk-IGHDIWZU.js";
27
+ } from "./chunk-VYTIJ6HJ.js";
26
28
  import {
27
29
  installConsoleBranding,
28
30
  readBrandEnv,
@@ -30,7 +32,7 @@ import {
30
32
  version
31
33
  } from "./chunk-32P26BZT.js";
32
34
  import "./chunk-JWHYXEA2.js";
33
- import "./chunk-IWKJQZJQ.js";
35
+ import "./chunk-GZVCNYR4.js";
34
36
  import "./chunk-VKVL7WBN.js";
35
37
 
36
38
  // src/index.ts
@@ -39,7 +41,41 @@ import { pathToFileURL } from "url";
39
41
 
40
42
  // src/orgs.ts
41
43
  import process from "process";
44
+ async function runOrgMembers(argv) {
45
+ const { apiUrl, token } = await resolveConfig(argv);
46
+ const res = await fetch(`${apiUrl}/org/members`, {
47
+ headers: { Authorization: `Bearer ${token}` }
48
+ });
49
+ if (!res.ok) {
50
+ console.error("Failed to fetch members. You may need to re-login: cofactor login");
51
+ process.exit(1);
52
+ }
53
+ const data = await res.json();
54
+ if (!data.ok || !data.items) {
55
+ console.error("Failed to fetch members:", data.error ?? "Unknown error");
56
+ process.exit(1);
57
+ }
58
+ if (hasFlag(argv, "--json")) {
59
+ console.log(JSON.stringify(data.items, null, 2));
60
+ return;
61
+ }
62
+ if (data.items.length === 0) {
63
+ console.log("No members.");
64
+ return;
65
+ }
66
+ console.log("Members (\u2713 = Slack-linked, can receive utilities slack DMs):\n");
67
+ for (const m of data.items) {
68
+ const slack = m.slackLinked ? "\u2713" : " ";
69
+ const name = m.displayName ?? "(no name)";
70
+ const email = m.primaryEmail ?? "(no email)";
71
+ console.log(` ${slack} ${name} <${email}> [${m.role}]`);
72
+ }
73
+ }
42
74
  async function runOrgs(argv) {
75
+ const sub = argv.find((a) => !a.startsWith("-"));
76
+ if (sub === "members") {
77
+ return runOrgMembers(argv.filter((a) => a !== "members"));
78
+ }
43
79
  const { apiUrl, token } = await resolveConfig(argv);
44
80
  const env = getArgValue(argv, "--env");
45
81
  const auth = await readStoredAuth(env ? envToProfile(env) : void 0);
@@ -410,8 +446,7 @@ async function createCliUserEventRecorder(argv, cliVersion) {
410
446
  origin: "cli",
411
447
  onError: (error) => {
412
448
  const message = error instanceof Error ? error.message : String(error);
413
- process3.stderr.write(`[canary] user event tracking skipped: ${message}
414
- `);
449
+ debug(`user event tracking skipped: ${message}`);
415
450
  }
416
451
  }),
417
452
  metadata: buildBaseMetadata(argv, cliVersion, config.apiUrl)
@@ -442,15 +477,18 @@ async function recordCliInstrumentationFailure(argv, cliVersion, stage, error) {
442
477
  }
443
478
 
444
479
  // src/index.ts
445
- var loadMcp = () => import("./mcp-LA452TOA.js").then((m) => m.runMcp);
446
- var loadDebugWorkflow = () => import("./debug-workflow-BXRU72YZ.js").then((m) => m.runDebugWorkflow);
447
- var loadRecord = () => import("./record-KWKHP2ZY.js").then((m) => m.runRecord);
448
- var loadSession = () => import("./session-M4ULYDYP.js").then((m) => m.runSession);
449
- var loadLocal = () => import("./local-VGYRSW22.js").then((m) => m.runLocal);
480
+ var loadMcp = () => import("./mcp-V4GKEL2J.js").then((m) => m.runMcp);
481
+ var loadDebugWorkflow = () => import("./debug-workflow-ZNP5XZQF.js").then((m) => m.runDebugWorkflow);
482
+ var loadRecord = () => import("./record-LDNKS42Y.js").then((m) => m.runRecord);
483
+ var loadSession = () => import("./session-Y6RO7GFC.js").then((m) => m.runSession);
484
+ var loadLocal = () => import("./local-NSKOZHHA.js").then((m) => m.runLocal);
450
485
  function printVersion() {
451
486
  console.log(`canary v${version}`);
452
487
  }
453
- function printHelp({ isSuperadmin }) {
488
+ function printHelp({
489
+ isSuperadmin,
490
+ features = {}
491
+ }) {
454
492
  const lines = [
455
493
  `canary v${version}: Testing and QA CLI`,
456
494
  "",
@@ -459,7 +497,7 @@ function printHelp({ isSuperadmin }) {
459
497
  " canary mcp Start MCP server (stdio)",
460
498
  " canary install [--target <id>] Install MCP server into Claude, Cursor, etc.",
461
499
  " canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]",
462
- " canary orgs List organizations",
500
+ " canary orgs [members] List organizations (or org members)",
463
501
  " canary debug <workflowId> [options] Debug workflow in local headed browser",
464
502
  " canary record [options] Record browser interactions",
465
503
  " canary local <sub-command> Set up and manage local testing",
@@ -476,12 +514,19 @@ function printHelp({ isSuperadmin }) {
476
514
  lines.push(
477
515
  " canary application <sub-command> List and create applications, view linked repos (alias: property)",
478
516
  " canary environment <sub-command> List, create, and default environments (alias: env)",
479
- " canary task <sub-command> Manage agent tasks (requires feature flag)",
480
517
  " canary sandbox <sub-command> Manage sandbox templates and instances",
481
518
  " canary attachment <sub-command> List, upload, and manage attachments",
482
519
  " canary tag <sub-command> List, create, and assign tags",
483
520
  " canary triage <sub-command> Read AI triage results for a test suite execution"
484
521
  );
522
+ if (features.agentTasks) {
523
+ lines.push(" canary task <sub-command> Manage agent tasks");
524
+ }
525
+ if (features.utilities) {
526
+ lines.push(
527
+ " canary utilities <group> <sub> Object storage, gists, email/slack (agent toolkit)"
528
+ );
529
+ }
485
530
  if (isSuperadmin) {
486
531
  lines.push(
487
532
  " canary debug-session [--env dev|local] [--json] Create browser debug session",
@@ -491,6 +536,7 @@ function printHelp({ isSuperadmin }) {
491
536
  " canary feature-flag <sub-command> Manage feature flags",
492
537
  " canary knobs <sub-command> Manage knobs (global config)",
493
538
  " canary product <sub-command> Manage the Product board (cards, fields, flag links)",
539
+ " canary metrics <sub-command> Manage product metrics (pull/review health metrics)",
494
540
  " canary account <sub-command> Manage the Accounts board (accounts, org links)"
495
541
  );
496
542
  }
@@ -660,6 +706,7 @@ var COMMANDS_WITH_UPDATE_CHECK = /* @__PURE__ */ new Set([
660
706
  "sandbox",
661
707
  "attachment",
662
708
  "attachments",
709
+ "utilities",
663
710
  "tag",
664
711
  "tags",
665
712
  "api-catalog"
@@ -680,6 +727,7 @@ var COMMANDS_WITH_HELP = /* @__PURE__ */ new Set([
680
727
  "sandbox",
681
728
  "attachment",
682
729
  "attachments",
730
+ "utilities",
683
731
  "tag",
684
732
  "tags",
685
733
  "api-catalog"
@@ -690,6 +738,34 @@ async function resolveIsSuperadmin() {
690
738
  const tokens = await readAllStoredTokens();
691
739
  return tokens.some((t) => isSuperadminToken(t));
692
740
  }
741
+ async function resolveOrgFeatures() {
742
+ try {
743
+ const config = await resolveOptionalConfig([]);
744
+ if (!config) return {};
745
+ const controller = new AbortController();
746
+ const timer = setTimeout(() => controller.abort(), 3e3);
747
+ try {
748
+ const res = await fetch(`${config.apiUrl}/me`, {
749
+ headers: { Authorization: `Bearer ${config.token}` },
750
+ signal: controller.signal
751
+ });
752
+ if (!res.ok) return {};
753
+ const body = await res.json();
754
+ return body.user?.features ?? {};
755
+ } finally {
756
+ clearTimeout(timer);
757
+ }
758
+ } catch {
759
+ return {};
760
+ }
761
+ }
762
+ async function showGlobalHelp() {
763
+ const [isSuperadmin, features] = await Promise.all([
764
+ resolveIsSuperadmin(),
765
+ resolveOrgFeatures()
766
+ ]);
767
+ printHelp({ isSuperadmin, features });
768
+ }
693
769
  function normalizeExitCode(value) {
694
770
  if (typeof value === "number") return value;
695
771
  if (typeof value === "string") {
@@ -729,7 +805,7 @@ async function executeCommand(command, rest) {
729
805
  return;
730
806
  }
731
807
  if (command === "install") {
732
- const { runInstall } = await import("./install-XRKEQAFZ.js");
808
+ const { runInstall } = await import("./install-DMEFGQHD.js");
733
809
  await runInstall(rest);
734
810
  return;
735
811
  }
@@ -766,74 +842,79 @@ async function executeCommand(command, rest) {
766
842
  return;
767
843
  }
768
844
  if (command === "psql") {
769
- const { runPsql } = await import("./psql-XGLBI6T7.js");
845
+ const { runPsql } = await import("./psql-4JHPJ2CO.js");
770
846
  await runPsql(rest);
771
847
  return;
772
848
  }
773
849
  if (command === "redis") {
774
- const { runRedis } = await import("./redis-VJGCUJPV.js");
850
+ const { runRedis } = await import("./redis-N44ZZ6VB.js");
775
851
  await runRedis(rest);
776
852
  return;
777
853
  }
778
854
  if (command === "release") {
779
- const { runRelease } = await import("./release-NDRHPW6V.js");
855
+ const { runRelease } = await import("./release-R7GKLEAI.js");
780
856
  await runRelease(rest);
781
857
  return;
782
858
  }
783
859
  if (command === "docs") {
784
- const { runDocs } = await import("./docs-PVBXPTGR.js");
860
+ const { runDocs } = await import("./docs-XVU4LA7G.js");
785
861
  await runDocs(rest);
786
862
  return;
787
863
  }
788
864
  if (command === "feature-flag") {
789
- const { runFeatureFlag } = await import("./feature-flag-K5REGGDY.js");
865
+ const { runFeatureFlag } = await import("./feature-flag-D3DQZ6DX.js");
790
866
  await runFeatureFlag(rest);
791
867
  return;
792
868
  }
793
869
  if (command === "product") {
794
- const { runProduct } = await import("./product-RSZV5HMB.js");
870
+ const { runProduct } = await import("./product-WGOLTBRI.js");
795
871
  await runProduct(rest);
796
872
  return;
797
873
  }
874
+ if (command === "metrics") {
875
+ const { runMetrics } = await import("./metrics-DM4YQQZN.js");
876
+ await runMetrics(rest);
877
+ return;
878
+ }
798
879
  if (command === "account") {
799
- const { runAccount } = await import("./account-62I7FG5G.js");
880
+ const { runAccount } = await import("./account-ZSM2Q3RB.js");
800
881
  await runAccount(rest);
801
882
  return;
802
883
  }
803
884
  if (command === "scenarios" || command === "scenario") {
804
- const { runScenarios } = await import("./scenarios-2HRLCGFY.js");
885
+ const { runScenarios } = await import("./scenarios-WUUUKP2S.js");
805
886
  await runScenarios(rest);
806
887
  return;
807
888
  }
808
889
  if (command === "knobs") {
809
- const { runKnobs } = await import("./knobs-6WLJMB44.js");
890
+ const { runKnobs } = await import("./knobs-NA6SPLHX.js");
810
891
  await runKnobs(rest);
811
892
  return;
812
893
  }
813
894
  if (command === "issues") {
814
- const { runIssues } = await import("./issues-I3V6GEXU.js");
895
+ const { runIssues } = await import("./issues-E4YQ4DVC.js");
815
896
  await runIssues(rest);
816
897
  return;
817
898
  }
818
899
  if (command === "credential") {
819
- const { runCredential } = await import("./credential-JGVSEGVH.js");
900
+ const { runCredential } = await import("./credential-WOATCWOU.js");
820
901
  await runCredential(rest);
821
902
  return;
822
903
  }
823
904
  if (command === "persona" || command === "personas" || // Backwards-compat aliases for the former "credential template" name.
824
905
  command === "credential-template" || command === "credential-templates") {
825
- const { runCredentialTemplate } = await import("./credential-template-CWWMOKB2.js");
906
+ const { runCredentialTemplate } = await import("./credential-template-Q3DQE2AH.js");
826
907
  await runCredentialTemplate(rest);
827
908
  return;
828
909
  }
829
910
  if (command === "workflow") {
830
- const { runWorkflow } = await import("./workflow-ZGJU4QCV.js");
911
+ const { runWorkflow } = await import("./workflow-76EKT3DS.js");
831
912
  await runWorkflow(rest);
832
913
  return;
833
914
  }
834
915
  if (command === "spec") {
835
- const { resolveConfig: resolveConfig2 } = await import("./auth-DURHUZDW.js");
836
- const { handleSpec } = await import("./spec-XZ2TKUFZ.js");
916
+ const { resolveConfig: resolveConfig2 } = await import("./auth-OYF5A4BY.js");
917
+ const { handleSpec } = await import("./spec-ESPA3H26.js");
837
918
  const wantsAuth = rest[0] === "compile" || rest[0] === "pull" || rest[0] === "diff";
838
919
  if (wantsAuth) {
839
920
  const { apiUrl, token } = await resolveConfig2(rest);
@@ -844,8 +925,8 @@ async function executeCommand(command, rest) {
844
925
  return;
845
926
  }
846
927
  if (command === "augmentor" || command === "augmentors") {
847
- const { resolveConfig: resolveConfig2 } = await import("./auth-DURHUZDW.js");
848
- const { runAugmentor } = await import("./augmentor-GAF3MFY6.js");
928
+ const { resolveConfig: resolveConfig2 } = await import("./auth-OYF5A4BY.js");
929
+ const { runAugmentor } = await import("./augmentor-LSJLMJYP.js");
849
930
  if (rest[0] === void 0 || rest[0] === "help" || rest[0] === "--help") {
850
931
  await runAugmentor(rest, "", "");
851
932
  } else {
@@ -855,66 +936,71 @@ async function executeCommand(command, rest) {
855
936
  return;
856
937
  }
857
938
  if (command === "api-catalog") {
858
- const { resolveConfig: resolveConfig2 } = await import("./auth-DURHUZDW.js");
859
- const { runApiCatalog } = await import("./api-catalog-CAJUASVC.js");
939
+ const { resolveConfig: resolveConfig2 } = await import("./auth-OYF5A4BY.js");
940
+ const { runApiCatalog } = await import("./api-catalog-MMPFWS52.js");
860
941
  const { apiUrl, token } = await resolveConfig2(rest);
861
942
  await runApiCatalog(rest, apiUrl, token);
862
943
  return;
863
944
  }
864
945
  if (command === "skill" || command === "skills") {
865
- const { runSkill } = await import("./skill-4DGPRDUC.js");
946
+ const { runSkill } = await import("./skill-3SP7MAA4.js");
866
947
  await runSkill(rest);
867
948
  return;
868
949
  }
869
950
  if (command === "task") {
870
- const { runTask } = await import("./task-MCUHAVTD.js");
951
+ const { runTask } = await import("./task-PRR75HI4.js");
871
952
  await runTask(rest);
872
953
  return;
873
954
  }
874
955
  if (command === "test-suite") {
875
- const { runTestSuite } = await import("./test-suite-BICBRSBP.js");
956
+ const { runTestSuite } = await import("./test-suite-O3UY7EER.js");
876
957
  await runTestSuite(rest);
877
958
  return;
878
959
  }
879
960
  if (command === "triage") {
880
- const { runTriage } = await import("./triage-M3RZ2ASB.js");
961
+ const { runTriage } = await import("./triage-2BKUBMMX.js");
881
962
  await runTriage(rest);
882
963
  return;
883
964
  }
884
965
  if (command === "application" || command === "applications" || command === "property" || command === "properties") {
885
- const { runProperty } = await import("./property-YP4GHQAR.js");
966
+ const { runProperty } = await import("./property-B7QMGLVW.js");
886
967
  await runProperty(rest);
887
968
  return;
888
969
  }
889
970
  if (command === "environment" || command === "env") {
890
- const { runEnvironment } = await import("./environment-WZKIO3R3.js");
971
+ const { runEnvironment } = await import("./environment-MRDNWU47.js");
891
972
  await runEnvironment(rest);
892
973
  return;
893
974
  }
894
975
  if (command === "sandbox") {
895
- const { runSandbox } = await import("./sandbox-OOCANWOG.js");
976
+ const { runSandbox } = await import("./sandbox-PLYUNOFX.js");
896
977
  await runSandbox(rest);
897
978
  return;
898
979
  }
899
980
  if (command === "attachment" || command === "attachments") {
900
- const { runAttachment } = await import("./attachment-RL4AZUJE.js");
981
+ const { runAttachment } = await import("./attachment-NSYL5X3S.js");
901
982
  await runAttachment(rest);
902
983
  return;
903
984
  }
985
+ if (command === "utilities") {
986
+ const { runUtilities } = await import("./utilities-O3OO64T5.js");
987
+ await runUtilities(rest);
988
+ return;
989
+ }
904
990
  if (command === "tag" || command === "tags") {
905
- const { runTag } = await import("./tag-T45MMSCH.js");
991
+ const { runTag } = await import("./tag-DAGHQZAR.js");
906
992
  await runTag(rest);
907
993
  return;
908
994
  }
909
995
  if (command === "trace") {
910
- const { runTrace } = await import("./trace-2BAPMYAS.js");
996
+ const { runTrace } = await import("./trace-BCSP7PCX.js");
911
997
  await runTrace(rest);
912
998
  return;
913
999
  }
914
1000
  if (command === "auth") {
915
1001
  const sub = rest[0];
916
1002
  if (sub === "doctor") {
917
- const { runAuthDoctor } = await import("./doctor-RHMKD4W5.js");
1003
+ const { runAuthDoctor } = await import("./doctor-PGNHD3TI.js");
918
1004
  await runAuthDoctor(rest.slice(1));
919
1005
  return;
920
1006
  }
@@ -922,7 +1008,7 @@ async function executeCommand(command, rest) {
922
1008
  process4.exit(1);
923
1009
  }
924
1010
  console.log(`Unknown command "${command}".`);
925
- printHelp({ isSuperadmin: await resolveIsSuperadmin() });
1011
+ await showGlobalHelp();
926
1012
  process4.exit(1);
927
1013
  }
928
1014
  async function main(argv) {
@@ -937,19 +1023,21 @@ async function main(argv) {
937
1023
  const [command, ...rest] = argv;
938
1024
  const hasHelpFlag = argv.includes("--help") || argv.includes("-h");
939
1025
  if (hasHelpFlag && (!command || !COMMANDS_WITH_HELP.has(command))) {
940
- printHelp({ isSuperadmin: await resolveIsSuperadmin() });
1026
+ await showGlobalHelp();
941
1027
  return;
942
1028
  }
943
1029
  if (!command || command === "help") {
944
- printHelp({ isSuperadmin: await resolveIsSuperadmin() });
1030
+ await showGlobalHelp();
945
1031
  return;
946
1032
  }
947
1033
  if (command === "version") {
948
1034
  printVersion();
949
1035
  return;
950
1036
  }
951
- if (command && COMMANDS_WITH_UPDATE_CHECK.has(command)) {
952
- await checkForUpdate(version);
1037
+ if (command && COMMANDS_WITH_UPDATE_CHECK.has(command) && !wantsMachineOutput) {
1038
+ if (await resolveAuthSource(argv) === "stored") {
1039
+ await checkForUpdate(version);
1040
+ }
953
1041
  }
954
1042
  let tracking = null;
955
1043
  try {