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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
314 changes: 68 additions & 246 deletions catalog.json

Large diffs are not rendered by default.

Binary file added packages/pi.workspace-file-guard-0.2.8.piplug
Binary file not shown.
2 changes: 1 addition & 1 deletion plugins/pi.workspace-file-guard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 才会注入。

Expand Down
35 changes: 15 additions & 20 deletions plugins/pi.workspace-file-guard/main.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;正式源码放项目树。",
});
}

Expand All @@ -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: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。",
},
},
},
Expand All @@ -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"],
Expand All @@ -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: "环境变量脚本方言",
},
},
},
Expand All @@ -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: "可选的绝对项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。",
},
},
},
Expand Down
32 changes: 16 additions & 16 deletions plugins/pi.workspace-file-guard/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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盘防垃圾",
Expand All @@ -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": [
Expand All @@ -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",
Expand All @@ -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": "可选的项目根覆盖;仅在用户明确指定时使用。工具无法核实该选择。"
}
}
}
Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion tests/workspace-file-guard-main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading