Native Shell
Native Shell: AI-generated UI, native in your app, on every platform. Apps on iOS, Android, macOS, Windows and Linux, GPUI apps and web pages load signed, sandboxed TSX modules at run time and draw th
Your agents need a director. troupe runs your development process with a team of agents, asking only when it needs you. Pre-alpha: you can install it with uv.
Developer toolsHTML · PythonGitHub @troupe-runOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Your agents need a director. troupe runs your development process with a team of agents, asking only when it needs you.
Taken from the repository README
Loading the full README.
Read the full README ↗Your agents need a director.
troupe runs your development process with a team of agents, asking only when it needs you. Work branches and loops, decisions go to whoever owns them, and every decision records who made it.
Pre-alpha: you can install it with uv and run an actor with it. See troupe.run for the principles, and the roadmap for the open decisions and what's next.
You need uv. troupe needs Python 3.12 to 3.15, on Linux, macOS or Windows, and uv downloads one for it if you don't have one. This installs the latest release:
uv tool install --no-sources "git+https://github.com/troupe-run/[email protected]#subdirectory=packages/troupe-run"
It installs troupe-run, which is troupe with the adapters and runners it bundles, and puts troupe on your path.
If your shell can't find troupe afterwards, run uv tool update-shell and open a new terminal. Each release is
tagged troupe-run-v<version>, on the releases page: to install
another, put its tag in the command. To install the latest main or a particular commit, put it in place of the tag
and leave out --no-sources.
uv tool upgrade troupe-run
only moves an install of main.uv tool uninstall troupe-run.Your first performance runs an actor with it.
You need uv. It installs the right Python for you. troupe is developed and tested on Linux, macOS and Windows.
uv sync
uv run scripts/check.py
troupe supports Python 3.12 to 3.15, exactly the versions CI tests. Every pyproject.toml says so
(requires-python = ">=3.12,<3.16"), and uv refuses any other version, naming the bound. Plain uv run uses
3.12, the lowest. To run on another supported version, name it:
uv run scripts/on.py 3.15 scripts/check.py
Each version gets its own environment in .venvs/, so switching back and forth rebuilds nothing. Delete
.venvs/ whenever you like. To support a new Python version, widen the bound and add the version to CI's matrix
in the same change. scripts/check.py fails if either moves without the other.
scripts/check.py runs every gate in order, and stops at the first failure: ruff (lint and format), mypy --strict, the import contracts, and the tests. CI runs the same script on all three platforms and every
supported Python version. Each push to a pull request runs what its changed paths need, as a commit does: nothing
for a change only to openspec/, the scoped check for scoped paths, and the full check otherwise. Its paths are
what it changed since the last push whose check passed, or the whole pull request's when no earlier push passed. main runs the full check
after every merge. The one required check, check, passes when every platform's run passed, or when none was
needed.
The check runs the tests in parallel with pytest-xdist, one worker for each CPU it may use. Set
PYTEST_XDIST_AUTO_NUM_WORKERS to change the count. Every run prints its 25 slowest tests, so a slowdown shows in
the log with its cause. Running pytest yourself (uv run pytest ...) stays in one
process, which is easier for narrowing to one test or stepping through it in a debugger.
Turn on the repository's git hooks once per clone (Claude Code sessions do this for you):
git config core.hooksPath .githooks
They refuse commits on main, commits on a branch with no matching OpenSpec change, messages that aren't
Conventional Commits, and commits whose checks fail.
A commit runs only what its staged paths need, as scripts/check-paths.toml declares. A commit that changes only
openspec/ skips the check. One that changes only docs/ (or the scripted runner's README) runs every gate, but
only the tests that check the docs against the code. One that changes only one package outside core, or only
scripts/, runs every gate, but only the test suites that reach what it changed. Anything else runs the full check,
including core, any package's pyproject.toml, and check.py and the guard files. To run a scope by hand:
uv run scripts/check.py --scope docs
uv run scripts/check.py --scope store_text
Every test run also checks the declaration. A test that reads a scope's path without that scope's tag, or that reads
anything under openspec/, fails and is named. A full run also fails when a scope's tests aren't exactly the suites
that reach its package; uv run scripts/check_paths_reach.py prints the lists to declare. The rules are maintained in troupe-run/infrastructure, and
development-workflow.md lists every rule and how an override works.
| Where | What |
|---|---|
packages/troupe/ | The troupe distribution: the core, the command line and the platform seam |
plugins/ | Out-of-process plugins (why they're separate) |
protocol/ | Language-neutral contracts, as JSON Schema (more) |
openspec/ | Specs and changes (OpenSpec) |
docs/ | The user docs, published at troupe.run/docs: reference for the command line |
contributing/ | For people working on troupe: config, runs, runners, the platform seam, the event store, releasing and hunting flaky tests |
How work flows, from issue to OpenSpec change to pull request, is in the
contributing guide. Contributions are signed
off under the Developer Certificate of Origin (git commit -s).
Apache-2.0. The troupe name, logo and characters are trademarks of HPS.GD PTY LTD, and aren't covered by the licence.