@runcofactor/cli 0.10.0 → 0.15.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 (166) hide show
  1. package/dist/account-22LMP5PX.js +255 -0
  2. package/dist/account-22LMP5PX.js.map +1 -0
  3. package/dist/{api-catalog-GFGCLVS4.js → api-catalog-WTFQNLK6.js} +5 -4
  4. package/dist/{api-catalog-GFGCLVS4.js.map → api-catalog-WTFQNLK6.js.map} +1 -1
  5. package/dist/{attachment-SJC7D7FY.js → attachment-U3NKVPEY.js} +5 -4
  6. package/dist/{attachment-SJC7D7FY.js.map → attachment-U3NKVPEY.js.map} +1 -1
  7. package/dist/augmentor-5GMNAX4M.js +198 -0
  8. package/dist/augmentor-5GMNAX4M.js.map +1 -0
  9. package/dist/{auth-EN6NQCJY.js → auth-VQG2CDUD.js} +3 -2
  10. package/dist/{chunk-A4OFTUVV.js → chunk-3X3NW7QA.js} +7 -4
  11. package/dist/chunk-3X3NW7QA.js.map +1 -0
  12. package/dist/{chunk-N7HFALX3.js → chunk-46IUJXSD.js} +2 -2
  13. package/dist/{chunk-IMPZAX6L.js → chunk-5GD47G2D.js} +37 -1
  14. package/dist/{chunk-IMPZAX6L.js.map → chunk-5GD47G2D.js.map} +1 -1
  15. package/dist/{chunk-B2VISN2V.js → chunk-7VMO2WOZ.js} +238 -68
  16. package/dist/chunk-7VMO2WOZ.js.map +1 -0
  17. package/dist/{chunk-QFDOWABX.js → chunk-CMGI7UZD.js} +6 -3
  18. package/dist/chunk-CMGI7UZD.js.map +1 -0
  19. package/dist/{chunk-XQXVG7RA.js → chunk-FNPMWDUQ.js} +3 -3
  20. package/dist/chunk-G4UYGRZR.js +2 -0
  21. package/dist/{chunk-I4QLI3JO.js → chunk-HDFYUFBI.js} +2 -2
  22. package/dist/chunk-JMJVGMXI.js +92 -0
  23. package/dist/chunk-JMJVGMXI.js.map +1 -0
  24. package/dist/{chunk-SJJW77WN.js → chunk-JYGNMKZ5.js} +129 -38
  25. package/dist/chunk-JYGNMKZ5.js.map +1 -0
  26. package/dist/{chunk-52IO7ACJ.js → chunk-KCHKFYVX.js} +68 -10
  27. package/dist/{chunk-52IO7ACJ.js.map → chunk-KCHKFYVX.js.map} +1 -1
  28. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  29. package/dist/chunk-KRWRUU6R.js.map +1 -0
  30. package/dist/{chunk-CLAWT7BJ.js → chunk-NHTEKEYE.js} +3 -3
  31. package/dist/{chunk-WOHL4FTB.js → chunk-PRBRSIZP.js} +16 -10
  32. package/dist/chunk-PRBRSIZP.js.map +1 -0
  33. package/dist/{chunk-GKY2KXO5.js → chunk-UETBLPKM.js} +154 -37
  34. package/dist/chunk-UETBLPKM.js.map +1 -0
  35. package/dist/{chunk-4PNOV7OV.js → chunk-VGYN2KU2.js} +9284 -1421
  36. package/dist/chunk-VGYN2KU2.js.map +1 -0
  37. package/dist/{chunk-Q4BO4Z5V.js → chunk-XJ5YYYGC.js} +4 -4
  38. package/dist/{credential-COLTBV6D.js → credential-E6KUHRGU.js} +24 -20
  39. package/dist/credential-E6KUHRGU.js.map +1 -0
  40. package/dist/{credential-template-EEPYFG7R.js → credential-template-4GPOPBGD.js} +30 -28
  41. package/dist/credential-template-4GPOPBGD.js.map +1 -0
  42. package/dist/{debug-workflow-KOVH5GOP.js → debug-workflow-XCLCY6S7.js} +5 -4
  43. package/dist/{debug-workflow-KOVH5GOP.js.map → debug-workflow-XCLCY6S7.js.map} +1 -1
  44. package/dist/{docs-3SSORHB5.js → docs-COCZYMW6.js} +95 -10
  45. package/dist/docs-COCZYMW6.js.map +1 -0
  46. package/dist/{doctor-OTSIWV6G.js → doctor-ERIVTCQS.js} +9 -5
  47. package/dist/doctor-ERIVTCQS.js.map +1 -0
  48. package/dist/environment-7Y4BV6XY.js +221 -0
  49. package/dist/environment-7Y4BV6XY.js.map +1 -0
  50. package/dist/{feature-flag-T2LRZME3.js → feature-flag-MHONEX6T.js} +164 -16
  51. package/dist/feature-flag-MHONEX6T.js.map +1 -0
  52. package/dist/index.js +123 -58
  53. package/dist/index.js.map +1 -1
  54. package/dist/{init-TGWRECT2.js → init-OROOM4HF.js} +5 -4
  55. package/dist/{init-TGWRECT2.js.map → init-OROOM4HF.js.map} +1 -1
  56. package/dist/{install-DXSNWZKO.js → install-OJFXHY6U.js} +7 -7
  57. package/dist/{issues-XIZOPX6T.js → issues-32GONR6C.js} +5 -4
  58. package/dist/{issues-XIZOPX6T.js.map → issues-32GONR6C.js.map} +1 -1
  59. package/dist/{knobs-NBINZIUB.js → knobs-UQGGY3CP.js} +7 -5
  60. package/dist/knobs-UQGGY3CP.js.map +1 -0
  61. package/dist/{list-3TDHK637.js → list-ZMIKEC5P.js} +5 -4
  62. package/dist/{list-3TDHK637.js.map → list-ZMIKEC5P.js.map} +1 -1
  63. package/dist/{local-HICVD6PU.js → local-PUD24GGQ.js} +7 -6
  64. package/dist/{local-HICVD6PU.js.map → local-PUD24GGQ.js.map} +1 -1
  65. package/dist/{login-UOIUXVUK.js → login-BSO7YX2D.js} +5 -4
  66. package/dist/{login-UOIUXVUK.js.map → login-BSO7YX2D.js.map} +1 -1
  67. package/dist/{mcp-54IJEOUA.js → mcp-4LS7OJUT.js} +24 -25
  68. package/dist/mcp-4LS7OJUT.js.map +1 -0
  69. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  70. package/dist/product-3JKSJCBC.js +346 -0
  71. package/dist/product-3JKSJCBC.js.map +1 -0
  72. package/dist/{property-UXLOLPTD.js → property-K5DBL4UE.js} +76 -4
  73. package/dist/property-K5DBL4UE.js.map +1 -0
  74. package/dist/{psql-BYUUNLGG.js → psql-PQFUFTSE.js} +3 -2
  75. package/dist/{psql-BYUUNLGG.js.map → psql-PQFUFTSE.js.map} +1 -1
  76. package/dist/{record-4TR2UIIS.js → record-EIIYLFJ4.js} +16 -17
  77. package/dist/record-EIIYLFJ4.js.map +1 -0
  78. package/dist/{redis-35VBUYW7.js → redis-BU36EZZI.js} +3 -2
  79. package/dist/redis-BU36EZZI.js.map +1 -0
  80. package/dist/{release-OOLTUBUT.js → release-LYC2P7DZ.js} +5 -4
  81. package/dist/{release-OOLTUBUT.js.map → release-LYC2P7DZ.js.map} +1 -1
  82. package/dist/{sandbox-XGSUU6G7.js → sandbox-CKHXXZHU.js} +55 -10
  83. package/dist/sandbox-CKHXXZHU.js.map +1 -0
  84. package/dist/{scenarios-GWLJEGHA.js → scenarios-2XJ2G3KR.js} +5 -4
  85. package/dist/{scenarios-GWLJEGHA.js.map → scenarios-2XJ2G3KR.js.map} +1 -1
  86. package/dist/{session-MYFNZPRP.js → session-UTOD5ZYH.js} +77 -10
  87. package/dist/session-UTOD5ZYH.js.map +1 -0
  88. package/dist/{skill-KM34LDMO.js → skill-GMAERMQL.js} +220 -70
  89. package/dist/skill-GMAERMQL.js.map +1 -0
  90. package/dist/skills/debug-run/SKILL.md +40 -23
  91. package/dist/skills/debug-run/history/1.2.0.md +262 -0
  92. package/dist/skills/debug-run/history/1.3.0.md +273 -0
  93. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  94. package/dist/skills/debug-run/version.json +1 -1
  95. package/dist/skills/optimize-cache/SKILL.md +233 -0
  96. package/dist/{spec-RA3CFEKG.js → spec-2NP36U3Y.js} +54 -25
  97. package/dist/spec-2NP36U3Y.js.map +1 -0
  98. package/dist/{src-LB4HBTJQ.js → src-4T6GHXVO.js} +19 -11
  99. package/dist/src-4T6GHXVO.js.map +1 -0
  100. package/dist/{src-N3TPKGTY.js → src-CG52HEE7.js} +10 -7
  101. package/dist/{src-UVDX5UP6.js → src-PK5OZXCM.js} +4 -2
  102. package/dist/src-UEOOC425.js +5941 -0
  103. package/dist/src-UEOOC425.js.map +1 -0
  104. package/dist/{start-PSEQSQA3.js → start-3C7EEFW2.js} +5 -4
  105. package/dist/{start-PSEQSQA3.js.map → start-3C7EEFW2.js.map} +1 -1
  106. package/dist/{tag-YY6YAABQ.js → tag-JSHOMLBR.js} +6 -5
  107. package/dist/{task-IQC3YR5K.js → task-YGWVYTBJ.js} +5 -4
  108. package/dist/{task-IQC3YR5K.js.map → task-YGWVYTBJ.js.map} +1 -1
  109. package/dist/{test-suite-DZNJFXDW.js → test-suite-LI7ZH367.js} +12 -7
  110. package/dist/{test-suite-DZNJFXDW.js.map → test-suite-LI7ZH367.js.map} +1 -1
  111. package/dist/trace-UMLOSIIR.js +16 -0
  112. package/dist/{triage-ORG45R5W.js → triage-ZWJG4NBJ.js} +6 -5
  113. package/dist/triage-ZWJG4NBJ.js.map +1 -0
  114. package/dist/{upgrade-L2VYMP2V.js → upgrade-S7CGEK6H.js} +3 -3
  115. package/dist/{workflow-XYFH5LTP.js → workflow-T4HSAOGW.js} +316 -241
  116. package/dist/workflow-T4HSAOGW.js.map +1 -0
  117. package/dist/{workflow-cache-NQJQFWMV.js → workflow-cache-XVEZ36KF.js} +140 -7
  118. package/dist/workflow-cache-XVEZ36KF.js.map +1 -0
  119. package/dist/{workflow-debug-BGD4UIXU.js → workflow-debug-T2BULXZ7.js} +9 -8
  120. package/dist/{workflow-debug-BGD4UIXU.js.map → workflow-debug-T2BULXZ7.js.map} +1 -1
  121. package/dist/{workflow-proposals-MTUDX46O.js → workflow-proposals-XXEZICN2.js} +5 -6
  122. package/dist/workflow-proposals-XXEZICN2.js.map +1 -0
  123. package/package.json +2 -1
  124. package/dist/chunk-4PNOV7OV.js.map +0 -1
  125. package/dist/chunk-A4OFTUVV.js.map +0 -1
  126. package/dist/chunk-B2VISN2V.js.map +0 -1
  127. package/dist/chunk-GKY2KXO5.js.map +0 -1
  128. package/dist/chunk-JICSYFRJ.js +0 -46
  129. package/dist/chunk-JICSYFRJ.js.map +0 -1
  130. package/dist/chunk-QFDOWABX.js.map +0 -1
  131. package/dist/chunk-SJJW77WN.js.map +0 -1
  132. package/dist/chunk-WOHL4FTB.js.map +0 -1
  133. package/dist/chunk-ZD3KHESI.js.map +0 -1
  134. package/dist/credential-COLTBV6D.js.map +0 -1
  135. package/dist/credential-template-EEPYFG7R.js.map +0 -1
  136. package/dist/docs-3SSORHB5.js.map +0 -1
  137. package/dist/doctor-OTSIWV6G.js.map +0 -1
  138. package/dist/feature-flag-T2LRZME3.js.map +0 -1
  139. package/dist/knobs-NBINZIUB.js.map +0 -1
  140. package/dist/mcp-54IJEOUA.js.map +0 -1
  141. package/dist/property-UXLOLPTD.js.map +0 -1
  142. package/dist/record-4TR2UIIS.js.map +0 -1
  143. package/dist/redis-35VBUYW7.js.map +0 -1
  144. package/dist/sandbox-XGSUU6G7.js.map +0 -1
  145. package/dist/session-MYFNZPRP.js.map +0 -1
  146. package/dist/skill-KM34LDMO.js.map +0 -1
  147. package/dist/spec-RA3CFEKG.js.map +0 -1
  148. package/dist/src-LB4HBTJQ.js.map +0 -1
  149. package/dist/trace-HXIW7U2D.js +0 -14
  150. package/dist/workflow-XYFH5LTP.js.map +0 -1
  151. package/dist/workflow-cache-NQJQFWMV.js.map +0 -1
  152. package/dist/workflow-proposals-MTUDX46O.js.map +0 -1
  153. /package/dist/{auth-EN6NQCJY.js.map → auth-VQG2CDUD.js.map} +0 -0
  154. /package/dist/{chunk-N7HFALX3.js.map → chunk-46IUJXSD.js.map} +0 -0
  155. /package/dist/{chunk-XQXVG7RA.js.map → chunk-FNPMWDUQ.js.map} +0 -0
  156. /package/dist/{pdf-extract-ABWV3L5X.js.map → chunk-G4UYGRZR.js.map} +0 -0
  157. /package/dist/{chunk-I4QLI3JO.js.map → chunk-HDFYUFBI.js.map} +0 -0
  158. /package/dist/{chunk-CLAWT7BJ.js.map → chunk-NHTEKEYE.js.map} +0 -0
  159. /package/dist/{chunk-Q4BO4Z5V.js.map → chunk-XJ5YYYGC.js.map} +0 -0
  160. /package/dist/{install-DXSNWZKO.js.map → install-OJFXHY6U.js.map} +0 -0
  161. /package/dist/{src-N3TPKGTY.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  162. /package/dist/{src-UVDX5UP6.js.map → src-CG52HEE7.js.map} +0 -0
  163. /package/dist/{tag-YY6YAABQ.js.map → src-PK5OZXCM.js.map} +0 -0
  164. /package/dist/{trace-HXIW7U2D.js.map → tag-JSHOMLBR.js.map} +0 -0
  165. /package/dist/{triage-ORG45R5W.js.map → trace-UMLOSIIR.js.map} +0 -0
  166. /package/dist/{upgrade-L2VYMP2V.js.map → upgrade-S7CGEK6H.js.map} +0 -0
@@ -7,14 +7,15 @@ import {
7
7
  fetchList,
8
8
  promptChoice,
9
9
  selectProperty
10
- } from "./chunk-WOHL4FTB.js";
11
- import "./chunk-SJJW77WN.js";
10
+ } from "./chunk-PRBRSIZP.js";
12
11
  import "./chunk-3CZU7XCS.js";
13
12
  import {
14
13
  getArgValue,
15
14
  resolveConfig
16
- } from "./chunk-A4OFTUVV.js";
15
+ } from "./chunk-3X3NW7QA.js";
16
+ import "./chunk-JMJVGMXI.js";
17
17
  import "./chunk-JWHYXEA2.js";
18
+ import "./chunk-JYGNMKZ5.js";
18
19
  import "./chunk-VKVL7WBN.js";
19
20
 
20
21
  // src/local/start.ts
@@ -148,4 +149,4 @@ Use \`canary session\` commands to interact with the browser.`);
148
149
  export {
149
150
  runLocalStart
150
151
  };
151
- //# sourceMappingURL=start-PSEQSQA3.js.map
152
+ //# sourceMappingURL=start-3C7EEFW2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/local/start.ts"],"sourcesContent":["/**\n * `canary local start` — Start a headed session for a local environment.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { getArgValue, resolveConfig } from '../auth.js';\nimport {\n selectProperty,\n promptChoice,\n fetchList,\n downloadStorageState,\n} from '../cli-helpers.js';\nimport { createSession } from '../session/daemon-client.js';\nimport type { CredentialListItem } from '../cli-helpers.js';\n\ninterface LocalEnvironment {\n id: string;\n name: string;\n url: string;\n propertyId: string;\n}\n\nexport async function runLocalStart(argv: string[]) {\n const config = await resolveConfig(argv);\n const propertyHint = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n const envHint = getArgValue(argv, '--environment');\n const credentialHint = getArgValue(argv, '--credential');\n\n // Select property\n const property = await selectProperty(config.apiUrl, config.token, propertyHint);\n if (!property) {\n process.exitCode = 1;\n return;\n }\n\n // Get local environments for this property\n const envs = await fetchList<LocalEnvironment>(\n config.apiUrl,\n config.token,\n `/org/properties/${property.id}/environments/local`,\n 'items'\n );\n\n if (envs.length === 0) {\n console.error('No local environments found. Run `canary local init` first.');\n process.exitCode = 1;\n return;\n }\n\n let selectedEnv: LocalEnvironment;\n if (envHint) {\n const match = envs.find(\n (e) => e.id === envHint || e.name.toLowerCase() === envHint.toLowerCase()\n );\n if (!match) {\n console.error(`Environment \"${envHint}\" not found.`);\n console.error('Available environments:');\n for (const e of envs) {\n console.error(` - ${e.name} (${e.url})`);\n }\n process.exitCode = 1;\n return;\n }\n selectedEnv = match;\n } else if (envs.length === 1) {\n selectedEnv = envs[0];\n } else {\n const picked = await promptChoice(\n 'Select a local environment:',\n envs.map((e) => ({ label: `${e.name} — ${e.url}`, value: e }))\n );\n if (!picked) {\n process.exitCode = 1;\n return;\n }\n selectedEnv = picked;\n }\n\n // Look up credentials for this environment\n const allCredentials = await fetchList<CredentialListItem>(\n config.apiUrl,\n config.token,\n '/org/credentials',\n 'items'\n );\n\n const envCredentials = allCredentials.filter(\n (c) => c.propertyId === property.id\n );\n\n let storageStatePath: string | undefined;\n let credentialName: string | undefined;\n\n if (envCredentials.length > 0) {\n // Pick a credential if multiple\n let credential: CredentialListItem;\n if (credentialHint) {\n const match = envCredentials.find(\n (c) => c.id === credentialHint || c.name.toLowerCase() === credentialHint.toLowerCase()\n );\n if (!match) {\n console.error(`Credential \"${credentialHint}\" not found.`);\n console.error('Available credentials:');\n for (const c of envCredentials) {\n console.error(` - ${c.name}`);\n }\n process.exitCode = 1;\n return;\n }\n credential = match;\n } else if (envCredentials.length === 1) {\n credential = envCredentials[0];\n } else {\n const picked = await promptChoice(\n 'Select a credential:',\n envCredentials.map((c) => ({ label: c.name, value: c }))\n );\n if (!picked) {\n process.exitCode = 1;\n return;\n }\n credential = picked;\n }\n\n credentialName = credential.name;\n\n // Download storage state if available\n if (credential.storageStateS3Key) {\n console.log('Loading saved login state...');\n storageStatePath = await downloadStorageState({\n apiUrl: config.apiUrl,\n token: config.token,\n propertyId: property.id,\n credentialId: credential.id,\n prefix: 'local',\n });\n }\n }\n\n // Create headed session\n console.log(`Starting session at ${selectedEnv.url}...`);\n const result = await createSession({\n name: `local-${property.name}`,\n url: selectedEnv.url,\n storageStatePath,\n credentialName,\n });\n\n if (!result.ok || !result.data) {\n console.error(`Failed to start session: ${result.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`\\nSession started: ${result.data.id}`);\n console.log(` URL: ${selectedEnv.url}`);\n if (credentialName) console.log(` Credential: ${credentialName}`);\n if (storageStatePath) console.log(` Login state: loaded`);\n console.log(`\\nUse \\`canary session\\` commands to interact with the browser.`);\n if (credentialName) {\n console.log(\n `If the login expires, run \\`canary local login\\` — the agent can log you back in without opening a browser.`\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/local/start.ts"],"sourcesContent":["/**\n * `canary local start` — Start a headed session for a local environment.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { getArgValue, resolveConfig } from '../auth.js';\nimport {\n selectProperty,\n promptChoice,\n fetchList,\n downloadStorageState,\n} from '../cli-helpers.js';\nimport { createSession } from '../session/daemon-client.js';\nimport type { CredentialListItem } from '../cli-helpers.js';\n\ninterface LocalEnvironment {\n id: string;\n name: string;\n url: string;\n propertyId: string;\n}\n\nexport async function runLocalStart(argv: string[]) {\n const config = await resolveConfig(argv);\n const propertyHint = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n const envHint = getArgValue(argv, '--environment');\n const credentialHint = getArgValue(argv, '--credential');\n\n // Select property\n const property = await selectProperty(config.apiUrl, config.token, propertyHint);\n if (!property) {\n process.exitCode = 1;\n return;\n }\n\n // Get local environments for this property\n const envs = await fetchList<LocalEnvironment>(\n config.apiUrl,\n config.token,\n `/org/properties/${property.id}/environments/local`,\n 'items'\n );\n\n if (envs.length === 0) {\n console.error('No local environments found. Run `canary local init` first.');\n process.exitCode = 1;\n return;\n }\n\n let selectedEnv: LocalEnvironment;\n if (envHint) {\n const match = envs.find(\n (e) => e.id === envHint || e.name.toLowerCase() === envHint.toLowerCase()\n );\n if (!match) {\n console.error(`Environment \"${envHint}\" not found.`);\n console.error('Available environments:');\n for (const e of envs) {\n console.error(` - ${e.name} (${e.url})`);\n }\n process.exitCode = 1;\n return;\n }\n selectedEnv = match;\n } else if (envs.length === 1) {\n selectedEnv = envs[0];\n } else {\n const picked = await promptChoice(\n 'Select a local environment:',\n envs.map((e) => ({ label: `${e.name} — ${e.url}`, value: e }))\n );\n if (!picked) {\n process.exitCode = 1;\n return;\n }\n selectedEnv = picked;\n }\n\n // Look up credentials for this environment\n const allCredentials = await fetchList<CredentialListItem>(\n config.apiUrl,\n config.token,\n '/org/credentials',\n 'items'\n );\n\n const envCredentials = allCredentials.filter(\n (c) => c.propertyId === property.id\n );\n\n let storageStatePath: string | undefined;\n let credentialName: string | undefined;\n\n if (envCredentials.length > 0) {\n // Pick a credential if multiple\n let credential: CredentialListItem;\n if (credentialHint) {\n const match = envCredentials.find(\n (c) => c.id === credentialHint || c.name.toLowerCase() === credentialHint.toLowerCase()\n );\n if (!match) {\n console.error(`Credential \"${credentialHint}\" not found.`);\n console.error('Available credentials:');\n for (const c of envCredentials) {\n console.error(` - ${c.name}`);\n }\n process.exitCode = 1;\n return;\n }\n credential = match;\n } else if (envCredentials.length === 1) {\n credential = envCredentials[0];\n } else {\n const picked = await promptChoice(\n 'Select a credential:',\n envCredentials.map((c) => ({ label: c.name, value: c }))\n );\n if (!picked) {\n process.exitCode = 1;\n return;\n }\n credential = picked;\n }\n\n credentialName = credential.name;\n\n // Download storage state if available\n if (credential.storageStateS3Key) {\n console.log('Loading saved login state...');\n storageStatePath = await downloadStorageState({\n apiUrl: config.apiUrl,\n token: config.token,\n propertyId: property.id,\n credentialId: credential.id,\n prefix: 'local',\n });\n }\n }\n\n // Create headed session\n console.log(`Starting session at ${selectedEnv.url}...`);\n const result = await createSession({\n name: `local-${property.name}`,\n url: selectedEnv.url,\n storageStatePath,\n credentialName,\n });\n\n if (!result.ok || !result.data) {\n console.error(`Failed to start session: ${result.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`\\nSession started: ${result.data.id}`);\n console.log(` URL: ${selectedEnv.url}`);\n if (credentialName) console.log(` Credential: ${credentialName}`);\n if (storageStatePath) console.log(` Login state: loaded`);\n console.log(`\\nUse \\`canary session\\` commands to interact with the browser.`);\n if (credentialName) {\n console.log(\n `If the login expires, run \\`canary local login\\` — the agent can log you back in without opening a browser.`\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAMA,OAAO,aAAa;AAkBpB,eAAsB,cAAc,MAAgB;AAClD,QAAM,SAAS,MAAM,cAAc,IAAI;AACvC,QAAM,eAAe,YAAY,MAAM,eAAe,KAAK,YAAY,MAAM,YAAY;AACzF,QAAM,UAAU,YAAY,MAAM,eAAe;AACjD,QAAM,iBAAiB,YAAY,MAAM,cAAc;AAGvD,QAAM,WAAW,MAAM,eAAe,OAAO,QAAQ,OAAO,OAAO,YAAY;AAC/E,MAAI,CAAC,UAAU;AACb,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,OAAO,MAAM;AAAA,IACjB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,mBAAmB,SAAS,EAAE;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ,MAAM,6DAA6D;AAC3E,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,SAAS;AACX,UAAM,QAAQ,KAAK;AAAA,MACjB,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,KAAK,YAAY,MAAM,QAAQ,YAAY;AAAA,IAC1E;AACA,QAAI,CAAC,OAAO;AACV,cAAQ,MAAM,gBAAgB,OAAO,cAAc;AACnD,cAAQ,MAAM,yBAAyB;AACvC,iBAAW,KAAK,MAAM;AACpB,gBAAQ,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,GAAG,GAAG;AAAA,MAC1C;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,kBAAc;AAAA,EAChB,WAAW,KAAK,WAAW,GAAG;AAC5B,kBAAc,KAAK,CAAC;AAAA,EACtB,OAAO;AACL,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,KAAK,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,WAAM,EAAE,GAAG,IAAI,OAAO,EAAE,EAAE;AAAA,IAC/D;AACA,QAAI,CAAC,QAAQ;AACX,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,kBAAc;AAAA,EAChB;AAGA,QAAM,iBAAiB,MAAM;AAAA,IAC3B,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAAiB,eAAe;AAAA,IACpC,CAAC,MAAM,EAAE,eAAe,SAAS;AAAA,EACnC;AAEA,MAAI;AACJ,MAAI;AAEJ,MAAI,eAAe,SAAS,GAAG;AAE7B,QAAI;AACJ,QAAI,gBAAgB;AAClB,YAAM,QAAQ,eAAe;AAAA,QAC3B,CAAC,MAAM,EAAE,OAAO,kBAAkB,EAAE,KAAK,YAAY,MAAM,eAAe,YAAY;AAAA,MACxF;AACA,UAAI,CAAC,OAAO;AACV,gBAAQ,MAAM,eAAe,cAAc,cAAc;AACzD,gBAAQ,MAAM,wBAAwB;AACtC,mBAAW,KAAK,gBAAgB;AAC9B,kBAAQ,MAAM,OAAO,EAAE,IAAI,EAAE;AAAA,QAC/B;AACA,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,mBAAa;AAAA,IACf,WAAW,eAAe,WAAW,GAAG;AACtC,mBAAa,eAAe,CAAC;AAAA,IAC/B,OAAO;AACL,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA,eAAe,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,EAAE;AAAA,MACzD;AACA,UAAI,CAAC,QAAQ;AACX,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,mBAAa;AAAA,IACf;AAEA,qBAAiB,WAAW;AAG5B,QAAI,WAAW,mBAAmB;AAChC,cAAQ,IAAI,8BAA8B;AAC1C,yBAAmB,MAAM,qBAAqB;AAAA,QAC5C,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,QACd,YAAY,SAAS;AAAA,QACrB,cAAc,WAAW;AAAA,QACzB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAGA,UAAQ,IAAI,uBAAuB,YAAY,GAAG,KAAK;AACvD,QAAM,SAAS,MAAM,cAAc;AAAA,IACjC,MAAM,SAAS,SAAS,IAAI;AAAA,IAC5B,KAAK,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAC9B,YAAQ,MAAM,4BAA4B,OAAO,SAAS,eAAe,EAAE;AAC3E,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,UAAQ,IAAI;AAAA,mBAAsB,OAAO,KAAK,EAAE,EAAE;AAClD,UAAQ,IAAI,UAAU,YAAY,GAAG,EAAE;AACvC,MAAI,eAAgB,SAAQ,IAAI,iBAAiB,cAAc,EAAE;AACjE,MAAI,iBAAkB,SAAQ,IAAI,uBAAuB;AACzD,UAAQ,IAAI;AAAA,8DAAiE;AAC7E,MAAI,gBAAgB;AAClB,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -5,12 +5,13 @@ import {
5
5
  formatUnknownTagsError,
6
6
  resolveTagNames,
7
7
  runTag
8
- } from "./chunk-XQXVG7RA.js";
9
- import "./chunk-WOHL4FTB.js";
10
- import "./chunk-SJJW77WN.js";
8
+ } from "./chunk-FNPMWDUQ.js";
9
+ import "./chunk-PRBRSIZP.js";
11
10
  import "./chunk-3CZU7XCS.js";
12
- import "./chunk-A4OFTUVV.js";
11
+ import "./chunk-3X3NW7QA.js";
12
+ import "./chunk-JMJVGMXI.js";
13
13
  import "./chunk-JWHYXEA2.js";
14
+ import "./chunk-JYGNMKZ5.js";
14
15
  import "./chunk-VKVL7WBN.js";
15
16
  export {
16
17
  applyWorkflowTagFlags,
@@ -19,4 +20,4 @@ export {
19
20
  resolveTagNames,
20
21
  runTag
21
22
  };
22
- //# sourceMappingURL=tag-YY6YAABQ.js.map
23
+ //# sourceMappingURL=tag-JSHOMLBR.js.map
@@ -1,15 +1,16 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  apiRequest
4
- } from "./chunk-WOHL4FTB.js";
5
- import "./chunk-SJJW77WN.js";
4
+ } from "./chunk-PRBRSIZP.js";
6
5
  import "./chunk-3CZU7XCS.js";
7
6
  import {
8
7
  getArgValue,
9
8
  hasFlag,
10
9
  resolveConfig
11
- } from "./chunk-A4OFTUVV.js";
10
+ } from "./chunk-3X3NW7QA.js";
11
+ import "./chunk-JMJVGMXI.js";
12
12
  import "./chunk-JWHYXEA2.js";
13
+ import "./chunk-JYGNMKZ5.js";
13
14
  import "./chunk-VKVL7WBN.js";
14
15
 
15
16
  // src/task.ts
@@ -919,4 +920,4 @@ async function runTask(argv) {
919
920
  export {
920
921
  runTask
921
922
  };
922
- //# sourceMappingURL=task-IQC3YR5K.js.map
923
+ //# sourceMappingURL=task-YGWVYTBJ.js.map
@@ -1 +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":[]}
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":[]}
@@ -1,21 +1,22 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  runRemoteTest
4
- } from "./chunk-GKY2KXO5.js";
4
+ } from "./chunk-UETBLPKM.js";
5
5
  import {
6
6
  isTriageEnabledForExecution
7
- } from "./chunk-CLAWT7BJ.js";
7
+ } from "./chunk-NHTEKEYE.js";
8
8
  import {
9
9
  apiRequest
10
- } from "./chunk-WOHL4FTB.js";
11
- import "./chunk-SJJW77WN.js";
10
+ } from "./chunk-PRBRSIZP.js";
12
11
  import "./chunk-3CZU7XCS.js";
13
12
  import {
14
13
  getArgValue,
15
14
  hasFlag,
16
15
  resolveConfig
17
- } from "./chunk-A4OFTUVV.js";
16
+ } from "./chunk-3X3NW7QA.js";
17
+ import "./chunk-JMJVGMXI.js";
18
18
  import "./chunk-JWHYXEA2.js";
19
+ import "./chunk-JYGNMKZ5.js";
19
20
  import "./chunk-VKVL7WBN.js";
20
21
 
21
22
  // src/test-suite.ts
@@ -328,8 +329,10 @@ function printTestSuiteHelp() {
328
329
  " canary triage get latest Resolves to the most recent suite",
329
330
  "",
330
331
  "Run options:",
332
+ " --suite <name|id> Run a named, layered test suite (members run in layer order)",
331
333
  " --application <name|id> Target a specific application (alias: --property)",
332
- " --environment <name|id> Target a specific environment",
334
+ " --environment <name|id> Target a specific environment (required with --env-mode force)",
335
+ " --env-mode <mode> mixed (default \u2014 each flow on its preferred env) | force (pin to --environment)",
333
336
  " --tag <tag> Filter workflows by tag",
334
337
  " --name-pattern <pat> Filter workflows by name pattern",
335
338
  " --verbose, -v Show all SSE events",
@@ -351,7 +354,9 @@ function printTestSuiteHelp() {
351
354
  "",
352
355
  "Examples:",
353
356
  " canary test-suite run Run all workflow tests",
357
+ ' canary test-suite run --suite "Checkout flow" Run a named, layered suite',
354
358
  " canary test-suite run --tag smoke Run smoke-tagged workflows",
359
+ ' canary test-suite run --suite "Checkout flow" --env-mode force --environment staging',
355
360
  ' canary test-suite run --application "My App" --environment staging',
356
361
  " canary test-suite list List recent suite executions",
357
362
  " canary test-suite get <id> --failures-only Show only failures"
@@ -391,4 +396,4 @@ async function runTestSuite(argv) {
391
396
  export {
392
397
  runTestSuite
393
398
  };
394
- //# sourceMappingURL=test-suite-DZNJFXDW.js.map
399
+ //# sourceMappingURL=test-suite-LI7ZH367.js.map