mirror of
https://github.com/dohooo/helmor.git
synced 2026-09-22 16:40:02 +08:00
6cea31b094
* feat(win): platform layer + cross-platform process/PTY/fs/limits
- Add platform/ module (process group via taskkill, fs symlink-or-copy)
- Migrate sidecar, tunnel, git/ops, shell_env, runtime_registry to platform::process
- Rewrite workspace/scripts.rs PTY terminal on portable-pty (Unix+ConPTY); PowerShell shell on Windows
- cfg-gate libc to unix; add windows + uds_windows + portable-pty deps
- system_limits: _setmaxstdio on Windows; helpers: cross-platform symlink
- boring-sys2 Release CRT override (fixes MSVC debug-CRT link mismatch)
- Windows icon.ico + Store/Square logos for tauri-build resource
* feat(win): Phase 4 parity + clippy-clean
- UI-sync over AF_UNIX (uds_windows); GlobalMemoryStatusEx RAM; Claude creds from ~/.claude/.credentials.json
- gate macOS-only menu IDs / applescript / editor bundle_ids; module-level allow for macOS-only Slack scraper
- drop unneeded portable_pty trait imports; restore too_many_arguments allows
* fix(win): resolve home dir via USERPROFILE when HOME is unset
The Tauri setup hook panicked with 'Could not determine home directory' on
Windows because data_dir only consulted $HOME. Fall back to USERPROFILE then
HOMEDRIVE+HOMEPATH on Windows. Verified: the app window now launches.
* fix(win): skip login-shell PATH capture on Windows (no-op)
Windows GUI processes inherit the full user/system PATH from the registry, so
the macOS/Linux login-shell env capture (which tried to spawn /bin/zsh) is
unnecessary and was erroring. Gate the unix capture module + call to cfg(unix);
gate the now-Windows-unused codex_config::declared_env_keys lint accordingly.
* feat(win): Windows vendor-CLI staging + codex config home
- stage-vendor.ts: detect win32, stage claude-code/codex/opencode from the
installed win32-x64 sub-packages, download gh/glab/cloudflared/llama win
artifacts; cross-platform sha256 (node crypto), tar -xf for zip+tgz, .exe
naming, codex codex-resources copied adjacent, soft-verify unpinned hashes,
optional stagers non-fatal on Windows. Verified: all 7 components staged.
- codex_config: resolve ~/.codex via USERPROFILE on Windows (match codex)
- stage-dev-cli.mjs: append .exe to staged helmor-cli triple name on Windows
* fix(win): helmor-cli .exe, npx via cmd /c, agent CLI PATHEXT lookup
- cli_source_binary_name + agent_invocation_path use helmor-cli.exe on Windows
- install_helmor_skills / install_skills_silent spawn npx through cmd /c
(npm ships npx.cmd/.ps1, not npx.exe — Command::new("npx") fails)
- resolve_agent_binary falls back to a PATH+PATHEXT lookup on Windows so a
bare 'codex'/'claude' resolves to codex.cmd/.exe instead of program-not-found
Fixes the 'Helmor CLI' and 'Helmor Skills (Beta)' error cards on Windows.
* fix(win): PowerShell-correct agent/forge login boot commands
The onboarding login terminals run PowerShell on Windows, where a quoted exe
path is a string literal — executing it needs the call operator '&'. Add
scripts::format_boot_command (& <cmd>; exit on Windows) and use it for the
claude/codex/opencode and gh/glab auth terminals. Also make which_on_path skip
extensionless npm shims so 'claude' resolves to claude.exe/.cmd, not the Unix
bash shim.
Fixes 'Unexpected token auth' ParserError on Windows login.
* fix(win): centralize home-dir resolution (platform::home_dir)
Many features read $HOME directly and broke on Windows GUI processes (no HOME):
opencode config ('HOME is not set' error spam), claude project files, codex
rate-limits, glab config, cloudflared dir, and the agent/forge login working
dir. Add platform::home_dir (HOME -> USERPROFILE -> HOMEDRIVE+HOMEPATH) and
route these through it.
* fix(win): resolve bun + agent CLIs via PATHEXT (platform::which)
The dev sidecar spawn used Command::new("bun"), which fails on Windows because
bun on PATH is a .cmd/.ps1 shim and CreateProcess ignores PATHEXT ('Failed to
start sidecar — is Bun installed?'). Add platform::which (PATHEXT-aware) and use
it for the bun spawn; dedupe resolve_agent_binary onto it too.
* build(win): NSIS installer bundle config
- tauri.conf bundle.windows with NSIS current-user install + icon.ico
- disable createUpdaterArtifacts (local installer doesn't sign update artifacts)
- prepare-sidecar.mjs stages helmor-sidecar/helmor-cli with the .exe + triple
suffix Tauri's externalBin expects on Windows
Produces Helmor_<ver>_x64-setup.exe bundling the sidecar + claude/codex/gh/glab/
cloudflared/llama binaries.
* fix(windows): hide child-process consoles, resolve bundled CLIs, install CLI shim
Three Windows-port fixes driven by first real-device testing:
- Spawned CLIs (git, gh/glab polls, claude probes, taskkill, tunnels...)
flashed a console window on every invocation. Worse, each console stole
focus from the main window, so `refetchOnWindowFocus: "always"` auth
probes re-fired the moment it closed - a self-sustaining ~1/s terminal
strobe loop. New `platform::process::hide_console` (+`_tokio`) helpers
apply CREATE_NO_WINDOW at every one-shot spawn site; long-lived children
were already covered by `configure_new_group`.
- Bundled gh/glab resolution assumed the macOS Contents/Resources bundle
layout, so the installed Windows app fell back to PATH (and errored once
per probe on missing glab). `forge::bundled` now probes both the
exe-adjacent layout (NSIS/MSI) and Contents/Resources (macOS).
- `install_cli` bailed with "symlink only supported on Unix". Windows now
installs a `.cmd` shim in %LOCALAPPDATA%\Helmor\bin forwarding to the
bundled helmor-cli.exe, registers that dir on the user PATH
(HKCU\Environment, REG_EXPAND_SZ-preserving, WM_SETTINGCHANGE broadcast),
and classifies Managed/Stale by parsing the shim target.
Also makes the Rust test suite buildable and runnable on Windows for the
first time: cfg-gates unix/mac-only tests, and embeds a common-controls v6
app manifest into every linked target via build.rs (tauri-build switched to
new_without_app_manifest) - without it each test exe died at startup with
STATUS_ENTRYPOINT_NOT_FOUND because TaskDialogIndirect needs comctl32 v6.
Verified: clippy --all-targets -D warnings clean; all 11 integration test
targets pass; changed-module unit tests pass (23 pre-existing lib-test
failures remain in unrelated areas, first time the suite has run on
Windows).
* fix(windows): hide consoles for agent probes and npx skills installer
Follow-up to e27a9323: the spawn sites in commands/system_commands.rs were
left out of the hide_console sweep. They are the most visible offenders -
agent version probes (claude/codex/opencode --version), claude/codex login
status checks, and the `cmd /c npx` skills installer that the silent
startup update check runs - each flashed a console window from the GUI
process on launch and whenever Settings opened.
* fix(windows): resolve bundled agent binaries via exe-adjacent layout
The sidecar boot path resolved bundled claude/codex/opencode binaries only
under the macOS Contents/Resources layout, so on Windows (NSIS/MSI, vendor/
next to the exe) claude_bin came back None and HELMOR_CLAUDE_CODE_BIN_PATH
was never set. The sidecar's own resolveClaudeBinPath then threw at module
load (require.resolve always fails inside a bun --compile binary), killing
the process with "Invalid sidecar ready signal".
- sidecar.rs: probe both exe-adjacent (Windows) and Contents/Resources
(macOS) roots, mirroring forge::bundled.
- claude-session-manager.ts: resolveClaudeBinPath returns undefined instead
of throwing when nothing resolves, scoping any failure to a single Claude
session and letting the SDK attempt its own resolution.
* fix(windows): green the Windows CI jobs
- build.rs: append `.exe` to the externalBin placeholders on Windows so a
clean checkout doesn't panic in tauri-build ("resource path …-msvc.exe
doesn't exist") before prepare-sidecar.mjs produces the real artifacts.
Unblocks both the Build and Rust Test jobs.
- stage-vendor.ts: extract via the Windows in-box bsdtar (System32\tar.exe)
instead of a bare `tar`, which under the CI bash shell resolves to Git's
GNU tar and reads the `D:` drive in an archive path as an rsh host
("Cannot connect to D: resolve failed"), silently skipping gh/glab/llama.
- codex-app-server-manager.test.ts: the global `mock.module` for git-access
leaked into git-access.test.ts (file order is filesystem-dependent, so it
only bit on Windows); the stub now delegates to the real module unless a
codex test is actively driving it.
* fix(windows): resolve remaining Windows CI test + setup failures
- repos: normalize repo paths with dunce::canonicalize (strips the Windows
`\\?\` verbatim prefix) and route git --show-toplevel through the same
normalizer + OS-native separators, so repo dedup and clone-target detection
compare equal for the same directory. Fixes the duplicate-repo and
clone_from_url failures on Windows. Also split repo-name inference on `\`.
- cli/image_store/workspaces tests: assert against the platform path shape
(`helmor-cli.exe`, separator-agnostic) instead of hardcoded `/` forms.
- rate_limits::claude::process tests: gate to unix (they spawn /bin/echo etc.).
- setup-js: add an install-sccache input (default true); the Windows jobs opt
out since they don't use sccache and its installer is flaky on Windows.
* fix(windows): keep updater artifacts on macOS, disable only on Windows
createUpdaterArtifacts was flipped to false on the branch so the keyless NSIS
build wouldn't try to sign an updater artifact — but that's a global flag, so
it also disabled macOS auto-update and broke the build-platform boundary test
(which asserts the base config is unchanged). Restore the base to true and move
the Windows-only opt-out into tauri.windows.conf.json, which Tauri merges over
the base for Windows builds.
* fix(windows): use platform Pid type in runtime registry liveness probe
probe_pid_alive cast the pid to u32, which only matches platform::process::Pid
on Windows; on macOS Pid is i32, so the lib failed to compile there (E0308),
taking down the macOS Rust Test and Lint jobs. Cast to the platform Pid alias
so it builds on both.
* test(windows): gate macOS-only CLI permission-denied test
try_install_cli_silent_at_bails_with_friendly_message_on_permission_denied
probes /usr/local/bin and asserts the macOS sudo elevation message. On the
Windows CI runner the /usr/local/bin write fails differently (so the test's
writable-skip guard doesn't trigger) and the Windows shim install produces a
different error, failing the assertion. Windows installs a .cmd shim with no
elevation flow, so gate the test to macOS.
* fix(windows): re-hide console for git and cloudflared spawns
The #747 merge took theirs for git/ops.rs and companion/tunnel.rs and dropped
the configure_background_cli wraps windows-port had at those spawn sites,
which re-introduced the terminal-flashing loop: git status / git diff /
git stash pop polls and cloudflared tunnel create/delete each popped a
console window. Re-wrap them via configure_background_cli (CREATE_NO_WINDOW
on Windows, no-op on Unix).
* ci(windows): override checked-in sccache rustc-wrapper for Windows jobs
src-tauri/.cargo/config.toml sets rustc-wrapper = "sccache" so the macOS
jobs (setup-rust-tauri installs sccache) pick it up. The Windows jobs opt
out of installing sccache, so cargo fails immediately:
error: could not execute process `sccache rustc.exe -vV` (never executed)
Set RUSTC_WRAPPER="" at the job level for Windows Rust Test + Build to
override the file config. The macOS Typecheck flake (curl 504 fetching
sccache) is unrelated install-action infra and will recover on rerun.
* test(windows): normalize repo paths in fixture-db inserts so dedup matches
The test harness was storing the raw temp-dir path in repos.root_path while
production goes through normalize_filesystem_path (dunce::canonicalize). My
machine and the CI Windows runner disagree on what dunce returns for the
runner's temp paths, so the lookup misses and a duplicate repo gets created,
failing add_repository_from_local_path_focuses_existing_workspace_for_duplicate_repo
and add_repository_from_local_path_re_add_with_only_archived_workspaces_lands_on_start.
Route the harness inserts through the same normalizer so stored == lookup on
both platforms.
* test: assert against canonicalized repo root in workspace_creation tests
Sibling fix to e1bd54b5 (harness now stores repos.root_path via
normalize_filesystem_path so dedup matches on Windows CI). Two prepare/finalize
assertions still compared response.working_directory against the raw
harness.source_repo_root, which on macOS broke because canonicalize resolves
/var → /private/var. Compare against the canonicalized form on both sides so
the test passes uniformly.
---------
Co-authored-by: Qui Luong <jerry.luong.94@gmail.com>
Co-authored-by: Caspian 東澔 <caspian.zhao@outlook.com>