You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 059b31e
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix(sdk,cli): resolve linked team state for both teamRoot forms (#2119)
teamRoot can name the team repo (what `squad link` writes) or the team's
.squad/ dir (what the docs show), but callers assumed different forms:
effectiveSquadDir and cast appended .squad, while the state MCP server
did not. The docs form broke `squad loop`/`watch`/`cast`; the link form
made squad_decide write decisions outside .squad/.
Add ResolvedSquadPaths.teamSquadDir, which resolves either form to the
team's squad dir (legacy .ai-team included), and use it in
effectiveSquadDir, cast, state-mcp, and the local-backend storage root.
Document on teamDir that callers must not join team-state paths onto it.
`squad doctor` now warns when a linked team repo still holds state-mcp
output outside .squad/. It checks every path the state tools can write
(exported as MUTABLE_STATE_PATHS, with isMutableStateKey) and lists each
.md/.json file to move, or to merge by hand when the same file already
exists under .squad/. It reports only and does not move files.
The SDK changeset is minor because teamSquadDir is a required field on
the exported ResolvedSquadPaths type.
Closes#2107
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Brady Gaster <41929050+bradygaster@users.noreply.github.com>
Co-authored-by: Tamir Dresher <tamir.dresher@gmail.com>
Linked teams now work with either `teamRoot` form: the team repository (what `squad link` writes) or the team's `.squad/` directory (what the docs show). `resolveSquadPaths()` adds `teamSquadDir`, the team's squad directory for both forms, and `resolveSquadState()` roots local-backend storage there. `squad loop`/`watch`, `squad cast`, and the state MCP server read team state from `teamSquadDir`, so `squad loop` no longer reports "No squad found" for the docs form, and `squad_decide` no longer writes decisions outside `.squad/` for the `squad link` form. Closes #2107.
7
+
8
+
`teamSquadDir` is a required field on the exported `ResolvedSquadPaths` type, so code that constructs that type must now set it. `@bradygaster/squad-sdk/tools` also exports `MUTABLE_STATE_PATHS` and `isMutableStateKey()`, the list of state paths that the state tools can write.
9
+
10
+
If you linked a team with `squad link`: state that the state MCP server wrote to the team repo root (`decisions.md`, `decisions/inbox/`, `casting/policy.json`, `agents/*/history.md`, `log/`, `orchestration-log/`, `sessions/`, `.scratch/`, `identity/`) now belongs in `<team>/.squad/`. Squad does not move it. Run `squad doctor` to find leftovers. It lists the `.md` and `.json` files to move to the same relative path under `<team>/.squad/` (for example `<team>/identity/now.md` to `<team>/.squad/identity/now.md`), and the files that already exist there, which you must merge by hand without overwriting the newer state. Do not replace the existing `<team>/.squad/` directories. Skills that `squad_skill` wrote went to `.github/skills/` in the folder that contains the team repo; move any you want to keep to `<team>/.github/skills/`. Doctor does not check that folder.
Copy file name to clipboardExpand all lines: docs/src/content/docs/guide/faq.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -131,6 +131,8 @@ If your project links to a remote team repository:
131
131
132
132
The path should be relative to your **project root** (where `.squad/` or `squad.config.ts` lives), not to the `.squad/` directory itself.
133
133
134
+
`teamRoot` can name either the team repository (`"../team-repo"`, which is what `squad link` writes) or its `.squad/` directory (`"../team-repo/.squad"`). Squad resolves both forms to the same team directory.
`found ${stray.length} team state file(s) in ${paths.teamDir}, outside the team's squad dir. Squad now reads team state from ${paths.teamSquadDir}.`,
224
+
];
225
+
// teamSquadDir normally has its own agents/ and decisions/, so tell the user
226
+
// to move files, not to move (and replace) the directories.
227
+
if(toMove.length>0)parts.push(`Move each file to the same relative path under it: ${formatKeyList(toMove)}.`);
228
+
if(toMerge.length>0)parts.push(`A file already exists at the same relative path for these; merge by hand and do not overwrite the newer state: ${formatKeyList(toMerge)}.`);
229
+
parts.push('Do not replace the existing directories there.');
230
+
231
+
return{name: 'linked team state location',status: 'warn',message: parts.join(' ')};
'State mutations are limited to mutable runtime state (decisions, inbox, casting policy, logs, sessions, scratch files, agent history, and identity). The casting registry/history pair must only be changed through the atomic casting protocol. Static config such as config.json, team.md, routing.md, charters, templates, and skills must not be changed with state tools.',
0 commit comments