diff --git a/web/lib/flow-sources.ts b/web/lib/flow-sources.ts index b3eed86..ffa4daa 100644 --- a/web/lib/flow-sources.ts +++ b/web/lib/flow-sources.ts @@ -10,7 +10,13 @@ export const ISSUE_SOURCES = [ ] }, { id: 'shortcut', label: 'Shortcut', fields: [ { key: 'workspace', label: 'Workspace', placeholder: 'Your workspace' }, - { key: 'project', label: 'Project', placeholder: 'Web app' }, + // Shortcut scopes work by Group, branded "Team" in its UI. Projects are + // legacy: `/api/v3/projects` is empty in a modern workspace and a story's + // `project_id` is null there, so a project filter could never match one — + // and the launcher compared the name typed here against a numeric id, which + // silently dropped every story. Cloud now matches this against the team + // name (or its group id), so ask for the thing a story actually carries. + { key: 'team', label: 'Team (group)', placeholder: 'Platform' }, { key: 'labels', label: 'Required labels', placeholder: 'ready-for-agent' }, ] }, { id: 'jira', label: 'Jira', fields: [ diff --git a/web/lib/test/flow-sources.test.ts b/web/lib/test/flow-sources.test.ts index f5fb913..8cc74e3 100644 --- a/web/lib/test/flow-sources.test.ts +++ b/web/lib/test/flow-sources.test.ts @@ -27,13 +27,17 @@ describe('generated issue source filters', () => { it('combines source-specific filters and allows any selected source', () => { const matches = matcher(['linear', 'shortcut', 'jira'], { linear: { team: 'Engineering', project: 'Web', labels: 'ready' }, - shortcut: { workspace: 'acme', project: 'App', labels: 'bug, ready' }, + shortcut: { workspace: 'acme', team: 'Platform', labels: 'bug, ready' }, jira: { project: 'ENG', labels: 'ready' }, }); expect(matches({ ...issue, team: 'Engineering', project: 'Web' })).toBe(true); expect(matches({ ...issue, team: 'Design', project: 'Web' })).toBe(false); - expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', project: 'App', labels: ['ready', 'bug'] })).toBe(true); - expect(matches({ ...issue, source: 'shortcut', workspace: 'other', project: 'App', labels: ['ready', 'bug'] })).toBe(false); + expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', team: 'Platform', labels: ['ready', 'bug'] })).toBe(true); + expect(matches({ ...issue, source: 'shortcut', workspace: 'other', team: 'Platform', labels: ['ready', 'bug'] })).toBe(false); + // Paired negative on the field itself: same workspace, different team. A + // Shortcut story names its team by `group_id`, never by a project name, so + // this is the scoping that has to hold — and has to still reject. + expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', team: 'Growth', labels: ['ready', 'bug'] })).toBe(false); expect(matches({ ...issue, source: 'jira', project: 'ENG' })).toBe(true); expect(matches({ ...issue, source: 'github' })).toBe(false); });