@runcofactor/cli 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +125 -0
  2. package/dist/api-catalog-GFGCLVS4.js +401 -0
  3. package/dist/api-catalog-GFGCLVS4.js.map +1 -0
  4. package/dist/attachment-SJC7D7FY.js +276 -0
  5. package/dist/attachment-SJC7D7FY.js.map +1 -0
  6. package/dist/auth-EN6NQCJY.js +31 -0
  7. package/dist/auth-EN6NQCJY.js.map +1 -0
  8. package/dist/bin.js +7 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/chunk-3CZU7XCS.js +272 -0
  11. package/dist/chunk-3CZU7XCS.js.map +1 -0
  12. package/dist/chunk-4NRDONSC.js +1048 -0
  13. package/dist/chunk-4NRDONSC.js.map +1 -0
  14. package/dist/chunk-4PNOV7OV.js +51980 -0
  15. package/dist/chunk-4PNOV7OV.js.map +1 -0
  16. package/dist/chunk-52IO7ACJ.js +2941 -0
  17. package/dist/chunk-52IO7ACJ.js.map +1 -0
  18. package/dist/chunk-6LEZCKKV.js +663 -0
  19. package/dist/chunk-6LEZCKKV.js.map +1 -0
  20. package/dist/chunk-A4OFTUVV.js +170 -0
  21. package/dist/chunk-A4OFTUVV.js.map +1 -0
  22. package/dist/chunk-B2VISN2V.js +2459 -0
  23. package/dist/chunk-B2VISN2V.js.map +1 -0
  24. package/dist/chunk-CLAWT7BJ.js +271 -0
  25. package/dist/chunk-CLAWT7BJ.js.map +1 -0
  26. package/dist/chunk-GKY2KXO5.js +281 -0
  27. package/dist/chunk-GKY2KXO5.js.map +1 -0
  28. package/dist/chunk-I4QLI3JO.js +413 -0
  29. package/dist/chunk-I4QLI3JO.js.map +1 -0
  30. package/dist/chunk-IMPZAX6L.js +180 -0
  31. package/dist/chunk-IMPZAX6L.js.map +1 -0
  32. package/dist/chunk-J6SH7GQT.js +241 -0
  33. package/dist/chunk-J6SH7GQT.js.map +1 -0
  34. package/dist/chunk-JDBCZ3Z2.js +298 -0
  35. package/dist/chunk-JDBCZ3Z2.js.map +1 -0
  36. package/dist/chunk-JICSYFRJ.js +46 -0
  37. package/dist/chunk-JICSYFRJ.js.map +1 -0
  38. package/dist/chunk-JWHYXEA2.js +32 -0
  39. package/dist/chunk-JWHYXEA2.js.map +1 -0
  40. package/dist/chunk-N7HFALX3.js +88 -0
  41. package/dist/chunk-N7HFALX3.js.map +1 -0
  42. package/dist/chunk-Q4BO4Z5V.js +178 -0
  43. package/dist/chunk-Q4BO4Z5V.js.map +1 -0
  44. package/dist/chunk-QFDOWABX.js +195 -0
  45. package/dist/chunk-QFDOWABX.js.map +1 -0
  46. package/dist/chunk-SJJW77WN.js +605 -0
  47. package/dist/chunk-SJJW77WN.js.map +1 -0
  48. package/dist/chunk-VKVL7WBN.js +50 -0
  49. package/dist/chunk-VKVL7WBN.js.map +1 -0
  50. package/dist/chunk-WOHL4FTB.js +353 -0
  51. package/dist/chunk-WOHL4FTB.js.map +1 -0
  52. package/dist/chunk-XQXVG7RA.js +426 -0
  53. package/dist/chunk-XQXVG7RA.js.map +1 -0
  54. package/dist/chunk-ZD3KHESI.js +94 -0
  55. package/dist/chunk-ZD3KHESI.js.map +1 -0
  56. package/dist/credential-COLTBV6D.js +450 -0
  57. package/dist/credential-COLTBV6D.js.map +1 -0
  58. package/dist/credential-template-EEPYFG7R.js +291 -0
  59. package/dist/credential-template-EEPYFG7R.js.map +1 -0
  60. package/dist/debug-workflow-KOVH5GOP.js +259 -0
  61. package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
  62. package/dist/dist-44PZR7BQ.js +423 -0
  63. package/dist/dist-44PZR7BQ.js.map +1 -0
  64. package/dist/docs-3SSORHB5.js +366 -0
  65. package/dist/docs-3SSORHB5.js.map +1 -0
  66. package/dist/doctor-OTSIWV6G.js +132 -0
  67. package/dist/doctor-OTSIWV6G.js.map +1 -0
  68. package/dist/feature-flag-T2LRZME3.js +283 -0
  69. package/dist/feature-flag-T2LRZME3.js.map +1 -0
  70. package/dist/file-type-S3UUBVCT.js +4205 -0
  71. package/dist/file-type-S3UUBVCT.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +982 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/init-TGWRECT2.js +208 -0
  76. package/dist/init-TGWRECT2.js.map +1 -0
  77. package/dist/install-DXSNWZKO.js +295 -0
  78. package/dist/install-DXSNWZKO.js.map +1 -0
  79. package/dist/issues-XIZOPX6T.js +564 -0
  80. package/dist/issues-XIZOPX6T.js.map +1 -0
  81. package/dist/knobs-NBINZIUB.js +295 -0
  82. package/dist/knobs-NBINZIUB.js.map +1 -0
  83. package/dist/list-3TDHK637.js +59 -0
  84. package/dist/list-3TDHK637.js.map +1 -0
  85. package/dist/local-HICVD6PU.js +100 -0
  86. package/dist/local-HICVD6PU.js.map +1 -0
  87. package/dist/login-UOIUXVUK.js +315 -0
  88. package/dist/login-UOIUXVUK.js.map +1 -0
  89. package/dist/mcp-54IJEOUA.js +1956 -0
  90. package/dist/mcp-54IJEOUA.js.map +1 -0
  91. package/dist/pdf-extract-ABWV3L5X.js +13 -0
  92. package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
  93. package/dist/pdfjs-DQ2YA5S3.js +41561 -0
  94. package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
  95. package/dist/property-UXLOLPTD.js +701 -0
  96. package/dist/property-UXLOLPTD.js.map +1 -0
  97. package/dist/property-skill-guide.md +189 -0
  98. package/dist/psql-BYUUNLGG.js +115 -0
  99. package/dist/psql-BYUUNLGG.js.map +1 -0
  100. package/dist/record-4TR2UIIS.js +233 -0
  101. package/dist/record-4TR2UIIS.js.map +1 -0
  102. package/dist/redis-35VBUYW7.js +116 -0
  103. package/dist/redis-35VBUYW7.js.map +1 -0
  104. package/dist/release-OOLTUBUT.js +354 -0
  105. package/dist/release-OOLTUBUT.js.map +1 -0
  106. package/dist/sandbox-XGSUU6G7.js +2046 -0
  107. package/dist/sandbox-XGSUU6G7.js.map +1 -0
  108. package/dist/scenarios-GWLJEGHA.js +280 -0
  109. package/dist/scenarios-GWLJEGHA.js.map +1 -0
  110. package/dist/session-MYFNZPRP.js +2414 -0
  111. package/dist/session-MYFNZPRP.js.map +1 -0
  112. package/dist/skill-KM34LDMO.js +1839 -0
  113. package/dist/skill-KM34LDMO.js.map +1 -0
  114. package/dist/skills/debug-run/SKILL.md +262 -0
  115. package/dist/skills/debug-run/history/1.0.0.md +244 -0
  116. package/dist/skills/debug-run/history/1.0.1.md +245 -0
  117. package/dist/skills/debug-run/history/1.0.2.md +254 -0
  118. package/dist/skills/debug-run/history/1.1.0.md +262 -0
  119. package/dist/skills/debug-run/version.json +3 -0
  120. package/dist/spec-RA3CFEKG.js +951 -0
  121. package/dist/spec-RA3CFEKG.js.map +1 -0
  122. package/dist/src-LB4HBTJQ.js +1516 -0
  123. package/dist/src-LB4HBTJQ.js.map +1 -0
  124. package/dist/src-N3TPKGTY.js +244 -0
  125. package/dist/src-N3TPKGTY.js.map +1 -0
  126. package/dist/src-UVDX5UP6.js +17 -0
  127. package/dist/src-UVDX5UP6.js.map +1 -0
  128. package/dist/start-PSEQSQA3.js +151 -0
  129. package/dist/start-PSEQSQA3.js.map +1 -0
  130. package/dist/tag-YY6YAABQ.js +22 -0
  131. package/dist/tag-YY6YAABQ.js.map +1 -0
  132. package/dist/task-IQC3YR5K.js +922 -0
  133. package/dist/task-IQC3YR5K.js.map +1 -0
  134. package/dist/test-suite-DZNJFXDW.js +394 -0
  135. package/dist/test-suite-DZNJFXDW.js.map +1 -0
  136. package/dist/trace-HXIW7U2D.js +14 -0
  137. package/dist/trace-HXIW7U2D.js.map +1 -0
  138. package/dist/triage-ORG45R5W.js +16 -0
  139. package/dist/triage-ORG45R5W.js.map +1 -0
  140. package/dist/upgrade-L2VYMP2V.js +61 -0
  141. package/dist/upgrade-L2VYMP2V.js.map +1 -0
  142. package/dist/workflow-XYFH5LTP.js +3708 -0
  143. package/dist/workflow-XYFH5LTP.js.map +1 -0
  144. package/dist/workflow-cache-NQJQFWMV.js +253 -0
  145. package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
  146. package/dist/workflow-debug-BGD4UIXU.js +927 -0
  147. package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
  148. package/dist/workflow-proposals-MTUDX46O.js +382 -0
  149. package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
  150. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/task.ts"],"sourcesContent":["/**\n * CLI Agent Task Management\n *\n * Create, list, complete, and manage trigger-based agent tasks.\n */\n\nimport process from 'node:process';\nimport { execSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\n/** Full task shape returned by detail/create/lifecycle endpoints */\ntype AgentTask = {\n id: string;\n orgId: string;\n propertyGithubRepoId: string;\n title: string;\n description: string;\n triggerType: string;\n triggerConfig: Record<string, unknown>;\n status: string;\n sourceCommit: string | null;\n resolutionCommit: string | null;\n createdBy: string;\n assignedTo: string | null;\n priority: number;\n tags: string[];\n groupKey: string | null;\n parentTaskId: string | null;\n expiresAt: string | null;\n triggeredAt: string | null;\n completedAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\n/** Lighter shape returned by the list endpoint (omits description/triggerConfig) */\ntype AgentTaskListItem = Omit<AgentTask, 'description' | 'triggerConfig'>;\n\ntype TaskListResponse = {\n ok: boolean;\n error?: string;\n data: AgentTaskListItem[];\n pagination: {\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n };\n};\n\ntype AgentTaskCustomer = {\n id: string;\n orgId: string | null;\n name: string;\n};\n\ntype TaskAttachment = {\n id: string;\n filename: string;\n contentType: string;\n sizeBytes: number;\n createdAt: string;\n downloadUrl: string;\n};\n\ntype TaskResponse = {\n ok: boolean;\n error?: string;\n data?: AgentTask & {\n events?: Array<{ eventType: string; actor: string | null; createdAt: string }>;\n relevantCustomers?: AgentTaskCustomer[];\n subtaskSummary?: { total: number; completed: number; canceled: number; inProgress: number } | null;\n attachments?: TaskAttachment[];\n };\n};\n\nfunction getHeadCommit(): string | null {\n try {\n return execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim();\n } catch {\n return null;\n }\n}\n\nfunction printHelp(): void {\n console.log(\n [\n 'canary task: Manage trigger-based agent tasks',\n '',\n 'Sub-commands:',\n ' create Create a new task',\n ' list [options] List tasks',\n ' get <id> Get task details',\n ' update <id> [options] Update task fields',\n ' complete <id> [--pr <number>] [--commit <sha>] Mark task complete (--pr preferred under squash-merge)',\n ' set-commit <id> [--pr <number>] [--commit <sha>] Update resolution PR/commit (use \"\" to clear)',\n ' cancel <id> Cancel a task',\n ' reopen <id> [--status <s>] Reopen a canceled task (default: actionable)',\n ' release <id> [--status <s>] Release an in-progress task (default: actionable)',\n ' trigger <id> Manually trigger a task',\n ' claim <id> Claim a task (mark in progress)',\n ' execute <id> --instance <id> Execute task on a sandbox instance',\n ' comment <id> <message> Add a comment to a task',\n ' comments <id> List comments for a task',\n ' subtasks <id> List subtasks of a parent task',\n ' link-customer <id> [opts] Link a customer to a task',\n ' unlink-customer <id> [opts] Unlink a customer from a task',\n '',\n 'Create options:',\n ' --title <text> Short title (required)',\n ' --description <text> Task description (required, or -file/-stdin)',\n ' --description-file <path> Read description from file',\n ' --description-stdin Read description from stdin (pipe or heredoc)',\n ' --trigger <type> Trigger type (required)',\n ' --commit <sha> Source commit (default: git HEAD)',\n ' --flag <name> Flag name (for flag-* triggers)',\n ' --knob <key> Knob key (for knob-* triggers)',\n ' --pr <number> PR number (for pr-merged)',\n ' --scheduled-date <date> ISO date (for scheduled)',\n ' --assign <email> Assignee',\n ' --priority <0|1|2> Priority (0=normal, 1=high, 2=critical)',\n ' --tag <tag> Tag (repeatable)',\n ' --repo <owner/repo> Target repo (auto-selected if org has one)',\n ' --role <frontend|backend|...> Resolve repo by role (alternative to --repo)',\n ' --expires <date> Expiry date (ISO 8601)',\n ' --parent <id> Parent task ID (creates a subtask)',\n ' --customer <value> Customer (org UUID or freeform name, repeatable)',\n '',\n 'Update options:',\n ' --title <text> New title',\n ' --description <text> New description',\n ' --description-file <path> Read new description from file',\n ' --description-stdin Read new description from stdin',\n ' --assign <email> New assignee (use \"\" to unassign)',\n ' --priority <0|1|2> New priority',\n ' --tag <tag> Replace tags (repeatable)',\n ' --commit <sha> Resolution commit (use \"\" to clear)',\n '',\n 'List options:',\n ' --assigned-to <email> Filter by assignee',\n ' --page <n> Page number (1-based, default 1)',\n ' --page-size <n> Page size (max 100, default 25)',\n ' --parent <id> Filter by parent task (show subtasks)',\n ' --group-key <key> Filter by groupKey',\n ' --priority <val> Filter by priority (repeatable). Accepts critical|high|normal|0|1|2',\n ' --sort <field> [<dir>] Sort by field (repeatable, applied in order).',\n ' field ∈ priority | createdAt (alias: date)',\n ' dir ∈ asc | desc (default: desc)',\n ' Default: --sort priority desc --sort createdAt asc',\n ' --status <status> Filter by status',\n ' --trigger <type> Filter by trigger type',\n '',\n 'Link-customer options:',\n ' --org <orgId> Organization UUID to link',\n ' --name <text> Freeform customer name (e.g. prospect)',\n '',\n 'Unlink-customer options:',\n ' --customer-id <id> Customer link ID (from `canary task get`)',\n '',\n 'Trigger types:',\n ' production-deploy, flag-deprecated, flag-cleanup, flag-deleted,',\n ' knob-deprecated, knob-cleanup, knob-deleted, scheduled,',\n ' pr-merged, immediate, manual',\n '',\n 'Global options:',\n ' --env <env> Target environment',\n ' --json JSON output',\n ' --api-url <url> API URL override',\n ' --token <key> Token override',\n ].join('\\n')\n );\n}\n\nconst STATUS_ICONS: Record<string, string> = {\n waiting: '⏳',\n actionable: '🟢',\n in_progress: '🔵',\n completed: '✅',\n canceled: '❌',\n expired: '⏰',\n};\n\nconst PRIORITY_LABELS = ['normal', 'high', 'critical'];\n\nconst PRIORITY_VALUE_BY_NAME: Record<string, number> = {\n normal: 0,\n high: 1,\n critical: 2,\n};\n\nfunction parsePriorityArgs(argv: string[]): number[] {\n const values: number[] = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] !== '--priority' || !argv[i + 1]) continue;\n const raw = argv[i + 1]!.toLowerCase();\n // Allow a single flag with comma-separated values: --priority critical,high\n for (const part of raw.split(',').map((s) => s.trim()).filter(Boolean)) {\n if (part in PRIORITY_VALUE_BY_NAME) {\n values.push(PRIORITY_VALUE_BY_NAME[part]!);\n } else {\n const n = Number(part);\n if (!Number.isInteger(n)) {\n console.error(`Error: invalid --priority value \"${part}\". Use critical|high|normal or 0|1|2.`);\n process.exit(1);\n }\n values.push(n);\n }\n }\n }\n return values;\n}\n\n/**\n * Parse repeated `--sort <field> [<dir>]` flags into `field[:dir]` tokens for\n * the server's comma-separated `sort` query param. The direction arg is only\n * consumed when the token after `<field>` doesn't itself look like a flag; if\n * it's present but isn't `asc`/`desc`, we error rather than silently dropping\n * it (user probably typo'd the direction).\n */\nfunction parseSortArgs(argv: string[]): string[] {\n const tokens: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] !== '--sort' || !argv[i + 1]) continue;\n const field = argv[i + 1]!;\n const maybeDir = argv[i + 2];\n let dir: 'asc' | 'desc' | undefined;\n if (maybeDir && !maybeDir.startsWith('--')) {\n if (maybeDir === 'asc' || maybeDir === 'desc') {\n dir = maybeDir;\n } else {\n console.error(\n `Error: invalid --sort direction \"${maybeDir}\" for field \"${field}\". Use: asc, desc.`\n );\n process.exit(1);\n }\n }\n tokens.push(dir ? `${field}:${dir}` : field);\n }\n return tokens;\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const status = getArgValue(argv, '--status');\n const triggerType = getArgValue(argv, '--trigger');\n const assignedTo = getArgValue(argv, '--assigned-to');\n const page = getArgValue(argv, '--page');\n const pageSize = getArgValue(argv, '--page-size');\n const parentId = getArgValue(argv, '--parent');\n const groupKey = getArgValue(argv, '--group-key');\n const priorities = parsePriorityArgs(argv);\n const sortTokens = parseSortArgs(argv);\n\n const params = new URLSearchParams();\n if (status) params.set('status', status);\n if (triggerType) params.set('triggerType', triggerType);\n if (assignedTo) params.set('assignedTo', assignedTo);\n if (parentId) params.set('parentTaskId', parentId);\n if (groupKey) params.set('groupKey', groupKey);\n if (priorities.length > 0) params.set('priority', priorities.join(','));\n if (sortTokens.length > 0) params.set('sort', sortTokens.join(','));\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const path = `/tasks${qs ? `?${qs}` : ''}`;\n\n const result = await apiRequest<TaskListResponse>(apiUrl, token, 'GET', path);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (result.data.length === 0) {\n console.log('No tasks found.');\n return;\n }\n\n console.log(`Tasks (page ${result.pagination.page}/${result.pagination.totalPages}, ${result.pagination.totalItems} total):\\n`);\n\n for (const task of result.data) {\n const icon = STATUS_ICONS[task.status] ?? '?';\n const priority = task.priority > 0 ? ` [${PRIORITY_LABELS[task.priority]}]` : '';\n const commit = task.sourceCommit ? ` (${task.sourceCommit.slice(0, 7)})` : '';\n const created = task.createdAt ? new Date(task.createdAt).toLocaleString() : '';\n const updated = task.updatedAt ? new Date(task.updatedAt).toLocaleString() : '';\n console.log(` ${icon} ${task.id.slice(0, 8)} | ${task.title}${priority}${commit}`);\n console.log(` trigger=${task.triggerType} status=${task.status} created=${created} updated=${updated}`);\n }\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task get <id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'GET', `/tasks/${id}`);\n\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'Task not found'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n const task = result.data;\n const icon = STATUS_ICONS[task.status] ?? '?';\n console.log(`${icon} ${task.title}`);\n console.log(`ID: ${task.id}`);\n console.log(`Status: ${task.status}`);\n console.log(`Trigger: ${task.triggerType}`);\n console.log(`Priority: ${PRIORITY_LABELS[task.priority] ?? task.priority}`);\n if (task.sourceCommit) console.log(`Source: ${task.sourceCommit}`);\n if (task.resolutionCommit) console.log(`Resolution: ${task.resolutionCommit}`);\n if (task.assignedTo) console.log(`Assigned to: ${task.assignedTo}`);\n if (task.tags.length > 0) console.log(`Tags: ${task.tags.join(', ')}`);\n if (task.groupKey) console.log(`Group key: ${task.groupKey}`);\n if (task.parentTaskId) console.log(`Parent: ${task.parentTaskId}`);\n if (task.subtaskSummary && task.subtaskSummary.total > 0) {\n const s = task.subtaskSummary;\n console.log(`Subtasks: ${s.completed}/${s.total} completed, ${s.inProgress} in progress, ${s.canceled} canceled`);\n }\n if (task.relevantCustomers && task.relevantCustomers.length > 0) {\n console.log('Customers:');\n for (const c of task.relevantCustomers) {\n const orgTag = c.orgId ? ` (org: ${c.orgId.slice(0, 8)})` : ' (freeform)';\n console.log(` ${c.name}${orgTag} [${c.id}]`);\n }\n }\n console.log(`Created: ${task.createdAt}`);\n console.log(`Updated: ${task.updatedAt}`);\n if (task.triggeredAt) console.log(`Triggered: ${task.triggeredAt}`);\n if (task.completedAt) console.log(`Completed: ${task.completedAt}`);\n\n if (Object.keys(task.triggerConfig).length > 0) {\n console.log(`Trigger cfg: ${JSON.stringify(task.triggerConfig)}`);\n }\n\n console.log(`\\nDescription:\\n${task.description}`);\n\n if (task.attachments && task.attachments.length > 0) {\n console.log('\\nAttachments:');\n for (const att of task.attachments) {\n const sizeKb = Math.round(att.sizeBytes / 1024);\n console.log(` ${att.filename} (${sizeKb} KB) — ${att.downloadUrl}`);\n }\n }\n\n if (task.events && task.events.length > 0) {\n console.log('\\nEvent history:');\n for (const evt of task.events) {\n console.log(` ${evt.createdAt} ${evt.eventType} by ${evt.actor ?? 'system'}`);\n }\n }\n}\n\nasync function handleSubtasks(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing parent task ID.');\n console.error('Usage: canary task subtasks <parent-id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const result = await apiRequest<{ ok: boolean; error?: string; data?: AgentTaskListItem[] }>(\n apiUrl, token, 'GET', `/tasks/${id}/subtasks`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to list subtasks'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const subtasks = result.data ?? [];\n if (subtasks.length === 0) {\n console.log('No subtasks found.');\n return;\n }\n\n console.log(`Subtasks of ${id} (${subtasks.length} total):\\n`);\n for (const task of subtasks) {\n const icon = STATUS_ICONS[task.status] ?? '?';\n const priority = task.priority > 0 ? ` [${PRIORITY_LABELS[task.priority]}]` : '';\n const created = task.createdAt ? new Date(task.createdAt).toLocaleString() : '';\n console.log(` ${icon} ${task.id.slice(0, 8)} | ${task.title}${priority}`);\n console.log(` status=${task.status} created=${created}`);\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const title = getArgValue(argv, '--title');\n const triggerType = getArgValue(argv, '--trigger');\n let description = getArgValue(argv, '--description');\n const descriptionFile = getArgValue(argv, '--description-file');\n const descriptionStdin = hasFlag(argv, '--description-stdin');\n const jsonOutput = hasFlag(argv, '--json');\n\n if (!title) {\n console.error('Error: --title is required.');\n process.exit(1);\n }\n if (!triggerType) {\n console.error('Error: --trigger is required.');\n process.exit(1);\n }\n\n if (descriptionFile) {\n try {\n description = readFileSync(descriptionFile, 'utf-8');\n } catch (err) {\n console.error(`Error reading description file: ${err}`);\n process.exit(1);\n }\n } else if (descriptionStdin) {\n try {\n description = readFileSync('/dev/stdin', 'utf-8');\n } catch (err) {\n console.error(`Error reading description from stdin: ${err}`);\n process.exit(1);\n }\n }\n\n if (!description) {\n console.error('Error: --description, --description-file, or --description-stdin is required.');\n process.exit(1);\n }\n\n // Build trigger config from flags\n const triggerConfig: Record<string, unknown> = {};\n const flagName = getArgValue(argv, '--flag');\n const knobKey = getArgValue(argv, '--knob');\n const prNumber = getArgValue(argv, '--pr');\n const scheduledDate = getArgValue(argv, '--scheduled-date');\n\n if (flagName) triggerConfig.flagName = flagName;\n if (knobKey) triggerConfig.knobKey = knobKey;\n if (prNumber) triggerConfig.prNumber = parseInt(prNumber, 10);\n if (scheduledDate) triggerConfig.scheduledDate = scheduledDate;\n\n // Auto-detect commit from git if not specified\n const commit = getArgValue(argv, '--commit') ?? getHeadCommit();\n\n // Resolve repo - first try --repo-id, --repo, or --role; otherwise fetch from API\n let propertyGithubRepoId = getArgValue(argv, '--repo-id');\n const repoFullName = getArgValue(argv, '--repo');\n const role = getArgValue(argv, '--role');\n\n if (!propertyGithubRepoId) {\n // Fetch org's linked repos to resolve\n const reposResult = await apiRequest<{\n ok: boolean;\n data: Array<{\n id: string;\n repoFullName: string;\n propertyId: string;\n propertyName: string;\n role?: string | null;\n }>;\n }>(apiUrl, token, 'GET', '/tasks/repos');\n\n if (!reposResult.ok || !reposResult.data?.length) {\n console.error('Error: No GitHub repositories linked to your organization.');\n console.error('Connect a repository first before creating tasks.');\n process.exit(1);\n }\n\n if (repoFullName) {\n const match = reposResult.data.find((r) => r.repoFullName === repoFullName);\n if (!match) {\n console.error(`Error: Repository \"${repoFullName}\" not found in your organization.`);\n console.error(`Available: ${reposResult.data.map((r) => r.repoFullName).join(', ')}`);\n process.exit(1);\n }\n propertyGithubRepoId = match.id;\n } else if (role) {\n const matches = reposResult.data.filter((r) => r.role === role);\n if (matches.length === 0) {\n console.error(`Error: No repos found with role \"${role}\".`);\n const seenRoles = Array.from(\n new Set(reposResult.data.map((r) => r.role).filter((x): x is string => !!x))\n );\n if (seenRoles.length) console.error(`Available roles: ${seenRoles.join(', ')}`);\n process.exit(1);\n }\n if (matches.length > 1) {\n console.error(\n `Error: Multiple repos with role \"${role}\". Use --repo <owner/repo> to disambiguate.`\n );\n console.error(`Available: ${matches.map((r) => r.repoFullName).join(', ')}`);\n process.exit(1);\n }\n propertyGithubRepoId = matches[0]!.id;\n } else if (reposResult.data.length === 1) {\n propertyGithubRepoId = reposResult.data[0]!.id;\n } else {\n console.error(\n 'Error: Multiple repos found. Use --repo <owner/repo> or --role <role> to specify.'\n );\n console.error(`Available: ${reposResult.data.map((r) => r.repoFullName).join(', ')}`);\n process.exit(1);\n }\n }\n\n if (triggerType === 'pr-merged') {\n triggerConfig.propertyGithubRepoId = propertyGithubRepoId;\n }\n\n // Collect tags\n const tags: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--tag' && argv[i + 1]) {\n tags.push(argv[i + 1]!);\n }\n }\n\n // Collect customers (repeatable --customer flag)\n const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n const customers: Array<{ orgId?: string; name?: string }> = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--customer' && argv[i + 1]) {\n const val = argv[i + 1]!;\n if (UUID_RE.test(val)) {\n customers.push({ orgId: val });\n } else {\n customers.push({ name: val });\n }\n }\n }\n\n const assignedTo = getArgValue(argv, '--assign');\n const priorityRaw = getArgValue(argv, '--priority');\n const expiresAt = getArgValue(argv, '--expires');\n const parentTaskId = getArgValue(argv, '--parent');\n\n const body: Record<string, unknown> = {\n propertyGithubRepoId,\n title,\n description,\n triggerType,\n triggerConfig,\n sourceCommit: commit,\n assignedTo: assignedTo ?? undefined,\n priority: priorityRaw ? parseInt(priorityRaw, 10) : undefined,\n tags: tags.length > 0 ? tags : undefined,\n parentTaskId: parentTaskId ?? undefined,\n expiresAt: expiresAt ?? undefined,\n customers: customers.length > 0 ? customers : undefined,\n };\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', '/tasks', body);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to create task'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n const task = result.data!;\n console.log(`Task created: ${task.id}`);\n console.log(` Title: ${task.title}`);\n console.log(` Status: ${task.status}`);\n console.log(` Trigger: ${task.triggerType}`);\n if (task.sourceCommit) console.log(` Commit: ${task.sourceCommit.slice(0, 7)}`);\n\n if (triggerType === 'pr-merged') {\n console.log('\\nThis task will become actionable when the matching PR is merged.');\n }\n}\n\nasync function handleUpdate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task update <id> [--title ...] [--description ...] [--assign ...] [--priority ...] [--tag ...]');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const title = getArgValue(argv, '--title');\n let description = getArgValue(argv, '--description');\n const descriptionFile = getArgValue(argv, '--description-file');\n const descriptionStdin = hasFlag(argv, '--description-stdin');\n const assignRaw = getArgValue(argv, '--assign');\n const priorityRaw = getArgValue(argv, '--priority');\n const commitRaw = getArgValue(argv, '--commit');\n\n if (descriptionFile) {\n try {\n description = readFileSync(descriptionFile, 'utf-8');\n } catch (err) {\n console.error(`Error reading description file: ${err}`);\n process.exit(1);\n }\n } else if (descriptionStdin) {\n try {\n description = readFileSync('/dev/stdin', 'utf-8');\n } catch (err) {\n console.error(`Error reading description from stdin: ${err}`);\n process.exit(1);\n }\n }\n\n const tags: string[] = [];\n let hasTags = false;\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--tag') {\n hasTags = true;\n if (argv[i + 1]) tags.push(argv[i + 1]!);\n }\n }\n\n const body: Record<string, unknown> = {};\n if (title) body.title = title;\n if (description) body.description = description;\n if (assignRaw !== undefined) body.assignedTo = assignRaw === '' ? null : assignRaw;\n if (priorityRaw) body.priority = parseInt(priorityRaw, 10);\n if (hasTags) body.tags = tags;\n if (commitRaw !== undefined) body.resolutionCommit = commitRaw === '' ? null : commitRaw;\n\n if (Object.keys(body).length === 0) {\n console.error('Error: No fields to update. Provide at least one of --title, --description, --assign, --priority, --tag, --commit.');\n process.exit(1);\n }\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'PATCH', `/tasks/${id}`, body);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to update task'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n const task = result.data!;\n console.log(`Task ${id} updated.`);\n console.log(` Title: ${task.title}`);\n console.log(` Priority: ${PRIORITY_LABELS[task.priority] ?? task.priority}`);\n if (task.assignedTo) console.log(` Assigned: ${task.assignedTo}`);\n}\n\nasync function handleComplete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task complete <id> [--pr <number>] [--commit <sha>]');\n process.exit(1);\n }\n\n const prRaw = getArgValue(argv, '--pr');\n const prNumber = parsePrFlag(prRaw);\n // If --pr is supplied, don't auto-attach git HEAD — the user explicitly\n // prefers the PR reference. Squash merges rewrite branch SHAs, so attaching\n // both would just store a SHA that will soon dangle.\n const explicitCommit = getArgValue(argv, '--commit');\n const commit = explicitCommit ?? (prNumber !== undefined ? undefined : getHeadCommit() ?? undefined);\n const jsonOutput = hasFlag(argv, '--json');\n\n const body: Record<string, unknown> = {};\n if (commit) body.resolutionCommit = commit;\n if (prNumber !== undefined) body.resolutionPrNumber = prNumber;\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/complete`, body);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to complete task'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n console.log(`Task ${id} marked as completed.`);\n if (prNumber !== undefined) console.log(`Resolution PR: #${prNumber}`);\n if (commit) console.log(`Resolution commit: ${commit.slice(0, 7)}`);\n}\n\nasync function handleSetCommit(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task set-commit <id> [--pr <number>] [--commit <sha>]');\n process.exit(1);\n }\n\n const prRaw = getArgValue(argv, '--pr');\n const prFlagPresent = prRaw !== undefined;\n // `--pr \"\"` clears, `--pr <n>` sets, omitted = untouched.\n const prNumber: number | null | undefined = prFlagPresent\n ? prRaw === ''\n ? null\n : parsePrFlag(prRaw) ?? undefined\n : undefined;\n\n // `--commit \"\"` clears; `--commit <sha>` sets; if neither flag is supplied,\n // fall back to git HEAD (legacy behavior). If --pr was supplied, skip the\n // HEAD fallback so the user can patch just the PR.\n const explicit = getArgValue(argv, '--commit');\n let commit: string | null | undefined;\n if (explicit !== undefined) {\n commit = explicit === '' ? null : explicit;\n } else if (prFlagPresent) {\n commit = undefined;\n } else {\n const head = getHeadCommit();\n if (head === null) {\n console.error('Error: Could not determine commit — not in a git repo. Pass --commit <sha> or --pr <n> explicitly.');\n process.exit(1);\n }\n commit = head;\n }\n\n const body: Record<string, unknown> = {};\n if (commit !== undefined) body.resolutionCommit = commit;\n if (prNumber !== undefined) body.resolutionPrNumber = prNumber;\n\n if (Object.keys(body).length === 0) {\n console.error('Error: Nothing to update. Pass --commit <sha> or --pr <n>.');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'PATCH', `/tasks/${id}`, body);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to update resolution'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n if (commit === null) console.log(`Task ${id} resolution commit cleared.`);\n else if (commit !== undefined) console.log(`Task ${id} resolution commit set to ${commit.slice(0, 7)}.`);\n if (prNumber === null) console.log(`Task ${id} resolution PR cleared.`);\n else if (prNumber !== undefined) console.log(`Task ${id} resolution PR set to #${prNumber}.`);\n}\n\n/**\n * Parse and validate `--pr <number>`. Rejects URLs (must pass number).\n * Returns undefined if the flag is missing or empty; exits on invalid input.\n */\nfunction parsePrFlag(raw: string | undefined): number | undefined {\n if (raw === undefined || raw === '') return undefined;\n if (raw.includes('/') || raw.includes('http')) {\n console.error(`Error: --pr expects a number, got \"${raw}\". Pass the PR number only.`);\n process.exit(1);\n }\n const n = Number(raw);\n if (!Number.isInteger(n) || n <= 0) {\n console.error(`Error: --pr must be a positive integer, got \"${raw}\".`);\n process.exit(1);\n }\n return n;\n}\n\nasync function handleCancel(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n process.exit(1);\n }\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/cancel`);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to cancel task'}`);\n process.exit(1);\n }\n\n console.log(`Task ${id} canceled.`);\n}\n\nasync function handleTrigger(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n process.exit(1);\n }\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/trigger`);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to trigger task'}`);\n process.exit(1);\n }\n\n console.log(`Task ${id} triggered (now actionable).`);\n}\n\nasync function handleReopen(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task reopen <id> [--status <actionable|in_progress>]');\n process.exit(1);\n }\n\n const status = getArgValue(argv, '--status') ?? 'actionable';\n if (status !== 'actionable' && status !== 'in_progress') {\n console.error(`Error: Invalid status \"${status}\". Must be \"actionable\" or \"in_progress\".`);\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/reopen`, { status });\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to reopen task'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n console.log(`Task ${id} reopened (now ${status}).`);\n}\n\nasync function handleRelease(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task release <id> [--status <actionable|waiting>]');\n process.exit(1);\n }\n\n const status = getArgValue(argv, '--status') ?? 'actionable';\n if (status !== 'actionable' && status !== 'waiting') {\n console.error(`Error: Invalid status \"${status}\". Must be \"actionable\" or \"waiting\".`);\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/release`, { status });\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to release task'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n\n console.log(`Task ${id} released (now ${status}).`);\n}\n\nasync function handleClaim(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n process.exit(1);\n }\n\n const result = await apiRequest<TaskResponse>(apiUrl, token, 'POST', `/tasks/${id}/claim`);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to claim task'}`);\n process.exit(1);\n }\n\n console.log(`Task ${id} claimed (now in progress).`);\n}\n\nasync function handleExecute(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task execute <id> --instance <instanceId>');\n process.exit(1);\n }\n\n const instanceId = getArgValue(argv, '--instance');\n if (!instanceId) {\n console.error('Error: --instance <instanceId> is required.');\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: { jobId: string; taskId: string } }>(\n apiUrl,\n token,\n 'POST',\n `/tasks/${id}/execute`,\n { instanceId }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to execute task'}`);\n process.exit(1);\n }\n\n console.log(`Task ${id} dispatched to sandbox instance ${instanceId}.`);\n if (result.data?.jobId) {\n console.log(`Job ID: ${result.data.jobId}`);\n }\n}\n\nasync function handleLinkCustomer(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task link-customer <id> --org <orgId> | --name \"Customer Name\"');\n process.exit(1);\n }\n\n const orgId = getArgValue(argv, '--org');\n const name = getArgValue(argv, '--name');\n\n if (!orgId && !name) {\n console.error('Error: --org <orgId> or --name \"Customer Name\" is required.');\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (orgId) body.orgId = orgId;\n if (name) body.name = name;\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: AgentTaskCustomer }>(\n apiUrl,\n token,\n 'POST',\n `/tasks/${id}/customers`,\n body\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to link customer'}`);\n process.exit(1);\n }\n\n console.log(`Customer linked to task ${id}: ${result.data?.name ?? name ?? orgId}`);\n}\n\nasync function handleUnlinkCustomer(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task unlink-customer <taskId> --customer-id <customerId>');\n process.exit(1);\n }\n\n const customerId = getArgValue(argv, '--customer-id');\n if (!customerId) {\n console.error('Error: --customer-id is required. Use `canary task get <id>` to see customer IDs.');\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/tasks/${id}/customers/${customerId}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to unlink customer'}`);\n process.exit(1);\n }\n\n console.log(`Customer unlinked from task ${id}.`);\n}\n\ntype TaskCommentItem = {\n id: string;\n taskId: string;\n authorId: string;\n authorDisplayName: string | null;\n body: string;\n createdAt: string;\n updatedAt: string;\n};\n\ntype TaskCommentsResponse = {\n ok: boolean;\n error?: string;\n data: TaskCommentItem[];\n pagination: { page: number; pageSize: number; totalItems: number; totalPages: number };\n};\n\ntype TaskCommentCreateResponse = {\n ok: boolean;\n error?: string;\n comment?: TaskCommentItem;\n};\n\nasync function handleComment(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task comment <id> <message>');\n console.error(' canary task comment <id> --body <message>');\n process.exit(1);\n }\n\n // Support both positional and --body flag\n let body = getArgValue(argv, '--body');\n if (!body) {\n // Positional: everything after the ID that isn't a flag\n const rest = argv.slice(1).filter((a) => !a.startsWith('--'));\n body = rest.join(' ').trim();\n }\n\n if (!body) {\n console.error('Error: Comment body is required.');\n console.error('Usage: canary task comment <id> \"Your comment here\"');\n process.exit(1);\n }\n\n const result = await apiRequest<TaskCommentCreateResponse>(\n apiUrl,\n token,\n 'POST',\n `/tasks/${id}/comments`,\n { body }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to add comment'}`);\n process.exit(1);\n }\n\n console.log(`Comment added to task ${id.slice(0, 8)}.`);\n}\n\nasync function handleComments(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing task ID.');\n console.error('Usage: canary task comments <id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const page = getArgValue(argv, '--page') ?? '1';\n\n const result = await apiRequest<TaskCommentsResponse>(\n apiUrl,\n token,\n 'GET',\n `/tasks/${id}/comments?page=${page}&pageSize=25`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Failed to list comments'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (result.data.length === 0) {\n console.log('No comments.');\n return;\n }\n\n console.log(`Comments (page ${result.pagination.page}/${result.pagination.totalPages}, ${result.pagination.totalItems} total):\\n`);\n for (const c of result.data) {\n const author = c.authorDisplayName ?? c.authorId.slice(0, 8);\n const date = new Date(c.createdAt).toLocaleString();\n console.log(` ${author} · ${date}`);\n console.log(` ${c.body}\\n`);\n }\n}\n\nexport async function runTask(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case 'create':\n await handleCreate(rest, apiUrl, token);\n break;\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'update':\n await handleUpdate(rest, apiUrl, token);\n break;\n case 'complete':\n await handleComplete(rest, apiUrl, token);\n break;\n case 'set-commit':\n await handleSetCommit(rest, apiUrl, token);\n break;\n case 'cancel':\n await handleCancel(rest, apiUrl, token);\n break;\n case 'reopen':\n await handleReopen(rest, apiUrl, token);\n break;\n case 'release':\n await handleRelease(rest, apiUrl, token);\n break;\n case 'trigger':\n await handleTrigger(rest, apiUrl, token);\n break;\n case 'claim':\n await handleClaim(rest, apiUrl, token);\n break;\n case 'execute':\n await handleExecute(rest, apiUrl, token);\n break;\n case 'comment':\n await handleComment(rest, apiUrl, token);\n break;\n case 'comments':\n await handleComments(rest, apiUrl, token);\n break;\n case 'subtasks':\n await handleSubtasks(rest, apiUrl, token);\n break;\n case 'link-customer':\n await handleLinkCustomer(rest, apiUrl, token);\n break;\n case 'unlink-customer':\n await handleUnlinkCustomer(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,394 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ runRemoteTest
4
+ } from "./chunk-GKY2KXO5.js";
5
+ import {
6
+ isTriageEnabledForExecution
7
+ } from "./chunk-CLAWT7BJ.js";
8
+ import {
9
+ apiRequest
10
+ } from "./chunk-WOHL4FTB.js";
11
+ import "./chunk-SJJW77WN.js";
12
+ import "./chunk-3CZU7XCS.js";
13
+ import {
14
+ getArgValue,
15
+ hasFlag,
16
+ resolveConfig
17
+ } from "./chunk-A4OFTUVV.js";
18
+ import "./chunk-JWHYXEA2.js";
19
+ import "./chunk-VKVL7WBN.js";
20
+
21
+ // src/test-suite.ts
22
+ import process from "process";
23
+ var STATUS_ICONS = {
24
+ completed: "\u2705",
25
+ completed_with_errors: "\u26A0\uFE0F",
26
+ success: "\u2705",
27
+ failed: "\u274C",
28
+ running: "\u{1F535}",
29
+ queued: "\u23F3",
30
+ canceled: "\u{1F6AB}",
31
+ timeout: "\u23F0",
32
+ skipped: "\u23ED\uFE0F",
33
+ flaky_success: "\u{1F7E1}",
34
+ pending: "\u23F3"
35
+ };
36
+ function statusIcon(status) {
37
+ return STATUS_ICONS[status] ?? "\u2753";
38
+ }
39
+ function formatRelative(iso) {
40
+ if (!iso) return "\u2014";
41
+ const diffMs = Date.now() - new Date(iso).getTime();
42
+ if (diffMs < 0) return "just now";
43
+ const seconds = Math.floor(diffMs / 1e3);
44
+ if (seconds < 60) return "just now";
45
+ const minutes = Math.floor(seconds / 60);
46
+ if (minutes < 60) return `${minutes}m ago`;
47
+ const hours = Math.floor(minutes / 60);
48
+ if (hours < 24) return `${hours}h ago`;
49
+ const days = Math.floor(hours / 24);
50
+ return `${days}d ago`;
51
+ }
52
+ function computeDuration(startedAt, finishedAt) {
53
+ if (!startedAt || !finishedAt) return "\u2014";
54
+ const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();
55
+ if (ms < 0) return "\u2014";
56
+ const totalSeconds = Math.floor(ms / 1e3);
57
+ if (totalSeconds < 60) return `${totalSeconds}s`;
58
+ const minutes = Math.floor(totalSeconds / 60);
59
+ const seconds = totalSeconds % 60;
60
+ if (minutes < 60) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
61
+ const hours = Math.floor(minutes / 60);
62
+ const remainMins = minutes % 60;
63
+ return remainMins > 0 ? `${hours}h ${remainMins}m` : `${hours}h`;
64
+ }
65
+ function pad(str, len) {
66
+ return str.padEnd(len);
67
+ }
68
+ async function handleList(argv, apiUrl, token) {
69
+ const jsonOutput = hasFlag(argv, "--json");
70
+ const page = getArgValue(argv, "--page") ?? "1";
71
+ const pageSize = getArgValue(argv, "--page-size") ?? "20";
72
+ const params = new URLSearchParams();
73
+ params.set("page", page);
74
+ params.set("pageSize", pageSize);
75
+ params.set("sortBy", "createdAt");
76
+ params.set("sortOrder", "desc");
77
+ const result = await apiRequest(
78
+ apiUrl,
79
+ token,
80
+ "GET",
81
+ `/workflows/test-executions?${params}`
82
+ );
83
+ if (!result.ok) {
84
+ console.error(`Error: ${result.error ?? "Unknown error"}`);
85
+ process.exit(1);
86
+ }
87
+ if (jsonOutput) {
88
+ console.log(JSON.stringify(result, null, 2));
89
+ return;
90
+ }
91
+ const { data, pagination } = result;
92
+ if (data.length === 0) {
93
+ console.log("No test suites found.");
94
+ return;
95
+ }
96
+ console.log(
97
+ `Test Suites (page ${pagination.page}/${pagination.totalPages}, ${pagination.totalItems} total)
98
+ `
99
+ );
100
+ for (const exec of data) {
101
+ const icon = statusIcon(exec.status);
102
+ const total = String(exec.totalWorkflows).padStart(3);
103
+ const passed = String(exec.successfulWorkflows).padStart(3);
104
+ const failed = String(exec.failedWorkflows).padStart(3);
105
+ const time = formatRelative(exec.createdAt);
106
+ console.log(
107
+ ` ${icon} ${exec.id} ${total} total ${passed} passed ${failed} failed ${time}`
108
+ );
109
+ }
110
+ console.log("");
111
+ }
112
+ async function handleGet(argv, apiUrl, token) {
113
+ const id = argv.find((a) => !a.startsWith("-"));
114
+ if (!id) {
115
+ console.error("Error: Missing execution ID. Usage: canary test-suite get <id>");
116
+ process.exit(1);
117
+ }
118
+ const jsonOutput = hasFlag(argv, "--json");
119
+ const failuresOnly = hasFlag(argv, "--failures-only");
120
+ const result = await apiRequest(
121
+ apiUrl,
122
+ token,
123
+ "GET",
124
+ `/workflows/test-executions/${id}`
125
+ );
126
+ if (!result.ok) {
127
+ console.error(`Error: ${result.error ?? "Unknown error"}`);
128
+ process.exit(1);
129
+ }
130
+ if (jsonOutput) {
131
+ console.log(JSON.stringify(result, null, 2));
132
+ return;
133
+ }
134
+ const { execution, testRuns } = result;
135
+ const duration = computeDuration(execution.startedAt, execution.finishedAt);
136
+ console.log(`Test Suite: ${execution.id}`);
137
+ console.log(`Status: ${statusIcon(execution.status)} ${execution.status}`);
138
+ console.log(`Duration: ${duration}`);
139
+ console.log(
140
+ `Total: ${execution.totalWorkflows} | Passed: ${execution.successfulWorkflows} | Failed: ${execution.failedWorkflows} | Skipped: ${execution.skippedWorkflows} | Degraded: ${execution.degradedWorkflows ?? 0}`
141
+ );
142
+ console.log("");
143
+ let runs = testRuns;
144
+ if (failuresOnly) {
145
+ runs = runs.filter((r) => r.status === "failed");
146
+ if (runs.length === 0) {
147
+ console.log("No failing runs.");
148
+ return;
149
+ }
150
+ }
151
+ console.log("Runs:");
152
+ for (const run of runs) {
153
+ const icon = statusIcon(run.status);
154
+ const name = run.workflowName ?? "Unnamed";
155
+ const dur = computeDuration(run.startedAt, run.finishedAt);
156
+ const runId = run.workflowRunId ?? "\u2014";
157
+ console.log(` ${icon} ${pad(name, 30)} ${dur}`);
158
+ console.log(` wf: ${run.workflowId} run: ${runId}`);
159
+ if (run.errorMessage) {
160
+ console.log(` Error: ${run.errorMessage}`);
161
+ }
162
+ if (run.skipReason) {
163
+ console.log(` Skip reason: ${run.skipReason}`);
164
+ }
165
+ if (run.linkedIssueId) {
166
+ console.log(` Linked issue: ${run.linkedIssueId}`);
167
+ }
168
+ }
169
+ console.log("");
170
+ if (execution.failedWorkflows > 0) {
171
+ const triageEnabled = await isTriageEnabledForExecution(apiUrl, token, execution.id);
172
+ if (triageEnabled) {
173
+ console.log(`Triage: canary triage get ${execution.id}`);
174
+ console.log("");
175
+ }
176
+ }
177
+ }
178
+ async function handleDiagnostics(argv, apiUrl, token) {
179
+ const positional = argv.filter((a) => !a.startsWith("-"));
180
+ if (positional.length < 2) {
181
+ console.error(
182
+ "Error: Missing arguments. Usage: canary test-suite diagnostics <workflowId> <runId>"
183
+ );
184
+ process.exit(1);
185
+ }
186
+ const [workflowId, runId] = positional;
187
+ const jsonOutput = hasFlag(argv, "--json");
188
+ const showThoughts = hasFlag(argv, "--thoughts");
189
+ const result = await apiRequest(
190
+ apiUrl,
191
+ token,
192
+ "GET",
193
+ `/workflows/${workflowId}/runs/${runId}/failure-diagnostic${showThoughts ? "?includeThoughts=true" : ""}`
194
+ );
195
+ if (!result.ok) {
196
+ console.error(`Error: ${result.error ?? "Unknown error"}`);
197
+ process.exit(1);
198
+ }
199
+ if (jsonOutput) {
200
+ console.log(JSON.stringify(result, null, 2));
201
+ return;
202
+ }
203
+ if (!result.data) {
204
+ console.log("No diagnostic available for this run.");
205
+ return;
206
+ }
207
+ const { status, diagnostic } = result.data;
208
+ if (status === "pending" || status === "running") {
209
+ console.log(`Diagnostic is still in progress (status: ${status}).`);
210
+ return;
211
+ }
212
+ if (status === "failed") {
213
+ console.log("Diagnostic analysis failed.");
214
+ return;
215
+ }
216
+ if (!diagnostic) {
217
+ console.log("Diagnostic completed but no analysis data available.");
218
+ return;
219
+ }
220
+ console.log("Failure Diagnostic");
221
+ console.log(`Status: ${status}`);
222
+ if (diagnostic.category) {
223
+ const conf = diagnostic.confidence !== null && diagnostic.confidence !== void 0 ? ` (${diagnostic.confidence > 1 ? Math.round(diagnostic.confidence) : Math.round(diagnostic.confidence * 100)}% confidence)` : "";
224
+ console.log(`Category: ${diagnostic.category}${conf}`);
225
+ }
226
+ if (diagnostic.title) {
227
+ console.log(`Title: ${diagnostic.title}`);
228
+ }
229
+ if (diagnostic.analysis) {
230
+ console.log("");
231
+ console.log("Analysis:");
232
+ console.log(` ${diagnostic.analysis}`);
233
+ }
234
+ if (diagnostic.recommendation) {
235
+ console.log("");
236
+ console.log("Recommendation:");
237
+ console.log(` ${diagnostic.recommendation}`);
238
+ }
239
+ if (diagnostic.smokingGun) {
240
+ console.log("");
241
+ console.log("Smoking Gun:");
242
+ console.log(` > ${diagnostic.smokingGun.description}`);
243
+ if (diagnostic.smokingGun.detail) {
244
+ console.log(` ${diagnostic.smokingGun.detail}`);
245
+ }
246
+ }
247
+ if (showThoughts) {
248
+ const thoughts = result.data.thoughts ?? [];
249
+ console.log("");
250
+ console.log(`Agent reasoning (${thoughts.length} step${thoughts.length === 1 ? "" : "s"}):`);
251
+ if (thoughts.length === 0) {
252
+ console.log(" (no reasoning trace captured for this diagnostic)");
253
+ } else {
254
+ for (const t of thoughts) {
255
+ const tool = t.toolName ? ` \u2192 ${t.toolName}()` : "";
256
+ console.log(` [${t.orderIndex}]${tool}`);
257
+ for (const line of t.content.split("\n")) {
258
+ console.log(` ${line}`);
259
+ }
260
+ }
261
+ }
262
+ }
263
+ console.log("");
264
+ }
265
+ async function handleSteps(argv, apiUrl, token) {
266
+ const positional = argv.filter((a) => !a.startsWith("-"));
267
+ if (positional.length < 2) {
268
+ console.error("Error: Missing arguments. Usage: canary test-suite steps <workflowId> <runId>");
269
+ process.exit(1);
270
+ }
271
+ const [workflowId, runId] = positional;
272
+ const jsonOutput = hasFlag(argv, "--json");
273
+ const result = await apiRequest(
274
+ apiUrl,
275
+ token,
276
+ "GET",
277
+ `/workflows/${workflowId}/runs/${runId}`
278
+ );
279
+ if (!result.ok) {
280
+ console.error(`Error: ${result.error ?? "Unknown error"}`);
281
+ process.exit(1);
282
+ }
283
+ if (jsonOutput) {
284
+ console.log(JSON.stringify(result, null, 2));
285
+ return;
286
+ }
287
+ const { run } = result.data;
288
+ const duration = computeDuration(run.startedAt, run.finishedAt);
289
+ console.log(`Run: ${run.id} (${run.status})`);
290
+ console.log(`Duration: ${duration}`);
291
+ if (run.errorMessage) {
292
+ console.log(`Error: ${run.errorMessage}`);
293
+ }
294
+ const steps = (run.steps ?? []).sort((a, b) => a.orderIndex - b.orderIndex);
295
+ if (steps.length === 0) {
296
+ console.log("\nNo steps recorded.");
297
+ return;
298
+ }
299
+ console.log(`
300
+ Steps (${steps.length}):`);
301
+ for (const step of steps) {
302
+ const idx = String(step.orderIndex + 1).padStart(2);
303
+ const icon = statusIcon(step.status);
304
+ const nodeId = step.nodeId.slice(0, 8);
305
+ const dur = computeDuration(step.startedAt, step.finishedAt);
306
+ console.log(` ${idx}. ${icon} ${pad(nodeId, 10)} ${dur}`);
307
+ if (step.errorMessage) {
308
+ console.log(` Error: ${step.errorMessage}`);
309
+ }
310
+ }
311
+ console.log("");
312
+ }
313
+ function printTestSuiteHelp() {
314
+ console.log(
315
+ [
316
+ "Usage: canary test-suite <sub-command> [options]",
317
+ "",
318
+ "Sub-commands:",
319
+ " run [options] Trigger a test suite and stream results",
320
+ " list [options] List recent test suites",
321
+ " get <id> [options] Get test suite detail with runs",
322
+ " diagnostics <workflowId> <runId> Get failure diagnostic for a run (--thoughts for the agent reasoning trace)",
323
+ " steps <workflowId> <runId> Get workflow run steps",
324
+ "",
325
+ "After a run, the suite id can be passed to triage commands:",
326
+ " canary triage wait <suiteId> Block until AI clusters failures (beta)",
327
+ " canary triage get <suiteId> Show clustered failures + suggested actions",
328
+ " canary triage get latest Resolves to the most recent suite",
329
+ "",
330
+ "Run options:",
331
+ " --application <name|id> Target a specific application (alias: --property)",
332
+ " --environment <name|id> Target a specific environment",
333
+ " --tag <tag> Filter workflows by tag",
334
+ " --name-pattern <pat> Filter workflows by name pattern",
335
+ " --verbose, -v Show all SSE events",
336
+ "",
337
+ "List options:",
338
+ " --page <n> Page number (default: 1)",
339
+ " --page-size <n> Page size (default: 20)",
340
+ "",
341
+ "Get options:",
342
+ " --failures-only Show only failing test runs",
343
+ "",
344
+ "Output options:",
345
+ " --json Output raw JSON",
346
+ "",
347
+ "Common options:",
348
+ " --env <env> Target environment (prod, dev)",
349
+ " --api-url <url> API URL override",
350
+ " --token <key> API token override",
351
+ "",
352
+ "Examples:",
353
+ " canary test-suite run Run all workflow tests",
354
+ " canary test-suite run --tag smoke Run smoke-tagged workflows",
355
+ ' canary test-suite run --application "My App" --environment staging',
356
+ " canary test-suite list List recent suite executions",
357
+ " canary test-suite get <id> --failures-only Show only failures"
358
+ ].join("\n")
359
+ );
360
+ }
361
+ async function runTestSuite(argv) {
362
+ const [subCommand, ...rest] = argv;
363
+ if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
364
+ printTestSuiteHelp();
365
+ return;
366
+ }
367
+ if (subCommand === "run") {
368
+ await runRemoteTest(rest);
369
+ return;
370
+ }
371
+ const { apiUrl, token } = await resolveConfig(argv);
372
+ switch (subCommand) {
373
+ case "list":
374
+ await handleList(rest, apiUrl, token);
375
+ break;
376
+ case "get":
377
+ await handleGet(rest, apiUrl, token);
378
+ break;
379
+ case "diagnostics":
380
+ await handleDiagnostics(rest, apiUrl, token);
381
+ break;
382
+ case "steps":
383
+ await handleSteps(rest, apiUrl, token);
384
+ break;
385
+ default:
386
+ console.error(`Unknown sub-command: ${subCommand}`);
387
+ printTestSuiteHelp();
388
+ process.exit(1);
389
+ }
390
+ }
391
+ export {
392
+ runTestSuite
393
+ };
394
+ //# sourceMappingURL=test-suite-DZNJFXDW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/test-suite.ts"],"sourcesContent":["/**\n * CLI subcommand for querying and triggering test suite (workflow test execution) runs.\n *\n * @module TestSuiteCLI\n */\n\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { runRemoteTest } from './remote-test.js';\nimport { isTriageEnabledForExecution } from './triage.js';\n\n// ---------------------------------------------------------------------------\n// Types (matching API serializers in apps/api/src/workflows/routes/shared.ts)\n// ---------------------------------------------------------------------------\n\ntype Pagination = {\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n};\n\ntype TestExecutionSummary = {\n id: string;\n status: string;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n skippedWorkflows: number;\n /** @deprecated Quarantine removed; always 0. Use degradedWorkflows. */\n quarantinedWorkflows: number;\n degradedWorkflows?: number;\n startedAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n};\n\ntype TestExecution = TestExecutionSummary & {\n orgId: string;\n mode: string;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n errorMessage: string | null;\n updatedAt: string;\n};\n\ntype TestRunResult = {\n id: string;\n testRunId: string;\n workflowId: string;\n nodeId: string;\n status: string;\n message: string | null;\n issueId: string | null;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype TestRun = {\n id: string;\n executionId: string | null;\n workflowId: string;\n status: string;\n snapshotVersion: number;\n workflowRunId: string | null;\n triggeredByUserId: string | null;\n triggeredReason: string | null;\n linkedIssueId: string | null;\n isQuarantined: boolean;\n errorMessage: string | null;\n skipReason: string | null;\n startedAt: string | null;\n finishedAt: string | null;\n workflowName: string | null;\n results: TestRunResult[];\n};\n\ntype TestExecutionListResponse = {\n ok: boolean;\n error?: string;\n data: TestExecutionSummary[];\n pagination: Pagination;\n};\n\ntype TestExecutionDetailResponse = {\n ok: boolean;\n error?: string;\n execution: TestExecution;\n testRuns: TestRun[];\n};\n\ntype RunStep = {\n id: string;\n runId: string;\n nodeId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n orderIndex: number;\n metadataJson: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype WorkflowRun = {\n id: string;\n workflowId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n steps: RunStep[];\n};\n\ntype RunWithStepsResponse = {\n ok: boolean;\n error?: string;\n data: { run: WorkflowRun };\n};\n\ntype DiagnosticJson = {\n category?: string;\n confidence?: number;\n title?: string;\n analysis?: string;\n recommendation?: string;\n smokingGun?: { type: string; description: string; detail?: string } | null;\n};\n\ntype DiagnosticThought = {\n content: string;\n toolName: string | null;\n orderIndex: number;\n createdAt: string;\n};\n\ntype FailureDiagnosticResponse = {\n ok: boolean;\n error?: string;\n data: {\n id: string;\n status: string;\n diagnostic: DiagnosticJson | null;\n createdAt: string;\n updatedAt: string;\n thoughts?: DiagnosticThought[];\n } | null;\n};\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nconst STATUS_ICONS: Record<string, string> = {\n completed: '✅',\n completed_with_errors: '⚠️',\n success: '✅',\n failed: '❌',\n running: '🔵',\n queued: '⏳',\n canceled: '🚫',\n timeout: '⏰',\n skipped: '⏭️',\n flaky_success: '🟡',\n pending: '⏳',\n};\n\nfunction statusIcon(status: string): string {\n return STATUS_ICONS[status] ?? '❓';\n}\n\nfunction formatRelative(iso: string | null): string {\n if (!iso) return '—';\n const diffMs = Date.now() - new Date(iso).getTime();\n if (diffMs < 0) return 'just now';\n const seconds = Math.floor(diffMs / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction computeDuration(startedAt: string | null, finishedAt: string | null): string {\n if (!startedAt || !finishedAt) return '—';\n const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();\n if (ms < 0) return '—';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n const remainMins = minutes % 60;\n return remainMins > 0 ? `${hours}h ${remainMins}m` : `${hours}h`;\n}\n\nfunction pad(str: string, len: number): string {\n return str.padEnd(len);\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const page = getArgValue(argv, '--page') ?? '1';\n const pageSize = getArgValue(argv, '--page-size') ?? '20';\n\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('pageSize', pageSize);\n params.set('sortBy', 'createdAt');\n params.set('sortOrder', 'desc');\n\n const result = await apiRequest<TestExecutionListResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions?${params}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { data, pagination } = result;\n\n if (data.length === 0) {\n console.log('No test suites found.');\n return;\n }\n\n console.log(\n `Test Suites (page ${pagination.page}/${pagination.totalPages}, ${pagination.totalItems} total)\\n`\n );\n\n for (const exec of data) {\n const icon = statusIcon(exec.status);\n const total = String(exec.totalWorkflows).padStart(3);\n const passed = String(exec.successfulWorkflows).padStart(3);\n const failed = String(exec.failedWorkflows).padStart(3);\n const time = formatRelative(exec.createdAt);\n\n console.log(\n ` ${icon} ${exec.id} ${total} total ${passed} passed ${failed} failed ${time}`\n );\n }\n\n console.log('');\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: Missing execution ID. Usage: canary test-suite get <id>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const failuresOnly = hasFlag(argv, '--failures-only');\n\n const result = await apiRequest<TestExecutionDetailResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/test-executions/${id}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { execution, testRuns } = result;\n const duration = computeDuration(execution.startedAt, execution.finishedAt);\n\n console.log(`Test Suite: ${execution.id}`);\n console.log(`Status: ${statusIcon(execution.status)} ${execution.status}`);\n console.log(`Duration: ${duration}`);\n console.log(\n `Total: ${execution.totalWorkflows} | Passed: ${execution.successfulWorkflows} | Failed: ${execution.failedWorkflows} | Skipped: ${execution.skippedWorkflows} | Degraded: ${execution.degradedWorkflows ?? 0}`\n );\n console.log('');\n\n let runs = testRuns;\n if (failuresOnly) {\n runs = runs.filter((r) => r.status === 'failed');\n if (runs.length === 0) {\n console.log('No failing runs.');\n return;\n }\n }\n\n console.log('Runs:');\n for (const run of runs) {\n const icon = statusIcon(run.status);\n const name = run.workflowName ?? 'Unnamed';\n const dur = computeDuration(run.startedAt, run.finishedAt);\n const runId = run.workflowRunId ?? '—';\n\n console.log(` ${icon} ${pad(name, 30)} ${dur}`);\n console.log(` wf: ${run.workflowId} run: ${runId}`);\n\n if (run.errorMessage) {\n console.log(` Error: ${run.errorMessage}`);\n }\n if (run.skipReason) {\n console.log(` Skip reason: ${run.skipReason}`);\n }\n if (run.linkedIssueId) {\n console.log(` Linked issue: ${run.linkedIssueId}`);\n }\n }\n\n console.log('');\n\n if (execution.failedWorkflows > 0) {\n const triageEnabled = await isTriageEnabledForExecution(apiUrl, token, execution.id);\n if (triageEnabled) {\n console.log(`Triage: canary triage get ${execution.id}`);\n console.log('');\n }\n }\n}\n\nasync function handleDiagnostics(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error(\n 'Error: Missing arguments. Usage: canary test-suite diagnostics <workflowId> <runId>'\n );\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n const showThoughts = hasFlag(argv, '--thoughts');\n\n const result = await apiRequest<FailureDiagnosticResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}/failure-diagnostic${\n showThoughts ? '?includeThoughts=true' : ''\n }`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.data) {\n console.log('No diagnostic available for this run.');\n return;\n }\n\n const { status, diagnostic } = result.data;\n\n if (status === 'pending' || status === 'running') {\n console.log(`Diagnostic is still in progress (status: ${status}).`);\n return;\n }\n\n if (status === 'failed') {\n console.log('Diagnostic analysis failed.');\n return;\n }\n\n if (!diagnostic) {\n console.log('Diagnostic completed but no analysis data available.');\n return;\n }\n\n console.log('Failure Diagnostic');\n console.log(`Status: ${status}`);\n if (diagnostic.category) {\n const conf =\n diagnostic.confidence !== null && diagnostic.confidence !== undefined\n ? ` (${diagnostic.confidence > 1 ? Math.round(diagnostic.confidence) : Math.round(diagnostic.confidence * 100)}% confidence)`\n : '';\n console.log(`Category: ${diagnostic.category}${conf}`);\n }\n if (diagnostic.title) {\n console.log(`Title: ${diagnostic.title}`);\n }\n\n if (diagnostic.analysis) {\n console.log('');\n console.log('Analysis:');\n console.log(` ${diagnostic.analysis}`);\n }\n\n if (diagnostic.recommendation) {\n console.log('');\n console.log('Recommendation:');\n console.log(` ${diagnostic.recommendation}`);\n }\n\n if (diagnostic.smokingGun) {\n console.log('');\n console.log('Smoking Gun:');\n console.log(` > ${diagnostic.smokingGun.description}`);\n if (diagnostic.smokingGun.detail) {\n console.log(` ${diagnostic.smokingGun.detail}`);\n }\n }\n\n if (showThoughts) {\n const thoughts = result.data.thoughts ?? [];\n console.log('');\n console.log(`Agent reasoning (${thoughts.length} step${thoughts.length === 1 ? '' : 's'}):`);\n if (thoughts.length === 0) {\n console.log(' (no reasoning trace captured for this diagnostic)');\n } else {\n for (const t of thoughts) {\n const tool = t.toolName ? ` → ${t.toolName}()` : '';\n console.log(` [${t.orderIndex}]${tool}`);\n for (const line of t.content.split('\\n')) {\n console.log(` ${line}`);\n }\n }\n }\n }\n\n console.log('');\n}\n\nasync function handleSteps(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n if (positional.length < 2) {\n console.error('Error: Missing arguments. Usage: canary test-suite steps <workflowId> <runId>');\n process.exit(1);\n }\n\n const [workflowId, runId] = positional;\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<RunWithStepsResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/runs/${runId}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const { run } = result.data;\n const duration = computeDuration(run.startedAt, run.finishedAt);\n\n console.log(`Run: ${run.id} (${run.status})`);\n console.log(`Duration: ${duration}`);\n\n if (run.errorMessage) {\n console.log(`Error: ${run.errorMessage}`);\n }\n\n const steps = (run.steps ?? []).sort((a, b) => a.orderIndex - b.orderIndex);\n\n if (steps.length === 0) {\n console.log('\\nNo steps recorded.');\n return;\n }\n\n console.log(`\\nSteps (${steps.length}):`);\n for (const step of steps) {\n const idx = String(step.orderIndex + 1).padStart(2);\n const icon = statusIcon(step.status);\n const nodeId = step.nodeId.slice(0, 8);\n const dur = computeDuration(step.startedAt, step.finishedAt);\n\n console.log(` ${idx}. ${icon} ${pad(nodeId, 10)} ${dur}`);\n\n if (step.errorMessage) {\n console.log(` Error: ${step.errorMessage}`);\n }\n }\n\n console.log('');\n}\n\n// ---------------------------------------------------------------------------\n// Help\n// ---------------------------------------------------------------------------\n\nfunction printTestSuiteHelp(): void {\n console.log(\n [\n 'Usage: canary test-suite <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' run [options] Trigger a test suite and stream results',\n ' list [options] List recent test suites',\n ' get <id> [options] Get test suite detail with runs',\n ' diagnostics <workflowId> <runId> Get failure diagnostic for a run (--thoughts for the agent reasoning trace)',\n ' steps <workflowId> <runId> Get workflow run steps',\n '',\n 'After a run, the suite id can be passed to triage commands:',\n ' canary triage wait <suiteId> Block until AI clusters failures (beta)',\n ' canary triage get <suiteId> Show clustered failures + suggested actions',\n ' canary triage get latest Resolves to the most recent suite',\n '',\n 'Run options:',\n ' --application <name|id> Target a specific application (alias: --property)',\n ' --environment <name|id> Target a specific environment',\n ' --tag <tag> Filter workflows by tag',\n ' --name-pattern <pat> Filter workflows by name pattern',\n ' --verbose, -v Show all SSE events',\n '',\n 'List options:',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 20)',\n '',\n 'Get options:',\n ' --failures-only Show only failing test runs',\n '',\n 'Output options:',\n ' --json Output raw JSON',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n '',\n 'Examples:',\n ' canary test-suite run Run all workflow tests',\n ' canary test-suite run --tag smoke Run smoke-tagged workflows',\n ' canary test-suite run --application \"My App\" --environment staging',\n ' canary test-suite list List recent suite executions',\n ' canary test-suite get <id> --failures-only Show only failures',\n ].join('\\n')\n );\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nexport async function runTestSuite(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printTestSuiteHelp();\n return;\n }\n\n if (subCommand === 'run') {\n // Delegate to runRemoteTest — pass through remaining args\n await runRemoteTest(rest);\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'diagnostics':\n await handleDiagnostics(rest, apiUrl, token);\n break;\n case 'steps':\n await handleSteps(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printTestSuiteHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,14 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ runTrace
4
+ } from "./chunk-Q4BO4Z5V.js";
5
+ import "./chunk-A4OFTUVV.js";
6
+ import "./chunk-4PNOV7OV.js";
7
+ import "./chunk-JWHYXEA2.js";
8
+ import "./chunk-6LEZCKKV.js";
9
+ import "./chunk-ZD3KHESI.js";
10
+ import "./chunk-VKVL7WBN.js";
11
+ export {
12
+ runTrace
13
+ };
14
+ //# sourceMappingURL=trace-HXIW7U2D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,16 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ isTriageEnabledForExecution,
4
+ runTriage
5
+ } from "./chunk-CLAWT7BJ.js";
6
+ import "./chunk-WOHL4FTB.js";
7
+ import "./chunk-SJJW77WN.js";
8
+ import "./chunk-3CZU7XCS.js";
9
+ import "./chunk-A4OFTUVV.js";
10
+ import "./chunk-JWHYXEA2.js";
11
+ import "./chunk-VKVL7WBN.js";
12
+ export {
13
+ isTriageEnabledForExecution,
14
+ runTriage
15
+ };
16
+ //# sourceMappingURL=triage-ORG45R5W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}