Thanks to visit codestin.com
Credit goes to github.com

Skip to content

tu11aa/squadrant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

711 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Squadrant

Multi-project orchestration layer for coding agents. One command session controls everything.

Direction: Squadrant is moving to support all major coding agents β€” Claude Code, Codex, Cursor, Gemini CLI β€” not just Claude Code. Claude Code is the reference implementation today; other agents land through the plugin system's driver abstractions and the upcoming cross-agent projection layer (#31). See docs/specs/2026-04-24-multi-agent-direction.md.

How It Works

squadrant launch <project>          β†’ Captain (per project, in cmux)
squadrant launch --all              β†’ Every Captain
squadrant command --task briefing   β†’ One-shot Command session in a split pane
                                       (also: --task learnings-review | wiki-aggregate)
Captain β†’ squadrant crew spawn …    β†’ Crew (new tab in the captain workspace, fresh agent CLI)
  1. squadrant init β€” first-time setup
  2. squadrant launch <project> β€” start the project's captain in cmux
  3. squadrant launch --all β€” start every captain at once
  4. squadrant command --task briefing β€” on-demand Command session for cross-project work (optional; spawns in a split pane and exits when done)
  5. squadrant status β€” quick status check without spawning anything

Install

npm i -g squadrant               # global `squadrant` CLI (alias: `squad`)
squadrant init
squadrant doctor

Or from source:

git clone https://github.com/tu11aa/squadrant.git
cd squadrant
pnpm install
pnpm build                       # produces dist/index.js (the squadrant bin)
npm link                         # symlinks the global `squadrant`/`squad` to dist/index.js
squadrant init
squadrant doctor

Squadrant was formerly published/developed as claude-cockpit; it was rebranded in 0.9.0 as it grew into a multi-agent orchestration layer.

Prerequisites

Required Integrations

# Claude Memory β€” cross-session continuity
/plugin marketplace add thedotmack/claude-mem
/plugin install claude-mem

# Task Master β€” PRD decomposition (works via Max subscription)
npm install -g task-master-ai

# GSD β€” wave-based execution for crew (fresh context per step)
npx get-shit-done-cc@latest --claude --global

See core/plugins.md for full plugin setup.

Obsidian Plugins

See obsidian/plugins.md for Dataview, Templater setup.

Commands

Command Description
squadrant init First-time setup β€” config, hub vault, scripts
squadrant launch <project> Start a specific project captain
squadrant launch --all Launch all captain workspaces
squadrant command [--task <briefing|learnings-review|wiki-aggregate>] [--agent <a>] Spawn a one-shot Command session in a split pane (no persistent Command).
squadrant status Show all project status (no Claude needed)
squadrant standup Daily standup summary (zero LLM tokens)
squadrant doctor Health check β€” verify dependencies
squadrant projects list List registered projects
squadrant projects add <name> <path> Register a project
squadrant projects remove <name> Unregister a project
squadrant dashboard [--once] Print a one-shot status grid for all projects to the terminal.
squadrant dashboard --pane [--direction <dir>] [--interval <s>] Open a refreshing sidebar pane in the current cmux workspace.
squadrant dashboard sync-hub [--json] Mirror spoke status.md files into {hubVault}/projects/ for Obsidian Dataview.
squadrant runtime status <project> Check if a project's captain workspace is running
squadrant runtime send <project> <msg> Send a message to a captain workspace (auto-Enter)
squadrant runtime list List all workspaces from the active runtime
squadrant workspace read <project> <path> Read a scope-relative file from the project's spoke vault
squadrant workspace list <project> <dir> List entries in a spoke vault directory
squadrant workspace read --hub <path> Read from the hub vault
squadrant notify <message> Send a message to the user via the configured notifier
squadrant projection emit [--scope user|project] [--project <name>] [--target <name>] [--all] Emit squadrant rules + skills to Cursor/Codex/Gemini config files
squadrant projection diff [same flags] Preview projection changes without writing
squadrant projection list Show registered projection targets and their destinations
squadrant crew spawn <project> <task> [--name <n>] [--direction tab|right|left|up|down] [--agent <a>] Spawn an interactive crew sub-session (tab in the captain workspace by default; --direction for a pane)
squadrant crew send <project> <name> <message> Send a follow-up turn to an existing crew
squadrant crew read <project> <name> Read a crew session's current screen
squadrant crew close <project> <name> Shutdown a crew session (closes its tab)
squadrant crew list <project> List live crews for a project
squadrant shutdown [project] Graceful shutdown
squadrant effort [max|balance|low] Get or set the global crew tokenomics dial (no arg prints current)
squadrant retro Generate a retro (weekly/sprint summary) from daily logs and git (zero tokens)
squadrant config check Detect config drift vs the current default schema
squadrant heal [--dry-run|daemon] Targeted, idempotent remediation for squadrant components (daemon, health)
squadrant group dispatch … Cross-project intra-group operations (dispatch a task to a sibling project)
squadrant cmux … cmux integration helpers
squadrant feedback Open opt-in feedback issue

Monorepo structure

Six internal packages in a one-way dependency DAG. All are private (not published to npm).

Package Owns Notes
@squadrant/shared Config schema, TypeScript types, constants Leaf lib β€” zero internal deps
@squadrant/core Daemon logic, state-machine, protocol, AgentDriver interface, task/crew bus No concrete drivers β€” pure interfaces + orchestration
@squadrant/agents AI driver seam β€” claude, codex, opencode, gemini drivers + registry Implements AgentDriver. Add a new AI agent here.
@squadrant/workspaces Runtime (cmux), workspace (obsidian), notifier (cmux) drivers + registries Implements surface/workspace/notifier seams
@squadrant/web Observability dashboard β€” bundled HTML/JS served by CLI Read-only UI; inlined by CLI's tsup build
@squadrant/cli Commands, bin entry, daemon host, templates, plugin dir Root β€” depends on all other packages

Dependency DAG: shared β—„ core β—„ {agents, workspaces, web} β—„ cli

Build outputs (pnpm build via tsup, all internal packages inlined):

  • dist/index.js β€” CLI bin (squadrant command), entry: packages/cli/src/index.ts
  • dist/squadrantd.js β€” daemon process, entry: packages/cli/src/daemon-host.ts

See the architecture diagram for a visual overview.

Architecture

Roles

  • Command (Opus) β€” on-demand cross-project session. Spawned by squadrant command --task <briefing|learnings-review|wiki-aggregate> in a split pane; exits when the task completes. No persistent Command process.
  • Captain (Opus) β€” project leader, uses Agent Teams + git worktrees
  • Crew (Sonnet by default) β€” interactive sub-session running as a new tab in the captain's workspace (or a split pane via --direction). Each crew is named (crew-1, crew-2, …) and stays idle between turns waiting for the captain's next message β€” same model as a Claude Agent Team subagent. Spawn with squadrant crew spawn, send follow-ups with squadrant crew send, close when done. Works with any agent CLI (claude and opencode are fully interactive; codex/gemini currently print-mode). Uses GSD for complex tasks.

Model Routing

Each role runs on the optimal model for cost/quality tradeoff. Configured in config.json:

  • Command/Captain/Review: Opus (coordination + quality)
  • Crew: Sonnet (execution)
  • Exploration: Haiku (cheap lookups)

Runtime Abstraction

Workspaces run on a pluggable runtime driver (currently only cmux). Each project may override the global default via its runtime field. Bash scripts call squadrant runtime <op> to talk to the configured runtime instead of any specific binary. New runtimes (tmux, Docker, SSH) are added as driver files in @squadrant/workspaces (packages/workspaces/runtimes/) β€” see docs/specs/archive/2026-04-20-plugin-system-runtime-design.md.

Workspace Abstraction

Vault storage (hub + per-project spokes) runs behind a pluggable workspace driver (currently only obsidian). Filesystem operations β€” read, write, list, exists, mkdir β€” go through the driver instead of fs directly. Each project may override the global default via its workspace field. Bash scripts call squadrant workspace <op> to read/write vault data without hardcoding paths. New backends (Notion, plain-md, S3) are added as driver files in @squadrant/workspaces (packages/workspaces/workspaces/) β€” see docs/specs/archive/2026-04-21-plugin-system-workspace-design.md.

Notifier Abstraction

User-facing notifications run behind a pluggable notifier driver (currently only cmux). Escalations and other "tell the user" events go through squadrant notify <message>. The default CmuxNotifier delegates to squadrant runtime send --command β€” the abstraction exists as a swap-point for future Slack/Discord/email/pager drivers. Notifier is global (no per-project override). See docs/specs/archive/2026-04-21-plugin-system-notifier-design.md.

Crew Spawn (Interactive Sub-Sessions)

Crew is the captain's equivalent of an Agent Team subagent β€” but runtime-agnostic. The captain spawns a crew via squadrant crew spawn <project> "<task>" [--name <n>], which opens a new tab in the captain's cmux workspace, boots an interactive Claude session (no -p), and sends the task as the first turn. The crew works on it and stays idle waiting for follow-ups. The captain drives the session with squadrant crew send/read/close/list, addressing each crew by its tab title (πŸ”§ <project>:<name>).

Pass --direction right|left|up|down to use a split pane instead of a tab. State lives in the surface buffer + git; tabs die with the captain workspace on squadrant shutdown. Non-Claude agents (codex/gemini) currently still launch in print-mode; full interactive support is a follow-up. See docs/specs/archive/2026-05-05-squadrant-thin-redirect-design.md.

Effort Dial (Tokenomics)

squadrant effort max|balance|low is a single global dial that biases how aggressively crews consume tokens β€” a captain-discretion signal, not mechanical routing. max favors quality/tokens, low biases toward economy (e.g. preferring opencode for cheap work); balance sits between. Run squadrant effort with no argument to print the current setting. The value lives in config and is honored by captains via the captain-ops playbook (#317 / #381).

Crew Lifecycle & Delivery

  • Daemon-direct delivery β€” crew turns and handoffs are delivered straight to the cmux surface by the daemon. The old notify-relay supervisor was deleted; there is no relay process to keep alive (#332).
  • Semantic heartbeat β€” crews emit a lifecycle signal the captain reads as CREW IDLE / QUIET / STALLED, distinguishing "waiting for you" from "wedged" without scraping the pane (#354).
  • stopped project status + orphan reap β€” when a captain goes away, the daemon reaps its orphaned crews and marks the project stopped (intentional shutdown) rather than leaving stale tabs or faulting (#324 / #323 / #388).

Telegram (Two-Way, opt-in)

Drive squadrant from your phone (#65). When a telegram block is present in config, a daemon-internal bridge:

  • Outbound β€” pushes each project's crew lifecycle events (CREW DONE / FAILED / BLOCKED / APPROVAL / INPUT / TIMEOUT / IDLE) and other captain notifications to that project's Telegram forum topic, filtered by a per-project crew tier (see Notification tuning below). Best-effort: a Telegram failure never delays or breaks delivery to the captain pane.
  • Inbound (project topic) β€” a message you send in a project's topic is delivered into that project's captain pane as a labeled πŸ“© [from Telegram] message; the captain decides what to do with it. With remote control enabled (see below), if no captain is alive the daemon auto-launches one, then delivers (#403).
  • General command channel β€” slash commands in the supergroup's General topic run a curated set of squadrant operations from your phone (#402). Available: /help, /status, /projects, /crews <project>, /launch <project>, /effort [max|balance|low], /config get <key>, /config set <key> <value>, /spawn <project> <task…>. Each maps to a validated CLI argv run via async execFile β€” never a shell passthrough. Unknown commands and freeform text get a /help hint.

Absent the config block, the bridge is never constructed β€” zero behavior change. No runtime SDK is added (plain fetch; @grammyjs/types is a dev-only type dependency).

Setup (recommended):

  1. Create a bot with @BotFather and copy its token.
  2. Run squadrant telegram setup β€” it prompts for the bot token (input hidden), validates it via the Bot API, auto-detects your supergroup id, captures your Telegram user-id, and offers to enable remote control.
  3. Bind a project to a topic: squadrant telegram link <project> (creates the forum topic and records the binding).
  4. Check wiring with squadrant telegram status.

Setup (manual): Put the token + ids in config (or export TELEGRAM_BOT_TOKEN) β€” see the telegram block under Config. Then run squadrant telegram link <project>.

Security model (#321) β€” fail-closed remote control

The control surfaces (auto-launch + General command channel) are off by default and gated by two independent checks. A control action runs only when both hold:

  1. remoteControl: true β€” an explicit opt-in master switch (default false).
  2. message.from.id ∈ users[] β€” the sender's Telegram user-id is on the allowlist. An empty/absent users list β‡’ control is disabled (fail-closed). Chat membership alone is never enough for control.

When remote control is off (the default after upgrade), behavior is exactly v1: project-topic messages queue to the captain pane (no auto-launch), and General-topic slash commands are rejected with β›” not authorized. Inbound text is always treated as data; only the curated registry maps to actions, and /config set is restricted to a default-deny writable-key allowlist (currently just defaults.effort) β€” secrets (botToken, users, chats, supergroupId) can never be written over Telegram.

Notification tuning (per-project)

Notifications resolve through a layered config: built-in defaults β†’ global config.json (telegram.notify) β†’ per-project ~/.config/squadrant/projects/<name>.json, merged per key (overriding one key never resets its siblings). Two axes are independent:

  • Live mute (active) β€” system-tracked session state in telegram-state.json. Flipped by engagement (any message into a topic auto-unmutes), /mute / /unmute (Telegram), or squadrant telegram notify <project> on|off. The live value wins over the config default when present.
  • Deliberate preferences (crew, cap) β€” persistent settings in the per-project config file. Written by squadrant telegram notify <project> crew <tier> / cap <on|off> (CLI) or /notify crew <tier> / /notify cap <on|off> (Telegram, fail-closed behind remote control).

Crew tiers (cumulative) select which lifecycle events reach a topic when active:

Tier Events delivered
none nothing
done_only task.done, task.failed
alert_only (default) done_only + task.blocked, task.approval.requested, task.input.requested, task.timeout
all every lifecycle event (incl. progress/heartbeat noise)

cap (default on) gates explicit captain pushes via squadrant telegram send β€” set cap off for a project to stop the captain DM-ing you there (independent of idle-mute; an explicit push is not dropped just because the topic is idle-muted).

Config (deliberate prefs) and state (live toggles) are kept separate by design: /unmute flips your session, it does not rewrite your config file. An absent projects/<name>.json behaves exactly as the global defaults β€” the layer is fully additive, no migration. See docs/superpowers/specs/2026-06-23-per-project-layered-config-design.md.

Remote wake (#403) β€” operator-side

Auto-launch boots a captain when the daemon is already running. Waking a sleeping Mac from your phone (Wake-on-LAN / a relay that nudges the machine) is operator-side infrastructure, out of scope for this repo β€” see #403 for the end-to-end flow.

Interim note (link ↔ daemon 409): the Telegram Bot API allows only one getUpdates consumer at a time. The setup wizard polls getUpdates to detect your group/user-id, so run it with the daemon stopped. link uses only createForumTopic, so it's unaffected.

Projection (Cross-Agent Config Sync)

Squadrant rules (Karpathy principles, captain-ops) and per-project AGENTS.md emit to each supported agent's canonical path via squadrant projection emit. User-level projection pushes squadrant's skills to ~/.cursor/rules/squadrant-global.mdc, ~/.codex/AGENTS.md, ~/.gemini/GEMINI.md. Project-level projection pushes a managed project's own AGENTS.md into {project}/CLAUDE.md, {project}/.cursor/rules/squadrant.mdc, {project}/GEMINI.md β€” zero squadrant-global content leaks into the project repo. Shared files use <!-- squadrant:start --> ... <!-- squadrant:end --> markers; dedicated files overwrite. See docs/specs/archive/2026-04-24-plugin-system-projection-design.md.

The user-level projection now also inlines templates/captain.generic.md and templates/crew.generic.md as ## Captain Role / ## Crew Role sections inside the squadrant marker block, so non-Claude agents (Codex, Gemini, Cursor) load the same role descriptions Claude Code loads via --append-system-prompt-file. See docs/specs/archive/2026-05-05-multi-agent-template-parity-plan.md (#45).

Obsidian Vaults (Hub-and-Spoke)

  • Hub vault (~/squadrant-hub) β€” cross-project dashboard + hub wiki
  • Spoke vaults β€” per-project status, learnings, and wiki

Knowledge System (opt-in writes)

  • Status (opt-in) β€” captains record {spokeVault}/status.md via write-status.sh (also written by the captain session-end hook) when there's something worth noting (a blocker, "starting work on X"). Not on a schedule.
  • Dashboard β€” squadrant dashboard --pane opens a refreshing sidebar pane in cmux that lists every project's live state, queried from the squadrant daemon's task records. squadrant dashboard sync-hub mirrors each spoke status.md into {hubVault}/projects/ so the hub vault's dashboard.md Dataview query renders the same data inside Obsidian.
  • Handoff files β€” captain writes when in-flight work needs to survive into tomorrow; skipped on uneventful sessions.
  • Daily logs β€” captain writes when the day produced something worth a log; not on a schedule.
  • Learnings β€” recorded when a captain encounters a genuinely surprising or reusable pattern.
  • Wiki β€” compiled, indexed knowledge pages in spoke vaults (wiki/pages/); promoted from learnings when worth maintaining.
  • Hub Wiki β€” cross-project knowledge aggregated by an on-demand squadrant command --task wiki-aggregate run.
  • Scripts: wiki-ingest.sh, wiki-query.sh, wiki-log.sh.

Session Continuity

  • Handoff files β€” captain writes context on shutdown, reads on startup
  • Session freshness β€” auto-detects new day or template changes, forces fresh context
  • claude-mem β€” cross-session memory via MCP plugin

Config

~/.config/squadrant/config.json

{
  "commandName": "command",
  "hubVault": "~/squadrant-hub",
  "runtime": "cmux",
  "workspace": "obsidian",
  "notifier": "cmux",
  "telegram": {
    "botToken": "123456:ABC...",
    "supergroupId": -1001234567890,
    "chats": [-1001234567890],
    "users": [987654321],
    "remoteControl": true,
    "pollMs": 1000
  },
  "projects": {
    "brove": {
      "path": "~/projects/brove",
      "captainName": "brove-captain",
      "spokeVault": "~/squadrant-hub/spokes/brove",
      "host": "local",
      "runtime": "cmux",
      "workspace": "obsidian",
    }
  },
  "defaults": {
    "maxCrew": 5,
    "worktreeDir": ".worktrees",
    "teammateMode": "in-process",
    "permissions": {
      "command": "default",
      "captain": "acceptEdits"
    },
    "models": {
      "command": "opus",
      "captain": "opus",
      "crew": "sonnet",
      "exploration": "haiku",
      "review": "opus"
    }
  }
}

The telegram block is optional β€” omit it and the Telegram bridge is never constructed. botToken may be left out of the file and supplied via the TELEGRAM_BOT_TOKEN env var instead. chats is the inbound chat_id allowlist; users is the per-user-id allowlist for control actions and remoteControl (default false) is the master opt-in for auto-launch + the General command channel β€” both must be set for any remote control to act (fail-closed, #321). pollMs (default 1000) is the inbound long-poll cadence. See Telegram (Two-Way, opt-in).

Supported Agents

Agent Status Notes
Claude Code βœ… Shipping Reference implementation; reads CLAUDE.md, Skill tool, MCP via settings.json
Codex CLI βœ… projection (skills + roles) Captain/crew roles inlined into ~/.codex/AGENTS.md (#45). First-class role identity is #35.
Cursor βœ… projection (skills + roles) Captain/crew roles inlined into ~/.cursor/rules/squadrant-global.mdc (#45).
Gemini CLI βœ… projection (skills + roles) Captain/crew roles inlined into ~/.gemini/GEMINI.md (#45).
opencode βœ… driver + projection (interactive crew) opencode run "<prompt>" with --format json / -m <model>; AGENTS.md projects to ~/.config/opencode/AGENTS.md.

Cross-agent config sync (one canonical source β†’ agent-specific formats) is tracked in #31.

Inspirations

License

MIT

About

Multi-project agent orchestration for Claude Code. One command session controls everything.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors