@gotgenes/pi-permission-system 21.0.0 → 22.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 +21 -0
- package/README.md +9 -0
- package/docs/configuration.md +6 -0
- package/docs/migration/0644-project-trust-gating.md +32 -0
- package/package.json +1 -1
- package/src/config-loader.ts +15 -4
- package/src/config-store.ts +7 -3
- package/src/handlers/before-agent-start.ts +5 -1
- package/src/handlers/lifecycle.ts +36 -4
- package/src/index.ts +5 -3
- package/src/permission-session.ts +25 -8
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ 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
|
+
## [22.0.0](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v21.0.0...pi-permission-system-v22.0.0) (2026-07-24)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### ⚠ BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* **pi-permission-system:** In an untrusted project, project-scoped permission configuration (project config.json and project-agent frontmatter) and project-scoped runtime config (yoloMode, permissionReviewLog, etc.) are no longer loaded until the user grants project trust. Only global policy applies. Grant project trust, or set defaultProjectTrust, to restore the prior behavior.
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **pi-permission-system:** support skipping project scope in loadAndMergeConfigs ([e5a2e57](https://github.com/gotgenes/pi-packages/commit/e5a2e57b39c7bae44e7ac126b24094c2d5dce155))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **pi-permission-system:** gate project-scoped config on project trust ([f264e71](https://github.com/gotgenes/pi-packages/commit/f264e711b90c7947d805bec654bc78199a76fada))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Documentation
|
|
26
|
+
|
|
27
|
+
* **pi-permission-system:** document project-trust gating for project config ([e955a29](https://github.com/gotgenes/pi-packages/commit/e955a299156215be57144000d5157481615d8060))
|
|
28
|
+
|
|
8
29
|
## [21.0.0](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v20.10.0...pi-permission-system-v21.0.0) (2026-07-24)
|
|
9
30
|
|
|
10
31
|
|
package/README.md
CHANGED
|
@@ -107,6 +107,7 @@ Config lives in one JSON file per scope:
|
|
|
107
107
|
| Project | `<cwd>/.pi/extensions/pi-permission-system/config.json` |
|
|
108
108
|
|
|
109
109
|
Project overrides global; per-agent YAML frontmatter overrides both.
|
|
110
|
+
Project config (policy and runtime knobs) is loaded only once the project is trusted — in an untrusted directory only global config applies, so an untrusted repository cannot loosen your global policy (see [Upgrading](#2200--project-config-requires-project-trust)).
|
|
110
111
|
|
|
111
112
|
Within a surface map like `bash` or `mcp`, **last matching rule wins** — put broad catch-alls first and specific overrides after.
|
|
112
113
|
|
|
@@ -120,6 +121,13 @@ For the full reference — all surfaces, runtime knobs, per-agent overrides, mer
|
|
|
120
121
|
|
|
121
122
|
## Upgrading
|
|
122
123
|
|
|
124
|
+
### 22.0.0 — project config requires project trust
|
|
125
|
+
|
|
126
|
+
Project-scoped configuration (the project `config.json` and project-agent frontmatter — both permission policy and runtime knobs such as `yoloMode`) is now loaded only when Pi reports the project as trusted.
|
|
127
|
+
In an untrusted directory, only global config applies; a skip is surfaced with a warning and a `project_trust.skipped` review-log entry.
|
|
128
|
+
Grant project trust (or set `defaultProjectTrust`) to load a project's config.
|
|
129
|
+
See [docs/migration/0644-project-trust-gating.md](docs/migration/0644-project-trust-gating.md).
|
|
130
|
+
|
|
123
131
|
### 16.0.0 — the bash gate now fails closed
|
|
124
132
|
|
|
125
133
|
The permission gate fails closed: an internal gate error blocks the tool (with a `gate_error` review-log entry) instead of running it ungated, and a non-empty bash command that cannot be parsed resolves to `ask` (sentinel `<unparseable-bash-command>`) rather than falling through to a permissive top-level `*`.
|
|
@@ -140,6 +148,7 @@ If you relied on the old permissive behavior for bash, set an explicit permissiv
|
|
|
140
148
|
| [docs/troubleshooting.md](docs/troubleshooting.md) | Common issues, diagnostic logging, threat model |
|
|
141
149
|
| [docs/migration/legacy-to-flat.md](docs/migration/legacy-to-flat.md) | Migration from pre-v2 config layout |
|
|
142
150
|
| [docs/migration/strict-config-validation.md](docs/migration/strict-config-validation.md) | Strict config validation (breaking) — rejected configs, and the cross-scope fail-closed clamp |
|
|
151
|
+
| [docs/migration/0644-project-trust-gating.md](docs/migration/0644-project-trust-gating.md) | Project-trust gating (breaking) — project config loads only after project trust |
|
|
143
152
|
|
|
144
153
|
## Development
|
|
145
154
|
|
package/docs/configuration.md
CHANGED
|
@@ -11,6 +11,12 @@ One unified config file per scope:
|
|
|
11
11
|
|
|
12
12
|
Project config overrides global config; per-agent frontmatter overrides both.
|
|
13
13
|
|
|
14
|
+
**Project config requires project trust.**
|
|
15
|
+
Project and project-agent scopes (both permission policy and runtime config such as `yoloMode`) are loaded only when Pi reports the project as trusted (`ctx.isProjectTrusted()`).
|
|
16
|
+
In an untrusted directory, only global (and global-agent) config applies, so an untrusted repository cannot loosen your global policy; the extension surfaces a loud warning plus a `project_trust.skipped` review-log entry when it skips a project scope.
|
|
17
|
+
Grant project trust (or configure `defaultProjectTrust`) to load the project's config; a trust grant reloads project policy on the next `resources_discover` reload.
|
|
18
|
+
See [migration/0644-project-trust-gating.md](migration/0644-project-trust-gating.md).
|
|
19
|
+
|
|
14
20
|
> **Coming from OpenCode?**
|
|
15
21
|
> This extension's permission model was inspired by OpenCode's.
|
|
16
22
|
> See [OpenCode Compatibility](opencode-compatibility.md) for shared concepts, divergences, and a porting guide.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Migration guide: project-trust gating
|
|
2
|
+
|
|
3
|
+
Starting with the release that closes #644, the permission-system loads project-scoped configuration only after Pi reports the project as **trusted** (`ctx.isProjectTrusted()`).
|
|
4
|
+
This is a **breaking change** in how config is loaded in an untrusted directory.
|
|
5
|
+
|
|
6
|
+
## What changed
|
|
7
|
+
|
|
8
|
+
The extension used to load project-scoped config from the current working directory unconditionally — it never consulted Pi's project-trust decision.
|
|
9
|
+
Because project scope has higher precedence than global, an untrusted repository could ship a `.pi/extensions/pi-permission-system/config.json` that **loosened** an operator's global policy before the user granted trust — for example flipping a global `bash: deny` to `bash: allow`, or setting `yoloMode: true`.
|
|
10
|
+
|
|
11
|
+
Now, when the project is **not** trusted:
|
|
12
|
+
|
|
13
|
+
- Project and project-agent **permission policy** scopes are not loaded — only global (and global-agent) policy participates in resolution.
|
|
14
|
+
- Project **runtime config** (`yoloMode`, `permissionReviewLog`, `piInfrastructureReadPaths`, `shellTools`, `authorizerChain`, …) is not merged.
|
|
15
|
+
- Each skip is surfaced loudly: a UI warning and a `project_trust.skipped` entry in the permission review log.
|
|
16
|
+
|
|
17
|
+
This aligns the extension with Pi's own trust model, which already withholds project-local skills, prompts, and agents from untrusted directories.
|
|
18
|
+
|
|
19
|
+
## Timing and recovery
|
|
20
|
+
|
|
21
|
+
Pi resolves the trust decision (including any `defaultProjectTrust` setting) before `session_start`, so the guard sees the effective decision from the first tool call.
|
|
22
|
+
If you grant trust after the session starts, Pi fires `resources_discover` with `reason: "reload"`, and the extension re-reads trust and loads the project **policy** at that point.
|
|
23
|
+
Project **runtime** config (e.g. `yoloMode`) is re-read on the next session start.
|
|
24
|
+
|
|
25
|
+
## What you need to do
|
|
26
|
+
|
|
27
|
+
If you only use global config, nothing changes.
|
|
28
|
+
|
|
29
|
+
If you rely on a project's `.pi/extensions/pi-permission-system/config.json`, **grant the project trust** when Pi prompts (or configure `defaultProjectTrust` to always trust).
|
|
30
|
+
Until then, the project's permission rules and runtime knobs are ignored and only your global policy applies.
|
|
31
|
+
|
|
32
|
+
If a project's rules stop taking effect after upgrading (surfaces you allowed at the project scope start prompting or denying per global policy), check whether the project is trusted — the review log will contain a `project_trust.skipped` entry naming the untrusted `cwd`.
|
package/package.json
CHANGED
package/src/config-loader.ts
CHANGED
|
@@ -286,12 +286,20 @@ export interface MergedConfigResult {
|
|
|
286
286
|
* Legacy files are detected and warned about. Their content is parsed with the
|
|
287
287
|
* flat-format parser — legacy-format keys (defaultPolicy, tools, bash, etc.)
|
|
288
288
|
* are not translated and contribute no permission rules.
|
|
289
|
+
*
|
|
290
|
+
* When `options.includeProjectScope` is `false`, the project-scope steps (4 and
|
|
291
|
+
* 5) are skipped entirely — neither the legacy project policy nor the new
|
|
292
|
+
* project config is read or merged. This gates project-local config on project
|
|
293
|
+
* trust: an untrusted repository cannot loosen the operator's global policy
|
|
294
|
+
* (#644). It defaults to `true`, preserving the trusted / caller-agnostic path.
|
|
289
295
|
*/
|
|
290
296
|
export function loadAndMergeConfigs(
|
|
291
297
|
agentDir: string,
|
|
292
298
|
cwd: string,
|
|
293
299
|
extensionRoot: string,
|
|
300
|
+
options: { includeProjectScope?: boolean } = {},
|
|
294
301
|
): MergedConfigResult {
|
|
302
|
+
const includeProjectScope = options.includeProjectScope !== false;
|
|
295
303
|
const allIssues: string[] = [];
|
|
296
304
|
|
|
297
305
|
const newGlobalPath = getGlobalConfigPath(agentDir);
|
|
@@ -339,8 +347,8 @@ export function loadAndMergeConfigs(
|
|
|
339
347
|
const globalConfig = globalResult.config;
|
|
340
348
|
merged = mergeUnifiedConfigs(merged, globalConfig);
|
|
341
349
|
|
|
342
|
-
// 4. Legacy project policy
|
|
343
|
-
if (existsSync(legacyProjectPolicyPath)) {
|
|
350
|
+
// 4. Legacy project policy — skipped when the project scope is withheld.
|
|
351
|
+
if (includeProjectScope && existsSync(legacyProjectPolicyPath)) {
|
|
344
352
|
const legacy = loadUnifiedConfig(legacyProjectPolicyPath);
|
|
345
353
|
allIssues.push(
|
|
346
354
|
`Legacy project policy found at '${legacyProjectPolicyPath}'. ` +
|
|
@@ -351,8 +359,11 @@ export function loadAndMergeConfigs(
|
|
|
351
359
|
merged = mergeUnifiedConfigs(merged, legacy.config);
|
|
352
360
|
}
|
|
353
361
|
|
|
354
|
-
// 5. New project config
|
|
355
|
-
|
|
362
|
+
// 5. New project config — skipped when the project scope is withheld, so an
|
|
363
|
+
// untrusted project contributes nothing and `project` reports empty.
|
|
364
|
+
const projectResult = includeProjectScope
|
|
365
|
+
? loadUnifiedConfig(newProjectPath)
|
|
366
|
+
: { config: {}, issues: [] };
|
|
356
367
|
allIssues.push(...projectResult.issues);
|
|
357
368
|
const projectConfig = projectResult.config;
|
|
358
369
|
merged = mergeUnifiedConfigs(merged, projectConfig);
|
package/src/config-store.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface ConfigReader {
|
|
|
41
41
|
* coupling between the class and test doubles.
|
|
42
42
|
*/
|
|
43
43
|
export interface SessionConfigStore extends ConfigReader {
|
|
44
|
-
refresh(ctx
|
|
44
|
+
refresh(ctx: ExtensionContext | undefined, projectTrusted: boolean): void;
|
|
45
45
|
logResolvedPaths(cwd?: string): void;
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -96,14 +96,17 @@ export class ConfigStore implements SessionConfigStore, CommandConfigStore {
|
|
|
96
96
|
* Reload merged config from disk.
|
|
97
97
|
*
|
|
98
98
|
* If `ctx` is provided, uses it to derive the cwd and sync UI status.
|
|
99
|
-
*
|
|
99
|
+
* When `projectTrusted` is `false`, the project scope is withheld so an
|
|
100
|
+
* untrusted repository's runtime config (`yoloMode`, `permissionReviewLog`,
|
|
101
|
+
* …) cannot loosen the operator's global config (#644).
|
|
100
102
|
*/
|
|
101
|
-
refresh(ctx
|
|
103
|
+
refresh(ctx: ExtensionContext | undefined, projectTrusted: boolean): void {
|
|
102
104
|
const cwd = ctx?.cwd ?? null;
|
|
103
105
|
const mergeResult = loadAndMergeConfigs(
|
|
104
106
|
this.deps.agentDir,
|
|
105
107
|
cwd ?? "",
|
|
106
108
|
EXTENSION_ROOT,
|
|
109
|
+
{ includeProjectScope: projectTrusted },
|
|
107
110
|
);
|
|
108
111
|
const runtimeConfig = normalizePermissionSystemConfig(mergeResult.merged);
|
|
109
112
|
this.config = runtimeConfig;
|
|
@@ -127,6 +130,7 @@ export class ConfigStore implements SessionConfigStore, CommandConfigStore {
|
|
|
127
130
|
debugLog: runtimeConfig.debugLog,
|
|
128
131
|
permissionReviewLog: runtimeConfig.permissionReviewLog,
|
|
129
132
|
yoloMode: runtimeConfig.yoloMode,
|
|
133
|
+
projectTrusted,
|
|
130
134
|
});
|
|
131
135
|
}
|
|
132
136
|
|
|
@@ -62,7 +62,11 @@ export class AgentPrepHandler {
|
|
|
62
62
|
// to whole-string matching.
|
|
63
63
|
this.warmParser();
|
|
64
64
|
this.session.activate(ctx);
|
|
65
|
-
|
|
65
|
+
// Gate the mid-session runtime-config refresh on project trust too, so an
|
|
66
|
+
// untrusted project cannot slip its runtime config (e.g. `yoloMode`) in
|
|
67
|
+
// right before agent start after session_start withheld it (#644). The
|
|
68
|
+
// session_start handler already warned; do not re-warn on every start.
|
|
69
|
+
this.session.refreshConfig(ctx, ctx.isProjectTrusted());
|
|
66
70
|
|
|
67
71
|
const agentName = this.session.resolveAgentName(ctx, event.systemPrompt);
|
|
68
72
|
const activeTools = this.toolRegistry.getActive();
|
|
@@ -17,6 +17,15 @@ interface ResourcesDiscoverPayload {
|
|
|
17
17
|
reason: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Shown when project config is skipped because the project is untrusted, so the
|
|
22
|
+
* reduced-scope state is never silent (#644). Exported for assertion in tests.
|
|
23
|
+
*/
|
|
24
|
+
export const UNTRUSTED_PROJECT_MESSAGE =
|
|
25
|
+
"pi-permission-system: project is not trusted — skipping project-scoped " +
|
|
26
|
+
"permission configuration. Only global policy applies. Grant project trust " +
|
|
27
|
+
"to load this project's permission rules.";
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
* Handles session lifecycle events: start, reload, and shutdown.
|
|
22
31
|
*
|
|
@@ -42,9 +51,13 @@ export class SessionLifecycleHandler {
|
|
|
42
51
|
event: SessionStartPayload,
|
|
43
52
|
ctx: ExtensionContext,
|
|
44
53
|
): Promise<void> {
|
|
45
|
-
|
|
46
|
-
this.session.
|
|
54
|
+
const projectTrusted = ctx.isProjectTrusted();
|
|
55
|
+
this.session.refreshConfig(ctx, projectTrusted);
|
|
56
|
+
this.session.resetForNewSession(ctx, projectTrusted);
|
|
47
57
|
this.session.logResolvedConfigPaths();
|
|
58
|
+
if (!projectTrusted) {
|
|
59
|
+
this.warnProjectUntrusted(ctx, "session_start");
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
const agentName = this.session.resolveAgentName(ctx);
|
|
50
63
|
const policyIssues = this.resolver.getConfigIssues(agentName ?? undefined);
|
|
@@ -68,12 +81,19 @@ export class SessionLifecycleHandler {
|
|
|
68
81
|
return Promise.resolve();
|
|
69
82
|
}
|
|
70
83
|
|
|
71
|
-
handleResourcesDiscover(
|
|
84
|
+
handleResourcesDiscover(
|
|
85
|
+
event: ResourcesDiscoverPayload,
|
|
86
|
+
ctx: ExtensionContext,
|
|
87
|
+
): Promise<void> {
|
|
72
88
|
if (event.reason !== "reload") {
|
|
73
89
|
return Promise.resolve();
|
|
74
90
|
}
|
|
75
91
|
|
|
76
|
-
|
|
92
|
+
const projectTrusted = ctx.isProjectTrusted();
|
|
93
|
+
this.session.reload(projectTrusted);
|
|
94
|
+
if (!projectTrusted) {
|
|
95
|
+
this.warnProjectUntrusted(ctx, "resources_discover");
|
|
96
|
+
}
|
|
77
97
|
this.logger.debug("lifecycle.reload", {
|
|
78
98
|
triggeredBy: "resources_discover",
|
|
79
99
|
reason: event.reason,
|
|
@@ -82,6 +102,18 @@ export class SessionLifecycleHandler {
|
|
|
82
102
|
return Promise.resolve();
|
|
83
103
|
}
|
|
84
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Record the project-trust skip in the review log and surface a loud warning
|
|
107
|
+
* to the user, so the reduced (global-only) scope is never silent (#644).
|
|
108
|
+
*/
|
|
109
|
+
private warnProjectUntrusted(
|
|
110
|
+
ctx: ExtensionContext,
|
|
111
|
+
phase: "session_start" | "resources_discover",
|
|
112
|
+
): void {
|
|
113
|
+
this.logger.review("project_trust.skipped", { cwd: ctx.cwd, phase });
|
|
114
|
+
this.logger.warn(UNTRUSTED_PROJECT_MESSAGE);
|
|
115
|
+
}
|
|
116
|
+
|
|
85
117
|
handleSessionShutdown(): Promise<void> {
|
|
86
118
|
const ctx = this.session.getRuntimeContext();
|
|
87
119
|
if (ctx) {
|
package/src/index.ts
CHANGED
|
@@ -171,7 +171,9 @@ export default function piPermissionSystemExtension(pi: ExtensionAPI): void {
|
|
|
171
171
|
// refresh() must run after `session` is assigned: a debug-write IO failure
|
|
172
172
|
// triggers the logger's notify sink — `session.notify(m)` — which no-ops
|
|
173
173
|
// on the null context but requires `session` to be bound.
|
|
174
|
-
|
|
174
|
+
// No ctx/trust decision exists at factory init, so withhold the project
|
|
175
|
+
// scope (fail closed); session_start reloads with the real trust decision.
|
|
176
|
+
configStore.refresh(undefined, false);
|
|
175
177
|
|
|
176
178
|
const configPath = getGlobalConfigPath(agentDir);
|
|
177
179
|
registerPermissionSystemCommand(pi, {
|
|
@@ -258,8 +260,8 @@ export default function piPermissionSystemExtension(pi: ExtensionAPI): void {
|
|
|
258
260
|
pi.on("session_start", (event, ctx) =>
|
|
259
261
|
lifecycle.handleSessionStart(event, ctx),
|
|
260
262
|
);
|
|
261
|
-
pi.on("resources_discover", (event) =>
|
|
262
|
-
lifecycle.handleResourcesDiscover(event),
|
|
263
|
+
pi.on("resources_discover", (event, ctx) =>
|
|
264
|
+
lifecycle.handleResourcesDiscover(event, ctx),
|
|
263
265
|
);
|
|
264
266
|
pi.on("session_shutdown", () => lifecycle.handleSessionShutdown());
|
|
265
267
|
pi.on("before_agent_start", (event, ctx) => agentPrep.handle(event, ctx));
|
|
@@ -99,11 +99,15 @@ export class PermissionSession implements ToolCallGateInputs {
|
|
|
99
99
|
/**
|
|
100
100
|
* Reset all mutable state for a new session.
|
|
101
101
|
*
|
|
102
|
-
* Configures the injected PermissionManager for `ctx.cwd
|
|
102
|
+
* Configures the injected PermissionManager for `ctx.cwd` (or global-only
|
|
103
|
+
* when `projectTrusted` is `false`, withholding the project cwd so an
|
|
104
|
+
* untrusted project's policy scopes are not loaded, #644), clears skill
|
|
103
105
|
* entries, and activates the new context.
|
|
104
106
|
*/
|
|
105
|
-
resetForNewSession(ctx: ExtensionContext): void {
|
|
106
|
-
this.permissionManager.configureForCwd(
|
|
107
|
+
resetForNewSession(ctx: ExtensionContext, projectTrusted: boolean): void {
|
|
108
|
+
this.permissionManager.configureForCwd(
|
|
109
|
+
projectTrusted ? ctx.cwd : undefined,
|
|
110
|
+
);
|
|
107
111
|
this.skillEntries = [];
|
|
108
112
|
this.activate(ctx);
|
|
109
113
|
}
|
|
@@ -121,9 +125,15 @@ export class PermissionSession implements ToolCallGateInputs {
|
|
|
121
125
|
/**
|
|
122
126
|
* Reload permission manager and clear skill entries for the current context.
|
|
123
127
|
* Used on config reload (e.g. `resources_discover` with reason "reload").
|
|
128
|
+
*
|
|
129
|
+
* When `projectTrusted` is `false` the project cwd is withheld, so a reload
|
|
130
|
+
* in an untrusted project reloads only global policy; a trust grant on a
|
|
131
|
+
* later reload re-includes the project scope (#644).
|
|
124
132
|
*/
|
|
125
|
-
reload(): void {
|
|
126
|
-
this.permissionManager.configureForCwd(
|
|
133
|
+
reload(projectTrusted: boolean): void {
|
|
134
|
+
this.permissionManager.configureForCwd(
|
|
135
|
+
projectTrusted ? this.context?.cwd : undefined,
|
|
136
|
+
);
|
|
127
137
|
this.skillEntries = [];
|
|
128
138
|
}
|
|
129
139
|
|
|
@@ -168,9 +178,16 @@ export class PermissionSession implements ToolCallGateInputs {
|
|
|
168
178
|
|
|
169
179
|
// ── Config ─────────────────────────────────────────────────────────────
|
|
170
180
|
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Reload merged config from disk; optionally update the stored runtime
|
|
183
|
+
* context. When `projectTrusted` is `false`, the project scope is withheld
|
|
184
|
+
* so an untrusted project's runtime config is not merged (#644).
|
|
185
|
+
*/
|
|
186
|
+
refreshConfig(
|
|
187
|
+
ctx: ExtensionContext | undefined,
|
|
188
|
+
projectTrusted: boolean,
|
|
189
|
+
): void {
|
|
190
|
+
this.configStore.refresh(ctx, projectTrusted);
|
|
174
191
|
}
|
|
175
192
|
|
|
176
193
|
/** Write the resolved config path set to the review and debug logs. */
|