diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb78e24..6671d0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,8 @@ jobs: test: # IPC is interprocess::local_socket on every platform (Unix sockets on # Linux/macOS, named pipes on Windows). Signals are cfg-gated so Windows - # gets GenerateConsoleCtrlEvent + TerminateProcess instead of killpg. + # uses ConPTY-input ETX (SIGINT) + taskkill tree-kill (SIGTERM/SIGKILL) + # instead of killpg. name: test (${{ matrix.os }}) runs-on: ${{ matrix.os }} strategy: diff --git a/docs/design/windows-strategy.md b/docs/design/windows-strategy.md index 5a0635c..3c04bb5 100644 --- a/docs/design/windows-strategy.md +++ b/docs/design/windows-strategy.md @@ -9,9 +9,11 @@ ## TL;DR Windows works once we swap three cfg-gated pieces: **IPC** (Unix socket → named -pipe), **signal delivery** (`killpg` → `GenerateConsoleCtrlEvent`/Job Object -termination), and a few **path/comm assumptions**. None require an architecture -change. Estimate: ~2 cycles. +pipe), **signal delivery** (`killpg` → ConPTY-input ETX for SIGINT + +`taskkill /F /T` descendant-tree kill for SIGTERM/SIGKILL — as implemented in +PR #124, superseding the original `GenerateConsoleCtrlEvent`/Job Object plan; +see the signal table in §2), and a few **path/comm assumptions**. None require +an architecture change. Estimate: ~2 cycles. PTY itself isn't a blocker — `portable-pty` already uses ConPTY on Windows. diff --git a/tracker.md b/tracker.md index e0f0245..e3c2a2b 100644 --- a/tracker.md +++ b/tracker.md @@ -38,7 +38,7 @@ Implication: v1 does not have Kitty graphics + Sixel + OSC 8 hyperlinks in the e - **PluginAdapter (sub-process JSON-RPC over stdio)** — Moved to P4 alongside `mcp serve`. Both speak stdio JSON-RPC; build the framework once. - **nvim / tmux built-in adapters** — Will land as external plug-ins via PluginAdapter once #2 ships. Avoids dragging `nvim --headless` / `tmux -CC` into CI. - **wezterm engine real impl** — Blocked on `wezterm-term` being published to crates.io. Track only. -- **Windows runtime — cycle W2 (signal mapping + `.exe` strip in adapter comm + re-enable `windows-latest` in CI).** Cycle W1 (IPC swap to `interprocess`) shipped on all platforms; Windows-specific signal handling (`GenerateConsoleCtrlEvent` / `TerminateProcess` instead of `killpg`) is the next ~80 LOC cycle. See `docs/design/windows-strategy.md` for the full plan. +- **Windows runtime — cycle W2 — SHIPPED (PR #124), with a mechanism change.** Cycle W1 (IPC swap to `interprocess`) shipped on all platforms; W2 landed signal handling as ConPTY-input ETX (SIGINT) + `taskkill /F /T` descendant-tree kill (SIGTERM/SIGKILL) instead of the planned `GenerateConsoleCtrlEvent` (which cannot reach a child on its own pseudoconsole), plus ConPTY DSR render, headless pipe spawn for `run`/`ask`/`edit`, the `run | consumer` handle-inheritance fix, and `windows-latest` in the CI matrix. SIGBREAK/SIGQUIT is rejected honestly (no delivery path). Still open: owner-only DACL on the named pipe, real Ctrl-Break delivery — see `docs/design/windows-strategy.md`. ### P-UX6 — timeout fix + small primitives (this PR)