Devflow separates its core orchestration engine from the logic used to build, test, and package your software. The logic is handled by Extensions—specialized programs that connect to Devflow.
While Devflow comes with official extensions for languages like Rust or Node.js, you may need to use Custom Extensions provided by your organization or the open-source community. Let’s look at how to use and manage extensions.
How Extensions Work¶
When you type devflow test, Devflow doesn’t actually know how to run tests for your project. Instead, it:
Searches your system for installed extensions.
Identifies which extension claimed support for the
testcapability.Delegates the heavy lifting to that extension, which then figures out whether to call
cargo test,npm run test,pytest, etc.
Finding and Installing Extensions¶
Extensions are simply executable binaries or scripts in your $PATH that start with the devflow-ext- prefix.
To install an extension:
Download the Binary: Drop the
devflow-ext-xyzbinary into a folder that falls into your system$PATH(e.g.,/usr/local/binor your~/binpath).Verify it’s Executable: Make sure your operating system is permitted to run it (
chmod +x devflow-ext-xyzon Linux/macOS).
Once in your $PATH, Devflow automatically discovers it the next time you run a command.
Trust Model for Subprocess Extensions¶
By default, subprocess extensions are discovered but treated as untrusted for host-side negotiation in runtime.profile = "container".
Default behavior:
trusted = falseOpt-in behavior: explicitly configure trusted extensions in
devflow.toml
[extensions.python]
source = "path"
path = "./tools/devflow-ext-python"
trusted = true
required = trueUse trusted = true only for extensions you have reviewed and control.
Troubleshooting Extensions¶
If a command fails because an extension isn’t running as expected, you can manually isolate the problem without running Devflow.
Check if Devflow sees the extension: Execute the extension directly with the
--discoverflag to ensure it’s responding with capabilities.# Make sure the extension is in your PATH. devflow-ext-myplugin --discoverExpected output:
["test", "build", "fmt"]Diagnose capability gaps: If you get an error saying Devflow does not expose a capability like
test:integration, you can check the JSON output of the discover command above to confirm whether the author missed it.Check execution actions: You can mock what Devflow does by streaming a JSON payload to the extension:
echo '{"primary": "test"}' | devflow-ext-myplugin --build-actionYou should see a printed JSON object showing what program the extension is trying to invoke (e.g.
{"program": "pytest", "args": ["tests/"]}).
Developing Your Own¶
Devflow extensions can be built in any language—Go, Python, Bash, Rust, etc.—because they communicate via simple standard JSON payload I/O. For detailed tutorials on creating your own custom extensions, please check our Developer Guide.
Subprocess Extensions inside Containers¶
A major advantage of the JSON-RPC architecture is that it gracefully delegates through Devflow’s Container Proxy (profile = "container").
If you write a custom extension for Python in a script called devflow-ext-python:
Devflow executes
devflow-ext-pythonlocally on your host when that extension is configured astrusted = true.The local script responds with JSON indicating how to execute
pytest.Devflow then launches
podman run python-ext-ci pytestvia the container engine.
This means you do not need to install your Devflow JSON-RPC extension scripts into the CI images! Devflow runs the extension locally to discover the execution boundaries, and then runs the target toolchain (flake8, pytest) securely isolated inside your locked container.
[project]
name = "python-ext"
stack = ["python"] # Stack matches the configured extension name
[container]
image = "python-ext-ci"
engine = "podman"
[extensions.python]
source = "path"
path = "devflow-ext-python"
trusted = true
required = true