Skip to content

feat(electron): launch-connection chooser + Windows native build#377

Merged
danshapiro merged 2 commits into
mainfrom
feat/electron-launch-chooser
May 31, 2026
Merged

feat(electron): launch-connection chooser + Windows native build#377
danshapiro merged 2 commits into
mainfrom
feat/electron-launch-chooser

Conversation

@danshapiro
Copy link
Copy Markdown
Owner

Summary

Lands the Electron launch-connection chooser plus the native-Windows build pipeline (the source behind the Windows installer).

  • Launch chooser — a new Electron window that discovers running Freshell servers and lets the user choose how to connect. Backed by an enhanced unauthenticated /api/health (createHealthRouter) reporting instanceId / startedAt / requiresAuth, plus token resolution and an always-ask / one-time launch policy.
  • Windows buildnpm run electron:build:win, guarded by assert-native-windows-build (must run on win32 so node-pty compiles native), producing a one-click NSIS installer (installer.nsh) with a bundled standalone Node runtime and a dedicated launch-chooser Vite bundle.
  • Docsdocs/development/windows-electron-build.md (how to build on native Windows, including the WSL-via-interop recipe) + an AGENTS.md pointer.

Notes

Reconstructed cleanly on top of current origin/main. The original working branch was a stale May-24 tree that also carried work since merged separately (favicon #363, codex runtime-flake #376); that is intentionally not included here. server/index.ts and package.json were 3-way merged so upstream's claude-activity wiring and run-with-default-port dev scripts are preserved.

Test plan

  • npm run typecheck, npm run build:electron, npm run build:launch-chooser — green
  • Coordinated full suite (npm test) — green (incl. new unit coverage for chooser logic/UI, discovery, launch policy, token resolver, icon path, health router, build guard, electron-builder config, prepare-bundled-node)
  • Windows NSIS installer produced & verified out-of-band (bundled node.exe + win32 node-pty + packaged launch-chooser)

🤖 Generated with Claude Code

Adds an Electron launch-connection chooser window that discovers and
probes running Freshell servers via an unauthenticated /api/health
endpoint (now reporting instanceId/startedAt/requiresAuth), with token
resolution and an always-ask/one-time launch policy. Also adds the
native-Windows NSIS build pipeline (electron:build:win) that compiles
node-pty for win32 and bundles a standalone Node runtime.

- electron: launch-chooser window + discovery/policy/token-resolver,
  IPC handlers (get/choose-launch-option), tray icon path helper
- server: extract /api/health into createHealthRouter with launch
  discovery metadata (instanceId, startedAt, requiresAuth)
- build: electron:build:win + assert-native-windows-build guard,
  installer.nsh (NSIS one-click), bundled-node prep (tar/extract-zip),
  build:launch-chooser vite config
- docs: docs/development/windows-electron-build.md + AGENTS.md pointer
- tests: unit coverage for chooser logic, discovery, policy, token
  resolver, icon path, health router, build guard, electron-builder
  config, prepare-bundled-node; e2e-electron smoke

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56e21ca556

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
}

await options.patchDesktopConfig({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor the unchecked Remember choice

When the chooser sends remember: false (the user unchecked “Remember this choice”), this handler still unconditionally writes the selected serverMode, remoteUrl, and remoteToken to desktop.json; the start-local branch likewise persists the local mode. As a result, a one-time connection is saved and can auto-connect on the next launch, and remote tokens are stored despite the user's explicit choice. Gate the config patch on choice.remember or use a transient startup path for one-time launches.

Useful? React with 👍 / 👎.

await chooser.waitForLoadState('domcontentloaded')

await chooser.getByRole('checkbox', { name: 'Always ask on launch' }).uncheck()
await chooser.getByRole('button', { name: 'Connect', exact: true }).first().click()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Query the chooser button by its accessible name

In this flow, the candidate button rendered by LaunchChooser has an aria-label like Connect to localhost:3001, and ARIA labels override the visible text for role queries. With exact: true, this locator looks for the accessible name Connect, so the new e2e fails before it can exercise connecting from the chooser; query the actual accessible name or avoid the exact visible-text match.

Useful? React with 👍 / 👎.

The launch-chooser/Windows-build tests assumed POSIX path separators and
LF line endings, so they failed on the windows-latest CI runner (this
feature's first run on Windows):

- startup + prepare-bundled-node: assert against path.join() output
  (OS-native separators) instead of hardcoded '/', and normalize
  separators where only path structure matters
- electron-builder-config: normalize CRLF -> LF before regex/content
  assertions (a Windows checkout may convert the LF repo files)

Production code is unchanged; path.join output is correct on each host.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@danshapiro danshapiro merged commit 08a5c8d into main May 31, 2026
1 of 4 checks passed
@danshapiro danshapiro deleted the feat/electron-launch-chooser branch May 31, 2026 00:50
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.

2 participants