# Salesforce CLI Org Launcher

Salesforce CLI Org Launcher is a Manifest V3 Chromium extension backed by a Node.js native messaging host. It groups Salesforce CLI authenticated orgs by local project instead of by org type so you can jump into the right environment faster.

Crafted with ❤️ by [Kiran Markad](https://www.linkedin.com/in/kiranmarkad).

## Highlights

- Project-first launcher UI with search, favorites, and collapsible groups
- Custom saved org groups that persist between extension opens
- Native integration with `sf` and `sfdx`
- Configurable project roots and cache duration
- Theme support for light, dark, and system
- One-click `sf org open --url-only` launch

## Project Structure

- `extension/`: popup UI and background service worker
- `native-host/`: Node native messaging host
- `scripts/`: build and install helpers
- `dist/`: generated artifacts for Chrome and native host install

## Local Development

```bash
npm install
npm run build
```

Load the unpacked extension from:

```text
/Users/kiranmarkad/Desktop/SalesforceOrgLauncher/dist/extension
```

If Chrome's folder picker selects the parent build folder, `/Users/kiranmarkad/Desktop/SalesforceOrgLauncher/dist` is also generated as a valid unpacked extension root.

## Native Host Install

1. Build the project.
2. Load the unpacked extension once in Chrome and copy the extension ID.
3. Install the native host manifest:

```bash
CHROME_EXTENSION_ID=<your_extension_id> npm run install:native:mac
```

The current unpacked build uses a stable manifest key, so its extension ID resolves to:

```text
kanjinfiojebibldeeajnbmgjmdipjjn
```

The script writes the manifest to:

```text
~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.kiran.salesforce_org_launcher.json
```

The installer copies the native host runtime into the user's app-data folder and points Chrome's native messaging manifest there. This keeps the helper independent of the unzipped package location and avoids repeatedly launching the helper from protected folders such as Desktop. The installer also records the target machine's Node.js executable in `node-path.txt`, which avoids Chrome native messaging failures caused by a missing shell `PATH`.

## Portable Release Package

Build a shareable package for macOS, Windows, and Linux:

```bash
npm run package
```

Generated files:

```text
release/SalesforceOrgLauncher-chrome-web-store.zip
release/SalesforceOrgLauncher-webstore-assets.zip
release/SalesforceOrgLauncher-portable-mac-windows-linux.zip
release/SalesforceOrgLauncher-extension-unpacked.zip
```

Upload `release/SalesforceOrgLauncher-chrome-web-store.zip` to the Chrome Web Store Developer Dashboard.
Use `release/SalesforceOrgLauncher-webstore-assets.zip` for screenshots, listing copy, privacy policy draft, and reviewer notes.

Send `SalesforceOrgLauncher-portable-mac-windows-linux.zip` to another machine. After unzipping:

- Load the `extension` folder from `chrome://extensions` with Developer mode enabled.
- Run `./install-mac-linux.sh` on macOS/Linux.
- Run `powershell -ExecutionPolicy Bypass -File .\install-windows.ps1` on Windows.

On macOS, if a user adds Desktop, Documents, Downloads, or another protected folder as a project root, macOS may ask for folder access the first time the native helper scans that root. The popup loads cached org data on open and only rescans local project folders when the user clicks **Refresh** or saves changed roots.

The extension folder is the practical packed artifact for side-loading. A Chrome Web Store-style `.crx` can be produced later for managed distribution, but native messaging still requires the OS installer because Chrome requires a registered native host on every machine.

See `docs/CHROME_WEB_STORE.md` for the full publish flow.

## Public Service Worker Documentation Repository

Only the service worker source and documentation are intended to be public on GitHub.

Local public-ready repository:

```text
/Users/kiranmarkad/Desktop/salesforce-cli-org-launcher-service-worker
```

Recommended public GitHub repository:

```text
salesforce-cli-org-launcher-service-worker
```

Recommended repository protections:

- Keep the repository public for transparency.
- Protect the `main` branch.
- Require pull requests before merging into `main`.
- Do not grant write access to untrusted users.

The full extension application source, popup UI, and native host implementation should remain private unless you decide otherwise later.

The privacy policy can be hosted with GitHub Pages from:

```text
docs/privacy-policy.html
```

See `docs/PRIVACY_POLICY_HOSTING.md`.

## Testing

Run a quick host smoke test:

```bash
npm run test:smoke
```

Then validate in Chrome:

1. Open `chrome://extensions`
2. Enable Developer mode
3. Load unpacked from `dist/extension`
4. Open the extension popup
5. Install the native host using the real extension ID
6. Click Refresh and open an org

## Notes

- Project matching currently prioritizes each project's configured `target-org`, then falls back to project-name matching against org metadata.
- The org list uses Salesforce CLI's fast local list mode. If an org has an expired session, the launcher shows a clear re-authorization message when the user clicks Open.
- Windows support is handled by the PowerShell installer, which writes the required HKCU native messaging registry key.
