feat(desktop): Electron desktop app skeleton + Windows enablement groundwork#752
Draft
AbirAbbas wants to merge 6 commits into
Draft
feat(desktop): Electron desktop app skeleton + Windows enablement groundwork#752AbirAbbas wants to merge 6 commits into
AbirAbbas wants to merge 6 commits into
Conversation
Docker-Desktop-style dashboard for non-technical users: shows control plane health (GET /health) and the locally installed agent nodes from ~/.agentfield/installed.yaml, cross-checked against GET /api/v1/nodes for a running/stopped/unknown badge per agent. Polls every 5s with a manual Refresh button and graceful empty states. Electron + electron-vite + React + TypeScript, plain CSS. Secure defaults: contextIsolation on, nodeIntegration off, sandboxed renderer, single contextBridge API. All data access is isolated in src/main/agentfield.ts with a marked seam to later swap the registry read to `af list -o json`. 29 vitest unit tests cover registry parsing, health mapping, and badge derivation. Self-contained under desktop/ (own package.json); no packaging (electron-builder) yet, and the GUI is untested in this headless environment — typecheck, production build, and unit tests all pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces the stale commented-out windows block with a real agentfield-windows-amd64 build mirroring the linux/darwin ones (goreleaser appends .exe on its own). Groundwork only: the release workflow's build matrix filters by --id and does not build this id yet; shipping the artifact needs a follow-up matrix entry (windows runner, or mingw-w64 on the linux runner for the CGO sqlite dependency). Also modernizes archives.builds/format to ids/formats so `goreleaser check` passes clean again (both were deprecated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`af stop` used process.Signal(os.Interrupt) and a signal-0 probe, both unsupported on Windows (and os.FindProcess always succeeds there, so the liveness check was meaningless). Extract the two process operations into build-tagged helpers: proc_unix.go keeps the existing SIGINT + signal-0 behaviour; proc_windows.go uses taskkill for the graceful request and a tasklist PID query for liveness. stop.go changes are limited to swapping the two call sites and the now-unused syscall import. Windows paths are compile-verified only (GOOS=windows cross-build), not yet tested on a real Windows machine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`af logs` shelled out to tail(1), which does not exist on Windows. The tail/follow commands now go through one tailCommand helper: unchanged tail(1) invocations on Unix, PowerShell Get-Content -Tail (-Wait for follow) on Windows, with proper single-quote escaping of the log path. Windows path is compile-verified only, not yet run on a real machine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Go agent nodes declare unix-style binary paths in their manifests (entrypoint.start: bin/foo). On Windows the install-time `go build -o` output now carries the conventional .exe extension, and the runner's GoBinaryProgram resolves an extensionless start path to the built .exe when present. No behaviour change on other platforms; windows path is compile-verified only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
📊 Coverage gateThresholds from
✅ Gate passedNo surface regressed past the allowed threshold and the aggregate stayed above the floor. |
Contributor
📐 Patch coverage gateThreshold: 80% on lines this PR touches vs
✅ Patch gate passedEvery surface whose lines were touched by this PR has patch coverage at or above the threshold. |
…ed helpers The patch-coverage gate flagged the runtime.GOOS-gated windows branches (PowerShell tail construction in logs.go, .exe naming/resolution in gointerp.go) as untestable on linux CI. Extract each into a pure helper taking an explicit goos string — tailCommandArgs, withExeSuffixFor, goBinaryProgramFor — with the exported wrappers passing runtime.GOOS, so behavior is unchanged while both platform paths are unit-testable anywhere. Table-driven tests cover the windows tail command (incl. single-quote escaping), .exe suffixing, and the built-.exe fallback resolution; refactored regions now profile with zero uncovered blocks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First cut of the AgentField desktop app (Docker-Desktop-style, for non-technical users on Mac and Windows), plus the Windows enablement groundwork the desktop story depends on.
Part 1 —
desktop/: Electron app skeleton (read-only v1)Electron 33 + electron-vite + React 18 + TypeScript, fully self-contained (own
package.json; no root Makefile/CI changes). Secure IPC defaults:contextIsolation: true,nodeIntegration: false,sandbox: true, window-open denied, a singlegetSnapshot()bridge.GET /health(3s timeout), distinguishes running / reachable-but-unhealthy / not reachable.~/.agentfield/installed.yaml(platform-aware home dir), shows name, version, language, port, PID.GET /api/v1/nodes(running / stopped / unknown, including stale-registry and conflict cases).~/.agentfield, zero agents, control plane down).desktop/src/main/agentfield.tswith a markedTODO(af-cli)seam to swap toaf list -o json(added by feat(control-plane): agent-mode steering verbs, events query resource, and --json lifecycle output #751).Known v1 limits (deliberate): read-only, hardcoded
localhost:8080, no packaging/electron-builder yet. Developed in a headless environment —tsc, production build, and unit tests are green, but the GUI has not been visually smoke-tested.Part 2 — Windows enablement (compile-verified only)
.goreleaser.yml: realagentfield-windows-amd64build block (CGO=1 via mingw-w64, embedded+sqlite_fts5 tags) replacing the stale commented one; archive config modernized (builds/format→ids/formats,goreleaser checknow passes clean).proc_unix.go/proc_windows.go): SIGINT + signal-0 on unix;taskkill+tasklistPID query on Windows (os.FindProcessalways succeeds there).stop.gocall-site swaps only.af logstailing: unchangedtail(1)on unix; PowerShellGet-Content -Tail [-Wait]on Windows.go build -ogets.exeon Windows and manifest-declared extensionless paths resolve to it. No-op elsewhere.Scripts\handling, home-dir resolution, af-tray build tags. Deferred: pyenv fallback path (pyenv is effectively unix-only).release.ymladds the new build id to its matrix (needs mingw-w64 on the linux runner or a windows runner for the CGO sqlite dep). CI workflows deliberately untouched here.Notes for review
stop.go's output layer while this one extracts its process ops — whichever merges second needs a trivial rebase.go testfailures (TestDevServiceRunDevet al.) are pre-existing/environmental (fail identically at base6b8b404e); touched packages fully green including new tests.🤖 Generated with Claude Code