feat(nodes): add Bash node for running shell commands#158
Draft
xujustinj wants to merge 1 commit into
Draft
Conversation
Implements #157. Every shell command can be viewed as a workflow node: a Jinja-rendered command line runs in a subprocess and its standard streams become output files. - `command` param is a Jinja template rendered with the node's `arguments` input, so upstream values substitute in via `{{ name }}`. - `combine_output` param merges stderr into stdout (2>&1), switching the output shape to a single combined file (via dynamic_output_type). - Outputs `stdout`/`stderr` files plus an `exit_code`. - Runs in the user's $SHELL (falls back to /bin/bash) in the engine's own environment, per the maintainer discussion on the issue. This is effectively RCE and is documented as trusted-local-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #157.
Implements the idea from #157: every shell command can be viewed as a workflow node with arguments in and its standard streams as output files.
What's new
BashNode(type: "Bash"):commandparam — the shell command, rendered as a Jinja template so values from upstream nodes substitute in via{{ name }}(StrictUndefined, so a missing variable errors instead of blanking).combine_outputparam — whentrue, merges stderr into stdout (2>&1) and switches the node's output shape to a single combinedoutputfile (viadynamic_output_type), as described in the issue.argumentsinput — aStringMapValue[StringValue](defaults empty, so argument-free commands need no edge) supplying the Jinja variables.stdout+stderrfiles and anexit_code, or a singleoutputfile +exit_codewhen combining.$SHELL(falls back to/bin/bash) in the engine's own environment, matching the maintainer discussion on the issue.Security
This is effectively remote code execution — it runs arbitrary commands in the engine's environment. The node/module descriptions and docs flag it as trusted, locally-operated engines only; never expose it on an engine that runs untrusted workflows or accepts workflows over the network.
Notes / open questions
exit_codeis just an output, leaving failure handling to downstream nodes. Happy to add acheckparam that raises on non-zero if preferred..bashrcsourcing — the issue mused about full interactive-shell init. This uses a plain non-interactivebash -c(no-i/-l) to avoid hangs and job-control noise; users add init via&&as the issue suggests.Testing
New
tests/test_shell.py(4 tests): basic command, Jinja arg substitution through an input edge, non-zero exit + stderr capture, combined output. Full suite green: ruff (check + format), pyright (0 errors), 648 passed.🤖 Generated with Claude Code