Repository navigation
Description
Summary
The Squad CLI supports satellite/remote-team mode via squad init --mode remote <path>, squad link <path>, and squad externalize — all of which write a .squad/config.json with a teamRoot field pointing to an external team root (e.g., a personal squad at %APPDATA%\squad).
However, the coordinator agent (squad.agent.md) has zero awareness of this mechanism. It only inspects .squad/team.md to decide whether to enter Init Mode, and never reads config.json.teamRoot to discover that the authoritative roster lives elsewhere. As a result, a correctly-linked satellite repo triggers full Init Mode (proposes a brand-new cast, asks "what are you building?", offers to scaffold a local team) every session — even though the repo is properly set up.
squad status has the same blind spot: for a satellite repo it reports Active squad: repo / Reason: Found .squad/ in repository tree, ignoring the teamRoot redirect in config.json.
Reproduction
mkdir foo && cd foo && git init
npx @bradygaster/squad-cli init --mode remote <path-to-personal-squad>
# .squad/config.json is created with { "teamRoot": "<personal-squad-path>" }
# .squad/team.md is created as a stub (empty ## Members table)
copilot --agent squad
> team rosterExpected: Coordinator reads .squad/config.json, sees teamRoot, loads the personal squad's team.md, and reports the existing roster.
Actual: Coordinator sees empty ## Members table in the local stub, enters Init Mode Phase 1, asks "What are you building?", and proposes to cast a brand-new local team — silently ignoring the satellite configuration the CLI just created.
Concrete example
In my setup:
- Personal squad lives at
C:\Users\jbenami\AppData\Roaming\squad\.squad(LOTR universe — Gandalf/Elrond/Frodo/etc.) - TIA repo was correctly linked via
squad init --mode remote. Its.squad/config.jsoncontains:{ "version": 1, "teamRoot": "..\\..\\..\\Users\\jbenami\\AppData\\Roaming\\squad", "projectKey": null } - pa-squad (the home repo) uses the identical pattern.
Opening copilot --agent squad in TIA, asking "team roster":
- Coordinator never reads
config.json - Coordinator sees empty
## Membersin local.squad/team.md - Coordinator enters Init Mode, proposes to cast a new team
I had to explicitly tell it "this team is already connected to a global squad" before it would look elsewhere.
Root cause
I grepped the entire 83KB squad.agent.md shipped with v0.9.4-insider.1 for teamRoot, --mode remote, squad link, Satellite, and satellite — zero hits. The only config.json references are about model preferences (Layer 0 of model selection). The same gap exists in the personal squad's template squad.agent.md, so this isn't a stale local file — it's upstream.
The init-mode check at the top of the coordinator instructions:
Check: Does `.squad/team.md` exist?
- No → Init Mode
- Yes, but `## Members` has zero roster entries → Init Mode (treat as unconfigured)
- Yes, with roster entries → Team Mode
…has no branch for "yes, with a config.json redirecting to another team root." It treats the satellite stub as a half-finished setup that needs casting.
Suggested fix
Before the existing init check, add a config-resolution step:
- If
.squad/config.jsonexists and contains ateamRootfield, resolve it (relative or absolute path) and treat that path's.squad/as the authoritative team root for this session — Team Mode, not Init Mode. - Pass the resolved external
teamRootto every spawn prompt (replacing the local repo path). - State management (decisions, history, orchestration logs, casting, identity) all write to the external team root, not the local repo.
- The local
.squad/team.mdstub becomes informational only (or can be deleted). - Update
squad statusto surface the redirect:Active squad: remote / Reason: .squad/config.json points to <teamRoot>.
A documented "Satellite Mode" section in squad.agent.md would also let the coordinator give users an honest status message instead of silently proposing a new team.
Workaround (current)
Tell the coordinator explicitly at the start of each session that the repo is governed by a personal/remote squad, so it knows to look at %APPDATA%\squad\.squad\team.md. This is brittle — relies on the user remembering, and resets every session.
Environment
- Squad CLI:
@bradygaster/squad-cliv0.9.4-insider.1 squad.agent.mdversion: 0.9.4-insider.1 (stamped header)- Platform: Windows 11, PowerShell 7,
copilot --agent squad - Personal squad:
%APPDATA%\squad\.squad - Affected repo: properly linked satellite with
config.json.teamRootset
Activity
fix(coordinator): resolve externalized state, teamRoot, stale work, a…