Commit Graph
17 Commits
Author SHA1 Message Date
yetone 652e5e1ec5 ci: the gateway's race suite runs over one process per core, not one at a time (wizzy-yang, #923)
The Race step took 690s on ubuntu and 908s on macOS, almost all of it
internal/gateway: its 1046 tests can't call t.Parallel (t.Setenv rules
it out), so the package ran on one core under the race detector.
build/race-shards.sh compiles nothing itself: it takes the package's race
test binary (go test -race -c), splits its tests round-robin by name over
N processes run at once, prints each process's log in a folded group and
fails when any does. The gateway's TestMain already isolates every
process in its own temporary home, keychain stand-ins and PATH, so the
processes share nothing. The step runs it with one process per core
(getconf _NPROCESSORS_ONLN: 4 on ubuntu, 3 on macOS), the same -race
binary and the same 20-minute timeout; redact keeps its own go test -race.
Every test still runs under the race detector, once.

Locally (Apple silicon, 4 processes) the gateway's race suite passed in
4:39 against 567s of test time run one after another; one test,
TestLargeRequestEndpoints (seven 64 MB bodies, 198s), now bounds it.
2026-10-05 23:54:03 +08:00
tobitege 21702d01ff Add German translation; harden paths against unset env vars (#770)
* Add German translation and harden paths against unset env vars

Add a German locale to the GUI, tray menu, usage alerts and website home page, and refuse to start when the home folder is unset or relative so nothing is written under the working folder; the pi plugin no longer adopts the user's PI_CODING_AGENT_DIR, and an inherited APPIMAGE no longer selects portable mode. Scripts refuse to run from the wrong folder or empty a shared out folder, and a new internal/testenv sandboxes every test package from the user's real files, which also fixes the Claude picker and Termux installer tests on Windows.

* Makefile: know magpie's folder by its go.mod, so paths with spaces work

The check compared $(CURDIR) with $(dir $(abspath …)), which make splits on spaces, so a checkout under 'My Projects' or 'John Doe' refused every target. It now reads go.mod relative to the working folder and wants magpie's module there: make -C and a symlinked Makefile work, make -f from another folder still stops before any recipe runs.

* i18n: German for the strings main added since, with a parity test

75 strings main added (group order, patterns, slow-start wait, usage caps, RTK savings …) get their German, and two that main dropped go. gui-de.test.cjs checks, as gui-ja does, that de has every zh string with its placeholders and tags, and that the window reads in German when picked or on a German system.

* appdir: ignore relative folder variables when reading, keep them for children

CheckEnv no longer unsets anything. magpie reads the XDG folders, APPDATA/LOCALAPPDATA and every agent's folder variable through appdir.Getenv/LookupEnv, which pass over a relative value; the environment stays as it is, so the agents magpie starts get the variable as the user set it. That covers what proc.UserPath lends from the login shell too, which is set after main's check and reached the desktop app unchecked. On Windows a path rooted on the current drive (\Users\x, Git Bash's /c/x) counts as usable, and magpie version and help answer without a home, before run makes any folder.

* Sandbox the tests main added since

internal/wslrun gets testenv's TestMain, and four tests main added that set HOME alone set their home with testenv.SetHome, so on Windows they don't read the runner's profile through USERPROFILE.

* agentenv: PI_CONFIG_DIR and OPENCODE_DB take relative names on purpose

omp puts $PI_CONFIG_DIR under the home and OpenCode a relative $OPENCODE_DB in its data folder, so neither depends on the working folder: appdir no longer passes them over.

* i18n: German for the Library's multi-select and System One's decision API

The 19 strings main added since (#791's skill multi-select, the decision API snippets) get their German; the one main replaced (four APIs → five APIs) goes.

* appdir: tidy the import into magpie's group; say what Go makes of /c/x

The appdir import joins the group of magpie's own imports where a file has one. rooted's comment now says that Go takes a Git Bash path like /c/x as \c\x on the current drive, not C:\x.
2026-10-04 23:30:56 +08:00
yetone 2ce745a850 tray: the menu bar bird is smaller (@SherlockYoYo on X: 菜单栏icon可以再优化一下吗,感觉这只鸟有些大) — drawn to the edges of its 22pt square it was a full 22pt wide, bigger than the menu bar's own glyphs, and its flap frames were cut off at the sides; build/icon/gen.go now draws it at .8 about the middle (trayK), about 18pt by 14pt, the still bird and every flap frame alike. TestTrayIconSize fails without the change. go vet, go build (darwin GUI), go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass. 2026-09-30 18:31:08 +08:00
yetone b881932ec2 gui: the page runs in macOS 12's WebKit — no regex lookbehind, the few newer built-ins filled in, fallbacks for container queries, subgrid, :has and color-mix (#220 uclort: on macOS 12.7.6 the app opened blank, the panel showing its tab bar, a "Profiles + Save current" heading and "Open magpie · Quit" and nothing else, no button working) — the page runs in the system's WebKit, on macOS 12 Safari 15.x's, and app.js's snippet highlighter had a regex lookbehind, (?<==)\S+ (app.js:2167), which WebKit only parses from Safari 16.4: a SyntaxError in a literal fails the whole file, so app.js never ran (and routing.js and library.js, which lean on it, threw), leaving index.html's static markup; library.js had two more, (?<![\w-]) in the SVG greying (library.js:162-163). The highlighter now finds a value after "=" by hand (the character before the match, a sticky \S+) and the greying checks the character before a colour name in its replace callback, each giving the same output as before (compared on shell, curl, Python and Node snippets and an SVG with attribute and style colours, data-fill and x-color left alone). Built-ins newer than Safari 15.0 in use, routing.js:307's findLast and library.js:1042's structuredClone (15.4), are filled in by a new compat.js loaded before the other scripts (with at, findLastIndex and Object.hasOwn), each only where missing; structuredClone there is a JSON copy, enough for the API's plain data. Styles: a selector list with :focus-visible (15.4) drops the whole rule before 15.4, so the agent handle's hover, an account's Remove and protocol buttons showing on hover, the protocol menu's hover and the editor's focus ring are split from their :focus-visible (or it is dropped where :focus covers it); .acc:has(.aq) and the panel's .profiles:has(> .chip-input) hint (15.4) are classes set by app.js (with-aq, naming); the Routing page's container queries and the request list's subgrid (16) get @supports not fallbacks by the window's width (the tray panel is narrower than all of them) and a row's own columns; and the panel's --panel-tint, a color-mix() (16.2) in a custom property that would have gone invalid and painted the panel clear (tintPanel then handing the system white under dark text), falls back to --bg, as the floating status and Library's sticky head do. Other things newer than 15.0 are left as cosmetic: inert (15.5) on the folded agent list, accent-color, the rest of color-mix() on hover and focus shades, .quota's subgrid rows. The build: Go 1.25 and later run on macOS 12 and up only (the linker stamps 12.0 as the oldest), so Info.plist's LSMinimumSystemVersion and the Makefile's -mmacosx-version-min go from 11.0 to 12.0 and the site says macOS 12+ rather than 11+. Tested with a new internal/gui/tests/old-webkit.test.cjs: every assets/*.js parsed with the Babel parser Playwright bundles, failing on a regex lookbehind, v flag or modifiers (in a literal or new RegExp("…")), a class static block, decorators, import attributes or using (checked against the old highlighter's regex and a static block, and not on named groups, lookahead, ??= or private methods); a grep for built-ins newer than 15.0 (at, findLast, structuredClone, hasOwn, toSorted and co., Set methods, groupBy, withResolvers, Iterator helpers, popover …) unless compat.js fills them in (fails on main's routing.js:307 and library.js:1042 without it); compat.js the first of the page's scripts and every script loaded; the CSS with no :has(), no :focus-visible in a mixed list, no nesting or dvh, and @container, subgrid columns and a color-mix() custom property only with an @supports not fallback in the same file; and, in WebKit with those built-ins deleted, the panel's tabs, Save current's name field and every window page drawn with no page error. Documented in internal/gui/tests/README.md. go build -tags nogui (and GOOS=linux, GOOS=windows), go build (darwin GUI), go test -tags nogui ./... and the whole GUI suite (130 tests) pass. Not tried on a real macOS 12 or Safari 15: the old engine's parse is judged by the parser, not run. 2026-09-29 23:52:38 +08:00
yetone e0c6892f56 dev: a Go change hands the backend over instead of cutting the agents off (为什么老是会reconnecting) — make dev killed the backend, and the dev gateway with it, on every Go save, so Cindy's Pi on :3426 lost its stream and reconnected; now the new backend listens beside the old one (SO_REUSEPORT, dev only), and once it does the old one is sent USR2, stops taking requests, finishes those in flight — a stream as long as it takes — and exits. A backend that builds but never comes up leaves the old one serving. Tested in a sandbox: a 12s stream through the gateway ran to [DONE] across a handover, new requests went to the new backend, and the old one exited when the stream ended 2026-09-28 18:56:50 +08:00
yetone 33ffb48f50 tray: clicked, the bird flaps as the header logo does on hover (一定要用应用里的那个 Magpie icon 被 hover 的动画效果) — the frames were a bend of the outline of my own; now build/icon/gen.go draws app.css's .logo.wag itself: the bird cut into body, tail and wing by index.html's clip paths, each turned about the same origin through the same keyframes, cubic-bezier(.3, 0, .3, 1) between each two, the whole bobbing about its feet, over the same .9s — 29 frames played 30ms apart. Checked against Chrome's own rendering of the logo paused at the same 29 moments: at most 0.7% of pixels differ, all of them at anti-aliased edges 2026-09-28 18:43:55 +08:00
yetone ebc33c721b tray: a click on the bird flaps it — the wing beats twice and the tail flicks up once, 16 frames over about half a second (build/icon/gen.go tray-flap bends the outline about the tail's root and the shoulder, eased, so it stays one line); and the usage beside it no longer sits hard against it, a thin space between (Image #13: 图标与用量之间没有任何的间距) 2026-09-28 16:15:40 +08:00
yetone 8f34b6d37e icon: macOS 26 draws magpie's icon light or dark — AppIcon.icon (the bird on a pale tile, or in white on a dark one) compiled into Assets.car beside the .icns, where the .icns alone was darkened whole in dark mode, the black bird lost on a black tile (#117); the app no longer sets a light picture over it in the Dock 2026-09-27 22:55:20 +08:00
yetone 9a0078f08c dev: a Go change under make dev rebuilds and restarts only the backend — the API and the gateway — behind windows and a tray that stay up, and the page refreshes what it shows in place, keeping its tab and anything open; a build that fails leaves the running backend be (build/dev.sh) 2026-09-25 01:14:56 +08:00
yetone 4bd3f3a4b5 import: magpie://import links add a provider after the user confirms
A vendor or relay can hand out a ready-made provider as a link. The app
registers the magpie scheme (Info.plist on macOS, HKCU on Windows, a
.desktop handler on Linux), a second launch hands the link to the running
one, and the window shows what the link would add, with the hosts the
prompts and key would go to, before anything is saved. `magpie import`
does the same in a terminal.
2026-09-24 12:17:45 +08:00
yetone 75cb192647 Desktop app for Windows and Linux
The Windows app cross-compiles (WebView2, no cgo) as a GUI program with an
icon, version info and a DPI-aware manifest; run from a terminal with a
command it borrows the console. The Linux app links GTK 3 and WebKitGTK
4.1. Off the Mac the app updates its own binary from its own build:
downloaded in the background, swapped in on restart or quit, and the
relaunched process waits for the old one before taking the gateway. The
window leaves room for traffic lights only on a Mac.
2026-09-24 03:22:02 +08:00
yetone 3b0cf9a965 logo: a round magpie in black and white, drawn from one SVG 2026-09-24 01:09:59 +08:00
yetone 402a96c39d Rename dial to magpie, with a magpie for a logo
The product, module path (github.com/yetone/magpie), binaries, env vars
(MAGPIE_ADDR, MAGPIE_DEV_UI, MAGPIE_THEME, MAGPIE_DEBUG), config and cache
folders (~/.config/magpie, ~/.cache/magpie), bundle id (com.yetone.magpie),
gateway provider id and token, and every UI string now say magpie.

On first run magpie copies ~/.config/dial and ~/.cache/dial to the new
folders when they don't exist yet (copy, not move, so a still-running dial
keeps working; the old folders can be deleted by hand later).

The logo is a small round magpie in profile: one path for the header and
the tray, and the app tile adds the white belly and the blue-green tail.
The header mark is drawn in ink rather than the accent colour, which
fought the text in light mode.
2026-09-23 23:55:11 +08:00
yetone 9e3e338e63 logo: a kingfisher
The gateway glyph is gone. The mark is now a kingfisher in profile, facing
the wordmark: big head, dagger beak, short tail, one line for the wing, the
eye a hole. The header draws it in ink rather than the accent, which fought
the text in light mode. The icon generator rasterizes the same SVG path
(flattened cubics, even-odd fill), and the app tile is kingfisher blue.
2026-09-23 23:25:07 +08:00
yetone ec2eb09853 logo: the gateway mark
Three inputs from the left, two of them curving in, meet at a hollow node
and one line leaves to the right: many models, one endpoint. Replaces the
detent ring, which read as a power button.
2026-09-23 14:01:54 +08:00
yetone 7fefa62851 logo: the detent mark
A control ring open to the upper right with a detached index reaching
through the opening: the instant a knob clicks into position. One glyph
on a 44-unit grid drives the window header SVG, the menu bar template
icon and the app icon; the generator draws it with round-capped strokes
so the three stay identical.
2026-09-23 01:11:20 +08:00
yetoneandClaude 0a234ce41d dial: one dial for every coding agent's model
Wails v3 tray panel and window, TUI and CLI. Switches model, effort and
provider for Claude Code, Codex, Gemini CLI, OpenCode, Pi, Goose, Cursor,
Copilot CLI and Crush with format-preserving config edits. Providers page
and registry, stored keys, live vendor model lists, profiles.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-22 21:47:29 +08:00