@runcofactor/cli 0.13.0 → 0.15.1

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 (149) hide show
  1. package/dist/account-62I7FG5G.js +255 -0
  2. package/dist/account-62I7FG5G.js.map +1 -0
  3. package/dist/{api-catalog-7HLEN7C2.js → api-catalog-CAJUASVC.js} +5 -5
  4. package/dist/{attachment-OVNQD6Z2.js → attachment-RL4AZUJE.js} +5 -5
  5. package/dist/augmentor-GAF3MFY6.js +198 -0
  6. package/dist/augmentor-GAF3MFY6.js.map +1 -0
  7. package/dist/{auth-VUHL74FH.js → auth-DURHUZDW.js} +3 -3
  8. package/dist/{chunk-YN763NWQ.js → chunk-26U3DGUM.js} +10 -4
  9. package/dist/chunk-26U3DGUM.js.map +1 -0
  10. package/dist/{chunk-JZMJUPZP.js → chunk-32P26BZT.js} +3 -3
  11. package/dist/chunk-32P26BZT.js.map +1 -0
  12. package/dist/{chunk-QQVWGWPI.js → chunk-5R4HMSNX.js} +8561 -1511
  13. package/dist/chunk-5R4HMSNX.js.map +1 -0
  14. package/dist/{chunk-VGTKUOYS.js → chunk-AQPJQ5AE.js} +2 -2
  15. package/dist/{chunk-CQE46HSM.js → chunk-CFJXYPTF.js} +14 -8
  16. package/dist/chunk-CFJXYPTF.js.map +1 -0
  17. package/dist/{chunk-NL7CVG56.js → chunk-CJEKEW7R.js} +57 -10
  18. package/dist/chunk-CJEKEW7R.js.map +1 -0
  19. package/dist/{chunk-Z5LUTUDN.js → chunk-G5SXUXSU.js} +3 -3
  20. package/dist/{chunk-ZTOE3ND3.js → chunk-HKQ5XQAQ.js} +4 -4
  21. package/dist/{chunk-PZ4LCN6K.js → chunk-IGHDIWZU.js} +2 -2
  22. package/dist/{chunk-QGI4UCJX.js → chunk-IWKJQZJQ.js} +124 -74
  23. package/dist/chunk-IWKJQZJQ.js.map +1 -0
  24. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  25. package/dist/chunk-KRWRUU6R.js.map +1 -0
  26. package/dist/{chunk-CRHPDPRS.js → chunk-PXFDH6YL.js} +63 -8
  27. package/dist/{chunk-CRHPDPRS.js.map → chunk-PXFDH6YL.js.map} +1 -1
  28. package/dist/{chunk-EJ4U242G.js → chunk-UZ2ZA5A6.js} +2 -2
  29. package/dist/{chunk-EEN2TZUQ.js → chunk-VKBTI5EF.js} +3 -3
  30. package/dist/{chunk-ENDHMYEJ.js → chunk-ZXRVFFCY.js} +3 -3
  31. package/dist/{credential-LO2SEEHU.js → credential-JGVSEGVH.js} +5 -5
  32. package/dist/{credential-template-ZN7W7734.js → credential-template-CWWMOKB2.js} +5 -5
  33. package/dist/{debug-workflow-R3RYYAXK.js → debug-workflow-BXRU72YZ.js} +5 -5
  34. package/dist/{docs-DIAFBDXQ.js → docs-PVBXPTGR.js} +95 -11
  35. package/dist/docs-PVBXPTGR.js.map +1 -0
  36. package/dist/{doctor-NZPUSCRE.js → doctor-RHMKD4W5.js} +3 -3
  37. package/dist/{environment-RQVU4P5M.js → environment-WZKIO3R3.js} +5 -5
  38. package/dist/{feature-flag-XG26RURR.js → feature-flag-K5REGGDY.js} +98 -12
  39. package/dist/feature-flag-K5REGGDY.js.map +1 -0
  40. package/dist/index.js +107 -51
  41. package/dist/index.js.map +1 -1
  42. package/dist/{init-EDNLKGPT.js → init-FFUZO5D7.js} +5 -5
  43. package/dist/{install-FYZ3HNZK.js → install-XRKEQAFZ.js} +5 -5
  44. package/dist/{issues-NNRVTJ4L.js → issues-I3V6GEXU.js} +5 -5
  45. package/dist/{knobs-A2BOBH22.js → knobs-6WLJMB44.js} +7 -6
  46. package/dist/knobs-6WLJMB44.js.map +1 -0
  47. package/dist/{list-F33VZ4BJ.js → list-PHC7VYNS.js} +5 -5
  48. package/dist/{local-DQDTM3XA.js → local-VGYRSW22.js} +7 -7
  49. package/dist/{login-BUMVIB36.js → login-QPU2BKG2.js} +5 -5
  50. package/dist/{mcp-B5Y5CDMQ.js → mcp-LA452TOA.js} +9 -9
  51. package/dist/{mcp-B5Y5CDMQ.js.map → mcp-LA452TOA.js.map} +1 -1
  52. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  53. package/dist/product-RSZV5HMB.js +346 -0
  54. package/dist/product-RSZV5HMB.js.map +1 -0
  55. package/dist/{property-NJ4SRXQG.js → property-YP4GHQAR.js} +5 -5
  56. package/dist/{psql-VBZFCMNR.js → psql-XGLBI6T7.js} +3 -3
  57. package/dist/{record-WAO36O7G.js → record-KWKHP2ZY.js} +6 -6
  58. package/dist/{redis-DHZXHL4S.js → redis-VJGCUJPV.js} +3 -3
  59. package/dist/redis-VJGCUJPV.js.map +1 -0
  60. package/dist/{release-STJKUKTE.js → release-NDRHPW6V.js} +5 -5
  61. package/dist/{sandbox-DWSGLY7B.js → sandbox-OOCANWOG.js} +51 -7
  62. package/dist/sandbox-OOCANWOG.js.map +1 -0
  63. package/dist/{scenarios-HCIDY725.js → scenarios-2HRLCGFY.js} +5 -5
  64. package/dist/{session-Y5RHU54D.js → session-M4ULYDYP.js} +8 -9
  65. package/dist/session-M4ULYDYP.js.map +1 -0
  66. package/dist/{skill-23WAHUOB.js → skill-4DGPRDUC.js} +10 -10
  67. package/dist/{skill-23WAHUOB.js.map → skill-4DGPRDUC.js.map} +1 -1
  68. package/dist/skills/debug-run/SKILL.md +7 -1
  69. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  70. package/dist/skills/debug-run/version.json +1 -1
  71. package/dist/skills/optimize-cache/SKILL.md +41 -4
  72. package/dist/{spec-LM5XHOQ5.js → spec-XZ2TKUFZ.js} +5 -5
  73. package/dist/{src-BGDRMOKC.js → src-2FK3JHGW.js} +315 -104
  74. package/dist/src-2FK3JHGW.js.map +1 -0
  75. package/dist/{src-NCJPUAE6.js → src-CV57ZD6I.js} +10 -8
  76. package/dist/{src-22RI5VP2.js → src-HL7HEJIW.js} +2 -2
  77. package/dist/{src-Y3K7UJEF.js → src-OU7544PM.js} +6 -4
  78. package/dist/{start-SWY55CZX.js → start-IYKF3C3X.js} +5 -5
  79. package/dist/{tag-YSU2XXPI.js → tag-T45MMSCH.js} +6 -6
  80. package/dist/{task-NLBKLD7D.js → task-MCUHAVTD.js} +5 -5
  81. package/dist/{test-suite-QCPWZ2LS.js → test-suite-BICBRSBP.js} +10 -8
  82. package/dist/{test-suite-QCPWZ2LS.js.map → test-suite-BICBRSBP.js.map} +1 -1
  83. package/dist/trace-2BAPMYAS.js +16 -0
  84. package/dist/{triage-TT4BMDBU.js → triage-M3RZ2ASB.js} +6 -6
  85. package/dist/{upgrade-6ZUFETKX.js → upgrade-4QCRAUHP.js} +3 -3
  86. package/dist/{workflow-2CX3ZNOQ.js → workflow-4J23FV7K.js} +86 -15
  87. package/dist/workflow-4J23FV7K.js.map +1 -0
  88. package/dist/{workflow-cache-GXNE6SU2.js → workflow-cache-XPSK6KC7.js} +26 -13
  89. package/dist/workflow-cache-XPSK6KC7.js.map +1 -0
  90. package/dist/{workflow-debug-PRX3DWGD.js → workflow-debug-W4USZH35.js} +9 -9
  91. package/dist/{workflow-proposals-BW327WGL.js → workflow-proposals-5E3DTYZB.js} +5 -7
  92. package/dist/workflow-proposals-5E3DTYZB.js.map +1 -0
  93. package/package.json +5 -1
  94. package/dist/chunk-CQE46HSM.js.map +0 -1
  95. package/dist/chunk-JZMJUPZP.js.map +0 -1
  96. package/dist/chunk-NL7CVG56.js.map +0 -1
  97. package/dist/chunk-QGI4UCJX.js.map +0 -1
  98. package/dist/chunk-QQVWGWPI.js.map +0 -1
  99. package/dist/chunk-YN763NWQ.js.map +0 -1
  100. package/dist/chunk-ZD3KHESI.js.map +0 -1
  101. package/dist/docs-DIAFBDXQ.js.map +0 -1
  102. package/dist/feature-flag-XG26RURR.js.map +0 -1
  103. package/dist/knobs-A2BOBH22.js.map +0 -1
  104. package/dist/redis-DHZXHL4S.js.map +0 -1
  105. package/dist/sandbox-DWSGLY7B.js.map +0 -1
  106. package/dist/session-Y5RHU54D.js.map +0 -1
  107. package/dist/src-BGDRMOKC.js.map +0 -1
  108. package/dist/trace-A3ZY6K26.js +0 -16
  109. package/dist/workflow-2CX3ZNOQ.js.map +0 -1
  110. package/dist/workflow-cache-GXNE6SU2.js.map +0 -1
  111. package/dist/workflow-proposals-BW327WGL.js.map +0 -1
  112. /package/dist/{api-catalog-7HLEN7C2.js.map → api-catalog-CAJUASVC.js.map} +0 -0
  113. /package/dist/{attachment-OVNQD6Z2.js.map → attachment-RL4AZUJE.js.map} +0 -0
  114. /package/dist/{auth-VUHL74FH.js.map → auth-DURHUZDW.js.map} +0 -0
  115. /package/dist/{chunk-VGTKUOYS.js.map → chunk-AQPJQ5AE.js.map} +0 -0
  116. /package/dist/{chunk-Z5LUTUDN.js.map → chunk-G5SXUXSU.js.map} +0 -0
  117. /package/dist/{chunk-ZTOE3ND3.js.map → chunk-HKQ5XQAQ.js.map} +0 -0
  118. /package/dist/{chunk-PZ4LCN6K.js.map → chunk-IGHDIWZU.js.map} +0 -0
  119. /package/dist/{chunk-EJ4U242G.js.map → chunk-UZ2ZA5A6.js.map} +0 -0
  120. /package/dist/{chunk-EEN2TZUQ.js.map → chunk-VKBTI5EF.js.map} +0 -0
  121. /package/dist/{chunk-ENDHMYEJ.js.map → chunk-ZXRVFFCY.js.map} +0 -0
  122. /package/dist/{credential-LO2SEEHU.js.map → credential-JGVSEGVH.js.map} +0 -0
  123. /package/dist/{credential-template-ZN7W7734.js.map → credential-template-CWWMOKB2.js.map} +0 -0
  124. /package/dist/{debug-workflow-R3RYYAXK.js.map → debug-workflow-BXRU72YZ.js.map} +0 -0
  125. /package/dist/{doctor-NZPUSCRE.js.map → doctor-RHMKD4W5.js.map} +0 -0
  126. /package/dist/{environment-RQVU4P5M.js.map → environment-WZKIO3R3.js.map} +0 -0
  127. /package/dist/{init-EDNLKGPT.js.map → init-FFUZO5D7.js.map} +0 -0
  128. /package/dist/{install-FYZ3HNZK.js.map → install-XRKEQAFZ.js.map} +0 -0
  129. /package/dist/{issues-NNRVTJ4L.js.map → issues-I3V6GEXU.js.map} +0 -0
  130. /package/dist/{list-F33VZ4BJ.js.map → list-PHC7VYNS.js.map} +0 -0
  131. /package/dist/{local-DQDTM3XA.js.map → local-VGYRSW22.js.map} +0 -0
  132. /package/dist/{login-BUMVIB36.js.map → login-QPU2BKG2.js.map} +0 -0
  133. /package/dist/{pdf-extract-ABWV3L5X.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  134. /package/dist/{property-NJ4SRXQG.js.map → property-YP4GHQAR.js.map} +0 -0
  135. /package/dist/{psql-VBZFCMNR.js.map → psql-XGLBI6T7.js.map} +0 -0
  136. /package/dist/{record-WAO36O7G.js.map → record-KWKHP2ZY.js.map} +0 -0
  137. /package/dist/{release-STJKUKTE.js.map → release-NDRHPW6V.js.map} +0 -0
  138. /package/dist/{scenarios-HCIDY725.js.map → scenarios-2HRLCGFY.js.map} +0 -0
  139. /package/dist/{spec-LM5XHOQ5.js.map → spec-XZ2TKUFZ.js.map} +0 -0
  140. /package/dist/{src-NCJPUAE6.js.map → src-CV57ZD6I.js.map} +0 -0
  141. /package/dist/{src-22RI5VP2.js.map → src-HL7HEJIW.js.map} +0 -0
  142. /package/dist/{src-Y3K7UJEF.js.map → src-OU7544PM.js.map} +0 -0
  143. /package/dist/{start-SWY55CZX.js.map → start-IYKF3C3X.js.map} +0 -0
  144. /package/dist/{tag-YSU2XXPI.js.map → tag-T45MMSCH.js.map} +0 -0
  145. /package/dist/{task-NLBKLD7D.js.map → task-MCUHAVTD.js.map} +0 -0
  146. /package/dist/{trace-A3ZY6K26.js.map → trace-2BAPMYAS.js.map} +0 -0
  147. /package/dist/{triage-TT4BMDBU.js.map → triage-M3RZ2ASB.js.map} +0 -0
  148. /package/dist/{upgrade-6ZUFETKX.js.map → upgrade-4QCRAUHP.js.map} +0 -0
  149. /package/dist/{workflow-debug-PRX3DWGD.js.map → workflow-debug-W4USZH35.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/workflow-cache.ts"],"sourcesContent":["/**\n * CLI handlers for `canary workflow cache {status,clear,optimize,substrate,locator,commit}`.\n *\n * @module WorkflowCacheCLI\n */\n\nimport process from 'node:process';\nimport { hasFlag } from './auth.js';\nimport { apiRequest, promptInput } from './cli-helpers.js';\n\ntype CacheStatusResponse = {\n ok: boolean;\n error?: string;\n workflowId?: string;\n nodes?: Array<{\n nodeId: string;\n cacheId: string;\n compilerVersion: number | null;\n playbookHealth: string | null;\n stepFailureCounts: Record<string, number> | null;\n cachedAt: string | null;\n lastUsedAt: string | null;\n useCount: number;\n gapCount: number;\n }>;\n};\n\ntype CacheClearResponse = {\n ok: boolean;\n error?: string;\n invalidated?: number;\n mode?: string;\n};\n\ntype WorkflowResetResponse = {\n ok: boolean;\n error?: string;\n nodesReset?: number;\n};\n\ntype OptimizeResponse = {\n ok: boolean;\n error?: string;\n jobId?: string;\n runId?: string;\n};\n\ntype CacheRecipeResponse = {\n ok: boolean;\n error?: string;\n cacheId?: string;\n nodeHash?: string;\n cachedStepCount?: number;\n gapStepCount?: number;\n};\n\nfunction flagValue(argv: string[], name: string): string | undefined {\n const i = argv.indexOf(name);\n if (i === -1 || i === argv.length - 1) return undefined;\n return argv[i + 1];\n}\n\n/**\n * Pure helper: build the `cache-clear` request body from parsed argv flags.\n * Returns a discriminated result so callers can surface parse errors without\n * the helper itself writing to stderr or calling `process.exit`.\n *\n * Exported for unit testing.\n */\nexport function buildCacheClearBody(opts: {\n nodeId?: string;\n belowVersionRaw?: string;\n staleOnly?: boolean;\n mode?: string;\n}):\n | { ok: true; body: Record<string, unknown> }\n | { ok: false; error: string } {\n const body: Record<string, unknown> = {};\n if (opts.nodeId) body.nodeId = opts.nodeId;\n if (opts.belowVersionRaw !== undefined) {\n const n = Number(opts.belowVersionRaw);\n if (!Number.isInteger(n) || n <= 0) {\n return {\n ok: false,\n error: `--below-version must be a positive integer, got \"${opts.belowVersionRaw}\"`,\n };\n }\n body.belowVersion = n;\n }\n if (opts.staleOnly) body.staleOnly = true;\n if (opts.mode) {\n if (opts.mode !== 'all' && opts.mode !== 'hard') {\n return {\n ok: false,\n error: `--mode must be \"all\" or \"hard\", got \"${opts.mode}\"`,\n };\n }\n body.mode = opts.mode;\n }\n\n const modeCount =\n (body.nodeId !== undefined ? 1 : 0) +\n (body.belowVersion !== undefined ? 1 : 0) +\n (body.staleOnly !== undefined ? 1 : 0) +\n (body.mode !== undefined ? 1 : 0);\n if (modeCount === 0) {\n return {\n ok: false,\n error:\n 'cache clear requires one of: --node <id>, --below-version <n>, --stale-only, --mode all, or --mode hard',\n };\n }\n if (modeCount > 1) {\n return {\n ok: false,\n error: 'cache clear accepts exactly one of --node / --below-version / --stale-only / --mode',\n };\n }\n return { ok: true, body };\n}\n\nfunction printUsage(): void {\n console.error(\n [\n 'Usage:',\n ' canary workflow cache status <workflowId> [--json]',\n ' canary workflow cache clear <workflowId> <mode> [--json]',\n ' canary workflow cache optimize <workflowId> [--run <runId>] [--json]',\n ' canary workflow cache substrate --workspace <dir> --action <idx> [--phase before|after]',\n ' canary workflow cache locator --workspace <dir> --action <idx> --ref <ref> [--var k=v ...]',\n ' canary workflow cache commit <workflowId> --node <nodeId> --recipe <file.json> [--json]',\n '',\n 'Cache clear modes (pick exactly one):',\n ' --node <nodeId> Invalidate one node\\'s cache row',\n ' --below-version <n> Invalidate caches with compilerVersion < n',\n ' --stale-only Invalidate caches whose playbookHealth = \"stale\"',\n ' --mode all Invalidate every cache row (rows kept, isValid=false)',\n ' --mode hard DESTRUCTIVE: delete cache rows, strip playbookSteps',\n ' from node configs, and null lastRunId. Equivalent to',\n ' the UI \"Reset flow\" button. Requires --yes.',\n '',\n 'Options:',\n ' --yes Skip the interactive confirmation for --mode hard',\n ' --json Output raw JSON',\n ].join('\\n')\n );\n}\n\nexport async function handleWorkflowCache(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const [sub, ...rest] = argv;\n if (!sub || hasFlag(argv, '--help', '-h')) {\n printUsage();\n return;\n }\n\n switch (sub) {\n case 'status':\n await handleStatus(rest, apiUrl, token);\n return;\n case 'clear':\n await handleClear(rest, apiUrl, token);\n return;\n case 'optimize':\n await handleOptimize(rest, apiUrl, token);\n return;\n case 'substrate':\n await handleSubstrate(rest);\n return;\n case 'locator':\n await handleLocator(rest);\n return;\n case 'commit':\n await handleCommit(rest, apiUrl, token);\n return;\n default:\n console.error(`Unknown cache sub-command: ${sub}`);\n printUsage();\n process.exit(1);\n }\n}\n\nasync function handleStatus(argv: string[], apiUrl: string, token: string): Promise<void> {\n const workflowId = argv.find((a) => !a.startsWith('-'));\n if (!workflowId) {\n console.error('Missing workflowId.');\n printUsage();\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n\n const result = await apiRequest<CacheStatusResponse>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/cache-status`\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const nodes = result.nodes ?? [];\n console.log(`Cache status for workflow ${workflowId} (${nodes.length} valid cache rows)\\n`);\n if (nodes.length === 0) {\n console.log(' No valid caches.');\n return;\n }\n\n for (const n of nodes) {\n const health = n.playbookHealth ?? '—';\n const ver = n.compilerVersion ?? 'pre-v2';\n const gaps = n.gapCount;\n const age = n.cachedAt ? new Date(n.cachedAt).toISOString().slice(0, 10) : '—';\n console.log(\n ` node=${n.nodeId.slice(0, 8)} compilerVersion=${ver} health=${health} gaps=${gaps} cachedAt=${age} uses=${n.useCount}`\n );\n }\n}\n\nasync function handleClear(argv: string[], apiUrl: string, token: string): Promise<void> {\n const workflowId = argv.find((a) => !a.startsWith('-'));\n if (!workflowId) {\n console.error('Missing workflowId.');\n printUsage();\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n\n const built = buildCacheClearBody({\n nodeId: flagValue(argv, '--node'),\n belowVersionRaw: flagValue(argv, '--below-version'),\n staleOnly: hasFlag(argv, '--stale-only'),\n mode: flagValue(argv, '--mode'),\n });\n if (!built.ok) {\n console.error(built.error);\n process.exit(1);\n }\n const body = built.body;\n\n if (body.mode === 'hard') {\n await handleHardReset(workflowId, hasFlag(argv, '--yes'), json, apiUrl, token);\n return;\n }\n\n const result = await apiRequest<CacheClearResponse>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/cache-clear`,\n body\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`Cleared (${result.mode}): ${result.invalidated ?? 0} cache row(s)`);\n}\n\nasync function handleHardReset(\n workflowId: string,\n yesFlag: boolean,\n json: boolean,\n apiUrl: string,\n token: string\n): Promise<void> {\n if (!yesFlag) {\n console.log(\n [\n '',\n `Hard reset on workflow ${workflowId} will:`,\n ' - DELETE all cached browser actions for this workflow',\n ' - REMOVE playbookSteps from every node config',\n ' - CLEAR the workflow lastRunId',\n '',\n 'This is equivalent to the UI \"Reset flow\" button and cannot be undone.',\n '',\n ].join('\\n')\n );\n const answer = await promptInput('Type \"yes\" to confirm');\n if (answer.toLowerCase() !== 'yes') {\n console.error('Aborted.');\n process.exit(1);\n }\n }\n\n const result = await apiRequest<WorkflowResetResponse>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/reset`\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(\n `Reset workflow: ${result.nodesReset ?? 0} node(s) cleared (cache rows deleted, playbook steps removed, lastRunId cleared)`\n );\n}\n\nasync function handleOptimize(argv: string[], apiUrl: string, token: string): Promise<void> {\n const workflowId = argv.find((a) => !a.startsWith('-'));\n if (!workflowId) {\n console.error('Missing workflowId.');\n printUsage();\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n const runId = flagValue(argv, '--run');\n\n const result = await apiRequest<OptimizeResponse>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/optimize-cache`,\n runId ? { runId } : {}\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`Cache optimizer job enqueued: ${result.jobId} (harvesting run ${result.runId})`);\n}\n\n/**\n * Reconstruct one trace action's page state and capture its substrate-v2,\n * entirely locally against a materialized run workspace\n * (`canary workflow debug materialize <runId> --out <dir>`).\n */\nasync function handleSubstrate(argv: string[]): Promise<void> {\n const workspace = flagValue(argv, '--workspace');\n const actionIndexRaw = flagValue(argv, '--action');\n const phase = (flagValue(argv, '--phase') ?? 'before') as 'before' | 'after';\n if (!workspace || actionIndexRaw === undefined) {\n console.error('Usage: canary workflow cache substrate --workspace <dir> --action <idx> [--phase before|after]');\n process.exit(1);\n }\n const actionIndex = Number(actionIndexRaw);\n const { SubstrateMaterializer } = await import('@chatsdet/workflow-cache');\n const path = await import('node:path');\n const materializer = new SubstrateMaterializer({\n traceZipPath: path.join(workspace, 'browser', 'trace.zip'),\n outDir: path.join(workspace, 'optimizer', 'substrates'),\n });\n try {\n const result = await materializer.materialize(actionIndex, phase);\n console.log(\n JSON.stringify(\n { substratePath: result.substratePath, domPath: result.domPath },\n null,\n 2\n )\n );\n } finally {\n await materializer.close();\n }\n}\n\n/**\n * Derive a deterministic locator for an element (by aria-ref) and verify it\n * offline against the trace-reconstructed DOM. Locally, no API.\n */\nasync function handleLocator(argv: string[]): Promise<void> {\n const workspace = flagValue(argv, '--workspace');\n const actionIndexRaw = flagValue(argv, '--action');\n const ref = flagValue(argv, '--ref');\n const phase = (flagValue(argv, '--phase') ?? 'before') as 'before' | 'after';\n if (!workspace || actionIndexRaw === undefined || !ref) {\n console.error('Usage: canary workflow cache locator --workspace <dir> --action <idx> --ref <ref> [--var name=value ...]');\n process.exit(1);\n }\n const variableValues: Record<string, string> = {};\n for (let i = 0; i < argv.length - 1; i++) {\n if (argv[i] === '--var') {\n const [name, ...valueParts] = (argv[i + 1] ?? '').split('=');\n if (name && valueParts.length > 0) variableValues[name] = valueParts.join('=');\n }\n }\n const actionIndex = Number(actionIndexRaw);\n const { HeadlessDomSession, SubstrateMaterializer, LocatorVerifier, buildLocator } = await import(\n '@chatsdet/workflow-cache'\n );\n const { parseSnapshot } = await import('@chatsdet/browser-core');\n const path = await import('node:path');\n // One Chromium for capture + verification — they must share a rendering\n // environment or the aria-ref table shifts between the two.\n const session = new HeadlessDomSession();\n const materializer = new SubstrateMaterializer({\n traceZipPath: path.join(workspace, 'browser', 'trace.zip'),\n outDir: path.join(workspace, 'optimizer', 'substrates'),\n session,\n });\n const verifier = new LocatorVerifier({ session });\n try {\n const substrate = await materializer.materialize(actionIndex, phase);\n const snapshot = parseSnapshot(substrate.substrateYaml);\n const built = buildLocator(snapshot, ref, variableValues);\n if (built.irreducible) {\n console.log(\n JSON.stringify(\n { verified: false, irreducible: true, reason: 'no unique predicate — mark as gap' },\n null,\n 2\n )\n );\n process.exit(2);\n }\n const verification = await verifier.verify({\n domPath: substrate.domPath,\n targetRef: ref,\n strategy: built.selectors,\n variableValues,\n });\n console.log(\n JSON.stringify(\n { verified: verification.verdict, predicate: built.predicate, selectors: built.selectors, verification },\n null,\n 2\n )\n );\n if (!verification.verdict) process.exit(2);\n } finally {\n await session.close();\n }\n}\n\n/** Commit an optimizer-authored recipe through the server-validated endpoint. */\nasync function handleCommit(argv: string[], apiUrl: string, token: string): Promise<void> {\n const workflowId = argv.find((a) => !a.startsWith('-'));\n const nodeId = flagValue(argv, '--node');\n const recipePath = flagValue(argv, '--recipe');\n const json = hasFlag(argv, '--json');\n if (!workflowId || !nodeId || !recipePath) {\n console.error('Usage: canary workflow cache commit <workflowId> --node <nodeId> --recipe <file.json>');\n process.exit(1);\n }\n const fs = await import('node:fs/promises');\n const recipe = JSON.parse(await fs.readFile(recipePath, 'utf-8')) as Record<string, unknown>;\n const result = await apiRequest<CacheRecipeResponse>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/nodes/${nodeId}/cache-recipe`,\n recipe\n );\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n console.log(\n `Recipe committed: cache ${result.cacheId} under hash ${result.nodeHash} ` +\n `(${result.cachedStepCount} cached, ${result.gapStepCount} gap steps)`\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/workflow-proposals.ts","../src/proposals-format.ts"],"sourcesContent":["/**\n * `canary workflow proposals <verb>` — list / get / diff / accept / reject /\n * revert workflow proposals.\n *\n * Output mode auto-detects: JSON when piped (`!process.stdout.isTTY`), pretty\n * text when running interactively. `--json` and `--text` flags force either\n * mode. Designed so an agent can pipe JSON straight into `jq` without any\n * extra flag, and a human gets the readable report at a terminal.\n */\n\nimport process from 'node:process';\nimport {\n diffSnapshots,\n fromApiSnapshot,\n type SnapshotDiff,\n} from '@chatsdet/workflow-diff';\nimport { getArgValue, hasFlag } from './auth.js';\n\n/**\n * Like `getArgValue` but also accepts the `--key=value` form that many\n * agents emit by default. Falls back to the space-separated form. Matches\n * only exact `--key=` to avoid false-positives on `--status-filter=x` when\n * looking for `--status`.\n */\nfunction getArg(argv: string[], key: string): string | undefined {\n const prefix = `${key}=`;\n const eq = argv.find((a) => a.startsWith(prefix));\n if (eq) return eq.slice(prefix.length);\n return getArgValue(argv, key);\n}\n\n/** @internal — exported for unit tests only. */\nexport const _internalsForTesting = { getArg };\nimport { apiRequest } from './cli-helpers.js';\nimport { renderProposalList, renderProposalDiff } from './proposals-format.js';\n\n// ── Types ────────────────────────────────────────────────────────────────\n\nexport interface ProposalSummary {\n id: string;\n workflowId: string;\n title: string;\n description: string | null;\n source: 'agent' | 'user' | 'import' | 'api';\n status: 'pending' | 'accepted' | 'rejected' | 'stale';\n createdByUserId: string | null;\n decidedByUserId: string | null;\n decidedAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProposalDetail extends ProposalSummary {\n snapshotJson: {\n nodes?: Array<{\n id: string;\n nodeType: string;\n orderIndex?: number;\n configJson?: Record<string, unknown>;\n }>;\n edges?: Array<{\n id: string;\n sourceNodeId: string;\n targetNodeId: string;\n edgeType?: string | null;\n }>;\n };\n sourceMetadata: Record<string, unknown> | null;\n}\n\ninterface WorkflowDetail {\n id: string;\n nodes: Array<{\n id: string;\n nodeType: string;\n orderIndex?: number;\n configJson?: Record<string, unknown>;\n }>;\n edges: Array<{\n id: string;\n sourceNodeId: string;\n targetNodeId: string;\n edgeType?: string | null;\n }>;\n updatedAt?: string;\n}\n\n// ── Dispatcher ───────────────────────────────────────────────────────────\n\nexport async function handleWorkflowProposals(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n const [verb, ...rest] = argv;\n switch (verb) {\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'diff':\n await handleDiff(rest, apiUrl, token);\n break;\n case 'accept':\n await handleAccept(rest, apiUrl, token);\n break;\n case 'reject':\n await handleReject(rest, apiUrl, token);\n break;\n case 'revert':\n await handleRevert(rest, apiUrl, token);\n break;\n default:\n printHelp();\n process.exit(verb ? 1 : 0);\n }\n}\n\nfunction printHelp() {\n console.error(\n [\n 'Usage: canary workflow proposals <verb> <workflowId> [<proposalId>] [options]',\n '',\n 'Verbs:',\n ' list <wf> list proposals for a workflow',\n ' get <wf> <pid> fetch a proposal (full snapshot)',\n ' diff <wf> <pid> show the diff against the current draft',\n ' accept <wf> <pid> apply the proposal (full or --select=id1,id2)',\n ' reject <wf> <pid> reject the proposal (no draft change)',\n ' revert <wf> <pid> revert a previously-accepted proposal to pending',\n '',\n 'Global options:',\n ' --json force JSON output',\n ' --text force pretty-text output (default when stdout is a TTY)',\n ' --status=<status> (list) filter by pending|accepted|rejected|stale|all',\n ' --include-unchanged (diff) also list rows that did not change',\n ' --select=<ids> (accept) comma-separated node ids to accept (default: all)',\n ].join('\\n'),\n );\n}\n\n// ── Output-mode helper ───────────────────────────────────────────────────\n\nfunction wantsJson(argv: string[]): boolean {\n if (hasFlag(argv, '--json')) return true;\n if (hasFlag(argv, '--text')) return false;\n return !process.stdout.isTTY;\n}\n\nfunction emit(argv: string[], textFallback: string, json: unknown): void {\n if (wantsJson(argv)) {\n console.log(JSON.stringify(json, null, 2));\n } else {\n console.log(textFallback);\n }\n}\n\nfunction requireArgs(\n argv: string[],\n n: number,\n verb: string,\n): asserts argv is string[] {\n if (argv.length < n) {\n console.error(\n `Error: canary workflow proposals ${verb} requires ${n} argument${n === 1 ? '' : 's'}`,\n );\n printHelp();\n process.exit(1);\n }\n}\n\n// ── Handlers ─────────────────────────────────────────────────────────────\n\nasync function handleList(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 1, 'list');\n const [workflowId] = argv;\n const status = getArg(argv, '--status') ?? 'pending';\n const query = status === 'all' ? '' : `?status=${encodeURIComponent(status)}`;\n\n const result = await apiRequest<{\n ok: boolean;\n data?: ProposalSummary[];\n error?: string;\n }>(apiUrl, token, 'GET', `/workflows/${workflowId}/proposals${query}`);\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'failed to list proposals'}`);\n process.exit(1);\n }\n\n const proposals = result.data ?? [];\n emit(argv, renderProposalList(proposals), {\n workflowId,\n count: proposals.length,\n proposals,\n });\n}\n\nasync function handleGet(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 2, 'get');\n const [workflowId, proposalId] = argv;\n\n const result = await apiRequest<{\n ok: boolean;\n data?: ProposalDetail;\n error?: string;\n }>(apiUrl, token, 'GET', `/workflows/${workflowId}/proposals/${proposalId}`);\n\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'proposal not found'}`);\n process.exit(1);\n }\n\n const prop = result.data;\n const text = [\n `Proposal: ${prop.title}`,\n `Source: ${prop.source} Status: ${prop.status}`,\n `Created: ${prop.createdAt}`,\n `Nodes: ${prop.snapshotJson.nodes?.length ?? 0} Edges: ${prop.snapshotJson.edges?.length ?? 0}`,\n ].join('\\n');\n emit(argv, text, prop);\n}\n\nasync function handleDiff(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 2, 'diff');\n const [workflowId, proposalId] = argv;\n\n const [propRes, wfRes] = await Promise.all([\n apiRequest<{ ok: boolean; data?: ProposalDetail; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}/proposals/${proposalId}`,\n ),\n apiRequest<{ ok: boolean; workflow?: WorkflowDetail; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/workflows/${workflowId}`,\n ),\n ]);\n\n if (!propRes.ok || !propRes.data) {\n console.error(`Error: ${propRes.error ?? 'proposal not found'}`);\n process.exit(1);\n }\n if (!wfRes.workflow) {\n console.error(`Error: ${wfRes.error ?? 'workflow not found'}`);\n process.exit(1);\n }\n\n const proposal = propRes.data;\n const workflow = wfRes.workflow;\n\n const current = fromApiSnapshot({\n nodes: workflow.nodes,\n edges: workflow.edges,\n });\n const proposed = fromApiSnapshot(proposal.snapshotJson);\n const diff = diffSnapshots(current, proposed);\n\n const payload = buildDiffPayload(proposal, proposed, diff);\n const includeUnchanged = hasFlag(argv, '--include-unchanged');\n emit(argv, renderProposalDiff(payload, { includeUnchanged }), payload);\n}\n\nasync function handleAccept(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 2, 'accept');\n const [workflowId, proposalId] = argv;\n const selectArg = getArg(argv, '--select');\n const body: { selection?: { acceptedNodeIds: string[] } } = {};\n if (selectArg) {\n const ids = selectArg.split(',').map((s) => s.trim()).filter(Boolean);\n body.selection = { acceptedNodeIds: ids };\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/proposals/${proposalId}/accept`,\n selectArg ? body : undefined,\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'accept failed'}`);\n process.exit(1);\n }\n\n emit(\n argv,\n selectArg\n ? `Accepted ${body.selection!.acceptedNodeIds.length} changes from ${proposalId}.`\n : `Accepted proposal ${proposalId} in full.`,\n { ok: true, proposalId, workflowId, partial: Boolean(selectArg) },\n );\n}\n\nasync function handleReject(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 2, 'reject');\n const [workflowId, proposalId] = argv;\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/proposals/${proposalId}/reject`,\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'reject failed'}`);\n process.exit(1);\n }\n emit(argv, `Rejected proposal ${proposalId}.`, {\n ok: true,\n proposalId,\n workflowId,\n });\n}\n\nasync function handleRevert(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n requireArgs(argv, 2, 'revert');\n const [workflowId, proposalId] = argv;\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/workflows/${workflowId}/proposals/${proposalId}/revert`,\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'revert failed'}`);\n process.exit(1);\n }\n emit(argv, `Reverted proposal ${proposalId} back to pending.`, {\n ok: true,\n proposalId,\n workflowId,\n });\n}\n\n// ── Diff payload shaper ──────────────────────────────────────────────────\n\nexport interface DiffPayload {\n proposal: {\n id: string;\n title: string;\n source: string;\n status: string;\n stale: boolean;\n createdAt: string;\n decidedAt: string | null;\n };\n summary: {\n addedNodes: number;\n removedNodes: number;\n changedNodes: number;\n addedEdges: number;\n removedEdges: number;\n touchedCount: number;\n isEmpty: boolean;\n };\n nodes: {\n added: Array<{\n id: string;\n nodeType: string;\n configJson: Record<string, unknown>;\n }>;\n removed: Array<{\n id: string;\n nodeType: string;\n configJson: Record<string, unknown>;\n }>;\n changed: Array<{\n id: string;\n nodeType: string;\n typeChanged: boolean;\n beforeType?: string;\n afterType?: string;\n fieldChanges: Array<{ path: string; before: unknown; after: unknown }>;\n }>;\n };\n edges: {\n added: Array<{\n sourceNodeId: string;\n targetNodeId: string;\n edgeType: string | null;\n }>;\n removed: Array<{\n sourceNodeId: string;\n targetNodeId: string;\n edgeType: string | null;\n }>;\n };\n}\n\nfunction buildDiffPayload(\n proposal: ProposalDetail,\n proposedSnap: ReturnType<typeof fromApiSnapshot>,\n diff: SnapshotDiff,\n): DiffPayload {\n // Build a proposed-nodes map so the diff payload can include configJson\n // for each changed node (the diff itself only has field-level changes).\n const byId = new Map(proposedSnap.nodes.map((n) => [n.id, n]));\n\n return {\n proposal: {\n id: proposal.id,\n title: proposal.title,\n source: proposal.source,\n status: proposal.status,\n stale: proposal.status === 'stale',\n createdAt: proposal.createdAt,\n decidedAt: proposal.decidedAt,\n },\n summary: {\n addedNodes: diff.addedNodes.length,\n removedNodes: diff.removedNodes.length,\n changedNodes: diff.changedNodes.length,\n addedEdges: diff.addedEdges.length,\n removedEdges: diff.removedEdges.length,\n touchedCount: diff.touchedCount,\n isEmpty: diff.isEmpty,\n },\n nodes: {\n added: diff.addedNodes.map((n) => ({\n id: n.id,\n nodeType: n.nodeType,\n configJson: n.configJson,\n })),\n removed: diff.removedNodes.map((n) => ({\n id: n.id,\n nodeType: n.nodeType,\n configJson: n.configJson,\n })),\n changed: diff.changedNodes.map((c) => ({\n id: c.id,\n nodeType: c.nodeType,\n typeChanged: c.typeChanged,\n beforeType: c.beforeType,\n afterType: c.afterType,\n fieldChanges: c.fieldChanges,\n })),\n },\n edges: {\n added: diff.addedEdges.map((e) => ({\n sourceNodeId: e.sourceNodeId,\n targetNodeId: e.targetNodeId,\n edgeType: e.edgeType ?? null,\n })),\n removed: diff.removedEdges.map((e) => ({\n sourceNodeId: e.sourceNodeId,\n targetNodeId: e.targetNodeId,\n edgeType: e.edgeType ?? null,\n })),\n },\n };\n void byId;\n}\n","/**\n * Pretty-text renderers for `canary workflow proposals list | diff`.\n * Pure — no fetching, easy to test.\n */\n\nimport { getNodeDisplayTitle } from '@chatsdet/workflow-diff';\nimport type { ProposalSummary, DiffPayload } from './workflow-proposals.js';\n\nconst STATUS_DOTS: Record<string, string> = {\n pending: '●',\n accepted: '✓',\n rejected: '✗',\n stale: '⚠',\n};\n\nexport function renderProposalList(proposals: ProposalSummary[]): string {\n if (proposals.length === 0) return 'No proposals.';\n const rows = proposals.map((p) => {\n const dot = STATUS_DOTS[p.status] ?? '•';\n return `${dot} ${pad(p.status, 10)} ${pad(p.source, 8)} ${p.id.slice(0, 8)}… ${p.title}`;\n });\n return [\n `${proposals.length} proposal${proposals.length === 1 ? '' : 's'}`,\n '',\n ...rows,\n ].join('\\n');\n}\n\nexport function renderProposalDiff(\n payload: DiffPayload,\n opts: { includeUnchanged?: boolean } = {},\n): string {\n const { proposal, summary, nodes, edges } = payload;\n const staleNote = proposal.stale ? ' ⚠ STALE' : '';\n const header = [\n `Proposal: ${proposal.title}`,\n `Source: ${proposal.source} Status: ${proposal.status}${staleNote}`,\n `Created: ${proposal.createdAt}`,\n '',\n `Summary: ${summary.addedNodes} added · ${summary.removedNodes} removed · ${summary.changedNodes} changed · ${summary.touchedCount} touched`,\n ];\n\n if (summary.isEmpty) {\n return [...header, '', 'No changes — proposal matches the current draft.'].join('\\n');\n }\n\n const blocks: string[] = [];\n\n for (const n of nodes.added) {\n blocks.push(\n `+ ${pad(n.nodeType.toUpperCase(), 14)} ${getNodeDisplayTitle(n.nodeType, n.configJson)} (${n.id})`,\n );\n }\n for (const n of nodes.removed) {\n blocks.push(\n `- ${pad(n.nodeType.toUpperCase(), 14)} ${getNodeDisplayTitle(n.nodeType, n.configJson)} (${n.id})`,\n );\n }\n for (const c of nodes.changed) {\n const lines = [\n `~ ${pad(c.nodeType.toUpperCase(), 14)} ${c.id}`,\n ];\n if (c.typeChanged) {\n lines.push(` nodeType: ${c.beforeType} → ${c.afterType}`);\n }\n for (const fc of c.fieldChanges) {\n lines.push(` ${fc.path}: ${fmt(fc.before)} → ${fmt(fc.after)}`);\n }\n blocks.push(lines.join('\\n'));\n }\n\n const edgeLine = `Edges: +${summary.addedEdges} -${summary.removedEdges}`;\n if (edges.added.length === 0 && edges.removed.length === 0) {\n return [...header, '', ...blocks, '', edgeLine].join('\\n');\n }\n const edgeLines = [\n ...edges.added.map(\n (e) => ` + ${e.sourceNodeId} → ${e.targetNodeId}${e.edgeType ? ` [${e.edgeType}]` : ''}`,\n ),\n ...edges.removed.map(\n (e) => ` - ${e.sourceNodeId} → ${e.targetNodeId}${e.edgeType ? ` [${e.edgeType}]` : ''}`,\n ),\n ];\n\n const out = [...header, '', ...blocks, '', edgeLine, ...edgeLines];\n\n // --include-unchanged is a passthrough hook for a future expansion; today\n // the diff engine doesn't surface unchanged nodes, so we just note that.\n if (opts.includeUnchanged) {\n out.push('', '(--include-unchanged has no additional output in v1)');\n }\n\n return out.join('\\n');\n}\n\nfunction pad(s: string, n: number): string {\n return s.length >= n ? s : s + ' '.repeat(n - s.length);\n}\n\nfunction fmt(v: unknown): string {\n if (v === undefined) return '(none)';\n if (v === null) return 'null';\n if (typeof v === 'string') return JSON.stringify(v);\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n"],"mappings":"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","names":[]}