Skip to content

feat(path-access): add alwaysScope to save 'always' grants globally#35

Open
yonilerner wants to merge 1 commit intoaliou:mainfrom
yonilerner:yoni/path-access-global-grants
Open

feat(path-access): add alwaysScope to save 'always' grants globally#35
yonilerner wants to merge 1 commit intoaliou:mainfrom
yonilerner:yoni/path-access-global-grants

Conversation

@yonilerner
Copy link
Copy Markdown

Summary

Adds pathAccess.alwaysScope ("local" | "global", default "local") so users can choose where the path-access prompt's "Allow … always" grants are persisted.

Today, picking "Allow file always" or "Allow directory always" in the outside-workspace prompt always saves the grant to the project-local config ({project}/.pi/extensions/guardrails.json). For paths that are universally fine across every project — ~/.nvm/versions/node/..., ~/.config/<tool>, shared library checkouts — having to re-grant them in every project is repetitive.

The merge logic in afterMerge already supports global-scope allowedPaths (additive across global > local > memory), so this PR only changes where new grants from the prompt are written. No change to existing configs.

Behaviour

  • Default (alwaysScope: "local") — unchanged from today.
  • alwaysScope: "global" — "Allow … always" writes to ~/.pi/agent/extensions/guardrails.json, applying the grant in every project.
  • "Allow … this session" continues to go to memory, regardless of alwaysScope.
  • "Allow once" continues to not persist anywhere.

alwaysScope itself can be set per-scope; resolution is memory > local > global (matching the rest of the config).

UI

Exposed in /guardrails:settings under Path Access → Always-grant scope with the same enum-select UX as pathAccess.mode.

Tests

Added src/hooks/path-access.test.ts covering:

  • allow-file-alwayslocal by default
  • allow-file-alwaysglobal when alwaysScope: "global"
  • allow-dir-alwaysglobal (with parent-dir + trailing-slash behaviour preserved)
  • session grants always go to memory regardless of alwaysScope
  • "allow once" never persists
  • existing raw config fields are preserved on save (does not clobber unrelated fields)

pnpm test → 180/180 passing. pnpm typecheck clean. pnpm lint clean.

Docs / changeset

  • README.md — updated Path Access section.
  • docs/defaults.md — added the new default and a description.
  • .changeset/path-access-always-scope.md — minor bump.

Backward compatibility

Default value "local" matches current behaviour exactly. Existing configs without alwaysScope are unaffected. The merge already handled the global scope; only the persistence destination of new grants changes when the user opts in.

By default, the path-access prompt's 'Allow ... always' options save the
grant to the project-local guardrails config. This adds a new
'pathAccess.alwaysScope' setting (default 'local', for backward compat)
that lets users save those grants to the user-wide config instead, so
the same grant applies in every project.

The allowedPaths merge in afterMerge already supports global scope, so
this only changes where new grants are written. Setting is exposed in
the settings UI under Path Access > Always-grant scope.
@yonilerner
Copy link
Copy Markdown
Author

sorry pi got a little ahead of itself, i havent even tested it yet. closing for now

@yonilerner yonilerner closed this May 9, 2026
@yonilerner
Copy link
Copy Markdown
Author

Well it seems like it works. I dont really understand the changeset system so not sure if that addition makes any sense

@yonilerner yonilerner reopened this May 9, 2026
@aliou
Copy link
Copy Markdown
Owner

aliou commented May 9, 2026

Hey @yonilerner thanks for the PR! I'm in the process of rewriting the extension so not going to merge this. There's a good chance this will be handled in that rewrite; but I'm going to leave the PR open to not forget about it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants