iii-exec
v0.14.0-next.2Execute shell commands as part of engine startup.
skill doc
iii-exec
indexiii-exec
Run a sequential pipeline of shell commands as part of engine startup. Each entry in the configured exec: array launches as a separate child process, must exit 0 before the next entry starts, and the final entry is kept running as a long-lived process for the lifetime of the engine. Optionally, a watch: glob list restarts the entire pipeline whenever a matching file changes.
The worker exposes no callable functions and no trigger types. Its surface is entirely declarative — configure exec: in iii-config.yaml and the engine handles the rest. There is nothing for an agent to call at runtime; this skill describes when to reach for the worker and how to shape its config.
Config schema:
exec: string[]— required. Sequential pipeline of shell commands. Each entry is run as a separate child process; intermediate entries must exit0before the next starts, and the final entry is held open as the long-lived process for the worker's lifetime.watch: string[]— optional. Glob patterns that trigger a full pipeline restart on file change. Caveat: the watcher matches by root directory + file extension only — the filename portion is ignored, sosrc/**/*.test.tsmatches every.tsfile undersrc/, not only test files. Files without an extension (Makefile, shell scripts) are never matched. Use**for recursive subdirectory matching (config/*.jsonwatches only the top level ofconfig/;config/**/*.jsonwatches at any depth).Startup pipeline (
exec:) — sequential commands that must succeed in order, with the final command kept running as a long-lived process bound to the engine's lifecycle.File-watch restart (
watch:) — glob patterns that trigger a full pipeline restart on change. Useful for development; rarely the right choice for production.
How-tos
When to use iii-exec
Reach for this worker when the engine should manage the lifecycle of a separate process — typically a long-running app or daemon that the engine boots, supervises, and shuts down alongside itself. Common patterns:
Build then serve. Two prep commands that must succeed before the long-lived server runs:
- name: iii-exec config: exec: - cd frontend && npm install - cd frontend && npm run build - bun run --enable-source-maps index-production.jsThe first two run sequentially and must exit
0; the third stays running. If any prep step fails (non-zero exit), the pipeline stops, the long-lived server never starts, and the engine surfaces the failure.Development with file watch. Add a
watch:block so the pipeline restarts when source files change:- name: iii-exec config: watch: - steps/**/*.{ts,js} - config/*.json exec: - cd frontend && npm install - cd frontend && npm run build - bun run --enable-source-maps index-production.jsThe watch caveat (repeated for visibility): patterns match by root directory + file extension only — the filename portion is ignored.
src/**/*.test.tsmatches every.tsfile undersrc/, not only*.test.ts. Files without an extension are never matched.
When not to use iii-exec
- Recurring scheduled jobs. Use the
cronreactive trigger fromiii-cron(see its skills bundle) —iii-execis for one-shot startup pipelines and a single long-lived process, not for cron-style scheduling. - Inter-process state sharing across entries. Each entry runs in its own shell, so working directory and environment changes do not carry forward. Chain steps that need to share state with
&&inside one entry:- cd path/to/project && npm run build - Calling shell commands at runtime from a function.
iii-execruns at engine startup only. There's no engine function for "execute this command now."
Operational notes
- Sequential execution, not parallel. Entries run in order. Use a separate process supervisor (or multiple
iii-execworker instances if your config supports them) when you genuinely need parallel processes. - Exit-code propagation. Non-zero exit on any intermediate command stops the pipeline; remaining commands are skipped. The final long-lived command's exit signals engine shutdown of this worker.
- Watch caveats. The watcher is intentionally simple — see the pattern-matching limits documented above before relying on watch in CI or production.
For runnable examples, see the iii main repo.