Windows compatibility pass (beta target)

External editor via cmd/start + exe picker; Permissions hidden for
Windows-local (chmod only flips read-only there); Explorer/Recycle Bin
wording; Ctrl vs Cmd shortcut labels; separator-aware path joins +
drive-root detection; drives list in the panel source picker; icon.ico
+ colored tray icon; icacls ACL on connections.json; README Windows
(beta) section with upstream known issues and a smoke-test checklist.
Runtime paths pending first boot on a real Windows machine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jokin
2026-07-14 00:02:42 +02:00
co-authored by Claude Fable 5
parent d80d5c23dc
commit c7271fb7cf
23 changed files with 223 additions and 57 deletions
+19
View File
@@ -1,4 +1,5 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import type { ConnectionsFile, SavedConnection, Stack } from "../../shared/types";
import { appDataDir } from "./paths";
@@ -68,5 +69,23 @@ export class ConnectionStore {
await fs.writeFile(tmp, JSON.stringify(this.data, null, "\t"), { mode: 0o600 });
await fs.rename(tmp, this.file);
await fs.chmod(this.file, 0o600);
this.restrictOnWindows();
}
/**
* PORTABILITY: 0o600 only toggles the read-only bit on Windows, so the
* plaintext passwords in this file would be world-readable there. Replace
* inheritance with a current-user-only ACL, best effort.
*/
private restrictOnWindows(): void {
if (process.platform !== "win32") return;
try {
Bun.spawn(
["icacls", this.file, "/inheritance:r", "/grant:r", `${os.userInfo().username}:F`],
{ stdout: "ignore", stderr: "ignore" },
);
} catch {
// ACL tooling unavailable — file still works, just unprotected
}
}
}