Skip to content

fix(FN-1721): scope GitHub import remotes to project - #1722

Merged
gsxdsm merged 2 commits into
mainfrom
feature/import-github-fix
Jun 22, 2026
Merged

fix(FN-1721): scope GitHub import remotes to project#1722
gsxdsm merged 2 commits into
mainfrom
feature/import-github-fix

Conversation

@gsxdsm

@gsxdsm gsxdsm commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #1721.

The Import from GitHub modal now passes the active projectId into remote detection, so /api/git/remotes is queried for the selected project instead of falling back to the dashboard process context. This prevents the dialog from showing "No GitHub remotes detected" when a project has configured GitHub remotes.

The remote-loading effect also ignores stale responses when the active project changes while the modal remains open, so an older project's remotes cannot overwrite the current project's selection.

This PR also exposes the shared dashboard ViewHeader alias to Vite/Vitest/app TypeScript config so bundled plugin dashboard views resolve the host component in CI.

Root Cause

GitHubImportModal called fetchGitRemotes() without projectId. In multi-project mode the backend returns an empty remote list without project scope, causing the modal to display the no-remotes state despite valid GitHub remotes.

The CI failure was caused by plugins/fusion-plugin-compound-engineering/src/dashboard/CompoundEngineeringView.tsx importing @fusion/dashboard/app/components/ViewHeader while the dashboard build/test aliases only exposed TaskCard.

Validation

Local:

  • pnpm --filter @fusion/dashboard exec vitest run --project dashboard-app-quality-backfill --silent=passed-only --reporter=dot --exclude '**/build-output.test.ts' app/components/__tests__/GitHubImportModal.test.tsx
  • pnpm exec eslint packages/dashboard/app/components/GitHubImportModal.tsx packages/dashboard/app/components/__tests__/GitHubImportModal.test.tsx packages/dashboard/vite.config.ts packages/dashboard/vitest.config.ts
  • pnpm --filter @fusion/dashboard typecheck
  • pnpm --filter @fusion/dashboard build

CI:

  • Lint passed
  • Typecheck passed
  • Build passed
  • Gate passed

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Resolved an issue where GitHub remote detection in multi-project dashboards displayed stale remote data when switching between projects. The UI now correctly passes the active project context to ensure the appropriate GitHub remotes are retrieved and displayed.
  • Tests

    • Added test coverage to verify GitHub remote fetching includes the active project context and that stale responses are properly ignored when the project changes.

Pass the active projectId when the GitHub import modal detects remotes so multi-project dashboards do not show a false no-remotes state. Ignore stale remote responses when projectId changes while the modal remains open.

References: #1721
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 20d26ca8-a497-4483-9c8f-3f8f452e800d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/import-github-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ghost

ghost commented Jun 22, 2026

Copy link
Copy Markdown

Ready to review this PR? Stage has broken it down into 4 individual chapters for you:

Title
1 Fix ViewHeader path aliases in configuration
2 Scope GitHub remote detection to projectId
3 Verify project-scoped remote loading in tests
4 Add changeset for GitHub remote fix
Open in Stage

Chapters generated by Stage for commit 5e0e9c0 on Jun 22, 2026 4:36pm UTC.

Map the shared dashboard ViewHeader module in Vite, Vitest, and app TS paths so bundled plugin dashboard views resolve the host component during PR build/typecheck.

References: #1721
@gsxdsm
gsxdsm marked this pull request as ready for review June 22, 2026 16:40
@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes GitHubImportModal showing "No GitHub remotes detected" in multi-project mode by forwarding the active projectId to fetchGitRemotes, and prevents stale project data from overwriting the current project's selection when a project switch happens while the modal is open.

  • Remote scoping: fetchGitRemotes(projectId) is now called instead of the no-arg form, and projectId is added to the effect's dependency array so the remote list refreshes automatically when the active project changes mid-modal.
  • Stale-response guard: A closure-scoped cancelled flag (set in the effect cleanup) prevents in-flight responses from an older project from applying to the new project's state; the companion remoteLoadRequestIdRef counter adds an extra redundant layer of defense for the same case.
  • Pre-existing fix: projectId was silently missing from handleImport's useCallback dependency array even though it was already forwarded to the import API calls — this PR closes that stale-closure gap.
  • CI alias: ViewHeader is now exposed in all four config files (vite.config.ts, vitest.config.ts, tsconfig.app.json, tsconfig.test-check.json) so plugin dashboard views that import @fusion/dashboard/app/components/ViewHeader resolve correctly in build and typecheck.

Confidence Score: 5/5

Safe to merge. The changes are narrowly scoped to remote detection in the GitHub import modal and alias additions to build/typecheck configs with no risk to other surfaces.

The core logic change (passing projectId + stale-response guard) is straightforward and backed by two targeted regression tests — one verifying the forwarding, one exercising the race condition. The missing projectId dependency on handleImport was a real pre-existing stale-closure bug that is now closed. Alias additions are additive-only and consistent across all four config files. No state-management surprises, no unguarded edge cases in the new async flow.

No files require special attention. The stale-response guard in GitHubImportModal.tsx is worth a read to verify the cancelled + requestId dual-guard reasoning, but both mechanisms agree and the test covers the scenario end-to-end.

Important Files Changed

Filename Overview
packages/dashboard/app/components/GitHubImportModal.tsx Passes projectId to fetchGitRemotes, adds per-invocation cancelled flag + request-ID counter to prevent stale responses, and adds projectId to handleImport's dependency array (closes a pre-existing stale-closure bug on that callback).
packages/dashboard/app/components/tests/GitHubImportModal.test.tsx Adds two new tests: one asserting projectId is forwarded to fetchGitRemotes, and one asserting that a late-resolving stale request (project-a) cannot overwrite the current project-b state after a project switch mid-modal.
packages/dashboard/vite.config.ts Adds @fusion/dashboard/app/components/ViewHeader alias so plugin dashboard views resolve the host component during bundled builds.
packages/dashboard/vitest.config.ts Mirrors the ViewHeader alias addition into the Vitest resolver config so CI test runs resolve the same path as the production build.
packages/dashboard/tsconfig.app.json Adds ViewHeader path alias to TypeScript compiler paths to keep typecheck consistent with the Vite/Vitest aliases.
packages/dashboard/tsconfig.test-check.json Mirrors the ViewHeader alias into the test typecheck config so pnpm typecheck covers the same import surface as the build.
.changeset/github-import-project-remotes.md Correct patch-level changeset for @runfusion/fusion as required by AGENTS.md for published-package bug fixes.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as GitHubImportModal
    participant Ref as remoteLoadRequestIdRef
    participant API as fetchGitRemotes (API)

    Note over UI: isOpen=true, projectId=A
    UI->>Ref: "increment → requestId=1"
    UI->>API: fetchGitRemotes("project-a")

    Note over UI: projectId changes to B (modal stays open)
    UI->>UI: "cleanup: cancelled_A=true"
    UI->>Ref: "increment → requestId=2"
    UI->>API: fetchGitRemotes("project-b")

    API-->>UI: resolve project-b remotes
    UI->>UI: "guard passes (requestId=2, !cancelled_B)"
    UI->>UI: setRemotes(project-b remotes)

    API-->>UI: resolve project-a remotes (stale)
    UI->>UI: "guard fires (cancelled_A=true → skip)"
    Note over UI: project-a data discarded ✓
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as GitHubImportModal
    participant Ref as remoteLoadRequestIdRef
    participant API as fetchGitRemotes (API)

    Note over UI: isOpen=true, projectId=A
    UI->>Ref: "increment → requestId=1"
    UI->>API: fetchGitRemotes("project-a")

    Note over UI: projectId changes to B (modal stays open)
    UI->>UI: "cleanup: cancelled_A=true"
    UI->>Ref: "increment → requestId=2"
    UI->>API: fetchGitRemotes("project-b")

    API-->>UI: resolve project-b remotes
    UI->>UI: "guard passes (requestId=2, !cancelled_B)"
    UI->>UI: setRemotes(project-b remotes)

    API-->>UI: resolve project-a remotes (stale)
    UI->>UI: "guard fires (cancelled_A=true → skip)"
    Note over UI: project-a data discarded ✓
Loading

Reviews (1): Last reviewed commit: "fix(FN-1721): expose ViewHeader to dashb..." | Re-trigger Greptile

@gsxdsm
gsxdsm merged commit dfd4baf into main Jun 22, 2026
6 checks passed
@gsxdsm
gsxdsm deleted the feature/import-github-fix branch July 24, 2026 06:08
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.

Import from GitHub dialog shows 'no remotes' — missing projectId in API call

1 participant