One click. Browser opens. You're in.
A lightweight desktop app for managing and launching multiple Microsoft 365 test accounts. Click an account card, the browser opens with auto-login, and you land on Copilot Chat (or any M365 destination). The app sits in the system tray and stays out of the way.
You manage ~20 M365 test accounts across different license tiers and roles. Every day you need to log in and out of these accounts repeatedly. Navigating to the login page, entering credentials, handling redirects, clicking "Stay signed in?" — it's tedious and error-prone.
One app. One click. The browser opens, logs in, and lands on the right page.
How it works
- You click an account card
- Playwright launches Chrome/Edge with an isolated profile directory
- Navigates to your configured destination URL
- Detects the login scenario (already logged in? login form? account picker?)
- Fills credentials automatically if needed
- Disconnects — the browser stays open as a normal window
- Next time, the session may still be valid — instant launch, no login needed
- One-click launch — click a card, browser opens, you're logged in
- Isolated browser profiles — each account gets its own sandboxed session via
--user-data-dir - Session persistence — cookies persist between launches; valid sessions skip login entirely
- Simultaneous sessions — multiple accounts open side by side in separate windows
- Configurable browser — Google Chrome or Microsoft Edge, switchable in Settings
- Configurable destinations — Copilot Chat, M365 Admin Center, or any URL
- Dark / Light / System theme — three-way toggle, follows OS preference
- Grouped accounts — organize by role, team, or license tier with color-coded groups
- Search & filter — find accounts instantly across labels, usernames, groups, and destinations
- System tray — close the window, app stays running; click tray icon to reopen
- CSV import/export — bulk import accounts from CSV with preview screen, conflict detection, and defaults; export with optional password inclusion
- Auto-update — checks GitHub Releases on launch; download and install updates from within the app, or via tray menu
- In-app help — Help tab in Settings with quick start, CSV guide, troubleshooting
- Send Logs — one-click email of recent app logs for troubleshooting (Settings > General)
- Cross-platform — runs on macOS and Windows
- Encrypted credentials — passwords encrypted via OS keychain (Electron safeStorage), never in the renderer process
- No admin rights — per-user install, user-writable paths only
| Light | Dark |
|---|---|
![]() |
![]() |
| Accounts | Destinations | General |
|---|---|---|
![]() |
![]() |
![]() |
| Add Account | Edit Account | Add Destination |
|---|---|---|
![]() |
![]() |
![]() |
New to the app? See the User Guide for step-by-step setup and onboarding instructions.
CSV Import: Download the sample CSV template to get started with bulk account import.
- Node.js 18+
- Google Chrome or Microsoft Edge installed
- npm (comes with Node.js)
git clone https://github.com/nikhilsi/copilots-launchpad.git
cd copilots-launchpad
npm install
npm run devThis starts Vite (React dev server) and Electron concurrently with hot reload.
# macOS (.dmg)
npm run dist:mac
# Windows (.exe — NSIS installer)
npm run dist:winOutput goes to dist/. The Windows build can be cross-compiled from macOS.
macOS: Open the .dmg, drag to Applications.
Windows: Run the .exe installer — Next, Next, Finish. No admin rights needed (installs to user directory).
First launch:
- App opens to Settings (no accounts yet)
- Add one or more destinations (e.g., "Copilot Chat" →
https://m365.cloud.microsoft/chat) - Add accounts with credentials, assign each to a destination
- Go back to Launcher — click any card to launch
┌─────────────────────────────────────────────┐
│ Renderer Process (React + Tailwind) │
│ ┌─────────┐ ┌──────────┐ ┌───────────┐ │
│ │Launcher │ │ Settings │ │ Modals │ │
│ └────┬────┘ └────┬─────┘ └─────┬─────┘ │
│ │ │ │ │
│ └────────────┼──────────────┘ │
│ │ IPC (contextBridge) │
├────────────────────┼────────────────────────┤
│ Main Process │ (Electron + Node.js) │
│ ┌─────────┐ ┌────┴─────┐ ┌───────────┐ │
│ │ Tray │ │IPC Router│ │ Launcher │ │
│ └─────────┘ └────┬─────┘ │(Playwright)│ │
│ │ └───────────┘ │
│ ┌────┴─────┐ │
│ │ Store │ │
│ │(encrypted)│ │
│ └──────────┘ │
└─────────────────────────────────────────────┘
| Component | Technology |
|---|---|
| App shell | Electron |
| UI | React + Tailwind CSS |
| Browser automation | playwright-core |
| Credential storage | Electron safeStorage (OS keychain) |
| Data persistence | electron-store |
| Auto-update | electron-updater (GitHub Releases) |
| Code signing (Windows) | Azure Trusted Signing |
| Packaging | electron-builder |
| Platforms | macOS, Windows |
| Browsers | Google Chrome, Microsoft Edge |
copilots-launchpad/
├── electron/
│ ├── main.js # Window, tray, IPC handlers, input validation
│ ├── preload.js # Context bridge (renderer ↔ main)
│ ├── store.js # Encrypted CRUD for accounts, destinations, settings
│ ├── launcher.js # Playwright login flow, profile management
│ ├── updater.js # Auto-updater (checks GitHub Releases)
│ └── logger.js # In-memory ring buffer for troubleshooting logs
├── src/
│ ├── App.jsx # Root component, view routing
│ ├── pages/ # Launcher, Settings
│ ├── components/ # AccountCard, GroupSection, Modals, ThemeToggle, etc.
│ ├── hooks/ # useAccounts, useDestinations, useTheme
│ └── styles/ # Tailwind imports
├── assets/ # App icons (ico, png, tray)
├── docs/ # Design spec, UI prototype
├── LICENSE # MIT
├── electron-builder.yml
└── package.json
| Concern | Approach |
|---|---|
| Credentials at rest | Encrypted via Electron's safeStorage API (OS keychain — Keychain on macOS, DPAPI on Windows) |
| Credentials in memory | Passwords never sent to renderer process in list responses; cleared from React state after save |
| IPC boundary | All inputs validated in main process (types, required fields, URL scheme whitelist, color format) |
| Browser profiles | Isolated via --user-data-dir; path components sanitized against traversal |
| Content Security Policy | Enforced in production: script-src 'self', object-src 'none', frame-ancestors 'none' |
| Electron hardening | contextIsolation: true, nodeIntegration: false, sandbox: true |
| Destination URLs | Must be http:// or https:// (blocks file://, javascript:, etc.) |
| Code signing | Windows .exe signed via Azure Trusted Signing (Public Trust certificate, verified publisher) |
| Admin rights | Not required — per-user install, user-writable paths only |
Important: This app is designed for test environments with MFA disabled. It does not handle MFA prompts.
Each account gets its own isolated browser profile directory, namespaced by browser:
<app-data>/copilots-launchpad/profiles/
├── chrome/
│ ├── acc-01/ # Chrome session data for account 1
│ └── acc-02/
└── msedge/
├── acc-01/ # Edge session data for account 1
└── acc-02/
These are not visible in the browser's profile picker. They're invisible sandboxes managed entirely by the app. Switching browsers requires a fresh login (cookies are encrypted per-browser and not portable).
Profiles are created on first launch and deleted when an account is removed (across all browsers).
After navigating to the destination URL, the app detects the scenario using sequential priority checks:
| Scenario | Detection | Action |
|---|---|---|
| Sign-in button | Destination page has a "Sign in" button | Click it, then re-detect |
| Login required | input[name="loginfmt"] visible |
Fill username → Next → password → Sign In → "Stay signed in?" → Yes |
| Account picker | Existing accounts listed with "Use another account" | Click matching account tile (→ password only) or "Use another account" (→ full login) |
| Password only | input[name="passwd"] visible (user already known) |
Fill password → Sign In → "Stay signed in?" → Yes |
| Session alive | No login elements, not on login domain | Done — status turns green |
Each step has a 30-second timeout. On failure, the card shows a red error dot.
After login completes, Playwright disconnects. The browser stays open as a normal window under your control.
| Setting | Location | Default |
|---|---|---|
| Browser | Settings → General | Chrome (macOS), Edge (Windows) |
| Theme | Toggle in top bar | System |
| Accounts | Settings → Accounts | — |
| Destinations | Settings → Destinations | — |
All settings are stored locally in <app-data>/copilots-launchpad/config.json.
npm run dev # Start dev server + Electron (hot reload)
npm run build # Build React production bundle
npm run dist:mac # Package macOS .dmg
npm run dist:win # Package Windows .exe (NSIS)macOS note: The first time you launch a browser via the app, macOS may ask for Automation permission (System Settings → Privacy & Security → Automation). This is a dev-only concern — packaged apps request their own permission.








