From 849fa57078a61eea14a12e546ef5eb49312130dd Mon Sep 17 00:00:00 2001 From: xingleiwu Date: Mon, 14 Sep 2026 13:06:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(pi.workspace-file-guard):=200.2.8=20?= =?UTF-8?q?=E4=BB=8B=E7=BB=8D=E3=80=81=E5=B7=A5=E5=85=B7=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E5=92=8C=20changelog=20=E5=85=A8=E9=83=A8=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E4=B8=AD=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 市场 i18n.en 与 zh-CN 使用同一套中文文案;manifest / registerTool 描述改为中文。 --- catalog.json | 314 ++++-------------- packages/pi.workspace-file-guard-0.2.8.piplug | Bin 0 -> 41528 bytes plugins/pi.workspace-file-guard/README.md | 2 +- plugins/pi.workspace-file-guard/main.js | 35 +- plugins/pi.workspace-file-guard/manifest.json | 32 +- tests/workspace-file-guard-main.test.js | 2 +- 6 files changed, 101 insertions(+), 284 deletions(-) create mode 100644 packages/pi.workspace-file-guard-0.2.8.piplug diff --git a/catalog.json b/catalog.json index dfed967..7d8499e 100644 --- a/catalog.json +++ b/catalog.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "providerId": "official", "name": "PI-Desktop Official Plugins", - "updatedAt": "2026-09-14T04:38:39Z", + "updatedAt": "2026-09-14T05:06:41Z", "homepage": "https://github.com/vastsa/pi-desktop-plugins", "plugins": [ { @@ -35,7 +35,7 @@ "versions": [ { "version": "0.3.3", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.3.3: fills the v3 panel surface, improves responsive spacing and focus states, and keeps the host window-control capsule synchronized with theme changes. Release 0.3.2: migrates the panel to v3 paint-through chrome so top-band controls remain clickable while blank space remains draggable. Release 0.3.1: refreshes the panel surface to match PI-Desktop's compact neutral design system.", "minPiDesktop": ">=0.2.0", "shasum": "6c3d3fcded92d15ab78552671fcac4687e26324d8ac6ed5df5452dffb153ee4b", @@ -81,7 +81,7 @@ "versions": [ { "version": "0.2.3", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.2.3: makes the editor use the full panel height with a stable responsive action row and synchronized host capsule colors. Release 0.2.2: migrates the panel to v3 paint-through chrome so top-band controls remain clickable while blank space remains draggable. Release 0.2.1: refreshes the notes panel controls, editor surface, focus states, and responsive spacing.", "minPiDesktop": ">=0.2.0", "shasum": "7a094cba0dc998ec4d628b4abfe731b7fd44a9af79f89e5e99ad370832d83a65", @@ -133,7 +133,7 @@ "versions": [ { "version": "0.2.3", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.2.3: lets the summary output fill the remaining panel height, keeps its internal scroll local, and synchronizes the host capsule with theme changes. Release 0.2.2: migrates the panel to v3 paint-through chrome so top-band controls remain clickable while blank space remains draggable. Release 0.2.1: refreshes the summary panel hierarchy, cards, controls, and narrow-window layout. Initial practical template: workspace inventory, README preview, copy summary, agent tool.", "minPiDesktop": ">=0.2.0", "shasum": "41d951ab4d95ead69f4f9a7d6fb0ba18a560185919fca7ce076c13e8c4d84711", @@ -150,131 +150,6 @@ } ] }, - { - "id": "io.github.liushunqiu.pi-idea-git", - "name": "IDEA Git", - "description": "An IntelliJ-IDEA-style Git tool window for PI-Desktop: staged/unstaged change lists, hunk-level stage & revert, commit, branch switcher, graph log and stashes. IDEA Git \u98ce\u683c\u7684 Git \u5de5\u5177\u7a97\u53e3\uff1a\u6682\u5b58/\u672a\u6682\u5b58\u5206\u7ec4\u3001\u6309\u4ee3\u7801\u5757\u6682\u5b58\u4e0e\u8fd8\u539f\u3001\u63d0\u4ea4\u3001\u5206\u652f\u5207\u6362\u3001\u56fe\u5f62\u5316\u65e5\u5fd7\u4e0e\u50a8\u85cf\u3002", - "i18n": { - "en": { - "name": "IDEA Git", - "description": "An IntelliJ-IDEA-style Git tool window for PI-Desktop: staged/unstaged change lists, hunk-level stage & revert, commit, branch switcher, graph log and stashes.", - "safetyNotes": "Reads workspace files through the host fs APIs (Open File / Reveal only); discarding an untracked file deletes it (with a confirmation dialog) \u2014 every other write goes through Git commands. Commit-message generation calls the host model with your own model setup and quota (host rate limit 8/min); the plugin holds no API keys, makes no network requests, no telemetry. HTTPS credentials come from your own Git credential helper; keys that live only in ssh-agent do not work \u2014 use an HTTPS remote or a keychain-backed key." - }, - "zh-CN": { - "name": "IDEA Git", - "description": "PI-Desktop \u7684 IDEA \u98ce\u683c Git \u5de5\u5177\u7a97\u53e3\uff1a\u6682\u5b58/\u672a\u6682\u5b58\u5206\u7ec4\u3001\u6309\u4ee3\u7801\u5757\u6682\u5b58\u4e0e\u8fd8\u539f\u3001\u63d0\u4ea4\u3001\u5206\u652f\u5207\u6362\u3001\u56fe\u5f62\u5316\u65e5\u5fd7\u4e0e\u50a8\u85cf\u3002", - "safetyNotes": "\u53ea\u8bfb\u5de5\u4f5c\u533a\u6587\u4ef6\uff08Open File / Reveal \u8d70\u5bbf\u4e3b fs \u63a5\u53e3\uff09\uff1b\u4e22\u5f03\u672a\u8ddf\u8e2a\u6587\u4ef6\u65f6\u4f1a\u76f4\u63a5\u5220\u9664\u8be5\u6587\u4ef6\uff08\u64cd\u4f5c\u524d\u6709\u786e\u8ba4\u6846\uff09\uff0c\u5176\u4f59\u5199\u64cd\u4f5c\u4e00\u5f8b\u8d70 Git \u547d\u4ee4\u3002\u751f\u6210\u63d0\u4ea4\u4fe1\u606f\u8c03\u7528\u5bbf\u4e3b\u6a21\u578b\uff0c\u7528\u7684\u662f\u4f60\u81ea\u5df1\u7684\u6a21\u578b\u914d\u7f6e\u4e0e\u989d\u5ea6\uff08\u5bbf\u4e3b\u9650\u6d41 8 \u6b21/\u5206\uff09\uff0c\u63d2\u4ef6\u4e0d\u6301\u6709\u4efb\u4f55 API Key\uff0c\u4e0d\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\uff0c\u65e0\u9065\u6d4b\u3002HTTPS \u51ed\u636e\u8d70\u4f60\u81ea\u5df1\u7684 Git \u51ed\u636e\u52a9\u624b\uff1b\u53ea\u6d3b\u5728 ssh-agent \u91cc\u7684\u5bc6\u94a5\u7528\u4e0d\u4e86\uff0c\u8bf7\u7528 HTTPS \u8fdc\u7aef\u6216\u94a5\u5319\u4e32\u5bc6\u94a5\u3002" - } - }, - "author": "liushunqiu", - "categories": [ - "developer-tools", - "productivity" - ], - "verified": true, - "downloads": 0, - "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/io.github.liushunqiu.pi-idea-git", - "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# IDEA Git \u2014\u2014 PI-Desktop \u7684 IntelliJ IDEA \u98ce\u683c Git \u5de5\u5177\u7a97\u53e3\n\n`io.github.liushunqiu.pi-idea-git` \u628a IntelliJ IDEA \u7684 Git \u754c\u9762\u642c\u8fdb PI-Desktop\uff1a\u4f60\u771f\u7684\u4f1a\u4e00\u76f4\u5f85\u5728\u91cc\u9762\u7684\u90a3\u4e24\u4e2a\n\u5de5\u5177\u7a97\u53e3\u3001\u6682\u5b58/\u672a\u6682\u5b58\u5206\u7ec4\u3001\u6309\u4ee3\u7801\u5757\uff08hunk\uff09\u6682\u5b58\u3001\u56fe\u5f62\u5316\u65e5\u5fd7\u4e0e Console\u3002\n\n\u8fd9\u91cc\u7684\u6bcf\u4e00\u4e2a Git \u52a8\u4f5c\u90fd\u662f**\u771f\u7684\u53bb\u8c03 `git`**\uff0c\u5bf9\u7740\u771f\u5b9e\u7684\u7d22\u5f15\u5e72\u6d3b\u3002\u6ca1\u6709\u4efb\u4f55\u529f\u80fd\u662f\u5728\u6e32\u67d3\u5c42\n\u5047\u88c5\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u7ec8\u7aef\u91cc\u7684 `git status` \u6c38\u8fdc\u548c\u9762\u677f\u663e\u793a\u4e00\u81f4\u3002\n\n\u2014\u2014 \u4ee5\u4e0b\u5185\u5bb9\u6309\u300c\u80fd\u770b\u5230\u4ec0\u4e48 \u2192 \u600e\u4e48\u7528 \u2192 \u4e3a\u4ec0\u4e48\u8fd9\u6837\u5b9e\u73b0 \u2192 \u600e\u4e48\u6539\u300d\u6392\u5217\u3002\n\n| \u7ae0\u8282 | \u5185\u5bb9 |\n| --- | --- |\n| \u754c\u9762\u4e0e\u529f\u80fd | \u4e24\u4e2a\u89c6\u56fe\u3001Changes \u533a\u3001diff \u9762\u677f\u3001Log/Console \u5168\u90e8\u80fd\u529b\u8868 |\n| \u5feb\u6377\u952e | \u7ed1\u5b9a\u8868\uff0c\u4ee5\u53ca\u300c\u7126\u70b9\u5728\u54ea\u51b3\u5b9a\u8c01\u80fd\u6536\u5230\u6309\u952e\u300d |\n| \u4e0e IDEA \u7684\u6709\u610f\u5dee\u5f02 | \u54ea\u4e9b\u5730\u65b9\u523b\u610f\u4e0d\u7167\u6284 |\n| \u6743\u9650 | 6 \u9879\u6743\u9650\u5404\u81ea\u4e3a\u4ec0\u4e48\u9700\u8981 |\n| \u5de5\u7a0b\u7ed3\u6784 | \u6e90\u7801\u5e03\u5c40\u3001\u4e3a\u4ec0\u4e48\u5fc5\u987b\u6784\u5efa\u3001\u751f\u6210\u7269\u4e3a\u4ec0\u4e48\u4e0d\u80fd\u624b\u6539 |\n| \u5f15\u64ce\u8bbe\u8ba1 | \u89c6\u56fe\u5982\u4f55\u4e0e Git \u901a\u4fe1\u3001\u73af\u5883\u8865\u9f50\u3001\u72b6\u6001\u4e0e\u8865\u4e01\u7684\u5173\u952e\u53d6\u820d |\n| \u4e00\u4e2a\u9879\u76ee\u91cc\u7684\u591a\u4e2a\u4ed3\u5e93 | \u5b50\u6a21\u5757\u4e0e\u5d4c\u5957\u4ed3\u5e93\u7684\u8bc6\u522b\u3001Root \u9009\u62e9\u5668\u4e0e\u5176\u8fb9\u754c |\n| \u8fdc\u7aef\u540c\u6b65 | \u63a8\u9001\u88ab\u62d2\u3001\u5206\u53c9\u3001\u51b2\u7a81\u3001\u4ee5\u53ca\u672a\u5b8c\u6210\u5408\u5e76\u7684\u51fa\u8def |\n| \u8ba4\u8bc1 | \u4e3a\u4ec0\u4e48\u63d2\u4ef6\u4e0d\u9700\u8981\u51ed\u636e\uff0c\u4ee5\u53ca\u552f\u4e00\u505a\u4e0d\u5230\u7684\u4e8b |\n| \u751f\u6210\u63d0\u4ea4\u4fe1\u606f | \u7528\u5bbf\u4e3b\u6a21\u578b\u8d77\u8349\uff0c\u8bed\u8a00/\u683c\u5f0f/\u8303\u56f4\u5982\u4f55\u5904\u7406 |\n| \u914d\u8272 | \u54ea\u4e9b\u53d6\u81ea JetBrains \u6587\u6863\uff0c\u54ea\u4e9b\u662f\u523b\u610f\u7684\u504f\u79bb |\n| \u6d4b\u8bd5\u4e0e\u5de5\u5177 | harness / smoke / drive / \u51b3\u7b56\u7b14\u8bb0\u95e8\u7981 |\n| \u5f00\u53d1\u4e0e\u6253\u5305 | \u52a0\u8f7d\u672c\u5730\u63d2\u4ef6\u3001\u6784\u5efa\u3001\u6253\u5305\u542b\u6743\u9650\u6269\u5f20\u7684\u5751 |\n| \u5df2\u77e5\u7f3a\u53e3 | \u8bda\u5b9e\u6e05\u5355\uff1a\u54ea\u4e9b\u63a7\u4ef6\u65e0\u6548\u3001\u54ea\u4e9b\u80fd\u529b\u53d7\u9650 |\n| \u8bb0\u5fc6\u4e0e\u51b3\u7b56\u7b14\u8bb0 | `.memories/`\u3001`.agents/notes/` \u4e0e\u53cd\u5411\u7d22\u5f15 |\n\n## \u754c\u9762\u4e0e\u529f\u80fd\n\n\u5de5\u4f5c\u9762\u677f\u91cc\u6709\u4e24\u4e2a docked \u89c6\u56fe\uff0c\u5bf9\u5e94 IDEA \u7684\u4e24\u4e2a\u5de5\u5177\u7a97\u53e3\uff1a\n\n| \u9762\u677f | \u5bf9\u5e94 IDEA | \u5185\u5bb9 |\n| --- | --- | --- |\n| **\u63d0\u4ea4**\uff08`views/commit.html`\uff09 | Commit \u5de5\u5177\u7a97\u53e3\uff0c`Alt+0` | Changes \u533a\uff08Staged / Unstaged / Unversioned Files / Merge Conflicts\uff09\u3001\u9009\u4e2d\u6587\u4ef6\u7684 diff\u3001\u5e26\u5386\u53f2\u7684\u63d0\u4ea4\u4fe1\u606f\u6846\u3001Amend\u3001Sign-off\u3001Commit\u3001Commit and Push |\n| **Git**\uff08`views/git.html`\uff09 | Git \u5de5\u5177\u7a97\u53e3\uff0c`Alt+9` | **Log** \u9875\u7b7e\uff08\u5206\u652f\u9762\u677f\u3001\u5e26\u56fe\u5f62\u4e0e\u5f15\u7528\u5fbd\u6807\u7684\u63d0\u4ea4\u5217\u8868\u3001changed files\u3001commit details\uff09\u4e0e **Console** \u9875\u7b7e |\n\n> `Alt+0` / `Alt+9` \u662f IDEA \u81ea\u5df1\u7684\u7ed1\u5b9a\uff0c\u63d2\u4ef6**\u6ca1\u6709**\u6ce8\u518c\u70ed\u952e\uff08`manifest.json` \u91cc\u6ca1\u6709\n> `keybindings` \u6bb5\uff09\uff1b\u8fd9\u91cc\u53ea\u662f\u544a\u8bc9\u4f60\u5b83\u4eec\u5728 IDEA \u91cc\u5bf9\u5e94\u4ec0\u4e48\u3002\n\n\u547d\u4ee4\u9762\u677f\u91cc\u53e6\u6709\u4e24\u6761\u547d\u4ee4\uff1a`IDEA Git: Open as a separate window`\uff08\u628a\u4e24\u4e2a\u7a97\u53e3\u5e76\u5230\u4e00\u4e2a\u6807\u7b7e\u680f\u91cc\uff0c\n\u5bbd\u5c4f\u7528\uff0c\u52a0\u8f7d `renderer/index.html`\uff09\u4e0e `IDEA Git: Refresh repository`\u3002\u63d2\u4ef6\u5728\u542f\u52a8\u65f6\u6fc0\u6d3b\n\uff08`activationEvents: onStartup`\uff09\u3002\n\n### \u529f\u80fd\u5bf9\u7167\u8868\uff08\u7528 IDEA \u81ea\u5df1\u7684\u8bf4\u6cd5\uff09\n\n| \u529f\u80fd | \u4f4d\u7f6e | \u8bf4\u660e |\n| --- | --- | --- |\n| `Staged` / `Unstaged` / `Unversioned Files` / `Merge Conflicts` | \u63d0\u4ea4 \u2192 Changes \u533a | \u6309**\u76ee\u5f55\u6811**\u5206\u7ec4\uff0c\u6bcf\u4e2a\u6587\u4ef6\u843d\u5728\u5b83\u6240\u5c5e\u7684\u6587\u4ef6\u5939\u4e0b\u3002\u6587\u4ef6\u5939\u7684\u52fe\u9009\u662f\u7ea7\u8054\u7684\uff1a\u52fe\u4e0a\u4f1a\u628a\u5176\u4e0b\u6240\u6709\u6587\u4ef6\uff08\u542b\u66f4\u6df1\u5c42\u76ee\u5f55\uff09\u52a0\u5165\u7d22\u5f15\uff0c\u53d6\u6d88\u5219\u6574\u68f5\u5b50\u6811\u79fb\u51fa\u7d22\u5f15\u3002\u540c\u65f6\u6709\u5df2\u6682\u5b58\u4e0e\u672a\u6682\u5b58\u6539\u52a8\u7684\u6587\u4ef6\u4f1a**\u540c\u65f6\u51fa\u73b0\u5728\u4e24\u7ec4\u91cc**\u2014\u2014Git \u81ea\u5df1\u5c31\u662f\u8fd9\u4e48\u62a5\u7684 |\n| \u89c6\u56fe\u9009\u9879\uff08\u9f7f\u8f6e\uff09 | \u63d0\u4ea4 \u2192 Changes \u5934\u90e8 | `Group by Directory`\uff08\u76ee\u5f55\u6811\uff09\u4e0e\u5e73\u94fa\u6a21\u5f0f\u5207\u6362\uff08\u5173\u6389\u5b83\u5c31\u662f\u5e73\u94fa\uff09\u3001`Compact Middle Directories`\uff08`src/views/app` \u5408\u6210\u4e00\u884c\uff09\u3001`Collapse All`\u3001\u4ee5\u53ca\u300c\u5168\u90e8\u52a0\u5165\u7d22\u5f15 / \u5168\u90e8\u79fb\u51fa\u7d22\u5f15\u300d\u4e24\u4e2a\u52a8\u4f5c\u3002\u4e24\u4e2a\u89c6\u56fe\u9009\u9879\u90fd\u4f1a\u6301\u4e45\u5316 |\n| \u8fc7\u6ee4\u53d8\u66f4 | \u63d0\u4ea4 \u2192 Changes \u5934\u90e8 | \u628a\u6811\u6536\u7a84\u5230\u5339\u914d\u7684\u6587\u4ef6\u3001\u5e76\u4fdd\u7559\u5176\u7956\u5148\u76ee\u5f55\uff1b\u5206\u7ec4\u6807\u9898\u663e\u793a `matched/total`\u3002`Esc` \u6e05\u7a7a |\n| `Commit Message` + \u63d0\u4ea4\u4fe1\u606f\u5386\u53f2 | \u63d0\u4ea4 \u2192 \u5e95\u90e8 | \u65f6\u949f\u6309\u94ae\u56de\u653e\u4e4b\u524d\u5199\u8fc7\u7684\u4fe1\u606f\uff0c\u6700\u65b0\u5728\u524d\uff0c\u8de8\u91cd\u542f\u4fdd\u7559\uff08\u672c\u5730\u65e0\u5386\u53f2\u65f6\u7ed9\u63d0\u793a\uff0c\u83dc\u5355\u5e95\u90e8\u6709 `Clear All`\uff09 |\n| `Generate Commit Message` | \u63d0\u4ea4 \u2192 \u5e95\u90e8 | \u7528**\u5bbf\u4e3b\u81ea\u5df1\u7684\u6a21\u578b**\u8d77\u8349\u4fe1\u606f\u3002\u63cf\u8ff0\u5f53\u524d\u9009\u4e2d\u7684\u6587\u4ef6\uff1b\u6ca1\u9009\u6587\u4ef6\u65f6\u63cf\u8ff0\u6240\u6709\u5df2\u6682\u5b58\u5185\u5bb9\uff1b\u7bad\u5934\u83dc\u5355\u7528\u6765\u6311\u6a21\u578b |\n| `Amend`\u3001`Sign-off commit` | \u63d0\u4ea4 \u2192 \u5e95\u90e8 | `--amend`\u3001`--signoff` |\n| `Commit`\u3001`Commit and Push` | \u63d0\u4ea4 \u2192 \u5e95\u90e8 | \u62c6\u5206\u6309\u94ae\uff1b\u4e0b\u62c9\u91cc\u8fd8\u6709 Amend / Sign-off / \u56de\u6eda\uff08\u628a\u5df2\u6682\u5b58\u5185\u5bb9\u5168\u90e8\u79fb\u51fa\u7d22\u5f15\uff09 |\n| \u6bcf\u4e2a\u4ee3\u7801\u5757\u7684 `Include into commit` | \u63d0\u4ea4 \u2192 diff \u9762\u677f | **\u5c40\u90e8\u63d0\u4ea4**\u3002\u6bcf\u4e2a hunk \u5e26\u4e00\u4e2a\u52fe\u9009\u6846\uff1b\u5207\u6362\u5b83\u65f6\u7528\u91cd\u5efa\u51fa\u6765\u7684\u8865\u4e01\u8dd1 `git apply --cached`\uff08\u6216 `-R`\uff09\uff0c\u4e8e\u662f\u53ea\u6709\u88ab\u9009\u4e2d\u7684 hunk \u8fdb\u5165\u8fd9\u6b21\u63d0\u4ea4 |\n| `Stage Hunk` / `Discard Hunk` / `Unstage Hunk` | \u63d0\u4ea4 \u2192 diff \u9762\u677f | \u9f20\u6807\u60ac\u505c\u5230\u5de5\u4f5c\u533a diff \u7684 hunk \u5934\u65f6\u51fa\u73b0\uff1b\u5df2\u6682\u5b58 diff \u4e0a\u5219\u662f\u53cd\u5411\u7684 `Unstage Hunk` |\n| hunk \u5934\u4e0a\u7684\u9644\u6ce8 | \u63d0\u4ea4 \u2192 diff \u9762\u677f | \u7eaf\u7a7a\u767d hunk \u6807 `\u00b7 whitespace only`\uff1b\u5b50\u6a21\u5757\u6307\u9488\u53d8\u5316\u6807 `\u00b7 submodule abc1234 \u2192 def5678` |\n| `Show Diff`\u3001`Rollback`\u3001`Add`/`Remove from index`\u3001`Open File`\u3001`Reveal in File Manager`\u3001`Copy Hash` | \u63d0\u4ea4 \u2192 \u6587\u4ef6\u53f3\u952e\u83dc\u5355 | `Rollback` \u4f1a\u5148\u786e\u8ba4\uff1b\u5b83\u4f1a\u5220\u9664\u672a\u8ddf\u8e2a\u6587\u4ef6\u3001\u8fd8\u539f\u5df2\u8ddf\u8e2a\u6587\u4ef6 |\n | \u5206\u652f\u63a7\u4ef6\uff08`main \u21912 \u21931`\uff09 | \u4e24\u4e2a\u5de5\u5177\u680f | \u5206\u652f\u540d\u3001\u9886\u5148/\u843d\u540e\uff0c\u70b9\u5f00\u662f\u672c\u5730/\u8fdc\u7aef\u5206\u652f\u5217\u8868\uff0c\u70b9\u4e00\u884c\u5373 checkout\uff1b`New Branch`\u3001`Merge into Current\u2026`\u3001`Rebase Current onto\u2026`\u3001`Rename`\u3001`Set/Unset Upstream`\u3001`Delete\u2026`\u3001`Fetch`\u3001`Pull`\u3001`Push`\u3001`Force Push (with lease)`\u3001`Stash Changes` \u4e0e\u50a8\u85cf\u5217\u8868\uff08Apply/Pop/Drop\uff09\u3002\uff08\u5206\u652f\u7684**\u5b8c\u6574\u53f3\u952e\u52a8\u4f5c\u83dc\u5355\u5728 Git \u89c6\u56fe\u7684 `Branches` \u9762\u677f**\u91cc\uff0c\u5de5\u5177\u680f\u5f39\u5c42\u662f\u5e38\u7528\u5b50\u96c6\uff09 |\n| \u4ed3\u5e93\u63a7\u4ef6\uff08`mod \u00b7 submodule`\uff09 | \u4e24\u4e2a\u5de5\u5177\u680f | \u5217\u51fa\u5de5\u4f5c\u533a\u4ed3\u5e93\u4ee5\u53ca\u5d4c\u5957\u5728\u5b83\u91cc\u9762\u7684\u6bcf\u4e00\u4e2a\u4ed3\u5e93\u2014\u2014\u5b50\u6a21\u5757\u3001\u4ee5\u53ca\u6070\u597d\u4f4f\u5728\u8fd9\u91cc\u7684\u514b\u9686\u2014\u2014\u9009\u4e2d\u5b83\u5c31\u628a\u6574\u4e2a\u5de5\u5177\u7a97\u53e3\u5bf9\u51c6\u90a3\u4e2a\u4ed3\u5e93\u3002\u53ea\u6709\u4e00\u4e2a\u4ed3\u5e93\u65f6\uff08\u5355\u4ed3\u5e93\u9879\u76ee\uff09\u9690\u85cf |\n| `Log`\u3001`Console` | Git \u2192 \u9875\u7b7e | Console \u663e\u793a\u63d2\u4ef6\u8dd1\u8fc7\u7684\u547d\u4ee4\u4e0e\u8f93\u51fa\uff0c\u5931\u8d25\u6807\u7ea2\uff0c\u53ef `Clear All`\uff08\u89c1\u4e0b\u65b9\u300c\u5df2\u77e5\u7f3a\u53e3\u300d\uff1a\u63a2\u6d4b\u578b\u547d\u4ee4\u6210\u529f\u65f6\u4e0d\u8bb0\u5f55\uff09 |\n| \u63d0\u4ea4\u56fe | Git \u2192 Log | \u6cf3\u9053\u7531\u7236\u63d0\u4ea4\u4fe1\u606f\u7b97\u51fa\uff1b\u5206\u652f\u5c16\u7aef\u9ec4\u8272\u3001\u672c\u5730\u5206\u652f\u7eff\u8272\u3001\u8fdc\u7aef\u7d2b\u8272\u3001\u6807\u7b7e\u7070\u8272\u3002\u81ea\u5df1\u7684\u63d0\u4ea4 subject \u52a0\u7c97\uff0c\u5f53\u524d\u5206\u652f\u7684\u884c\u6709\u5e95\u8272 |\n | `Branches` \u9762\u677f | Git \u2192 Log \u2192 \u5de6\u4fa7 | `HEAD`\uff08\u70b9\u4e00\u70b9\u56de\u5230\u5f53\u524d\u63d0\u4ea4\uff09\uff0f`Local branches`\uff0f`Remote branches`\uff08`feature/*` \u8fd9\u7c7b\u6309 `/` \u6298\u6210\u53ef\u5c55\u5f00\u7684\u6587\u4ef6\u5939\uff1b\u70b9\u8fdc\u7aef\u5206\u652f\u4f1a\u81ea\u52a8\u5efa\u672c\u5730\u8ddf\u8e2a\u5206\u652f\uff0c\u4e0d\u518d\u662f detached HEAD\uff09\uff0f`Tags`\uff08\u70b9\u4e00\u70b9\u6309\u8be5\u6807\u7b7e\u8fc7\u6ee4\u65e5\u5fd7\uff09\uff0f`Remotes`\uff08Fetch / Fetch+Prune / \u590d\u5236\u5730\u5740\uff09\uff0f`Stashes`\uff08Show / Apply / Pop / Drop\uff09\u3002\u5206\u652f\u53f3\u952e\uff1a`Checkout`\u3001`New Branch from Here`\u3001`Merge into Current`\u3001`Rebase Current onto Selected`\u3001`Rename`\u3001`Set/Unset Upstream`\u3001`Delete`\uff08\u672a\u5b8c\u5168\u5408\u5e76\u8d70\u4e8c\u6b21\u786e\u8ba4\uff09\u3001`Copy Branch Name`\u3001`Push`\u3001`Fetch` |\n| `Changed Files`\u3001`Commit Details` | Git \u2192 Log \u2192 \u5217\u8868\u4e0b\u65b9 | Details \u663e\u793a\u54c8\u5e0c\u3001\u4f5c\u8005\u3001\u65e5\u671f\u3001subject \u4e0e\u5b8c\u6574\u6b63\u6587 |\n| `Graph Options` | Git \u2192 \u5de5\u5177\u680f | `By commit date` / `Topologically`\u3001`Show First Parent`\u3001`No Merges`\u3001`Show Graph`\u3001\u5404\u9762\u677f\u5f00\u5173 |\n | \u8fc7\u6ee4 | Git \u2192 \u5de5\u5177\u680f | \u6587\u672c\u641c\u7d22\uff08\u672c\u5730 substring\uff09\u3001\u5206\u652f\u8fc7\u6ee4\u3001\u7528\u6237\u8fc7\u6ee4\uff08\u5168\u90e8\uff0f\u53ea\u770b\u6211\u7684\uff09\u3001\u65e5\u671f\u8fc7\u6ee4\uff08\u5168\u90e8\uff0f24 \u5c0f\u65f6\uff0f\u4e00\u5468\uff0f\u4e00\u6708\uff09\u3001\u8def\u5f84\u8fc7\u6ee4\uff08\u670d\u52a1\u7aef `git log -- `\uff0c\u8f93\u5165\u9632\u6296 450ms\u3001\u56de\u8f66\u7acb\u5373\u5237\uff09 |\n | \u63d0\u4ea4\u52a8\u4f5c | Git \u2192 Log \u2192 \u53f3\u952e\u63d0\u4ea4 | `Show Diff`\u3001`Copy Revision Number`\u3001`Copy Message`\u3001`Compare with HEAD`\u3001`Checkout Revision`\u3001`New Branch from Here`\u3001`New Tag`\u3001`Cherry-Pick`\u3001`Revert`\u3001`Reset Current Branch to Here`\uff08soft/mixed/hard\uff09\u3001`Edit Commit Message`\uff08\u4ec5 HEAD\uff09 |\n| `Side-by-side viewer` / `Unified viewer` | diff \u9762\u677f\u5934\u90e8 | \u4e24\u8005\u6e32\u67d3\u540c\u4e00\u4efd\u89e3\u6790\u597d\u7684 hunk |\n| `Ignore Differences` \u2192 `None` / `Ignore whitespaces` | diff \u9762\u677f\u9f7f\u8f6e | \u7531 Git \u81ea\u5df1\u5b9e\u73b0\uff08`git diff -w`\uff09\uff0c\u4e0d\u662f\u628a\u884c\u85cf\u8d77\u6765\u3002\u5f00\u7740\u5b83\u65f6**\u7981\u7528 hunk \u6682\u5b58**\uff0c\u56e0\u4e3a\u5ffd\u7565\u7a7a\u767d\u7684 diff \u4e0d\u662f\u5408\u6cd5\u8865\u4e01 |\n| `Show Whitespaces` | diff \u9762\u677f\u773c\u775b\u56fe\u6807 | \u7a7a\u683c\u6e32\u67d3\u6210 `\u00b7`\uff0c\u5236\u8868\u7b26\u6e32\u67d3\u6210 `\u2192` |\n| `Show Line Numbers` | diff \u9762\u677f\u9f7f\u8f6e / commit diff \u6d6e\u5c42\u5934\u90e8 | \u884c\u53f7\u680f\u3002\u63d0\u4ea4\u89c6\u56fe\u9ed8\u8ba4**\u5173**\u3001\u4e14\u8fd9\u4e2a\u5f00\u5173\u4f1a\u88ab\u8bb0\u4f4f\uff1bcommit diff \u6d6e\u5c42\u9ed8\u8ba4**\u5f00**\uff0c\u4f46\u6bcf\u6b21\u6253\u5f00\u90fd\u56de\u5230\u9ed8\u8ba4\uff08\u6d6e\u5c42\u4e0d\u6301\u4e45\u5316\uff09 |\n| `Collapse Unchanged Fragments` | diff \u9762\u677f | \u957f\u7684\u4e0a\u4e0b\u6587\u4f1a\u6298\u53e0\u6210\u4e00\u884c\u53ef\u70b9\u51fb\u7684\u6761\uff08`\u22ee N \u884c\u672a\u4fee\u6539`\uff09\u3002\u53ea\u5728**\u7edf\u4e00\u89c6\u56fe**\u91cc\u6298\u53e0\uff0c\u5e76\u6392\u89c6\u56fe\u4e0d\u6298 |\n| \u9ad8\u4eae\u5dee\u5f02 | diff \u9762\u677f | **\u8bcd\u7ea7**\uff1a\u884c\u4e2d\u95f4\u53d8\u5316\u7684\u90e8\u5206\u88ab\u6807\u51fa\u6765\uff0c\u4e8e\u662f `1.0.0` \u2192 `1.1.0` \u53ea\u6807\u51fa\u90a3\u4e00\u4e2a\u4e0d\u540c\u7684\u5b57\u7b26 |\n| \u63d0\u4ea4\u533a\u72b6\u6001\u884c | \u63d0\u4ea4 \u2192 \u63d0\u4ea4\u6309\u94ae\u4e0a\u65b9 | \u4e09\u79cd\u72b6\u6001\uff1a\u8fdb\u884c\u4e2d\u7684\u64cd\u4f5c\uff08\u5e26 `Continue`/`Abort`\uff09\u3001\u51b2\u7a81\u63d0\u793a\u3001`Nothing is staged` \u8b66\u544a\uff0c\u5e38\u89c4\u65f6\u663e\u793a\u300c\u5c06\u63d0\u4ea4 N / M \u4e2a\u6587\u4ef6\u300d |\n| Console \u7ec6\u8282 | Git \u2192 Console | \u6bcf\u6761\u547d\u4ee4\u5e26 `[hh:mm:ss]` \u65f6\u95f4\u6233\u3001\u53f3\u4e0a\u89d2\u663e\u793a\u6761\u6570\u3001\u72ec\u7acb\u7684 Refresh\u3001\u7a7a\u6001\u63d0\u793a |\n| \u5de5\u5177\u680f\u53f3\u4fa7 | \u4e24\u4e2a\u5de5\u5177\u680f | \u5f53\u524d\u4ed3\u5e93/\u5de5\u4f5c\u533a\u76ee\u5f55\u540d |\n\n`Ctrl+F5` \u7684\u884c\u4e3a\u2014\u2014\u300c\u6bcf\u4e2a\u52a8\u4f5c\u4e4b\u540e\u90fd\u5237\u65b0\u300d\u2014\u2014\u662f\u5185\u5efa\u7684\uff1a\u4efb\u4f55\u5199\u5165\u52a8\u4f5c\u4e4b\u540e\u90fd\u4f1a\u5237\u65b0\u72b6\u6001\u3001diff \u4e0e\u5217\u8868\u3002\n\n## \u5feb\u6377\u952e\n\n\u5bbf\u4e3b\u5728\u4e3b\u7a97\u53e3\u6e32\u67d3\u5c42\u8dd1\u5e94\u7528\u81ea\u5df1\u7684\u5feb\u6377\u952e\uff0c\u800c\u63d2\u4ef6\u89c6\u56fe\u662f\u72ec\u7acb\u7684 `WebContentsView`\u2014\u2014\u6240\u4ee5**\u7126\u70b9\u5728\u89c6\u56fe\u91cc\u65f6\uff0c\u5bbf\u4e3b\u6536\u4e0d\u5230\u6309\u952e**\u3002\n\u7ed3\u8bba\uff1a**\u51e1\u662f\u6309\u94ae\u5e7f\u544a\u51fa\u6765\u7684\u952e\uff0c\u90fd\u5fc5\u987b\u5728\u9875\u5185\u81ea\u5df1\u7ed1\u5b9a**\uff0c\u4e0b\u9762\u8fd9\u4e9b\u5c31\u662f\uff1a\n\n| \u52a8\u4f5c | macOS | Windows / Linux |\n| --- | --- | --- |\n| \u5237\u65b0 | `\u2318R` | `Ctrl+R` |\n| \u5237\u65b0\uff08IDEA \u7684\u7ed1\u5b9a\uff09 | `\u2303F5` | `Ctrl+F5` |\n| \u52a0\u5165\u7d22\u5f15 | `\u2318\u2325A` | `Ctrl+Alt+A` |\n| \u56de\u6eda\uff08\u5148\u786e\u8ba4\uff09 | `\u2318\u2325Z` | `Ctrl+Alt+Z` |\n| Show Diff | `\u2318D` | `Ctrl+D` |\n| \u63d0\u4ea4\u4fe1\u606f\uff08\u63d0\u4ea4\u89c6\u56fe\uff09 | `\u2318K` | `Ctrl+K` |\n| \u641c\u7d22\u65e5\u5fd7\uff08Git \u89c6\u56fe\uff09 | `\u2318F` | `Ctrl+F` |\n| \u5173\u95ed\u5bf9\u8bdd\u6846 / \u83dc\u5355 / diff | `Esc` | `Esc` |\n| \u5728\u63d0\u4ea4\u5217\u8868\u4e2d\u79fb\u52a8 | `\u2191` `\u2193` | `\u2191` `\u2193` |\n\n\u63d0\u793a\u6587\u6848\u7531\u7ed1\u5b9a\u7684\u540c\u4e00\u4efd\u89c4\u683c\u751f\u6210\uff08`PIG.formatShortcut`\uff09\uff0c\u6240\u4ee5**\u4e0d\u53ef\u80fd\u51fa\u73b0\u300c\u5199\u4e86\u5374\u6309\u4e0d\u51fa\u300d\u7684\u63d0\u793a\u952e**\u2014\u2014\n\u8fd9\u662f\u4e2a\u503c\u5f97\u5728\u8bbe\u8ba1\u4e0a\u6392\u9664\u7684\u9519\u8bef\uff0c\u56e0\u4e3a\u5b83\u76f4\u5230\u6709\u4eba\u53bb\u6309\u624d\u4f1a\u66b4\u9732\u3002\n\n\u4ee3\u7801\u91cc\u8fd8\u7ed1\u4e86\uff1a\u63d0\u4ea4\u884c\u4e0a `Enter` / `Space` \u9009\u4e2d\u8be5\u63d0\u4ea4\uff1b\u5bf9\u8bdd\u6846\u91cc `Enter` \u786e\u8ba4\uff1b\u5f39\u51fa\u83dc\u5355\u6253\u5f00\u65f6\u81ea\u52a8\u805a\u7126\u7b2c\u4e00\u4e2a\u53ef\u9009\u9879\uff1b\n`\u2318\u21e7P` \u4f1a\u5f39\u4e00\u53e5\u63d0\u793a\uff08\u89c1\u4e0b\uff09\u3002\n\n### \u54ea\u4e2a\u952e\u5728\u54ea\u91cc\u6709\u6548\n\n\u5bbf\u4e3b\u7684\u52a0\u901f\u952e\u4e0e\u63d2\u4ef6\u7684\u7ed1\u5b9a\u4f4f\u5728\u4e0d\u540c\u5730\u65b9\uff0c\u6240\u4ee5\u300c\u540c\u4e00\u4e2a\u952e\u5e72\u4ec0\u4e48\u300d\u53d6\u51b3\u4e8e\u7126\u70b9\u5728\u54ea\u3002\u503c\u5f97\u7cbe\u786e\u77e5\u9053\uff1a\n\n| \u6309\u952e | \u5e94\u7528\u5185\uff08\u7126\u70b9\u4e0d\u5728\u89c6\u56fe\u91cc\uff09 | \u672c\u63d2\u4ef6\u89c6\u56fe\u5185 |\n| --- | --- | --- |\n| `\u2318K` / `Ctrl+K` | \u5e94\u7528\u7684**\u4f1a\u8bdd\u641c\u7d22** | **\u63d0\u4ea4\u89c6\u56fe**\uff1a\u805a\u7126\u63d0\u4ea4\u4fe1\u606f\u6846\u3002**Git \u89c6\u56fe**\uff1a\u65e0\uff08\u5e94\u7528\u7684\u641c\u7d22\u5728\u8fd9\u91cc\u591f\u4e0d\u5230\uff09 |\n| `\u2318\u21e7P` / `Ctrl+Shift+P` | \u5e94\u7528\u7684**\u547d\u4ee4\u9762\u677f** | \u6ca1\u7528\u2014\u2014\u6309\u952e\u5230\u4e0d\u4e86\u5e94\u7528\uff0c\u6240\u4ee5\u89c6\u56fe\u4f1a\u660e\u786e\u544a\u8bc9\u4f60\u8be5\u53bb\u54ea\uff08`Alt+Space`\uff09 |\n| `Alt+Space` | \u63d2\u4ef6\u542f\u52a8\u5668 | **\u4e00\u6837\u53ef\u7528\u2014\u2014\u5b83\u662f\u771f\u6b63\u7684\u5168\u5c40\u5feb\u6377\u952e** |\n| `\u2318R` / `Ctrl+R` | \u91cd\u65b0\u52a0\u8f7d | \u5237\u65b0\u4ed3\u5e93 |\n| `\u2318D`\u3001`\u2318\u2325A`\u3001`\u2318\u2325Z`\u3001`\u2318F`\u3001`Esc`\u3001`\u2191` `\u2193` | \u5e94\u7528\u81ea\u5df1\u7684\u542b\u4e49 | \u63d2\u4ef6\u7684\u542b\u4e49\uff0c\u89c1\u4e0a\u8868 |\n\n\u6240\u4ee5\uff1a**\u8981\u8dd1\u5e94\u7528\u7ea7\u547d\u4ee4\uff08\u5305\u62ec `IDEA Git: Open as a separate window`\uff09\uff0c\u6309 `Alt+Space`\uff0c\u6216\u8005\u70b9\u56de\u5e94\u7528\u91cc\u7528 `\u2318\u21e7P`\u3002**\n\u73b0\u5728\u5728\u89c6\u56fe\u91cc\u6309 `\u2318\u21e7P` \u4f1a\u5f39\u4e00\u53e5\u8bf4\u660e\uff0c\u800c\u4e0d\u662f\u6beb\u65e0\u53cd\u5e94\u3002\n\n## \u4e0e IDEA \u7684\u6709\u610f\u5dee\u5f02\n\n- **\u6ca1\u6709\u7f16\u8f91\u5668\u3002** IDEA \u628a diff \u5f00\u5728\u7f16\u8f91\u5668\u6807\u7b7e\u9875\u91cc\uff1b\u8fd9\u91cc\u63d0\u4ea4\u7684 diff \u5f00\u5728 Git \u5de5\u5177\u7a97\u53e3\u5185\u7684\u6d6e\u5c42\u91cc\u3002\n `Jump to Source` \u6362\u6210\u4e86 `Open File`\uff08\u4ea4\u7ed9\u7cfb\u7edf\u9ed8\u8ba4\u7a0b\u5e8f\u6253\u5f00\uff09\u4e0e `Reveal in File Manager`\u3002\n- **\u6ca1\u6709 changelist\u3002** IDEA \u7684 changelist \u662f IDE \u4fa7\u6982\u5ff5\uff0cGit \u91cc\u6ca1\u6709\u5bf9\u5e94\u7269\uff1bStaged/Unstaged \u7684\u5206\u7ec4\u53d6\u4ee3\u4e86\u5b83\u3002\n \u4e00\u4efd\u5de5\u4f5c\u526f\u672c\uff0c\u4e00\u4efd\u53d8\u66f4\u96c6\u3002\n- **\u6ca1\u6709 shelf\u3002** `Stash` \u8986\u76d6 Git \u539f\u751f\u7684\u90a3\u90e8\u5206\u573a\u666f\u3002\n- **\u5e76\u6392\u89c6\u56fe\u4e0d\u8054\u52a8\u6eda\u52a8\u3002** \u5de6\u53f3\u4e24\u680f\u4f5c\u4e3a\u4e00\u4e2a\u7f51\u683c\u4e00\u8d77\u6a2a\u5411\u6eda\u52a8\uff0c\u4e8e\u662f\u4e24\u680f\u6c38\u8fdc\u5728\u540c\u4e00\u4e2a\u504f\u79fb\u4e0a\u3002\n- **`Edit Commit Message` \u53ea\u5bf9\u5c16\u7aef\u63d0\u4ea4\u5f00\u653e**\uff0c\u56e0\u4e3a\u6539\u5199\u66f4\u65e9\u7684\u63d0\u4ea4\u9700\u8981 rebase\u3002\n- **`Ignore whitespaces` \u6a21\u5f0f\u4e0b\u7981\u7528 hunk \u6682\u5b58**\uff0c\u672a\u8ddf\u8e2a\u6587\u4ef6\u4e5f\u7981\u7528\u2014\u2014\u5ffd\u7565\u7a7a\u767d\u7684 diff\u3001\u4ee5\u53ca\u5bf9\u7740 `/dev/null` \u7684 diff\uff0c\n \u90fd\u4e0d\u662f Git \u4f1a\u63a5\u53d7\u7684\u8865\u4e01\u3002\u6574\u6587\u4ef6\u7684 `Add` \u4ecd\u7136\u53ef\u7528\u3002\n- **\u5220\u9664\u884c\u662f\u7ea2\u8272\uff0c\u4e0d\u662f JetBrains \u7684\u7070\u8272**\uff0c\u6697\u8272 diff \u914d\u8272\u662f\u8c03\u51fa\u6765\u7684\u800c\u975e\u7167\u6284\u7684\u3002\u89c1\u300c\u914d\u8272\u300d\u3002\n\n## \u6743\u9650\n\n| \u6743\u9650 | \u4e3a\u4ec0\u4e48 |\n| --- | --- |\n| `ui.panel` | \u72ec\u7acb\u7a97\u53e3\uff08`renderer/index.html`\uff09 |\n| `ui.view` | \u4e24\u4e2a docked \u89c6\u56fe |\n| `clipboard.write` | `Copy Revision Number`\u3001`Copy Hash` \u8fd9\u7c7b\u590d\u5236\u52a8\u4f5c |\n| `fs.read` | \u5bf9\u53d8\u66f4\u6587\u4ef6\u6267\u884c `Open File` \u4e0e `Reveal in File Manager` |\n| `models.list` | \u751f\u6210\u6309\u94ae\u4e0a\u7684\u6a21\u578b\u9009\u62e9\u83dc\u5355 |\n| `agent.complete` | \u7528\u5bbf\u4e3b\u6a21\u578b\u8d77\u8349\u63d0\u4ea4\u4fe1\u606f |\n\n`PluginCheck` \u4f1a\u628a `clipboard.write` \u4e0e `fs.read` \u62a5\u6210 unused\uff0c\u56e0\u4e3a\u5b83\u53ea\u626b `main.js`\uff1b\u8fd9\u4e24\u4e2a\u90fd\u662f\u4ece\u89c6\u56fe\u7ecf\u9762\u677f\u6865\u8c03\u7684\n\uff08`clipboard.writeText` \u5728 `src/common.js`\uff0c`fs.openDefault` / `fs.reveal` \u5728 `src/commit-view.js`\uff09\uff0c\u5c5e\u8bef\u62a5\u3002\n\n`fs` \u7684\u8bfb\u53d6\u8303\u56f4\u58f0\u660e\u4e3a `{\"root\":\"workspace\",\"scope\":[\"**\"]}`\u2014\u2014\u53ea\u8bfb\u5de5\u4f5c\u533a\u3002\n\n**\u552f\u4e00\u4e00\u5904\u63d2\u4ef6\u5199\u5de5\u4f5c\u533a\u7684\u5730\u65b9**\u662f\u4e22\u5f03\u672a\u8ddf\u8e2a\u6587\u4ef6\uff08\u6216\u8fd8\u539f\u672a\u8ddf\u8e2a\u6587\u4ef6\u7684 hunk\uff09\uff1a\u5f15\u64ce\u76f4\u63a5 `fs.rmSync` \u5220\u6587\u4ef6\uff0c\n\u89c6\u56fe\u4fa7\u4f1a\u5148\u786e\u8ba4\u3002\u9664\u6b64\u4e4b\u5916\u4e0d\u78b0\u5de5\u4f5c\u533a\u7684\u6587\u4ef6\u2014\u2014\u6240\u6709\u53d8\u66f4\u90fd\u7ecf\u8fc7 `git`\u3002\n\uff08\u63d2\u4ef6\u53e6\u6709\u4e00\u5904\u5199\u76d8\uff0c\u5199\u7684\u662f\u5b83**\u81ea\u5df1**\u7684\u6570\u636e\u76ee\u5f55\uff1a`prefs.json`\uff0c\u5b58\u63d0\u4ea4\u4fe1\u606f\u5386\u53f2\u4e0e\u89c6\u56fe\u9009\u9879\uff0c\u4e0d\u843d\u5728\u4ed3\u5e93\u91cc\u3002\uff09\n\n## \u5de5\u7a0b\u7ed3\u6784\n\n```\nmain.js Node \u8fdb\u7a0b\uff1aGit \u5f15\u64ce + \u901a\u9053\u8def\u7531\uff08\u7ea6 2600 \u884c\uff09\nsrc/theme.css IDEA \u8c03\u8272\u677f\u4e0e\u7ec4\u4ef6\u6837\u5f0f \u2500\u2510\nsrc/layout.css \u5e03\u5c40\u4e0e\u54cd\u5e94\u5f0f \u2500\u2524\nsrc/common.js \u6865\u3001i18n\u3001\u56fe\u6807\u3001\u5f39\u51fa\u83dc\u5355 \u2500\u2524 tools/build.mjs\nsrc/diff.js \u7edf\u4e00 diff \u89e3\u6790\u4e0e\u6e32\u67d3 \u2500\u2524 \u5185\u8054\u8fdb\nsrc/commit-view.js \u63d0\u4ea4\u5de5\u5177\u7a97\u53e3 \u2500\u2524\nsrc/git-view.js Log + Console\uff0c\u4ee5\u53ca\u542f\u52a8 \u2500\u2518\nviews/commit.html \u751f\u6210\u7269\u2014\u2014\u4e0d\u8981\u624b\u6539\nviews/git.html \u751f\u6210\u7269\u2014\u2014\u4e0d\u8981\u624b\u6539\nrenderer/index.html \u751f\u6210\u7269\u2014\u2014\u4e24\u4e2a\u7a97\u53e3\u5e76\u5230\u4e00\u4e2a\u6807\u7b7e\u680f\ntools/build.mjs \u5185\u8054\u5668\ntools/harness.mjs \u5f15\u64ce\u56de\u5f52\uff08\u771f\u5b9e\u4ed3\u5e93\uff0c136 \u6761\u65ad\u8a00\uff09\ntools/drive.mjs \u4e0d\u5f00 GUI \u76f4\u63a5\u9a71\u52a8\u5f15\u64ce\ntools/smoke.mjs \u7528\u6869 bridge \u6e32\u67d3\u89c6\u56fe\u5230 .smoke/\ntools/notes.mjs \u51b3\u7b56\u7b14\u8bb0\u95e8\u7981\uff08+ tools/agent-notes/ \u7684 vendored \u6821\u9a8c\u5668\uff09\nmanifest.json \u6e05\u5355\uff1a\u89c6\u56fe\u3001\u547d\u4ee4\u3001\u6743\u9650\u3001engines\n```\n\n### \u4e3a\u4ec0\u4e48\u5fc5\u987b\u6709\u6784\u5efa\u6b65\u9aa4\n\n\u5bbf\u4e3b\u7528 `loadURL(pathToFileURL(entry))` \u52a0\u8f7d\u89c6\u56fe\uff0c\u4e5f\u5c31\u662f `file://` URL\uff0c\u800c **Chromium \u62d2\u7edd\u4ece `file://` \u52a0\u8f7d ES module**\n\uff08\u4e0d\u900f\u660e\u6e90\uff09\u3002\u5b98\u65b9\u81ea\u5e26\u63d2\u4ef6\u662f\u9760\u300c\u6bcf\u4e2a\u89c6\u56fe\u4e00\u4e2a\u5de8\u5927\u7684\u81ea\u5305\u542b HTML\u300d\u7ed5\u8fc7\u53bb\u7684\uff1b`tools/build.mjs` \u4ece\u53ef\u8bfb\u7684\u6e90\u7801\u4ea7\u51fa\u540c\u6837\u7684\u5f62\u72b6\uff1a\n\n```bash\nnode tools/build.mjs # \u5199\u51fa views/*.html \u4e0e renderer/index.html\n```\n\n\u6539 `src/`\uff0c\u8dd1\u6784\u5efa\uff0c\u6b63\u5728\u8fd0\u884c\u7684\u5f00\u53d1\u63d2\u4ef6\u4f1a\u70ed\u91cd\u8f7d\u3002\u76f4\u63a5\u6539\u751f\u6210\u51fa\u6765\u7684 HTML \u662f\u767d\u8d39\u529b\u6c14\u2014\u2014\u4e0b\u6b21\u6784\u5efa\u5c31\u8986\u76d6\u4e86\u3002\n\n> \u751f\u6210\u5668\u56fa\u5b9a\u5199 `lang=\"en\"`\uff08`tools/build.mjs`\uff09\uff0c\u4e0e\u754c\u9762\u8bed\u8a00\u65e0\u5173\u3002\u53ea\u5f71\u54cd\u65e0\u969c\u788d\u8bed\u4e49\u4e0e\u5b57\u4f53\u56de\u9000\uff0c\u4e0d\u5f71\u54cd\u663e\u793a\u3002\n\n## \u5f15\u64ce\u8bbe\u8ba1\n\n### \u89c6\u56fe\u600e\u4e48\u8ddf Git \u8bf4\u8bdd\n\n`main.js` \u8dd1\u5728\u4e13\u5c5e Node \u8fdb\u7a0b\u91cc\uff08Electron `utilityProcess`\uff09\uff0c\u6240\u4ee5\u5b83\u6709\u771f\u6b63\u7684 Node API\u3001\u80fd\u8d77 `git` \u8fdb\u7a0b\u3002\n\u89c6\u56fe\u662f\u6c99\u7bb1\u9875\u9762\uff0c\u53ea\u62ff\u5230 `window.pluginBridge`\u3002\u5bbf\u4e3b\u81ea\u5df1\u4e0d\u5b9e\u73b0\u7684\u901a\u9053**\u5168\u90e8**\u8f6c\u53d1\u7ed9\u63d2\u4ef6\u5bfc\u51fa\u7684 `onPanelInvoke`\u2014\u2014\n\u8fd9\u6b63\u662f\u81ea\u5b9a\u4e49\u901a\u9053\u80fd\u5de5\u4f5c\u7684\u539f\u56e0\uff1a\n\n```\n\u89c6\u56fe --pluginBridge.invoke(\"git/\u2026\")--> \u5bbf\u4e3b --> onPanelInvoke --> git\n```\n\n`onPanelInvoke` \u91cc\u4e00\u5171 **36 \u4e2a `git/*` \u901a\u9053**\uff1b\u4e0d\u8ba4\u8bc6\u7684\u901a\u9053\u4f1a\u660e\u786e\u56de `Unsupported channel`\uff0c\u800c\u4e0d\u662f\u9759\u9ed8\u4ec0\u4e48\u90fd\u4e0d\u505a\u3002\n\n### \u4e24\u4e2a\u73af\u5883\u4e8b\u5b9e\u51b3\u5b9a\u4e86\u5f15\u64ce\u7684\u5f62\u72b6\n\n- \u63d2\u4ef6\u8fdb\u7a0b\u53ea\u88ab\u4ea4\u7ed9 `PATH`\u3001`LANG` \u548c\u4e34\u65f6\u76ee\u5f55\u53d8\u91cf\uff0c**\u6ca1\u6709 `HOME`**\uff08Windows \u4e0a\u662f `USERPROFILE`\uff09\uff0c\n \u800c Git \u9700\u8981\u5b83\u6765\u8bfb `~/.gitconfig`\uff08\u8eab\u4efd\u3001\u51ed\u636e\u52a9\u624b\uff09\u3002\u6240\u4ee5\u6bcf\u6b21\u8c03\u7528\u90fd\u81ea\u5df1\u8865\u56de\u53bb\u3002**\u8fd9\u662f\u300c\u96f6\u914d\u7f6e\u8ba4\u8bc1\u300d\u7684\u5b9e\u73b0\u57fa\u7840\u3002**\n- \u6ca1\u6709\u7ec8\u7aef\uff0c\u6240\u4ee5\u4ea4\u4e92\u5f0f\u63d0\u793a\u88ab\u5173\u6389\uff08`GIT_TERMINAL_PROMPT=0`\u3001`GIT_ASKPASS=echo`\u3001`GIT_EDITOR=true`\u2026\uff09\uff0c\n \u4e8e\u662f `push` / `pull` \u4f1a**\u5feb\u901f\u3001\u53ef\u89c1\u5730\u5931\u8d25**\uff0c\u800c\u4e0d\u662f\u5bf9\u7740\u4e00\u4e2a\u6ca1\u4eba\u80fd\u8f93\u5165\u7684\u5bc6\u7801\u6846\u6c38\u8fdc\u6302\u7740\u3002\n\n\u987a\u5e26\u8865\u4e0a\u7684\u8fd8\u6709 `GIT_OPTIONAL_LOCKS=0`\uff08\u8bfb\u64cd\u4f5c\u4e0d\u62ff\u7d22\u5f15\u9501\uff09\u3001`GIT_PAGER=cat`\u3001`GIT_CONFIG_NOSYSTEM` \u515c\u5e95\u3002\n`git` \u53ef\u6267\u884c\u6587\u4ef6\u5728 `PATH` \u4e0e\u4e00\u7ec4\u6807\u51c6\u5b89\u88c5\u8def\u5f84\u91cc\u627e\uff0c\u627e\u4e0d\u5230\u4f1a\u7ed9\u4e00\u6761\u660e\u786e\u7684\u9519\u8bef\uff0c\u800c\u4e0d\u662f\u8ba9\u6bcf\u4e2a\u52a8\u4f5c\u90fd\u83ab\u540d\u5931\u8d25\u3002\n\n### \u547d\u4ee4\u7684\u6267\u884c\u8fb9\u754c\n\n\u5355\u6761\u547d\u4ee4 **25 \u79d2**\u540e SIGKILL\u2014\u2014\u523b\u610f\u77ed\u4e8e\u5bbf\u4e3b\u7684 30 \u79d2\u9762\u677f\u8d85\u65f6\uff0c\u5426\u5219\u8d85\u65f6\u4f1a\u4ee5\u300c\u9762\u677f\u65e0\u54cd\u5e94\u300d\u7684\u5f62\u5f0f\u51fa\u73b0\uff0c\n\u800c\u770b\u4e0d\u5230 Git \u5230\u5e95\u5361\u5728\u54ea\u3002\u6bcf\u6761\u8f93\u51fa\u6d41\u4e0a\u9650 **8 MiB**\uff0c\u8d85\u51fa\u7684\u90e8\u5206\u662f\u5de8\u91cf\u65e5\u5fd7\uff0c\u4e0d\u662f\u4fe1\u606f\u3002\n\n### \u72b6\u6001\u662f\u600e\u4e48\u8bfb\u7684\n\n\u72b6\u6001\u7528 `git status --porcelain=v2 -z` \u8bfb\uff1a`-z` \u662f\u552f\u4e00\u80fd**\u539f\u6837**\u8fd4\u56de\u8def\u5f84\u7684\u5f62\u5f0f\uff0c\u6240\u4ee5\u7a7a\u683c\u4e0e\u975e ASCII \u6587\u4ef6\u540d\u80fd\u6d3b\u4e0b\u6765\uff1b\nv2 \u628a\u7d22\u5f15\u5217\u4e0e\u5de5\u4f5c\u533a\u5217\u5206\u5f00\uff0c\u800c\u8fd9\u4e24\u5217\u6b63\u597d\u5c31\u662f\u754c\u9762\u663e\u793a\u7684\u300c\u5df2\u6682\u5b58 / \u672a\u6682\u5b58\u300d\u3002\n\uff08\u53ea\u6709\u4e00\u5904\u4f8b\u5916\uff1a\u751f\u6210\u63d0\u4ea4\u4fe1\u606f\u65f6\u4e3a\u4e86\u907f\u514d\u91cd\u547d\u540d\u88ab\u91cd\u590d\u63cf\u8ff0\uff0c\u53e6\u8dd1\u4e86\u4e00\u6b21 v1 \u7684 `--porcelain`\u3002\uff09\n\n### diff \u4e0e\u8865\u4e01\n\ndiff \u7528 Git \u9ed8\u8ba4\u7684 `a/`-`b/` \u524d\u7f00\u4ea7\u51fa\uff0c\u56e0\u4e3a `git apply` \u4f1a\u5265\u6389\u4e00\u4e2a\u524d\u5bfc\u8def\u5f84\u5206\u91cf\u2014\u2014\n**\u7ed9 `git diff` \u52a0 `--no-prefix` \u4f1a\u8ba9 hunk \u8865\u4e01\u88ab\u62d2\u7edd**\uff0c\u8fd9\u662f\u672c\u4ed3\u5e93\u7684\u4e00\u6761\u786c\u6027\u7ea6\u5b9a\u3002\n\u56de\u4f20\u7ed9 Git \u7684\u8865\u4e01\u662f\u300c\u539f\u59cb\u5934\u90e8 + \u88ab\u9009\u4e2d\u7684 hunk\u300d\uff0c\u8fd9\u6b63\u662f `--recount` \u80fd\u63a5\u53d7\u90e8\u5206\u9009\u62e9\u7684\u539f\u56e0\u3002\n\n\u8865\u4e01\u8fd8\u5e26**\u6765\u6e90\u4ed3\u5e93\u6807\u8bc6**\uff1a`git/apply-patch` \u4f1a\u6821\u9a8c `root`\uff0c\u4e0d\u7b26\u5219\u56de `STALE_REPOSITORY`\u3002\n\u56e0\u4e3a `discard` \u4f1a\u5199\u5de5\u4f5c\u6811\uff0c\u4e00\u4e2a\u300c\u8bfb\u51fa\u6765\u3001\u8fc7\u4e00\u4f1a\u513f\u518d\u5199\u56de\u53bb\u300d\u7684\u901a\u9053\u5fc5\u987b\u80fd\u62d2\u7edd\u6765\u81ea\u5df2\u5207\u6362\u4ed3\u5e93\u7684\u65e7\u8865\u4e01\u3002\n\n### Console \u8bb0\u4ec0\u4e48\n\nConsole \u662f\u73af\u5f62\u7f13\u51b2\uff1a**\u6700\u591a 200 \u6761**\uff0c\u6bcf\u6761 stdout / stderr \u5404\u622a\u5230 **4000 \u5b57\u7b26**\u3002\n\u63a2\u6d4b\u578b\u547d\u4ee4\uff08`rev-parse`\u3001`ls-files`\u3001`for-each-ref`\u3001`config`\u3001`--version` \u7b49\uff09\u6210\u529f\u65f6**\u4e0d\u8bb0\u5f55**\u2014\u2014\n\u5b83\u4eec\u6bcf\u6b21\u5237\u65b0\u90fd\u8dd1\uff0c\u8bb0\u4e0b\u6765\u53ea\u4f1a\u628a\u6709\u7528\u7684\u8f93\u51fa\u51b2\u6389\u3002\n\n### \u5931\u8d25\u4fe1\u606f\u662f\u5206\u5c42\u7684\n\n\u77ed\u6d88\u606f\u53ea\u4fdd\u7559 6 \u884c\uff0c\u5e76**\u5254\u9664 `hint:` \u884c**\u2014\u2014\u90a3\u4e9b\u884c\u662f\u7ed9\u7ec8\u7aef\u8bfb\u8005\u7684\uff0c\u754c\u9762\u6539\u7528\u672c\u5730\u5316\u7684\u8865\u6551\u8bf4\u660e\uff1b\n\u4f46\u5982\u679c\u5254\u9664\u540e\u4f1a\u4e00\u4e2a\u5b57\u90fd\u4e0d\u5269\uff0c\u5c31\u9000\u56de\u4fdd\u7559 hint\uff08\u89c4\u5219\u662f\u300c\u8bf4\u70b9\u4ec0\u4e48\u300d\uff0c\u4e0d\u662f\u300c\u6765\u81ea hint \u7684\u5c31\u4e00\u5f8b\u4e0d\u8bf4\u300d\uff09\u3002\n\u5b8c\u6574 stdout+stderr \u8d70 `detail` \u5b57\u6bb5\uff0c\u7531 toast \u4e0a\u7684\u300c\u8be6\u60c5\u300d\u94fe\u63a5\u6253\u5f00\u5bf9\u8bdd\u6846\u67e5\u770b\uff08detail \u4e5f\u6709 4000 \u5b57\u7b26\u4e0a\u9650\uff0c\u8d85\u51fa\u52a0\u7701\u7565\u53f7\uff09\u3002\n\n\u5f15\u64ce\u7ed9\u6bcf\u4e00\u7c7b\u5931\u8d25\u6253**\u7a33\u5b9a\u7684\u5206\u7c7b\u7801**\uff0c\u7531\u89c6\u56fe\u672c\u5730\u5316\u6210\u63aa\u8f9e\uff1a`authHint`\uff08`ssh` / `credentials`\uff09\u3001\n`pushHint`\uff08`remote-ahead` / `remote-rejected`\uff09\u3001`pullHint`\uff08`diverged` / `conflicts`\uff09\u3002\n\uff08`needsReconcile` \u4e0d\u662f\u5206\u7c7b\u7801\uff0c\u5b83\u662f\u5f15\u64ce\u5185\u90e8\u7528\u6765\u5224\u65ad\u300c\u662f\u5426\u8be5\u8865\u4e00\u6b21 `--no-rebase`\u300d\u7684\u8c13\u8bcd\uff0c\u89c6\u56fe\u770b\u4e0d\u5230\u5b83\u3002\uff09\n\u65b0\u589e\u4efb\u4f55\u5931\u8d25\u5206\u652f\u65f6\uff0c\u522b\u628a Git \u7684\u539f\u6587\u4e22\u6389\uff0c\u4e5f\u522b\u628a\u6574\u6bb5\u585e\u8fdb toast\u3002\n\n### \u76f8\u5bf9\u8def\u5f84\u4e0e\u771f\u5b9e\u8def\u5f84\n\n\u8def\u5f84\u6bd4\u8f83\u4e00\u5f8b\u6309**\u771f\u5b9e\u8def\u5f84**\uff1aGit \u8fd4\u56de\u7684\u662f\u771f\u5b9e\u8def\u5f84\uff08macOS \u4e0a `/private/var/\u2026`\uff09\uff0c\u5bbf\u4e3b\u7ed9\u7684\u662f\u7528\u6237\u6253\u5f00\u65f6\u7684\u8def\u5f84\uff08`/var/\u2026`\uff09\u3002\n\u7528\u5b57\u7b26\u4e32\u524d\u7f00\u6bd4\u8f83\u4f1a\u628a\u540c\u4e00\u4e2a\u76ee\u5f55\u5224\u6210\u4e24\u4e2a\uff0c\u540e\u679c\u662f**\u9759\u9ed8\u964d\u7ea7**\uff08\u300c\u6253\u5f00\u6587\u4ef6 / \u5728\u8bbf\u8fbe\u4e2d\u663e\u793a\u300d\u88ab\u7981\u7528\uff09\uff0c\u800c\u4e0d\u662f\u62a5\u9519\u3002\n\u89c6\u56fe\u4fa7\u4e0d\u8981\u81ea\u5df1\u62fc\u7edd\u5bf9\u8def\u5f84\uff0c\u7528\u5f15\u64ce\u7b97\u597d\u7684 `repo.workspacePrefix`\uff08`null` \u6709\u8bed\u4e49\uff1a\u4ed3\u5e93\u5728\u5de5\u4f5c\u533a\u4e4b\u4e0a\uff0c\u4e0d\u80fd\u6298\u6210 `\".\"`\uff09\u3002\n\n## \u4e00\u4e2a\u9879\u76ee\u91cc\u7684\u591a\u4e2a\u4ed3\u5e93\n\n\u4e00\u4e2a\u9879\u76ee\u5e38\u5e38\u4e0d\u6b62\u4e00\u4e2a\u4ed3\u5e93\uff1a\u4e00\u4e2a\u5df2\u68c0\u51fa\u7684\u5b50\u6a21\u5757\uff0c\u6216\u8005\u4e00\u4e2a\u6070\u597d\u4f4f\u5728\u53e6\u4e00\u4e2a\u4ed3\u5e93\u91cc\u7684\u514b\u9686\u3002\u5b83\u4eec\u662f**\u72ec\u7acb\u7684\u4ed3\u5e93\uff0c\u4e0d\u662f\u6587\u4ef6\u5939**\u2014\u2014\n\u7236\u4ed3\u5e93\u53ea\u8bb0\u5f55\u5b50\u6a21\u5757*\u6307\u5411\u54ea\u4e2a\u63d0\u4ea4*\u2014\u2014\u6240\u4ee5\u7236\u4ed3\u5e93\u7684 `git status` \u6c38\u8fdc\u53ea\u7ed9\u4e00\u884c gitlink\uff0c\u770b\u4e0d\u5230\u5b50\u6a21\u5757\u91cc\u9762\u7684\u6587\u4ef6\u3002\nCommit \u89c6\u56fe\u56e0\u6b64\u505a\u6210 IDEA \u5f0f\u7684**\u805a\u5408\u663e\u793a**\uff1a\u5148\u6309\u6682\u5b58/\u672a\u6682\u5b58/\u51b2\u7a81/\u672a\u8ddf\u8e2a\u5206\u5927\u7c7b\uff0c\u5927\u7c7b\u4e0b\u6309**\u4ed3\u5e93**\u6392\u2014\u2014\n\u6bcf\u4e2a\u6709\u6539\u52a8\u7684\u4ed3\u5e93\uff08\u7236\u4ed3\u5e93\u53c2\u4e0e\u5b57\u6bcd\u6392\u5e8f\uff09\u5404\u5360\u4e00\u884c\"\u989c\u8272\u5757 + \u540d + N \u4e2a\u6587\u4ef6 + \u5206\u652f\u5fbd\u6807\"\uff0c\u6587\u4ef6\u518d\u5d4c\u5728\u884c\u4e0b\u5c55\u5f00\uff0c\n\u6682\u5b58\u3001diff\u3001hunk\u3001\u56de\u6eda\u90fd\u76f4\u63a5\u53ef\u7528\uff1b\n\u63d0\u4ea4\u6309\u94ae\u7528\u540c\u4e00\u63d0\u4ea4\u4fe1\u606f\u9010\u4ed3\u63d0\u4ea4\uff08\u5b50\u6a21\u5757\u5148\u3001\u7236\u4ed3\u5e93\u540e\uff09\uff0c\u7236\u4ed3\u5e93\u968f\u540e\u51fa\u73b0\u7684\u6307\u9488\u66f4\u65b0\u518d\u63d0\u4ea4\u4e00\u6b21\u5373\u6536\u655b\u3002\n`Commit and Push` \u628a\u521a\u624d\u63d0\u4ea4\u7684\u90a3 N \u4e2a\u4ed3\u9010\u4e2a\u63a8\u51fa\u53bb\uff0c\u4e0d\u518d\u53ea\u63a8\u5f53\u524d\u4ed3\u3002\n\u4ed3\u5e93\u884c\u53f3\u952e\"\u5207\u6362\u5230\u8be5\u4ed3\u5e93\"\u4f1a\u8df3\u5230 Root \u9009\u62e9\u5668\u7684\u90a3\u4e2a\u4ed3\u5e93\uff08Log/\u5206\u652f/\u50a8\u85cf\u4ecd\u6309\u4ed3\u5e93\u5207\u6362\u67e5\u770b\uff09\u3002\n\u63a8\u9001\u8d70 IDEA \u5f0f\u7684 **Push \u5bf9\u8bdd\u6846**\uff1a\u591a\u4ed3\u65f6\u5de5\u5177\u680f Push \u5217\u51fa\u6bcf\u4e2a\u4ed3\u5e93\u7684\u5206\u652f\u53bb\u5411\uff08`main \u2192 origin/main`\uff09\u3001`\u2191/\u2193` \u4e0e\u52fe\u9009\u6846\uff0c\n`Push All` \u9010\u4ed3\u63a8\u9001\uff0c\u5355\u4e2a\u5931\u8d25\u4e0d\u6321\u5176\u4ed6\u4ed3\uff0c\u884c\u5185\u663e\u793a\u6210\u529f/\u62d2\u56e0\uff1b\u5355\u4ed3\u65f6\u4fdd\u6301\u76f4\u63a5\u63a8\u9001\u3002Git \u89c6\u56fe\u5de5\u5177\u680f\u540c\u6837\u6709 Push \u5165\u53e3\u3002\n\u4e24\u4e2a\u5de5\u5177\u680f\u6700\u5de6\u8fb9\u7684\u4ed3\u5e93\u63a7\u4ef6\u4ecd\u7136\u662f\u5207\u6362\u5f53\u524d\u4ed3\u5e93\u7684\u4e1c\u897f\uff1a\u9009\u4e2d\u4e00\u4e2a\uff0c\u89c6\u56fe\u80cc\u540e\u7684\u6bcf\u6761\u547d\u4ee4\uff08\u72b6\u6001\u3001diff\u3001\u65e5\u5fd7\u3001\u5206\u652f\u3001\u50a8\u85cf\u3001\u63d0\u4ea4\u3001hunk \u6682\u5b58\uff09\n\u5c31\u90fd\u5728\u5b83\u91cc\u9762\u8dd1\u3002\n\n\u5de5\u4f5c\u533a\u672c\u8eab\u4e0d\u662f\u4ed3\u5e93\u3001\u4f46\u6587\u4ef6\u5939\u91cc\u5e76\u6392\u6446\u7740\u591a\u4e2a\u4ed3\u5e93\u65f6\uff08`repoA/`\u3001`repoB/`\uff09\uff0c\u540c\u6837\u53ef\u7528\uff1a\u4ed3\u5e93\u5217\u8868\u5217\u51fa\u5b83\u4eec\uff08`sibling repository`\n\u5fbd\u6807\uff09\uff0cCommit \u89c6\u56fe\u805a\u5408\u663e\u793a\u5176\u4ed6\u5e73\u7ea7\u4ed3\u7684\u6539\u52a8\uff0cPush \u5bf9\u8bdd\u6846\u4e00\u6b21\u63a8\u5b8c\u3002\u7a7a\u6587\u4ef6\u5939\uff08\u5185\u65e0\u4ed3\u5e93\uff09\u4ecd\u62a5\"\u4e0d\u662f Git \u4ed3\u5e93\"\u3002\n\n\u5217\u8868\u7531\u5de5\u4f5c\u533a\u4ed3\u5e93\u51fa\u53d1\u904d\u5386\u6784\u5efa\uff0c\u4e14**\u904d\u5386\u662f\u6709\u8fb9\u754c\u7684**\uff1a\u6700\u591a 4 \u5c42\u6df1\u3001\u6700\u591a 5000 \u4e2a\u76ee\u5f55\uff0c\u5e76\u4e14\u4e0d\u4e0b\u6f5c\u4f9d\u8d56/\u6784\u5efa/\u7f13\u5b58\u76ee\u5f55\n\uff08`node_modules`\u3001`vendor`\u3001`Pods`\u3001`.venv`\u2026 \u5171 17 \u4e2a\u540d\u5b57\uff0c\u542b `.git`\uff09\u3002\n\u4f46 `.gitmodules` \u91cc**\u58f0\u660e**\u7684\u8def\u5f84\u4e0d\u53d7\u8fd9\u4e9b\u8fb9\u754c\u9650\u5236\u2014\u2014\u90a3\u91cc\u7684\u6761\u76ee\u662f\u5173\u4e8e\u9879\u76ee\u7684\u65ad\u8a00\uff0c\u800c\u8fb9\u754c\u53ea\u662f\u5bf9\u9879\u76ee\u89c4\u6a21\u7684\u731c\u6d4b\u3002\n\u5df2\u58f0\u660e\u4f46\u672a\u68c0\u51fa\u7684\u5b50\u6a21\u5757\u4e0d\u5217\u51fa\uff1a\u6ca1\u6709\u5de5\u4f5c\u6811\uff0c\u5c31\u6ca1\u5f97\u663e\u793a\u3001\u4e5f\u6ca1\u5f97\u63d0\u4ea4\u3002\n\n\u4e24\u4e2a\u957f\u5f97\u5f88\u50cf\u7684\u4ed3\u5e93\u662f**\u6309\u7236\u4ed3\u5e93\u7684\u7d22\u5f15**\u533a\u5206\u7684\uff0c\u4e0d\u662f\u6309 `.gitmodules`\uff1a\u88ab\u7236\u4ed3\u5e93\u8bb0\u6210 `160000` gitlink \u7684\u8def\u5f84\u662f**\u5b50\u6a21\u5757**\n\uff08\u5728\u90a3\u91cc\u6682\u5b58\u7b49\u4e8e\u8bb0\u5f55\u4e00\u4e2a\u63d0\u4ea4\uff09\uff0c\u5176\u4ed6\u90fd\u662f**\u5d4c\u5957\u4ed3\u5e93**\uff08\u7236\u4ed3\u5e93\u4e0d\u5b58\u5b83\u7684\u4efb\u4f55\u6587\u4ef6\uff09\u3002\u754c\u9762\u4e0a\u5206\u522b\u6253 `submodule` / `nested repository` \u5fbd\u6807\u3002\n\n\u8fd9\u4e2a\u9009\u62e9\u5c5e\u4e8e**\u6253\u5f00\u7684\u90a3\u4e2a\u9879\u76ee**\uff0c\u4e0d\u5199\u8fdb prefs\uff1a\u5207\u9879\u76ee\u3001\u6216\u8005\u628a\u76ee\u5f55\u79fb\u8d70\uff0c\u5c31\u9000\u56de\u5de5\u4f5c\u533a\u81ea\u5df1\u7684\u4ed3\u5e93\u3002\n\n## \u8fdc\u7aef\u540c\u6b65\uff1a\u63a8\u9001\u88ab\u62d2\u4e0e\u5408\u5e76\u51b2\u7a81\n\n\u88ab\u62d2\u7edd\u7684\u63a8\u9001\u662f**\u5e38\u89c4\u60c5\u51b5\uff0c\u4e0d\u662f\u5f02\u5e38**\uff1a\u522b\u4eba\u5f80\u540c\u4e00\u4e2a\u5206\u652f\u63a8\u4e86\u4e1c\u897f\u3002Git \u4f1a\u5728 stderr \u4e0a\u8bf4\u660e\uff0c\u5e76\u5728 `hint:` \u884c\u91cc\u7ed9\u51fa\u8865\u6551\u529e\u6cd5\uff0c\n\u8fd9\u4e24\u8005\u90fd\u8bfb\u2014\u2014\u77ed\u6d88\u606f\u91cc\u662f Git \u81ea\u5df1\u90a3\u51e0\u884c\uff0c\u4e0a\u9762\u90a3\u53e5\u5206\u7c7b\u597d\u7684\u8865\u6551\u8bf4\u660e\u662f\u63d2\u4ef6\u7684\uff1a\n\n| \u5931\u8d25 | \u63d2\u4ef6\u600e\u4e48\u8bf4 |\n| --- | --- |\n| \u63a8\u9001\u88ab\u62d2\uff08`fetch first`\u3001`non-fast-forward`\u3001`stale info`\uff09 | \u8fdc\u7aef\u6709\u4f60\u6ca1\u6709\u7684\u63d0\u4ea4\u2014\u2014\u5148 Fetch\uff0c\u518d Pull\uff0c\u7136\u540e\u91cd\u65b0\u63a8\u9001\uff1b\u5982\u679c\u8be5\u4fdd\u7559\u7684\u662f\u672c\u5730\u5386\u53f2\uff0c\u7528 Force Push |\n| \u63a8\u9001\u88ab\u62d2\uff08`protected branch`\u3001\u94a9\u5b50\uff09 | \u670d\u52a1\u5668\u62d2\u7edd\u4e86\u5b83\uff1b\u5206\u652f\u5927\u6982\u662f\u53d7\u4fdd\u62a4\u7684 |\n| \u62c9\u53d6\u5361\u5728\u51b2\u7a81\u4e0a | \u5728 Changes \u533a\u91cc\u89e3\u51b3\uff0c\u7136\u540e\u63d0\u4ea4 |\n| \u5206\u53c9\u4e14 `pull.ff = only` | \u5148 merge \u6216 rebase\uff0c\u518d\u63a8\u9001 |\n| \u6ca1\u6709\u5b58\u4e0b\u6765\u7684\u51ed\u636e\uff08HTTPS\uff09 | \u5728\u7ec8\u7aef\u91cc\u8dd1\u4e00\u6b21 `git push` \u8ba9\u51ed\u636e\u52a9\u624b\u5b58\u4e0b\u6765\uff0c\u518d\u91cd\u8bd5 |\n| `Permission denied (publickey)` | \u6362\u6210 HTTPS \u8fdc\u7aef\uff0c\u6216\u8005\u8ba9\u5bc6\u94a5\u4e0d\u4f9d\u8d56 `ssh-agent`\u2014\u2014\u5bbf\u4e3b\u4e0d\u4f20 `SSH_AUTH_SOCK` |\n\n\u4e09\u6761\u5f15\u64ce\u51b3\u7b56\u6491\u8d77\u8fd9\u5957\u884c\u4e3a\uff1a\n\n- **\u4e24\u4e2a\u6d41\u90fd\u8bfb\u3002** `git push` \u628a\u62d2\u7edd\u5199\u5728 stderr\uff0c\u4f46 `git merge`\uff08\u4e5f\u5c31\u662f `git pull` \u7684\u540e\u534a\u6bb5\uff09\u628a `CONFLICT` \u5199\u5728 stdout\u3002\n \u53ea\u8bfb stderr \u4f1a\u628a\u4e00\u6b21\u51b2\u7a81\u7684 pull \u6e32\u67d3\u6210\u4e00\u6bb5\u300c\u770b\u8d77\u6765\u50cf\u6210\u529f\u7684 fetch \u65e5\u5fd7\u300d\u3002\n **\u5224\u636e\u662f\u300c\u5931\u8d25\u65f6\u54ea\u4e00\u884c\u80fd\u6307\u51fa\u4e0b\u4e00\u6b65\u300d\uff0c\u4e0d\u662f\u300c\u54ea\u4e2a\u6d41\u66f4\u50cf\u9519\u8bef\u6d41\u300d\u3002**\n- **`git pull` \u6309\u914d\u7f6e\u8dd1\uff0c\u53ea\u5728 Git \u81ea\u5df1\u56e0\u7f3a\u7b56\u7565\u800c\u62d2\u7edd\u65f6\u91cd\u8bd5\u4e00\u6b21\u3002** \u81ea\u4ece 2.27\uff0c\u5728\u5206\u53c9\u5206\u652f\u4e0a\u88f8\u8dd1 `git pull` \u662f\u786c\u5931\u8d25\n \uff08`fatal: Need to specify how to reconcile divergent branches`\uff09\u2014\u2014\u4e8e\u662f\u88ab\u62d2\u7684\u63a8\u9001\u8ba9\u4f60\u8dd1\u7684\u90a3\u6761\u547d\u4ee4\u81ea\u5df1\u8dd1\u4e0d\u8d77\u6765\u3002\n \u53ea\u6709\u8fd9\u4e00\u4e2a\u5931\u8d25\u4f1a\u88ab `--no-rebase`\uff08merge\uff09\u91cd\u8bd5\u4e00\u6b21\uff0c\u5176\u4f59\u7ed3\u679c\u90fd\u662f Git \u7684\u3002\n \u8fd9\u91cc\u4e0d\u505a\u7b56\u7565\u63a8\u5bfc\uff0c\u6240\u4ee5 `branch..rebase`\u3001`pull.rebase = merges|interactive`\u3001`pull.ff = only` \u5168\u90e8\u7167\u5e38\u751f\u6548\u2014\u2014\n \u5b83\u4eec\u662f\u88ab**\u7b2c\u4e00\u6b21\u5c1d\u8bd5**\u8bfb\u5230\u7684\uff0c\u800c\u4e0d\u662f\u88ab\u4e00\u4efd\u66f4\u5dee\u7684 Git \u4f18\u5148\u7ea7\u89c4\u5219\u526f\u672c\u8bfb\u5230\u7684\u3002\n- **Force push \u53ea\u80fd\u662f lease\uff0c\u4e0d\u80fd\u662f\u88f8 force\u3002** `--force-with-lease` \u662f\u63d2\u4ef6\u552f\u4e00\u80fd\u53d1\u51fa\u7684 force\uff1a\u5982\u679c\u8fdc\u7aef\u5df2\u7ecf\u4e0d\u5728\u8fd9\u4e2a\u7a97\u53e3\n \u4e0a\u6b21\u770b\u5230\u7684\u4f4d\u7f6e\uff0c\u5b83\u5c31\u4f1a\u88ab\u62d2\u7edd\uff0c\u4e8e\u662f\u540c\u4e8b\u7684\u63a8\u9001\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u62b9\u6389\u3002\u8fdc\u7aef\u4e0e ref \u662f\u4f4d\u7f6e\u53c2\u6570\uff0c\u6240\u4ee5\u4ea4\u7ed9 Git \u4e4b\u524d\u4f1a\u5148\u6821\u9a8c\u2014\u2014\n `git push origin --force` \u6b63\u662f\u300c\u672a\u6821\u9a8c\u7684 `-` \u5f00\u5934\u53d6\u503c\u300d\u4f1a\u4ea7\u51fa\u7684\u4e1c\u897f\u3002\n\n**\u63a8\u9001\u63a8\u5230\u54ea\u91cc\uff0c\u7531\u5206\u652f\u8ffd\u8e2a\u5173\u7cfb\u51b3\u5b9a**\uff0c\u4e0d\u662f `origin` + \u672c\u5730\u5206\u652f\u540d\u3002\u8fd9\u4e24\u8005\u53ea\u5728\u5206\u652f\u8ffd\u8e2a\u540c\u4e00\u5904\u65f6\u624d\u4e00\u81f4\u2014\u2014\n\u4e00\u65e6\u5206\u652f\u8ffd\u8e2a\u522b\u5904\uff0c\u65e7\u884c\u4e3a\u5c31\u4f1a\u628a\u65b0\u5206\u652f\u63a8\u5230 `origin`\uff0c\u800c \u2191/\u2193 \u6807\u7b7e\u8fd8\u5728\u5bf9\u7740\u771f\u6b63\u7684 upstream \u8ba1\u6570\u3002\n\u5b8c\u5168\u6ca1\u6709 upstream \u65f6\u56de\u9000\u8303\u56f4\u5f88\u7a84\uff1a`origin`\uff0c\u6216\u8005\u53ea\u6709\u4e00\u4e2a\u8fdc\u7aef\u65f6\u5c31\u7528\u5b83\u3002\n\u6709\u591a\u4e2a\u8fdc\u7aef\u53c8\u6ca1 upstream \u65f6\u65e0\u4ece\u63a8\u65ad\uff0c\u4e8e\u662f\u62d2\u7edd\u63a8\u9001\u5e76\u5217\u51fa\u8fdc\u7aef\u5217\u8868\uff0c\u800c\u4e0d\u662f\u628a\u5206\u652f\u53d1\u5e03\u5230\u6392\u5e8f\u7b2c\u4e00\u4e2a\u7684\u540d\u5b57\u4e0a\u53bb\u3002\n\u9996\u6b21\u63a8\u9001\u53ef\u4ee5\u76f4\u63a5\u5efa\u7acb\u8ffd\u8e2a\uff08\u8ffd\u52a0 `--set-upstream`\uff09\u3002\n\u53e6\u5916\u4e24\u79cd\u4f1a\u660e\u786e\u62d2\u7edd\u7684\u60c5\u51b5\uff1a\u5206\u652f\u8ffd\u8e2a\u7684\u662f\u4e00\u4e2a**\u672c\u5730\u5206\u652f**\uff08\u540d\u5b57\u91cc\u6ca1\u6709 `/`\uff09\uff0c\u4ee5\u53ca**\u5c1a\u65e0\u63d0\u4ea4**\u7684\u5206\u652f\u3002\n\n### \u79bb\u5f00\u4e00\u4e2a\u672a\u5b8c\u6210\u7684\u5408\u5e76\n\n\u51b2\u7a81\u7684 `pull` \u4f1a\u628a\u4ed3\u5e93\u7559\u5728\u5408\u5e76\u4e2d\u95f4\uff0c\u4e8e\u662f\u63d0\u4ea4\u6309\u94ae\u4e0a\u65b9\u7684\u72b6\u6001\u884c\u4f1a\u5199\u51fa**\u8fdb\u884c\u4e2d\u7684\u64cd\u4f5c**\u5e76\u5e26\u4e0a\u5b83\u7684\u51fa\u53e3\uff1a\n\u56db\u4e2a\u64cd\u4f5c\u90fd\u6709 **Abort**\uff0c\u53ea\u6709\u5e8f\u5217\u7c7b\u7684\u4e09\u4e2a\uff08cherry-pick / revert / rebase\uff09\u6709 **Continue**\u3002\nmerge **\u4e0d\u8fdb\u8fd9\u4e2a\u5217\u8868**\uff1a\u5b83\u6ca1\u6709\u9700\u8981\u7ee7\u7eed\u7684\u534a\u6210\u54c1\u72b6\u6001\uff0c\u4e00\u6b21\u5408\u5e76\u662f\u9760**\u63d0\u4ea4**\u6765\u7ed3\u675f\u7684\u2014\u2014\u6240\u4ee5\u63d2\u4ef6\u4e0d\u7ed9\u5b83 Continue\n\uff08\u987a\u5e26\u8bf4\u660e\uff1a`git merge --continue` \u5728\u7ec8\u7aef\u91cc\u662f\u5b58\u5728\u7684\uff0c\u53ea\u662f\u8fd9\u91cc\u7528\u4e0d\u4e0a\uff0c\u56e0\u6b64\u4e0d\u63d0\u4f9b\uff09\u3002\nContinue \u7528 `core.editor=true` \u8dd1\uff0c\u56e0\u4e3a\u6ca1\u6709\u7ec8\u7aef\u53ef\u4ee5\u5199\u63d0\u4ea4\u4fe1\u606f\uff0c\u5426\u5219 Git \u53ea\u4f1a\u5931\u8d25\u2014\u2014\u7528\u7684\u662f\u8be5\u64cd\u4f5c\u5df2\u7ecf\u8bb0\u5f55\u597d\u7684\u90a3\u6761\u4fe1\u606f\u3002\n\n\u8fd9\u884c\u5728**\u51b2\u7a81\u88ab\u6682\u5b58\u4e4b\u540e**\u4ecd\u7136\u4fdd\u7559\u64cd\u4f5c\u540d\uff0c\u8fd9\u624d\u662f\u91cd\u70b9\uff1a\u89e3\u51b3\u51b2\u7a81\u4f1a\u628a `u` \u884c\u53d8\u6210\u666e\u901a\u7d22\u5f15\u884c\uff0c\n\u4e8e\u662f porcelain \u4e0d\u518d\u63d0\u5b83\u2014\u2014\u800c\u300c\u628a\u6240\u6709\u51b2\u7a81\u90fd\u6682\u5b58\u4e86\u300d\u6b63\u662f `--continue` \u5f00\u59cb\u80fd\u591f\u6210\u529f\u7684\u65f6\u523b\u3002\n\u628a\u68c0\u67e5\u9650\u5236\u5728\u300c\u6709\u51b2\u7a81\u65f6\u300d\u4f1a\u85cf\u8d77\u6765\u63d2\u4ef6\u81ea\u5df1\u521b\u9020\u7684\u90a3\u4e2a\u72b6\u6001\u7684\u552f\u4e00\u51fa\u53e3\uff0c\u6240\u4ee5\u63a2\u9488\u5728**\u6709\u51b2\u7a81 _\u6216_ \u521a\u624d\u53d1\u73b0\u8fc7\u64cd\u4f5c**\u65f6\u90fd\u8fd0\u884c\u3002\n\n\u4e0d\u8ba4\u8bc6\u7684\u64cd\u4f5c\u540d\u4e0d\u4f1a\u88ab\u8fd0\u884c\uff1a\u5f15\u64ce\u53ea\u63a5\u53d7\u5b83\u80fd\u62a5\u51fa\u7684\u90a3\u56db\u4e2a\u540d\u5b57\uff0c\u6240\u4ee5\u4e00\u4e2a\u7578\u5f62\u7684\u8f7d\u8377\u4e0d\u4f1a\u53d8\u6210\u4e00\u4e2a\u4efb\u610f\u7684 `git` \u52a8\u8bcd\u3002\n\n### \u914d\u7f6e\u914d\u65b9\n\n**GitHub\uff0cHTTPS** \u2014\u2014 `gh auth login` \u7136\u540e `gh auth setup-git` \u4f1a\u628a\u52a9\u624b\u5199\u8fdb `~/.gitconfig`\u3002\u4e0d\u9700\u8981\u522b\u7684\u3002\n\n**GitLab\uff08\u4efb\u610f\u4e3b\u673a\uff09\uff0cHTTPS** \u2014\u2014 \u8ba9 Git \u5b58\u4e00\u6b21\uff1a\n\n```bash\ngit config --global credential.helper osxkeychain # macOS\uff08Linux \u7528 libsecret\uff0c\n # Windows \u7528 manager\uff09\ngit push # \u8f93\u4e00\u6b21 token\uff0c\u6b64\u540e\u90fd\u4f1a\u88ab\u5b58\u4e0b\u6765\n```\n\n\u81ea\u5efa GitLab **\u4e0d\u9700\u8981\u4efb\u4f55\u63d2\u4ef6\u4fa7\u914d\u7f6e**\uff0c\u56e0\u4e3a\u7528\u7684\u5c31\u662f\u4f60 shell \u7528\u7684\u90a3\u4e2a\u51ed\u636e\u5e93\u3002\n\n**SSH** \u2014\u2014 \u65e0\u53e3\u4ee4\u7684\u5bc6\u94a5\u3001\u6216\u8005\u53e3\u4ee4\u5b58\u5728 macOS \u94a5\u5319\u4e32\u91cc\uff08`UseKeychain yes`\uff09\u7684\u5bc6\u94a5\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u3002\n\u53ea\u6d3b\u5728 `ssh-agent` \u91cc\u7684\u5bc6\u94a5\u4e0d\u884c\uff0c\u56e0\u4e3a\u5bbf\u4e3b\u4e0d\u4f1a\u628a `SSH_AUTH_SOCK` \u4ea4\u7ed9\u63d2\u4ef6\u8fdb\u7a0b\uff1b\u8fd9\u7c7b\u60c5\u51b5\u8bf7\u7528 HTTPS \u8fdc\u7aef\uff0c\u6216\u628a\u5bc6\u94a5\u52a0\u8fdb\u94a5\u5319\u4e32\u3002\n\n> \u591a\u8d26\u53f7\u914d\u7f6e\uff1a\u63d2\u4ef6\u8bfb\u7684\u662f\u4f60\u7684\u51ed\u636e\u52a9\u624b\u4e3a\u8be5 URL \u89e3\u6790\u51fa\u7684\u90a3\u4e2a\u8d26\u53f7\uff0c\u6240\u4ee5\n> `credential..username` \u548c `includeIf \"gitdir:\u2026\"` \u7684\u89c4\u5219\u5728\u8fd9\u91cc\u548c\u7ec8\u7aef\u91cc\u4e00\u6837\u751f\u6548\u3002\n\n## \u8ba4\u8bc1\n\n**\u63d2\u4ef6\u4e0d\u6301\u6709\u4efb\u4f55\u51ed\u636e\uff0c\u4e5f\u4e0d\u9700\u8981\u3002** \u5b83\u8dd1\u7684\u662f\u7528\u6237\u81ea\u5df1\u7684 `git`\u3001\u5e26\u7684\u662f\u7528\u6237\u81ea\u5df1\u7684 `HOME`\uff0c\n\u4e8e\u662f\u5b83\u7ee7\u627f\u7684\u6b63\u662f\u7ec8\u7aef\u5df2\u7ecf\u5728\u7528\u7684\u90a3\u5957\u4e1c\u897f\uff1a\u540c\u4e00\u4e2a `~/.gitconfig`\u3001\u540c\u4e00\u4e2a\u51ed\u636e\u52a9\u624b\u3001\u540c\u4e00\u4efd `~/.ssh/config` \u4e0e\u5bc6\u94a5\u3002\nshell \u91cc\u4ec0\u4e48\u80fd\u8ba4\u8bc1\u4e00\u6b21 `git push`\uff0c\u8fd9\u91cc\u5c31\u80fd\uff0c\u5728 GitHub\u3001\u81ea\u5efa GitLab \u6216\u4efb\u4f55\u522b\u7684\u5730\u65b9\u2014\u2014**\u6ca1\u6709\u4efb\u4f55\u6309\u4e3b\u673a\u914d\u7f6e\u7684\u4e1c\u897f**\u3002\n\n\u8fd9\u79cd\u7ee7\u627f\u662f\u523b\u610f\u7684\u3002\u63d2\u4ef6\u4e0d\u8be5\u88ab\u6258\u4ed8 token\uff0c\u800c\u4e00\u4efd\u300c\u6309\u4e3b\u673a\u586b\u51ed\u636e\u300d\u7684\u8868\u5355\u4e5f\u53ea\u80fd\u8986\u76d6\u5b83\u8ba4\u8bc6\u7684\u90a3\u4e9b\u4e3b\u673a\u3002\n\n\u63d2\u4ef6\u552f\u4e00\u505a\u4e0d\u5230\u7684\u4e8b\u662f**\u63d0\u95ee**\u3002\u5de5\u5177\u7a97\u53e3\u80cc\u540e\u6ca1\u6709\u7ec8\u7aef\uff0c\u6240\u4ee5\u63d0\u793a\u88ab\u5173\u6389\uff0c\u547d\u4ee4\u4f1a\u7acb\u523b\u5931\u8d25\uff0c\u800c\u4e0d\u662f\u6c38\u8fdc\u6302\u5728\u4e00\u4e2a\u6ca1\u4eba\u80fd\u8f93\u5165\u7684\u5bc6\u7801\u4e0a\u3002\n\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u539f\u59cb\u7684 Git \u9519\u8bef\u4f1a\u8fde\u540c\u300c\u8be5\u600e\u4e48\u529e\u300d\u4e00\u8d77\u663e\u793a\uff08\u89c1\u4e0a\u4e00\u8282\u7684\u8868\uff09\u3002\n\n## \u751f\u6210\u63d0\u4ea4\u4fe1\u606f\n\n\u63d0\u4ea4\u4fe1\u606f\u6846\u65c1\u8fb9\u7684\u95ea\u5149\u6309\u94ae\u4f1a\u66ff\u4f60\u8d77\u8349\u4fe1\u606f\u3002\u5b83\u901a\u8fc7 `pi.agent.complete` \u627e**\u5bbf\u4e3b**\u7684\u6a21\u578b\uff0c\n\u6240\u4ee5\u7528\u7684\u5c31\u662f\u4f60**\u5df2\u7ecf**\u914d\u597d\u7684 provider\u3001\u6a21\u578b\u4e0e\u989d\u5ea6\u2014\u2014\u63d2\u4ef6\u4e0d\u6301\u6709 API key\uff0c\u4e5f\u4e0d\u65b0\u589e\u4efb\u4f55\u8d26\u53f7\u3002\n\n\u5b83\u53d1\u51fa\u53bb\u7684\u662f\u4e09\u6837\u4e1c\u897f\uff1a\u53d8\u66f4\u672c\u8eab\u3001\u4ed3\u5e93\u8fd1\u671f\u63d0\u4ea4\u7684**subject \u4e0e\u6b63\u6587\u6837\u672c**\uff0c\u4ee5\u53ca\u8fd9\u4efd\u6837\u672c\u6d4b\u51fa\u6765\u7684\u4e1c\u897f\u2014\u2014\n\u63d0\u4ea4\u8bed\u8a00\u3001subject \u662f\u5426\u5e26 `type(scope):` \u524d\u7f00\u3001\u6709\u6ca1\u6709\u4eba\u5199\u6b63\u6587\u3002\u6837\u672c\u53d6**\u6700\u8fd1 40 \u6761**\u63d0\u4ea4\u3002\ndiff \u622a\u65ad\u5728 **12 000 \u5b57\u7b26**\uff1a\u8fd9\u662f\u63d0\u793a\u8bcd\uff0c\u4e0d\u662f\u5907\u4efd\u3002\n\n**\u8bed\u8a00\u3002** \u7531\u95ea\u5149\u6309\u94ae\u65c1\u7684\u7bad\u5934\u83dc\u5355\u51b3\u5b9a\uff0c\u56e0\u4e3a\u300c\u7167\u7740\u4ed3\u5e93\u5199\u300d\u4e0d\u662f\u4e00\u6761\u8bed\u8a00\u7b56\u7565\uff1a\n\u4e00\u4efd\u5168\u82f1\u6587\u7684\u5386\u53f2\u4f1a\u8ba9\u4e2d\u6587\u8bfb\u8005\u4e5f\u62ff\u5230\u82f1\u6587\u8349\u7a3f\u3002\u9009\u9879\u662f\n**\u8ddf\u968f\u4ed3\u5e93\u5386\u53f2**\uff08\u9ed8\u8ba4\uff1a\u7528\u5b9e\u6d4b\u8bed\u8a00\uff0c\u6ca1\u6709\u5386\u53f2\u65f6\u56de\u9000\u5230\u754c\u9762\u8bed\u8a00\uff09\u3001**\u7b80\u4f53\u4e2d\u6587**\u3001**English**\u3002\n\u65e0\u8bba\u54ea\u79cd\uff0c`type` \u4e0e `scope` \u90fd\u4fdd\u6301 ASCII\uff0c\u5c31\u50cf Conventional Commits \u7684\u5404\u79cd\u8bed\u8a00\u8bd1\u672c\u505a\u7684\u90a3\u6837\u2014\u2014\n`feat(\u767b\u5f55): \u652f\u6301\u77ed\u4fe1\u9a8c\u8bc1\u7801`\u3002\n\n\u63d0\u793a\u8bcd\u6309 Git \u81ea\u5df1\u7684\u60ef\u4f8b\uff08git-commit(1)\u3001Tim Pope\u3001Chris Beams\u3001Conventional Commits 1.0.0\uff09\u5199\u660e\u786c\u6027\u89c4\u5219\uff1a\nsubject \u540e\u4e00\u4e2a\u7a7a\u884c\u3001\u76ee\u6807 50 \u5b57\u7b26\u4e0a\u9650 72\uff08\u4e2d\u6587\u7ea6 25 \u5b57\uff0c\u56e0\u4e3a CJK \u5b57\u5f62\u5927\u81f4\u662f\u4e24\u500d\u5bbd\uff09\u3001\n\u7ed3\u5c3e\u4e0d\u52a0\u53e5\u53f7\u3001\u82f1\u6587 subject \u7528\u7948\u4f7f\u53e5\u3001\u6b63\u6587\u8bf4 **why** \u800c\u4e0d\u662f\u590d\u8ff0 diff\u3001\n`BREAKING CHANGE:` \u662f\u552f\u4e00\u5141\u8bb8\u5b83\u81ea\u884c\u8ffd\u52a0\u7684 trailer\u3002\n\n**\u5f62\u72b6\u662f\u88ab\u5f3a\u5236\u7684\uff0c\u4e0d\u662f\u88ab\u8bf7\u6c42\u7684\u3002** \u63d0\u793a\u8bcd\u4e0d\u80fd\u662f\u683c\u5f0f\u7684\u6700\u540e\u4e00\u9053\u9632\u7ebf\uff0c\u56e0\u4e3a\u8981\u547d\u7684\u90a3\u4e2a\u5931\u8d25\u5bf9\u5199\u63d0\u793a\u8bcd\u7684\u4eba\u662f\u9690\u5f62\u7684\uff1a\nGit \u628a**\u7b2c\u4e00\u4e2a\u7a7a\u884c\u4e4b\u524d\u7684\u6bcf\u4e00\u884c**\u90fd\u5f53\u6210\u6807\u9898\uff0c\u6240\u4ee5\u4e00\u4e2a\u628a\u6b63\u6587\u7d27\u8d34\u5728 subject \u4e0b\u9762\u7684\u56de\u590d**\u6839\u672c\u6ca1\u6709\u6b63\u6587**\u2014\u2014\n\u5b83\u662f\u4e00\u4e2a\u5de8\u5927\u7684 subject\uff0c\u800c\u8fd9\u6b63\u662f\u8bfb\u8005\u53e3\u4e2d\u7684\u300c\u63d0\u4ea4\u4fe1\u606f\u4e0d\u89c4\u8303\u300d\u3002\u6240\u4ee5\u56de\u590d\u5728\u8fdb\u5165\u4fe1\u606f\u6846\u4e4b\u524d\u4f1a\u8fc7\u4e00\u904d `formatCommitMessage`\uff1a\n\n- \u5148\u5265\u6389 ``` \u4ee3\u7801\u56f4\u680f\u548c `commit message:` / `\u63d0\u4ea4\u4fe1\u606f:` \u8fd9\u7c7b\u524d\u7f00\uff08\u6a21\u578b\u5f88\u7231\u52a0\uff09\uff1b\n- \u4fdd\u8bc1 subject \u662f\u5355\u884c\uff0c\u5e76\u4e14\u65e0\u8bba\u6a21\u578b\u600e\u4e48\u6392\uff0c\u540e\u9762\u90fd\u6070\u597d\u4e00\u4e2a\u7a7a\u884c\uff1b\n- \u8fc7\u957f\u7684 subject \u4f1a\u628a\u5c3e\u5df4**\u5728\u4ece\u53e5\u8fb9\u754c**\u632a\u8fdb\u6b63\u6587\uff0c\u800c\u4e0d\u662f\u622a\u65ad\uff0c\u4e8e\u662f\u6a21\u578b\u4ece diff \u91cc\u8bfb\u5230\u7684\u4fe1\u606f\u4e0d\u4f1a\u4e22\uff1b\n- \u628a\u6b63\u6587\u6298\u5230 Git \u7684 72 \u5217\uff0cCJK \u5b57\u5f62\u6309\u7ec8\u7aef\u90a3\u6837\u7b97\u4e24\u5217\uff1b\n- \u628a\u5206\u53f7\u4e32\u8d77\u6765\u7684\u4ece\u53e5\u62c6\u6210\u300c\u4e00\u4e2a\u60f3\u6cd5\u4e00\u6761\u300d\u7684\u9879\u76ee\u7b26\u53f7\uff1b\n- \u5f53 `,` `;` \u5939\u5728\u4e2d\u6587\u5b57\u7b26\u4e4b\u95f4\u65f6\u89c4\u8303\u6210 `\uff0c` `\uff1b`\u2014\u2014\u800c ASCII \u539f\u6837\u4fdd\u7559\uff0c\u6240\u4ee5 `feat(a,b): \u2026` \u4e0d\u4f1a\u88ab\u78b0\u3002\n\n\u5b83\u4e0d\u6539\u5199\u4efb\u4f55\u63aa\u8f9e\uff0c\u800c\u4e14\u662f**\u5e42\u7b49**\u7684\uff1a\u5f62\u72b6\u5df2\u7ecf\u6b63\u786e\u7684\u8349\u7a3f\u4f1a\u539f\u6837\u901a\u8fc7\u3002\n\n**\u8303\u56f4\u3002** Changes \u5217\u8868\u91cc\u6709\u9009\u4e2d\u7684\u6587\u4ef6\u65f6\uff0c\u5b83\u63cf\u8ff0*\u90a3\u4e2a\u6587\u4ef6*\uff1b\u6ca1\u9009\u4e2d\u65f6\u63cf\u8ff0*\u6240\u6709\u5df2\u6682\u5b58\u5185\u5bb9*\u3002\n\u7528\u4e86\u54ea\u4e00\u79cd\u4f1a\u5728\u63d0\u793a\u6761\u91cc\u8bf4\u660e\uff0c\u6240\u4ee5\u8303\u56f4\u6c38\u8fdc\u4e0d\u662f\u731c\u7684\u3002\u4e24\u8005\u90fd\u4e0d\u5b58\u5728\u65f6\u5b83\u4f1a\u76f4\u8bf4\uff0c\u800c\u4e0d\u662f\u7f16\u4e00\u6761\u4fe1\u606f\u51fa\u6765\u3002\n\n**\u8349\u7a3f\u5c31\u662f\u8349\u7a3f\u3002** \u5b83\u843d\u5728\u4fe1\u606f\u6846\u91cc\uff0c\u53ef\u4ee5\u7167\u5e38\u7f16\u8f91\u3002\u5982\u679c\u4f60\u5df2\u7ecf\u5199\u4e86\u5185\u5bb9\uff0c\u5b83\u4f1a\u5148\u95ee\u4e00\u53e5\u518d\u66ff\u6362\u3002\n\n\u6743\u9650\u662f `models.list`\uff08\u63d0\u4f9b\u6a21\u578b\u83dc\u5355\uff09\u4e0e `agent.complete`\uff08\u9ad8\u98ce\u9669\u2014\u2014\u4f1a\u82b1\u4f60\u7684\u6a21\u578b\u989d\u5ea6\uff09\u3002\n\u5bbf\u4e3b\u628a\u8fd9\u4ef6\u4e8b\u9650\u6d41\u5230**\u6bcf\u5206\u949f 8 \u6b21**\uff1b\u63d2\u4ef6\u628a\u8fd9\u4e2a\u9650\u5236\u62a5\u51fa\u6765\uff0c\u800c\u4e0d\u662f\u76f2\u76ee\u91cd\u8bd5\u3002\n\n## \u914d\u8272\n\n\u6d45\u8272\u914d\u8272\u5927\u90e8\u5206\u6284\u81ea JetBrains \u81ea\u5df1\u7684\u6587\u6863\uff1a\u65b0\u589e\u884c `#c6e4c1`\u3001\u4fee\u6539\u884c `#e9eff9`\u3001\u53d8\u5316\u7247\u6bb5\u84dd `#c6d7f0`\u3001\n\u9762\u677f\u5206\u9694\u7ebf\u3001\u7f16\u8f91\u5668\u8fb9\u680f\u7684\u53d8\u66f4\u6761\uff0c\u4ee5\u53ca\u6587\u4ef6\u72b6\u6001\u8272\uff08\u65b0\u589e `#0a7700`\u3001\u4fee\u6539 `#0032a0`\u3001\u672a\u7248\u672c\u63a7\u5236 `#993300` \u7b49\uff09\u3002\n\u4f59\u4e0b\u7684\u754c\u9762\u9970\u4ef6\u7167\u7740 IntelliJ Light \u4e0e Darcula \u7684\u6837\u5b50\u6765\uff0c\u90a3\u4e9b\u5730\u65b9 JetBrains \u6ca1\u6709\u516c\u5e03\u6570\u503c\u3002\n\n**\u4e00\u4e2a\u523b\u610f\u7684\u504f\u79bb\uff0c\u4e24\u5957\u4e3b\u9898\u90fd\u6709\uff1a** JetBrains \u628a\u5220\u9664\u884c\u8bb0\u6210\u4e00\u4e2a\u4e2d\u6027\u7070\uff08\u6d45\u8272 `#D7D6D6`\uff09\u3002\n\u7d27\u6328\u7740\u7eff\u8272\u7684\u65b0\u589e\uff0c\u90a3\u4e2a\u7070\u8bfb\u8d77\u6765\u50cf*\u892a\u8272*\u800c\u4e0d\u662f*\u88ab\u5220\u6389*\uff0c\u6240\u4ee5\u5220\u9664\u7528\u67d4\u548c\u7684\u7ea2\u8272\u2014\u2014\u6d45\u8272 `#f7d2d2`\uff0c\u6697\u8272 `#452a2e`\u3002\n\n**\u6697\u8272 diff \u914d\u8272\u662f\u8c03\u51fa\u6765\u7684\uff0c\u4e0d\u662f\u6284\u7684\u3002** \u6587\u6863\u91cc\u7684\u6697\u8272\u503c\u7ed9\u51fa\u4e00\u79cd\u504f\u68d5\u7684\u884c\u5e95\u8272\uff0c\u800c\u4e00\u5757\u94a2\u84dd\u8272\u7684\u7247\u6bb5\u8865\u4e01\u538b\u5728\u6697\u7ea2\u884c\u4e0a\u4f1a\u53d8\u6210\u4e00\u56e2\u6ce5\u3002\n\u6240\u4ee5\u6697\u8272\u5e26\u81ea\u5df1\u7684\u4e00\u5957\u503c\uff0c\u800c\u4e14\u53d8\u5316\u7247\u6bb5\u7684\u989c\u8272\u8ddf\u7740\u5b83\u6240\u5728\u7684\u884c\u8d70\uff1a\u5220\u9664\u884c\u4e0a\u66f4\u7ea2\uff0c\u65b0\u589e\u884c\u4e0a\u66f4\u7eff\u3002\n`--diff-fragment-deleted` / `--diff-fragment-inserted` \u662f\u4e24\u4e2a\u8986\u76d6\u70b9\uff08\u53ea\u5728\u6697\u8272\u4e3b\u9898\u91cc\u5b9a\u4e49\uff09\uff1b\u6d45\u8272\u4e3b\u9898\u4e0d\u8bbe\u5b83\u4eec\uff0c\u4fdd\u7559 JetBrains \u7684\u84dd\u3002\n\n\u4e3b\u9898\u5207\u6362\u8d70 `document.documentElement.dataset.theme`\uff0c\u7531 `app.getAppearance` \u521d\u59cb\u5316\u3001\u5e76\u8ba2\u9605 `appearance:changed` \u8ddf\u968f\u5bbf\u4e3b\u3002\n\u5168\u90e8\u90fd\u5728 `src/theme.css` \u9876\u90e8\u7684 CSS \u53d8\u91cf\u91cc\uff0c\u6240\u4ee5\u91cd\u65b0\u8c03\u4e00\u5904\u5c31\u662f\u6539\u4e00\u884c\u3002\n\n## \u6d4b\u8bd5\u4e0e\u5de5\u5177\n\n### \u5f15\u64ce\u56de\u5f52\n\n`tools/harness.mjs` \u5bf9\u7740**\u5f53\u573a\u9020\u51fa\u6765\u7684\u771f\u5b9e\u4ed3\u5e93**\u9a71\u52a8\u5f15\u64ce\u2014\u2014\u4e00\u4e2a\u88f8\u8fdc\u7aef\u3001\u4e00\u4e2a\u76f4\u63a5\u521d\u59cb\u5316\u7684\u5de5\u4f5c\u526f\u672c\u52a0\u4e00\u4e2a\u771f\u6b63\u7684 `git clone`\u3001\n\u4e00\u6b21\u771f\u5b9e\u7684\u53cc\u4eba\u5206\u53c9\u3001\u4e00\u4e2a\u5185\u542b\u5b50\u6a21\u5757\u7684\u5b50\u6a21\u5757\u2014\u2014\n\u5e76\u65ad\u8a00\u90a3\u4e9b\u300c\u62d2\u7edd\u300d\u6240\u4f9d\u8d56\u7684\u884c\u4e3a\uff1a\u5206\u7c7b\u3001\u6d88\u606f\u3001\u8be6\u60c5\u3001\u5148\u9648\u65e7\u518d fetch \u7684 ahead/behind \u6807\u7b7e\u3001\u51b2\u7a81\u7684\u5408\u5e76\u53ca\u5176\u51fa\u53e3\u3001\n\u4e00\u6b21\u63a8\u9001\u843d\u5230\u54ea\u91cc\uff08\u4ee5\u53ca\u88ab\u62d2\u7edd\u843d\u5230\u54ea\u91cc\uff09\u3001\u9648\u65e7\u7684 lease \u6c38\u8fdc\u4e0d\u4f1a\u8986\u76d6\u540c\u4e8b\u7684\u5de5\u4f5c\uff1b\n\u6700\u540e\u51e0\u6bb5\u8fd8\u5305\u62ec\uff1a\u5d4c\u5957\u5728\u53e6\u4e00\u4e2a\u4ed3\u5e93\u91cc\u7684\u4ed3\u5e93\u4f1a\u88ab\u5217\u51fa\u3001\u53ef\u4ee5\u88ab\u9009\u4e2d\u3001\u53ef\u4ee5\u5728\u91cc\u9762\u63d0\u4ea4\u3001\u626b\u63cf\u80fd\u770b\u591a\u8fdc\u3001\n`.gitmodules` \u7684\u58f0\u660e\u80fd\u63a8\u7ffb\u4ec0\u4e48\uff0c\u4ee5\u53ca\u4e00\u4efd\u6765\u81ea\u300c\u89c6\u56fe\u5df2\u7ecf\u79bb\u5f00\u7684\u4ed3\u5e93\u300d\u7684\u8865\u4e01\u4f1a\u88ab\u62d2\u7edd\u800c\u4e0d\u662f\u88ab\u5e94\u7528\u3002\n\n```bash\nnode tools/harness.mjs # \u5b9e\u6d4b\u8f93\u51fa\uff1a136/136 passed\uff0c\u5168\u90e8\u5bf9\u7740\u771f\u5b9e git\nnode tools/harness.mjs --keep # \u4fdd\u7559\u4e34\u65f6\u4ed3\u5e93\uff0c\u4fbf\u4e8e\u4e8b\u540e\u7ffb\u770b\n```\n\n`PLUGIN_DIR` \u53ef\u4ee5\u628a harness \u6307\u5411\u53e6\u4e00\u4efd\u68c0\u51fa\u3002\n\n### \u51b3\u7b56\u7b14\u8bb0\u95e8\u7981\n\n`.agents/notes/` \u4e0b\u7684\u7b14\u8bb0\u627f\u8f7d\u300c\u4ee3\u7801\u672c\u8eab\u5e26\u4e0d\u52a8\u7684\u51b3\u5b9a\u300d\u2014\u2014\u4e3a\u4ec0\u4e48\u662f\u8fd9\u4e2a\u5f62\u72b6\uff0c\u4ee5\u53ca\u5b83\u6362\u6389\u4e86\u4ec0\u4e48\u3002\n\u4e00\u7bc7\u6ca1\u4eba\u80fd\u627e\u5230\u7684\u7b14\u8bb0\u3001\u6216\u8005\u5934\u5757\u6f02\u79fb\u4e86\u7684\u7b14\u8bb0\uff0c\u662f\u4e0b\u4e00\u4e2a\u8bfb\u8005\uff08\u4eba\u6216 agent\uff09\u4e0d\u4f1a\u4fe1\u4efb\u7684\u7b14\u8bb0\uff0c\n\u6240\u4ee5\u5f62\u72b6\u662f**\u5f3a\u5236**\u7684\u800c\u4e0d\u662f\u7ea6\u5b9a\u4fd7\u6210\u7684\uff1a\n\n```bash\nnode tools/notes.mjs # \u4e24\u9879\u6821\u9a8c\uff1a\u76ee\u5f55/\u5206\u7c7b/\u76f8\u5bf9\u94fe\u63a5 + \u5934\u5757/Status/\u5fc5\u9700\u7ae0\u8282\n```\n\n\u4e24\u4e2a\u6821\u9a8c\u5668\u9010\u5b57\u8282 vendored \u5728 `tools/agent-notes/` \u4e0b\uff0c\u6240\u4ee5**\u65e0\u8bba\u673a\u5668\u4e0a\u88c5\u6ca1\u88c5\u90a3\u4e2a skill \u90fd\u80fd\u8dd1**\uff1b\n\u5b83\u4eec\u4e5f\u7531 `node tools/harness.mjs` \u4e00\u8d77\u65ad\u8a00\uff08136 \u6761\u91cc\u6709 2 \u6761\u6765\u81ea\u8fd9\u91cc\uff09\u3002\n\u672c\u673a Node 26 \u80fd\u76f4\u63a5\u6267\u884c `.ts`\uff0c\u4e0d\u9700\u8981 tsx \u6216\u4efb\u4f55 flag\u3002\n\n### \u4e0d\u5f00 GUI \u9a71\u52a8\u5f15\u64ce\n\n`tools/drive.mjs` \u8c03\u7528\u7684\u662f\u89c6\u56fe\u8c03\u7528**\u540c\u4e00\u6279** `onPanelInvoke` \u901a\u9053\uff0c\u53ea\u662f\u7ed9\u4e86\u4e2a\u6869 `pi` \u5168\u5c40\uff0c\n\u6240\u4ee5\u4e00\u6761\u6d41\u7a0b\u53ef\u4ee5\u4ece\u7ec8\u7aef\u6216\u6d4b\u8bd5\u811a\u672c\u91cc\u8dd1\u901a\uff1a\n\n```bash\nnode tools/drive.mjs /path/to/repo git/repo\nnode tools/drive.mjs /path/to/repo git/stage '{\"paths\":[\"src/app.js\"]}'\nnode tools/drive.mjs /path/to/repo git/commit '{\"message\":\"Fix the thing\"}'\n```\n\n\u7528**\u524a\u51cf\u8fc7\u7684\u73af\u5883**\u8dd1\u5b83\uff0c\u624d\u548c\u771f\u5b9e\u63d2\u4ef6\u8fdb\u7a0b\u62ff\u5230\u7684\u4e1c\u897f\u4e00\u81f4\u2014\u2014`PATH`\u3001`LANG` \u548c\u4e34\u65f6\u53d8\u91cf\uff0c\u4f46**\u6ca1\u6709 `HOME`**\uff1a\n\n```bash\nenv -i PATH=\"$PATH\" TMPDIR=\"${TMPDIR:-/tmp}\" node tools/drive.mjs . git/repo\n```\n\n\u8fd9\u4e48\u8dd1\u7b49\u4e8e\u590d\u73b0\u4e86\u771f\u5b9e\u63d2\u4ef6\u8fdb\u7a0b\u7684\u73af\u5883\uff0c\u6240\u4ee5\u63a8\u9001\u8def\u5f84\u4e5f\u80fd\u5728**\u4e0d\u52a0\u7ec8\u7aef**\u7684\u60c5\u51b5\u4e0b\u5bf9\u7740\u4efb\u610f\u8fdc\u7aef\u8bd5\u2014\u2014\n\uff08\u6ce8\u610f harness \u91cc\u5168\u90e8\u8fdc\u7aef\u90fd\u662f\u672c\u5730\u88f8\u4ed3\uff0c\u6ca1\u6709\u771f\u7684\u5f80 HTTPS \u8fdc\u7aef\u63a8\u8fc7\uff1b\u8981\u9a8c\u8bc1\u771f\u5b9e\u6258\u7ba1\uff0c\u8bf7\u81ea\u5df1\u6311\u4e00\u4e2a\u8fdc\u7aef\u8dd1\u4e0a\u9762\u8fd9\u6761\u547d\u4ee4\u3002\uff09\n\n\u6a21\u578b\u76f8\u5173\u7684\u4e24\u4e2a\u901a\u9053\u6709\u6869\uff1a`PIG_FAKE_MODELS`\uff08\u503c `denied` \u4f1a\u8fd4\u56de `PERMISSION_DENIED`\uff09\u3001\n`PIG_FAKE_COMPLETE`\uff08`RATE_LIMITED` / `error:\u2026`\uff09\u3001`PIG_SHOW_PROMPT=1` \u4f1a\u628a\u771f\u6b63\u53d1\u51fa\u53bb\u7684\u63d0\u793a\u8bcd\u6253\u51fa\u6765\u3002\n\n### \u6ca1\u6709\u5bbf\u4e3b\u4e5f\u80fd\u770b\u89c6\u56fe\n\n`tools/smoke.mjs` \u628a\u6784\u5efa\u597d\u7684\u89c6\u56fe\u914d\u4e0a\u6869 `window.pluginBridge` \u5199\u5230 `.smoke/`\uff0c\n\u4e8e\u662f\u90a3\u4e9b\u96be\u4ee5\u6309\u9700\u5236\u9020\u7684\u72b6\u6001\uff08\u4ed3\u5e93\u5361\u5728\u5408\u5e76\u4e2d\u3001\u4e00\u6b21\u88ab\u8fdc\u7aef\u62d2\u7edd\u7684\u63a8\u9001\u3001\u4e00\u4e2a\u5df2\u68c0\u51fa\u7684\u5b50\u6a21\u5757\u4f5c\u4e3a\u5f53\u524d\u4ed3\u5e93\uff09\u53ef\u4ee5\u6e32\u67d3\u51fa\u6765\u770b\uff1a\n\n```bash\nnode tools/build.mjs && node tools/smoke.mjs commit zh-CN\n```\n\n\u89c6\u56fe\u540d\u4e0e\u8bed\u8a00\u90fd\u662f\u4f4d\u7f6e\u53c2\u6570\uff08\u4ea7\u7269\u662f `.smoke/<\u89c6\u56fe>-<\u8bed\u8a00>.html`\uff09\u3002\u6869\u5728\u5de5\u5177\u91cc\uff0c\u4e0d\u5728\u63d2\u4ef6\u91cc\uff0c`.smoke/` \u5df2 gitignore\u3002\n\n## \u5f00\u53d1\u4e0e\u6253\u5305\n\n1. \u6269\u5c55\u9875\u53f3\u4e0a\u89d2 **`\u00b7\u00b7\u00b7` \u2192 \u300c\u52a0\u8f7d\u672c\u5730\u63d2\u4ef6\u300d** \u2192 \u9009\u8fd9\u4e2a\u76ee\u5f55\u3002\n2. \u6539 `src/`\uff0c\u8dd1 `node tools/build.mjs`\uff0c\u89c6\u56fe\u4f1a\u70ed\u91cd\u8f7d\u3002\n3. \u7ec4\u88c5\u5e72\u51c0\u7684\u53d1\u5e03\u76ee\u5f55\u518d\u6253 Pack\uff1a`node tools/build.mjs && node tools/make-publish-dir.mjs`\uff0c\u7136\u540e\u5bf9 `dist-publish/io.github.liushunqiu.pi-idea-git/` \u8dd1 `PluginCheck` / `PluginPack`\uff08\u4ea7\u7269\u5728\u8be5\u76ee\u5f55\u7684 `dist/*.piplug`\uff0c8 \u4e2a\u6587\u4ef6\u7ea6 0.9MB\uff09\u3002**\u4e0d\u8981\u76f4\u63a5\u5bf9\u4ed3\u5e93\u6839\u6253 Pack**\u2014\u2014\u5b83\u4f1a\u628a `.smoke/`\u3001`.memories/`\u3001`tools/`\u3001`src/` \u7b49\u5f00\u53d1\u6587\u4ef6\u4e00\u8d77\u6253\u8fdb\u53bb\uff08`PluginPack` \u4e0d\u8bfb `.gitignore`\uff0c\u4e14\u6ca1\u6709\u6392\u9664\u6587\u4ef6\u673a\u5236\uff0c\u5b9e\u6d4b 2.1MB / 46 \u6587\u4ef6\uff09\u3002\n \u4ece\u8001 ID `local.pi-idea-git` \u5347\u7ea7\u4e0a\u6765\u7684\u7528\u6237\uff0c\u63d0\u4ea4\u4fe1\u606f\u5386\u53f2\u4e0e\u89c6\u56fe\u9009\u9879\u4e0d\u4f1a\u8fc1\u79fb\uff08\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u6309 ID \u9694\u79bb\uff09\u3002\n\n\u8d28\u91cf\u5e95\u7ebf\uff08\u6539\u5b8c\u4ee3\u7801\u8fc7\u4e00\u904d\uff09\uff1a`node --check` \u6bcf\u4e2a `src/*.js`\u3001`PluginCheck` \u65e0 error\u3001`node tools/harness.mjs` \u5168\u7eff\u3002\n\n> **\u6269\u5927 `permissions` \u9700\u8981\u6bd4\u300cReload\u300d\u6309\u94ae\u66f4\u957f\u7684\u8def\u5f84\u3002**\n> \u4fdd\u5b58\u89e6\u53d1\u7684\u70ed\u91cd\u8f7d\u4f1a\u62d2\u7edd\u4e00\u4e2a\u300c\u8981\u7684\u6743\u9650\u591a\u4e8e\u8fd0\u884c\u5b9e\u4f8b\u5df2\u83b7\u6279\u7684\u300d\u6e05\u5355\u3002\u5361\u7247\u4e0a\u7684 **Reload** \u6309\u94ae\u4e5f\u4e0d\u591f\uff1a\n> \u5b83\u628a\u65b0\u6e05\u5355\u4e0e `registry.json` \u91cc\u8bb0\u5f55\u7684\u6743\u9650\u6c42\u4ea4\u96c6\uff0c**\u9759\u9ed8\u4e22\u6389\u65b0\u589e\u7684\u90a3\u4e9b\uff0c\u5374\u7167\u6837\u62a5\u544a\u6210\u529f**\u3002\n> \u53ea\u6709 **`\u00b7\u00b7\u00b7` \u2192 \u300c\u52a0\u8f7d\u672c\u5730\u63d2\u4ef6\u300d**\uff08\u91cd\u65b0\u9009\u4e00\u6b21\u76ee\u5f55\uff09\u4f1a\u91cd\u8bfb\u6e05\u5355\u5e76\u91cd\u65b0\u5f81\u6c42\u540c\u610f\u3002\n\n\u5bbf\u4e3b\u7248\u672c\u8981\u6c42\u5199\u5728\u540c\u4e00\u4efd\u6e05\u5355\u91cc\uff1a`engines.piDesktop >= 0.8.0`\u3002\n\n## \u5df2\u77e5\u7f3a\u53e3\n\n\u8bda\u5b9e\u6e05\u5355\u2014\u2014\u8fd9\u4e9b\u662f\u5f53\u524d\u5b9e\u73b0\u91cc\u786e\u5b9e\u5b58\u5728\u3001\u4e14\u7528\u6237\u53ef\u80fd\u649e\u4e0a\u7684\u9650\u5236\uff1a\n\n - **\u6587\u672c\u641c\u7d22\u662f\u672c\u5730\u8fc7\u6ee4**\uff1a\u5de5\u5177\u680f\u641c\u7d22\u6846\u53ea\u5728\u5df2\u53d6\u56de\u7684 200 \u6761\u5185\u505a substring \u5339\u914d\uff1b\u8981\u6309\u63d0\u4ea4\u4fe1\u606f\u5728\u670d\u52a1\u7aef\u67e5\uff0c\u7528\u5206\u652f\uff0f\u7528\u6237\uff0f\u65e5\u671f\uff0f\u8def\u5f84\u8fc7\u6ee4\uff08\u5b83\u4eec\u90fd\u8fdb `git log` \u53c2\u6570\uff09\u3002\n- **Console \u4e0d\u662f\u300c\u6bcf\u6761\u547d\u4ee4\u90fd\u8bb0\u300d**\uff1a\u63a2\u6d4b\u578b\u547d\u4ee4\u6210\u529f\u65f6\u4e0d\u8bb0\u5f55\uff08\u89c1\u300c\u5f15\u64ce\u8bbe\u8ba1\u300d\uff09\uff0c\u5931\u8d25\u65f6 short/detail \u90fd\u6709\u957f\u5ea6\u4e0a\u9650\u3002\n- **hunk \u7ea7\u64cd\u4f5c\u7684\u9002\u7528\u9762**\uff1a`Ignore whitespaces` \u6253\u5f00\u65f6\u7981\u7528\uff0c\u672a\u8ddf\u8e2a\u6587\u4ef6\u7981\u7528\uff08\u6574\u6587\u4ef6 `Add` \u4ecd\u53ef\u7528\uff09\u3002\n- **`Edit Commit Message` \u53ea\u5bf9 HEAD \u5f00\u653e**\u3002\n- **Commit \u89c6\u56fe\u6587\u4ef6\u83dc\u5355\u7684\u590d\u5236\u9879**\uff1a\u6709\u63d0\u4ea4\u65f6\u663e\u793a\u300cCopy Revision Number\u300d\u5e76\u590d\u5236 HEAD\uff08\u4e0e Log \u89c6\u56fe\u4e00\u81f4\uff09\uff0c\u5c1a\u65e0\u63d0\u4ea4\u65f6\u663e\u793a\u300c\u590d\u5236\u8def\u5f84/Copy Path\u300d\u5e76\u590d\u5236\u6587\u4ef6\u8def\u5f84\u3002\n- **\u4e24\u5904\u300c\u56de\u6eda\u300d\u540c\u540d\u4e0d\u540c\u4e49**\uff1a\u63d0\u4ea4\u4e0b\u62c9\u91cc\u7684\u300c\u56de\u6eda\u300d\u628a\u5df2\u6682\u5b58\u5185\u5bb9\u79fb\u51fa\u7d22\u5f15\uff08`git/unstage`\uff09\uff0c\u6587\u4ef6\u53f3\u952e\u91cc\u7684\u300c\u56de\u6eda\u300d\u4f1a**\u4e22\u5f03\u6539\u52a8**\uff08`git/discard`\uff0c\u672a\u8ddf\u8e2a\u6587\u4ef6\u76f4\u63a5\u5220\u9664\uff09\u3002\u540c\u540d\uff0c\u4f46\u5371\u9669\u7b49\u7ea7\u4e0d\u540c\u2014\u2014\u6309\u4e0b\u53bb\u4e4b\u524d\u5148\u770b\u5b83\u95ee\u7684\u662f\u4ec0\u4e48\u3002\n- **\u751f\u6210\u7684 HTML \u56fa\u5b9a `lang=\"en\"`**\uff0c\u4e0e\u754c\u9762\u8bed\u8a00\u65e0\u5173\u3002\n- **\u6267\u884c\u8fb9\u754c**\uff1a\u5355\u6761\u547d\u4ee4 25 \u79d2\u540e\u88ab\u6740\uff1bConsole \u53ea\u7559\u6700\u8fd1 200 \u6761\u3001\u65e5\u5fd7\u4e00\u6b21\u6700\u591a\u53d6 500 \u6761\u3001\u9519\u8bef\u8be6\u60c5\u4e0e Console \u7684\u6bcf\u6761\u8f93\u51fa\u90fd\u622a\u5230 4000 \u5b57\u7b26\u2014\u2014\u8fd9\u4e9b\u622a\u65ad\u662f\u9759\u9ed8\u7684\u3002\u552f\u4e00\u4f1a**\u62a5\u51fa\u6765**\u7684\u662f stdout \u8d85\u8fc7 8 MiB\uff1a\u90a3\u6761\u547d\u4ee4\u88ab\u6740\u6b7b\u5e76\u62a5 `Git output exceeded the size limit.`\uff08stderr \u8d85\u9650\u5219\u662f\u9759\u9ed8\u505c\u6b62\u6536\u96c6\uff09\u3002\n- **\u5bbf\u4e3b\u8d85\u65f6**\uff1a\u4efb\u4f55\u4e00\u6b21\u9762\u677f\u8c03\u7528\u8d85\u8fc7 30 \u79d2\uff0c\u90fd\u4f1a\u4ee5\u5bbf\u4e3b\u4fa7\u8d85\u65f6\u7684\u5f62\u5f0f\u5931\u8d25\uff1b\u5f15\u64ce\u7684 25 \u79d2\u4e0a\u9650\u5c31\u662f\u4e3a\u4e86\u8ba9\u5931\u8d25\u5148\u53d1\u751f\u5728 Git \u8fd9\u4e00\u4fa7\u3002\n- **\u6d4b\u8bd5\u4e0d\u8986\u76d6\u771f\u5b9e\u5bbf\u4e3b**\uff1aharness \u4e0e smoke \u7528\u7684\u662f\u6869\uff0c`PluginCheck` \u53ea\u770b `main.js`\uff08\u4e8e\u662f\u89c6\u56fe\u7ecf\u6865\u8c03\u7528\u7684\u6743\u9650\u88ab\u8bef\u62a5\u4e3a unused\uff09\u3002\n\n## \u8bb0\u5fc6\u4e0e\u51b3\u7b56\u7b14\u8bb0\n\n\u4ed3\u5e93\u91cc\u4e24\u7c7b\u7b14\u8bb0\u90fd\u662f\u7eaf Markdown\uff0c\u968f\u5305\u4e00\u8d77\u8d70\uff1a\n\n- `.memories/` \u2014\u2014 \u6392\u67e5\u8fc7\u7a0b\u4e0e\u8fd0\u884c\u65f6\u4e8b\u5b9e\uff08\u63d2\u4ef6\u8fd0\u884c\u65f6\u7ea6\u675f\u3001\u6e32\u67d3\u8fdb\u7a0b CPU \u8bca\u65ad\u6cd5\u3001\u5bbf\u4e3b API \u4e8b\u5b9e\u3001\n push/pull \u51b2\u7a81\u3001\u5d4c\u5957\u4ed3\u5e93\u3001\u7b14\u8bb0 skill \u6f02\u79fb\uff09\u3002\n- `.agents/notes/implemented/architecture/` \u2014\u2014 \u56db\u7bc7\u843d\u5730\u51b3\u7b56\u7b14\u8bb0\uff1a\u4e3a\u4ec0\u4e48\u7528 Git CLI \u800c\u4e0d\u662f\u89e3\u6790 `.git/`\u3001\n \u4e3a\u4ec0\u4e48\u505a\u6210\u4e24\u4e2a docked view\u3001\u4e3a\u4ec0\u4e48\u52a0\u6784\u5efa\u6b65\u9aa4\u3001\u53d8\u66f4\u5217\u8868\u4e3a\u4ec0\u4e48\u6539\u6210\u76ee\u5f55\u6811\uff1b\n \u63d0\u4ea4\u4fe1\u606f\u63d0\u793a\u8bcd\u4e3a\u4ec0\u4e48\u628a\u8bed\u8a00\u505a\u6210\u663e\u5f0f\u53c2\u6570\uff1b\u8fdc\u7aef\u51b2\u7a81\u4e3a\u4ec0\u4e48\u5fc5\u987b\u8bfb\u4e24\u4e2a\u6d41\u3001\u4e3a\u4ec0\u4e48\u53ea\u80fd\u6709 `--force-with-lease`\uff1b\n \u4e3a\u4ec0\u4e48\u4ed3\u5e93\u5217\u8868\u662f\u4f1a\u8bdd\u7ea7\u7684\u3001\u4ee5\u53ca `kind` \u4e3a\u4ec0\u4e48\u7531 gitlink \u5224\u5b9a\u3002\n\n\u6838\u5fc3\u4ee3\u7801\u5165\u53e3\u7559\u4e86\u4e00\u884c `// Note: <\u4e3a\u4ec0\u4e48\u8fd9\u6837\u505a\u3001\u653e\u5f03\u4e86\u4ec0\u4e48> \u2014 \u89c1 .agents/notes/\u2026`\uff0c\u523b\u610f\u4e0d\u9010\u884c\u6807\uff1b\n\u51b3\u5b9a\u88ab\u53d6\u4ee3\u65f6\uff0c\u8fd9\u4e9b\u6ce8\u91ca\u5c31\u662f\u8981\u540c\u6b65\u7684\u4ee3\u7801\u6e05\u5355\u3002\n", - "safetyNotes": "\u53ea\u8bfb\u5de5\u4f5c\u533a\u6587\u4ef6\uff08Open File / Reveal \u8d70\u5bbf\u4e3b fs \u63a5\u53e3\uff09\uff1b\u4e22\u5f03\u672a\u8ddf\u8e2a\u6587\u4ef6\u65f6\u4f1a\u76f4\u63a5\u5220\u9664\u8be5\u6587\u4ef6\uff08\u64cd\u4f5c\u524d\u6709\u786e\u8ba4\u6846\uff09\uff0c\u5176\u4f59\u5199\u64cd\u4f5c\u4e00\u5f8b\u8d70 Git \u547d\u4ee4\u3002\u751f\u6210\u63d0\u4ea4\u4fe1\u606f\u8c03\u7528\u5bbf\u4e3b\u6a21\u578b\uff0c\u7528\u7684\u662f\u4f60\u81ea\u5df1\u7684\u6a21\u578b\u914d\u7f6e\u4e0e\u989d\u5ea6\uff08\u5bbf\u4e3b\u9650\u6d41 8 \u6b21/\u5206\uff09\uff0c\u63d2\u4ef6\u4e0d\u6301\u6709\u4efb\u4f55 API Key\uff0c\u4e0d\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\uff0c\u65e0\u9065\u6d4b\u3002HTTPS \u51ed\u636e\u8d70\u4f60\u81ea\u5df1\u7684 Git \u51ed\u636e\u52a9\u624b\uff1b\u53ea\u6d3b\u5728 ssh-agent \u91cc\u7684\u5bc6\u94a5\u7528\u4e0d\u4e86\uff0c\u8bf7\u7528 HTTPS \u8fdc\u7aef\u6216\u94a5\u5319\u4e32\u5bc6\u94a5\u3002", - "versions": [ - { - "version": "0.3.0", - "publishedAt": "2026-09-14T04:35:09Z", - "changelog": "Release 0.3.0: Git operations parity (Branches panel with HEAD/Tags/Remotes/Stashes groups and slash-folder collapsing; branch merge/rebase/rename/upstream/delete; commit copy/compare; toolbar user/date/path server-side filters, Go to HEAD, Fetch+Pull shortcuts); git/log server-side author/since/until/search/paths filters plus git/tags, git/remotes, git/merge, git/rebase and more; remote checkout creates a tracking branch (IDEA behavior); commit-message drafting follows the checked/staged scope.", - "minPiDesktop": ">=0.8.0", - "shasum": "fbf784997dfa00c617437bc3d90d30b1d818d1af37cfb0927c4e22c2b37701f5", - "url": "packages/io.github.liushunqiu.pi-idea-git-0.3.0.piplug", - "sizeBytes": 1057159, - "permissions": [ - "ui.panel", - "ui.view", - "clipboard.write", - "fs.read", - "models.list", - "agent.complete" - ], - "fs": { - "read": { - "root": "workspace", - "scope": [ - "**" - ] - } - } - } - ] - }, - { - "id": "io.github.muzimu217.deps-audit", - "name": "Deps Audit", - "description": "\u4f9d\u8d56\u6f0f\u6d1e\u626b\u63cf\uff1a\u5524\u8d77 osv-scanner \u626b\u63cf\u5de5\u4f5c\u533a\uff0c\u5217\u51fa OSV \u6570\u636e\u5e93\u4e2d\u7684\u4f9d\u8d56\u6f0f\u6d1e\uff0c\u8ba9 Agent \u7ed9\u51fa\u5347\u7ea7\u6216\u4fee\u590d patch\u3002", - "i18n": { - "en": { - "name": "Deps Audit", - "description": "Dependency vulnerability audit: invoke osv-scanner over the workspace, list known OSV matches, and let the Agent propose a fix or upgrade.", - "safetyNotes": "Reads only the workspace-root dependency manifests listed in the declared fs.read scope (package.json, lockfiles, requirements.txt, Cargo.toml/lock, go.mod/sum, pom.xml, composer.json/lock, Gemfile/lock, pyproject.toml) through the host fs gateway, stages sanitized copies in a throwaway temp directory, and spawns the local osv-scanner binary against that directory \u2014 the spawned binary never reads the workspace directly and contacts the OSV database over the network (declared High-risk capability). Staging copies are deleted after each scan. Nothing in the workspace is ever written." - }, - "zh-CN": { - "name": "\u4f9d\u8d56\u5ba1\u8ba1", - "description": "\u4f9d\u8d56\u6f0f\u6d1e\u626b\u63cf\uff1a\u5524\u8d77 osv-scanner \u626b\u63cf\u5de5\u4f5c\u533a\uff0c\u5217\u51fa OSV \u6570\u636e\u5e93\u4e2d\u7684\u4f9d\u8d56\u6f0f\u6d1e\uff0c\u8ba9 Agent \u7ed9\u51fa\u5347\u7ea7\u6216\u4fee\u590d patch\u3002", - "safetyNotes": "Reads only the workspace-root dependency manifests listed in the declared fs.read scope (package.json, lockfiles, requirements.txt, Cargo.toml/lock, go.mod/sum, pom.xml, composer.json/lock, Gemfile/lock, pyproject.toml) through the host fs gateway, stages sanitized copies in a throwaway temp directory, and spawns the local osv-scanner binary against that directory \u2014 the spawned binary never reads the workspace directly and contacts the OSV database over the network (declared High-risk capability). Staging copies are deleted after each scan. Nothing in the workspace is ever written." - } - }, - "author": "muzimu217", - "categories": [ - "security", - "developer-tools", - "audit" - ], - "verified": true, - "downloads": 0, - "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/io.github.muzimu217.deps-audit", - "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# Deps Audit \u2014 io.github.muzimu217.deps-audit\n\n\u4f9d\u8d56\u6f0f\u6d1e\u626b\u63cf\uff1a\u628a\u5de5\u4f5c\u533a\u4ea4\u7ed9 [osv-scanner](https://github.com/google/osv-scanner)\uff0c\n\u628a\u7ed3\u679c\u4ee5 OSV \u6570\u636e\u5e93\u7684\u5206\u7c7b\u4e0e\u4e25\u91cd\u5ea6\u5c55\u793a\u5728\u5de5\u4f5c\u9762\u677f\u91cc\uff1b\u9009\u4e2d\u4e00\u6761\uff0cAgent \u7ed9\u51fa**\u6700\u5c0f\u5347\u7ea7\u6216\u4fee\u590d\u65b9\u6848**\n\uff08\u4e0d\u4f1a\u81ea\u52a8\u6539\u4efb\u4f55\u6587\u4ef6\uff0c\u5fc5\u987b\u4f60\u786e\u8ba4\uff09\u3002\n\n## \u5b89\u5168\u6a21\u578b\uff08\u5a01\u80c1\u6a21\u578b\uff09\n\nDeps Audit \u89e6\u53ca\u4e24\u7c7b\u9ad8\u6743\u80fd\u529b\uff1a**\u539f\u751f\u8fdb\u7a0b\u6267\u884c**\uff08osv-scanner\uff09\u4e0e**\u7f51\u7edc**\uff08osv-scanner\n\u81ea\u884c\u8bbf\u95ee OSV \u6570\u636e\u5e93\uff09\u3002\u6309\u4ed3\u5e93 SECURITY.md \u8fd9\u662f High \u98ce\u9669\u6863\uff0c\u63d2\u4ef6\u7684\u7ea6\u675f\u8bbe\u8ba1\uff1a\n\n1. **\u5de5\u4f5c\u533a\u8bfb\u53d6\u53ea\u8d70\u5bbf\u4e3b\u7f51\u5173**\uff1a\u6e05\u5355\u6587\u4ef6\u901a\u8fc7 `pi.fs.readText` \u8bfb\u53d6\uff0c\u4f5c\u7528\u57df\u5728\n manifest \u7684 `fs.read` \u58f0\u660e\u91cc\u9010\u6587\u4ef6\u5217\u51fa\uff08package.json\u3001\u5404\u8bed\u8a00\u9501\u6587\u4ef6\u7b49\uff09\uff0c\n \u5de5\u4f5c\u533a\u5176\u4f59\u5185\u5bb9\u5bf9\u63d2\u4ef6\u4e0d\u53ef\u89c1\u3002\n2. **\u539f\u751f\u4e8c\u8fdb\u5236\u6c38\u4e0d\u76f4\u63a5\u63a5\u89e6\u5de5\u4f5c\u533a**\uff1a\u8bfb\u53d6\u5230\u7684\u6e05\u5355\u5185\u5bb9\u4ee5\u51c0\u5316\u526f\u672c\u5f62\u5f0f\u5199\u5165\u4e00\u6b21\u6027\n \u4e34\u65f6\u76ee\u5f55\uff0cosv-scanner \u53ea\u88ab\u5141\u8bb8\u626b\u63cf\u8be5\u76ee\u5f55\uff1b\u626b\u63cf\u7ed3\u675f\u540e\u526f\u672c\u5373\u88ab\u5220\u9664\u3002\n3. **\u7f51\u7edc\u8fb9\u754c**\uff1a\u63d2\u4ef6\u8fdb\u7a0b\u81ea\u8eab\u96f6\u7f51\u7edc\u8bf7\u6c42\uff1b\u5bf9 OSV \u6570\u636e\u5e93\u7684\u8bbf\u95ee\u7531 osv-scanner\n \u4e8c\u8fdb\u5236\u81ea\u884c\u5b8c\u6210\uff08\u8fd9\u662f\u5b83\u4f5c\u4e3a\u626b\u63cf\u5668\u7684\u6838\u5fc3\u529f\u80fd\uff09\u3002\n4. **\u53ea\u8bfb\u627f\u8bfa**\uff1a\u5de5\u4f5c\u533a\u6c38\u4e0d\u88ab\u5199\u5165\uff1b\u9009\u4e2d\u6f0f\u6d1e\u540e\u300c\u8bf7 Agent \u4fee\u590d\u300d\u6c38\u8fdc\u9700\u8981\u7528\u6237\n \u663e\u5f0f\u53d1\u8d77\uff0c\u63d2\u4ef6\u53ea\u751f\u6210\u8bf7\u6c42\u6587\u672c\u3002\n5. **\u5931\u8d25\u53ef\u89c1**\uff1a\u4e8c\u8fdb\u5236\u7f3a\u5931/\u635f\u574f\u3001\u626b\u63cf\u8d85\u65f6\u3001\u975e\u96f6\u9000\u51fa\u3001\u8f93\u51fa\u4e0d\u53ef\u89e3\u6790\u90fd\u6709\u660e\u786e\u7684\n \u7ed3\u6784\u5316\u9519\u8bef\u4e0e\u6d4b\u8bd5\u8986\u76d6\uff0c\u4e0d\u4f1a\u9759\u9ed8\u541e\u6389\u3002\n\n## \u4e3a\u4ec0\u4e48\u9700\u8981\u8fd9\u4e2a\u63d2\u4ef6\n\nPI-Desktop \u7684 `pi.advisor` \u5df2\u7ecf\u5728\u505a\"second opinion reviewer\"\uff0c\u4f46**\u6ca1\u6709\u63d2\u4ef6\u505a\"\u628a\u5de5\u4f5c\u533a\n\u4ea4\u7ed9\u4e00\u4e2a\u771f\u5b9e\u7684\u4f9d\u8d56\u626b\u63cf\u5668\uff0c\u518d\u7528 Agent \u89e3\u8bfb\u7ed3\u679c\"\u8fd9\u4e00\u6bb5**\u3002OSV.dev \u662f Google \u7ef4\u62a4\u7684\u5f00\u653e\u6f0f\u6d1e\n\u6570\u636e\u5e93\uff0c\u8986\u76d6 npm / PyPI / crates.io / Go / Maven / Composer / RubyGems\uff0c\u4e14 osv-scanner \u662f\nApache-2.0 \u7684\u7eaf\u672c\u5730 CLI\u2014\u2014\u975e\u5e38\u9002\u5408\u4f5c\u4e3a\"\u5b89\u5168\u4fa7\"\u8f93\u5165\u3002\n\n## \u5b89\u88c5\n\nDeps Audit **\u4e0d\u5f3a\u4f9d\u8d56** osv-scanner \u4e8c\u8fdb\u5236\u5b58\u5728\uff1b\u5982\u679c\u6ca1\u88c5\uff0c\u5b83\u4f1a\u7ed9\u51fa\u660e\u786e\u6307\u5f15\uff08\u8be6\u89c1\n\u6545\u969c\u6392\u67e5\uff09\u3002\u6700\u7a33\u7684\u5b89\u88c5\u65b9\u5f0f\uff1a\n\n```bash\n# \u65b9\u5f0f 1: Homebrew (macOS / Linux)\nbrew install osv-scanner\n\n# \u65b9\u5f0f 2: Go\ngo install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest\n\n# \u65b9\u5f0f 3: GitHub release\uff08\u6ce8\u610f macOS \u9700 ad-hoc \u7b7e\u540d\u6216\u4e0b\u8f7d\u672a\u538b\u7f29\u7684 brew bottle\uff09\n# https://github.com/google/osv-scanner/releases\n```\n\n## \u4f7f\u7528\n\n\u6253\u5f00 PI-Desktop\uff0c\u5728\u5de5\u4f5c\u9762\u677f\u91cc\u70b9 **Deps Audit**\uff08\u76fe\u724c\u56fe\u6807\uff09\uff0c\u6216\uff1a\n\n- **\u547d\u4ee4\u9762\u677f**\uff08`Cmd+K` / `Ctrl+K`\uff09\uff1a\n - `Deps Audit: Open Work-Panel View` \u2014 \u6253\u5f00\u9762\u677f\n - `Deps Audit: Scan Workspace Now` \u2014 \u7acb\u5373\u626b\u63cf\n- **Agent \u5de5\u5177**\uff1a`deps_audit_run` \u2014 Agent \u5728\u9700\u8981\u65f6\u53ef\u4ee5\u4e3b\u52a8\u8c03\u8d77\u626b\u63cf\n\n## \u5de5\u4f5c\u6d41\u7a0b\n\n1. \u6253\u5f00\u89c6\u56fe\uff0c\u70b9\u51fb\u300c\u626b\u63cf\u300d\n2. \u63d2\u4ef6 spawn \u4f60\u672c\u5730\u7684 `osv-scanner` \u626b\u63cf\u5de5\u4f5c\u533a\u6839\u4e0b\u7684 manifest\uff08`package.json`\u3001\n `requirements.txt`\u3001`Cargo.toml` \u7b49\uff09\n3. osv-scanner \u62c9\u53d6 OSV \u6570\u636e\u5e93\uff08**\u5b83**\u505a\u7684\u7f51\u7edc\u8bf7\u6c42\uff0c**\u63d2\u4ef6\u672c\u8eab\u4e0d\u8054\u7f51**\uff09\uff0c\u8fd4\u56de\u7ed3\u6784\u5316 JSON\n4. \u63d2\u4ef6\u89e3\u6790\u540e\u6309\u4e25\u91cd\u5ea6\uff08Critical \u2192 High \u2192 Medium \u2192 Low\uff09\u5c55\u793a\u5728\u5de5\u4f5c\u9762\u677f\n5. \u9009\u4e2d\u4e00\u6761 \u2192 \u70b9\u51fb\u300c\u590d\u5236\u7ed9 Agent \u8be2\u95ee\u4fee\u590d\u5efa\u8bae\u300d\u2192 \u6587\u672c\u91cc\u5305\u542b\u6f0f\u6d1e\u6458\u8981\u3001\u56fa\u5b9a\u7248\u672c\u3001advisory \u94fe\u63a5\n6. \u7c98\u5230 PI-Desktop \u5bf9\u8bdd\u6846 \u2192 Agent \u5148\u89e3\u91ca\u98ce\u9669\uff0c\u7ed9\u51fa\u6700\u5c0f\u5347\u7ea7\u65b9\u6848\uff0c**\u7b49\u4f60\u786e\u8ba4**\u624d\u6539\u6587\u4ef6\n\n## \u6743\u9650\u8bf4\u660e\n\n| \u6743\u9650 | \u7528\u9014 |\n| --- | --- |\n| `ui.panel` / `ui.view` | \u5de5\u4f5c\u9762\u677f\u89c6\u56fe |\n| `fs.read` | \u7ecf\u5bbf\u4e3b\u7f51\u5173\u8bfb\u53d6\u5de5\u4f5c\u533a\u6839\u76ee\u5f55\u7684\u4f9d\u8d56\u6e05\u5355\uff08\u9010\u6587\u4ef6\u5217\u5728 manifest \u7684 `fs.read` \u4f5c\u7528\u57df\u91cc\uff09\uff0c\u7528\u4e8e\u751f\u6210\u51c0\u5316\u526f\u672c |\n| `clipboard.write` | \u300c\u590d\u5236\u7ed9 Agent\u300d\u7ecf\u5bbf\u4e3b\u526a\u8d34\u677f\u6865\u5199\u5165 |\n| `agent.tool.register` | \u6ce8\u518c `deps_audit_run` \u5de5\u5177\uff08risk: high \u2014\u2014 \u539f\u751f\u6267\u884c + \u8054\u7f51\uff09 |\n\n**\u4e0d**\u58f0\u660e\u3001\u4e5f**\u4e0d**\u4f7f\u7528\u7684\uff1a\n- `agent.complete` / `models.list` \u2014\u2014 \u4fee\u590d\u5efa\u8bae\u7531\u4f60\u5728\u5bf9\u8bdd\u91cc\u5411 Agent \u53d1\u8d77\uff0c\u63d2\u4ef6\u4e0d\u8c03\u7528\u6a21\u578b\u3002\n- `fs.write` / `fs.delete` \u2014\u2014 \u5de5\u4f5c\u533a\u6c38\u4e0d\u88ab\u5199\u5165\u6216\u5220\u9664\u3002\n- `net.fetch` \u2014\u2014 \u63d2\u4ef6\u8fdb\u7a0b\u81ea\u8eab\u96f6\u7f51\u7edc\u8bf7\u6c42\uff1bOSV \u6570\u636e\u5e93\u7531 osv-scanner \u4e8c\u8fdb\u5236\u81ea\u884c\u62c9\u53d6\n \uff08\u8be5\u8054\u7f51\u884c\u4e3a\u5c5e\u4e8e SECURITY.md High \u6863\u7684\u539f\u751f\u6267\u884c\u80fd\u529b\uff0c\u5df2\u5728\u5b89\u5168\u6a21\u578b\u5c0f\u8282\u58f0\u660e\uff09\u3002\n\n## \u652f\u6301\u7684 manifest\n\n`package.json` / `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` /\n`requirements.txt` / `pyproject.toml` / `Pipfile` /\n`Cargo.toml` / `Cargo.lock` / `go.mod` / `go.sum` /\n`pom.xml` / `composer.json` / `composer.lock` / `Gemfile` / `Gemfile.lock`\n\nAgent \u5de5\u5177 `deps_audit_run` \u53ef\u901a\u8fc7 `manifests` \u53c2\u6570\u6536\u7a84\u8303\u56f4\u3002\n\n## \u8bbe\u7f6e\n\n- `scannerPath` \u2014 `osv-scanner` \u4e8c\u8fdb\u5236\u8def\u5f84\u6216 PATH \u4e2d\u7684\u540d\u5b57\uff08\u9ed8\u8ba4 `osv-scanner`\uff09\n- `severityMin` \u2014 \u4e25\u91cd\u5ea6\u8fc7\u6ee4\uff08`low` / `medium` / `high` / `critical`\uff0c\u9ed8\u8ba4 `low`\uff09\n\n## \u6545\u969c\u6392\u67e5\n\n**\u75c7\u72b6**\uff1a\u626b\u63cf\u540e\u72b6\u6001\u6761\u663e\u793a\"\u51fa\u9519\"\u4e14\u9762\u677f\u9876\u90e8\u7ea2\u8272 banner\n\n\u6700\u5e38\u89c1\u539f\u56e0\uff1a\n\n1. **\u672a\u5b89\u88c5 osv-scanner** \u2192 \u6309\u4e0a\u9762\"\u5b89\u88c5\"\u5c0f\u8282\u88c5\u4e00\u4e2a\uff0c\u6216\u5728\u8bbe\u7f6e\u91cc\u6539 `scannerPath` \u6307\u5411\n \u4f60\u81ea\u5df1\u88c5\u7684\u4e8c\u8fdb\u5236\u3002\n2. **\u8d85\u65f6**\uff08>120 \u79d2\uff09\u2192 \u4ed3\u5e93\u5f88\u5927\u3001\u4f9d\u8d56\u5f88\u591a\u3001\u6216 OSV \u6570\u636e\u5e93\u4e0b\u8f7d\u6162\u3002\u53ef\u624b\u52a8\u5148\u8dd1\n `osv-scanner scan source --format json .` \u770b\u8017\u65f6\u3002\n3. **JSON \u89e3\u6790\u5931\u8d25** \u2192 \u6781\u5c11\u89c1\uff0c\u8bf4\u660e osv-scanner \u8f93\u51fa\u4e86\u4e0d\u517c\u5bb9\u7684\u7248\u672c\u3002\u8bf7\u628a stderr \u8d34\u5230\n issue \u91cc\u3002\n\n## \u8bbe\u8ba1\u9009\u62e9\n\n- **\u4e3a\u4ec0\u4e48\u6e05\u5355\u8981\u5148\u590d\u5236\u5230\u4e34\u65f6\u76ee\u5f55\u518d\u626b**\uff1fosv-scanner \u662f\u539f\u751f\u4e8c\u8fdb\u5236\uff0c\u6309 SECURITY.md \u5c5e\u4e8e\n High \u98ce\u9669\u80fd\u529b\u3002\u8ba9\u5b83\u53ea\u8bfb\u53d6\u63d2\u4ef6\u7ecf\u5bbf\u4e3b\u7f51\u5173\u8bfb\u5230\u7684\u6e05\u5355\u526f\u672c\uff08\u4e00\u6b21\u6027\u4e34\u65f6\u76ee\u5f55\u3001\u626b\u63cf\u540e\u5373\u5220\uff09\uff0c\n \u88ab\u62c9\u8d77\u7684\u4e8c\u8fdb\u5236\u5c31\u6c38\u8fdc\u4e0d\u4f1a\u76f4\u63a5\u89e6\u78b0\u5de5\u4f5c\u533a\u2014\u2014\u8fb9\u754c\u5148\u5728\u63d2\u4ef6\u4fa7\u5b88\u4f4f\uff0c\u5bbf\u4e3b\u7f51\u5173\u662f\u7b2c\u4e8c\u9053\u9501\u3002\n- **\u4e3a\u4ec0\u4e48\u662f\"\u590d\u5236\u7ed9 Agent\"\u800c\u4e0d\u662f\u4e00\u952e fix**\uff1f\u5347\u7ea7\u4f9d\u8d56\u662f\u9ad8\u98ce\u9669\u64cd\u4f5c\uff08\u7834\u574f\u6027\u53d8\u66f4\u3001lock \u91cd\u751f\u3001\n \u5f71\u54cd\u4e0b\u6e38\uff09\u3002\u8ba9 Agent \u5148\u89e3\u91ca\u3001\u518d\u7ed9\u65b9\u6848\u3001\u6700\u540e\u7531\u4f60\u70b9\u5934\uff0c\u662f\u6700\u4e0d\u5bb9\u6613\u51fa\u4e8b\u7684\u4eba\u673a\u534f\u4f5c\u3002\n- **\u4e3a\u4ec0\u4e48 `deps_audit_run` \u662f high-risk**\uff1f\u5b83\u4f1a\u62c9\u8d77\u672c\u673a osv-scanner \u4e8c\u8fdb\u5236\uff08\u539f\u751f\u6267\u884c\uff09\uff0c\n \u4e14 osv-scanner \u4f1a\u8054\u7f51\u8bbf\u95ee OSV \u6570\u636e\u5e93\u3002\u5b81\u53ef\u8ba9\u7528\u6237\u5728\u6388\u6743\u65f6\u591a\u770b\u4e00\u773c\u3002\n\n## \u5f00\u53d1\n\n```bash\n# \u5728 PI-Desktop \u4ed3\u5e93\u5185\u6821\u9a8c\ncd ~/dev/pi-desktop\nenv -u NODE_OPTIONS -u PYTHONPATH ./node_modules/.bin/pi-plugin check \\\n ~/dev/pi-desktop-plugin-lab/deps-audit\n\n# \u8dd1\u6d4b\u8bd5\nnode --test test/*.test.mjs\n```\n\n## License\n\nMIT\n", - "safetyNotes": "\u53ea\u7ecf\u5bbf\u4e3b fs \u7f51\u5173\u8bfb\u53d6\u58f0\u660e\u4f5c\u7528\u57df\u5185\u7684\u5de5\u4f5c\u533a\u6839\u76ee\u5f55\u4f9d\u8d56\u6e05\u5355\uff08package.json\u3001\u5404\u8bed\u8a00\u9501\u6587\u4ef6\u7b49\uff09\uff0c\u628a\u51c0\u5316\u526f\u672c\u653e\u5165\u4e00\u6b21\u6027\u4e34\u65f6\u76ee\u5f55\uff0c\u518d\u5bf9\u4e34\u65f6\u76ee\u5f55\u8fd0\u884c\u672c\u673a osv-scanner \u4e8c\u8fdb\u5236\u2014\u2014\u88ab\u62c9\u8d77\u7684\u4e8c\u8fdb\u5236\u7edd\u4e0d\u76f4\u63a5\u8bfb\u53d6\u5de5\u4f5c\u533a\uff0c\u4e14\u4f1a\u8054\u7f51\u8bbf\u95ee OSV \u6570\u636e\u5e93\uff08\u5df2\u58f0\u660e High \u98ce\u9669\u80fd\u529b\uff09\u3002\u4e34\u65f6\u526f\u672c\u5728\u6bcf\u6b21\u626b\u63cf\u540e\u5220\u9664\uff1b\u5de5\u4f5c\u533a\u6c38\u4e0d\u88ab\u5199\u5165\u3002", - "versions": [ - { - "version": "0.2.0", - "publishedAt": "2026-09-12T17:13:25Z", - "changelog": "0.2.0\uff1a\u6309\u7ef4\u62a4\u8005\u8bc4\u5ba1\u91cd\u505a\uff08#20\uff09\u3002\u4fee\u590d\u63d2\u4ef6\u751f\u547d\u5468\u671f\uff08onLoad \u6539\u7528\u5bbf\u4e3b\u6ce8\u5165\u7684 globalThis.pi\uff0c\u539f\u5b9e\u73b0\u56e0\u7f3a\u53c2\u800c\u4ece\u4e0d\u6ce8\u518c\uff09\uff1b\u626b\u63cf\u9762\u677f\u6539\u7ecf\u5bbf\u4e3b API \u89e3\u6790\u5f53\u524d\u5de5\u4f5c\u533a\u4e0e\u8bbe\u7f6e\uff08\u4e0d\u518d\u8bef\u626b\u63d2\u4ef6\u8fdb\u7a0b\u76ee\u5f55\uff09\uff1b\u6e05\u5355\u6587\u4ef6\u6539\u7ecf fs.read \u6743\u9650\u7f51\u5173\u8bfb\u53d6\uff0c\u51c0\u5316\u526f\u672c\u6682\u5b58\u4e00\u6b21\u6027\u4e34\u65f6\u76ee\u5f55\u540e\u518d\u4ea4\u7ed9 osv-scanner\uff08\u539f\u751f\u4e8c\u8fdb\u5236\u4e0e\u7f51\u7edc\u80fd\u529b\u6309 SECURITY.md \u58f0\u660e\u4e3a High \u98ce\u9669\uff0c\u9644\u8d1f\u9762\u8def\u5f84\u6d4b\u8bd5\uff09\uff1bosv-scanner \u547d\u4ee4\u6539\u4e3a v2 \u6b63\u786e\u7528\u6cd5\uff08scan source --format json --recursive\uff09\uff1b\u526a\u8d34\u677f\u590d\u5236\u6539\u8d70\u5bbf\u4e3b clipboard.write \u6865\uff1bPATH \u67e5\u627e\u517c\u5bb9 Windows\uff08where.exe\uff09\uff1b\u9762\u677f\u7b26\u5408 v3 chrome \u5951\u7ea6\u30020.1.0\uff1a\u9996\u4e2a\u516c\u5f00\u7248\u672c\u3002", - "minPiDesktop": ">=0.14.3", - "shasum": "9df6675b676b9b731124ea696ed9480c1e16e98548d823e408616c2c5bb8b1f2", - "url": "packages/io.github.muzimu217.deps-audit-0.2.0.piplug", - "sizeBytes": 82410, - "permissions": [ - "ui.panel", - "ui.view", - "fs.read", - "clipboard.write", - "agent.tool.register" - ], - "fs": { - "read": { - "root": "workspace", - "scope": [ - "package.json", - "package-lock.json", - "yarn.lock", - "pnpm-lock.yaml", - "requirements.txt", - "pyproject.toml", - "Pipfile", - "Cargo.toml", - "Cargo.lock", - "go.mod", - "go.sum", - "pom.xml", - "composer.json", - "composer.lock", - "Gemfile", - "Gemfile.lock" - ] - } - } - } - ] - }, { "id": "io.github.muzimu217.session-import", "name": "Universal Session Import", @@ -301,20 +176,21 @@ "downloads": 0, "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/io.github.muzimu217.session-import", "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# Universal Session Import\uff08\u4e00\u4f53\u5316\u4f1a\u8bdd\u5bfc\u5165\uff09\n\nPI-Desktop \u63d2\u4ef6\uff1a**\u626b\u63cf\u672c\u673a\u5b89\u88c5\u7684\u7f16\u7a0b\u5de5\u5177\uff0c\u628a\u5b83\u4eec\uff08ZCode\u3001WorkBuddy\u3001Claude Code\u3001Codex\u3001OpenCode\u3001Pi\uff09\u7684\u672c\u5730\u4f1a\u8bdd\u7edf\u4e00\u5bfc\u5165 PI-Desktop\u3002**\n\n![scan sources](docs/screenshots/01-scan-sources.png)\n\n## \u4f7f\u7528\u6d41\u7a0b\n\n### 1. \u626b\u63cf\u672c\u673a\u5de5\u5177\n\n\u6253\u5f00\u9762\u677f\u70b9\u51fb\u300c\u626b\u63cf\u672c\u673a\u5de5\u5177\u300d\uff0c\u63d2\u4ef6\u5e76\u884c\u63a2\u6d4b\u516d\u4e2a\u6765\u6e90\uff0c\u5b9e\u65f6\u663e\u793a\u5404\u81ea\u68c0\u6d4b\u5230\u7684\u4f1a\u8bdd\u6570\uff08\u672a\u5b89\u88c5\u7684\u5de5\u5177\u663e\u793a\u300c\u672a\u68c0\u6d4b\u5230\u300d\uff09\u3002\n\n### 2. \u9009\u62e9\u6765\u6e90\uff0c\u6d4f\u89c8\u4f1a\u8bdd\n\n\u70b9\u51fb\u68c0\u6d4b\u5230\u7684\u5de5\u5177\u5361\u7247\uff0c\u6309\u9879\u76ee\u5206\u7ec4\u8f7d\u5165\u8be5\u6765\u6e90\u7684\u4f1a\u8bdd\u5217\u8868\uff08\u652f\u6301\u641c\u7d22\u3001\u6574\u7ec4\u5168\u9009\uff09\uff1a\n\n![session list](docs/screenshots/02-session-list.png)\n\n### 3. \u9884\u89c8\u5bf9\u8bdd\n\n\u70b9\u4efb\u610f\u4f1a\u8bdd\u5373\u53ef\u6309\u539f\u59cb\u987a\u5e8f\u8fd8\u539f\u5b8c\u6574\u5bf9\u8bdd\u2014\u2014\u7528\u6237\u6d88\u606f\u3001\u52a9\u624b\u56de\u590d\u3001\u5de5\u5177\u8c03\u7528\uff08\u53c2\u6570 + \u7ed3\u679c\u6298\u53e0\u5c55\u793a\uff0c\u9519\u8bef\u6807\u7ea2\uff09\uff1a\n\n![preview](docs/screenshots/03-preview.png)\n\n### 4. \u5bfc\u5165\u4e3a\u4f1a\u8bdd\n\n\u52fe\u9009\u4f1a\u8bdd\uff08\u652f\u6301\u6574\u7ec4\u5168\u9009\uff09\u2192\u300c\u5bfc\u5165\u4e3a\u4f1a\u8bdd\u300d\uff0c\u901a\u8fc7\u5bbf\u4e3b `session.import` \u901a\u9053\u5199\u5165 PI-Desktop \u4f1a\u8bdd\u5e93\uff1a\n\n![import status](docs/screenshots/04-import-status.png)\n\n\u5bfc\u5165\u7684\u4f1a\u8bdd\u6309**\u539f\u59cb\u5de5\u4f5c\u76ee\u5f55**\u5f52\u5c5e\u9879\u76ee\uff1a\u8be5\u9879\u76ee\u5df2\u5728 PI-Desktop \u6253\u5f00\u65f6**\u7acb\u523b\u5c55\u5f00\u53ef\u89c1**\uff1b\u672a\u6253\u5f00\u7684\u9879\u76ee\u4e5f\u4f1a\u81ea\u52a8\u52a0\u5165\u5de6\u4fa7\u9879\u76ee\u5217\u8868\u5e76\u5c55\u5f00\uff1a\n\n![sidebar auto expand](docs/screenshots/05-sidebar-auto-expand.png)\n\n![sidebar codex](docs/screenshots/06-sidebar-codex.png)\n\n\u91cd\u590d\u5bfc\u5165\u81ea\u52a8\u8df3\u8fc7\uff08\u5e42\u7b49 id\uff1a`import-<\u6765\u6e90>-<\u5916\u90e8\u4f1a\u8bdd id>`\uff09\u3002\n\n## \u6765\u6e90\u4e0e\u7279\u6b8a\u5904\u7406\n\n| \u6765\u6e90 | \u6570\u636e\u4f4d\u7f6e | \u7279\u6b8a\u5904\u7406 |\n| --- | --- | --- |\n| ZCode | `~/.zcode/cli/db/db.sqlite` | `node:sqlite` \u53ea\u8bfb\uff1b\u8fc7\u6ee4 `subagent_child` \u5185\u90e8\u4f1a\u8bdd\u4e0e `synthetic` \u6ce8\u5165\u6587\u672c\uff1b\u5de5\u5177\u8c03\u7528\u6309\u5b58\u50a8\u987a\u5e8f\u8fd8\u539f |\n| WorkBuddy | `~/.workbuddy/projects/**/*.jsonl` | \u5265\u79bb ``/`` \u6ce8\u5165\u5757\uff1b`function_call` \u6309 `callId` \u914d\u5bf9\uff1b\u5916\u7f6e\u5927\u7ed3\u679c\u5b89\u5168\u56de\u8bfb\uff1b`ai-title` \u4f18\u5148 |\n| Claude Code | `~/.claude/projects/**/*.jsonl` | \u8fc7\u6ee4 sidechain \u4e0e\u5408\u6210\u7528\u6237\u884c\uff1b`tool_use`/`tool_result` \u914d\u5bf9 |\n| Codex | `~/.codex/sessions/**/*.jsonl` | \u517c\u5bb9\u65b0\u65e7\u4e24\u79cd\u683c\u5f0f\uff1b\u8fc7\u6ee4 `# AGENTS.md` \u7b49\u5408\u6210\u884c |\n| OpenCode | `~/.local/share/opencode/opencode.db` | `node:sqlite` \u53ea\u8bfb\uff1bsession\u2192message\u2192part \u4e09\u5c42\u8fd8\u539f\uff08OpenCode v1.x SQLite\uff09 |\n| Pi | `~/.pi/agent/sessions/**/*.jsonl` | `toolCall`/`toolResult` \u914d\u5bf9\uff1b`session_info.name` \u4f18\u5148 |\n\n## \u81ea\u5b9a\u4e49\u6765\u6e90\uff08\u65e0\u9700\u6539\u4ee3\u7801\uff09\n\n\u5185\u7f6e 6 \u4e2a\u6765\u6e90\u4e4b\u5916\uff0c\u4f60\u53ef\u4ee5\u5728**\u5f53\u524d\u5de5\u4f5c\u533a**\u653e\u4e00\u4efd\u7eaf JSON\uff0c\u63cf\u8ff0\u81ea\u5df1\u7684\u5de5\u5177\uff1a\n\n```\ndocs/session-import-sources.json\n```\n\n\u5185\u7f6e\u9a71\u52a8\u8986\u76d6\u4e09\u7c7b\u78c1\u76d8\u683c\u5f0f\uff0c\u7edd\u5927\u591a\u6570\u5de5\u5177\u90fd\u80fd\u843d\u5728\u5176\u4e2d\u4e00\u4e2a\u4e0a\uff1a\n\n| driver | \u9002\u7528 | \u5185\u7f6e\u4f7f\u7528\u8005 |\n| --- | --- | --- |\n| `jsonl-transcript` | \u4e00\u884c\u4e00\u6761\u8bb0\u5f55\u7684 JSONL \u5bf9\u8bdd\u6587\u4ef6 | Claude Code\u3001Codex\u3001WorkBuddy\u3001Pi |\n| `sqlite-session` | SQLite\uff1a`session \u2192 message \u2192 part` \u4e09\u5c42\uff08\u6216 session+message \u4e24\u5c42\uff09 | ZCode\u3001OpenCode |\n| `json-tree` | \u4e00\u4e2a JSON \u6587\u4ef6\u5373\u4e00\u4e2a\u4f1a\u8bdd | \u65e7\u7248 OpenCode / Claude \u5e03\u5c40 |\n\n\u9762\u677f\u300c\u81ea\u5b9a\u4e49\u6765\u6e90 \u2192 \u91cd\u65b0\u52a0\u8f7d\u300d\u5373\u53ef\u70ed\u52a0\u8f7d\uff0c\u65b0\u6765\u6e90\u5e26 `\u81ea\u5b9a\u4e49` \u6807\u7b7e\u51fa\u73b0\u3002\u5b8c\u6574\u5b57\u6bb5\u89c1\n[`docs/CUSTOM-SOURCES.md`](docs/CUSTOM-SOURCES.md)\uff0c\u91cc\u9762\u6709\u53ef\u76f4\u63a5\u590d\u5236\u7684\u4e09\u4e2a driver \u793a\u4f8b\u3002\n\n> **\u5b89\u5168\u8fb9\u754c**\uff1a\u914d\u7f6e**\u53ea\u5141\u8bb8\u7eaf\u6570\u636e**\u3002\u4efb\u4f55 `eval` / `code` / `require` / `transform` / `script`\n> \u4e4b\u7c7b\u7684\u952e\uff08\u4efb\u610f\u5c42\u7ea7\uff09\u90fd\u4f1a\u88ab\u62d2\u7edd\u2014\u2014\u63d2\u4ef6\u5bf9\u7528\u6237\u4e3b\u76ee\u5f55\u6709\u8bfb\u6743\u9650\uff0c\u5141\u8bb8\u914d\u7f6e\u643a\u5e26\u4ee3\u7801\u7b49\u540c\u4e8e\u4efb\u610f\u4ee3\u7801\u6267\u884c\u3002\n> \u6570\u636e\u6839\u76ee\u5f55\u4e5f\u4e0d\u63a5\u53d7 `/` \u6216\u6574\u4e2a home\u3002\n\n## \u6743\u9650\n\n| \u6743\u9650 | \u7528\u9014 |\n| --- | --- |\n| `ui.panel` / `ui.view` | \u5bfc\u5165\u9762\u677f\u4e0e\u300c\u4f1a\u8bdd\u7194\u7089\u300d\u5de5\u4f5c\u9762\u677f\u89c6\u56fe |\n| `session.read` / `session.read.own` | \u8bfb\u56de\u672c\u63d2\u4ef6\u5bfc\u5165\u8fc7\u7684\u4f1a\u8bdd\uff0c\u4f9b\u7194\u7089\u84b8\u998f |\n| `session.import` | \u628a\u9009\u4e2d\u7684\u4f1a\u8bdd\u5199\u5165 PI-Desktop \u4f1a\u8bdd\u5e93 |\n| `project.create` | \u6309\u4f1a\u8bdd\u7684 `projectPath` \u5e42\u7b49\u89e3\u6790 / \u7ed1\u5b9a projectId\uff08\u65e0\u6b64\u80fd\u529b\u7684\u5bbf\u4e3b\u9000\u56de\u672a\u7ed1\u5b9a\u5bfc\u5165\uff09 |\n| `agent.complete` / `models.list` | \u8c03\u7528\u5bbf\u4e3b\u6a21\u578b\u505a\u84b8\u998f\uff08\u4f7f\u7528\u5bbf\u4e3b\u51ed\u636e\u4e0e\u989d\u5ea6\uff0c\u63d2\u4ef6\u4e0d\u63a5\u89e6 API Key\uff09 |\n| `fs.read` | \u53ea\u8bfb\u5404\u5de5\u5177\u7684\u672c\u5730\u4f1a\u8bdd\u6570\u636e\uff08`.jsonl` / SQLite \u7684 `readOnly` \u6a21\u5f0f\uff09\uff1b\u5e76\u8bfb\u53d6\u5de5\u4f5c\u533a `docs/session-import-sources.json` \u91cc\u7684\u81ea\u5b9a\u4e49\u6765\u6e90\u914d\u7f6e |\n| `fs.write` | **\u4ec5**\u7528\u4e8e\u4fdd\u5b58\u84b8\u998f\u7ed3\u679c\uff0c\u8303\u56f4\u9650\u5b9a\u5728\u5de5\u4f5c\u533a\u5185\u7684 `AGENTS.md`\u3001`*.md`\u3001`docs/**`\u3001`.agents/skills/**` |\n\n\u8bfb\u53d6\u5404\u5de5\u5177\u672c\u5730\u6570\u636e\u7531\u63d2\u4ef6\u8fdb\u7a0b**\u53ea\u8bfb**\u5b8c\u6210\uff08`node:sqlite` \u7684 `readOnly` \u6a21\u5f0f\uff0c\u6216\u76f4\u63a5\u8bfb\u53d6\n`.jsonl`\uff09\u3002**\u5bfc\u5165**\u7ecf\u7531\u5bbf\u4e3b `session.import` \u901a\u9053\u5b8c\u6210\uff08\u8be5\u901a\u9053\u4e3a\u63d2\u4ef6\u5bbf\u4e3b\u65b0\u589e\u7684\u5e95\u5c42 API\n\u63d0\u6848\uff0c\u89c1 [PI-Desktop#134](https://github.com/vastsa/PI-Desktop/issues/134)\uff09\u3002\n\n\u63d2\u4ef6\u4e0d\u53d1\u8d77\u4efb\u4f55\u7f51\u7edc\u8bf7\u6c42\u3001\u65e0\u9065\u6d4b\u4e0a\u62a5\uff1b\u7194\u7089\u8c03\u7528\u8d70\u5bbf\u4e3b `pi.agent.complete`\uff0c\u51ed\u636e\u4fdd\u7559\u5728\nElectron \u4e3b\u8fdb\u7a0b\u3002\n\n## \u5f00\u53d1\n\n```bash\n# \u5728 PI-Desktop \u4ed3\u5e93\u5185\u6821\u9a8c\u4e0e\u6253\u5305\npnpm --filter @pi-desktop/plugin-devkit... build\nnode packages/plugin-devkit/dist/cli.js check /absolute/path/to/pi-desktop-session-import\nnode packages/plugin-devkit/dist/cli.js pack /absolute/path/to/pi-desktop-session-import\n```\n\n\u5728 PI-Desktop \u4e2d\uff1a\u63d2\u4ef6\u9875 \u2192 Load development plugin \u2192 \u9009\u62e9\u672c\u76ee\u5f55\u3002\n\n## License\n\nMIT\n", + "readmeMarkdown": "# Universal Session Import\uff08\u4e00\u4f53\u5316\u4f1a\u8bdd\u5bfc\u5165\uff09\n\nPI-Desktop \u63d2\u4ef6\uff1a**\u626b\u63cf\u672c\u673a\u5b89\u88c5\u7684\u7f16\u7a0b\u5de5\u5177\uff0c\u628a\u5b83\u4eec\uff08ZCode\u3001WorkBuddy\u3001Claude Code\u3001Codex\u3001OpenCode\u3001Pi\uff09\u7684\u672c\u5730\u4f1a\u8bdd\u7edf\u4e00\u5bfc\u5165 PI-Desktop\u3002**\n\n![scan sources](docs/screenshots/01-scan-sources.png)\n\n## \u4f7f\u7528\u6d41\u7a0b\n\n### 1. \u626b\u63cf\u672c\u673a\u5de5\u5177\n\n\u6253\u5f00\u9762\u677f\u70b9\u51fb\u300c\u626b\u63cf\u672c\u673a\u5de5\u5177\u300d\uff0c\u63d2\u4ef6\u5e76\u884c\u63a2\u6d4b\u516d\u4e2a\u6765\u6e90\uff0c\u5b9e\u65f6\u663e\u793a\u5404\u81ea\u68c0\u6d4b\u5230\u7684\u4f1a\u8bdd\u6570\uff08\u672a\u5b89\u88c5\u7684\u5de5\u5177\u663e\u793a\u300c\u672a\u68c0\u6d4b\u5230\u300d\uff09\u3002\n\n### 2. \u9009\u62e9\u6765\u6e90\uff0c\u6d4f\u89c8\u4f1a\u8bdd\n\n\u70b9\u51fb\u68c0\u6d4b\u5230\u7684\u5de5\u5177\u5361\u7247\uff0c\u6309\u9879\u76ee\u5206\u7ec4\u8f7d\u5165\u8be5\u6765\u6e90\u7684\u4f1a\u8bdd\u5217\u8868\uff08\u652f\u6301\u641c\u7d22\u3001\u6574\u7ec4\u5168\u9009\uff09\uff1a\n\n![session list](docs/screenshots/02-session-list.png)\n\n### 3. \u9884\u89c8\u5bf9\u8bdd\n\n\u70b9\u4efb\u610f\u4f1a\u8bdd\u5373\u53ef\u6309\u539f\u59cb\u987a\u5e8f\u8fd8\u539f\u5b8c\u6574\u5bf9\u8bdd\u2014\u2014\u7528\u6237\u6d88\u606f\u3001\u52a9\u624b\u56de\u590d\u3001\u5de5\u5177\u8c03\u7528\uff08\u53c2\u6570 + \u7ed3\u679c\u6298\u53e0\u5c55\u793a\uff0c\u9519\u8bef\u6807\u7ea2\uff09\uff1a\n\n![preview](docs/screenshots/03-preview.png)\n\n### 4. \u5bfc\u5165\u4e3a\u4f1a\u8bdd\n\n\u52fe\u9009\u4f1a\u8bdd\uff08\u652f\u6301\u6574\u7ec4\u5168\u9009\uff09\u2192\u300c\u5bfc\u5165\u4e3a\u4f1a\u8bdd\u300d\uff0c\u901a\u8fc7\u5bbf\u4e3b `session.import` \u901a\u9053\u5199\u5165 PI-Desktop \u4f1a\u8bdd\u5e93\uff1a\n\n![import status](docs/screenshots/04-import-status.png)\n\n\u5bfc\u5165\u7684\u4f1a\u8bdd\u6309**\u539f\u59cb\u5de5\u4f5c\u76ee\u5f55**\u5f52\u5c5e\u9879\u76ee\uff1a\u8be5\u9879\u76ee\u5df2\u5728 PI-Desktop \u6253\u5f00\u65f6**\u7acb\u523b\u5c55\u5f00\u53ef\u89c1**\uff1b\u672a\u6253\u5f00\u7684\u9879\u76ee\u4e5f\u4f1a\u81ea\u52a8\u52a0\u5165\u5de6\u4fa7\u9879\u76ee\u5217\u8868\u5e76\u5c55\u5f00\uff1a\n\n![sidebar auto expand](docs/screenshots/05-sidebar-auto-expand.png)\n\n![sidebar codex](docs/screenshots/06-sidebar-codex.png)\n\n\u91cd\u590d\u5bfc\u5165\u81ea\u52a8\u8df3\u8fc7\uff08\u5e42\u7b49 id\uff1a`import-<\u6765\u6e90>-<\u5916\u90e8\u4f1a\u8bdd id>`\uff09\u3002\n\n## \u6765\u6e90\u4e0e\u7279\u6b8a\u5904\u7406\n\n| \u6765\u6e90 | \u6570\u636e\u4f4d\u7f6e | \u7279\u6b8a\u5904\u7406 |\n| --- | --- | --- |\n| ZCode | `~/.zcode/cli/db/db.sqlite` | `node:sqlite` \u53ea\u8bfb\uff1b\u8fc7\u6ee4 `subagent_child` \u5185\u90e8\u4f1a\u8bdd\u4e0e `synthetic` \u6ce8\u5165\u6587\u672c\uff1b\u5de5\u5177\u8c03\u7528\u6309\u5b58\u50a8\u987a\u5e8f\u8fd8\u539f |\n| WorkBuddy | `~/.workbuddy/projects/**/*.jsonl` | \u5265\u79bb ``/`` \u6ce8\u5165\u5757\uff1b`function_call` \u6309 `callId` \u914d\u5bf9\uff1b\u5916\u7f6e\u5927\u7ed3\u679c\u5b89\u5168\u56de\u8bfb\uff1b`ai-title` \u4f18\u5148 |\n| Claude Code | `~/.claude/projects/**/*.jsonl` | \u8fc7\u6ee4 sidechain \u4e0e\u5408\u6210\u7528\u6237\u884c\uff1b`tool_use`/`tool_result` \u914d\u5bf9 |\n| Codex | `~/.codex/sessions/**/*.jsonl` | \u517c\u5bb9\u65b0\u65e7\u4e24\u79cd\u683c\u5f0f\uff1b\u8fc7\u6ee4 `# AGENTS.md` \u7b49\u5408\u6210\u884c |\n| OpenCode | `~/.local/share/opencode/opencode.db` | `node:sqlite` \u53ea\u8bfb\uff1bsession\u2192message\u2192part \u4e09\u5c42\u8fd8\u539f\uff08OpenCode v1.x SQLite\uff09 |\n| Pi | `~/.pi/agent/sessions/**/*.jsonl` | `toolCall`/`toolResult` \u914d\u5bf9\uff1b`session_info.name` \u4f18\u5148 |\n\n## \u81ea\u5b9a\u4e49\u6765\u6e90\uff08\u65e0\u9700\u6539\u4ee3\u7801\uff09\n\n\u5185\u7f6e 6 \u4e2a\u6765\u6e90\u4e4b\u5916\uff0c\u4f60\u53ef\u4ee5\u5728**\u5f53\u524d\u5de5\u4f5c\u533a**\u653e\u4e00\u4efd\u7eaf JSON\uff0c\u63cf\u8ff0\u81ea\u5df1\u7684\u5de5\u5177\uff1a\n\n```\ndocs/session-import-sources.json\n```\n\n\u5185\u7f6e\u9a71\u52a8\u8986\u76d6\u4e09\u7c7b\u78c1\u76d8\u683c\u5f0f\uff0c\u7edd\u5927\u591a\u6570\u5de5\u5177\u90fd\u80fd\u843d\u5728\u5176\u4e2d\u4e00\u4e2a\u4e0a\uff1a\n\n| driver | \u9002\u7528 | \u5185\u7f6e\u4f7f\u7528\u8005 |\n| --- | --- | --- |\n| `jsonl-transcript` | \u4e00\u884c\u4e00\u6761\u8bb0\u5f55\u7684 JSONL \u5bf9\u8bdd\u6587\u4ef6 | Claude Code\u3001Codex\u3001WorkBuddy\u3001Pi |\n| `sqlite-session` | SQLite\uff1a`session \u2192 message \u2192 part` \u4e09\u5c42\uff08\u6216 session+message \u4e24\u5c42\uff09 | ZCode\u3001OpenCode |\n| `json-tree` | \u4e00\u4e2a JSON \u6587\u4ef6\u5373\u4e00\u4e2a\u4f1a\u8bdd | \u65e7\u7248 OpenCode / Claude \u5e03\u5c40 |\n\n\u9762\u677f\u300c\u81ea\u5b9a\u4e49\u6765\u6e90 \u2192 \u91cd\u65b0\u52a0\u8f7d\u300d\u5373\u53ef\u70ed\u52a0\u8f7d\uff0c\u65b0\u6765\u6e90\u5e26 `\u81ea\u5b9a\u4e49` \u6807\u7b7e\u51fa\u73b0\u3002\u5b8c\u6574\u5b57\u6bb5\u89c1\n[`docs/CUSTOM-SOURCES.md`](docs/CUSTOM-SOURCES.md)\uff0c\u91cc\u9762\u6709\u53ef\u76f4\u63a5\u590d\u5236\u7684\u4e09\u4e2a driver \u793a\u4f8b\u3002\n\n> **\u5b89\u5168\u8fb9\u754c**\uff1a\u914d\u7f6e**\u53ea\u5141\u8bb8\u7eaf\u6570\u636e**\u3002\u4efb\u4f55 `eval` / `code` / `require` / `transform` / `script`\n> \u4e4b\u7c7b\u7684\u952e\uff08\u4efb\u610f\u5c42\u7ea7\uff09\u90fd\u4f1a\u88ab\u62d2\u7edd\u2014\u2014\u63d2\u4ef6\u5bf9\u7528\u6237\u4e3b\u76ee\u5f55\u6709\u8bfb\u6743\u9650\uff0c\u5141\u8bb8\u914d\u7f6e\u643a\u5e26\u4ee3\u7801\u7b49\u540c\u4e8e\u4efb\u610f\u4ee3\u7801\u6267\u884c\u3002\n> \u6570\u636e\u6839\u76ee\u5f55\u4e5f\u4e0d\u63a5\u53d7 `/` \u6216\u6574\u4e2a home\u3002\n\n## \u6743\u9650\n\n| \u6743\u9650 | \u7528\u9014 |\n| --- | --- |\n| `ui.panel` / `ui.view` | \u5bfc\u5165\u9762\u677f\u4e0e\u300c\u4f1a\u8bdd\u7194\u7089\u300d\u5de5\u4f5c\u9762\u677f\u89c6\u56fe |\n| `notify` | \u626b\u63cf / \u5bfc\u5165\u5b8c\u6210\u6216\u5931\u8d25\u65f6\u53d1\u4e00\u6761\u901a\u77e5 |\n| `session.read` / `session.read.own` | \u8bfb\u56de\u672c\u63d2\u4ef6\u5bfc\u5165\u8fc7\u7684\u4f1a\u8bdd\uff0c\u4f9b\u7194\u7089\u84b8\u998f |\n| `session.import` | \u628a\u9009\u4e2d\u7684\u4f1a\u8bdd\u5199\u5165 PI-Desktop \u4f1a\u8bdd\u5e93 |\n| `project.create` | \u6309\u4f1a\u8bdd\u7684 `projectPath` \u5e42\u7b49\u89e3\u6790 / \u7ed1\u5b9a projectId\uff08\u65e0\u6b64\u80fd\u529b\u7684\u5bbf\u4e3b\u9000\u56de\u672a\u7ed1\u5b9a\u5bfc\u5165\uff09 |\n| `agent.complete` / `models.list` | \u8c03\u7528\u5bbf\u4e3b\u6a21\u578b\u505a\u84b8\u998f\uff08\u4f7f\u7528\u5bbf\u4e3b\u51ed\u636e\u4e0e\u989d\u5ea6\uff0c\u63d2\u4ef6\u4e0d\u63a5\u89e6 API Key\uff09 |\n| `fs.read` | \u53ea\u8bfb\u5404\u5de5\u5177\u7684\u672c\u5730\u4f1a\u8bdd\u6570\u636e\uff08`.jsonl` / SQLite \u7684 `readOnly` \u6a21\u5f0f\uff09\uff1b\u5e76\u8bfb\u53d6\u5de5\u4f5c\u533a `docs/session-import-sources.json` \u91cc\u7684\u81ea\u5b9a\u4e49\u6765\u6e90\u914d\u7f6e |\n| `fs.write` | **\u4ec5**\u7528\u4e8e\u4fdd\u5b58\u84b8\u998f\u7ed3\u679c\uff0c\u8303\u56f4\u9650\u5b9a\u5728\u5de5\u4f5c\u533a\u5185\u7684 `AGENTS.md`\u3001`*.md`\u3001`docs/**`\u3001`.agents/skills/**` |\n\n\u8bfb\u53d6\u5404\u5de5\u5177\u672c\u5730\u6570\u636e\u7531\u63d2\u4ef6\u8fdb\u7a0b**\u53ea\u8bfb**\u5b8c\u6210\uff08`node:sqlite` \u7684 `readOnly` \u6a21\u5f0f\uff0c\u6216\u76f4\u63a5\u8bfb\u53d6\n`.jsonl`\uff09\u3002**\u5bfc\u5165**\u7ecf\u7531\u5bbf\u4e3b `session.import` \u901a\u9053\u5b8c\u6210\uff08\u8be5\u901a\u9053\u4e3a\u63d2\u4ef6\u5bbf\u4e3b\u65b0\u589e\u7684\u5e95\u5c42 API\n\u63d0\u6848\uff0c\u89c1 [PI-Desktop#134](https://github.com/vastsa/PI-Desktop/issues/134)\uff09\u3002\n\n\u63d2\u4ef6\u4e0d\u53d1\u8d77\u4efb\u4f55\u7f51\u7edc\u8bf7\u6c42\u3001\u65e0\u9065\u6d4b\u4e0a\u62a5\uff1b\u7194\u7089\u8c03\u7528\u8d70\u5bbf\u4e3b `pi.agent.complete`\uff0c\u51ed\u636e\u4fdd\u7559\u5728\nElectron \u4e3b\u8fdb\u7a0b\u3002\n\n## \u5f00\u53d1\n\n```bash\n# \u5728 PI-Desktop \u4ed3\u5e93\u5185\u6821\u9a8c\u4e0e\u6253\u5305\npnpm --filter @pi-desktop/plugin-devkit... build\nnode packages/plugin-devkit/dist/cli.js check /absolute/path/to/pi-desktop-session-import\nnode packages/plugin-devkit/dist/cli.js pack /absolute/path/to/pi-desktop-session-import\n```\n\n\u5728 PI-Desktop \u4e2d\uff1a\u63d2\u4ef6\u9875 \u2192 Load development plugin \u2192 \u9009\u62e9\u672c\u76ee\u5f55\u3002\n\n## License\n\nMIT\n", "safetyNotes": "\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\u5404\u5de5\u5177\u7684\u672c\u5730\u4f1a\u8bdd\u6570\u636e\u5e93\uff1b\u4f1a\u8bdd\u5199\u5165\u8d70\u5bbf\u4e3b session \u5bfc\u5165\u63a5\u53e3\u3002\u7194\u7089\u4f7f\u7528\u5bbf\u4e3b\u81ea\u8eab\u989d\u5ea6\u8c03\u7528\u6a21\u578b\uff0c\u63d2\u4ef6\u4e0d\u63a5\u89e6 API Key\u3002fs.write \u4ec5\u7528\u4e8e\u4fdd\u5b58\u84b8\u998f\u7ed3\u679c\uff0c\u8303\u56f4\u9650\u5b9a\u5728\u5de5\u4f5c\u533a\u5185\u7684 AGENTS.md\u3001*.md\u3001docs/**\u3001.agents/skills/**\u3002\u4e0d\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\uff0c\u65e0\u9065\u6d4b\u3002 \u81ea\u5b9a\u4e49\u6765\u6e90\u914d\u7f6e\uff08\u5de5\u4f5c\u533a docs/session-import-sources.json\uff09\u53ea\u63a5\u53d7\u7eaf\u6570\u636e\uff0c\u63d2\u4ef6\u6c38\u4e0d\u6267\u884c\u5176\u4e2d\u7684\u4ee3\u7801\u3002", "versions": [ { - "version": "0.4.8", - "publishedAt": "2026-09-12T17:13:25Z", - "changelog": "Release 0.4.8\uff08\u5bfc\u5165\u884c\u4e3a\u4fee\u6b63\uff09\uff1a\u9ed8\u8ba4\u6309\u9879\u76ee\u5f52\u7ec4\u5bfc\u5165\u2014\u2014\u79fb\u9664\u65e0\u610f\u4e49\u7684\u300c\u5f52\u7ec4\u5230\u9879\u76ee\u300d\u52fe\u9009\u9879\uff08\u5bbf\u4e3b import_session \u53ea\u8981 project_path \u975e\u7a7a\u5373\u81ea\u52a8\u7ed1\u5b9a\u9879\u76ee\uff0c\u5ffd\u7565 projectId\uff0c\u6545\u8be5\u5f00\u5173\u662f\u7a7a\u64cd\u4f5c\uff09\uff1b\u65e0 projectPath \u7684\u4f1a\u8bdd\u56de\u843d\u72ec\u7acb\u300c\u4f1a\u8bdd\u300d\u5217\u8868\uff0c\u6c38\u4e0d\u4e22\u6570\u636e\u3002\u79fb\u9664\u5bfc\u5165\u5b8c\u6210\u540e\u7684\u300c\u4f1a\u8bdd\u7194\u7089\u300d\u539f\u751f\u901a\u77e5\uff08\u6587\u6848\u4e0d\u6e05\u6670\uff1b\u4f1a\u8bdd\u7194\u7089\u529f\u80fd\u4fdd\u7559\uff09\uff0cmanifest \u4e0d\u518d\u9700\u8981 notify \u6743\u9650\u3002\u4fdd\u7559 0.4.7 \u7684\u58f0\u660e\u5f0f\u683c\u5f0f\u9a71\u52a8\u5c42\u3001\u81ea\u5b9a\u4e49\u6765\u6e90\u4e0e\u5176\u5b89\u5168\u52a0\u56fa\uff08\u62d2\u7edd\u6587\u4ef6\u7cfb\u7edf\u6839/Windows \u76d8\u7b26\u6839\u3001extension \u5fc5\u987b\u4e3a\u771f\u540e\u7f00\u3001SQLite \u6807\u8bc6\u7b26\u5b57\u7b26\u96c6\u9650\u5236\u3001convert \u9650\u5236\u5728 spec \u6839\u5185\uff09\uff0c\u4ee5\u53ca 0.4.6 \u5065\u58ee\u6027\u52a0\u56fa\u3002\u57fa\u4e8e 0.4.7 \u4e4b\u4e0a\u53d1\u5e03\u3002", + "version": "0.4.7", + "publishedAt": "2026-09-11T18:47:58Z", + "changelog": "Release 0.4.7\uff08\u53ef\u6269\u5c55\u6765\u6e90\uff09\uff1a\u65b0\u589e\u58f0\u660e\u5f0f\u683c\u5f0f\u9a71\u52a8\u5c42\u2014\u2014jsonl-transcript / sqlite-session / json-tree \u4e09\u4e2a driver \u8986\u76d6\u300c\u4e00\u884c\u4e00\u6761 JSON\u300d\u300csession\u2192message\u2192part \u7684 SQLite\u300d\u300c\u5355\u6587\u4ef6\u5373\u4e00\u4f1a\u8bdd\u300d\u4e09\u7c7b\u78c1\u76d8\u683c\u5f0f\uff0c\u4efb\u4f55\u65b0\u6765\u6e90\u53ea\u9700\u914d\u7f6e\u3001\u65e0\u9700\u5199\u4ee3\u7801\uff1b\u7528\u6237\u53ef\u5728\u5de5\u4f5c\u533a docs/session-import-sources.json \u91cc\u63cf\u8ff0\u81ea\u5df1\u7684\u5de5\u5177\u5e76\u70ed\u52a0\u8f7d\uff08\u914d\u7f6e\u53ea\u63a5\u53d7\u7eaf\u6570\u636e\uff0c\u6c38\u4e0d\u6267\u884c\u4ee3\u7801\uff0c\u6570\u636e\u6839\u76ee\u5f55\u62d2\u7edd / \u4e0e\u6574\u4e2a home\uff09\u3002\u9a71\u52a8\u5c42\u5df2\u7528\u672c\u673a\u771f\u5b9e\u6570\u636e\u9010\u6761\u6bd4\u5bf9\u6821\u9a8c\uff1a1693 \u4e2a\u4f1a\u8bdd\u4e0e\u624b\u5199\u9002\u914d\u5668\u9010\u5b57\u8282\u4e00\u81f4\uff08Claude 61/61\u3001Codex 774/774\u3001WorkBuddy 159/159\u3001ZCode 70/70\u3001OpenCode 629/629\uff09\u3002\u5305\u542b 0.4.6 \u7684\u5065\u58ee\u6027\u52a0\u56fa\uff08\u770b\u95e8\u72d7\u8d85\u65f6\u3001\u6309 externalId \u53bb\u91cd\u5e76\u6807\u8bb0\u8d85\u5927\u4f1a\u8bdd\u3001\u5951\u7ea6\u622a\u65ad\u663e\u5f0f\u56de\u4f20 truncated\uff09\u3002\u57fa\u4e8e 0.4.6 \u4e4b\u4e0a\u53d1\u5e03\u3002", "minPiDesktop": ">=0.14.3", - "shasum": "ff32b931be2f9befeb3698746b7f11d7a37b51b742f4134cae1f7d0057121e7a", - "url": "packages/io.github.muzimu217.session-import-0.4.8.piplug", - "sizeBytes": 3551806, + "shasum": "4dbd73e4060c8ad92932962976d2fe22dd5fedd7dc4a64fee2d0a7a21c01423a", + "url": "packages/io.github.muzimu217.session-import-0.4.7.piplug", + "sizeBytes": 3553027, "permissions": [ "ui.panel", "ui.view", + "notify", "session.read", "session.read.own", "session.import", @@ -377,7 +253,7 @@ "versions": [ { "version": "0.1.5", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.1.5: reserves space for the host window-control capsule so top-right panel actions no longer overlap it. Release 0.1.4: gives the panel an explicit full-height page surface and keeps the host window-control capsule synchronized with live theme changes. Release 0.1.3: migrates the panel to v3 paint-through chrome so top-band controls remain clickable without the legacy 46px blank area. Release 0.1.2: refreshes the sticky-notes panel chrome, controls, focus states, dialogs, and compact responsive spacing. Release 0.1.1: adapts the panel to PI-Desktop's cross-platform 46px host drag band and minimal three-button window-control capsule. First release: multiple notes, Markdown preview/editing, task lists, highlights, image paste, and recycle bin.", "minPiDesktop": ">=0.7.1", "shasum": "816ea81e1b029f7534b0600feabcdf4b272f36b9082679bcad658888ae73fae5", @@ -423,7 +299,7 @@ "versions": [ { "version": "0.2.2", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.2.2: reserves the host capsule's right-side safe area in the toolbar and retints the capsule after live palette changes. Release 0.2.1: migrates the panel to v3 paint-through chrome and removes the duplicate 46px top inset; top-band controls remain clickable while blank space remains draggable. Release 0.2.0: \u652f\u6301\u526a\u8d34\u677f\u56fe\u7247\u91c7\u96c6\u4e0e\u6062\u590d\uff08\u5bbf\u4e3b getHistory \u53ef\u7528\u65f6\u81ea\u52a8\u542f\u7528\uff0c\u53ef\u5173\u95ed\uff09\uff1b\u65b0\u589e\u4fdd\u5b58\u56fe\u7247\u5f00\u5173\u3002Image capture & restore when the host exposes getHistory, with a save-images toggle.\nRelease 0.1.0: \u9996\u4e2a\u7248\u672c\u2014\u2014\u540e\u53f0\u91c7\u96c6\u526a\u8d34\u677f\u6587\u672c\u3001\u6309\u5929\u5f52\u6863\u4fdd\u7559 30 \u5929\u3001\u9762\u677f\u4e00\u952e\u6062\u590d/\u5220\u9664/\u6e05\u7a7a\u3001\u6682\u505c\u5f00\u5173\u4e0e\u8f6e\u8be2\u95f4\u9694\u53ef\u8c03\u3002Initial release \u2014 background clipboard capture, 30-day daily archives, one-click restore/delete/clear in a panel, pause toggle and configurable poll interval.", "minPiDesktop": ">=0.8.0", "shasum": "0c1dcc5504b964252b2d5f7660fd5be033185253ffd1a2cba1b95be6c0900cd4", @@ -442,17 +318,17 @@ { "id": "pi.file-manager", "name": "\u6587\u4ef6\u7ba1\u7406\u5668", - "description": "\u5728\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u4e2d\u6d4f\u89c8\u3001\u67e5\u770b\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\uff1a\u5b8c\u6574\u76ee\u5f55\u6811\uff08\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\uff09\u3001\u5de6\u53f3\u5206\u680f\u3001\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58\u3001Markdown \u9884\u89c8\u3001\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u67e5\u770b\u3001CSV/JSON \u7ed3\u6784\u5316\u67e5\u770b\uff0c\u4ee5\u53ca\u53f3\u952e\u65b0\u5efa\u3001\u91cd\u547d\u540d/\u79fb\u52a8\u3001\u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002", + "description": "\u5728\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u4e2d\u6d4f\u89c8\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\uff1a\u5b8c\u6574\u76ee\u5f55\u6811\uff08\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\uff09\u3001\u5de6\u53f3\u5206\u680f\u3001\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58\u3001Markdown \u9884\u89c8/\u7f16\u8f91\u5207\u6362\uff0c\u4ee5\u53ca\u53f3\u952e\u65b0\u5efa\u3001\u91cd\u547d\u540d/\u79fb\u52a8\u3001\u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002", "i18n": { "en": { "name": "File Manager", - "description": "Browse, view and edit the open project in the right work panel: a full directory tree with per-file-type icons, syntax-highlighted editing, a Markdown preview, image and media viewing, CSV/JSON structured views, read-only SQLite browsing with a SQL query box, a context menu for creating and renaming, and filename search.", - "safetyNotes": "Databases are opened strictly read-only (readOnly + PRAGMA query_only) and the query box only accepts single read-only statements, so a database can be browsed but never modified. fs.read is declared only for the two host-mediated actions \"open with default app\" and \"show in folder\" (same permission and scope as the bundled Files view); the plugin's own reading and writing goes through Node's fs inside the plugin's own process \u2014 the host permission gateway does not mediate these calls, and the manifest cannot declare a whole-tree write. Access is confined to the project root by the plugin itself: resolved paths must stay inside the root (symlink and junction escapes are refused), credential paths (.env*, .ssh/, *.pem, .git/**) are refused, saves are atomic (temp file + rename), and overwriting a file changed outside the editor asks first. Images and media are read up to their own size limits (8 MiB / 24 MiB) and handed to the view as base64 data URIs; binaries such as zip or exe are never decoded, only reported as unsupported. No network access; the plugin data directory only holds settings and a write audit log." + "description": "Browse and edit the open project in the right work panel: a full directory tree with per-file-type icons, syntax-highlighted editing, a Markdown preview/edit toggle, a context menu for creating and renaming, and filename search.", + "safetyNotes": "Reads and writes files in the open project through Node's fs inside the plugin's own process \u2014 the host permission gateway does not mediate these calls, and the manifest cannot declare a whole-tree write. Access is confined to the project root by the plugin itself: resolved paths must stay inside the root (symlink and junction escapes are refused), credential paths (.env*, .ssh/, *.pem, .git/**) are refused, saves are atomic (temp file + rename), and overwriting a file changed outside the editor asks first. No network access; the plugin data directory only holds settings and a write audit log." }, "zh-CN": { "name": "\u6587\u4ef6\u7ba1\u7406\u5668", - "description": "\u5728\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u4e2d\u6d4f\u89c8\u3001\u67e5\u770b\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\uff1a\u5b8c\u6574\u76ee\u5f55\u6811\uff08\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\uff09\u3001\u5de6\u53f3\u5206\u680f\u3001\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58\u3001Markdown \u9884\u89c8\u3001\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u67e5\u770b\u3001CSV/JSON \u7ed3\u6784\u5316\u67e5\u770b\u3001SQLite \u53ea\u8bfb\u6d4f\u89c8\u4e0e SQL \u67e5\u8be2\uff0c\u4ee5\u53ca\u53f3\u952e\u65b0\u5efa\u3001\u91cd\u547d\u540d/\u79fb\u52a8\u3001\u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002", - "safetyNotes": "\u6570\u636e\u5e93\u4e00\u5f8b\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\uff08readOnly + PRAGMA query_only\uff09\uff0cSQL \u6846\u53ea\u63a5\u53d7\u5355\u6761\u53ea\u8bfb\u8bed\u53e5\uff0c\u56e0\u6b64\u53ea\u80fd\u6d4f\u89c8\u3001\u7edd\u65e0\u4fee\u6539\uff1bfs.read \u4ec5\u7528\u4e8e\u300c\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00\u300d\u4e0e\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d\u8fd9\u4e24\u4e2a\u7531\u5bbf\u4e3b\u4ee3\u4e3a\u6267\u884c\u7684\u52a8\u4f5c\uff08\u6743\u9650\u4e0e\u8303\u56f4\u540c\u5185\u7f6e\u7684 Files \u89c6\u56fe\uff09\uff0c\u63d2\u4ef6\u81ea\u8eab\u7684\u8bfb\u5199\u4ecd\u8d70\u81ea\u5df1\u8fdb\u7a0b\u5185\u7684 Node fs\u2014\u2014\u5bbf\u4e3b\u7684\u6743\u9650\u7f51\u5173\u4e0d\u4ecb\u5165\u8fd9\u4e9b\u8c03\u7528\uff0cmanifest \u4e5f\u65e0\u6cd5\u7533\u62a5\u300c\u6574\u6811\u5199\u5165\u300d\u3002\u8bbf\u95ee\u8303\u56f4\u7531\u63d2\u4ef6\u81ea\u8eab\u9650\u5b9a\u5728\u9879\u76ee\u6839\u76ee\u5f55\u5185\uff1a\u89e3\u6790\u540e\u7684\u8def\u5f84\u5fc5\u987b\u4ecd\u5728\u6839\u5185\uff08\u62d2\u7edd\u7b26\u53f7\u94fe\u63a5\u4e0e junction \u9003\u9038\uff09\u3001\u62d2\u7edd\u51ed\u636e\u7c7b\u8def\u5f84\uff08.env*\u3001.ssh/\u3001*.pem\u3001.git/**\uff09\u3001\u4fdd\u5b58\u91c7\u7528\u539f\u5b50\u5199\uff08\u4e34\u65f6\u6587\u4ef6 + \u91cd\u547d\u540d\uff09\u3001\u8986\u76d6\u5728\u7f16\u8f91\u5668\u5916\u88ab\u6539\u52a8\u8fc7\u7684\u6587\u4ef6\u524d\u4f1a\u5148\u8be2\u95ee\u3002\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u6309\u5404\u81ea\u4e0a\u9650\uff088 MiB / 24 MiB\uff09\u8bfb\u53d6\u540e\u4ee5 base64 data URI \u4ea4\u7ed9\u89c6\u56fe\uff1bzip\u3001exe \u8fd9\u7c7b\u4e8c\u8fdb\u5236\u53ea\u62a5\u300c\u4e0d\u652f\u6301\u9884\u89c8\u300d\uff0c\u4e0d\u505a\u4efb\u4f55\u89e3\u7801\u3002\u65e0\u7f51\u7edc\u8bbf\u95ee\uff1b\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u53ea\u4fdd\u5b58\u8bbe\u7f6e\u4e0e\u5199\u5165\u5ba1\u8ba1\u65e5\u5fd7\u3002" + "description": "\u5728\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u4e2d\u6d4f\u89c8\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\uff1a\u5b8c\u6574\u76ee\u5f55\u6811\uff08\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\uff09\u3001\u5de6\u53f3\u5206\u680f\u3001\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58\u3001Markdown \u9884\u89c8/\u7f16\u8f91\u5207\u6362\uff0c\u4ee5\u53ca\u53f3\u952e\u65b0\u5efa\u3001\u91cd\u547d\u540d/\u79fb\u52a8\u3001\u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002", + "safetyNotes": "\u63d2\u4ef6\u5728\u81ea\u5df1\u7684\u8fdb\u7a0b\u5185\u901a\u8fc7 Node fs \u8bfb\u5199\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\u2014\u2014\u5bbf\u4e3b\u7684\u6743\u9650\u7f51\u5173\u4e0d\u4ecb\u5165\u8fd9\u4e9b\u8c03\u7528\uff0cmanifest \u4e5f\u65e0\u6cd5\u7533\u62a5\u300c\u6574\u6811\u5199\u5165\u300d\u3002\u8bbf\u95ee\u8303\u56f4\u7531\u63d2\u4ef6\u81ea\u8eab\u9650\u5b9a\u5728\u9879\u76ee\u6839\u76ee\u5f55\u5185\uff1a\u89e3\u6790\u540e\u7684\u8def\u5f84\u5fc5\u987b\u4ecd\u5728\u6839\u5185\uff08\u62d2\u7edd\u7b26\u53f7\u94fe\u63a5\u4e0e junction \u9003\u9038\uff09\u3001\u62d2\u7edd\u51ed\u636e\u7c7b\u8def\u5f84\uff08.env*\u3001.ssh/\u3001*.pem\u3001.git/**\uff09\u3001\u4fdd\u5b58\u91c7\u7528\u539f\u5b50\u5199\uff08\u4e34\u65f6\u6587\u4ef6 + \u91cd\u547d\u540d\uff09\u3001\u8986\u76d6\u5728\u7f16\u8f91\u5668\u5916\u88ab\u6539\u52a8\u8fc7\u7684\u6587\u4ef6\u524d\u4f1a\u5148\u8be2\u95ee\u3002\u65e0\u7f51\u7edc\u8bbf\u95ee\uff1b\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u53ea\u4fdd\u5b58\u8bbe\u7f6e\u4e0e\u5199\u5165\u5ba1\u8ba1\u65e5\u5fd7\u3002" } }, "author": "Tioit-Wang", @@ -464,29 +340,21 @@ "downloads": 0, "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/pi.file-manager", "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# \u6587\u4ef6\u7ba1\u7406\u5668\uff08File Manager\uff09\n\n\u5728 PI-Desktop \u7684**\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f**\u91cc\u6d4f\u89c8\u3001\u67e5\u770b\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\uff1a\u5b8c\u6574\u76ee\u5f55\u6811\uff08\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\uff09\u3001\u5de6\u53f3\u5206\u680f\u3001\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58\u3001\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u67e5\u770b\u3001CSV/JSON \u7ed3\u6784\u5316\u67e5\u770b\uff0c\u4ee5\u53ca\u65b0\u5efa\u3001\u91cd\u547d\u540d/\u79fb\u52a8\u3001\u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002\n\n## \u529f\u80fd\n\n- **\u5b8c\u6574\u76ee\u5f55\u6811**\uff1a\u61d2\u52a0\u8f7d\u3001\u53ef\u6309\u5c42\u5c55\u5f00\u3001\u76ee\u5f55\u5728\u524d\u3002\u6bcf\u4e00\u884c\u7684\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\u2014\u2014\u6587\u4ef6\u5939\u3001\u4ee3\u7801\u3001JSON\u3001Markdown\u3001\u6837\u5f0f\u3001HTML/Vue/Svelte\u3001YAML/TOML\u3001Shell\u3001SQL\u3001\u56fe\u7247\u3001\u538b\u7f29\u5305\u3001\u5b57\u4f53\u3001\u9501\u6587\u4ef6\u7b49\u5404\u6709\u81ea\u5df1\u7684\u5b57\u5f62\u4e0e\u914d\u8272\uff1b`package.json`\u3001`Dockerfile`\u3001`LICENSE`\u3001`.gitignore` \u8fd9\u7c7b\u7279\u6b8a\u6587\u4ef6\u540d\u4f18\u5148\u4e8e\u6269\u5c55\u540d\u5224\u5b9a\u3002\n- **\u9009\u4e2d\u6001\u4e0e\u60ac\u505c\u6001\u660e\u786e\u533a\u5206**\uff1a\u60ac\u505c\u662f\u6de1\u6de1\u7684\u4e2d\u6027\u5e95\u8272\uff08\u53ea\u8868\u793a\u9f20\u6807\u4f4d\u7f6e\uff09\uff1b\u9009\u4e2d\u662f\u5f3a\u8c03\u8272\u5e95 + \u5de6\u4fa7\u5f3a\u8c03\u8272\u7ad6\u6761 + \u524d\u666f\u8272\u6587\u5b57 + \u4e2d\u7b49\u5b57\u91cd\uff0c\u9f20\u6807\u79fb\u5f00\u4e5f\u4fdd\u6301\uff0c\u60ac\u505c\u5230\u9009\u4e2d\u884c\u4e0a\u8fd8\u4f1a\u518d\u52a0\u6df1\u4e00\u6863\uff0c\u4e0d\u4f1a\u8ba9\u4eba\u8bef\u4ee5\u4e3a\u9009\u4e2d\u4e22\u4e86\u3002\n- **\u53f3\u952e\u83dc\u5355**\uff1a\u5728\u6587\u4ef6/\u6587\u4ef6\u5939\u4e0a\u53f3\u952e\u53ef\u65b0\u5efa\u6587\u4ef6\u3001\u65b0\u5efa\u6587\u4ef6\u5939\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u3001\u6253\u5f00\u3001\u5237\u65b0\uff1b\u5728\u5217\u8868\u7a7a\u767d\u5904\u53f3\u952e\u5219\u53ea\u63d0\u4f9b\u300c\u5728\u6b64\u65b0\u5efa\u300d\u4e0e\u5237\u65b0\u3002\u652f\u6301 \u2191\u2193 / Home / End / Enter / Esc\u3002\n- **\u5de6\u53f3\u5206\u680f**\uff1a\u5de6\u4fa7\u6587\u4ef6\u5217\u8868\uff0c\u53f3\u4fa7\u5185\u5bb9\u3002\u4e2d\u95f4\u5206\u9694\u6761\u53ef\u62d6\u62fd\uff0c\u5bbd\u5ea6\u4f1a\u8bb0\u4f4f\u3002\n- **\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91**\uff1aCodeMirror 6\uff0c\u884c\u53f7\u3001\u67e5\u627e\u66ff\u6362\u3001\u591a\u5149\u6807\u3001\u62ec\u53f7\u5339\u914d\u3001\u4ee3\u7801\u6298\u53e0\u3002\u6309\u6587\u4ef6\u540d\u52a0\u8f7d\u5bf9\u5e94\u8bed\u8a00\u7684\u8bed\u6cd5\u9ad8\u4eae\uff0c\u8986\u76d6 TypeScript/TSX\u3001JavaScript/JSX\u3001JSON\u3001Markdown\u3001CSS/SCSS/Sass/Less\u3001HTML\u3001Vue\u3001XML\u3001YAML\u3001TOML\u3001Properties\u3001Python\u3001Go\u3001Rust\u3001Java\u3001C/C++\u3001C#\u3001Kotlin\u3001Scala\u3001Dart\u3001Objective-C\u3001PHP\u3001Ruby\u3001Lua\u3001Shell\u3001PowerShell\u3001SQL\u3001Dockerfile\u3001Diff\u3002\u5168\u90e8\u968f\u5305\u5185\u7f6e\u3001\u79bb\u7ebf\u53ef\u7528\uff0c\u4e0d\u8bf7\u6c42\u7f51\u7edc\u3002`Ctrl/Cmd+S` \u6216\u5de5\u5177\u680f\u6309\u94ae\u4fdd\u5b58\uff1b**\u6ca1\u6709\u6539\u52a8\u65f6\u4e0d\u5199\u76d8**\uff0c\u4fdd\u5b58\u540e\u5149\u6807\u4e0e\u6eda\u52a8\u4f4d\u7f6e\u7559\u5728\u539f\u5904\uff08\u4e0d\u4f1a\u8df3\u56de\u5f00\u5934\uff09\uff0c\u754c\u9762\u663e\u793a\u7684\u59cb\u7ec8\u662f\u78c1\u76d8\u4e0a\u90a3\u4efd\u5185\u5bb9\u3002\u7126\u70b9\u4e0d\u5728\u7f16\u8f91\u5668\u91cc\uff08\u521a\u70b9\u8fc7\u5de5\u5177\u680f\u3001\u6216\u505c\u5728\u9884\u89c8 / \u8868\u683c / \u6811\u89c6\u56fe\uff09\u65f6 `Ctrl/Cmd+S` \u540c\u6837\u6709\u6548\u3002\n- **Markdown \u9884\u89c8 / \u7f16\u8f91\u5207\u6362**\uff1a\u6253\u5f00 `.md` / `.markdown` / `.mdx` \u65f6\uff0c\u5de5\u5177\u680f\u51fa\u73b0\u300c\u7f16\u8f91 / \u9884\u89c8\u300d\u5207\u6362\u3002\u9884\u89c8\u652f\u6301\u6807\u9898\u3001\u56f4\u680f\u4ee3\u7801\u5757\uff08\u5e26\u540c\u6837\u7684\u8bed\u6cd5\u9ad8\u4eae\uff09\u3001\u5f15\u7528\u3001\u5206\u9694\u7ebf\u3001\u6709\u5e8f/\u65e0\u5e8f/\u4efb\u52a1\u5217\u8868\uff08\u6309\u7f29\u8fdb\u5d4c\u5957\uff09\u3001\u8868\u683c\uff08\u542b\u5bf9\u9f50\uff09\u3001\u884c\u5185 code / \u7c97\u4f53 / \u659c\u4f53 / \u5220\u9664\u7ebf / \u94fe\u63a5 / \u56fe\u7247\u3002\u5207\u6362\u4f1a\u8bb0\u4f4f\u3002\n- **\u56fe\u7247\u67e5\u770b**\uff1apng / jpg / jpeg / gif / webp / avif / bmp / ico / svg\u3002\u9ed8\u8ba4\u9002\u5e94\u7a97\u53e3\uff0c\u53ef\u5207\u300c\u5b9e\u9645\u5927\u5c0f\u300d\uff1b\u5e95\u90e8\u663e\u793a\u50cf\u7d20\u5c3a\u5bf8\u4e0e\u6587\u4ef6\u4f53\u79ef\uff0c\u821e\u53f0\u94fa\u68cb\u76d8\u683c\uff0c\u900f\u660e\u533a\u57df\u4e00\u773c\u53ef\u89c1\u3002\n- **\u97f3\u89c6\u9891\u64ad\u653e**\uff1amp4 / m4v / mov / webm / ogv / mkv \u7528\u64ad\u653e\u5668\uff0cmp3 / m4a / aac / wav / flac / ogg / opus / weba \u7528\u97f3\u9891\u6761\u3002**\u4e0d\u81ea\u52a8\u64ad\u653e**\uff1b\u7f16\u7801\u6216\u5c01\u88c5\u4e0d\u88ab\u652f\u6301\u65f6\u7ed9\u660e\u786e\u63d0\u793a\uff0c\u800c\u4e0d\u662f\u7559\u4e00\u5757\u9ed1\u6846\u3002\n- **CSV / TSV \u8868\u683c\uff08\u5206\u9875\uff09**\uff1a\u6253\u5f00 `.csv` / `.tsv` \u5c31\u662f\u8868\u683c\uff0c\u9ed8\u8ba4**\u6bcf\u9875 1000 \u884c**\uff1b\u5e95\u90e8\u5de5\u5177\u6761\u53ef\u4ee5\u7ffb\u9875\uff08\u9996\u9875/\u4e0a\u4e00\u9875/\u4e0b\u4e00\u9875/\u672b\u9875\uff09\u3001\u770b\u300c\u5f53\u524d\u8303\u56f4 / \u603b\u884c\u6570\u300d\uff0c\u4e5f\u80fd\u6539\u6bcf\u9875\u884c\u6570\uff08100\u20135000\uff0c\u9009\u62e9\u4f1a\u8bb0\u4f4f\uff09\u3002\u9996\u884c\u5f53\u8868\u5934\u4e14\u5438\u9876\uff0c\u6700\u5de6\u4e00\u5217\u662f\u884c\u53f7\u4e14\u5438\u5de6\uff0c\u6574\u884c\u60ac\u505c\u9ad8\u4eae\uff0c\u6574\u5217\u90fd\u662f\u6570\u5b57\u65f6\u81ea\u52a8\u53f3\u5bf9\u9f50\uff0c\u88ab\u7701\u7565\u53f7\u622a\u65ad\u7684\u503c\u60ac\u505c\u53ef\u770b\u5168\u3002**\u70b9\u8868\u5934\u6392\u5e8f**\uff1a\u5347\u5e8f \u2192 \u964d\u5e8f \u2192 \u53d6\u6d88\uff08\u56de\u5230\u6587\u4ef6\u539f\u5e8f\uff09\uff1b\u6574\u5217\u90fd\u662f\u6570\u5b57\u6309\u6570\u503c\u6bd4\uff0c\u5426\u5219\u6309\u81ea\u7136\u5e8f\u6587\u672c\u6bd4\uff0c\u7a7a\u503c\u6c38\u8fdc\u6c89\u5e95\u3002\u89e3\u6790\u652f\u6301\u5f15\u53f7\u5305\u88f9\u3001`\"\"` \u8f6c\u4e49\u3001\u5b57\u6bb5\u5185\u6362\u884c\u3001CRLF \u4e0e\u53c2\u5dee\u7684\u884c\uff1b\u5217\u6570\u4e0a\u9650 60\u3001\u89e3\u6790\u4e0a\u9650 20 \u4e07\u884c\uff0c\u8d85\u51fa\u4f1a\u5728\u5e95\u90e8\u8bf4\u660e\u3002\u5de5\u5177\u680f\u53ef\u5207\u56de\u6e90\u7801\u7f16\u8f91\u3002\n- **JSON \u6298\u53e0\u6811**\uff1a`.json` / `.jsonc` / `.json5` \u53ef\u5207\u6811\u89c6\u56fe\uff0c\u9ed8\u8ba4\u5c55\u5f00\u4e24\u5c42\u3001\u5355\u8282\u70b9\u6700\u591a\u76f4\u63a5\u94fa 100 \u4e2a\u952e\uff0c\u957f\u5b57\u7b26\u4e32\u622a\u65ad\uff08\u5b8c\u6574\u503c\u5728\u60ac\u505c\u63d0\u793a\u91cc\uff09\u3002`//` \u6ce8\u91ca\u3001\u5c3e\u9017\u53f7\u8fd9\u7c7b\u975e\u4e25\u683c JSON \u4e0d\u4f1a\u70b8\u9762\u677f\uff0c\u53ea\u663e\u793a\u300c\u89e3\u6790\u5931\u8d25 + \u539f\u56e0\u300d\uff0c\u6e90\u7801\u89c6\u56fe\u7167\u5e38\u53ef\u7f16\u8f91\u3002\n- **SQLite \u6570\u636e\u5e93\uff08\u53ea\u8bfb\uff09**\uff1a`.db` / `.sqlite` / `.sqlite3` / `.db3` \u6253\u5f00\u5373\u7528\u2014\u2014\u9876\u90e8\u6982\u89c8\uff08\u4f53\u79ef\u3001\u9875\u5927\u5c0f \u00d7 \u9875\u6570\u3001\u7f16\u7801\u3001SQLite \u5e93\u7248\u672c\u3001WAL \u63d0\u793a\uff09\uff0c\u300c\u6d4f\u89c8\u300d\u9875\u7b7e\u91cc\u9009\u8868\u6216\u89c6\u56fe\u770b\u6570\u636e\uff08\u5206\u9875\u3001\u70b9\u8868\u5934\u6392\u5e8f\u3001\u6700\u5de6 `rowid`\u3001`NULL` \u7070\u663e\u3001BLOB \u53ea\u663e\u793a\u4f53\u79ef\uff09\u3001\u300c\u7ed3\u6784\u300d\u6309\u94ae\u770b\u5217\u4e0e\u7c7b\u578b/\u7d22\u5f15/\u89e6\u53d1\u5668/`CREATE` \u539f\u6587\uff0c\u4ee5\u53ca\u300cSQL\u300d\u9875\u7b7e\u91cc\u7684**\u53ea\u8bfb\u67e5\u8be2\u6846**\uff08`Ctrl/Cmd+Enter` \u8fd0\u884c\uff0c\u53ef\u9009\u884c\u6570\u4e0a\u9650\uff0c\u663e\u793a\u8017\u65f6\u4e0e\u622a\u65ad\u63d0\u793a\uff09\u3002\n \u8fd9\u662f\u63d2\u4ef6\u91cc**\u552f\u4e00\u80fd\u6253\u5f00\u5927\u6587\u4ef6**\u7684\u9884\u89c8\u7c7b\u578b\uff1a\u6570\u636e\u5e93\u7684\u5b57\u8282\u6839\u672c\u4e0d\u8fdb\u89c6\u56fe\uff0c\u4e3b\u8fdb\u7a0b\u6bcf\u6b21\u53ea\u53d6\u4e00\u9875\u3002\n- **\u4e8c\u8fdb\u5236\u8bf4\u6e05\u695a**\uff1azip / apk / exe \u8fd9\u7c7b\u6ca1\u6709\u53ef\u9884\u89c8\u5f62\u6001\u7684\u6587\u4ef6\uff0c\u63d0\u793a\u300c\u4e8c\u8fdb\u5236\u6587\u4ef6\uff08zip\u3001apk\u3001exe \u7b49\uff09\uff0c\u6682\u4e0d\u652f\u6301\u9884\u89c8\u300d\uff0c\u4e0d\u505a\u9b54\u6cd5\u8bc6\u522b\uff0c\u4e5f\u4e0d\u5047\u88c5\u80fd\u89e3\u538b\u3002\n- **\u6587\u4ef6\u64cd\u4f5c**\uff1a\u65b0\u5efa\u6587\u4ef6\u3001\u65b0\u5efa\u6587\u4ef6\u5939\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u5230\u6307\u5b9a\u76ee\u5f55\u3002\n- **\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00 / \u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a**\uff1a\u6587\u4ef6\u53f3\u952e\u5373\u53ef\uff08`fs.openDefault` / `fs.reveal`\uff09\u3002\u8fd9\u4e24\u4e2a\u52a8\u4f5c\u7531\u5bbf\u4e3b\u6267\u884c\uff0c\u6743\u9650\u4e0e\u8303\u56f4\u540c\u5185\u7f6e\u7684 Files \u89c6\u56fe\u3002\n- **\u6309\u6587\u4ef6\u540d\u641c\u7d22**\uff1a\u6574\u4e2a\u9879\u76ee\u8303\u56f4\u5185\u5206\u9875\u641c\u7d22\uff0c\u70b9\u51fb\u7ed3\u679c\u76f4\u63a5\u8df3\u8f6c\u5e76\u5c55\u5f00\u5230\u8be5\u6587\u4ef6\u3002\n- **\u5ffd\u7565\u89c4\u5219**\uff1a\u9879\u76ee\u91cc\u6709 `.gitignore` / `.ignore` \u5c31\u6309\u89c4\u5219\u9690\u85cf\u6761\u76ee\uff08\u53ef\u7528\u5de5\u5177\u680f\u7684\u773c\u775b\u6309\u94ae\u5207\u56de\u663e\u793a\uff09\uff1b**\u4e00\u4e2a\u89c4\u5219\u6587\u4ef6\u90fd\u6ca1\u6709\u65f6\uff0c\u76ee\u5f55\u6811\u5c55\u793a\u5168\u90e8\u6761\u76ee**\u3002\n- **\u8ddf\u968f\u5bbf\u4e3b\u5916\u89c2**\uff1a\u4eae/\u6697\u914d\u8272\u4e0e\u754c\u9762\u8bed\u8a00\uff08\u4e2d\u6587 / English\uff09\u8ddf\u968f PI-Desktop \u4e3b\u4f53\uff0c\u7f16\u8f91\u5668\u4e0e\u9884\u89c8\u7684\u9ad8\u4eae\u914d\u8272\u4e00\u5e76\u8ddf\u968f\u3002\n\n## \u5b89\u88c5\n\n\u5728 PI-Desktop \u7684 Plugins \u9875\u9762\uff1a\n\n1. **Load development plugin** \u2192 \u9009\u62e9\u672c\u76ee\u5f55\uff1b\u6216\n2. \u7528 `dist/pi.file-manager-0.3.1.piplug` \u8d70 **Install plugin package**\u3002\n\n\u88c5\u597d\u540e\u6253\u5f00\u4e00\u4e2a\u9879\u76ee\uff0c\u5728**\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u5934\u90e8\u7684\u5207\u6362\u83dc\u5355 \u2192 \u201cPlugin views / \u63d2\u4ef6\u89c6\u56fe\u201d** \u5206\u7ec4\u91cc\u70b9\u51fb\u300c\u6587\u4ef6\u7ba1\u7406\u5668\u300d\u3002\n\n> \u8fd9\u4e2a\u63d2\u4ef6\u6ca1\u6709\u547d\u4ee4\u9762\u677f\u5165\u53e3\uff0c\u4e5f\u4e0d\u6ce8\u518c\u9762\u677f\u7a97\u53e3\u2014\u2014\u5b83\u53ea\u63d0\u4f9b\u4e00\u4e2a\u505c\u9760\u5728\u53f3\u4fa7\u680f\u7684\u89c6\u56fe\uff08`contributes.views`\uff09\u3002\u5bbf\u4e3b\u6ca1\u6709\u63d0\u4f9b\u300c\u7528\u547d\u4ee4\u6253\u5f00\u89c6\u56fe\u300d\u7684\u901a\u9053\uff0c\u6240\u4ee5\u8fd9\u91cc\u4e5f\u4e0d\u58f0\u660e\u8bef\u5bfc\u6027\u7684\u547d\u4ee4\u3002\n\n## \u5f00\u53d1\n\n```bash\ncd views-src\npnpm install\npnpm typecheck\npnpm build # \u4ea7\u7269\u8f93\u51fa\u5230 ../views\uff08\u5165\u5e93\uff0c\u5bbf\u4e3b\u52a0\u8f7d views/index.html\uff09\n```\n\n`views-src` \u662f\u6e90\u7801\uff08React + TypeScript + Tailwind + CodeMirror 6\uff09\uff1b`views` \u662f\u6784\u5efa\u4ea7\u7269\uff0c\u76f4\u63a5\u5165\u5e93\u3002\u6784\u5efa\u4e3a **IIFE \u5355\u6587\u4ef6**\u5e76\u5185\u8054\u5168\u90e8\u52a8\u6001 import\u2014\u2014\u5bbf\u4e3b\u7684\u89c6\u56fe\u7528 `file://` \u52a0\u8f7d\u9875\u9762\uff0c`type=\"module\"` \u4e0e `crossorigin` \u4f1a\u88ab Chromium \u62e6\u6389\uff0c\u6240\u4ee5 `vite.config.ts` \u91cc\u6709\u4e00\u4e2a `fileProtocolCompat` \u63d2\u4ef6\u8d1f\u8d23\u6539\u5199 `index.html`\u3002\n\n`main.js` \u662f\u624b\u5199\u3001\u96f6\u4f9d\u8d56\u7684 CommonJS\uff0c\u63d2\u4ef6\u7684\u4f9d\u8d56\u4e0d\u4f1a\u88ab\u5b89\u88c5\uff0c\u6240\u4ee5\u4e0d\u8981\u5f80\u5b83\u91cc\u9762 `require` \u7b2c\u4e09\u65b9\u5305\u3002\n\n### \u6821\u9a8c\n\n```bash\ncd views-src\npnpm typecheck\npnpm verify # \u8bed\u6cd5\u9ad8\u4eae + Markdown \u9884\u89c8 + \u67e5\u770b\u5668\u7684\u79bb\u7ebf\u6821\u9a8c\n```\n\n`pnpm verify` \u8dd1\u4e09\u4e2a\u4e0d\u9700\u8981 DOM \u7684\u6821\u9a8c\u811a\u672c\uff0c\u7528\u4e8e\u8986\u76d6\u300c\u9759\u9ed8\u5931\u8d25\u300d\u7684\u4e09\u6761\u94fe\u8def\uff1a\n\n- **`verify-highlight.mjs`**\uff1a\u5bf9 17 \u79cd\u771f\u5b9e\u6587\u4ef6\u8d70\u5b8c\u6574\u7684\n `\u6587\u4ef6\u540d \u2192 \u8bed\u8a00\u89e3\u6790 \u2192 \u8f7d\u5165 \u2192 \u8bed\u6cd5\u6811 \u2192 \u9ad8\u4eae token` \u94fe\u8def\uff0c\u65ad\u8a00\u6bcf\u79cd\u90fd\u4ea7\u51fa\u8db3\u591f\u591a\u7684\n \u4e0d\u540c\u9ad8\u4eae class\uff0c\u5e76\u53cd\u5411\u65ad\u8a00 `.txt` / `.bin` / `.zip` / `.png` / `LICENSE` \u4e0d\u4f1a\u88ab\u8bef\u8ba4\u9886\u3002\n CodeMirror \u7684\u9ad8\u4eae\u662f\u300c\u89e3\u6790\u4e0d\u51fa\u6765\u5c31\u4ec0\u4e48\u90fd\u4e0d\u62a5\u300d\u7684\u5178\u578b\u2014\u2014\u53ea grep \u4ea7\u7269\u5b57\u7b26\u4e32\u4f1a\u6f0f\u6389\n \u8fd0\u884c\u65f6\u95ee\u9898\uff08\u672c\u63d2\u4ef6\u7b2c\u4e00\u7248\u5c31\u8e29\u8fc7\uff1a`basicSetup` \u81ea\u5e26\u7684 fallback \u9ad8\u4eae\u5668\u628a\u81ea\u5df1\u7684\u6837\u5f0f\u76d6\u4f4f\u4e86\uff09\u3002\n- **`verify-markdown.mjs`**\uff1a\u65ad\u8a00\u9884\u89c8\u771f\u5b9e\u4ea7\u51fa\u7684\u5143\u7d20\u6811\uff08\u6807\u9898/\u5217\u8868/\u8868\u683c/\u4efb\u52a1\u5217\u8868/\u5d4c\u5957\n \u5f3a\u8c03\uff09\uff0c\u94fe\u63a5\u534f\u8bae\u767d\u540d\u5355\uff0c\u4ee5\u53ca**\u4e0d\u5b58\u5728 `dangerouslySetInnerHTML`**\u3001\u539f\u59cb HTML \u88ab\u8f6c\u4e49\u3002\n \u5176\u4e2d\u4e00\u4e2a\u56de\u5f52\u7528\u4f8b\u4e13\u95e8\u76ef\u4f4f\u300c\u884c\u5185\u89e3\u6790\u9012\u5f52\u65f6\u5171\u4eab\u5e26 `g` \u7684\u6b63\u5219\u300d\u2014\u2014\u90a3\u4f1a\u8ba9\u9884\u89c8\u5361\u6b7b\u5e76\u5403\u5149\u5185\u5b58\u3002\n- **`verify-viewers.mjs`**\uff1a\u65ad\u8a00 CSV \u89e3\u6790\u7684 12 \u4e2a\u7528\u4f8b\uff08\u5f15\u53f7\u5305\u88f9\u3001`\"\"` \u8f6c\u4e49\u3001\u5b57\u6bb5\u5185\u6362\u884c\u3001\n CRLF\u3001\u53c2\u5dee\u7684\u884c\u3001\u622a\u65ad\u4e0e\u5217\u6570\u5c01\u9876\uff09\u3001\u5206\u9875\u5207\u7247\uff08\u9875\u7801\u8d8a\u754c\u5939\u7d27\u3001\u672b\u9875\u4e0d\u6ee1\u3001\u7a7a\u8868\u4e5f\u6709 1 \u9875\uff09\u3001\n \u6570\u5b57\u5217\u8bc6\u522b\u3001JSON \u5408\u6cd5/\u975e\u6cd5\u4e24\u6761\u8def\u5f84\uff0c\u4ee5\u53ca\u300c\u54ea\u4e2a\u6587\u4ef6\u6709\u54ea\u51e0\u79cd\u770b\u6cd5\u3001\u9ed8\u8ba4\u843d\u5728\u54ea\u4e00\u4fa7\u300d\u7684\u5224\u5b9a\u3002\n \u8868\u683c\u4e0e\u6811\u90fd\u662f\u300c\u628a\u6587\u4ef6\u5185\u5bb9\u53d8\u6210\u754c\u9762\u300d\u7684\u8def\u5f84\uff0c\u89e3\u6790\u5668\u9519\u4e86\u4e0d\u4f1a\u629b\u5f02\u5e38\u3001\u53ea\u4f1a\u9759\u9ed8\u663e\u793a\u9519\u3002\n\n\u5192\u70df\u6d4b\u8bd5\uff08\u5728\u4ed3\u5e93\u6839\u76ee\u5f55\u8fd0\u884c\uff09\uff1a\n\n```bash\nnode ../pi-file-manager-smoke-test.cjs\n```\n\n## \u6570\u636e\u4e0e\u5b89\u5168\n\n**\u8fd9\u4e2a\u63d2\u4ef6\u7528\u81ea\u5df1\u7684 Node `fs` \u8bfb\u5199\u5f53\u524d\u9879\u76ee\u91cc\u7684\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5bbf\u4e3b\u7684 `pi.fs` \u7f51\u5173\u3002**\n\n\u4e3a\u4ec0\u4e48\u5fc5\u987b\u8fd9\u6837\uff1a\u5bbf\u4e3b\u7684 `manifest.fs` \u5728\u8bed\u6cd5\u4e0a\u5c31**\u7981\u6b62\u6574\u6811\u5199\u5165**\uff08\u5199\u5165 scope \u4e0d\u80fd\u662f `**`\uff09\uff0c\u4efb\u4f55\u4e00\u4e2a\u80fd\u901a\u8fc7\u6821\u9a8c\u7684\u7a84 scope \u90fd\u4f1a\u8ba9\u300c\u4fdd\u5b58\u300d\u53d8\u6210\u6bcf\u6b21\u90fd\u5f39\u6743\u9650\u786e\u8ba4\uff1b\u800c\u4e14 `pi.fs.*` \u6ca1\u6709\u521b\u5efa/\u91cd\u547d\u540d/\u79fb\u52a8\uff0c`fs.glob` \u4e0e `fs.list` \u8fd8\u6709\u6761\u6570\u4e0a\u9650\u3001\u4f1a\u8df3\u8fc7 `node_modules`\u3001\u5c4f\u853d\u51ed\u636e\u8def\u5f84\u3002\u4e0e\u4e4b\u5bf9\u5e94\u7684\u4ee3\u4ef7\u662f\uff1a**\u5bbf\u4e3b\u7684\u6743\u9650\u7f51\u5173\u4e0d\u4ecb\u5165\u8fd9\u4e9b\u8c03\u7528**\uff0c\u6240\u4ee5\u5b89\u5168\u8d23\u4efb\u7531\u63d2\u4ef6\u81ea\u5df1\u627f\u62c5\u3002manifest \u91cc\u56e0\u6b64\u6ca1\u6709\u7533\u62a5 `fs.write`\uff08\u5199\u6743\u9650\u6839\u672c\u65e0\u6cd5\u8bda\u5b9e\u7533\u62a5\uff09\uff0c\u53ea\u7533\u62a5\u4e86 `ui.view` \u4e0e `fs.read`\u2014\u2014**\u540e\u8005\u4ec5\u7528\u4e8e\u300c\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00\u300d\u4e0e\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d\u8fd9\u4e24\u4e2a\u53ea\u80fd\u7531\u5bbf\u4e3b\u4ee3\u4e3a\u6267\u884c\u7684\u52a8\u4f5c**\uff08`fs.openDefault` / `fs.reveal`\uff0c\u6743\u9650\u4e0e\u8303\u56f4\u540c\u5185\u7f6e\u7684 Files \u89c6\u56fe\uff1aroot `workspace`\u3001scope `**`\uff09\u3002\u8fd9\u4e24\u4e2a\u901a\u9053\u7531\u5bbf\u4e3b\u6309\u58f0\u660e\u7684\u8303\u56f4\u6821\u9a8c\uff0c\u8d8a\u754c\u4f1a\u88ab\u5bbf\u4e3b\u81ea\u5df1\u62d2\u6389\u3002\n\n\u63d2\u4ef6\u81ea\u5df1\u5b9e\u65bd\u7684\u5168\u90e8\u9650\u5236\uff1a\n\n| \u9650\u5236 | \u8bf4\u660e |\n|---|---|\n| \u8def\u5f84\u5305\u542b | \u53ea\u63a5\u53d7\u76f8\u5bf9\u9879\u76ee\u6839\u7684\u8def\u5f84\uff1b\u7edd\u5bf9\u8def\u5f84\u3001`..`\u3001\u4ee5\u53ca realpath \u540e\u843d\u5230\u6839\u76ee\u5f55\u4e4b\u5916\u7684**\u7b26\u53f7\u94fe\u63a5 / junction** \u4e00\u5f8b\u62d2\u7edd |\n| \u654f\u611f\u8def\u5f84 | `.env*`\u3001`.ssh`\u3001`.aws`\u3001`.gnupg`\u3001`.git/**`\u3001`*.pem`\u3001`*.key`\u3001`*.p12` \u7b49\u8bfb\u5199\u5168\u62d2\uff1b`node_modules` \u53ef\u8bfb\u4e0d\u53ef\u5199 |\n| \u539f\u5b50\u5199 | \u5148\u5199\u540c\u76ee\u5f55\u4e34\u65f6\u6587\u4ef6 \u2192 `fsync` \u2192 \u4fdd\u7559\u539f\u6587\u4ef6\u6743\u9650\u4f4d \u2192 `rename` \u8986\u76d6\uff0c\u4e2d\u65ad\u4e0d\u4f1a\u7559\u4e0b\u534a\u5199\u6587\u4ef6 |\n| \u51b2\u7a81\u68c0\u6d4b | \u4ee5 `mtimeMs` + \u6587\u4ef6\u5927\u5c0f\u4f5c\u4e3a\u4e50\u89c2\u9501\uff1b\u6587\u4ef6\u5728\u7f16\u8f91\u5668\u4e4b\u5916\u88ab\u6539\u52a8\u8fc7\u65f6**\u4e0d\u4f1a\u9759\u9ed8\u8986\u76d6**\uff0c\u4f1a\u5148\u5f39\u5bf9\u8bdd\u6846\u8ba9\u4f60\u9009\u62e9\u8986\u76d6 / \u653e\u5f03 / \u91cd\u65b0\u52a0\u8f7d |\n| \u5199\u5165\u5ba1\u8ba1 | \u6bcf\u6b21\u5199\u5165\u8ffd\u52a0\u4e00\u884c\u5230\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u7684 `write-audit.jsonl`\uff08\u7ea6 1 MiB \u540e\u8f6e\u8f6c\uff09\uff0c\u56e0\u4e3a\u5bbf\u4e3b\u5ba1\u8ba1\u4e0d\u5230\u8fd9\u6761\u8def\u5f84 |\n| \u6570\u636e\u5e93\u53ea\u8bfb | \u4ee5 `readOnly` \u6253\u5f00 + `PRAGMA query_only = 1`\uff08\u5b9e\u6d4b `DROP`/`INSERT` \u4f1a\u88ab SQLite \u81ea\u5df1\u62d2\u7edd\uff09\uff0c\u518d\u53e0\u4e00\u5c42\u8bed\u53e5\u767d\u540d\u5355\uff1a\u53ea\u653e\u884c `select` / `with` / `values` / `explain` \u4e0e\u53ea\u8bfb `pragma`\uff0c\u4e14\u5fc5\u987b\u662f**\u5355\u6761**\u8bed\u53e5\u2014\u2014`node:sqlite` \u7684 prepare \u5bf9\u591a\u8bed\u53e5\u662f\u653e\u884c\u7684\uff08\u5b9e\u6d4b `select 1; select 2` \u53ea\u6267\u884c\u7b2c\u4e00\u6761\u3001\u4e0d\u62a5\u9519\uff09\uff0c\u6240\u4ee5\u5fc5\u987b\u81ea\u5df1\u62e6\u3002\u8868\u540d/\u5217\u540d\u5148\u4e0e `sqlite_schema` \u6838\u5bf9\u518d\u62fc\u5f15\u53f7\uff0c\u7edd\u4e0d\u76f4\u63a5\u63d2\u503c |\n| \u4f53\u79ef\u4e0a\u9650 | \u6587\u672c\u9884\u89c8 2 MiB\u3001\u56fe\u7247 8 MiB\u3001\u97f3\u89c6\u9891 24 MiB\u3001\u5199\u5165 8 MiB\u3002\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u5355\u72ec\u8bbe\u9650\u662f\u56e0\u4e3a\u5b83\u4eec\u7684\u5b57\u8282\u8981\u4ee5 base64 \u968f\u54cd\u5e94\u53d1\u7ed9\u89c6\u56fe\uff08\u81a8\u80c0\u7ea6 1/3\uff09\uff1b\u8d85\u9650\u65f6\u63d0\u793a\u91cc\u4f1a\u5e26\u4e0a\u5177\u4f53\u4e0a\u9650 |\n\n\u884c\u4e3a\u4e0a\u7684\u4e24\u70b9\u8bf4\u660e\uff1a\n\n- `.git` \u76ee\u5f55**\u4e0d\u4f1a\u51fa\u73b0\u5728\u6811\u91cc**\uff08\u4f53\u91cf\u5de8\u5927\u4e14\u6c38\u8fdc\u65e0\u7528\uff09\u3002\n- \u5ffd\u7565\u89c4\u5219\u6765\u81ea `.gitignore` \u4e0e `.ignore`\uff08\u652f\u6301 `!` \u53d6\u53cd\u3001\u672b\u5c3e `/`\u3001\u524d\u5bfc `/` \u951a\u5b9a\u3001`*` / `?` / `**`\uff09\u3002\u8fd9\u662f gitignore \u7684\u4e00\u4e2a\u5b50\u96c6\uff0c\u4e0d\u652f\u6301 `\\` \u8f6c\u4e49\u548c `[a-z]` \u5b57\u7b26\u7c7b\uff1b\u504f\u5dee\u53ea\u5f71\u54cd\u300c\u663e\u4e0d\u663e\u793a\u300d\uff0c\u4e14\u968f\u65f6\u53ef\u4ee5\u7528\u5de5\u5177\u680f\u7684\u773c\u775b\u6309\u94ae\u7ffb\u76d8\u3002\n\n**Markdown \u9884\u89c8\u7684\u5b89\u5168\u505a\u6cd5**\uff1a\u9884\u89c8**\u4e0d\u4f7f\u7528** `dangerouslySetInnerHTML`\uff0c\u800c\u662f\u628a Markdown \u89e3\u6790\u6210 React \u5143\u7d20\u2014\u2014\u8282\u70b9\u7531 React \u8f6c\u4e49\uff0c\u7ed3\u6784\u4e0a\u4e0d\u5b58\u5728\u6ce8\u5165\u9762\uff0c\u56e0\u6b64\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684 sanitizer\u3002\u539f\u56e0\u5f88\u76f4\u63a5\uff1a\u8fd9\u4e2a\u89c6\u56fe\u7684 bridge \u901a\u5411\u4e00\u4e2a\u80fd\u8bfb\u5199\u9879\u76ee\u6587\u4ef6\u7684\u63d2\u4ef6\u4e3b\u8fdb\u7a0b\uff0c\u9884\u89c8\u91cc\u7684 XSS \u5c31\u7b49\u4e8e\u4efb\u610f\u6587\u4ef6\u5199\u5165\u3002\u9884\u89c8\u4e2d\u7684\u94fe\u63a5\u4e5f\u4e0d\u4f1a\u5bfc\u822a\uff08\u70b9\u4e00\u4e0b\u5c31\u79bb\u5f00\u63d2\u4ef6\u9875\u9762\u56de\u4e0d\u6765\u4e86\uff09\uff0c\u70b9\u51fb\u53ea\u4f1a\u628a\u5730\u5740\u663e\u793a\u51fa\u6765\u3002\n\n**\u4e0d\u8bbf\u95ee\u7f51\u7edc**\uff1a\u6ca1\u6709 `net.domains`\uff0c\u8fd0\u884c\u65f6\u4e0d\u53d1\u8d77\u4efb\u4f55\u8bf7\u6c42\u3002\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u91cc\u53ea\u653e\u8bbe\u7f6e\uff08\u5206\u680f\u5bbd\u5ea6\u3001\u663e\u793a\u5f00\u5173\u3001Markdown \u9ed8\u8ba4\u89c6\u56fe\uff09\u548c\u4e0a\u9762\u90a3\u4efd\u5ba1\u8ba1\u65e5\u5fd7\u3002\n\n## \u5df2\u77e5\u9650\u5236\n\n- **\u4e0d\u5220\u9664\u6587\u4ef6/\u76ee\u5f55**\u3002\u5220\u9664\u662f\u7834\u574f\u6027\u64cd\u4f5c\uff0c\u800c\u4e14\u5bbf\u4e3b\u7684 `fs.remove` \u5e76\u6ca1\u6709\u5f00\u653e\u7ed9\u89c6\u56fe\u6865\uff0c\u53ea\u80fd\u8d70\u539f\u751f `rm`\u2014\u2014\u672c\u671f\u4e0d\u505a\u3002\n- **\u300c\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00\u300d\u4e0e\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d\u53ea\u5bf9\u6587\u4ef6\u6709\u6548**\uff08\u5bbf\u4e3b\u5bf9\u76ee\u5f55\u8fd4\u56de `INVALID_ARGUMENT`\uff09\uff0c\u5165\u53e3\u5728\u6587\u4ef6\u6811\u7684\u53f3\u952e\u83dc\u5355\u91cc\u3002\n- **Markdown \u9884\u89c8\u91cc\u7684\u56fe\u7247\u4ecd\u662f\u5360\u4f4d\u5757**\uff1a`![](path)` \u663e\u793a\u6210\u5e26\u6587\u4ef6\u540d\u7684\u5360\u4f4d\u7b26\u3002\u6587\u4ef6\u7ea7\u7684\u56fe\u7247\u67e5\u770b\u8d70 data URI \u5df2\u7ecf\u53ef\u7528\uff0c\u4f46\u9884\u89c8\u91cc\u7684\u56fe\u7247\u8981\u9010\u5f20\u6309\u76f8\u5bf9\u8def\u5f84\u53bb\u8bfb\uff0c\u672c\u8f6e\u6ca1\u505a\u3002\u539f\u56e0\u8fd8\u662f\u90a3\u6761\uff1a\u9762\u677f\u4ee5 `file://` \u52a0\u8f7d\uff0c\u76f8\u5bf9\u8def\u5f84\u6307\u5411\u89c6\u56fe\u81ea\u8eab\u800c\u4e0d\u662f\u9879\u76ee\u3002\n- **\u6587\u4ef6\u76d1\u542c**\uff1a\u5bbf\u4e3b\u6ca1\u6709\u300c\u63d2\u4ef6 \u2192 \u89c6\u56fe\u300d\u7684\u63a8\u9001\u901a\u9053\uff08\u89c6\u56fe\u53ea\u80fd\u53d1\u8d77\u8bf7\u6c42\u3001\u62ff\u54cd\u5e94\uff09\uff0c\u6240\u4ee5\u5916\u90e8\u6539\u52a8\u4e0d\u662f\u5b9e\u65f6\u7684\uff1b\u4fdd\u5b58\u540e\u4f1a\u5237\u65b0\u76ee\u5f55\uff0c\u5de5\u5177\u680f\u7684\u300c\u4ece\u78c1\u76d8\u91cd\u65b0\u52a0\u8f7d\u300d\u968f\u65f6\u53ef\u70b9\uff0c\u7528\u6765\u628a\u522b\u5904\u6539\u52a8\u62c9\u8fdb\u6765\uff08\u5f53\u524d\u6709\u672a\u4fdd\u5b58\u6539\u52a8\u65f6\u4f1a\u5148\u786e\u8ba4\uff09\u3002\n- **\u4e8c\u8fdb\u5236\u4e0d\u53ef\u9884\u89c8**\uff1azip / apk / exe / tiff \u53ea\u7ed9\u63d0\u793a\u2014\u2014\u4e0d\u89e3\u538b\u3001\u4e0d\u5217\u5f52\u6863\u5185\u5bb9\u3001\u4e0d\u505a\u5341\u516d\u8fdb\u5236\u67e5\u770b\u3002TIFF \u5355\u72ec\u8bf4\u660e\uff1aChromium \u89e3\u4e0d\u4e86\u5b83\uff0c\u6240\u4ee5\u6309\u4e8c\u8fdb\u5236\u5904\u7406\uff0c\u800c\u4e0d\u662f\u663e\u793a\u4e00\u5f20\u7834\u56fe\u3002\n- **\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u53ea\u8bfb**\uff1a\u53ea\u505a\u67e5\u770b\uff0c\u4e0d\u8fdb\u7f16\u8f91\u5668\u3001\u4e0d\u80fd\u6539\uff08\u4e0d\u5f71\u54cd\u5176\u5b83\u6587\u4ef6\u7684\u7f16\u8f91\uff09\u3002\n- **\u5927\u6587\u4ef6\u4e0d\u9884\u89c8**\uff1a\u56fe\u7247\u8d85\u8fc7 8 MiB\u3001\u97f3\u89c6\u9891\u8d85\u8fc7 24 MiB \u53ea\u63d0\u793a\u4e0a\u9650\u3002\n- **`.avi` \u8fd9\u7c7b\u6309\u4e8c\u8fdb\u5236\u5904\u7406**\uff08Chromium \u653e\u4e0d\u4e86\uff09\uff1b`.mkv` / `.mov` \u80fd\u4e0d\u80fd\u64ad\u653e\u53d6\u51b3\u4e8e\u91cc\u9762\u7684\u7f16\u7801\uff0c\u653e\u4e0d\u4e86\u4f1a\u660e\u786e\u63d0\u793a\u3002\n- **SQLite \u53ea\u8bfb**\uff1a\u4e0d\u5199\u5165\u3001\u4e0d VACUUM\u3001\u4e0d\u5efa `-shm`\u3002**WAL \u6a21\u5f0f\u4e0b\u5c1a\u672a\u5408\u5e76\u56de\u4e3b\u6587\u4ef6\u7684\u5185\u5bb9\u770b\u4e0d\u5230**\uff08\u9876\u90e8\u6709\u63d0\u793a\uff09\uff1b\u52a0\u5bc6\u5e93\uff08SQLCipher\uff09\u4e0e\u635f\u574f\u6587\u4ef6\u90fd\u660e\u786e\u62a5\u300c\u8bfb\u4e0d\u4e86\u300d\uff0c\u4e0d\u4f1a\u9759\u9ed8\u7a7a\u767d\u3002\n- **\u6570\u636e\u5e93\u6df1\u7ffb\u9875\u6709\u4e0a\u9650**\uff08OFFSET \u2264 10 \u4e07\u884c\uff09\uff1a`node:sqlite` \u662f\u540c\u6b65 API\u3001\u6ca1\u6709\u4e2d\u65ad\u63a5\u53e3\uff0c\u53ea\u80fd\u8ba9\u67e5\u8be2\u5929\u751f\u6709\u754c\u2014\u2014\u8981\u770b\u66f4\u8fdc\u5c31\u5728 SQL \u6846\u91cc\u52a0\u6761\u4ef6\u6536\u7a84\u3002\n- **\u8868\u6e05\u5355\u91cc\u7684\u884c\u6570\u662f\u4f30\u7b97**\uff08`max(rowid)`\uff09\uff1a\u7cbe\u786e `COUNT(*)` \u5728\u5927\u8868\u4e0a\u662f\u5168\u8868\u626b\u63cf\uff0c\u8bf7\u6309\u9700\u5728 SQL \u6846\u91cc\u6267\u884c\u3002\n- **\u9700\u8981\u5bbf\u4e3b\u8fd0\u884c\u65f6\u5e26 `node:sqlite`**\uff08Node \u2265 22.5\uff1b\u5f53\u524d\u5bbf\u4e3b Electron 43 / Node 24 \u6ee1\u8db3\uff09\u3002\u63a2\u6d4b\u4e0d\u5230\u65f6\u63d2\u4ef6\u4e0d\u4f1a\u5d29\uff0c\u53ea\u663e\u793a\u6982\u89c8\u5e76\u8bf4\u660e\u539f\u56e0\u3002\n\n## \u8bb8\u53ef\n\nMIT\u3002\n", - "safetyNotes": "fs.read \u4ec5\u7528\u4e8e\u300c\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00\u300d\u4e0e\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d\u8fd9\u4e24\u4e2a\u7531\u5bbf\u4e3b\u4ee3\u4e3a\u6267\u884c\u7684\u52a8\u4f5c\uff08\u6743\u9650\u4e0e\u8303\u56f4\u540c\u5185\u7f6e\u7684 Files \u89c6\u56fe\uff1aroot workspace\u3001scope **\uff09\uff1b\u63d2\u4ef6\u81ea\u8eab\u7684\u8bfb\u5199\u8d70\u81ea\u5df1\u8fdb\u7a0b\u5185\u7684 Node fs\u2014\u2014\u5bbf\u4e3b\u7684\u6743\u9650\u7f51\u5173\u4e0d\u4ecb\u5165\u8fd9\u4e9b\u8c03\u7528\uff0cmanifest \u4e5f\u65e0\u6cd5\u7533\u62a5\u300c\u6574\u6811\u5199\u5165\u300d\u3002\u8bbf\u95ee\u8303\u56f4\u7531\u63d2\u4ef6\u81ea\u8eab\u9650\u5b9a\u5728\u9879\u76ee\u6839\u76ee\u5f55\u5185\uff1a\u89e3\u6790\u540e\u7684\u8def\u5f84\u5fc5\u987b\u4ecd\u5728\u6839\u5185\uff08\u62d2\u7edd\u7b26\u53f7\u94fe\u63a5\u4e0e junction \u9003\u9038\uff09\u3001\u62d2\u7edd\u51ed\u636e\u7c7b\u8def\u5f84\uff08.env*\u3001.ssh/\u3001*.pem\u3001.git/**\uff09\u3001\u4fdd\u5b58\u91c7\u7528\u539f\u5b50\u5199\uff08\u4e34\u65f6\u6587\u4ef6 + \u91cd\u547d\u540d\uff09\u3001\u8986\u76d6\u5728\u7f16\u8f91\u5668\u5916\u88ab\u6539\u52a8\u8fc7\u7684\u6587\u4ef6\u524d\u4f1a\u5148\u8be2\u95ee\u3002\u56fe\u7247\u4e0e\u97f3\u89c6\u9891\u6309\u5404\u81ea\u4e0a\u9650\uff088 MiB / 24 MiB\uff09\u8bfb\u53d6\u540e\u4ee5 base64 data URI \u4ea4\u7ed9\u89c6\u56fe\uff1b\u6570\u636e\u5e93\u4e00\u5f8b\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\uff08readOnly + PRAGMA query_only\uff09\uff0cSQL \u6846\u53ea\u63a5\u53d7\u5355\u6761\u53ea\u8bfb\u8bed\u53e5\uff0c\u53ea\u80fd\u6d4f\u89c8\u3001\u7edd\u65e0\u4fee\u6539\uff1bzip\u3001exe \u8fd9\u7c7b\u4e8c\u8fdb\u5236\u53ea\u62a5\u300c\u4e0d\u652f\u6301\u9884\u89c8\u300d\uff0c\u4e0d\u505a\u4efb\u4f55\u89e3\u7801\u3002\u65e0\u7f51\u7edc\u8bbf\u95ee\uff1b\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u53ea\u4fdd\u5b58\u8bbe\u7f6e\u4e0e\u5199\u5165\u5ba1\u8ba1\u65e5\u5fd7\u3002", + "readmeMarkdown": "# \u6587\u4ef6\u7ba1\u7406\u5668\uff08File Manager\uff09\n\n\u5728 PI-Desktop \u7684**\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f**\u91cc\u6d4f\u89c8\u5e76\u7f16\u8f91\u5f53\u524d\u9879\u76ee\u7684\u6587\u4ef6\u3002\u5b83\u4e0d\u662f\u5bbf\u4e3b\u5185\u7f6e\u300c\u6587\u4ef6\u300d\u89c6\u56fe\u7684\u66ff\u4ee3\u54c1\uff0c\u800c\u662f\u5e76\u5217\u7684\u4e00\u884c\uff1a\u5185\u7f6e\u89c6\u56fe\u53ea\u8bfb\uff0c\u8fd9\u4e00\u884c\u53ef\u7f16\u8f91\u3002\n\n\u6e90\u7801\u4ed3\u5e93\uff1a\n\n## \u4e3a\u4ec0\u4e48\u505a\u8fd9\u4e2a\n\n\u5bbf\u4e3b\u5185\u7f6e\u7684\u300c\u6587\u4ef6\u300d\u89c6\u56fe\u53ea\u80fd\u770b\u4e0d\u80fd\u6539\uff0c\u800c\u5bbf\u4e3b\u7684 `pi.fs` \u7f51\u5173\u5728\u8bed\u6cd5\u4e0a\u5c31**\u7981\u6b62\u6574\u6811\u5199\u5165**\uff08`manifest.fs` \u7684 write scope \u4e0d\u80fd\u662f `**`\uff09\uff0c\u4efb\u4f55\u4e00\u4e2a\u80fd\u901a\u8fc7\u6821\u9a8c\u7684\u7a84 scope \u90fd\u4f1a\u8ba9\u300c\u4fdd\u5b58\u300d\u53d8\u6210\u6bcf\u6b21\u90fd\u5f39\u6743\u9650\u786e\u8ba4\uff1b`pi.fs.*` \u4e5f\u6ca1\u6709\u521b\u5efa / \u91cd\u547d\u540d / \u79fb\u52a8\u80fd\u529b\u3002\n\n\u6240\u4ee5\u8fd9\u4e2a\u63d2\u4ef6\u5728\u81ea\u5df1\u7684\u8fdb\u7a0b\u91cc\u7528 Node `fs` \u8bfb\u5199\u5f53\u524d\u9879\u76ee\uff0c\u5e76**\u81ea\u5df1\u627f\u62c5\u5168\u90e8\u5b89\u5168\u8d23\u4efb**\uff08\u89c1\u4e0b\u9762\u7684\u300c\u5b89\u5168\u300d\u4e00\u8282\uff09\u3002\n\n## \u529f\u80fd\n\n- **\u5b8c\u6574\u76ee\u5f55\u6811**\uff1a\u61d2\u52a0\u8f7d\u3001\u76ee\u5f55\u4f18\u5148\u3001\u952e\u76d8\u5bfc\u822a\uff08\u2191\u2193 Home End \u2190\u2192 Enter\uff09\uff1b\u6bcf\u4e00\u884c\u7684\u56fe\u6807\u968f\u6587\u4ef6\u7c7b\u578b\u53d8\u5316\u2014\u2014\u6587\u4ef6\u5939\u3001\u4ee3\u7801\u3001JSON\u3001Markdown\u3001\u6837\u5f0f\u3001HTML/Vue/Svelte\u3001YAML/TOML\u3001Shell\u3001SQL\u3001\u56fe\u7247\u3001\u538b\u7f29\u5305\u3001\u5b57\u4f53\u3001\u9501\u6587\u4ef6\u7b49\u5404\u6709\u5b57\u5f62\u4e0e\u914d\u8272\uff0c`package.json` / `Dockerfile` / `LICENSE` / `.gitignore` \u8fd9\u7c7b\u7279\u6b8a\u6587\u4ef6\u540d\u4f18\u5148\u4e8e\u6269\u5c55\u540d\u5224\u5b9a\u3002\n- **\u9009\u4e2d\u6001\u4e0e\u60ac\u505c\u6001\u660e\u786e\u533a\u5206**\uff1a\u60ac\u505c\u662f\u6de1\u4e2d\u6027\u5e95\u8272\uff1b\u9009\u4e2d\u662f\u5f3a\u8c03\u8272\u5e95 + \u5de6\u4fa7\u5f3a\u8c03\u8272\u7ad6\u6761 + \u524d\u666f\u8272\u6587\u5b57 + \u4e2d\u7b49\u5b57\u91cd\uff0c\u9f20\u6807\u79fb\u5f00\u4e5f\u4fdd\u6301\u3002\n- **\u53f3\u952e\u83dc\u5355**\uff1a\u5728\u6587\u4ef6 / \u6587\u4ef6\u5939\u4e0a\u53f3\u952e\u53ef\u65b0\u5efa\u6587\u4ef6\u3001\u65b0\u5efa\u6587\u4ef6\u5939\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u3001\u6253\u5f00\u3001\u5237\u65b0\uff1b\u5217\u8868\u7a7a\u767d\u5904\u53f3\u952e\u63d0\u4f9b\u300c\u5728\u6b64\u65b0\u5efa\u300d\u4e0e\u5237\u65b0\u3002\n- **\u5de6\u53f3\u5206\u680f**\uff1a\u5de6\u4fa7\u6587\u4ef6\u5217\u8868\uff0c\u53f3\u4fa7\u5185\u5bb9\uff1b\u5206\u9694\u6761\u53ef\u62d6\u62fd\uff0c\u5bbd\u5ea6\u4f1a\u8bb0\u4f4f\u3002\n- **\u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91**\uff1aCodeMirror 6\uff0c\u884c\u53f7\u3001\u67e5\u627e\u66ff\u6362\u3001\u591a\u5149\u6807\u3001\u62ec\u53f7\u5339\u914d\u3001\u4ee3\u7801\u6298\u53e0\u3002\u6309\u6587\u4ef6\u540d\u52a0\u8f7d\u8bed\u6cd5\u9ad8\u4eae\uff0c\u8986\u76d6 TypeScript/TSX\u3001JavaScript/JSX\u3001JSON\u3001Markdown\u3001CSS/SCSS/Sass/Less\u3001HTML\u3001Vue\u3001XML\u3001YAML\u3001TOML\u3001Properties\u3001Python\u3001Go\u3001Rust\u3001Java\u3001C/C++\u3001C#\u3001Kotlin\u3001Scala\u3001Dart\u3001Objective-C\u3001PHP\u3001Ruby\u3001Lua\u3001Shell\u3001PowerShell\u3001SQL\u3001Dockerfile\u3001Diff\u3002\u5168\u90e8\u968f\u5305\u5185\u7f6e\u3001\u79bb\u7ebf\u53ef\u7528\u3002`Ctrl/Cmd+S` \u6216\u5de5\u5177\u680f\u6309\u94ae\u4fdd\u5b58\u3002\n- **Markdown \u9884\u89c8 / \u7f16\u8f91\u5207\u6362**\uff1a\u6253\u5f00 `.md` / `.markdown` / `.mdx` \u65f6\u5de5\u5177\u680f\u51fa\u73b0\u5207\u6362\u3002\u9884\u89c8\u652f\u6301\u6807\u9898\u3001\u56f4\u680f\u4ee3\u7801\u5757\uff08\u590d\u7528\u7f16\u8f91\u5668\u540c\u4e00\u5957\u9ad8\u4eae\uff09\u3001\u5f15\u7528\u3001\u5206\u9694\u7ebf\u3001\u6709\u5e8f/\u65e0\u5e8f/\u4efb\u52a1\u5217\u8868\uff08\u6309\u7f29\u8fdb\u5d4c\u5957\uff09\u3001\u8868\u683c\uff08\u542b\u5bf9\u9f50\uff09\u3001\u884c\u5185 code / \u7c97\u4f53 / \u659c\u4f53 / \u5220\u9664\u7ebf / \u94fe\u63a5 / \u56fe\u7247\uff1b\u5207\u6362\u4f1a\u8bb0\u4f4f\u3002\n- **\u6309\u6587\u4ef6\u540d\u641c\u7d22**\uff1a\u6574\u4e2a\u9879\u76ee\u8303\u56f4\u5185\u5206\u9875\u641c\u7d22\uff0c\u70b9\u51fb\u7ed3\u679c\u76f4\u63a5\u8df3\u8f6c\u5e76\u5c55\u5f00\u5b9a\u4f4d\u3002\n- **\u5ffd\u7565\u89c4\u5219**\uff1a\u9879\u76ee\u91cc\u6709 `.gitignore` / `.ignore` \u5c31\u6309\u89c4\u5219\u9690\u85cf\u6761\u76ee\uff08\u5de5\u5177\u680f\u773c\u775b\u6309\u94ae\u53ef\u5207\u56de\u663e\u793a\uff09\uff1b**\u4e00\u4e2a\u89c4\u5219\u6587\u4ef6\u90fd\u6ca1\u6709\u65f6\uff0c\u76ee\u5f55\u6811\u5c55\u793a\u5168\u90e8\u6761\u76ee**\u3002\n- **\u8ddf\u968f\u5bbf\u4e3b\u5916\u89c2**\uff1a\u4eae / \u6697\u914d\u8272\u4e0e\u754c\u9762\u8bed\u8a00\uff08\u4e2d\u6587 / English\uff09\u8ddf\u968f PI-Desktop \u4e3b\u4f53\uff0c\u7f16\u8f91\u5668\u4e0e\u9884\u89c8\u7684\u9ad8\u4eae\u914d\u8272\u4e00\u5e76\u8ddf\u968f\u3002\n\n## \u5b89\u88c5\n\n\u5728 PI-Desktop \u7684 **\u63d2\u4ef6 \u2192 \u5e02\u573a** \u4e2d\u5b89\u88c5\uff1b\u6216\u4e0b\u8f7d `packages/pi.file-manager-0.2.0.piplug` \u540e\u8d70 **Install plugin package**\u3002\n\n\u88c5\u597d\u540e\u6253\u5f00\u4e00\u4e2a\u9879\u76ee\uff0c\u5728**\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u5934\u90e8\u7684\u5207\u6362\u83dc\u5355 \u2192\u300cPlugin views\u300d\u5206\u7ec4**\u91cc\u70b9\u51fb\u300c\u6587\u4ef6\u7ba1\u7406\u5668\u300d\u3002\n\n> \u8fd9\u4e2a\u63d2\u4ef6\u6ca1\u6709\u547d\u4ee4\u9762\u677f\u5165\u53e3\uff0c\u4e5f\u4e0d\u6ce8\u518c\u72ec\u7acb\u9762\u677f\u7a97\u53e3\u2014\u2014\u5b83\u53ea\u63d0\u4f9b\u4e00\u4e2a\u505c\u9760\u5728\u53f3\u4fa7\u680f\u7684\u89c6\u56fe\uff08`contributes.views`\uff09\u3002\u5bbf\u4e3b\u6ca1\u6709\u63d0\u4f9b\u300c\u7528\u547d\u4ee4\u6253\u5f00\u89c6\u56fe\u300d\u7684\u901a\u9053\uff0c\u6240\u4ee5\u8fd9\u91cc\u4e5f\u4e0d\u58f0\u660e\u8bef\u5bfc\u6027\u7684\u547d\u4ee4\u3002\n\n## \u6743\u9650\n\n\u53ea\u7533\u62a5\u4e00\u9879\uff1a\n\n- `ui.view` \u2014\u2014 \u628a\u89c6\u56fe\u505c\u9760\u5230\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u3002\n\n**\u4e3a\u4ec0\u4e48\u6ca1\u6709\u7533\u62a5 `fs.read` / `fs.write`**\uff1a\u5bbf\u4e3b `manifest.fs` \u5728\u8bed\u6cd5\u4e0a\u65e0\u6cd5\u8868\u8fbe\u300c\u6574\u6811\u5199\u5165\u300d\uff0c\u4efb\u4f55\u4e00\u4e2a\u80fd\u901a\u8fc7\u6821\u9a8c\u7684\u7a84 scope \u90fd\u4f1a\u9020\u6210\u300c\u5199\u5165\u53d7\u9650\u300d\u7684\u5047\u8c61\uff0c\u6bd4\u4e0d\u7533\u62a5\u66f4\u5371\u9669\uff1b\u800c `fs.read` \u672c\u63d2\u4ef6\u4ece\u4e0d\u4f7f\u7528\uff08\u4e0d\u8c03\u7528\u4efb\u4f55 `pi.fs.*`\uff09\u3002\u771f\u5b9e\u89e6\u8fbe\u5199\u5728 `i18n.*.safetyNotes` \u4e0e\u672c\u6587\u4ef6\u7684\u300c\u5b89\u5168\u300d\u4e00\u8282\uff0c\u8fd9\u662f\u5f53\u524d\u552f\u4e00\u80fd\u8bda\u5b9e\u8868\u8fbe\u5b83\u7684\u4f4d\u7f6e\u3002\n\n\u65e0\u7f51\u7edc\uff1a`manifest.json` \u6ca1\u6709 `net.domains`\uff0c\u8fd0\u884c\u65f6\u4e0d\u53d1\u8d77\u4efb\u4f55\u8bf7\u6c42\u3002\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u53ea\u4fdd\u5b58\u8bbe\u7f6e\uff08\u5206\u680f\u5bbd\u5ea6\u3001\u663e\u793a\u5f00\u5173\u3001Markdown \u9ed8\u8ba4\u89c6\u56fe\uff09\u548c\u4e00\u4efd\u5199\u5165\u5ba1\u8ba1\u65e5\u5fd7\u3002\n\n## \u5b89\u5168\n\n\u6587\u4ef6\u8bfb\u5199**\u7531\u63d2\u4ef6\u81ea\u8eab**\u9650\u5b9a\u5728\u9879\u76ee\u6839\u76ee\u5f55\u5185\uff0c\u5bbf\u4e3b\u7684\u6743\u9650\u7f51\u5173\u4e0d\u4ecb\u5165\u8fd9\u4e9b\u8c03\u7528\u3002\u63d2\u4ef6\u5b9e\u65bd\u7684\u5168\u90e8\u9650\u5236\uff1a\n\n| \u9650\u5236 | \u8bf4\u660e |\n|---|---|\n| \u8def\u5f84\u5305\u542b | \u53ea\u63a5\u53d7\u76f8\u5bf9\u9879\u76ee\u6839\u7684\u8def\u5f84\uff1b\u7edd\u5bf9\u8def\u5f84\u3001`..`\u3001\u4ee5\u53ca realpath \u540e\u843d\u5230\u6839\u76ee\u5f55\u4e4b\u5916\u7684**\u7b26\u53f7\u94fe\u63a5 / junction** \u4e00\u5f8b\u62d2\u7edd |\n| \u654f\u611f\u8def\u5f84 | `.env*`\u3001`.ssh`\u3001`.aws`\u3001`.gnupg`\u3001`.git/**`\u3001`*.pem`\u3001`*.key`\u3001`*.p12` \u7b49\u8bfb\u5199\u5168\u62d2\uff1b`node_modules` \u53ef\u8bfb\u4e0d\u53ef\u5199 |\n| \u539f\u5b50\u5199 | \u5148\u5199\u540c\u76ee\u5f55\u4e34\u65f6\u6587\u4ef6 \u2192 `fsync` \u2192 \u4fdd\u7559\u539f\u6587\u4ef6\u6743\u9650\u4f4d \u2192 `rename` \u8986\u76d6\uff0c\u4e2d\u65ad\u4e0d\u4f1a\u7559\u4e0b\u534a\u5199\u6587\u4ef6 |\n| \u51b2\u7a81\u68c0\u6d4b | \u4ee5 `mtimeMs` + \u6587\u4ef6\u5927\u5c0f\u4f5c\u4e3a\u4e50\u89c2\u9501\uff1b\u6587\u4ef6\u5728\u7f16\u8f91\u5668\u4e4b\u5916\u88ab\u6539\u52a8\u8fc7\u65f6**\u4e0d\u4f1a\u9759\u9ed8\u8986\u76d6**\uff0c\u4f1a\u5148\u5f39\u5bf9\u8bdd\u6846\u8ba9\u7528\u6237\u9009\u62e9\u8986\u76d6 / \u653e\u5f03 / \u91cd\u65b0\u52a0\u8f7d |\n| \u5199\u5165\u5ba1\u8ba1 | \u6bcf\u6b21\u5199\u5165\u8ffd\u52a0\u4e00\u884c\u5230\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\u7684 `write-audit.jsonl`\uff08\u7ea6 1 MiB \u540e\u8f6e\u8f6c\uff09\uff0c\u56e0\u4e3a\u5bbf\u4e3b\u5ba1\u8ba1\u4e0d\u5230\u8fd9\u6761\u8def\u5f84 |\n| \u4f53\u79ef\u4e0a\u9650 | \u9884\u89c8 2 MiB\u3001\u5199\u5165 8 MiB\uff1b\u4e8c\u8fdb\u5236\u6587\u4ef6\u4e0e\u56fe\u7247\u4e0d\u8fdb\u5165\u7f16\u8f91\u5668\uff0c\u53ea\u63d0\u793a |\n\nMarkdown \u9884\u89c8**\u4e0d\u4f7f\u7528** `dangerouslySetInnerHTML`\uff0c\u800c\u662f\u628a Markdown \u89e3\u6790\u6210 React \u5143\u7d20\u2014\u2014\u8282\u70b9\u7531 React \u8f6c\u4e49\uff0c\u7ed3\u6784\u4e0a\u4e0d\u5b58\u5728\u6ce8\u5165\u9762\uff0c\u56e0\u6b64\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684 sanitizer\u3002\u9884\u89c8\u4e2d\u7684\u94fe\u63a5\u4e0d\u4f1a\u5bfc\u822a\uff08\u70b9\u4e00\u4e0b\u5c31\u79bb\u5f00\u63d2\u4ef6\u9875\u9762\u56de\u4e0d\u6765\u4e86\uff09\uff0c\u70b9\u51fb\u53ea\u4f1a\u628a\u5730\u5740\u663e\u793a\u51fa\u6765\u3002\n\n\u884c\u4e3a\u8bf4\u660e\uff1a`.git` \u76ee\u5f55\u4e0d\u4f1a\u51fa\u73b0\u5728\u6811\u91cc\uff1b\u5ffd\u7565\u89c4\u5219\u662f gitignore \u7684\u4e00\u4e2a\u5b50\u96c6\uff08\u652f\u6301 `!` \u53d6\u53cd\u3001\u672b\u5c3e `/`\u3001\u524d\u5bfc `/` \u951a\u5b9a\u3001`*` / `?` / `**`\uff0c\u4e0d\u652f\u6301 `\\` \u8f6c\u4e49\u4e0e `[a-z]` \u5b57\u7b26\u7c7b\uff09\uff0c\u504f\u5dee\u53ea\u5f71\u54cd\u300c\u663e\u4e0d\u663e\u793a\u300d\uff0c\u968f\u65f6\u53ef\u7528\u5de5\u5177\u680f\u7684\u773c\u775b\u6309\u94ae\u7ffb\u76d8\u3002\n\n## \u5df2\u77e5\u9650\u5236\n\n- **\u4e0d\u5220\u9664\u6587\u4ef6 / \u76ee\u5f55**\uff1a\u5220\u9664\u662f\u7834\u574f\u6027\u64cd\u4f5c\uff0c\u4e14\u5bbf\u4e3b\u7684 `fs.remove` \u5e76\u672a\u5f00\u653e\u7ed9\u89c6\u56fe\u6865\uff0c\u53ea\u80fd\u8d70\u539f\u751f `rm`\u2014\u2014\u672c\u671f\u4e0d\u505a\u3002\n- **\u6ca1\u6709\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d/\u300c\u7528\u7cfb\u7edf\u7a0b\u5e8f\u6253\u5f00\u300d**\uff1a\u8fd9\u4e24\u4e2a\u5bbf\u4e3b\u901a\u9053\u9700\u8981 `fs.read` \u6743\u9650\uff0c\u800c\u672c\u63d2\u4ef6\u6709\u610f\u4e0d\u7533\u62a5\u4efb\u4f55 fs \u6743\u9650\u3002\n- **\u9884\u89c8\u91cc\u7684\u56fe\u7247\u4e0d\u52a0\u8f7d**\uff1a\u9762\u677f\u4ee5 `file://` \u52a0\u8f7d\uff0c\u76f8\u5bf9\u8def\u5f84\u6307\u5411\u89c6\u56fe\u81ea\u8eab\u800c\u4e0d\u662f\u9879\u76ee\uff0c\u56e0\u6b64\u56fe\u7247\u663e\u793a\u4e3a\u5e26\u6587\u4ef6\u540d\u7684\u5360\u4f4d\u5757\uff0c\u800c\u4e0d\u662f\u7834\u56fe\u3002\n- **\u6587\u4ef6\u76d1\u542c**\uff1a\u5bbf\u4e3b\u6ca1\u6709\u300c\u63d2\u4ef6 \u2192 \u89c6\u56fe\u300d\u7684\u63a8\u9001\u901a\u9053\uff08\u89c6\u56fe\u53ea\u80fd\u53d1\u8d77\u8bf7\u6c42\u3001\u62ff\u54cd\u5e94\uff09\uff0c\u5916\u90e8\u6539\u52a8\u4e0d\u662f\u5b9e\u65f6\u7684\uff1b\u4fdd\u5b58\u540e\u4f1a\u81ea\u52a8\u5237\u65b0\uff0c\u5de5\u5177\u680f\u4e5f\u6709\u624b\u52a8\u5237\u65b0\u3002\n- \u4e8c\u8fdb\u5236\u4e0e\u56fe\u7247\u4e0d\u53ef\u7f16\u8f91\uff0c\u4e5f\u4e0d\u505a\u56fe\u7247\u9884\u89c8\uff08\u4e0e\u5bbf\u4e3b\u5185\u7f6e\u7684\u300c\u6587\u4ef6\u300d\u89c6\u56fe\u4e00\u81f4\uff09\u3002\n\n## \u6784\u5efa\n\n\u672c\u76ee\u5f55\u53ea\u5305\u542b\u53ef\u76f4\u63a5\u8fd0\u884c\u7684\u4ea7\u7269\uff08`main.js` + `views/`\uff09\u3002\u89c6\u56fe\u6e90\u7801\uff08React + TypeScript + Tailwind + CodeMirror 6\uff09\u4e0e\u6784\u5efa\u811a\u672c\u5728\u6e90\u7801\u4ed3\u5e93\u7684 `views-src/`\uff1a\n\n```bash\ncd views-src\npnpm install\npnpm typecheck\npnpm verify # \u8bed\u6cd5\u9ad8\u4eae + Markdown \u9884\u89c8\u7684\u79bb\u7ebf\u6821\u9a8c\npnpm build # \u4ea7\u7269\u8f93\u51fa\u5230 ../views\n```\n\n## \u8bb8\u53ef\n\nMIT\u3002\n", + "safetyNotes": null, "versions": [ { - "version": "0.3.1", - "publishedAt": "2026-09-13T14:27:05Z", - "changelog": "Release 0.3.1\uff1a\u8865\u9f50\u300c\u7528\u9ed8\u8ba4\u5e94\u7528\u6253\u5f00\u300d\u4e0e\u300c\u5728\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u300d\uff08\u8d70\u5bbf\u4e3b\u7684 fs.openDefault / fs.reveal\uff0c\u4e3a\u6b64\u58f0\u660e fs.read\uff0c\u6743\u9650\u4e0e\u8303\u56f4\u540c\u5185\u7f6e Files \u89c6\u56fe\uff1b\u76ee\u5f55\u5bf9\u8fd9\u4e24\u4e2a\u52a8\u4f5c\u65e0\u6548\uff0c\u53ea\u5bf9\u6587\u4ef6\u63d0\u4f9b\uff09\u3002Release 0.3.0\uff1a\u4ece\u300c\u53ea\u80fd\u7f16\u8f91\u6587\u672c\u300d\u6269\u5230\u300c\u770b\u5f97\u89c1\u5404\u79cd\u6587\u4ef6\u300d\u2014\u2014\u56fe\u7247\u67e5\u770b\uff08png/jpg/gif/webp/avif/bmp/ico/svg\uff0c\u9002\u5e94\u7a97\u53e3\u4e0e\u5b9e\u9645\u5927\u5c0f\u3001\u68cb\u76d8\u683c\u3001\u50cf\u7d20\u5c3a\u5bf8\u4e0e\u4f53\u79ef\uff09\u3001\u97f3\u89c6\u9891\u64ad\u653e\uff08mp4/mov/webm/mkv \u4e0e mp3/wav/flac/ogg \u7b49\uff0c\u4e0d\u81ea\u52a8\u64ad\u653e\u3001\u7f16\u7801\u4e0d\u652f\u6301\u65f6\u660e\u786e\u63d0\u793a\uff09\u3001CSV/TSV \u8868\u683c\uff08\u9ed8\u8ba4\u6bcf\u9875 1000 \u884c\u53ef\u8c03\u5e76\u8bb0\u4f4f\u3001\u70b9\u8868\u5934\u5347/\u964d/\u53d6\u6d88\u6392\u5e8f\u3001\u884c\u53f7\u5217\u4e0e\u8868\u5934\u53cc\u5411\u5438\u9876\u3001\u6570\u5b57\u53f3\u5bf9\u9f50\u3001\u60ac\u505c\u770b\u5168\u503c\uff09\u3001JSON \u6298\u53e0\u6811\uff0c\u4ee5\u53ca SQLite \u53ea\u8bfb\u6d4f\u89c8\u4e0e SQL \u67e5\u8be2\u6846\uff08readOnly + PRAGMA query_only + \u5355\u6761\u53ea\u8bfb\u8bed\u53e5\u767d\u540d\u5355\u4e09\u5c42\u53ea\u8bfb\uff0c\u5b57\u8282\u4e0d\u8fdb\u89c6\u56fe\uff0c\u53ef\u6253\u5f00\u51e0\u767e MB \u7684\u5e93\uff09\u3002\u4e8c\u8fdb\u5236\u6587\u4ef6\uff08zip/apk/exe \u7b49\uff09\u660e\u786e\u63d0\u793a\u4e0d\u652f\u6301\u9884\u89c8\u3002\u540c\u65f6\u4fee\u6389\u4fdd\u5b58\u94fe\u8def\u7684\u4e00\u4e2a\u4e25\u91cd\u7f3a\u9677\uff1a\u4fdd\u5b58\u6210\u529f\u540e\u7f16\u8f91\u5668\u6587\u6863\u4f1a\u88ab\u91cd\u88c5\u56de\u6253\u5f00\u65f6\u7684\u65e7\u5185\u5bb9\uff08\u73b0\u4ee5 loadToken \u533a\u5206\u300c\u4ece\u78c1\u76d8\u88c5\u8f7d\u300d\u4e0e\u300c\u4fdd\u5b58\u540e\u66f4\u65b0 mtime\u300d\uff09\uff0c\u5e76\u4fee\u6389\u300c\u6ca1\u6709\u6539\u52a8\u4e5f\u5199\u76d8\u300d\u300c\u8fde\u6309 Ctrl+S \u81ea\u5df1\u649e\u51fa\u51b2\u7a81\u300d\u300c\u4fdd\u5b58\u8fd4\u56de\u65f6\u7528\u6237\u5df2\u5207\u8d70\u6587\u4ef6\u300d\u300cCtrl+S \u7126\u70b9\u4e0d\u5728\u7f16\u8f91\u5668\u5c31\u5931\u6548\u300d\u7b49\u95ee\u9898\u3002Release 0.2.0\uff1a\u4fee\u590d\u4ee3\u7801\u6ca1\u6709\u8bed\u6cd5\u9ad8\u4eae\uff08\u53bb\u6389 basicSetup \u81ea\u5e26\u7684 fallback \u9ad8\u4eae\u5668\uff09\u3001\u8bed\u8a00\u89e3\u6790\u6539\u4e3a\u663e\u5f0f\u6ce8\u518c\u8868\u3001\u65b0\u589e\u53f3\u952e\u83dc\u5355\u4e0e Markdown \u9884\u89c8/\u7f16\u8f91\u5207\u6362\u3002Release 0.1.0\uff1a\u9996\u4e2a\u7248\u672c\uff0c\u53f3\u4fa7\u5de5\u4f5c\u9762\u677f\u91cc\u7684\u5b8c\u6574\u76ee\u5f55\u6811 + \u4ee3\u7801\u9ad8\u4eae\u7f16\u8f91\u4e0e\u4fdd\u5b58 + \u65b0\u5efa/\u91cd\u547d\u540d/\u79fb\u52a8 + \u6309\u6587\u4ef6\u540d\u641c\u7d22\u3002", + "version": "0.2.0", + "publishedAt": "2026-09-11T18:47:58Z", + "changelog": "Release 0.2.0", "minPiDesktop": ">=0.9.0", - "shasum": "9f1acaad5322e73ba2209dd5230e0f470ba43f96a1b858db07400e6ea3e0f218", - "url": "packages/pi.file-manager-0.3.1.piplug", - "sizeBytes": 1409757, + "shasum": "3ef1466d213558db20b46ab60407242ee37a12bdb3dc5fb7108e4704a7f50d0d", + "url": "packages/pi.file-manager-0.2.0.piplug", + "sizeBytes": 1342507, "permissions": [ - "ui.view", - "fs.read" + "ui.view" ], - "fs": { - "read": { - "root": "workspace", - "scope": [ - "**" - ] - } - } + "fs": {} } ] }, @@ -520,7 +388,7 @@ "versions": [ { "version": "0.2.7", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.2.7: follow the app color mode only \u2014 never snap to the OS palette, which flashed when the two disagreed. Release 0.2.6: follows the app light/dark mode live in the work-panel view. Release 0.2.5: drop agent tools and the Git workflow skill \u2014 Git Lens is a human work-panel UI only. Release 0.2.5\uff1a\u53bb\u6389 AI \u5de5\u5177\u548c Git workflow skill\uff0cGit Lens \u53ea\u7ed9\u4eba\u7528\u3002 Release 0.2.4: command palette, toasts and the work-panel UI follow the app language (en / zh-CN) from the first paint. Release 0.2.3: compact work-panel UI \u2014 overview is a single count row; file/commit diffs open as a full-page sheet with Back. Release 0.2.0: docks only in the right work panel.", "minPiDesktop": ">=0.8.0", "shasum": "40babc1d5f59f221ca17f0299647053636d403fbf11c7dc97daab197a10dadf3", @@ -563,7 +431,7 @@ "versions": [ { "version": "0.1.1", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "0.1.1: docked work-panel chrome, fail-closed storage, namespaced commands, appearance adapter. 0.1.0: workspace-scoped goal pools, focus, regular and Sisyphus modes, task trees, completion evidence, pause/block/resume/archive lifecycle, bilingual dashboard, Agent tools, and host-owned completion audits.", "minPiDesktop": ">=0.13.11", "shasum": "f501107dcd2f444fab737c15ed81c257fd301a3f72318d2911d65c7149580615", @@ -612,7 +480,7 @@ "versions": [ { "version": "0.2.0", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.2.0\uff1a\u63d2\u4ef6 id \u5b9a\u7a3f pi.log-viewer\uff1b\u641c\u7d22\u4e0e\u6587\u672c\u8fc7\u6ee4\u5206\u79bb\uff08\u641c\u7d22\u9ad8\u4eae\u53ef\u8df3\u8f6c\uff0c\u8fc7\u6ee4\u53ea\u663e\u793a/\u9690\u85cf\u547d\u4e2d\uff09\uff1b\u8fc7\u6ee4\u89c6\u56fe\u865a\u62df\u6eda\u52a8\uff1b\u7b49\u7ea7\u914d\u8272\u8bbe\u7f6e\uff1b\u9489\u4f4f\u6700\u591a 5 \u884c\u5bf9\u6bd4\uff1b\u53f3\u952e\u300c\u6e05\u9664\u7b5b\u9009\u5e76\u8df3\u8f6c\u300d\uff1b\u7cfb\u7edf\u6587\u4ef6\u9009\u62e9\u5668\u6253\u5f00 .log/.txt\uff1b\u9996\u6b21\u6253\u5f00\u793a\u4f8b\u5f15\u5bfc\u65e5\u5fd7\uff1b\u4fee\u590d\u9759\u6001\u6587\u4ef6\u8bef\u62a5\u65b0\u589e\u3001\u9876\u90e8\u9996\u884c\u7a97\u53e3\u7a7a\u767d\u4e0e\u5e95\u90e8\u7559\u767d\u3002", "minPiDesktop": ">=0.14.3", "shasum": "43224cefed7fd52357d9a4a1094404edb13e3f14e60650c39107f9644838bf80", @@ -662,7 +530,7 @@ "versions": [ { "version": "0.5.0", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.5.0\uff1aAgent \u5de5\u5177\u6539\u4e3a\u300c\u9884\u89c8\u6a21\u5f0f\u6253\u5f00\u6587\u4ef6\u300d\u2014\u2014\u4ee5 preview_file \u53d6\u4ee3 open_file\uff1a\u6309\u7edd\u5bf9\u8def\u5f84\u4ee5\u53ea\u8bfb\u9884\u89c8\u6253\u5f00\u5355\u4e2a Markdown/\u6587\u672c\u6587\u4ef6\uff08\u672c\u5730 Node fs \u8bfb\u5199\uff0c\u65e0\u9700\u9009\u5b9a\u76ee\u5f55\u3001\u4efb\u610f\u8def\u5f84\u53ef\u7528\uff09\uff0c\u9762\u677f\u4e0d\u663e\u793a\u4fa7\u8fb9\u680f\uff0c\u53ea\u6709\u300c\u9884\u89c8 / \u7f16\u8f91\u300d\u4e24\u6001\uff0c\u7528\u6237\u70b9\u300c\u7f16\u8f91\u300d\u540e\u624d\u80fd\u4fee\u6539\u5e76\u81ea\u52a8\u5199\u56de\u539f\u6587\u4ef6\uff1b\u56e0\u6b64\u79fb\u9664 fs.read / fs.write \u6743\u9650\u4e0e manifest.fs \u58f0\u660e\u3002\u9762\u677f\u914d\u8272\u6539\u4e3a Typora Inkwell \u4e3b\u9898\uff08\u6d45\u8272\u67d4\u548c\u7070\u8c03 / \u9ed1\u591c\u6df1\u84dd\u4f4e\u9971\u548c\uff09\uff0c\u7f16\u8f91\u533a\u5bbd\u5ea6\u968f\u7a97\u53e3\u653e\u5bbd\uff08860 \u2192 1024 \u2192 1200\uff09\u3002\u4fee\u590d\u4ee3\u7801\u5757\u4e0e\u516c\u5f0f\u7684\u300c\u53cc\u5c42\u8fb9\u6846\u300d\uff08\u6539\u4e3a\u5355\u5c42\u5706\u89d2\u5bb9\u5668 + \u8bed\u8a00\u6807\u9898\u680f\uff09\u3001\u4ee3\u7801\u5757\u5728\u6d45\u8272\u4e3b\u9898\u4e0b\u88ab oneDark \u5f3a\u6491\u6df1\u8272\u914d\u8272\u3001Mermaid \u56fe\u8868\u4e0d\u968f\u4e3b\u9898\u5207\u6362\u3001\u4efb\u52a1\u5217\u8868\u52fe\u9009\u6846\u5bf9\u6bd4\u5ea6\u8fc7\u4f4e\u3001\u72b6\u6001\u680f\u6309\u94ae\u6ea2\u51fa 4px\uff1b\u516c\u5f0f\u4e0e Mermaid \u9ed8\u8ba4\u663e\u793a\u6e32\u67d3\u7ed3\u679c\uff08\u70b9\u300c\u7f16\u8f91\u300d\u770b\u6e90\u7801\uff09\u3001\u5757\u7ea7\u516c\u5f0f\u5c45\u4e2d\u3001\u53bb\u6389\u591a\u4f59\u7684\u300c\u9884\u89c8\u300d\u6807\u7b7e\uff1b\u4ee3\u7801\u5757\u6807\u9898\u680f\u4e0e\u8bed\u8a00\u4e0b\u62c9\u6536\u7d27\uff0849px \u2192 31px\uff0c\u7edf\u4e00 22px \u63a7\u4ef6\u4e0e\u6eda\u52a8\u6761\u6837\u5f0f\uff09\uff1b\u6e05\u7406 panel-polish.css \u4e2d\u4e00\u6279\u4ece\u672a\u751f\u6548\u7684\u9009\u62e9\u5668\uff08.sidebar-container / .editor-pane / .tab-button \u7b49\uff09\u3002Release 0.4.8\uff1a\u5408\u5e76\u5e02\u573a 0.4.7 \u57fa\u7ebf\u2014\u2014\u8fc1\u79fb v3 \u7a7f\u900f\u5f0f\u9876\u90e8 chrome\u3001panel-polish\u3001\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u5b9e\u65f6\u91cd\u7740\u8272\u4e0e pimd.theme.v1 \u4e3b\u9898\u955c\u50cf\u9884\u7ed8\uff1bmanifest \u589e\u8865 i18n \u53cc\u8bed\u5757\uff1b\u4fdd\u7559\u672c\u4ed3\u5e93\u72ec\u6709 open_file\uff08\u5bbf\u4e3b pi.fs \u6743\u9650\u7f51\u5173 + \u5355\u6587\u4ef6\u6a21\u5f0f\uff09\u4e0e\u9762\u677f\u4e2d\u82f1 i18n\u3002Release 0.4.7\uff1a\u5bbf\u4e3b\u9876\u90e8\u62d6\u62fd\u5e26\u6309\u9875\u9762\u5143\u7d20\u5207\u5206\uff0c\u63a7\u4ef6\u53ef\u70b9\u51fb\u3001\u7a7a\u767d\u5904\u53ef\u62d6\u62fd\uff1b\u9762\u677f\u6539\u4e3a v3 \u5168\u51fa\u8840\u5e03\u5c40\u3002Release 0.4.6\uff1a\u4fee\u590d v2 \u9762\u677f\u9876\u90e8\u5b89\u5168\u533a\u91cd\u590d\u7559\u767d\uff1b\u4fa7\u680f\u641c\u7d22\u4e0e\u7b14\u8bb0\u6807\u9898\u884c\u4ece\u5bbf\u4e3b 46px \u62d6\u62fd\u5e26\u4e0b\u6cbf\u76f4\u63a5\u5f00\u59cb\uff0c\u4fdd\u7559\u5bbf\u4e3b\u62d6\u62fd\u533a\u5e76\u6d88\u9664\u989d\u5916 8px \u9876\u90e8\u5185\u8fb9\u8ddd\uff1b\u540c\u65f6\u8ba9\u6839\u5e03\u5c40\u586b\u6ee1\u89c6\u53e3\uff0c\u907f\u514d\u5e95\u90e8\u51fa\u73b0\u5bf9\u5e94\u7a7a\u767d\u3002Release 0.4.5\uff1a\u538b\u7f29\u9762\u677f\u5185\u90e8\u7684\u5927\u95f4\u9699\u3002\u6839\u56e0\u662f Crepe \u81ea\u5e26\u4e3b\u9898\u5728 bundle \u4e2d\u6392\u5728\u5e94\u7528\u81ea\u5b9a\u4e49\u6837\u5f0f\u4e4b\u540e\uff0c\u5176 .ProseMirror { padding: 60px 120px } \u5728\u7ea7\u8054\u4e2d\u80dc\u51fa\u2014\u2014\u6b63\u6587\u7b2c\u4e00\u884c\u4e4b\u524d\u5b9e\u9645\u57ab\u4e86\u7ea6 190px\uff0846px \u62d6\u62fd\u5e26 + 53px \u6807\u9898\u884c + 60px Crepe \u5185\u8fb9\u8ddd + 28px \u9996\u4e2a\u6807\u9898\u5916\u8fb9\u8ddd\uff09\u3002\u73b0\u7531\u6700\u540e\u52a0\u8f7d\u7684 panel-polish.css \u91cd\u65b0\u58f0\u660e\u7d27\u51d1\u5185\u8fb9\u8ddd\uff08\u4e0a 12px\u3001\u968f\u5bbd\u81ea\u9002\u5e94\u3001\u5e95\u90e8 40vh \u6eda\u52a8\u4f59\u91cf\uff09\uff0c\u5e76\u53bb\u6389\u9996\u5757\u5143\u7d20\u7684\u5916\u8fb9\u8ddd\uff1b\u540c\u65f6\u6536\u7d27\u5404\u884c\u9ad8\uff1a\u4fa7\u680f\u641c\u7d22\u884c 49px\u219243px\u3001tabs \u884c 34px\u219230px\u3001\u7b14\u8bb0\u6807\u9898\u884c 53px\u219245px\uff1b\u4fa7\u680f\u7684 46px \u62d6\u62fd\u5e26\u533a\u57df\u6539\u7ed8\u4e3a\u4fa7\u680f\u5934\u90e8\u540c\u8272\uff0c\u4e0e\u641c\u7d22\u884c\u8fde\u6210\u4e00\u4f53\uff0c\u4e0d\u518d\u5448\u73b0\u4e3a\u7a7a\u6d1e\u3002Release 0.4.4\uff1a\u9762\u677f\u6539\u4e3a v2 \u5168\u51fa\u8840\u5e03\u5c40\uff0c\u5e76\u4fee\u590d\u4eae\u8272\u6a21\u5f0f\u4e0b\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u4e0d\u53ef\u89c1\u7684\u95ee\u9898\u3002(1) \u58f0\u660e pi-plugin-chrome=v2\uff0c\u5bbf\u4e3b\u4e0d\u518d\u5411 body \u6ce8\u5165 46px \u9876\u90e8\u5185\u8fb9\u8ddd\u2014\u2014\u5185\u5bb9\u76f4\u63a5\u9876\u5230\u7a97\u53e3\u4e0a\u6cbf\uff0c\u6eda\u52a8\u65f6\u4ece\u900f\u660e\u7684\u5bbf\u4e3b\u62d6\u62fd\u5e26\u4e0b\u65b9\u7a7f\u8fc7\uff08\u80f6\u56ca\u5373\u60ac\u6d6e\u5728\u5185\u5bb9\u4e4b\u4e0a\uff09\uff1b\u641c\u7d22\u6846\u3001tabs\u3001\u7b14\u8bb0\u6807\u9898\u884c\u7b49\u4ea4\u4e92\u884c\u56fa\u5b9a\u5728\u5e26\u4e0b\u6cbf\uff08top: var(--pi-plugin-titlebar-height, 46px)\uff09\u4e4b\u5916\uff0c\u56e0\u8be5\u533a\u57df\u4ec5\u4e3a\u62d6\u62fd\u533a\u3001\u4e0d\u63a5\u6536\u70b9\u51fb\u3002(2) \u5bbf\u4e3b\u53ea\u5728\u81ea\u5bb6\u5916\u89c2\u5e7f\u64ad\u65f6\u7ed9\u80f6\u56ca\u91cd\u65b0\u53d6\u8272\uff0c\u9762\u677f\u5185\u7c73\u767d/\u9ed1\u591c\u5207\u6362\u540e\u58a8\u8272\u505c\u7559\u5728\u65e7\u4e3b\u9898\u4e0a\uff0c\u4eae\u8272\u9875\u9762\u914d\u6d45\u8272\u58a8\u51e0\u4e4e\u4e0d\u53ef\u89c1\uff1b\u73b0\u7531\u6e32\u67d3\u7aef\u76d1\u542c data-theme \u53d8\u5316\uff0c\u5b9e\u65f6\u628a\u5f53\u524d\u8c03\u8272\u677f\u8986\u5199\u5230\u5bbf\u4e3b\u80f6\u56ca\u5143\u7d20\u7684\u4e24\u4e2a\u53d6\u8272\u53d8\u91cf\u4e0a\uff0c\u4efb\u4f55\u6765\u6e90\u7684\u4e3b\u9898\u5207\u6362\u80f6\u56ca\u90fd\u7acb\u5373\u91cd\u4e0a\u8272\u3002(3) body \u76f4\u63a5\u7740\u8272 rgb(var(--c-bg))/rgb(var(--c-ink))\uff0c\u5bbf\u4e3b\u4e00\u6b21\u6027\u53d6\u8272\u4e0e\u5b9e\u9645\u9875\u9762\u6c38\u8fdc\u4e00\u81f4\u3002Release 0.4.3\uff1a\u4fee\u590d\u5bbf\u4e3b\u5207\u6362\u5916\u89c2\u540e\u91cd\u5f00\u9762\u677f\u65f6\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u4ecd\u6309\u65e7\u914d\u8272\u7ed8\u5236\u800c\u4e0d\u53ef\u89c1\u7684\u95ee\u9898\u2014\u2014\u5bbf\u4e3b\u9a71\u52a8\u7684\u4e3b\u9898\u53d8\u66f4\u6b64\u524d\u53ea\u6539\u5199 data-theme\uff0cReact \u4e0d\u611f\u77e5\u3001pimd.theme.v1 \u955c\u50cf\u4e0d\u66f4\u65b0\uff0c\u4e0b\u6b21\u6253\u5f00\u5373\u6309\u8fc7\u671f\u4e3b\u9898\u9996\u7ed8\uff0c\u5bbf\u4e3b\u5728 DOMContentLoaded \u5bf9\u9875\u9762\u989c\u8272\u7684\u4e00\u6b21\u6027\u5feb\u7167\uff08\u80f6\u56ca\u53d6\u8272\uff09\u62ff\u5230\u9519\u8bef\u58a8\u8272\uff1b\u73b0\u7531\u5916\u89c2\u8fd0\u884c\u65f6\u5728\u6bcf\u6b21\u5b9e\u9645\u5e94\u7528\u7684\u4e3b\u9898\u53d8\u5316\u65f6\u628a\u771f\u5b9e\u4e3b\u9898\u5199\u56de\u955c\u50cf\uff0c\u9996\u5e27\u4e0e\u955c\u50cf\u6c38\u8fdc\u4e00\u81f4\u3002\u540c\u65f6\u538b\u7d27 46px \u5bbf\u4e3b\u62d6\u62fd\u5e26\u4e4b\u4e0b\u7684\u9996\u884c UI\uff1a\u4fa7\u680f\u5934\u90e8\u5185\u8fb9\u8ddd\u4e0e\u641c\u7d22\u6846\u9ad8\u5ea6\u6536\u7d27\u3001\u80cc\u666f\u6539\u7528\u9875\u9762\u5e95\u8272\uff0c\u7f16\u8f91\u5668\u9876\u680f\u6700\u5c0f\u9ad8\u5ea6 44px \u6536\u7a84\u4e3a 36px\uff0c\u6d88\u9664\u300c\u7a7a\u62d6\u62fd\u5e26 + \u9ad8\u5de5\u5177\u884c\u300d\u53e0\u6210\u53cc\u5c42\u5934\u90e8\u7684\u89c2\u611f\u3002Release 0.4.2\uff1a\u4fee\u590d\u6df1\u8272\u4e3b\u9898\u4e0b\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u8fd1\u4e4e\u4e0d\u53ef\u89c1\u7684\u95ee\u9898\u2014\u2014\u5bbf\u4e3b\u5728 DOMContentLoaded \u65f6\u5bf9\u9875\u9762\u989c\u8272\u505a\u5feb\u7167\u4e3a\u80f6\u56ca\u4e0a\u8272\uff0c\u800c\u6b64\u523b data-theme \u53ef\u80fd\u4ecd\u662f\u65e7\u503c/\u56de\u653e\u503c\uff1b\u73b0\u4e8e\u9996\u5e27\u524d\u4ece\u672c\u5730\u955c\u50cf\uff08pimd.theme.v1\uff09\u540c\u6b65\u6062\u590d\u5e94\u7528\u771f\u5b9e\u4e3b\u9898\uff0c\u4e3b\u9898\u53d8\u66f4\u65f6\u5b9e\u65f6\u5199\u56de\u955c\u50cf\uff0c\u521d\u59cb state \u4e5f\u8ddf\u968f\u5df2\u5e94\u7528\u7684 data-theme \u907f\u514d\u95ea\u5c4f\uff1b\u79fb\u9664\u5bf9\u5bbf\u4e3b\u4e0d\u5b58\u5728\u901a\u9053 appearance.sync \u7684\u65e0\u6548\u8c03\u7528\u3002Release 0.4.1\uff1a\u9002\u914d PI-Desktop \u8de8\u5e73\u53f0 46px \u4e3b\u673a\u62d6\u62fd\u5e26\u548c\u7b80\u7ea6\u4e09\u6309\u94ae\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\uff1bAgent \u5de5\u5177 open_file \u843d\u5730\uff08\u9700 agent.tool.register \u9ad8\u98ce\u9669\u6743\u9650\uff09\u2014\u2014Agent \u4f20\u5165\u5b8c\u6574\u7edd\u5bf9\u8def\u5f84\uff0c\u5373\u53ef\u5728\u9762\u677f\u5355\u6587\u4ef6\u6a21\u5f0f\u4e2d\u6253\u5f00\u8be5\u6587\u4ef6\u7f16\u8f91\uff08\u9690\u85cf\u7b14\u8bb0\u5217\u8868\uff0c\u4ec5\u663e\u793a\u5f53\u524d\u6587\u4ef6\uff0c\u65e0\u6cd5\u5207\u6362\u5176\u4ed6\u6587\u4ef6\uff09\uff0c\u7f16\u8f91\u7ecf 800ms \u9632\u6296\u81ea\u52a8\u4fdd\u5b58\u5199\u56de\u539f\u6587\u4ef6\uff08\u4fdd\u7559\u539f BOM\uff09\uff0c\u4ec5\u652f\u6301 .md/.markdown/.txt\u3001\u22645MB\u3001utf8 \u6587\u672c\uff08\u62d2\u7edd\u4e8c\u8fdb\u5236\uff09\uff0c\u9762\u677f 1s \u8f6e\u8be2\u62c9\u53d6\u5f85\u6253\u5f00\u6587\u4ef6\u3001\u5fc3\u8df3 60s \u8fc7\u671f\u540e\u53ef\u88ab\u65b0\u8c03\u7528\u63a5\u7ba1\u3001Plan \u6a21\u5f0f\u4e0d\u53ef\u7528\uff1b\u968f\u540e\u6587\u4ef6\u5185\u5bb9\u8bfb\u5199\u7531\u63d2\u4ef6\u8fdb\u7a0b\u5185 Node fs \u8fc1\u79fb\u81f3\u5bbf\u4e3b pi.fs \u6743\u9650\u7f51\u5173\uff08manifest.fs \u58f0\u660e userSelected \u6839\uff0c\u9996\u6b21\u8c03\u7528\u5f39\u51fa\u539f\u751f\u76ee\u5f55\u9009\u62e9\u5668\uff0c\u4ec5\u80fd\u6253\u5f00/\u5199\u56de\u7528\u6237\u9009\u5b9a\u76ee\u5f55\u5185\u7684\u6587\u4ef6\uff1b\u7f51\u5173\u8d1f\u8d23\u8d8a\u754c/\u7b26\u53f7\u94fe\u63a5/\u51ed\u636e\u8def\u5f84\u6821\u9a8c\u4e0e\u5ba1\u8ba1\uff09\uff1bmanifest.ui.title \u6539\u4e3a\u5bbf\u4e3b\u53cc\u8bed { en, \"zh-CN\" }\uff1b\u547d\u4ee4\u6807\u9898/\u9762\u677f\u6807\u9898/\u5de5\u5177\u63d0\u793a\u6309\u5bbf\u4e3b\u8bed\u8a00\uff08pi.app.getLocale\uff09\u5207\u6362\uff1b\u9762\u677f\u9ed8\u8ba4\u8ddf\u968f\u5bbf\u4e3b\u4e3b\u9898\uff08\u8bfb\u5bbf\u4e3b\u6ce8\u5165\u7684 data-theme\uff09\uff0c\u9762\u677f\u5185\u5207\u6362\u4fdd\u7559\u4e3a\u624b\u52a8\u8986\u76d6\uff08themeSource \u6301\u4e45\u5316\uff09\u3002Release 0.4.0\uff1a\u9762\u677f\u8ddf\u968f app \u4e3b\u4f53\u7684\u8bed\u8a00\u4e0e\u989c\u8272\u6a21\u5f0f\u2014\u2014\u5bbf\u4e3b\u5207\u6362\u4eae/\u6697\u6216\u8bed\u8a00\u65f6\uff0c\u7f16\u8f91\u5668\u4e0e\u754c\u9762\u914d\u8272\u5b9e\u65f6\u66f4\u65b0\uff08CSS \u7531 :root[data-theme=...] \u9a71\u52a8\uff0c\u914d\u5408\u5bbf\u4e3b app.getAppearance \u901a\u9053\u4e0e appearance:changed \u4e8b\u4ef6\uff09\uff1b\u672a\u624b\u52a8\u8986\u76d6\u4e3b\u9898\u65f6 settings.theme \u81ea\u52a8\u540c\u6b65\u4e3a\u5bbf\u4e3b base\uff0c\u9762\u677f\u5185\u7684\u7c73\u767d/\u9ed1\u591c\u5207\u6362\u4ecd\u53ef\u624b\u52a8\u8986\u76d6\uff08\u6b64\u540e\u4e0d\u518d\u88ab\u5bbf\u4e3b\u8986\u76d6\uff09\uff1b\u65e7\u7248\u5bbf\u4e3b\u81ea\u52a8\u964d\u7ea7\u4e3a\u9762\u677f\u81ea\u5e26\u7684\u4e3b\u9898\u8ddf\u968f\u3002Release 0.3.2\uff1a\u4ee3\u7801\u5757\u652f\u6301 Mermaid \u56fe\u8868\u5b9e\u65f6\u6e32\u67d3\uff08\u8f93\u5165 ```mermaid \u5373\u51fa\u56fe\u8868\uff0c\u6e90\u7801\u59cb\u7ec8\u53ef\u7f16\u8f91\u3001300ms \u9632\u6296\u968f\u660e\u6697\u4e3b\u9898\u5207\u6362\uff1bHTML/PNG \u5bfc\u51fa\u6e32\u67d3\u4e3a\u5185\u5d4c SVG\uff09\u3002Release 0.3.1\uff1a\u4fee\u590d LaTeX \u516c\u5f0f\u4f9d\u8d56 CodeMirror \u5bfc\u81f4\u7f16\u8f91\u5668\u65e0\u6cd5\u521d\u59cb\u5316\u7684\u95ee\u9898\uff1b\u4fee\u590d HTML/PNG \u5bfc\u51fa\u4e2d\u5757\u7ea7\u516c\u5f0f\u4e0e\u4ee3\u7801\u9ad8\u4eae\u7f3a\u5931\u7684\u95ee\u9898\uff08\u6539\u4e3a Markdown \u6e90\u7801\u7ecf\u7f16\u8f91\u5668 parser/serializer \u6e32\u67d3\uff09\uff1b\u65b0\u589e\u7c73\u767d\uff08\u9ed8\u8ba4\uff09/\u9ed1\u591c\u53cc\u4e3b\u9898\u4e0e\u72b6\u6001\u680f\u5207\u6362\u5f00\u5173\uff0c\u4e3b\u9898\u504f\u597d\u968f settings.json \u6301\u4e45\u5316\uff1b\u4ee3\u7801\u5757\u9884\u89c8\u5373\u6240\u5f97\uff08LaTeX \u76f4\u63a5\u663e\u793a KaTeX \u516c\u5f0f\u3001\u666e\u901a\u4ee3\u7801\u5757\u663e\u793a\u9ad8\u4eae\uff09\u3002Release 0.3.0\uff1a\u7f16\u8f91\u5668\u7531 Toast UI WYSIWYG\uff08\u5bcc\u6587\u672c+\u8865\u4e01\uff09\u66f4\u6362\u4e3a Milkdown Crepe\u2014\u2014\u771f\u6b63\u7684\u6240\u89c1\u5373\u6240\u5f97 Markdown \u7f16\u8f91\uff0c\u8f93\u5165\u8bed\u6cd5\u5373\u51fa\u6837\u5f0f\uff08\u542b\u4e2d\u6587\u8f93\u5165\u6cd5\uff09\u3001\u659c\u6760\u83dc\u5355/\u5757\u62d6\u62fd\u624b\u67c4\u3001\u56fe\u7247 data URL \u5185\u5d4c\u3001297 \u79cd\u8bed\u8a00 Prism \u9ad8\u4eae\u3002Release 0.2.0\uff1a\u5b8c\u6574 Markdown \u7b14\u8bb0\u5e94\u7528\uff08React + TypeScript + Tailwind \u91cd\u5199\u9762\u677f\uff09\u3002Release 0.1.0\uff1a\u6a21\u677f\u521d\u59cb\u7248\u672c\u3002", "minPiDesktop": ">=0.1.0", "shasum": "8289ee52d2cb8c1c91f5de3363140c0f8f7023ba420fda2b6649d95c9234cd6b", @@ -706,13 +574,13 @@ "safetyNotes": "Pure styling. The plugin contributes one global theme (CSS only) and a small info panel. No network, file, clipboard, or agent access.", "versions": [ { - "version": "1.0.4", - "publishedAt": "2026-09-12T17:13:25Z", - "changelog": "Release 1.0.4: fix invisible text inside dark user bubbles \u2014 filenames (file chips), image/command chips, text and code links, and inline code/code blocks now render in paper tones on the ink bubble (host 0.14.x class names). Release 1.0.3: add the Theme category tag for marketplace discovery. Release 1.0.2: add README screenshots (chat view and theme picker); force the warm code-block and inline-code palette against the host light-theme cascade (defensive specificity + !important). Release 1.0.1: fix parchment code-block and inline-code overrides against the host light-theme cascade. Release 1.0.0: first release. Warm parchment global theme built on the host design tokens: cream paper background with faint 22px grid, solid ink user bubbles with paper-colored text, soft paper assistant cards, warm code blocks and tables, monospace meta lines, and composer/message width alignment in both sidebar layouts.", + "version": "1.0.3", + "publishedAt": "2026-09-11T18:47:58Z", + "changelog": "Release 1.0.3: add the Theme category tag for marketplace discovery. Release 1.0.2: add README screenshots (chat view and theme picker); force the warm code-block and inline-code palette against the host light-theme cascade (defensive specificity + !important). Release 1.0.1: fix parchment code-block and inline-code overrides against the host light-theme cascade. Release 1.0.0: first release. Warm parchment global theme built on the host design tokens: cream paper background with faint 22px grid, solid ink user bubbles with paper-colored text, soft paper assistant cards, warm code blocks and tables, monospace meta lines, and composer/message width alignment in both sidebar layouts.", "minPiDesktop": ">=0.4.3", - "shasum": "11397e2ff5c7c245e8647c13ac8142bc545d9dd3b7922884f3ebd43aca7d0bb5", - "url": "packages/pi.parchment-1.0.4.piplug", - "sizeBytes": 351052, + "shasum": "52c664f5ce83480b6adbce993b20cd94031d6dd21c99bbacfeff96176bf6bb1a", + "url": "packages/pi.parchment-1.0.3.piplug", + "sizeBytes": 348211, "permissions": [ "ui.panel", "ui.theme" @@ -751,7 +619,7 @@ "versions": [ { "version": "0.3.3", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.3.3\uff1a\u8ba9\u8ba1\u7b97\u533a\u4e0e\u8349\u7a3f\u533a\u94fa\u6ee1\u9762\u677f\u5bbd\u5ea6\uff0c\u6d88\u9664\u5bbd\u7a97\u53e3\u53f3\u4fa7\u56fa\u5b9a\u5bbd\u5ea6\u7a7a\u767d\uff0c\u5e76\u5728\u4e3b\u9898\u53d8\u5316\u540e\u540c\u6b65\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u914d\u8272\u3002Release 0.3.2\uff1a\u8fc1\u79fb\u5230 v3 \u7a7f\u900f\u5f0f\u9876\u90e8 chrome\uff0c\u9876\u90e8\u63a7\u4ef6\u4fdd\u6301\u53ef\u70b9\u51fb\uff0c\u7a7a\u767d\u533a\u57df\u7ee7\u7eed\u53ef\u62d6\u62fd\u3002Release 0.3.1\uff1a\u9002\u914d PI-Desktop \u8de8\u5e73\u53f0 46px \u4e3b\u673a\u62d6\u62fd\u5e26\u548c\u7b80\u7ea6\u4e09\u6309\u94ae\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u3002Release 0.3.0\uff1a\u5916\u89c2\u8ddf\u968f app \u4e3b\u4f53\u2014\u2014\u9ed8\u8ba4\u8ddf\u968f\u5bbf\u4e3b\u4e3b\u9898\uff08app \u5207\u6362 light/dark \u5b9e\u65f6\u66f4\u65b0\uff0c\u65e0\u95ea\u5c4f\uff09\uff0c\u9762\u677f\u5185\u4fdd\u7559\u624b\u52a8\u4eae/\u6697\u5207\u6362\uff08\u8986\u76d6\u540e\u4e0d\u518d\u8ddf\u968f\uff0c\u53ef\u624b\u52a8\u6062\u590d\uff09\uff1b\u53ef\u89c1 chrome \u6587\u6848\uff08\u6807\u9898\u3001\u6309\u94ae\u3001toast\u3001\u5360\u4f4d\u63d0\u793a\u7b49\uff09\u652f\u6301 en/zh \u8ddf\u968f\u5bbf\u4e3b\u8bed\u8a00\u3002Release 0.2.0\uff1a\u91cd\u6784\u4e3a\u591a\u8349\u7a3f\u7a3f\u7eb8\uff08\u5e72\u51c0\u5229\u843d\u7684\u76f4\u89d2\u98ce\u683c\uff09\u2014\u2014\u5de6\u4fa7\u5f53\u524d\u8349\u7a3f\uff1a\u8f93\u5165\u884c\u5b9e\u65f6\u8ba1\u7b97 + \u672c\u7a3f\u5386\u53f2 + \u6bcf\u884c\u53ef\u7f16\u8f91\u5907\u6ce8 + \u6e05\u7a7a/\u590d\u5236\u4e3a\u56fe\u7247\uff1b\u53f3\u4fa7\u8349\u7a3f\u5217\u8868\uff1a\u65f6\u95f4\u547d\u540d\u65b0\u5efa\u3001\u70b9\u51fb\u5207\u6362\u3001\u7ba1\u7406\u6a21\u5f0f\u9010\u6761\u5220\u9664\u3002\u65e7\u7248\u5386\u53f2\u81ea\u52a8\u8fc1\u79fb\u3002", "minPiDesktop": ">=0.1.0", "shasum": "cd7510c2cd7b2271008605f86ce959da7da7e732ec9a8e21a3874d38699e0cb7", @@ -764,52 +632,6 @@ } ] }, - { - "id": "pi.session-orchestrator", - "name": "Session Orchestrator", - "description": "Coordinate durable PI-Desktop sessions with bidirectional messages, host-owned completion notifications, reliable results, and configured model selection.", - "i18n": { - "en": { - "name": "Session Orchestrator", - "description": "Create bounded sessions, discover existing Agent sessions, send messages in either direction using real Session IDs, receive automatic completion notifications, and inspect host-owned status and results.", - "safetyNotes": "This high-risk tool can create sessions, read session collaboration summaries and results, send messages that run the target Agent, and cancel collaboration work through desktop.control. Messages can address any existing Session ID and may consume configured model quota. The host binds the sender, preserves existing target configuration and permissions, labels session messages separately from user input, and bounds autonomous creation and callbacks. Plugin history never grants access. The plugin has no network permission and never deletes sessions or reads credentials." - }, - "zh-CN": { - "name": "Session Orchestrator \u4f1a\u8bdd\u7f16\u6392\u5668", - "description": "\u4f7f\u7528\u771f\u5b9e Session ID \u53d1\u73b0\u5e76\u901a\u4fe1\u72ec\u7acb Agent \u4f1a\u8bdd\uff0c\u521b\u5efa\u6709\u754c Worker\u3001\u53cc\u5411\u53d1\u9001\u4f1a\u8bdd\u6d88\u606f\uff0c\u81ea\u52a8\u63a5\u6536\u5b8c\u6210\u901a\u77e5\uff0c\u5e76\u67e5\u8be2\u5bbf\u4e3b\u8bb0\u5f55\u7684\u72b6\u6001\u548c\u6267\u884c\u7ed3\u679c\u3002", - "safetyNotes": "\u8fd9\u662f\u4e00\u4e2a\u9ad8\u98ce\u9669\u5de5\u5177\uff0c\u4f1a\u901a\u8fc7 desktop.control \u521b\u5efa\u4f1a\u8bdd\u3001\u8bfb\u53d6\u534f\u4f5c\u6458\u8981\u548c\u7ed3\u679c\u3001\u53d1\u9001\u6d88\u606f\u542f\u52a8\u76ee\u6807 Agent\uff0c\u4ee5\u53ca\u53d6\u6d88\u534f\u4f5c\u4efb\u52a1\u3002\u6d88\u606f\u53ef\u4ee5\u53d1\u7ed9\u4efb\u610f\u5df2\u5b58\u5728\u7684 Session ID\uff0c\u5e76\u53ef\u80fd\u6d88\u8017\u5df2\u914d\u7f6e\u6a21\u578b\u7684\u8c03\u7528\u989d\u5ea6\u3002\u5bbf\u4e3b\u7ed1\u5b9a\u771f\u5b9e\u53d1\u9001\u8005\u3001\u4fdd\u7559\u5df2\u6709\u76ee\u6807\u4f1a\u8bdd\u7684\u914d\u7f6e\u548c\u6743\u9650\u3001\u5c06\u4f1a\u8bdd\u6d88\u606f\u4e0e\u7528\u6237\u8f93\u5165\u533a\u5206\uff0c\u5e76\u9650\u5236\u81ea\u4e3b\u521b\u5efa\u548c\u81ea\u52a8\u56de\u8c03\u3002\u63d2\u4ef6\u5386\u53f2\u8bb0\u5f55\u4e0d\u6388\u4e88\u8bbf\u95ee\u6743\u9650\u3002\u63d2\u4ef6\u6ca1\u6709\u7f51\u7edc\u6743\u9650\uff0c\u4e0d\u5220\u9664\u4f1a\u8bdd\uff0c\u4e5f\u4e0d\u8bfb\u53d6\u51ed\u636e\u3002" - } - }, - "author": "PI-Desktop", - "categories": [ - "developer-tools", - "official" - ], - "verified": true, - "downloads": 0, - "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/pi.session-orchestrator", - "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# Session Orchestrator\n\nSession Orchestrator coordinates real PI-Desktop sessions through one\nhigh-risk Agent tool, `SessionTask`. Every session is addressed by its existing\ndurable `sessionId`; follow-up messages keep that session's context and model.\nThe host owns delivery, queue admission, execution state, results, and completion\nnotifications. The plugin does not infer success from assistant text.\n\n## A normal workflow\n\n1. Call `models` to inspect the user's ready configured models when a task needs\n a particular model. Then `spawn(task, title?, model?)` to create a worker.\n Keep the returned `sessionId` and delivery `messageId`.\n2. Work in parallel. By default the host sends a completion message back to the\n sending session when the target turn settles; repeated polling is unnecessary.\n3. Use `send(sessionId, message)` for follow-up work in the same session, or to\n communicate with any other existing session. Workers can reply to their\n initiating session and peers by their real Session IDs.\n4. Inspect `status` or `result` when needed. Pass `messageId` or `turnId` to\n retrieve one specific delivery instead of whichever message is latest.\n5. Review the actual result. `accept` optionally records that review for the\n exact completed message. `cancel` stops collaboration work and retains the\n durable session and history.\n\nA received message is explicitly identified as another session's communication,\nnot human input or new user authorization. Completion notices need no\nacknowledgement unless further work is necessary. Use\n`notifyOnCompletion: false` for informational messages to avoid unnecessary\nreturn messages. Host-generated completion notices never request another\nautomatic completion notice.\n\n## Actions\n\n| Action | Behavior |\n| --- | --- |\n| `spawn(task, title?, model?)` | Atomically creates a real worker and admits its first delivery through the host. |\n| `send(sessionId, message, kind?)` | Sends a task or message to an existing session, including a busy session's host queue. Does not reselect its model. |\n| `models()` | Lists ready model keys, aliases, reasoning metadata, AI-delegation eligibility, and the default. |\n| `status(sessionIds?)` | Reads host-owned live summaries; omission selects this caller's recent session references. |\n| `list()` | Reads a bounded host-backed directory of communicable Agent sessions, including independent top-level sessions. The response also retains a legacy `workers` field for recent-reference callers. |\n| `result(sessionId, messageId?, turnId?)` | Returns the host delivery and exact turn outcome. Failed or interrupted work is never accepted as a successful report. |\n| `wait(sessionIds, timeoutMs?)` | Explicit polling fallback, 25 seconds by default and at most 45 seconds. The entire read budget observes the deadline and cancellation. |\n| `supervise(sessionIds, message)` | Sends up to four follow-ups in parallel; returns successful receipts and any individual failures. |\n| `accept(sessionId|sessionIds, messageId?, note?)` | Stores review metadata keyed by the exact completed delivery. It never changes host execution state. |\n| `cancel(sessionId, messageId?)` | Cancels target collaboration work without deleting the session. |\n\n`result.ready` means the delivery has settled, including failure, cancellation,\nor interruption. Successful work requires `message.status === \"completed\"`;\nthe compatibility `worker.report` field is populated only for that outcome.\n\n`spawn` and `send` accept `notifyOnCompletion` (default true) and an optional\n`idempotencyKey` for retrying the same request. Use a different key for a new\nrequest. For batch supervision requiring retry identities, call `send` separately\nwith one key per target. Session identity and delivery identity have separate\npurposes: `messageId` names a ledger entry, not a second worker system.\n\n## Model selection\n\nAn omitted `model` first selects from ready bindings with\n`availableForSubagents: true`. A default within that set takes precedence;\notherwise the first configured eligible row provides a stable selection.\nOnly when that set is empty does the configured ready default apply. An empty\ncatalog or unavailable default produces a clear configuration error.\n\nThe spawn response records `requestedModel` and its selection policy; the\nactual session model is read from `status.modelKey`, including after an\nidempotent retry.\n\nAn explicit request resolves against existing model keys, IDs, aliases and\nnames. Matching handles case, spacing, punctuation, common English/Chinese\nfamily names, and supported reasoning/non-reasoning intent. Numeric version\norder is preserved. Multiple matches return bounded exact-key candidates;\nno match is an error. The plugin never invents a model ID or silently chooses\nan unrelated default. It does not rank model quality or cost from brand names;\nthe Parent can use `models` and the task requirements to make that decision.\n\nExisting-session `send` never changes provider, model, project, context, or\npermissions. New-session project and permission inheritance, effective thinking\nconfiguration, active-worker limits (four per creator, sixteen per plugin), and\nthe restriction on workers autonomously creating further workers are enforced\nby the host, using durable creation provenance.\n\n## State and recovery\n\nPI-Desktop's durable session communication ledger is authoritative. Status,\ncurrent task, sender, recent exchanges, and final outcome come directly from it.\nA callback is tied to the actual settled turn, retained on failure, and generated\nat most once. Restart follows the host's existing interruption fence; the\nplugin does not replay messages or start replacements during load.\n\nPrivate plugin settings retain at most 256 recent session references and 256\nmessage review notes. They contain no cached transcript, report, or execution\nstate. Reference eviction affects only recent-history discovery, never the\nability to address a known Session ID or the host's creation limits. Successful\nhost receipts remain available to the caller if optional history persistence\nfails; the response includes a warning.\n\nVersion 0.3 `workerSessionId`/`sessionId` records migrate to recent references.\nOld cached statuses, reports, rounds and acceptance markers are retired because\nthey cannot prove a host delivery's outcome. Existing sessions are preserved.\nLegacy `workerId`/`workerIds` arguments remain supported aliases; conflicting\naliases are rejected. Unloading cancels plugin reads and waits, unregisters the\ntool and command, and flushes metadata. Host-owned work and callbacks remain\nowned by the host.\n\n## Agents panel\n\nThe panel shows recent Session IDs, host status, creation/task source, and\nbounded recent exchanges. Open Session navigates explicitly; Stop calls the\nreviewed collaboration cancellation operation. Background refresh reads only\nbounded summaries every five seconds while the panel is visible. One missing\nor inaccessible session does not hide other references. Labels and previews\nare escaped before rendering, and asynchronous actions cannot be submitted\ntwice while pending.\n\n## Host compatibility and security\n\nThe manifest retains `engines.piDesktop >=0.14.7`, but version alone does not\nprove this additive capability exists. Each operation checks the host's reviewed\ncatalog for `session/collaboration/{spawn,send,list,status,result,cancel}`. An older\nhost receives an explicit update-required error; the plugin never falls back\nto untracked create/prompt calls or transcript inference. `session/open` is\nchecked independently.\n\n| Capability | Data and boundary |\n| --- | --- |\n| `desktop.control` | Creates sessions, exchanges messages, reads collaboration summaries/results, cancels work, and explicitly opens sessions. The host binds the sender to the current Agent tool invocation, enforces permissions and bounded creation, and labels provenance. Messages can consume configured model quota. |\n| `models.list` | Reads ready configured model identifiers, aliases, delegation flags and reasoning metadata; no credentials. |\n| `ui.panel` | Displays bounded summaries through the isolated plugin bridge; local Stop/Open actions remain host-authorized. |\n| Plugin settings | Stores only bounded recent references and review notes keyed by delivery identity. Never grants access or represents execution truth. |\n\nThe high-risk grant allows bidirectional communication with any existing\nsession. Message content is task data and cannot grant new permissions. The\nplugin has no direct network permission, never reads credentials or MCP tokens,\nnever executes downloaded code, and never deletes sessions. Host provider\nrequests continue to use the user's configured model and normal policy.\n", - "safetyNotes": "This high-risk tool can create sessions, read session collaboration summaries and results, send messages that run the target Agent, and cancel collaboration work through desktop.control. Messages can address any existing Session ID and may consume configured model quota. The host binds the sender, preserves existing target configuration and permissions, labels session messages separately from user input, and bounds autonomous creation and callbacks. Plugin history never grants access. The plugin has no network permission and never deletes sessions or reads credentials.", - "versions": [ - { - "version": "0.5.0", - "publishedAt": "2026-09-13T13:55:42Z", - "changelog": "Release 0.5.0: discovers existing independent Agent sessions through the host-backed list action while retaining legacy worker references and bidirectional messaging.\nRelease 0.4.0: moves delivery, completion callbacks and turn-bound results to the host; enables bidirectional messaging by real Session ID; resolves configured models by key, alias, family or reasoning intent; retains recent references without using them as authorization; fixes panel Stop and cancellable wait deadlines.", - "minPiDesktop": ">=0.14.7", - "shasum": "bd9fcf67ad5b3eff46e5ec20580cd1c6fd62c1e660f47efbadc4fd9311a7a504", - "url": "packages/pi.session-orchestrator-0.5.0.piplug", - "sizeBytes": 81273, - "permissions": [ - "ui.panel", - "agent.tool.register", - "desktop.control", - "models.list" - ], - "fs": {} - } - ] - }, { "id": "pi.ssh-manager", "name": "SSH Manager", @@ -835,17 +657,17 @@ "downloads": 0, "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/pi.ssh-manager", "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# SSH \u5728\u7ebf\u7ba1\u7406 \u00b7 SSH Manager\n\n`pi.ssh-manager` \u662f\u4e00\u4e2a\u672c\u5730\u4f18\u5148\u7684 SSH \u4e3b\u673a\u7ba1\u7406\u63d2\u4ef6\uff1a\u9762\u677f\u4fdd\u5b58\u4e3b\u673a\u8fde\u63a5\u5143\u6570\u636e\uff0c\n\u8ba4\u8bc1\u4ea4\u7ed9\u672c\u673a OpenSSH\u3001\u5df2\u6709\u7684 `~/.ssh/config`\u3001ssh-agent\u3001\u7528\u6237\u6307\u5b9a\u7684\u79c1\u94a5\u8def\u5f84\uff0c\u6216\u9762\u677f\u4e2d\n\u4e34\u65f6\u8f93\u5165\u7684\u5bc6\u7801\u3002\u6dfb\u52a0\u6216\u7f16\u8f91\u4e3b\u673a\u65f6\uff0c\u79c1\u94a5\u53ef\u4ee5\u624b\u52a8\u8f93\u5165\u8def\u5f84\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u300c\u9009\u62e9\u6587\u4ef6\u300d\uff1b\u63d2\u4ef6\u53ea\n\u4f7f\u7528 Electron \u63d0\u4f9b\u7684\u6587\u4ef6\u8def\u5f84\uff0c\u4ece\u4e0d\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002\n\u63d2\u4ef6\u628a\u6709\u9650\u65f6\u3001\u6709\u9650\u8f93\u51fa\u7684 SSH \u80fd\u529b\u63d0\u4f9b\u7ed9 PI-Desktop AI\u3002\n\n## \u80fd\u505a\u4ec0\u4e48\n\n- \u7ba1\u7406\u591a\u53f0 SSH \u4e3b\u673a\uff1a\u540d\u79f0\u3001\u4e3b\u673a\u3001\u7aef\u53e3\u3001\u7528\u6237\u540d\u3001\u79c1\u94a5\u8def\u5f84\u548c agent socket\u3002\n- \u4e00\u952e\u626b\u63cf\u5e76\u5bfc\u5165\u672c\u673a `~/.ssh/config`\uff08\u542b\u6709\u754c\u7684 `Include`\uff09\uff0c\u4fdd\u7559 Host \u522b\u540d\u4ee5\u7ee7\u7eed\u4f7f\u7528\u5b8c\u6574 OpenSSH \u914d\u7f6e\uff08\u5305\u62ec ProxyJump\uff09\u3002\u91cd\u590d\u626b\u63cf\u4f1a\u66f4\u65b0\u5df2\u6709\u5bfc\u5165\u9879\uff0c\u4e0d\u4f1a\u91cd\u590d\u521b\u5efa\u3002\u8fde\u63a5\u5931\u8d25\u4f1a\u4fdd\u7559 OpenSSH \u7684\u4f20\u8f93\u8bca\u65ad\uff08\u5305\u62ec Windows \u7684 banner exchange / connection refused\uff09\uff0c\u800c\u4e0d\u662f\u53ea\u663e\u793a\u7b3c\u7edf\u7684 exit 255\uff1bWindows \u4f1a\u7ee7\u627f SYSTEMROOT \u7b49\u7cfb\u7edf\u73af\u5883\u5e76\u67e5\u627e `ssh.exe`\u3002\n- \u5bfc\u5165\u81ea\u5b9a\u4e49\u914d\u7f6e\u6587\u4ef6\u65f6\u4f1a\u5728\u8fde\u63a5\u4e2d\u7ee7\u7eed\u4f7f\u7528\u8be5\u914d\u7f6e\u6587\u4ef6\uff1b\u7f16\u8f91\u5bfc\u5165\u4e3b\u673a\u7684\u5730\u5740\u3001\u7aef\u53e3\u3001\u7528\u6237\u540d\u6216\u5bc6\u94a5\u8def\u5f84\u540e\uff0c\u63d2\u4ef6\u4f1a\u81ea\u52a8\u89e3\u9664\u522b\u540d\u7ed1\u5b9a\u5e76\u6309\u8868\u5355\u4e2d\u7684\u663e\u5f0f\u503c\u8fde\u63a5\u3002\n- \u9ed8\u8ba4 `~/.ssh/config` \u4ecd\u6309\u666e\u901a OpenSSH \u65b9\u5f0f\u52a0\u8f7d\uff0c\u56e0\u6b64\u4e0d\u4f1a\u56e0\u663e\u5f0f `-F` \u800c\u8df3\u8fc7\u7cfb\u7edf\u7ea7 SSH \u914d\u7f6e\uff1bWindows \u5bc6\u7801 helper \u4e0d\u7ecf\u8fc7\u6279\u5904\u7406\u53d8\u91cf\u5c55\u5f00\uff0c\u5bc6\u7801\u4e2d\u7684\u547d\u4ee4\u7b26\u53f7\u4f1a\u539f\u6837\u4ea4\u7ed9 OpenSSH\u3002\n- \u9ed8\u8ba4\u4e25\u683c\u6821\u9a8c `known_hosts`\uff1b\u53ea\u6709\u7528\u6237\u663e\u5f0f\u9009\u62e9\u65f6\u624d\u4f7f\u7528 `accept-new`\u3002\n- \u5728\u9762\u677f\u4e2d\u6d4b\u8bd5\u8fde\u63a5\u3001\u6267\u884c\u4e00\u6b21\u6027\u547d\u4ee4\u3001\u67e5\u770b stdout/stderr\uff0c\u5e76\u5fd8\u8bb0\u903b\u8f91\u4f1a\u8bdd\u3002\n- \u5411 AI \u66b4\u9732\u56db\u4e2a\u5de5\u5177\uff1a\n - `plugin_pi_ssh_manager_ssh_list_hosts`\n - `plugin_pi_ssh_manager_ssh_connect`\n - `plugin_pi_ssh_manager_ssh_execute`\n - `plugin_pi_ssh_manager_ssh_disconnect`\n- \u9ed8\u8ba4\u53ea\u653e\u884c\u7ecf\u8fc7\u9759\u6001\u6821\u9a8c\u7684\u547d\u4ee4\uff1b\u9012\u5f52\u5220\u9664\u3001\u6587\u4ef6\u8986\u76d6\u3001\u78c1\u76d8\u5199\u5165\u3001\u6570\u636e\u5e93\u53d8\u66f4\u3001\u670d\u52a1/\u6743\u9650\u4fee\u6539\u3001\u5bb9\u5668\u5220\u9664\u3001\u91cd\u542f\u3001\u7f51\u7edc\u811a\u672c\u7ba1\u9053\u4ee5\u53ca shell \u94fe\u5f0f\u547d\u4ee4\u90fd\u4f1a\u88ab\u62e6\u622a\u3002\n- \u88ab\u62e6\u622a\u7684\u547d\u4ee4\u53ea\u6709\u5728 SSH \u7ba1\u7406\u9762\u677f\u52fe\u9009\u300c\u672c\u6b21\u5141\u8bb8\u6267\u884c\u88ab\u62e6\u622a\u7684\u5371\u9669\u6307\u4ee4\u300d\u540e\u624d\u4f1a\u653e\u884c\u4e00\u6b21\uff1bAI \u5de5\u5177\u4e0d\u80fd\u4f20\u5165\u6216\u4f2a\u9020\u8fd9\u4e2a\u6388\u6743\u3002\n\n## \u8ba4\u8bc1\u4e0e\u6570\u636e\u8fb9\u754c\n\n\u63d2\u4ef6\u4e0d\u4f1a\u6301\u4e45\u5316\u5bc6\u7801\u3001passphrase\u3001\u79c1\u94a5\u5185\u5bb9\u3001\u547d\u4ee4\u8f93\u51fa\u6216\u8fdc\u7a0b transcript\u3002\u9700\u8981\u5bc6\u7801\n\u8ba4\u8bc1\u65f6\uff0c\u53ef\u4ee5\u5728\u9762\u677f\u7684\u300c\u5bc6\u7801\uff08\u4e0d\u4fdd\u5b58\uff09\u300d\u8f93\u5165\u6846\u4e2d\u5f55\u5165\uff1b\u5bc6\u7801\u53ea\u5728\u5f53\u524d\u63d2\u4ef6\u8fdb\u7a0b\u5185\u4fdd\u5b58\n\u6700\u591a 30 \u5206\u949f\uff0c\u901a\u8fc7\u4e00\u6b21\u6027\u672c\u5730 IPC broker \u548c `SSH_ASKPASS` helper \u4ea4\u7ed9 OpenSSH\uff1b\u5bc6\u7801\u4e0d\u4f1a\u8fdb\u5165 `ssh` \u8fdb\u7a0b\u73af\u5883\uff0c\u907f\u514d\u88ab\u5bbd\u6cdb\u7684 `SendEnv` \u914d\u7f6e\u53d1\u9001\u5230\u8fdc\u7aef\u3002\u63d2\u4ef6\u91cd\u542f\u3001\u5378\u8f7d\u6216\n\u8d85\u65f6\u540e\u4f1a\u81ea\u52a8\u6e05\u9664\u3002AI \u5de5\u5177\u6c38\u8fdc\u4e0d\u4f1a\u63a5\u6536\u5bc6\u7801\u53c2\u6570\uff0c\u4f46\u53ef\u4ee5\u590d\u7528\u5f53\u524d\u5185\u5b58\u4e2d\u7684\u5bc6\u7801\u72b6\u6001\u3002\n\u8bf7\u4f18\u5148\u5728\u672c\u673a\u914d\u7f6e OpenSSH\uff1a\n\n```sshconfig\nHost production\n HostName server.example.com\n User deploy\n IdentityFile ~/.ssh/id_ed25519\n```\n\n\u7136\u540e\u5728\u9762\u677f\u4e2d\u628a `Host` \u586b\u4e3a `production`\uff0c\u6216\u76f4\u63a5\u586b\u5199\u5b9e\u9645\u4e3b\u673a\u540d\u3002\u9700\u8981\u4f7f\u7528\nssh-agent \u65f6\uff0c\u4f18\u5148\u8ba9 PI-Desktop \u7ee7\u627f\u6b63\u786e\u7684 `SSH_AUTH_SOCK`\uff0c\u4e5f\u53ef\u4ee5\u5728\u4e3b\u673a\u914d\u7f6e\u4e2d\n\u586b\u5199 agent socket \u8def\u5f84\u3002\u5e26 passphrase \u7684\u5bc6\u94a5\u5e94\u7531 ssh-agent \u6216\u7cfb\u7edf OpenSSH \u914d\u7f6e\n\u8d1f\u8d23\u89e3\u9501\uff1b\u63d2\u4ef6\u4e0d\u4f1a\u628a\u5b83\u4eec\u5199\u5165\u8bbe\u7f6e\u3002\n\n\u201c\u8fde\u63a5\u201d\u521b\u5efa\u7684\u662f\u63d2\u4ef6\u5185\u7684\u903b\u8f91\u4f1a\u8bdd\u3002\u6bcf\u6b21\u547d\u4ee4\u4ecd\u542f\u52a8\u4e00\u4e2a\u6709\u8d85\u65f6\u548c\u8f93\u51fa\u4e0a\u9650\u3001\u4e0d\u4f1a\u7ee7\u627f\u63d2\u4ef6\u6807\u51c6\u8f93\u5165\u7684\u672c\u673a\n`ssh` \u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u5728\u63d2\u4ef6\u8fdb\u7a0b\u91cc\u4fdd\u7559\u4e00\u4e2a\u53ef\u88ab\u540e\u53f0\u590d\u7528\u7684\u8fdc\u7a0b shell\u3002\n\n## Windows OpenSSH startup\n\nPI-Desktop passes a minimal environment to plugins. Windows OpenSSH requires\n`ProgramData` even for `ssh -V`; without it, it can exit 255 with no output before\nconnection diagnostics are initialized. The plugin preserves an inherited\n`ProgramData` (case-insensitive) or `ALLUSERSPROFILE`, and otherwise supplies\n`ProgramData` on the Windows system volume (normally `C:\\ProgramData`). It does\nnot copy unrelated environment variables or change host-key verification.\n\n## AI \u4f7f\u7528\u5efa\u8bae\n\nAI \u5e94\u5148\u8c03\u7528 `ssh_list_hosts`\uff0c\u518d\u4f7f\u7528\u7528\u6237\u786e\u8ba4\u8fc7\u7684 `profile_id` \u8fde\u63a5\u3002\u8fde\u63a5\u548c\u6267\u884c\n\u5747\u662f\u9ad8\u98ce\u9669\u5de5\u5177\uff0c\u4f1a\u7ecf\u8fc7 PI-Desktop \u7684\u5de5\u5177\u6743\u9650\u7b56\u7565\u3002AI \u4e0d\u5e94\u8981\u6c42\u7528\u6237\u628a\u5bc6\u7801\u3001\u79c1\u94a5\n\u6216 token \u7c98\u8d34\u5230\u5bf9\u8bdd\u4e2d\uff1b\u65b0\u4e3b\u673a\u5bc6\u94a5\u548c\u7834\u574f\u6027\u547d\u4ee4\u5fc5\u987b\u5148\u5411\u7528\u6237\u786e\u8ba4\u3002\u82e5\u547d\u4ee4\u88ab\u5b89\u5168\u8fc7\u6ee4\u5668\n\u62e6\u622a\uff0cAI \u53ea\u80fd\u63d0\u793a\u7528\u6237\u5728 SSH \u7ba1\u7406\u9762\u677f\u4e2d\u5ba1\u6838\u5e76\u52fe\u9009\u4e00\u6b21\u6027\u6388\u6743\uff0c\u4e0d\u80fd\u81ea\u884c\u7ed5\u8fc7\u8fc7\u6ee4\u5668\u3002\n\n## \u6743\u9650\n\n- `ui.panel`\uff1a\u6253\u5f00 SSH \u7ba1\u7406\u9762\u677f\u3002\n- `agent.tool.register`\uff1a\u6ce8\u518c AI SSH \u5de5\u5177\u3002\n- `agent.prompt.inject`\uff1a\u52a0\u8f7d\u5b89\u5168 SSH \u4f7f\u7528\u8bf4\u660e\u3002\n\n\u63d2\u4ef6\u53ea\u4f7f\u7528\u672c\u673a `ssh` \u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4e0d\u4f7f\u7528 `net.fetch`\uff0c\u4e5f\u4e0d\u628a\u51ed\u636e\u5199\u5165\u63d2\u4ef6\u8bbe\u7f6e\u3002\n\n## \u5f00\u53d1\u9a8c\u8bc1\n\n```bash\nnode --test tests/ssh-manager.test.mjs\npython3 scripts/pack_plugin.py plugins/pi.ssh-manager\npython3 scripts/rebuild_catalog.py\n```\n\n\u672c\u5730\u8fd0\u884c\u65f6\u8bf7\u5728 PI-Desktop \u4e2d\u9009\u62e9\u300c\u63d2\u4ef6 \u2192 \u52a0\u8f7d\u5f00\u53d1\u63d2\u4ef6\u300d\uff0c\u518d\u9009\u62e9\u672c\u76ee\u5f55\u3002\n", + "readmeMarkdown": "# SSH \u5728\u7ebf\u7ba1\u7406 \u00b7 SSH Manager\n\n`pi.ssh-manager` \u662f\u4e00\u4e2a\u672c\u5730\u4f18\u5148\u7684 SSH \u4e3b\u673a\u7ba1\u7406\u63d2\u4ef6\uff1a\u9762\u677f\u4fdd\u5b58\u4e3b\u673a\u8fde\u63a5\u5143\u6570\u636e\uff0c\n\u8ba4\u8bc1\u4ea4\u7ed9\u672c\u673a OpenSSH\u3001\u5df2\u6709\u7684 `~/.ssh/config`\u3001ssh-agent\u3001\u7528\u6237\u6307\u5b9a\u7684\u79c1\u94a5\u8def\u5f84\uff0c\u6216\u9762\u677f\u4e2d\n\u4e34\u65f6\u8f93\u5165\u7684\u5bc6\u7801\u3002\u6dfb\u52a0\u6216\u7f16\u8f91\u4e3b\u673a\u65f6\uff0c\u79c1\u94a5\u53ef\u4ee5\u624b\u52a8\u8f93\u5165\u8def\u5f84\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u300c\u9009\u62e9\u6587\u4ef6\u300d\uff1b\u63d2\u4ef6\u53ea\n\u4f7f\u7528 Electron \u63d0\u4f9b\u7684\u6587\u4ef6\u8def\u5f84\uff0c\u4ece\u4e0d\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002\n\u63d2\u4ef6\u628a\u6709\u9650\u65f6\u3001\u6709\u9650\u8f93\u51fa\u7684 SSH \u80fd\u529b\u63d0\u4f9b\u7ed9 PI-Desktop AI\u3002\n\n## \u80fd\u505a\u4ec0\u4e48\n\n- \u7ba1\u7406\u591a\u53f0 SSH \u4e3b\u673a\uff1a\u540d\u79f0\u3001\u4e3b\u673a\u3001\u7aef\u53e3\u3001\u7528\u6237\u540d\u3001\u79c1\u94a5\u8def\u5f84\u548c agent socket\u3002\n- \u4e00\u952e\u626b\u63cf\u5e76\u5bfc\u5165\u672c\u673a `~/.ssh/config`\uff08\u542b\u6709\u754c\u7684 `Include`\uff09\uff0c\u4fdd\u7559 Host \u522b\u540d\u4ee5\u7ee7\u7eed\u4f7f\u7528\u5b8c\u6574 OpenSSH \u914d\u7f6e\uff08\u5305\u62ec ProxyJump\uff09\u3002\u91cd\u590d\u626b\u63cf\u4f1a\u66f4\u65b0\u5df2\u6709\u5bfc\u5165\u9879\uff0c\u4e0d\u4f1a\u91cd\u590d\u521b\u5efa\u3002\u8fde\u63a5\u5931\u8d25\u4f1a\u5c55\u793a OpenSSH \u8bca\u65ad\u800c\u4e0d\u662f\u7b3c\u7edf\u7684 exit 255\uff1bWindows \u4f1a\u7ee7\u627f SYSTEMROOT \u7b49\u7cfb\u7edf\u73af\u5883\u5e76\u67e5\u627e `ssh.exe`\u3002\n- \u9ed8\u8ba4\u4e25\u683c\u6821\u9a8c `known_hosts`\uff1b\u53ea\u6709\u7528\u6237\u663e\u5f0f\u9009\u62e9\u65f6\u624d\u4f7f\u7528 `accept-new`\u3002\n- \u5728\u9762\u677f\u4e2d\u6d4b\u8bd5\u8fde\u63a5\u3001\u6267\u884c\u4e00\u6b21\u6027\u547d\u4ee4\u3001\u67e5\u770b stdout/stderr\uff0c\u5e76\u5fd8\u8bb0\u903b\u8f91\u4f1a\u8bdd\u3002\n- \u5411 AI \u66b4\u9732\u56db\u4e2a\u5de5\u5177\uff1a\n - `plugin_pi_ssh_manager_ssh_list_hosts`\n - `plugin_pi_ssh_manager_ssh_connect`\n - `plugin_pi_ssh_manager_ssh_execute`\n - `plugin_pi_ssh_manager_ssh_disconnect`\n- \u9ed8\u8ba4\u53ea\u653e\u884c\u7ecf\u8fc7\u9759\u6001\u6821\u9a8c\u7684\u547d\u4ee4\uff1b\u9012\u5f52\u5220\u9664\u3001\u6587\u4ef6\u8986\u76d6\u3001\u78c1\u76d8\u5199\u5165\u3001\u6570\u636e\u5e93\u53d8\u66f4\u3001\u670d\u52a1/\u6743\u9650\u4fee\u6539\u3001\u5bb9\u5668\u5220\u9664\u3001\u91cd\u542f\u3001\u7f51\u7edc\u811a\u672c\u7ba1\u9053\u4ee5\u53ca shell \u94fe\u5f0f\u547d\u4ee4\u90fd\u4f1a\u88ab\u62e6\u622a\u3002\n- \u88ab\u62e6\u622a\u7684\u547d\u4ee4\u53ea\u6709\u5728 SSH \u7ba1\u7406\u9762\u677f\u52fe\u9009\u300c\u672c\u6b21\u5141\u8bb8\u6267\u884c\u88ab\u62e6\u622a\u7684\u5371\u9669\u6307\u4ee4\u300d\u540e\u624d\u4f1a\u653e\u884c\u4e00\u6b21\uff1bAI \u5de5\u5177\u4e0d\u80fd\u4f20\u5165\u6216\u4f2a\u9020\u8fd9\u4e2a\u6388\u6743\u3002\n\n## \u8ba4\u8bc1\u4e0e\u6570\u636e\u8fb9\u754c\n\n\u63d2\u4ef6\u4e0d\u4f1a\u6301\u4e45\u5316\u5bc6\u7801\u3001passphrase\u3001\u79c1\u94a5\u5185\u5bb9\u3001\u547d\u4ee4\u8f93\u51fa\u6216\u8fdc\u7a0b transcript\u3002\u9700\u8981\u5bc6\u7801\n\u8ba4\u8bc1\u65f6\uff0c\u53ef\u4ee5\u5728\u9762\u677f\u7684\u300c\u5bc6\u7801\uff08\u4e0d\u4fdd\u5b58\uff09\u300d\u8f93\u5165\u6846\u4e2d\u5f55\u5165\uff1b\u5bc6\u7801\u53ea\u5728\u5f53\u524d\u63d2\u4ef6\u8fdb\u7a0b\u5185\u4fdd\u5b58\n\u6700\u591a 30 \u5206\u949f\uff0c\u901a\u8fc7\u4e00\u6b21\u6027 `SSH_ASKPASS` helper \u4ea4\u7ed9 OpenSSH\uff0c\u63d2\u4ef6\u91cd\u542f\u3001\u5378\u8f7d\u6216\n\u8d85\u65f6\u540e\u4f1a\u81ea\u52a8\u6e05\u9664\u3002AI \u5de5\u5177\u6c38\u8fdc\u4e0d\u4f1a\u63a5\u6536\u5bc6\u7801\u53c2\u6570\uff0c\u4f46\u53ef\u4ee5\u590d\u7528\u5f53\u524d\u5185\u5b58\u4e2d\u7684\u5bc6\u7801\u72b6\u6001\u3002\n\u8bf7\u4f18\u5148\u5728\u672c\u673a\u914d\u7f6e OpenSSH\uff1a\n\n```sshconfig\nHost production\n HostName server.example.com\n User deploy\n IdentityFile ~/.ssh/id_ed25519\n```\n\n\u7136\u540e\u5728\u9762\u677f\u4e2d\u628a `Host` \u586b\u4e3a `production`\uff0c\u6216\u76f4\u63a5\u586b\u5199\u5b9e\u9645\u4e3b\u673a\u540d\u3002\u9700\u8981\u4f7f\u7528\nssh-agent \u65f6\uff0c\u4f18\u5148\u8ba9 PI-Desktop \u7ee7\u627f\u6b63\u786e\u7684 `SSH_AUTH_SOCK`\uff0c\u4e5f\u53ef\u4ee5\u5728\u4e3b\u673a\u914d\u7f6e\u4e2d\n\u586b\u5199 agent socket \u8def\u5f84\u3002\u5e26 passphrase \u7684\u5bc6\u94a5\u5e94\u7531 ssh-agent \u6216\u7cfb\u7edf OpenSSH \u914d\u7f6e\n\u8d1f\u8d23\u89e3\u9501\uff1b\u63d2\u4ef6\u4e0d\u4f1a\u628a\u5b83\u4eec\u5199\u5165\u8bbe\u7f6e\u3002\n\n\u201c\u8fde\u63a5\u201d\u521b\u5efa\u7684\u662f\u63d2\u4ef6\u5185\u7684\u903b\u8f91\u4f1a\u8bdd\u3002\u6bcf\u6b21\u547d\u4ee4\u4ecd\u542f\u52a8\u4e00\u4e2a\u6709\u8d85\u65f6\u548c\u8f93\u51fa\u4e0a\u9650\u7684\u672c\u673a\n`ssh` \u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u5728\u63d2\u4ef6\u8fdb\u7a0b\u91cc\u4fdd\u7559\u4e00\u4e2a\u53ef\u88ab\u540e\u53f0\u590d\u7528\u7684\u8fdc\u7a0b shell\u3002\n\n## AI \u4f7f\u7528\u5efa\u8bae\n\nAI \u5e94\u5148\u8c03\u7528 `ssh_list_hosts`\uff0c\u518d\u4f7f\u7528\u7528\u6237\u786e\u8ba4\u8fc7\u7684 `profile_id` \u8fde\u63a5\u3002\u8fde\u63a5\u548c\u6267\u884c\n\u5747\u662f\u9ad8\u98ce\u9669\u5de5\u5177\uff0c\u4f1a\u7ecf\u8fc7 PI-Desktop \u7684\u5de5\u5177\u6743\u9650\u7b56\u7565\u3002AI \u4e0d\u5e94\u8981\u6c42\u7528\u6237\u628a\u5bc6\u7801\u3001\u79c1\u94a5\n\u6216 token \u7c98\u8d34\u5230\u5bf9\u8bdd\u4e2d\uff1b\u65b0\u4e3b\u673a\u5bc6\u94a5\u548c\u7834\u574f\u6027\u547d\u4ee4\u5fc5\u987b\u5148\u5411\u7528\u6237\u786e\u8ba4\u3002\u82e5\u547d\u4ee4\u88ab\u5b89\u5168\u8fc7\u6ee4\u5668\n\u62e6\u622a\uff0cAI \u53ea\u80fd\u63d0\u793a\u7528\u6237\u5728 SSH \u7ba1\u7406\u9762\u677f\u4e2d\u5ba1\u6838\u5e76\u52fe\u9009\u4e00\u6b21\u6027\u6388\u6743\uff0c\u4e0d\u80fd\u81ea\u884c\u7ed5\u8fc7\u8fc7\u6ee4\u5668\u3002\n\n## \u6743\u9650\n\n- `ui.panel`\uff1a\u6253\u5f00 SSH \u7ba1\u7406\u9762\u677f\u3002\n- `agent.tool.register`\uff1a\u6ce8\u518c AI SSH \u5de5\u5177\u3002\n- `agent.prompt.inject`\uff1a\u52a0\u8f7d\u5b89\u5168 SSH \u4f7f\u7528\u8bf4\u660e\u3002\n\n\u63d2\u4ef6\u53ea\u4f7f\u7528\u672c\u673a `ssh` \u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4e0d\u4f7f\u7528 `net.fetch`\uff0c\u4e5f\u4e0d\u628a\u51ed\u636e\u5199\u5165\u63d2\u4ef6\u8bbe\u7f6e\u3002\n\n## \u5f00\u53d1\u9a8c\u8bc1\n\n```bash\nnode --test tests/ssh-manager.test.mjs\npython3 scripts/pack_plugin.py plugins/pi.ssh-manager\npython3 scripts/rebuild_catalog.py\n```\n\n\u672c\u5730\u8fd0\u884c\u65f6\u8bf7\u5728 PI-Desktop \u4e2d\u9009\u62e9\u300c\u63d2\u4ef6 \u2192 \u52a0\u8f7d\u5f00\u53d1\u63d2\u4ef6\u300d\uff0c\u518d\u9009\u62e9\u672c\u76ee\u5f55\u3002\n", "safetyNotes": "SSH credentials are never persisted by this plugin. Passwords entered in the panel are held in memory for at most 30 minutes and private-key contents stay outside the plugin. Authentication is delegated to the local OpenSSH client. The panel stores only connection metadata in plugin settings; AI tools can connect to configured hosts and execute remote shell commands, so PI-Desktop's high-risk tool policy must remain enabled.", "versions": [ { - "version": "0.1.5", - "publishedAt": "2026-09-13T07:10:40Z", - "changelog": "Release 0.1.5: restores ProgramData in PI-Desktop's minimal Windows plugin environment so OpenSSH no longer exits 255 silently before connecting; adds a real OpenSSH startup regression test. Release 0.1.4: closes the askpass broker lifecycle boundary so an unload cannot start a new SSH child after the broker has been cleaned up. Release 0.1.3: keeps OpenSSH transport diagnostics visible on Windows instead of suppressing banner-exchange errors behind exit 255, preserves non-default config files for imported aliases without bypassing system config for the default file, detaches an alias when its explicit connection fields are edited, prevents one-shot commands from inheriting plugin stdin, passes special-character passwords through a one-shot local askpass broker without placing them in the ssh process environment, and preserves missing-client diagnostics through the panel bridge. Release 0.1.2: imports concrete hosts from the local OpenSSH config, preserves aliases for complete SSH behavior, adds identity-file selection, surfaces OpenSSH diagnostics instead of a bare exit 255, inherits Windows system environment so ssh.exe can run, and stops leftover ssh processes from throwing on quit. Release 0.1.1: strengthens destructive-command filtering and makes one-time dangerous-command approval available only from the SSH Manager panel. Release 0.1.0: adds local SSH host profiles, strict host-key verification, OpenSSH key/agent and transient password authentication, bounded remote command execution, a focused management panel, and an AI skill describing safe SSH workflows.", + "version": "0.1.2", + "publishedAt": "2026-09-11T18:47:58Z", + "changelog": "Release 0.1.2: imports concrete hosts from the local OpenSSH config, preserves aliases for complete SSH behavior, adds identity-file selection, surfaces OpenSSH diagnostics instead of a bare exit 255, inherits Windows system environment so ssh.exe can run, and stops leftover ssh processes from throwing on quit. Release 0.1.1: strengthens destructive-command filtering and makes one-time dangerous-command approval available only from the SSH Manager panel. Release 0.1.0: adds local SSH host profiles, strict host-key verification, OpenSSH key/agent and transient password authentication, bounded remote command execution, a focused management panel, and an AI skill describing safe SSH workflows.", "minPiDesktop": ">=0.2.9", - "shasum": "02dfeca1840ea9d8a572bc01a1913800bed68ee97b36a5a92ecd7f9fe9817067", - "url": "packages/pi.ssh-manager-0.1.5.piplug", - "sizeBytes": 146730, + "shasum": "6064c87b78b0b00aea4d28cdeb6ea4370cdd960396caf1884bb7af3f958c792d", + "url": "packages/pi.ssh-manager-0.1.2.piplug", + "sizeBytes": 134376, "permissions": [ "ui.panel", "agent.tool.register", @@ -885,7 +707,7 @@ "versions": [ { "version": "0.4.5", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "v0.4.5\uff1a\u4fee\u590d\u9762\u677f\u6eda\u52a8\u5bb9\u5668\u56fa\u5b9a\u5bbd\u5ea6\u5bfc\u81f4\u7684\u53f3\u4fa7\u5927\u9762\u79ef\u7a7a\u767d\uff0c\u6b63\u6587\u6eda\u52a8\u533a\u57df\u73b0\u5728\u968f\u7a97\u53e3\u5168\u5bbd\u4f38\u5c55\u3002v0.4.4\uff1a\u5bf9\u9f50 Markdown \u9762\u677f\u7684 v3 \u9876\u90e8\u5904\u7406\uff0c\u63d0\u524d\u7ed8\u5236 body/root \u80cc\u666f\u5e76\u540c\u6b65\u4e3b\u9898\u53d8\u5316\u5230\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\uff0c\u6d88\u9664\u9876\u90e8\u8272\u5e26\u7a7a\u9699\u548c\u80f6\u56ca\u914d\u8272\u4e0d\u5339\u914d\u3002v0.4.3\uff1a\u4fee\u590d v3 \u5168\u51fa\u8840\u5e03\u5c40\uff0c\u4fa7\u680f\u4e0e\u4e3b\u5185\u5bb9\u586b\u6ee1\u89c6\u53e3\uff0c\u5e76\u4e3a\u81ea\u5b9a\u4e49\u5bfc\u822a\u63a7\u4ef6\u8865\u9f50 no-drag \u6807\u8bb0\uff0c\u907f\u514d\u9876\u90e8\u62d6\u62fd\u5e26\u8986\u76d6\u9875\u9762\u4ea4\u4e92\u3002v0.4.2\uff1a\u8fc1\u79fb\u5230 v3 \u7a7f\u900f\u5f0f\u9876\u90e8 chrome\uff0c\u9876\u90e8\u63a7\u4ef6\u4fdd\u6301\u53ef\u70b9\u51fb\uff0c\u7a7a\u767d\u533a\u57df\u7ee7\u7eed\u53ef\u62d6\u62fd\u3002v0.4.1\uff1a\u9002\u914d PI-Desktop \u8de8\u5e73\u53f0 46px \u4e3b\u673a\u62d6\u62fd\u5e26\u548c\u7b80\u7ea6\u4e09\u6309\u94ae\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u3002v0.4.0\uff1a\u5916\u89c2\u8ddf\u968f app \u4e3b\u4f53\u2014\u2014\u9884\u7ed8\u6309\u300c\u5916\u89c2\u7f13\u5b58 \u2192 \u81ea\u5e26 sdm.settings.theme \u2192 \u7cfb\u7edf\u300d\u6062\u590d\u4e3b\u9898\u5e76\u540c\u6b65 data-lang/lang\uff0c\u8fd0\u884c\u65f6\u8ba2\u9605\u5bbf\u4e3b theme/locale \u5b9e\u65f6\u66f4\u65b0\uff08\u65e0\u95ea\u5c4f\uff09\uff1b\u9762\u677f\u5185\u624b\u52a8\u5207\u6362\u4e3b\u9898\u4ecd\u53ef\u7528\u3002v0.3.1\uff1a\u58f0\u660e manifest.net.domains \u7f51\u7edc\u767d\u540d\u5355\uff08\u4e91\u5382\u5546 API\u3001crt.sh\u3001\u901a\u77e5 Webhook\u3001ACME CA\uff09\uff0c\u4fee\u590d\u65b0\u7248\u5bbf\u4e3b egress \u7b56\u7565\u4e0b\u6240\u6709\u7f51\u7edc\u8bf7\u6c42\u88ab\u62d2\uff08plugin declares no manifest.net.domains; api.cloudflare.com is unreachable\uff09\u7684\u95ee\u9898\u3002v0.2.0\uff1a\u91cd\u6784\u4e3a\u5e72\u51c0\u5229\u843d\u7684\u76f4\u89d2\u98ce\u683c\uff08\u9ed1\u767d\u7070 + \u6a59\u8272\u5f3a\u8c03\u3001\u65e0\u5706\u89d2\u65e0\u6295\u5f71\u30011px \u7ec6\u7ebf\u5206\u9694\uff09\uff1b\u9ed8\u8ba4\u8ddf\u968f\u7cfb\u7edf\u6df1\u6d45\u6a21\u5f0f\uff0c\u4fa7\u8fb9\u680f\u53ef\u4e00\u952e\u5207\u6362\uff1b\u8fdb\u5165\u89e3\u6790\u8bb0\u5f55\u81ea\u52a8\u62c9\u53d6\u6570\u636e\uff1b\u5b50\u9875\u9762\u5bfc\u822a\u4fdd\u6301\u7236\u83dc\u5355\u9009\u4e2d\u6001\u3002", "minPiDesktop": ">=0.1.0", "shasum": "90142ee272408b952731aa00a7c5d37d1c37afd21e46113197872741c20f9f33", @@ -934,7 +756,7 @@ "versions": [ { "version": "0.1.6", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.1.6: on Windows, attach PowerShell to ConPTY inside the work panel instead of opening a separate console window. Release 0.1.5: follow the app color mode only \u2014 never snap to the OS palette, which flashed when the two disagreed. Release 0.1.4: follows the app light/dark mode live in the work-panel view, including the xterm canvas. Release 0.1.3: isolates PTY tabs per open project so switching workspaces cannot mix sessions. Release 0.1.2: docks only in the right work panel; the detached window is removed. Release 0.1.1: login-shell environment so GUI-launched sessions inherit PATH (pnpm, nvm, Homebrew, cargo, bun); denser Otty-like chrome with bottom tabs, find, and font-size controls. Release 0.1.0: first release. Multi-tab PTY sessions, cross-platform default shells (zsh / bash / PowerShell / optional Git Bash), theme and language following, and copy/paste.", "minPiDesktop": ">=0.8.0", "shasum": "e915e96f6895a3f3881314e29099ae3c59236e8e93e6f805f4ba6d3f14919c22", @@ -981,7 +803,7 @@ "versions": [ { "version": "0.6.5", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.6.5\uff1a\u5230\u671f\u63d0\u9192\u8fc1\u79fb\u5230\u5bbf\u4e3b\u6258\u7ba1\u540e\u53f0\u670d\u52a1\uff08contributes.services due-reminder + background.service \u6743\u9650\uff09\u2014\u2014\u9762\u677f\u5173\u95ed\u65f6\u63d2\u4ef6\u8fdb\u7a0b\u5e38\u9a7b\u8c03\u5ea6\uff0c\u5230\u671f\u4efb\u52a1\u7ecf\u539f\u751f\u7cfb\u7edf\u901a\u77e5\u63d0\u9192\uff08\u5bbf\u4e3b ADR 0074\uff0c\u65e0\u7a97\u53e3\u72b6\u6001\u9650\u5236\uff09\uff1b\u4e3b\u8fdb\u7a0b\u4e0e\u6e32\u67d3\u7aef\u5171\u7528 reminded \u5b57\u6bb5\u53bb\u91cd\uff0c\u4e0d\u91cd\u590d\u901a\u77e5\u3002Release 0.6.4\uff1av3 \u5934\u90e8\u5bf9\u9f50\u2014\u2014\u9996\u884c\u5934\u90e8\u8ba9\u51fa\u53f3\u4e0a\u89d2\u5bbf\u4e3b\u7a97\u53e3\u63a7\u5236\u80f6\u56ca 104px \u533a\u57df\uff0c\u65b0\u589e capsule-retint.js \u6309\u9762\u677f\u5b9e\u9645\u8c03\u8272\u677f\u5b9e\u65f6\u91cd\u7740\u8272\u80f6\u56ca\uff08\u4efb\u4f55\u6765\u6e90\u7684\u4e3b\u9898\u5207\u6362\u5747\u7acb\u5373\u751f\u6548\uff09\u3002Release 0.6.3\uff1a\u6e90\u7801\u4ed3\u5e93\u5bf9\u9f50\u5e02\u573a 0.6.2 \u57fa\u7ebf\uff08v3 \u7a7f\u900f\u5f0f\u9876\u90e8 chrome + panel-polish.css + i18n manifest \u53cc\u8bed\u5757\uff09\u3002Release 0.6.2\uff1a\u8fc1\u79fb\u5230 v3 \u7a7f\u900f\u5f0f\u9876\u90e8 chrome\uff0c\u9876\u90e8\u63a7\u4ef6\u4fdd\u6301\u53ef\u70b9\u51fb\uff0c\u7a7a\u767d\u533a\u57df\u7ee7\u7eed\u53ef\u62d6\u62fd\u3002Release 0.6.1\uff1a\u9002\u914d PI-Desktop \u8de8\u5e73\u53f0 46px \u4e3b\u673a\u62d6\u62fd\u5e26\u548c\u7b80\u7ea6\u4e09\u6309\u94ae\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u3002Release 0.6.0\uff1a\u9762\u677f\u8ddf\u968f app \u4e3b\u4f53\u7684\u8bed\u8a00\u4e0e\u989c\u8272\u6a21\u5f0f\u2014\u2014\u65b0\u589e\u6df1\u8272\u914d\u8272\uff08\u4fdd\u7559\u539f\u6d45\u8272\u89c2\u611f\uff09\uff0c\u5bbf\u4e3b\u5207\u6362\u4eae/\u6697\u65f6\u5b9e\u65f6\u6362\u80a4\uff1b\u53ef\u89c1\u6587\u6848\uff08\u6807\u9898/\u5360\u4f4d\u7b26/\u7b5b\u9009/\u8c61\u9650/\u6309\u94ae/\u7a7a\u6001/\u5230\u671f\u63d0\u793a/\u63d0\u9192\u7b49\uff09\u62bd\u6210\u4e2d\u82f1\u53cc\u8bed\u8868\uff0c\u6309 app \u8bed\u8a00\u5b9e\u65f6\u5207\u6362\uff1b\u65e7\u7248\u5bbf\u4e3b\u81ea\u52a8\u964d\u7ea7\uff08\u8ddf\u968f\u7cfb\u7edf\u504f\u597d + \u4e2d\u6587\u754c\u9762\uff09\u3002Release 0.1.0\uff1a\u9996\u4e2a\u7248\u672c\uff0c\u7b80\u5355\u5217\u8868\u5f85\u529e\u3002Release 0.2.0\uff1a\u65b0\u589e\u56db\u8c61\u9650\u77e9\u9635\u5e03\u5c40\uff08\u62d6\u62fd\u79fb\u52a8\u8c61\u9650\uff09\u3001\u53cc\u5e03\u5c40\u5207\u6362\u5e76\u8bb0\u4f4f\u3001\u7a97\u53e3 1000\u00d7700\u3002Release 0.3.0\uff1a\u4efb\u52a1\u53ef\u8bbe\u7f6e\u5230\u671f\u65f6\u95f4\u3001\u5230\u671f\u63d0\u9192\uff08\u4f4e\u5360\u7528\u5355\u5b9a\u65f6\u5668\u8c03\u5ea6\uff09\u3002Release 0.3.1\uff1a\u5230\u671f\u63d0\u9192\u5347\u7ea7\u4e3a\u539f\u751f\u7cfb\u7edf\u901a\u77e5\uff08ui.showNativeNotification\uff0c\u5bbf\u4e3b ADR 0074\uff09\u3002Release 0.4.0\uff1a\u63d2\u4ef6 id \u5b9a\u7a3f\u4e3a pi.todo\uff08\u5b98\u65b9 pi. \u524d\u7f00\uff09\u3002Release 0.5.0\uff1a\u6ce8\u518c agent \u5de5\u5177 todo_manage\uff08AI \u53ef\u7ba1\u7406\u5f85\u529e\uff1a\u67e5\u8be2/\u6dfb\u52a0/\u5927\u6bb5\u62c6\u5206/\u6a21\u7cca\u5b8c\u6210/\u5ef6\u671f/\u6e05\u7a7a\u8fc7\u671f/\u5220\u9664\uff09\uff1b\u6570\u636e\u8fc1\u79fb\u81f3\u63d2\u4ef6\u6570\u636e\u76ee\u5f55 settings.json\uff0c\u9762\u677f\u4e0e AI \u5171\u4eab\u540c\u4e00\u4efd\u6570\u636e\uff0c\u53cc\u5411\u540c\u6b65\u3002Release 0.5.1\uff1a\u8865\u4e01\u53d1\u5e03\uff0c\u65e0\u529f\u80fd\u53d8\u66f4\uff08\u540c\u6b65\u6e90\u7801\u4ed3\u5e93\u4e0e\u5e02\u573a\u7248\u672c\u53f7\uff09\u3002", "minPiDesktop": ">=0.1.0", "shasum": "25bda064f4d3daa8fbadc6dfc31c9d8b59664335756cf091d257791f0235b625", @@ -1028,7 +850,7 @@ "versions": [ { "version": "0.4.8", - "publishedAt": "2026-09-12T17:13:25Z", + "publishedAt": "2026-09-11T18:47:58Z", "changelog": "Release 0.4.8: Fold PI-Desktop completed-turn totals from the host database into the dashboard, so subagent spend that never lands on parent message.usage still appears without double-counting transcript rows. Settings no longer has a Usage page; this panel is the heatmap. Release 0.4.8\uff1a\u628a\u5bbf\u4e3b\u5df2\u5b8c\u6210\u56de\u5408\u7684 token \u5408\u8ba1\u6298\u5165\u4eea\u8868\u76d8\uff0c\u8f6c\u5f55\u672c message.usage \u672a\u8ba1\u5165\u7684\u5b50\u667a\u80fd\u4f53\u7528\u91cf\u4f1a\u8865\u4e0a\u4e14\u4e0d\u4e0e JSONL \u91cd\u590d\u3002\u8bbe\u7f6e\u9875\u4e0d\u518d\u6709\u7528\u91cf\u5165\u53e3\uff0c\u70ed\u529b\u56fe\u4ee5\u672c\u9762\u677f\u4e3a\u51c6\u3002 Release 0.4.7: Fix the extra empty right-side rail on Windows by keeping the stable scrollbar gutter on the dashboard scroller instead of reserving it again on the root viewport. Release 0.4.7\uff1a\u4fee\u590d Windows \u53f3\u4fa7\u591a\u51fa\u7a7a\u767d\u4fa7\u680f\u7684\u95ee\u9898\uff1a\u4ec5\u5728\u4eea\u8868\u76d8\u6eda\u52a8\u5bb9\u5668\u4fdd\u7559\u7a33\u5b9a\u6eda\u52a8\u6761\u69fd\u4f4d\uff0c\u4e0d\u518d\u5728\u6839\u89c6\u53e3\u91cd\u590d\u9884\u7559\u3002 Release 0.4.6: Fix the titlebar's appearance and refresh buttons overlapping the host window-control capsule. The panel paints through the 46px band under v3 chrome, but the capsule still floats over the top-right corner, so both buttons sat under it and stopped being clickable. The titlebar now reserves the capsule's 104px corner (kept at narrow widths too, where the gutter override previously reset it), the appearance menu stays anchored to the buttons that open it, and a long title truncates instead of running under the reserve. Release 0.4.6\uff1a\u4fee\u590d\u6807\u9898\u680f\u7684\u5916\u89c2\u4e0e\u5237\u65b0\u6309\u94ae\u4e0e\u5bbf\u4e3b\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u91cd\u53e0\u7684\u95ee\u9898\u3002v3 chrome \u4e0b\u9762\u677f\u53ef\u7ed8\u5236\u5230 46px \u9876\u680f\uff0c\u4f46\u80f6\u56ca\u4ecd\u6d6e\u4e8e\u53f3\u4e0a\u89d2\uff0c\u5bfc\u81f4\u4e24\u4e2a\u6309\u94ae\u88ab\u906e\u6321\u4e14\u65e0\u6cd5\u70b9\u51fb\u3002\u6807\u9898\u680f\u73b0\u4e3a\u80f6\u56ca\u4fdd\u7559 104px \u53f3\u4fa7\u7a7a\u95f4\uff08\u7a84\u5bbd\u5ea6\u4e0b\u7684 gutter \u8986\u76d6\u6b64\u524d\u4f1a\u91cd\u7f6e\u8be5\u4fdd\u7559\u503c\uff0c\u73b0\u5df2\u4fdd\u7559\uff09\uff0c\u5916\u89c2\u83dc\u5355\u7ee7\u7eed\u5bf9\u9f50\u89e6\u53d1\u6309\u94ae\uff0c\u8fc7\u957f\u6807\u9898\u4ee5\u7701\u7565\u53f7\u622a\u65ad\u3002 Release 0.4.5: Migrates the panel to v3 paint-through chrome so top-band controls remain clickable while blank space remains draggable. Release 0.4.4: Fix the window-control capsule being drawn with default black-on-white colors on a panel's very first open \u2014 with no cached appearance, data-theme stayed unset until the host answered, so the host's one-shot color snapshot at DOMContentLoaded missed; boot now falls back to the OS palette synchronously while content stays cloaked. Also stop startAppearanceWatch from resetting the appearance fingerprint, which made every open-command run rewrite hostAppearance. Release 0.4.4\uff1a\u4fee\u590d\u9996\u6b21\u6253\u5f00\u9762\u677f\u65f6\u7a97\u53e3\u63a7\u5236\u80f6\u56ca\u914d\u8272\u9519\u8bef\u7684\u95ee\u9898\u2014\u2014\u65e0\u7f13\u5b58\u5916\u89c2\u65f6 data-theme \u672a\u8bbe\u7f6e\uff0c\u5bbf\u4e3b\u5728 DOMContentLoaded \u7684\u53d6\u8272\u5feb\u7167\u62ff\u5230\u6d4f\u89c8\u5668\u9ed8\u8ba4\u9ed1/\u767d\uff0c\u73b0\u540c\u6b65\u56de\u9000 OS \u914d\u8272\uff08\u5185\u5bb9\u4ecd\u6309 data-booting \u9690\u85cf\u81f3\u771f\u5b9e\u5916\u89c2\u5230\u8fbe\uff09\uff1b\u4fee\u590d startAppearanceWatch \u91cd\u7f6e\u5916\u89c2\u6307\u7eb9\u5bfc\u81f4\u6bcf\u6b21\u6253\u5f00\u547d\u4ee4\u90fd\u91cd\u590d\u5199\u5165 hostAppearance \u7684\u95ee\u9898\u3002 Release 0.4.3: Align the panel with PI-Desktop's cross-platform 46px host drag band and minimal three-button window-control capsule. Fixes two visible faults: elements toggled with the hidden attribute were being kept on screen by their own CSS display, so the loading skeleton stayed over real data, an empty chip strip and the custom date inputs were always drawn, and the last scan sentence lingered; and the from/to fields now always show the window the selected range covers, so picking 7D/90D/ALL keeps them in step and switching to Custom inherits what you were looking at. Includes 0.4.1's scan progress with a real file count, stale-scan recovery, visibility-based polling and debounced source watching, on top of 0.4.0's theme/language following, filters and streak layer.", "minPiDesktop": ">=0.2.9", "shasum": "220506deb22c680074fb65856ad0b769435246a7a850184e8226f602bc9eb427", @@ -1042,20 +864,20 @@ } ] }, - { + { "id": "pi.workspace-file-guard", - "name": "C\u76d8\u9632\u5783\u573e", - "description": "\u9632\u6b62\u6a21\u578b\u628a\u6d4b\u8bd5\u3001\u65e5\u5fd7\u3001\u7f13\u5b58\u3001\u4e34\u65f6\u6587\u4ef6\u5199\u5230\u7cfb\u7edf\u76d8\u3001\u684c\u9762\u3001\u4e0b\u8f7d\u3002\u5783\u573e\u53ea\u5f85\u5728\u5f53\u524d\u9879\u76ee\u7684 Temp \u6216 scratch\u3002", + "name": "C盘防垃圾", + "description": "防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 Temp 或 scratch。", "i18n": { "en": { - "name": "Keep junk off C:", - "description": "Keep test, log, cache, and temp files out of the system drive, Desktop, and Downloads. Junk stays in the current project's Temp or scratch.", - "safetyNotes": "Behavioral confinement, not a disk lock. The plugin only classifies paths and injects agent rules. It does not change ACLs or use the network." + "name": "C盘防垃圾", + "description": "防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 Temp 或 scratch。", + "safetyNotes": "这是行为约束,不是磁盘锁。插件只分类路径并注入 Agent 规则,不改 ACL、不联网。" }, "zh-CN": { - "name": "C\u76d8\u9632\u5783\u573e", - "description": "\u9632\u6b62\u6a21\u578b\u628a\u6d4b\u8bd5\u3001\u65e5\u5fd7\u3001\u7f13\u5b58\u3001\u4e34\u65f6\u6587\u4ef6\u5199\u5230\u7cfb\u7edf\u76d8\u3001\u684c\u9762\u3001\u4e0b\u8f7d\u3002\u5783\u573e\u53ea\u5f85\u5728\u5f53\u524d\u9879\u76ee\u7684 Temp \u6216 scratch\u3002", - "safetyNotes": "\u8fd9\u662f\u884c\u4e3a\u7ea6\u675f\uff0c\u4e0d\u662f\u78c1\u76d8\u9501\u3002\u63d2\u4ef6\u53ea\u5206\u7c7b\u8def\u5f84\u5e76\u6ce8\u5165 Agent \u89c4\u5219\uff0c\u4e0d\u6539 ACL\u3001\u4e0d\u8054\u7f51\u3002" + "name": "C盘防垃圾", + "description": "防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 Temp 或 scratch。", + "safetyNotes": "这是行为约束,不是磁盘锁。插件只分类路径并注入 Agent 规则,不改 ACL、不联网。" } }, "author": "xingleiwu", @@ -1066,17 +888,17 @@ "downloads": 0, "homepage": "https://github.com/vastsa/pi-desktop-plugins/tree/main/plugins/pi.workspace-file-guard", "repository": "https://github.com/vastsa/pi-desktop-plugins", - "readmeMarkdown": "# C\u76d8\u9632\u5783\u573e\n\n\u9632\u6b62\u6a21\u578b\u628a\u6d4b\u8bd5\u3001\u65e5\u5fd7\u3001\u7f13\u5b58\u3001\u4e34\u65f6\u6587\u4ef6\u5199\u5230\u7cfb\u7edf\u76d8\u3001\u684c\u9762\u3001\u4e0b\u8f7d\u3002\u5783\u573e\u53ea\u5f85\u5728\u5f53\u524d\u9879\u76ee\u7684 `Temp` \u6216 scratch\u3002\n\n\u542f\u7528\u4e00\u6b21\u5373\u53ef\u3002\u8def\u5f84\u6309\u5f53\u524d\u673a\u5668\u89e3\u6790\uff0c\u4e0d\u5199\u6b7b\u76d8\u7b26\u6216\u7528\u6237\u540d\u3002\u8fd9\u662f\u884c\u4e3a\u7ea6\u675f\uff0c\u4e0d\u662f\u78c1\u76d8\u9501\u3002\n\n## \u63d0\u4f9b\u4ec0\u4e48\n\n- Skill\uff1a`skills/workspace-file-guard.md`\uff08\u63d2\u4ef6\u542f\u7528\u671f\u95f4\u6ce8\u5165 Agent\uff09\n- \u5de5\u5177\uff1a`project_root` / `check_path` / `temp_env` / `tmp_layout`\n- \u62d2\u7edd\u6e05\u5355\uff1a`references/denied-paths.md`\n- \u5206\u7c7b\u5668\uff1a`guard.js`\n\n## \u6587\u4ef6\u8be5\u5199\u5230\u54ea\n\n| \u7c7b\u578b | \u4f4d\u7f6e |\n| --- | --- |\n| \u7528\u6237\u8981\u6c42\u4fdd\u7559\u7684\u6e90\u7801 | \u5de5\u4f5c\u533a\uff08`src/`\u3001`tests/` \u7b49\uff09 |\n| \u4e00\u6b21\u6027\u8349\u7a3f\u3001\u8f6c\u50a8\u3001\u65e5\u5fd7 | `$PI_SCRATCH_DIR` |\n| \u9879\u76ee\u672c\u5730\u7f13\u5b58 / \u4e00\u6b21\u6027\u6d4b\u8bd5 | `$project/Temp/` |\n\n\u7981\u6b62\uff1a\u684c\u9762\u3001\u4e0b\u8f7d\u3001\u6587\u6863\u3001\u7cfb\u7edf\u4e34\u65f6\u76ee\u5f55\uff1b\u9879\u76ee\u5728\u5176\u4ed6\u76d8\u65f6\u7981\u6b62\u5199\u5230\u7cfb\u7edf\u76d8\uff1bProgram Files\u3001`/usr`\u3001`/Applications`\u3002\n\n## \u6743\u9650\n\n| \u6743\u9650 | \u7528\u9014 |\n| --- | --- |\n| `agent.prompt.inject` | \u6ce8\u5165\u62a4\u680f\u89c4\u5219\uff0c\u8ba9 Agent \u9ed8\u8ba4\u628a\u5783\u573e\u6587\u4ef6\u5173\u5728\u5de5\u4f5c\u533a / scratch |\n| `agent.tool.register` | \u6ce8\u518c\u8def\u5f84\u5206\u7c7b\u5de5\u5177\uff0c\u4f9b Agent \u5728\u5199\u6587\u4ef6\u524d\u67e5\u8be2 |\n\n\u4e0d\u7533\u8bf7 `fs.*` \u5bbf\u4e3b\u6587\u4ef6\u7cfb\u7edf\u6743\u9650\u3001\u7f51\u7edc\u3001\u526a\u8d34\u677f\u6216\u540e\u53f0\u670d\u52a1\u6743\u9650\u3002\u4e3a\u8bc6\u522b Linux/XDG \u81ea\u5b9a\u4e49\u7528\u6237\u76ee\u5f55\uff0c\u5206\u7c7b\u5668\u4f1a\u53ea\u8bfb\u672c\u673a `~/.config/user-dirs.dirs`\uff08\u82e5\u5b58\u5728\uff09\uff0c\u4e0d\u4f1a\u4e0a\u4f20\u6216\u8fd4\u56de\u8be5\u6587\u4ef6\u539f\u6587\u3002\u63d2\u4ef6\u672c\u8eab\u4e0d\u5199\u76d8\u3001\u4e0d\u6539 ACL\u3001\u4e0d\u8054\u7f51\uff1b\u771f\u6b63\u843d\u76d8\u7684\u4ecd\u662f Agent \u81ea\u5df1\u7684 Write / Bash\u3002\n\n## \u5b89\u88c5\n\n1. PI-Desktop \u2192 \u6269\u5c55 \u2192 \u5b89\u88c5\u63d2\u4ef6\u5305\uff0c\u9009\u62e9 `packages/pi.workspace-file-guard-0.2.7.piplug`\u3002\n2. \u82e5\u51fa\u73b0\u6743\u9650\u786e\u8ba4\uff0c\u52fe\u9009 `agent.prompt.inject` \u4e0e `agent.tool.register`\uff08\u5f53\u524d\u5bbf\u4e3b\u5bf9\u672c\u5730 `.piplug` \u53ef\u80fd\u6309\u6e05\u5355\u9759\u9ed8\u5168\u6388\uff09\u3002\n3. \u65b0\u5f00\u4e00\u4e2a Agent \u4f1a\u8bdd\uff0cskill \u624d\u4f1a\u6ce8\u5165\u3002\n\n\u4e5f\u53ef\u628a\u672c\u76ee\u5f55\u5f53\u4f5c\u5f00\u53d1\u63d2\u4ef6\u52a0\u8f7d\uff08\u4fdd\u5b58\u540e\u70ed\u91cd\u8f7d\uff09\u3002\u5f00\u53d1\u63d2\u4ef6\u6269\u6743\u540e\u8bf7\u91cd\u65b0\u300c\u52a0\u8f7d\u5f00\u53d1\u63d2\u4ef6\u300d\uff0c\u4e0d\u8981\u53ea\u70b9\u300c\u91cd\u65b0\u52a0\u8f7d\u300d\u3002\n\n## \u5f00\u53d1\u9a8c\u8bc1\n\n```bash\nnode tests/workspace-file-guard-guard.test.js\nnode tests/workspace-file-guard-main.test.js\npython scripts/pack_plugin.py plugins/pi.workspace-file-guard\npython scripts/rebuild_catalog.py\npython scripts/security_audit.py --check-packages\n```\n\n## \u80fd\u529b\u8fb9\u754c\n\n- \u4e0d\u662f\u4e8b\u540e\u6e05\u7406\u78c1\u76d8\u3002\n- \u4e0d\u662f\u8de8\u9879\u76ee\u8bbf\u95ee\u9694\u79bb\u3002\n- \u4e0d\u662f\u64cd\u4f5c\u7cfb\u7edf\u6c99\u7bb1\u3001BitLocker\u3001SIP \u6216\u6587\u4ef6\u5939 ACL\u3002\n- `root` \u8986\u76d6\u53ea\u5728\u7528\u6237\u660e\u786e\u9009\u62e9\u9879\u76ee\u6839\u65f6\u4f7f\u7528\uff1b\u5de5\u5177\u65e0\u6cd5\u9a8c\u8bc1\u8be5\u9009\u62e9\uff0c\u4e0d\u80fd\u628a\u5b83\u5f53\u6210\u5b89\u5168\u8fb9\u754c\u3002\n- `explicit` \u53ea\u662f\u6a21\u578b\u5bf9\u7528\u6237\u610f\u56fe\u7684\u58f0\u660e\uff1b\u684c\u9762\u3001\u4e0b\u8f7d\u3001\u6587\u6863\u548c\u7cfb\u7edf\u4e34\u65f6\u76ee\u5f55\u5373\u4f7f\u6807\u8bb0\u4e5f\u7981\u6b62\u3002\n\n## \u80fd\u529b / \u6570\u636e\u6d41\n\n| \u80fd\u529b | \u6570\u636e | \u65b9\u5411 |\n| --- | --- | --- |\n| `agent.prompt.inject` | \u672c\u63d2\u4ef6 `skills/workspace-file-guard.md` \u89c4\u5219\u6587\u672c | \u6ce8\u5165\u5f53\u524d\u4f1a\u8bdd\u7684\u7cfb\u7edf\u63d0\u793a\uff0c\u4e0d\u8bfb\u804a\u5929\u8bb0\u5f55 |\n| `agent.tool.register` | \u8c03\u7528\u53c2\u6570\u91cc\u7684\u8def\u5f84\u5b57\u7b26\u4e32\uff1b`pi.workspace.get()` \u7684\u5de5\u4f5c\u533a\u8def\u5f84\uff1b`PI_SCRATCH_DIR` / \u4e3b\u76ee\u5f55 / \u5e38\u89c1\u7cfb\u7edf\u76ee\u5f55 | \u53ea\u8fd4\u56de\u5206\u7c7b\u7ed3\u679c\u4e0e\u73af\u5883\u53d8\u91cf\u5efa\u8bae\uff0c\u4e0d\u5199\u76d8 |\n| \u6587\u4ef6\u7cfb\u7edf | \u672c\u673a `~/.config/user-dirs.dirs`\uff08\u82e5\u5b58\u5728\uff09 | \u4ec5\u7528\u4e8e\u8bc6\u522b XDG \u7528\u6237\u76ee\u5f55\uff0c\u4e0d\u4e0a\u4f20\u3001\u4e0d\u8fd4\u56de\u539f\u6587 |\n| \u7f51\u7edc / \u526a\u8d34\u677f / \u540e\u53f0\u670d\u52a1 | \u65e0 | \u4e0d\u7533\u8bf7\u3001\u4e0d\u4f7f\u7528 |\n\n\u5931\u8d25\u8def\u5f84\uff1a\u6ca1\u6709\u6253\u5f00\u5de5\u4f5c\u533a\u4e14\u672a\u4f20 `root` \u65f6\u5de5\u5177\u8fd4\u56de `ok: false`\uff0c\u4e0d\u4f1a\u56de\u9000\u5230\u63d2\u4ef6\u5b89\u88c5\u76ee\u5f55\u6216 cwd\u3002\u684c\u9762\u3001\u4e0b\u8f7d\u3001\u6587\u6863\u3001\u7cfb\u7edf\u4e34\u65f6\u76ee\u5f55\u5373\u4f7f `explicit=true` \u4e5f\u62d2\u7edd\u3002\n", - "safetyNotes": "\u8fd9\u662f\u884c\u4e3a\u7ea6\u675f\uff0c\u4e0d\u662f\u78c1\u76d8\u9501\u3002\u63d2\u4ef6\u53ea\u5206\u7c7b\u8def\u5f84\u5e76\u6ce8\u5165 Agent \u89c4\u5219\uff0c\u4e0d\u6539 ACL\u3001\u4e0d\u8054\u7f51\u3002", + "readmeMarkdown": "# C盘防垃圾\n\n防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 `Temp` 或 scratch。\n\n启用一次即可。路径按当前机器解析,不写死盘符或用户名。这是行为约束,不是磁盘锁。\n\n## 提供什么\n\n- Skill:`skills/workspace-file-guard.md`(插件启用期间注入 Agent)\n- 工具:`project_root` / `check_path` / `temp_env` / `tmp_layout`\n- 拒绝清单:`references/denied-paths.md`\n- 分类器:`guard.js`\n\n## 文件该写到哪\n\n| 类型 | 位置 |\n| --- | --- |\n| 用户要求保留的源码 | 工作区(`src/`、`tests/` 等) |\n| 一次性草稿、转储、日志 | `$PI_SCRATCH_DIR` |\n| 项目本地缓存 / 一次性测试 | `$project/Temp/` |\n\n禁止:桌面、下载、文档、系统临时目录;项目在其他盘时禁止写到系统盘;Program Files、`/usr`、`/Applications`。\n\n## 权限\n\n| 权限 | 用途 |\n| --- | --- |\n| `agent.prompt.inject` | 注入护栏规则,让 Agent 默认把垃圾文件关在工作区 / scratch |\n| `agent.tool.register` | 注册路径分类工具,供 Agent 在写文件前查询 |\n\n不申请 `fs.*` 宿主文件系统权限、网络、剪贴板或后台服务权限。为识别 Linux/XDG 自定义用户目录,分类器会只读本机 `~/.config/user-dirs.dirs`(若存在),不会上传或返回该文件原文。插件本身不写盘、不改 ACL、不联网;真正落盘的仍是 Agent 自己的 Write / Bash。\n\n## 安装\n\n1. PI-Desktop → 扩展 → 安装插件包,选择 `packages/pi.workspace-file-guard-0.2.8.piplug`。\n2. 若出现权限确认,勾选 `agent.prompt.inject` 与 `agent.tool.register`(当前宿主对本地 `.piplug` 可能按清单静默全授)。\n3. 新开一个 Agent 会话,skill 才会注入。\n\n也可把本目录当作开发插件加载(保存后热重载)。开发插件扩权后请重新「加载开发插件」,不要只点「重新加载」。\n\n## 开发验证\n\n```bash\nnode tests/workspace-file-guard-guard.test.js\nnode tests/workspace-file-guard-main.test.js\npython scripts/pack_plugin.py plugins/pi.workspace-file-guard\npython scripts/rebuild_catalog.py\npython scripts/security_audit.py --check-packages\n```\n\n## 能力边界\n\n- 不是事后清理磁盘。\n- 不是跨项目访问隔离。\n- 不是操作系统沙箱、BitLocker、SIP 或文件夹 ACL。\n- `root` 覆盖只在用户明确选择项目根时使用;工具无法验证该选择,不能把它当成安全边界。\n- `explicit` 只是模型对用户意图的声明;桌面、下载、文档和系统临时目录即使标记也禁止。\n\n## 能力 / 数据流\n\n| 能力 | 数据 | 方向 |\n| --- | --- | --- |\n| `agent.prompt.inject` | 本插件 `skills/workspace-file-guard.md` 规则文本 | 注入当前会话的系统提示,不读聊天记录 |\n| `agent.tool.register` | 调用参数里的路径字符串;`pi.workspace.get()` 的工作区路径;`PI_SCRATCH_DIR` / 主目录 / 常见系统目录 | 只返回分类结果与环境变量建议,不写盘 |\n| 文件系统 | 本机 `~/.config/user-dirs.dirs`(若存在) | 仅用于识别 XDG 用户目录,不上传、不返回原文 |\n| 网络 / 剪贴板 / 后台服务 | 无 | 不申请、不使用 |\n\n失败路径:没有打开工作区且未传 `root` 时工具返回 `ok: false`,不会回退到插件安装目录或 cwd。桌面、下载、文档、系统临时目录即使 `explicit=true` 也拒绝。\n", + "safetyNotes": "这是行为约束,不是磁盘锁。插件只分类路径并注入 Agent 规则,不改 ACL、不联网。", "versions": [ { - "version": "0.2.7", - "publishedAt": "2026-09-14T04:38:39Z", - "changelog": "0.2.7\uff1a\u5e02\u573a\u540d\u79f0\u6539\u4e3a\u300cC\u76d8\u9632\u5783\u573e\u300d\uff1b\u9879\u76ee\u5783\u573e\u6539\u653e\u5230 $project/Temp/\uff1b\u62d2\u7edd\u628a Temp \u503e\u5012\u76ee\u5f55\u5f53\u9879\u76ee\u6839\u3002 0.2.6\uff1a\u5e02\u573a\u540d\u79f0\u6539\u4e3a\u76f4\u767d\u4e2d\u6587\u3002 0.2.5: Quote generated bash and PowerShell assignments safely, reject unsafe cmd values, enforce canonical root/scratch and symlink boundaries, include negative-path tests in CI, and sync the package. 0.2.4\uff1a\u8bf4\u660e\u6539\u4e3a\u4e2d\u6587\u30020.2.3\uff1a\u53bb\u6389 git/cwd \u4f5c\u4e3a\u9879\u76ee\u6839\u56de\u9000\uff1bcmd \u73af\u5883\u53d8\u91cf\u62d2\u7edd\u5185\u5d4c\u5f15\u53f7\uff1b\u8986\u76d6\u5de5\u4f5c\u533a API \u5931\u8d25\u4e0e explicit \u4e34\u65f6\u76ee\u5f55\u62d2\u7edd\u30020.2.2\uff1a\u76f8\u5bf9\u8def\u5f84\u76f8\u5bf9\u5de5\u4f5c\u533a\u89e3\u6790\u30020.2.1\uff1aexplicit \u76ee\u6807\u4e0e XDG_DOWNLOAD_DIR\u30020.2.0\uff1a\u8de8\u673a\u5668\u4fbf\u643a\u3002", + "version": "0.2.8", + "publishedAt": "2026-09-14T05:06:41Z", + "changelog": "0.2.8:介绍、工具说明和 changelog 全部改为中文。0.2.7:市场名称改为「C盘防垃圾」;项目垃圾改放到 $project/Temp/;拒绝把 Temp 倾倒目录当项目根。0.2.6:市场名称改为直白中文。0.2.5:安全引用 bash/PowerShell 赋值,拒绝不安全的 cmd 值,强制规范 root/scratch 与符号链接边界,CI 加入负向路径测试并同步包装。0.2.4:说明改为中文。0.2.3:去掉 git/cwd 作为项目根回退;cmd 环境变量拒绝内嵌引号;覆盖工作区 API 失败与 explicit 临时目录拒绝。0.2.2:相对路径相对工作区解析。0.2.1:explicit 目标与 XDG_DOWNLOAD_DIR。0.2.0:跨机器便携。", "minPiDesktop": ">=0.2.0", - "shasum": "f4fb247dfd66ed63286a774bacbf77cfb42f231fe3ebf380b075534b0bb224d0", - "url": "packages/pi.workspace-file-guard-0.2.7.piplug", - "sizeBytes": 42134, + "shasum": "e91dcc2aeeac449a135543508f537fa199dffa82385af0e4b0fff5aa589e4e6d", + "url": "packages/pi.workspace-file-guard-0.2.8.piplug", + "sizeBytes": 41528, "permissions": [ "agent.prompt.inject", "agent.tool.register" diff --git a/packages/pi.workspace-file-guard-0.2.8.piplug b/packages/pi.workspace-file-guard-0.2.8.piplug new file mode 100644 index 0000000000000000000000000000000000000000..5ee1eede9f33e1b2284b72b618fc5bea0450ea27 GIT binary patch literal 41528 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 B&_MtI literal 0 HcmV?d00001 diff --git a/plugins/pi.workspace-file-guard/README.md b/plugins/pi.workspace-file-guard/README.md index 0dde73c..b4287bf 100644 --- a/plugins/pi.workspace-file-guard/README.md +++ b/plugins/pi.workspace-file-guard/README.md @@ -32,7 +32,7 @@ ## 安装 -1. PI-Desktop → 扩展 → 安装插件包,选择 `packages/pi.workspace-file-guard-0.2.7.piplug`。 +1. PI-Desktop → 扩展 → 安装插件包,选择 `packages/pi.workspace-file-guard-0.2.8.piplug`。 2. 若出现权限确认,勾选 `agent.prompt.inject` 与 `agent.tool.register`(当前宿主对本地 `.piplug` 可能按清单静默全授)。 3. 新开一个 Agent 会话,skill 才会注入。 diff --git a/plugins/pi.workspace-file-guard/main.js b/plugins/pi.workspace-file-guard/main.js index e1db117..3313988 100644 --- a/plugins/pi.workspace-file-guard/main.js +++ b/plugins/pi.workspace-file-guard/main.js @@ -1,11 +1,10 @@ "use strict"; /** - * Workspace File Guard — PI-Desktop plugin entry. + * C盘防垃圾 — PI-Desktop 插件入口。 * - * Skills in this pack are injected into the agent prompt while the plugin - * is enabled. Tools let the agent resolve the project root and reject writes - * that would leak test/temp/junk files onto the system volume, Desktop, Downloads, or temp dirs. + * 插件启用期间会把 skill 注入 Agent。工具用来解析项目根, + * 并拒绝把测试/临时/垃圾文件写到系统盘、桌面、下载或系统临时目录。 */ const { @@ -100,7 +99,7 @@ async function toolTmpLayout(args) { scratch, layout: tmpLayout(projectRoot), hint: - "Create these folders only when needed. Put throwaway files in Temp or scratch; keep durable source in the project tree.", + "只在需要时创建这些文件夹。一次性文件放 Temp 或 scratch;正式源码放项目树。", }); } @@ -110,15 +109,14 @@ async function onLoad() { await pi.agent.registerTool({ name: "project_root", description: - "Resolve the active PI-Desktop workspace, PI scratch directory, and recommended Temp layout. Fails if no workspace is open and root is omitted. Use before creating test/temp/scratch files.", + "解析当前打开的 PI-Desktop 工作区、PI scratch,以及推荐的 Temp 布局。未打开工作区且未传 root 时失败。写测试/临时/草稿文件前先调用。", risk: "low", schema: { type: "object", properties: { root: { type: "string", - description: - "Optional absolute project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection.", + description: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。", }, }, }, @@ -129,21 +127,20 @@ async function onLoad() { await pi.agent.registerTool({ name: "check_path", description: - "Classify whether a write path is allowed. Read allowed, not ok: ok=true only means classification succeeded. Relative paths are resolved against the workspace, not the plugin process cwd. allowed=false must be redirected into the workspace or PI scratch.", + "判断写入路径是否允许。看 allowed,不要看 ok:ok=true 只表示分类成功。相对路径相对工作区解析,不是插件进程 cwd。allowed=false 必须改写到工作区或 PI scratch。", risk: "low", schema: { type: "object", properties: { - path: { type: "string", description: "Path that would be written" }, + path: { type: "string", description: "准备写入的路径" }, root: { type: "string", - description: - "Optional absolute project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection.", + description: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。", }, explicit: { type: "boolean", description: - "Set true only when this turn's user message named this absolute destination. The tool cannot verify that; Desktop/Downloads/temp stay forbidden anyway.", + "仅当本轮用户消息点名了这个绝对路径时设为 true。工具无法核实;桌面、下载、系统临时目录仍然禁止。", }, }, required: ["path"], @@ -155,20 +152,19 @@ async function onLoad() { await pi.agent.registerTool({ name: "temp_env", description: - "Return TMP/TEMP/cache environment assignments that keep tool junk inside the project Temp and PI scratch. Fails if no workspace is open and root is omitted.", + "返回 TMP/TEMP/缓存环境变量赋值,把工具垃圾关在项目 Temp 和 PI scratch。未打开工作区且未传 root 时失败。", risk: "low", schema: { type: "object", properties: { root: { type: "string", - description: - "Optional absolute project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection.", + description: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。", }, shell: { type: "string", enum: ["powershell", "cmd", "bash", "json"], - description: "Script dialect for the env assignments", + description: "环境变量脚本方言", }, }, }, @@ -179,15 +175,14 @@ async function onLoad() { await pi.agent.registerTool({ name: "tmp_layout", description: - "Return the recommended $project/Temp/{tests,scripts,cache,out} layout without creating files. Fails if no workspace is open and root is omitted.", + "返回推荐的 $project/Temp/{tests,scripts,cache,out} 布局,不创建文件。未打开工作区且未传 root 时失败。", risk: "low", schema: { type: "object", properties: { root: { type: "string", - description: - "Optional absolute project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection.", + description: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。", }, }, }, diff --git a/plugins/pi.workspace-file-guard/manifest.json b/plugins/pi.workspace-file-guard/manifest.json index efe6f93..e12ff22 100644 --- a/plugins/pi.workspace-file-guard/manifest.json +++ b/plugins/pi.workspace-file-guard/manifest.json @@ -2,13 +2,13 @@ "schemaVersion": 1, "id": "pi.workspace-file-guard", "name": "C盘防垃圾", - "version": "0.2.7", + "version": "0.2.8", "description": "防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 Temp 或 scratch。", "i18n": { "en": { - "name": "Keep junk off C:", - "description": "Keep test, log, cache, and temp files out of the system drive, Desktop, and Downloads. Junk stays in the current project's Temp or scratch.", - "safetyNotes": "Behavioral confinement, not a disk lock. The plugin only classifies paths and injects agent rules. It does not change ACLs or use the network." + "name": "C盘防垃圾", + "description": "防止模型把测试、日志、缓存、临时文件写到系统盘、桌面、下载。垃圾只待在当前项目的 Temp 或 scratch。", + "safetyNotes": "这是行为约束,不是磁盘锁。插件只分类路径并注入 Agent 规则,不改 ACL、不联网。" }, "zh-CN": { "name": "C盘防垃圾", @@ -25,36 +25,36 @@ "agentTools": [ { "name": "project_root", - "description": "Resolve the open PI-Desktop workspace, PI scratch directory, and recommended Temp layout. Fails if no workspace is open and root is omitted.", + "description": "解析当前打开的 PI-Desktop 工作区、PI scratch,以及推荐的 Temp 布局。未打开工作区且未传 root 时失败。", "risk": "low", "schema": { "type": "object", "properties": { "root": { "type": "string", - "description": "Optional project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection." + "description": "可选的项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。" } } } }, { "name": "check_path", - "description": "Classify whether a write path is allowed. Read allowed, not ok. Relative paths are resolved against the workspace, not the plugin process cwd. allowed=false must be redirected into the workspace or PI scratch.", + "description": "判断写入路径是否允许。看 allowed,不要看 ok。相对路径相对工作区解析,不是插件进程 cwd。allowed=false 必须改写到工作区或 PI scratch。", "risk": "low", "schema": { "type": "object", "properties": { "path": { "type": "string", - "description": "Path that would be written" + "description": "准备写入的路径" }, "root": { "type": "string", - "description": "Optional project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection." + "description": "可选的项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。" }, "explicit": { "type": "boolean", - "description": "Set true only when the user clearly named this destination" + "description": "仅当用户明确点名这个目标时设为 true" } }, "required": [ @@ -64,14 +64,14 @@ }, { "name": "temp_env", - "description": "Return TMP/TEMP/cache environment assignments that keep tool junk inside the project Temp and PI scratch.", + "description": "返回 TMP/TEMP/缓存环境变量赋值,把工具垃圾关在项目 Temp 和 PI scratch。", "risk": "low", "schema": { "type": "object", "properties": { "root": { "type": "string", - "description": "Optional project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection." + "description": "可选的项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。" }, "shell": { "type": "string", @@ -81,21 +81,21 @@ "bash", "json" ], - "description": "Script dialect for the env assignments. Defaults to PowerShell on Windows and bash elsewhere." + "description": "环境变量脚本方言。Windows 默认 PowerShell,其他系统默认 bash。" } } } }, { "name": "tmp_layout", - "description": "Return the recommended $project/Temp/{tests,scripts,cache,out} layout without creating files.", + "description": "返回推荐的 $project/Temp/{tests,scripts,cache,out} 布局,不创建文件。", "risk": "low", "schema": { "type": "object", "properties": { "root": { "type": "string", - "description": "Optional project root override; use only for a root explicitly selected by the user. The tool cannot verify that selection." + "description": "可选的项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。" } } } @@ -112,7 +112,7 @@ "categories": [ "productivity" ], - "changelog": "0.2.7:市场名称改为「C盘防垃圾」;项目垃圾改放到 $project/Temp/;拒绝把 Temp 倾倒目录当项目根。 0.2.6:市场名称改为直白中文。 0.2.5: Quote generated bash and PowerShell assignments safely, reject unsafe cmd values, enforce canonical root/scratch and symlink boundaries, include negative-path tests in CI, and sync the package. 0.2.4:说明改为中文。0.2.3:去掉 git/cwd 作为项目根回退;cmd 环境变量拒绝内嵌引号;覆盖工作区 API 失败与 explicit 临时目录拒绝。0.2.2:相对路径相对工作区解析。0.2.1:explicit 目标与 XDG_DOWNLOAD_DIR。0.2.0:跨机器便携。", + "changelog": "0.2.8:介绍、工具说明和 changelog 全部改为中文。0.2.7:市场名称改为「C盘防垃圾」;项目垃圾改放到 $project/Temp/;拒绝把 Temp 倾倒目录当项目根。0.2.6:市场名称改为直白中文。0.2.5:安全引用 bash/PowerShell 赋值,拒绝不安全的 cmd 值,强制规范 root/scratch 与符号链接边界,CI 加入负向路径测试并同步包装。0.2.4:说明改为中文。0.2.3:去掉 git/cwd 作为项目根回退;cmd 环境变量拒绝内嵌引号;覆盖工作区 API 失败与 explicit 临时目录拒绝。0.2.2:相对路径相对工作区解析。0.2.1:explicit 目标与 XDG_DOWNLOAD_DIR。0.2.0:跨机器便携。", "safetyNotes": "这是行为约束,不是磁盘锁。插件只分类路径并注入 Agent 规则,不改 ACL、不联网。", "activationEvents": [ "onStartup" diff --git a/tests/workspace-file-guard-main.test.js b/tests/workspace-file-guard-main.test.js index b737b78..a7481c6 100644 --- a/tests/workspace-file-guard-main.test.js +++ b/tests/workspace-file-guard-main.test.js @@ -28,7 +28,7 @@ async function run() { const manifest = JSON.parse( fs.readFileSync(path.join(__dirname, "..", "plugins", "pi.workspace-file-guard", "manifest.json"), "utf8") ); - assert(manifest.version === "0.2.7", "manifest version must match the reviewed release"); + assert(manifest.version === "0.2.8", "manifest version must match the reviewed release"); assert( JSON.stringify(manifest.permissions) === JSON.stringify(["agent.prompt.inject", "agent.tool.register"]), "manifest permissions must remain minimal and exact"