fix: monorepo subfolder support — never run git init (#939)#944
fix: monorepo subfolder support — never run git init (#939)#944tamirdresher merged 4 commits intodevfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes squad init behavior in monorepo subfolders by removing the nested-repo “auto-fix” and instead placing the Copilot agent file at the git root while keeping .squad/ team state in the working subfolder.
Changes:
- Updated CLI init flow to detect “monorepo/subfolder” and never run
git init, introducingagentFileRootto control where.github/agents/squad.agent.mdis written. - Extended SDK
InitOptionswithagentFileRootand used it for agent file placement. - Updated
squad.agent.md.template“Worktree Awareness” section to describe CWD-first.squad/resolution for monorepos.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| packages/squad-cli/src/cli/core/init.ts | Stops nested git init; passes agentFileRoot and stamps agent version at git root when needed. |
| packages/squad-sdk/src/config/init.ts | Adds agentFileRoot option and uses it when writing .github/agents/squad.agent.md. |
| packages/squad-cli/templates/squad.agent.md.template | Updates template documentation for CWD-first .squad/ resolution. |
| packages/squad-sdk/templates/squad.agent.md.template | Updates template documentation for CWD-first .squad/ resolution. |
🔍 Review finding: Workflow placement gap in monorepo modeAfter running full E2E tests, a review identified a gap: In monorepo mode, GitHub Actions workflow files (squad-heartbeat.yml, squad-triage.yml, etc.) are placed in the subfolder's .github/workflows/ — a location GitHub Actions completely ignores. Only Current behavior (with this PR)
Options
I'm leaning toward option 1 (skip) for now and tracking the multi-squad workflow story separately. Would love feedback from @bradygaster on the preferred approach. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
packages/squad-cli/src/cli/core/init.ts:280
runInit()currently never surfacesresult.warningsfromsdkInitSquad(). With this change, monorepo-subfolder mode intentionally emits a warning about workflows being skipped, but the CLI UX will drop it on the floor. Please print warnings after the created/skipped file lists (and consider using the same yellow warning styling used elsewhere) so users know workflows were intentionally not installed.
// Ensure version is fully stamped in squad.agent.md
const agentPath = path.join(agentFileRoot, '.github', 'agents', 'squad.agent.md');
if (storage.existsSync(agentPath)) {
stampVersion(agentPath, version);
}
// Persist --roles flag for the REPL to pick up during casting
if (options.roles) {
const rolesMarker = path.join(squadDir, '.init-roles');
storage.writeSync(rolesMarker, '1');
success(`base roles enabled — team will use built-in role catalog`);
}
// Report .init-prompt storage
if (options.prompt) {
success(`.init-prompt stored — team will be cast when you start squad`);
}
// Report created files
for (const file of result.createdFiles) {
// Files are already relative to teamRoot, just display as-is
success(file);
}
// Report skipped files
for (const file of result.skippedFiles) {
// Files are already relative to teamRoot, just display as-is
console.log(`${DIM}${file} already exists — skipping${RESET}`);
}
I agree.
Q: how do I move to this? just squad upgrade? it's fine if I need to move the files/folders manually. |
When squad init is run in a subfolder of a monorepo, it previously ran git init to create a nested repo boundary. This broke monorepo workflows by creating git-in-git. Changes: - Never run git init in init command - Detect monorepo (cwd != git root) and split file placement: - .github/agents/squad.agent.md → git root (Copilot needs it there) - .squad/ → cwd subfolder (team state lives here) - Add �gentFileRoot option to InitOptions for explicit control - Update team root resolution: check CWD first for .squad/, then fall back to git root (enables multiple squads per monorepo) Closes #939 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Sync canonical template (.squad-templates/) and run sync-templates.mjs - Fix toRelativePath() to use path.relative() for cross-root paths - Reuse detectParentGitRepo() instead of duplicating git-root logic - Add monorepo regression test (no nested .git, agent at root, .squad in subfolder) - Add .changeset for release tracking Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GitHub Actions only reads workflows from <repo-root>/.github/workflows/. In monorepo mode, placing workflows in a subfolder has no effect. Additionally, multiple squads would conflict on the same workflow files. - Skip workflow placement when agentFileRoot != teamRoot - Emit warning in InitResult.warnings explaining why - Add workflow skip + warning assertions to monorepo test Found by Q (Devil's Advocate reviewer) during E2E test review. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ion, CLI test - Revert all package.json versions from 0.9.1-build.3 to 0.9.1 (build versions are local-only, changesets drive real bumps) - Revert .github/agents/squad.agent.md to canonical template content - Fix isMonorepoSubfolder: use path.resolve() + case-insensitive compare - Add CLI-level runInit() monorepo test (verifies no .git in subfolder) - Import path.resolve in SDK init.ts Addresses review comments on #944. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
420de99 to
2a60095
Compare
✅ All review comments addressed (rebased + 4th commit)Branch has been rebased onto latest \dev\ and all 12 review comments are fixed: Version bumps (3 comments)
|
|
Hey @serbrech Workflows: Already skippable via Skills: They resolve from CWD-relative Migration: For now it's 3 manual steps:
|
Problem
When
squad initruns in a subfolder of a monorepo, it detects that CWD != git root and runsgit initto create a nested repo boundary. This breaks monorepo workflows — users end up with git-in-git.Reported in #939 with a +1 from another monorepo user.
Solution
Never run
git init. Instead, split file placement:.github/agents/squad.agent.md.squad/(team state)This enables multiple squads in a monorepo:
/monorepo/ .github/agents/squad.agent.md ← shared agent (at git root) team-alpha/.squad/ ← alpha's team state team-beta/.squad/ ← beta's team stateChanges
packages/squad-cli/src/cli/core/init.ts— replacedgit initblock with monorepo-aware placement. AddedagentFileRootvariable that points to git root when in subfolder.packages/squad-sdk/src/config/init.ts— addedagentFileRoottoInitOptionsinterface. Uses it for.github/agents/placement (falls back toteamRoot).Both
squad.agent.md.templatefiles — updated Worktree Awareness section to check CWD first for.squad/, enabling monorepo subfolder resolution.How the agent finds the right
.squad/The coordinator resolves team root by checking CWD first:
.squad/? → use it (monorepo case).squad/? → use it (normal case)Since Copilot CLI sets CWD to wherever you launched
copilotfrom,cd team-alpha && copilotfinds alpha's squad,cd team-beta && copilotfinds beta's.