@gotgenes/pi-permission-system 5.9.0 → 5.10.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 +15 -0
- package/package.json +1 -1
- package/src/handlers/before-agent-start.ts +19 -32
- package/src/handlers/input.ts +5 -5
- package/src/handlers/lifecycle.ts +17 -33
- package/src/handlers/tool-call.ts +11 -18
- package/src/handlers/types.ts +11 -38
- package/src/index.ts +14 -17
- package/src/permission-session.ts +252 -0
- package/src/runtime.ts +5 -30
- package/src/skill-prompt-sanitizer.ts +15 -4
- package/tests/handlers/before-agent-start.test.ts +79 -110
- package/tests/handlers/input-events.test.ts +19 -31
- package/tests/handlers/input.test.ts +41 -73
- package/tests/handlers/lifecycle.test.ts +61 -179
- package/tests/handlers/tool-call-events.test.ts +66 -92
- package/tests/handlers/tool-call.test.ts +40 -61
- package/tests/permission-session.test.ts +546 -0
- package/tests/runtime.test.ts +2 -77
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.10.0](https://github.com/gotgenes/pi-permission-system/compare/v5.9.0...v5.10.0) (2026-05-08)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* PermissionSession class with delegation methods ([#129](https://github.com/gotgenes/pi-permission-system/issues/129)) ([a8486ce](https://github.com/gotgenes/pi-permission-system/commit/a8486ce1d0678a7617e3cc6d8131e5f3080a1bea))
|
|
14
|
+
* PermissionSession lifecycle, cache, agent name, and infra methods ([#129](https://github.com/gotgenes/pi-permission-system/issues/129)) ([8f6edf7](https://github.com/gotgenes/pi-permission-system/commit/8f6edf727856a974dc8061c1ff6003838d916662))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Documentation
|
|
18
|
+
|
|
19
|
+
* plan PermissionSession extraction ([#129](https://github.com/gotgenes/pi-permission-system/issues/129)) ([9dc21b4](https://github.com/gotgenes/pi-permission-system/commit/9dc21b457ff5ca5e95b920eed1e5b48511175cdf))
|
|
20
|
+
* **retro:** add retro notes for issue [#128](https://github.com/gotgenes/pi-permission-system/issues/128) ([9794053](https://github.com/gotgenes/pi-permission-system/commit/979405305ee5ddeac97186ea949373aff947a210))
|
|
21
|
+
* update architecture for PermissionSession ([#129](https://github.com/gotgenes/pi-permission-system/issues/129)) ([d452c50](https://github.com/gotgenes/pi-permission-system/commit/d452c50a7edb7ca1c2c7715836b007386814e1b3))
|
|
22
|
+
|
|
8
23
|
## [5.9.0](https://github.com/gotgenes/pi-permission-system/compare/v5.8.0...v5.9.0) (2026-05-08)
|
|
9
24
|
|
|
10
25
|
|
package/package.json
CHANGED
|
@@ -11,12 +11,11 @@ interface BeforeAgentStartPayload {
|
|
|
11
11
|
import {
|
|
12
12
|
createActiveToolsCacheKey,
|
|
13
13
|
createBeforeAgentStartPromptStateKey,
|
|
14
|
-
shouldApplyCachedAgentStartState,
|
|
15
14
|
} from "../before-agent-start-cache";
|
|
16
|
-
import type { PermissionManager } from "../permission-manager";
|
|
17
15
|
import { resolveSkillPromptEntries } from "../skill-prompt-sanitizer";
|
|
18
16
|
import { sanitizeAvailableToolsSection } from "../system-prompt-sanitizer";
|
|
19
17
|
import { getToolNameFromValue } from "../tool-registry";
|
|
18
|
+
import type { PermissionState } from "../types";
|
|
20
19
|
import type { HandlerDeps } from "./types";
|
|
21
20
|
|
|
22
21
|
/**
|
|
@@ -27,12 +26,9 @@ import type { HandlerDeps } from "./types";
|
|
|
27
26
|
export function shouldExposeTool(
|
|
28
27
|
toolName: string,
|
|
29
28
|
agentName: string | null,
|
|
30
|
-
|
|
29
|
+
getToolPermission: (toolName: string, agentName?: string) => PermissionState,
|
|
31
30
|
): boolean {
|
|
32
|
-
const toolPermission =
|
|
33
|
-
toolName,
|
|
34
|
-
agentName ?? undefined,
|
|
35
|
-
);
|
|
31
|
+
const toolPermission = getToolPermission(toolName, agentName ?? undefined);
|
|
36
32
|
return toolPermission !== "deny";
|
|
37
33
|
}
|
|
38
34
|
|
|
@@ -41,12 +37,11 @@ export async function handleBeforeAgentStart(
|
|
|
41
37
|
event: BeforeAgentStartPayload,
|
|
42
38
|
ctx: ExtensionContext,
|
|
43
39
|
): Promise<BeforeAgentStartEventResult> {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const { session } = deps;
|
|
41
|
+
session.activate(ctx);
|
|
42
|
+
session.refreshConfig(ctx);
|
|
47
43
|
|
|
48
|
-
const agentName =
|
|
49
|
-
const { permissionManager } = deps.session;
|
|
44
|
+
const agentName = session.resolveAgentName(ctx, event.systemPrompt);
|
|
50
45
|
const allTools = deps.getAllTools();
|
|
51
46
|
const allowedTools: string[] = [];
|
|
52
47
|
|
|
@@ -55,42 +50,34 @@ export async function handleBeforeAgentStart(
|
|
|
55
50
|
if (!toolName) {
|
|
56
51
|
continue;
|
|
57
52
|
}
|
|
58
|
-
if (
|
|
53
|
+
if (
|
|
54
|
+
shouldExposeTool(toolName, agentName, (t, a) =>
|
|
55
|
+
session.getToolPermission(t, a),
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
59
58
|
allowedTools.push(toolName);
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
const activeToolsCacheKey = createActiveToolsCacheKey(allowedTools);
|
|
64
|
-
if (
|
|
65
|
-
shouldApplyCachedAgentStartState(
|
|
66
|
-
deps.session.lastActiveToolsCacheKey,
|
|
67
|
-
activeToolsCacheKey,
|
|
68
|
-
)
|
|
69
|
-
) {
|
|
63
|
+
if (session.shouldUpdateActiveTools(activeToolsCacheKey)) {
|
|
70
64
|
deps.setActiveTools(allowedTools);
|
|
71
|
-
|
|
65
|
+
session.commitActiveToolsCacheKey(activeToolsCacheKey);
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
const promptStateCacheKey = createBeforeAgentStartPromptStateKey({
|
|
75
69
|
agentName,
|
|
76
70
|
cwd: ctx.cwd,
|
|
77
|
-
permissionStamp:
|
|
78
|
-
agentName ?? undefined,
|
|
79
|
-
),
|
|
71
|
+
permissionStamp: session.getPolicyCacheStamp(agentName ?? undefined),
|
|
80
72
|
systemPrompt: event.systemPrompt,
|
|
81
73
|
allowedToolNames: allowedTools,
|
|
82
74
|
});
|
|
83
75
|
|
|
84
|
-
if (
|
|
85
|
-
!shouldApplyCachedAgentStartState(
|
|
86
|
-
deps.session.lastPromptStateCacheKey,
|
|
87
|
-
promptStateCacheKey,
|
|
88
|
-
)
|
|
89
|
-
) {
|
|
76
|
+
if (!session.shouldUpdatePromptState(promptStateCacheKey)) {
|
|
90
77
|
return {};
|
|
91
78
|
}
|
|
92
79
|
|
|
93
|
-
|
|
80
|
+
session.commitPromptStateCacheKey(promptStateCacheKey);
|
|
94
81
|
|
|
95
82
|
const toolPromptResult = sanitizeAvailableToolsSection(
|
|
96
83
|
event.systemPrompt,
|
|
@@ -98,11 +85,11 @@ export async function handleBeforeAgentStart(
|
|
|
98
85
|
);
|
|
99
86
|
const skillPromptResult = resolveSkillPromptEntries(
|
|
100
87
|
toolPromptResult.prompt,
|
|
101
|
-
|
|
88
|
+
session,
|
|
102
89
|
agentName,
|
|
103
90
|
ctx.cwd,
|
|
104
91
|
);
|
|
105
|
-
|
|
92
|
+
session.setActiveSkillEntries(skillPromptResult.entries);
|
|
106
93
|
|
|
107
94
|
if (skillPromptResult.prompt !== event.systemPrompt) {
|
|
108
95
|
return { systemPrompt: skillPromptResult.prompt };
|
package/src/handlers/input.ts
CHANGED
|
@@ -40,16 +40,16 @@ export async function handleInput(
|
|
|
40
40
|
event: InputPayload,
|
|
41
41
|
ctx: ExtensionContext,
|
|
42
42
|
): Promise<InputEventResult> {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const { session } = deps;
|
|
44
|
+
session.activate(ctx);
|
|
45
45
|
|
|
46
46
|
const skillName = extractSkillNameFromInput(event.text);
|
|
47
47
|
if (!skillName) {
|
|
48
48
|
return { action: "continue" };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const agentName =
|
|
52
|
-
const check =
|
|
51
|
+
const agentName = session.resolveAgentName(ctx);
|
|
52
|
+
const check = session.checkPermission(
|
|
53
53
|
"skill",
|
|
54
54
|
{ name: skillName },
|
|
55
55
|
agentName ?? undefined,
|
|
@@ -82,7 +82,7 @@ export async function handleInput(
|
|
|
82
82
|
skillInputAutoApproved = decision.autoApproved === true;
|
|
83
83
|
return decision;
|
|
84
84
|
},
|
|
85
|
-
writeLog:
|
|
85
|
+
writeLog: session.logger.review,
|
|
86
86
|
logContext: {
|
|
87
87
|
source: "skill_input",
|
|
88
88
|
skillName,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
import { getActiveAgentName } from "../active-agent";
|
|
4
3
|
import { PERMISSION_SYSTEM_STATUS_KEY } from "../status";
|
|
5
4
|
import type { HandlerDeps } from "./types";
|
|
6
5
|
|
|
@@ -19,25 +18,19 @@ export async function handleSessionStart(
|
|
|
19
18
|
event: SessionStartPayload,
|
|
20
19
|
ctx: ExtensionContext,
|
|
21
20
|
): Promise<void> {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
deps.session.lastActiveToolsCacheKey = null;
|
|
27
|
-
deps.session.lastPromptStateCacheKey = null;
|
|
28
|
-
deps.session.lastKnownActiveAgentName = getActiveAgentName(ctx);
|
|
29
|
-
deps.forwarding.start(ctx);
|
|
30
|
-
deps.logResolvedConfigPaths();
|
|
21
|
+
const { session } = deps;
|
|
22
|
+
session.refreshConfig(ctx);
|
|
23
|
+
session.resetForNewSession(ctx);
|
|
24
|
+
session.logResolvedConfigPaths();
|
|
31
25
|
|
|
32
|
-
const agentName =
|
|
33
|
-
const policyIssues =
|
|
34
|
-
deps.session.permissionManager.getConfigIssues(agentName);
|
|
26
|
+
const agentName = session.resolveAgentName(ctx);
|
|
27
|
+
const policyIssues = session.getConfigIssues(agentName);
|
|
35
28
|
for (const issue of policyIssues) {
|
|
36
|
-
|
|
29
|
+
session.logger.warn(issue);
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
if (event.reason === "reload") {
|
|
40
|
-
|
|
33
|
+
session.logger.debug("lifecycle.reload", {
|
|
41
34
|
triggeredBy: "session_start",
|
|
42
35
|
reason: event.reason,
|
|
43
36
|
cwd: ctx.cwd,
|
|
@@ -53,30 +46,21 @@ export async function handleResourcesDiscover(
|
|
|
53
46
|
return;
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
const {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
60
|
-
deps.session.activeSkillEntries = [];
|
|
61
|
-
deps.session.lastActiveToolsCacheKey = null;
|
|
62
|
-
deps.session.lastPromptStateCacheKey = null;
|
|
63
|
-
deps.logger.debug("lifecycle.reload", {
|
|
49
|
+
const { session } = deps;
|
|
50
|
+
session.reload();
|
|
51
|
+
session.logger.debug("lifecycle.reload", {
|
|
64
52
|
triggeredBy: "resources_discover",
|
|
65
53
|
reason: event.reason,
|
|
66
|
-
cwd:
|
|
54
|
+
cwd: session.getRuntimeContext()?.cwd ?? null,
|
|
67
55
|
});
|
|
68
56
|
}
|
|
69
57
|
|
|
70
58
|
export async function handleSessionShutdown(deps: HandlerDeps): Promise<void> {
|
|
71
|
-
const {
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
const { session } = deps;
|
|
60
|
+
const ctx = session.getRuntimeContext();
|
|
61
|
+
if (ctx) {
|
|
62
|
+
ctx.ui.setStatus(PERMISSION_SYSTEM_STATUS_KEY, undefined);
|
|
74
63
|
}
|
|
75
|
-
|
|
76
|
-
deps.session.activeSkillEntries = [];
|
|
77
|
-
deps.session.lastActiveToolsCacheKey = null;
|
|
78
|
-
deps.session.lastPromptStateCacheKey = null;
|
|
79
|
-
deps.session.sessionRules.clear();
|
|
80
|
-
deps.forwarding.stop();
|
|
64
|
+
session.shutdown();
|
|
81
65
|
deps.stopPermissionRpcHandlers();
|
|
82
66
|
}
|
|
@@ -43,10 +43,10 @@ export async function handleToolCall(
|
|
|
43
43
|
event: unknown,
|
|
44
44
|
ctx: ExtensionContext,
|
|
45
45
|
): Promise<{ block?: true; reason?: string }> {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const { session } = deps;
|
|
47
|
+
session.activate(ctx);
|
|
48
48
|
|
|
49
|
-
const agentName =
|
|
49
|
+
const agentName = session.resolveAgentName(ctx);
|
|
50
50
|
const toolName = getToolNameFromValue(event);
|
|
51
51
|
|
|
52
52
|
if (!toolName) {
|
|
@@ -91,22 +91,16 @@ export async function handleToolCall(
|
|
|
91
91
|
deps.promptPermission(ctx, details);
|
|
92
92
|
const emitDecision: GateRunnerDeps["emitDecision"] = (e) =>
|
|
93
93
|
emitDecisionEvent(deps.events, e);
|
|
94
|
-
const
|
|
94
|
+
const writeReviewLog = session.logger.review;
|
|
95
95
|
const checkPermission: GateRunnerDeps["checkPermission"] = (
|
|
96
96
|
surface,
|
|
97
97
|
input,
|
|
98
98
|
agent,
|
|
99
99
|
sessionRules,
|
|
100
|
-
) =>
|
|
101
|
-
|
|
102
|
-
surface,
|
|
103
|
-
input,
|
|
104
|
-
agent,
|
|
105
|
-
sessionRules,
|
|
106
|
-
);
|
|
107
|
-
const getSessionRuleset = () => deps.session.sessionRules.getRuleset();
|
|
100
|
+
) => session.checkPermission(surface, input, agent, sessionRules);
|
|
101
|
+
const getSessionRuleset = () => session.getSessionRuleset();
|
|
108
102
|
const approveSessionRule = (surface: string, pattern: string) =>
|
|
109
|
-
|
|
103
|
+
session.approveSessionRule(surface, pattern);
|
|
110
104
|
|
|
111
105
|
// ── Shared runner deps (built once, reused for all gates) ─────────────
|
|
112
106
|
const runnerDeps: GateRunnerDeps = {
|
|
@@ -120,9 +114,8 @@ export async function handleToolCall(
|
|
|
120
114
|
};
|
|
121
115
|
|
|
122
116
|
// ── Skill-read gate (descriptor + runner) ────────────────────────────────
|
|
123
|
-
const skillDescriptor = describeSkillReadGate(
|
|
124
|
-
|
|
125
|
-
() => deps.session.activeSkillEntries,
|
|
117
|
+
const skillDescriptor = describeSkillReadGate(tcc, () =>
|
|
118
|
+
session.getActiveSkillEntries(),
|
|
126
119
|
);
|
|
127
120
|
if (skillDescriptor) {
|
|
128
121
|
const skillResult = await runGateCheck(
|
|
@@ -138,8 +131,8 @@ export async function handleToolCall(
|
|
|
138
131
|
|
|
139
132
|
// ── External-directory gate (descriptor + runner) ─────────────────────────
|
|
140
133
|
const infraDirs = [
|
|
141
|
-
...
|
|
142
|
-
...
|
|
134
|
+
...session.getInfrastructureDirs(),
|
|
135
|
+
...session.getInfrastructureReadPaths(),
|
|
143
136
|
];
|
|
144
137
|
const extDirDesc = describeExternalDirectoryGate(tcc, infraDirs);
|
|
145
138
|
if (extDirDesc) {
|
package/src/handlers/types.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
import type { ForwardingController } from "../forwarding-manager";
|
|
4
3
|
import type { PermissionPromptDecision } from "../permission-dialog";
|
|
5
4
|
import type { PermissionEventBus } from "../permission-events";
|
|
6
|
-
import type {
|
|
7
|
-
import type { SessionState } from "../runtime";
|
|
8
|
-
import type { SessionLogger } from "../session-logger";
|
|
5
|
+
import type { PermissionSession } from "../permission-session";
|
|
9
6
|
|
|
10
7
|
export type PermissionReviewSource = "tool_call" | "skill_input" | "skill_read";
|
|
11
8
|
|
|
@@ -29,46 +26,23 @@ export interface PromptPermissionDetails {
|
|
|
29
26
|
/**
|
|
30
27
|
* Explicit dependency bag passed to each extracted event handler.
|
|
31
28
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
29
|
+
* `session` is a `PermissionSession` that encapsulates all mutable state
|
|
30
|
+
* and exposes operations instead of fields — eliminating LoD violations,
|
|
31
|
+
* output arguments, and scattered field resets.
|
|
32
|
+
*
|
|
33
|
+
* Remaining top-level fields are things the session does not own:
|
|
34
|
+
* event bus, RPC cleanup, Pi tool API, and permission request ID generation.
|
|
36
35
|
*/
|
|
37
36
|
export interface HandlerDeps {
|
|
38
|
-
// ── Session
|
|
39
|
-
/**
|
|
40
|
-
readonly session:
|
|
41
|
-
|
|
42
|
-
// ── Logging ────────────────────────────────────────────────────────────
|
|
43
|
-
readonly logger: SessionLogger;
|
|
44
|
-
|
|
45
|
-
// ── Immutable infrastructure paths ───────────────────────────────────
|
|
46
|
-
readonly piInfrastructureDirs: readonly string[];
|
|
47
|
-
/** Returns config-derived infrastructure read paths (current at call time). */
|
|
48
|
-
getPiInfrastructureReadPaths(): string[];
|
|
37
|
+
// ── Session ─────────────────────────────────────────────────────────
|
|
38
|
+
/** Encapsulates all mutable session state and permission operations. */
|
|
39
|
+
readonly session: PermissionSession;
|
|
49
40
|
|
|
50
41
|
// ── Event bus ────────────────────────────────────────────────────────
|
|
51
42
|
/** Event bus for emitting permissions:decision broadcast events. */
|
|
52
43
|
readonly events: PermissionEventBus;
|
|
53
44
|
|
|
54
|
-
// ── Factories ──────────────────────────────────────────────────────────
|
|
55
|
-
/** Create a new PermissionManager scoped to cwd's config hierarchy. */
|
|
56
|
-
createPermissionManagerForCwd(
|
|
57
|
-
cwd: string | undefined | null,
|
|
58
|
-
): PermissionManager;
|
|
59
|
-
|
|
60
|
-
// ── Config & lifecycle helpers ─────────────────────────────────────────
|
|
61
|
-
/** Reload merged config from disk; optionally update the stored runtime context. */
|
|
62
|
-
refreshExtensionConfig(ctx?: ExtensionContext): void;
|
|
63
|
-
/** Write the resolved config path set to the review and debug logs. */
|
|
64
|
-
logResolvedConfigPaths(): void;
|
|
65
|
-
|
|
66
45
|
// ── Permission helpers ─────────────────────────────────────────────────
|
|
67
|
-
/**
|
|
68
|
-
* Resolve the active agent name from the session context or system prompt.
|
|
69
|
-
* Updates session.lastKnownActiveAgentName as a side effect.
|
|
70
|
-
*/
|
|
71
|
-
resolveAgentName(ctx: ExtensionContext, systemPrompt?: string): string | null;
|
|
72
46
|
/** Whether the current context can show an interactive permission prompt. */
|
|
73
47
|
canRequestPermissionConfirmation(ctx: ExtensionContext): boolean;
|
|
74
48
|
/** Prompt the user for a permission decision, log the outcome, and return it. */
|
|
@@ -79,8 +53,7 @@ export interface HandlerDeps {
|
|
|
79
53
|
/** Generate a unique ID for a permission request. */
|
|
80
54
|
createPermissionRequestId(prefix: string): string;
|
|
81
55
|
|
|
82
|
-
// ──
|
|
83
|
-
readonly forwarding: ForwardingController;
|
|
56
|
+
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
84
57
|
/** Unsubscribe the permissions:rpc:check and permissions:rpc:prompt handlers. */
|
|
85
58
|
stopPermissionRpcHandlers(): void;
|
|
86
59
|
|
package/src/index.ts
CHANGED
|
@@ -16,12 +16,11 @@ import { requestPermissionDecisionFromUi } from "./permission-dialog";
|
|
|
16
16
|
import { registerPermissionRpcHandlers } from "./permission-event-rpc";
|
|
17
17
|
import { emitReadyEvent } from "./permission-events";
|
|
18
18
|
import { PermissionPrompter } from "./permission-prompter";
|
|
19
|
+
import { PermissionSession } from "./permission-session";
|
|
19
20
|
import {
|
|
20
21
|
createExtensionRuntime,
|
|
21
|
-
createPermissionManagerForCwd,
|
|
22
22
|
logResolvedConfigPaths,
|
|
23
23
|
refreshExtensionConfig,
|
|
24
|
-
resolveAgentName,
|
|
25
24
|
saveExtensionConfig,
|
|
26
25
|
} from "./runtime";
|
|
27
26
|
import { createSessionLogger } from "./session-logger";
|
|
@@ -56,6 +55,18 @@ export default function piPermissionSystemExtension(pi: ExtensionAPI): void {
|
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
refreshExtensionConfig(runtime);
|
|
58
|
+
|
|
59
|
+
const session = new PermissionSession(
|
|
60
|
+
runtime,
|
|
61
|
+
createSessionLogger(runtime),
|
|
62
|
+
new ForwardingManager(runtime.subagentSessionsDir, forwardingDeps),
|
|
63
|
+
{
|
|
64
|
+
refreshExtensionConfig: (ctx) => refreshExtensionConfig(runtime, ctx),
|
|
65
|
+
logResolvedConfigPaths: () => logResolvedConfigPaths(runtime),
|
|
66
|
+
getConfig: () => runtime.config,
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
59
70
|
registerPermissionSystemCommand(pi, {
|
|
60
71
|
getConfig: () => runtime.config,
|
|
61
72
|
setConfig: (next, ctx) => saveExtensionConfig(runtime, next, ctx),
|
|
@@ -78,18 +89,8 @@ export default function piPermissionSystemExtension(pi: ExtensionAPI): void {
|
|
|
78
89
|
});
|
|
79
90
|
|
|
80
91
|
const deps: HandlerDeps = {
|
|
81
|
-
session
|
|
82
|
-
logger: createSessionLogger(runtime),
|
|
83
|
-
piInfrastructureDirs: runtime.piInfrastructureDirs,
|
|
84
|
-
getPiInfrastructureReadPaths: () =>
|
|
85
|
-
runtime.config.piInfrastructureReadPaths ?? [],
|
|
92
|
+
session,
|
|
86
93
|
events: pi.events,
|
|
87
|
-
createPermissionManagerForCwd: (cwd) =>
|
|
88
|
-
createPermissionManagerForCwd(runtime.agentDir, cwd),
|
|
89
|
-
refreshExtensionConfig: (ctx) => refreshExtensionConfig(runtime, ctx),
|
|
90
|
-
logResolvedConfigPaths: () => logResolvedConfigPaths(runtime),
|
|
91
|
-
resolveAgentName: (ctx, systemPrompt) =>
|
|
92
|
-
resolveAgentName(runtime, ctx, systemPrompt),
|
|
93
94
|
canRequestPermissionConfirmation: (ctx) =>
|
|
94
95
|
canResolveAskPermissionRequest({
|
|
95
96
|
config: runtime.config,
|
|
@@ -101,10 +102,6 @@ export default function piPermissionSystemExtension(pi: ExtensionAPI): void {
|
|
|
101
102
|
}),
|
|
102
103
|
promptPermission: (ctx, details) => prompter.prompt(ctx, details),
|
|
103
104
|
createPermissionRequestId,
|
|
104
|
-
forwarding: new ForwardingManager(
|
|
105
|
-
runtime.subagentSessionsDir,
|
|
106
|
-
forwardingDeps,
|
|
107
|
-
),
|
|
108
105
|
stopPermissionRpcHandlers: () => {
|
|
109
106
|
rpcHandles.unsubCheck();
|
|
110
107
|
rpcHandles.unsubPrompt();
|