Skip to content

fix(cast): pass repo root to LocalAgentSource instead of .squad/ dir#892

Merged
tamirdresher merged 2 commits intodevfrom
squad/871-fix-cast-base-path
Apr 12, 2026
Merged

fix(cast): pass repo root to LocalAgentSource instead of .squad/ dir#892
tamirdresher merged 2 commits intodevfrom
squad/871-fix-cast-base-path

Conversation

@diberry
Copy link
Copy Markdown
Collaborator

@diberry diberry commented Apr 7, 2026

What

\cast\ command passed \paths.teamDir\ (which is .squad/) to \LocalAgentSource, but \LocalAgentSource\ internally appends .squad/agents\ — resulting in .squad/.squad/agents\ (double-nested, wrong path). Agents were never discovered in local mode.

Fix

Changed
ew LocalAgentSource(paths.teamDir)\ to
ew LocalAgentSource(cwd)\ in \packages/squad-cli/src/cli/commands/cast.ts.

Tests

Added \ est/cli/cast.test.ts\ with two regression tests:

  1. Agents discovered from correct path (<repo>/.squad/agents/)
  2. Decoy agent at wrong double-nested path (.squad/.squad/agents/) is NOT discovered

Verification

  • Grepped all \LocalAgentSource\ usages — no other callers have the same bug
  • Both tests pass

Closes #871

Copilot AI review requested due to automatic review settings April 7, 2026 03:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 7, 2026

🟡 Impact Analysis — PR #892

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 3
Files added 2
Files modified 1
Files deleted 0
Modules touched 3

🎯 Risk Factors

  • 3 files changed (≤5 → LOW)
  • 3 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (1 file)
  • .changeset/fix-cast-base-path.md
squad-cli (1 file)
  • packages/squad-cli/src/cli/commands/cast.ts
tests (1 file)
  • test/cli/cast.test.ts

This report is generated automatically for every PR. See #733 for details.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes local cast agent discovery by passing the repo root (cwd) to LocalAgentSource, avoiding the erroneous double-nested .squad/.squad/agents lookup.

Changes:

  • Update runCast() to instantiate LocalAgentSource with cwd instead of paths.teamDir.
  • Add Vitest regression coverage ensuring agents are discovered from <repo>/.squad/agents and not from .squad/.squad/agents.
  • Add a changeset documenting the CLI patch release, plus an agent history note capturing the learning.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/squad-cli/src/cli/commands/cast.ts Fixes the base path passed to LocalAgentSource so local project agents are discoverable.
test/cli/cast.test.ts Adds regression tests to prove correct agent discovery and prevent the double-nested-path regression.
.squad/agents/eecom/history.md Documents the root cause/fix pattern for future reference.
.changeset/fix-cast-base-path.md Declares a patch release for @bradygaster/squad-cli with a summary of the fix.

Comment thread test/cli/cast.test.ts Outdated
Comment thread .squad/agents/eecom/history.md Outdated
@diberry diberry force-pushed the squad/871-fix-cast-base-path branch 3 times, most recently from 64b4590 to 9b5841e Compare April 8, 2026 16:41
@diberry
Copy link
Copy Markdown
Collaborator Author

diberry commented Apr 8, 2026

🔍 Squad Review — Kaylee (Engineering)

# Check Status Notes
1 Changelog entry .changeset/fix-cast-base-path.md (CLI patch)
2 Squashed to 1 commit 1 commit
3 CI green All checks passed
4 Copilot comments resolved 2/2 threads resolved — leaked .squad/ file removed, spy cleanup fixed
5 No .squad/ files Clean (leaked file was removed per resolved thread)
6 No unrelated files 3 files — cast.ts fix, tests, changeset
7 Tests for changes est/cli/cast.test.ts — 2 regression tests (#871)
8 Not a duplicate/reversal Unique scope (closes #871)

Verdict: ✅ Ready to merge


Review by Squad AI team (Kaylee — Engineering) · requested by Dina Berry

Copy link
Copy Markdown
Collaborator Author

@diberry diberry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: Branch is behind dev — needs rebase before merge to ensure CI runs clean against latest.

suggestion: No test for .ai-team/agents fallback path. Low risk given the bug history but worth a third test case.

nit: Test charter uses YAML frontmatter but parseCharterMetadata only parses ## Identity markdown sections — template is misleading for future test authors.

nit: Changeset description reads ambiguously — consider: 'Passes repo root to LocalAgentSource instead of .squad/ dir, preventing a double-nested .squad/.squad/agents/ lookup.'

@diberry
Copy link
Copy Markdown
Collaborator Author

diberry commented Apr 10, 2026

CI validation passed on fork: diberry#139 (7/7 checks green)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment on lines 21 to 28
const paths = resolveSquadPaths(cwd);
if (!paths) {
fatal('No squad found. Run "squad init" first.');
}

// Discover project agents
const projectSource = new LocalAgentSource(paths.teamDir);
const projectSource = new LocalAgentSource(cwd);
const projectAgents = await projectSource.listAgents();
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveSquadPaths(cwd) returns paths.teamDir as the team identity root in remote mode (team repo root) and as the .squad/ directory in local mode. Passing raw cwd into LocalAgentSource makes agent discovery depend on the caller already being at the repo root, and it also breaks remote mode by scanning <project>/.squad/agents instead of <teamDir>/.squad/agents. Use paths to derive the correct base path (e.g., local: parent of paths.teamDir / paths.projectDir; remote: paths.teamDir).

Copilot uses AI. Check for mistakes.
Comment thread test/cli/cast.test.ts
Comment on lines +61 to +96
it('discovers project agents using repo root, not .squad/ dir (#871)', async () => {
await scaffold(TEST_ROOT);

// Suppress console output during test
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});

const { runCast } = await import('@bradygaster/squad-cli/commands/cast');
await runCast(TEST_ROOT);

// If the bug were present (passing paths.teamDir = .squad/ to LocalAgentSource),
// it would look in .squad/.squad/agents/ — which doesn't exist — and find 0 agents.
// With the fix, it looks in TEST_ROOT/.squad/agents/ and finds our test agent.
const output = logSpy.mock.calls.map(c => c.join(' ')).join('\n');
// Agent discovered from .squad/agents/test-agent/ (name derived from directory)
expect(output).toContain('test-agent');
expect(output).toContain('Session Cast');
});

it('does not look in double-nested .squad/.squad/agents/ path', async () => {
await scaffold(TEST_ROOT);

// Create a decoy agent at the WRONG double-nested path
const wrongPath = join(TEST_ROOT, '.squad', '.squad', 'agents', 'decoy');
await mkdir(wrongPath, { recursive: true });
await writeFile(join(wrongPath, 'charter.md'), `---\nname: Decoy\nrole: Wrong\n---\n# Decoy\n`);

const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});

const { runCast } = await import('@bradygaster/squad-cli/commands/cast');
await runCast(TEST_ROOT);

const output = logSpy.mock.calls.map(c => c.join(' ')).join('\n');
// Should find test-agent from correct path, not decoy from wrong path
expect(output).toContain('test-agent');
expect(output).not.toContain('decoy');
});
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tests cover local-mode discovery when runCast() is invoked with the repo root, but they don’t cover two important path-resolution scenarios that this change affects: (1) invoking runCast() from a nested subdirectory (which resolveSquadPaths() supports via walk-up), and (2) remote mode where agents should be discovered from paths.teamDir (team repo root). Adding regression coverage for these cases would prevent future path regressions.

Copilot uses AI. Check for mistakes.
@bradygaster
Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

…t(projectDir), remote: teamDir)

- Local mode: pass path.resolve(paths.projectDir, '..') (repo root) instead of raw cwd
- Remote mode: pass paths.teamDir (team repo root) for correct agent discovery
- Add tests for nested subdirectory invocation and remote mode
- Fix SAMPLE_CHARTER to use ## Identity sections matching parseCharterMetadata()
- Update changeset description for clarity

Agent-Logs-Url: https://github.com/bradygaster/squad/sessions/d90f6c33-1da0-4f17-90f3-9bae6f3650da

Co-authored-by: bradygaster <41929050+bradygaster@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 11, 2026

@copilot apply changes based on the comments in this thread

Applied in commit 1284bf6.

Changes based on the reviewer thread:

cast.tsLocalAgentSource appends .squad/agents to its base path, so we now derive it from paths instead of raw cwd:

  • Local mode: path.resolve(paths.projectDir, '..') (parent of .squad/ = repo root)
  • Remote mode: paths.teamDir (team repo root, which itself contains .squad/agents)

test/cli/cast.test.ts — added two new regression tests:

  1. Nested subdirectory invocation — runCast() called from a deep subdirectory; resolveSquadPaths walks up to find .squad/, then the fix computes the correct repo root
  2. Remote mode — project .squad/config.json has teamRoot pointing to a separate team repo; agents are discovered from paths.teamDir not from the project's own .squad/

Also fixed SAMPLE_CHARTER to use ## Identity sections (matching parseCharterMetadata()'s actual parsing logic) and updated the changeset description.

Copilot AI requested a review from bradygaster April 11, 2026 08:01
@tamirdresher tamirdresher merged commit c16a84b into dev Apr 12, 2026
@tamirdresher tamirdresher deleted the squad/871-fix-cast-base-path branch April 12, 2026 10:34
tamirdresher pushed a commit that referenced this pull request Apr 21, 2026
…892)

* fix(cast): pass repo root to LocalAgentSource instead of .squad/ dir

* fix(cast): derive LocalAgentSource base path from paths (local: parent(projectDir), remote: teamDir)

- Local mode: pass path.resolve(paths.projectDir, '..') (repo root) instead of raw cwd
- Remote mode: pass paths.teamDir (team repo root) for correct agent discovery
- Add tests for nested subdirectory invocation and remote mode
- Fix SAMPLE_CHARTER to use ## Identity sections matching parseCharterMetadata()
- Update changeset description for clarity

Agent-Logs-Url: https://github.com/bradygaster/squad/sessions/d90f6c33-1da0-4f17-90f3-9bae6f3650da

Co-authored-by: bradygaster <41929050+bradygaster@users.noreply.github.com>

---------

Co-authored-by: Dina Berry <diberry@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bradygaster <41929050+bradygaster@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cast uses wrong base path for LocalAgentSource in local mode

5 participants