Autonomous task orchestrator. Goal in, merged PRs out.
Give aitm a sentence, walk away, come back to a stack of merged pull requests. It runs a Planner β Worker β Reviewer loop against a real repo using the Vercel AI SDK and OpenRouter, and ships the work as PR-sized commits with CI gating and review-comment handling baked in.
π‘ Inspired by the (now deprecated)
developerz-ai/claude-task-master.aitmis the spiritual successor β same idea (a task-master that drives the work to merge), rebuilt on the Vercel AI SDK + OpenRouter, provider-agnostic, with concurrent PR groups, MCP client support, and a much smaller surface area.
Coding agents are great at single steps, terrible at staying on task across hours. aitm closes that gap:
- π§ Planner splits a goal into ordered, PR-sized task groups.
- π οΈ Worker branches, codes, and opens the PR.
- π Reviewer drives review-comment resolution and pushes fixes.
- π Auto-merge waits for CI green, then merges β by default.
- π§± Two commands to learn (
aitm start,aitm merge-pr). That's it.
No babysitting. No prompt-stuffing. No bespoke agent framework.
bun install -g @developerz.ai/aitm # recommended for local dev
npm install -g @developerz.ai/aitm # works the same
deno install -A npm:@developerz.ai/aitmThe package is scoped (@developerz.ai/aitm); the installed command is still aitm.
Plain ESM + a bun build --compile single-file binary. No runtime lock-in.
export OPENROUTER_API_KEY=sk-or-...
cd path/to/your/repo
aitm start "add JWT auth to /login" --max-prs 3aitm plans the goal into up to 3 PR-sized groups, opens a branch per group, works through them in parallel, opens each PR, watches CI, addresses review comments, and auto-merges. Need a human gate?
aitm start "migrate Mongo β Postgres" --no-automerge
# ... review the PR in your browser ...
aitm merge-pr| Scenario | What you type | What aitm does |
|---|---|---|
| π Add a feature end-to-end | aitm start "add password reset flow" |
Splits into schema + endpoint + email + tests, one PR per slice |
| π§Ή Refactor across many files | aitm start "rename Logger to Tracer everywhere" --max-prs 1 |
Single sweeping PR, full test pass before merge |
| π Bug ticket β fix | aitm start "$(gh issue view 412 --json title,body -q '.title + \"\\n\\n\" + .body')" |
Reads the issue, ships a PR, links it back |
| π§ͺ Raise coverage | aitm start "add tests for src/billing/* until 90% coverage" --max-sessions 20 |
Iterates until coverage target hits, or sessions cap is reached |
| π Docs sweep | aitm start "document every public export in src/api" |
One PR per package, opens drafts for review |
| β¬οΈ Dependency upgrade | aitm start "bump zod to v4 and fix all type errors" |
Bumps, fixes, runs tests, opens PR; conflicts surface as blocked |
βββββββββββββββββ
β CLAUDE.md / β (coding style for subagents)
β AGENTS.md β
ββββββββ¬βββββββββ
β
goal βββΆ Planner βββΆ task groups βββΆ Orchestrator βββΆ Worker βββΆ PR
β β β
β ββββΆ β
CI / π Reviewer
βΌ β
StateStore βββββ auto-merge βββ
- Provider: any OpenAI-compatible endpoint through one credential β OpenRouter by default, or point
baseURLat z.ai GLM, a self-hosted gateway, or another provider. No Anthropic SDK. See π Providers & profiles. - Coding style:
aitmreads your repo'sCLAUDE.mdorAGENTS.mdand feeds it to subagents as a style signal. - State: every run persists to
.ai-task-master/so resume-after-crash is one command. - Worktrees: concurrent groups run in isolated
git worktrees β no branch trampling.
| Requirement | Note |
|---|---|
| π’ JS runtime | Bun β₯ 1.1, Node β₯ 20, or Deno β₯ 1.40. Bun preferred locally. |
π£ gh CLI |
authenticated against the target repo's remote |
| π Agent config | CLAUDE.md or AGENTS.md at the target repo root |
| π Credentials | OPENROUTER_API_KEY env. That's it. |
π‘ Claude-conventioned projects:
aitmwill pick upCLAUDE.mdas its coding-style source automatically. The provider is still OpenRouter β the file is only a style signal.
start and merge-pr are the only user-facing commands.
- π’ With automerge on (default):
startruns the whole loop end-to-end. - π‘ With
--no-automerge:startstops after each PR opens; you callaitm merge-pronce you're happy.
Everything else β planning, task grouping, branch management, retries, review-comment handling β happens inside those two calls.
| Flag | Default | Effect |
|---|---|---|
--max-prs N |
5 | Hard cap on PR groups Planner may emit. |
--max-sessions N |
unlimited | Hard cap on subagent sessions per run. |
--concurrency N |
1 | How many groups to run in parallel (isolated worktrees). |
--no-automerge |
off | Stop after each PR opens; require manual aitm merge-pr. |
--style <path> |
CLAUDE.md / AGENTS.md |
Override the coding-style file fed to subagents. |
--model <id> |
provider default | Pin the model (e.g. anthropic/claude-opus-4.7). |
--criteria <text> |
β | Acceptance criteria appended to the goal. |
π‘ Both
--key valueand--key=valueforms are accepted:--max-prs=3works the same as--max-prs 3.
User config lives at ~/.aitm.json; per-project overrides at .ai-task-master/config.json:
aitm config set models.smart anthropic/claude-opus-4.7
aitm config set models.coding anthropic/claude-sonnet-4.6
aitm config set models.fast openai/gpt-5-mini
aitm config set autoMerge true --project
aitm config listSee docs/config.md for the full schema.
aitm talks to one OpenAI-compatible endpoint. The default is OpenRouter; override the base URL to run against any other OpenAI-compatible provider β z.ai's GLM coding plan, a self-hosted gateway, OpenAI, β¦ One credential, no Anthropic SDK. The only hard requirement is OpenAI-style function/tool calling (OpenRouter, z.ai GLM, and OpenAI all support it).
Profiles bundle the provider triple (key + base URL + per-tier models) under a name, so you switch the whole provider in one command β version-manager style (think nvm use):
# Create profiles from built-in presets (openrouter | zai), add your key:
aitm profile add openrouter --preset openrouter --api-key "sk-or-..."
aitm profile add z.ai --preset zai --api-key "<your z.ai key>"
aitm profile use z.ai # switch the active providerβ¦
aitm start "add a /healthz endpoint with a test" --max-prs 1 # β¦now running on z.ai GLM
aitm profile use openrouter # β¦and back
aitm profile list # '*' marks the active profile; keys shown maskedβ Verified end-to-end against z.ai GLM β the Planner/Worker/Reviewer loop runs on
glm-5.2/glm-5-turbothrough the GLM coding endpoint (https://api.z.ai/api/coding/paas/v4).
Prefer editing JSON? The same thing as plain config:
Full walkthrough in docs/providers.md; profile command reference in docs/commands/profile.md.
# 1. Clone a throwaway repo
git clone https://github.com/you/scratch && cd scratch
# 2. Drop a tiny CLAUDE.md so subagents know the style
echo "# CLAUDE.md\n- TypeScript strict.\n- No comments unless necessary." > CLAUDE.md
# 3. Set your key and go
export OPENROUTER_API_KEY=sk-or-...
aitm start "add a /healthz endpoint with a test" --max-prs 1A single PR opens, CI runs, it merges. Total wall-clock: a few minutes.
| Topic | Path |
|---|---|
| ποΈ Architecture | docs/architecture.md |
π’ aitm start |
docs/commands/start.md |
π‘ aitm merge-pr |
docs/commands/merge-pr.md |
π aitm profile |
docs/commands/profile.md |
| π Providers (OpenRouter / z.ai / generic) | docs/providers.md |
| βοΈ Config | docs/config.md |
| π Agent config detection | docs/agent-config-detection.md |
| π¨ Coding style | docs/coding-style.md |
| π§± Task groups (PRs) | docs/task-groups.md |
| π€ Subagents | docs/subagents.md |
| πΎ State | docs/state.md |
| π Auth | docs/auth.md |
| π GitHub integration | docs/github-integration.md |
| π Runtime | docs/runtime.md |
| π Vercel AI SDK reference (chunked) | docs/vendor/ai-sdk/index.md |
PRs welcome. House style is in CLAUDE.md: SOLID, one responsibility per module, every module ships with a paired *.test.ts, no any, no default exports, conventional commits, no emoji in source.
bun install
bun test # unit + integration
bun run typecheck
bun run lintMIT.