@gotgenes/pi-permission-system 5.14.0 → 5.15.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
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [5.15.0](https://github.com/gotgenes/pi-permission-system/compare/v5.14.1...v5.15.0) (2026-05-13)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add PI_SUBAGENT_PARENT_SESSION convention for parent session resolution ([3829195](https://github.com/gotgenes/pi-permission-system/commit/3829195c7de1f755adf9aa35809de699434d9aae)), closes [#143](https://github.com/gotgenes/pi-permission-system/issues/143)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
* add Cross-Extension Integration section to AGENTS.md ([#145](https://github.com/gotgenes/pi-permission-system/issues/145)) ([90209f7](https://github.com/gotgenes/pi-permission-system/commit/90209f75ecd0845b6ac13c6c4895da32a4c82909))
|
|
19
|
+
|
|
20
|
+
## [5.14.1](https://github.com/gotgenes/pi-permission-system/compare/v5.14.0...v5.14.1) (2026-05-11)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* show tool name instead of bare wildcard in session-approval label ([1a65c30](https://github.com/gotgenes/pi-permission-system/commit/1a65c3017f25012c3a7ced63f26d40fcecea81d3))
|
|
26
|
+
* surface-prefixed session-approval labels for all permission surfaces ([759da03](https://github.com/gotgenes/pi-permission-system/commit/759da03be9c0d847ec6de58e161ef2e7cbbc70b8))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
* **retro:** add retro notes for issue [#122](https://github.com/gotgenes/pi-permission-system/issues/122) ([7867db2](https://github.com/gotgenes/pi-permission-system/commit/7867db22054df00e13aa6c88347238dadaa63166))
|
|
32
|
+
|
|
8
33
|
## [5.14.0](https://github.com/gotgenes/pi-permission-system/compare/v5.13.0...v5.14.0) (2026-05-09)
|
|
9
34
|
|
|
10
35
|
|
package/package.json
CHANGED
|
@@ -113,8 +113,9 @@ export async function waitForForwardedPermissionApproval(
|
|
|
113
113
|
deps.logger,
|
|
114
114
|
`Permission forwarding target session could not be resolved. ` +
|
|
115
115
|
`Checked env vars: ${SUBAGENT_PARENT_SESSION_ENV_CANDIDATES.join(", ")}. ` +
|
|
116
|
-
`If you are using nicobailon/pi-subagents
|
|
117
|
-
`
|
|
116
|
+
`If you are using a subagent extension (nicobailon/pi-subagents, HazAT/pi-interactive-subagents, etc.), ` +
|
|
117
|
+
`ask its maintainer to set PI_SUBAGENT_PARENT_SESSION in the child process environment ` +
|
|
118
|
+
`(see https://github.com/gotgenes/pi-permission-system/issues/143).`,
|
|
118
119
|
);
|
|
119
120
|
return { approved: false, state: "denied" };
|
|
120
121
|
}
|
package/src/pattern-suggest.ts
CHANGED
|
@@ -57,8 +57,21 @@ export function suggestMcpPattern(target: string): string {
|
|
|
57
57
|
return "*";
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
/** Surface-aware human-readable labels for the session-approval option. */
|
|
61
|
+
function buildLabel(pattern: string, surface: string): string {
|
|
62
|
+
switch (surface) {
|
|
63
|
+
case "bash":
|
|
64
|
+
return `Yes, allow bash "${pattern}" for this session`;
|
|
65
|
+
case "mcp":
|
|
66
|
+
return `Yes, allow mcp tool "${pattern}" for this session`;
|
|
67
|
+
case "skill":
|
|
68
|
+
return `Yes, allow skill "${pattern}" for this session`;
|
|
69
|
+
case "external_directory":
|
|
70
|
+
return `Yes, allow access to external directory "${pattern}" for this session`;
|
|
71
|
+
default:
|
|
72
|
+
// Tool surfaces (read, write, edit, grep, find, ls, extension tools)
|
|
73
|
+
return `Yes, allow tool "${surface}" for this session`;
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
/**
|
|
@@ -92,5 +105,5 @@ export function suggestSessionPattern(
|
|
|
92
105
|
break;
|
|
93
106
|
}
|
|
94
107
|
|
|
95
|
-
return { surface, pattern, label: buildLabel(pattern) };
|
|
108
|
+
return { surface, pattern, label: buildLabel(pattern, surface) };
|
|
96
109
|
}
|
|
@@ -24,6 +24,9 @@ export const SUBAGENT_ENV_HINT_KEYS = [
|
|
|
24
24
|
export const SUBAGENT_PARENT_SESSION_ENV_CANDIDATES: readonly string[] = [
|
|
25
25
|
// pi-agent-router (original)
|
|
26
26
|
"PI_AGENT_ROUTER_PARENT_SESSION_ID",
|
|
27
|
+
// Shared convention for CLI-based subagent extensions
|
|
28
|
+
// (nicobailon/pi-subagents, HazAT/pi-interactive-subagents, etc.)
|
|
29
|
+
"PI_SUBAGENT_PARENT_SESSION",
|
|
27
30
|
] as const;
|
|
28
31
|
|
|
29
32
|
/** @deprecated Use SUBAGENT_PARENT_SESSION_ENV_CANDIDATES */
|
|
@@ -136,23 +136,46 @@ describe("suggestSessionPattern", () => {
|
|
|
136
136
|
const result = suggestSessionPattern("edit", "*");
|
|
137
137
|
expect(result).toMatchObject({ surface: "edit", pattern: "*" });
|
|
138
138
|
});
|
|
139
|
+
|
|
140
|
+
it("label shows tool name instead of bare wildcard", () => {
|
|
141
|
+
const result = suggestSessionPattern("find", "*");
|
|
142
|
+
expect(result.label).toBe('Yes, allow tool "find" for this session');
|
|
143
|
+
});
|
|
139
144
|
});
|
|
140
145
|
|
|
141
146
|
describe("label field", () => {
|
|
142
|
-
it("
|
|
143
|
-
// git arity=2, "git status" has 2 tokens → trailing wildcard.
|
|
147
|
+
it("bash label includes surface prefix and pattern", () => {
|
|
144
148
|
const result = suggestSessionPattern("bash", "git status");
|
|
145
|
-
expect(result.label).
|
|
149
|
+
expect(result.label).toBe(
|
|
150
|
+
'Yes, allow bash "git status*" for this session',
|
|
151
|
+
);
|
|
146
152
|
});
|
|
147
153
|
|
|
148
|
-
it("
|
|
154
|
+
it("mcp label includes surface prefix and pattern", () => {
|
|
149
155
|
const result = suggestSessionPattern("mcp", "exa:search");
|
|
150
|
-
expect(result.label).
|
|
156
|
+
expect(result.label).toBe('Yes, allow mcp tool "exa:*" for this session');
|
|
151
157
|
});
|
|
152
158
|
|
|
153
|
-
it("label
|
|
159
|
+
it("skill label includes surface prefix", () => {
|
|
154
160
|
const result = suggestSessionPattern("skill", "librarian");
|
|
155
|
-
expect(result.label).toBe(
|
|
161
|
+
expect(result.label).toBe(
|
|
162
|
+
'Yes, allow skill "librarian" for this session',
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("external_directory label includes surface prefix", () => {
|
|
167
|
+
const result = suggestSessionPattern(
|
|
168
|
+
"external_directory",
|
|
169
|
+
"/tmp/foo.txt",
|
|
170
|
+
);
|
|
171
|
+
expect(result.label).toBe(
|
|
172
|
+
'Yes, allow access to external directory "/tmp/*" for this session',
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("tool label shows tool name, not wildcard pattern", () => {
|
|
177
|
+
const result = suggestSessionPattern("edit", "*");
|
|
178
|
+
expect(result.label).toBe('Yes, allow tool "edit" for this session');
|
|
156
179
|
});
|
|
157
180
|
});
|
|
158
181
|
});
|
|
@@ -17,6 +17,12 @@ describe("SUBAGENT_PARENT_SESSION_ENV_CANDIDATES", () => {
|
|
|
17
17
|
);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
test("contains PI_SUBAGENT_PARENT_SESSION for CLI-based subagent extensions", () => {
|
|
21
|
+
expect(SUBAGENT_PARENT_SESSION_ENV_CANDIDATES).toContain(
|
|
22
|
+
"PI_SUBAGENT_PARENT_SESSION",
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
20
26
|
test("deprecated SUBAGENT_PARENT_SESSION_ENV_KEY equals the first candidate", () => {
|
|
21
27
|
expect(SUBAGENT_PARENT_SESSION_ENV_KEY).toBe(
|
|
22
28
|
SUBAGENT_PARENT_SESSION_ENV_CANDIDATES[0],
|
|
@@ -80,33 +86,31 @@ describe("resolvePermissionForwardingTargetSessionId", () => {
|
|
|
80
86
|
).toBe("parent-session-abc");
|
|
81
87
|
});
|
|
82
88
|
|
|
83
|
-
test("isSubagent=true,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
test("isSubagent=true, PI_SUBAGENT_PARENT_SESSION resolves when PI_AGENT_ROUTER_PARENT_SESSION_ID is absent", () => {
|
|
90
|
+
expect(
|
|
91
|
+
resolvePermissionForwardingTargetSessionId({
|
|
92
|
+
hasUI: false,
|
|
93
|
+
isSubagent: true,
|
|
94
|
+
currentSessionId: "session-xyz",
|
|
95
|
+
env: {
|
|
96
|
+
PI_SUBAGENT_PARENT_SESSION: "parent-from-convention",
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
).toBe("parent-from-convention");
|
|
100
|
+
});
|
|
93
101
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
// Restore original array contents.
|
|
107
|
-
(SUBAGENT_PARENT_SESSION_ENV_CANDIDATES as unknown as string[]).length =
|
|
108
|
-
originalCandidates.length;
|
|
109
|
-
}
|
|
102
|
+
test("isSubagent=true, PI_AGENT_ROUTER_PARENT_SESSION_ID takes precedence over PI_SUBAGENT_PARENT_SESSION", () => {
|
|
103
|
+
expect(
|
|
104
|
+
resolvePermissionForwardingTargetSessionId({
|
|
105
|
+
hasUI: false,
|
|
106
|
+
isSubagent: true,
|
|
107
|
+
currentSessionId: "session-xyz",
|
|
108
|
+
env: {
|
|
109
|
+
PI_AGENT_ROUTER_PARENT_SESSION_ID: "parent-from-router",
|
|
110
|
+
PI_SUBAGENT_PARENT_SESSION: "parent-from-convention",
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
).toBe("parent-from-router");
|
|
110
114
|
});
|
|
111
115
|
|
|
112
116
|
test("isSubagent=true, candidate value is empty string returns null", () => {
|