From f2fcb07ae021edf643753a3959a3c10aef92abc3 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Mon, 23 Feb 2026 09:33:12 -0600 Subject: [PATCH] fix: pass squadFolder to GitHubIssuesService for .squad workspaces GitHubIssuesService created its own TeamMdService with the default '.ai-team' folder, ignoring the runtime-detected squad folder. This caused all GitHub issue and milestone fetches to silently return empty results in workspaces using the new .squad/ folder structure. This was missed in commit 5c01e1f which fixed the same issue in four other places. Added squadFolder option to GitHubIssuesServiceOptions and tests verifying both .squad detection and default .ai-team fallback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/extension.ts | 2 +- src/services/GitHubIssuesService.ts | 5 ++- src/test/suite/gitHubIssuesService.test.ts | 45 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 7af18c3..d21467f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -81,7 +81,7 @@ export function activate(context: vscode.ExtensionContext): void { const decisionsProvider = new DecisionsTreeProvider(dataProvider, squadFolderName); // Wire up GitHub Issues service - const issuesService = new GitHubIssuesService(); + const issuesService = new GitHubIssuesService({ squadFolder: squadFolderName }); teamProvider.setIssuesService(issuesService); // Create dashboard webview diff --git a/src/services/GitHubIssuesService.ts b/src/services/GitHubIssuesService.ts index 0cdbc5c..4233e0f 100644 --- a/src/services/GitHubIssuesService.ts +++ b/src/services/GitHubIssuesService.ts @@ -50,6 +50,9 @@ export interface GitHubIssuesServiceOptions { /** GitHub API base URL (default: https://api.github.com) */ apiBaseUrl?: string; + + /** Squad folder name (default: '.ai-team') */ + squadFolder?: '.squad' | '.ai-team'; } /** @@ -66,7 +69,7 @@ export class GitHubIssuesService { private issueSourceCache: IssueSourceConfig | null = null; constructor(options: GitHubIssuesServiceOptions = {}) { - this.teamMdService = new TeamMdService(); + this.teamMdService = new TeamMdService(options.squadFolder); this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS; this.token = options.token; this.apiBaseUrl = (options.apiBaseUrl ?? 'https://api.github.com').replace(/\/+$/, ''); diff --git a/src/test/suite/gitHubIssuesService.test.ts b/src/test/suite/gitHubIssuesService.test.ts index 1285ebe..78d5125 100644 --- a/src/test/suite/gitHubIssuesService.test.ts +++ b/src/test/suite/gitHubIssuesService.test.ts @@ -58,6 +58,37 @@ suite('GitHubIssuesService', () => { } }); + test('reads team.md from .squad folder when squadFolder option is set', async () => { + const tempDir = path.join(TEST_FIXTURES_ROOT, 'temp-squad-folder'); + const squadDir = path.join(tempDir, '.squad'); + await fs.promises.mkdir(squadDir, { recursive: true }); + await fs.promises.writeFile(path.join(squadDir, 'team.md'), [ + '# Team', + '', + '## Issue Source', + '', + '| Field | Value |', + '|-------|-------|', + '| **Repository** | testowner/testrepo |', + ].join('\n')); + + try { + // Without squadFolder option, service looks in .ai-team (misses .squad) + const defaultService = new GitHubIssuesService(); + const defaultConfig = await defaultService.getIssueSource(tempDir); + assert.strictEqual(defaultConfig, null, 'Default service should not find .squad/team.md'); + + // With squadFolder option, service finds team.md in .squad + const squadService = new GitHubIssuesService({ squadFolder: '.squad' }); + const squadConfig = await squadService.getIssueSource(tempDir); + assert.ok(squadConfig, 'Squad service should find .squad/team.md'); + assert.strictEqual(squadConfig!.owner, 'testowner'); + assert.strictEqual(squadConfig!.repo, 'testrepo'); + } finally { + await fs.promises.rm(tempDir, { recursive: true, force: true }); + } + }); + test('parses owner/repo format correctly', async () => { const tempDir = path.join(TEST_FIXTURES_ROOT, 'temp-repo-format'); const aiTeamDir = path.join(tempDir, '.ai-team'); @@ -423,5 +454,19 @@ suite('GitHubIssuesService', () => { const token = (service as unknown as { token: string }).token; assert.strictEqual(token, 'ghp_test123'); }); + + test('passes squadFolder to internal TeamMdService', () => { + const service = new GitHubIssuesService({ squadFolder: '.squad' }); + + const teamMdService = (service as unknown as { teamMdService: { squadFolder: string } }).teamMdService; + assert.strictEqual(teamMdService.squadFolder, '.squad'); + }); + + test('defaults to .ai-team when squadFolder not specified', () => { + const service = new GitHubIssuesService(); + + const teamMdService = (service as unknown as { teamMdService: { squadFolder: string } }).teamMdService; + assert.strictEqual(teamMdService.squadFolder, '.ai-team'); + }); }); });