mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
配置统一:权限策略、硬防御、Tool Search、提示词封面以及新迁入的 RTK、pi-compaction、pi-worktree、pi-hermes-memory 配置全部由扩展 直接读取已安装组合包内的 config/,pi install / pi update 即完成部署; 删除 rebuild-bundle-config.mjs 与 bundle-manifest.json,my-pi/ 只保留 日志与缓存。update.sh 成功升级后将默认 git 来源的已安装副本 reset 回发布版本。AGENTS.md 新增「组合包配置原则」。 脚本整合:search_config.sh / ssh_config.sh 合并为 configure.sh search|ssh;install.sh / update.sh 共享函数抽到 scripts/lib.sh,远程 安装器改为先下载到临时文件再执行,下载失败可被检测。 权限:hard-guards 新增 protectedWrites,写入 Pi 凭据/设置、已安装 组合包与扩展目录、pi-ssh 凭据库时一律人工确认(跳过 AutoReview、 yolo 与 Session grant,无 UI 时拒绝);放行 ls、LSP 查询、ctx 只读、 web_search、Chrome 只读与 git 只读命令,skill_manage 改为 ask。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
150 lines
12 KiB
Markdown
150 lines
12 KiB
Markdown
<p align="center">
|
|
<img src="docs/assets/logo.png" alt="pi-permission-system logo">
|
|
</p>
|
|
|
|
# @gotgenes/pi-permission-system
|
|
|
|
[](https://www.npmjs.com/package/@gotgenes/pi-permission-system) [](https://github.com/gotgenes/pi-packages/actions/workflows/ci.yml) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/) [](https://pnpm.io/) [](https://pi.mariozechner.at/)
|
|
|
|
Permission enforcement extension for the [Pi](https://pi.mariozechner.at/) coding agent that provides centralized, deterministic permission gates over tool, bash, MCP, skill, and special operations.
|
|
|
|
> **Fork notice:** This package is a full fork of [MasuRii/pi-permission-system](https://github.com/MasuRii/pi-permission-system), published to npm as `@gotgenes/pi-permission-system`.
|
|
> It has diverged substantially from upstream in config format, internal architecture, and permission model.
|
|
>
|
|
> **my-pi maintenance note:** This directory was imported from upstream tag `pi-permission-system-v26.2.1` at commit `ec4fdb11343dc94f7185b113e559a4cf9f8dc035`. It is loaded from source and maintained directly by my-pi; npm `dist` output is not used. my-pi uses one global ordinary policy and a separate non-overridable hard-guard file; explicitly configured authorizers may approve any ordinary-policy `ask`, including `path`.
|
|
|
|
## What It Does
|
|
|
|
- **Enforces `allow` / `ask` / `deny`** at tool-call time with UI confirmation dialogs
|
|
- **Uses one global ordinary policy file**; project `policy.jsonc` files are not loaded
|
|
- **Chooses the most specific matching pattern**, so a specific deny wins over a broad `"*": "allow"` regardless of declaration order
|
|
- **Applies a separate hard-guard policy first** so session grants, per-agent rules, and model review cannot override high-risk denies
|
|
- **Keeps protected writes human-only**: files listed in `protectedWrites` (Pi credentials, settings, the installed bundle itself, …) always reach the local human prompt — never AutoReview, never yolo, never a session grant — and are denied when no confirmation UI exists. Reads are unaffected.
|
|
- **Controls Bash, paths, MCP, skills, and tool surfaces** while leaving active-tool ownership entirely to Tool Search
|
|
- **Reviews ordinary `ask` requests automatically** with integrated AutoReview; its `allow` verdict is final for ordinary tools and `path`, while `defer` reaches the next authorizer or human terminal
|
|
- **Follows the session's current model**: AutoReview asks the model you are already chatting with to judge each ask, so the review always reflects the model the operator actually selected; set `autoReview.provider` and `autoReview.model` together to pin a different reviewer
|
|
- **Decides through tool calls only**: the reviewer reaches its verdict by calling exactly one of two tools, `approve` or `reject`, each carrying a reason — prose answers, even well-formed JSON, are ignored
|
|
- **Never hard-denies on a refusal or failure**: a `reject` verdict or any review failure defers the ask to the human prompt, with the model's reason shown and labelled model-generated
|
|
- **Forwards subagent `ask` decisions** to the parent authority and keeps structured audit logs
|
|
|
|
## Install
|
|
|
|
```bash
|
|
pi install npm:@gotgenes/pi-permission-system
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
1. Ordinary policy lives in the installed bundle at `config/pi-permission-policy.jsonc` (the bundle repository's `config/` directory — edit it there for durable changes):
|
|
|
|
```jsonc
|
|
{
|
|
"authorizerChain": ["auto-review"],
|
|
"autoReview": { "enabled": true },
|
|
"permission": {
|
|
"*": "ask",
|
|
"read": "allow",
|
|
"bash": {
|
|
"*": "ask",
|
|
"git status*": "allow"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
2. Independent hard guards live beside it at `config/pi-permission-hard-guards.jsonc`:
|
|
|
|
```jsonc
|
|
{
|
|
"version": 1,
|
|
"permission": {
|
|
"*": "allow",
|
|
"*.env": "deny",
|
|
"*.env.*": "deny",
|
|
"*.env.example": "allow",
|
|
"~/.ssh/**": "deny"
|
|
},
|
|
"protectedWrites": [
|
|
{ "pattern": "{agentDir}/auth.json", "label": "Pi credentials" }
|
|
]
|
|
}
|
|
```
|
|
|
|
3. Restart Pi or run `/reload`. Ordinary `ask` requests now reach AutoReview first; only `defer` opens the human dialog.
|
|
|
|
The `path` surface is a cross-cutting gate that applies to **all** file access — Pi tools, bash commands, MCP calls, and extension tools alike.
|
|
Extension and MCP tools that operate on paths (via `input.path`, a unified `mcp` proxy tool's `input.arguments.path`, or a registered access extractor) are gated by default, so a `path` deny cannot be overridden by a per-tool allow — making it the right place to protect sensitive files like `.env` or `~/.ssh/*` from every tool at once.
|
|
A `path` pattern matches both the path as the agent references it and its canonical (symlink-resolved) form, so a deny still fires when a symlink aliases a sensitive target.
|
|
|
|
For per-tool path patterns (`read`, `write`, `edit`, `find`, `grep`, `ls`), patterns are matched against the file path from `input.path`.
|
|
This lets you express rules like "allow reads but deny `.env` files" at the individual tool level.
|
|
Like the cross-cutting `path` surface, per-tool patterns match both the referenced path and its canonical (symlink-resolved) form, so a per-tool deny resists symlink-alias evasion.
|
|
When Pi's current working directory is known, relative path inputs also match their cwd-normalized absolute form, so `src/App.jsx` can match both `src/*` and `/workspace/project/*`.
|
|
|
|
Paths outside the working tree have no separate boundary gate. Configure them with the same `path`, per-tool, and Bash patterns used for in-project paths. These layers still compose with most-restrictive-wins.
|
|
See [docs/configuration.md](docs/configuration.md) for the full recipe.
|
|
|
|
## Configuration
|
|
|
|
The integrated extension uses two independent global JSONC files:
|
|
|
|
| Purpose | Scope | Path |
|
|
| ------- | ----- | ---- |
|
|
| Ordinary policy, runtime knobs, AutoReview | Global only | `config/pi-permission-policy.jsonc` inside the installed bundle |
|
|
| Non-overridable hard guards | Global only | `config/pi-permission-hard-guards.jsonc` inside the installed bundle |
|
|
|
|
Project-level `policy.jsonc` files are ignored. Project agent Markdown remains a separate per-agent restriction mechanism.
|
|
|
|
Both files are read directly from the bundle's `config/` directory — the single source of truth. Nothing is deployed to, seeded into, or migrated from the agent directory; `pi update` refreshes them with the bundle. Files left at the former `~/.pi/agent/my-pi/permission-system/` location are ignored.
|
|
|
|
Within a pattern map, the most specific match wins: exact patterns, then more literal characters, fewer wildcards, and longer patterns. Declaration order is only a tie-breaker.
|
|
|
|
There is no `external_directory` gate. Outside-CWD paths use the same configured tool, `path`, and Bash rules as other paths.
|
|
|
|
Tool Search alone owns Pi's active tool list. Permission System only decides whether an invoked tool call is allowed, denied, or requires confirmation.
|
|
|
|
See [docs/configuration.md](docs/configuration.md) for the complete reference, including the [protected writes](docs/configuration.md#protected-writes) format in the hard-guard file.
|
|
|
|
## Documentation
|
|
|
|
| Document | Contents |
|
|
| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
| [docs/configuration.md](docs/configuration.md) | Full policy reference, runtime knobs, per-agent overrides, recipes |
|
|
| [docs/session-approvals.md](docs/session-approvals.md) | Session-scoped rules, pattern suggestions, bash arity table |
|
|
| [docs/cross-extension-api.md](docs/cross-extension-api.md) | Cross-extension service accessor, event bus integration, prompt and decision broadcasts |
|
|
| [docs/subagent-integration.md](docs/subagent-integration.md) | Permission forwarding, coexistence with subagent extensions |
|
|
| [docs/guides/permission-frontmatter-for-subagent-extensions.md](docs/guides/permission-frontmatter-for-subagent-extensions.md) | Convention guide for subagent extension authors |
|
|
| [docs/opencode-compatibility.md](docs/opencode-compatibility.md) | OpenCode compatibility — shared concepts, divergences, porting guide |
|
|
| [docs/troubleshooting.md](docs/troubleshooting.md) | Common issues, diagnostic logging, threat model |
|
|
| [docs/migration/legacy-to-flat.md](docs/migration/legacy-to-flat.md) | Migration from pre-v2 config layout |
|
|
| [docs/migration/strict-config-validation.md](docs/migration/strict-config-validation.md) | Strict config validation (breaking) — rejected configs, and the cross-scope fail-closed clamp |
|
|
| [docs/migration/0644-project-trust-gating.md](docs/migration/0644-project-trust-gating.md) | Project-trust gating (breaking) — project config loads only after project trust |
|
|
| [docs/migration/0745-prompt-payload-contracts.md](docs/migration/0745-prompt-payload-contracts.md) | Prompt payload contracts (breaking) — the forwarded wire, the `ui_prompt` broadcast, and the deprecated preview caps |
|
|
| [docs/migration/0746-review-log-fields.md](docs/migration/0746-review-log-fields.md) | Review-log fields (breaking) — `message` replaced by request facts, and the `reviewLogFieldMaxWidth` bound |
|
|
|
|
## Development
|
|
|
|
```bash
|
|
pnpm run check # Type-check TypeScript (no emit)
|
|
pnpm run lint # Biome + ESLint + lint:md
|
|
pnpm run lint:md # rumdl on README and docs
|
|
pnpm run test # Run tests from ./test
|
|
pnpm run test:watch # Run tests in watch mode
|
|
```
|
|
|
|
### Pre-commit hooks
|
|
|
|
This project uses [prek](https://prek.j178.dev/) to run Biome, ESLint, and rumdl on staged files before each commit.
|
|
Run `pnpm install` to set up hooks automatically.
|
|
|
|
## Acknowledgments
|
|
|
|
This project began as a fork of [MasuRii/pi-permission-system](https://github.com/MasuRii/pi-permission-system).
|
|
Thank you to [MasuRii](https://github.com/MasuRii) for the original work that made this possible.
|
|
|
|
Thank you to the [OpenCode](https://opencode.ai) team for the permission model design that inspired the flat config format and evaluation semantics used in this extension.
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|