Commit Graph
14 Commits
Author SHA1 Message Date
yetone 89825eca1a go.mod: go mod tidy — moejs is required directly (internal/gateway imports it), and go.sum drops testify 1.11.1 and go-spew/go-difflib, which nothing builds with
go mod verify, go vet, go build (darwin, GOOS=linux nogui, GOOS=windows) and the gateway and library tests pass.
2026-10-06 04:01:01 +08:00
yetone eebd0b4222 plugin, gateway, gui: a plugin can be gateway middleware — onRequest, onEvent and onResponse run in magpie's gateway on what agents send and get back (moejs) — a plugin could only be a subscription provider, run in the Bun host, a process away from the gateway. A plugin may now declare middleware (package.json magpie.middleware, or a *.middleware.js / .mjs file), run in-process by moejs (pure-Go JS engine): compiled once, one runtime per request from a pool, so every hook of a request shares ctx.state. onRequest(body, ctx) sees the agent's body in its own API before routing; what it returns is the body the next middleware and the gateway get, undefined leaves the bytes as they were, ctx.reject(status, msg) answers with an error in the agent's API's shape. onEvent(ev, ctx) sees each SSE event's JSON (export const events = [...] filters by name; an object changes it, null drops it, undefined passes the bytes through untouched; data: [DONE] is no JSON and passes by). onResponse(body, ctx) sees a whole JSON reply, with ctx.status. ctx has protocol, model, stream, path, agent, the plugin's options and state. A hook that throws, returns a non-object or runs past its limit (250ms request/response, 50ms an event, 1s load; interrupted) leaves the request or reply as it was and is counted and logged (60 lines a minute); a compressed reply passes as-is. Files are reloaded within a second of a change. Only agents' requests run through it (serveAgent at the gateway's agent entry points and the Codex backend), never magpie's own titles, classifier or stand-ins; it sees bodies before redaction. A middleware-only package is skipped by the Bun host. The Plugins page marks a middleware with a chip, its hooks, calls and µs per call (JSON in and out counted), failures in red with the last error, and a load error. en/zh/ja/de; docs/reference.md and usemagpie.ai/docs/plugins#middleware (en/zh/ja) with an alias example. Tested with a real DeepSeek account through magpie web --gateway in a sandbox HOME: an alias middleware served "fast" and named it in message_start, a reject came back as 403 permission_error, a Chat stream uppercased; real Claude Code (sandbox CLAUDE_CONFIG_DIR) did Read, Bash and Glob tool turns through three middlewares with 0 failures: ≈1–1.6µs an event, 0.2–0.7ms an onRequest that parses and rewrites Claude Code's ≈80KB body. Real use found two bugs fixed here: [DONE] parsed as JSON (SyntaxError on every Chat stream) and stats leaving out the JSON time. internal/middleware tests (chain, undefined keeps bytes, reject, fail-open on throw/spin/string with the runtime reused, async hook, load errors, off and Bun skip, reload, split/CRLF/filtered/dropped stream events, [DONE] untouched, whole reply and gzip, 64 in parallel; BenchmarkEvent ≈0.9µs, 11 allocs) and TestMiddlewareThroughGateway (alias routed, events by protocol, redaction still upstream, reject in Anthropic's shape; fails without the change) are new; plugin-middleware.test.cjs (Chromium and WebKit, en and zh: chip, hooks and stats, failures with last error, broken and off, no left border) fails without it. The other plugin GUI tests and click-scroll pass in WebKit. go vet, go build (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./... under a temp HOME pass (internal/provider failed once under load and passes alone). 2026-10-05 19:14:31 +08:00
yetone e698e7dddd claude: adding a Claude account is Claude Code's own claude auth login, and magpie never refreshes a Claude sign-in nor asks Anthropic anything with one (the user: 把 magpie 自己的 Claude 登录改成直接用 claude /login,只要体验上没什么差别就改) — magpie traded the sign-in page's code for tokens with Claude Code's OAuth client, asked Anthropic's profile and model list with them, refreshed saved accounts itself (daily keepalive included) and handed a saved account to Claude Code as CLAUDE_CODE_OAUTH_TOKEN. Now Add account runs claude auth login --claudeai in a config directory of magpie's own: the page Claude Code would open comes to magpie's window (Claude Code is given magpie as its BROWSER, which writes the page down and exits), the browser comes back to Claude Code's own listener, and when the browser can't reach this machine the address it ended on, or the code Claude's page shows, is pasted as before and handed to Claude Code. Who signed in is what Claude Code kept (.claude.json, auth status). A saved account in use beside the signed-in one runs Claude Code with CLAUDE_CONFIG_DIR set to its own directory (claude-accounts/ beside magpie's config), its sign-in put there once from logins.json and read back as Claude Code refreshes it; switching to it moves it into Claude Code's own store and removes the directory, as forgetting it does. Claude's models are the catalog's (models.dev), not asked of Anthropic; an imported Claude login is kept as the file has it, and Claude Code refreshes it on first use. Claude Code is required to add a Claude account. TestClaudeSignInByPaste, TestClaudeSignInByPastedAddress, TestClaudeSavedAccountDir (a fake claude CLI, and a server standing in for Anthropic that fails the test if asked) and the reworked sign-in, import and gateway tests fail without the change. With the real Claude Code 2.1.286 in a sandbox directory, its sign-in page (localhost callback) reached magpie's binary and the sign-in waited for the browser; nothing was left behind once it was canceled. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass; claude-risk, plugin-signin, signin-callback, signin-link, signin-paste-codex, routing-signin, own-signin-remove, click-scroll, old-webkit pass. 2026-10-01 16:37:07 +08:00
yetone b0a0165fc9 usage: a notification when a window is nearly used up or a balance runs low (#368) — Settings has Usage alert (off, or a share of 1–100%, 80 by default) and Low balance alert (off, or an amount, 5 by default), and magpie quota alert sets them from the command line. Each subscription or plan window, other than one set aside, is told once a run when it reaches the share, and a balance once until topped up past the amount again; what was said is kept, so a restart doesn't say it again, and a failed or stale reading neither alerts nor clears. The system's notifications are started only when first needed, so a Mac build that can't have them or a Linux desktop without a daemon still starts, and Settings says when they are refused or unavailable; a click opens the Usage page. TestDueAlerts and friends, TestAlertText and usage-alert.test.cjs fail without the change. 2026-10-01 04:16:28 +08:00
yetone 839c762098 app: Magpie is in the Start menu on Windows (#158: Windows 便携版首次运行后,无法在开始菜单 / 系统搜索中找到 Magpie — @Aimer779) — the Windows build is one portable exe with no installer, so nothing put it anywhere Windows search looks. Each start of the desktop app (not the CLI, TUI or serve) now makes sure %APPDATA%\Microsoft\Windows\Start Menu\Programs\Magpie.lnk (the Programs known folder) opens the exe it runs as, symlinks resolved, in its folder, with its icon and "Magpie" as its description; one that already does is left be, one for where the exe was before it was moved is pointed here again. It is the shell's own link, made through WScript.Shell with go-ole (already in the build through Wails, now a direct require), in the background beside the magpie:// registration, and a failure is only logged. An update replaces the exe in place, so the shortcut stays good; a magpie left running from magpie.exe.old(-N) (or .new) points it at magpie.exe, never at what was moved aside. HKCU App Paths\magpie.exe is set to the exe (and its folder) so Win+R magpie opens it too. No uninstall entry, nothing copied. MAGPIE_NO_SHORTCUT=1 skips it (tests, sandboxes); other systems do nothing. Tested with the Windows test built here and run on Windows 11: a shortcut made, left as it was on a second start, pointed at the moved exe. Run on Windows 11 as the desktop app: the shortcut made with the exe's folder and icon, pointed anew after the exe moved, left as it was on a start with nothing changed; App Paths set 2026-09-28 22:44:36 +08:00
Zhizhen He d36dbe46f5 chore: go mod tidy (#66) 2026-09-25 22:11:19 +08:00
yetone dfc2d7fa93 library: MCP servers, skills and instructions are kept once in magpie and given to any agent from one place, with a market to find and add them (#29). Each agent reads MCP servers and skills from files of its own and in a format of its own, so one server was set up again in Claude Code, Codex, Gemini CLI, OpenCode, Pi, Goose, Cursor, Copilot CLI and Crush. The Library view keeps each once: a server is added (stdio, http or sse, its env and headers) and switched on per agent with its icon, and magpie writes it into each agent's config in that agent's format, leaving what the agent has of its own as it is; a server or skill an agent already has is shown, to bring into the library. A skill is a folder with a SKILL.md, kept in the library from GitHub (owner/repo, or a link to a folder in one; updated from it later) or linked from a folder on this machine, and linked into each agent's skills folder. The instructions every agent reads (CLAUDE.md, AGENTS.md, GEMINI.md…) can be kept as one too. The market offers checked MCP servers first, then the official MCP Registry's, filled in from what the registry says each needs (keys asked for in a form, never guessed), and skills.sh's most installed skills with what each says it is for; each shows its real icon (the vendor's own, else its GitHub owner's), fetched through magpie only for the icons the market or the library gave out, and an added server or skill keeps its icon in the library. What magpie changes in an agent's files is backed up first 2026-09-25 14:11:17 +08:00
yetone c3931c91df codex: magpie's models join Codex's own rather than replacing them — signed in (ChatGPT or an API key), Codex keeps its built-in OpenAI provider and sign-in and is pointed at magpie with openai_base_url alone, so its official models still go to OpenAI on the user's own account, its threads (listed per provider) stay together, and the Codex app keeps its model picker; magpie's gateway answers at /backend-api/codex, passing Codex's own models through as they came, serving magpie's (provider/model) itself, and handing out OpenAI's model list with magpie's after it for /model. Compacting a magpie model's conversation is done by that model with Codex's own prompt; Codex's compressed request bodies are read, and usage is counted for both. Not signed in, magpie stays a provider of Codex's as before; a magpie set up that way moves over the next time a magpie model is picked 2026-09-25 02:42:24 +08:00
yetone 41931e2895 agent: omp (oh-my-pi) — its model picked in magpie like any agent's; a model through magpie adds magpie as a keyless provider in ~/.omp/agent/models.yml with the catalog as its models, and sets config.yml's modelRoles.default to magpie/<provider>/<model>; its other roles and the rest of both files stay as they are, comments too, and default takes magpie's entry out unless another role still uses it (#34) 2026-09-24 22:36:15 +08:00
yetone efbe5660b0 backup: everything set up in magpie carried to another machine in one file — magpie backup writes the providers with their keys (or none, with --no-keys), the pictures picked for them, the settings, the profiles and every agent's model, sealed with a passphrase (AES-256-GCM, PBKDF2-SHA256) so nothing in it reads without it; magpie restore puts it in, replacing providers by id, keeping the keys already there for one that came without, and setting models only for the agents installed there; subscriptions stay with the machine they were signed in on (#28) 2026-09-24 20:34:15 +08:00
yetone 0b0f258c0f providers: import from other apps — the add sheet's Import… reads the providers CC Switch (its database, or the older config.json) and Alma have set up, read-only, and lists them to pick from: what magpie has already is marked, a key for a vendor that is already here can join it as another key, an id in use is kept beside or replaced, and sign-ins, Azure, Gemini-protocol relays and entries pointing at magpie itself are shown but not offered; keys are read again on import and only reach the window masked 2026-09-24 18:48:08 +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 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
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