@canaryai/cli 0.2.13 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{chunk-Z3F373YR.js → chunk-4A4G5KTC.js} +2 -1
  2. package/dist/chunk-4A4G5KTC.js.map +1 -0
  3. package/dist/{chunk-IFOJT3A5.js → chunk-6IAPGYZQ.js} +38 -16
  4. package/dist/{chunk-IFOJT3A5.js.map → chunk-6IAPGYZQ.js.map} +1 -1
  5. package/dist/{chunk-SVU2XTYZ.js → chunk-ZQF72UTG.js} +2 -2
  6. package/dist/{debug-workflow-K2LL6CO4.js → debug-workflow-DIQZDFMN.js} +3 -3
  7. package/dist/{docs-SR7CW24Y.js → docs-CSVSGIGW.js} +45 -2
  8. package/dist/docs-CSVSGIGW.js.map +1 -0
  9. package/dist/index.js +8 -8
  10. package/dist/{init-KXAVWHYE.js → init-BTDX5N6P.js} +2 -2
  11. package/dist/{local-34FX3M5K.js → local-ZPVM4BXX.js} +4 -4
  12. package/dist/{local-browser-VPOSJS52.js → local-browser-WV4IH2DU.js} +3 -3
  13. package/dist/{login-MSIM2VIH.js → login-W4GXV3VA.js} +2 -2
  14. package/dist/{mcp-YBR7G254.js → mcp-YER5GQG7.js} +4 -4
  15. package/dist/{record-DXXQHPGT.js → record-KRS2PHMW.js} +2 -2
  16. package/dist/{session-XQGCLWNC.js → session-CLWAVJ2K.js} +3 -3
  17. package/dist/{src-F7LQ5PY2.js → src-WLOHOI6P.js} +2 -2
  18. package/dist/{start-ZOMUD6LW.js → start-CNNQUP5I.js} +2 -2
  19. package/dist/{workflow-5UZTKX7X.js → workflow-XXL4H5R4.js} +3 -2
  20. package/dist/workflow-XXL4H5R4.js.map +1 -0
  21. package/package.json +1 -1
  22. package/dist/chunk-Z3F373YR.js.map +0 -1
  23. package/dist/docs-SR7CW24Y.js.map +0 -1
  24. package/dist/workflow-5UZTKX7X.js.map +0 -1
  25. /package/dist/{chunk-SVU2XTYZ.js.map → chunk-ZQF72UTG.js.map} +0 -0
  26. /package/dist/{debug-workflow-K2LL6CO4.js.map → debug-workflow-DIQZDFMN.js.map} +0 -0
  27. /package/dist/{init-KXAVWHYE.js.map → init-BTDX5N6P.js.map} +0 -0
  28. /package/dist/{local-34FX3M5K.js.map → local-ZPVM4BXX.js.map} +0 -0
  29. /package/dist/{local-browser-VPOSJS52.js.map → local-browser-WV4IH2DU.js.map} +0 -0
  30. /package/dist/{login-MSIM2VIH.js.map → login-W4GXV3VA.js.map} +0 -0
  31. /package/dist/{mcp-YBR7G254.js.map → mcp-YER5GQG7.js.map} +0 -0
  32. /package/dist/{record-DXXQHPGT.js.map → record-KRS2PHMW.js.map} +0 -0
  33. /package/dist/{session-XQGCLWNC.js.map → session-CLWAVJ2K.js.map} +0 -0
  34. /package/dist/{src-F7LQ5PY2.js.map → src-WLOHOI6P.js.map} +0 -0
  35. /package/dist/{start-ZOMUD6LW.js.map → start-CNNQUP5I.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/workflow.ts","../src/workflow-create.ts"],"sourcesContent":["/**\n * CLI Workflow Management\n *\n * Inspect workflow definitions and steps from the terminal.\n */\n\nimport fs from 'node:fs/promises';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { handleWorkflowCreate } from './workflow-create.js';\n\n/* ── Types ────────────────────────────────────────────────────────────── */\n\ntype WorkflowNode = {\n id: string;\n nodeType: string;\n orderIndex: number;\n configJson: Record<string, unknown>;\n};\n\ntype WorkflowSummary = {\n id: string;\n name: string;\n description: string | null;\n status: string;\n flowType: string;\n nodes: WorkflowNode[];\n edges: unknown[];\n};\n\ntype Pagination = {\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n};\n\ntype WorkflowListItem = {\n id: string;\n name: string;\n status: string;\n flowType: string;\n nodeCount?: number;\n};\n\ntype WorkflowListResponse = {\n ok: boolean;\n error?: string;\n data: WorkflowListItem[];\n pagination: Pagination;\n};\n\ntype WorkflowDetailResponse = {\n ok?: boolean;\n error?: string;\n workflow?: WorkflowSummary;\n targetOrgId?: string;\n targetOrgName?: string;\n};\n\n/* ── Node Helpers ─────────────────────────────────────────────────────── */\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return text.slice(0, max - 1) + '…';\n}\n\nfunction getNodeTitle(node: WorkflowNode): string {\n const c = node.configJson;\n switch (node.nodeType) {\n case 'login':\n return (c.credentialName as string) || 'Login';\n case 'navigate':\n return (c.pageTitle as string) || truncate((c.pageUrl as string) || 'Navigate', 40);\n case 'action':\n return (\n (c.customActionTitle as string) || truncate((c.actionDescription as string) || 'Action', 50)\n );\n case 'assertion':\n return truncate((c.condition as string) || 'Assertion', 50);\n case 'setup':\n return (c.setupFlowName as string) || 'Setup';\n case 'seed':\n return (c.seedWorkflowName as string) || 'Seed';\n case 'wait':\n return 'Wait';\n case 'condition':\n return truncate((c.conditionDescription as string) || 'Condition', 50);\n case 'end':\n return 'End';\n case 'api_sequence':\n return 'API Sequence';\n default:\n return node.nodeType;\n }\n}\n\nfunction getCleanConfig(node: WorkflowNode): Record<string, unknown> {\n const c = node.configJson;\n switch (node.nodeType) {\n case 'login':\n return pick(c, ['credentialName', 'performLogin']);\n case 'navigate':\n return {\n ...pick(c, ['pageUrl', 'pageTitle']),\n ...(c.openInNewTab ? { openInNewTab: true } : {}),\n };\n case 'action':\n return pick(c, [\n 'actionDescription',\n 'customActionInstructions',\n 'playbookSteps',\n 'inputValues',\n 'declaredOutputs',\n ]);\n case 'assertion':\n return pick(c, ['condition', 'expectedOutcome', 'strict', 'alwaysUseAgent']);\n case 'setup':\n return pick(c, ['setupFlowId', 'setupFlowName']);\n case 'seed':\n return pick(c, ['seedWorkflowId', 'seedWorkflowName', 'snapshotVersion']);\n case 'end':\n return pick(c, ['outcome']);\n case 'wait':\n case 'condition':\n case 'api_sequence':\n return c;\n default:\n return c;\n }\n}\n\nfunction pick(obj: Record<string, unknown>, keys: string[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const key of keys) {\n if (obj[key] !== undefined && obj[key] !== null) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/* ── Markdown Formatter ───────────────────────────────────────────────── */\n\nfunction formatWorkflowMarkdown(workflow: WorkflowSummary): string {\n const sections: string[] = [];\n\n sections.push(`# ${workflow.name}`);\n const meta = [\n `**ID:** ${workflow.id}`,\n `**Status:** ${workflow.status}`,\n `**Type:** ${workflow.flowType}`,\n ];\n sections.push(meta.join(' | '));\n\n if (workflow.description) {\n sections.push(`**Description:** ${workflow.description}`);\n }\n\n sections.push('---');\n\n const sorted = [...workflow.nodes].sort((a, b) => a.orderIndex - b.orderIndex);\n\n for (let i = 0; i < sorted.length; i++) {\n const node = sorted[i];\n const title = getNodeTitle(node);\n const stepLines: string[] = [];\n\n stepLines.push(`## Step ${i + 1}: ${title}`);\n stepLines.push(`**Type:** ${node.nodeType}`);\n\n const c = node.configJson;\n switch (node.nodeType) {\n case 'login': {\n if (c.credentialName) stepLines.push(`**Credential:** ${c.credentialName}`);\n if (c.performLogin !== undefined)\n stepLines.push(`**Perform Login:** ${c.performLogin ? 'Yes' : 'No'}`);\n break;\n }\n case 'navigate': {\n if (c.pageUrl) stepLines.push(`**URL:** ${c.pageUrl}`);\n if (c.openInNewTab) stepLines.push(`**Open in New Tab:** Yes`);\n break;\n }\n case 'action': {\n const instructions =\n (c.customActionInstructions as string) || (c.actionDescription as string);\n if (instructions) stepLines.push(`**Instructions:** ${instructions}`);\n const playbook = c.playbookSteps as\n | Array<{ order: number; action: string; target: string }>\n | undefined;\n if (playbook && playbook.length > 0) {\n stepLines.push('');\n stepLines.push('**Playbook:**');\n for (const step of playbook) {\n stepLines.push(`${step.order}. [${step.action}] ${step.target}`);\n }\n }\n break;\n }\n case 'assertion': {\n if (c.condition) stepLines.push(`**Condition:** ${c.condition}`);\n if (c.strict) stepLines.push(`**Strict:** Yes`);\n break;\n }\n case 'setup': {\n if (c.setupFlowName) stepLines.push(`**Setup Flow:** ${c.setupFlowName}`);\n break;\n }\n case 'seed': {\n if (c.seedWorkflowName) stepLines.push(`**Seed Workflow:** ${c.seedWorkflowName}`);\n break;\n }\n case 'wait': {\n if (c.waitDuration) stepLines.push(`**Duration:** ${c.waitDuration}`);\n break;\n }\n case 'condition': {\n if (c.conditionDescription) stepLines.push(`**Condition:** ${c.conditionDescription}`);\n break;\n }\n case 'end': {\n if (c.outcome) stepLines.push(`**Outcome:** ${c.outcome}`);\n break;\n }\n }\n\n sections.push(stepLines.join('\\n'));\n }\n\n return sections.join('\\n\\n');\n}\n\n/* ── JSON Formatter ───────────────────────────────────────────────────── */\n\nfunction formatWorkflowJson(workflow: WorkflowSummary): object {\n const sorted = [...workflow.nodes].sort((a, b) => a.orderIndex - b.orderIndex);\n\n return {\n workflow: {\n id: workflow.id,\n name: workflow.name,\n description: workflow.description,\n status: workflow.status,\n flowType: workflow.flowType,\n },\n steps: sorted.map((node, i) => ({\n index: i + 1,\n nodeId: node.id,\n nodeType: node.nodeType,\n title: getNodeTitle(node),\n config: getCleanConfig(node),\n })),\n };\n}\n\n/* ── Sub-command Handlers ─────────────────────────────────────────────── */\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n\n const params = new URLSearchParams();\n const search = getArgValue(argv, '--search');\n const flowType = getArgValue(argv, '--flow-type');\n const status = getArgValue(argv, '--status');\n const page = getArgValue(argv, '--page');\n const pageSize = getArgValue(argv, '--page-size');\n\n if (search) params.set('search', search);\n if (flowType) params.set('flowType', flowType);\n if (status) params.set('status', status);\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const path = `/workflows${qs ? `?${qs}` : ''}`;\n\n const result = await apiRequest<WorkflowListResponse>(apiUrl, token, 'GET', path);\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify({ data: result.data, pagination: result.pagination }, null, 2));\n return;\n }\n\n // Default table output\n const { data, pagination } = result;\n console.log(\n `Workflows: ${pagination.totalItems} total (page ${pagination.page}/${pagination.totalPages})\\n`\n );\n\n if (data.length === 0) {\n console.log('No workflows found.');\n return;\n }\n\n // Column widths\n const idW = 36;\n const nameW = 30;\n const statusW = 12;\n const typeW = 10;\n\n const header = [\n 'ID'.padEnd(idW),\n 'Name'.padEnd(nameW),\n 'Status'.padEnd(statusW),\n 'Type'.padEnd(typeW),\n ].join(' ');\n\n console.log(header);\n\n for (const w of data) {\n const row = [\n w.id.padEnd(idW),\n truncate(w.name, nameW).padEnd(nameW),\n w.status.padEnd(statusW),\n w.flowType.padEnd(typeW),\n ].join(' ');\n console.log(row);\n }\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const workflowId = argv[0];\n if (!workflowId || workflowId.startsWith('--')) {\n console.error('Error: Missing workflow ID.');\n console.error('Usage: canary workflow get <workflowId>');\n process.exit(1);\n }\n\n const _jsonOutput = hasFlag(argv, '--json') || getArgValue(argv, '--format') === 'json';\n const markdownOutput =\n hasFlag(argv, '--markdown') || getArgValue(argv, '--format') === 'markdown';\n const outputFile = getArgValue(argv, '--output');\n\n const res = await fetch(`${apiUrl}/workflows/${workflowId}`, {\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n });\n if (res.status === 401) {\n console.error('Error: Unauthorized. Your session may have expired.');\n console.error('Run: canary login');\n process.exit(1);\n }\n const result = (await res.json()) as WorkflowDetailResponse;\n\n if (result.error === 'WORKFLOW_NOT_FOUND') {\n console.error('Error: Workflow not found.');\n process.exit(1);\n }\n if (result.error === 'WORKFLOW_WRONG_ORG') {\n console.error(\n `Error: Workflow belongs to another org: ${result.targetOrgName ?? result.targetOrgId}`\n );\n process.exit(1);\n }\n if (!result.workflow) {\n console.error(`Error: ${result.error ?? 'Unexpected response'}`);\n process.exit(1);\n }\n\n const workflow = result.workflow;\n let output: string;\n\n if (markdownOutput) {\n output = formatWorkflowMarkdown(workflow);\n } else {\n // Default to JSON for agent-friendly output\n output = JSON.stringify(formatWorkflowJson(workflow), null, 2);\n }\n\n if (outputFile) {\n try {\n await fs.writeFile(outputFile, output, 'utf-8');\n console.log(`Written to ${outputFile}`);\n } catch (err) {\n console.error(\n `Error writing to ${outputFile}: ${err instanceof Error ? err.message : String(err)}`\n );\n process.exit(1);\n }\n return;\n }\n\n console.log(output);\n}\n\n/* ── Help & Entry Point ───────────────────────────────────────────────── */\n\nfunction printWorkflowHelp(): void {\n console.log(\n [\n 'Usage: canary workflow <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' list [options] List workflows',\n ' get <workflowId> [options] Get workflow definition with steps',\n ' create [options] Create workflow from JSON (stdin or file)',\n '',\n 'List options:',\n ' --search <query> Search by name',\n ' --flow-type <type> Filter: standard, setup, seed, teardown',\n ' --status <status> Filter: draft, published, archived',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 25)',\n ' --json Output raw JSON',\n '',\n 'Get options:',\n ' --format json|markdown Output format (default: json)',\n ' --json Shorthand for --format json',\n ' --markdown Shorthand for --format markdown',\n ' --output <file> Write output to file',\n '',\n 'Create options:',\n ' --from-stdin Read workflow JSON from stdin (default)',\n ' --from-file <path> Read workflow JSON from file',\n ' --quarantine Create with quarantined status (auto-promotes after 3 passes)',\n ' --run-and-publish Create as draft, run test, publish on success',\n ' --property <name|id> Property for run-and-publish',\n ' --environment <name|id> Environment for run-and-publish',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev, local)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\nexport async function runWorkflow(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printWorkflowHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'create':\n await handleWorkflowCreate(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printWorkflowHelp();\n process.exit(1);\n }\n}\n","/**\n * CLI Workflow Creation\n *\n * Creates a workflow with nodes and edges atomically via the API.\n * Supports reading workflow JSON from stdin or file.\n *\n * @module workflow-create\n */\n\nimport fs from \"node:fs/promises\";\nimport process from \"node:process\";\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport { getArgValue, hasFlag } from \"./auth.js\";\n\n/* ── Types ────────────────────────────────────────────────────────────── */\n\ntype WorkflowNodeInput = {\n nodeType: string;\n configJson?: Record<string, unknown>;\n};\n\ntype WorkflowCreateInput = {\n name: string;\n description?: string;\n status?: \"draft\" | \"quarantined\";\n flowType?: \"standard\" | \"setup\" | \"seed\" | \"teardown\";\n createdVia?: string;\n propertyId?: string;\n credentialId?: string;\n nodes: WorkflowNodeInput[];\n};\n\ntype CreateResponse = {\n ok: boolean;\n error?: string;\n workflow?: {\n id: string;\n name: string;\n status: string;\n flowType: string;\n createdVia: string | null;\n };\n nodes?: Array<{ id: string; nodeType: string; orderIndex: number }>;\n edges?: Array<{ id: string; sourceNodeId: string; targetNodeId: string }>;\n};\n\ntype SessionStatusResponse = {\n sessions?: Array<{\n id: string;\n propertyId?: string;\n credentialId?: string;\n propertyName?: string;\n credentialName?: string;\n }>;\n};\n\ntype TriggerRunResponse = {\n ok: boolean;\n error?: string;\n jobId?: string;\n suiteId?: string;\n appUrl?: string;\n};\n\ntype WorkflowTestEvent = {\n type: \"workflow-test\";\n workflowId: string;\n testRunId: string;\n status: string;\n errorMessage?: string | null;\n message?: string;\n};\n\ntype WorkflowTestSuiteEvent = {\n type: \"workflow-test-suite\";\n status: string;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n};\n\n/* ── Input Reading ───────────────────────────────────────────────────── */\n\nasync function readFromStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n const stdin = process.stdin;\n\n if (stdin.isTTY) {\n throw new Error(\"No input on stdin. Pipe workflow JSON or use --from-file.\");\n }\n\n return new Promise((resolve, reject) => {\n stdin.on(\"data\", (chunk) => chunks.push(chunk));\n stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n stdin.on(\"error\", reject);\n });\n}\n\nasync function readWorkflowInput(argv: string[]): Promise<WorkflowCreateInput> {\n let raw: string;\n\n const fromFile = getArgValue(argv, \"--from-file\");\n if (fromFile) {\n try {\n raw = await fs.readFile(fromFile, \"utf-8\");\n } catch (err) {\n throw new Error(`Failed to read file ${fromFile}: ${err instanceof Error ? err.message : String(err)}`);\n }\n } else {\n raw = await readFromStdin();\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\"Invalid JSON input. Please provide valid workflow JSON.\");\n }\n\n const input = parsed as WorkflowCreateInput;\n\n if (!input.name || typeof input.name !== \"string\") {\n throw new Error('Workflow JSON must include a \"name\" string field.');\n }\n\n if (!Array.isArray(input.nodes) || input.nodes.length === 0) {\n throw new Error('Workflow JSON must include a non-empty \"nodes\" array.');\n }\n\n const validNodeTypes = [\"login\", \"navigate\", \"action\", \"assertion\", \"end\", \"setup\", \"seed\", \"wait\"];\n for (const node of input.nodes) {\n if (!node.nodeType || !validNodeTypes.includes(node.nodeType)) {\n throw new Error(\n `Invalid nodeType \"${node.nodeType}\". Valid types: ${validNodeTypes.join(\", \")}`\n );\n }\n }\n\n return input;\n}\n\n/* ── Session Auto-linking ────────────────────────────────────────────── */\n\nasync function detectSessionContext(\n apiUrl: string,\n token: string\n): Promise<{ propertyId?: string; credentialId?: string }> {\n try {\n const res = await fetch(`${apiUrl}/sessions/status`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) return {};\n\n const data = (await res.json()) as SessionStatusResponse;\n const sessions = data.sessions;\n\n if (!sessions || sessions.length === 0) return {};\n\n // Use the first active session's property/credential\n const session = sessions[0];\n return {\n propertyId: session.propertyId,\n credentialId: session.credentialId,\n };\n } catch {\n // Session detection is best-effort\n return {};\n }\n}\n\n/* ── Run-and-Publish ─────────────────────────────────────────────────── */\n\nasync function runAndPublish(opts: {\n apiUrl: string;\n token: string;\n workflowId: string;\n workflowName: string;\n propertyId?: string;\n environmentId?: string;\n}): Promise<boolean> {\n const { apiUrl, token, workflowId, workflowName } = opts;\n\n // 1. Trigger a test run for this single workflow\n const body: Record<string, string> = {};\n if (opts.propertyId) body.propertyId = opts.propertyId;\n if (opts.environmentId) body.environmentId = opts.environmentId;\n\n const triggerUrl = `${apiUrl}/workflows/test-runs?namePattern=${encodeURIComponent(workflowName)}`;\n\n let triggerRes: Response;\n try {\n triggerRes = await fetch(triggerUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n } catch (err) {\n console.error(`Failed to trigger test run: ${err}`);\n return false;\n }\n\n if (!triggerRes.ok) {\n const errorText = await triggerRes.text();\n console.error(`Failed to trigger test run: ${triggerRes.status} ${errorText}`);\n return false;\n }\n\n const triggerData = (await triggerRes.json()) as TriggerRunResponse;\n if (!triggerData.ok || !triggerData.suiteId) {\n console.error(`Failed to trigger test run: ${triggerData.error ?? \"Unknown error\"}`);\n return false;\n }\n\n const { suiteId } = triggerData;\n console.log(`Test run started (suite: ${suiteId})`);\n console.log(\"Streaming results...\\n\");\n\n // 2. Stream SSE events\n const streamUrl = `${apiUrl}/workflows/test-runs/stream?suiteId=${suiteId}`;\n\n let streamRes: Response;\n try {\n streamRes = await fetch(streamUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"text/event-stream\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to event stream: ${err}`);\n return false;\n }\n\n if (!streamRes.ok || !streamRes.body) {\n console.error(`Failed to connect to event stream: ${streamRes.status}`);\n return false;\n }\n\n let success = false;\n let hasCompleted = false;\n\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as WorkflowTestEvent | WorkflowTestSuiteEvent;\n\n if (event.event === \"workflow-test\") {\n const testEvent = data as WorkflowTestEvent;\n if (testEvent.status === \"success\") {\n console.log(` \\u2713 ${workflowName}`);\n success = true;\n } else if (testEvent.status === \"failed\") {\n console.log(` \\u2717 ${workflowName}`);\n if (testEvent.errorMessage) {\n console.log(` Error: ${testEvent.errorMessage.slice(0, 200)}`);\n }\n success = false;\n } else if (testEvent.status === \"running\") {\n console.log(` \\u25B6 Running ${workflowName}...`);\n }\n }\n\n if (event.event === \"workflow-test-suite\") {\n const suiteEvent = data as WorkflowTestSuiteEvent;\n if (suiteEvent.status === \"completed\") {\n hasCompleted = true;\n }\n }\n } catch {\n // Ignore parse errors for keepalive\n }\n },\n });\n\n const reader = streamRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (!hasCompleted) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n } finally {\n reader.releaseLock();\n }\n\n // 3. If success, publish the workflow\n if (success) {\n try {\n const publishRes = await fetch(`${apiUrl}/workflows/${workflowId}/publish`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (publishRes.ok) {\n console.log(`\\n\\u2713 Workflow published successfully`);\n return true;\n } else {\n console.error(`\\nFailed to publish workflow: ${publishRes.status}`);\n return false;\n }\n } catch (err) {\n console.error(`\\nFailed to publish workflow: ${err}`);\n return false;\n }\n }\n\n console.log(`\\n\\u2717 Test failed — workflow left in draft for manual review`);\n return false;\n}\n\n/* ── Main Handler ────────────────────────────────────────────────────── */\n\nexport async function handleWorkflowCreate(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const quarantine = hasFlag(argv, \"--quarantine\");\n const runAndPublishFlag = hasFlag(argv, \"--run-and-publish\");\n const propertyArg = getArgValue(argv, \"--property\");\n const environmentArg = getArgValue(argv, \"--environment\");\n\n if (quarantine && runAndPublishFlag) {\n console.error(\"Error: --quarantine and --run-and-publish are mutually exclusive.\");\n process.exit(1);\n }\n\n // 1. Read and validate input\n let input: WorkflowCreateInput;\n try {\n input = await readWorkflowInput(argv);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n // 2. Auto-detect session context for property/credential linking\n if (!input.propertyId && !input.credentialId) {\n const sessionCtx = await detectSessionContext(apiUrl, token);\n if (sessionCtx.propertyId) {\n input.propertyId = sessionCtx.propertyId;\n console.log(`Auto-linked property from active session`);\n }\n if (sessionCtx.credentialId) {\n input.credentialId = sessionCtx.credentialId;\n console.log(`Auto-linked credential from active session`);\n }\n }\n\n // 3. Set status based on flags\n if (quarantine) {\n input.status = \"quarantined\";\n }\n\n input.createdVia = \"cli\";\n\n // 4. Create workflow via API\n const res = await fetch(`${apiUrl}/workflows/create-with-nodes`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(input),\n });\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Your session may have expired.\");\n console.error(\"Run: canary login\");\n process.exit(1);\n }\n\n const result = (await res.json()) as CreateResponse;\n\n if (!result.ok || !result.workflow) {\n console.error(`Error: ${result.error ?? \"Failed to create workflow\"}`);\n process.exit(1);\n }\n\n const { workflow, nodes, edges } = result;\n\n console.log(`\\n\\u2713 Workflow created: ${workflow.name}`);\n console.log(` ID: ${workflow.id}`);\n console.log(` Status: ${workflow.status}`);\n console.log(` Nodes: ${nodes?.length ?? 0}`);\n console.log(` Edges: ${edges?.length ?? 0}`);\n\n // Derive web UI URL from API URL\n const webUrl = apiUrl.replace(/\\/api\\b|api\\./, \"app.\").replace(/:\\d+$/, \":5173\");\n console.log(` URL: ${webUrl}/workflows/${workflow.id}`);\n\n // 5. Run-and-publish if requested\n if (runAndPublishFlag) {\n console.log(\"\\nTriggering test run...\");\n\n const passed = await runAndPublish({\n apiUrl,\n token,\n workflowId: workflow.id,\n workflowName: workflow.name,\n propertyId: propertyArg ?? input.propertyId,\n environmentId: environmentArg,\n });\n\n if (!passed) {\n process.exit(1);\n }\n }\n}\n"],"mappings":"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","names":["fs","process","process","fs"]}