pi-permission-system 0.1.0
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/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +421 -0
- package/config/config.example.json +27 -0
- package/index.ts +3 -0
- package/package.json +50 -0
- package/schemas/permissions.schema.json +86 -0
- package/src/bash-filter.ts +77 -0
- package/src/index.ts +826 -0
- package/src/permission-manager.ts +651 -0
- package/src/test.ts +297 -0
- package/src/tool-registry.ts +148 -0
- package/src/types.ts +43 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-03-02
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Reorganized repository structure to match standard extension layout:
|
|
14
|
+
- moved implementation and tests into `src/`
|
|
15
|
+
- added root `index.ts` shim for Pi auto-discovery
|
|
16
|
+
- standardized TypeScript project settings with Bundler module resolution
|
|
17
|
+
- Added package distribution metadata and scripts, including `pi.extensions` and publish file whitelist.
|
|
18
|
+
- Added repository scaffolding files (`README.md`, `CHANGELOG.md`, `LICENSE`, `.gitignore`, `.npmignore`) and config starter template.
|
|
19
|
+
|
|
20
|
+
### Preserved
|
|
21
|
+
- Global permission config path semantics remained `~/.pi/agent/pi-permissions.jsonc`.
|
|
22
|
+
- Permission schema location remained `schemas/permissions.schema.json`.
|
|
23
|
+
- Permission enforcement behavior remained intact.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MasuRii
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# pi-permission-system
|
|
2
|
+
|
|
3
|
+
Permission enforcement extension for the Pi coding agent.
|
|
4
|
+
|
|
5
|
+
This extension enforces **tool**, **bash**, **MCP**, **skill**, and a small set of **special** permission policies.
|
|
6
|
+
It is designed to reduce accidental or policy-violating actions by:
|
|
7
|
+
|
|
8
|
+
- hiding disallowed tools from the agent *before it starts* (reduces “try another tool” behavior), and
|
|
9
|
+
- blocking/asking/allowing at **tool call time** (the actual enforcement point).
|
|
10
|
+
|
|
11
|
+
> Global runtime policy file (JSON-with-comments):
|
|
12
|
+
>
|
|
13
|
+
> `~/.pi/agent/pi-permissions.jsonc`
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Threat model / goal
|
|
20
|
+
|
|
21
|
+
**Goal:** Provide a centralized, deterministic permission gate for the Pi agent runtime so that *policy is enforced by the host*, not by the model.
|
|
22
|
+
|
|
23
|
+
**Threat model (what this is meant to stop):**
|
|
24
|
+
|
|
25
|
+
- The agent calling tools it should not use (e.g., `write`, dangerous `bash`, broad MCP actions).
|
|
26
|
+
- “Tool switching” attempts (agent tries a different tool name or a server tool directly).
|
|
27
|
+
- Accidental escalation via skill loading or reading skill files from disk.
|
|
28
|
+
|
|
29
|
+
**Non-goals / limitations:**
|
|
30
|
+
|
|
31
|
+
- If a dangerous action is possible using an allowed tool (e.g., destructive shell commands via allowed `bash`), policy must explicitly restrict that.
|
|
32
|
+
- This is not a sandbox; it is a permission decision layer.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## How it integrates with Pi
|
|
37
|
+
|
|
38
|
+
This extension integrates via Pi’s extension lifecycle hooks:
|
|
39
|
+
|
|
40
|
+
- `before_agent_start`
|
|
41
|
+
- Filters the active tool list via `pi.setActiveTools(...)` based on the resolved permission policy.
|
|
42
|
+
- Filters the `<available_skills> ... </available_skills>` section in the system prompt so skills with `deny` are removed.
|
|
43
|
+
- `tool_call`
|
|
44
|
+
- Enforces permissions for every tool call.
|
|
45
|
+
- When a permission is `ask`, it prompts the user via the UI confirmation dialog.
|
|
46
|
+
- `input`
|
|
47
|
+
- Intercepts `/skill:<name>` requests and enforces the `skills` policy before the skill is loaded.
|
|
48
|
+
|
|
49
|
+
Additional enforcement behaviors:
|
|
50
|
+
|
|
51
|
+
- **Unknown/unregistered tools are blocked** before permission checks (prevents bypass via calling non-existent tool names).
|
|
52
|
+
- The delegation tool **`task` is restricted to the `orchestrator` agent**.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
### Local extension folder
|
|
59
|
+
|
|
60
|
+
Place this folder in one of:
|
|
61
|
+
|
|
62
|
+
- Global: `~/.pi/agent/extensions/pi-permission-system`
|
|
63
|
+
- Project: `.pi/extensions/pi-permission-system`
|
|
64
|
+
|
|
65
|
+
Pi auto-discovers these paths.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Configuration
|
|
70
|
+
|
|
71
|
+
### Global policy file (required)
|
|
72
|
+
|
|
73
|
+
Runtime policy is loaded from:
|
|
74
|
+
|
|
75
|
+
- `~/.pi/agent/pi-permissions.jsonc`
|
|
76
|
+
|
|
77
|
+
Notes:
|
|
78
|
+
|
|
79
|
+
- The file is parsed as JSON after stripping `// ...` and `/* ... */` comments.
|
|
80
|
+
- Trailing commas are **not** supported (it still uses `JSON.parse` after comment stripping).
|
|
81
|
+
- If the file cannot be read or parsed, the extension falls back to an empty config with a default of **`ask`** for all categories.
|
|
82
|
+
|
|
83
|
+
### Per-agent overrides (frontmatter)
|
|
84
|
+
|
|
85
|
+
Per-agent overrides are loaded from the agent markdown file:
|
|
86
|
+
|
|
87
|
+
- `~/.pi/agent/agents/<agent>.md`
|
|
88
|
+
|
|
89
|
+
Add a YAML frontmatter block at the top of the agent file and include a `permission:` map.
|
|
90
|
+
Example:
|
|
91
|
+
|
|
92
|
+
```md
|
|
93
|
+
---
|
|
94
|
+
name: my-agent
|
|
95
|
+
permission:
|
|
96
|
+
defaultPolicy:
|
|
97
|
+
tools: ask
|
|
98
|
+
bash: ask
|
|
99
|
+
mcp: ask
|
|
100
|
+
skills: ask
|
|
101
|
+
special: ask
|
|
102
|
+
|
|
103
|
+
# Recommended: configure permissions by section.
|
|
104
|
+
tools:
|
|
105
|
+
read: allow
|
|
106
|
+
write: deny
|
|
107
|
+
bash: ask
|
|
108
|
+
|
|
109
|
+
# Alternative (equivalent): direct tool keys also work, but avoid duplicates.
|
|
110
|
+
# read: allow
|
|
111
|
+
# write: deny
|
|
112
|
+
|
|
113
|
+
bash:
|
|
114
|
+
git status: allow
|
|
115
|
+
git *: ask
|
|
116
|
+
|
|
117
|
+
mcp:
|
|
118
|
+
mcp_status: allow
|
|
119
|
+
# Prefer the underscore form in frontmatter (no ':' parsing edge cases):
|
|
120
|
+
myServer_*: ask
|
|
121
|
+
|
|
122
|
+
skills:
|
|
123
|
+
"*": ask
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
# Agent prompt
|
|
127
|
+
...
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Precedence:** agent frontmatter overrides global config (shallow-merged per section).
|
|
131
|
+
|
|
132
|
+
**Frontmatter parser limitations:** the agent override parser is intentionally minimal (a simple YAML-ish map parser). Stick to:
|
|
133
|
+
|
|
134
|
+
- `key: value` scalars and nested maps via indentation
|
|
135
|
+
- `#` comments
|
|
136
|
+
|
|
137
|
+
Avoid advanced YAML features (arrays, multi-line scalars, anchors, etc.).
|
|
138
|
+
|
|
139
|
+
**Reload behavior:**
|
|
140
|
+
|
|
141
|
+
- Global config (`pi-permissions.jsonc`) is re-read during permission checks, so edits typically apply immediately.
|
|
142
|
+
- Agent frontmatter overrides are cached for some checks (notably tool exposure/mapping). If an override change does not appear to apply, restart the session.
|
|
143
|
+
|
|
144
|
+
### Config example
|
|
145
|
+
|
|
146
|
+
A starter template is provided at:
|
|
147
|
+
|
|
148
|
+
- `config/config.example.json`
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Policy reference
|
|
153
|
+
|
|
154
|
+
The policy file is a JSON object with these top-level keys:
|
|
155
|
+
|
|
156
|
+
- `defaultPolicy` (required)
|
|
157
|
+
- `tools` (built-in tools)
|
|
158
|
+
- `bash` (command patterns)
|
|
159
|
+
- `mcp` (MCP target patterns)
|
|
160
|
+
- `skills` (skill name patterns)
|
|
161
|
+
- `special` (reserved/special checks)
|
|
162
|
+
|
|
163
|
+
All permission states are one of:
|
|
164
|
+
|
|
165
|
+
- `allow`
|
|
166
|
+
- `deny`
|
|
167
|
+
- `ask` (requires UI confirmation)
|
|
168
|
+
|
|
169
|
+
### `defaultPolicy`
|
|
170
|
+
|
|
171
|
+
Sets defaults when no specific rule matches.
|
|
172
|
+
|
|
173
|
+
```jsonc
|
|
174
|
+
{
|
|
175
|
+
"defaultPolicy": {
|
|
176
|
+
"tools": "ask",
|
|
177
|
+
"bash": "ask",
|
|
178
|
+
"mcp": "ask",
|
|
179
|
+
"skills": "ask",
|
|
180
|
+
"special": "ask"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `tools`
|
|
186
|
+
|
|
187
|
+
Controls built-in tools by exact name (no wildcard matching):
|
|
188
|
+
|
|
189
|
+
- `bash`, `read`, `write`, `edit`, `grep`, `find`, `ls`
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
|
|
193
|
+
```jsonc
|
|
194
|
+
{
|
|
195
|
+
"tools": {
|
|
196
|
+
"read": "allow",
|
|
197
|
+
"write": "deny",
|
|
198
|
+
"edit": "deny"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Bash nuance:** setting `tools.bash` affects the *default* decision for bash commands, but `bash` patterns (see below) can still provide command-level allow/deny/ask.
|
|
204
|
+
|
|
205
|
+
### `bash`
|
|
206
|
+
|
|
207
|
+
Command permissions are matched against the full command string using `*` wildcards.
|
|
208
|
+
Patterns are anchored (`^...$`) and matched by specificity:
|
|
209
|
+
|
|
210
|
+
1. fewer `*` wildcards wins
|
|
211
|
+
2. then longer literal text wins
|
|
212
|
+
3. then longer overall pattern wins
|
|
213
|
+
|
|
214
|
+
Example:
|
|
215
|
+
|
|
216
|
+
```jsonc
|
|
217
|
+
{
|
|
218
|
+
"bash": {
|
|
219
|
+
"git status": "allow",
|
|
220
|
+
"git *": "ask",
|
|
221
|
+
"rm -rf *": "deny"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### `skills`
|
|
227
|
+
|
|
228
|
+
Matches skill names using `*` wildcards (same specificity approach as above).
|
|
229
|
+
|
|
230
|
+
```jsonc
|
|
231
|
+
{
|
|
232
|
+
"skills": {
|
|
233
|
+
"*": "ask",
|
|
234
|
+
"dangerous-*": "deny"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### `mcp`
|
|
240
|
+
|
|
241
|
+
MCP permissions match against a set of derived “targets” from the `mcp` tool input. You can write rules against:
|
|
242
|
+
|
|
243
|
+
- baseline operations: `mcp_status`, `mcp_list`, `mcp_search`, `mcp_describe`, `mcp_connect`
|
|
244
|
+
- the server name (e.g. `myServer`)
|
|
245
|
+
- server/tool combinations (e.g. `myServer:search`, `myServer_search`)
|
|
246
|
+
- generic categories like `mcp_call`
|
|
247
|
+
|
|
248
|
+
Example:
|
|
249
|
+
|
|
250
|
+
```jsonc
|
|
251
|
+
{
|
|
252
|
+
"mcp": {
|
|
253
|
+
"mcp_status": "allow",
|
|
254
|
+
"mcp_list": "allow",
|
|
255
|
+
"mcp_search": "allow",
|
|
256
|
+
|
|
257
|
+
"myServer": "ask",
|
|
258
|
+
"myServer:*": "ask",
|
|
259
|
+
|
|
260
|
+
"dangerousServer": "deny"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Baseline auto-allow behavior:** when you allow *any* MCP rule (or set `defaultPolicy.mcp` to `allow`), baseline discovery targets like `mcp_status` may be auto-allowed to support normal MCP discovery flows.
|
|
266
|
+
|
|
267
|
+
### `special`
|
|
268
|
+
|
|
269
|
+
The schema includes these keys:
|
|
270
|
+
|
|
271
|
+
- `doom_loop`
|
|
272
|
+
- `external_directory`
|
|
273
|
+
- `tool_call_limit`
|
|
274
|
+
|
|
275
|
+
Only `doom_loop` and `external_directory` are recognized as “special permission names” by this extension’s permission manager.
|
|
276
|
+
`tool_call_limit` is present in the schema for forward compatibility and is **not enforced by this extension version**.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Schema reference & validation
|
|
281
|
+
|
|
282
|
+
- Schema file (in this repo): `schemas/permissions.schema.json`
|
|
283
|
+
|
|
284
|
+
How to validate:
|
|
285
|
+
|
|
286
|
+
1. Ensure your config is valid JSON (remove comments if your validator does not support JSONC).
|
|
287
|
+
2. Use any JSON Schema validator against `schemas/permissions.schema.json`.
|
|
288
|
+
|
|
289
|
+
Example (Ajv CLI):
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Validate a comment-free copy of your config
|
|
293
|
+
npx --yes ajv-cli@5 validate \
|
|
294
|
+
-s ./schemas/permissions.schema.json \
|
|
295
|
+
-d ./pi-permissions.valid.json
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Editor tip: you may add a `$schema` field to your config so editors can provide autocomplete/validation.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Common recipes
|
|
303
|
+
|
|
304
|
+
### 1) Read-only by default (deny writes)
|
|
305
|
+
|
|
306
|
+
```jsonc
|
|
307
|
+
{
|
|
308
|
+
"defaultPolicy": { "tools": "ask", "bash": "ask", "mcp": "ask", "skills": "ask", "special": "ask" },
|
|
309
|
+
"tools": {
|
|
310
|
+
"read": "allow",
|
|
311
|
+
"grep": "allow",
|
|
312
|
+
"find": "allow",
|
|
313
|
+
"ls": "allow",
|
|
314
|
+
|
|
315
|
+
"write": "deny",
|
|
316
|
+
"edit": "deny"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 2) Allow only a small bash surface
|
|
322
|
+
|
|
323
|
+
```jsonc
|
|
324
|
+
{
|
|
325
|
+
"defaultPolicy": { "tools": "ask", "bash": "deny", "mcp": "ask", "skills": "ask", "special": "ask" },
|
|
326
|
+
"bash": {
|
|
327
|
+
"git status": "allow",
|
|
328
|
+
"git diff": "allow",
|
|
329
|
+
"git *": "ask"
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 3) Allow MCP discovery, ask on server calls
|
|
335
|
+
|
|
336
|
+
```jsonc
|
|
337
|
+
{
|
|
338
|
+
"defaultPolicy": { "tools": "ask", "bash": "ask", "mcp": "ask", "skills": "ask", "special": "ask" },
|
|
339
|
+
"mcp": {
|
|
340
|
+
"mcp_status": "allow",
|
|
341
|
+
"mcp_list": "allow",
|
|
342
|
+
"mcp_search": "allow",
|
|
343
|
+
"mcp_describe": "allow",
|
|
344
|
+
|
|
345
|
+
"*": "ask"
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### 4) Tighten one agent only (frontmatter override)
|
|
351
|
+
|
|
352
|
+
In `~/.pi/agent/agents/reviewer.md`:
|
|
353
|
+
|
|
354
|
+
```md
|
|
355
|
+
---
|
|
356
|
+
permission:
|
|
357
|
+
tools:
|
|
358
|
+
write: deny
|
|
359
|
+
edit: deny
|
|
360
|
+
bash:
|
|
361
|
+
"*": deny
|
|
362
|
+
---
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Troubleshooting
|
|
368
|
+
|
|
369
|
+
### “My config isn’t applied (everything still asks)”
|
|
370
|
+
|
|
371
|
+
- Confirm the file is at `~/.pi/agent/pi-permissions.jsonc`.
|
|
372
|
+
- Check for JSON parse errors (common causes: trailing commas, missing quotes).
|
|
373
|
+
- If parsing fails, the extension silently falls back to an empty config (defaults to `ask`).
|
|
374
|
+
|
|
375
|
+
### “My per-agent override isn’t applied”
|
|
376
|
+
|
|
377
|
+
- Confirm the file exists at `~/.pi/agent/agents/<agent>.md`.
|
|
378
|
+
- Ensure the frontmatter starts at the very top of the file and is delimited by `---`.
|
|
379
|
+
- Keep the `permission:` block simple (maps + scalars only).
|
|
380
|
+
- Restart the Pi session if you edited agent frontmatter during an active session (some override data is cached).
|
|
381
|
+
|
|
382
|
+
### “Tool was blocked as unregistered”
|
|
383
|
+
|
|
384
|
+
- The extension blocks unregistered tool names before permission checks.
|
|
385
|
+
- If you intended to call an MCP server tool directly, use the built-in `mcp` tool instead (e.g. `{ "tool": "server:tool" }`).
|
|
386
|
+
|
|
387
|
+
### “/skill:<name> is blocked”
|
|
388
|
+
|
|
389
|
+
- Skill loading requires a known active agent context and a non-`deny` `skills` policy.
|
|
390
|
+
- If you run headless (no UI), `ask` decisions may effectively behave like blocks because they cannot be confirmed.
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Development
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
npm run build
|
|
398
|
+
npm run lint
|
|
399
|
+
npm run test
|
|
400
|
+
npm run check
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Project layout
|
|
406
|
+
|
|
407
|
+
- `index.ts` - root Pi entrypoint shim
|
|
408
|
+
- `src/index.ts` - extension bootstrap + enforcement integration (`before_agent_start`, `tool_call`, `input`)
|
|
409
|
+
- `src/permission-manager.ts` - policy loading, merging, and permission resolution
|
|
410
|
+
- `src/bash-filter.ts` - bash wildcard matcher / specificity sorting
|
|
411
|
+
- `src/tool-registry.ts` - registered tool name resolution + pre-check
|
|
412
|
+
- `src/types.ts` - shared permission types
|
|
413
|
+
- `src/test.ts` - TypeScript test runner
|
|
414
|
+
- `schemas/permissions.schema.json` - permission config schema
|
|
415
|
+
- `config/config.example.json` - starter config template
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## License
|
|
420
|
+
|
|
421
|
+
MIT
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaultPolicy": {
|
|
3
|
+
"tools": "ask",
|
|
4
|
+
"bash": "ask",
|
|
5
|
+
"mcp": "ask",
|
|
6
|
+
"skills": "ask",
|
|
7
|
+
"special": "ask"
|
|
8
|
+
},
|
|
9
|
+
"tools": {
|
|
10
|
+
"read": "allow",
|
|
11
|
+
"write": "deny"
|
|
12
|
+
},
|
|
13
|
+
"bash": {
|
|
14
|
+
"git status": "allow",
|
|
15
|
+
"git *": "ask"
|
|
16
|
+
},
|
|
17
|
+
"mcp": {
|
|
18
|
+
"mcp_status": "allow"
|
|
19
|
+
},
|
|
20
|
+
"skills": {
|
|
21
|
+
"*": "ask"
|
|
22
|
+
},
|
|
23
|
+
"special": {
|
|
24
|
+
"doom_loop": "deny",
|
|
25
|
+
"external_directory": "ask"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-permission-system",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Permission enforcement extension for the Pi coding agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.ts",
|
|
12
|
+
"src",
|
|
13
|
+
"config/config.example.json",
|
|
14
|
+
"schemas/permissions.schema.json",
|
|
15
|
+
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
|
|
21
|
+
"lint": "npm run build",
|
|
22
|
+
"test": "bun ./src/test.ts",
|
|
23
|
+
"check": "npm run lint && npm run test"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"pi-package",
|
|
27
|
+
"pi",
|
|
28
|
+
"pi-extension",
|
|
29
|
+
"permissions",
|
|
30
|
+
"policy",
|
|
31
|
+
"coding-agent"
|
|
32
|
+
],
|
|
33
|
+
"author": "MasuRii",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"pi": {
|
|
42
|
+
"extensions": [
|
|
43
|
+
"./index.ts"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@mariozechner/pi-coding-agent": "*",
|
|
48
|
+
"@sinclair/typebox": "*"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://pi-coding-agent.local/schemas/permissions.schema.json",
|
|
4
|
+
"title": "PI Permission Configuration",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"$schema": {
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"defaultPolicy": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"required": ["tools", "bash", "mcp", "skills"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"tools": {
|
|
17
|
+
"$ref": "#/$defs/permissionState"
|
|
18
|
+
},
|
|
19
|
+
"bash": {
|
|
20
|
+
"$ref": "#/$defs/permissionState"
|
|
21
|
+
},
|
|
22
|
+
"mcp": {
|
|
23
|
+
"$ref": "#/$defs/permissionState"
|
|
24
|
+
},
|
|
25
|
+
"skills": {
|
|
26
|
+
"$ref": "#/$defs/permissionState"
|
|
27
|
+
},
|
|
28
|
+
"special": {
|
|
29
|
+
"$ref": "#/$defs/permissionState"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"tools": {
|
|
34
|
+
"$ref": "#/$defs/permissionMap"
|
|
35
|
+
},
|
|
36
|
+
"bash": {
|
|
37
|
+
"$ref": "#/$defs/permissionMap"
|
|
38
|
+
},
|
|
39
|
+
"mcp": {
|
|
40
|
+
"$ref": "#/$defs/permissionMap"
|
|
41
|
+
},
|
|
42
|
+
"skills": {
|
|
43
|
+
"$ref": "#/$defs/permissionMap"
|
|
44
|
+
},
|
|
45
|
+
"special": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"properties": {
|
|
49
|
+
"doom_loop": {
|
|
50
|
+
"$ref": "#/$defs/permissionState"
|
|
51
|
+
},
|
|
52
|
+
"external_directory": {
|
|
53
|
+
"$ref": "#/$defs/permissionState"
|
|
54
|
+
},
|
|
55
|
+
"tool_call_limit": {
|
|
56
|
+
"oneOf": [
|
|
57
|
+
{
|
|
58
|
+
"$ref": "#/$defs/permissionState"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "integer",
|
|
62
|
+
"minimum": 0
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"required": ["defaultPolicy"],
|
|
70
|
+
"$defs": {
|
|
71
|
+
"permissionState": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"enum": ["allow", "deny", "ask"]
|
|
74
|
+
},
|
|
75
|
+
"permissionMap": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"propertyNames": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1
|
|
80
|
+
},
|
|
81
|
+
"additionalProperties": {
|
|
82
|
+
"$ref": "#/$defs/permissionState"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|