pi-permission-system 0.4.3 → 0.4.5

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 CHANGED
@@ -7,21 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [0.4.3] - 2026-04-22
10
+ ## [0.4.5] - 2026-04-27
11
+
12
+ ### Fixed
13
+ - Added a model option compatibility guard for OpenAI Responses/Codex streams so unsupported `temperature` values are removed from stream options and outgoing payloads before provider calls.
14
+
15
+ ## [0.4.4] - 2026-04-25
11
16
 
12
17
  ### Added
13
- - Added `src/skill-prompt-sanitizer.ts` to centralize skill prompt parsing and sanitization helpers
18
+ - Added runtime enforcement for the `external_directory` special permission on path-bearing tools (`read`, `write`, `edit`, `find`, `grep`, `ls`) before normal tool permission checks (thanks to @gotgenes for PR #9)
19
+ - Added readable `ask` prompt summaries for built-in file tools and bounded input previews for generic extension tools so users can make informed approval decisions (thanks to @beantownbytes for PR #8)
20
+ - Added `skill-prompt-sanitizer.ts` to parse and sanitize every `<available_skills>` block, including prompts with multiple skill sections
14
21
 
15
22
  ### Changed
16
- - Updated `@mariozechner/pi-coding-agent` and `@mariozechner/pi-tui` peer dependencies to `^0.68.1`
17
- - Refactored `src/index.ts` to reuse shared skill prompt sanitizer helpers
23
+ - Updated `@mariozechner/pi-coding-agent` and `@mariozechner/pi-tui` peer dependencies to `^0.70.2`
24
+ - Refactored skill prompt filtering out of `src/index.ts` into a dedicated module for clearer ownership and reuse
25
+ - Permission prompts for `edit`, `write`, `read`, `find`, `grep`, and `ls` now show concise path/action summaries instead of raw multiline JSON
18
26
 
19
27
  ### Fixed
20
- - Skill prompt sanitization now removes denied skills from every `<available_skills>` block and drops fully denied blocks from the prompt
21
- - Hidden skills are no longer retained for skill path matching after sanitization
28
+ - Denied skills are now removed from all available-skill prompt blocks instead of only the first block
29
+ - Denied skill entries are no longer retained for later skill-read path matching after prompt sanitization
30
+ - External path access now honors `special.external_directory: deny` and blocks `ask` decisions when no UI or forwarding channel is available
22
31
 
23
32
  ### Tests
24
- - Added regression coverage for multi-block `<available_skills>` parsing, sanitization, and visible-skill path matching
33
+ - Added runtime `tool_call` coverage for external directory deny, ask-without-UI, ask approval, internal path allow, and optional path omission
34
+ - Added prompt regression coverage for generic tool input previews and readable built-in file-tool approval summaries
35
+ - Added multi-block skill prompt sanitizer regression coverage
25
36
 
26
37
  ## [0.4.2] - 2026-04-20
27
38
 
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # 🔐 pi-permission-system
2
2
 
3
- [![Version](https://img.shields.io/badge/version-0.4.2-blue.svg)](package.json)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/pi-permission-system?style=flat-square)](https://www.npmjs.com/package/pi-permission-system) [![License](https://img.shields.io/github/license/MasuRii/pi-permission-system?style=flat-square)](LICENSE)
5
4
 
6
5
  Permission enforcement extension for the Pi coding agent that provides centralized, deterministic permission gates for tool, bash, MCP, skill, and special operations.
7
6
 
@@ -12,18 +11,27 @@ Permission enforcement extension for the Pi coding agent that provides centraliz
12
11
 
13
12
  - **Tool Filtering** — Hides disallowed tools from the agent before it starts (reduces "try another tool" behavior)
14
13
  - **System Prompt Sanitization** — Removes denied tool entries from the `Available tools:` system prompt section so the agent only sees tools it can actually call
15
- - **Runtime Enforcement** — Blocks/asks/allows at tool call time with UI confirmation dialogs
14
+ - **Runtime Enforcement** — Blocks/asks/allows at tool call time with UI confirmation dialogs and readable approval summaries
16
15
  - **Bash Command Control** — Wildcard pattern matching for granular bash command permissions
17
16
  - **MCP Access Control** — Server and tool-level permissions for MCP operations
18
- - **Skill Protection** — Controls which skills can be loaded or read from disk
17
+ - **Skill Protection** — Controls which skills can be loaded or read from disk, including multi-block prompt sanitization
19
18
  - **Per-Agent Overrides** — Agent-specific permission policies via YAML frontmatter
20
19
  - **Subagent Permission Forwarding** — Forwards `ask` confirmations from non-UI subagents back to the main interactive session
21
20
  - **File-Based Review Logging** — Writes permission request/denial review entries to a file by default for later auditing
22
21
  - **Optional Debug Logging** — Keeps verbose extension diagnostics in a separate file when enabled in `config.json`
23
22
  - **JSON Schema Validation** — Full schema for editor autocomplete and config validation
23
+ - **External Directory Guard** — Enforces `special.external_directory` for path-bearing file tools that target paths outside the active working directory
24
24
 
25
25
  ## Installation
26
26
 
27
+ ### npm package
28
+
29
+ ```bash
30
+ pi install npm:pi-permission-system
31
+ ```
32
+
33
+ ### Local extension folder
34
+
27
35
  Place this folder in one of the following locations:
28
36
 
29
37
  | Scope | Path |
@@ -84,6 +92,8 @@ The extension integrates via Pi's lifecycle hooks:
84
92
  - The `Available tools:` system prompt section is rewritten to match the filtered active tool set
85
93
  - Extension-provided tools like `task`, `mcp`, and third-party tools are handled by exact registered name instead of private built-in hardcodes
86
94
  - When a subagent hits an `ask` permission without direct UI access, the request can be forwarded to the main interactive session for confirmation
95
+ - Generic extension-tool approval prompts include a bounded input preview; built-in file tools use concise human-readable summaries instead of raw multiline JSON
96
+ - Path-bearing file tools (`read`, `write`, `edit`, `find`, `grep`, `ls`) evaluate `special.external_directory` before their normal tool permission when an explicit path points outside `ctx.cwd`
87
97
 
88
98
  ## Configuration
89
99
 
@@ -122,7 +132,7 @@ The policy file is a JSON object with these sections:
122
132
  | `bash` | Command pattern permissions |
123
133
  | `mcp` | MCP server/tool permissions for calls routed through a registered `mcp` tool |
124
134
  | `skills` | Skill name pattern permissions |
125
- | `special` | Reserved permission checks |
135
+ | `special` | Reserved permission checks such as external directory access |
126
136
 
127
137
  > **Note:** Trailing commas are **not** supported. If parsing fails, the extension falls back to `ask` for all categories.
128
138
 
@@ -310,7 +320,7 @@ Reserved permission checks:
310
320
  | Key | Description |
311
321
  |----------------------|------------------------------------------|
312
322
  | `doom_loop` | Controls doom loop detection behavior |
313
- | `external_directory` | Controls access outside working directory |
323
+ | `external_directory` | Enforces ask/allow/deny decisions for path-bearing built-in tools (`read`, `write`, `edit`, `find`, `grep`, `ls`) when they target paths outside the active working directory |
314
324
  | `tool_call_limit` | *(schema only, not enforced yet)* |
315
325
 
316
326
  ```jsonc
@@ -322,6 +332,8 @@ Reserved permission checks:
322
332
  }
323
333
  ```
324
334
 
335
+ `external_directory` is evaluated before the normal tool permission check. For example, `tools.read: "allow"` can permit ordinary reads while `special.external_directory: "ask"` still requires confirmation before reading `../outside.txt` or an absolute path outside `ctx.cwd`. Optional-path search tools (`find`, `grep`, `ls`) skip this check when no `path` is provided because they default to the active working directory.
336
+
325
337
  ---
326
338
 
327
339
  ## Common Recipes
@@ -390,6 +402,21 @@ permission:
390
402
 
391
403
  ## Technical Details
392
404
 
405
+ ### Permission Prompt Summaries
406
+
407
+ When a tool permission resolves to `ask`, the prompt is designed to be readable enough for an informed approval decision:
408
+
409
+ - `bash` prompts show the command and matched bash pattern when available.
410
+ - `mcp` prompts show the derived MCP target and matched rule when available.
411
+ - Built-in file tools show concise summaries, such as the target path and edit/write line counts, instead of raw multiline JSON.
412
+ - Unknown or third-party extension tools show a bounded single-line JSON preview of the input so users are not asked to approve a blind tool name.
413
+
414
+ Example edit approval prompt:
415
+
416
+ ```text
417
+ Current agent requested tool 'edit' for '.gitignore' (1 replacement: edit #1 replaces 5 lines with 2 lines). Allow this call?
418
+ ```
419
+
393
420
  ### Subagent Permission Forwarding
394
421
 
395
422
  When a delegated or routed subagent runs without direct UI access, `ask` permissions can still be enforced by forwarding the confirmation request through Pi session directories. The main interactive session polls for forwarded requests, shows the confirmation prompt, writes the response, and the subagent resumes once that decision is available.
@@ -413,10 +440,11 @@ Actual global logs directory: $PI_CODING_AGENT_DIR/extensions/pi-permission-syst
413
440
  ```
414
441
  index.ts → Root Pi entrypoint shim
415
442
  src/
416
- ├── index.ts → Extension bootstrap, permission checks, review logging, reload handling, and subagent forwarding
443
+ ├── index.ts → Extension bootstrap, permission checks, readable prompts, review logging, reload handling, and subagent forwarding
417
444
  ├── extension-config.ts → Extension-local config loading and default creation
418
445
  ├── logging.ts → File-only debug/review logging helpers
419
446
  ├── permission-manager.ts → Global/project policy loading, merging, and resolution with caching
447
+ ├── skill-prompt-sanitizer.ts → Skill prompt parsing, multi-block sanitization, and skill-read path matching
420
448
  ├── bash-filter.ts → Bash command wildcard pattern matching
421
449
  ├── wildcard-matcher.ts → Shared wildcard pattern compilation and matching
422
450
  ├── common.ts → Shared utilities (YAML parsing, type guards, etc.)
@@ -442,6 +470,7 @@ The extension uses a modular architecture with shared utilities:
442
470
  | `wildcard-matcher.ts` | Compile-once wildcard patterns with specificity sorting: `compileWildcardPatterns()`, `findCompiledWildcardMatch()` |
443
471
  | `permission-manager.ts` | Policy resolution with file stamp caching for performance |
444
472
  | `bash-filter.ts` | Uses shared wildcard matcher for bash command patterns |
473
+ | `skill-prompt-sanitizer.ts` | Parses all available skill prompt blocks, removes denied skills, and tracks visible skill paths for read protection |
445
474
 
446
475
  #### Performance Optimizations
447
476
 
@@ -457,6 +486,7 @@ The extension uses a modular architecture with shared utilities:
457
486
  - Agent calling tools it shouldn't use (e.g., `write`, dangerous `bash`)
458
487
  - Tool switching attempts (calling non-existent tool names)
459
488
  - Accidental escalation via skill loading
489
+ - Unapproved path-bearing tool access outside the active working directory when `external_directory` is `ask` or `deny`
460
490
 
461
491
  **Limitations:**
462
492
  - If a dangerous action is possible via an allowed tool, policy must explicitly restrict it
@@ -484,6 +514,8 @@ npx --yes ajv-cli@5 validate \
484
514
  | Per-agent override not applied | Frontmatter parsing issue | Ensure `---` delimiters at file top; keep YAML simple; restart session |
485
515
  | Tool blocked as unregistered | Unknown tool name | Use a registered `mcp` tool for server tools: `{ "tool": "server:tool" }` |
486
516
  | `/skill:<name>` blocked | Deny policy or confirmation unavailable | Check merged `skills` policy (global/project/agent layers). Active agent context is optional in the main session; `ask` still requires UI or forwarded confirmation. |
517
+ | External file path blocked | `special.external_directory` is `ask` without UI or `deny` | Allow/ask the special permission or keep file tools inside the active working directory. |
518
+ | Permission prompt is too verbose | Generic extension tool input is large | Built-in file tools are summarized automatically; third-party tools are capped to a bounded one-line JSON preview. |
487
519
 
488
520
  ---
489
521
 
package/package.json CHANGED
@@ -1,65 +1,66 @@
1
- {
2
- "name": "pi-permission-system",
3
- "version": "0.4.3",
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
- "tests",
14
- "config.json",
15
- "config/config.example.json",
16
- "schemas/permissions.schema.json",
17
- "README.md",
18
- "CHANGELOG.md",
19
- "LICENSE"
20
- ],
21
- "scripts": {
22
- "build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
23
- "lint": "npm run build",
24
- "test": "bun ./tests/permission-system.test.ts && bun ./tests/config-modal.test.ts",
25
- "check": "npm run lint && npm run test"
26
- },
27
- "keywords": [
28
- "pi-package",
29
- "pi",
30
- "pi-extension",
31
- "pi-coding-agent",
32
- "coding-agent",
33
- "permissions",
34
- "policy",
35
- "access-control",
36
- "authorization",
37
- "security"
38
- ],
39
- "author": "MasuRii",
40
- "license": "MIT",
41
- "repository": {
42
- "type": "git",
43
- "url": "git+https://github.com/MasuRii/pi-permission-system.git"
44
- },
45
- "homepage": "https://github.com/MasuRii/pi-permission-system#readme",
46
- "bugs": {
47
- "url": "https://github.com/MasuRii/pi-permission-system/issues"
48
- },
49
- "engines": {
50
- "node": ">=20"
51
- },
52
- "publishConfig": {
53
- "access": "public"
54
- },
55
- "pi": {
56
- "extensions": [
57
- "./index.ts"
58
- ]
59
- },
60
- "peerDependencies": {
61
- "@mariozechner/pi-coding-agent": "^0.68.1",
62
- "@mariozechner/pi-tui": "^0.68.1",
63
- "@sinclair/typebox": "^0.34.49"
64
- }
65
- }
1
+ {
2
+ "name": "pi-permission-system",
3
+ "version": "0.4.5",
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
+ "tests",
14
+ "config.json",
15
+ "config/config.example.json",
16
+ "schemas/permissions.schema.json",
17
+ "README.md",
18
+ "CHANGELOG.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
23
+ "lint": "npm run build",
24
+ "test": "bun ./tests/permission-system.test.ts && bun ./tests/config-modal.test.ts",
25
+ "check": "npm run lint && npm run test"
26
+ },
27
+ "keywords": [
28
+ "pi-package",
29
+ "pi",
30
+ "pi-extension",
31
+ "pi-coding-agent",
32
+ "coding-agent",
33
+ "permissions",
34
+ "policy",
35
+ "access-control",
36
+ "authorization",
37
+ "security"
38
+ ],
39
+ "author": "MasuRii",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/MasuRii/pi-permission-system.git"
44
+ },
45
+ "homepage": "https://github.com/MasuRii/pi-permission-system#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/MasuRii/pi-permission-system/issues"
48
+ },
49
+ "engines": {
50
+ "node": ">=20"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "pi": {
56
+ "extensions": [
57
+ "./index.ts"
58
+ ]
59
+ },
60
+ "peerDependencies": {
61
+ "@mariozechner/pi-ai": "^0.70.2",
62
+ "@mariozechner/pi-coding-agent": "^0.70.2",
63
+ "@mariozechner/pi-tui": "^0.70.2",
64
+ "@sinclair/typebox": "^0.34.49"
65
+ }
66
+ }