@gotgenes/pi-permission-system 7.3.1 → 7.3.2
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,13 @@ 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
|
+
## [7.3.2](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v7.3.1...pi-permission-system-v7.3.2) (2026-05-27)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* replace \n with <br/> in Mermaid node labels ([3312a45](https://github.com/gotgenes/pi-packages/commit/3312a4559100cf9ae923f67819653b5a99fceb12))
|
|
14
|
+
|
|
8
15
|
## [7.3.1](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v7.3.0...pi-permission-system-v7.3.1) (2026-05-26)
|
|
9
16
|
|
|
10
17
|
|
package/package.json
CHANGED
|
@@ -41,7 +41,6 @@ export function shouldExposeTool(
|
|
|
41
41
|
*/
|
|
42
42
|
export class AgentPrepHandler {
|
|
43
43
|
constructor(
|
|
44
|
-
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: accessed via destructuring (const { session } = this)
|
|
45
44
|
private readonly session: PermissionSession,
|
|
46
45
|
private readonly toolRegistry: ToolRegistry,
|
|
47
46
|
) {}
|
|
@@ -51,11 +50,10 @@ export class AgentPrepHandler {
|
|
|
51
50
|
event: BeforeAgentStartPayload,
|
|
52
51
|
ctx: ExtensionContext,
|
|
53
52
|
): Promise<BeforeAgentStartEventResult> {
|
|
54
|
-
|
|
55
|
-
session.
|
|
56
|
-
session.refreshConfig(ctx);
|
|
53
|
+
this.session.activate(ctx);
|
|
54
|
+
this.session.refreshConfig(ctx);
|
|
57
55
|
|
|
58
|
-
const agentName = session.resolveAgentName(ctx, event.systemPrompt);
|
|
56
|
+
const agentName = this.session.resolveAgentName(ctx, event.systemPrompt);
|
|
59
57
|
const allTools = this.toolRegistry.getAll();
|
|
60
58
|
const allowedTools: string[] = [];
|
|
61
59
|
|
|
@@ -66,7 +64,7 @@ export class AgentPrepHandler {
|
|
|
66
64
|
}
|
|
67
65
|
if (
|
|
68
66
|
shouldExposeTool(toolName, agentName, (t, a) =>
|
|
69
|
-
session.getToolPermission(t, a),
|
|
67
|
+
this.session.getToolPermission(t, a),
|
|
70
68
|
)
|
|
71
69
|
) {
|
|
72
70
|
allowedTools.push(toolName);
|
|
@@ -74,24 +72,24 @@ export class AgentPrepHandler {
|
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
const activeToolsCacheKey = createActiveToolsCacheKey(allowedTools);
|
|
77
|
-
if (session.shouldUpdateActiveTools(activeToolsCacheKey)) {
|
|
75
|
+
if (this.session.shouldUpdateActiveTools(activeToolsCacheKey)) {
|
|
78
76
|
this.toolRegistry.setActive(allowedTools);
|
|
79
|
-
session.commitActiveToolsCacheKey(activeToolsCacheKey);
|
|
77
|
+
this.session.commitActiveToolsCacheKey(activeToolsCacheKey);
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
const promptStateCacheKey = createBeforeAgentStartPromptStateKey({
|
|
83
81
|
agentName,
|
|
84
82
|
cwd: ctx.cwd,
|
|
85
|
-
permissionStamp: session.getPolicyCacheStamp(agentName ?? undefined),
|
|
83
|
+
permissionStamp: this.session.getPolicyCacheStamp(agentName ?? undefined),
|
|
86
84
|
systemPrompt: event.systemPrompt,
|
|
87
85
|
allowedToolNames: allowedTools,
|
|
88
86
|
});
|
|
89
87
|
|
|
90
|
-
if (!session.shouldUpdatePromptState(promptStateCacheKey)) {
|
|
88
|
+
if (!this.session.shouldUpdatePromptState(promptStateCacheKey)) {
|
|
91
89
|
return {};
|
|
92
90
|
}
|
|
93
91
|
|
|
94
|
-
session.commitPromptStateCacheKey(promptStateCacheKey);
|
|
92
|
+
this.session.commitPromptStateCacheKey(promptStateCacheKey);
|
|
95
93
|
|
|
96
94
|
const toolPromptResult = sanitizeAvailableToolsSection(
|
|
97
95
|
event.systemPrompt,
|
|
@@ -99,11 +97,11 @@ export class AgentPrepHandler {
|
|
|
99
97
|
);
|
|
100
98
|
const skillPromptResult = resolveSkillPromptEntries(
|
|
101
99
|
toolPromptResult.prompt,
|
|
102
|
-
session,
|
|
100
|
+
this.session,
|
|
103
101
|
agentName,
|
|
104
102
|
ctx.cwd,
|
|
105
103
|
);
|
|
106
|
-
session.setActiveSkillEntries(skillPromptResult.entries);
|
|
104
|
+
this.session.setActiveSkillEntries(skillPromptResult.entries);
|
|
107
105
|
|
|
108
106
|
if (skillPromptResult.prompt !== event.systemPrompt) {
|
|
109
107
|
return { systemPrompt: skillPromptResult.prompt };
|
|
@@ -22,7 +22,6 @@ interface ResourcesDiscoverPayload {
|
|
|
22
22
|
*/
|
|
23
23
|
export class SessionLifecycleHandler {
|
|
24
24
|
constructor(
|
|
25
|
-
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: accessed via destructuring (const { session } = this)
|
|
26
25
|
private readonly session: PermissionSession,
|
|
27
26
|
private readonly cleanupRpc: () => void,
|
|
28
27
|
) {}
|
|
@@ -31,19 +30,18 @@ export class SessionLifecycleHandler {
|
|
|
31
30
|
event: SessionStartPayload,
|
|
32
31
|
ctx: ExtensionContext,
|
|
33
32
|
): Promise<void> {
|
|
34
|
-
|
|
35
|
-
session.
|
|
36
|
-
session.
|
|
37
|
-
session.logResolvedConfigPaths();
|
|
33
|
+
this.session.refreshConfig(ctx);
|
|
34
|
+
this.session.resetForNewSession(ctx);
|
|
35
|
+
this.session.logResolvedConfigPaths();
|
|
38
36
|
|
|
39
|
-
const agentName = session.resolveAgentName(ctx);
|
|
40
|
-
const policyIssues = session.getConfigIssues(agentName ?? undefined);
|
|
37
|
+
const agentName = this.session.resolveAgentName(ctx);
|
|
38
|
+
const policyIssues = this.session.getConfigIssues(agentName ?? undefined);
|
|
41
39
|
for (const issue of policyIssues) {
|
|
42
|
-
session.logger.warn(issue);
|
|
40
|
+
this.session.logger.warn(issue);
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
if (event.reason === "reload") {
|
|
46
|
-
session.logger.debug("lifecycle.reload", {
|
|
44
|
+
this.session.logger.debug("lifecycle.reload", {
|
|
47
45
|
triggeredBy: "session_start",
|
|
48
46
|
reason: event.reason,
|
|
49
47
|
cwd: ctx.cwd,
|
|
@@ -57,23 +55,21 @@ export class SessionLifecycleHandler {
|
|
|
57
55
|
return Promise.resolve();
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
session.reload
|
|
62
|
-
session.logger.debug("lifecycle.reload", {
|
|
58
|
+
this.session.reload();
|
|
59
|
+
this.session.logger.debug("lifecycle.reload", {
|
|
63
60
|
triggeredBy: "resources_discover",
|
|
64
61
|
reason: event.reason,
|
|
65
|
-
cwd: session.getRuntimeContext()?.cwd ?? null,
|
|
62
|
+
cwd: this.session.getRuntimeContext()?.cwd ?? null,
|
|
66
63
|
});
|
|
67
64
|
return Promise.resolve();
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
handleSessionShutdown(): Promise<void> {
|
|
71
|
-
const
|
|
72
|
-
const ctx = session.getRuntimeContext();
|
|
68
|
+
const ctx = this.session.getRuntimeContext();
|
|
73
69
|
if (ctx) {
|
|
74
70
|
ctx.ui.setStatus(PERMISSION_SYSTEM_STATUS_KEY, undefined);
|
|
75
71
|
}
|
|
76
|
-
session.shutdown();
|
|
72
|
+
this.session.shutdown();
|
|
77
73
|
this.cleanupRpc();
|
|
78
74
|
return Promise.resolve();
|
|
79
75
|
}
|
|
@@ -47,7 +47,6 @@ interface InputPayload {
|
|
|
47
47
|
*/
|
|
48
48
|
export class PermissionGateHandler {
|
|
49
49
|
constructor(
|
|
50
|
-
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: accessed via destructuring (const { session } = this)
|
|
51
50
|
private readonly session: PermissionSession,
|
|
52
51
|
private readonly events: PermissionEventBus,
|
|
53
52
|
private readonly toolRegistry: ToolRegistry,
|
|
@@ -57,10 +56,9 @@ export class PermissionGateHandler {
|
|
|
57
56
|
event: unknown,
|
|
58
57
|
ctx: ExtensionContext,
|
|
59
58
|
): Promise<{ block?: true; reason?: string }> {
|
|
60
|
-
|
|
61
|
-
session.activate(ctx);
|
|
59
|
+
this.session.activate(ctx);
|
|
62
60
|
|
|
63
|
-
const agentName = session.resolveAgentName(ctx);
|
|
61
|
+
const agentName = this.session.resolveAgentName(ctx);
|
|
64
62
|
const toolName = getToolNameFromValue(event);
|
|
65
63
|
|
|
66
64
|
if (!toolName) {
|
|
@@ -100,22 +98,22 @@ export class PermissionGateHandler {
|
|
|
100
98
|
};
|
|
101
99
|
|
|
102
100
|
// ── Shared gate adapter closures ─────────────────────────────────────
|
|
103
|
-
const canConfirm = () => session.canPrompt(ctx);
|
|
101
|
+
const canConfirm = () => this.session.canPrompt(ctx);
|
|
104
102
|
const promptPermission = (details: PromptPermissionDetails) =>
|
|
105
|
-
session.prompt(ctx, details);
|
|
103
|
+
this.session.prompt(ctx, details);
|
|
106
104
|
const emitDecision: GateRunnerDeps["emitDecision"] = (e) =>
|
|
107
105
|
emitDecisionEvent(this.events, e);
|
|
108
106
|
// eslint-disable-next-line @typescript-eslint/unbound-method -- logger.review is a plain function closure; no this-binding issue
|
|
109
|
-
const writeReviewLog = session.logger.review;
|
|
107
|
+
const writeReviewLog = this.session.logger.review;
|
|
110
108
|
const checkPermission: GateRunnerDeps["checkPermission"] = (
|
|
111
109
|
surface,
|
|
112
110
|
input,
|
|
113
111
|
agent,
|
|
114
112
|
sessionRules,
|
|
115
|
-
) => session.checkPermission(surface, input, agent, sessionRules);
|
|
116
|
-
const getSessionRuleset = () => session.getSessionRuleset();
|
|
113
|
+
) => this.session.checkPermission(surface, input, agent, sessionRules);
|
|
114
|
+
const getSessionRuleset = () => this.session.getSessionRuleset();
|
|
117
115
|
const approveSessionRule = (surface: string, pattern: string) =>
|
|
118
|
-
session.approveSessionRule(surface, pattern);
|
|
116
|
+
this.session.approveSessionRule(surface, pattern);
|
|
119
117
|
|
|
120
118
|
// ── Shared runner deps (built once, reused for all gates) ────────────
|
|
121
119
|
const runnerDeps: GateRunnerDeps = {
|
|
@@ -130,7 +128,7 @@ export class PermissionGateHandler {
|
|
|
130
128
|
|
|
131
129
|
// ── Skill-read gate (descriptor + runner) ───────────────────────────────
|
|
132
130
|
const skillDescriptor = describeSkillReadGate(tcc, () =>
|
|
133
|
-
session.getActiveSkillEntries(),
|
|
131
|
+
this.session.getActiveSkillEntries(),
|
|
134
132
|
);
|
|
135
133
|
if (skillDescriptor) {
|
|
136
134
|
const skillResult = await runGateCheck(
|
|
@@ -166,8 +164,8 @@ export class PermissionGateHandler {
|
|
|
166
164
|
|
|
167
165
|
// ── External-directory gate (descriptor + runner) ────────────────────────
|
|
168
166
|
const infraDirs = [
|
|
169
|
-
...session.getInfrastructureDirs(),
|
|
170
|
-
...session.getInfrastructureReadPaths(),
|
|
167
|
+
...this.session.getInfrastructureDirs(),
|
|
168
|
+
...this.session.getInfrastructureReadPaths(),
|
|
171
169
|
];
|
|
172
170
|
const extDirDesc = describeExternalDirectoryGate(tcc, infraDirs);
|
|
173
171
|
if (extDirDesc) {
|
|
@@ -265,16 +263,15 @@ export class PermissionGateHandler {
|
|
|
265
263
|
event: InputPayload,
|
|
266
264
|
ctx: ExtensionContext,
|
|
267
265
|
): Promise<InputEventResult> {
|
|
268
|
-
|
|
269
|
-
session.activate(ctx);
|
|
266
|
+
this.session.activate(ctx);
|
|
270
267
|
|
|
271
268
|
const skillName = extractSkillNameFromInput(event.text);
|
|
272
269
|
if (!skillName) {
|
|
273
270
|
return { action: "continue" };
|
|
274
271
|
}
|
|
275
272
|
|
|
276
|
-
const agentName = session.resolveAgentName(ctx);
|
|
277
|
-
const check = session.checkPermission(
|
|
273
|
+
const agentName = this.session.resolveAgentName(ctx);
|
|
274
|
+
const check = this.session.checkPermission(
|
|
278
275
|
"skill",
|
|
279
276
|
{ name: skillName },
|
|
280
277
|
agentName ?? undefined,
|
|
@@ -291,14 +288,14 @@ export class PermissionGateHandler {
|
|
|
291
288
|
skillName,
|
|
292
289
|
agentName ?? undefined,
|
|
293
290
|
);
|
|
294
|
-
const skillInputCanConfirm = session.canPrompt(ctx);
|
|
291
|
+
const skillInputCanConfirm = this.session.canPrompt(ctx);
|
|
295
292
|
let skillInputAutoApproved = false;
|
|
296
293
|
const skillInputGate = await applyPermissionGate({
|
|
297
294
|
state: check.state,
|
|
298
295
|
canConfirm: skillInputCanConfirm,
|
|
299
296
|
promptForApproval: async () => {
|
|
300
|
-
const decision = await session.prompt(ctx, {
|
|
301
|
-
requestId: session.createPermissionRequestId("skill-input"),
|
|
297
|
+
const decision = await this.session.prompt(ctx, {
|
|
298
|
+
requestId: this.session.createPermissionRequestId("skill-input"),
|
|
302
299
|
source: "skill_input",
|
|
303
300
|
agentName,
|
|
304
301
|
message: skillInputMessage,
|
|
@@ -308,7 +305,7 @@ export class PermissionGateHandler {
|
|
|
308
305
|
return decision;
|
|
309
306
|
},
|
|
310
307
|
// eslint-disable-next-line @typescript-eslint/unbound-method -- logger.review is a plain function closure; no this-binding issue
|
|
311
|
-
writeLog: session.logger.review,
|
|
308
|
+
writeLog: this.session.logger.review,
|
|
312
309
|
logContext: {
|
|
313
310
|
source: "skill_input",
|
|
314
311
|
skillName,
|