@gotgenes/pi-permission-system 3.10.0 → 4.0.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 +55 -0
- package/README.md +135 -168
- package/config/config.example.json +11 -21
- package/package.json +1 -1
- package/schemas/permissions.schema.json +34 -102
- package/src/config-loader.ts +87 -118
- package/src/defaults.ts +6 -56
- package/src/extension-config.ts +3 -4
- package/src/handlers/tool-call.ts +15 -18
- package/src/normalize.ts +22 -60
- package/src/permission-manager.ts +309 -431
- package/src/rule.ts +5 -0
- package/src/session-rules.ts +1 -1
- package/src/synthesize.ts +87 -0
- package/src/types.ts +13 -19
- package/tests/config-loader.test.ts +113 -63
- package/tests/defaults.test.ts +8 -101
- package/tests/extension-config.test.ts +12 -4
- package/tests/normalize.test.ts +67 -64
- package/tests/permission-system.test.ts +310 -677
- package/tests/rule.test.ts +31 -0
- package/tests/session-rules.test.ts +1 -0
- package/tests/session-start.test.ts +1 -7
- package/tests/synthesize.test.ts +240 -0
package/src/normalize.ts
CHANGED
|
@@ -1,70 +1,32 @@
|
|
|
1
|
+
import { isPermissionState } from "./common";
|
|
1
2
|
import type { Rule, Ruleset } from "./rule";
|
|
2
|
-
import type {
|
|
3
|
+
import type { FlatPermissionConfig } from "./types";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
* Used as the input shape for normalizeConfig().
|
|
7
|
-
*/
|
|
8
|
-
export interface NormalizableConfig {
|
|
9
|
-
tools?: Record<string, PermissionState>;
|
|
10
|
-
bash?: Record<string, PermissionState>;
|
|
11
|
-
mcp?: Record<string, PermissionState>;
|
|
12
|
-
skills?: Record<string, PermissionState>;
|
|
13
|
-
special?: Record<string, PermissionState>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Keys in the `tools` map that serve as fallback defaults for their
|
|
18
|
-
* respective pattern-based surfaces rather than as tool-level rules.
|
|
19
|
-
*
|
|
20
|
-
* `tools.bash` sets the bash default (fallback when no bash pattern matches).
|
|
21
|
-
* `tools.mcp` sets the tool-level MCP fallback.
|
|
6
|
+
* Convert a flat permission config into a Ruleset.
|
|
22
7
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*/
|
|
27
|
-
export const TOOL_SURFACE_OVERRIDE_KEYS: ReadonlySet<string> = new Set([
|
|
28
|
-
"bash",
|
|
29
|
-
"mcp",
|
|
30
|
-
]);
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Convert the on-disk config shape into a flat Ruleset.
|
|
8
|
+
* Each key is a surface name. A string value is shorthand for
|
|
9
|
+
* `{ "*": action }`. An object value maps patterns to actions.
|
|
10
|
+
* Invalid action values are silently skipped.
|
|
34
11
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* 3. mcp entries (surface "mcp", pattern = target glob)
|
|
39
|
-
* 4. skills entries (surface "skill", pattern = skill glob)
|
|
40
|
-
* 5. special entries (surface "special", pattern = key name)
|
|
41
|
-
*
|
|
42
|
-
* `tools.bash` and `tools.mcp` are excluded — see TOOL_SURFACE_OVERRIDE_KEYS.
|
|
43
|
-
* `defaultPolicy` is NOT included — handled separately by the caller.
|
|
12
|
+
* The universal fallback key `"*"` is included if present — callers
|
|
13
|
+
* that use `"*"` only for `synthesizeDefaults()` should strip it before
|
|
14
|
+
* calling this function.
|
|
44
15
|
*/
|
|
45
|
-
export function
|
|
16
|
+
export function normalizeFlatConfig(permission: FlatPermissionConfig): Ruleset {
|
|
46
17
|
const rules: Rule[] = [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
18
|
+
for (const [surface, value] of Object.entries(permission)) {
|
|
19
|
+
if (typeof value === "string") {
|
|
20
|
+
if (isPermissionState(value)) {
|
|
21
|
+
rules.push({ surface, pattern: "*", action: value });
|
|
22
|
+
}
|
|
23
|
+
} else if (typeof value === "object" && value !== null) {
|
|
24
|
+
for (const [pattern, action] of Object.entries(value)) {
|
|
25
|
+
if (isPermissionState(action)) {
|
|
26
|
+
rules.push({ surface, pattern, action });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
51
30
|
}
|
|
52
|
-
|
|
53
|
-
for (const [pattern, action] of Object.entries(config.bash ?? {})) {
|
|
54
|
-
rules.push({ surface: "bash", pattern, action });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
for (const [pattern, action] of Object.entries(config.mcp ?? {})) {
|
|
58
|
-
rules.push({ surface: "mcp", pattern, action });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
for (const [pattern, action] of Object.entries(config.skills ?? {})) {
|
|
62
|
-
rules.push({ surface: "skill", pattern, action });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
for (const [name, action] of Object.entries(config.special ?? {})) {
|
|
66
|
-
rules.push({ surface: "special", pattern: name, action });
|
|
67
|
-
}
|
|
68
|
-
|
|
69
31
|
return rules;
|
|
70
32
|
}
|