feat(FN-3577): add native shell guide and bridge contract documentation

Adds a native shell integration guide (FN-3577) with fusionShell bridge contract documentation, wired into the docs navigation, plus a regression test; also hardens the dependency graph's task filtering (FN-3085) to include in-review tasks and handle orphan edges, with corresponding test coverage ac

Fusion-Task-Id: FN-3577
This commit is contained in:
Fusion
2026-05-07 03:59:43 -07:00
committed by gsxdsm
parent 3f09037cfe
commit f3c99eb4fa
7 changed files with 201 additions and 12 deletions

View File

@@ -23,6 +23,7 @@ For a full walkthrough (installation, onboarding, first task, and daily workflow
| [Dashboard Guide](./dashboard-guide.md) | Board/list views, terminal, git manager, files, planning, and UI tools |
| [CLI Reference](./cli-reference.md) | Complete `fn` command reference with subcommands, flags, and examples |
| [Remote Access](./remote-access.md) | Operator runbook for Tailscale/Cloudflare setup, tokenized login links, security caveats, and troubleshooting |
| [Native Shell Connection Guide](./native-shell.md) | Canonical mobile/desktop shell onboarding, profile management, QR/manual setup, and remote handoff behavior |
### Task & Project Management
| Guide | Description |

View File

@@ -21,6 +21,38 @@ At a high level, Fusion is split into:
Native shells expose a shared host-neutral bridge at `window.fusionShell` for first-run shell onboarding, connection profile persistence, and active shell mode/profile state. The dashboard consumes `window.fusionShell` when present and degrades cleanly in plain web/PWA mode.
### `window.fusionShell` bridge contract
Canonical dashboard-side types live in `packages/dashboard/app/types/native-shell.d.ts`.
Shared bridge methods used by dashboard/mobile/desktop flows:
- `getState()`
- `listProfiles()`
- `saveProfile(profile)`
- `deleteProfile(profileId)`
- `setActiveProfile(profileId)`
- `setDesktopMode(mode)`
- `startQrScan()`
- `openConnectionManager()`
- `subscribe(listener)`
Shared shell state contract (`ShellConnectionState`):
- `host` (`"web" | "mobile-shell" | "desktop-shell"`)
- `desktopMode` (`"local" | "remote"`, optional)
- `activeProfileId`
- `profiles`
- `localServer` (`status`, optional `port`, optional `error`)
Desktop-specific bootstrap extension:
- Electron preload also exposes `getDesktopModeState()` for first-run desktop mode selection (`{ isFirstRun, desktopMode }`).
- The dashboard itself does **not** depend on that preload-only helper for steady-state rendering; it consumes shared shell state via `ShellContext` (`packages/dashboard/app/context/ShellContext.tsx`).
Persistence ownership by host:
- **Mobile shell** persists connection profiles + active profile with Capacitor Preferences (`packages/mobile/src/plugins/connection-profiles.ts`).
- **Desktop shell** persists shell settings in app-owned JSON at `app.getPath("userData")/shell-connections.json` (`packages/desktop/src/shell-settings.ts`).
These are shell-owned persistence layers, intentionally separate from Fusion project/global settings.
### High-level runtime diagram
```text

View File

@@ -379,6 +379,12 @@ Click the chevron next to the status indicator to open the node selector dropdow
The selected node persists across browser sessions via localStorage. If the selected remote node is unregistered, the dashboard automatically falls back to local mode.
## Native shell connection flow
If you use Fusion from a native shell (mobile app or desktop shell in remote mode), dashboard startup is gated by shell onboarding until a connection is selected.
For the canonical workflow (first-run onboarding, QR/manual setup, saved profiles, and desktop local/remote handoff), see [Native Shell Connection Guide](./native-shell.md).
## Remote Access (Settings)
Dashboard remote controls live in **Settings → Remote Access**.

95
docs/native-shell.md Normal file
View File

@@ -0,0 +1,95 @@
# Native Shell Connection Guide
[← Docs index](./README.md)
This is the canonical guide for how Fusion native shells (mobile and desktop) connect to remote Fusion dashboards, persist saved connections, and hand off shell state to the dashboard.
## Overview
Native shells expose a shared `window.fusionShell` bridge that the dashboard reads through `ShellContext`.
- **Mobile shell** always runs in remote mode and requires an active connection profile.
- **Desktop shell** supports both **Local Fusion** and **Remote Server** modes.
- **Web/PWA** does not use shell onboarding.
## First-run onboarding flow
The dashboard gates first-run shell onboarding in `requiresNativeShellOnboarding(...)` (`packages/dashboard/app/App.tsx`):
- `host === "mobile-shell"`: onboarding is required until `activeProfileId` is set.
- `host === "desktop-shell"`:
- `desktopMode === "local"`: onboarding is not required.
- `desktopMode === "remote"` (or unset): onboarding is required until `activeProfileId` is set.
`NativeShellOnboardingModal` then provides:
1. **Desktop mode choice** (desktop only):
- **Local Fusion** → calls `setDesktopMode("local")`.
- **Remote Server** → stays in remote flow.
2. **Remote connection entry** (mobile + desktop remote mode):
- **Scan QR** (`startQrScan()`)
- Manual fields: profile name, server URL, optional auth token
3. **Continue**:
- Saves profile via `saveProfile(...)`
- Sets desktop mode to remote when relevant
- Activates profile via `setActiveProfile(...)`
- Redirects to selected remote dashboard URL (adds `rt=<token>` query when token is present)
## QR scan and manual fallback
QR scan is optional convenience. Manual entry is always supported.
QR payload parsing accepts either:
- JSON payload with `serverUrl` and optional `authToken`
- URL payload, reading token from `authToken` or `rt`
If scanning fails or is unavailable, users can continue with manual URL + token entry.
## Saved connection profiles
Profiles are first-class saved objects shared by onboarding and Connection Manager:
- `name`
- `serverUrl`
- optional `authToken`
- timestamps (`createdAt`, `updatedAt`, `lastUsedAt`)
Connection Manager supports:
- **Use** (activate profile)
- **Edit** (update name/URL/token)
- **Delete**
- **Add connection**
Activation updates `activeProfileId` and stamps `lastUsedAt` on the selected profile.
## Desktop remote handoff behavior
Desktop shell stores shell settings separately from Fusion project/global settings.
When desktop mode is `remote` and an active profile exists, `App.tsx` redirects to that profile URL and appends `rt` when a token exists.
When desktop mode is `local` and the local server reports `ready` with a port, `App.tsx` redirects to `http://localhost:<port>`.
## Persistence model
- **Mobile shell**: connection profiles + active profile are persisted through Capacitor Preferences (`packages/mobile/src/plugins/connection-profiles.ts`).
- **Desktop shell**: shell settings are persisted in app-owned JSON at `app.getPath("userData")/shell-connections.json` (`packages/desktop/src/shell-settings.ts`).
## Security guidance
Tokenized URLs and QR payloads are secrets.
- Treat `rt`/`authToken` values like passwords.
- Do not paste tokenized links into chats, screenshots, or tickets.
- Prefer short-lived token workflows when sharing access.
For canonical token caveats and operator guidance, see [Remote Access runbook](./remote-access.md).
## Related docs
- [Dashboard Guide](./dashboard-guide.md)
- [Architecture](./architecture.md)
- [Mobile Development Guide](../MOBILE.md)
- [Remote Access runbook](./remote-access.md)