permission-pi 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,277 @@
1
+ # Permission Extension
2
+
3
+ Layered permission control for pi-coding-agent.
4
+
5
+ ## Levels
6
+
7
+ | Level | Description | Allowed Operations |
8
+ |-------|-------------|-------------------|
9
+ | **minimal** | Read-only (default) | `cat`, `ls`, `grep`, `git status/log/diff`, `npm list` |
10
+ | **low** | File operations | + `write`/`edit` files |
11
+ | **medium** | Dev operations | + `npm install`, `git commit`, build commands |
12
+ | **high** | Full operations | + `git push`, deployments, scripts |
13
+
14
+ **Dangerous commands** (always prompt, even at high): `sudo`, `rm -rf`, `chmod 777`, `dd`, `mkfs`
15
+
16
+ ## Usage
17
+
18
+ ### Interactive Mode
19
+
20
+ ```bash
21
+ # Extension loads automatically from ~/.pi/agent/extensions/ or .pi/extensions/
22
+ pi
23
+ ```
24
+
25
+ **Commands:**
26
+ - `/permission` - Show selector to change level
27
+ - `/permission medium` - Set level directly (asks session/global)
28
+ - `/permission-mode` - Switch between ask/block when permission is required
29
+ - `/permission-mode block` - Block instead of prompting
30
+
31
+ **When a command needs higher permission:**
32
+ ```
33
+ 🔒 Requires Medium: npm install lodash
34
+
35
+ [Allow once] → Execute this command only
36
+ [Allow all (Medium)] → Update global settings and execute
37
+ [Cancel] → Don't execute
38
+ ```
39
+
40
+ If permission mode is set to block, commands that require higher permission are blocked without prompting. Use `/permission-mode ask` to restore prompts.
41
+
42
+ ### Print Mode
43
+
44
+ Permission mode is ignored in print mode; insufficient permissions always block.
45
+
46
+ ```bash
47
+ # Set level via environment variable
48
+ PI_PERMISSION_LEVEL=medium pi -p "install deps and run tests"
49
+
50
+ # Bypass all permission checks (CI/containers - dangerous!)
51
+ PI_PERMISSION_LEVEL=bypassed pi -p "do anything"
52
+ ```
53
+
54
+ **If permission is insufficient:**
55
+ The command is blocked but execution continues. The agent receives:
56
+ ```
57
+ Blocked by permission (minimal). Command: npm install lodash
58
+ Allowed at this level: read-only (cat, ls, grep, git status/diff/log, npm list, version checks)
59
+ User can re-run with: PI_PERMISSION_LEVEL=medium pi -p "..."
60
+ ```
61
+
62
+ The agent can then work around the limitation or inform the user.
63
+
64
+ ## Environment Variables
65
+
66
+ | Variable | Values | Description |
67
+ |----------|--------|-------------|
68
+ | `PI_PERMISSION_LEVEL` | `minimal`, `low`, `medium`, `high`, `bypassed` | Set permission level |
69
+
70
+ ## Settings
71
+
72
+ Global settings stored in `~/.pi/agent/settings.json`:
73
+
74
+ ```json
75
+ {
76
+ "permissionLevel": "medium",
77
+ "permissionMode": "ask"
78
+ }
79
+ ```
80
+
81
+ `permissionMode` accepts `ask` (prompt) or `block` (deny without prompting).
82
+
83
+ ## Custom Configuration
84
+
85
+ Configure permission overrides and prefix mappings in `~/.pi/agent/settings.json`:
86
+
87
+ ```json
88
+ {
89
+ "permissionLevel": "medium",
90
+ "permissionMode": "ask",
91
+ "permissionConfig": {
92
+ "overrides": {
93
+ "minimal": ["tmux list-*", "tmux show-*"],
94
+ "medium": ["tmux attach*", "tmux new*"],
95
+ "high": ["rm -rf *"],
96
+ "dangerous": ["dd if=* of=/dev/*"]
97
+ },
98
+ "prefixMappings": [
99
+ { "from": "fvm flutter", "to": "flutter" },
100
+ { "from": "nvm exec", "to": "" },
101
+ { "from": "rbenv exec", "to": "" }
102
+ ]
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Override Patterns
108
+
109
+ Glob patterns matched against the full command:
110
+ - `*` matches any characters
111
+ - `?` matches single character
112
+ - Patterns are case-insensitive
113
+
114
+ Override priority (highest to lowest):
115
+ 1. `dangerous` - Always prompt, even at high level
116
+ 2. `high` - Require high permission
117
+ 3. `medium` - Require medium permission
118
+ 4. `low` - Require low permission
119
+ 5. `minimal` - Allow at minimal (read-only)
120
+
121
+ > **Note:** When a command matches patterns in multiple levels, the **most restrictive** level wins. Avoid overlapping patterns across levels. For example, don't put `tmux *` in medium if you want `tmux list-*` to be minimal.
122
+
123
+ **Examples:**
124
+ ```json
125
+ {
126
+ "overrides": {
127
+ "minimal": [
128
+ "tmux list-*", // tmux list-sessions, tmux list-windows, etc.
129
+ "tmux show-*", // tmux show-options, tmux show-messages, etc.
130
+ "screen -list" // List screen sessions
131
+ ],
132
+ "medium": [
133
+ "tmux attach*", // Attach to sessions
134
+ "tmux new*", // Create new sessions
135
+ "screen -r *" // Reattach to screen
136
+ ],
137
+ "high": [
138
+ "rm -rf *", // Force rm with any arguments
139
+ "dd of=/dev/*" // dd writing to any device
140
+ ],
141
+ "dangerous": [
142
+ "dd if=* of=/dev/*" // dd writing to device from any source
143
+ ]
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### Prefix Mappings
149
+
150
+ Normalize version manager commands to their base tools:
151
+ - `fvm flutter build` → treated as `flutter build` (medium)
152
+ - `rbenv exec ruby` → treated as `ruby` (classified normally)
153
+
154
+ **Common mappings:**
155
+ ```json
156
+ {
157
+ "prefixMappings": [
158
+ { "from": "fvm flutter", "to": "flutter" },
159
+ { "from": "nvm exec", "to": "" },
160
+ { "from": "rbenv exec", "to": "" },
161
+ { "from": "pyenv exec", "to": "" }
162
+ ]
163
+ }
164
+ ```
165
+
166
+ **How it works:**
167
+ 1. Commands are checked against prefix mappings first
168
+ 2. If a prefix matches, it's replaced with the mapped value
169
+ 3. The normalized command is then classified
170
+
171
+ ### /permission config Command
172
+
173
+ View and manage configuration from the CLI:
174
+
175
+ ```
176
+ /permission config show # Display current configuration
177
+ /permission config reset # Reset to default (empty)
178
+ ```
179
+
180
+ Edit `~/.pi/agent/settings.json` directly for full control.
181
+
182
+ ## Command Classification
183
+
184
+ The principle: **building/installing is MEDIUM, running code is HIGH**.
185
+
186
+ ### Minimal Level (Read-only)
187
+ - File reading: `cat`, `less`, `head`, `tail`, `bat`
188
+ - Directory: `ls`, `tree`, `pwd`, `find`, `fd`
189
+ - Search: `grep`, `rg`, `ag`
190
+ - Info: `echo`, `whoami`, `date`, `uname`, `ps`, `env`
191
+ - Git read: `git status`, `git log`, `git diff`, `git show`, `git branch`, `git fetch`
192
+ - Package info: `npm list`, `pip list`, `cargo tree`
193
+
194
+ ### Medium Level (Build/Install/Test - Reversible)
195
+ - **Node.js**: `npm install/ci/test/build`, `yarn install/add/build/test`, `pnpm`, `bun`
196
+ - **npm run** (safe scripts only): `build`, `test`, `lint`, `format`, `check`, `typecheck`
197
+ - **Python**: `pip install`, `poetry install/build`, `pytest`
198
+ - **Rust**: `cargo build/test/check/clippy/fmt` (NOT `cargo run`)
199
+ - **Go**: `go build/test/get/mod` (NOT `go run`)
200
+ - **Ruby**: `gem install`, `bundle install`
201
+ - **CocoaPods**: `pod install`, `pod update`, `pod repo update`
202
+ - **PHP**: `composer install`
203
+ - **Java**: `mvn compile/test`, `gradle build/test`
204
+ - **.NET**: `dotnet build/test`
205
+ - **Git local**: `git add`, `git commit`, `git pull`, `git checkout`, `git merge`, `git clone`
206
+ - **Build tools**: `make`, `cmake`, `ninja`
207
+ - **Linters**: All static analysis tools that only check/report without executing code
208
+ - **JavaScript/TypeScript**: `eslint`, `prettier`, `tsc --noEmit`, `tslint`, `standard`, `xo`
209
+ - **Python**: `pylint`, `flake8`, `black`, `mypy`, `pyright`, `ruff`, `pyflakes`, `bandit`
210
+ - **Rust**: `cargo clippy`, `cargo fmt`, `rustfmt`
211
+ - **Go**: `gofmt`, `go vet`, `golangci-lint`, `golint`, `staticcheck`, `errcheck`, `misspell`
212
+ - **Ruby**: `rubocop`, `standardrb`, `reek`, `brakeman`
213
+ - **Swift**: `swiftlint`, `swiftformat`
214
+ - **Kotlin**: `ktlint`, `detekt`
215
+ - **Dart/Flutter**: `dart analyze`, `flutter analyze`, `dart format`, `flutter format`
216
+ - **C/C++**: `clang-tidy`, `clang-format`, `cppcheck`
217
+ - **Java**: `checkstyle`, `pmd`, `spotbugs`, `error-prone`
218
+ - **C#**: `dotnet format`, `dotnet build -t:RunCodeAnalysis`
219
+ - **PHP**: `phpcs`, `phpmd`, `phpstan`, `psalm`, `php-cs-fixer`
220
+ - **Lua**: `luacheck`
221
+ - **Shell**: `shellcheck`
222
+ - **Infrastructure as Code**: `checkov`, `tflint`, `terraform validate`
223
+ - **Protocol Buffers**: `buf lint`, `protoc --lint`
224
+ - **SQL**: `sqlfluff`
225
+ - **YAML**: `yamllint`
226
+ - **Markdown**: `markdownlint`
227
+ - **HTML/Django**: `djlint`, `djhtml`
228
+ - **Git**: `commitlint`
229
+ - **File ops**: `mkdir`, `touch`, `cp`, `mv`
230
+
231
+ ### High Level (Runs Code / Irreversible)
232
+ - **Running code**: `python script.py`, `node app.js`, `cargo run`, `go run`
233
+ - **npm run** (unsafe scripts): `dev`, `start`, `serve`, `watch`, `preview`
234
+ - **Package executors**: `npx`, `bunx`, `pnpx` (run arbitrary packages)
235
+ - **Git remote**: `git push`, `git push --force`
236
+ - **Git irreversible**: `git reset --hard`, `git clean`, `git restore`
237
+ - **Network**: `curl`, `wget` (can't verify trusted endpoints)
238
+ - **Deployment**: `docker push`, `kubectl`, `helm`, `terraform`
239
+ - **Remote access**: `ssh`, `scp`, `rsync`
240
+ - **Shell execution**: `eval`, `exec`, `source`, `xargs`
241
+
242
+ ### Dangerous (Always Prompt)
243
+ - `sudo` (any form)
244
+ - `rm` with `-r` AND `-f` flags
245
+ - `chmod 777` or `a+rwx`
246
+ - `dd of=/dev/...`
247
+ - `mkfs`, `mkfs.ext4`, `fdisk`, `parted`
248
+ - `shutdown`, `reboot`, `halt`, `poweroff`
249
+
250
+ ## Shell Trick Detection
251
+
252
+ Commands containing these patterns require HIGH permission:
253
+ - Command substitution: `$(cmd)`, `` `cmd` ``
254
+ - Process substitution: `<(cmd)`, `>(cmd)`
255
+ - Dangerous expansions: `${VAR:-$(cmd)}` (nested command substitution)
256
+
257
+ ## Installation
258
+
259
+ Install the package and enable extensions:
260
+ ```bash
261
+ pi install git:github.com/prateekmedia/pi-hooks
262
+ pi config
263
+ ```
264
+
265
+ Dependencies are installed automatically during `pi install`.
266
+
267
+ ## File Structure
268
+
269
+ | File | Purpose |
270
+ |------|---------|
271
+ | `permission.ts` | Extension (entry point + state management + handlers) |
272
+ | `permission-core.ts` | Core permission logic (classification, config) |
273
+ | `package.json` | Declares extension via "pi" field |
274
+
275
+ ## License
276
+
277
+ MIT
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "permission-pi",
3
+ "version": "1.0.1",
4
+ "description": "Layered permission control extension for pi-coding-agent",
5
+ "type": "module",
6
+ "scripts": {
7
+ "test": "npx tsx tests/permission.test.ts"
8
+ },
9
+ "keywords": [
10
+ "permission",
11
+ "security",
12
+ "pi-coding-agent",
13
+ "extension",
14
+ "pi-package"
15
+ ],
16
+ "author": "",
17
+ "license": "MIT",
18
+ "pi": {
19
+ "extensions": ["./permission.ts"]
20
+ },
21
+ "dependencies": {
22
+ "shell-quote": "^1.8.3"
23
+ },
24
+ "devDependencies": {
25
+ "@mariozechner/pi-coding-agent": "^0.50.0",
26
+ "@types/node": "^25.0.3",
27
+ "typescript": "^5.9.3"
28
+ }
29
+ }