@runcofactor/cli 0.13.0 → 0.15.1

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 (149) hide show
  1. package/dist/account-62I7FG5G.js +255 -0
  2. package/dist/account-62I7FG5G.js.map +1 -0
  3. package/dist/{api-catalog-7HLEN7C2.js → api-catalog-CAJUASVC.js} +5 -5
  4. package/dist/{attachment-OVNQD6Z2.js → attachment-RL4AZUJE.js} +5 -5
  5. package/dist/augmentor-GAF3MFY6.js +198 -0
  6. package/dist/augmentor-GAF3MFY6.js.map +1 -0
  7. package/dist/{auth-VUHL74FH.js → auth-DURHUZDW.js} +3 -3
  8. package/dist/{chunk-YN763NWQ.js → chunk-26U3DGUM.js} +10 -4
  9. package/dist/chunk-26U3DGUM.js.map +1 -0
  10. package/dist/{chunk-JZMJUPZP.js → chunk-32P26BZT.js} +3 -3
  11. package/dist/chunk-32P26BZT.js.map +1 -0
  12. package/dist/{chunk-QQVWGWPI.js → chunk-5R4HMSNX.js} +8561 -1511
  13. package/dist/chunk-5R4HMSNX.js.map +1 -0
  14. package/dist/{chunk-VGTKUOYS.js → chunk-AQPJQ5AE.js} +2 -2
  15. package/dist/{chunk-CQE46HSM.js → chunk-CFJXYPTF.js} +14 -8
  16. package/dist/chunk-CFJXYPTF.js.map +1 -0
  17. package/dist/{chunk-NL7CVG56.js → chunk-CJEKEW7R.js} +57 -10
  18. package/dist/chunk-CJEKEW7R.js.map +1 -0
  19. package/dist/{chunk-Z5LUTUDN.js → chunk-G5SXUXSU.js} +3 -3
  20. package/dist/{chunk-ZTOE3ND3.js → chunk-HKQ5XQAQ.js} +4 -4
  21. package/dist/{chunk-PZ4LCN6K.js → chunk-IGHDIWZU.js} +2 -2
  22. package/dist/{chunk-QGI4UCJX.js → chunk-IWKJQZJQ.js} +124 -74
  23. package/dist/chunk-IWKJQZJQ.js.map +1 -0
  24. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  25. package/dist/chunk-KRWRUU6R.js.map +1 -0
  26. package/dist/{chunk-CRHPDPRS.js → chunk-PXFDH6YL.js} +63 -8
  27. package/dist/{chunk-CRHPDPRS.js.map → chunk-PXFDH6YL.js.map} +1 -1
  28. package/dist/{chunk-EJ4U242G.js → chunk-UZ2ZA5A6.js} +2 -2
  29. package/dist/{chunk-EEN2TZUQ.js → chunk-VKBTI5EF.js} +3 -3
  30. package/dist/{chunk-ENDHMYEJ.js → chunk-ZXRVFFCY.js} +3 -3
  31. package/dist/{credential-LO2SEEHU.js → credential-JGVSEGVH.js} +5 -5
  32. package/dist/{credential-template-ZN7W7734.js → credential-template-CWWMOKB2.js} +5 -5
  33. package/dist/{debug-workflow-R3RYYAXK.js → debug-workflow-BXRU72YZ.js} +5 -5
  34. package/dist/{docs-DIAFBDXQ.js → docs-PVBXPTGR.js} +95 -11
  35. package/dist/docs-PVBXPTGR.js.map +1 -0
  36. package/dist/{doctor-NZPUSCRE.js → doctor-RHMKD4W5.js} +3 -3
  37. package/dist/{environment-RQVU4P5M.js → environment-WZKIO3R3.js} +5 -5
  38. package/dist/{feature-flag-XG26RURR.js → feature-flag-K5REGGDY.js} +98 -12
  39. package/dist/feature-flag-K5REGGDY.js.map +1 -0
  40. package/dist/index.js +107 -51
  41. package/dist/index.js.map +1 -1
  42. package/dist/{init-EDNLKGPT.js → init-FFUZO5D7.js} +5 -5
  43. package/dist/{install-FYZ3HNZK.js → install-XRKEQAFZ.js} +5 -5
  44. package/dist/{issues-NNRVTJ4L.js → issues-I3V6GEXU.js} +5 -5
  45. package/dist/{knobs-A2BOBH22.js → knobs-6WLJMB44.js} +7 -6
  46. package/dist/knobs-6WLJMB44.js.map +1 -0
  47. package/dist/{list-F33VZ4BJ.js → list-PHC7VYNS.js} +5 -5
  48. package/dist/{local-DQDTM3XA.js → local-VGYRSW22.js} +7 -7
  49. package/dist/{login-BUMVIB36.js → login-QPU2BKG2.js} +5 -5
  50. package/dist/{mcp-B5Y5CDMQ.js → mcp-LA452TOA.js} +9 -9
  51. package/dist/{mcp-B5Y5CDMQ.js.map → mcp-LA452TOA.js.map} +1 -1
  52. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  53. package/dist/product-RSZV5HMB.js +346 -0
  54. package/dist/product-RSZV5HMB.js.map +1 -0
  55. package/dist/{property-NJ4SRXQG.js → property-YP4GHQAR.js} +5 -5
  56. package/dist/{psql-VBZFCMNR.js → psql-XGLBI6T7.js} +3 -3
  57. package/dist/{record-WAO36O7G.js → record-KWKHP2ZY.js} +6 -6
  58. package/dist/{redis-DHZXHL4S.js → redis-VJGCUJPV.js} +3 -3
  59. package/dist/redis-VJGCUJPV.js.map +1 -0
  60. package/dist/{release-STJKUKTE.js → release-NDRHPW6V.js} +5 -5
  61. package/dist/{sandbox-DWSGLY7B.js → sandbox-OOCANWOG.js} +51 -7
  62. package/dist/sandbox-OOCANWOG.js.map +1 -0
  63. package/dist/{scenarios-HCIDY725.js → scenarios-2HRLCGFY.js} +5 -5
  64. package/dist/{session-Y5RHU54D.js → session-M4ULYDYP.js} +8 -9
  65. package/dist/session-M4ULYDYP.js.map +1 -0
  66. package/dist/{skill-23WAHUOB.js → skill-4DGPRDUC.js} +10 -10
  67. package/dist/{skill-23WAHUOB.js.map → skill-4DGPRDUC.js.map} +1 -1
  68. package/dist/skills/debug-run/SKILL.md +7 -1
  69. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  70. package/dist/skills/debug-run/version.json +1 -1
  71. package/dist/skills/optimize-cache/SKILL.md +41 -4
  72. package/dist/{spec-LM5XHOQ5.js → spec-XZ2TKUFZ.js} +5 -5
  73. package/dist/{src-BGDRMOKC.js → src-2FK3JHGW.js} +315 -104
  74. package/dist/src-2FK3JHGW.js.map +1 -0
  75. package/dist/{src-NCJPUAE6.js → src-CV57ZD6I.js} +10 -8
  76. package/dist/{src-22RI5VP2.js → src-HL7HEJIW.js} +2 -2
  77. package/dist/{src-Y3K7UJEF.js → src-OU7544PM.js} +6 -4
  78. package/dist/{start-SWY55CZX.js → start-IYKF3C3X.js} +5 -5
  79. package/dist/{tag-YSU2XXPI.js → tag-T45MMSCH.js} +6 -6
  80. package/dist/{task-NLBKLD7D.js → task-MCUHAVTD.js} +5 -5
  81. package/dist/{test-suite-QCPWZ2LS.js → test-suite-BICBRSBP.js} +10 -8
  82. package/dist/{test-suite-QCPWZ2LS.js.map → test-suite-BICBRSBP.js.map} +1 -1
  83. package/dist/trace-2BAPMYAS.js +16 -0
  84. package/dist/{triage-TT4BMDBU.js → triage-M3RZ2ASB.js} +6 -6
  85. package/dist/{upgrade-6ZUFETKX.js → upgrade-4QCRAUHP.js} +3 -3
  86. package/dist/{workflow-2CX3ZNOQ.js → workflow-4J23FV7K.js} +86 -15
  87. package/dist/workflow-4J23FV7K.js.map +1 -0
  88. package/dist/{workflow-cache-GXNE6SU2.js → workflow-cache-XPSK6KC7.js} +26 -13
  89. package/dist/workflow-cache-XPSK6KC7.js.map +1 -0
  90. package/dist/{workflow-debug-PRX3DWGD.js → workflow-debug-W4USZH35.js} +9 -9
  91. package/dist/{workflow-proposals-BW327WGL.js → workflow-proposals-5E3DTYZB.js} +5 -7
  92. package/dist/workflow-proposals-5E3DTYZB.js.map +1 -0
  93. package/package.json +5 -1
  94. package/dist/chunk-CQE46HSM.js.map +0 -1
  95. package/dist/chunk-JZMJUPZP.js.map +0 -1
  96. package/dist/chunk-NL7CVG56.js.map +0 -1
  97. package/dist/chunk-QGI4UCJX.js.map +0 -1
  98. package/dist/chunk-QQVWGWPI.js.map +0 -1
  99. package/dist/chunk-YN763NWQ.js.map +0 -1
  100. package/dist/chunk-ZD3KHESI.js.map +0 -1
  101. package/dist/docs-DIAFBDXQ.js.map +0 -1
  102. package/dist/feature-flag-XG26RURR.js.map +0 -1
  103. package/dist/knobs-A2BOBH22.js.map +0 -1
  104. package/dist/redis-DHZXHL4S.js.map +0 -1
  105. package/dist/sandbox-DWSGLY7B.js.map +0 -1
  106. package/dist/session-Y5RHU54D.js.map +0 -1
  107. package/dist/src-BGDRMOKC.js.map +0 -1
  108. package/dist/trace-A3ZY6K26.js +0 -16
  109. package/dist/workflow-2CX3ZNOQ.js.map +0 -1
  110. package/dist/workflow-cache-GXNE6SU2.js.map +0 -1
  111. package/dist/workflow-proposals-BW327WGL.js.map +0 -1
  112. /package/dist/{api-catalog-7HLEN7C2.js.map → api-catalog-CAJUASVC.js.map} +0 -0
  113. /package/dist/{attachment-OVNQD6Z2.js.map → attachment-RL4AZUJE.js.map} +0 -0
  114. /package/dist/{auth-VUHL74FH.js.map → auth-DURHUZDW.js.map} +0 -0
  115. /package/dist/{chunk-VGTKUOYS.js.map → chunk-AQPJQ5AE.js.map} +0 -0
  116. /package/dist/{chunk-Z5LUTUDN.js.map → chunk-G5SXUXSU.js.map} +0 -0
  117. /package/dist/{chunk-ZTOE3ND3.js.map → chunk-HKQ5XQAQ.js.map} +0 -0
  118. /package/dist/{chunk-PZ4LCN6K.js.map → chunk-IGHDIWZU.js.map} +0 -0
  119. /package/dist/{chunk-EJ4U242G.js.map → chunk-UZ2ZA5A6.js.map} +0 -0
  120. /package/dist/{chunk-EEN2TZUQ.js.map → chunk-VKBTI5EF.js.map} +0 -0
  121. /package/dist/{chunk-ENDHMYEJ.js.map → chunk-ZXRVFFCY.js.map} +0 -0
  122. /package/dist/{credential-LO2SEEHU.js.map → credential-JGVSEGVH.js.map} +0 -0
  123. /package/dist/{credential-template-ZN7W7734.js.map → credential-template-CWWMOKB2.js.map} +0 -0
  124. /package/dist/{debug-workflow-R3RYYAXK.js.map → debug-workflow-BXRU72YZ.js.map} +0 -0
  125. /package/dist/{doctor-NZPUSCRE.js.map → doctor-RHMKD4W5.js.map} +0 -0
  126. /package/dist/{environment-RQVU4P5M.js.map → environment-WZKIO3R3.js.map} +0 -0
  127. /package/dist/{init-EDNLKGPT.js.map → init-FFUZO5D7.js.map} +0 -0
  128. /package/dist/{install-FYZ3HNZK.js.map → install-XRKEQAFZ.js.map} +0 -0
  129. /package/dist/{issues-NNRVTJ4L.js.map → issues-I3V6GEXU.js.map} +0 -0
  130. /package/dist/{list-F33VZ4BJ.js.map → list-PHC7VYNS.js.map} +0 -0
  131. /package/dist/{local-DQDTM3XA.js.map → local-VGYRSW22.js.map} +0 -0
  132. /package/dist/{login-BUMVIB36.js.map → login-QPU2BKG2.js.map} +0 -0
  133. /package/dist/{pdf-extract-ABWV3L5X.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  134. /package/dist/{property-NJ4SRXQG.js.map → property-YP4GHQAR.js.map} +0 -0
  135. /package/dist/{psql-VBZFCMNR.js.map → psql-XGLBI6T7.js.map} +0 -0
  136. /package/dist/{record-WAO36O7G.js.map → record-KWKHP2ZY.js.map} +0 -0
  137. /package/dist/{release-STJKUKTE.js.map → release-NDRHPW6V.js.map} +0 -0
  138. /package/dist/{scenarios-HCIDY725.js.map → scenarios-2HRLCGFY.js.map} +0 -0
  139. /package/dist/{spec-LM5XHOQ5.js.map → spec-XZ2TKUFZ.js.map} +0 -0
  140. /package/dist/{src-NCJPUAE6.js.map → src-CV57ZD6I.js.map} +0 -0
  141. /package/dist/{src-22RI5VP2.js.map → src-HL7HEJIW.js.map} +0 -0
  142. /package/dist/{src-Y3K7UJEF.js.map → src-OU7544PM.js.map} +0 -0
  143. /package/dist/{start-SWY55CZX.js.map → start-IYKF3C3X.js.map} +0 -0
  144. /package/dist/{tag-YSU2XXPI.js.map → tag-T45MMSCH.js.map} +0 -0
  145. /package/dist/{task-NLBKLD7D.js.map → task-MCUHAVTD.js.map} +0 -0
  146. /package/dist/{trace-A3ZY6K26.js.map → trace-2BAPMYAS.js.map} +0 -0
  147. /package/dist/{triage-TT4BMDBU.js.map → triage-M3RZ2ASB.js.map} +0 -0
  148. /package/dist/{upgrade-6ZUFETKX.js.map → upgrade-4QCRAUHP.js.map} +0 -0
  149. /package/dist/{workflow-debug-PRX3DWGD.js.map → workflow-debug-W4USZH35.js.map} +0 -0
@@ -1,6 +1,5 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
- AUTO_SNAPSHOT_MARKER,
4
3
  BROWSER_LIFECYCLE_TOOLS,
5
4
  BrowserToolExecutor,
6
5
  CdpScreencastManager,
@@ -9,6 +8,7 @@ import {
9
8
  DEFAULT_VIEWPORT,
10
9
  FfmpegProcess,
11
10
  LARGE_GRID_CHAR_THRESHOLD,
11
+ LiveSnapshotStatsAccumulator,
12
12
  MAX_DIMENSION,
13
13
  PlaywrightClient,
14
14
  ScreencastFileEncoder,
@@ -21,6 +21,7 @@ import {
21
21
  annotateScreenshotIndexed,
22
22
  appendHintsToResponse,
23
23
  appendRowsToCSV,
24
+ applyCustomAugmentors,
24
25
  buildAncestorPath,
25
26
  buildResolutionNote,
26
27
  buildSectionTree,
@@ -32,7 +33,6 @@ import {
32
33
  combineSignals,
33
34
  compareEditingContexts,
34
35
  compareSnapshots,
35
- composeActionResult,
36
36
  computeFingerprint,
37
37
  cropImage,
38
38
  decodeV2Value,
@@ -44,6 +44,7 @@ import {
44
44
  dispatchBrowserToolWithTimeout,
45
45
  dispatchConsolidatedBrowserTool,
46
46
  downsampleImage,
47
+ emptyLiveSnapshotStats,
47
48
  encodeV2Value,
48
49
  ensureAllowedHost,
49
50
  estimateTextTokens,
@@ -112,19 +113,18 @@ import {
112
113
  withRecoveryNotice,
113
114
  withRecoveryNoticeMCP,
114
115
  withToolTimeout
115
- } from "./chunk-QQVWGWPI.js";
116
+ } from "./chunk-5R4HMSNX.js";
116
117
  import "./chunk-JWHYXEA2.js";
117
- import "./chunk-QGI4UCJX.js";
118
+ import "./chunk-IWKJQZJQ.js";
118
119
  import "./chunk-6LEZCKKV.js";
119
120
  import {
120
121
  consoleLogger,
121
122
  extractPdfText,
122
123
  extractPdfTextFromBuffer,
123
124
  setPdfExtractLogger
124
- } from "./chunk-ZD3KHESI.js";
125
+ } from "./chunk-KRWRUU6R.js";
125
126
  import "./chunk-VKVL7WBN.js";
126
127
  export {
127
- AUTO_SNAPSHOT_MARKER,
128
128
  BROWSER_LIFECYCLE_TOOLS,
129
129
  BrowserToolExecutor,
130
130
  CdpScreencastManager,
@@ -133,6 +133,7 @@ export {
133
133
  DEFAULT_VIEWPORT,
134
134
  FfmpegProcess,
135
135
  LARGE_GRID_CHAR_THRESHOLD,
136
+ LiveSnapshotStatsAccumulator,
136
137
  MAX_DIMENSION,
137
138
  PlaywrightClient,
138
139
  ScreencastFileEncoder,
@@ -145,6 +146,7 @@ export {
145
146
  annotateScreenshotIndexed,
146
147
  appendHintsToResponse,
147
148
  appendRowsToCSV,
149
+ applyCustomAugmentors,
148
150
  estimateTextTokens as approxTokenCount,
149
151
  buildAncestorPath,
150
152
  buildResolutionNote,
@@ -157,7 +159,6 @@ export {
157
159
  combineSignals,
158
160
  compareEditingContexts,
159
161
  compareSnapshots,
160
- composeActionResult,
161
162
  computeFingerprint,
162
163
  consoleLogger,
163
164
  cropImage,
@@ -170,6 +171,7 @@ export {
170
171
  dispatchBrowserToolWithTimeout,
171
172
  dispatchConsolidatedBrowserTool,
172
173
  downsampleImage,
174
+ emptyLiveSnapshotStats,
173
175
  encodeV2Value,
174
176
  ensureAllowedHost,
175
177
  estimateTextTokens,
@@ -242,4 +244,4 @@ export {
242
244
  withRecoveryNoticeMCP,
243
245
  withToolTimeout
244
246
  };
245
- //# sourceMappingURL=src-NCJPUAE6.js.map
247
+ //# sourceMappingURL=src-CV57ZD6I.js.map
@@ -2,7 +2,7 @@ import { createRequire as __cr } from "module"; const require = __cr(import.meta
2
2
  import {
3
3
  parseTraceActions,
4
4
  reconstructSnapshots
5
- } from "./chunk-CRHPDPRS.js";
5
+ } from "./chunk-PXFDH6YL.js";
6
6
  import "./chunk-VKVL7WBN.js";
7
7
 
8
8
  // ../diagnostic-workspace/src/assemble-workspace.ts
@@ -1521,4 +1521,4 @@ export {
1521
1521
  writeStepRollups,
1522
1522
  writeSummary
1523
1523
  };
1524
- //# sourceMappingURL=src-22RI5VP2.js.map
1524
+ //# sourceMappingURL=src-HL7HEJIW.js.map
@@ -5,8 +5,9 @@ import {
5
5
  filterMutationActions,
6
6
  parseTraceActions,
7
7
  parseTraceGroups,
8
- reconstructSnapshots
9
- } from "./chunk-CRHPDPRS.js";
8
+ reconstructSnapshots,
9
+ toMutationIndex
10
+ } from "./chunk-PXFDH6YL.js";
10
11
  import "./chunk-VKVL7WBN.js";
11
12
  export {
12
13
  cleanupTrace,
@@ -14,6 +15,7 @@ export {
14
15
  filterMutationActions,
15
16
  parseTraceActions,
16
17
  parseTraceGroups,
17
- reconstructSnapshots
18
+ reconstructSnapshots,
19
+ toMutationIndex
18
20
  };
19
- //# sourceMappingURL=src-Y3K7UJEF.js.map
21
+ //# sourceMappingURL=src-OU7544PM.js.map
@@ -7,15 +7,15 @@ import {
7
7
  fetchList,
8
8
  promptChoice,
9
9
  selectProperty
10
- } from "./chunk-CQE46HSM.js";
10
+ } from "./chunk-CFJXYPTF.js";
11
11
  import "./chunk-3CZU7XCS.js";
12
12
  import {
13
13
  getArgValue,
14
14
  resolveConfig
15
- } from "./chunk-PZ4LCN6K.js";
16
- import "./chunk-JZMJUPZP.js";
15
+ } from "./chunk-IGHDIWZU.js";
16
+ import "./chunk-32P26BZT.js";
17
17
  import "./chunk-JWHYXEA2.js";
18
- import "./chunk-QGI4UCJX.js";
18
+ import "./chunk-IWKJQZJQ.js";
19
19
  import "./chunk-VKVL7WBN.js";
20
20
 
21
21
  // src/local/start.ts
@@ -149,4 +149,4 @@ Use \`canary session\` commands to interact with the browser.`);
149
149
  export {
150
150
  runLocalStart
151
151
  };
152
- //# sourceMappingURL=start-SWY55CZX.js.map
152
+ //# sourceMappingURL=start-IYKF3C3X.js.map
@@ -5,13 +5,13 @@ import {
5
5
  formatUnknownTagsError,
6
6
  resolveTagNames,
7
7
  runTag
8
- } from "./chunk-EEN2TZUQ.js";
9
- import "./chunk-CQE46HSM.js";
8
+ } from "./chunk-VKBTI5EF.js";
9
+ import "./chunk-CFJXYPTF.js";
10
10
  import "./chunk-3CZU7XCS.js";
11
- import "./chunk-PZ4LCN6K.js";
12
- import "./chunk-JZMJUPZP.js";
11
+ import "./chunk-IGHDIWZU.js";
12
+ import "./chunk-32P26BZT.js";
13
13
  import "./chunk-JWHYXEA2.js";
14
- import "./chunk-QGI4UCJX.js";
14
+ import "./chunk-IWKJQZJQ.js";
15
15
  import "./chunk-VKVL7WBN.js";
16
16
  export {
17
17
  applyWorkflowTagFlags,
@@ -20,4 +20,4 @@ export {
20
20
  resolveTagNames,
21
21
  runTag
22
22
  };
23
- //# sourceMappingURL=tag-YSU2XXPI.js.map
23
+ //# sourceMappingURL=tag-T45MMSCH.js.map
@@ -1,16 +1,16 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  apiRequest
4
- } from "./chunk-CQE46HSM.js";
4
+ } from "./chunk-CFJXYPTF.js";
5
5
  import "./chunk-3CZU7XCS.js";
6
6
  import {
7
7
  getArgValue,
8
8
  hasFlag,
9
9
  resolveConfig
10
- } from "./chunk-PZ4LCN6K.js";
11
- import "./chunk-JZMJUPZP.js";
10
+ } from "./chunk-IGHDIWZU.js";
11
+ import "./chunk-32P26BZT.js";
12
12
  import "./chunk-JWHYXEA2.js";
13
- import "./chunk-QGI4UCJX.js";
13
+ import "./chunk-IWKJQZJQ.js";
14
14
  import "./chunk-VKVL7WBN.js";
15
15
 
16
16
  // src/task.ts
@@ -920,4 +920,4 @@ async function runTask(argv) {
920
920
  export {
921
921
  runTask
922
922
  };
923
- //# sourceMappingURL=task-NLBKLD7D.js.map
923
+ //# sourceMappingURL=task-MCUHAVTD.js.map
@@ -1,22 +1,22 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  runRemoteTest
4
- } from "./chunk-NL7CVG56.js";
4
+ } from "./chunk-CJEKEW7R.js";
5
5
  import {
6
6
  isTriageEnabledForExecution
7
- } from "./chunk-ENDHMYEJ.js";
7
+ } from "./chunk-ZXRVFFCY.js";
8
8
  import {
9
9
  apiRequest
10
- } from "./chunk-CQE46HSM.js";
10
+ } from "./chunk-CFJXYPTF.js";
11
11
  import "./chunk-3CZU7XCS.js";
12
12
  import {
13
13
  getArgValue,
14
14
  hasFlag,
15
15
  resolveConfig
16
- } from "./chunk-PZ4LCN6K.js";
17
- import "./chunk-JZMJUPZP.js";
16
+ } from "./chunk-IGHDIWZU.js";
17
+ import "./chunk-32P26BZT.js";
18
18
  import "./chunk-JWHYXEA2.js";
19
- import "./chunk-QGI4UCJX.js";
19
+ import "./chunk-IWKJQZJQ.js";
20
20
  import "./chunk-VKVL7WBN.js";
21
21
 
22
22
  // src/test-suite.ts
@@ -331,7 +331,8 @@ function printTestSuiteHelp() {
331
331
  "Run options:",
332
332
  " --suite <name|id> Run a named, layered test suite (members run in layer order)",
333
333
  " --application <name|id> Target a specific application (alias: --property)",
334
- " --environment <name|id> Target a specific environment",
334
+ " --environment <name|id> Target a specific environment (required with --env-mode force)",
335
+ " --env-mode <mode> mixed (default \u2014 each flow on its preferred env) | force (pin to --environment)",
335
336
  " --tag <tag> Filter workflows by tag",
336
337
  " --name-pattern <pat> Filter workflows by name pattern",
337
338
  " --verbose, -v Show all SSE events",
@@ -355,6 +356,7 @@ function printTestSuiteHelp() {
355
356
  " canary test-suite run Run all workflow tests",
356
357
  ' canary test-suite run --suite "Checkout flow" Run a named, layered suite',
357
358
  " canary test-suite run --tag smoke Run smoke-tagged workflows",
359
+ ' canary test-suite run --suite "Checkout flow" --env-mode force --environment staging',
358
360
  ' canary test-suite run --application "My App" --environment staging',
359
361
  " canary test-suite list List recent suite executions",
360
362
  " canary test-suite get <id> --failures-only Show only failures"
@@ -394,4 +396,4 @@ async function runTestSuite(argv) {
394
396
  export {
395
397
  runTestSuite
396
398
  };
397
- //# sourceMappingURL=test-suite-QCPWZ2LS.js.map
399
+ //# sourceMappingURL=test-suite-BICBRSBP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/test-suite.ts"],"sourcesContent":["/**\n * CLI subcommand for querying and triggering test suite (workflow test execution) runs.\n *\n * @module TestSuiteCLI\n */\n\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { runRemoteTest } from './remote-test.js';\nimport { isTriageEnabledForExecution } from './triage.js';\n\n// ---------------------------------------------------------------------------\n// Types (matching API serializers in apps/api/src/workflows/routes/shared.ts)\n// ---------------------------------------------------------------------------\n\ntype Pagination = {\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n};\n\ntype TestExecutionSummary = {\n id: string;\n status: string;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n skippedWorkflows: number;\n /** @deprecated Quarantine removed; always 0. Use degradedWorkflows. */\n quarantinedWorkflows: number;\n degradedWorkflows?: number;\n startedAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n};\n\ntype TestExecution = TestExecutionSummary & {\n orgId: string;\n mode: string;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n errorMessage: string | null;\n updatedAt: string;\n};\n\ntype TestRunResult = {\n id: string;\n testRunId: string;\n workflowId: string;\n nodeId: string;\n status: string;\n message: string | null;\n issueId: string | null;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype TestRun = {\n id: string;\n executionId: string | null;\n workflowId: string;\n status: string;\n snapshotVersion: number;\n workflowRunId: string | null;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n linkedIssueId: string | null;\n isQuarantined: boolean;\n errorMessage: string | null;\n skipReason: string | null;\n startedAt: string | null;\n finishedAt: string | null;\n workflowName: string | null;\n results: TestRunResult[];\n};\n\ntype TestExecutionListResponse = {\n ok: boolean;\n error?: string;\n data: TestExecutionSummary[];\n pagination: Pagination;\n};\n\ntype TestExecutionDetailResponse = {\n ok: boolean;\n error?: string;\n execution: TestExecution;\n testRuns: TestRun[];\n};\n\ntype RunStep = {\n id: string;\n runId: string;\n nodeId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n orderIndex: number;\n metadataJson: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype WorkflowRun = {\n id: string;\n workflowId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n steps: RunStep[];\n};\n\ntype RunWithStepsResponse = {\n ok: boolean;\n error?: string;\n data: { run: WorkflowRun };\n};\n\ntype DiagnosticJson = {\n category?: string;\n confidence?: number;\n title?: string;\n analysis?: string;\n recommendation?: string;\n smokingGun?: { type: string; description: string; detail?: string } | null;\n};\n\ntype DiagnosticThought = {\n content: string;\n toolName: string | null;\n orderIndex: number;\n createdAt: string;\n};\n\ntype FailureDiagnosticResponse = {\n ok: boolean;\n error?: string;\n data: {\n id: string;\n status: string;\n diagnostic: DiagnosticJson | null;\n createdAt: string;\n updatedAt: string;\n thoughts?: DiagnosticThought[];\n } | null;\n};\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nconst STATUS_ICONS: Record<string, string> = {\n completed: '✅',\n completed_with_errors: '⚠️',\n success: '✅',\n failed: '❌',\n running: '🔵',\n queued: '⏳',\n canceled: '🚫',\n timeout: '⏰',\n skipped: '⏭️',\n flaky_success: '🟡',\n pending: '⏳',\n};\n\nfunction statusIcon(status: string): string {\n return STATUS_ICONS[status] ?? '❓';\n}\n\nfunction formatRelative(iso: string | null): string {\n if (!iso) return '—';\n const diffMs = Date.now() - new Date(iso).getTime();\n if (diffMs < 0) return 'just now';\n const seconds = Math.floor(diffMs / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction computeDuration(startedAt: string | null, finishedAt: string | null): string {\n if (!startedAt || !finishedAt) return '—';\n const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();\n if (ms < 0) return '—';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n const remainMins = minutes % 60;\n return remainMins > 0 ? `${hours}h ${remainMins}m` : `${hours}h`;\n}\n\nfunction pad(str: string, len: number): string {\n return str.padEnd(len);\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const page = getArgValue(argv, '--page') ?? '1';\n const pageSize = getArgValue(argv, '--page-size') ?? '20';\n\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('pageSize', pageSize);\n params.set('sortBy', 'createdAt');\n params.set('sortOrder', 'desc');\n\n const result = await apiRequest<TestExecutionListResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions?${params}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { data, pagination } = result;\n\n if (data.length === 0) {\n console.log('No test suites found.');\n return;\n }\n\n console.log(\n `Test Suites (page ${pagination.page}/${pagination.totalPages}, ${pagination.totalItems} total)\\n`\n );\n\n for (const exec of data) {\n const icon = statusIcon(exec.status);\n const total = String(exec.totalWorkflows).padStart(3);\n const passed = String(exec.successfulWorkflows).padStart(3);\n const failed = String(exec.failedWorkflows).padStart(3);\n const time = formatRelative(exec.createdAt);\n\n console.log(\n ` ${icon} ${exec.id} ${total} total ${passed} passed ${failed} failed ${time}`\n );\n }\n\n console.log('');\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: Missing execution ID. Usage: canary test-suite get <id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const failuresOnly = hasFlag(argv, '--failures-only');\n\n const result = await apiRequest<TestExecutionDetailResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions/${id}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { execution, testRuns } = result;\n const duration = computeDuration(execution.startedAt, execution.finishedAt);\n\n console.log(`Test Suite: ${execution.id}`);\n console.log(`Status: ${statusIcon(execution.status)} ${execution.status}`);\n console.log(`Duration: ${duration}`);\n console.log(\n `Total: ${execution.totalWorkflows} | Passed: ${execution.successfulWorkflows} | Failed: ${execution.failedWorkflows} | Skipped: ${execution.skippedWorkflows} | Degraded: ${execution.degradedWorkflows ?? 0}`\n );\n console.log('');\n\n let runs = testRuns;\n if (failuresOnly) {\n runs = runs.filter((r) => r.status === 'failed');\n if (runs.length === 0) {\n console.log('No failing runs.');\n return;\n }\n }\n\n console.log('Runs:');\n for (const run of runs) {\n const icon = statusIcon(run.status);\n const name = run.workflowName ?? 'Unnamed';\n const dur = computeDuration(run.startedAt, run.finishedAt);\n const runId = run.workflowRunId ?? '—';\n\n console.log(` ${icon} ${pad(name, 30)} ${dur}`);\n console.log(` wf: ${run.workflowId} run: ${runId}`);\n\n if (run.errorMessage) {\n console.log(` Error: ${run.errorMessage}`);\n }\n if (run.skipReason) {\n console.log(` Skip reason: ${run.skipReason}`);\n }\n if (run.linkedIssueId) {\n console.log(` Linked issue: ${run.linkedIssueId}`);\n }\n }\n\n console.log('');\n\n if (execution.failedWorkflows > 0) {\n const triageEnabled = await isTriageEnabledForExecution(apiUrl, token, execution.id);\n if (triageEnabled) {\n console.log(`Triage: canary triage get ${execution.id}`);\n console.log('');\n }\n }\n}\n\nasync function handleDiagnostics(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error(\n 'Error: Missing arguments. Usage: canary test-suite diagnostics <workflowId> <runId>'\n );\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n const showThoughts = hasFlag(argv, '--thoughts');\n\n const result = await apiRequest<FailureDiagnosticResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}/failure-diagnostic${\n showThoughts ? '?includeThoughts=true' : ''\n }`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.data) {\n console.log('No diagnostic available for this run.');\n return;\n }\n\n const { status, diagnostic } = result.data;\n\n if (status === 'pending' || status === 'running') {\n console.log(`Diagnostic is still in progress (status: ${status}).`);\n return;\n }\n\n if (status === 'failed') {\n console.log('Diagnostic analysis failed.');\n return;\n }\n\n if (!diagnostic) {\n console.log('Diagnostic completed but no analysis data available.');\n return;\n }\n\n console.log('Failure Diagnostic');\n console.log(`Status: ${status}`);\n if (diagnostic.category) {\n const conf =\n diagnostic.confidence !== null && diagnostic.confidence !== undefined\n ? ` (${diagnostic.confidence > 1 ? Math.round(diagnostic.confidence) : Math.round(diagnostic.confidence * 100)}% confidence)`\n : '';\n console.log(`Category: ${diagnostic.category}${conf}`);\n }\n if (diagnostic.title) {\n console.log(`Title: ${diagnostic.title}`);\n }\n\n if (diagnostic.analysis) {\n console.log('');\n console.log('Analysis:');\n console.log(` ${diagnostic.analysis}`);\n }\n\n if (diagnostic.recommendation) {\n console.log('');\n console.log('Recommendation:');\n console.log(` ${diagnostic.recommendation}`);\n }\n\n if (diagnostic.smokingGun) {\n console.log('');\n console.log('Smoking Gun:');\n console.log(` > ${diagnostic.smokingGun.description}`);\n if (diagnostic.smokingGun.detail) {\n console.log(` ${diagnostic.smokingGun.detail}`);\n }\n }\n\n if (showThoughts) {\n const thoughts = result.data.thoughts ?? [];\n console.log('');\n console.log(`Agent reasoning (${thoughts.length} step${thoughts.length === 1 ? '' : 's'}):`);\n if (thoughts.length === 0) {\n console.log(' (no reasoning trace captured for this diagnostic)');\n } else {\n for (const t of thoughts) {\n const tool = t.toolName ? ` → ${t.toolName}()` : '';\n console.log(` [${t.orderIndex}]${tool}`);\n for (const line of t.content.split('\\n')) {\n console.log(` ${line}`);\n }\n }\n }\n }\n\n console.log('');\n}\n\nasync function handleSteps(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error('Error: Missing arguments. Usage: canary test-suite steps <workflowId> <runId>');\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<RunWithStepsResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { run } = result.data;\n const duration = computeDuration(run.startedAt, run.finishedAt);\n\n console.log(`Run: ${run.id} (${run.status})`);\n console.log(`Duration: ${duration}`);\n\n if (run.errorMessage) {\n console.log(`Error: ${run.errorMessage}`);\n }\n\n const steps = (run.steps ?? []).sort((a, b) => a.orderIndex - b.orderIndex);\n\n if (steps.length === 0) {\n console.log('\\nNo steps recorded.');\n return;\n }\n\n console.log(`\\nSteps (${steps.length}):`);\n for (const step of steps) {\n const idx = String(step.orderIndex + 1).padStart(2);\n const icon = statusIcon(step.status);\n const nodeId = step.nodeId.slice(0, 8);\n const dur = computeDuration(step.startedAt, step.finishedAt);\n\n console.log(` ${idx}. ${icon} ${pad(nodeId, 10)} ${dur}`);\n\n if (step.errorMessage) {\n console.log(` Error: ${step.errorMessage}`);\n }\n }\n\n console.log('');\n}\n\n// ---------------------------------------------------------------------------\n// Help\n// ---------------------------------------------------------------------------\n\nfunction printTestSuiteHelp(): void {\n console.log(\n [\n 'Usage: canary test-suite <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' run [options] Trigger a test suite and stream results',\n ' list [options] List recent test suites',\n ' get <id> [options] Get test suite detail with runs',\n ' diagnostics <workflowId> <runId> Get failure diagnostic for a run (--thoughts for the agent reasoning trace)',\n ' steps <workflowId> <runId> Get workflow run steps',\n '',\n 'After a run, the suite id can be passed to triage commands:',\n ' canary triage wait <suiteId> Block until AI clusters failures (beta)',\n ' canary triage get <suiteId> Show clustered failures + suggested actions',\n ' canary triage get latest Resolves to the most recent suite',\n '',\n 'Run options:',\n ' --suite <name|id> Run a named, layered test suite (members run in layer order)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all SSE events',\n '',\n 'List options:',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 20)',\n '',\n 'Get options:',\n ' --failures-only Show only failing test runs',\n '',\n 'Output options:',\n ' --json Output raw JSON',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n '',\n 'Examples:',\n ' canary test-suite run Run all workflow tests',\n ' canary test-suite run --suite \"Checkout flow\" Run a named, layered suite',\n ' canary test-suite run --tag smoke Run smoke-tagged workflows',\n ' canary test-suite run --application \"My App\" --environment staging',\n ' canary test-suite list List recent suite executions',\n ' canary test-suite get <id> --failures-only Show only failures',\n ].join('\\n')\n );\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nexport async function runTestSuite(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printTestSuiteHelp();\n return;\n }\n\n if (subCommand === 'run') {\n // Delegate to runRemoteTest — pass through remaining args\n await runRemoteTest(rest);\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 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'diagnostics':\n await handleDiagnostics(rest, apiUrl, token);\n break;\n case 'steps':\n await handleSteps(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printTestSuiteHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/test-suite.ts"],"sourcesContent":["/**\n * CLI subcommand for querying and triggering test suite (workflow test execution) runs.\n *\n * @module TestSuiteCLI\n */\n\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { runRemoteTest } from './remote-test.js';\nimport { isTriageEnabledForExecution } from './triage.js';\n\n// ---------------------------------------------------------------------------\n// Types (matching API serializers in apps/api/src/workflows/routes/shared.ts)\n// ---------------------------------------------------------------------------\n\ntype Pagination = {\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n};\n\ntype TestExecutionSummary = {\n id: string;\n status: string;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n skippedWorkflows: number;\n /** @deprecated Quarantine removed; always 0. Use degradedWorkflows. */\n quarantinedWorkflows: number;\n degradedWorkflows?: number;\n startedAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n};\n\ntype TestExecution = TestExecutionSummary & {\n orgId: string;\n mode: string;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n errorMessage: string | null;\n updatedAt: string;\n};\n\ntype TestRunResult = {\n id: string;\n testRunId: string;\n workflowId: string;\n nodeId: string;\n status: string;\n message: string | null;\n issueId: string | null;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype TestRun = {\n id: string;\n executionId: string | null;\n workflowId: string;\n status: string;\n snapshotVersion: number;\n workflowRunId: string | null;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n linkedIssueId: string | null;\n isQuarantined: boolean;\n errorMessage: string | null;\n skipReason: string | null;\n startedAt: string | null;\n finishedAt: string | null;\n workflowName: string | null;\n results: TestRunResult[];\n};\n\ntype TestExecutionListResponse = {\n ok: boolean;\n error?: string;\n data: TestExecutionSummary[];\n pagination: Pagination;\n};\n\ntype TestExecutionDetailResponse = {\n ok: boolean;\n error?: string;\n execution: TestExecution;\n testRuns: TestRun[];\n};\n\ntype RunStep = {\n id: string;\n runId: string;\n nodeId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n orderIndex: number;\n metadataJson: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype WorkflowRun = {\n id: string;\n workflowId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n steps: RunStep[];\n};\n\ntype RunWithStepsResponse = {\n ok: boolean;\n error?: string;\n data: { run: WorkflowRun };\n};\n\ntype DiagnosticJson = {\n category?: string;\n confidence?: number;\n title?: string;\n analysis?: string;\n recommendation?: string;\n smokingGun?: { type: string; description: string; detail?: string } | null;\n};\n\ntype DiagnosticThought = {\n content: string;\n toolName: string | null;\n orderIndex: number;\n createdAt: string;\n};\n\ntype FailureDiagnosticResponse = {\n ok: boolean;\n error?: string;\n data: {\n id: string;\n status: string;\n diagnostic: DiagnosticJson | null;\n createdAt: string;\n updatedAt: string;\n thoughts?: DiagnosticThought[];\n } | null;\n};\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nconst STATUS_ICONS: Record<string, string> = {\n completed: '✅',\n completed_with_errors: '⚠️',\n success: '✅',\n failed: '❌',\n running: '🔵',\n queued: '⏳',\n canceled: '🚫',\n timeout: '⏰',\n skipped: '⏭️',\n flaky_success: '🟡',\n pending: '⏳',\n};\n\nfunction statusIcon(status: string): string {\n return STATUS_ICONS[status] ?? '❓';\n}\n\nfunction formatRelative(iso: string | null): string {\n if (!iso) return '—';\n const diffMs = Date.now() - new Date(iso).getTime();\n if (diffMs < 0) return 'just now';\n const seconds = Math.floor(diffMs / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction computeDuration(startedAt: string | null, finishedAt: string | null): string {\n if (!startedAt || !finishedAt) return '—';\n const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();\n if (ms < 0) return '—';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n const remainMins = minutes % 60;\n return remainMins > 0 ? `${hours}h ${remainMins}m` : `${hours}h`;\n}\n\nfunction pad(str: string, len: number): string {\n return str.padEnd(len);\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const page = getArgValue(argv, '--page') ?? '1';\n const pageSize = getArgValue(argv, '--page-size') ?? '20';\n\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('pageSize', pageSize);\n params.set('sortBy', 'createdAt');\n params.set('sortOrder', 'desc');\n\n const result = await apiRequest<TestExecutionListResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions?${params}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { data, pagination } = result;\n\n if (data.length === 0) {\n console.log('No test suites found.');\n return;\n }\n\n console.log(\n `Test Suites (page ${pagination.page}/${pagination.totalPages}, ${pagination.totalItems} total)\\n`\n );\n\n for (const exec of data) {\n const icon = statusIcon(exec.status);\n const total = String(exec.totalWorkflows).padStart(3);\n const passed = String(exec.successfulWorkflows).padStart(3);\n const failed = String(exec.failedWorkflows).padStart(3);\n const time = formatRelative(exec.createdAt);\n\n console.log(\n ` ${icon} ${exec.id} ${total} total ${passed} passed ${failed} failed ${time}`\n );\n }\n\n console.log('');\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: Missing execution ID. Usage: canary test-suite get <id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const failuresOnly = hasFlag(argv, '--failures-only');\n\n const result = await apiRequest<TestExecutionDetailResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions/${id}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { execution, testRuns } = result;\n const duration = computeDuration(execution.startedAt, execution.finishedAt);\n\n console.log(`Test Suite: ${execution.id}`);\n console.log(`Status: ${statusIcon(execution.status)} ${execution.status}`);\n console.log(`Duration: ${duration}`);\n console.log(\n `Total: ${execution.totalWorkflows} | Passed: ${execution.successfulWorkflows} | Failed: ${execution.failedWorkflows} | Skipped: ${execution.skippedWorkflows} | Degraded: ${execution.degradedWorkflows ?? 0}`\n );\n console.log('');\n\n let runs = testRuns;\n if (failuresOnly) {\n runs = runs.filter((r) => r.status === 'failed');\n if (runs.length === 0) {\n console.log('No failing runs.');\n return;\n }\n }\n\n console.log('Runs:');\n for (const run of runs) {\n const icon = statusIcon(run.status);\n const name = run.workflowName ?? 'Unnamed';\n const dur = computeDuration(run.startedAt, run.finishedAt);\n const runId = run.workflowRunId ?? '—';\n\n console.log(` ${icon} ${pad(name, 30)} ${dur}`);\n console.log(` wf: ${run.workflowId} run: ${runId}`);\n\n if (run.errorMessage) {\n console.log(` Error: ${run.errorMessage}`);\n }\n if (run.skipReason) {\n console.log(` Skip reason: ${run.skipReason}`);\n }\n if (run.linkedIssueId) {\n console.log(` Linked issue: ${run.linkedIssueId}`);\n }\n }\n\n console.log('');\n\n if (execution.failedWorkflows > 0) {\n const triageEnabled = await isTriageEnabledForExecution(apiUrl, token, execution.id);\n if (triageEnabled) {\n console.log(`Triage: canary triage get ${execution.id}`);\n console.log('');\n }\n }\n}\n\nasync function handleDiagnostics(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error(\n 'Error: Missing arguments. Usage: canary test-suite diagnostics <workflowId> <runId>'\n );\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n const showThoughts = hasFlag(argv, '--thoughts');\n\n const result = await apiRequest<FailureDiagnosticResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}/failure-diagnostic${\n showThoughts ? '?includeThoughts=true' : ''\n }`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.data) {\n console.log('No diagnostic available for this run.');\n return;\n }\n\n const { status, diagnostic } = result.data;\n\n if (status === 'pending' || status === 'running') {\n console.log(`Diagnostic is still in progress (status: ${status}).`);\n return;\n }\n\n if (status === 'failed') {\n console.log('Diagnostic analysis failed.');\n return;\n }\n\n if (!diagnostic) {\n console.log('Diagnostic completed but no analysis data available.');\n return;\n }\n\n console.log('Failure Diagnostic');\n console.log(`Status: ${status}`);\n if (diagnostic.category) {\n const conf =\n diagnostic.confidence !== null && diagnostic.confidence !== undefined\n ? ` (${diagnostic.confidence > 1 ? Math.round(diagnostic.confidence) : Math.round(diagnostic.confidence * 100)}% confidence)`\n : '';\n console.log(`Category: ${diagnostic.category}${conf}`);\n }\n if (diagnostic.title) {\n console.log(`Title: ${diagnostic.title}`);\n }\n\n if (diagnostic.analysis) {\n console.log('');\n console.log('Analysis:');\n console.log(` ${diagnostic.analysis}`);\n }\n\n if (diagnostic.recommendation) {\n console.log('');\n console.log('Recommendation:');\n console.log(` ${diagnostic.recommendation}`);\n }\n\n if (diagnostic.smokingGun) {\n console.log('');\n console.log('Smoking Gun:');\n console.log(` > ${diagnostic.smokingGun.description}`);\n if (diagnostic.smokingGun.detail) {\n console.log(` ${diagnostic.smokingGun.detail}`);\n }\n }\n\n if (showThoughts) {\n const thoughts = result.data.thoughts ?? [];\n console.log('');\n console.log(`Agent reasoning (${thoughts.length} step${thoughts.length === 1 ? '' : 's'}):`);\n if (thoughts.length === 0) {\n console.log(' (no reasoning trace captured for this diagnostic)');\n } else {\n for (const t of thoughts) {\n const tool = t.toolName ? ` → ${t.toolName}()` : '';\n console.log(` [${t.orderIndex}]${tool}`);\n for (const line of t.content.split('\\n')) {\n console.log(` ${line}`);\n }\n }\n }\n }\n\n console.log('');\n}\n\nasync function handleSteps(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error('Error: Missing arguments. Usage: canary test-suite steps <workflowId> <runId>');\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<RunWithStepsResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { run } = result.data;\n const duration = computeDuration(run.startedAt, run.finishedAt);\n\n console.log(`Run: ${run.id} (${run.status})`);\n console.log(`Duration: ${duration}`);\n\n if (run.errorMessage) {\n console.log(`Error: ${run.errorMessage}`);\n }\n\n const steps = (run.steps ?? []).sort((a, b) => a.orderIndex - b.orderIndex);\n\n if (steps.length === 0) {\n console.log('\\nNo steps recorded.');\n return;\n }\n\n console.log(`\\nSteps (${steps.length}):`);\n for (const step of steps) {\n const idx = String(step.orderIndex + 1).padStart(2);\n const icon = statusIcon(step.status);\n const nodeId = step.nodeId.slice(0, 8);\n const dur = computeDuration(step.startedAt, step.finishedAt);\n\n console.log(` ${idx}. ${icon} ${pad(nodeId, 10)} ${dur}`);\n\n if (step.errorMessage) {\n console.log(` Error: ${step.errorMessage}`);\n }\n }\n\n console.log('');\n}\n\n// ---------------------------------------------------------------------------\n// Help\n// ---------------------------------------------------------------------------\n\nfunction printTestSuiteHelp(): void {\n console.log(\n [\n 'Usage: canary test-suite <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' run [options] Trigger a test suite and stream results',\n ' list [options] List recent test suites',\n ' get <id> [options] Get test suite detail with runs',\n ' diagnostics <workflowId> <runId> Get failure diagnostic for a run (--thoughts for the agent reasoning trace)',\n ' steps <workflowId> <runId> Get workflow run steps',\n '',\n 'After a run, the suite id can be passed to triage commands:',\n ' canary triage wait <suiteId> Block until AI clusters failures (beta)',\n ' canary triage get <suiteId> Show clustered failures + suggested actions',\n ' canary triage get latest Resolves to the most recent suite',\n '',\n 'Run options:',\n ' --suite <name|id> Run a named, layered test suite (members run in layer order)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment (required with --env-mode force)',\n ' --env-mode <mode> mixed (default — each flow on its preferred env) | force (pin to --environment)',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all SSE events',\n '',\n 'List options:',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 20)',\n '',\n 'Get options:',\n ' --failures-only Show only failing test runs',\n '',\n 'Output options:',\n ' --json Output raw JSON',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n '',\n 'Examples:',\n ' canary test-suite run Run all workflow tests',\n ' canary test-suite run --suite \"Checkout flow\" Run a named, layered suite',\n ' canary test-suite run --tag smoke Run smoke-tagged workflows',\n ' canary test-suite run --suite \"Checkout flow\" --env-mode force --environment staging',\n ' canary test-suite run --application \"My App\" --environment staging',\n ' canary test-suite list List recent suite executions',\n ' canary test-suite get <id> --failures-only Show only failures',\n ].join('\\n')\n );\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nexport async function runTestSuite(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printTestSuiteHelp();\n return;\n }\n\n if (subCommand === 'run') {\n // Delegate to runRemoteTest — pass through remaining args\n await runRemoteTest(rest);\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 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'diagnostics':\n await handleDiagnostics(rest, apiUrl, token);\n break;\n case 'steps':\n await handleSteps(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printTestSuiteHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,16 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ runTrace
4
+ } from "./chunk-HKQ5XQAQ.js";
5
+ import "./chunk-IGHDIWZU.js";
6
+ import "./chunk-32P26BZT.js";
7
+ import "./chunk-5R4HMSNX.js";
8
+ import "./chunk-JWHYXEA2.js";
9
+ import "./chunk-IWKJQZJQ.js";
10
+ import "./chunk-6LEZCKKV.js";
11
+ import "./chunk-KRWRUU6R.js";
12
+ import "./chunk-VKVL7WBN.js";
13
+ export {
14
+ runTrace
15
+ };
16
+ //# sourceMappingURL=trace-2BAPMYAS.js.map
@@ -2,16 +2,16 @@ import { createRequire as __cr } from "module"; const require = __cr(import.meta
2
2
  import {
3
3
  isTriageEnabledForExecution,
4
4
  runTriage
5
- } from "./chunk-ENDHMYEJ.js";
6
- import "./chunk-CQE46HSM.js";
5
+ } from "./chunk-ZXRVFFCY.js";
6
+ import "./chunk-CFJXYPTF.js";
7
7
  import "./chunk-3CZU7XCS.js";
8
- import "./chunk-PZ4LCN6K.js";
9
- import "./chunk-JZMJUPZP.js";
8
+ import "./chunk-IGHDIWZU.js";
9
+ import "./chunk-32P26BZT.js";
10
10
  import "./chunk-JWHYXEA2.js";
11
- import "./chunk-QGI4UCJX.js";
11
+ import "./chunk-IWKJQZJQ.js";
12
12
  import "./chunk-VKVL7WBN.js";
13
13
  export {
14
14
  isTriageEnabledForExecution,
15
15
  runTriage
16
16
  };
17
- //# sourceMappingURL=triage-TT4BMDBU.js.map
17
+ //# sourceMappingURL=triage-M3RZ2ASB.js.map
@@ -1,10 +1,10 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  clearUpdateCache
4
- } from "./chunk-VGTKUOYS.js";
4
+ } from "./chunk-AQPJQ5AE.js";
5
5
  import {
6
6
  packageName
7
- } from "./chunk-JZMJUPZP.js";
7
+ } from "./chunk-32P26BZT.js";
8
8
  import "./chunk-VKVL7WBN.js";
9
9
 
10
10
  // src/upgrade.ts
@@ -58,4 +58,4 @@ Successfully upgraded ${packageName}.`);
58
58
  export {
59
59
  runUpgrade
60
60
  };
61
- //# sourceMappingURL=upgrade-6ZUFETKX.js.map
61
+ //# sourceMappingURL=upgrade-4QCRAUHP.js.map
@@ -4,17 +4,17 @@ import {
4
4
  } from "./chunk-4NRDONSC.js";
5
5
  import {
6
6
  workflowToSpec
7
- } from "./chunk-YN763NWQ.js";
7
+ } from "./chunk-26U3DGUM.js";
8
8
  import {
9
9
  applyWorkflowTagFlags
10
- } from "./chunk-EEN2TZUQ.js";
10
+ } from "./chunk-VKBTI5EF.js";
11
11
  import {
12
12
  alignSnapshotNodeIds
13
13
  } from "./chunk-JDBCZ3Z2.js";
14
14
  import {
15
15
  apiRequest,
16
16
  renderWorkflowUserError
17
- } from "./chunk-CQE46HSM.js";
17
+ } from "./chunk-CFJXYPTF.js";
18
18
  import {
19
19
  apiFetch,
20
20
  exitOnFailure,
@@ -25,16 +25,16 @@ import {
25
25
  hasFlag,
26
26
  resolveAppUrl,
27
27
  resolveConfig
28
- } from "./chunk-PZ4LCN6K.js";
28
+ } from "./chunk-IGHDIWZU.js";
29
29
  import {
30
30
  specExtension
31
- } from "./chunk-JZMJUPZP.js";
31
+ } from "./chunk-32P26BZT.js";
32
32
  import "./chunk-JWHYXEA2.js";
33
33
  import {
34
34
  NODE_TYPE_LABEL,
35
35
  USER_SETTABLE_WORKFLOW_STATUSES,
36
36
  normalizeNodeType
37
- } from "./chunk-QGI4UCJX.js";
37
+ } from "./chunk-IWKJQZJQ.js";
38
38
  import "./chunk-VKVL7WBN.js";
39
39
 
40
40
  // src/workflow.ts
@@ -2866,6 +2866,7 @@ function formatWorkflowMarkdown(workflow) {
2866
2866
  function formatWorkflowJson(workflow) {
2867
2867
  const sorted = [...workflow.nodes].sort((a, b) => a.orderIndex - b.orderIndex);
2868
2868
  const seedOutputs = workflow.seedOutputsJson;
2869
+ const env = workflow;
2869
2870
  return {
2870
2871
  workflow: {
2871
2872
  id: workflow.id,
@@ -2873,7 +2874,18 @@ function formatWorkflowJson(workflow) {
2873
2874
  description: workflow.description,
2874
2875
  status: workflow.status,
2875
2876
  flowType: workflow.flowType,
2876
- ...seedOutputs && seedOutputs.length > 0 ? { seedOutputs } : {}
2877
+ ...seedOutputs && seedOutputs.length > 0 ? { seedOutputs } : {},
2878
+ ...env.defaultEnvironmentId !== void 0 ? { defaultEnvironmentId: env.defaultEnvironmentId } : {},
2879
+ ...env.eligibleEnvironmentIds ? { eligibleEnvironmentIds: env.eligibleEnvironmentIds } : {},
2880
+ ...env.passByEnvironment && env.passByEnvironment.length > 0 ? {
2881
+ passByEnvironment: env.passByEnvironment.map((p) => ({
2882
+ environment: `${p.environmentName} (${p.environmentType})`,
2883
+ everPassed: p.everPassed,
2884
+ passed: p.passed,
2885
+ total: p.total,
2886
+ health: p.health
2887
+ }))
2888
+ } : {}
2877
2889
  },
2878
2890
  steps: sorted.map((node, i) => ({
2879
2891
  index: i + 1,
@@ -2998,7 +3010,7 @@ async function handlePatch(argv, apiUrl, token) {
2998
3010
  const workflowId = argv.find((a) => !a.startsWith("-"));
2999
3011
  if (!workflowId) {
3000
3012
  console.error("Error: Missing workflow ID.");
3001
- console.error("Usage: canary workflow patch <workflowId> [--name ...] [--description ...] [--status ...] [--flow-type ...]");
3013
+ console.error("Usage: canary workflow patch <workflowId> [--name ...] [--description ...] [--status ...] [--flow-type ...] [--default-environment <name|id>] [--clear-default-environment] [--any-environment] [--eligible-env-types permanent,sandbox] [--eligible-environments <names|ids>]");
3002
3014
  process9.exit(1);
3003
3015
  }
3004
3016
  const name = getArgValue(argv, "--name");
@@ -3008,10 +3020,28 @@ async function handlePatch(argv, apiUrl, token) {
3008
3020
  const seedOutputsJsonRaw = getArgValue(argv, "--seed-outputs-json");
3009
3021
  const seedOutputsFile = getArgValue(argv, "--seed-outputs-file");
3010
3022
  const jsonOutput = hasFlag(argv, "--json");
3023
+ const defaultEnvironment = getArgValue(argv, "--default-environment");
3024
+ const clearDefaultEnvironment = hasFlag(argv, "--clear-default-environment");
3025
+ const anyEnvironment = hasFlag(argv, "--any-environment");
3026
+ const eligibleEnvTypes = getArgValue(argv, "--eligible-env-types");
3027
+ const eligibleEnvironments = getArgValue(argv, "--eligible-environments");
3028
+ const hasEnvFlag = defaultEnvironment !== void 0 || clearDefaultEnvironment || anyEnvironment || eligibleEnvTypes !== void 0 || eligibleEnvironments !== void 0;
3011
3029
  const hasTagFlag = getArgValue(argv, "--tags") !== void 0 || getArgValue(argv, "--tags-add") !== void 0 || getArgValue(argv, "--tags-remove") !== void 0 || getArgValue(argv, "--tag-id") !== void 0;
3012
- if (!name && !description && !status && !flowType && !seedOutputsJsonRaw && !seedOutputsFile && !hasTagFlag) {
3030
+ if (!name && !description && !status && !flowType && !seedOutputsJsonRaw && !seedOutputsFile && !hasTagFlag && !hasEnvFlag) {
3013
3031
  console.error(
3014
- "Error: No fields to update. Provide at least one of: --name, --description, --status, --flow-type, --seed-outputs-json, --seed-outputs-file, --tags, --tags-add, --tags-remove, --tag-id"
3032
+ "Error: No fields to update. Provide at least one of: --name, --description, --status, --flow-type, --seed-outputs-json, --seed-outputs-file, --tags, --tags-add, --tags-remove, --tag-id, --default-environment, --clear-default-environment, --any-environment, --eligible-env-types, --eligible-environments"
3033
+ );
3034
+ process9.exit(1);
3035
+ }
3036
+ if (anyEnvironment && (eligibleEnvTypes !== void 0 || eligibleEnvironments !== void 0)) {
3037
+ console.error(
3038
+ "Error: --any-environment is mutually exclusive with --eligible-env-types / --eligible-environments."
3039
+ );
3040
+ process9.exit(1);
3041
+ }
3042
+ if (clearDefaultEnvironment && defaultEnvironment !== void 0) {
3043
+ console.error(
3044
+ "Error: --clear-default-environment is mutually exclusive with --default-environment."
3015
3045
  );
3016
3046
  process9.exit(1);
3017
3047
  }
@@ -3056,6 +3086,47 @@ async function handlePatch(argv, apiUrl, token) {
3056
3086
  process9.exit(1);
3057
3087
  }
3058
3088
  }
3089
+ if (hasEnvFlag) {
3090
+ if (anyEnvironment) body.environmentConstraints = null;
3091
+ if (eligibleEnvTypes !== void 0) {
3092
+ const types = eligibleEnvTypes.split(",").map((t) => t.trim()).filter(Boolean);
3093
+ const valid = ["permanent", "ephemeral", "local", "sandbox"];
3094
+ const bad = types.filter((t) => !valid.includes(t));
3095
+ if (bad.length > 0) {
3096
+ console.error(`Error: invalid env type(s): ${bad.join(", ")}. Valid: ${valid.join(", ")}`);
3097
+ process9.exit(1);
3098
+ }
3099
+ body.environmentConstraints = { mode: "envTypes", types };
3100
+ }
3101
+ if (clearDefaultEnvironment) body.defaultEnvironmentId = null;
3102
+ const needsResolution = defaultEnvironment !== void 0 || eligibleEnvironments !== void 0;
3103
+ if (needsResolution) {
3104
+ const detailRes = await apiRequest(
3105
+ apiUrl,
3106
+ token,
3107
+ "GET",
3108
+ `/workflows/${workflowId}`
3109
+ );
3110
+ const envs = detailRes.workflow?.environments ?? [];
3111
+ const resolveEnv = (nameOrId) => {
3112
+ const match = envs.find((e) => e.id === nameOrId) ?? envs.find((e) => e.name.toLowerCase() === nameOrId.toLowerCase());
3113
+ if (!match) {
3114
+ console.error(
3115
+ `Error: environment "${nameOrId}" not found on this flow's property. Known: ${envs.map((e) => `${e.name} (${e.type})`).join(", ") || "(none)"}`
3116
+ );
3117
+ process9.exit(1);
3118
+ }
3119
+ return match.id;
3120
+ };
3121
+ if (defaultEnvironment !== void 0) {
3122
+ body.defaultEnvironmentId = resolveEnv(defaultEnvironment);
3123
+ }
3124
+ if (eligibleEnvironments !== void 0) {
3125
+ const ids = eligibleEnvironments.split(",").map((t) => t.trim()).filter(Boolean).map(resolveEnv);
3126
+ body.environmentConstraints = { mode: "only", environmentIds: ids };
3127
+ }
3128
+ }
3129
+ }
3059
3130
  let tagResult = null;
3060
3131
  if (Object.keys(body).length > 0) {
3061
3132
  const result = await apiRequest(
@@ -3602,7 +3673,7 @@ async function runWorkflow(argv) {
3602
3673
  return;
3603
3674
  }
3604
3675
  if (subCommand === "debug" && hasFlag(rest, "--help", "-h")) {
3605
- const { handleWorkflowDebug } = await import("./workflow-debug-PRX3DWGD.js");
3676
+ const { handleWorkflowDebug } = await import("./workflow-debug-W4USZH35.js");
3606
3677
  await handleWorkflowDebug(rest, "", "");
3607
3678
  return;
3608
3679
  }
@@ -3680,7 +3751,7 @@ async function runWorkflow(argv) {
3680
3751
  await handleWorkflowSync(rest, apiUrl, token);
3681
3752
  break;
3682
3753
  case "proposals": {
3683
- const { handleWorkflowProposals } = await import("./workflow-proposals-BW327WGL.js");
3754
+ const { handleWorkflowProposals } = await import("./workflow-proposals-5E3DTYZB.js");
3684
3755
  await handleWorkflowProposals(rest, apiUrl, token);
3685
3756
  break;
3686
3757
  }
@@ -3691,12 +3762,12 @@ async function runWorkflow(argv) {
3691
3762
  await handleWorkflowApiSequence(rest, apiUrl, token);
3692
3763
  break;
3693
3764
  case "cache": {
3694
- const { handleWorkflowCache } = await import("./workflow-cache-GXNE6SU2.js");
3765
+ const { handleWorkflowCache } = await import("./workflow-cache-XPSK6KC7.js");
3695
3766
  await handleWorkflowCache(rest, apiUrl, token);
3696
3767
  break;
3697
3768
  }
3698
3769
  case "debug": {
3699
- const { handleWorkflowDebug } = await import("./workflow-debug-PRX3DWGD.js");
3770
+ const { handleWorkflowDebug } = await import("./workflow-debug-W4USZH35.js");
3700
3771
  await handleWorkflowDebug(rest, apiUrl, token);
3701
3772
  break;
3702
3773
  }
@@ -3709,4 +3780,4 @@ async function runWorkflow(argv) {
3709
3780
  export {
3710
3781
  runWorkflow
3711
3782
  };
3712
- //# sourceMappingURL=workflow-2CX3ZNOQ.js.map
3783
+ //# sourceMappingURL=workflow-4J23FV7K.js.map