Write all path variants for every .json in the bundle when building
for win32 (backslash, with/without leading slash) so bundle.read()
returns content regardless of runtime key normalization. Refill empty
or invalid JSON from alternate key or disk before writing variants.
Explicitly write tt-native package.json under Windows path variants
in Fix 1. Document in CHANGELOG.
Use forward-slash addon resolution key for all platforms in the
distributable build so the runtime finds the tt-native prebuild when
the bundle normalizes paths on Windows. Update CHANGELOG and
CONTRIBUTING to document the fix.
After unmount, the runtime may resolve #package with or without a
leading slash. Write the same content to both keys so the .json
loader never gets an empty entry and the host no longer crashes with
"Unexpected end of JSON input" on Windows.
patchBundle so the runtime never gets empty content for that key
(fixes "Unexpected end of JSON input" in Module._extensions..json
when the host is started by the extension on Windows).
- State: treat empty or whitespace-only state.json (and legacy
persist file) as missing and return default state instead of
throwing in JSON.parse.
- State: add ensureStorageDir() and call it from message-router
after setStoragePath so the storage directory exists on fresh
install before any state is loaded or saved.
- SECURITY.md: Note that we install to system store and run
update-ca-certificates; add that Chrome/Firefox may not use it.
- Add step-by-step instructions to manually import the CA into
Chrome/Chromium and Firefox on Linux (path to ca.cert.pem).
- INSTALLATION.md: In first-time setup, add Linux note and link
to SECURITY.md for manual import.
- Replace sudo with pkexec so PolicyKit shows a graphical auth dialog
when the native host is launched by the browser (no terminal).
- Pass DISPLAY and XAUTHORITY into the pkexec env so the polkit
agent can display the dialog in the current session.
- Keep copy + update-ca-certificates in a single pkexec sh -c for
one password prompt.
- Update SECURITY.md and JSDoc to describe pkexec / PolicyKit.
When building with --all, the bundle used a single addon resolution (darwin-arm64),
so the Linux binary tried to load the wrong prebuild and tt-native failed. Patch
tt-native binding with a nested resolution map (addon → bare → node → platform →
arch) so the runtime selects the correct prebuild per platform; SSH PTY then works
on Linux.
- scripts/build-distributable.js: build host-specific addonResolutions, write
binding with full map; update comments
- docs/ARCHITECTURE.md, CONTRIBUTING.md: document addon resolution patch
- CHANGELOG.md: add entry under bug fixes
When building with --all, the bundle used a single addon resolution (darwin-arm64),
so the Linux binary tried to load the wrong prebuild and tt-native failed. Patch
tt-native binding with a nested resolution map (addon → bare → node → platform →
arch) so the runtime selects the correct prebuild per platform; SSH PTY then works
on Linux.
- Move connect-proxy and https-proxy into proxy/
- Move certificate-authority, backup-manager, ssh-manager, rdp-manager into managers/
- Move messenger.js into host/
- Move test-dirname.cjs into test/
- Update imports, CI lint paths, and ARCHITECTURE.md
- Import host/message-router.js and holesail-manager/index.js directly
- Delete host.js and holesail-manager.js
- Drop shim entries from CI syntax checks
- Update ARCHITECTURE.md diagram and file table
- Add "Use TLS (secure connection)" checkbox in Add Virtual Host modal
- Persist and restore useTls in state; show TLS badge in table
- When enabled, HTTPS proxy connects to tunnel backend over TLS (SNI =
hostname) for HTTP and WebSocket; supports services on port 443
- CHANGELOG: add Firefox support subsection (manifest_firefox, background
scripts, proxy/native-messaging/CSP, installer, pack, extension-id)
- CONTRIBUTING: repo layout with background-boot/main, Firefox load steps
and private-windows note, install.sh Chrome vs Firefox manifests,
DEBUG_VERBOSE in background-boot.js
- ARCHITECTURE: manifest.json vs manifest_firefox.json, background.js
importScripts, background-boot/main and proxy/native-messaging notes,
native host lifecycle and separate manifests
- INSTALLATION: allowed_origins vs allowed_extensions, Allow in Private
Windows for Firefox, extension ID updates both manifests
- SECURITY: PAC scope Chrome vs Firefox (autoConfig/data URL), proxy
security and private-windows requirement
Firefox's default MV3 CSP includes upgrade-insecure-requests, which upgrades
ws://127.0.0.1 to wss:// and breaks SSH/RDP WebSocket connections to the
local native host. Add explicit content_security_policy to manifest_firefox.json
allowing ws://127.0.0.1:* and http://127.0.0.1:* on extension pages.
- Firefox rejects native messaging manifest if allowed_origins is present.
Install script now writes Chrome-only manifest (allowed_origins) and
Firefox-only manifest (allowed_extensions) to their respective locations.
- Fix local Firefox manifest by removing allowed_origins.
- Log disconnect reason from port.error (Firefox) in addition to
runtime.lastError (Chrome) so native messaging failures are visible.
- Log getState failures on disconnect for easier debugging.
- Treat PAC as active when mode === 'pac_script' (Chrome) or proxyType ===
'autoConfig' (Firefox) so we don't mis-detect "not active" in Firefox.
- In proxy.settings.onChange, only call applyPAC() when levelOfControl !==
'controlled_by_this_extension'. When we still have control, return without
re-applying to stop the set -> onChange -> applyPAC loop.
Firefox's match pattern validator does not allow the moz-extension:// scheme
in matches. Use extension_ids: ["*"] so extension pages can load the
resources without invalid manifest error.
Firefox MV3 does not support background.service_worker. Split background
into background-boot.js (globals) and background-main.js (startup logic);
Chrome keeps using importScripts() in background.js, Firefox manifest uses
background.scripts with the same file list so the extension loads in both.
- Add extension/manifest_firefox.json (no key, moz-extension://*/* for
web_accessible_resources) for correct Firefox MV3 behavior
- Update pack-extension.js: zip excludes manifest_firefox.json; XPI
built separately with manifest_firefox.json as manifest.json
- Update generate-extension-id.js to set gecko.id in manifest_firefox.json
when present (no key in Firefox manifest)
- Document dual-manifest layout and pack/generate-id behavior in CONTRIBUTING.md
Use var(--bg) for btn-primary text color and color-mix for hover to
correctly adapt across themes. Add --terminal-bg CSS variable and
_getXtermTheme() helper so the SSH terminal picks up the correct
palette at connection time.
Normalize loadAvg to [0,0,0] fallback in both the native host handler
and the dashboard renderer to prevent TypeError when bare-node-os returns
a non-array value for loadavg().
- Add getProcessStats message handler to native host returning process
memory (rss, heap used/total, external), PID, uptime, OS memory,
CPU load averages, core count, platform/arch, and tunnel state counts
- Add stats-tracker.js to background SW tracking cumulative connections,
reconnect count, last disconnect time, and per-minute connection rate
ring buffer (30 buckets) for sparkline display
- Include statsHistory and activeConnections array in all getState responses
- Add Statistics dashboard page with six sections: Native Host Process,
System Resources, Tunnel Health, Proxy Traffic, Peer Connections
(with SVG sparkline), and Extension & Proxy Info
- Preserve checkbox selection across table re-renders on all bulk-action
tables (virtual hosts, servers, service tunnels)
- Add theme-aware custom checkbox styling for bulk selection rows using
design system tokens, with white checkmark override for light theme
Replace native browser checkbox appearance on table row and select-all
checkboxes with fully custom styled controls using design system tokens,
with a white checkmark override for the light theme's darker cyan.