@runcofactor/cli 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts-NKJEQ62J.js +186 -0
- package/dist/prompts-NKJEQ62J.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,21 @@ canary skill install issue-log-xref # auto-detect agent and install it
|
|
|
105
105
|
canary skill install issue-log-xref --agent codex # install to .codex/skills/
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
## Prompt Library
|
|
109
|
+
|
|
110
|
+
Curated, agent-agnostic starter prompts — common recipes for getting going with a coding agent. The library mixes **Cofactor's global prompts** with your **org's own prompts**, and is also browsable in the web app under **Agent Tools → Prompt Library**.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
canary prompts list # global + your org prompts
|
|
114
|
+
canary prompts get install-cli # print a prompt's markdown to stdout
|
|
115
|
+
canary prompts get install-cli --json
|
|
116
|
+
canary prompts create recipe.md --title "Set up CI" # share a prompt with your org
|
|
117
|
+
cat recipe.md | canary prompts create --stdin --title "Set up CI"
|
|
118
|
+
canary prompts delete <id>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`canary prompts get <slug>` prints raw markdown so you can pipe or paste it straight into an agent. `--global` (superadmin only) creates a Cofactor-wide prompt instead of an org one.
|
|
122
|
+
|
|
108
123
|
## Release QA (CI/CD)
|
|
109
124
|
|
|
110
125
|
Trigger and monitor Release QA runs from CI pipelines:
|
package/dist/index.js
CHANGED
|
@@ -147,7 +147,8 @@ function printHelp({
|
|
|
147
147
|
" canary workflow <sub-command> Inspect workflow definitions",
|
|
148
148
|
` canary spec <sub-command> Author workflows from ${specExtension} spec files`,
|
|
149
149
|
" canary api-catalog <sub-command> Manage API catalog sources and endpoints",
|
|
150
|
-
" canary skill <name> Install an AI agent skill template (--name to rename)"
|
|
150
|
+
" canary skill <name> Install an AI agent skill template (--name to rename)",
|
|
151
|
+
" canary prompts <list|get> Curated starter prompts for coding agents"
|
|
151
152
|
];
|
|
152
153
|
lines.push(" canary release <sub-command> Release QA gate (CI/CD)");
|
|
153
154
|
lines.push(
|
|
@@ -740,6 +741,15 @@ var COMMAND_DEFINITIONS = [
|
|
|
740
741
|
await runSkill(rest);
|
|
741
742
|
}
|
|
742
743
|
},
|
|
744
|
+
{
|
|
745
|
+
name: "prompts",
|
|
746
|
+
aliases: ["prompt"],
|
|
747
|
+
handlesHelp: ["prompts", "prompt"],
|
|
748
|
+
run: async (rest) => {
|
|
749
|
+
const { runPrompts } = await import("./prompts-NKJEQ62J.js");
|
|
750
|
+
await runPrompts(rest);
|
|
751
|
+
}
|
|
752
|
+
},
|
|
743
753
|
{
|
|
744
754
|
name: "task",
|
|
745
755
|
updateCheck: true,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/command-registry.ts","../src/debug-session.ts","../src/help.ts","../src/orgs.ts","../src/user-event-tracking.ts","../../sdk/src/errors.ts","../../sdk/src/client.ts","../../sdk/src/user-events.ts","../../user-events/src/recorder.ts"],"sourcesContent":["import process from 'node:process';\nimport { pathToFileURL } from 'node:url';\nimport { installConsoleBranding, version } from './brand.js';\nimport { COMMANDS_WITH_HELP, executeCommand, maybeCheckForUpdate } from './command-registry.js';\nimport { printVersion, showGlobalHelp } from './help.js';\nimport {\n ProcessExitSignal,\n createCliUserEventRecorder,\n isExpectedCliInputError,\n recordCliInstrumentationFailure,\n} from './user-event-tracking.js';\n\nfunction normalizeExitCode(value: string | number | null | undefined): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 1;\n }\n return 0;\n}\n\nexport async function main(argv: string[]) {\n // Rebrand human-readable output for the `cofactor` binary (no-op for\n // `canary`). Skipped for the `mcp` JSON-RPC transport and `--json`/`--format`\n // output so structured payloads are never rewritten — display branding only.\n const wantsMachineOutput = argv.includes('--json') || argv.includes('--format');\n if (argv[0] !== 'mcp' && !wantsMachineOutput) {\n installConsoleBranding();\n }\n\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 await showGlobalHelp();\n return;\n }\n\n if (!command || command === 'help') {\n await showGlobalHelp();\n return;\n }\n\n if (command === 'version') {\n printVersion();\n return;\n }\n\n // Non-blocking upgrade check — only for interactive humans logged in via\n // `canary login`. Never nag API-key auth (--token / *_API_TOKEN env var,\n // i.e. CI/automation) or machine-readable (`--json`/`--format`) runs, where\n // the banner is noise that can wrap structured output.\n if (command && !wantsMachineOutput) {\n await maybeCheckForUpdate(command, argv, version);\n }\n let tracking: Awaited<ReturnType<typeof createCliUserEventRecorder>> = null;\n try {\n tracking = await createCliUserEventRecorder(argv, version);\n } catch (error) {\n await recordCliInstrumentationFailure(argv, version, 'recorder-init', error);\n }\n const startedAt = Date.now();\n const originalExit = process.exit.bind(process);\n let finalExitCode = 0;\n let handledExpectedInputError = false;\n\n if (tracking) {\n await tracking.recorder.recordCommandStarted(tracking.metadata);\n }\n\n (process as typeof process & { exit: typeof process.exit }).exit = ((code?: number) => {\n throw new ProcessExitSignal(code ?? normalizeExitCode(process.exitCode));\n }) as typeof process.exit;\n\n try {\n await executeCommand(command, rest);\n finalExitCode = normalizeExitCode(process.exitCode);\n if (tracking) {\n const metadata = {\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n };\n if (finalExitCode === 0) {\n await tracking.recorder.recordCommandCompleted(metadata);\n } else {\n await tracking.recorder.recordCommandFailed({\n ...metadata,\n errorKind: 'exit-code',\n });\n }\n }\n } catch (error) {\n if (error instanceof ProcessExitSignal) {\n finalExitCode = error.exitCode;\n if (tracking) {\n const metadata = {\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n };\n if (finalExitCode === 0) {\n await tracking.recorder.recordCommandCompleted(metadata);\n } else {\n await tracking.recorder.recordCommandFailed({\n ...metadata,\n errorKind: 'process-exit',\n });\n }\n }\n } else {\n finalExitCode = normalizeExitCode(process.exitCode) || 1;\n const expectedInputError = isExpectedCliInputError(error);\n if (tracking) {\n await tracking.recorder.recordCommandFailed({\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n errorKind: error instanceof Error ? error.name : typeof error,\n errorName: error instanceof Error ? error.name : undefined,\n errorMessage: error instanceof Error ? error.message : String(error),\n ...(expectedInputError\n ? {}\n : {\n reportToSentry: true,\n sentryFingerprint: [\n 'canary-cli',\n tracking.metadata.commandPath,\n error instanceof Error ? error.name : typeof error,\n ],\n }),\n });\n }\n if (expectedInputError) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n handledExpectedInputError = true;\n } else {\n throw error;\n }\n }\n } finally {\n (process as typeof process & { exit: typeof process.exit }).exit = originalExit;\n }\n\n if (finalExitCode !== 0 || handledExpectedInputError) {\n originalExit(finalExitCode);\n }\n}\n\nif (import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main(process.argv.slice(2));\n}\n","import process from 'node:process';\nimport { resolveAuthSource } from './auth';\nimport { runDebugSession } from './debug-session';\nimport { printTestHelp, resolveIsSuperadmin, showGlobalHelp } from './help.js';\nimport { runLogin } from './login';\nimport { runOrgs } from './orgs';\nimport { runRemoteTest } from './remote-test';\n\ntype CommandRunner = (rest: string[], command: string) => Promise<void>;\ntype CommandMetadataFlag = true | readonly string[];\n\nexport type CommandDefinition = {\n name: string;\n aliases?: readonly string[];\n updateCheck?: CommandMetadataFlag;\n handlesHelp?: CommandMetadataFlag;\n run: CommandRunner;\n};\n\n// Lazy-load playwright-dependent modules.\nconst loadMcp = () => import('./mcp').then((m) => m.runMcp);\nconst loadRecord = () => import('./record.js').then((m) => m.runRecord);\nconst loadSession = () => import('./session/index.js').then((m) => m.runSession);\nconst loadLocal = () => import('./local/index.js').then((m) => m.runLocal);\n\nasync function runDeprecatedTest(rest: string[]) {\n // Sub-command help\n if (rest.includes('--help') || rest.includes('-h')) {\n printTestHelp();\n return;\n }\n // Check for --remote flag — deprecated, forward to test-suite run\n if (rest.includes('--remote')) {\n console.warn(\n '\\x1b[33m⚠ `canary test --remote` is deprecated and will be removed in a future release.\\x1b[0m'\n );\n console.warn(' Use `canary test-suite run` instead.\\n');\n const remoteArgs = rest.filter((arg) => arg !== '--remote');\n await runRemoteTest(remoteArgs);\n return;\n }\n // Local Playwright test runner has been removed\n console.error(\n '`canary test` (local Playwright runner) has been removed.\\n' +\n 'Use `canary test-suite run` for remote workflow tests.\\n' +\n '\\n' +\n 'Examples:\\n' +\n ' canary test-suite run\\n' +\n ' canary test-suite run --tag smoke\\n' +\n ' canary test-suite run --property \"My App\" --environment staging'\n );\n process.exit(1);\n}\n\nasync function runSpec(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { handleSpec } = await import('./spec/index.js');\n // `validate` is purely offline — don't fail on missing auth config.\n const wantsAuth = rest[0] === 'compile' || rest[0] === 'pull' || rest[0] === 'diff';\n if (wantsAuth) {\n const { apiUrl, token } = await resolveConfig(rest);\n await handleSpec(rest, apiUrl, token);\n } else {\n await handleSpec(rest, '', '');\n }\n}\n\nasync function runAugmentorCommand(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { runAugmentor } = await import('./augmentor.js');\n // `help` is offline; everything else needs auth.\n if (rest[0] === undefined || rest[0] === 'help' || rest[0] === '--help') {\n await runAugmentor(rest, '', '');\n } else {\n const { apiUrl, token } = await resolveConfig(rest);\n await runAugmentor(rest, apiUrl, token);\n }\n}\n\nasync function runApiCatalogCommand(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { runApiCatalog } = await import('./api-catalog.js');\n const { apiUrl, token } = await resolveConfig(rest);\n await runApiCatalog(rest, apiUrl, token);\n}\n\nasync function runStatusCommand(rest: string[], command: string) {\n // Superadmin-only. Gated client-side (the command talks to AWS directly,\n // not the cofactor API, so there is no server-side 403 to rely on). Treat\n // non-superadmins as if the command does not exist.\n if (!(await resolveIsSuperadmin())) {\n console.log(`Unknown command \"${command}\".`);\n await showGlobalHelp();\n process.exit(1);\n }\n const { runStatus } = await import('./status.js');\n await runStatus(rest);\n}\n\nasync function runAuthCommand(rest: string[]) {\n const sub = rest[0];\n if (sub === 'doctor') {\n const { runAuthDoctor } = await import('./doctor.js');\n await runAuthDoctor(rest.slice(1));\n return;\n }\n console.error('Usage: canary auth doctor [--env <env>]');\n process.exit(1);\n}\n\nexport const COMMAND_DEFINITIONS: readonly CommandDefinition[] = [\n {\n name: 'upgrade',\n run: async () => {\n const { runUpgrade } = await import('./upgrade.js');\n await runUpgrade();\n },\n },\n {\n name: 'test',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => runDeprecatedTest(rest),\n },\n {\n name: 'mcp',\n run: async (rest) => {\n const runMcp = await loadMcp();\n await runMcp(rest);\n },\n },\n {\n name: 'install',\n handlesHelp: true,\n run: async (rest) => {\n const { runInstall } = await import('./install.js');\n await runInstall(rest);\n },\n },\n {\n name: 'login',\n updateCheck: true,\n run: async (rest) => runLogin(rest),\n },\n {\n name: 'orgs',\n updateCheck: true,\n run: async (rest) => runOrgs(rest),\n },\n {\n name: 'record',\n updateCheck: true,\n run: async (rest) => {\n const runRecord = await loadRecord();\n await runRecord(rest);\n },\n },\n {\n name: 'session',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const runSession = await loadSession();\n await runSession(rest);\n },\n },\n {\n name: 'local',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const runLocal = await loadLocal();\n await runLocal(rest);\n },\n },\n {\n name: 'debug-session',\n run: async (rest) => runDebugSession(rest),\n },\n {\n name: 'psql',\n run: async (rest) => {\n const { runPsql } = await import('./psql.js');\n await runPsql(rest);\n },\n },\n {\n name: 'redis',\n run: async (rest) => {\n const { runRedis } = await import('./redis.js');\n await runRedis(rest);\n },\n },\n {\n name: 'release',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runRelease } = await import('./release.js');\n await runRelease(rest);\n },\n },\n {\n name: 'docs',\n run: async (rest) => {\n const { runDocs } = await import('./docs.js');\n await runDocs(rest);\n },\n },\n {\n name: 'feature-flag',\n run: async (rest) => {\n const { runFeatureFlag } = await import('./feature-flag.js');\n await runFeatureFlag(rest);\n },\n },\n {\n name: 'schedule',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runSchedule } = await import('./schedule.js');\n await runSchedule(rest);\n },\n },\n {\n name: 'alert',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runAlert } = await import('./alert.js');\n await runAlert(rest);\n },\n },\n {\n name: 'product',\n run: async (rest) => {\n const { runProduct } = await import('./product.js');\n await runProduct(rest);\n },\n },\n {\n name: 'metrics',\n run: async (rest) => {\n const { runMetrics } = await import('./metrics.js');\n await runMetrics(rest);\n },\n },\n {\n name: 'account',\n run: async (rest) => {\n const { runAccount } = await import('./account.js');\n await runAccount(rest);\n },\n },\n {\n name: 'scenario',\n aliases: ['scenarios'],\n run: async (rest) => {\n const { runScenarios } = await import('./scenarios.js');\n await runScenarios(rest);\n },\n },\n {\n name: 'knobs',\n run: async (rest) => {\n const { runKnobs } = await import('./knobs.js');\n await runKnobs(rest);\n },\n },\n {\n name: 'issues',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runIssues } = await import('./issues.js');\n await runIssues(rest);\n },\n },\n {\n name: 'credential',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runCredential } = await import('./credential.js');\n await runCredential(rest);\n },\n },\n {\n name: 'persona',\n aliases: ['personas', 'credential-template', 'credential-templates'],\n run: async (rest) => {\n const { runCredentialTemplate } = await import('./credential-template.js');\n await runCredentialTemplate(rest);\n },\n },\n {\n name: 'workflow',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runWorkflow } = await import('./workflow.js');\n await runWorkflow(rest);\n },\n },\n {\n name: 'spec',\n run: async (rest) => runSpec(rest),\n },\n {\n name: 'augmentor',\n aliases: ['augmentors'],\n run: async (rest) => runAugmentorCommand(rest),\n },\n {\n name: 'api-catalog',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => runApiCatalogCommand(rest),\n },\n {\n name: 'skill',\n aliases: ['skills'],\n updateCheck: ['skill', 'skills'],\n handlesHelp: ['skill', 'skills'],\n run: async (rest) => {\n const { runSkill } = await import('./skill.js');\n await runSkill(rest);\n },\n },\n {\n name: 'task',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runTask } = await import('./task.js');\n await runTask(rest);\n },\n },\n {\n name: 'test-suite',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runTestSuite } = await import('./test-suite.js');\n await runTestSuite(rest);\n },\n },\n {\n name: 'triage',\n run: async (rest) => {\n const { runTriage } = await import('./triage.js');\n await runTriage(rest);\n },\n },\n {\n // \"application\" is the user-facing name; \"property\" stays as a backwards-compat alias.\n name: 'application',\n aliases: ['applications', 'property', 'properties'],\n run: async (rest) => {\n const { runProperty } = await import('./property.js');\n await runProperty(rest);\n },\n },\n {\n name: 'environment',\n aliases: ['env'],\n run: async (rest) => {\n const { runEnvironment } = await import('./environment.js');\n await runEnvironment(rest);\n },\n },\n {\n name: 'sandbox',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runSandbox } = await import('./sandbox.js');\n await runSandbox(rest);\n },\n },\n {\n name: 'attachment',\n aliases: ['attachments'],\n updateCheck: ['attachment', 'attachments'],\n handlesHelp: ['attachment', 'attachments'],\n run: async (rest) => {\n const { runAttachment } = await import('./attachment.js');\n await runAttachment(rest);\n },\n },\n {\n name: 'utilities',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runUtilities } = await import('./utilities.js');\n await runUtilities(rest);\n },\n },\n {\n name: 'tag',\n aliases: ['tags'],\n updateCheck: ['tag', 'tags'],\n handlesHelp: ['tag', 'tags'],\n run: async (rest) => {\n const { runTag } = await import('./tag.js');\n await runTag(rest);\n },\n },\n {\n name: 'trace',\n run: async (rest) => {\n const { runTrace } = await import('./trace.js');\n await runTrace(rest);\n },\n },\n {\n name: 'status',\n run: async (rest, command) => runStatusCommand(rest, command),\n },\n {\n name: 'auth',\n run: async (rest) => runAuthCommand(rest),\n },\n];\n\nfunction namesForMetadata(\n definition: CommandDefinition,\n value: CommandMetadataFlag | undefined\n): readonly string[] {\n if (value === true) return [definition.name];\n return value ?? [];\n}\n\nconst commandDefinitionMap = new Map<string, CommandDefinition>();\n\nfor (const definition of COMMAND_DEFINITIONS) {\n commandDefinitionMap.set(definition.name, definition);\n for (const alias of definition.aliases ?? []) {\n commandDefinitionMap.set(alias, definition);\n }\n}\n\n/** Commands that trigger the upgrade-available warning. */\nexport const COMMANDS_WITH_UPDATE_CHECK = new Set(\n COMMAND_DEFINITIONS.flatMap((definition) =>\n Array.from(namesForMetadata(definition, definition.updateCheck))\n )\n);\n\n/** Commands that handle --help themselves instead of showing global help. */\nexport const COMMANDS_WITH_HELP = new Set(\n COMMAND_DEFINITIONS.flatMap((definition) =>\n Array.from(namesForMetadata(definition, definition.handlesHelp))\n )\n);\n\nexport function getCommandDefinition(command: string): CommandDefinition | undefined {\n return commandDefinitionMap.get(command);\n}\n\nexport async function maybeCheckForUpdate(command: string, argv: string[], version: string) {\n if (!COMMANDS_WITH_UPDATE_CHECK.has(command)) return;\n if ((await resolveAuthSource(argv)) !== 'stored') return;\n\n const { checkForUpdate } = await import('./update-check.js');\n await checkForUpdate(version);\n}\n\nexport async function executeCommand(command: string, rest: string[]) {\n const definition = getCommandDefinition(command);\n if (!definition) {\n console.log(`Unknown command \"${command}\".`);\n await showGlobalHelp();\n process.exit(1);\n }\n\n await definition.run(rest, command);\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\";\nimport { fetchOrExit } from \"./api-fetch.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 fetchOrExit(`${apiUrl}/auth/debug-session/create`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n token,\n });\n\n // Handle HTTP errors before parsing JSON\n if (!res.ok) {\n const text = await res.text();\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","import { readAllStoredTokens, resolveOptionalConfig } from './auth';\nimport { version, readBrandEnv, specExtension } from './brand.js';\nimport { isSuperadminToken } from './jwt';\n\nexport function printVersion() {\n console.log(`canary v${version}`);\n}\n\nexport function printHelp({\n isSuperadmin,\n features = {},\n}: {\n isSuperadmin: boolean;\n features?: Record<string, boolean>;\n}) {\n const lines: string[] = [\n `canary v${version}: Testing and QA CLI`,\n '',\n 'Usage:',\n ' canary test-suite <sub-command> Run and query test suite results',\n ' canary mcp Start MCP server (stdio)',\n ' canary install [--target <id>] Install MCP server into Claude, Cursor, etc.',\n ' canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]',\n ' canary orgs [members] List organizations (or org members)',\n ' canary record [options] Record browser interactions',\n ' canary local <sub-command> Set up and manage local testing',\n ' canary session <sub-command> Manage local browser sessions',\n ' canary issues <sub-command> Search and view issues',\n ' canary credential <sub-command> List, create, update, and test credentials',\n ' canary persona <sub-command> Manage per-application personas',\n ' canary workflow <sub-command> Inspect workflow definitions',\n ` canary spec <sub-command> Author workflows from ${specExtension} spec files`,\n ' canary api-catalog <sub-command> Manage API catalog sources and endpoints',\n ' canary skill <name> Install an AI agent skill template (--name to rename)',\n ];\n\n lines.push(' canary release <sub-command> Release QA gate (CI/CD)');\n\n lines.push(\n ' canary application <sub-command> List and create applications, view linked repos (alias: property)',\n ' canary environment <sub-command> List, create, and default environments (alias: env)',\n ' canary sandbox <sub-command> Manage sandbox templates and instances',\n ' canary attachment <sub-command> List, upload, and manage attachments',\n ' canary tag <sub-command> List, create, and assign tags',\n ' canary triage <sub-command> Read AI triage results for a test suite execution',\n ' canary schedule suite <sub-command> Schedule recurring test-suite runs',\n ' canary alert <sub-command> Manage notify-only alerts (Slack/email)'\n );\n\n // Feature-gated agent commands — only listed when the signed-in org has the\n // backing feature flag (resolved from /me). Hidden otherwise so help never\n // advertises a command that returns 403.\n if (features.agentTasks) {\n lines.push(' canary task <sub-command> Manage agent tasks');\n }\n if (features.utilities) {\n lines.push(\n ' canary utilities <group> <sub> Object storage, gists, email/slack (agent toolkit)'\n );\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 docs <sub-command> Manage documentation pages',\n ' canary feature-flag <sub-command> Manage feature flags',\n ' canary knobs <sub-command> Manage knobs (global config)',\n ' canary product <sub-command> Manage the Product board (cards, fields, flag links)',\n ' canary metrics <sub-command> Manage product metrics (pull/review health metrics)',\n ' canary account <sub-command> Manage the Accounts board (accounts, org links)',\n ' canary status <sub-command> Publish incidents to the status page'\n );\n }\n\n lines.push(\n ' canary auth doctor [--env <env>] Diagnose auth / corporate-proxy issues',\n ' canary upgrade Upgrade CLI to latest version',\n ' canary version Show version',\n ' canary help',\n '',\n 'Test suite sub-commands:',\n ' run [options] Trigger a test suite and stream results',\n ' list [options] List recent test suites',\n ' get <id> [options] Show suite detail with runs',\n ' diagnostics <workflowId> <runId> Get failure diagnostic',\n ' steps <workflowId> <runId> Get workflow run steps',\n '',\n 'Test suite run options:',\n ' --token <key> API key (or set CANARY_API_TOKEN)',\n ' --api-url <url> API URL (default: https://api.trycanary.ai)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all events',\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 ' --application-id <uuid> Filter by application (alias: --property-id)',\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 --application-id <uuid> Trigger a Release QA run (alias: --property-id)',\n ' status <run-id> [--json] Check run status',\n ' run --application-id <uuid> [--timeout N] Trigger and poll until complete',\n '',\n 'Record options:',\n ' --credential <id> Credential ID (skip interactive selection)',\n ' --url <startUrl> URL to navigate to after launch',\n ' --output <dir> Local output directory (default: temp dir)',\n ' --env <env> Environment (local, dev, prod)',\n ' --no-upload Save locally only, skip API upload',\n ''\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 'Product board sub-commands (org you are logged into):',\n ' list [--search <t>] [--priority p0,p1] [--include-deprecated] List items',\n ' create <title> [--description <t>] [--stage <s>] [--priority <p0-p3>] Create item',\n ' set <id> [--title <t>] [--description <t>] [--priority <p0-p3|null>] Update fields',\n ' move <id> --stage <s> [--before <id>] [--after <id>] Move card to a column',\n ' delete <id> Delete item',\n ' customer add <id> (--account-card <id> | --org <orgId>) [--name <t>] Link customer',\n ' customer remove <id> <customerId> Unlink customer',\n ' link-flag <cardId> --flag <name> | --flag <name> --clear Link/unlink a feature flag',\n ' flags <cardId> List flags linked to a card',\n '',\n 'Account board sub-commands (org you are logged into):',\n ' list [--search <t>] [--stage <s>] List accounts',\n ' create <name> [--description <t>] [--stage <s>] Create account (default stage=prospect)',\n ' set <id> [--title <t>] [--description <t>] [--stage <s>] Update fields',\n ' delete <id> Delete account',\n ' link-org <id> --org <customerOrgId> Bind account to a customer org',\n ' unlink-org <id> Remove org link',\n ' linked-org <id> Show linked org'\n );\n }\n\n lines.push('', 'Flags:', ' -h, --help Show help', ' -V, --version Show version');\n\n console.log(lines.join('\\n'));\n}\n\nexport function printTestHelp() {\n console.log(\n [\n `canary v${version}: Test command`,\n '',\n '\\x1b[33m⚠ `canary test` is deprecated. Use `canary test-suite run` instead.\\x1b[0m',\n '',\n 'Usage:',\n ' canary test-suite run [options] Trigger a test suite and stream results',\n ' canary test-suite list List recent test suites',\n ' canary test-suite get <id> Show suite detail with runs',\n '',\n 'Run options:',\n ' --token <key> API key (or set CANARY_API_TOKEN)',\n ' --api-url <url> API URL (default: https://api.trycanary.ai)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all events',\n '',\n 'Examples:',\n ' canary test-suite run Run all workflow tests',\n ' canary test-suite run --tag smoke Run smoke-tagged workflows',\n ' canary test-suite run --property \"My App\" --environment staging',\n ].join('\\n')\n );\n}\n\n/** Check if any stored profile (or env token) has superadmin privileges */\nexport async function resolveIsSuperadmin(): Promise<boolean> {\n const envToken = readBrandEnv('CANARY_API_TOKEN');\n if (envToken) return isSuperadminToken(envToken);\n\n const tokens = await readAllStoredTokens();\n return tokens.some((t) => isSuperadminToken(t));\n}\n\n/**\n * Best-effort fetch of the signed-in org's enabled feature flags (the same\n * `user.features` map the web app uses), so the global help can hide commands\n * for features the org doesn't have. Fail-closed: any error, timeout, or\n * missing auth yields `{}`, which hides feature-gated commands rather than\n * advertising something the org can't use. Never throws.\n */\nexport async function resolveOrgFeatures(): Promise<Record<string, boolean>> {\n try {\n const config = await resolveOptionalConfig([]);\n if (!config) return {};\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 3000);\n try {\n const res = await fetch(`${config.apiUrl}/me`, {\n headers: { Authorization: `Bearer ${config.token}` },\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json()) as { user?: { features?: Record<string, boolean> } };\n return body.user?.features ?? {};\n } finally {\n clearTimeout(timer);\n }\n } catch {\n return {};\n }\n}\n\n/** Resolve superadmin + org features in parallel, then print the global help. */\nexport async function showGlobalHelp(): Promise<void> {\n const [isSuperadmin, features] = await Promise.all([resolveIsSuperadmin(), resolveOrgFeatures()]);\n printHelp({ isSuperadmin, features });\n}\n","import process from 'node:process';\nimport {\n envToProfile,\n getArgValue,\n hasFlag,\n readStoredAuth,\n resolveConfig,\n} 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\ntype SuperadminOrgsResponse = {\n ok: boolean;\n organizations?: Array<{ id: string; name: string; memberCount?: number }>;\n error?: string;\n};\n\ntype OrgMembersResponse = {\n ok: boolean;\n error?: string;\n items?: Array<{\n userId: string;\n displayName: string | null;\n primaryEmail: string | null;\n role: string;\n isActive: boolean;\n slackLinked: boolean;\n }>;\n};\n\n/**\n * `cofactor org members` — list members of the current org, annotated with\n * whether each has linked their Slack user. Powers recipient lookup for the\n * `utilities email` / `utilities slack` commands.\n */\nasync function runOrgMembers(argv: string[]) {\n const { apiUrl, token } = await resolveConfig(argv);\n const res = await fetch(`${apiUrl}/org/members`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) {\n console.error('Failed to fetch members. You may need to re-login: cofactor login');\n process.exit(1);\n }\n const data = (await res.json()) as OrgMembersResponse;\n if (!data.ok || !data.items) {\n console.error('Failed to fetch members:', data.error ?? 'Unknown error');\n process.exit(1);\n }\n\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify(data.items, null, 2));\n return;\n }\n\n if (data.items.length === 0) {\n console.log('No members.');\n return;\n }\n console.log('Members (✓ = Slack-linked, can receive utilities slack DMs):\\n');\n for (const m of data.items) {\n const slack = m.slackLinked ? '✓' : ' ';\n const name = m.displayName ?? '(no name)';\n const email = m.primaryEmail ?? '(no email)';\n console.log(` ${slack} ${name} <${email}> [${m.role}]`);\n }\n}\n\nexport async function runOrgs(argv: string[]) {\n // `orgs members` is a sub-command; everything else lists organizations.\n const sub = argv.find((a) => !a.startsWith('-'));\n if (sub === 'members') {\n return runOrgMembers(argv.filter((a) => a !== 'members'));\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n // Read the same profile's stored auth so the \"* = current\" marker reflects\n // the profile we just resolved, not the default profile.\n const env = getArgValue(argv, '--env');\n const auth = await readStoredAuth(env ? envToProfile(env) : undefined);\n const showAll = hasFlag(argv, '--all');\n\n if (showAll) {\n // Superadmin: list all organizations\n const res = await fetch(`${apiUrl}/superadmin/organizations`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n if (res.status === 403) {\n console.error('Superadmin access required for --all');\n } else {\n console.error('Failed to fetch organizations. You may need to re-login: canary login');\n }\n process.exit(1);\n }\n\n const data = (await res.json()) as SuperadminOrgsResponse;\n if (!data.ok || !data.organizations) {\n console.error('Failed to fetch organizations:', data.error ?? 'Unknown error');\n process.exit(1);\n }\n\n console.log('All Organizations:\\n');\n for (const org of data.organizations) {\n const members = org.memberCount !== undefined && org.memberCount !== null ? ` (${org.memberCount} members)` : '';\n console.log(` ${org.name}${members} [${org.id}]`);\n }\n\n console.log(`\\nTotal: ${data.organizations.length} organizations`);\n return;\n }\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}) [${org.id}]${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 { createClient } from '@chatsdet/sdk';\nimport {\n createUserEventRecorder,\n type CliCommandBaseMetadata,\n type UserEventRecorder,\n} from '@chatsdet/user-events';\nimport { resolveOptionalConfig } from './auth.js';\nimport { debug } from './debug.js';\n\nconst SUBCOMMAND_COMMANDS = new Set([\n 'api-catalog',\n 'attachment',\n 'attachments',\n 'auth',\n 'credential',\n 'credential-template',\n 'credential-templates',\n 'docs',\n 'feature-flag',\n 'issues',\n 'knobs',\n 'local',\n 'property',\n 'release',\n 'sandbox',\n 'session',\n 'tag',\n 'tags',\n 'task',\n 'test-suite',\n 'workflow',\n]);\n\nconst UNTRACKED_COMMANDS = new Set(['help', 'upgrade', 'version']);\n\nexport class ProcessExitSignal extends Error {\n readonly exitCode: number;\n\n constructor(exitCode: number) {\n super(`Process exited with code ${exitCode}`);\n this.name = 'ProcessExitSignal';\n this.exitCode = exitCode;\n }\n}\n\nfunction shouldTrack(argv: string[]): boolean {\n const command = argv[0];\n if (!command || UNTRACKED_COMMANDS.has(command)) return false;\n if (argv.includes('--help') || argv.includes('-h')) return false;\n return true;\n}\n\nfunction getSubcommand(argv: string[]): string | undefined {\n const command = argv[0];\n if (!command || !SUBCOMMAND_COMMANDS.has(command)) return undefined;\n const candidate = argv[1];\n if (!candidate || candidate.startsWith('-')) return undefined;\n return candidate;\n}\n\nfunction getApiHost(apiUrl: string): string | undefined {\n try {\n return new URL(apiUrl).host;\n } catch {\n return undefined;\n }\n}\n\nfunction getArgNames(argv: string[]): string[] {\n return argv.filter((arg) => arg.startsWith('-'));\n}\n\nfunction buildBaseMetadata(argv: string[], cliVersion: string, apiUrl: string): CliCommandBaseMetadata {\n const topLevelCommand = argv[0] ?? 'unknown';\n const subcommand = getSubcommand(argv);\n return {\n commandPath: subcommand ? `${topLevelCommand} ${subcommand}` : topLevelCommand,\n topLevelCommand,\n subcommand,\n cliVersion,\n apiHost: getApiHost(apiUrl),\n isInteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n args: getArgNames(argv),\n };\n}\n\nfunction errorMetadata(error: unknown): {\n errorKind: string;\n errorName?: string;\n errorMessage: string;\n} {\n return {\n errorKind: error instanceof Error ? error.name : typeof error,\n errorName: error instanceof Error ? error.name : undefined,\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n}\n\nexport function isExpectedCliInputError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n return /^Action index \\d+ out of range \\(0-\\d+\\)$/.test(error.message);\n}\n\nexport async function createCliUserEventRecorder(\n argv: string[],\n cliVersion: string\n): Promise<{ recorder: UserEventRecorder; metadata: CliCommandBaseMetadata } | null> {\n if (!shouldTrack(argv)) return null;\n\n // Not every command uses resolveConfig() yet. Until CLI config resolution is\n // centralized, tracking can target a different backend than the command body.\n const config = await resolveOptionalConfig(argv);\n if (!config) return null;\n\n const client = createClient({\n baseUrl: config.apiUrl,\n token: config.token,\n });\n\n return {\n recorder: createUserEventRecorder({\n client,\n origin: 'cli',\n onError: (error: unknown) => {\n // Tracking is best-effort diagnostics and must never affect command\n // execution or pollute output (e.g. wrap `--json` payloads). Stay silent\n // unless the user opted into debug logging.\n const message = error instanceof Error ? error.message : String(error);\n debug(`user event tracking skipped: ${message}`);\n },\n }),\n metadata: buildBaseMetadata(argv, cliVersion, config.apiUrl),\n };\n}\n\nexport async function recordCliInstrumentationFailure(\n argv: string[],\n cliVersion: string,\n stage: 'recorder-init' | 'record-started' | 'record-completed' | 'record-failed',\n error: unknown\n): Promise<void> {\n if (!shouldTrack(argv)) return;\n\n try {\n const config = await resolveOptionalConfig(argv);\n if (!config) return;\n\n const client = createClient({\n baseUrl: config.apiUrl,\n token: config.token,\n });\n const recorder = createUserEventRecorder({\n client,\n origin: 'cli',\n });\n await recorder.recordCommandInstrumentationFailed({\n ...buildBaseMetadata(argv, cliVersion, config.apiUrl),\n stage,\n ...errorMetadata(error),\n reportToSentry: true,\n sentryFingerprint: ['canary-cli', 'instrumentation-failed', stage],\n });\n } catch {\n // Diagnostics must never affect command execution.\n }\n}\n\nexport const __internals = {\n getArgNames,\n getSubcommand,\n isExpectedCliInputError,\n shouldTrack,\n};\n","/**\n * Error classes thrown by the SDK. Callers match on these rather than\n * parsing raw HTTP responses.\n */\n\nexport interface ApiErrorBody {\n ok?: false;\n error?: string;\n userError?: boolean;\n code?: string;\n details?: unknown;\n}\n\nexport class SdkError extends Error {\n readonly status: number;\n readonly body: ApiErrorBody | undefined;\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message);\n this.name = 'SdkError';\n this.status = status;\n this.body = body;\n }\n}\n\nexport class AuthError extends SdkError {\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message, status, body);\n this.name = 'AuthError';\n }\n}\n\nexport class ValidationError extends SdkError {\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message, status, body);\n this.name = 'ValidationError';\n }\n}\n\n/** Build the right error subtype for an HTTP status. */\nexport function errorFromResponse(\n status: number,\n body: ApiErrorBody | undefined\n): SdkError {\n const message = body?.error ?? `Request failed with status ${status}`;\n if (status === 401 || status === 403) return new AuthError(message, status, body);\n if (status === 400 || status === 422) return new ValidationError(message, status, body);\n return new SdkError(message, status, body);\n}\n","/**\n * Minimal, typed `fetch` wrapper that all SDK resource modules go through.\n *\n * Design:\n * - Exactly one HTTP call site. Auth header + content-type + error\n * shaping live here; resource modules are thin method wrappers.\n * - No dependency on a generated OpenAPI types file yet — the typed\n * `paths` map will plug in via `client.GET<'/some/path'>(...)` once\n * `scripts/generate-types.ts` is wired up.\n */\nimport { errorFromResponse, type ApiErrorBody } from './errors.js';\n\nexport interface ClientConfig {\n /** API base URL, e.g. `https://api.trycanary.ai` — no trailing slash. */\n baseUrl: string;\n /**\n * Bearer token (JWT) or API key. A function is accepted so callers\n * can refresh on 401 without reconstructing the client.\n */\n token?: string | (() => string | Promise<string>);\n /** Custom fetch implementation (tests, proxies). Defaults to global. */\n fetch?: typeof fetch;\n /** Additional default headers merged into every request. */\n headers?: Record<string, string>;\n}\n\nexport interface RequestOptions {\n /** Path params substituted into `:name` placeholders in the URL. */\n params?: Record<string, string | number>;\n /** Query params appended to the URL. */\n query?: Record<string, string | number | boolean | undefined | null>;\n /** JSON body (stringified automatically). */\n body?: unknown;\n /** Per-request header overrides. */\n headers?: Record<string, string>;\n /** AbortSignal forwarded to fetch. */\n signal?: AbortSignal;\n}\n\nexport interface Client {\n readonly baseUrl: string;\n request<T = unknown>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n opts?: RequestOptions\n ): Promise<T>;\n /** Replace the stored token (e.g. after org switch). */\n setToken(token: string | (() => string | Promise<string>) | undefined): void;\n}\n\nfunction interpolate(path: string, params: Record<string, string | number> | undefined): string {\n if (!params) return path;\n return path.replace(/:([A-Za-z0-9_]+)/g, (_, k: string) => {\n const v = params[k];\n if (v === undefined) throw new Error(`Missing path param :${k} for ${path}`);\n return encodeURIComponent(String(v));\n });\n}\n\nfunction buildQuery(q: RequestOptions['query']): string {\n if (!q) return '';\n const usp = new URLSearchParams();\n for (const [k, v] of Object.entries(q)) {\n if (v === undefined || v === null) continue;\n usp.set(k, String(v));\n }\n const s = usp.toString();\n return s ? `?${s}` : '';\n}\n\nexport function createClient(cfg: ClientConfig): Client {\n let token = cfg.token;\n const fetchImpl = cfg.fetch ?? fetch;\n\n async function resolveToken(): Promise<string | undefined> {\n if (typeof token === 'function') return token();\n return token;\n }\n\n async function request<T>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n opts: RequestOptions = {}\n ): Promise<T> {\n const url =\n cfg.baseUrl.replace(/\\/$/, '') +\n interpolate(path, opts.params) +\n buildQuery(opts.query);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...cfg.headers,\n ...opts.headers,\n };\n const resolvedToken = await resolveToken();\n if (resolvedToken && !headers.authorization) {\n headers.authorization = `Bearer ${resolvedToken}`;\n }\n if (opts.body !== undefined && !headers['content-type']) {\n headers['content-type'] = 'application/json';\n }\n\n const res = await fetchImpl(url, {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n signal: opts.signal,\n });\n\n const text = await res.text();\n let parsed: unknown;\n if (text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const body = (parsed && typeof parsed === 'object' ? parsed : undefined) as\n | ApiErrorBody\n | undefined;\n throw errorFromResponse(res.status, body);\n }\n return parsed as T;\n }\n\n return {\n get baseUrl() {\n return cfg.baseUrl;\n },\n request,\n setToken(next) {\n token = next;\n },\n };\n}\n","import type { Client } from './client.js';\n\nexport interface RecordUserEventInput<\n Origin extends string = string,\n Metadata = Record<string, unknown>,\n> {\n eventType: string;\n origin: Origin;\n metadata: Metadata;\n}\n\nexport async function recordUserEvent<\n Origin extends string = string,\n Metadata = Record<string, unknown>,\n>(\n client: Client,\n input: RecordUserEventInput<Origin, Metadata>\n): Promise<void> {\n await client.request('POST', '/events', {\n body: input,\n });\n}\n","import { recordUserEvent, type Client } from '@chatsdet/sdk';\nimport type {\n CliCommandCompletedMetadata,\n CliCommandFailedMetadata,\n CliCommandInstrumentationFailedMetadata,\n CliCommandStartedMetadata,\n UserEventOrigin,\n UserEventPayloads,\n UserEventType,\n} from './types.js';\n\nexport interface UserEventRecorder {\n record<T extends UserEventType>(eventType: T, metadata: UserEventPayloads[T]): Promise<void>;\n recordCommandStarted(metadata: CliCommandStartedMetadata): Promise<void>;\n recordCommandCompleted(metadata: CliCommandCompletedMetadata): Promise<void>;\n recordCommandFailed(metadata: CliCommandFailedMetadata): Promise<void>;\n recordCommandInstrumentationFailed(\n metadata: CliCommandInstrumentationFailedMetadata\n ): Promise<void>;\n}\n\nexport function createUserEventRecorder(opts: {\n client: Client;\n origin: UserEventOrigin;\n onError?: (error: unknown) => void;\n}): UserEventRecorder {\n const safeRecord = async <T extends UserEventType>(\n eventType: T,\n metadata: UserEventPayloads[T]\n ): Promise<void> => {\n try {\n await recordUserEvent(opts.client, {\n eventType,\n origin: opts.origin,\n metadata,\n });\n } catch (error) {\n opts.onError?.(error);\n }\n };\n\n return {\n record: safeRecord,\n recordCommandStarted(metadata) {\n return safeRecord('command.started', metadata);\n },\n recordCommandCompleted(metadata) {\n return safeRecord('command.completed', metadata);\n },\n recordCommandFailed(metadata) {\n return safeRecord('command.failed', metadata);\n },\n recordCommandInstrumentationFailed(metadata) {\n return safeRecord('command.instrumentation-failed', metadata);\n },\n };\n}\n"],"mappings":"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","names":["process","process","process","process","res","data","process","resolveConfig","version","process","path","process","process"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/command-registry.ts","../src/debug-session.ts","../src/help.ts","../src/orgs.ts","../src/user-event-tracking.ts","../../sdk/src/errors.ts","../../sdk/src/client.ts","../../sdk/src/user-events.ts","../../user-events/src/recorder.ts"],"sourcesContent":["import process from 'node:process';\nimport { pathToFileURL } from 'node:url';\nimport { installConsoleBranding, version } from './brand.js';\nimport { COMMANDS_WITH_HELP, executeCommand, maybeCheckForUpdate } from './command-registry.js';\nimport { printVersion, showGlobalHelp } from './help.js';\nimport {\n ProcessExitSignal,\n createCliUserEventRecorder,\n isExpectedCliInputError,\n recordCliInstrumentationFailure,\n} from './user-event-tracking.js';\n\nfunction normalizeExitCode(value: string | number | null | undefined): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 1;\n }\n return 0;\n}\n\nexport async function main(argv: string[]) {\n // Rebrand human-readable output for the `cofactor` binary (no-op for\n // `canary`). Skipped for the `mcp` JSON-RPC transport and `--json`/`--format`\n // output so structured payloads are never rewritten — display branding only.\n const wantsMachineOutput = argv.includes('--json') || argv.includes('--format');\n if (argv[0] !== 'mcp' && !wantsMachineOutput) {\n installConsoleBranding();\n }\n\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 await showGlobalHelp();\n return;\n }\n\n if (!command || command === 'help') {\n await showGlobalHelp();\n return;\n }\n\n if (command === 'version') {\n printVersion();\n return;\n }\n\n // Non-blocking upgrade check — only for interactive humans logged in via\n // `canary login`. Never nag API-key auth (--token / *_API_TOKEN env var,\n // i.e. CI/automation) or machine-readable (`--json`/`--format`) runs, where\n // the banner is noise that can wrap structured output.\n if (command && !wantsMachineOutput) {\n await maybeCheckForUpdate(command, argv, version);\n }\n let tracking: Awaited<ReturnType<typeof createCliUserEventRecorder>> = null;\n try {\n tracking = await createCliUserEventRecorder(argv, version);\n } catch (error) {\n await recordCliInstrumentationFailure(argv, version, 'recorder-init', error);\n }\n const startedAt = Date.now();\n const originalExit = process.exit.bind(process);\n let finalExitCode = 0;\n let handledExpectedInputError = false;\n\n if (tracking) {\n await tracking.recorder.recordCommandStarted(tracking.metadata);\n }\n\n (process as typeof process & { exit: typeof process.exit }).exit = ((code?: number) => {\n throw new ProcessExitSignal(code ?? normalizeExitCode(process.exitCode));\n }) as typeof process.exit;\n\n try {\n await executeCommand(command, rest);\n finalExitCode = normalizeExitCode(process.exitCode);\n if (tracking) {\n const metadata = {\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n };\n if (finalExitCode === 0) {\n await tracking.recorder.recordCommandCompleted(metadata);\n } else {\n await tracking.recorder.recordCommandFailed({\n ...metadata,\n errorKind: 'exit-code',\n });\n }\n }\n } catch (error) {\n if (error instanceof ProcessExitSignal) {\n finalExitCode = error.exitCode;\n if (tracking) {\n const metadata = {\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n };\n if (finalExitCode === 0) {\n await tracking.recorder.recordCommandCompleted(metadata);\n } else {\n await tracking.recorder.recordCommandFailed({\n ...metadata,\n errorKind: 'process-exit',\n });\n }\n }\n } else {\n finalExitCode = normalizeExitCode(process.exitCode) || 1;\n const expectedInputError = isExpectedCliInputError(error);\n if (tracking) {\n await tracking.recorder.recordCommandFailed({\n ...tracking.metadata,\n durationMs: Date.now() - startedAt,\n exitCode: finalExitCode,\n errorKind: error instanceof Error ? error.name : typeof error,\n errorName: error instanceof Error ? error.name : undefined,\n errorMessage: error instanceof Error ? error.message : String(error),\n ...(expectedInputError\n ? {}\n : {\n reportToSentry: true,\n sentryFingerprint: [\n 'canary-cli',\n tracking.metadata.commandPath,\n error instanceof Error ? error.name : typeof error,\n ],\n }),\n });\n }\n if (expectedInputError) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n handledExpectedInputError = true;\n } else {\n throw error;\n }\n }\n } finally {\n (process as typeof process & { exit: typeof process.exit }).exit = originalExit;\n }\n\n if (finalExitCode !== 0 || handledExpectedInputError) {\n originalExit(finalExitCode);\n }\n}\n\nif (import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main(process.argv.slice(2));\n}\n","import process from 'node:process';\nimport { resolveAuthSource } from './auth';\nimport { runDebugSession } from './debug-session';\nimport { printTestHelp, resolveIsSuperadmin, showGlobalHelp } from './help.js';\nimport { runLogin } from './login';\nimport { runOrgs } from './orgs';\nimport { runRemoteTest } from './remote-test';\n\ntype CommandRunner = (rest: string[], command: string) => Promise<void>;\ntype CommandMetadataFlag = true | readonly string[];\n\nexport type CommandDefinition = {\n name: string;\n aliases?: readonly string[];\n updateCheck?: CommandMetadataFlag;\n handlesHelp?: CommandMetadataFlag;\n run: CommandRunner;\n};\n\n// Lazy-load playwright-dependent modules.\nconst loadMcp = () => import('./mcp').then((m) => m.runMcp);\nconst loadRecord = () => import('./record.js').then((m) => m.runRecord);\nconst loadSession = () => import('./session/index.js').then((m) => m.runSession);\nconst loadLocal = () => import('./local/index.js').then((m) => m.runLocal);\n\nasync function runDeprecatedTest(rest: string[]) {\n // Sub-command help\n if (rest.includes('--help') || rest.includes('-h')) {\n printTestHelp();\n return;\n }\n // Check for --remote flag — deprecated, forward to test-suite run\n if (rest.includes('--remote')) {\n console.warn(\n '\\x1b[33m⚠ `canary test --remote` is deprecated and will be removed in a future release.\\x1b[0m'\n );\n console.warn(' Use `canary test-suite run` instead.\\n');\n const remoteArgs = rest.filter((arg) => arg !== '--remote');\n await runRemoteTest(remoteArgs);\n return;\n }\n // Local Playwright test runner has been removed\n console.error(\n '`canary test` (local Playwright runner) has been removed.\\n' +\n 'Use `canary test-suite run` for remote workflow tests.\\n' +\n '\\n' +\n 'Examples:\\n' +\n ' canary test-suite run\\n' +\n ' canary test-suite run --tag smoke\\n' +\n ' canary test-suite run --property \"My App\" --environment staging'\n );\n process.exit(1);\n}\n\nasync function runSpec(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { handleSpec } = await import('./spec/index.js');\n // `validate` is purely offline — don't fail on missing auth config.\n const wantsAuth = rest[0] === 'compile' || rest[0] === 'pull' || rest[0] === 'diff';\n if (wantsAuth) {\n const { apiUrl, token } = await resolveConfig(rest);\n await handleSpec(rest, apiUrl, token);\n } else {\n await handleSpec(rest, '', '');\n }\n}\n\nasync function runAugmentorCommand(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { runAugmentor } = await import('./augmentor.js');\n // `help` is offline; everything else needs auth.\n if (rest[0] === undefined || rest[0] === 'help' || rest[0] === '--help') {\n await runAugmentor(rest, '', '');\n } else {\n const { apiUrl, token } = await resolveConfig(rest);\n await runAugmentor(rest, apiUrl, token);\n }\n}\n\nasync function runApiCatalogCommand(rest: string[]) {\n const { resolveConfig } = await import('./auth.js');\n const { runApiCatalog } = await import('./api-catalog.js');\n const { apiUrl, token } = await resolveConfig(rest);\n await runApiCatalog(rest, apiUrl, token);\n}\n\nasync function runStatusCommand(rest: string[], command: string) {\n // Superadmin-only. Gated client-side (the command talks to AWS directly,\n // not the cofactor API, so there is no server-side 403 to rely on). Treat\n // non-superadmins as if the command does not exist.\n if (!(await resolveIsSuperadmin())) {\n console.log(`Unknown command \"${command}\".`);\n await showGlobalHelp();\n process.exit(1);\n }\n const { runStatus } = await import('./status.js');\n await runStatus(rest);\n}\n\nasync function runAuthCommand(rest: string[]) {\n const sub = rest[0];\n if (sub === 'doctor') {\n const { runAuthDoctor } = await import('./doctor.js');\n await runAuthDoctor(rest.slice(1));\n return;\n }\n console.error('Usage: canary auth doctor [--env <env>]');\n process.exit(1);\n}\n\nexport const COMMAND_DEFINITIONS: readonly CommandDefinition[] = [\n {\n name: 'upgrade',\n run: async () => {\n const { runUpgrade } = await import('./upgrade.js');\n await runUpgrade();\n },\n },\n {\n name: 'test',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => runDeprecatedTest(rest),\n },\n {\n name: 'mcp',\n run: async (rest) => {\n const runMcp = await loadMcp();\n await runMcp(rest);\n },\n },\n {\n name: 'install',\n handlesHelp: true,\n run: async (rest) => {\n const { runInstall } = await import('./install.js');\n await runInstall(rest);\n },\n },\n {\n name: 'login',\n updateCheck: true,\n run: async (rest) => runLogin(rest),\n },\n {\n name: 'orgs',\n updateCheck: true,\n run: async (rest) => runOrgs(rest),\n },\n {\n name: 'record',\n updateCheck: true,\n run: async (rest) => {\n const runRecord = await loadRecord();\n await runRecord(rest);\n },\n },\n {\n name: 'session',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const runSession = await loadSession();\n await runSession(rest);\n },\n },\n {\n name: 'local',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const runLocal = await loadLocal();\n await runLocal(rest);\n },\n },\n {\n name: 'debug-session',\n run: async (rest) => runDebugSession(rest),\n },\n {\n name: 'psql',\n run: async (rest) => {\n const { runPsql } = await import('./psql.js');\n await runPsql(rest);\n },\n },\n {\n name: 'redis',\n run: async (rest) => {\n const { runRedis } = await import('./redis.js');\n await runRedis(rest);\n },\n },\n {\n name: 'release',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runRelease } = await import('./release.js');\n await runRelease(rest);\n },\n },\n {\n name: 'docs',\n run: async (rest) => {\n const { runDocs } = await import('./docs.js');\n await runDocs(rest);\n },\n },\n {\n name: 'feature-flag',\n run: async (rest) => {\n const { runFeatureFlag } = await import('./feature-flag.js');\n await runFeatureFlag(rest);\n },\n },\n {\n name: 'schedule',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runSchedule } = await import('./schedule.js');\n await runSchedule(rest);\n },\n },\n {\n name: 'alert',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runAlert } = await import('./alert.js');\n await runAlert(rest);\n },\n },\n {\n name: 'product',\n run: async (rest) => {\n const { runProduct } = await import('./product.js');\n await runProduct(rest);\n },\n },\n {\n name: 'metrics',\n run: async (rest) => {\n const { runMetrics } = await import('./metrics.js');\n await runMetrics(rest);\n },\n },\n {\n name: 'account',\n run: async (rest) => {\n const { runAccount } = await import('./account.js');\n await runAccount(rest);\n },\n },\n {\n name: 'scenario',\n aliases: ['scenarios'],\n run: async (rest) => {\n const { runScenarios } = await import('./scenarios.js');\n await runScenarios(rest);\n },\n },\n {\n name: 'knobs',\n run: async (rest) => {\n const { runKnobs } = await import('./knobs.js');\n await runKnobs(rest);\n },\n },\n {\n name: 'issues',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runIssues } = await import('./issues.js');\n await runIssues(rest);\n },\n },\n {\n name: 'credential',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runCredential } = await import('./credential.js');\n await runCredential(rest);\n },\n },\n {\n name: 'persona',\n aliases: ['personas', 'credential-template', 'credential-templates'],\n run: async (rest) => {\n const { runCredentialTemplate } = await import('./credential-template.js');\n await runCredentialTemplate(rest);\n },\n },\n {\n name: 'workflow',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runWorkflow } = await import('./workflow.js');\n await runWorkflow(rest);\n },\n },\n {\n name: 'spec',\n run: async (rest) => runSpec(rest),\n },\n {\n name: 'augmentor',\n aliases: ['augmentors'],\n run: async (rest) => runAugmentorCommand(rest),\n },\n {\n name: 'api-catalog',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => runApiCatalogCommand(rest),\n },\n {\n name: 'skill',\n aliases: ['skills'],\n updateCheck: ['skill', 'skills'],\n handlesHelp: ['skill', 'skills'],\n run: async (rest) => {\n const { runSkill } = await import('./skill.js');\n await runSkill(rest);\n },\n },\n {\n name: 'prompts',\n aliases: ['prompt'],\n handlesHelp: ['prompts', 'prompt'],\n run: async (rest) => {\n const { runPrompts } = await import('./prompts.js');\n await runPrompts(rest);\n },\n },\n {\n name: 'task',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runTask } = await import('./task.js');\n await runTask(rest);\n },\n },\n {\n name: 'test-suite',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runTestSuite } = await import('./test-suite.js');\n await runTestSuite(rest);\n },\n },\n {\n name: 'triage',\n run: async (rest) => {\n const { runTriage } = await import('./triage.js');\n await runTriage(rest);\n },\n },\n {\n // \"application\" is the user-facing name; \"property\" stays as a backwards-compat alias.\n name: 'application',\n aliases: ['applications', 'property', 'properties'],\n run: async (rest) => {\n const { runProperty } = await import('./property.js');\n await runProperty(rest);\n },\n },\n {\n name: 'environment',\n aliases: ['env'],\n run: async (rest) => {\n const { runEnvironment } = await import('./environment.js');\n await runEnvironment(rest);\n },\n },\n {\n name: 'sandbox',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runSandbox } = await import('./sandbox.js');\n await runSandbox(rest);\n },\n },\n {\n name: 'attachment',\n aliases: ['attachments'],\n updateCheck: ['attachment', 'attachments'],\n handlesHelp: ['attachment', 'attachments'],\n run: async (rest) => {\n const { runAttachment } = await import('./attachment.js');\n await runAttachment(rest);\n },\n },\n {\n name: 'utilities',\n updateCheck: true,\n handlesHelp: true,\n run: async (rest) => {\n const { runUtilities } = await import('./utilities.js');\n await runUtilities(rest);\n },\n },\n {\n name: 'tag',\n aliases: ['tags'],\n updateCheck: ['tag', 'tags'],\n handlesHelp: ['tag', 'tags'],\n run: async (rest) => {\n const { runTag } = await import('./tag.js');\n await runTag(rest);\n },\n },\n {\n name: 'trace',\n run: async (rest) => {\n const { runTrace } = await import('./trace.js');\n await runTrace(rest);\n },\n },\n {\n name: 'status',\n run: async (rest, command) => runStatusCommand(rest, command),\n },\n {\n name: 'auth',\n run: async (rest) => runAuthCommand(rest),\n },\n];\n\nfunction namesForMetadata(\n definition: CommandDefinition,\n value: CommandMetadataFlag | undefined\n): readonly string[] {\n if (value === true) return [definition.name];\n return value ?? [];\n}\n\nconst commandDefinitionMap = new Map<string, CommandDefinition>();\n\nfor (const definition of COMMAND_DEFINITIONS) {\n commandDefinitionMap.set(definition.name, definition);\n for (const alias of definition.aliases ?? []) {\n commandDefinitionMap.set(alias, definition);\n }\n}\n\n/** Commands that trigger the upgrade-available warning. */\nexport const COMMANDS_WITH_UPDATE_CHECK = new Set(\n COMMAND_DEFINITIONS.flatMap((definition) =>\n Array.from(namesForMetadata(definition, definition.updateCheck))\n )\n);\n\n/** Commands that handle --help themselves instead of showing global help. */\nexport const COMMANDS_WITH_HELP = new Set(\n COMMAND_DEFINITIONS.flatMap((definition) =>\n Array.from(namesForMetadata(definition, definition.handlesHelp))\n )\n);\n\nexport function getCommandDefinition(command: string): CommandDefinition | undefined {\n return commandDefinitionMap.get(command);\n}\n\nexport async function maybeCheckForUpdate(command: string, argv: string[], version: string) {\n if (!COMMANDS_WITH_UPDATE_CHECK.has(command)) return;\n if ((await resolveAuthSource(argv)) !== 'stored') return;\n\n const { checkForUpdate } = await import('./update-check.js');\n await checkForUpdate(version);\n}\n\nexport async function executeCommand(command: string, rest: string[]) {\n const definition = getCommandDefinition(command);\n if (!definition) {\n console.log(`Unknown command \"${command}\".`);\n await showGlobalHelp();\n process.exit(1);\n }\n\n await definition.run(rest, command);\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\";\nimport { fetchOrExit } from \"./api-fetch.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 fetchOrExit(`${apiUrl}/auth/debug-session/create`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n token,\n });\n\n // Handle HTTP errors before parsing JSON\n if (!res.ok) {\n const text = await res.text();\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","import { readAllStoredTokens, resolveOptionalConfig } from './auth';\nimport { version, readBrandEnv, specExtension } from './brand.js';\nimport { isSuperadminToken } from './jwt';\n\nexport function printVersion() {\n console.log(`canary v${version}`);\n}\n\nexport function printHelp({\n isSuperadmin,\n features = {},\n}: {\n isSuperadmin: boolean;\n features?: Record<string, boolean>;\n}) {\n const lines: string[] = [\n `canary v${version}: Testing and QA CLI`,\n '',\n 'Usage:',\n ' canary test-suite <sub-command> Run and query test suite results',\n ' canary mcp Start MCP server (stdio)',\n ' canary install [--target <id>] Install MCP server into Claude, Cursor, etc.',\n ' canary login [--org <name>] [--app-url https://app.trycanary.ai] [--no-open]',\n ' canary orgs [members] List organizations (or org members)',\n ' canary record [options] Record browser interactions',\n ' canary local <sub-command> Set up and manage local testing',\n ' canary session <sub-command> Manage local browser sessions',\n ' canary issues <sub-command> Search and view issues',\n ' canary credential <sub-command> List, create, update, and test credentials',\n ' canary persona <sub-command> Manage per-application personas',\n ' canary workflow <sub-command> Inspect workflow definitions',\n ` canary spec <sub-command> Author workflows from ${specExtension} spec files`,\n ' canary api-catalog <sub-command> Manage API catalog sources and endpoints',\n ' canary skill <name> Install an AI agent skill template (--name to rename)',\n ' canary prompts <list|get> Curated starter prompts for coding agents',\n ];\n\n lines.push(' canary release <sub-command> Release QA gate (CI/CD)');\n\n lines.push(\n ' canary application <sub-command> List and create applications, view linked repos (alias: property)',\n ' canary environment <sub-command> List, create, and default environments (alias: env)',\n ' canary sandbox <sub-command> Manage sandbox templates and instances',\n ' canary attachment <sub-command> List, upload, and manage attachments',\n ' canary tag <sub-command> List, create, and assign tags',\n ' canary triage <sub-command> Read AI triage results for a test suite execution',\n ' canary schedule suite <sub-command> Schedule recurring test-suite runs',\n ' canary alert <sub-command> Manage notify-only alerts (Slack/email)'\n );\n\n // Feature-gated agent commands — only listed when the signed-in org has the\n // backing feature flag (resolved from /me). Hidden otherwise so help never\n // advertises a command that returns 403.\n if (features.agentTasks) {\n lines.push(' canary task <sub-command> Manage agent tasks');\n }\n if (features.utilities) {\n lines.push(\n ' canary utilities <group> <sub> Object storage, gists, email/slack (agent toolkit)'\n );\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 docs <sub-command> Manage documentation pages',\n ' canary feature-flag <sub-command> Manage feature flags',\n ' canary knobs <sub-command> Manage knobs (global config)',\n ' canary product <sub-command> Manage the Product board (cards, fields, flag links)',\n ' canary metrics <sub-command> Manage product metrics (pull/review health metrics)',\n ' canary account <sub-command> Manage the Accounts board (accounts, org links)',\n ' canary status <sub-command> Publish incidents to the status page'\n );\n }\n\n lines.push(\n ' canary auth doctor [--env <env>] Diagnose auth / corporate-proxy issues',\n ' canary upgrade Upgrade CLI to latest version',\n ' canary version Show version',\n ' canary help',\n '',\n 'Test suite sub-commands:',\n ' run [options] Trigger a test suite and stream results',\n ' list [options] List recent test suites',\n ' get <id> [options] Show suite detail with runs',\n ' diagnostics <workflowId> <runId> Get failure diagnostic',\n ' steps <workflowId> <runId> Get workflow run steps',\n '',\n 'Test suite run options:',\n ' --token <key> API key (or set CANARY_API_TOKEN)',\n ' --api-url <url> API URL (default: https://api.trycanary.ai)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all events',\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 ' --application-id <uuid> Filter by application (alias: --property-id)',\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 --application-id <uuid> Trigger a Release QA run (alias: --property-id)',\n ' status <run-id> [--json] Check run status',\n ' run --application-id <uuid> [--timeout N] Trigger and poll until complete',\n '',\n 'Record options:',\n ' --credential <id> Credential ID (skip interactive selection)',\n ' --url <startUrl> URL to navigate to after launch',\n ' --output <dir> Local output directory (default: temp dir)',\n ' --env <env> Environment (local, dev, prod)',\n ' --no-upload Save locally only, skip API upload',\n ''\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 'Product board sub-commands (org you are logged into):',\n ' list [--search <t>] [--priority p0,p1] [--include-deprecated] List items',\n ' create <title> [--description <t>] [--stage <s>] [--priority <p0-p3>] Create item',\n ' set <id> [--title <t>] [--description <t>] [--priority <p0-p3|null>] Update fields',\n ' move <id> --stage <s> [--before <id>] [--after <id>] Move card to a column',\n ' delete <id> Delete item',\n ' customer add <id> (--account-card <id> | --org <orgId>) [--name <t>] Link customer',\n ' customer remove <id> <customerId> Unlink customer',\n ' link-flag <cardId> --flag <name> | --flag <name> --clear Link/unlink a feature flag',\n ' flags <cardId> List flags linked to a card',\n '',\n 'Account board sub-commands (org you are logged into):',\n ' list [--search <t>] [--stage <s>] List accounts',\n ' create <name> [--description <t>] [--stage <s>] Create account (default stage=prospect)',\n ' set <id> [--title <t>] [--description <t>] [--stage <s>] Update fields',\n ' delete <id> Delete account',\n ' link-org <id> --org <customerOrgId> Bind account to a customer org',\n ' unlink-org <id> Remove org link',\n ' linked-org <id> Show linked org'\n );\n }\n\n lines.push('', 'Flags:', ' -h, --help Show help', ' -V, --version Show version');\n\n console.log(lines.join('\\n'));\n}\n\nexport function printTestHelp() {\n console.log(\n [\n `canary v${version}: Test command`,\n '',\n '\\x1b[33m⚠ `canary test` is deprecated. Use `canary test-suite run` instead.\\x1b[0m',\n '',\n 'Usage:',\n ' canary test-suite run [options] Trigger a test suite and stream results',\n ' canary test-suite list List recent test suites',\n ' canary test-suite get <id> Show suite detail with runs',\n '',\n 'Run options:',\n ' --token <key> API key (or set CANARY_API_TOKEN)',\n ' --api-url <url> API URL (default: https://api.trycanary.ai)',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all events',\n '',\n 'Examples:',\n ' canary test-suite run Run all workflow tests',\n ' canary test-suite run --tag smoke Run smoke-tagged workflows',\n ' canary test-suite run --property \"My App\" --environment staging',\n ].join('\\n')\n );\n}\n\n/** Check if any stored profile (or env token) has superadmin privileges */\nexport async function resolveIsSuperadmin(): Promise<boolean> {\n const envToken = readBrandEnv('CANARY_API_TOKEN');\n if (envToken) return isSuperadminToken(envToken);\n\n const tokens = await readAllStoredTokens();\n return tokens.some((t) => isSuperadminToken(t));\n}\n\n/**\n * Best-effort fetch of the signed-in org's enabled feature flags (the same\n * `user.features` map the web app uses), so the global help can hide commands\n * for features the org doesn't have. Fail-closed: any error, timeout, or\n * missing auth yields `{}`, which hides feature-gated commands rather than\n * advertising something the org can't use. Never throws.\n */\nexport async function resolveOrgFeatures(): Promise<Record<string, boolean>> {\n try {\n const config = await resolveOptionalConfig([]);\n if (!config) return {};\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 3000);\n try {\n const res = await fetch(`${config.apiUrl}/me`, {\n headers: { Authorization: `Bearer ${config.token}` },\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json()) as { user?: { features?: Record<string, boolean> } };\n return body.user?.features ?? {};\n } finally {\n clearTimeout(timer);\n }\n } catch {\n return {};\n }\n}\n\n/** Resolve superadmin + org features in parallel, then print the global help. */\nexport async function showGlobalHelp(): Promise<void> {\n const [isSuperadmin, features] = await Promise.all([resolveIsSuperadmin(), resolveOrgFeatures()]);\n printHelp({ isSuperadmin, features });\n}\n","import process from 'node:process';\nimport {\n envToProfile,\n getArgValue,\n hasFlag,\n readStoredAuth,\n resolveConfig,\n} 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\ntype SuperadminOrgsResponse = {\n ok: boolean;\n organizations?: Array<{ id: string; name: string; memberCount?: number }>;\n error?: string;\n};\n\ntype OrgMembersResponse = {\n ok: boolean;\n error?: string;\n items?: Array<{\n userId: string;\n displayName: string | null;\n primaryEmail: string | null;\n role: string;\n isActive: boolean;\n slackLinked: boolean;\n }>;\n};\n\n/**\n * `cofactor org members` — list members of the current org, annotated with\n * whether each has linked their Slack user. Powers recipient lookup for the\n * `utilities email` / `utilities slack` commands.\n */\nasync function runOrgMembers(argv: string[]) {\n const { apiUrl, token } = await resolveConfig(argv);\n const res = await fetch(`${apiUrl}/org/members`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) {\n console.error('Failed to fetch members. You may need to re-login: cofactor login');\n process.exit(1);\n }\n const data = (await res.json()) as OrgMembersResponse;\n if (!data.ok || !data.items) {\n console.error('Failed to fetch members:', data.error ?? 'Unknown error');\n process.exit(1);\n }\n\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify(data.items, null, 2));\n return;\n }\n\n if (data.items.length === 0) {\n console.log('No members.');\n return;\n }\n console.log('Members (✓ = Slack-linked, can receive utilities slack DMs):\\n');\n for (const m of data.items) {\n const slack = m.slackLinked ? '✓' : ' ';\n const name = m.displayName ?? '(no name)';\n const email = m.primaryEmail ?? '(no email)';\n console.log(` ${slack} ${name} <${email}> [${m.role}]`);\n }\n}\n\nexport async function runOrgs(argv: string[]) {\n // `orgs members` is a sub-command; everything else lists organizations.\n const sub = argv.find((a) => !a.startsWith('-'));\n if (sub === 'members') {\n return runOrgMembers(argv.filter((a) => a !== 'members'));\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n // Read the same profile's stored auth so the \"* = current\" marker reflects\n // the profile we just resolved, not the default profile.\n const env = getArgValue(argv, '--env');\n const auth = await readStoredAuth(env ? envToProfile(env) : undefined);\n const showAll = hasFlag(argv, '--all');\n\n if (showAll) {\n // Superadmin: list all organizations\n const res = await fetch(`${apiUrl}/superadmin/organizations`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n if (res.status === 403) {\n console.error('Superadmin access required for --all');\n } else {\n console.error('Failed to fetch organizations. You may need to re-login: canary login');\n }\n process.exit(1);\n }\n\n const data = (await res.json()) as SuperadminOrgsResponse;\n if (!data.ok || !data.organizations) {\n console.error('Failed to fetch organizations:', data.error ?? 'Unknown error');\n process.exit(1);\n }\n\n console.log('All Organizations:\\n');\n for (const org of data.organizations) {\n const members = org.memberCount !== undefined && org.memberCount !== null ? ` (${org.memberCount} members)` : '';\n console.log(` ${org.name}${members} [${org.id}]`);\n }\n\n console.log(`\\nTotal: ${data.organizations.length} organizations`);\n return;\n }\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}) [${org.id}]${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 { createClient } from '@chatsdet/sdk';\nimport {\n createUserEventRecorder,\n type CliCommandBaseMetadata,\n type UserEventRecorder,\n} from '@chatsdet/user-events';\nimport { resolveOptionalConfig } from './auth.js';\nimport { debug } from './debug.js';\n\nconst SUBCOMMAND_COMMANDS = new Set([\n 'api-catalog',\n 'attachment',\n 'attachments',\n 'auth',\n 'credential',\n 'credential-template',\n 'credential-templates',\n 'docs',\n 'feature-flag',\n 'issues',\n 'knobs',\n 'local',\n 'property',\n 'release',\n 'sandbox',\n 'session',\n 'tag',\n 'tags',\n 'task',\n 'test-suite',\n 'workflow',\n]);\n\nconst UNTRACKED_COMMANDS = new Set(['help', 'upgrade', 'version']);\n\nexport class ProcessExitSignal extends Error {\n readonly exitCode: number;\n\n constructor(exitCode: number) {\n super(`Process exited with code ${exitCode}`);\n this.name = 'ProcessExitSignal';\n this.exitCode = exitCode;\n }\n}\n\nfunction shouldTrack(argv: string[]): boolean {\n const command = argv[0];\n if (!command || UNTRACKED_COMMANDS.has(command)) return false;\n if (argv.includes('--help') || argv.includes('-h')) return false;\n return true;\n}\n\nfunction getSubcommand(argv: string[]): string | undefined {\n const command = argv[0];\n if (!command || !SUBCOMMAND_COMMANDS.has(command)) return undefined;\n const candidate = argv[1];\n if (!candidate || candidate.startsWith('-')) return undefined;\n return candidate;\n}\n\nfunction getApiHost(apiUrl: string): string | undefined {\n try {\n return new URL(apiUrl).host;\n } catch {\n return undefined;\n }\n}\n\nfunction getArgNames(argv: string[]): string[] {\n return argv.filter((arg) => arg.startsWith('-'));\n}\n\nfunction buildBaseMetadata(argv: string[], cliVersion: string, apiUrl: string): CliCommandBaseMetadata {\n const topLevelCommand = argv[0] ?? 'unknown';\n const subcommand = getSubcommand(argv);\n return {\n commandPath: subcommand ? `${topLevelCommand} ${subcommand}` : topLevelCommand,\n topLevelCommand,\n subcommand,\n cliVersion,\n apiHost: getApiHost(apiUrl),\n isInteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n args: getArgNames(argv),\n };\n}\n\nfunction errorMetadata(error: unknown): {\n errorKind: string;\n errorName?: string;\n errorMessage: string;\n} {\n return {\n errorKind: error instanceof Error ? error.name : typeof error,\n errorName: error instanceof Error ? error.name : undefined,\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n}\n\nexport function isExpectedCliInputError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n return /^Action index \\d+ out of range \\(0-\\d+\\)$/.test(error.message);\n}\n\nexport async function createCliUserEventRecorder(\n argv: string[],\n cliVersion: string\n): Promise<{ recorder: UserEventRecorder; metadata: CliCommandBaseMetadata } | null> {\n if (!shouldTrack(argv)) return null;\n\n // Not every command uses resolveConfig() yet. Until CLI config resolution is\n // centralized, tracking can target a different backend than the command body.\n const config = await resolveOptionalConfig(argv);\n if (!config) return null;\n\n const client = createClient({\n baseUrl: config.apiUrl,\n token: config.token,\n });\n\n return {\n recorder: createUserEventRecorder({\n client,\n origin: 'cli',\n onError: (error: unknown) => {\n // Tracking is best-effort diagnostics and must never affect command\n // execution or pollute output (e.g. wrap `--json` payloads). Stay silent\n // unless the user opted into debug logging.\n const message = error instanceof Error ? error.message : String(error);\n debug(`user event tracking skipped: ${message}`);\n },\n }),\n metadata: buildBaseMetadata(argv, cliVersion, config.apiUrl),\n };\n}\n\nexport async function recordCliInstrumentationFailure(\n argv: string[],\n cliVersion: string,\n stage: 'recorder-init' | 'record-started' | 'record-completed' | 'record-failed',\n error: unknown\n): Promise<void> {\n if (!shouldTrack(argv)) return;\n\n try {\n const config = await resolveOptionalConfig(argv);\n if (!config) return;\n\n const client = createClient({\n baseUrl: config.apiUrl,\n token: config.token,\n });\n const recorder = createUserEventRecorder({\n client,\n origin: 'cli',\n });\n await recorder.recordCommandInstrumentationFailed({\n ...buildBaseMetadata(argv, cliVersion, config.apiUrl),\n stage,\n ...errorMetadata(error),\n reportToSentry: true,\n sentryFingerprint: ['canary-cli', 'instrumentation-failed', stage],\n });\n } catch {\n // Diagnostics must never affect command execution.\n }\n}\n\nexport const __internals = {\n getArgNames,\n getSubcommand,\n isExpectedCliInputError,\n shouldTrack,\n};\n","/**\n * Error classes thrown by the SDK. Callers match on these rather than\n * parsing raw HTTP responses.\n */\n\nexport interface ApiErrorBody {\n ok?: false;\n error?: string;\n userError?: boolean;\n code?: string;\n details?: unknown;\n}\n\nexport class SdkError extends Error {\n readonly status: number;\n readonly body: ApiErrorBody | undefined;\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message);\n this.name = 'SdkError';\n this.status = status;\n this.body = body;\n }\n}\n\nexport class AuthError extends SdkError {\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message, status, body);\n this.name = 'AuthError';\n }\n}\n\nexport class ValidationError extends SdkError {\n constructor(message: string, status: number, body?: ApiErrorBody) {\n super(message, status, body);\n this.name = 'ValidationError';\n }\n}\n\n/** Build the right error subtype for an HTTP status. */\nexport function errorFromResponse(\n status: number,\n body: ApiErrorBody | undefined\n): SdkError {\n const message = body?.error ?? `Request failed with status ${status}`;\n if (status === 401 || status === 403) return new AuthError(message, status, body);\n if (status === 400 || status === 422) return new ValidationError(message, status, body);\n return new SdkError(message, status, body);\n}\n","/**\n * Minimal, typed `fetch` wrapper that all SDK resource modules go through.\n *\n * Design:\n * - Exactly one HTTP call site. Auth header + content-type + error\n * shaping live here; resource modules are thin method wrappers.\n * - No dependency on a generated OpenAPI types file yet — the typed\n * `paths` map will plug in via `client.GET<'/some/path'>(...)` once\n * `scripts/generate-types.ts` is wired up.\n */\nimport { errorFromResponse, type ApiErrorBody } from './errors.js';\n\nexport interface ClientConfig {\n /** API base URL, e.g. `https://api.trycanary.ai` — no trailing slash. */\n baseUrl: string;\n /**\n * Bearer token (JWT) or API key. A function is accepted so callers\n * can refresh on 401 without reconstructing the client.\n */\n token?: string | (() => string | Promise<string>);\n /** Custom fetch implementation (tests, proxies). Defaults to global. */\n fetch?: typeof fetch;\n /** Additional default headers merged into every request. */\n headers?: Record<string, string>;\n}\n\nexport interface RequestOptions {\n /** Path params substituted into `:name` placeholders in the URL. */\n params?: Record<string, string | number>;\n /** Query params appended to the URL. */\n query?: Record<string, string | number | boolean | undefined | null>;\n /** JSON body (stringified automatically). */\n body?: unknown;\n /** Per-request header overrides. */\n headers?: Record<string, string>;\n /** AbortSignal forwarded to fetch. */\n signal?: AbortSignal;\n}\n\nexport interface Client {\n readonly baseUrl: string;\n request<T = unknown>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n opts?: RequestOptions\n ): Promise<T>;\n /** Replace the stored token (e.g. after org switch). */\n setToken(token: string | (() => string | Promise<string>) | undefined): void;\n}\n\nfunction interpolate(path: string, params: Record<string, string | number> | undefined): string {\n if (!params) return path;\n return path.replace(/:([A-Za-z0-9_]+)/g, (_, k: string) => {\n const v = params[k];\n if (v === undefined) throw new Error(`Missing path param :${k} for ${path}`);\n return encodeURIComponent(String(v));\n });\n}\n\nfunction buildQuery(q: RequestOptions['query']): string {\n if (!q) return '';\n const usp = new URLSearchParams();\n for (const [k, v] of Object.entries(q)) {\n if (v === undefined || v === null) continue;\n usp.set(k, String(v));\n }\n const s = usp.toString();\n return s ? `?${s}` : '';\n}\n\nexport function createClient(cfg: ClientConfig): Client {\n let token = cfg.token;\n const fetchImpl = cfg.fetch ?? fetch;\n\n async function resolveToken(): Promise<string | undefined> {\n if (typeof token === 'function') return token();\n return token;\n }\n\n async function request<T>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n opts: RequestOptions = {}\n ): Promise<T> {\n const url =\n cfg.baseUrl.replace(/\\/$/, '') +\n interpolate(path, opts.params) +\n buildQuery(opts.query);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...cfg.headers,\n ...opts.headers,\n };\n const resolvedToken = await resolveToken();\n if (resolvedToken && !headers.authorization) {\n headers.authorization = `Bearer ${resolvedToken}`;\n }\n if (opts.body !== undefined && !headers['content-type']) {\n headers['content-type'] = 'application/json';\n }\n\n const res = await fetchImpl(url, {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n signal: opts.signal,\n });\n\n const text = await res.text();\n let parsed: unknown;\n if (text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const body = (parsed && typeof parsed === 'object' ? parsed : undefined) as\n | ApiErrorBody\n | undefined;\n throw errorFromResponse(res.status, body);\n }\n return parsed as T;\n }\n\n return {\n get baseUrl() {\n return cfg.baseUrl;\n },\n request,\n setToken(next) {\n token = next;\n },\n };\n}\n","import type { Client } from './client.js';\n\nexport interface RecordUserEventInput<\n Origin extends string = string,\n Metadata = Record<string, unknown>,\n> {\n eventType: string;\n origin: Origin;\n metadata: Metadata;\n}\n\nexport async function recordUserEvent<\n Origin extends string = string,\n Metadata = Record<string, unknown>,\n>(\n client: Client,\n input: RecordUserEventInput<Origin, Metadata>\n): Promise<void> {\n await client.request('POST', '/events', {\n body: input,\n });\n}\n","import { recordUserEvent, type Client } from '@chatsdet/sdk';\nimport type {\n CliCommandCompletedMetadata,\n CliCommandFailedMetadata,\n CliCommandInstrumentationFailedMetadata,\n CliCommandStartedMetadata,\n UserEventOrigin,\n UserEventPayloads,\n UserEventType,\n} from './types.js';\n\nexport interface UserEventRecorder {\n record<T extends UserEventType>(eventType: T, metadata: UserEventPayloads[T]): Promise<void>;\n recordCommandStarted(metadata: CliCommandStartedMetadata): Promise<void>;\n recordCommandCompleted(metadata: CliCommandCompletedMetadata): Promise<void>;\n recordCommandFailed(metadata: CliCommandFailedMetadata): Promise<void>;\n recordCommandInstrumentationFailed(\n metadata: CliCommandInstrumentationFailedMetadata\n ): Promise<void>;\n}\n\nexport function createUserEventRecorder(opts: {\n client: Client;\n origin: UserEventOrigin;\n onError?: (error: unknown) => void;\n}): UserEventRecorder {\n const safeRecord = async <T extends UserEventType>(\n eventType: T,\n metadata: UserEventPayloads[T]\n ): Promise<void> => {\n try {\n await recordUserEvent(opts.client, {\n eventType,\n origin: opts.origin,\n metadata,\n });\n } catch (error) {\n opts.onError?.(error);\n }\n };\n\n return {\n record: safeRecord,\n recordCommandStarted(metadata) {\n return safeRecord('command.started', metadata);\n },\n recordCommandCompleted(metadata) {\n return safeRecord('command.completed', metadata);\n },\n recordCommandFailed(metadata) {\n return safeRecord('command.failed', metadata);\n },\n recordCommandInstrumentationFailed(metadata) {\n return safeRecord('command.instrumentation-failed', metadata);\n },\n };\n}\n"],"mappings":"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","names":["process","process","process","process","res","data","process","resolveConfig","version","process","path","process","process"]}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
|
|
2
|
+
import {
|
|
3
|
+
apiRequest
|
|
4
|
+
} from "./chunk-SZOPRIBA.js";
|
|
5
|
+
import "./chunk-H3LWYSKY.js";
|
|
6
|
+
import {
|
|
7
|
+
getArgValue,
|
|
8
|
+
hasFlag,
|
|
9
|
+
resolveConfig
|
|
10
|
+
} from "./chunk-ZPPG4MGR.js";
|
|
11
|
+
import "./chunk-S3Q7MDCS.js";
|
|
12
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
13
|
+
import "./chunk-ZSOAFMES.js";
|
|
14
|
+
import "./chunk-ICKB3EOT.js";
|
|
15
|
+
|
|
16
|
+
// src/prompts.ts
|
|
17
|
+
import fs from "fs/promises";
|
|
18
|
+
import path from "path";
|
|
19
|
+
import process from "process";
|
|
20
|
+
function printHelp() {
|
|
21
|
+
const lines = [
|
|
22
|
+
"Curated starter prompts for coding agents.",
|
|
23
|
+
"",
|
|
24
|
+
"Usage:",
|
|
25
|
+
" canary prompts list [--json] List global + your org prompts",
|
|
26
|
+
" canary prompts get <slug|id> [--json|--raw] Print a prompt (markdown to stdout)",
|
|
27
|
+
" canary prompts create [<file>|--stdin] --title <t> [--description <d>] [--global] [--json]",
|
|
28
|
+
" canary prompts delete <id> Delete one of your org prompts",
|
|
29
|
+
"",
|
|
30
|
+
"Notes:",
|
|
31
|
+
" --global creates/edits a Cofactor-wide prompt (superadmin only).",
|
|
32
|
+
"",
|
|
33
|
+
"Examples:",
|
|
34
|
+
" canary prompts list",
|
|
35
|
+
" canary prompts get install-cli",
|
|
36
|
+
' canary prompts create recipe.md --title "Set up CI"',
|
|
37
|
+
' cat recipe.md | canary prompts create --stdin --title "Set up CI"'
|
|
38
|
+
];
|
|
39
|
+
console.log(lines.join("\n"));
|
|
40
|
+
}
|
|
41
|
+
async function readStdin() {
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
|
|
44
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
45
|
+
}
|
|
46
|
+
async function promptsList(argv, apiUrl, token) {
|
|
47
|
+
const result = await apiRequest(
|
|
48
|
+
apiUrl,
|
|
49
|
+
token,
|
|
50
|
+
"GET",
|
|
51
|
+
"/prompts"
|
|
52
|
+
);
|
|
53
|
+
if (!result.ok) {
|
|
54
|
+
console.error(`Error: ${result.error ?? "failed to list prompts"}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
if (hasFlag(argv, "--json")) {
|
|
58
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (result.data.length === 0) {
|
|
62
|
+
console.log("No prompts.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const slugWidth = Math.max(...result.data.map((p) => p.slug.length));
|
|
66
|
+
console.log("Available prompts:\n");
|
|
67
|
+
for (const p of result.data) {
|
|
68
|
+
const tag = p.scope === "global" ? "[global]" : "[org] ";
|
|
69
|
+
console.log(` ${tag} ${p.slug.padEnd(slugWidth)} ${p.title}`);
|
|
70
|
+
if (p.description) console.log(` ${" ".repeat(slugWidth)} ${p.description}`);
|
|
71
|
+
}
|
|
72
|
+
console.log("\nPrint one with: canary prompts get <slug>");
|
|
73
|
+
}
|
|
74
|
+
async function promptsGet(argv, apiUrl, token) {
|
|
75
|
+
const idOrSlug = argv.find((a) => !a.startsWith("-"));
|
|
76
|
+
if (!idOrSlug) {
|
|
77
|
+
console.error("Error: missing prompt. Usage: canary prompts get <slug|id> [--raw|--json]");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const result = await apiRequest(
|
|
81
|
+
apiUrl,
|
|
82
|
+
token,
|
|
83
|
+
"GET",
|
|
84
|
+
`/prompts/${encodeURIComponent(idOrSlug)}`
|
|
85
|
+
);
|
|
86
|
+
if (!result.ok || !result.data) {
|
|
87
|
+
console.error(`Error: ${result.error ?? "prompt not found"}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
if (hasFlag(argv, "--json")) {
|
|
91
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(result.data.content);
|
|
95
|
+
}
|
|
96
|
+
async function promptsCreate(argv, apiUrl, token) {
|
|
97
|
+
const filePath = argv[0] && !argv[0].startsWith("-") ? argv[0] : void 0;
|
|
98
|
+
const inline = getArgValue(argv, "--content");
|
|
99
|
+
let content;
|
|
100
|
+
if (hasFlag(argv, "--stdin")) {
|
|
101
|
+
content = await readStdin();
|
|
102
|
+
} else if (inline !== void 0) {
|
|
103
|
+
content = inline;
|
|
104
|
+
} else if (filePath) {
|
|
105
|
+
try {
|
|
106
|
+
content = await fs.readFile(filePath, "utf-8");
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error(
|
|
109
|
+
`Error: failed to read ${filePath}: ${err instanceof Error ? err.message : err}`
|
|
110
|
+
);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
console.error("Error: provide content via a <file> arg, --stdin, or --content <text>.");
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
const title = getArgValue(argv, "--title") ?? (filePath ? path.basename(filePath).replace(/\.[^.]+$/, "") : void 0);
|
|
118
|
+
if (!title) {
|
|
119
|
+
console.error("Error: a title is required. Pass --title <t>.");
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const description = getArgValue(argv, "--description");
|
|
123
|
+
const scope = hasFlag(argv, "--global") ? "global" : "org";
|
|
124
|
+
const result = await apiRequest(
|
|
125
|
+
apiUrl,
|
|
126
|
+
token,
|
|
127
|
+
"POST",
|
|
128
|
+
"/prompts",
|
|
129
|
+
{ title, content, scope, ...description ? { description } : {} }
|
|
130
|
+
);
|
|
131
|
+
if (!result.ok || !result.data) {
|
|
132
|
+
console.error(`Error: ${result.error ?? "failed to create prompt"}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
if (hasFlag(argv, "--json")) {
|
|
136
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
console.log(`\u2713 Created ${result.data.scope} prompt "${result.data.title}"`);
|
|
140
|
+
console.log(` slug: ${result.data.slug}`);
|
|
141
|
+
console.log(` id: ${result.data.id}`);
|
|
142
|
+
}
|
|
143
|
+
async function promptsDelete(argv, apiUrl, token) {
|
|
144
|
+
const id = argv.find((a) => !a.startsWith("-"));
|
|
145
|
+
if (!id) {
|
|
146
|
+
console.error("Error: missing prompt id. Usage: canary prompts delete <id>");
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
const result = await apiRequest(
|
|
150
|
+
apiUrl,
|
|
151
|
+
token,
|
|
152
|
+
"DELETE",
|
|
153
|
+
`/prompts/${encodeURIComponent(id)}`
|
|
154
|
+
);
|
|
155
|
+
if (!result.ok) {
|
|
156
|
+
console.error(`Error: ${result.error ?? "failed to delete prompt"}`);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
console.log("\u2713 Deleted prompt");
|
|
160
|
+
}
|
|
161
|
+
async function runPrompts(argv) {
|
|
162
|
+
const [sub, ...rest] = argv;
|
|
163
|
+
if (!sub || sub === "help" || hasFlag(argv, "--help", "-h")) {
|
|
164
|
+
printHelp();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const { apiUrl, token } = await resolveConfig(rest);
|
|
168
|
+
switch (sub) {
|
|
169
|
+
case "list":
|
|
170
|
+
return promptsList(rest, apiUrl, token);
|
|
171
|
+
case "get":
|
|
172
|
+
return promptsGet(rest, apiUrl, token);
|
|
173
|
+
case "create":
|
|
174
|
+
return promptsCreate(rest, apiUrl, token);
|
|
175
|
+
case "delete":
|
|
176
|
+
return promptsDelete(rest, apiUrl, token);
|
|
177
|
+
default:
|
|
178
|
+
console.error(`Unknown prompts subcommand: ${sub}`);
|
|
179
|
+
printHelp();
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export {
|
|
184
|
+
runPrompts
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=prompts-NKJEQ62J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/prompts.ts"],"sourcesContent":["/**\n * CLI Prompt Library\n *\n * Browse and manage the Prompt Library from the terminal — curated,\n * agent-agnostic starter prompts. Lists Cofactor's GLOBAL prompts plus your\n * org's prompts; create/delete your org's prompts (and, as a superadmin,\n * GLOBAL ones with `--global`). Backed by the `/prompts` API.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\ntype PromptScope = 'global' | 'org';\n\ninterface PromptSummary {\n id: string;\n slug: string;\n title: string;\n description: string | null;\n scope: PromptScope;\n}\n\ninterface PromptDetail extends PromptSummary {\n content: string;\n}\n\nfunction printHelp(): void {\n const lines = [\n 'Curated starter prompts for coding agents.',\n '',\n 'Usage:',\n ' canary prompts list [--json] List global + your org prompts',\n ' canary prompts get <slug|id> [--json|--raw] Print a prompt (markdown to stdout)',\n ' canary prompts create [<file>|--stdin] --title <t> [--description <d>] [--global] [--json]',\n ' canary prompts delete <id> Delete one of your org prompts',\n '',\n 'Notes:',\n ' --global creates/edits a Cofactor-wide prompt (superadmin only).',\n '',\n 'Examples:',\n ' canary prompts list',\n ' canary prompts get install-cli',\n ' canary prompts create recipe.md --title \"Set up CI\"',\n ' cat recipe.md | canary prompts create --stdin --title \"Set up CI\"',\n ];\n console.log(lines.join('\\n'));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nasync function promptsList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const result = await apiRequest<{ ok: boolean; error?: string; data: PromptSummary[] }>(\n apiUrl,\n token,\n 'GET',\n '/prompts'\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'failed to list prompts'}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n if (result.data.length === 0) {\n console.log('No prompts.');\n return;\n }\n const slugWidth = Math.max(...result.data.map((p) => p.slug.length));\n console.log('Available prompts:\\n');\n for (const p of result.data) {\n const tag = p.scope === 'global' ? '[global]' : '[org] ';\n console.log(` ${tag} ${p.slug.padEnd(slugWidth)} ${p.title}`);\n if (p.description) console.log(` ${' '.repeat(slugWidth)} ${p.description}`);\n }\n console.log('\\nPrint one with: canary prompts get <slug>');\n}\n\nasync function promptsGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const idOrSlug = argv.find((a) => !a.startsWith('-'));\n if (!idOrSlug) {\n console.error('Error: missing prompt. Usage: canary prompts get <slug|id> [--raw|--json]');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string; data?: PromptDetail }>(\n apiUrl,\n token,\n 'GET',\n `/prompts/${encodeURIComponent(idOrSlug)}`\n );\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'prompt not found'}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n // Raw markdown to stdout so it pastes cleanly into an agent.\n console.log(result.data.content);\n}\n\nasync function promptsCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n // A positional file is only the FIRST arg (`prompts create <file> …`); anything\n // else is a flag (or a flag's value, e.g. `--title \"Set up CI\"`) and must not be\n // mistaken for a path.\n const filePath = argv[0] && !argv[0].startsWith('-') ? argv[0] : undefined;\n const inline = getArgValue(argv, '--content');\n let content: string;\n if (hasFlag(argv, '--stdin')) {\n content = await readStdin();\n } else if (inline !== undefined) {\n content = inline;\n } else if (filePath) {\n try {\n content = await fs.readFile(filePath, 'utf-8');\n } catch (err) {\n console.error(\n `Error: failed to read ${filePath}: ${err instanceof Error ? err.message : err}`\n );\n process.exit(1);\n }\n } else {\n console.error('Error: provide content via a <file> arg, --stdin, or --content <text>.');\n process.exit(1);\n }\n\n const title =\n getArgValue(argv, '--title') ??\n (filePath ? path.basename(filePath).replace(/\\.[^.]+$/, '') : undefined);\n if (!title) {\n console.error('Error: a title is required. Pass --title <t>.');\n process.exit(1);\n }\n const description = getArgValue(argv, '--description');\n const scope = hasFlag(argv, '--global') ? 'global' : 'org';\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: PromptDetail }>(\n apiUrl,\n token,\n 'POST',\n '/prompts',\n { title, content, scope, ...(description ? { description } : {}) }\n );\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'failed to create prompt'}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n console.log(`✓ Created ${result.data.scope} prompt \"${result.data.title}\"`);\n console.log(` slug: ${result.data.slug}`);\n console.log(` id: ${result.data.id}`);\n}\n\nasync function promptsDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing prompt id. Usage: canary prompts delete <id>');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/prompts/${encodeURIComponent(id)}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'failed to delete prompt'}`);\n process.exit(1);\n }\n console.log('✓ Deleted prompt');\n}\n\nexport async function runPrompts(argv: string[]): Promise<void> {\n const [sub, ...rest] = argv;\n\n if (!sub || sub === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(rest);\n\n switch (sub) {\n case 'list':\n return promptsList(rest, apiUrl, token);\n case 'get':\n return promptsGet(rest, apiUrl, token);\n case 'create':\n return promptsCreate(rest, apiUrl, token);\n case 'delete':\n return promptsDelete(rest, apiUrl, token);\n default:\n console.error(`Unknown prompts subcommand: ${sub}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
|