Skip to content

Commit b96f713

Browse files
akessonclaude
andauthored
Add Windows support and CI (#7)
* Add Windows support via interprocess crate - Replace Unix domain sockets with interprocess local sockets (Unix sockets on Unix, named pipes on Windows) - Add process.rs module for cross-platform process management - Move nix crate to Unix-only, add windows-sys for Windows - Update force_stop() to use platform-specific termination - Document Windows limitation: no graceful shutdown (immediate kill) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add comprehensive test coverage for identified gaps - Add 9 tests for ErrorContextBuffer (circular eviction, cloning, timestamps) - Add 4 process termination tests (SIGTERM→SIGKILL escalation, Windows) - Add 8 integration tests (panic recovery, large output, stale cleanup, stress) - Add 2 version tests (mismatch detection, protocol behavior) - Add Debug derive to TerminateResult for better test output Total test count increased from ~30 to 57 tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add GitHub Actions CI with fmt, clippy, and nextest Runs on Linux, macOS, and Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix clippy warnings and formatting issues - Fix collapsible if statement in client.rs - Use inspect_err instead of map_err in client.rs - Use assert! instead of assert_eq! with bool literal - Remove redundant trim() before split_whitespace() - Use .first() instead of .get(0) - Fix redundant guards in match statements - Apply cargo fmt fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix unused imports on Windows Add #[cfg(unix)] to imports only used on Unix: - bail, Duration, sleep in process.rs - fs in transport.rs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix graceful timeout skipped when < 100ms Use ceiling division so any positive timeout performs at least one iteration before escalating to SIGKILL. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove redundant INVALID_HANDLE_VALUE checks on Windows OpenProcess returns null on failure, not INVALID_HANDLE_VALUE. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add owner-only security descriptor for Windows named pipes Apply SDDL security descriptor D:P(A;;GA;;;OW) to restrict pipe access to the owner only, equivalent to Unix 0o600 socket permissions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix Windows process_exists to check actual process status Use GetExitCodeProcess to verify process is still running, not just that OpenProcess succeeds. Fixes test_terminate_spawned_process_windows which was failing because OpenProcess can succeed on terminated processes during kernel cleanup. Also fix clippy warning by using div_ceil(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fmt * Fix STILL_ACTIVE type mismatch on Windows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Complete test_multiple_commands_same_connection test Actually send a second command and verify the connection is closed, confirming the server's one-shot semantics. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Bump windows-sys to 0.61.2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add cargo-husky for git hooks - pre-commit: runs cargo fmt --check and clippy - pre-push: runs cargo nextest 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Bump version to 0.6.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2b73324 commit b96f713

16 files changed

Lines changed: 1309 additions & 188 deletions

File tree

.cargo-husky/hooks/pre-commit

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
set -e
3+
4+
cargo fmt -- --check
5+
cargo clippy -- -D warnings

.cargo-husky/hooks/pre-push

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
set -e
3+
4+
cargo nextest run

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUSTFLAGS: "-D warnings"
12+
13+
jobs:
14+
fmt:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: dtolnay/rust-toolchain@stable
19+
with:
20+
components: rustfmt
21+
- run: cargo fmt --check
22+
23+
clippy:
24+
strategy:
25+
matrix:
26+
os: [ubuntu-latest, macos-latest, windows-latest]
27+
runs-on: ${{ matrix.os }}
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: dtolnay/rust-toolchain@stable
31+
with:
32+
components: clippy
33+
- uses: Swatinem/rust-cache@v2
34+
- run: cargo clippy --all-targets --all-features -- -D warnings
35+
36+
test:
37+
needs: [fmt, clippy]
38+
strategy:
39+
matrix:
40+
os: [ubuntu-latest, macos-latest, windows-latest]
41+
runs-on: ${{ matrix.os }}
42+
steps:
43+
- uses: actions/checkout@v4
44+
- uses: dtolnay/rust-toolchain@stable
45+
- uses: Swatinem/rust-cache@v2
46+
- uses: taiki-e/install-action@nextest
47+
- run: cargo nextest run --all-features

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/.cache
12
/target
23
Cargo.lock
34

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.6.0] - 2025-11-28
9+
10+
### Added
11+
12+
- Windows support (named pipes, process management)
13+
- Git hooks via cargo-husky (pre-commit: fmt/clippy, pre-push: nextest)
14+
815
## [0.5.0] - 2025-01-23
916

1017
### Added

Cargo.toml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "daemon-cli"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
edition = "2024"
55

66
[dependencies]
@@ -18,12 +18,23 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
1818
parking_lot = "0.12"
1919
terminal_size = "0.4"
2020
supports-color = "3.0"
21+
interprocess = { version = "2.2", features = ["tokio"] }
22+
23+
[target.'cfg(unix)'.dependencies]
2124
nix = { version = "0.30.1", features = ["signal"] }
2225

26+
[target.'cfg(windows)'.dependencies]
27+
windows-sys = { version = "0.61.2", features = [
28+
"Win32_Foundation",
29+
"Win32_System_Threading",
30+
] }
31+
widestring = "1.0"
32+
2333
[[example]]
2434
name = "cli"
2535
path = "examples/cli.rs"
2636

2737
[dev-dependencies]
2838
tokio-test = "0.4"
2939
rand = "0.8"
40+
cargo-husky = { version = "1", default-features = false, features = ["user-hooks"] }

examples/common/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ impl CommandHandler for CommandProcessor {
3030
mut output: impl AsyncWrite + Send + Unpin,
3131
cancel_token: CancellationToken,
3232
) -> Result<i32> {
33-
let parts: Vec<&str> = command.trim().split_whitespace().collect();
33+
let parts: Vec<&str> = command.split_whitespace().collect();
3434

35-
match parts.get(0) {
35+
match parts.first() {
3636
Some(&"status") => {
3737
output.write_all(b"Daemon ready for processing\n").await?;
3838
Ok(0)

examples/concurrent.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ impl CommandHandler for TaskQueueHandler {
8383
});
8484
});
8585

86-
let parts: Vec<&str> = command.trim().split_whitespace().collect();
86+
let parts: Vec<&str> = command.split_whitespace().collect();
8787

88-
match parts.get(0) {
88+
match parts.first() {
8989
Some(&"add-task") => {
9090
let task_description = parts[1..].join(" ");
9191
if task_description.is_empty() {

0 commit comments

Comments
 (0)