Project tool
Empryo auto-detects your toolchain across 21 ecosystems and runs the right lint, typecheck, test, and build commands, with code-enforced pre-commit checks and
The project tool auto-detects your toolchain from config files and runs the correct commands -- no setup, no guessing.
Actions
| Action | Description | Example |
|---|---|---|
lint | Run project linter | project(action: "lint") |
typecheck | Run type checker | project(action: "typecheck") |
test | Run test suite | project(action: "test", file: "src/foo.test.ts") |
build | Build project | project(action: "build") |
run | Run dev server or script | project(action: "run", script: "dev") |
list | Discover monorepo packages | project(action: "list") |
Parameters
| Param | Type | Description |
|---|---|---|
action | required | lint, typecheck, test, build, run, list |
file | optional | Target specific file (test, lint) |
fix | optional | Auto-fix lint issues (biome --write, eslint --fix, ruff --fix) |
flags | optional | Extra CLI flags |
env | optional | Environment variables |
cwd | optional | Working directory (for monorepos) |
timeout | optional | Timeout in ms (default 120000) |
Toolchain detection
detectProfile(cwd) scans for config files and lockfiles:
bun.lock -> bun test, bun run lint, bunx tsc --noEmit
Cargo.toml -> cargo test, cargo clippy, cargo check
go.mod -> go test, golangci-lint run, go build
pyproject.toml -> pytest, ruff check, mypy/pyright
composer.json -> phpunit, phpstan/psalm
Gemfile -> rspec, rubocop
build.gradle -> gradle test, gradle checkJS/TS linter detection
Priority order:
biome.json/biome.jsonc->biome check .oxlintrc.json/.oxlintrc.json->oxlint .eslint.config.js/.eslintrc*->eslint .
Python type checker detection
pyrightconfig.jsonexists ->pyright- Otherwise ->
mypy .
Full ecosystem support
| Ecosystem | Lint | Typecheck | Test | Build |
|---|---|---|---|---|
| JS/TS (Bun) | biome / oxlint / eslint | tsc | bun test | bun run build |
| JS/TS (Node) | biome / oxlint / eslint | tsc | npm test | npm run build |
| Deno | deno lint | deno check | deno test | -- |
| Rust | cargo clippy | cargo check | cargo test | cargo build |
| Go | golangci-lint / go vet | go build | go test | go build |
| Python | ruff / flake8 | pyright / mypy | pytest | -- |
| PHP | phpstan / psalm | phpstan / psalm | phpunit | -- |
| Ruby | rubocop | -- | rspec / rails test | -- |
| Swift | swiftlint | swift build | swift test | swift build |
| Elixir | credo | dialyzer | mix test | mix compile |
| Java/Kotlin | gradle check | javac / kotlinc | gradle test | gradle build |
| C/C++ | clang-tidy | cmake build | ctest | cmake build |
| Dart/Flutter | dart analyze | dart analyze | flutter test | flutter build |
| Zig | -- | zig build | zig build test | zig build |
| Haskell | hlint | stack build | stack test | stack build |
| Scala | -- | sbt compile | sbt test | sbt compile |
| .NET/C# | dotnet format | dotnet build | dotnet test | dotnet build |
| iOS/Xcode | swiftlint | xcodebuild build | xcodebuild test | xcodebuild build |
| Java (Maven) | checkstyle | mvn compile | mvn test | mvn package |
| C/C++ (Make) | -- | -- | make test | make |
| Clojure | clj-kondo | -- | lein test / clj -M:test | lein uberjar |
Pre-commit checks
When the agent runs git commit via the shell tool, Empryo auto-runs detectNativeChecks(cwd) before allowing the commit:
- JS/TS:
biome check . && tsc --noEmit - Rust:
cargo clippy && cargo check - Go:
golangci-lint run && go build ./... - Python:
ruff check && pyright
If checks fail, the commit is blocked and errors are returned to the agent. This is code-enforced -- no prompt instruction needed.
To skip pre-commit checks, commit directly via shell outside Empryo.
The pre-commit check uses detectNativeChecks() which identifies tools from config files directly, never from package.json scripts. This ensures only known, safe tools are run.
Monorepo discovery
project(action: "list") discovers workspace packages:
Supported workspace formats
- pnpm:
pnpm-workspace.yaml - npm/yarn:
workspacesfield inpackage.json - Cargo:
[workspace] membersinCargo.toml - Go:
usedirectives ingo.work
Example output
5 packages:
@myapp/web -- packages/web (biome) [lint, typecheck, test]
@myapp/api -- packages/api (biome) [lint, typecheck, test]
@myapp/shared -- packages/shared (biome) [lint, typecheck]
@myapp/cli -- packages/cli (biome) [lint]
@myapp/docs -- packages/docs [test]
Use project(action: "lint", cwd: "<path>") to target a specific package.Each package gets its own detectProfile() call, so capabilities are accurate per-package.
System prompt integration
The detected toolchain is injected into the system prompt:
Toolchain: bun
Project commands: lint: `bun run lint` . typecheck: `bun run typecheck` . test: `bun test` . build: `bun run build`The agent sees available actions without guessing.
Shell redirect hints
When the agent runs bun run lint, cargo clippy, etc. via shell instead of the project tool, the result includes a hint:
Command succeeded. Next time use project(action: "lint") -- it auto-detects
the toolchain, results are structured, and output is visible in the UI.This educates the agent to prefer the project tool without blocking the command.