@runcofactor/cli 0.10.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 (150) hide show
  1. package/README.md +125 -0
  2. package/dist/api-catalog-GFGCLVS4.js +401 -0
  3. package/dist/api-catalog-GFGCLVS4.js.map +1 -0
  4. package/dist/attachment-SJC7D7FY.js +276 -0
  5. package/dist/attachment-SJC7D7FY.js.map +1 -0
  6. package/dist/auth-EN6NQCJY.js +31 -0
  7. package/dist/auth-EN6NQCJY.js.map +1 -0
  8. package/dist/bin.js +7 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/chunk-3CZU7XCS.js +272 -0
  11. package/dist/chunk-3CZU7XCS.js.map +1 -0
  12. package/dist/chunk-4NRDONSC.js +1048 -0
  13. package/dist/chunk-4NRDONSC.js.map +1 -0
  14. package/dist/chunk-4PNOV7OV.js +51980 -0
  15. package/dist/chunk-4PNOV7OV.js.map +1 -0
  16. package/dist/chunk-52IO7ACJ.js +2941 -0
  17. package/dist/chunk-52IO7ACJ.js.map +1 -0
  18. package/dist/chunk-6LEZCKKV.js +663 -0
  19. package/dist/chunk-6LEZCKKV.js.map +1 -0
  20. package/dist/chunk-A4OFTUVV.js +170 -0
  21. package/dist/chunk-A4OFTUVV.js.map +1 -0
  22. package/dist/chunk-B2VISN2V.js +2459 -0
  23. package/dist/chunk-B2VISN2V.js.map +1 -0
  24. package/dist/chunk-CLAWT7BJ.js +271 -0
  25. package/dist/chunk-CLAWT7BJ.js.map +1 -0
  26. package/dist/chunk-GKY2KXO5.js +281 -0
  27. package/dist/chunk-GKY2KXO5.js.map +1 -0
  28. package/dist/chunk-I4QLI3JO.js +413 -0
  29. package/dist/chunk-I4QLI3JO.js.map +1 -0
  30. package/dist/chunk-IMPZAX6L.js +180 -0
  31. package/dist/chunk-IMPZAX6L.js.map +1 -0
  32. package/dist/chunk-J6SH7GQT.js +241 -0
  33. package/dist/chunk-J6SH7GQT.js.map +1 -0
  34. package/dist/chunk-JDBCZ3Z2.js +298 -0
  35. package/dist/chunk-JDBCZ3Z2.js.map +1 -0
  36. package/dist/chunk-JICSYFRJ.js +46 -0
  37. package/dist/chunk-JICSYFRJ.js.map +1 -0
  38. package/dist/chunk-JWHYXEA2.js +32 -0
  39. package/dist/chunk-JWHYXEA2.js.map +1 -0
  40. package/dist/chunk-N7HFALX3.js +88 -0
  41. package/dist/chunk-N7HFALX3.js.map +1 -0
  42. package/dist/chunk-Q4BO4Z5V.js +178 -0
  43. package/dist/chunk-Q4BO4Z5V.js.map +1 -0
  44. package/dist/chunk-QFDOWABX.js +195 -0
  45. package/dist/chunk-QFDOWABX.js.map +1 -0
  46. package/dist/chunk-SJJW77WN.js +605 -0
  47. package/dist/chunk-SJJW77WN.js.map +1 -0
  48. package/dist/chunk-VKVL7WBN.js +50 -0
  49. package/dist/chunk-VKVL7WBN.js.map +1 -0
  50. package/dist/chunk-WOHL4FTB.js +353 -0
  51. package/dist/chunk-WOHL4FTB.js.map +1 -0
  52. package/dist/chunk-XQXVG7RA.js +426 -0
  53. package/dist/chunk-XQXVG7RA.js.map +1 -0
  54. package/dist/chunk-ZD3KHESI.js +94 -0
  55. package/dist/chunk-ZD3KHESI.js.map +1 -0
  56. package/dist/credential-COLTBV6D.js +450 -0
  57. package/dist/credential-COLTBV6D.js.map +1 -0
  58. package/dist/credential-template-EEPYFG7R.js +291 -0
  59. package/dist/credential-template-EEPYFG7R.js.map +1 -0
  60. package/dist/debug-workflow-KOVH5GOP.js +259 -0
  61. package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
  62. package/dist/dist-44PZR7BQ.js +423 -0
  63. package/dist/dist-44PZR7BQ.js.map +1 -0
  64. package/dist/docs-3SSORHB5.js +366 -0
  65. package/dist/docs-3SSORHB5.js.map +1 -0
  66. package/dist/doctor-OTSIWV6G.js +132 -0
  67. package/dist/doctor-OTSIWV6G.js.map +1 -0
  68. package/dist/feature-flag-T2LRZME3.js +283 -0
  69. package/dist/feature-flag-T2LRZME3.js.map +1 -0
  70. package/dist/file-type-S3UUBVCT.js +4205 -0
  71. package/dist/file-type-S3UUBVCT.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +982 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/init-TGWRECT2.js +208 -0
  76. package/dist/init-TGWRECT2.js.map +1 -0
  77. package/dist/install-DXSNWZKO.js +295 -0
  78. package/dist/install-DXSNWZKO.js.map +1 -0
  79. package/dist/issues-XIZOPX6T.js +564 -0
  80. package/dist/issues-XIZOPX6T.js.map +1 -0
  81. package/dist/knobs-NBINZIUB.js +295 -0
  82. package/dist/knobs-NBINZIUB.js.map +1 -0
  83. package/dist/list-3TDHK637.js +59 -0
  84. package/dist/list-3TDHK637.js.map +1 -0
  85. package/dist/local-HICVD6PU.js +100 -0
  86. package/dist/local-HICVD6PU.js.map +1 -0
  87. package/dist/login-UOIUXVUK.js +315 -0
  88. package/dist/login-UOIUXVUK.js.map +1 -0
  89. package/dist/mcp-54IJEOUA.js +1956 -0
  90. package/dist/mcp-54IJEOUA.js.map +1 -0
  91. package/dist/pdf-extract-ABWV3L5X.js +13 -0
  92. package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
  93. package/dist/pdfjs-DQ2YA5S3.js +41561 -0
  94. package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
  95. package/dist/property-UXLOLPTD.js +701 -0
  96. package/dist/property-UXLOLPTD.js.map +1 -0
  97. package/dist/property-skill-guide.md +189 -0
  98. package/dist/psql-BYUUNLGG.js +115 -0
  99. package/dist/psql-BYUUNLGG.js.map +1 -0
  100. package/dist/record-4TR2UIIS.js +233 -0
  101. package/dist/record-4TR2UIIS.js.map +1 -0
  102. package/dist/redis-35VBUYW7.js +116 -0
  103. package/dist/redis-35VBUYW7.js.map +1 -0
  104. package/dist/release-OOLTUBUT.js +354 -0
  105. package/dist/release-OOLTUBUT.js.map +1 -0
  106. package/dist/sandbox-XGSUU6G7.js +2046 -0
  107. package/dist/sandbox-XGSUU6G7.js.map +1 -0
  108. package/dist/scenarios-GWLJEGHA.js +280 -0
  109. package/dist/scenarios-GWLJEGHA.js.map +1 -0
  110. package/dist/session-MYFNZPRP.js +2414 -0
  111. package/dist/session-MYFNZPRP.js.map +1 -0
  112. package/dist/skill-KM34LDMO.js +1839 -0
  113. package/dist/skill-KM34LDMO.js.map +1 -0
  114. package/dist/skills/debug-run/SKILL.md +262 -0
  115. package/dist/skills/debug-run/history/1.0.0.md +244 -0
  116. package/dist/skills/debug-run/history/1.0.1.md +245 -0
  117. package/dist/skills/debug-run/history/1.0.2.md +254 -0
  118. package/dist/skills/debug-run/history/1.1.0.md +262 -0
  119. package/dist/skills/debug-run/version.json +3 -0
  120. package/dist/spec-RA3CFEKG.js +951 -0
  121. package/dist/spec-RA3CFEKG.js.map +1 -0
  122. package/dist/src-LB4HBTJQ.js +1516 -0
  123. package/dist/src-LB4HBTJQ.js.map +1 -0
  124. package/dist/src-N3TPKGTY.js +244 -0
  125. package/dist/src-N3TPKGTY.js.map +1 -0
  126. package/dist/src-UVDX5UP6.js +17 -0
  127. package/dist/src-UVDX5UP6.js.map +1 -0
  128. package/dist/start-PSEQSQA3.js +151 -0
  129. package/dist/start-PSEQSQA3.js.map +1 -0
  130. package/dist/tag-YY6YAABQ.js +22 -0
  131. package/dist/tag-YY6YAABQ.js.map +1 -0
  132. package/dist/task-IQC3YR5K.js +922 -0
  133. package/dist/task-IQC3YR5K.js.map +1 -0
  134. package/dist/test-suite-DZNJFXDW.js +394 -0
  135. package/dist/test-suite-DZNJFXDW.js.map +1 -0
  136. package/dist/trace-HXIW7U2D.js +14 -0
  137. package/dist/trace-HXIW7U2D.js.map +1 -0
  138. package/dist/triage-ORG45R5W.js +16 -0
  139. package/dist/triage-ORG45R5W.js.map +1 -0
  140. package/dist/upgrade-L2VYMP2V.js +61 -0
  141. package/dist/upgrade-L2VYMP2V.js.map +1 -0
  142. package/dist/workflow-XYFH5LTP.js +3708 -0
  143. package/dist/workflow-XYFH5LTP.js.map +1 -0
  144. package/dist/workflow-cache-NQJQFWMV.js +253 -0
  145. package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
  146. package/dist/workflow-debug-BGD4UIXU.js +927 -0
  147. package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
  148. package/dist/workflow-proposals-MTUDX46O.js +382 -0
  149. package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
  150. package/package.json +61 -0
@@ -0,0 +1,291 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ apiRequest,
4
+ fetchProperties,
5
+ getApplicationArg
6
+ } from "./chunk-WOHL4FTB.js";
7
+ import "./chunk-SJJW77WN.js";
8
+ import "./chunk-3CZU7XCS.js";
9
+ import {
10
+ getArgValue,
11
+ hasFlag,
12
+ resolveConfig
13
+ } from "./chunk-A4OFTUVV.js";
14
+ import "./chunk-JWHYXEA2.js";
15
+ import "./chunk-VKVL7WBN.js";
16
+
17
+ // src/credential-template.ts
18
+ import process from "process";
19
+ function printHelp() {
20
+ console.log(
21
+ [
22
+ "Usage: canary credential-template <sub-command> [options]",
23
+ "",
24
+ "Sub-commands: (--application accepted as --app; --property is a backwards-compat alias)",
25
+ " list --application <name|id> List templates on an application",
26
+ " create --application <name|id> --name <name> [--description <text>]",
27
+ " show --application <name|id> <templateId> Show template + its bindings",
28
+ " rename --application <name|id> <templateId> --name <new-name>",
29
+ " delete --application <name|id> <templateId>",
30
+ " link --application <name|id> <templateId> --credential <credId>",
31
+ " unlink --application <name|id> <templateId> --credential <credId>",
32
+ "",
33
+ "Common options:",
34
+ " --json Output raw JSON",
35
+ " --env <env> Target environment (prod, dev, local)",
36
+ " --api-url <url> API URL override",
37
+ " --token <key> API token override"
38
+ ].join("\n")
39
+ );
40
+ }
41
+ function getPositionalArg(argv, flagsWithValues) {
42
+ const skip = /* @__PURE__ */ new Set();
43
+ for (let i = 0; i < argv.length; i++) {
44
+ if (flagsWithValues.includes(argv[i]) && i + 1 < argv.length) {
45
+ skip.add(i);
46
+ skip.add(i + 1);
47
+ }
48
+ }
49
+ for (let i = 0; i < argv.length; i++) {
50
+ if (skip.has(i)) continue;
51
+ const a = argv[i];
52
+ if (!a.startsWith("-")) return a;
53
+ }
54
+ return void 0;
55
+ }
56
+ var TEMPLATE_FLAGS = [
57
+ "--application",
58
+ "--property",
59
+ "--credential",
60
+ "--name",
61
+ "--description",
62
+ "--env",
63
+ "--api-url",
64
+ "--token"
65
+ ];
66
+ async function resolveProperty(apiUrl, token, arg) {
67
+ const properties = await fetchProperties(apiUrl, token);
68
+ const property = properties.find(
69
+ (p) => p.id === arg || p.name.toLowerCase() === arg.toLowerCase()
70
+ );
71
+ if (!property) {
72
+ console.error(`Error: Application "${arg}" not found.`);
73
+ process.exit(1);
74
+ }
75
+ return property;
76
+ }
77
+ async function handleList(argv, apiUrl, token) {
78
+ const propertyArg = getApplicationArg(argv);
79
+ const jsonFlag = hasFlag(argv, "--json");
80
+ if (!propertyArg) {
81
+ console.error("Error: --application is required (alias: --property).");
82
+ process.exit(1);
83
+ }
84
+ const property = await resolveProperty(apiUrl, token, propertyArg);
85
+ const result = await apiRequest(
86
+ apiUrl,
87
+ token,
88
+ "GET",
89
+ `/org/properties/${property.id}/credential-templates`
90
+ );
91
+ if (!result.ok) {
92
+ console.error(`Error: ${result.error ?? "Failed to list templates"}`);
93
+ process.exit(1);
94
+ }
95
+ const items = result.items ?? [];
96
+ if (jsonFlag) {
97
+ console.log(JSON.stringify(items, null, 2));
98
+ return;
99
+ }
100
+ if (items.length === 0) {
101
+ console.log(`No credential templates on application "${property.name}".`);
102
+ return;
103
+ }
104
+ for (const t of items) {
105
+ console.log(`${t.id} ${t.name}${t.description ? ` \u2014 ${t.description}` : ""}`);
106
+ }
107
+ }
108
+ async function handleCreate(argv, apiUrl, token) {
109
+ const propertyArg = getApplicationArg(argv);
110
+ const name = getArgValue(argv, "--name");
111
+ const description = getArgValue(argv, "--description");
112
+ const jsonFlag = hasFlag(argv, "--json");
113
+ if (!propertyArg || !name) {
114
+ console.error("Error: --application and --name are required.");
115
+ process.exit(1);
116
+ }
117
+ const property = await resolveProperty(apiUrl, token, propertyArg);
118
+ const result = await apiRequest(
119
+ apiUrl,
120
+ token,
121
+ "POST",
122
+ `/org/properties/${property.id}/credential-templates`,
123
+ { name, description: description ?? null }
124
+ );
125
+ if (!result.ok || !result.template) {
126
+ console.error(`Error: ${result.error ?? "Failed to create template"}`);
127
+ process.exit(1);
128
+ }
129
+ if (jsonFlag) {
130
+ console.log(JSON.stringify(result.template, null, 2));
131
+ return;
132
+ }
133
+ console.log(`Created template "${result.template.name}" (${result.template.id})`);
134
+ }
135
+ async function handleShow(argv, apiUrl, token) {
136
+ const propertyArg = getApplicationArg(argv);
137
+ const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);
138
+ const jsonFlag = hasFlag(argv, "--json");
139
+ if (!propertyArg || !templateId) {
140
+ console.error("Error: --application and <templateId> are required.");
141
+ process.exit(1);
142
+ }
143
+ const property = await resolveProperty(apiUrl, token, propertyArg);
144
+ const result = await apiRequest(
145
+ apiUrl,
146
+ token,
147
+ "GET",
148
+ `/org/properties/${property.id}/credential-templates/${templateId}`
149
+ );
150
+ if (!result.ok || !result.template) {
151
+ console.error(`Error: ${result.error ?? "Failed to fetch template"}`);
152
+ process.exit(1);
153
+ }
154
+ if (jsonFlag) {
155
+ console.log(JSON.stringify(result, null, 2));
156
+ return;
157
+ }
158
+ const t = result.template;
159
+ console.log(`${t.name} (${t.id})`);
160
+ if (t.description) console.log(` ${t.description}`);
161
+ console.log(`Bindings (${result.bindings?.length ?? 0}):`);
162
+ for (const b of result.bindings ?? []) {
163
+ const env = b.environmentId ?? "(no env)";
164
+ const eph = b.isEphemeral ? " [ephemeral]" : "";
165
+ console.log(` ${b.id} env=${env} ${b.name}${eph}`);
166
+ }
167
+ }
168
+ async function handleRename(argv, apiUrl, token) {
169
+ const propertyArg = getApplicationArg(argv);
170
+ const newName = getArgValue(argv, "--name");
171
+ const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);
172
+ if (!propertyArg || !templateId || !newName) {
173
+ console.error("Error: --application, <templateId>, and --name are required.");
174
+ process.exit(1);
175
+ }
176
+ const property = await resolveProperty(apiUrl, token, propertyArg);
177
+ const result = await apiRequest(
178
+ apiUrl,
179
+ token,
180
+ "PATCH",
181
+ `/org/properties/${property.id}/credential-templates/${templateId}`,
182
+ { name: newName }
183
+ );
184
+ if (!result.ok) {
185
+ console.error(`Error: ${result.error ?? "Failed to rename template"}`);
186
+ process.exit(1);
187
+ }
188
+ console.log(`Renamed template ${templateId} \u2192 "${newName}"`);
189
+ }
190
+ async function handleDelete(argv, apiUrl, token) {
191
+ const propertyArg = getApplicationArg(argv);
192
+ const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);
193
+ if (!propertyArg || !templateId) {
194
+ console.error("Error: --application and <templateId> are required.");
195
+ process.exit(1);
196
+ }
197
+ const property = await resolveProperty(apiUrl, token, propertyArg);
198
+ const result = await apiRequest(
199
+ apiUrl,
200
+ token,
201
+ "DELETE",
202
+ `/org/properties/${property.id}/credential-templates/${templateId}`
203
+ );
204
+ if (!result.ok) {
205
+ console.error(`Error: ${result.error ?? "Failed to delete template"}`);
206
+ process.exit(1);
207
+ }
208
+ console.log(`Deleted template ${templateId}`);
209
+ }
210
+ async function handleLink(argv, apiUrl, token) {
211
+ const propertyArg = getApplicationArg(argv);
212
+ const credentialId = getArgValue(argv, "--credential");
213
+ const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);
214
+ if (!propertyArg || !templateId || !credentialId) {
215
+ console.error("Error: --application, <templateId>, and --credential are required.");
216
+ process.exit(1);
217
+ }
218
+ const property = await resolveProperty(apiUrl, token, propertyArg);
219
+ const result = await apiRequest(
220
+ apiUrl,
221
+ token,
222
+ "POST",
223
+ `/org/properties/${property.id}/credential-templates/${templateId}/bindings`,
224
+ { credentialId }
225
+ );
226
+ if (!result.ok) {
227
+ console.error(`Error: ${result.error ?? "Failed to link credential"}`);
228
+ process.exit(1);
229
+ }
230
+ console.log(`Linked credential ${credentialId} to template ${templateId}`);
231
+ }
232
+ async function handleUnlink(argv, apiUrl, token) {
233
+ const propertyArg = getApplicationArg(argv);
234
+ const credentialId = getArgValue(argv, "--credential");
235
+ const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);
236
+ if (!propertyArg || !templateId || !credentialId) {
237
+ console.error("Error: --application, <templateId>, and --credential are required.");
238
+ process.exit(1);
239
+ }
240
+ const property = await resolveProperty(apiUrl, token, propertyArg);
241
+ const result = await apiRequest(
242
+ apiUrl,
243
+ token,
244
+ "DELETE",
245
+ `/org/properties/${property.id}/credential-templates/${templateId}/bindings/${credentialId}`
246
+ );
247
+ if (!result.ok) {
248
+ console.error(`Error: ${result.error ?? "Failed to unlink credential"}`);
249
+ process.exit(1);
250
+ }
251
+ console.log(`Unlinked credential ${credentialId} from template ${templateId}`);
252
+ }
253
+ async function runCredentialTemplate(argv) {
254
+ const [subCommand, ...rest] = argv;
255
+ if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
256
+ printHelp();
257
+ return;
258
+ }
259
+ const { apiUrl, token } = await resolveConfig(rest);
260
+ switch (subCommand) {
261
+ case "list":
262
+ await handleList(rest, apiUrl, token);
263
+ return;
264
+ case "create":
265
+ await handleCreate(rest, apiUrl, token);
266
+ return;
267
+ case "show":
268
+ await handleShow(rest, apiUrl, token);
269
+ return;
270
+ case "rename":
271
+ await handleRename(rest, apiUrl, token);
272
+ return;
273
+ case "delete":
274
+ await handleDelete(rest, apiUrl, token);
275
+ return;
276
+ case "link":
277
+ await handleLink(rest, apiUrl, token);
278
+ return;
279
+ case "unlink":
280
+ await handleUnlink(rest, apiUrl, token);
281
+ return;
282
+ default:
283
+ console.error(`Unknown credential-template sub-command: ${subCommand}`);
284
+ printHelp();
285
+ process.exit(1);
286
+ }
287
+ }
288
+ export {
289
+ runCredentialTemplate
290
+ };
291
+ //# sourceMappingURL=credential-template-EEPYFG7R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/credential-template.ts"],"sourcesContent":["/**\n * CLI Credential Template Commands\n *\n * Manage property-scoped credential templates (logical credential identities\n * that group per-environment concrete credential bindings).\n *\n * @module credential-template\n */\n\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, fetchProperties, getApplicationArg } from './cli-helpers.js';\n\ntype Template = {\n id: string;\n propertyId: string;\n name: string;\n description: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\ntype Binding = {\n id: string;\n name: string;\n environmentId: string | null;\n isEphemeral: boolean;\n templateId: string | null;\n};\n\nfunction printHelp(): void {\n console.log(\n [\n 'Usage: canary credential-template <sub-command> [options]',\n '',\n 'Sub-commands: (--application accepted as --app; --property is a backwards-compat alias)',\n ' list --application <name|id> List templates on an application',\n ' create --application <name|id> --name <name> [--description <text>]',\n ' show --application <name|id> <templateId> Show template + its bindings',\n ' rename --application <name|id> <templateId> --name <new-name>',\n ' delete --application <name|id> <templateId>',\n ' link --application <name|id> <templateId> --credential <credId>',\n ' unlink --application <name|id> <templateId> --credential <credId>',\n '',\n 'Common options:',\n ' --json Output raw JSON',\n ' --env <env> Target environment (prod, dev, local)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\n/**\n * Return the first positional argument, excluding values consumed by the given\n * `--flag value` pairs. Prior implementation used `argv.find(a => !a.startsWith('-'))`\n * which incorrectly returned the value of `--property` (the first flag value) as\n * the templateId.\n */\nfunction getPositionalArg(argv: string[], flagsWithValues: string[]): string | undefined {\n const skip = new Set<number>();\n for (let i = 0; i < argv.length; i++) {\n if (flagsWithValues.includes(argv[i]!) && i + 1 < argv.length) {\n skip.add(i);\n skip.add(i + 1);\n }\n }\n for (let i = 0; i < argv.length; i++) {\n if (skip.has(i)) continue;\n const a = argv[i]!;\n if (!a.startsWith('-')) return a;\n }\n return undefined;\n}\n\nconst TEMPLATE_FLAGS = [\n '--application',\n '--property',\n '--credential',\n '--name',\n '--description',\n '--env',\n '--api-url',\n '--token',\n];\n\nasync function resolveProperty(\n apiUrl: string,\n token: string,\n arg: string\n): Promise<{ id: string; name: string }> {\n const properties = await fetchProperties(apiUrl, token);\n const property = properties.find(\n (p) => p.id === arg || p.name.toLowerCase() === arg.toLowerCase()\n );\n if (!property) {\n console.error(`Error: Application \"${arg}\" not found.`);\n process.exit(1);\n }\n return property;\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const jsonFlag = hasFlag(argv, '--json');\n if (!propertyArg) {\n console.error('Error: --application is required (alias: --property).');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; items?: Template[]; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${property.id}/credential-templates`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to list templates'}`);\n process.exit(1);\n }\n const items = result.items ?? [];\n if (jsonFlag) {\n console.log(JSON.stringify(items, null, 2));\n return;\n }\n if (items.length === 0) {\n console.log(`No credential templates on application \"${property.name}\".`);\n return;\n }\n for (const t of items) {\n console.log(`${t.id} ${t.name}${t.description ? ` — ${t.description}` : ''}`);\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const name = getArgValue(argv, '--name');\n const description = getArgValue(argv, '--description');\n const jsonFlag = hasFlag(argv, '--json');\n\n if (!propertyArg || !name) {\n console.error('Error: --application and --name are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; template?: Template; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${property.id}/credential-templates`,\n { name, description: description ?? null }\n );\n if (!result.ok || !result.template) {\n console.error(`Error: ${result.error ?? 'Failed to create template'}`);\n process.exit(1);\n }\n if (jsonFlag) {\n console.log(JSON.stringify(result.template, null, 2));\n return;\n }\n console.log(`Created template \"${result.template.name}\" (${result.template.id})`);\n}\n\nasync function handleShow(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);\n const jsonFlag = hasFlag(argv, '--json');\n\n if (!propertyArg || !templateId) {\n console.error('Error: --application and <templateId> are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{\n ok: boolean;\n template?: Template;\n bindings?: Binding[];\n error?: string;\n }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${property.id}/credential-templates/${templateId}`\n );\n if (!result.ok || !result.template) {\n console.error(`Error: ${result.error ?? 'Failed to fetch template'}`);\n process.exit(1);\n }\n if (jsonFlag) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n const t = result.template;\n console.log(`${t.name} (${t.id})`);\n if (t.description) console.log(` ${t.description}`);\n console.log(`Bindings (${result.bindings?.length ?? 0}):`);\n for (const b of result.bindings ?? []) {\n const env = b.environmentId ?? '(no env)';\n const eph = b.isEphemeral ? ' [ephemeral]' : '';\n console.log(` ${b.id} env=${env} ${b.name}${eph}`);\n }\n}\n\nasync function handleRename(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const newName = getArgValue(argv, '--name');\n const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);\n if (!propertyArg || !templateId || !newName) {\n console.error('Error: --application, <templateId>, and --name are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; template?: Template; error?: string }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/properties/${property.id}/credential-templates/${templateId}`,\n { name: newName }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to rename template'}`);\n process.exit(1);\n }\n console.log(`Renamed template ${templateId} → \"${newName}\"`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);\n if (!propertyArg || !templateId) {\n console.error('Error: --application and <templateId> are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/properties/${property.id}/credential-templates/${templateId}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to delete template'}`);\n process.exit(1);\n }\n console.log(`Deleted template ${templateId}`);\n}\n\nasync function handleLink(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const credentialId = getArgValue(argv, '--credential');\n const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);\n if (!propertyArg || !templateId || !credentialId) {\n console.error('Error: --application, <templateId>, and --credential are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${property.id}/credential-templates/${templateId}/bindings`,\n { credentialId }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to link credential'}`);\n process.exit(1);\n }\n console.log(`Linked credential ${credentialId} to template ${templateId}`);\n}\n\nasync function handleUnlink(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyArg = getApplicationArg(argv);\n const credentialId = getArgValue(argv, '--credential');\n const templateId = getPositionalArg(argv, TEMPLATE_FLAGS);\n if (!propertyArg || !templateId || !credentialId) {\n console.error('Error: --application, <templateId>, and --credential are required.');\n process.exit(1);\n }\n const property = await resolveProperty(apiUrl, token, propertyArg);\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/properties/${property.id}/credential-templates/${templateId}/bindings/${credentialId}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to unlink credential'}`);\n process.exit(1);\n }\n console.log(`Unlinked credential ${credentialId} from template ${templateId}`);\n}\n\nexport async function runCredentialTemplate(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(rest);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n return;\n case 'create':\n await handleCreate(rest, apiUrl, token);\n return;\n case 'show':\n await handleShow(rest, apiUrl, token);\n return;\n case 'rename':\n await handleRename(rest, apiUrl, token);\n return;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n return;\n case 'link':\n await handleLink(rest, apiUrl, token);\n return;\n case 'unlink':\n await handleUnlink(rest, apiUrl, token);\n return;\n default:\n console.error(`Unknown credential-template sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,259 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ acquireCloudLock,
4
+ createSessionWithRelay,
5
+ deleteSession,
6
+ releaseCloudLock
7
+ } from "./chunk-J6SH7GQT.js";
8
+ import {
9
+ downloadStorageState
10
+ } from "./chunk-WOHL4FTB.js";
11
+ import "./chunk-SJJW77WN.js";
12
+ import "./chunk-3CZU7XCS.js";
13
+ import {
14
+ getArgValue,
15
+ hasFlag,
16
+ resolveConfig
17
+ } from "./chunk-A4OFTUVV.js";
18
+ import "./chunk-JWHYXEA2.js";
19
+ import "./chunk-VKVL7WBN.js";
20
+
21
+ // src/debug-workflow.ts
22
+ import fs from "fs/promises";
23
+ import process from "process";
24
+ import { createParser } from "eventsource-parser";
25
+ async function runDebugWorkflow(argv) {
26
+ const workflowId = argv.find((arg) => !arg.startsWith("-"));
27
+ if (!workflowId) {
28
+ console.error("Usage: canary debug <workflowId> [--to-step N] [--env local|dev|prod]");
29
+ process.exit(1);
30
+ }
31
+ const toStepStr = getArgValue(argv, "--to-step");
32
+ const toStep = toStepStr ? parseInt(toStepStr, 10) : void 0;
33
+ const verbose = hasFlag(argv, "--verbose", "-v");
34
+ if (toStep !== void 0 && (isNaN(toStep) || toStep < 1)) {
35
+ console.error("Error: --to-step must be a positive integer");
36
+ process.exit(1);
37
+ }
38
+ const { apiUrl, token } = await resolveConfig(argv);
39
+ console.log("Loading workflow...");
40
+ let debugSession;
41
+ try {
42
+ const res = await fetch(`${apiUrl}/cli/debug/sessions`, {
43
+ method: "POST",
44
+ headers: {
45
+ "Content-Type": "application/json",
46
+ Authorization: `Bearer ${token}`
47
+ },
48
+ body: JSON.stringify({ workflowId })
49
+ });
50
+ if (!res.ok) {
51
+ const text = await res.text();
52
+ console.error(`Failed to create debug session: ${res.status} ${text}`);
53
+ process.exit(1);
54
+ }
55
+ debugSession = await res.json();
56
+ if (!debugSession.ok || !debugSession.sessionId) {
57
+ console.error(`Failed to create debug session: ${debugSession.error}`);
58
+ process.exit(1);
59
+ }
60
+ } catch (err) {
61
+ console.error(`Failed to create debug session: ${err}`);
62
+ process.exit(1);
63
+ }
64
+ const debugSessionId = debugSession.sessionId;
65
+ let storageStatePath;
66
+ if (debugSession.isAuthenticated && debugSession.credential) {
67
+ console.log("Downloading storage state...");
68
+ storageStatePath = await downloadStorageState({
69
+ apiUrl,
70
+ token,
71
+ propertyId: debugSession.credential.propertyId,
72
+ credentialId: debugSession.credential.credentialId,
73
+ prefix: "canary-debug-ss"
74
+ });
75
+ if (storageStatePath) {
76
+ console.log("Storage state loaded.");
77
+ } else {
78
+ console.warn("Could not download storage state, continuing without it.");
79
+ }
80
+ }
81
+ console.log("Launching headed browser...");
82
+ let daemonSessionId;
83
+ let localBrowserSessionId;
84
+ try {
85
+ const result = await createSessionWithRelay({
86
+ headless: false,
87
+ storageStatePath,
88
+ name: `debug-${workflowId.slice(0, 8)}`,
89
+ cloudRelay: { apiUrl, token }
90
+ });
91
+ if (!result.ok || !result.data) {
92
+ console.error(`Failed to create browser session: ${result.error}`);
93
+ process.exit(1);
94
+ }
95
+ daemonSessionId = result.data.id;
96
+ localBrowserSessionId = result.data.cloudRelay?.localBrowserSessionId;
97
+ if (!localBrowserSessionId) {
98
+ console.error("Cloud relay not established. Cannot run debug workflow.");
99
+ await deleteSession(daemonSessionId);
100
+ process.exit(1);
101
+ }
102
+ } catch (err) {
103
+ console.error(`Failed to start browser: ${err}`);
104
+ process.exit(1);
105
+ }
106
+ try {
107
+ const res = await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}/link`, {
108
+ method: "POST",
109
+ headers: {
110
+ "Content-Type": "application/json",
111
+ Authorization: `Bearer ${token}`
112
+ },
113
+ body: JSON.stringify({ localBrowserSessionId })
114
+ });
115
+ if (!res.ok) {
116
+ const text = await res.text();
117
+ console.error(`Failed to link debug session to browser: ${res.status} ${text}`);
118
+ await deleteSession(daemonSessionId);
119
+ process.exit(1);
120
+ }
121
+ } catch (err) {
122
+ console.error(`Failed to link debug session: ${err}`);
123
+ await deleteSession(daemonSessionId);
124
+ process.exit(1);
125
+ }
126
+ console.log("Browser connected.");
127
+ console.log();
128
+ const cleanup = async () => {
129
+ console.log("\nShutting down...");
130
+ try {
131
+ await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}`, {
132
+ method: "DELETE",
133
+ headers: { Authorization: `Bearer ${token}` }
134
+ });
135
+ } catch {
136
+ }
137
+ if (storageStatePath) {
138
+ await fs.unlink(storageStatePath).catch(() => {
139
+ });
140
+ }
141
+ await deleteSession(daemonSessionId);
142
+ process.exit(0);
143
+ };
144
+ process.on("SIGINT", () => void cleanup());
145
+ process.on("SIGTERM", () => void cleanup());
146
+ const nodes = debugSession.nodes ?? [];
147
+ const totalSteps = nodes.length;
148
+ const effectiveToStep = toStep ? Math.min(toStep, totalSteps) : totalSteps;
149
+ console.log(`Debugging: "${debugSession.workflowName}" (${totalSteps} steps)`);
150
+ if (toStep) {
151
+ console.log(`Running steps 1-${effectiveToStep} of ${totalSteps}`);
152
+ }
153
+ console.log();
154
+ await acquireCloudLock(daemonSessionId);
155
+ let runRes;
156
+ try {
157
+ runRes = await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}/run`, {
158
+ method: "POST",
159
+ headers: {
160
+ "Content-Type": "application/json",
161
+ Authorization: `Bearer ${token}`,
162
+ Accept: "text/event-stream"
163
+ },
164
+ body: JSON.stringify({ toStep: effectiveToStep })
165
+ });
166
+ } catch (err) {
167
+ console.error(`Failed to start execution: ${err}`);
168
+ await cleanup();
169
+ return;
170
+ }
171
+ if (!runRes.ok || !runRes.body) {
172
+ console.error(`Failed to start execution: ${runRes.status}`);
173
+ await cleanup();
174
+ return;
175
+ }
176
+ let currentStep = 0;
177
+ let _hasError = false;
178
+ const stepResults = /* @__PURE__ */ new Map();
179
+ const parser = createParser({
180
+ onEvent: (event) => {
181
+ if (!event.data) return;
182
+ try {
183
+ const data = JSON.parse(event.data);
184
+ if (verbose) {
185
+ console.log(`[SSE] ${JSON.stringify(data)}`);
186
+ }
187
+ if (data.type === "step-started") {
188
+ const e = data;
189
+ currentStep = e.stepIndex;
190
+ process.stdout.write(`[${e.stepIndex}/${e.totalSteps}] ${e.stepName} `);
191
+ }
192
+ if (data.type === "completed") {
193
+ const e = data;
194
+ const stepIndex = e.stepIndex ?? currentStep;
195
+ const success = e.result.success;
196
+ const source = e.result.source;
197
+ if (success) {
198
+ const sourceLabel = source === "cache" ? "(cache)" : source === "agent" ? "(agent)" : "";
199
+ console.log(`\u2713 ${sourceLabel}`);
200
+ } else {
201
+ console.log("\u2717");
202
+ if (e.result.errorMessage) {
203
+ console.log(` Error: ${e.result.errorMessage.slice(0, 200)}`);
204
+ }
205
+ _hasError = true;
206
+ }
207
+ stepResults.set(stepIndex, {
208
+ name: `Step ${stepIndex}`,
209
+ success,
210
+ source
211
+ });
212
+ }
213
+ if (data.type === "run-complete") {
214
+ const e = data;
215
+ console.log();
216
+ if (e.stoppedEarly) {
217
+ console.log(
218
+ `Stopped at step ${e.stepsExecuted} of ${e.totalSteps}. ${e.reason === "step-failed" ? "Step failed." : "Error occurred."}`
219
+ );
220
+ } else {
221
+ console.log(`All ${e.stepsExecuted} step(s) completed.`);
222
+ }
223
+ }
224
+ if (data.type === "run-error") {
225
+ const errorData = data;
226
+ console.log(`\u2717`);
227
+ if (errorData.error) {
228
+ console.log(` Error: ${String(errorData.error).slice(0, 200)}`);
229
+ }
230
+ _hasError = true;
231
+ }
232
+ } catch {
233
+ }
234
+ }
235
+ });
236
+ const reader = runRes.body.getReader();
237
+ const decoder = new TextDecoder();
238
+ try {
239
+ while (true) {
240
+ const { done, value } = await reader.read();
241
+ if (done) break;
242
+ parser.feed(decoder.decode(value, { stream: true }));
243
+ }
244
+ } finally {
245
+ reader.releaseLock();
246
+ }
247
+ await releaseCloudLock(daemonSessionId);
248
+ console.log();
249
+ console.log("Browser is open for inspection.");
250
+ console.log(" Take control: canary session take-control");
251
+ console.log(" Resume cloud: canary session resume-cloud");
252
+ console.log("Press Ctrl+C to close.");
253
+ await new Promise(() => {
254
+ });
255
+ }
256
+ export {
257
+ runDebugWorkflow
258
+ };
259
+ //# sourceMappingURL=debug-workflow-KOVH5GOP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/debug-workflow.ts"],"sourcesContent":["/**\n * Debug Workflow Command\n *\n * Runs a workflow in a local headed browser for debugging. Replays cached\n * actions where possible and falls back to the agent for uncached steps.\n * The browser stays open after execution so the user can inspect page state.\n *\n * Uses the session daemon for browser lifecycle and cloud relay for\n * server-driven step execution.\n *\n * Usage:\n * canary debug <workflowId> [--to-step N] [--api-url URL] [--env local|dev|prod]\n *\n * @module debug-workflow\n */\n\nimport fs from 'node:fs/promises';\nimport process from 'node:process';\nimport { createParser, type EventSourceMessage } from 'eventsource-parser';\nimport { resolveConfig, getArgValue, hasFlag } from './auth';\nimport { downloadStorageState } from './cli-helpers.js';\nimport {\n createSessionWithRelay,\n deleteSession,\n acquireCloudLock,\n releaseCloudLock,\n} from './session/daemon-client.js';\n\ninterface DebugSessionResponse {\n ok: boolean;\n sessionId?: string;\n workflowName?: string;\n nodes?: Array<{\n index: number;\n id: string;\n name: string;\n type: string;\n }>;\n isAuthenticated?: boolean;\n credential?: { credentialId: string; propertyId: string } | null;\n error?: string;\n}\n\ninterface StepStartedEvent {\n type: 'step-started';\n stepIndex: number;\n totalSteps: number;\n stepName: string;\n nodeType: string;\n nodeId: string;\n}\n\ninterface NodeCompletedEvent {\n type: 'completed';\n stepIndex?: number;\n result: { success: boolean; errorMessage?: string; source?: string };\n}\n\ninterface RunCompleteEvent {\n type: 'run-complete';\n stepsExecuted: number;\n totalSteps: number;\n stoppedEarly: boolean;\n reason?: string;\n}\n\ntype DebugEvent =\n | StepStartedEvent\n | NodeCompletedEvent\n | RunCompleteEvent\n | { type: string; [key: string]: unknown };\n\nexport async function runDebugWorkflow(argv: string[]): Promise<void> {\n const workflowId = argv.find((arg) => !arg.startsWith('-'));\n\n if (!workflowId) {\n console.error('Usage: canary debug <workflowId> [--to-step N] [--env local|dev|prod]');\n process.exit(1);\n }\n\n const toStepStr = getArgValue(argv, '--to-step');\n const toStep = toStepStr ? parseInt(toStepStr, 10) : undefined;\n const verbose = hasFlag(argv, '--verbose', '-v');\n\n if (toStep !== undefined && (isNaN(toStep) || toStep < 1)) {\n console.error('Error: --to-step must be a positive integer');\n process.exit(1);\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n // 1. Create debug session (before browser launch so we can download storage state)\n console.log('Loading workflow...');\n\n let debugSession: DebugSessionResponse;\n try {\n const res = await fetch(`${apiUrl}/cli/debug/sessions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ workflowId }),\n });\n\n if (!res.ok) {\n const text = await res.text();\n console.error(`Failed to create debug session: ${res.status} ${text}`);\n process.exit(1);\n }\n\n debugSession = (await res.json()) as DebugSessionResponse;\n if (!debugSession.ok || !debugSession.sessionId) {\n console.error(`Failed to create debug session: ${debugSession.error}`);\n process.exit(1);\n }\n } catch (err) {\n console.error(`Failed to create debug session: ${err}`);\n process.exit(1);\n }\n\n const debugSessionId: string = debugSession.sessionId!;\n\n // 2. Download storage state if the workflow has valid credentials\n let storageStatePath: string | undefined;\n if (debugSession.isAuthenticated && debugSession.credential) {\n console.log('Downloading storage state...');\n storageStatePath = await downloadStorageState({\n apiUrl,\n token,\n propertyId: debugSession.credential.propertyId,\n credentialId: debugSession.credential.credentialId,\n prefix: 'canary-debug-ss',\n });\n if (storageStatePath) {\n console.log('Storage state loaded.');\n } else {\n console.warn('Could not download storage state, continuing without it.');\n }\n }\n\n // 3. Create a daemon session with cloud relay\n console.log('Launching headed browser...');\n\n let daemonSessionId: string;\n let localBrowserSessionId: string | undefined;\n try {\n const result = await createSessionWithRelay({\n headless: false,\n storageStatePath,\n name: `debug-${workflowId.slice(0, 8)}`,\n cloudRelay: { apiUrl, token },\n });\n\n if (!result.ok || !result.data) {\n console.error(`Failed to create browser session: ${result.error}`);\n process.exit(1);\n }\n\n daemonSessionId = result.data.id;\n localBrowserSessionId = result.data.cloudRelay?.localBrowserSessionId;\n\n if (!localBrowserSessionId) {\n console.error('Cloud relay not established. Cannot run debug workflow.');\n await deleteSession(daemonSessionId);\n process.exit(1);\n }\n } catch (err) {\n console.error(`Failed to start browser: ${err}`);\n process.exit(1);\n }\n\n // 4. Link the debug session to the cloud browser session\n try {\n const res = await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}/link`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ localBrowserSessionId }),\n });\n\n if (!res.ok) {\n const text = await res.text();\n console.error(`Failed to link debug session to browser: ${res.status} ${text}`);\n await deleteSession(daemonSessionId);\n process.exit(1);\n }\n } catch (err) {\n console.error(`Failed to link debug session: ${err}`);\n await deleteSession(daemonSessionId);\n process.exit(1);\n }\n\n console.log('Browser connected.');\n console.log();\n\n // Set up cleanup\n const cleanup = async () => {\n console.log('\\nShutting down...');\n\n try {\n await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${token}` },\n });\n } catch {\n // Ignore cleanup errors\n }\n\n if (storageStatePath) {\n await fs.unlink(storageStatePath).catch(() => {});\n }\n\n await deleteSession(daemonSessionId);\n process.exit(0);\n };\n\n process.on('SIGINT', () => void cleanup());\n process.on('SIGTERM', () => void cleanup());\n\n const nodes = debugSession.nodes ?? [];\n const totalSteps = nodes.length;\n const effectiveToStep = toStep ? Math.min(toStep, totalSteps) : totalSteps;\n\n console.log(`Debugging: \"${debugSession.workflowName}\" (${totalSteps} steps)`);\n if (toStep) {\n console.log(`Running steps 1-${effectiveToStep} of ${totalSteps}`);\n }\n console.log();\n\n // 5. Acquire cloud lock so the server can control the browser\n await acquireCloudLock(daemonSessionId);\n\n // 6. Run steps via SSE\n let runRes: Response;\n try {\n runRes = await fetch(`${apiUrl}/cli/debug/sessions/${debugSessionId}/run`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n Accept: 'text/event-stream',\n },\n body: JSON.stringify({ toStep: effectiveToStep }),\n });\n } catch (err) {\n console.error(`Failed to start execution: ${err}`);\n await cleanup();\n return;\n }\n\n if (!runRes.ok || !runRes.body) {\n console.error(`Failed to start execution: ${runRes.status}`);\n await cleanup();\n return;\n }\n\n // Track execution state\n let currentStep = 0;\n let _hasError = false;\n const stepResults = new Map<number, { name: string; success: boolean; source?: string }>();\n\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as DebugEvent;\n\n if (verbose) {\n console.log(`[SSE] ${JSON.stringify(data)}`);\n }\n\n if (data.type === 'step-started') {\n const e = data as StepStartedEvent;\n currentStep = e.stepIndex;\n process.stdout.write(`[${e.stepIndex}/${e.totalSteps}] ${e.stepName} `);\n }\n\n if (data.type === 'completed') {\n const e = data as NodeCompletedEvent;\n const stepIndex = e.stepIndex ?? currentStep;\n const success = e.result.success;\n const source = e.result.source;\n\n if (success) {\n const sourceLabel =\n source === 'cache' ? '(cache)' : source === 'agent' ? '(agent)' : '';\n console.log(`\\u2713 ${sourceLabel}`);\n } else {\n console.log('\\u2717');\n if (e.result.errorMessage) {\n console.log(` Error: ${e.result.errorMessage.slice(0, 200)}`);\n }\n _hasError = true;\n }\n\n stepResults.set(stepIndex, {\n name: `Step ${stepIndex}`,\n success,\n source,\n });\n }\n\n if (data.type === 'run-complete') {\n const e = data as RunCompleteEvent;\n console.log();\n if (e.stoppedEarly) {\n console.log(\n `Stopped at step ${e.stepsExecuted} of ${e.totalSteps}. ${e.reason === 'step-failed' ? 'Step failed.' : 'Error occurred.'}`\n );\n } else {\n console.log(`All ${e.stepsExecuted} step(s) completed.`);\n }\n }\n\n if (data.type === 'run-error') {\n const errorData = data as { error?: string };\n console.log(`\\u2717`);\n if (errorData.error) {\n console.log(` Error: ${String(errorData.error).slice(0, 200)}`);\n }\n _hasError = true;\n }\n } catch {\n // Ignore parse errors\n }\n },\n });\n\n const reader = runRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n } finally {\n reader.releaseLock();\n }\n\n // 7. Release cloud lock — hand control back to CLI for inspection\n await releaseCloudLock(daemonSessionId);\n\n // 8. Keep browser open for inspection\n console.log();\n console.log('Browser is open for inspection.');\n console.log(' Take control: canary session take-control');\n console.log(' Resume cloud: canary session resume-cloud');\n console.log('Press Ctrl+C to close.');\n\n // Keep the process running until Ctrl+C\n await new Promise(() => {});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAgBA,OAAO,QAAQ;AACf,OAAO,aAAa;AACpB,SAAS,oBAA6C;AAsDtD,eAAsB,iBAAiB,MAA+B;AACpE,QAAM,aAAa,KAAK,KAAK,CAAC,QAAQ,CAAC,IAAI,WAAW,GAAG,CAAC;AAE1D,MAAI,CAAC,YAAY;AACf,YAAQ,MAAM,uEAAuE;AACrF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,YAAY,MAAM,WAAW;AAC/C,QAAM,SAAS,YAAY,SAAS,WAAW,EAAE,IAAI;AACrD,QAAM,UAAU,QAAQ,MAAM,aAAa,IAAI;AAE/C,MAAI,WAAW,WAAc,MAAM,MAAM,KAAK,SAAS,IAAI;AACzD,YAAQ,MAAM,6CAA6C;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAGlD,UAAQ,IAAI,qBAAqB;AAEjC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,uBAAuB;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,WAAW,CAAC;AAAA,IACrC,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAQ,MAAM,mCAAmC,IAAI,MAAM,IAAI,IAAI,EAAE;AACrE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,mBAAgB,MAAM,IAAI,KAAK;AAC/B,QAAI,CAAC,aAAa,MAAM,CAAC,aAAa,WAAW;AAC/C,cAAQ,MAAM,mCAAmC,aAAa,KAAK,EAAE;AACrE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,mCAAmC,GAAG,EAAE;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,iBAAyB,aAAa;AAG5C,MAAI;AACJ,MAAI,aAAa,mBAAmB,aAAa,YAAY;AAC3D,YAAQ,IAAI,8BAA8B;AAC1C,uBAAmB,MAAM,qBAAqB;AAAA,MAC5C;AAAA,MACA;AAAA,MACA,YAAY,aAAa,WAAW;AAAA,MACpC,cAAc,aAAa,WAAW;AAAA,MACtC,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,kBAAkB;AACpB,cAAQ,IAAI,uBAAuB;AAAA,IACrC,OAAO;AACL,cAAQ,KAAK,0DAA0D;AAAA,IACzE;AAAA,EACF;AAGA,UAAQ,IAAI,6BAA6B;AAEzC,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,SAAS,MAAM,uBAAuB;AAAA,MAC1C,UAAU;AAAA,MACV;AAAA,MACA,MAAM,SAAS,WAAW,MAAM,GAAG,CAAC,CAAC;AAAA,MACrC,YAAY,EAAE,QAAQ,MAAM;AAAA,IAC9B,CAAC;AAED,QAAI,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAC9B,cAAQ,MAAM,qCAAqC,OAAO,KAAK,EAAE;AACjE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,sBAAkB,OAAO,KAAK;AAC9B,4BAAwB,OAAO,KAAK,YAAY;AAEhD,QAAI,CAAC,uBAAuB;AAC1B,cAAQ,MAAM,yDAAyD;AACvE,YAAM,cAAc,eAAe;AACnC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,4BAA4B,GAAG,EAAE;AAC/C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,uBAAuB,cAAc,SAAS;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,sBAAsB,CAAC;AAAA,IAChD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAQ,MAAM,4CAA4C,IAAI,MAAM,IAAI,IAAI,EAAE;AAC9E,YAAM,cAAc,eAAe;AACnC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,iCAAiC,GAAG,EAAE;AACpD,UAAM,cAAc,eAAe;AACnC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,oBAAoB;AAChC,UAAQ,IAAI;AAGZ,QAAM,UAAU,YAAY;AAC1B,YAAQ,IAAI,oBAAoB;AAEhC,QAAI;AACF,YAAM,MAAM,GAAG,MAAM,uBAAuB,cAAc,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,MAC9C,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,QAAI,kBAAkB;AACpB,YAAM,GAAG,OAAO,gBAAgB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAClD;AAEA,UAAM,cAAc,eAAe;AACnC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,GAAG,UAAU,MAAM,KAAK,QAAQ,CAAC;AACzC,UAAQ,GAAG,WAAW,MAAM,KAAK,QAAQ,CAAC;AAE1C,QAAM,QAAQ,aAAa,SAAS,CAAC;AACrC,QAAM,aAAa,MAAM;AACzB,QAAM,kBAAkB,SAAS,KAAK,IAAI,QAAQ,UAAU,IAAI;AAEhE,UAAQ,IAAI,eAAe,aAAa,YAAY,MAAM,UAAU,SAAS;AAC7E,MAAI,QAAQ;AACV,YAAQ,IAAI,mBAAmB,eAAe,OAAO,UAAU,EAAE;AAAA,EACnE;AACA,UAAQ,IAAI;AAGZ,QAAM,iBAAiB,eAAe;AAGtC,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,MAAM,GAAG,MAAM,uBAAuB,cAAc,QAAQ;AAAA,MACzE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,QAC9B,QAAQ;AAAA,MACV;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,QAAQ,gBAAgB,CAAC;AAAA,IAClD,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,8BAA8B,GAAG,EAAE;AACjD,UAAM,QAAQ;AACd;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAC9B,YAAQ,MAAM,8BAA8B,OAAO,MAAM,EAAE;AAC3D,UAAM,QAAQ;AACd;AAAA,EACF;AAGA,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,QAAM,cAAc,oBAAI,IAAiE;AAEzF,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS,CAAC,UAA8B;AACtC,UAAI,CAAC,MAAM,KAAM;AAEjB,UAAI;AACF,cAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAElC,YAAI,SAAS;AACX,kBAAQ,IAAI,SAAS,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,QAC7C;AAEA,YAAI,KAAK,SAAS,gBAAgB;AAChC,gBAAM,IAAI;AACV,wBAAc,EAAE;AAChB,kBAAQ,OAAO,MAAM,IAAI,EAAE,SAAS,IAAI,EAAE,UAAU,KAAK,EAAE,QAAQ,GAAG;AAAA,QACxE;AAEA,YAAI,KAAK,SAAS,aAAa;AAC7B,gBAAM,IAAI;AACV,gBAAM,YAAY,EAAE,aAAa;AACjC,gBAAM,UAAU,EAAE,OAAO;AACzB,gBAAM,SAAS,EAAE,OAAO;AAExB,cAAI,SAAS;AACX,kBAAM,cACJ,WAAW,UAAU,YAAY,WAAW,UAAU,YAAY;AACpE,oBAAQ,IAAI,UAAU,WAAW,EAAE;AAAA,UACrC,OAAO;AACL,oBAAQ,IAAI,QAAQ;AACpB,gBAAI,EAAE,OAAO,cAAc;AACzB,sBAAQ,IAAI,cAAc,EAAE,OAAO,aAAa,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,YACjE;AACA,wBAAY;AAAA,UACd;AAEA,sBAAY,IAAI,WAAW;AAAA,YACzB,MAAM,QAAQ,SAAS;AAAA,YACvB;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAEA,YAAI,KAAK,SAAS,gBAAgB;AAChC,gBAAM,IAAI;AACV,kBAAQ,IAAI;AACZ,cAAI,EAAE,cAAc;AAClB,oBAAQ;AAAA,cACN,mBAAmB,EAAE,aAAa,OAAO,EAAE,UAAU,KAAK,EAAE,WAAW,gBAAgB,iBAAiB,iBAAiB;AAAA,YAC3H;AAAA,UACF,OAAO;AACL,oBAAQ,IAAI,OAAO,EAAE,aAAa,qBAAqB;AAAA,UACzD;AAAA,QACF;AAEA,YAAI,KAAK,SAAS,aAAa;AAC7B,gBAAM,YAAY;AAClB,kBAAQ,IAAI,QAAQ;AACpB,cAAI,UAAU,OAAO;AACnB,oBAAQ,IAAI,cAAc,OAAO,UAAU,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,UACnE;AACA,sBAAY;AAAA,QACd;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OAAO,KAAK,UAAU;AACrC,QAAM,UAAU,IAAI,YAAY;AAEhC,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,aAAO,KAAK,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,IACrD;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AAGA,QAAM,iBAAiB,eAAe;AAGtC,UAAQ,IAAI;AACZ,UAAQ,IAAI,iCAAiC;AAC7C,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,wBAAwB;AAGpC,QAAM,IAAI,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC5B;","names":[]}