@canaryai/cli 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TO66FC4R.js → chunk-JMI7WWPF.js} +2 -2
- package/dist/chunk-OE6O7H45.js +92 -0
- package/dist/chunk-OE6O7H45.js.map +1 -0
- package/dist/chunk-PLDDJCW6.js +49 -0
- package/dist/chunk-ZTWHPIXU.js +42798 -0
- package/dist/chunk-ZTWHPIXU.js.map +1 -0
- package/dist/debug-workflow-PMLMWKWI.js +241 -0
- package/dist/debug-workflow-PMLMWKWI.js.map +1 -0
- package/dist/dist-6NXLJYRZ.js +335 -0
- package/dist/dist-6NXLJYRZ.js.map +1 -0
- package/dist/{feature-flag-ZDLDYRSF.js → feature-flag-D3QTHGL6.js} +2 -2
- package/dist/index.js +41 -9
- package/dist/index.js.map +1 -1
- package/dist/issues-6MHRFKTU.js +362 -0
- package/dist/issues-6MHRFKTU.js.map +1 -0
- package/dist/{knobs-3MKMOXIV.js → knobs-ED6LXBVM.js} +2 -2
- package/dist/{local-browser-GG5GUXDS.js → local-browser-YSE3XCUW.js} +4 -3
- package/dist/{local-browser-GG5GUXDS.js.map → local-browser-YSE3XCUW.js.map} +1 -1
- package/dist/{mcp-AD67OLQM.js → mcp-LKHFYMA6.js} +4 -3
- package/dist/{mcp-AD67OLQM.js.map → mcp-LKHFYMA6.js.map} +1 -1
- package/dist/pdf-extract-YIDRKYUD.js +12 -0
- package/dist/pdf-extract-YIDRKYUD.js.map +1 -0
- package/dist/pdfjs-44AOKLEM.js +35242 -0
- package/dist/pdfjs-44AOKLEM.js.map +1 -0
- package/dist/{psql-IVAPNYZV.js → psql-U5LF6ELS.js} +2 -2
- package/dist/{redis-LWY7L6AS.js → redis-PBQZGU6T.js} +2 -2
- package/dist/{release-KQFCTAXA.js → release-QBSP474D.js} +2 -2
- package/dist/runner/preload.js +2 -2
- package/dist/test.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-UEOXNF5X.js +0 -371
- package/dist/chunk-UEOXNF5X.js.map +0 -1
- /package/dist/{chunk-TO66FC4R.js.map → chunk-JMI7WWPF.js.map} +0 -0
- /package/dist/{chunk-DGUM43GV.js.map → chunk-PLDDJCW6.js.map} +0 -0
- /package/dist/{feature-flag-ZDLDYRSF.js.map → feature-flag-D3QTHGL6.js.map} +0 -0
- /package/dist/{knobs-3MKMOXIV.js.map → knobs-ED6LXBVM.js.map} +0 -0
- /package/dist/{psql-IVAPNYZV.js.map → psql-U5LF6ELS.js.map} +0 -0
- /package/dist/{redis-LWY7L6AS.js.map → redis-PBQZGU6T.js.map} +0 -0
- /package/dist/{release-KQFCTAXA.js.map → release-QBSP474D.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "./chunk-7R4YFGP6.js";
|
|
19
19
|
import {
|
|
20
20
|
__require
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-PLDDJCW6.js";
|
|
22
22
|
|
|
23
23
|
// src/index.ts
|
|
24
24
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -909,8 +909,9 @@ function isSuperadminToken(token) {
|
|
|
909
909
|
// src/index.ts
|
|
910
910
|
var require2 = createRequire2(import.meta.url);
|
|
911
911
|
var pkg = require2("../package.json");
|
|
912
|
-
var loadMcp = () => import("./mcp-
|
|
913
|
-
var loadLocalBrowser = () => import("./local-browser-
|
|
912
|
+
var loadMcp = () => import("./mcp-LKHFYMA6.js").then((m) => m.runMcp);
|
|
913
|
+
var loadLocalBrowser = () => import("./local-browser-YSE3XCUW.js").then((m) => m.runLocalBrowser);
|
|
914
|
+
var loadDebugWorkflow = () => import("./debug-workflow-PMLMWKWI.js").then((m) => m.runDebugWorkflow);
|
|
914
915
|
var canary = { run };
|
|
915
916
|
var baseDir = typeof __dirname !== "undefined" ? __dirname : path4.dirname(fileURLToPath2(import.meta.url));
|
|
916
917
|
var preloadPath = path4.join(baseDir, "runner", "preload.js");
|
|
@@ -952,7 +953,9 @@ function printHelp({ isSuperadmin }) {
|
|
|
952
953
|
" canary mcp",
|
|
953
954
|
" canary browser [--mode playwright|cdp] [--cdp-url <url>] [--no-headless]",
|
|
954
955
|
" canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]",
|
|
955
|
-
" canary orgs List organizations"
|
|
956
|
+
" canary orgs List organizations",
|
|
957
|
+
" canary debug <workflowId> [options] Debug workflow in local headed browser",
|
|
958
|
+
" canary issues <sub-command> Search and view issues"
|
|
956
959
|
];
|
|
957
960
|
lines.push(
|
|
958
961
|
" canary release <sub-command> Release QA gate (CI/CD)"
|
|
@@ -996,6 +999,25 @@ function printHelp({ isSuperadmin }) {
|
|
|
996
999
|
" export CANARY_API_URL=http://localhost:3000"
|
|
997
1000
|
);
|
|
998
1001
|
lines.push(
|
|
1002
|
+
"",
|
|
1003
|
+
"Debug options:",
|
|
1004
|
+
" --to-step <N> Stop after step N (1-based, default: all)",
|
|
1005
|
+
" --env <env> Environment (local, dev, prod)",
|
|
1006
|
+
" --verbose, -v Show all SSE events",
|
|
1007
|
+
"",
|
|
1008
|
+
"Issues sub-commands:",
|
|
1009
|
+
" list [options] List and search issues",
|
|
1010
|
+
" get <issueId> [options] Get issue detail with diagnostics",
|
|
1011
|
+
"",
|
|
1012
|
+
"Issues options:",
|
|
1013
|
+
" --search <query> Full-text search",
|
|
1014
|
+
" --severity <level> Filter: low, medium, high, unknown",
|
|
1015
|
+
" --status <statuses> Filter: open, closed, not_a_bug (comma-separated)",
|
|
1016
|
+
" --property-id <uuid> Filter by property",
|
|
1017
|
+
" --page <n> Page number (default: 1)",
|
|
1018
|
+
" --page-size <n> Page size (default: 25)",
|
|
1019
|
+
" --json Output raw JSON",
|
|
1020
|
+
" --format markdown Output as markdown",
|
|
999
1021
|
"",
|
|
1000
1022
|
"Release sub-commands:",
|
|
1001
1023
|
" trigger --property-id <uuid> Trigger a Release QA run",
|
|
@@ -1142,35 +1164,45 @@ async function main(argv) {
|
|
|
1142
1164
|
await runLocalBrowser(rest);
|
|
1143
1165
|
return;
|
|
1144
1166
|
}
|
|
1167
|
+
if (command === "debug") {
|
|
1168
|
+
const runDebugWorkflow = await loadDebugWorkflow();
|
|
1169
|
+
await runDebugWorkflow(rest);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1145
1172
|
if (command === "debug-session") {
|
|
1146
1173
|
await runDebugSession(rest);
|
|
1147
1174
|
return;
|
|
1148
1175
|
}
|
|
1149
1176
|
if (command === "psql") {
|
|
1150
|
-
const { runPsql } = await import("./psql-
|
|
1177
|
+
const { runPsql } = await import("./psql-U5LF6ELS.js");
|
|
1151
1178
|
await runPsql(rest);
|
|
1152
1179
|
return;
|
|
1153
1180
|
}
|
|
1154
1181
|
if (command === "redis") {
|
|
1155
|
-
const { runRedis } = await import("./redis-
|
|
1182
|
+
const { runRedis } = await import("./redis-PBQZGU6T.js");
|
|
1156
1183
|
await runRedis(rest);
|
|
1157
1184
|
return;
|
|
1158
1185
|
}
|
|
1159
1186
|
if (command === "release") {
|
|
1160
|
-
const { runRelease } = await import("./release-
|
|
1187
|
+
const { runRelease } = await import("./release-QBSP474D.js");
|
|
1161
1188
|
await runRelease(rest);
|
|
1162
1189
|
return;
|
|
1163
1190
|
}
|
|
1164
1191
|
if (command === "feature-flag") {
|
|
1165
|
-
const { runFeatureFlag } = await import("./feature-flag-
|
|
1192
|
+
const { runFeatureFlag } = await import("./feature-flag-D3QTHGL6.js");
|
|
1166
1193
|
await runFeatureFlag(rest);
|
|
1167
1194
|
return;
|
|
1168
1195
|
}
|
|
1169
1196
|
if (command === "knobs") {
|
|
1170
|
-
const { runKnobs } = await import("./knobs-
|
|
1197
|
+
const { runKnobs } = await import("./knobs-ED6LXBVM.js");
|
|
1171
1198
|
await runKnobs(rest);
|
|
1172
1199
|
return;
|
|
1173
1200
|
}
|
|
1201
|
+
if (command === "issues") {
|
|
1202
|
+
const { runIssues } = await import("./issues-6MHRFKTU.js");
|
|
1203
|
+
await runIssues(rest);
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1174
1206
|
console.log(`Unknown command "${command}".`);
|
|
1175
1207
|
printHelp({ isSuperadmin: await resolveIsSuperadmin() });
|
|
1176
1208
|
process7.exit(1);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/runner/common.ts","../src/run.ts","../src/login.ts","../src/orgs.ts","../src/run-local.ts","../src/remote-test.ts","../src/debug-session.ts","../src/jwt.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport process from \"node:process\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\nimport { run as runCanary } from \"./run\";\nimport { runLocalTest } from \"./local-run\";\nimport { runTunnel } from \"./tunnel\";\nimport { runLogin } from \"./login\";\nimport { runOrgs } from \"./orgs\";\nimport { runLocalSession } from \"./run-local\";\nimport { runRemoteTest } from \"./remote-test\";\nimport { readAllStoredTokens, readStoredToken } from \"./auth\";\nimport { runDebugSession } from \"./debug-session\";\nimport { isSuperadminToken } from \"./jwt\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\n\n// Lazy-load playwright-dependent modules\nconst loadMcp = () => import(\"./mcp\").then((m) => m.runMcp);\nconst loadLocalBrowser = () => import(\"./local-browser/index\").then((m) => m.runLocalBrowser);\n\nexport const canary = { run: runCanary };\nexport { runCanary as run };\n\nconst baseDir =\n typeof __dirname !== \"undefined\" ? __dirname : path.dirname(fileURLToPath(import.meta.url));\nconst preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\nconst requireFn = makeRequire();\n\nfunction runPlaywrightTests(args: string[]) {\n // Resolve the local @playwright/test CLI directly (drop-in replacement)\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = {\n ...process.env,\n CANARY_ENABLED: process.env.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n ...(nodeOptions ? { NODE_OPTIONS: nodeOptions } : {}),\n };\n\n const result = spawnSync(runnerBin, [playwrightCli, \"test\", ...args], {\n env,\n stdio: \"inherit\",\n cwd: process.cwd(),\n });\n\n if (result.error) {\n console.error(\"canary failed to launch Playwright:\", result.error);\n process.exit(1);\n }\n\n process.exit(result.status ?? 1);\n}\n\nfunction printVersion() {\n console.log(`canary v${pkg.version}`);\n}\n\nfunction printHelp({ isSuperadmin }: { isSuperadmin: boolean }) {\n const lines: string[] = [\n `canary v${pkg.version}: Local and remote testing CLI`,\n \"\",\n \"Usage:\",\n \" canary test [playwright options] Run local Playwright tests\",\n \" canary test --remote [options] Run remote workflow tests\",\n \" canary local-run --tunnel-url <url> [options]\",\n \" canary tunnel --port <localPort> [options]\",\n \" canary run --port <localPort> [options]\",\n \" canary mcp\",\n \" canary browser [--mode playwright|cdp] [--cdp-url <url>] [--no-headless]\",\n \" canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]\",\n \" canary orgs List organizations\",\n ];\n\n lines.push(\n \" canary release <sub-command> Release QA gate (CI/CD)\",\n );\n\n if (isSuperadmin) {\n lines.push(\n \" canary debug-session [--env dev|local] [--json] Create browser debug session\",\n \" canary psql <query> [--json] Execute read-only SQL\",\n \" canary redis <command> [--json] Execute read-only Redis commands\",\n \" canary feature-flag <sub-command> Manage feature flags\",\n \" canary knobs <sub-command> Manage knobs (global config)\",\n );\n }\n\n lines.push(\n \" canary version Show version\",\n \" canary help\",\n \"\",\n \"Remote test options:\",\n \" --token <key> API key (or set CANARY_API_TOKEN)\",\n \" --api-url <url> API URL (default: https://api.trycanary.ai)\",\n \" --tag <tag> Filter workflows by tag\",\n \" --name-pattern <pat> Filter workflows by name pattern\",\n \" --verbose, -v Show all events\",\n \"\",\n \"Browser options:\",\n \" --mode <playwright|cdp> Browser mode (default: playwright)\",\n \" --cdp-url <url> CDP endpoint for existing Chrome\",\n \" --no-headless Run browser with visible UI\",\n \" --storage-state <path> Path to storage state JSON\",\n \" --instructions <text> Instructions for the cloud agent\",\n \"\",\n \"Login options:\",\n \" --org <name> Select organization by name or ID (for multi-org users)\",\n \"\",\n \"Login environments:\",\n \" Production: canary login\",\n \" Dev: canary login --app-url https://app.dev.trycanary.ai --api-url https://api.dev.trycanary.ai\",\n \" Local: canary login --app-url http://localhost:5173 --api-url http://localhost:3000\",\n \"\",\n \" Or set CANARY_API_URL env var for non-production environments:\",\n \" export CANARY_API_URL=http://localhost:3000\",\n );\n\n lines.push(\n \"\",\n \"Release sub-commands:\",\n \" trigger --property-id <uuid> Trigger a Release QA run\",\n \" status <run-id> [--json] Check run status\",\n \" run --property-id <uuid> [--timeout N] Trigger and poll until complete\",\n );\n\n if (isSuperadmin) {\n lines.push(\n \"\",\n \"PSQL options:\",\n \" --json Output results as JSON\",\n \" --query <sql> SQL query (alternative to positional)\",\n \"\",\n \"Redis options:\",\n \" --json Output results as JSON\",\n \"\",\n \"Feature flag sub-commands:\",\n \" list List all flags\",\n \" create <name> [--description <text>] Create a flag\",\n \" delete <name> Delete a flag and its gates\",\n \" enable <name> --org <orgId> Enable for an org\",\n \" disable <name> --org <orgId> Disable for an org\",\n \" lifecycle <name> --stage <stage> [--final-value true|false]\",\n \" Set lifecycle metadata\",\n \"\",\n \"Knobs sub-commands:\",\n \" list List all knobs\",\n \" get <key> Get a knob value\",\n \" set <key> <value> --type <type> Set a knob value\",\n \" delete <key> Delete a knob\",\n \" toggle <key> Toggle a boolean knob\",\n \" lifecycle <key> --stage <stage> [--final-value <value>]\",\n \" Set lifecycle metadata\",\n );\n }\n\n lines.push(\n \"\",\n \"Flags:\",\n \" -h, --help Show help\",\n \" -V, --version Show version\",\n );\n\n console.log(lines.join(\"\\n\"));\n}\n\nfunction printTestHelp() {\n console.log(\n [\n `canary v${pkg.version}: Test command`,\n \"\",\n \"Usage:\",\n \" canary test [playwright options] Run local Playwright tests\",\n \" canary test --remote [options] Run remote workflow tests\",\n \"\",\n \"Local Playwright options (passed through to Playwright):\",\n \" --grep <pattern> Only run tests matching pattern\",\n \" --headed Run in headed browser mode\",\n \" --workers <n> Number of parallel workers\",\n \" --project <name> Run specific project\",\n \" --reporter <reporter> Use a specific reporter\",\n \" --retries <n> Number of retries for failed tests\",\n \" --timeout <ms> Test timeout in milliseconds\",\n \"\",\n \"Remote test options:\",\n \" --remote Run tests remotely (required)\",\n \" --token <key> API key (or set CANARY_API_TOKEN)\",\n \" --api-url <url> API URL (default: https://api.trycanary.ai)\",\n \" --tag <tag> Filter workflows by tag\",\n \" --name-pattern <pat> Filter workflows by name pattern\",\n \" --verbose, -v Show all events\",\n \"\",\n \"Examples:\",\n \" canary test Run all local tests\",\n ' canary test --grep \"login\" Run tests matching \"login\"',\n \" canary test --headed --workers 1 Debug with visible browser\",\n \" canary test --remote --tag smoke Run remote smoke tests\",\n ].join(\"\\n\")\n );\n}\n\n/** Commands that handle --help themselves instead of showing global help. */\nconst COMMANDS_WITH_HELP = new Set([\"test\"]);\n\nasync function resolveToken(): Promise<string | null> {\n return process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n}\n\n/** Check if any stored profile (or env token) has superadmin privileges */\nasync function resolveIsSuperadmin(): Promise<boolean> {\n const envToken = process.env.CANARY_API_TOKEN;\n if (envToken) return isSuperadminToken(envToken);\n\n const tokens = await readAllStoredTokens();\n return tokens.some((t) => isSuperadminToken(t));\n}\n\nexport async function main(argv: string[]) {\n if (argv.includes(\"--version\") || argv.includes(\"-V\")) {\n printVersion();\n return;\n }\n\n const [command, ...rest] = argv;\n const hasHelpFlag = argv.includes(\"--help\") || argv.includes(\"-h\");\n\n // Global help: --help/‑h without a command that handles it, or explicit \"help\"\n if (hasHelpFlag && (!command || !COMMANDS_WITH_HELP.has(command))) {\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n return;\n }\n\n if (!command || command === \"help\") {\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n return;\n }\n\n if (command === \"version\") {\n printVersion();\n return;\n }\n\n if (command === \"test\") {\n // Sub-command help\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n printTestHelp();\n return;\n }\n // Check for --remote flag to run remote workflow tests\n if (rest.includes(\"--remote\")) {\n const remoteArgs = rest.filter((arg) => arg !== \"--remote\");\n await runRemoteTest(remoteArgs);\n return;\n }\n runPlaywrightTests(rest);\n return;\n }\n\n if (command === \"local-run\") {\n await runLocalTest(rest);\n return;\n }\n\n if (command === \"run\") {\n await runLocalSession(rest);\n return;\n }\n\n if (command === \"mcp\") {\n const runMcp = await loadMcp();\n await runMcp(rest);\n return;\n }\n\n if (command === \"tunnel\") {\n await runTunnel(rest);\n return;\n }\n\n if (command === \"login\") {\n await runLogin(rest);\n return;\n }\n\n if (command === \"orgs\") {\n await runOrgs(rest);\n return;\n }\n\n if (command === \"browser\") {\n const runLocalBrowser = await loadLocalBrowser();\n await runLocalBrowser(rest);\n return;\n }\n\n if (command === \"debug-session\") {\n await runDebugSession(rest);\n return;\n }\n\n if (command === \"psql\") {\n const { runPsql } = await import(\"./psql.js\");\n await runPsql(rest);\n return;\n }\n\n if (command === \"redis\") {\n const { runRedis } = await import(\"./redis.js\");\n await runRedis(rest);\n return;\n }\n\n if (command === \"release\") {\n const { runRelease } = await import(\"./release.js\");\n await runRelease(rest);\n return;\n }\n\n if (command === \"feature-flag\") {\n const { runFeatureFlag } = await import(\"./feature-flag.js\");\n await runFeatureFlag(rest);\n return;\n }\n\n if (command === \"knobs\") {\n const { runKnobs } = await import(\"./knobs.js\");\n await runKnobs(rest);\n return;\n }\n\n console.log(`Unknown command \"${command}\".`);\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n process.exit(1);\n}\n\nif (import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main(process.argv.slice(2));\n}\n","import { spawnSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nexport function makeRequire() {\n try {\n return createRequire(import.meta.url);\n } catch {\n try {\n return createRequire(process.cwd());\n } catch {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof require !== \"undefined\" ? (require as any) : createRequire(\".\");\n }\n }\n}\n\nexport function resolveRunner(preloadPath?: string): { runnerBin: string; preloadFlag?: string } {\n const { bin, version } = pickNodeBinary();\n const supportsImport = typeof version === \"number\" && version >= 18;\n\n if (supportsImport && preloadPath && fs.existsSync(preloadPath)) {\n return { runnerBin: bin, preloadFlag: `--import=${pathToFileURL(preloadPath).href}` };\n }\n\n if (preloadPath) {\n console.warn(\"[canary] Warning: no preload module found; instrumentation may be disabled.\");\n }\n\n return { runnerBin: bin };\n}\n\nexport function pickNodeBinary(): { bin: string; version?: number } {\n const candidates = collectNodeCandidates();\n\n // Prefer the first viable candidate with version >=18; otherwise pick highest version found.\n let best: { bin: string; version?: number } | undefined;\n let fallback: { bin: string; version?: number } | undefined;\n\n for (const bin of candidates) {\n const version = getNodeMajor(bin);\n if (!version) continue;\n const current = { bin, version };\n if (version >= 18 && !fallback) {\n fallback = current;\n }\n if (!best || version > (best.version ?? 0)) {\n best = current;\n }\n }\n\n if (fallback) return fallback;\n if (best) return best;\n\n // Last resort\n return { bin: candidates[0] ?? \"node\" };\n}\n\nexport function collectNodeCandidates(): string[] {\n const seen = new Set<string>();\n const push = (value?: string) => {\n if (!value) return;\n if (seen.has(value)) return;\n seen.add(value);\n };\n\n const isBun = path.basename(process.execPath).includes(\"bun\");\n\n push(process.env.CANARY_NODE_BIN);\n push(isBun ? undefined : process.execPath);\n push(\"node\"); // default PATH lookup\n\n // Collect from `which -a node` if available.\n try {\n const which = spawnSync(\"which\", [\"-a\", \"node\"], { encoding: \"utf-8\" });\n which.stdout\n ?.toString()\n .split(\"\\n\")\n .map((line) => line.trim())\n .forEach((line) => push(line));\n } catch {\n // ignore\n }\n\n // NVM installations (grab highest versions)\n const nvmDir = process.env.NVM_DIR || (process.env.HOME ? path.join(process.env.HOME, \".nvm\") : undefined);\n if (nvmDir) {\n const versionsDir = path.join(nvmDir, \"versions\", \"node\");\n if (fs.existsSync(versionsDir)) {\n try {\n const versions = fs.readdirSync(versionsDir);\n versions\n .sort((a, b) => (a > b ? -1 : 1))\n .forEach((v) => push(path.join(versionsDir, v, \"bin\", \"node\")));\n } catch {\n // ignore\n }\n }\n }\n\n return Array.from(seen);\n}\n\nexport function getNodeMajor(bin: string): number | undefined {\n try {\n const result = spawnSync(bin, [\"-v\"], { encoding: \"utf-8\" });\n const output = (result.stdout || result.stderr || \"\").toString().trim();\n const match = output.match(/^v(\\d+)/);\n if (match) return Number(match[1]);\n } catch {\n // ignore\n }\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\n\nexport type HealingOptions = {\n apiKey?: string;\n provider?: string;\n model?: string;\n timeoutMs?: number;\n maxActions?: number;\n vision?: boolean;\n dryRun?: boolean;\n warnOnly?: boolean;\n debug?: boolean;\n readOnly?: boolean;\n allowEvaluate?: boolean;\n allowRunCode?: boolean;\n maxPayloadBytes?: number;\n};\n\nexport type RunRequest = {\n projectRoot?: string;\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n env?: Record<string, string>;\n healing?: HealingOptions;\n reporter?: \"default\" | \"json\" | string;\n timeoutMs?: number;\n nodeBin?: string;\n stdio?: \"inherit\" | \"pipe\";\n};\n\nexport type RunResult = {\n ok: boolean;\n exitCode: number;\n summary: {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n healed?: number;\n warned?: number;\n durationMs: number;\n };\n artifactsDir?: string;\n rawOutput?: string;\n error?: Error;\n};\n\ntype JsonReport = {\n suites?: JsonSuite[];\n duration?: number;\n};\n\ntype JsonSuite = {\n suites?: JsonSuite[];\n tests?: Array<{\n title: string;\n results: Array<{\n status: \"passed\" | \"failed\" | \"timedOut\" | \"skipped\" | \"interrupted\";\n duration: number;\n errors?: unknown[];\n }>;\n }>;\n};\n\nexport async function run(request: RunRequest = {}): Promise<RunResult> {\n const cwd = request.projectRoot ?? process.cwd();\n const stdio = request.stdio ?? \"inherit\";\n const requireFn = makeRequire();\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const baseDir = path.dirname(fileURLToPath(import.meta.url));\n const preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const { jsonReportPath, eventLogPath, artifactsDir } = prepareArtifactsDir(cwd);\n const reporter = buildReporterArgs(request.reporter, jsonReportPath);\n const args = buildArgs({\n testDir: request.testDir,\n configFile: request.configFile,\n cliArgs: request.cliArgs,\n reporter,\n });\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = buildEnv({\n base: process.env,\n overrides: request.env,\n healing: request.healing,\n eventLogPath,\n nodeOptions,\n });\n\n const runResult = await spawnPlaywright({\n bin: request.nodeBin ?? runnerBin,\n args: [playwrightCli, ...args],\n cwd,\n env,\n stdio,\n timeoutMs: request.timeoutMs,\n });\n\n const summary = summarize(jsonReportPath, eventLogPath, runResult.durationMs);\n\n return {\n ok: runResult.exitCode === 0,\n exitCode: runResult.exitCode,\n summary,\n artifactsDir,\n rawOutput: runResult.output,\n error: runResult.error,\n };\n}\n\nfunction buildArgs(opts: {\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n reporter: string;\n}): string[] {\n const args = [\"test\"];\n\n if (opts.testDir) {\n const dirs = Array.isArray(opts.testDir) ? opts.testDir : [opts.testDir];\n args.push(...dirs);\n }\n\n if (opts.configFile) {\n args.push(\"--config\", opts.configFile);\n }\n\n args.push(\"--reporter\", opts.reporter);\n\n if (opts.cliArgs?.length) {\n args.push(...opts.cliArgs);\n }\n\n return args;\n}\n\nfunction buildReporterArgs(requested: RunRequest[\"reporter\"], jsonReportPath: string): string {\n if (requested === \"json\") return `json=${jsonReportPath}`;\n if (requested && requested !== \"default\") return requested;\n // Default: keep list output plus JSON for programmatic summary\n return `list,json=${jsonReportPath}`;\n}\n\nfunction prepareArtifactsDir(cwd: string): { jsonReportPath: string; eventLogPath: string; artifactsDir: string } {\n const dir = fs.mkdtempSync(path.join(os.tmpdir(), \"canary-run-\"));\n const jsonReportPath = path.join(dir, \"report.json\");\n const eventLogPath = path.join(dir, \"events-worker-0.jsonl\");\n const artifactsDir = path.join(cwd, \"test-results\", \"ai-healer\");\n return { jsonReportPath, eventLogPath, artifactsDir: dir };\n}\n\nfunction buildEnv(params: {\n base: NodeJS.ProcessEnv;\n overrides?: Record<string, string>;\n healing?: HealingOptions;\n eventLogPath: string;\n nodeOptions?: string;\n}): NodeJS.ProcessEnv {\n const healing = params.healing ?? {};\n const env: NodeJS.ProcessEnv = {\n ...params.base,\n CANARY_ENABLED: params.base.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n CANARY_EVENT_LOG: params.eventLogPath,\n ...(params.nodeOptions ? { NODE_OPTIONS: params.nodeOptions } : {}),\n ...(healing.apiKey ? { AI_API_KEY: healing.apiKey } : {}),\n ...(healing.provider ? { AI_PROVIDER: healing.provider } : {}),\n ...(healing.model ? { AI_MODEL: healing.model } : {}),\n ...(healing.timeoutMs ? { AI_TIMEOUT_MS: String(healing.timeoutMs) } : {}),\n ...(healing.maxActions ? { CANARY_MAX_ACTIONS: String(healing.maxActions) } : {}),\n ...(healing.vision ? { CANARY_VISION: \"1\" } : {}),\n ...(healing.dryRun ? { CANARY_DRY_RUN: \"1\" } : {}),\n ...(healing.warnOnly ? { CANARY_WARN_ONLY: \"1\" } : {}),\n ...(healing.debug ? { CANARY_DEBUG: \"1\" } : {}),\n ...(healing.readOnly ? { CANARY_READ_ONLY: \"1\" } : {}),\n ...(healing.allowEvaluate === false ? { CANARY_ALLOW_EVALUATE: \"0\" } : {}),\n ...(healing.allowRunCode ? { CANARY_ALLOW_RUN_CODE: \"1\" } : {}),\n ...(healing.maxPayloadBytes ? { CANARY_MAX_PAYLOAD_BYTES: String(healing.maxPayloadBytes) } : {}),\n ...params.overrides,\n };\n return env;\n}\n\nasync function spawnPlaywright(opts: {\n bin: string;\n args: string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n stdio: \"inherit\" | \"pipe\";\n timeoutMs?: number;\n}): Promise<{ exitCode: number; output?: string; durationMs: number; error?: Error }> {\n return new Promise((resolve) => {\n const started = Date.now();\n const child = spawn(opts.bin, opts.args, {\n cwd: opts.cwd,\n env: opts.env,\n stdio: opts.stdio === \"inherit\" ? \"inherit\" : [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let timer: NodeJS.Timeout | undefined;\n let output = \"\";\n let error: Error | undefined;\n\n if (opts.stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n if (opts.timeoutMs && opts.timeoutMs > 0) {\n timer = setTimeout(() => {\n error = new Error(`canary.run timed out after ${opts.timeoutMs}ms`);\n child.kill(\"SIGKILL\");\n }, opts.timeoutMs);\n }\n\n child.on(\"close\", (code) => {\n if (timer) clearTimeout(timer);\n resolve({ exitCode: code ?? 1, output: output || undefined, durationMs: Date.now() - started, error });\n });\n });\n}\n\nfunction summarize(jsonReportPath: string, eventLogPath: string, durationMs: number): RunResult[\"summary\"] {\n const base = {\n total: 0,\n passed: 0,\n failed: 0,\n flaky: 0,\n skipped: 0,\n durationMs,\n };\n\n const jsonReport = readJsonReport(jsonReportPath);\n if (jsonReport) {\n const counts = countTests(jsonReport);\n base.total = counts.total;\n base.passed = counts.passed;\n base.failed = counts.failed;\n base.flaky = counts.flaky;\n base.skipped = counts.skipped;\n base.durationMs = jsonReport.duration ?? durationMs;\n }\n\n const healed = countHealed(eventLogPath);\n if (healed) {\n return { ...base, healed };\n }\n return base;\n}\n\nfunction readJsonReport(reportPath: string): JsonReport | undefined {\n try {\n if (fs.existsSync(reportPath)) {\n const raw = fs.readFileSync(reportPath, \"utf-8\");\n return JSON.parse(raw) as JsonReport;\n }\n } catch {\n // ignore parse issues\n }\n return undefined;\n}\n\nfunction countTests(report: JsonReport): {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n} {\n let total = 0;\n let passed = 0;\n let failed = 0;\n let flaky = 0;\n let skipped = 0;\n\n const visitSuite = (suite?: JsonSuite) => {\n if (!suite) return;\n suite.tests?.forEach((test) => {\n total += 1;\n const statuses = test.results.map((r) => r.status);\n const hasFailed = statuses.includes(\"failed\") || statuses.includes(\"interrupted\");\n const hasPassed = statuses.includes(\"passed\");\n const hasTimedOut = statuses.includes(\"timedOut\");\n const allSkipped = statuses.every((s) => s === \"skipped\");\n\n if (allSkipped) {\n skipped += 1;\n } else if ((hasFailed || hasTimedOut) && hasPassed) {\n flaky += 1;\n } else if (hasFailed || hasTimedOut) {\n failed += 1;\n } else if (hasPassed && statuses.length > 1) {\n flaky += 1;\n } else if (hasPassed) {\n passed += 1;\n }\n });\n\n suite.suites?.forEach(visitSuite);\n };\n\n report.suites?.forEach(visitSuite);\n\n return { total, passed, failed, flaky, skipped };\n}\n\nfunction countHealed(eventLogPath: string): number | undefined {\n try {\n if (!fs.existsSync(eventLogPath)) return undefined;\n const raw = fs.readFileSync(eventLogPath, \"utf-8\").trim();\n if (!raw) return undefined;\n const lines = raw.split(\"\\n\");\n let healed = 0;\n for (const line of lines) {\n try {\n const event = JSON.parse(line);\n if (event?.healed === true) healed += 1;\n } catch {\n // ignore bad lines\n }\n }\n return healed;\n } catch {\n return undefined;\n }\n}\n\nexport const __internals = {\n buildArgs,\n buildReporterArgs,\n buildEnv,\n countTests,\n countHealed,\n summarize,\n};\n","import process from \"node:process\";\nimport readline from \"node:readline\";\nimport { spawn } from \"node:child_process\";\nimport { saveAuth, ENV_URLS, envToProfile, getArgValue } from \"./auth\";\n\ntype StartResponse = {\n ok: boolean;\n deviceCode?: string;\n userCode?: string;\n verificationUrl?: string;\n expiresAt?: string;\n intervalSeconds?: number;\n error?: string;\n};\n\ntype PollResponse = {\n ok: boolean;\n status?: \"pending\" | \"approved\" | \"rejected\" | \"expired\";\n accessToken?: string;\n orgId?: string;\n error?: string;\n};\n\ntype OrgsResponse = {\n ok: boolean;\n currentOrgId?: string;\n organizations?: Array<{ id: string; name: string; role: string }>;\n error?: string;\n};\n\ntype SwitchOrgResponse = {\n ok: boolean;\n accessToken?: string;\n orgId?: string;\n orgName?: string;\n role?: string;\n error?: string;\n};\n\nfunction shouldOpenBrowser(argv: string[]): boolean {\n return !argv.includes(\"--no-open\");\n}\n\nfunction openUrl(url: string) {\n const platform = process.platform;\n if (platform === \"darwin\") {\n spawn(\"open\", [url], { stdio: \"ignore\" });\n return;\n }\n if (platform === \"win32\") {\n spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { stdio: \"ignore\" });\n return;\n }\n spawn(\"xdg-open\", [url], { stdio: \"ignore\" });\n}\n\nfunction promptChoice(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function fetchOrgs(apiUrl: string, token: string): Promise<OrgsResponse | null> {\n try {\n const res = await fetch(`${apiUrl}/cli-login/orgs`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) return null;\n return (await res.json()) as OrgsResponse;\n } catch {\n return null;\n }\n}\n\nasync function switchOrg(apiUrl: string, token: string, orgId: string): Promise<SwitchOrgResponse> {\n const res = await fetch(`${apiUrl}/cli-login/switch-org`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ orgId }),\n });\n return (await res.json()) as SwitchOrgResponse;\n}\n\nexport async function runLogin(argv: string[]) {\n const env = getArgValue(argv, \"--env\");\n const envUrls = env ? ENV_URLS[env] : undefined;\n\n if (env && !envUrls) {\n console.error(`Unknown environment: ${env}`);\n console.error(\"Valid environments: prod, dev, local\");\n process.exit(1);\n }\n\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n envUrls?.api ??\n process.env.CANARY_API_URL ??\n \"https://api.trycanary.ai\";\n const appUrl =\n getArgValue(argv, \"--app-url\") ??\n envUrls?.app ??\n process.env.CANARY_APP_URL ??\n \"https://app.trycanary.ai\";\n\n const orgFlag = getArgValue(argv, \"--org\");\n\n const startRes = await fetch(`${apiUrl}/cli-login/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ appUrl }),\n });\n\n const startJson = (await startRes.json()) as StartResponse;\n if (!startRes.ok || !startJson.ok || !startJson.deviceCode || !startJson.userCode) {\n console.error(\"Login start failed\", startJson.error ?? startRes.statusText);\n process.exit(1);\n }\n\n console.log(\"Login required.\");\n console.log(`User code: ${startJson.userCode}`);\n if (startJson.verificationUrl) {\n console.log(`Open: ${startJson.verificationUrl}`);\n if (shouldOpenBrowser(argv)) {\n try {\n openUrl(startJson.verificationUrl);\n } catch {\n console.log(\"Unable to open browser automatically. Please open the URL manually.\");\n }\n }\n }\n\n const intervalMs = (startJson.intervalSeconds ?? 3) * 1000;\n const expiresAt = startJson.expiresAt ? new Date(startJson.expiresAt).getTime() : null;\n\n let token: string | undefined;\n let initialOrgId: string | undefined;\n\n while (true) {\n if (expiresAt && Date.now() > expiresAt) {\n console.error(\"Login code expired.\");\n process.exit(1);\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n\n const pollRes = await fetch(`${apiUrl}/cli-login/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ deviceCode: startJson.deviceCode }),\n });\n\n const pollJson = (await pollRes.json()) as PollResponse;\n if (!pollRes.ok || !pollJson.ok) {\n console.error(\"Login poll failed\", pollJson.error ?? pollRes.statusText);\n process.exit(1);\n }\n\n if (pollJson.status === \"approved\" && pollJson.accessToken) {\n token = pollJson.accessToken;\n initialOrgId = pollJson.orgId;\n break;\n }\n\n if (pollJson.status === \"rejected\") {\n console.error(\"Login rejected.\");\n process.exit(1);\n }\n\n if (pollJson.status === \"expired\") {\n console.error(\"Login expired.\");\n process.exit(1);\n }\n }\n\n // Fetch user's organizations (gracefully skip if endpoint not available)\n const orgsData = await fetchOrgs(apiUrl, token);\n const orgs = orgsData?.organizations ?? [];\n\n let finalToken = token;\n let finalOrgId = initialOrgId;\n let finalOrgName: string | undefined;\n\n if (orgs.length <= 1) {\n // Single org (or none) — use as-is\n finalOrgName = orgs[0]?.name;\n } else {\n // Multiple orgs — determine which one to use\n let selectedOrg: (typeof orgs)[number] | undefined;\n\n if (orgFlag) {\n // Match --org flag by name (case-insensitive) or ID\n selectedOrg = orgs.find(\n (o) => o.name.toLowerCase() === orgFlag.toLowerCase() || o.id === orgFlag\n );\n if (!selectedOrg) {\n console.error(`Organization \"${orgFlag}\" not found. Available orgs:`);\n for (const o of orgs) {\n console.error(` - ${o.name} (${o.id})`);\n }\n process.exit(1);\n }\n } else if (process.stdin.isTTY) {\n // Interactive prompt\n console.log(\"\\nYou belong to multiple organizations. Select one:\");\n for (let i = 0; i < orgs.length; i++) {\n const marker = orgs[i].id === initialOrgId ? \" (current)\" : \"\";\n console.log(` ${i + 1}. ${orgs[i].name}${marker}`);\n }\n\n const answer = await promptChoice(`\\nChoice [1-${orgs.length}]: `);\n const idx = parseInt(answer, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= orgs.length) {\n console.error(\"Invalid selection.\");\n process.exit(1);\n }\n selectedOrg = orgs[idx];\n } else {\n // Non-interactive — use default from JWT\n const defaultOrg = orgs.find((o) => o.id === initialOrgId);\n console.log(\n `Warning: Multiple organizations available but running non-interactively. Using \"${defaultOrg?.name ?? initialOrgId}\".`\n );\n console.log('Tip: Use --org <name> to select a specific organization.');\n selectedOrg = defaultOrg;\n }\n\n if (selectedOrg && selectedOrg.id !== initialOrgId) {\n // Switch to selected org\n const switchRes = await switchOrg(apiUrl, token, selectedOrg.id);\n if (!switchRes.ok || !switchRes.accessToken) {\n console.error(\"Failed to switch organization:\", switchRes.error ?? \"Unknown error\");\n process.exit(1);\n }\n finalToken = switchRes.accessToken;\n finalOrgId = switchRes.orgId;\n finalOrgName = switchRes.orgName;\n } else if (selectedOrg) {\n finalOrgName = selectedOrg.name;\n }\n }\n\n const profileName = env ? envToProfile(env) : undefined;\n const filePath = await saveAuth({ token: finalToken, apiUrl, orgId: finalOrgId, orgName: finalOrgName }, profileName);\n const displayName = finalOrgName ? ` to ${finalOrgName}` : \"\";\n const profileLabel = profileName ? ` (profile: ${profileName})` : \"\";\n console.log(`Login successful${displayName}${profileLabel}. Token saved to ${filePath}`);\n console.log(\"Set CANARY_API_TOKEN to use the CLI without re-login.\");\n}\n","import process from \"node:process\";\nimport { readStoredAuth, readStoredToken } from \"./auth\";\n\ntype OrgsResponse = {\n ok: boolean;\n currentOrgId?: string;\n organizations?: Array<{ id: string; name: string; role: string }>;\n error?: string;\n};\n\nexport async function runOrgs(argv: string[]) {\n const token = process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n if (!token) {\n console.error(\"Not logged in. Run: canary login\");\n process.exit(1);\n }\n\n const auth = await readStoredAuth();\n const apiUrl =\n process.env.CANARY_API_URL ?? auth?.apiUrl ?? \"https://api.trycanary.ai\";\n\n const res = await fetch(`${apiUrl}/cli-login/orgs`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n console.error(\"Failed to fetch organizations. You may need to re-login: canary login\");\n process.exit(1);\n }\n\n const data = (await res.json()) as OrgsResponse;\n if (!data.ok || !data.organizations) {\n console.error(\"Failed to fetch organizations:\", data.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n const currentOrgId = auth?.orgId ?? data.currentOrgId;\n\n console.log(\"Organizations:\\n\");\n for (const org of data.organizations) {\n const marker = org.id === currentOrgId ? \" *\" : \"\";\n console.log(` ${org.name} (${org.role})${marker}`);\n }\n\n console.log(\"\\n* = current organization\");\n console.log(\"To switch: canary login --org <name>\");\n}\n","import process from \"node:process\";\nimport { readStoredToken } from \"./auth\";\nimport { createLocalRun } from \"./local-run\";\nimport { connectTunnel, createTunnel } from \"./tunnel\";\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nexport async function runLocalSession(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n if (!token) {\n console.error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n process.exit(1);\n }\n\n const portRaw = getArgValue(argv, \"--port\") ?? process.env.CANARY_LOCAL_PORT;\n const tunnelUrl = getArgValue(argv, \"--tunnel-url\");\n const title = getArgValue(argv, \"--title\");\n const featureSpec = getArgValue(argv, \"--feature\");\n const startUrl = getArgValue(argv, \"--start-url\");\n\n if (!tunnelUrl && !portRaw) {\n console.error(\"Missing --port or --tunnel-url\");\n process.exit(1);\n }\n\n let publicUrl = tunnelUrl;\n let ws: WebSocket | null = null;\n\n if (!publicUrl && portRaw) {\n const port = Number(portRaw);\n if (Number.isNaN(port) || port <= 0) {\n console.error(\"Invalid --port value\");\n process.exit(1);\n }\n\n const tunnel = await createTunnel({ apiUrl, token, port });\n publicUrl = tunnel.publicUrl;\n\n ws = connectTunnel({\n apiUrl,\n tunnelId: tunnel.tunnelId,\n token: tunnel.token,\n port,\n onReady: () => {\n console.log(`Tunnel connected: ${publicUrl ?? tunnel.tunnelId}`);\n },\n });\n }\n\n if (!publicUrl) {\n console.error(\"Failed to resolve tunnel URL\");\n process.exit(1);\n }\n\n const run = await createLocalRun({\n apiUrl,\n token,\n title,\n featureSpec,\n startUrl,\n tunnelUrl: publicUrl,\n });\n\n console.log(`Local test queued: ${run.runId}`);\n if (run.watchUrl) {\n console.log(`Watch: ${run.watchUrl}`);\n }\n\n if (ws) {\n console.log(\"Tunnel active. Press Ctrl+C to stop.\");\n process.on(\"SIGINT\", () => {\n ws?.close();\n process.exit(0);\n });\n await new Promise<void>(() => undefined);\n }\n}\n","/**\n * Remote Test Command\n *\n * Triggers workflow tests on the Canary platform and streams results via SSE.\n * Designed for CI/CD pipelines - exits with code 0 on success, 1 on failure.\n *\n * Usage:\n * canary test --remote [options]\n *\n * Options:\n * --token <key> API key (or set CANARY_API_TOKEN env var)\n * --api-url <url> API URL (default: https://api.trycanary.ai)\n * --tag <tag> Filter workflows by tag\n * --name-pattern <pat> Filter workflows by name pattern\n * --verbose, -v Show all events (not just results)\n */\n\nimport process from \"node:process\";\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport { readStoredToken } from \"./auth\";\n\ntype WorkflowTestStatus = \"queued\" | \"running\" | \"waiting\" | \"success\" | \"failed\";\n\ntype WorkflowTestEvent = {\n type: \"workflow-test\";\n suiteId: string;\n workflowId: string;\n testRunId: string;\n workflowRunId: string | null;\n status: WorkflowTestStatus;\n startedAt: string | null;\n finishedAt: string | null;\n durationMs: number | null;\n errorMessage?: string | null;\n linkedIssueId?: string | null;\n message?: string;\n resumeAt?: string | null;\n segmentIndex?: number | null;\n totalSegments?: number | null;\n};\n\ntype WorkflowTestSuiteEvent = {\n type: \"workflow-test-suite\";\n suiteId: string;\n status: \"running\" | \"completed\";\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n errorMessage?: string | null;\n message?: string;\n};\n\ntype TriggerResponse = {\n ok: boolean;\n jobId?: string;\n suiteId?: string;\n startedAt?: string;\n appUrl?: string;\n error?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1 || index >= argv.length - 1) return undefined;\n return argv[index + 1];\n}\n\nfunction hasFlag(argv: string[], ...flags: string[]): boolean {\n return flags.some((flag) => argv.includes(flag));\n}\n\nfunction buildQueryParams(tag?: string, namePattern?: string): string {\n const params = new URLSearchParams();\n if (tag) params.set(\"tag\", tag);\n if (namePattern) params.set(\"namePattern\", namePattern);\n return params.toString();\n}\n\nfunction extractWorkflowName(message: string | undefined, workflowId: string): string {\n if (!message) return workflowId;\n const match = message.match(/^Flow \"(.+?)\" /);\n return match ? match[1] : workflowId;\n}\n\ntype FailedTest = { name: string; testRunId: string };\n\nfunction formatFailedTests(\n failedTests: FailedTest[],\n appUrl: string | undefined,\n): string | null {\n if (failedTests.length === 0 || !appUrl) return null;\n\n const lines = [\"\", \"Failed tests:\"];\n for (const t of failedTests) {\n lines.push(` \\u2717 ${t.name}`);\n lines.push(` ${appUrl}/runs/tests/${t.testRunId}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatSummary(stats: {\n totalWorkflows: number;\n successfulWorkflows: number;\n failedWorkflows: number;\n completedWorkflows: number;\n}): { message: string; exitCode: number } {\n const { totalWorkflows, successfulWorkflows, failedWorkflows, completedWorkflows } = stats;\n\n if (totalWorkflows === 0) {\n return { message: \"No workflows found matching the filter criteria.\", exitCode: 0 };\n }\n\n const passRate = Math.round((successfulWorkflows / totalWorkflows) * 100);\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n\n let message: string;\n let exitCode: number;\n\n if (failedWorkflows > 0) {\n message = `FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`;\n exitCode = 1;\n } else {\n message = `PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`;\n exitCode = 0;\n }\n\n if (waitingWorkflows > 0) {\n message += `\\nNote: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`;\n }\n\n return { message, exitCode };\n}\n\n// Export internals for testing\nexport const __internals = {\n getArgValue,\n hasFlag,\n buildQueryParams,\n extractWorkflowName,\n formatSummary,\n formatFailedTests,\n};\n\nexport async function runRemoteTest(argv: string[]): Promise<void> {\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n process.env.CANARY_API_URL ??\n \"https://api.trycanary.ai\";\n\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n const tag = getArgValue(argv, \"--tag\");\n const namePattern = getArgValue(argv, \"--name-pattern\");\n const verbose = hasFlag(argv, \"--verbose\", \"-v\");\n\n if (!token) {\n console.error(\"Error: No API token found.\");\n console.error(\"\");\n console.error(\"Set CANARY_API_TOKEN environment variable or run:\");\n console.error(\" canary login\");\n console.error(\"\");\n console.error(\"Or create an API key in Settings > API Keys and pass it:\");\n console.error(\" canary test --remote --token cnry_...\");\n process.exit(1);\n }\n\n console.log(\"Starting remote workflow tests...\");\n if (tag) console.log(` Filtering by tag: ${tag}`);\n if (namePattern) console.log(` Filtering by name pattern: ${namePattern}`);\n console.log(\"\");\n\n // 1. Trigger test run\n const queryParams = new URLSearchParams();\n if (tag) queryParams.set(\"tag\", tag);\n if (namePattern) queryParams.set(\"namePattern\", namePattern);\n\n const triggerUrl = `${apiUrl}/workflows/test-runs${queryParams.toString() ? `?${queryParams}` : \"\"}`;\n\n let triggerRes: Response;\n try {\n triggerRes = await fetch(triggerUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to API: ${err}`);\n process.exit(1);\n }\n\n if (!triggerRes.ok) {\n const errorText = await triggerRes.text();\n console.error(`Failed to start tests: ${triggerRes.status}`);\n console.error(errorText);\n process.exit(1);\n }\n\n const triggerData = (await triggerRes.json()) as TriggerResponse;\n if (!triggerData.ok || !triggerData.suiteId) {\n console.error(`Failed to start tests: ${triggerData.error ?? \"Unknown error\"}`);\n process.exit(1);\n }\n\n const { suiteId, jobId, appUrl } = triggerData;\n if (verbose) {\n console.log(`Suite ID: ${suiteId}`);\n console.log(`Job ID: ${jobId}`);\n console.log(\"\");\n }\n\n // 2. Subscribe to SSE stream\n const streamUrl = `${apiUrl}/workflows/test-runs/stream?suiteId=${suiteId}`;\n\n let streamRes: Response;\n try {\n streamRes = await fetch(streamUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"text/event-stream\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to event stream: ${err}`);\n process.exit(1);\n }\n\n if (!streamRes.ok || !streamRes.body) {\n console.error(`Failed to connect to event stream: ${streamRes.status}`);\n process.exit(1);\n }\n\n // Track state\n let exitCode = 0;\n let hasCompleted = false;\n const workflowNames = new Map<string, string>();\n const failedTests: FailedTest[] = [];\n let totalWorkflows = 0;\n let completedWorkflows = 0;\n let failedWorkflows = 0;\n let successfulWorkflows = 0;\n\n // 3. Parse SSE events\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as\n | WorkflowTestEvent\n | WorkflowTestSuiteEvent\n | { error?: string };\n\n if (verbose) {\n console.log(`[${event.event}] ${JSON.stringify(data)}`);\n }\n\n if (event.event === \"workflow-test\") {\n const testEvent = data as WorkflowTestEvent;\n const { status, workflowId, message, errorMessage } = testEvent;\n const name = workflowNames.get(workflowId) || message?.replace(/^Flow \"(.+)\" .*$/, \"$1\") || workflowId;\n\n if (message?.startsWith('Flow \"')) {\n const match = message.match(/^Flow \"(.+?)\" /);\n if (match) workflowNames.set(workflowId, match[1]);\n }\n\n if (!verbose) {\n if (status === \"success\") {\n console.log(` \\u2713 ${name}`);\n } else if (status === \"failed\") {\n console.log(` \\u2717 ${name}`);\n if (errorMessage) {\n console.log(` Error: ${errorMessage.slice(0, 200)}`);\n }\n failedTests.push({ name, testRunId: testEvent.testRunId });\n exitCode = 1;\n } else if (status === \"running\") {\n // Don't log running status in non-verbose mode\n } else if (status === \"waiting\") {\n console.log(` \\u23F3 ${name} (waiting for scheduled time)`);\n }\n }\n }\n\n if (event.event === \"workflow-test-suite\") {\n const suiteEvent = data as WorkflowTestSuiteEvent;\n totalWorkflows = suiteEvent.totalWorkflows;\n completedWorkflows = suiteEvent.completedWorkflows;\n failedWorkflows = suiteEvent.failedWorkflows;\n successfulWorkflows = suiteEvent.successfulWorkflows;\n\n if (suiteEvent.status === \"completed\") {\n hasCompleted = true;\n }\n }\n\n if (event.event === \"error\") {\n const errorData = data as { error?: string };\n console.error(`Stream error: ${errorData.error ?? \"Unknown error\"}`);\n exitCode = 1;\n }\n } catch {\n // Ignore parse errors for keepalive, etc.\n }\n },\n });\n\n const reader = streamRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (!hasCompleted) {\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 // 4. Print summary\n console.log(\"\");\n console.log(\"─\".repeat(50));\n\n if (totalWorkflows === 0) {\n console.log(\"No workflows found matching the filter criteria.\");\n process.exit(0);\n }\n\n const passRate = totalWorkflows > 0 ? Math.round((successfulWorkflows / totalWorkflows) * 100) : 0;\n\n if (failedWorkflows > 0) {\n console.log(`FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`);\n exitCode = 1;\n } else {\n console.log(`PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`);\n }\n\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n if (waitingWorkflows > 0) {\n console.log(`Note: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`);\n }\n\n const failedSection = formatFailedTests(failedTests, appUrl);\n if (failedSection) {\n console.log(failedSection);\n }\n\n process.exit(exitCode);\n}\n","/**\n * CLI Debug Session Generator\n *\n * Creates a debug login token for browser-based debugging with Playwright.\n * Requires superadmin authentication.\n *\n * Usage:\n * canary debug-session [--env dev|prod|local] [--api-url <url>]\n *\n * Outputs the login URL that can be used with Playwright to authenticate\n * as the debug agent user for read-only browser access.\n */\n\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { resolveConfig, hasFlag } from \"./auth.js\";\n\ntype DebugSessionResponse = {\n ok: boolean;\n loginUrl?: string;\n expiresAt?: string;\n error?: string;\n message?: string;\n};\n\nasync function writeDebugSession(loginUrl: string, expiresAt: string, apiUrl: string) {\n const dir = path.join(os.homedir(), \".config\", \"canary-cli\");\n const filePath = path.join(dir, \"debug-session.json\");\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n await fs.writeFile(\n filePath,\n JSON.stringify({ loginUrl, expiresAt, apiUrl, createdAt: new Date().toISOString() }, null, 2),\n { encoding: \"utf8\", mode: 0o600 }\n );\n return filePath;\n}\n\nexport async function runDebugSession(argv: string[]): Promise<void> {\n const { apiUrl, token } = await resolveConfig(argv);\n const jsonOutput = hasFlag(argv, \"--json\");\n\n try {\n const res = await fetch(`${apiUrl}/auth/debug-session/create`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n // Handle HTTP errors before parsing JSON\n if (!res.ok) {\n const text = await res.text();\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Your session may have expired.\");\n console.error(\"Run: canary login\");\n process.exit(1);\n }\n\n if (res.status === 403) {\n console.error(\"Error: Forbidden. Debug session creation requires superadmin access.\");\n process.exit(1);\n }\n\n if (res.status === 404) {\n console.error(\n \"Error: Endpoint not found. The debug-session feature may not be deployed to this environment.\"\n );\n process.exit(1);\n }\n\n // Try to parse error as JSON, fallback to raw text\n try {\n const errorJson = JSON.parse(text) as { error?: string; message?: string };\n console.error(`Error: ${errorJson.message ?? errorJson.error ?? text}`);\n } catch {\n console.error(`Error (${res.status}): ${text || res.statusText}`);\n }\n process.exit(1);\n }\n\n const json = (await res.json()) as DebugSessionResponse;\n\n if (!json.ok || !json.loginUrl) {\n console.error(`Error: ${json.message ?? json.error ?? \"Failed to create debug session\"}`);\n process.exit(1);\n }\n\n // Save session info\n const filePath = await writeDebugSession(json.loginUrl, json.expiresAt ?? \"\", apiUrl);\n\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n {\n loginUrl: json.loginUrl,\n expiresAt: json.expiresAt,\n sessionFile: filePath,\n },\n null,\n 2\n )\n );\n } else {\n console.log(\"Debug session created successfully.\");\n console.log(\"\");\n console.log(`Login URL: ${json.loginUrl}`);\n console.log(`Expires: ${json.expiresAt}`);\n console.log(`Session saved to: ${filePath}`);\n console.log(\"\");\n console.log(\"Use this URL with Playwright to authenticate as the debug agent.\");\n console.log(\"The token is single-use and expires in 5 minutes.\");\n }\n } catch (err) {\n console.error(`Failed to create debug session: ${err}`);\n process.exit(1);\n }\n}\n","/**\n * JWT payload decoder for CLI superadmin detection.\n *\n * Decodes the payload section of a JWT locally (no signature verification,\n * no network calls). Used to conditionally show superadmin CLI commands.\n *\n * @module\n */\n\n/**\n * Decode the payload (second segment) of a JWT without verifying the signature.\n * Returns the parsed JSON object, or `null` if the token is malformed.\n */\nexport function decodeJwtPayload(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const base64 = parts[1]!.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = Buffer.from(base64, \"base64\").toString(\"utf8\");\n const payload: unknown = JSON.parse(json);\n\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) {\n return null;\n }\n return payload as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Returns `true` when the JWT's `is_superadmin` claim is exactly `true`.\n * Returns `false` for any invalid, missing, or non-superadmin token.\n */\nexport function isSuperadminToken(token: string | null | undefined): boolean {\n if (!token) return false;\n const payload = decodeJwtPayload(token);\n return payload?.is_superadmin === true;\n}\n"],"mappings":"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","names":["spawnSync","createRequire","process","path","fileURLToPath","pathToFileURL","preloadPath","fs","path","requireFn","baseDir","path","preloadPath","fs","process","spawn","process","spawn","process","process","process","getArgValue","process","run","process","getArgValue","hasFlag","getArgValue","process","hasFlag","fs","os","path","process","path","os","fs","process","require","createRequire","path","fileURLToPath","process","spawnSync","process","pathToFileURL"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/runner/common.ts","../src/run.ts","../src/login.ts","../src/orgs.ts","../src/run-local.ts","../src/remote-test.ts","../src/debug-session.ts","../src/jwt.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport process from \"node:process\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\nimport { run as runCanary } from \"./run\";\nimport { runLocalTest } from \"./local-run\";\nimport { runTunnel } from \"./tunnel\";\nimport { runLogin } from \"./login\";\nimport { runOrgs } from \"./orgs\";\nimport { runLocalSession } from \"./run-local\";\nimport { runRemoteTest } from \"./remote-test\";\nimport { readAllStoredTokens, readStoredToken } from \"./auth\";\nimport { runDebugSession } from \"./debug-session\";\nimport { isSuperadminToken } from \"./jwt\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\n\n// Lazy-load playwright-dependent modules\nconst loadMcp = () => import(\"./mcp\").then((m) => m.runMcp);\nconst loadLocalBrowser = () => import(\"./local-browser/index\").then((m) => m.runLocalBrowser);\nconst loadDebugWorkflow = () => import(\"./debug-workflow\").then((m) => m.runDebugWorkflow);\n\nexport const canary = { run: runCanary };\nexport { runCanary as run };\n\nconst baseDir =\n typeof __dirname !== \"undefined\" ? __dirname : path.dirname(fileURLToPath(import.meta.url));\nconst preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\nconst requireFn = makeRequire();\n\nfunction runPlaywrightTests(args: string[]) {\n // Resolve the local @playwright/test CLI directly (drop-in replacement)\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = {\n ...process.env,\n CANARY_ENABLED: process.env.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n ...(nodeOptions ? { NODE_OPTIONS: nodeOptions } : {}),\n };\n\n const result = spawnSync(runnerBin, [playwrightCli, \"test\", ...args], {\n env,\n stdio: \"inherit\",\n cwd: process.cwd(),\n });\n\n if (result.error) {\n console.error(\"canary failed to launch Playwright:\", result.error);\n process.exit(1);\n }\n\n process.exit(result.status ?? 1);\n}\n\nfunction printVersion() {\n console.log(`canary v${pkg.version}`);\n}\n\nfunction printHelp({ isSuperadmin }: { isSuperadmin: boolean }) {\n const lines: string[] = [\n `canary v${pkg.version}: Local and remote testing CLI`,\n \"\",\n \"Usage:\",\n \" canary test [playwright options] Run local Playwright tests\",\n \" canary test --remote [options] Run remote workflow tests\",\n \" canary local-run --tunnel-url <url> [options]\",\n \" canary tunnel --port <localPort> [options]\",\n \" canary run --port <localPort> [options]\",\n \" canary mcp\",\n \" canary browser [--mode playwright|cdp] [--cdp-url <url>] [--no-headless]\",\n \" canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]\",\n \" canary orgs List organizations\",\n \" canary debug <workflowId> [options] Debug workflow in local headed browser\",\n \" canary issues <sub-command> Search and view issues\",\n ];\n\n lines.push(\n \" canary release <sub-command> Release QA gate (CI/CD)\",\n );\n\n if (isSuperadmin) {\n lines.push(\n \" canary debug-session [--env dev|local] [--json] Create browser debug session\",\n \" canary psql <query> [--json] Execute read-only SQL\",\n \" canary redis <command> [--json] Execute read-only Redis commands\",\n \" canary feature-flag <sub-command> Manage feature flags\",\n \" canary knobs <sub-command> Manage knobs (global config)\",\n );\n }\n\n lines.push(\n \" canary version Show version\",\n \" canary help\",\n \"\",\n \"Remote test options:\",\n \" --token <key> API key (or set CANARY_API_TOKEN)\",\n \" --api-url <url> API URL (default: https://api.trycanary.ai)\",\n \" --tag <tag> Filter workflows by tag\",\n \" --name-pattern <pat> Filter workflows by name pattern\",\n \" --verbose, -v Show all events\",\n \"\",\n \"Browser options:\",\n \" --mode <playwright|cdp> Browser mode (default: playwright)\",\n \" --cdp-url <url> CDP endpoint for existing Chrome\",\n \" --no-headless Run browser with visible UI\",\n \" --storage-state <path> Path to storage state JSON\",\n \" --instructions <text> Instructions for the cloud agent\",\n \"\",\n \"Login options:\",\n \" --org <name> Select organization by name or ID (for multi-org users)\",\n \"\",\n \"Login environments:\",\n \" Production: canary login\",\n \" Dev: canary login --app-url https://app.dev.trycanary.ai --api-url https://api.dev.trycanary.ai\",\n \" Local: canary login --app-url http://localhost:5173 --api-url http://localhost:3000\",\n \"\",\n \" Or set CANARY_API_URL env var for non-production environments:\",\n \" export CANARY_API_URL=http://localhost:3000\",\n );\n\n lines.push(\n \"\",\n \"Debug options:\",\n \" --to-step <N> Stop after step N (1-based, default: all)\",\n \" --env <env> Environment (local, dev, prod)\",\n \" --verbose, -v Show all SSE events\",\n \"\",\n \"Issues sub-commands:\",\n \" list [options] List and search issues\",\n \" get <issueId> [options] Get issue detail with diagnostics\",\n \"\",\n \"Issues options:\",\n \" --search <query> Full-text search\",\n \" --severity <level> Filter: low, medium, high, unknown\",\n \" --status <statuses> Filter: open, closed, not_a_bug (comma-separated)\",\n \" --property-id <uuid> Filter by property\",\n \" --page <n> Page number (default: 1)\",\n \" --page-size <n> Page size (default: 25)\",\n \" --json Output raw JSON\",\n \" --format markdown Output as markdown\",\n \"\",\n \"Release sub-commands:\",\n \" trigger --property-id <uuid> Trigger a Release QA run\",\n \" status <run-id> [--json] Check run status\",\n \" run --property-id <uuid> [--timeout N] Trigger and poll until complete\",\n );\n\n if (isSuperadmin) {\n lines.push(\n \"\",\n \"PSQL options:\",\n \" --json Output results as JSON\",\n \" --query <sql> SQL query (alternative to positional)\",\n \"\",\n \"Redis options:\",\n \" --json Output results as JSON\",\n \"\",\n \"Feature flag sub-commands:\",\n \" list List all flags\",\n \" create <name> [--description <text>] Create a flag\",\n \" delete <name> Delete a flag and its gates\",\n \" enable <name> --org <orgId> Enable for an org\",\n \" disable <name> --org <orgId> Disable for an org\",\n \" lifecycle <name> --stage <stage> [--final-value true|false]\",\n \" Set lifecycle metadata\",\n \"\",\n \"Knobs sub-commands:\",\n \" list List all knobs\",\n \" get <key> Get a knob value\",\n \" set <key> <value> --type <type> Set a knob value\",\n \" delete <key> Delete a knob\",\n \" toggle <key> Toggle a boolean knob\",\n \" lifecycle <key> --stage <stage> [--final-value <value>]\",\n \" Set lifecycle metadata\",\n );\n }\n\n lines.push(\n \"\",\n \"Flags:\",\n \" -h, --help Show help\",\n \" -V, --version Show version\",\n );\n\n console.log(lines.join(\"\\n\"));\n}\n\nfunction printTestHelp() {\n console.log(\n [\n `canary v${pkg.version}: Test command`,\n \"\",\n \"Usage:\",\n \" canary test [playwright options] Run local Playwright tests\",\n \" canary test --remote [options] Run remote workflow tests\",\n \"\",\n \"Local Playwright options (passed through to Playwright):\",\n \" --grep <pattern> Only run tests matching pattern\",\n \" --headed Run in headed browser mode\",\n \" --workers <n> Number of parallel workers\",\n \" --project <name> Run specific project\",\n \" --reporter <reporter> Use a specific reporter\",\n \" --retries <n> Number of retries for failed tests\",\n \" --timeout <ms> Test timeout in milliseconds\",\n \"\",\n \"Remote test options:\",\n \" --remote Run tests remotely (required)\",\n \" --token <key> API key (or set CANARY_API_TOKEN)\",\n \" --api-url <url> API URL (default: https://api.trycanary.ai)\",\n \" --tag <tag> Filter workflows by tag\",\n \" --name-pattern <pat> Filter workflows by name pattern\",\n \" --verbose, -v Show all events\",\n \"\",\n \"Examples:\",\n \" canary test Run all local tests\",\n ' canary test --grep \"login\" Run tests matching \"login\"',\n \" canary test --headed --workers 1 Debug with visible browser\",\n \" canary test --remote --tag smoke Run remote smoke tests\",\n ].join(\"\\n\")\n );\n}\n\n/** Commands that handle --help themselves instead of showing global help. */\nconst COMMANDS_WITH_HELP = new Set([\"test\"]);\n\nasync function resolveToken(): Promise<string | null> {\n return process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n}\n\n/** Check if any stored profile (or env token) has superadmin privileges */\nasync function resolveIsSuperadmin(): Promise<boolean> {\n const envToken = process.env.CANARY_API_TOKEN;\n if (envToken) return isSuperadminToken(envToken);\n\n const tokens = await readAllStoredTokens();\n return tokens.some((t) => isSuperadminToken(t));\n}\n\nexport async function main(argv: string[]) {\n if (argv.includes(\"--version\") || argv.includes(\"-V\")) {\n printVersion();\n return;\n }\n\n const [command, ...rest] = argv;\n const hasHelpFlag = argv.includes(\"--help\") || argv.includes(\"-h\");\n\n // Global help: --help/‑h without a command that handles it, or explicit \"help\"\n if (hasHelpFlag && (!command || !COMMANDS_WITH_HELP.has(command))) {\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n return;\n }\n\n if (!command || command === \"help\") {\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n return;\n }\n\n if (command === \"version\") {\n printVersion();\n return;\n }\n\n if (command === \"test\") {\n // Sub-command help\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n printTestHelp();\n return;\n }\n // Check for --remote flag to run remote workflow tests\n if (rest.includes(\"--remote\")) {\n const remoteArgs = rest.filter((arg) => arg !== \"--remote\");\n await runRemoteTest(remoteArgs);\n return;\n }\n runPlaywrightTests(rest);\n return;\n }\n\n if (command === \"local-run\") {\n await runLocalTest(rest);\n return;\n }\n\n if (command === \"run\") {\n await runLocalSession(rest);\n return;\n }\n\n if (command === \"mcp\") {\n const runMcp = await loadMcp();\n await runMcp(rest);\n return;\n }\n\n if (command === \"tunnel\") {\n await runTunnel(rest);\n return;\n }\n\n if (command === \"login\") {\n await runLogin(rest);\n return;\n }\n\n if (command === \"orgs\") {\n await runOrgs(rest);\n return;\n }\n\n if (command === \"browser\") {\n const runLocalBrowser = await loadLocalBrowser();\n await runLocalBrowser(rest);\n return;\n }\n\n if (command === \"debug\") {\n const runDebugWorkflow = await loadDebugWorkflow();\n await runDebugWorkflow(rest);\n return;\n }\n\n if (command === \"debug-session\") {\n await runDebugSession(rest);\n return;\n }\n\n if (command === \"psql\") {\n const { runPsql } = await import(\"./psql.js\");\n await runPsql(rest);\n return;\n }\n\n if (command === \"redis\") {\n const { runRedis } = await import(\"./redis.js\");\n await runRedis(rest);\n return;\n }\n\n if (command === \"release\") {\n const { runRelease } = await import(\"./release.js\");\n await runRelease(rest);\n return;\n }\n\n if (command === \"feature-flag\") {\n const { runFeatureFlag } = await import(\"./feature-flag.js\");\n await runFeatureFlag(rest);\n return;\n }\n\n if (command === \"knobs\") {\n const { runKnobs } = await import(\"./knobs.js\");\n await runKnobs(rest);\n return;\n }\n\n if (command === \"issues\") {\n const { runIssues } = await import(\"./issues.js\");\n await runIssues(rest);\n return;\n }\n\n console.log(`Unknown command \"${command}\".`);\n printHelp({ isSuperadmin: await resolveIsSuperadmin() });\n process.exit(1);\n}\n\nif (import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main(process.argv.slice(2));\n}\n","import { spawnSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nexport function makeRequire() {\n try {\n return createRequire(import.meta.url);\n } catch {\n try {\n return createRequire(process.cwd());\n } catch {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof require !== \"undefined\" ? (require as any) : createRequire(\".\");\n }\n }\n}\n\nexport function resolveRunner(preloadPath?: string): { runnerBin: string; preloadFlag?: string } {\n const { bin, version } = pickNodeBinary();\n const supportsImport = typeof version === \"number\" && version >= 18;\n\n if (supportsImport && preloadPath && fs.existsSync(preloadPath)) {\n return { runnerBin: bin, preloadFlag: `--import=${pathToFileURL(preloadPath).href}` };\n }\n\n if (preloadPath) {\n console.warn(\"[canary] Warning: no preload module found; instrumentation may be disabled.\");\n }\n\n return { runnerBin: bin };\n}\n\nexport function pickNodeBinary(): { bin: string; version?: number } {\n const candidates = collectNodeCandidates();\n\n // Prefer the first viable candidate with version >=18; otherwise pick highest version found.\n let best: { bin: string; version?: number } | undefined;\n let fallback: { bin: string; version?: number } | undefined;\n\n for (const bin of candidates) {\n const version = getNodeMajor(bin);\n if (!version) continue;\n const current = { bin, version };\n if (version >= 18 && !fallback) {\n fallback = current;\n }\n if (!best || version > (best.version ?? 0)) {\n best = current;\n }\n }\n\n if (fallback) return fallback;\n if (best) return best;\n\n // Last resort\n return { bin: candidates[0] ?? \"node\" };\n}\n\nexport function collectNodeCandidates(): string[] {\n const seen = new Set<string>();\n const push = (value?: string) => {\n if (!value) return;\n if (seen.has(value)) return;\n seen.add(value);\n };\n\n const isBun = path.basename(process.execPath).includes(\"bun\");\n\n push(process.env.CANARY_NODE_BIN);\n push(isBun ? undefined : process.execPath);\n push(\"node\"); // default PATH lookup\n\n // Collect from `which -a node` if available.\n try {\n const which = spawnSync(\"which\", [\"-a\", \"node\"], { encoding: \"utf-8\" });\n which.stdout\n ?.toString()\n .split(\"\\n\")\n .map((line) => line.trim())\n .forEach((line) => push(line));\n } catch {\n // ignore\n }\n\n // NVM installations (grab highest versions)\n const nvmDir = process.env.NVM_DIR || (process.env.HOME ? path.join(process.env.HOME, \".nvm\") : undefined);\n if (nvmDir) {\n const versionsDir = path.join(nvmDir, \"versions\", \"node\");\n if (fs.existsSync(versionsDir)) {\n try {\n const versions = fs.readdirSync(versionsDir);\n versions\n .sort((a, b) => (a > b ? -1 : 1))\n .forEach((v) => push(path.join(versionsDir, v, \"bin\", \"node\")));\n } catch {\n // ignore\n }\n }\n }\n\n return Array.from(seen);\n}\n\nexport function getNodeMajor(bin: string): number | undefined {\n try {\n const result = spawnSync(bin, [\"-v\"], { encoding: \"utf-8\" });\n const output = (result.stdout || result.stderr || \"\").toString().trim();\n const match = output.match(/^v(\\d+)/);\n if (match) return Number(match[1]);\n } catch {\n // ignore\n }\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\n\nexport type HealingOptions = {\n apiKey?: string;\n provider?: string;\n model?: string;\n timeoutMs?: number;\n maxActions?: number;\n vision?: boolean;\n dryRun?: boolean;\n warnOnly?: boolean;\n debug?: boolean;\n readOnly?: boolean;\n allowEvaluate?: boolean;\n allowRunCode?: boolean;\n maxPayloadBytes?: number;\n};\n\nexport type RunRequest = {\n projectRoot?: string;\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n env?: Record<string, string>;\n healing?: HealingOptions;\n reporter?: \"default\" | \"json\" | string;\n timeoutMs?: number;\n nodeBin?: string;\n stdio?: \"inherit\" | \"pipe\";\n};\n\nexport type RunResult = {\n ok: boolean;\n exitCode: number;\n summary: {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n healed?: number;\n warned?: number;\n durationMs: number;\n };\n artifactsDir?: string;\n rawOutput?: string;\n error?: Error;\n};\n\ntype JsonReport = {\n suites?: JsonSuite[];\n duration?: number;\n};\n\ntype JsonSuite = {\n suites?: JsonSuite[];\n tests?: Array<{\n title: string;\n results: Array<{\n status: \"passed\" | \"failed\" | \"timedOut\" | \"skipped\" | \"interrupted\";\n duration: number;\n errors?: unknown[];\n }>;\n }>;\n};\n\nexport async function run(request: RunRequest = {}): Promise<RunResult> {\n const cwd = request.projectRoot ?? process.cwd();\n const stdio = request.stdio ?? \"inherit\";\n const requireFn = makeRequire();\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const baseDir = path.dirname(fileURLToPath(import.meta.url));\n const preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const { jsonReportPath, eventLogPath, artifactsDir } = prepareArtifactsDir(cwd);\n const reporter = buildReporterArgs(request.reporter, jsonReportPath);\n const args = buildArgs({\n testDir: request.testDir,\n configFile: request.configFile,\n cliArgs: request.cliArgs,\n reporter,\n });\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = buildEnv({\n base: process.env,\n overrides: request.env,\n healing: request.healing,\n eventLogPath,\n nodeOptions,\n });\n\n const runResult = await spawnPlaywright({\n bin: request.nodeBin ?? runnerBin,\n args: [playwrightCli, ...args],\n cwd,\n env,\n stdio,\n timeoutMs: request.timeoutMs,\n });\n\n const summary = summarize(jsonReportPath, eventLogPath, runResult.durationMs);\n\n return {\n ok: runResult.exitCode === 0,\n exitCode: runResult.exitCode,\n summary,\n artifactsDir,\n rawOutput: runResult.output,\n error: runResult.error,\n };\n}\n\nfunction buildArgs(opts: {\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n reporter: string;\n}): string[] {\n const args = [\"test\"];\n\n if (opts.testDir) {\n const dirs = Array.isArray(opts.testDir) ? opts.testDir : [opts.testDir];\n args.push(...dirs);\n }\n\n if (opts.configFile) {\n args.push(\"--config\", opts.configFile);\n }\n\n args.push(\"--reporter\", opts.reporter);\n\n if (opts.cliArgs?.length) {\n args.push(...opts.cliArgs);\n }\n\n return args;\n}\n\nfunction buildReporterArgs(requested: RunRequest[\"reporter\"], jsonReportPath: string): string {\n if (requested === \"json\") return `json=${jsonReportPath}`;\n if (requested && requested !== \"default\") return requested;\n // Default: keep list output plus JSON for programmatic summary\n return `list,json=${jsonReportPath}`;\n}\n\nfunction prepareArtifactsDir(cwd: string): { jsonReportPath: string; eventLogPath: string; artifactsDir: string } {\n const dir = fs.mkdtempSync(path.join(os.tmpdir(), \"canary-run-\"));\n const jsonReportPath = path.join(dir, \"report.json\");\n const eventLogPath = path.join(dir, \"events-worker-0.jsonl\");\n const artifactsDir = path.join(cwd, \"test-results\", \"ai-healer\");\n return { jsonReportPath, eventLogPath, artifactsDir: dir };\n}\n\nfunction buildEnv(params: {\n base: NodeJS.ProcessEnv;\n overrides?: Record<string, string>;\n healing?: HealingOptions;\n eventLogPath: string;\n nodeOptions?: string;\n}): NodeJS.ProcessEnv {\n const healing = params.healing ?? {};\n const env: NodeJS.ProcessEnv = {\n ...params.base,\n CANARY_ENABLED: params.base.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n CANARY_EVENT_LOG: params.eventLogPath,\n ...(params.nodeOptions ? { NODE_OPTIONS: params.nodeOptions } : {}),\n ...(healing.apiKey ? { AI_API_KEY: healing.apiKey } : {}),\n ...(healing.provider ? { AI_PROVIDER: healing.provider } : {}),\n ...(healing.model ? { AI_MODEL: healing.model } : {}),\n ...(healing.timeoutMs ? { AI_TIMEOUT_MS: String(healing.timeoutMs) } : {}),\n ...(healing.maxActions ? { CANARY_MAX_ACTIONS: String(healing.maxActions) } : {}),\n ...(healing.vision ? { CANARY_VISION: \"1\" } : {}),\n ...(healing.dryRun ? { CANARY_DRY_RUN: \"1\" } : {}),\n ...(healing.warnOnly ? { CANARY_WARN_ONLY: \"1\" } : {}),\n ...(healing.debug ? { CANARY_DEBUG: \"1\" } : {}),\n ...(healing.readOnly ? { CANARY_READ_ONLY: \"1\" } : {}),\n ...(healing.allowEvaluate === false ? { CANARY_ALLOW_EVALUATE: \"0\" } : {}),\n ...(healing.allowRunCode ? { CANARY_ALLOW_RUN_CODE: \"1\" } : {}),\n ...(healing.maxPayloadBytes ? { CANARY_MAX_PAYLOAD_BYTES: String(healing.maxPayloadBytes) } : {}),\n ...params.overrides,\n };\n return env;\n}\n\nasync function spawnPlaywright(opts: {\n bin: string;\n args: string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n stdio: \"inherit\" | \"pipe\";\n timeoutMs?: number;\n}): Promise<{ exitCode: number; output?: string; durationMs: number; error?: Error }> {\n return new Promise((resolve) => {\n const started = Date.now();\n const child = spawn(opts.bin, opts.args, {\n cwd: opts.cwd,\n env: opts.env,\n stdio: opts.stdio === \"inherit\" ? \"inherit\" : [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let timer: NodeJS.Timeout | undefined;\n let output = \"\";\n let error: Error | undefined;\n\n if (opts.stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n if (opts.timeoutMs && opts.timeoutMs > 0) {\n timer = setTimeout(() => {\n error = new Error(`canary.run timed out after ${opts.timeoutMs}ms`);\n child.kill(\"SIGKILL\");\n }, opts.timeoutMs);\n }\n\n child.on(\"close\", (code) => {\n if (timer) clearTimeout(timer);\n resolve({ exitCode: code ?? 1, output: output || undefined, durationMs: Date.now() - started, error });\n });\n });\n}\n\nfunction summarize(jsonReportPath: string, eventLogPath: string, durationMs: number): RunResult[\"summary\"] {\n const base = {\n total: 0,\n passed: 0,\n failed: 0,\n flaky: 0,\n skipped: 0,\n durationMs,\n };\n\n const jsonReport = readJsonReport(jsonReportPath);\n if (jsonReport) {\n const counts = countTests(jsonReport);\n base.total = counts.total;\n base.passed = counts.passed;\n base.failed = counts.failed;\n base.flaky = counts.flaky;\n base.skipped = counts.skipped;\n base.durationMs = jsonReport.duration ?? durationMs;\n }\n\n const healed = countHealed(eventLogPath);\n if (healed) {\n return { ...base, healed };\n }\n return base;\n}\n\nfunction readJsonReport(reportPath: string): JsonReport | undefined {\n try {\n if (fs.existsSync(reportPath)) {\n const raw = fs.readFileSync(reportPath, \"utf-8\");\n return JSON.parse(raw) as JsonReport;\n }\n } catch {\n // ignore parse issues\n }\n return undefined;\n}\n\nfunction countTests(report: JsonReport): {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n} {\n let total = 0;\n let passed = 0;\n let failed = 0;\n let flaky = 0;\n let skipped = 0;\n\n const visitSuite = (suite?: JsonSuite) => {\n if (!suite) return;\n suite.tests?.forEach((test) => {\n total += 1;\n const statuses = test.results.map((r) => r.status);\n const hasFailed = statuses.includes(\"failed\") || statuses.includes(\"interrupted\");\n const hasPassed = statuses.includes(\"passed\");\n const hasTimedOut = statuses.includes(\"timedOut\");\n const allSkipped = statuses.every((s) => s === \"skipped\");\n\n if (allSkipped) {\n skipped += 1;\n } else if ((hasFailed || hasTimedOut) && hasPassed) {\n flaky += 1;\n } else if (hasFailed || hasTimedOut) {\n failed += 1;\n } else if (hasPassed && statuses.length > 1) {\n flaky += 1;\n } else if (hasPassed) {\n passed += 1;\n }\n });\n\n suite.suites?.forEach(visitSuite);\n };\n\n report.suites?.forEach(visitSuite);\n\n return { total, passed, failed, flaky, skipped };\n}\n\nfunction countHealed(eventLogPath: string): number | undefined {\n try {\n if (!fs.existsSync(eventLogPath)) return undefined;\n const raw = fs.readFileSync(eventLogPath, \"utf-8\").trim();\n if (!raw) return undefined;\n const lines = raw.split(\"\\n\");\n let healed = 0;\n for (const line of lines) {\n try {\n const event = JSON.parse(line);\n if (event?.healed === true) healed += 1;\n } catch {\n // ignore bad lines\n }\n }\n return healed;\n } catch {\n return undefined;\n }\n}\n\nexport const __internals = {\n buildArgs,\n buildReporterArgs,\n buildEnv,\n countTests,\n countHealed,\n summarize,\n};\n","import process from \"node:process\";\nimport readline from \"node:readline\";\nimport { spawn } from \"node:child_process\";\nimport { saveAuth, ENV_URLS, envToProfile, getArgValue } from \"./auth\";\n\ntype StartResponse = {\n ok: boolean;\n deviceCode?: string;\n userCode?: string;\n verificationUrl?: string;\n expiresAt?: string;\n intervalSeconds?: number;\n error?: string;\n};\n\ntype PollResponse = {\n ok: boolean;\n status?: \"pending\" | \"approved\" | \"rejected\" | \"expired\";\n accessToken?: string;\n orgId?: string;\n error?: string;\n};\n\ntype OrgsResponse = {\n ok: boolean;\n currentOrgId?: string;\n organizations?: Array<{ id: string; name: string; role: string }>;\n error?: string;\n};\n\ntype SwitchOrgResponse = {\n ok: boolean;\n accessToken?: string;\n orgId?: string;\n orgName?: string;\n role?: string;\n error?: string;\n};\n\nfunction shouldOpenBrowser(argv: string[]): boolean {\n return !argv.includes(\"--no-open\");\n}\n\nfunction openUrl(url: string) {\n const platform = process.platform;\n if (platform === \"darwin\") {\n spawn(\"open\", [url], { stdio: \"ignore\" });\n return;\n }\n if (platform === \"win32\") {\n spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { stdio: \"ignore\" });\n return;\n }\n spawn(\"xdg-open\", [url], { stdio: \"ignore\" });\n}\n\nfunction promptChoice(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function fetchOrgs(apiUrl: string, token: string): Promise<OrgsResponse | null> {\n try {\n const res = await fetch(`${apiUrl}/cli-login/orgs`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) return null;\n return (await res.json()) as OrgsResponse;\n } catch {\n return null;\n }\n}\n\nasync function switchOrg(apiUrl: string, token: string, orgId: string): Promise<SwitchOrgResponse> {\n const res = await fetch(`${apiUrl}/cli-login/switch-org`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ orgId }),\n });\n return (await res.json()) as SwitchOrgResponse;\n}\n\nexport async function runLogin(argv: string[]) {\n const env = getArgValue(argv, \"--env\");\n const envUrls = env ? ENV_URLS[env] : undefined;\n\n if (env && !envUrls) {\n console.error(`Unknown environment: ${env}`);\n console.error(\"Valid environments: prod, dev, local\");\n process.exit(1);\n }\n\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n envUrls?.api ??\n process.env.CANARY_API_URL ??\n \"https://api.trycanary.ai\";\n const appUrl =\n getArgValue(argv, \"--app-url\") ??\n envUrls?.app ??\n process.env.CANARY_APP_URL ??\n \"https://app.trycanary.ai\";\n\n const orgFlag = getArgValue(argv, \"--org\");\n\n const startRes = await fetch(`${apiUrl}/cli-login/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ appUrl }),\n });\n\n const startJson = (await startRes.json()) as StartResponse;\n if (!startRes.ok || !startJson.ok || !startJson.deviceCode || !startJson.userCode) {\n console.error(\"Login start failed\", startJson.error ?? startRes.statusText);\n process.exit(1);\n }\n\n console.log(\"Login required.\");\n console.log(`User code: ${startJson.userCode}`);\n if (startJson.verificationUrl) {\n console.log(`Open: ${startJson.verificationUrl}`);\n if (shouldOpenBrowser(argv)) {\n try {\n openUrl(startJson.verificationUrl);\n } catch {\n console.log(\"Unable to open browser automatically. Please open the URL manually.\");\n }\n }\n }\n\n const intervalMs = (startJson.intervalSeconds ?? 3) * 1000;\n const expiresAt = startJson.expiresAt ? new Date(startJson.expiresAt).getTime() : null;\n\n let token: string | undefined;\n let initialOrgId: string | undefined;\n\n while (true) {\n if (expiresAt && Date.now() > expiresAt) {\n console.error(\"Login code expired.\");\n process.exit(1);\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n\n const pollRes = await fetch(`${apiUrl}/cli-login/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ deviceCode: startJson.deviceCode }),\n });\n\n const pollJson = (await pollRes.json()) as PollResponse;\n if (!pollRes.ok || !pollJson.ok) {\n console.error(\"Login poll failed\", pollJson.error ?? pollRes.statusText);\n process.exit(1);\n }\n\n if (pollJson.status === \"approved\" && pollJson.accessToken) {\n token = pollJson.accessToken;\n initialOrgId = pollJson.orgId;\n break;\n }\n\n if (pollJson.status === \"rejected\") {\n console.error(\"Login rejected.\");\n process.exit(1);\n }\n\n if (pollJson.status === \"expired\") {\n console.error(\"Login expired.\");\n process.exit(1);\n }\n }\n\n // Fetch user's organizations (gracefully skip if endpoint not available)\n const orgsData = await fetchOrgs(apiUrl, token);\n const orgs = orgsData?.organizations ?? [];\n\n let finalToken = token;\n let finalOrgId = initialOrgId;\n let finalOrgName: string | undefined;\n\n if (orgs.length <= 1) {\n // Single org (or none) — use as-is\n finalOrgName = orgs[0]?.name;\n } else {\n // Multiple orgs — determine which one to use\n let selectedOrg: (typeof orgs)[number] | undefined;\n\n if (orgFlag) {\n // Match --org flag by name (case-insensitive) or ID\n selectedOrg = orgs.find(\n (o) => o.name.toLowerCase() === orgFlag.toLowerCase() || o.id === orgFlag\n );\n if (!selectedOrg) {\n console.error(`Organization \"${orgFlag}\" not found. Available orgs:`);\n for (const o of orgs) {\n console.error(` - ${o.name} (${o.id})`);\n }\n process.exit(1);\n }\n } else if (process.stdin.isTTY) {\n // Interactive prompt\n console.log(\"\\nYou belong to multiple organizations. Select one:\");\n for (let i = 0; i < orgs.length; i++) {\n const marker = orgs[i].id === initialOrgId ? \" (current)\" : \"\";\n console.log(` ${i + 1}. ${orgs[i].name}${marker}`);\n }\n\n const answer = await promptChoice(`\\nChoice [1-${orgs.length}]: `);\n const idx = parseInt(answer, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= orgs.length) {\n console.error(\"Invalid selection.\");\n process.exit(1);\n }\n selectedOrg = orgs[idx];\n } else {\n // Non-interactive — use default from JWT\n const defaultOrg = orgs.find((o) => o.id === initialOrgId);\n console.log(\n `Warning: Multiple organizations available but running non-interactively. Using \"${defaultOrg?.name ?? initialOrgId}\".`\n );\n console.log('Tip: Use --org <name> to select a specific organization.');\n selectedOrg = defaultOrg;\n }\n\n if (selectedOrg && selectedOrg.id !== initialOrgId) {\n // Switch to selected org\n const switchRes = await switchOrg(apiUrl, token, selectedOrg.id);\n if (!switchRes.ok || !switchRes.accessToken) {\n console.error(\"Failed to switch organization:\", switchRes.error ?? \"Unknown error\");\n process.exit(1);\n }\n finalToken = switchRes.accessToken;\n finalOrgId = switchRes.orgId;\n finalOrgName = switchRes.orgName;\n } else if (selectedOrg) {\n finalOrgName = selectedOrg.name;\n }\n }\n\n const profileName = env ? envToProfile(env) : undefined;\n const filePath = await saveAuth({ token: finalToken, apiUrl, orgId: finalOrgId, orgName: finalOrgName }, profileName);\n const displayName = finalOrgName ? ` to ${finalOrgName}` : \"\";\n const profileLabel = profileName ? ` (profile: ${profileName})` : \"\";\n console.log(`Login successful${displayName}${profileLabel}. Token saved to ${filePath}`);\n console.log(\"Set CANARY_API_TOKEN to use the CLI without re-login.\");\n}\n","import process from \"node:process\";\nimport { readStoredAuth, readStoredToken } from \"./auth\";\n\ntype OrgsResponse = {\n ok: boolean;\n currentOrgId?: string;\n organizations?: Array<{ id: string; name: string; role: string }>;\n error?: string;\n};\n\nexport async function runOrgs(argv: string[]) {\n const token = process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n if (!token) {\n console.error(\"Not logged in. Run: canary login\");\n process.exit(1);\n }\n\n const auth = await readStoredAuth();\n const apiUrl =\n process.env.CANARY_API_URL ?? auth?.apiUrl ?? \"https://api.trycanary.ai\";\n\n const res = await fetch(`${apiUrl}/cli-login/orgs`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n console.error(\"Failed to fetch organizations. You may need to re-login: canary login\");\n process.exit(1);\n }\n\n const data = (await res.json()) as OrgsResponse;\n if (!data.ok || !data.organizations) {\n console.error(\"Failed to fetch organizations:\", data.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n const currentOrgId = auth?.orgId ?? data.currentOrgId;\n\n console.log(\"Organizations:\\n\");\n for (const org of data.organizations) {\n const marker = org.id === currentOrgId ? \" *\" : \"\";\n console.log(` ${org.name} (${org.role})${marker}`);\n }\n\n console.log(\"\\n* = current organization\");\n console.log(\"To switch: canary login --org <name>\");\n}\n","import process from \"node:process\";\nimport { readStoredToken } from \"./auth\";\nimport { createLocalRun } from \"./local-run\";\nimport { connectTunnel, createTunnel } from \"./tunnel\";\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nexport async function runLocalSession(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n if (!token) {\n console.error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n process.exit(1);\n }\n\n const portRaw = getArgValue(argv, \"--port\") ?? process.env.CANARY_LOCAL_PORT;\n const tunnelUrl = getArgValue(argv, \"--tunnel-url\");\n const title = getArgValue(argv, \"--title\");\n const featureSpec = getArgValue(argv, \"--feature\");\n const startUrl = getArgValue(argv, \"--start-url\");\n\n if (!tunnelUrl && !portRaw) {\n console.error(\"Missing --port or --tunnel-url\");\n process.exit(1);\n }\n\n let publicUrl = tunnelUrl;\n let ws: WebSocket | null = null;\n\n if (!publicUrl && portRaw) {\n const port = Number(portRaw);\n if (Number.isNaN(port) || port <= 0) {\n console.error(\"Invalid --port value\");\n process.exit(1);\n }\n\n const tunnel = await createTunnel({ apiUrl, token, port });\n publicUrl = tunnel.publicUrl;\n\n ws = connectTunnel({\n apiUrl,\n tunnelId: tunnel.tunnelId,\n token: tunnel.token,\n port,\n onReady: () => {\n console.log(`Tunnel connected: ${publicUrl ?? tunnel.tunnelId}`);\n },\n });\n }\n\n if (!publicUrl) {\n console.error(\"Failed to resolve tunnel URL\");\n process.exit(1);\n }\n\n const run = await createLocalRun({\n apiUrl,\n token,\n title,\n featureSpec,\n startUrl,\n tunnelUrl: publicUrl,\n });\n\n console.log(`Local test queued: ${run.runId}`);\n if (run.watchUrl) {\n console.log(`Watch: ${run.watchUrl}`);\n }\n\n if (ws) {\n console.log(\"Tunnel active. Press Ctrl+C to stop.\");\n process.on(\"SIGINT\", () => {\n ws?.close();\n process.exit(0);\n });\n await new Promise<void>(() => undefined);\n }\n}\n","/**\n * Remote Test Command\n *\n * Triggers workflow tests on the Canary platform and streams results via SSE.\n * Designed for CI/CD pipelines - exits with code 0 on success, 1 on failure.\n *\n * Usage:\n * canary test --remote [options]\n *\n * Options:\n * --token <key> API key (or set CANARY_API_TOKEN env var)\n * --api-url <url> API URL (default: https://api.trycanary.ai)\n * --tag <tag> Filter workflows by tag\n * --name-pattern <pat> Filter workflows by name pattern\n * --verbose, -v Show all events (not just results)\n */\n\nimport process from \"node:process\";\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport { readStoredToken } from \"./auth\";\n\ntype WorkflowTestStatus = \"queued\" | \"running\" | \"waiting\" | \"success\" | \"failed\";\n\ntype WorkflowTestEvent = {\n type: \"workflow-test\";\n suiteId: string;\n workflowId: string;\n testRunId: string;\n workflowRunId: string | null;\n status: WorkflowTestStatus;\n startedAt: string | null;\n finishedAt: string | null;\n durationMs: number | null;\n errorMessage?: string | null;\n linkedIssueId?: string | null;\n message?: string;\n resumeAt?: string | null;\n segmentIndex?: number | null;\n totalSegments?: number | null;\n};\n\ntype WorkflowTestSuiteEvent = {\n type: \"workflow-test-suite\";\n suiteId: string;\n status: \"running\" | \"completed\";\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n errorMessage?: string | null;\n message?: string;\n};\n\ntype TriggerResponse = {\n ok: boolean;\n jobId?: string;\n suiteId?: string;\n startedAt?: string;\n appUrl?: string;\n error?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1 || index >= argv.length - 1) return undefined;\n return argv[index + 1];\n}\n\nfunction hasFlag(argv: string[], ...flags: string[]): boolean {\n return flags.some((flag) => argv.includes(flag));\n}\n\nfunction buildQueryParams(tag?: string, namePattern?: string): string {\n const params = new URLSearchParams();\n if (tag) params.set(\"tag\", tag);\n if (namePattern) params.set(\"namePattern\", namePattern);\n return params.toString();\n}\n\nfunction extractWorkflowName(message: string | undefined, workflowId: string): string {\n if (!message) return workflowId;\n const match = message.match(/^Flow \"(.+?)\" /);\n return match ? match[1] : workflowId;\n}\n\ntype FailedTest = { name: string; testRunId: string };\n\nfunction formatFailedTests(\n failedTests: FailedTest[],\n appUrl: string | undefined,\n): string | null {\n if (failedTests.length === 0 || !appUrl) return null;\n\n const lines = [\"\", \"Failed tests:\"];\n for (const t of failedTests) {\n lines.push(` \\u2717 ${t.name}`);\n lines.push(` ${appUrl}/runs/tests/${t.testRunId}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatSummary(stats: {\n totalWorkflows: number;\n successfulWorkflows: number;\n failedWorkflows: number;\n completedWorkflows: number;\n}): { message: string; exitCode: number } {\n const { totalWorkflows, successfulWorkflows, failedWorkflows, completedWorkflows } = stats;\n\n if (totalWorkflows === 0) {\n return { message: \"No workflows found matching the filter criteria.\", exitCode: 0 };\n }\n\n const passRate = Math.round((successfulWorkflows / totalWorkflows) * 100);\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n\n let message: string;\n let exitCode: number;\n\n if (failedWorkflows > 0) {\n message = `FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`;\n exitCode = 1;\n } else {\n message = `PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`;\n exitCode = 0;\n }\n\n if (waitingWorkflows > 0) {\n message += `\\nNote: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`;\n }\n\n return { message, exitCode };\n}\n\n// Export internals for testing\nexport const __internals = {\n getArgValue,\n hasFlag,\n buildQueryParams,\n extractWorkflowName,\n formatSummary,\n formatFailedTests,\n};\n\nexport async function runRemoteTest(argv: string[]): Promise<void> {\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n process.env.CANARY_API_URL ??\n \"https://api.trycanary.ai\";\n\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n const tag = getArgValue(argv, \"--tag\");\n const namePattern = getArgValue(argv, \"--name-pattern\");\n const verbose = hasFlag(argv, \"--verbose\", \"-v\");\n\n if (!token) {\n console.error(\"Error: No API token found.\");\n console.error(\"\");\n console.error(\"Set CANARY_API_TOKEN environment variable or run:\");\n console.error(\" canary login\");\n console.error(\"\");\n console.error(\"Or create an API key in Settings > API Keys and pass it:\");\n console.error(\" canary test --remote --token cnry_...\");\n process.exit(1);\n }\n\n console.log(\"Starting remote workflow tests...\");\n if (tag) console.log(` Filtering by tag: ${tag}`);\n if (namePattern) console.log(` Filtering by name pattern: ${namePattern}`);\n console.log(\"\");\n\n // 1. Trigger test run\n const queryParams = new URLSearchParams();\n if (tag) queryParams.set(\"tag\", tag);\n if (namePattern) queryParams.set(\"namePattern\", namePattern);\n\n const triggerUrl = `${apiUrl}/workflows/test-runs${queryParams.toString() ? `?${queryParams}` : \"\"}`;\n\n let triggerRes: Response;\n try {\n triggerRes = await fetch(triggerUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to API: ${err}`);\n process.exit(1);\n }\n\n if (!triggerRes.ok) {\n const errorText = await triggerRes.text();\n console.error(`Failed to start tests: ${triggerRes.status}`);\n console.error(errorText);\n process.exit(1);\n }\n\n const triggerData = (await triggerRes.json()) as TriggerResponse;\n if (!triggerData.ok || !triggerData.suiteId) {\n console.error(`Failed to start tests: ${triggerData.error ?? \"Unknown error\"}`);\n process.exit(1);\n }\n\n const { suiteId, jobId, appUrl } = triggerData;\n if (verbose) {\n console.log(`Suite ID: ${suiteId}`);\n console.log(`Job ID: ${jobId}`);\n console.log(\"\");\n }\n\n // 2. Subscribe to SSE stream\n const streamUrl = `${apiUrl}/workflows/test-runs/stream?suiteId=${suiteId}`;\n\n let streamRes: Response;\n try {\n streamRes = await fetch(streamUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"text/event-stream\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to event stream: ${err}`);\n process.exit(1);\n }\n\n if (!streamRes.ok || !streamRes.body) {\n console.error(`Failed to connect to event stream: ${streamRes.status}`);\n process.exit(1);\n }\n\n // Track state\n let exitCode = 0;\n let hasCompleted = false;\n const workflowNames = new Map<string, string>();\n const failedTests: FailedTest[] = [];\n let totalWorkflows = 0;\n let completedWorkflows = 0;\n let failedWorkflows = 0;\n let successfulWorkflows = 0;\n\n // 3. Parse SSE events\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as\n | WorkflowTestEvent\n | WorkflowTestSuiteEvent\n | { error?: string };\n\n if (verbose) {\n console.log(`[${event.event}] ${JSON.stringify(data)}`);\n }\n\n if (event.event === \"workflow-test\") {\n const testEvent = data as WorkflowTestEvent;\n const { status, workflowId, message, errorMessage } = testEvent;\n const name = workflowNames.get(workflowId) || message?.replace(/^Flow \"(.+)\" .*$/, \"$1\") || workflowId;\n\n if (message?.startsWith('Flow \"')) {\n const match = message.match(/^Flow \"(.+?)\" /);\n if (match) workflowNames.set(workflowId, match[1]);\n }\n\n if (!verbose) {\n if (status === \"success\") {\n console.log(` \\u2713 ${name}`);\n } else if (status === \"failed\") {\n console.log(` \\u2717 ${name}`);\n if (errorMessage) {\n console.log(` Error: ${errorMessage.slice(0, 200)}`);\n }\n failedTests.push({ name, testRunId: testEvent.testRunId });\n exitCode = 1;\n } else if (status === \"running\") {\n // Don't log running status in non-verbose mode\n } else if (status === \"waiting\") {\n console.log(` \\u23F3 ${name} (waiting for scheduled time)`);\n }\n }\n }\n\n if (event.event === \"workflow-test-suite\") {\n const suiteEvent = data as WorkflowTestSuiteEvent;\n totalWorkflows = suiteEvent.totalWorkflows;\n completedWorkflows = suiteEvent.completedWorkflows;\n failedWorkflows = suiteEvent.failedWorkflows;\n successfulWorkflows = suiteEvent.successfulWorkflows;\n\n if (suiteEvent.status === \"completed\") {\n hasCompleted = true;\n }\n }\n\n if (event.event === \"error\") {\n const errorData = data as { error?: string };\n console.error(`Stream error: ${errorData.error ?? \"Unknown error\"}`);\n exitCode = 1;\n }\n } catch {\n // Ignore parse errors for keepalive, etc.\n }\n },\n });\n\n const reader = streamRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (!hasCompleted) {\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 // 4. Print summary\n console.log(\"\");\n console.log(\"─\".repeat(50));\n\n if (totalWorkflows === 0) {\n console.log(\"No workflows found matching the filter criteria.\");\n process.exit(0);\n }\n\n const passRate = totalWorkflows > 0 ? Math.round((successfulWorkflows / totalWorkflows) * 100) : 0;\n\n if (failedWorkflows > 0) {\n console.log(`FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`);\n exitCode = 1;\n } else {\n console.log(`PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`);\n }\n\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n if (waitingWorkflows > 0) {\n console.log(`Note: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`);\n }\n\n const failedSection = formatFailedTests(failedTests, appUrl);\n if (failedSection) {\n console.log(failedSection);\n }\n\n process.exit(exitCode);\n}\n","/**\n * CLI Debug Session Generator\n *\n * Creates a debug login token for browser-based debugging with Playwright.\n * Requires superadmin authentication.\n *\n * Usage:\n * canary debug-session [--env dev|prod|local] [--api-url <url>]\n *\n * Outputs the login URL that can be used with Playwright to authenticate\n * as the debug agent user for read-only browser access.\n */\n\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { resolveConfig, hasFlag } from \"./auth.js\";\n\ntype DebugSessionResponse = {\n ok: boolean;\n loginUrl?: string;\n expiresAt?: string;\n error?: string;\n message?: string;\n};\n\nasync function writeDebugSession(loginUrl: string, expiresAt: string, apiUrl: string) {\n const dir = path.join(os.homedir(), \".config\", \"canary-cli\");\n const filePath = path.join(dir, \"debug-session.json\");\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n await fs.writeFile(\n filePath,\n JSON.stringify({ loginUrl, expiresAt, apiUrl, createdAt: new Date().toISOString() }, null, 2),\n { encoding: \"utf8\", mode: 0o600 }\n );\n return filePath;\n}\n\nexport async function runDebugSession(argv: string[]): Promise<void> {\n const { apiUrl, token } = await resolveConfig(argv);\n const jsonOutput = hasFlag(argv, \"--json\");\n\n try {\n const res = await fetch(`${apiUrl}/auth/debug-session/create`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n // Handle HTTP errors before parsing JSON\n if (!res.ok) {\n const text = await res.text();\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Your session may have expired.\");\n console.error(\"Run: canary login\");\n process.exit(1);\n }\n\n if (res.status === 403) {\n console.error(\"Error: Forbidden. Debug session creation requires superadmin access.\");\n process.exit(1);\n }\n\n if (res.status === 404) {\n console.error(\n \"Error: Endpoint not found. The debug-session feature may not be deployed to this environment.\"\n );\n process.exit(1);\n }\n\n // Try to parse error as JSON, fallback to raw text\n try {\n const errorJson = JSON.parse(text) as { error?: string; message?: string };\n console.error(`Error: ${errorJson.message ?? errorJson.error ?? text}`);\n } catch {\n console.error(`Error (${res.status}): ${text || res.statusText}`);\n }\n process.exit(1);\n }\n\n const json = (await res.json()) as DebugSessionResponse;\n\n if (!json.ok || !json.loginUrl) {\n console.error(`Error: ${json.message ?? json.error ?? \"Failed to create debug session\"}`);\n process.exit(1);\n }\n\n // Save session info\n const filePath = await writeDebugSession(json.loginUrl, json.expiresAt ?? \"\", apiUrl);\n\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n {\n loginUrl: json.loginUrl,\n expiresAt: json.expiresAt,\n sessionFile: filePath,\n },\n null,\n 2\n )\n );\n } else {\n console.log(\"Debug session created successfully.\");\n console.log(\"\");\n console.log(`Login URL: ${json.loginUrl}`);\n console.log(`Expires: ${json.expiresAt}`);\n console.log(`Session saved to: ${filePath}`);\n console.log(\"\");\n console.log(\"Use this URL with Playwright to authenticate as the debug agent.\");\n console.log(\"The token is single-use and expires in 5 minutes.\");\n }\n } catch (err) {\n console.error(`Failed to create debug session: ${err}`);\n process.exit(1);\n }\n}\n","/**\n * JWT payload decoder for CLI superadmin detection.\n *\n * Decodes the payload section of a JWT locally (no signature verification,\n * no network calls). Used to conditionally show superadmin CLI commands.\n *\n * @module\n */\n\n/**\n * Decode the payload (second segment) of a JWT without verifying the signature.\n * Returns the parsed JSON object, or `null` if the token is malformed.\n */\nexport function decodeJwtPayload(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const base64 = parts[1]!.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = Buffer.from(base64, \"base64\").toString(\"utf8\");\n const payload: unknown = JSON.parse(json);\n\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) {\n return null;\n }\n return payload as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Returns `true` when the JWT's `is_superadmin` claim is exactly `true`.\n * Returns `false` for any invalid, missing, or non-superadmin token.\n */\nexport function isSuperadminToken(token: string | null | undefined): boolean {\n if (!token) return false;\n const payload = decodeJwtPayload(token);\n return payload?.is_superadmin === true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAAA,kBAAiB;AAC1B,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,cAAa;AACpB,OAAOC,WAAU;AACjB,SAAS,iBAAAC,gBAAe,iBAAAC,sBAAqB;;;ACJ7C,SAAS,iBAAiB;AAC1B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAEvB,SAAS,cAAc;AAC5B,MAAI;AACF,WAAO,cAAc,YAAY,GAAG;AAAA,EACtC,QAAQ;AACN,QAAI;AACF,aAAO,cAAc,QAAQ,IAAI,CAAC;AAAA,IACpC,QAAQ;AAEN,aAAO,OAAO,cAAY,cAAe,YAAkB,cAAc,GAAG;AAAA,IAC9E;AAAA,EACF;AACF;AAEO,SAAS,cAAcC,cAAmE;AAC/F,QAAM,EAAE,KAAK,QAAQ,IAAI,eAAe;AACxC,QAAM,iBAAiB,OAAO,YAAY,YAAY,WAAW;AAEjE,MAAI,kBAAkBA,gBAAe,GAAG,WAAWA,YAAW,GAAG;AAC/D,WAAO,EAAE,WAAW,KAAK,aAAa,YAAY,cAAcA,YAAW,EAAE,IAAI,GAAG;AAAA,EACtF;AAEA,MAAIA,cAAa;AACf,YAAQ,KAAK,6EAA6E;AAAA,EAC5F;AAEA,SAAO,EAAE,WAAW,IAAI;AAC1B;AAEO,SAAS,iBAAoD;AAClE,QAAM,aAAa,sBAAsB;AAGzC,MAAI;AACJ,MAAI;AAEJ,aAAW,OAAO,YAAY;AAC5B,UAAM,UAAU,aAAa,GAAG;AAChC,QAAI,CAAC,QAAS;AACd,UAAM,UAAU,EAAE,KAAK,QAAQ;AAC/B,QAAI,WAAW,MAAM,CAAC,UAAU;AAC9B,iBAAW;AAAA,IACb;AACA,QAAI,CAAC,QAAQ,WAAW,KAAK,WAAW,IAAI;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,SAAU,QAAO;AACrB,MAAI,KAAM,QAAO;AAGjB,SAAO,EAAE,KAAK,WAAW,CAAC,KAAK,OAAO;AACxC;AAEO,SAAS,wBAAkC;AAChD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,OAAO,CAAC,UAAmB;AAC/B,QAAI,CAAC,MAAO;AACZ,QAAI,KAAK,IAAI,KAAK,EAAG;AACrB,SAAK,IAAI,KAAK;AAAA,EAChB;AAEA,QAAM,QAAQ,KAAK,SAAS,QAAQ,QAAQ,EAAE,SAAS,KAAK;AAE5D,OAAK,QAAQ,IAAI,eAAe;AAChC,OAAK,QAAQ,SAAY,QAAQ,QAAQ;AACzC,OAAK,MAAM;AAGX,MAAI;AACF,UAAM,QAAQ,UAAU,SAAS,CAAC,MAAM,MAAM,GAAG,EAAE,UAAU,QAAQ,CAAC;AACtE,UAAM,QACF,SAAS,EACV,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,QAAQ,CAAC,SAAS,KAAK,IAAI,CAAC;AAAA,EACjC,QAAQ;AAAA,EAER;AAGA,QAAM,SAAS,QAAQ,IAAI,YAAY,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,MAAM,IAAI;AAChG,MAAI,QAAQ;AACV,UAAM,cAAc,KAAK,KAAK,QAAQ,YAAY,MAAM;AACxD,QAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,UAAI;AACF,cAAM,WAAW,GAAG,YAAY,WAAW;AAC3C,iBACG,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,CAAE,EAC/B,QAAQ,CAAC,MAAM,KAAK,KAAK,KAAK,aAAa,GAAG,OAAO,MAAM,CAAC,CAAC;AAAA,MAClE,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,aAAa,KAAiC;AAC5D,MAAI;AACF,UAAM,SAAS,UAAU,KAAK,CAAC,IAAI,GAAG,EAAE,UAAU,QAAQ,CAAC;AAC3D,UAAM,UAAU,OAAO,UAAU,OAAO,UAAU,IAAI,SAAS,EAAE,KAAK;AACtE,UAAM,QAAQ,OAAO,MAAM,SAAS;AACpC,QAAI,MAAO,QAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EACnC,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;ACnHA,SAAS,aAAa;AACtB,OAAOC,SAAQ;AACf,OAAO,QAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAmE9B,eAAsB,IAAI,UAAsB,CAAC,GAAuB;AACtE,QAAM,MAAM,QAAQ,eAAe,QAAQ,IAAI;AAC/C,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAMC,aAAY,YAAY;AAC9B,QAAM,gBAAgBA,WAAU,QAAQ,sBAAsB;AAC9D,QAAMC,WAAUC,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC3D,QAAMC,eAAcD,MAAK,KAAKD,UAAS,UAAU,YAAY;AAC7D,QAAM,EAAE,WAAW,YAAY,IAAI,cAAcE,YAAW;AAE5D,QAAM,EAAE,gBAAgB,cAAc,aAAa,IAAI,oBAAoB,GAAG;AAC9E,QAAM,WAAW,kBAAkB,QAAQ,UAAU,cAAc;AACnE,QAAM,OAAO,UAAU;AAAA,IACrB,SAAS,QAAQ;AAAA,IACjB,YAAY,QAAQ;AAAA,IACpB,SAAS,QAAQ;AAAA,IACjB;AAAA,EACF,CAAC;AAED,QAAM,cACJ,QAAQ,IAAI,gBAAgB,cACxB,GAAG,QAAQ,IAAI,YAAY,IAAI,WAAW,KAC1C,eAAe,QAAQ,IAAI;AAEjC,QAAM,MAAM,SAAS;AAAA,IACnB,MAAM,QAAQ;AAAA,IACd,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,YAAY,MAAM,gBAAgB;AAAA,IACtC,KAAK,QAAQ,WAAW;AAAA,IACxB,MAAM,CAAC,eAAe,GAAG,IAAI;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,QAAQ;AAAA,EACrB,CAAC;AAED,QAAM,UAAU,UAAU,gBAAgB,cAAc,UAAU,UAAU;AAE5E,SAAO;AAAA,IACL,IAAI,UAAU,aAAa;AAAA,IAC3B,UAAU,UAAU;AAAA,IACpB;AAAA,IACA;AAAA,IACA,WAAW,UAAU;AAAA,IACrB,OAAO,UAAU;AAAA,EACnB;AACF;AAEA,SAAS,UAAU,MAKN;AACX,QAAM,OAAO,CAAC,MAAM;AAEpB,MAAI,KAAK,SAAS;AAChB,UAAM,OAAO,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,UAAU,CAAC,KAAK,OAAO;AACvE,SAAK,KAAK,GAAG,IAAI;AAAA,EACnB;AAEA,MAAI,KAAK,YAAY;AACnB,SAAK,KAAK,YAAY,KAAK,UAAU;AAAA,EACvC;AAEA,OAAK,KAAK,cAAc,KAAK,QAAQ;AAErC,MAAI,KAAK,SAAS,QAAQ;AACxB,SAAK,KAAK,GAAG,KAAK,OAAO;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,WAAmC,gBAAgC;AAC5F,MAAI,cAAc,OAAQ,QAAO,QAAQ,cAAc;AACvD,MAAI,aAAa,cAAc,UAAW,QAAO;AAEjD,SAAO,aAAa,cAAc;AACpC;AAEA,SAAS,oBAAoB,KAAqF;AAChH,QAAM,MAAMC,IAAG,YAAYF,MAAK,KAAK,GAAG,OAAO,GAAG,aAAa,CAAC;AAChE,QAAM,iBAAiBA,MAAK,KAAK,KAAK,aAAa;AACnD,QAAM,eAAeA,MAAK,KAAK,KAAK,uBAAuB;AAC3D,QAAM,eAAeA,MAAK,KAAK,KAAK,gBAAgB,WAAW;AAC/D,SAAO,EAAE,gBAAgB,cAAc,cAAc,IAAI;AAC3D;AAEA,SAAS,SAAS,QAMI;AACpB,QAAM,UAAU,OAAO,WAAW,CAAC;AACnC,QAAM,MAAyB;AAAA,IAC7B,GAAG,OAAO;AAAA,IACV,gBAAgB,OAAO,KAAK,kBAAkB;AAAA,IAC9C,eAAe;AAAA,IACf,kBAAkB,OAAO;AAAA,IACzB,GAAI,OAAO,cAAc,EAAE,cAAc,OAAO,YAAY,IAAI,CAAC;AAAA,IACjE,GAAI,QAAQ,SAAS,EAAE,YAAY,QAAQ,OAAO,IAAI,CAAC;AAAA,IACvD,GAAI,QAAQ,WAAW,EAAE,aAAa,QAAQ,SAAS,IAAI,CAAC;AAAA,IAC5D,GAAI,QAAQ,QAAQ,EAAE,UAAU,QAAQ,MAAM,IAAI,CAAC;AAAA,IACnD,GAAI,QAAQ,YAAY,EAAE,eAAe,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC;AAAA,IACxE,GAAI,QAAQ,aAAa,EAAE,oBAAoB,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC;AAAA,IAC/E,GAAI,QAAQ,SAAS,EAAE,eAAe,IAAI,IAAI,CAAC;AAAA,IAC/C,GAAI,QAAQ,SAAS,EAAE,gBAAgB,IAAI,IAAI,CAAC;AAAA,IAChD,GAAI,QAAQ,WAAW,EAAE,kBAAkB,IAAI,IAAI,CAAC;AAAA,IACpD,GAAI,QAAQ,QAAQ,EAAE,cAAc,IAAI,IAAI,CAAC;AAAA,IAC7C,GAAI,QAAQ,WAAW,EAAE,kBAAkB,IAAI,IAAI,CAAC;AAAA,IACpD,GAAI,QAAQ,kBAAkB,QAAQ,EAAE,uBAAuB,IAAI,IAAI,CAAC;AAAA,IACxE,GAAI,QAAQ,eAAe,EAAE,uBAAuB,IAAI,IAAI,CAAC;AAAA,IAC7D,GAAI,QAAQ,kBAAkB,EAAE,0BAA0B,OAAO,QAAQ,eAAe,EAAE,IAAI,CAAC;AAAA,IAC/F,GAAG,OAAO;AAAA,EACZ;AACA,SAAO;AACT;AAEA,eAAe,gBAAgB,MAOuD;AACpF,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,QAAQ,MAAM,KAAK,KAAK,KAAK,MAAM;AAAA,MACvC,KAAK,KAAK;AAAA,MACV,KAAK,KAAK;AAAA,MACV,OAAO,KAAK,UAAU,YAAY,YAAY,CAAC,UAAU,QAAQ,MAAM;AAAA,IACzE,CAAC;AAED,QAAI;AACJ,QAAI,SAAS;AACb,QAAI;AAEJ,QAAI,KAAK,UAAU,QAAQ;AACzB,YAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU;AAClC,kBAAU,MAAM,SAAS;AAAA,MAC3B,CAAC;AACD,YAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU;AAClC,kBAAU,MAAM,SAAS;AAAA,MAC3B,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,aAAa,KAAK,YAAY,GAAG;AACxC,cAAQ,WAAW,MAAM;AACvB,gBAAQ,IAAI,MAAM,8BAA8B,KAAK,SAAS,IAAI;AAClE,cAAM,KAAK,SAAS;AAAA,MACtB,GAAG,KAAK,SAAS;AAAA,IACnB;AAEA,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,UAAI,MAAO,cAAa,KAAK;AAC7B,cAAQ,EAAE,UAAU,QAAQ,GAAG,QAAQ,UAAU,QAAW,YAAY,KAAK,IAAI,IAAI,SAAS,MAAM,CAAC;AAAA,IACvG,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,UAAU,gBAAwB,cAAsB,YAA0C;AACzG,QAAM,OAAO;AAAA,IACX,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT;AAAA,EACF;AAEA,QAAM,aAAa,eAAe,cAAc;AAChD,MAAI,YAAY;AACd,UAAM,SAAS,WAAW,UAAU;AACpC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO;AACtB,SAAK,aAAa,WAAW,YAAY;AAAA,EAC3C;AAEA,QAAM,SAAS,YAAY,YAAY;AACvC,MAAI,QAAQ;AACV,WAAO,EAAE,GAAG,MAAM,OAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAEA,SAAS,eAAe,YAA4C;AAClE,MAAI;AACF,QAAIE,IAAG,WAAW,UAAU,GAAG;AAC7B,YAAM,MAAMA,IAAG,aAAa,YAAY,OAAO;AAC/C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEA,SAAS,WAAW,QAMlB;AACA,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,QAAM,aAAa,CAAC,UAAsB;AACxC,QAAI,CAAC,MAAO;AACZ,UAAM,OAAO,QAAQ,CAAC,SAAS;AAC7B,eAAS;AACT,YAAM,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM;AACjD,YAAM,YAAY,SAAS,SAAS,QAAQ,KAAK,SAAS,SAAS,aAAa;AAChF,YAAM,YAAY,SAAS,SAAS,QAAQ;AAC5C,YAAM,cAAc,SAAS,SAAS,UAAU;AAChD,YAAM,aAAa,SAAS,MAAM,CAAC,MAAM,MAAM,SAAS;AAExD,UAAI,YAAY;AACd,mBAAW;AAAA,MACb,YAAY,aAAa,gBAAgB,WAAW;AAClD,iBAAS;AAAA,MACX,WAAW,aAAa,aAAa;AACnC,kBAAU;AAAA,MACZ,WAAW,aAAa,SAAS,SAAS,GAAG;AAC3C,iBAAS;AAAA,MACX,WAAW,WAAW;AACpB,kBAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAED,UAAM,QAAQ,QAAQ,UAAU;AAAA,EAClC;AAEA,SAAO,QAAQ,QAAQ,UAAU;AAEjC,SAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO,QAAQ;AACjD;AAEA,SAAS,YAAY,cAA0C;AAC7D,MAAI;AACF,QAAI,CAACA,IAAG,WAAW,YAAY,EAAG,QAAO;AACzC,UAAM,MAAMA,IAAG,aAAa,cAAc,OAAO,EAAE,KAAK;AACxD,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAI,SAAS;AACb,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,YAAI,OAAO,WAAW,KAAM,WAAU;AAAA,MACxC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACtVA,OAAOC,cAAa;AACpB,OAAO,cAAc;AACrB,SAAS,SAAAC,cAAa;AAqCtB,SAAS,kBAAkB,MAAyB;AAClD,SAAO,CAAC,KAAK,SAAS,WAAW;AACnC;AAEA,SAAS,QAAQ,KAAa;AAC5B,QAAM,WAAWC,SAAQ;AACzB,MAAI,aAAa,UAAU;AACzB,IAAAC,OAAM,QAAQ,CAAC,GAAG,GAAG,EAAE,OAAO,SAAS,CAAC;AACxC;AAAA,EACF;AACA,MAAI,aAAa,SAAS;AACxB,IAAAA,OAAM,OAAO,CAAC,MAAM,SAAS,IAAI,GAAG,GAAG,EAAE,OAAO,SAAS,CAAC;AAC1D;AAAA,EACF;AACA,EAAAA,OAAM,YAAY,CAAC,GAAG,GAAG,EAAE,OAAO,SAAS,CAAC;AAC9C;AAEA,SAAS,aAAa,UAAmC;AACvD,QAAM,KAAK,SAAS,gBAAgB,EAAE,OAAOD,SAAQ,OAAO,QAAQA,SAAQ,OAAO,CAAC;AACpF,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,cAAQ,OAAO,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,UAAU,QAAgB,OAA6C;AACpF,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,mBAAmB;AAAA,MAClD,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC9C,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,UAAU,QAAgB,OAAe,OAA2C;AACjG,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,yBAAyB;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,UAAU,KAAK;AAAA,MAC9B,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,EAChC,CAAC;AACD,SAAQ,MAAM,IAAI,KAAK;AACzB;AAEA,eAAsB,SAAS,MAAgB;AAC7C,QAAM,MAAM,YAAY,MAAM,OAAO;AACrC,QAAM,UAAU,MAAM,SAAS,GAAG,IAAI;AAEtC,MAAI,OAAO,CAAC,SAAS;AACnB,YAAQ,MAAM,wBAAwB,GAAG,EAAE;AAC3C,YAAQ,MAAM,sCAAsC;AACpD,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SACJ,YAAY,MAAM,WAAW,KAC7B,SAAS,OACTA,SAAQ,IAAI,kBACZ;AACF,QAAM,SACJ,YAAY,MAAM,WAAW,KAC7B,SAAS,OACTA,SAAQ,IAAI,kBACZ;AAEF,QAAM,UAAU,YAAY,MAAM,OAAO;AAEzC,QAAM,WAAW,MAAM,MAAM,GAAG,MAAM,oBAAoB;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;AAAA,EACjC,CAAC;AAED,QAAM,YAAa,MAAM,SAAS,KAAK;AACvC,MAAI,CAAC,SAAS,MAAM,CAAC,UAAU,MAAM,CAAC,UAAU,cAAc,CAAC,UAAU,UAAU;AACjF,YAAQ,MAAM,sBAAsB,UAAU,SAAS,SAAS,UAAU;AAC1E,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,iBAAiB;AAC7B,UAAQ,IAAI,cAAc,UAAU,QAAQ,EAAE;AAC9C,MAAI,UAAU,iBAAiB;AAC7B,YAAQ,IAAI,SAAS,UAAU,eAAe,EAAE;AAChD,QAAI,kBAAkB,IAAI,GAAG;AAC3B,UAAI;AACF,gBAAQ,UAAU,eAAe;AAAA,MACnC,QAAQ;AACN,gBAAQ,IAAI,qEAAqE;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,UAAU,mBAAmB,KAAK;AACtD,QAAM,YAAY,UAAU,YAAY,IAAI,KAAK,UAAU,SAAS,EAAE,QAAQ,IAAI;AAElF,MAAI;AACJ,MAAI;AAEJ,SAAO,MAAM;AACX,QAAI,aAAa,KAAK,IAAI,IAAI,WAAW;AACvC,cAAQ,MAAM,qBAAqB;AACnC,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,UAAU,CAAC;AAE9D,UAAM,UAAU,MAAM,MAAM,GAAG,MAAM,mBAAmB;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,YAAY,UAAU,WAAW,CAAC;AAAA,IAC3D,CAAC;AAED,UAAM,WAAY,MAAM,QAAQ,KAAK;AACrC,QAAI,CAAC,QAAQ,MAAM,CAAC,SAAS,IAAI;AAC/B,cAAQ,MAAM,qBAAqB,SAAS,SAAS,QAAQ,UAAU;AACvE,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,SAAS,WAAW,cAAc,SAAS,aAAa;AAC1D,cAAQ,SAAS;AACjB,qBAAe,SAAS;AACxB;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,YAAY;AAClC,cAAQ,MAAM,iBAAiB;AAC/B,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,SAAS,WAAW,WAAW;AACjC,cAAQ,MAAM,gBAAgB;AAC9B,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,UAAU,QAAQ,KAAK;AAC9C,QAAM,OAAO,UAAU,iBAAiB,CAAC;AAEzC,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI;AAEJ,MAAI,KAAK,UAAU,GAAG;AAEpB,mBAAe,KAAK,CAAC,GAAG;AAAA,EAC1B,OAAO;AAEL,QAAI;AAEJ,QAAI,SAAS;AAEX,oBAAc,KAAK;AAAA,QACjB,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,QAAQ,YAAY,KAAK,EAAE,OAAO;AAAA,MACpE;AACA,UAAI,CAAC,aAAa;AAChB,gBAAQ,MAAM,iBAAiB,OAAO,8BAA8B;AACpE,mBAAW,KAAK,MAAM;AACpB,kBAAQ,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,EAAE,GAAG;AAAA,QACzC;AACA,QAAAA,SAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,WAAWA,SAAQ,MAAM,OAAO;AAE9B,cAAQ,IAAI,qDAAqD;AACjE,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,SAAS,KAAK,CAAC,EAAE,OAAO,eAAe,eAAe;AAC5D,gBAAQ,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE;AAAA,MACpD;AAEA,YAAM,SAAS,MAAM,aAAa;AAAA,YAAe,KAAK,MAAM,KAAK;AACjE,YAAM,MAAM,SAAS,QAAQ,EAAE,IAAI;AACnC,UAAI,MAAM,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ;AAC/C,gBAAQ,MAAM,oBAAoB;AAClC,QAAAA,SAAQ,KAAK,CAAC;AAAA,MAChB;AACA,oBAAc,KAAK,GAAG;AAAA,IACxB,OAAO;AAEL,YAAM,aAAa,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AACzD,cAAQ;AAAA,QACN,mFAAmF,YAAY,QAAQ,YAAY;AAAA,MACrH;AACA,cAAQ,IAAI,0DAA0D;AACtE,oBAAc;AAAA,IAChB;AAEA,QAAI,eAAe,YAAY,OAAO,cAAc;AAElD,YAAM,YAAY,MAAM,UAAU,QAAQ,OAAO,YAAY,EAAE;AAC/D,UAAI,CAAC,UAAU,MAAM,CAAC,UAAU,aAAa;AAC3C,gBAAQ,MAAM,kCAAkC,UAAU,SAAS,eAAe;AAClF,QAAAA,SAAQ,KAAK,CAAC;AAAA,MAChB;AACA,mBAAa,UAAU;AACvB,mBAAa,UAAU;AACvB,qBAAe,UAAU;AAAA,IAC3B,WAAW,aAAa;AACtB,qBAAe,YAAY;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,aAAa,GAAG,IAAI;AAC9C,QAAM,WAAW,MAAM,SAAS,EAAE,OAAO,YAAY,QAAQ,OAAO,YAAY,SAAS,aAAa,GAAG,WAAW;AACpH,QAAM,cAAc,eAAe,OAAO,YAAY,KAAK;AAC3D,QAAM,eAAe,cAAc,cAAc,WAAW,MAAM;AAClE,UAAQ,IAAI,mBAAmB,WAAW,GAAG,YAAY,oBAAoB,QAAQ,EAAE;AACvF,UAAQ,IAAI,uDAAuD;AACrE;;;AC9PA,OAAOE,cAAa;AAUpB,eAAsB,QAAQ,MAAgB;AAC5C,QAAM,QAAQC,SAAQ,IAAI,oBAAqB,MAAM,gBAAgB;AACrE,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,kCAAkC;AAChD,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAO,MAAM,eAAe;AAClC,QAAM,SACJA,SAAQ,IAAI,kBAAkB,MAAM,UAAU;AAEhD,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,mBAAmB;AAAA,IAClD,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,YAAQ,MAAM,uEAAuE;AACrF,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,MAAI,CAAC,KAAK,MAAM,CAAC,KAAK,eAAe;AACnC,YAAQ,MAAM,kCAAkC,KAAK,SAAS,eAAe;AAC7E,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,eAAe,MAAM,SAAS,KAAK;AAEzC,UAAQ,IAAI,kBAAkB;AAC9B,aAAW,OAAO,KAAK,eAAe;AACpC,UAAM,SAAS,IAAI,OAAO,eAAe,OAAO;AAChD,YAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;AAAA,EACpD;AAEA,UAAQ,IAAI,4BAA4B;AACxC,UAAQ,IAAI,sCAAsC;AACpD;;;AC9CA,OAAOC,cAAa;AAKpB,SAASC,aAAY,MAAgB,KAAiC;AACpE,QAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,MAAI,UAAU,GAAI,QAAO;AACzB,SAAO,KAAK,QAAQ,CAAC;AACvB;AAEA,eAAsB,gBAAgB,MAAgB;AACpD,QAAM,SAASA,aAAY,MAAM,WAAW,KAAKC,SAAQ,IAAI,kBAAkB;AAC/E,QAAM,QACJD,aAAY,MAAM,SAAS,KAC3BC,SAAQ,IAAI,oBACX,MAAM,gBAAgB;AAEzB,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,kEAAkE;AAChF,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAUD,aAAY,MAAM,QAAQ,KAAKC,SAAQ,IAAI;AAC3D,QAAM,YAAYD,aAAY,MAAM,cAAc;AAClD,QAAM,QAAQA,aAAY,MAAM,SAAS;AACzC,QAAM,cAAcA,aAAY,MAAM,WAAW;AACjD,QAAM,WAAWA,aAAY,MAAM,aAAa;AAEhD,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,YAAQ,MAAM,gCAAgC;AAC9C,IAAAC,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,YAAY;AAChB,MAAI,KAAuB;AAE3B,MAAI,CAAC,aAAa,SAAS;AACzB,UAAM,OAAO,OAAO,OAAO;AAC3B,QAAI,OAAO,MAAM,IAAI,KAAK,QAAQ,GAAG;AACnC,cAAQ,MAAM,sBAAsB;AACpC,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,MAAM,aAAa,EAAE,QAAQ,OAAO,KAAK,CAAC;AACzD,gBAAY,OAAO;AAEnB,SAAK,cAAc;AAAA,MACjB;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO;AAAA,MACd;AAAA,MACA,SAAS,MAAM;AACb,gBAAQ,IAAI,qBAAqB,aAAa,OAAO,QAAQ,EAAE;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,MAAM,8BAA8B;AAC5C,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAMC,OAAM,MAAM,eAAe;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AAED,UAAQ,IAAI,sBAAsBA,KAAI,KAAK,EAAE;AAC7C,MAAIA,KAAI,UAAU;AAChB,YAAQ,IAAI,UAAUA,KAAI,QAAQ,EAAE;AAAA,EACtC;AAEA,MAAI,IAAI;AACN,YAAQ,IAAI,sCAAsC;AAClD,IAAAD,SAAQ,GAAG,UAAU,MAAM;AACzB,UAAI,MAAM;AACV,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AACD,UAAM,IAAI,QAAc,MAAM,MAAS;AAAA,EACzC;AACF;;;ACpEA,OAAOE,cAAa;AACpB,SAAS,oBAA6C;AA+CtD,SAASC,aAAY,MAAgB,KAAiC;AACpE,QAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,MAAI,UAAU,MAAM,SAAS,KAAK,SAAS,EAAG,QAAO;AACrD,SAAO,KAAK,QAAQ,CAAC;AACvB;AAEA,SAASC,SAAQ,SAAmB,OAA0B;AAC5D,SAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC;AACjD;AAiBA,SAAS,kBACP,aACA,QACe;AACf,MAAI,YAAY,WAAW,KAAK,CAAC,OAAQ,QAAO;AAEhD,QAAM,QAAQ,CAAC,IAAI,eAAe;AAClC,aAAW,KAAK,aAAa;AAC3B,UAAM,KAAK,YAAY,EAAE,IAAI,EAAE;AAC/B,UAAM,KAAK,OAAO,MAAM,eAAe,EAAE,SAAS,EAAE;AAAA,EACtD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AA6CA,eAAsB,cAAc,MAA+B;AACjE,QAAM,SACJC,aAAY,MAAM,WAAW,KAC7BC,SAAQ,IAAI,kBACZ;AAEF,QAAM,QACJD,aAAY,MAAM,SAAS,KAC3BC,SAAQ,IAAI,oBACX,MAAM,gBAAgB;AAEzB,QAAM,MAAMD,aAAY,MAAM,OAAO;AACrC,QAAM,cAAcA,aAAY,MAAM,gBAAgB;AACtD,QAAM,UAAUE,SAAQ,MAAM,aAAa,IAAI;AAE/C,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,4BAA4B;AAC1C,YAAQ,MAAM,EAAE;AAChB,YAAQ,MAAM,mDAAmD;AACjE,YAAQ,MAAM,gBAAgB;AAC9B,YAAQ,MAAM,EAAE;AAChB,YAAQ,MAAM,0DAA0D;AACxE,YAAQ,MAAM,yCAAyC;AACvD,IAAAD,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,mCAAmC;AAC/C,MAAI,IAAK,SAAQ,IAAI,uBAAuB,GAAG,EAAE;AACjD,MAAI,YAAa,SAAQ,IAAI,gCAAgC,WAAW,EAAE;AAC1E,UAAQ,IAAI,EAAE;AAGd,QAAM,cAAc,IAAI,gBAAgB;AACxC,MAAI,IAAK,aAAY,IAAI,OAAO,GAAG;AACnC,MAAI,YAAa,aAAY,IAAI,eAAe,WAAW;AAE3D,QAAM,aAAa,GAAG,MAAM,uBAAuB,YAAY,SAAS,IAAI,IAAI,WAAW,KAAK,EAAE;AAElG,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,MAAM,YAAY;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,6BAA6B,GAAG,EAAE;AAChD,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,WAAW,IAAI;AAClB,UAAM,YAAY,MAAM,WAAW,KAAK;AACxC,YAAQ,MAAM,0BAA0B,WAAW,MAAM,EAAE;AAC3D,YAAQ,MAAM,SAAS;AACvB,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAe,MAAM,WAAW,KAAK;AAC3C,MAAI,CAAC,YAAY,MAAM,CAAC,YAAY,SAAS;AAC3C,YAAQ,MAAM,0BAA0B,YAAY,SAAS,eAAe,EAAE;AAC9E,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,SAAS,OAAO,OAAO,IAAI;AACnC,MAAI,SAAS;AACX,YAAQ,IAAI,aAAa,OAAO,EAAE;AAClC,YAAQ,IAAI,WAAW,KAAK,EAAE;AAC9B,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,QAAM,YAAY,GAAG,MAAM,uCAAuC,OAAO;AAEzE,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,MAAM,WAAW;AAAA,MACjC,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,sCAAsC,GAAG,EAAE;AACzD,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,UAAU,MAAM,CAAC,UAAU,MAAM;AACpC,YAAQ,MAAM,sCAAsC,UAAU,MAAM,EAAE;AACtE,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,WAAW;AACf,MAAI,eAAe;AACnB,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,QAAM,cAA4B,CAAC;AACnC,MAAI,iBAAiB;AACrB,MAAI,qBAAqB;AACzB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAG1B,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS,CAAC,UAA8B;AACtC,UAAI,CAAC,MAAM,KAAM;AAEjB,UAAI;AACF,cAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAKlC,YAAI,SAAS;AACX,kBAAQ,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,QACxD;AAEA,YAAI,MAAM,UAAU,iBAAiB;AACnC,gBAAM,YAAY;AAClB,gBAAM,EAAE,QAAQ,YAAY,SAAS,aAAa,IAAI;AACtD,gBAAM,OAAO,cAAc,IAAI,UAAU,KAAK,SAAS,QAAQ,oBAAoB,IAAI,KAAK;AAE5F,cAAI,SAAS,WAAW,QAAQ,GAAG;AACjC,kBAAM,QAAQ,QAAQ,MAAM,gBAAgB;AAC5C,gBAAI,MAAO,eAAc,IAAI,YAAY,MAAM,CAAC,CAAC;AAAA,UACnD;AAEA,cAAI,CAAC,SAAS;AACZ,gBAAI,WAAW,WAAW;AACxB,sBAAQ,IAAI,YAAY,IAAI,EAAE;AAAA,YAChC,WAAW,WAAW,UAAU;AAC9B,sBAAQ,IAAI,YAAY,IAAI,EAAE;AAC9B,kBAAI,cAAc;AAChB,wBAAQ,IAAI,cAAc,aAAa,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,cACxD;AACA,0BAAY,KAAK,EAAE,MAAM,WAAW,UAAU,UAAU,CAAC;AACzD,yBAAW;AAAA,YACb,WAAW,WAAW,WAAW;AAAA,YAEjC,WAAW,WAAW,WAAW;AAC/B,sBAAQ,IAAI,YAAY,IAAI,+BAA+B;AAAA,YAC7D;AAAA,UACF;AAAA,QACF;AAEA,YAAI,MAAM,UAAU,uBAAuB;AACzC,gBAAM,aAAa;AACnB,2BAAiB,WAAW;AAC5B,+BAAqB,WAAW;AAChC,4BAAkB,WAAW;AAC7B,gCAAsB,WAAW;AAEjC,cAAI,WAAW,WAAW,aAAa;AACrC,2BAAe;AAAA,UACjB;AAAA,QACF;AAEA,YAAI,MAAM,UAAU,SAAS;AAC3B,gBAAM,YAAY;AAClB,kBAAQ,MAAM,iBAAiB,UAAU,SAAS,eAAe,EAAE;AACnE,qBAAW;AAAA,QACb;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,SAAS,UAAU,KAAK,UAAU;AACxC,QAAM,UAAU,IAAI,YAAY;AAEhC,MAAI;AACF,WAAO,CAAC,cAAc;AACpB,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,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAE1B,MAAI,mBAAmB,GAAG;AACxB,YAAQ,IAAI,kDAAkD;AAC9D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,iBAAiB,IAAI,KAAK,MAAO,sBAAsB,iBAAkB,GAAG,IAAI;AAEjG,MAAI,kBAAkB,GAAG;AACvB,YAAQ,IAAI,WAAW,eAAe,OAAO,cAAc,sBAAsB,QAAQ,cAAc;AACvG,eAAW;AAAA,EACb,OAAO;AACL,YAAQ,IAAI,WAAW,mBAAmB,OAAO,cAAc,mBAAmB;AAAA,EACpF;AAEA,QAAM,mBAAmB,iBAAiB;AAC1C,MAAI,mBAAmB,GAAG;AACxB,YAAQ,IAAI,SAAS,gBAAgB,sDAAsD;AAAA,EAC7F;AAEA,QAAM,gBAAgB,kBAAkB,aAAa,MAAM;AAC3D,MAAI,eAAe;AACjB,YAAQ,IAAI,aAAa;AAAA,EAC3B;AAEA,EAAAA,SAAQ,KAAK,QAAQ;AACvB;;;ACzVA,OAAOE,SAAQ;AACf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAOC,cAAa;AAWpB,eAAe,kBAAkB,UAAkB,WAAmB,QAAgB;AACpF,QAAM,MAAMC,MAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW,YAAY;AAC3D,QAAM,WAAWD,MAAK,KAAK,KAAK,oBAAoB;AACpD,QAAME,IAAG,MAAM,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACpD,QAAMA,IAAG;AAAA,IACP;AAAA,IACA,KAAK,UAAU,EAAE,UAAU,WAAW,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,GAAG,MAAM,CAAC;AAAA,IAC5F,EAAE,UAAU,QAAQ,MAAM,IAAM;AAAA,EAClC;AACA,SAAO;AACT;AAEA,eAAsB,gBAAgB,MAA+B;AACnE,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAClD,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,8BAA8B;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAGD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,UAAI,IAAI,WAAW,KAAK;AACtB,gBAAQ,MAAM,qDAAqD;AACnE,gBAAQ,MAAM,mBAAmB;AACjC,QAAAC,SAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,IAAI,WAAW,KAAK;AACtB,gBAAQ,MAAM,sEAAsE;AACpF,QAAAA,SAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,IAAI,WAAW,KAAK;AACtB,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,QAAAA,SAAQ,KAAK,CAAC;AAAA,MAChB;AAGA,UAAI;AACF,cAAM,YAAY,KAAK,MAAM,IAAI;AACjC,gBAAQ,MAAM,UAAU,UAAU,WAAW,UAAU,SAAS,IAAI,EAAE;AAAA,MACxE,QAAQ;AACN,gBAAQ,MAAM,UAAU,IAAI,MAAM,MAAM,QAAQ,IAAI,UAAU,EAAE;AAAA,MAClE;AACA,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAE7B,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,UAAU;AAC9B,cAAQ,MAAM,UAAU,KAAK,WAAW,KAAK,SAAS,gCAAgC,EAAE;AACxF,MAAAA,SAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,UAAM,WAAW,MAAM,kBAAkB,KAAK,UAAU,KAAK,aAAa,IAAI,MAAM;AAEpF,QAAI,YAAY;AACd,cAAQ;AAAA,QACN,KAAK;AAAA,UACH;AAAA,YACE,UAAU,KAAK;AAAA,YACf,WAAW,KAAK;AAAA,YAChB,aAAa;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,qCAAqC;AACjD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,cAAc,KAAK,QAAQ,EAAE;AACzC,cAAQ,IAAI,YAAY,KAAK,SAAS,EAAE;AACxC,cAAQ,IAAI,qBAAqB,QAAQ,EAAE;AAC3C,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,kEAAkE;AAC9E,cAAQ,IAAI,mDAAmD;AAAA,IACjE;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,mCAAmC,GAAG,EAAE;AACtD,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AC3GO,SAAS,iBAAiB,OAA+C;AAC9E,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,SAAS,MAAM,CAAC,EAAG,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,OAAO,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,MAAM;AAC1D,UAAM,UAAmB,KAAK,MAAM,IAAI;AAExC,QAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,GAAG;AAC7E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,kBAAkB,OAA2C;AAC3E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,iBAAiB,KAAK;AACtC,SAAO,SAAS,kBAAkB;AACpC;;;ARtBA,IAAMC,WAAUC,eAAc,YAAY,GAAG;AAC7C,IAAM,MAAMD,SAAQ,iBAAiB;AAGrC,IAAM,UAAU,MAAM,OAAO,mBAAO,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM;AAC1D,IAAM,mBAAmB,MAAM,OAAO,6BAAuB,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe;AAC5F,IAAM,oBAAoB,MAAM,OAAO,8BAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,gBAAgB;AAElF,IAAM,SAAS,EAAE,IAAe;AAGvC,IAAM,UACJ,OAAO,cAAc,cAAc,YAAYE,MAAK,QAAQC,eAAc,YAAY,GAAG,CAAC;AAC5F,IAAM,cAAcD,MAAK,KAAK,SAAS,UAAU,YAAY;AAC7D,IAAM,YAAY,YAAY;AAE9B,SAAS,mBAAmB,MAAgB;AAE1C,QAAM,gBAAgB,UAAU,QAAQ,sBAAsB;AAC9D,QAAM,EAAE,WAAW,YAAY,IAAI,cAAc,WAAW;AAE5D,QAAM,cACJE,SAAQ,IAAI,gBAAgB,cACxB,GAAGA,SAAQ,IAAI,YAAY,IAAI,WAAW,KAC1C,eAAeA,SAAQ,IAAI;AAEjC,QAAM,MAAM;AAAA,IACV,GAAGA,SAAQ;AAAA,IACX,gBAAgBA,SAAQ,IAAI,kBAAkB;AAAA,IAC9C,eAAe;AAAA,IACf,GAAI,cAAc,EAAE,cAAc,YAAY,IAAI,CAAC;AAAA,EACrD;AAEA,QAAM,SAASC,WAAU,WAAW,CAAC,eAAe,QAAQ,GAAG,IAAI,GAAG;AAAA,IACpE;AAAA,IACA,OAAO;AAAA,IACP,KAAKD,SAAQ,IAAI;AAAA,EACnB,CAAC;AAED,MAAI,OAAO,OAAO;AAChB,YAAQ,MAAM,uCAAuC,OAAO,KAAK;AACjE,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,EAAAA,SAAQ,KAAK,OAAO,UAAU,CAAC;AACjC;AAEA,SAAS,eAAe;AACtB,UAAQ,IAAI,WAAW,IAAI,OAAO,EAAE;AACtC;AAEA,SAAS,UAAU,EAAE,aAAa,GAA8B;AAC9D,QAAM,QAAkB;AAAA,IACtB,WAAW,IAAI,OAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAC9B;AAEA,SAAS,gBAAgB;AACvB,UAAQ;AAAA,IACN;AAAA,MACE,WAAW,IAAI,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAGA,IAAM,qBAAqB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAO3C,eAAe,sBAAwC;AACrD,QAAM,WAAWE,SAAQ,IAAI;AAC7B,MAAI,SAAU,QAAO,kBAAkB,QAAQ;AAE/C,QAAM,SAAS,MAAM,oBAAoB;AACzC,SAAO,OAAO,KAAK,CAAC,MAAM,kBAAkB,CAAC,CAAC;AAChD;AAEA,eAAsB,KAAK,MAAgB;AACzC,MAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,IAAI,GAAG;AACrD,iBAAa;AACb;AAAA,EACF;AAEA,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAC3B,QAAM,cAAc,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI;AAGjE,MAAI,gBAAgB,CAAC,WAAW,CAAC,mBAAmB,IAAI,OAAO,IAAI;AACjE,cAAU,EAAE,cAAc,MAAM,oBAAoB,EAAE,CAAC;AACvD;AAAA,EACF;AAEA,MAAI,CAAC,WAAW,YAAY,QAAQ;AAClC,cAAU,EAAE,cAAc,MAAM,oBAAoB,EAAE,CAAC;AACvD;AAAA,EACF;AAEA,MAAI,YAAY,WAAW;AACzB,iBAAa;AACb;AAAA,EACF;AAEA,MAAI,YAAY,QAAQ;AAEtB,QAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;AAClD,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,UAAU,GAAG;AAC7B,YAAM,aAAa,KAAK,OAAO,CAAC,QAAQ,QAAQ,UAAU;AAC1D,YAAM,cAAc,UAAU;AAC9B;AAAA,IACF;AACA,uBAAmB,IAAI;AACvB;AAAA,EACF;AAEA,MAAI,YAAY,aAAa;AAC3B,UAAM,aAAa,IAAI;AACvB;AAAA,EACF;AAEA,MAAI,YAAY,OAAO;AACrB,UAAM,gBAAgB,IAAI;AAC1B;AAAA,EACF;AAEA,MAAI,YAAY,OAAO;AACrB,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,OAAO,IAAI;AACjB;AAAA,EACF;AAEA,MAAI,YAAY,UAAU;AACxB,UAAM,UAAU,IAAI;AACpB;AAAA,EACF;AAEA,MAAI,YAAY,SAAS;AACvB,UAAM,SAAS,IAAI;AACnB;AAAA,EACF;AAEA,MAAI,YAAY,QAAQ;AACtB,UAAM,QAAQ,IAAI;AAClB;AAAA,EACF;AAEA,MAAI,YAAY,WAAW;AACzB,UAAM,kBAAkB,MAAM,iBAAiB;AAC/C,UAAM,gBAAgB,IAAI;AAC1B;AAAA,EACF;AAEA,MAAI,YAAY,SAAS;AACvB,UAAM,mBAAmB,MAAM,kBAAkB;AACjD,UAAM,iBAAiB,IAAI;AAC3B;AAAA,EACF;AAEA,MAAI,YAAY,iBAAiB;AAC/B,UAAM,gBAAgB,IAAI;AAC1B;AAAA,EACF;AAEA,MAAI,YAAY,QAAQ;AACtB,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,oBAAW;AAC5C,UAAM,QAAQ,IAAI;AAClB;AAAA,EACF;AAEA,MAAI,YAAY,SAAS;AACvB,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,qBAAY;AAC9C,UAAM,SAAS,IAAI;AACnB;AAAA,EACF;AAEA,MAAI,YAAY,WAAW;AACzB,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,uBAAc;AAClD,UAAM,WAAW,IAAI;AACrB;AAAA,EACF;AAEA,MAAI,YAAY,gBAAgB;AAC9B,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,4BAAmB;AAC3D,UAAM,eAAe,IAAI;AACzB;AAAA,EACF;AAEA,MAAI,YAAY,SAAS;AACvB,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,qBAAY;AAC9C,UAAM,SAAS,IAAI;AACnB;AAAA,EACF;AAEA,MAAI,YAAY,UAAU;AACxB,UAAM,EAAE,UAAU,IAAI,MAAM,OAAO,sBAAa;AAChD,UAAM,UAAU,IAAI;AACpB;AAAA,EACF;AAEA,UAAQ,IAAI,oBAAoB,OAAO,IAAI;AAC3C,YAAU,EAAE,cAAc,MAAM,oBAAoB,EAAE,CAAC;AACvD,EAAAA,SAAQ,KAAK,CAAC;AAChB;AAEA,IAAI,YAAY,QAAQC,eAAcD,SAAQ,KAAK,CAAC,CAAC,EAAE,MAAM;AAC3D,OAAK,KAAKA,SAAQ,KAAK,MAAM,CAAC,CAAC;AACjC;","names":["spawnSync","createRequire","process","path","fileURLToPath","pathToFileURL","preloadPath","fs","path","requireFn","baseDir","path","preloadPath","fs","process","spawn","process","spawn","process","process","process","getArgValue","process","run","process","getArgValue","hasFlag","getArgValue","process","hasFlag","fs","os","path","process","path","os","fs","process","require","createRequire","path","fileURLToPath","process","spawnSync","process","pathToFileURL"]}
|