feat(workflows): implement interactive workflow run with approval loops, quiet connection, and automatic file uploading - #547
Conversation
| handleSdkError(error, "run workflow"); | ||
| } | ||
| }); | ||
|
|
There was a problem hiding this comment.
Duplicate run command logic across src/cli/commands/sdk/workflows.ts and src/cli/commands/workflow.ts
The run command handler (id/name resolution, file upload, execution polling, the Interrupted approve/edit/abort flow, and result output) is duplicated almost verbatim between sdk/workflows.ts (cmd.command("run <id>")) and workflow.ts (workflow.command('run [workflow-id-or-name]')) — ~230 lines each, differing only in quote style and local variable names.
Could we extract the shared orchestration logic (everything past argument resolution — polling, interrupt handling, output formatting) into a single helper, and keep both command files as thin wrappers that only bind/resolve CLI arguments (id-or-name, --input, --file, --wait, --json) and delegate to it?
Note: this shared logic shouldn't move into services/workflows.ts — that layer is a clean SDK-only wrapper today (no chalk/ora/inquirer/console.log). The polling/prompt/output code is CLI-presentation logic, so it belongs in a separate CLI-level helper (e.g. sdk/actions/run-workflow.ts) that calls the existing runWorkflow service function, rather than being folded into the service itself.
There was a problem hiding this comment.
The sdk workflows run logic is deprecated. I will remove it
There was a problem hiding this comment.
Ok, but lets clean up logic here as well. I added some comments, but in general: we need to leave here only thin orchestration and ui logic (spinners, user interactions, logs)
|
|
||
| try { | ||
| let targetId = id; | ||
| if (!id.startsWith("wfl_")) { |
There was a problem hiding this comment.
Could you please elaborate what this constant actually mean?
| if (match) { | ||
| targetId = match.id; | ||
| } else if (workflows.length === 1) { | ||
| targetId = workflows[0].id; |
There was a problem hiding this comment.
Lets separate parameters - id and name
For id we can use getWorkflow service, for name - create separate helper service to find exact match and throw error if there is no exact match.
| } catch { | ||
| // Keep as string | ||
| } | ||
| } |
There was a problem hiding this comment.
Move to separate helper
| mimeType: "application/octet-stream", | ||
| }); | ||
| uploadedFileName = uploadRes.file_url; | ||
| uploadSpinner.succeed(chalk.green(`✓ File ${path.basename(opts.file)} uploaded successfully.`)); |
There was a problem hiding this comment.
Move to separate service
| const resumeSpinner = ora("Resuming workflow with edited message...").start(); | ||
| try { | ||
| await (client.workflows as any).api.put( | ||
| `/v1/workflows/${targetId}/executions/${execId}/resume`, |
| handleSdkError(error, "run workflow"); | ||
| } | ||
| }); | ||
|
|
There was a problem hiding this comment.
Ok, but lets clean up logic here as well. I added some comments, but in general: we need to leave here only thin orchestration and ui logic (spinners, user interactions, logs)
Ticket
EPMCDME-12353
Summary
This MR extended CodeMie CLI to support executing custom or shared workflows by ID or Name under the codemie workflow run and codemie sdk workflows run commands.
Changes
Impact
Both commands are feature-complete and support:
--no-waitor--jsonexecution), making the CLI commands fully pipeline-safe and compliant with Unix stdout standards.--no-waitoutputs ONLY clean, raw JSON starting metadata and exits instantly.-f,--file <name>option. Specifying a local file automatically reads and uploads it to the CodeMie files API before launching the workflow with its remote file_url reference attached.Verification & Testing Evidence
Integration Tests
Executed and passed 100% of the workflow test suite:
npx vitest run tests/integration/cli-commands/workflow.test.tsA. Standard Output Extraction (Successful Polled Run)
B. Clean JSON Trigger (
--no-waitSuppressing Spinner)1 node ./bin/codemie.js workflow run d362c364-ee7f-4716-a1b7-f6f706d09f0d --input "hello" --no-wait
✓ ✓ Workflow execution started successfully. (Status: In Progress)C. File Assignment & Interactive Approval loop
node ./bin/codemie.js workflow run d362c364-ee7f-4716-a1b7-f6f706d09f0d --input "hello my friend" --file "package.json"