@scanton/phase2s
v1.24.0
Published
AI coding assistant with 29 built-in skills, ChatGPT subscription support, and autonomous spec execution
Maintainers
Readme
Phase2S
Three things Phase2S does that most AI coding tools don't:
Runs on your ChatGPT subscription — If you pay for ChatGPT Plus or Pro, you can use that same subscription to power a full coding assistant in your terminal. No API key, no per-token billing. The $20/month you're already paying starts pulling its weight.
Gives Claude Code a second opinion — If you use Claude Code as your daily driver, Phase2S plugs in as an MCP server and gives Claude a tool to call that runs your plan through GPT from a completely different model with completely different training. Before Claude executes anything big, it gets challenged by a second AI that has no stake in agreeing with it.
Executes specs autonomously — Write a spec describing what you want built and how you'll know it's done. Run
phase2s goal your-spec.md. Phase2S breaks it into sub-tasks, implements each one, runs your tests, checks whether the results match your criteria, and retries with failure analysis if anything falls short. You come back when it's done.
Quick install
Requires Node.js >= 20.
If you have ChatGPT Plus or Pro (recommended)
npm install -g @openai/codex @scanton/phase2s
codex auth
phase2scodex auth opens a browser window and logs into your ChatGPT account. You do it once. After that, phase2s uses your subscription automatically — no API keys, no credits to manage.
If you have an OpenAI API key
npm install -g @scanton/phase2s
export OPENAI_API_KEY=sk-your-key-here
export PHASE2S_PROVIDER=openai-api
phase2sIf you have an Anthropic API key
npm install -g @scanton/phase2s
export ANTHROPIC_API_KEY=sk-ant-your-key-here
export PHASE2S_PROVIDER=anthropic
phase2sIf you want to run everything locally (free, private, no internet)
npm install -g @scanton/phase2s
ollama pull llama3.1:8b
export PHASE2S_PROVIDER=ollama
phase2sShell integration (ZSH)
After installing, run phase2s setup once to enable the : <prompt> shorthand from any directory in your terminal — no REPL required.
phase2s setup
# Activate in the current shell (or open a new terminal tab):
source ~/.phase2s/phase2s.plugin.zsh
# Then from any directory:
: fix the null check in auth.ts
: what does this codebase do?
: explain the retry logic in agent.ts
p2 suggest "find large log files"phase2s setup copies the ZSH plugin to ~/.phase2s/ and adds a source line to your ~/.zshrc. It's idempotent — safe to re-run after npm upgrades. Use phase2s setup --dry-run to preview what it would do.
Feature 1: Your ChatGPT subscription, in your terminal
Most people who pay for ChatGPT Plus use it by opening a browser tab and typing. Phase2S turns it into a programmable coding tool you can use from the command line, from scripts, and from inside Claude Code.
you > /review src/core/auth.ts
CRIT: session.destroy() is called without await on line 83.
If it rejects (Redis timeout, etc.), the error is silently dropped
and the response goes out before the session is actually cleared.
WARN: The JWT expiry check on line 47 uses Date.now() directly.
Clock skew between your server and the token issuer can cause
valid tokens to fail. Use a small leeway (±30s) instead.
NIT: The error message on line 91 says "auth failed" but should say
"session_expired" to match the error codes in api-errors.ts.you > /satori add rate limiting to the API
-- Attempt 1 --
[creates src/utils/rate-limiter.ts]
[creates src/middleware/rate-limit.ts]
[registers middleware in app.ts]
[writes tests in test/middleware/rate-limit.test.ts]
npm test: FAIL — bucket not clearing on window expiry
-- Attempt 2 --
[fixes resetAt logic in RateLimiter.check()]
npm test: PASS (23 tests)
Done in 2 attempts.The 29 built-in skills cover the full development loop: specify, plan, implement, test, review, debug, ship, deploy. All of them run on your subscription.
Feature 2: Claude Code + Phase2S adversarial review
If you use Claude Code, here's the problem: one model reviewing its own work has blind spots. Claude agrees with Claude. The same training data, the same biases, the same failure modes.
Phase2S solves this by plugging into Claude Code as an MCP server. When Claude is about to execute a plan, it can call Phase2S — which runs the same plan through GPT using your ChatGPT subscription — and get back a structured challenge:
VERDICT: CHALLENGED
STRONGEST_CONCERN: The token bucket resets per-request rather than per-window.
OBJECTIONS:
1. RateLimiter.check() increments the counter and checks it in the same call.
When the window expires, the bucket resets on the next request — meaning
a client can always make exactly one request immediately after the window
closes, even if they were throttled. The reset should happen on a fixed
schedule, not lazily on first request.
2. The middleware is registered after the auth middleware in app.ts line 34.
Unauthenticated requests bypass rate limiting entirely.
APPROVE_IF: Fix the window reset logic and move middleware before auth.Claude gets specific, falsifiable objections from a model that wasn't involved in writing the plan. You see the verdict. You decide whether to proceed.
Setup takes about 2 minutes. Step-by-step guide →
Feature 3: The dark factory
Write a spec. Run one command. Come back when it's done.
phase2s goal reads your spec, breaks it into sub-tasks, implements each one through the /satori skill (which runs implement → test → retry until green), runs your eval command, checks whether your acceptance criteria actually passed, and if they didn't — analyzes what broke, figures out which sub-tasks need to be re-run, and tries again with that failure context.
It keeps going until all criteria pass or it runs out of attempts.
When your spec has 3 or more independent sub-tasks, Phase2S runs them in parallel inside git worktrees — each worker gets its own isolated branch, and Phase2S merges everything back at level boundaries. A 3-sub-task spec that used to take 30 minutes can finish in 12.
# Write the spec interactively
phase2s
you > /deep-specify add pagination to the search endpoint
# Execute it autonomously
phase2s goal .phase2s/specs/2026-04-04-11-00-pagination.mdGoal executor: Pagination for search endpoint
Sub-tasks: 3 | Eval: npm test | Max attempts: 3
=== Attempt 1/3 ===
Running sub-task: Cursor-based pagination logic
[satori: implement → test → retry until green]
Running sub-task: API response format update
[satori: implement → test → retry until green]
Running sub-task: Frontend page controls
[satori: implement → test → retry until green]
Running evaluation: npm test
Acceptance criteria:
✗ Returns correct next_cursor on paginated results
✓ Returns 20 items per page by default
✓ next_cursor is null on last page
Retrying 1 sub-task(s): Cursor-based pagination logic
=== Attempt 2/3 ===
Running sub-task: Cursor-based pagination logic
[satori: implement → test → retry until green]
Running evaluation: npm test
Acceptance criteria:
✓ Returns correct next_cursor on paginated results
✓ Returns 20 items per page by default
✓ next_cursor is null on last page
✓ All acceptance criteria met after 2 attempt(s).This uses your ChatGPT subscription for all the implementation work. No API key needed.
Meet the A-team: Apollo, Athena, Ares
Phase2S ships three named agent personas, each with a distinct job and a hard-wired tool set. Switch mid-session without losing your conversation history.
you > :ask (or: apollo) — Switch to Apollo: read-only Q&A, fast model
you > :plan (or: athena) — Switch to Athena: planning assistant, writes to plans/
you > :build (or: ares) — Switch to Ares: full access, default agent
you > :agents — List all available agents with aliases and tool counts| Agent | Alias | Model | Tools | Best for |
|-------|-------|-------|-------|----------|
| Apollo | :ask | fast | glob, grep, file_read, browser | Questions, code exploration, "how does X work?" |
| Athena | :plan | smart | read tools + plans_write | Design docs, implementation plans, architecture notes |
| Ares | :build | smart | all tools | Writing code, running tests, shipping features |
Tool enforcement is hard. Apollo cannot write files — not because the system prompt says so, but because file_write is literally not in its registry. Athena can only write inside plans/. Project overrides in .phase2s/agents/ can narrow a built-in's tool list but never expand it.
# Apollo answers a question about your codebase
you > :ask
you > how does the session locking work?
# Athena writes a plan (saved to plans/ automatically)
you > :plan
you > design the rate limiting system before we build it
# Ares ships it
you > :build
you > implement the plan in plans/rate-limiting.md
# Custom agents: add .phase2s/agents/scout.md to your project
you > :agent scoutActive agent is saved on --resume — pick up where you left off with the same persona active.
All 29 skills
you > /review src/auth.ts — code review: CRIT / WARN / NIT
you > /diff — review all uncommitted changes
you > /satori add pagination — implement + test + retry until green
you > /deep-specify add OAuth — spec interview → 5-pillar spec file
you > /consensus-plan add OAuth — planner + architect + critic passes
you > /debug logout fails — reproduce, isolate, fix, verify
you > /investigate why 500s — evidence trail to root cause
you > /health — code quality score (tests, types, lint)
you > /audit — secrets scan, dependency CVEs, injection
you > /ship — diff review + commit message
you > /land-and-deploy — push, PR, CI wait, merge
you > /remember — save a project convention to memory
you > /retro — weekly velocity and pattern analysisphase2s skills # full list with model tier badges
phase2s skills --json # machine-readable for scriptsDocs
- Getting started — first install, first session, all four provider options
- Named agents — Apollo, Athena, Ares, custom agents, override-restrict policy
- Dark factory — write a spec, run
phase2s goal, get a feature - Claude Code integration — MCP setup, adversarial review, CLAUDE.md routing rules
- Skills reference — all 29 skills with examples
- Workflows — real development sessions end to end
- Memory and persistence — session resume, session branching and forking,
/remember, what gets saved - Writing custom skills — create your own
/commands - GitHub Action —
uses: scanton/phase2s@v1for CI (requires API key) - Advanced — streaming, model routing, tool allow/deny
- Configuration —
.phase2s.yamland environment variables - Contributing — session storage internals, lock correctness, NFS caveats
Providers
| Provider | Auth | Default Model | Setup |
|----------|------|---------------|-------|
| ChatGPT subscription | Browser login | gpt-4o | codex auth (one time) |
| OpenAI API | OPENAI_API_KEY | gpt-4o | phase2s init |
| Anthropic | ANTHROPIC_API_KEY | claude-3-5-sonnet | phase2s init |
| Ollama | Local (no auth) | llama3.1:8b | ollama pull llama3.1:8b |
| OpenRouter | OPENROUTER_API_KEY | openai/gpt-4o | phase2s init |
| Google Gemini | GEMINI_API_KEY | gemini-2.0-flash | Free tier at aistudio.google.com |
| MiniMax | MINIMAX_API_KEY | MiniMax-M2.5 | phase2s init |
Features in Depth
Dark Factory Tools
Start from a template:
# See the 6 bundled spec templates
phase2s template list
# Fill in placeholders and write a spec in one step
phase2s template use auth
phase2s template use api
phase2s template use bugphase2s template list shows all bundled templates with their descriptions. phase2s template use <name> runs a short wizard (3-4 questions), fills in placeholders like {{resource_name}} and {{test_command}}, and writes the spec to .phase2s/specs/ — ready to lint and run. Templates: auth, api, refactor, test, cli, bug.
Validate before you run:
# Check your spec for structural issues before a 20-minute agent run
phase2s lint specs/add-rate-limiting.md
# Only run if lint passes
phase2s lint specs/add-rate-limiting.md && phase2s goal specs/add-rate-limiting.mdphase2s lint catches missing titles, empty problem statements, specs with no sub-tasks, missing acceptance criteria, and warns about specs with 8+ sub-tasks or default eval commands.
Preview the plan without running it:
# See the decomposition tree without making any LLM calls
phase2s goal specs/add-rate-limiting.md --dry-runShows the parsed spec title, sub-task list, acceptance criteria, and eval command. No tokens spent.
Live progress during execution:
[1/3] Running: Cursor-based pagination logic (42s)
[2/3] Running: API response format update (18s)
[3/3] Running: Frontend page controls (31s)Real-time subtask progress with elapsed time per sub-task, so you know where the agent is.
Review completed runs:
# Chalk-colored timeline of a dark factory run
phase2s report .phase2s/runs/2026-04-05-goal-abc123.jsonlShows sub-task timeline, attempt counts, criteria verdicts, and total duration.
MCP Integration
Phase2S runs as an MCP server, exposing all skills as Claude Code tools. Setup guide →
Beyond skills, the MCP server provides:
State server — durable key-value store for Claude Code workflows:
# Claude Code can persist state across tool calls
phase2s__state_write({ key: "deploy_status", value: "in_progress" })
phase2s__state_read({ key: "deploy_status" }) # → "in_progress"
phase2s__state_clear({ key: "deploy_status" })Run report via MCP — Claude Code can summarize dark factory results:
phase2s__report({ runLogPath: ".phase2s/runs/2026-04-05-goal-abc123.jsonl" })AI Commit Messages
# Generate a commit message from staged changes
git add src/auth.ts
phase2s commit
# Preview the proposed message without committing
phase2s commit --preview
# Non-interactive for CI — commits immediately, fails fast on detected secrets
phase2s commit --autophase2s commit reads the staged diff, asks the fast model to write a Conventional Commits message (<type>(<scope>): <subject>), and walks you through accept / edit / cancel. The edit path opens $EDITOR if configured, or falls back to a readline prompt.
The secrets scanner runs before the diff leaves your machine. If it finds AWS keys, OpenAI or Anthropic keys, GitHub tokens, or Slack tokens in the staged changes, it warns and asks whether to continue. In --auto mode it fails hard instead of prompting.
From inside the REPL, :commit does the same thing without breaking your session.
For teams
Check a .phase2s.yaml into your repo. Everyone gets consistent Conventional Commits format without a style guide argument:
# .phase2s.yaml
commit:
format: conventional # <type>(<scope>): <subject>For CI, use --auto with a direct API provider (ChatGPT subscription requires browser auth, which doesn't work in CI). Set PHASE2S_PROVIDER=openai-api and OPENAI_API_KEY, then:
# .github/workflows/ci.yml
- name: Commit generated files
run: |
git add generated/
phase2s commit --auto
env:
PHASE2S_PROVIDER: openai-api
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}Use --preview in PR workflows to inspect proposed messages without committing — useful for audit logs or comment bots.
Tools and Configuration
Custom system prompt:
# Append a custom instruction to every agent session
phase2s --system "Always prefer Python for scripting tasks"Custom verification command — configure what /satori runs to check your work:
# .phase2s.yaml
verifyCommand: pytest tests/ -x # or: go test ./... or: npm testHeadless browser — enable for the /qa skill to test web apps:
# .phase2s.yaml
browser: true # requires playwright installedRoadmap
- [x] Codex CLI provider (ChatGPT subscription, no API key required)
- [x] 29 built-in skills across 6 categories
- [x] File sandbox: tools reject paths outside project directory, including symlink escapes
- [x] 1099 tests covering all tools, core modules, agent integration, goal executor, state server, run logs, MCP goal tool, notification gateway, run report viewer, onboarding wizard, glob tool filtering, OpenRouter provider, Gemini provider, MiniMax provider, installation health checks, self-update, skills search, spec linting, dark factory dry-run, lint PATH checks, parallel execution, dependency graph, worktree lifecycle, tmux dashboard, level context injection, parallel executor behavior, merge conflict detection, stash/unstash lifecycle, shared integration test harness, spec eval judge, multi-agent orchestrator, live re-planning, Telegram notification channel, spec template library, session branching DAG, bash shell integration, secrets scanning, AI-generated commit messages, session index/locking/DAG integrity, and session lock hardening (PID-suffixed tmp files, SIGKILL recovery, symlink escape guard)
- [x] CI: runs
npm teston every push and PR - [x] OpenAI API provider with live tool calling
- [x] Anthropic API provider — Claude 3.5 Sonnet and family
- [x] Ollama provider — local models, offline, no API keys
- [x] Streaming output
- [x] Session persistence — auto-save +
--resume - [x] Model-per-skill routing —
fast_model/smart_modeltiers - [x] Satori persistent execution — retry loop with shell verification
- [x] Consensus planning — planner + architect + critic
- [x] Claude Code MCP integration — all skills as Claude Code tools
- [x]
/adversarial— cross-model adversarial review - [x] Persistent memory —
/remember+ auto-inject into sessions - [x]
/skill— create new skills from inside Phase2S - [x]
/land-and-deploy— push, PR, CI wait, merge - [x] Model tier badges in
phase2s skillsoutput - [x]
--dry-runfor skill routing preview - [x] Typed input hints in REPL
- [x]
phase2s skills --json - [x] Shell completion —
eval "$(phase2s completion bash)" - [x] Tool allow/deny in
.phase2s.yaml - [x] Headless browser tool via Playwright
- [x] GitHub Action —
uses: scanton/phase2s@v1 - [x]
phase2s goal <spec.md>— dark factory: spec in, feature out - [x] 5-pillar spec format —
/deep-specifyoutput feeds directly intophase2s goal - [x] Real Codex streaming (JSONL stdout parsing) — step-by-step feedback for multi-step tasks
- [x] MCP state server —
state_read/state_write/state_clearas Claude Code tools - [x]
phase2s goal --resume— dark factory continuity: resumes from last completed sub-task after interruption - [x]
phase2s__goalMCP tool — Claude Code can trigger the dark factory directly, no terminal needed - [x] Structured JSONL run logs — per-sub-task observability at
.phase2s/runs/<timestamp>.jsonl - [x]
--review-before-run— adversarial pre-execution review before the dark factory starts - [x] Notification gateway —
phase2s goal --notifysends macOS system notification + optional Slack webhook on completion - [x]
phase2s report <log.jsonl>— chalk-colored run summary: sub-task timeline, durations, criteria verdicts, total time - [x]
phase2s__reportMCP tool — Claude Code can summarize a run log after triggering the dark factory - [x]
phase2s init— interactive onboarding wizard: provider choice, API key, model tiers, Slack/Discord/Teams webhooks, pre-fills from existing config - [x] Discord + Microsoft Teams notification channels for dark factory runs (
--notify) - [x] Glob/wildcard patterns in
toolsanddenyconfig (file_*matchesfile_readandfile_write) - [x] OpenRouter provider — 50+ models (GPT-4o, Claude, Gemini, Llama) under a single
OPENROUTER_API_KEY - [x]
phase2s doctor— installation health check: Node version, provider binary, auth, config, working dir - [x]
phase2s upgrade— self-update: checks npm registry, prompts to install,--checkfor CI - [x]
phase2s skills [query]— filter the skill list by name or description (phase2s skills security) - [x] Google Gemini provider — free tier,
gemini-2.0-flashdefault, OpenAI-compatible endpoint, no new SDK dependency - [x]
phase2s lint <spec.md>— validate a spec before a dark factory run: catches structural errors before the 20-minute agent loop begins - [x]
phase2s goal --dry-run— parse and display the spec decomposition tree without making a single LLM call - [x] Live dark factory progress:
[1/3] Running: Sub-task namewith elapsed time per sub-task - [x]
phase2s lint: >8 sub-task warning and evalCommand PATH check - [x] MiniMax provider — MiniMax-M2.5 default, OpenAI-compatible endpoint, no new SDK dependency
- [x] Parallel dark factory execution — leveled parallelism via git worktrees, auto-detected on 3+ independent subtasks,
--parallel/--sequential/--workers N/--dashboardflags, hybrid file-based dependency analysis, sequential merge with conflict halt, level context injection, parallel run reports - [x]
--resume --parallelhardened — deterministic worktree slugs (specHash + index), persisted worktree paths in state, resume correctly locates existing worktrees instead of recreating them - [x]
phase2s judge <spec.md> --diff <file>— spec eval judge: compares acceptance criteria against a git diff, produces a per-criterion coverage map and a 0-10 score. Exits 1 if score < 7 (CI integration). Also accepts diff via stdin:git diff HEAD~1 | phase2s judge spec.md - [x]
phase2s goal --judge— runs the spec eval judge automatically after each attempt, emitseval_judgedevent to the run log, and renders a JUDGE REPORT block inphase2s reportoutput - [x] P1 parallel executor fixes — timer leak in
executeWorker()(clearTimeout in finally), stash pop correctness (named stash + pop by ref instead of alwaysstash@{0}), concurrent worktree prune race (promise-chain mutex per repo) - [x] Multi-agent orchestrator —
**Role:** architect|implementer|tester|reviewerannotations in specs route subtasks to role-appropriate workers, each with a tailored system prompt. Architect workers emit a structured ````context-jsonblock that downstream workers receive in their system prompts.--orchestrator` flag forces orchestrator mode on any spec. Auto-detected when role annotations are present. - [x] Live re-planning — when a subtask fails, the orchestrator calls the LLM with a structured prompt describing the failure, remaining jobs, and architect context. The response (
DeltaResponse) is validated and merged back;buildLevels()re-levels the revised plan. Backward contamination DFS flags completed ancestors whose outputs the failed job consumed (suspectCountin the run log). Path traversal protection on all LLM-generated job IDs. - [x] Telegram notification channel —
sendTelegramNotification()innotify.ts, configurable viaPHASE2S_TELEGRAM_BOT_TOKEN+PHASE2S_TELEGRAM_CHAT_IDenv vars ornotify.telegramin.phase2s.yaml.phase2s init --telegram-setupwizard callsgetUpdates, picks the most recent chat, and prints the ready-to-paste YAML snippet. - [x]
model:spec annotation for parallel workers — subtasks declaremodel: fast,model: smart, or a literal model name.resolveSubtaskModel()maps aliases to configured tiers and falls back to the outer--modelflag. - [x]
phase2s template list/phase2s template use <name>— 6 bundled spec templates (auth,api,bug,refactor,test,cli). Short wizard fills in 3-4 placeholders, substitutes tokens in a single pass (no cascade injection), writes spec to.phase2s/specs/, and runs lint automatically. - [x]
phase2s doctortemplates check — verifies bundled templates directory is present and non-empty - [x]
phase2s conversations/:clone <uuid>— DAG-shaped session storage. Browse all sessions with fzf (or plain table), fork any session into a new branch. Sessions stored as{schemaVersion:2, meta:{id,parentId,branchName}, messages:[]}. Migration from YYYY-MM-DD.json is automatic, resumable, and non-destructive (backup created before any rename). - [x] Bash shell integration —
phase2s setup --bashinstalls~/.phase2s/phase2s-bash.shand sources it from~/.bash_profile. Provides the same: <prompt>shorthand andp2alias as the ZSH integration, plus bash tab completion. Fixes for:clonecorruption and atomic SIGINT save. - [x] Byte-aware context truncation —
level-context.tsusesBuffer.from(context,'utf8').subarray(0,limit).toString('utf8')instead ofString.slice(). Fixes silent byte overrun with emoji or CJK filenames. - [x]
phase2s commit— AI-generated commit messages from staged diffs. Interactive accept / edit / cancel flow.--autofor CI (non-interactive, fails fast on detected secrets).--previewfor dry-run inspection. Secrets scanner warns before sending the diff to your LLM provider.:commitREPL shorthand for in-session use. Conventional Commits format configurable via.phase2s.yaml. - [x] POSIX exclusive-create lock on
state.json—writeReplStateis now async and uses{ flag: "wx" }to prevent last-writer-wins races when multiple REPL instances run in parallel. Stale locks (>30 s) are removed automatically. - [x] O(1)
conversationslisting via session index —.phase2s/sessions/index.jsonis maintained on everysaveSession/cloneSessioncall.phase2s conversationsreads a single file instead of scanning every session on disk. Falls back to a full rebuild if the index is missing or corrupt. - [x]
phase2s doctorDAG integrity check — scans all session files and reports anyparentIdreferences that point to a non-existent session (dangling branches after manual deletion). - [x] Session lock hardening (v1.22.2) —
releasePosixLockreads the PID before unlinking to close an ABA race (also guards against decimal/corrupt PID viaNumber.isInteger);rebuildSessionIndexholds.index.lockonly for the O(1)renameSync(scan happens before lock acquisition to prevent lock starvation);migrateAllwritesprocess.pidto its lock file and callsreleasePosixLockinfinallyinstead of bareunlinkSync;listSessionsfast path and slow path both filter stale paths withexistsSyncbefore emitting results. - [x] Lock correctness closure + doom-loop prevention (v1.22.3) — PID-suffixed tmp files in
writeReplStateandcloneSessionprevent concurrent-write races on the same.tmppath; SIGKILL stale migration lock recovery viaprocess.kill(pid, 0)liveness check (dead process → steal lock, no more manualrm *.lock); two-phase symlink escape guard inmigrateAllLocked(lexical +realpathSync);phase2s doctornow checks Bash shell integration parity with ZSH; doom-loop reflection protocol replaces the one-liner retry prompt inbuildSatoriContext(setPHASE2S_DOOM_LOOP_REFLECTION=offto revert). - [x]
phase2s doctor --fix— rebuild session index and run DAG integrity check with a single flag; exits 1 on failure so it can be used in scripts and setup automation. - [x]
-C <path>global flag — runs any Phase2S subcommand as if started in<path>viaprocess.chdir()in apreActionhook. Useful for scripts and aliases that need to target a specific project directory without acd. - [x]
:re [high|low|default]— REPL reasoning-effort switcher. Changes the active reasoning level mid-session without leaving the REPL. Applies to normal turns only; skills keep their declared model tier. - [x] Tool error reflection — when a tool call fails on attempt 1 of a satori run, a structured 3-question reflection prompt is injected before the retry to help the model self-correct. Set
PHASE2S_TOOL_ERROR_REFLECTION=offto disable. - [x] Bash
:()limitation docs —phase2s setup --bashnow prints a warning about${VAR:=default}expansion conflicts; the same explanation is documented indocs/getting-started.md. - [x] Named agents (Apollo / Athena / Ares) — three built-in personas with hard-wired tool registries. Apollo (
:ask, fast, read-only), Athena (:plan, smart, writes only toplans/), Ares (:build, smart, full access). Switch mid-session with:ask,:plan,:build, or:agent <id>. Override-restrict policy prevents project configs from expanding a built-in's tool list. Resume persistence saves the active agent across sessions. 1191 tests.
License
MIT
