Skip to content

Windows: full test suite + gate auto-discovery for local MCP#54

Open
mind6 wants to merge 5 commits into
kahliburke:2.0-integrationfrom
mind6:2.0-integration
Open

Windows: full test suite + gate auto-discovery for local MCP#54
mind6 wants to merge 5 commits into
kahliburke:2.0-integrationfrom
mind6:2.0-integration

Conversation

@mind6

@mind6 mind6 commented Jun 21, 2026

Copy link
Copy Markdown

Summary

Windows is now usable end-to-end: the full test suite passes, and a local gate REPL is discoverable by a Kaimon MCP server (including Cursor).

Tests (914 passing on Windows / Julia 1.12.6)

  • Gate and service-endpoint subprocess tests use mode=:tcp instead of unsupported ipc://
  • ZMQ socket stress test scaled down to avoid EMFILE on Windows handle limits
  • Config tests use JSON.json(...) so paths like D:\Temp\... are not corrupted
  • Portable subprocess sleep via julia -e sleep(...) instead of Unix sleep
  • Expanded test/Project.toml for julia --project=test

Production: Windows gate auto-discovery

  • serve() defaults to TCP on Windows; localhost gates write sock metadata for file-based discovery
  • Escape backslashes in gate session JSON (project_path was invalid JSON and got deleted on parse)
  • Fix _is_pid_alive on Windows (ps unavailable; trust uv_kill)
  • Discover localhost TCP gates in discover_sessions (skip tcp-* poll bookkeeping only)
  • Align XDG_CACHE_HOME handling between gate and server cache dirs

Manually verified operational flow

  1. Gate REPL: using Kaimon; Kaimon.KaimonGate.serve() → binds tcp://127.0.0.1:<ephemeral> and writes %LOCALAPPDATA%\Kaimon\sock\<session>.json
  2. Server REPL: Kaimon.start!() → ConnectionManager discovers the gate from that sock dir
  3. Cursor MCP: ~/.cursor/mcp.jsonhttp://localhost:<port>/mcp (lax mode, no auth header)
  4. ex tool evaluates code in the connected gate REPL (e.g. df.dates[end]2020-03-31)

Test plan

  • julia --project=test test/runtests.jl — 914 passed on Windows
  • Pkg.test() in lib/KaimonGate — passing (3 IPC-only tests skipped on Windows)
  • Two-REPL flow: serve() + start!(), metadata persists in sock dir, session visible to server
  • Cursor MCP ex reaches gate REPL (eval mirrored in host REPL)

mind6 and others added 5 commits June 21, 2026 05:45
- additional tcp path for tests
- Scaled down number of open sockets in Windows.
- fixes raw config paths by switching to JSON.json
Default serve() to TCP on Windows, write discoverable sock metadata for loopback gates, escape backslashes in session JSON, fix PID liveness checks, and align XDG_CACHE_HOME between gate and server.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mind6 mind6 changed the title test: Windows portability — full suite passing on Windows Windows: full test suite + gate auto-discovery for local MCP Jun 21, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was taking over 10 minutes. Pulled out the database setup outside of @check, it currently finishes in under 15 seconds.

@kahliburke

Copy link
Copy Markdown
Owner

Thanks for this — the Windows end-to-end work is great, and the JSON-escaping fix in particular is a real bug squashed.

I reviewed and tested it on macOS:

  • Merges cleanly into the current 2.0-integration (the branch has moved a fair bit since you based off it — grep_code, the routing/roots work, etc.). After merging, the main suite and the KaimonGate suite are green (incl. your new metadata JSON escapes backslashes test, and CURVE 66/66). The only red I saw were a couple of pre-existing flakes (a Gate.progress @test_nowarn and the ZMQ-stress subprocess test, both pass in isolation) — nothing from your changes.
  • Could you rebase onto current 2.0-integration when you re-test? It merges without conflicts on my end.

On the discover_sessions change vs #50 — I dug into this since #50 was a nasty one. Good news: it does not reintroduce the original #50. The poll/reconnect markers connect_tcp! writes all use sid tcp-<host>-<port>, which your startswith(session_id, "tcp-") && continue still skips. 👍

I did find two smaller refinements for the new localhost-TCP discovery path, which I've pushed as a single commit on top of your head on branch pr54-50-hardening (cherry-pick 59a9b9f, or apply the diff below):

  1. Apply the already-tracked/same-PID dedup to localhost TCP too. Right now it's gated session_mode != :tcp, so an already-connected localhost TCP gate isn't skipped — each discovery cycle re-emits it and discover_sessions treats it as a "restart", causing repeated reconnect attempts.
  2. Attach the local auth token to discovered localhost TCP gates (env KAIMON_GATE_TOKEN → global-config api key, mirroring connect_tcp!). A localhost gate shares this machine's config; presenting the token authenticates an auth-required gate and is ignored by a lax one — instead of failing tokenless every cycle.
+function _resolve_local_gate_token()
+    tok = get(ENV, "KAIMON_GATE_TOKEN", "")
+    isempty(tok) || return tok
+    try
+        config = load_global_config()
+        if config.mode != :lax && !isempty(config.api_keys)
+            return first(config.api_keys)
+        end
+    catch
+    end
+    return ""
+end
@@ discover_sessions, TCP branch @@
-        if session_mode != :tcp && haskey(known_id_pids, session_id) && known_id_pids[session_id] == pid
+        if haskey(known_id_pids, session_id) && known_id_pids[session_id] == pid
             continue
         end
@@ conn construction @@
             server_pubkey = server_pubkey,
+            auth_token = session_mode == :tcp ? _resolve_local_gate_token() : "",

Those discovery/TCP testsets pass for me (83 total: stale-session, TCP auth, ephemeral+auth, poll backoff, PID refresh + localhost reaping).

Since I can't validate Windows here: could you fold in pr54-50-hardening, rebase onto current 2.0-integration, and re-run on Windows + the full suite? Once that's green we can merge. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants