Sno Station
Sno Station is your agents' workstation: open-source software that turns the AI agents you already run into one squad on your own machine. Two heads are better than one, and they get better with every
A Claude Code plugin for a structured dev workflow — 14 expert agents, code review, planning, and task tracking, all from the terminal.
PluginsGo · ShellGitHub @restarterSelf-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
Loading the full README. The saved excerpt is shown below.
A development workflow plugin for Claude Code
Stop babysitting your AI. Start shipping with it.
Claude Code is powerful, but without structure it drifts - forgets context between sessions, silently changes approach when something fails, reviews its own code with no outside perspective, and loses track of what was decided and why.Read the full README ↗A development workflow plugin for Claude Code
Stop babysitting your AI. Start shipping with it.
Claude Code is powerful, but without structure it drifts - forgets context between sessions, silently changes approach when something fails, reviews its own code with no outside perspective, and loses track of what was decided and why.
LETS fix this. You get a team of 15 specialized AI agents, a structured development workflow, and a PR review system that posts inline comments directly to GitHub - all from the terminal. Every session has a task. Every commit links to it. Context survives across sessions and conversation compaction.
You don't just chat with AI. You run a process — /lets:* commands and 15 expert agents cover the whole development cycle, every change is reviewed by the right specialists, and every decision is made deliberately, with you in the loop.
/lets:execute. Choices are made on purpose, not improvised..lets/.env: strict (every step asks, as before), standard (the default) or minimal. The AI never silently switches approach and never writes code without an approved plan.LETS statusline and /lets:review command in action
LETS is two pieces: a small lets CLI on your $PATH, and the plugin inside Claude Code. Install both, then initialize your project.
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/restarter/lets-workflow/main/scripts/install.sh | bash
You also need beads (bd) on $PATH — LETS uses it for task tracking. You don't have to learn beads: the plugin drives bd entirely for you, so just get it installed. Its install guide has all the options; the quick one-liner:
curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
Manual download, Windows, source builds, troubleshooting → docs/installation.md.
In Claude Code:
/plugin marketplace add restarter/lets-workflow
/plugin install lets
Install scope: Claude Code will ask where to install — all three options work:
- "Install for all collaborators on this repository" (project scope) — recommended for shared repos; the choice lands in
.claude/settings.json, so teammates inheritletswithout re-installing.- "Install for you, in this repo only" (local scope) — fine for a solo or throwaway project; not committed.
- "Install for yourself everywhere" (user scope) — one install for all your projects. After installing,
/lets:initin any project offerslets init --user: global workflow rules land in~/.claude/rules/lets-rules.mdand your personal defaults (language, launcher) in~/.lets/.env— every project gets LETS without per-project setup. Project rules override global on conflict. Details, precedence, and the opt-out limitation: docs/installation.md.
Stay current (do this once): in /plugin → Marketplaces → lets-workflow, Enable auto-update — the plugin then tracks every release on its own. Staying current then collapses to a single self-driving loop: run /lets:update, do the one thing it says, re-run until it prints ✓ Everything on vX.Y.Z — each run advances one step (binary → plugin → reload → done), the binary step offers to run the installer in-session, and rules never sync to a plugin that's still behind.
(Or install from a local clone — git clone https://github.com/restarter/lets-workflow, then /plugin marketplace add ./lets-workflow and /plugin install lets — handy for hacking on the plugin: edit the clone, then /reload-plugins to pick up your changes.)
cd your-project
claude
Then, inside the Claude Code session:
/lets:init
/lets:init creates .lets/ (config + statusline) and runs bd init if beads is installed. From there, start each work session with /lets:start — the full loop is in Using LETS below.
→ Full docs: docs/commands.md
| Command | Description |
|---|---|
/lets:start | Start session - restore context, show tasks, create feature branch (--main = no-task project-assistant mode) |
/lets:end | End session - save progress, sync tasks, write snapshot (--session, aliases --snapshot / --pre-compact / --compact, banks a snapshot without ending) |
/lets:commit | Commit with review and conventional commit format |
/lets:done | Finish task - create PR (GitHub or Bitbucket) or merge locally |
/lets:status | Read-only orient snapshot — where you are, what's in flight, what's next (tracker-universal) |
/lets:note | Add note to active task (--session, aliases --snapshot / --pre-compact / --compact, snapshots the session; --team writes a fact or a decision into the standing team's file) |
| Command | Description |
|---|---|
/lets:backlog | Backlog review (multi-agent, --workflow = off-context) + --fast quick no-agent pulse + interactive cleanup triage |
/lets:plan | Structured planning - explore codebase, design architecture, write plan (--fast = orchestrator-only, no subagents; --idea = concept document, no code) |
/lets:plan-workflow | PREVIEW - autonomous planning via a Dynamic Workflow: goal + rubric up front, off-context, you approve at the end (--fast = lean budget) |
/lets:execute | Execute plan from /lets:plan - inline in native plan mode (straight-through by default, or --step / --auto), or --implementers: one persistent implementer (or --parallel isolated groups) you review and correct chunk by chunk, under the gate policy you pick at Start |
/lets:team | Team management - run several tasks at once (one visible session per task, any launcher), create / disband a standing team, spawn / dismiss / roster its members, status, stop |
/lets:worktree | Create/manage worktrees for parallel sessions |
/lets:statusline | Manage & persist statusline appearance - light/dark, compact, hidden rows |
→ Full docs: docs/messaging.md
| Command | Description |
|---|---|
/lets:orc | Talk to the repo's orchestrator or a named peer session |
/lets:peer | Alias: /lets:peer <name> <verb> [text] = /lets:orc with a target |
/lets:hub | Orca addon: orchestrators across projects - read-only ask to a stopped one, wake one for gated work |
/lets:handoff | Hand-off brief so another agent (fresh session, Codex, Antigravity, external reviewer) can pick up the exact state and review it - same target selectors as /lets:review, plus --commits / --range. --codex runs it through Codex headless, --send types it into an agent's Orca tab, and the report comes back verified against the code; --execute --send hands an approved plan to that tab to implement instead; --fix applies the verified fixes here when nothing needs deciding (also on /lets:check and /lets:review) (old name /lets:review-handoff is a deprecated alias) |
| Command | Description |
|---|---|
/lets:check | Inline 6-perspective sanity check, no subagents |
/lets:review | Full code review with dynamic agent selection + verify pass |
/lets:github-pr | GitHub PR review lifecycle - analyze, discuss, post inline, follow-up, approve |
/lets:review-round | Work through a received review round - triage comments, record decisions, one final edit-pass |
/lets:opinion | Technical decision analysis (dynamic expert agents in parallel) |
/lets:ask | Quick expert consultation (single agent) - /lets:ask <expert> <question> |
/lets:research | Web-sourced cited answer to an external/technical question - cross-check flags weak/contradicted claims (--workflow off-context, --project repo-grounded) |
| Command | Description |
|---|---|
/lets:init | Initialize LETS in current project |
/lets:update | Sync project with the current release - .lets/.env + rules self-heal, plus version status for the lets binary and the plugin |
→ Full docs: docs/agents.md
LETS ships 15 specialized agents. You don't have to pick them by hand — the commands that use agents (/lets:review, /lets:opinion, /lets:ask, /lets:plan, /lets:backlog, /lets:research, /lets:team) look at what you're doing and bring in only the ones that fit. When you want one specific colleague, /lets:ask <expert> <question> goes straight to them.
| Agent | Expertise |
|---|---|
| architect | System design, patterns, SOLID, coupling |
| backend | APIs, business logic, error handling, performance |
| frontend | UI components, state management, accessibility |
| security | Vulnerabilities, auth, crypto, secrets, input validation |
| database | Schema design, migrations, query optimization, transactions |
| devops | Docker, CI/CD, deployment config, shell scripts |
| qa | Test strategy, coverage, assertion quality, mocking |
| compliance | Project standards and conventions (CLAUDE.md, style) |
| docs | Documentation sync, README accuracy, changelog |
| pragmatist | ROI analysis, overengineering detection, scope creep |
| git-historian | Blame analysis, past-decision context, change patterns |
| explorer | Codebase mapping, pattern discovery (used in /lets:plan) |
| implementer | Full-stack implementation (used by /lets:execute delegated runs and a standing team's /lets:team spawn implementer) |
| skeptic | Verifier, never a reviewer: tries to refute each /lets:review finding and cross-checks each /lets:research claim |
| actor | Any expert personality loaded from a URL or local file |
Dynamic selection. Each command analyzes the change (or the plan, or the question) and selects only the experts that matter — touch auth code and security, backend, and architect join; a pure docs update gets docs + compliance and nothing else; a full-stack feature can pull in up to 12, each focused on its domain. (compliance and docs always join a review. For plan reviews, the picks come from signals in the plan text — migrations, API endpoints, Docker configs, ….)
Tiered findings. Every finding is [BLOCKER] (must fix), [SUGGESTION] (should fix), or [NIT] (nice to have). Agents are tuned to skip the obvious and surface what actually matters — signal, not a wall of nitpicks.
Modes. The same agent behaves differently depending on context — review for code review, opinion for a technical decision, plan for evaluating an architecture, brainstorm for ideation, ask for a direct question. Same expertise, different lens.
Read-only by default. Agents analyze; they never touch your code. The one exception is implementer, which gets write access behind your approval, with every diff reviewed: /lets:execute hands it plan chunks you accept or correct - one persistent implementer, or parallel groups in isolated worktrees whose commits lets integrate lands as one verified patch each.
The actor agent. Give actor a personality — a URL or a local file — and it adopts that persona, then works with LETS's structured output. A senior iOS dev on your Swift code, a UX designer on your components, anyone — point it at their writeup and get their take. It's never auto-selected; you confirm each personality before it's loaded.
→ Full docs: docs/workflow.md
A LETS session runs a loop: start, work, commit, finish.
/lets:start ─── choose how to work ─── /lets:commit ─── /lets:done ─── /lets:end
Start - /lets:start restores context from the previous session, shows available tasks, and creates a feature branch. Context survives conversation compaction: /lets:start reads the latest session snapshot first, then the task's comments.
Choose how to work - depending on the task, you pick the approach:
┌─ You write code yourself ─────────────────────────────────────────────────┐
│ Write code with Claude. Use helpers along the way: │
│ /lets:opinion Technical decision with expert agents │
│ /lets:ask Quick question to a single expert │
│ /lets:check Inline sanity check (6 perspectives, no agents) │
│ /lets:review Multi-agent review + adversarial verify pass │
│ /lets:research Web-sourced cited answer to a question │
│ │
├─ You plan, Claude builds ─────────────────────────────────────────────────┤
│ /lets:backlog Backlog review (multi-agent) + cleanup triage │
│ /lets:plan Design how to build it - codebase exploration, arch │
│ /lets:execute Claude implements the plan you approved │
│ │
├─ Agents work in parallel ─────────────────────────────────────────────────┤
│ /lets:team Run several tasks at once, one visible session each │
│ /lets:worktree Open parallel sessions in separate terminals │
└───────────────────────────────────────────────────────────────────────────┘
Commit - /lets:commit reviews changes and creates a conventional commit (feat:, fix:, docs:, …) linked to the active task.
Finish - /lets:done creates a PR on GitHub or Bitbucket (or merges locally). /lets:end saves a session snapshot so the next conversation picks up where you left off.
→ Full docs: docs/plan-execute.md
Think → Design → Build
Backlog (/lets:backlog) - manage the task backlog in three modes: Review backlog (agents analyze your task list, find patterns, suggest priorities), --fast (a quick no-agent pulse - fast context scan, then a direct conversation), and Cleanup (find stale tasks, broken dependencies, forgotten work). /lets:backlog review, /lets:backlog --fast, and /lets:backlog cleanup skip the menu. /lets:backlog review --workflow runs the Review fan-out off-context.
Plan (/lets:plan) - codebase exploration with dynamically-scaled explorer agents, then architecture design with expert evaluation. Small project? One explorer. Large monorepo? Usually up to 10, each mapping a different area (more asks you to confirm). Want a quick talk-through instead? /lets:plan --fast skips the subagent phases and plans collaboratively in-session.
Execute (/lets:execute) - implements the plan in native plan mode. You approve the execution once, then pick how it runs: straight-through (the default - all tasks, commits at the plan's commit points), step-by-step (a pause after each task), auto (unattended), or implementers - one persistent agent writes chunk after chunk (or --parallel groups work side by side in isolated worktrees) while you review every diff, or let the team check accept low-risk chunks under the gate policy you approve at Start (its default follows LETS_GATES), and send corrections back to the same agent. No surprises.
Research (/lets:research) - unlike /lets:opinion (project-grounded judgment, no web) or /lets:ask (a quick model-knowledge consult), this answers an external or technical question with a CITED synthesis: it searches the web, fetches the best sources, and a cross-check pass flags single-source, contradicted, or stale claims before presenting. The deliverable is a sourced answer with a Sources list and an as-of date. --workflow runs it off-context; --project grounds findings against this repo.
→ Full docs: docs/code-review.md
Three levels of review, separated by who does the looking:
| Need | Command | Who reviews | What happens |
|---|---|---|---|
| Quick pre-commit check | /lets:check | The orchestrator, inline | 6-lens review: bugs, security, performance, quality, compliance, docs |
| Full code review | /lets:review | Expert subagents, then a verify pass | Dynamic agent selection - only relevant experts for your changes |
| Full PR lifecycle (GitHub) | /lets:github-pr <PR> | Review's agents, then you | Analyze, discuss, post inline comments, follow up on fixes, approve |
/lets:github-pr)This is where LETS shines. Instead of reviewing PRs in a browser, you do it from the terminal with expert agents. /lets:github-pr is GitHub-only. Bitbucket PRs review with /lets:review (fetch, diff, discussion, summary comment) and finish with /lets:done:
/lets:github-pr https://github.com/owner/repo/pull/42
/lets:github-pr --follow-up checks each finding: fixed, not fixed, or needs discussion/lets:github-pr --approve when ready, or request changesAuthors can respond with /lets:github-pr --respond - triage comments, auto-fix mechanical issues, post replies.
→ Full docs: docs/parallel-work.md
Two ways to work on multiple tasks at once:
Team runs — run several tasks at once, each in its own worktree and its own visible LETS session:
/lets:team run # select tasks, one worker session opens per task
Each worker runs its own /lets:start ... /lets:done, and you press its gates in its own terminal; this session is the orchestrator and talks to the workers through /lets:orc. It works on every launcher (terminal, cmux, tmux, Orca). A standing team goes further: /lets:team create gives an area its own worktree (team_<callsign>, named by a callsign like snake or frog), a lead session and a team file that remembers what it learned; the lead moves the worktree from task to task with /lets:start <id> (unfinished work is committed or parked, never stashed), /lets:team spawn brings in expert members (architect, skeptic, explorer, implementer) that keep working with it across tasks, and /lets:team disband retires it. Inside ONE task, /lets:execute --implementers --parallel splits the plan into file-disjoint groups for parallel implementers instead.
Worktrees (interactive) — work on multiple tasks yourself in separate terminals:
/lets:worktree create auth-feature # Terminal 1 (main repo)
cd .worktrees/auth-feature && claude # Terminal 2 - start new session
Each worktree gets its own branch, shares the task database and config via symlinks. Full LETS workflow in each terminal.
On Linux or macOS with tmux installed, set LETS_LAUNCHER=tmux (or run /lets:init and pick tmux) and /lets:worktree create opens the session in a tmux window/session automatically — no second terminal. On macOS, cmux is a GUI alternative (LETS_LAUNCHER=cmux). Both stay optional: without the launcher's binary (or on Windows) it falls back to the cd … && claude command above. If you run parallel agents in the Orca desktop app, LETS_LAUNCHER=orca opens each task worktree as an Orca workspace and links it back to LETS automatically. Orca is an opt-in addon: nothing Orca-related runs unless you pick it, and without the app it falls back to cmux, then the terminal command.
→ Full docs: docs/messaging.md
Sessions that talk to each other. Run a /lets:start --main orchestrator next to your worktree sessions and stop copying decisions between chats: a worker asks its orchestrator with /lets:orc ask, pings it about a PR, or reads what it said; /lets:peer <name> reaches any named session. Nothing is sent without your request in that chat, a peer's words arrive as data rather than instructions, and a message goes out through Claude's own session messaging, addressed by session name. At the default gate level your sessions talk without per-message confirmation once Go has verified who sent a message - a verified peer can get an unlisted action done inside the receiver's task, a listed one asks the receiver's owner once, and every hard gate still asks; at strict only a bound pair with a standing authorization talks that way. With Orca, /lets:hub looks across projects: it asks a stopped orchestrator a read-only question, or wakes it in a visible terminal when the work needs its gates.
Hand the work to another agent. When you want a second reader with no stake in this chat - Codex, Antigravity, a fresh Claude session - /lets:handoff --branch (or --last-commit, --plan, a PR, ...) builds one self-contained brief. On its own it prints the brief to paste anywhere; --codex runs it through Codex headless in a read-only sandbox, and with Orca --send types it into an agent's tab. Either way the report comes back UNVERIFIED, and every finding is checked against the code before it counts. The printed brief writes nothing; with --codex / --send the brief and the agent's report are saved under .lets/handoffs/. With --execute --send, the same tab implements an approved plan instead of reviewing it: the brief is the plan plus the rules it works under, and its commits come back UNVERIFIED for /lets:review --branch.
All three lanes share one safety model: nothing goes out without your request, whatever comes back is data rather than instructions, nothing is sent twice or typed over someone's half-written line, and anything read from another session is redacted. The Orca side is in docs/orca.md.
After key actions, Claude shows a contextual help box with the most likely next steps, so you always know what to do next:
┌─ LETS ─────────────────────────┐
│ Review? /lets:review │
│ Commit? /lets:commit │
└────────────────────────────────┘
→ Full docs: docs/tasks.md
LETS uses beads for persistent task tracking that survives conversation compaction:
/lets:status shows what's ready to work on→ Full docs: docs/configuration.md
After /lets:init, edit .lets/.env:
# Default response language — write the English name, like every value here (English, Ukrainian, Russian, Japanese, ...)
LETS_LANGUAGE=English
# Target branch for merges and PR base
LETS_MERGE_BRANCH=main
# PR flow: github | bitbucket | local
LETS_PR_FLOW=github
# Task tracker adapter: beads | none (selects .claude/rules/tracker-<name>.md; see docs/trackers.md)
LETS_TRACKER=beads
# How the sessions LETS launches start: default | auto | all-in (bypassPermissions - only on purpose,
# matching the class your orchestrator runs in)
LETS_LAUNCH_MODE=default
# Which actions ask you first: strict (every commit and confirm) | standard (default -
# irreversible or outward only) | minimal (empty or unknown = standard; see docs/workflow.md)
LETS_GATES=standard
All plugin-generated files live under .lets/ (gitignored); interactive worktrees under .worktrees/.
/lets:init wires the LETS statusline into .claude/settings.json (lets statusline). By default it draws a bordered multi-line box — identity (brand, folder/worktree, branch, diff, PR), budget (model + effort + usage), task, and a rotating tip line — width-responsive (Full ≥72 cols, Compact below), universal text glyphs (no Nerd Font or emoji needed), light/dark palettes.
Flags (set in settings.json's command):
| Flag / env | Effect |
|---|---|
--light | Light-terminal palette (default dark) |
--no-tip (or env LETS_STATUSLINE_TIP=off) | Hide the bottom tip line |
--no-dir (or env LETS_STATUSLINE_DIR=off) | Hide the location pill |
--no-task (or env LETS_STATUSLINE_TASK=off) | Hide the task line (also skips the background bd refresh) |
--compact | Legacy 2-line bar (fallback if the box misbehaves) |
To make a choice stick without hand-editing settings, run /lets:statusline (interactive) or lets statusline config --light … — it persists the flags to your personal, gitignored .claude/settings.local.json (not the shared settings.json, so it won't force your palette on collaborators). Restart Claude Code to apply.
{
"statusLine": {
"type": "command",
"command": "lets statusline --light"
}
}
Add --light for light-background terminals (default palette is dark). Full details — line anatomy, width tiers, worktree behavior — in docs/statusline.md.
| Dependency | Required | Purpose |
|---|---|---|
| Claude Code | Yes | AI coding agent (the thing LETS plugs into) |
| git | Yes | Version control, branching, worktrees |
| beads | Yes | Task tracking and issue management (Claude Code plugin) |
| gh | Optional | GitHub PR workflow (when LETS_PR_FLOW=github) |
bb-bash (bbb) | Optional | Bitbucket PR workflow (when LETS_PR_FLOW=bitbucket) |
The README is the tour; docs/ is the manual.
| Doc | What's in it |
|---|---|
| installation.md | Install the lets binary and the Claude Code plugin, initialize a project. Troubleshooting and uninstall. |
| workflow.md | The day-to-day loop — session lifecycle, the three ways to work, LETS boxes, how the hooks keep Claude on track. |
| plan-execute.md | The plan → execute flow — /lets:plan designs the change with codebase exploration and expert review, /lets:execute implements it behind approval gates. |
| code-review.md | Three levels of review — /lets:check, /lets:review, and /lets:github-pr (analyze, post inline, follow up, approve). Dynamic agent selection. |
| agents.md | The 15 expert agents, what triggers each, tiered scoring, agent modes, and the actor agent. |
| messaging.md | Talking to other sessions and agents — /lets:orc (the repo's orchestrator and peers), /lets:hub (other projects), /lets:handoff (a brief for Codex, Antigravity or any agent, report brought back and verified). |
| parallel-work.md | Working on several tasks at once — /lets:team run (one session per task), /lets:worktree (parallel terminals), and parallel implementers inside one task. |
| orca.md |
Building on the plugin itself? See CONTRIBUTING.md and CLAUDE.md.
MIT
The Orca addon — what LETS_LAUNCHER=orca switches on and how it degrades without Orca. |
| autonomous.md | Hands-off flows — Dynamic Workflows (--workflow) and the autonomous task pipeline (spawn → plan → execute, two gates). |
| sessions.md | Session continuity — what /lets:end settles, snapshots, trust-labelled commit ranges, --continue. |
| tasks.md | Task tracking — the task lifecycle, taking and creating tasks, notes, /lets:backlog, beads memory, shared backlogs for teams. |
| trackers.md | Pluggable tracker adapters — LETS_TRACKER selects beads (default) | none; one drift-tracked tracker-<name>.md per adapter, the neutral verb set, and how to add one. |
| commands.md | Full reference for every /lets:* command. |
| commands/ | Per-command deep dives — /lets:done, /lets:orc, /lets:handoff, /lets:research. |
| configuration.md | .lets/.env settings, the .lets/ file layout, lets init vs bd init setup order, and dependencies. |
| statusline.md | The statusline box — what each line shows, width tiers, flags, and /lets:statusline to persist your choice. |
| cli.md | The lets CLI a user touches — an index into cli/README.md. |