Example

Merge user and project settings

See a scalar take the project value, defaultTools edit or replace the user selection, and an untrusted project's settings never read.

Pi merges two files: user-level <agent-dir>/settings.json and, after you trust the project, <project>/.pi/settings.json. Scalars follow ordinary override, but defaultTools has its own rule, and an untrusted project’s settings are not read at all. The fragments below are small illustrative settings; the Chapter 7 tests assert each result on real files.

Scalar settings: project wins

User file:

{
  "compaction": { "reserveTokens": 1000, "keepRecentTokens": 5000 }
}

Project .pi/settings.json:

{
  "compaction": { "reserveTokens": 2000 }
}

The project value wins per key, and a nested key the project does not set still comes from the user file: the merged reserve is 2000, the retained-token value is 5000.

defaultTools edits, it does not always replace

A project list of only +name and -name entries edits the user’s selection; a plain name in the list replaces it outright.

User defaultTools Project defaultTools Result
["read","bash"] ["+grep","+find","+ls"] ["read","bash","grep","find","ls"]
["read","bash","edit","write"] ["read","powershell"] ["read","powershell"]
["read","bash","edit","write"] ["-bash"] ["read","edit","write"]
(unset) ["read","bash","-bash","+grep"] ["read","grep"]

Within one list, plain names form the selection and + / - then apply in order.

An untrusted project is not read

With trust withheld, the project file is ignored entirely and the user value stands — here reserveTokens stays 1000. Granting trust later makes the project layer apply and the value becomes 2000.

Mechanism and limitations

Documented: the pinned settings.md rule that project settings override agent-directory settings and resource lists combine, and the exported SettingsManager. Observed: settings.test.ts runs the merge through the real SettingsManager over real files and asserts every row above; union.test.ts loads resources through DefaultResourceLoader and shows that both files’ resource lists are unioned, and that an exclusion filter only reaches the resource in the file that lists it — a project !pattern does not remove a user-level skill. The union is observed at load time, while the SettingsManager getter returns one scope’s list.

The fragments are illustrative; they show the merge, not your files. defaultProjectTrust belongs in the agent-directory file only — a project file cannot set it. Chapter 6 owns the full defaultTools reload behaviour.

Full source and tests .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.