Repository navigation
fix(agent): a folder's settings no longer change what the desktop agent may do - #113
Merged
Merged
Conversation
…e/settings.json can change, in the real editor Opens the dev build as a separate instance on a folder whose settings turn Autopilot on, point levelcode.ai.baseURL at the folder's own server and set a verify command, with two stand-in providers (the user's and the folder's) that script the same turn. Runs twice: Workspace Trust off (a trusted folder) and Restricted Mode. A display preference set by the folder (chat.fontSize) is the positive control. On develop (08a2cc8) it fails 10 checks, the same in both modes: the pill reads Autopilot, every request goes to the folder's server with the user's key, the agent's command runs with no card, and the folder's verify command runs after the edit. Restricted Mode does not help because the extension declares untrustedWorkspaces.supported: true, and VS Code applies restrictedConfigurations only for 'limited'.
…preferences Every levelcode-ai setting is now application-scoped (user settings only) except the eleven the browser edition already opens to a folder (WORKSPACE_SETTINGS_OK): includeActiveFile, diagrams.enabled and nine chat.* display and context settings. Autopilot, the provider, its base URL, the cloud endpoint and API host, verify.*, the budgets, completions, skills, sessions and ollama.* are read from the user's settings only. sessions.dir stays machine-scoped and the MCP settings stay application-scoped, as before. test/settingsScope.test.js is default-deny: a setting a folder can set fails the suite unless it is on the list; a scope the editor does not know fails it too (VS Code reads a misspelt scope as 'window', which a folder can set); and the desktop and browser lists must be equal. Seven mutations put back one at a time were all caught. The web manifest test no longer pins the desktop manifest as unscoped. The real-editor check from the previous commit passes all 16 checks, trusted and in Restricted Mode, with the folder's display preference still applied. Application scope is shared by all profiles: a value in a non-default profile's settings.json is ignored, and an edit from another profile is written to the Default profile. Matches the browser edition, the MCP settings and VS Code's own chat.tools.global.autoApprove. Left out on purpose (owner's decision): levelcode-updater's levelcode.update.* and levelcode.init.enabled are still folder-settable, for a separate change.
v1.4.0's notes are its GitHub release body. The new file says what changes for someone who set one of these settings in a project on purpose, and that the settings are now shared by all profiles. A comment at the top says draft-release-notes.mjs --write replaces the file (merge, do not overwrite), and that the updater and init settings must be fixed or addressed before tagging.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The scope restrictions consistently enforce the intended boundary, supported by targeted regression checks and no identified blocking issues.
No open issues 🎉
What changed in this PR
Prevents desktop workspace settings from overriding sensitive LevelCode AI configuration, aligning desktop behavior with the browser edition.
Changes:
- Makes 33 settings application-scoped while preserving eleven folder-settable display and context preferences.
- Adds scope regression tests and a real-editor check covering trusted and restricted workspaces.
- Documents migration to user settings and cross-profile behavior.
| File | Description |
|---|---|
web/test/unit/manifest.test.js |
Checks desktop scope exceptions against the browser allowlist. |
web/ai-extension/manifest.js |
Documents the shared desktop/browser boundary. |
RELEASE-NOTES.md |
Explains the security change and migration implications. |
extensions/levelcode-ai/test/settingsScope.test.js |
Guards allowed scopes and desktop/browser parity. |
extensions/levelcode-ai/scripts/folder-settings-editor-check.js |
Checks workspace isolation in the real editor. |
extensions/levelcode-ai/package.json |
Restricts sensitive settings to application scope. |
docs/WEB.md |
Documents desktop alignment and verification. |
Review effort: Balanced
ndemianc
added a commit
that referenced
this pull request
Oct 20, 2026
agent.js: ask_user's answers now feed both the reviewer (ctx.userAnswers, #112) and what remember may quote (ctx.heardThisRun); both kept. package.json: the new levelcode.ai.sessions.memory.notes is application-scoped, like every other levelcode-ai setting since #113 (test/settingsScope.test.js failed on the merge without it: a folder's .vscode/settings.json could have switched remembering on or off).
ndemianc
added a commit
that referenced
this pull request
Oct 20, 2026
Conflicts, each keeping both sides: - agent.js, the end of a run: Ask When Risky's reviewer cost and summary row (#112) and this branch's plan completion and returned "Send now" messages; one agent.done log line with both sets of fields. - extension.js, resumeSession and New Chat: this branch's plan/steer reset and the reset of the person's recorded words (#112/#114), each in both places. - media/chat.html, the message switch: develop's `approvals` message (#112 replaced the two-option `autopilot` one, whose handler no longer exists) and this branch's agentStart/agentStatus, which keep the task list and drop the old plan bar. - test/sessionExpiredHost.test.js, the harness declarations: both sets (agentMode from env, the approvals mode and recorded words; this branch's agentPlan and steerInbox). Checked on the merged tree (macOS, Node 24): scripts/test-extensions.sh 136 files; tsc --checkJs on extension.js and agent.js, no new undefined names; in the dev build plan-progress-editor-check 17/17, approvals-editor-check 12/12, memory-editor-check 11/11 on one of four runs — its "History lists the session after New Session" step is flaky on develop too (1 of 2 there).
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
On the desktop, a folder's
.vscode/settings.jsoncould set every LevelCode AI setting, and its value won over the user's. So a repository could:levelcode.ai.baseURL);levelcode.ai.verify.command). That command never asks, even in Default Approvals.Restricted Mode did not stop it. VS Code applies
restrictedConfigurationsonly for an extension that declaresuntrustedWorkspaces.supported: 'limited', and levelcode-ai declarestrue. The browser edition closed this on 2026-10-11 (WORKSPACE_SETTINGS_OK). The desktop manifest was left as it was.This PR does on the desktop what the browser already does. Every levelcode-ai setting is
application-scoped (user settings only), except the same eleven display and context preferences.Commits
test(agent):scripts/folder-settings-editor-check.jsopens the dev build as a separate instance on a folder that tries all three, and checks the result.chat.fontSize) is the positive control.fix(agent):"scope": "application"on the 33 settings that had no scope.sessions.dirstaysmachine, and the MCP settings were alreadyapplication.test/settingsScope.test.js. It is default-deny: it fails on any folder-settable setting that is not on the list. It also fails on a scope the editor does not know, because VS Code'sparseScopereads a misspelt one aswindow, which a folder can set. And it fails if the desktop and browser lists differ.web/test/unit/manifest.test.jsno longer requires the desktop manifest to have no scopes.docs/WEB.mdand to the comment inweb/ai-extension/manifest.js.docs: starts the next release'sRELEASE-NOTES.mdwith this change. It covers what changes for someone who set one of these settings in a project on purpose, and that application-scoped settings are shared by all profiles. A comment at the top saysdraft-release-notes.mjs --writewould replace the file, so merge instead, and that the updater and init settings (below) come first.What a folder may still set
levelcode.ai.includeActiveFile,levelcode.ai.diagrams.enabled, andlevelcode.ai.chat.autoContext,autoContextMaxFiles,scopeToActiveProject,workspaceMap,startLocation,fontSize,maxImagesPerMessage,proseWidth,groupActivity. This is the browser'sWORKSPACE_SETTINGS_OK, which the owner chose on 2026-10-19.Verified
The real editor (macOS, the dev build), before and after:
chat.fontSizeapplies (positive control)settingsScope: 4 cases. I put back seven defects one at a time (autopilot unscoped, a misspelt scope,windowscope,sessions.dirunscoped, a new setting with no scope, a listed setting locked on the desktop only, autopilot added to the browser list). The suite caught all seven../scripts/test-extensions.sh: 128 test files pass on macOS. I did not run them on Linux (Docker was not answering on this Mac), so this PR'stest.ymlrun is the first Linux run. The new suite reads JSON and uses no timers.Not verified
levelcode.cloud.endpoint,apiUrl) works the same way, but I only read it. The editor check has no signed-in session to send.PROFILE_SCOPES,isSettingAppliedForAllProfiles) and did not run it. The same goes for the faded hint shown on an ignored value in a project'ssettings.json(preferencesRenderers.ts).Not in this PR (owner's decision)
These can still be set by a folder:
levelcode-updater'slevelcode.update.url,enabledandintervalHours. Withurl, the editor itself can offer an update whose Download opens the folder's link.levelcode.init.enabled.They are left for a separate change, and the release notes' TODO says to fix them before tagging. The npp-pack's six editing preferences stay folder-settable on purpose.
Conflicts with #112
#112 (Ask When Risky, draft) rewrites
levelcode.ai.agent.autopilot's description, on the line after the one where this PR adds itsscope. To resolve, keep #112's text and add"scope": "application". I resolved it that way in a scratch copy, wheresettingsScope, the web manifest suite,agentReviewandagentReviewGateall pass. With both merged, theget('agent.autopilot')fallback in #112'sreadApprovalMode()reads only the user's value, with no change needed in #112.