Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schemaVersion": 1,
"providerId": "official",
"name": "PI-Desktop Official Plugins",
"updatedAt": "2026-09-20T17:49:14Z",
"updatedAt": "2026-10-02T17:42:29Z",
"homepage": "https://github.com/vastsa/pi-desktop-plugins",
"plugins": [
{
Expand Down Expand Up @@ -319,6 +319,50 @@
}
]
},
{
"id": "io.github.yahooyuan666.zcode2pi",
"name": "ZCode Free Quota",
"description": "Use the ZCode / BigModel Coding Plan free quota inside PI-Desktop: declares a model provider in the manifest (provider.register) and runs a loopback relay (background.service) that forwards requests to BigModel's OpenAI-compatible Coding Plan endpoint. Both ends speak Chat Completions, so no protocol translation happens and streaming is passed through untouched. Your API key stays in PI-Desktop's own secret store \u2014 the relay never sees it.",
"i18n": {
"en": {
"name": "ZCode Free Quota",
"description": "Use the ZCode / BigModel Coding Plan free quota inside PI-Desktop: declares a model provider in the manifest (provider.register) and runs a loopback relay (background.service) that forwards requests to BigModel's OpenAI-compatible Coding Plan endpoint. Both ends speak Chat Completions, so no protocol translation happens and streaming is passed through untouched. Your API key stays in PI-Desktop's own secret store \u2014 the relay never sees it.",
"safetyNotes": "The relay binds 127.0.0.1 only and rejects any request whose Host header is not loopback. Its one and only network destination is open.bigmodel.cn. It never reads, stores or logs your API key: PI-Desktop attaches the key from its own secret store to the outgoing request and the relay forwards request headers unchanged. It does not read or write any file, touch the clipboard, run a shell, or load remote code. On an upstream error it logs one line describing the request's field names and counts only \u2014 never message content, tool arguments or credentials. It rewrites nothing in the request body, so what the model sees is exactly what PI-Desktop sent."
},
"zh-CN": {
"name": "ZCode\u514d\u8d39\u989d\u5ea6",
"description": "\u628a ZCode / BigModel Coding Plan \u7684\u514d\u8d39\u989d\u5ea6\u63a5\u8fdb PI-Desktop\uff1amanifest \u9759\u6001\u58f0\u660e\u6a21\u578b provider\uff08provider.register\uff09\uff0c\u540e\u53f0\u5e38\u9a7b\u4e00\u4e2a\u56de\u73af\u4e2d\u7ee7\uff08background.service\uff09\uff0c\u628a\u8bf7\u6c42\u8f6c\u53d1\u5230 BigModel \u7684 OpenAI \u517c\u5bb9 Coding Plan \u7aef\u70b9\u3002\u4e24\u7aef\u90fd\u662f Chat Completions \u65b9\u8a00\uff0c\u4e0d\u505a\u4efb\u4f55\u534f\u8bae\u8f6c\u6362\uff0c\u6d41\u5f0f\u8f93\u51fa\u9010\u5757\u900f\u4f20\u3002API Key \u59cb\u7ec8\u7559\u5728 PI-Desktop \u81ea\u5df1\u7684\u5bc6\u94a5\u5e93\u91cc\uff0c\u4e2d\u7ee7\u63a5\u89e6\u4e0d\u5230\u5b83\u3002",
"safetyNotes": "\u4e2d\u7ee7\u53ea\u7ed1\u5b9a 127.0.0.1\uff0c\u51e1 Host \u5934\u4e0d\u662f\u56de\u73af\u5730\u5740\u7684\u8bf7\u6c42\u4e00\u5f8b\u62d2\u7edd\u3002\u5b83\u552f\u4e00\u7684\u5bf9\u5916\u8fde\u63a5\u76ee\u6807\u662f open.bigmodel.cn\u3002\u5b83\u4e0d\u8bfb\u53d6\u3001\u4e0d\u4fdd\u5b58\u3001\u4e0d\u8bb0\u5f55\u4f60\u7684 API Key\uff1aKey \u7531 PI-Desktop \u4ece\u81ea\u5df1\u7684\u5bc6\u94a5\u5e93\u9644\u5230\u51fa\u7ad9\u8bf7\u6c42\u4e0a\uff0c\u4e2d\u7ee7\u539f\u6837\u900f\u4f20\u8bf7\u6c42\u5934\u3002\u5b83\u4e0d\u8bfb\u5199\u4efb\u4f55\u6587\u4ef6\u3001\u4e0d\u78b0\u526a\u8d34\u677f\u3001\u4e0d\u8d77 shell\u3001\u4e0d\u52a0\u8f7d\u8fdc\u7a0b\u4ee3\u7801\u3002\u4e0a\u6e38\u62a5\u9519\u65f6\u5b83\u53ea\u6253\u4e00\u884c\u300c\u8bf7\u6c42\u91cc\u6709\u54ea\u4e9b\u5b57\u6bb5\u3001\u5404\u591a\u5c11\u4e2a\u300d\u2014\u2014\u7edd\u4e0d\u6253\u6d88\u606f\u6b63\u6587\u3001\u5de5\u5177\u53c2\u6570\u6216\u51ed\u636e\u3002\u5b83\u4e0d\u6539\u5199\u8bf7\u6c42\u4f53\uff0c\u6a21\u578b\u770b\u5230\u7684\u5c31\u662f PI-Desktop \u53d1\u51fa\u7684\u539f\u6837\u3002"
}
},
"author": "YahooYuan666",
"categories": [
"developer-tools",
"community"
],
"verified": true,
"downloads": 0,
"homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/io.github.yahooyuan666.zcode2pi",
"repository": "https://github.com/vastsa/pi-desktop-plugins",
"readmeMarkdown": "# ZCode Free Quota\n\nUse the free quota that comes with your **ZCode / BigModel Coding Plan** as a model provider inside PI-Desktop.\n\nModel: `GLM-5.3-Flash` (1M context, vision).\n\n\u628a **ZCode / BigModel Coding Plan** \u81ea\u5e26\u7684\u514d\u8d39\u989d\u5ea6\uff0c\u4f5c\u4e3a\u6a21\u578b provider \u63a5\u8fdb PI-Desktop\u3002\n\n\u6a21\u578b\uff1a`GLM-5.3-Flash`\uff081M \u4e0a\u4e0b\u6587\uff0c\u652f\u6301\u8bfb\u56fe\uff09\u3002\n\n---\n\n## How it works\n\n```\nPI-Desktop model picker\n \u2514\u2500 \"ZCode Free Quota\" group (declared in manifest, provider.register)\n \u2514\u2500 baseUrl http://127.0.0.1:41940/v1\n \u2514\u2500 resident service zcode-proxy (background.service, 127.0.0.1 only)\n \u2514\u2500 https://open.bigmodel.cn/api/coding/paas/v4/chat/completions\n```\n\nBoth ends speak OpenAI Chat Completions, so the relay **translates nothing** and\nstreams SSE through chunk by chunk.\n\n\u4e24\u7aef\u90fd\u662f OpenAI Chat Completions \u65b9\u8a00\uff0c\u6240\u4ee5\u4e2d\u7ee7**\u4e0d\u505a\u4efb\u4f55\u8f6c\u6362**\uff0cSSE \u9010\u5757\u900f\u4f20\u3002\n\nThat endpoint is not an arbitrary choice: PI-Desktop's own first-class support path\nfor Zhipu Coding Plan is `apiStyle: \"chat_completions\"` against\n`https://open.bigmodel.cn/api/coding/paas/v4`\n(see [ADR 0155](https://github.com/vastsa/PI-Desktop/blob/main/docs/adr/0155-zhipu-endpoint-presets.md)).\nPointing a `chat_completions` provider at BigModel's *Anthropic* endpoint instead\nfails immediately \u2014 the host sends OpenAI-shaped tools (`{type, function}`) and that\nendpoint rejects them with `body.tools.0.name: Field required`.\n\n\u8fd9\u4e2a\u7aef\u70b9\u4e0d\u662f\u968f\u4fbf\u9009\u7684\uff1aPI-Desktop \u5bf9\u667a\u8c31 Coding Plan \u7684\u4e00\u7b49\u652f\u6301\u8def\u5f84\u5c31\u662f\n`apiStyle: \"chat_completions\"` \u914d `https://open.bigmodel.cn/api/coding/paas/v4`\n\uff08\u89c1 [ADR 0155](https://github.com/vastsa/PI-Desktop/blob/main/docs/adr/0155-zhipu-endpoint-presets.md)\uff09\u3002\n\u53cd\u8fc7\u6765\u628a `chat_completions` \u7684 provider \u6307\u5230 BigModel \u7684 *Anthropic* \u7aef\u70b9\u4f1a\u76f4\u63a5\u5931\u8d25\u2014\u2014\n\u5bbf\u4e3b\u53d1\u7684\u662f OpenAI \u5f62\u72b6\u7684\u5de5\u5177\uff08`{type, function}`\uff09\uff0c\u90a3\u4e2a\u7aef\u70b9\u4f1a\u4ee5\n`body.tools.0.name: Field required` \u62d2\u7edd\u3002\n\n## Setup\n\n1. **Get an API key** from <https://bigmodel.cn/coding-plan/personal/overview>.\n It is the same key your ZCode client uses to sign in to the Coding Plan.\n2. **Install the plugin**, then grant `provider.register` and `background.service`.\n3. **Enter the key** on the provider row in Settings.\n4. Pick `GLM-5.3-Flash` under \"ZCode Free Quota\" in the chat model picker.\n\n1. \u5230 <https://bigmodel.cn/coding-plan/personal/overview> \u7533\u8bf7\u4e00\u628a API Key,\n \u548c ZCode \u5ba2\u6237\u7aef\u767b\u5f55 Coding Plan \u7528\u7684\u662f\u540c\u4e00\u628a\u3002\n2. \u88c5\u597d\u63d2\u4ef6\u540e\uff0c\u6388\u6743 `provider.register` \u4e0e `background.service`\u3002\n3. \u5728\u8bbe\u7f6e\u91cc\u7684\u670d\u52a1\u5546\u884c\u586b\u5165 Key\u3002\n4. \u804a\u5929\u7a97\u6a21\u578b\u9009\u62e9\u5668\u91cc\u9009\u300cZCode\u514d\u8d39\u989d\u5ea6\u300d\u4e0b\u7684 `GLM-5.3-Flash`\u3002\n\n## Your API key never reaches this plugin\n\nThe provider is declared with `authKind: \"api_key\"`, so PI-Desktop keeps the key in\nits own secret store and attaches it to the outgoing request. The relay forwards\nrequest headers unchanged and has no code path that reads, stores or logs a\ncredential. There is no `.env`, no hard-coded key, and nothing to revoke here.\n\nprovider \u58f0\u660e\u7528\u7684\u662f `authKind: \"api_key\"`\uff0cKey \u7531 PI-Desktop \u5b58\u5728\u81ea\u5df1\u7684\u5bc6\u94a5\u5e93\u91cc\u3001\n\u968f\u51fa\u7ad9\u8bf7\u6c42\u9644\u4e0a\u3002\u4e2d\u7ee7\u539f\u6837\u900f\u4f20\u8bf7\u6c42\u5934\uff0c\u4ee3\u7801\u91cc\u6ca1\u6709\u4efb\u4f55\u8bfb\u53d6\u3001\u4fdd\u5b58\u6216\u8bb0\u5f55\u51ed\u636e\u7684\u8def\u5f84\uff0c\n\u6ca1\u6709 `.env`\uff0c\u6ca1\u6709\u5199\u6b7b\u7684 Key\uff0c\u8fd9\u91cc\u4e5f\u6ca1\u6709\u9700\u8981\u540a\u9500\u7684\u4e1c\u897f\u3002\n\n## What the relay does not do\n\n- **It does not force `stream`.** A caller that sends `stream: false` gets a complete\n JSON object back; a caller that sends `stream: true` gets SSE. This is deliberate:\n `JasonYu0822/opencode2pi-desktop` had to force `stream: true` upstream to pass\n OpenCode's anonymous free-lane gate, and that hack is what made non-streaming\n consumers receive unparseable SSE fragments\n ([issue #3](https://github.com/JasonYu0822/opencode2pi-desktop/issues/3)). BigModel's\n Coding Plan has no such gate, so this relay simply forwards what it was given.\n- **It does not inject placeholder tools.** The free-lane gate that\n [issue #1](https://github.com/JasonYu0822/opencode2pi-desktop/issues/1) describes\n (`bash` + `read` stubs) is an OpenCode anonymous-channel requirement, not a\n BigModel one.\n- **It does not rewrite the request body at all.** What the model sees is exactly what\n PI-Desktop sent. `passthrough.test.mjs` asserts this against a local echo upstream.\n\n- **\u4e0d\u5f3a\u5236 `stream`\u3002** \u53d1 `stream: false` \u7684\u8c03\u7528\u65b9\u62ff\u56de\u5b8c\u6574 JSON \u5bf9\u8c61\uff0c\u53d1 `stream: true`\n \u7684\u62ff\u56de SSE\u3002\u8fd9\u662f\u523b\u610f\u7684\uff1a`JasonYu0822/opencode2pi-desktop` \u4e3a\u4e86\u8fc7 OpenCode \u533f\u540d\u901a\u9053\u7684\u95e8\u7981\n \u88ab\u8feb\u5bf9\u4e0a\u6e38\u5f3a\u5236 `stream: true`\uff0c\u800c\u90a3\u4e2a hack \u6b63\u662f\u8ba9\u975e\u6d41\u5f0f\u6d88\u8d39\u8005\u6536\u5230\u65e0\u6cd5\u89e3\u6790\u7684 SSE \u788e\u7247\u7684\u539f\u56e0\n \uff08[issue #3](https://github.com/JasonYu0822/opencode2pi-desktop/issues/3)\uff09\u3002\n BigModel Coding Plan \u6ca1\u6709\u8fd9\u9053\u95e8\uff0c\u6240\u4ee5\u8fd9\u4e2a\u4e2d\u7ee7\u539f\u6837\u8f6c\u53d1\u3002\n- **\u4e0d\u6ce8\u5165\u5360\u4f4d\u5de5\u5177\u3002** [issue #1](https://github.com/JasonYu0822/opencode2pi-desktop/issues/1)\n \u91cc\u7684 `bash` + `read` \u5360\u4f4d\u6869\u662f OpenCode \u533f\u540d\u901a\u9053\u7684\u8981\u6c42\uff0c\u4e0d\u662f BigModel \u7684\u3002\n- **\u5b8c\u5168\u4e0d\u6539\u5199\u8bf7\u6c42\u4f53**\uff0c\u6a21\u578b\u770b\u5230\u7684\u5c31\u662f PI-Desktop \u53d1\u51fa\u7684\u539f\u6837\u3002\n `passthrough.test.mjs` \u7528\u672c\u5730\u56de\u663e\u4e0a\u6e38\u5bf9\u8fd9\u4e00\u70b9\u505a\u4e86\u65ad\u8a00\u3002\n\n## Ports\n\nThe relay prefers `41940` and falls back to `41941`, `41942` if those are taken, so a\nstale process from a previous session cannot silently hijack the provider.\n\n\u4e2d\u7ee7\u4f18\u5148\u7528 `41940`\uff0c\u88ab\u5360\u7528\u5219\u987a\u5ef6\u5230 `41941`/`41942`\uff0c\u907f\u514d\u4e0a\u4e2a\u4f1a\u8bdd\u7684\u6b8b\u7559\u8fdb\u7a0b\u6084\u6084\u5360\u4f4f\u3002\n\n## Health check\n\n```bash\ncurl http://127.0.0.1:41940/healthz\n```\n\nReturns the bound port, the upstream URL, request/failure counters and the last error.\nOn an upstream 4xx/5xx the relay also logs one line describing the request's field\nnames and counts \u2014 never content, never credentials.\n\n\u8fd4\u56de\u7ed1\u5b9a\u7aef\u53e3\u3001\u4e0a\u6e38\u5730\u5740\u3001\u8bf7\u6c42\u4e0e\u5931\u8d25\u8ba1\u6570\u3001\u6700\u8fd1\u4e00\u6b21\u9519\u8bef\u3002\u4e0a\u6e38\u62a5 4xx/5xx \u65f6\u8fd8\u4f1a\u6253\u4e00\u884c\n\u8bf7\u6c42\u91cc\u6709\u54ea\u4e9b\u5b57\u6bb5\u3001\u5404\u591a\u5c11\u4e2a\u2014\u2014\u7edd\u4e0d\u6253\u5185\u5bb9\u6216\u51ed\u636e\u3002\n\n## Permissions\n\n| Permission | Why |\n|---|---|\n| `provider.register` | Materialize the declared provider row in the model picker |\n| `background.service` | Run the 127.0.0.1 relay the provider's `baseUrl` points at |\n\nNo network, filesystem, clipboard or shell permission is requested. The relay opens no\nlistening socket on anything but loopback, and its only outbound destination is\n`open.bigmodel.cn`.\n\n## Tests\n\n```bash\nnode passthrough.test.mjs\n```\n\nPoints the relay at a local echo upstream and asserts request/response fidelity \u2014\n12 checks covering byte-identical request bodies, unforced `stream`, non-streaming\ncallers receiving JSON instead of SSE, SSE chunk order, and the absence of injected\ntools or `tool_choice`.\n\n## Credits\n\nThe provider-declaration + loopback-relay shape follows\n[`JasonYu0822/opencode2pi-desktop`](https://github.com/JasonYu0822/opencode2pi-desktop).\nThe `buildStoreZip` packaging format was reverse-engineered from PI-Desktop's own\n`packages/plugin-devkit/src/pack.ts`.\n\n## License\n\nMIT",
"safetyNotes": "The relay binds 127.0.0.1 only and rejects any request whose Host header is not loopback. Its one and only network destination is open.bigmodel.cn. It never reads, stores or logs your API key: PI-Desktop attaches the key from its own secret store to the outgoing request and the relay forwards request headers unchanged. It does not read or write any file, touch the clipboard, run a shell, or load remote code. On an upstream error it logs one line describing the request's field names and counts only \u2014 never message content, tool arguments or credentials. It rewrites nothing in the request body, so what the model sees is exactly what PI-Desktop sent.",
"versions": [
{
"version": "0.1.0",
"publishedAt": "2026-10-02T17:42:29Z",
"changelog": "Release 0.1.0: first release. Declares GLM-5.3-Flash over BigModel's OpenAI-compatible Coding Plan endpoint (the wire style PI-Desktop uses natively for Zhipu Coding Plan, see PI-Desktop ADR 0155), so no protocol translation is involved and SSE is forwarded chunk by chunk. Request bodies are passed through byte for byte: `stream` is never forced, placeholder tools are never injected, and a non-streaming caller gets a complete JSON object back rather than SSE fragments. The relay binds loopback only, rejects non-loopback Host headers, and never touches the API key. 0.1.0\uff1a\u9996\u4e2a\u7248\u672c\u3002\u7ecf BigModel \u7684 OpenAI \u517c\u5bb9 Coding Plan \u7aef\u70b9\u63a5\u5165 GLM-5.3-Flash\uff08\u8fd9\u662f PI-Desktop \u5bf9\u667a\u8c31 Coding Plan \u539f\u751f\u4f7f\u7528\u7684\u7ebf\u8def\uff0c\u89c1 ADR 0155\uff09\uff0c\u56e0\u6b64\u4e0d\u6d89\u53ca\u534f\u8bae\u8f6c\u6362\uff0cSSE \u9010\u5757\u900f\u4f20\u3002\u8bf7\u6c42\u4f53\u9010\u5b57\u8282\u900f\u4f20\uff1a\u4e0d\u5f3a\u5236 stream\u3001\u4e0d\u6ce8\u5165\u5360\u4f4d\u5de5\u5177\uff0c\u975e\u6d41\u5f0f\u8c03\u7528\u65b9\u62ff\u5230\u7684\u662f\u5b8c\u6574 JSON \u5bf9\u8c61\u800c\u4e0d\u662f SSE \u788e\u7247\u3002\u4e2d\u7ee7\u53ea\u7ed1\u56de\u73af\u3001\u62d2\u7edd\u975e\u56de\u73af Host\u3001\u4e0d\u63a5\u89e6 API Key\u3002",
"minPiDesktop": ">=0.9.0",
"shasum": "a779a30bd19f09014914c4d556802f791ad0753526dae7f41f774925a879f6a7",
"url": "packages/io.github.yahooyuan666.zcode2pi-0.1.0.piplug",
"sizeBytes": 28465,
"permissions": [
"provider.register",
"background.service"
],
"fs": {}
}
]
},
{
"id": "local.pi-desktop-install-guard",
"name": "\u4e00\u6b21\u88c5\u5230\u4f4d",
Expand Down
Binary file not shown.
Loading
Loading