Empryoempryo.beta
tools

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

ActionDescriptionExample
lintRun project linterproject(action: "lint")
typecheckRun type checkerproject(action: "typecheck")
testRun test suiteproject(action: "test", file: "src/foo.test.ts")
buildBuild projectproject(action: "build")
runRun dev server or scriptproject(action: "run", script: "dev")
listDiscover monorepo packagesproject(action: "list")

Parameters

ParamTypeDescription
actionrequiredlint, typecheck, test, build, run, list
fileoptionalTarget specific file (test, lint)
fixoptionalAuto-fix lint issues (biome --write, eslint --fix, ruff --fix)
flagsoptionalExtra CLI flags
envoptionalEnvironment variables
cwdoptionalWorking directory (for monorepos)
timeoutoptionalTimeout 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 check

JS/TS linter detection

Priority order:

  1. biome.json / biome.jsonc -> biome check .
  2. oxlintrc.json / .oxlintrc.json -> oxlint .
  3. eslint.config.js / .eslintrc* -> eslint .

Python type checker detection

  • pyrightconfig.json exists -> pyright
  • Otherwise -> mypy .

Full ecosystem support

EcosystemLintTypecheckTestBuild
JS/TS (Bun)biome / oxlint / eslinttscbun testbun run build
JS/TS (Node)biome / oxlint / eslinttscnpm testnpm run build
Denodeno lintdeno checkdeno test--
Rustcargo clippycargo checkcargo testcargo build
Gogolangci-lint / go vetgo buildgo testgo build
Pythonruff / flake8pyright / mypypytest--
PHPphpstan / psalmphpstan / psalmphpunit--
Rubyrubocop--rspec / rails test--
Swiftswiftlintswift buildswift testswift build
Elixircredodialyzermix testmix compile
Java/Kotlingradle checkjavac / kotlincgradle testgradle build
C/C++clang-tidycmake buildctestcmake build
Dart/Flutterdart analyzedart analyzeflutter testflutter build
Zig--zig buildzig build testzig build
Haskellhlintstack buildstack teststack build
Scala--sbt compilesbt testsbt compile
.NET/C#dotnet formatdotnet builddotnet testdotnet build
iOS/Xcodeswiftlintxcodebuild buildxcodebuild testxcodebuild build
Java (Maven)checkstylemvn compilemvn testmvn package
C/C++ (Make)----make testmake
Clojureclj-kondo--lein test / clj -M:testlein 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: workspaces field in package.json
  • Cargo: [workspace] members in Cargo.toml
  • Go: use directives in go.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.